Web Links Browse Collapse Expand PDF Previous Next

Introducing SQL Anywhere Studio

Version 9.0.2

DC38120-01-0902-01

October 2004

Copyright
About This Manual
Introducing SQL Anywhere Studio
Introducing Adaptive Server Anywhere and UltraLite
Introducing Replication Technologies
SQL Anywhere Studio for Windows CE
SQL Anywhere Studio Supported Platforms
The Architecture of Database Applications
Selecting Data from Database Tables
Selecting Data from Multiple Tables
Selecting Data Using Subqueries
Selecting Aggregate Data
Updating the Database
The Sample Database
Making the Connection
Using Interactive SQL
Managing Databases with Sybase Central
Designing and Building a Database
Synchronizing Databases with MobiLink
Replicating Data with SQL Remote
Designing Databases with PowerDesigner
Creating Reports with InfoMaker
Microsoft Visual Basic Quick Start
Glossary


Copyright

Copyright © 1989–2004 Sybase, Inc. Portions copyright © 2001–2004 iAnywhere Solutions, Inc. All rights reserved.

No part of this publication may be reproduced, transmitted, or translated in any form or by any means, electronic, mechanical, manual, optical, or otherwise, without the prior written permission of iAnywhere Solutions, Inc. iAnywhere Solutions, Inc. is a subsidiary of Sybase, Inc.

Sybase, SYBASE (logo), 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-Library, APT-Translator, ASEP, AvantGo, AvantGo Application Alerts, AvantGo Mobile Delivery, AvantGo Mobile Document Viewer, AvantGo Mobile Inspection, AvantGo Mobile Marketing Channel, AvantGo Mobile Pharma, AvantGo Mobile Sales, AvantGo Pylon, AvantGo Pylon Application Server, AvantGo Pylon Conduit, AvantGo Pylon PIM Server, AvantGo Pylon Pro, Backup Server, BayCam, Bit-Wise, BizTracker, Certified PowerBuilder Developer, Certified SYBASE Professional, Certified SYBASE Professional Logo, 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, Dynamic Mobility Model, Dynamo, e-ADK, E-Anywhere, e-Biz Integrator, 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 Portal (logo), Enterprise SQL Server Manager, Enterprise Work Architecture, Enterprise Work Designer, Enterprise Work Modeler, eProcurement Accelerator, eremote, Everything Works Better When Everything Works Together, EWA, E-Whatever, Financial Fusion, Financial Fusion (and design), Financial Fusion Server, Formula One, Fusion Powered e-Finance, Fusion Powered Financial Destinations, Fusion Powered STP, Gateway Manager, GeoPoint, GlobalFIX, iAnywhere, iAnywhere Solutions, ImpactNow, Industry Warehouse Studio, InfoMaker, Information Anywhere, Information Everywhere, InformationConnect, InstaHelp, Intelligent Self-Care, InternetBuilder, iremote, iScript, Jaguar CTS, jConnect for JDBC, KnowledgeBase, Logical Memory Manager, Mail Anywhere Studio, MainframeConnect, Maintenance Express, Manage Anywhere Studio, MAP, M-Business Channel, M-Business Network, M-Business Server, MDI Access Server, MDI Database Gateway, media.splash, Message Anywhere Server, MetaWorks, MethodSet, ML Query, MobiCATS, My AvantGo, My AvantGo Media Channel, My AvantGo Mobile Marketing, MySupport, Net-Gateway, Net-Library, New Era of Networks, Next Generation Learning, Next Generation Learning Studio, O DEVICE, OASiS, OASiS logo, 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++, Orchestration Studio, Partnerships that Work, PB-Gen, PC APT Execute, PC DB-Net, PC Net Library, PhysicalArchitect, Pocket PowerBuilder, PocketBuilder, Power Through Knowledge, power.stop, Power++, 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, QAnywhere, Rapport, Relational Beans, RepConnector, Replication Agent, Replication Driver, Replication Server, Replication Server Manager, Replication Toolkit, Report Workbench, Report-Execute, Resource Manager, RW-DisplayLib, RW-Library, 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 (logo), 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, TotalFix, TradeForce, Transact-SQL, Translation Toolkit, Turning Imagination Into Reality, UltraLite, UltraLite.NET, UNIBOM, Unilib, Uninull, Unisep, Unistring, URK Runtime Kit for UniCode, Versacore, Viewer, 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, and XP Server are trademarks of Sybase, Inc. or its subsidiaries.

All other trademarks are property of their respective owners.


About This Manual

Subject

This book introduces SQL Anywhere Studio, the complete relational data-management and synchronization system for mobile, embedded, and workgroup computing.

SQL Anywhere Studio is a set of software components for working with relational data. It includes the Adaptive Server Anywhere and UltraLite relational database-management systems, as well as data synchronization and replication technology. It also includes applications for designing and deploying databases, and for creating custom reports and data entry forms.

Audience

This book is for all application developers and database administrators using SQL Anywhere Studio.

Before you begin

This book assumes an elementary familiarity with relational databases and SQL.

SQL Anywhere Studio documentation
Accessing information online
Documentation conventions
The Adaptive Server Anywhere sample database
The CustDB sample database
Finding out more and providing feedback


SQL Anywhere Studio documentation

This book is part of the SQL Anywhere documentation set. This section describes the books in the documentation set and how you can use them.

The SQL Anywhere Studio documentation

The SQL Anywhere Studio documentation is available in a variety of forms: in an online form that combines all books in one large help file; as separate PDF files for each book; and as printed books that you can purchase. The documentation consists of the following books:

  • Introducing SQL Anywhere Studio This book provides an overview of the SQL Anywhere Studio database management and synchronization technologies. It includes tutorials to introduce you to each of the pieces that make up SQL Anywhere Studio.

  • What's New in SQL Anywhere Studio This book is for users of previous versions of the software. It lists new features in this and previous releases of the product and describes upgrade procedures.

  • Adaptive Server Anywhere Database Administration Guide This book covers material related to running, managing, and configuring databases and database servers.

  • Adaptive Server Anywhere SQL User's Guide This book describes how to design and create databases; how to import, export, and modify data; how to retrieve data; and how to build stored procedures and triggers.

  • Adaptive Server Anywhere SQL Reference Manual This book provides a complete reference for the SQL language used by Adaptive Server Anywhere. It also describes the Adaptive Server Anywhere system tables and procedures.

  • Adaptive Server Anywhere Programming Guide This book describes how to build and deploy database applications using the C, C++, and Java programming languages. Users of tools such as Visual Basic and PowerBuilder can use the programming interfaces provided by those tools. It also describes the Adaptive Server Anywhere ADO.NET data provider.

  • Adaptive Server Anywhere SNMP Extension Agent User's Guide This book describes how to configure the Adaptive Server Anywhere SNMP Extension Agent for use with SNMP management applications to manage Adaptive Server Anywhere databases.

  • Adaptive Server Anywhere Error Messages This book provides a complete listing of Adaptive Server Anywhere error messages together with diagnostic information.

  • SQL Anywhere Studio Security Guide This book provides information about security features in Adaptive Server Anywhere databases. Adaptive Server Anywhere 7.0 was awarded a TCSEC (Trusted Computer System Evaluation Criteria) C2 security rating from the U.S. Government. This book may be of interest to those who wish to run the current version of Adaptive Server Anywhere in a manner equivalent to the C2-certified environment.

  • MobiLink Administration Guide This book describes how to use the MobiLink data synchronization system for mobile computing, which enables sharing of data between a single Oracle, Sybase, Microsoft or IBM database and many Adaptive Server Anywhere or UltraLite databases.

  • MobiLink Clients This book describes how to set up and synchronize Adaptive Server Anywhere and UltraLite remote databases.

  • MobiLink Server-Initiated Synchronization User's Guide This book describes MobiLink server-initiated synchronization, a feature of MobiLink that allows you to initiate synchronization from the consolidated database.

  • MobiLink Tutorials This book provides several tutorials that walk you through how to set up and run MobiLink applications.

  • QAnywhere User's Guide This manual describes MobiLink QAnywhere, a messaging platform that enables the development and deployment of messaging applications for mobile and wireless clients, as well as traditional desktop and laptop clients.

  • iAnywhere Solutions ODBC Drivers This book describes how to set up ODBC drivers to access consolidated databases other than Adaptive Server Anywhere from the MobiLink synchronization server and from Adaptive Server Anywhere remote data access.

  • SQL Remote User's Guide This book describes all aspects of the SQL Remote data replication system for mobile computing, which enables sharing of data between a single Adaptive Server Anywhere or Adaptive Server Enterprise database and many Adaptive Server Anywhere databases using an indirect link such as e-mail or file transfer.

  • SQL Anywhere Studio Help This book includes the context-sensitive help for Sybase Central, Interactive SQL, and other graphical tools. It is not included in the printed documentation set.

  • UltraLite Database User's Guide This book is intended for all UltraLite developers. It introduces the UltraLite database system and provides information common to all UltraLite programming interfaces.

  • UltraLite Interface Guides A separate book is provided for each UltraLite programming interface. Some of these interfaces are provided as UltraLite components for rapid application development, and others are provided as static interfaces for C, C++, and Java development.

In addition to this documentation set, PowerDesigner and InfoMaker include their own online documentation.

Documentation formats

SQL Anywhere Studio provides documentation in the following formats:

  • Online documentation The online documentation contains the complete SQL Anywhere Studio documentation, including both the books and the context-sensitive help for SQL Anywhere tools. The online documentation is updated with each maintenance release of the product, and is the most complete and up-to-date source of documentation.

    To access the online documentation on Windows operating systems, choose Start > Programs > SQL Anywhere 9 > Online Books. You can navigate the online documentation using the HTML Help table of contents, index, and search facility in the left pane, as well as using the links and menus in the right pane.

    To access the online documentation on UNIX operating systems, see the HTML documentation under your SQL Anywhere installation.

  • PDF books The SQL Anywhere books are provided as a set of PDF files, viewable with Adobe Acrobat Reader.

    The PDF books are accessible from the online books, or from the Windows Start menu.

  • Printed books The complete set of books is available from Sybase sales or from eShop, the Sybase online store at [external link] http://eshop.sybase.com/eshop/documentation.


Accessing information online

The SQL Anywhere Studio online documentation features a number of tools to help you navigate through the information.

Online books (PDF)

Online books (PDF) are exact copies of the printed documentation in PDF format, viewable with Adobe Acrobat. The presence and appearance of some of the following features depends on which version of Acrobat or Acrobat Reader you are using.

  • Bookmarks tab The Bookmarks tab displays a list of all the chapters in the current book. You can click any chapter or page to view the expand or collapse the headings and view the structure of the document. Clicking a heading displays the page in the right side of the window. The Bookmarks tab provides an overview of the structure of the book and quick access to specific chapters and pages.

  • Active links Active links, such as see also references, are highlighted in blue. When you move your cursor over the link, the hand turns to a pointing finger. Clicking the link takes you to the place in the documentation the link points to, either in the current book or in other books. Links between books do not work properly when Acrobat is run as a plugin to certain browsers. They do work properly in Internet Explorer, or when using Acrobat directly.

  • Forward/Back buttons The Forward and Back buttons at the top left side of the help window let you retrace your steps, and revisit the pages in the order you visited them. Each time you click the Back button, the topic moves to the most recently visited page prior to the one currently displayed. The Forward button becomes enabled after you click the Back button at least once, and remains enabled until you return to the most recently visited page.

  • Go to start/Go to end buttons Clicking the Go to start button returns you to the very first page of the book, and clicking the Go to end button advances you to the very last page of the book.

Online books

Online books are exact copies of the printed documentation in Microsoft HTML Help format.

  • Contents tab The Contents tab displays a list of all the books in the SQL Anywhere Studio collection. You can double click any book to view the chapters within that book, and you can click each chapter to view its pages. The Contents tab provides an overview of the structure of the documentation and quick access to specific chapters and pages.

  • Page header The page header is located at the top of each page and describes the location of the current page. The current location is described as book title > chapter title > page title. You can click the book or chapter titles to move to that part of the book. Notice that as you navigate through the pages on the right side of the window, the placeholder on the Contents tab on the left side of the window moves accordingly.

  • Index tab The index contains keywords associated with chapters and pages. You can type a word or phrase in the top box of the Index tab to jump to a topic in the index in the scroll box below. When you find the entry you are looking for, simply double-click the entry to display the page.

  • Search tab Type a word or phrase in the top box of the Search tab, and click List Topics to display all topics that contain that word or phrase in the scroll box below. If you want to find an exact match, put the word or phrase in double quotation marks ("). You can further refine your selection by selecting the checkboxes at the bottom of the page, or using Boolean search terms by clicking the arrow next to the search box. Search previous results lets you narrow your next search to the topics displayed in your previous search. Match similar words looks for words that are close in spelling to the searched word. Search titles only will search only the titles for the desired word. When you find the entry you are looking for, simply double-click the entry to display the page.

  • Favorites tab When you find a page that you know you want to access again, add it to your Favorites list for quick access. Display the page you want to save, click the Favorites tab, then click the Add button at the bottom of the window. Clicking Add adds the topic listed in the Current topic box (the topic to the Topics list. You can modify your favorites list by selecting a topic and clicking Remove. Favorites entries are preserved between upgrades of the online books.

  • Previous/Next buttons The Previous and Next buttons at the top right side of the help window are equivalent to turning the pages of a book. Previous turns the page back one topic (moves to the previous page in chronological order). Next turns the page forward one topic (moves to the subsequent page in chronological order).

  • Forward/Back buttons The Forward and Back buttons on the menu bar let you retrace your steps, and revisit the pages in the order you visited them. Each time you click the Back button, the topic moves to the most recently visited page prior to the one currently displayed. The Forward button becomes enabled after you click the Back button at least once, and remains enabled until you return to the most recently visited page.

  • Web Links button The Web Links button at the top of the help window offers quick access to iAnywhere Solutions resources, including the iAnywhere web site, tech support, registration, downloads, and the iAnywhere Solutions developer community.

  • Browse button Click the Browse button for quick access to tutorials, a list of actions you can perform, and a glossary of terms.

  • Collapse button Some pages contain headings that are collapsible, as indicated by the plus (+) or minus (-) sign immediately to the left of the heading. You can click the Collapse button to either close all the headings, or click the Expand button to open all the headings.

  • PDF button Clicking the PDF button opens the current book in PDF format.


Documentation conventions

This section lists the typographic and graphical conventions used in this documentation.

Syntax conventions

The following conventions are used in the SQL syntax descriptions:

  • Keywords All SQL keywords appear in upper case, like the words ALTER TABLE in the following example:

    ALTER TABLE [ owner.]table-name

  • Placeholders Items that must be replaced with appropriate identifiers or expressions are shown like the words owner and table-name in the following example:

    ALTER TABLE [ owner.]table-name

  • Repeating items Lists of repeating items are shown with an element of the list followed by an ellipsis (three dots), like column-constraint in the following example:

    ADD column-definition [ column-constraint, ... ]

    One or more list elements are allowed. In this example, if more than one is specified, they must be separated by commas.

  • Optional portions Optional portions of a statement are enclosed by square brackets.

    RELEASE SAVEPOINT [ savepoint-name ]

    These square brackets indicate that the savepoint-name is optional. The square brackets should not be typed.

  • Options When none or only one of a list of items can be chosen, vertical bars separate the items and the list is enclosed in square brackets.

    [ ASC | DESC ]

    For example, you can choose one of ASC, DESC, or neither. The square brackets should not be typed.

  • Alternatives When precisely one of the options must be chosen, the alternatives are enclosed in curly braces and a bar is used to separate the options.

    [ QUOTES { ON | OFF } ]

    If the QUOTES option is used, one of ON or OFF must be provided. The brackets and braces should not be typed.

Graphic icons

The following icons are used in this documentation.

  • A client application.

    The icon for a client application: a box containing three triangles in a circle.

  • A database server, such as Sybase Adaptive Server Anywhere.

    The icon for a database server: a box containing a schematic table in a circle.

  • A database. In some high-level diagrams, the icon may be used to represent both the database and the database server that manages it.

    The icon for a database: a cylinder.

  • Replication or synchronization middleware. These assist in sharing data among databases. Examples are the MobiLink Synchronization Server and the SQL Remote Message Agent.

    The icon for replication or synchronization middleware: a box containing an arrow in a circle.

  • A programming interface.

    The icon for a client application: a shaded box with rounded ends.


The Adaptive Server Anywhere sample database

Many of the examples throughout the documentation use the Adaptive Server Anywhere sample database.

The sample database is held in a file named asademo.db, and is located in your SQL Anywhere directory.

The sample database represents a small company. It contains internal information about the company (employees, departments, and finances) as well as product information and sales information (sales orders, customers, and contacts). All information in the database is fictional.

The following figure shows the tables in the sample database and how they relate to each other.

The Adaptive Server Anywhere sample database, including tables, column names, primary keys, and foreign key relationships.


The CustDB sample database

Many of the examples in the MobiLink and UltraLite documentation use the UltraLite sample database.

The reference database for the UltraLite sample database is held in a file named custdb.db, and is located in the Samples\UltraLite\CustDB subdirectory of your SQL Anywhere directory. A complete application built on this database is also supplied.

The sample database is a sales-status database for a hardware supplier. It holds customer, product, and sales force information for the supplier.

The following figure shows the tables in the CustDB database and how they are related to each other.

The UltraLite sample database, including tables, column names, primary keys, and foreign key relationships.


Finding out more and providing feedback

We would like to receive your opinions, suggestions, and feedback on this documentation.

You can provide feedback on this documentation and on the software through newsgroups set up to discuss SQL Anywhere technologies. These newsgroups can be found on the forums.sybase.com news server.

The newsgroups include the following:

  • [external link] sybase.public.sqlanywhere.general

  • [external link] sybase.public.sqlanywhere.linux

  • [external link] sybase.public.sqlanywhere.mobilink

  • [external link] sybase.public.sqlanywhere.product_futures_discussion

  • [external link] sybase.public.sqlanywhere.replication

  • [external link] sybase.public.sqlanywhere.ultralite

  • [external link] ianywhere.public.sqlanywhere.qanywhere

Newsgroup disclaimer
iAnywhere Solutions has no obligation to provide solutions, information or ideas on its newsgroups, nor is iAnywhere Solutions obliged to provide anything other than a systems operator to monitor the service and insure its operation and availability.

iAnywhere Solutions Technical Advisors as well as other staff assist on the newsgroup service when they have time available. They offer their help on a volunteer basis and may not be available on a regular basis to provide solutions and information. Their ability to help is based on their workload.

You can e-mail comments and suggestions to the SQL Anywhere documentation team at [external link] iasdoc@ianywhere.com. Although we do not undertake to reply to e-mails at that address, you can be sure we will read your suggestions with interest.


Introducing SQL Anywhere Studio

Introducing SQL Anywhere Studio

About this chapter

This chapter introduces the pieces that make up SQL Anywhere Studio.


Welcome to SQL Anywhere Studio

With SQL Anywhere Studio, you can deliver information to workgroup, mobile, and embedded database systems throughout an entire organization.

SQL Anywhere Studio includes the following components.

Relational database systems

  • Adaptive Server Anywhere The relational database at the core of the product is a transaction-based SQL database designed for personal and workgroup use. Adaptive Server Anywhere runs on a wide range of operating systems, including many flavors of Windows and UNIX, as well as on Novell NetWare. It runs on hardware ranging from multiple-CPU workgroup servers to the most modest PCs, as well as on Windows CE devices.

  • UltraLite For building and deploying relational database applications on small devices, including the Palm Computing Platform and Windows CE. UltraLite has built-in support for MobiLink synchronization.

    UltraLite lets you build relational databases with less than 50 kb of disk space, and is specifically intended for small devices.

Data synchronization technologies

  • MobiLink For two-way synchronization of data between a central database and many remote UltraLite or Adaptive Server Anywhere databases. The central database can be Adaptive Server Anywhere, Adaptive Server Enterprise, or another DBMS such as Oracle, Microsoft SQL Server, or IBM DB2.

  • SQL Remote For two-way, message-based replication of data between a central database and many remote databases. With SQL Remote, you can replicate data between laptop computers and a central database, using e-mail or dial-up access.

  • Replication Agent For replicating data from Adaptive Server Anywhere databases to other databases via Sybase Replication Server.

Development, design, and administration tools

  • InfoMaker For querying databases and creating sophisticated and effective custom reports of data. InfoMaker is also a personal data assistant that lets you work with data in many ways.

  • PowerDesigner For designing, generating, documenting, and maintaining databases.

  • Management and development tools SQL Anywhere Studio includes the Sybase Central database management tool and the Interactive SQL database utility, as well as a query editor and a stored procedure debugger.

    SQL Anywhere Studio includes an optionally-installable accessibility enablement module. This component provides the Sun AccessBridge module, which is loaded whenever you use Sybase Central or Interactive SQL. Third-party software such as screen readers make use of this module to provide access to software features.

InfoMaker and PowerDesigner are available only on Windows operating systems. However, they can be used as clients of a server running on any supported operating system.

Separately-licensable components

The following components are separately licensable and must be ordered before you can install them.

  • Java option The Java virtual machine and runtime classes that enable the use of Java in the database must be ordered separately.

  • SQL Anywhere Studio security option The software for strong encryption must be ordered separately. Strong encryption can be used in the following cases:

    • Transport-layer security between an Adaptive Server Anywhere database server and client.

    • Transport-layer security between a MobiLink synchronization server and client.

    • AES_FIPS database encryption. (AES database file encryption other than AES_FIPS is included in the base package and does not require separate licensing.)

To order the Java and security components, you have the following options:

  • Visit [external link] http://www.sybase.com/detail?id=1015780.

  • See the card in your SQL Anywhere Studio package.

  • Call iAnywhere at (800) 801-2069.


Installing SQL Anywhere Studio

How you install SQL Anywhere Studio depends on the operating system you are using. You must ensure that you are properly licensed before installing the software.

toggle To install SQL Anywhere Studio (Windows operating systems)

  • Start the installation by running the setup.exe program in the root directory of the SQL Anywhere Studio CD-ROM. Follow the instructions in the setup wizard.

    The setup program allows you to choose which of the components you wish to install.

toggle To install SQL Anywhere Studio (Novell NetWare or Windows CE)

  • You must install Adaptive Server Anywhere for NetWare from a machine connected to the NetWare server and running a Microsoft Windows operating system. Run the SQL Anywhere Studio setup program and choose NetWare or Windows CE installation.

toggle To install SQL Anywhere Studio (UNIX)

  • The installation instructions depend on which UNIX operating system you are using. For more information, consult the separate Read Me First booklet, which is included in SQL Anywhere Studio for UNIX.

The SQL Anywhere program group


The SQL Anywhere program group

For Windows operating systems, after the software is installed, you will have a SQL Anywhere program group. You can reach the program group by clicking the Start button and choosing Programs > SQL Anywhere 9.

Installing SQL Anywhere Studio under UNIX does not provide a program group.

Program group items

The program group contains some or all of the following items. The items you see depend on the choices you made when installing the software.

  • Adaptive Server Anywhere Contains the items:

    • Interactive SQL Starts the Interactive SQL utility for sending SQL statements to a database.

    • Network Server Sample Starts the network database server and loads the sample database.

    • ODBC Administrator Starts the ODBC Administrator program for setting up and editing ODBC data sources.

    • Personal Server Sample Starts the personal server and loads the sample database.

  • MobiLink program group To access MobiLink synchronization programs and samples.

  • UltraLite program group To access UltraLite programs and samples.

  • Check for updates To access a web page with information about the latest updates available for your version of SQL Anywhere Studio.

  • iAnywhere Online Resources Opens a web page with information about iAnywhere Solutions.

  • Online Books Opens the online documentation for Adaptive Server Anywhere.

  • Sybase Central Starts Sybase Central, the database management tool.

In addition, you may have items for InfoMaker and PowerDesigner.


Introducing Adaptive Server Anywhere and UltraLite

About this chapter

This chapter introduces the Adaptive Server Anywhere relational database system, as well as the UltraLite, the small-footprint Adaptive Server Anywhere database. It describes their uses, features, and differences.

Introduction to Adaptive Server Anywhere
Intended uses
Hallmarks
The database server
Applications
Introduction to UltraLite
Comparing Adaptive Server Anywhere and UltraLite


Introduction to Adaptive Server Anywhere

This chapter describes the particular hallmarks of Adaptive Server Anywhere and describes the uses to which it can be put.

Adaptive Server Anywhere provides a series of tools for storing and managing data. You can use these tools to enter data into your database, to change your database structure, and to view or alter your data.

The Adaptive Server Anywhere relational database-management system is the heart of SQL Anywhere Studio. Adaptive Server Anywhere is designed for tasks that require a full-featured SQL database. It is designed to operate in varied environments. It takes advantage of available memory and CPU resources, providing good performance in environments with ample resources. It also operates well in environments with limited physical and database administration resources, including mobile computing environments, embedded database use, and use as a database server for small and medium businesses.


Intended uses

Roles for which Adaptive Server Anywhere is ideally suited include the following:

  • A small and medium business database server Adaptive Server Anywhere is built to handle the requirements of small and medium businesses, with anywhere from a few users to several hundred users. It provides a high-performance database for workgroups and companies, well-suited for (but not limited to) environments where administration and hardware resources are limited.

    Adaptive Server Anywhere can employ multiple CPUs and use up to 64 Gb of memory. Our customers have Adaptive Server Anywhere databases with tens of gigabytes of data in production use.

  • An embedded database Many applications require a database "behind the scenes". Personal Information Managers, document management systems, network monitoring applications—just about any application that stores information. Adaptive Server Anywhere is intended to be the database for these applications. The UltraLite deployment option is intended for embedded environments that have very restricted resources.

    A key feature of embedded databases is that they be able to run entirely without administration. Adaptive Server Anywhere has demonstrated this facility in many demanding commercial applications.

  • Mobile computing Laptop and notebook computers are now common in many workplaces. Adaptive Server Anywhere is intended to be the SQL database for these computers. With MobiLink synchronization and SQL Remote replication, Adaptive Server Anywhere extends transaction-based computing throughout the enterprise. The UltraLite deployment option and MobiLink synchronization technology provide full database functionality on devices with limited resources, such as hand-held computers.


Hallmarks

Adaptive Server Anywhere is built around the following technological hallmarks:

  • Full SQL relational database-management system Adaptive Server Anywhere is a transaction-processing relational database-management system (RDBMS), with full recovery capabilities, online backup, referential integrity actions, stored procedures, triggers, row-level concurrency control, schedules and events, a rich SQL language, and all the features you expect in a full SQL RDBMS.

  • Economical hardware requirements Adaptive Server Anywhere requires fewer memory and disk resources than other database-management systems.

  • Easy to use Adaptive Server Anywhere is self-tuning and easy to manage. You can use Adaptive Server Anywhere without the extensive database administration efforts usually associated with relational database-management systems.

  • Standalone and network use Adaptive Server Anywhere can be used in a standalone manner, for example as an embedded database in a data-centric application, or as a network server in a multi-user client/server or three-tier environment. As an embedded database system, it can be started automatically by an application when required.

  • High performance While Adaptive Server Anywhere is designed with simple administration and modest resource requirements in mind, it is a scalable, high-performance DBMS. Adaptive Server Anywhere can run on multiple CPUs, has an advanced query optimizer, and provides performance monitoring and tuning tools.

  • Industry standard interfaces Adaptive Server Anywhere provides a native ODBC 3.5 driver for high performance from ODBC applications, and an OLE DB driver for use from ActiveX Data Object (ADO) programming environments. It has an ADO.NET data provider for Adaptive Server Anywhere and it also comes with Sybase jConnect for JDBC, as well as an iAnywhere JDBC driver, and supports embedded SQL and Sybase Open Client interfaces.

  • A cross-platform solution Adaptive Server Anywhere can be run on many operating systems, including Windows, Novell NetWare, Sun Solaris, and Linux.

    The components available on each platform may differ. For information, see SQL Anywhere Studio Supported Platforms.

System requirements

For more information on supported operating systems for components in SQL Anywhere Studio, see SQL Anywhere Studio Supported Platforms.

Network software requirements


Network software requirements

If you are running an Adaptive Server Anywhere network server, you must have appropriate networking software installed and running.

The Adaptive Server Anywhere network server is available for Windows, Novell NetWare, Linux, and UNIX operating systems.

Adaptive Server Anywhere supports the TCP/IP network protocol and the SPX protocol for Novell NetWare.


The database server

There are two versions of the Adaptive Server Anywhere database server included in the product:

  • The personal database server This server is provided for single-user, same-machine use: for example, as an embedded database server. It is also useful for development work.

    The name of the personal server executable is as follows:

    • On UNIX operating systems, it is dbeng9.

    • On Windows, except Windows CE, it is dbeng9.exe.

  • The network database server In addition to the features of the personal server, the network server supports client/server communications across a network. It is provided for multi-user use.

    The name of the network server executable is as follows:

    • On UNIX operating systems, it is dbsrv9.

    • On Windows, including Windows CE, it is dbsrv9.exe.

    • On Novell NetWare, the server is a NetWare Loadable Module (NLM) called dbsrv9.nlm.

Same SQL features in each version

The request-processing engine is identical in the two versions of the server. They support exactly the same SQL language, and exactly the same database features. The personal server does not support communications across a network, more than ten concurrent connections, or the use of more than one CPU. Applications developed against a personal server work unchanged against a network server.


Applications

This section introduces some of the database applications that are supplied with Adaptive Server Anywhere in the SQL Anywhere Studio product. These applications help you design, build, and administer your databases.

Which components you have installed depends on which operating system you are using, what choices you made when installing the software, and whether you received the Adaptive Server Anywhere product itself, or installed Adaptive Server Anywhere as part of another product.

For example, if you have received Adaptive Server Anywhere as part of another product, you may not have both versions of the database server. Similarly, not all components are available on all operating systems. For example, there is no personal server for NetWare, only a network server.


Sybase Central

Sybase Central provides a graphical user interface for creating and modifying databases and database objects, for inspecting the structure of databases, and for database server administration. You can use it to perform such tasks as creating a new database, adding a table, or adding a column to a table.


Interactive SQL

Interactive SQL is an application for typing and sending SQL statements to a database. Interactive SQL allows you to query and alter data in your database, as well as modify the structure of your database. Everything that can be done in Sybase Central can be done in Interactive SQL, but administration tasks are easier in Sybase Central.


Utilities

A set of utilities is available for carrying out administration tasks such as backing up a database. Utilities are useful for including in batch files for repeated use.

For more information about administration utilities, see Database Administration Utilities.


Introduction to UltraLite

The appearance of small computing devices such as handheld computers, pagers, and mobile phones creates a demand for a database with even more modest memory requirements than Adaptive Server Anywhere. An obvious option is to produce a trimmed down relational database engine, but our experience has shown that each application and each customer has a distinct set of features that are, for them, essential. Further, such an approach would mean that customers would have to learn two different databases, inevitably different in some ways.

Instead, we developed UltraLite, a novel technology that uses a reference database and your application source code to generate a relational database engine containing only those features of Adaptive Server Anywhere used by your application. Each query is stored with a complete access plan for fast execution; the code needed to execute just those tasks you need are built into your UltraLite database engine. Each UltraLite database engine is different, but many are only a few tens of kilobytes, and can easily be run in a device as small as a pager.

Adaptive Server Anywhere serves as a reference database when you build your UltraLite application, and so your SQL statements, data types, and so on are exactly those of Adaptive Server Anywhere. UltraLite is a deployment technology for Adaptive Server Anywhere, not a different database system. The tasks that each UltraLite database engine is built to perform are carried out in a manner completely compatible with Adaptive Server Anywhere.

UltraLite has built-in MobiLink synchronization technology so that your application is linked into the information network.

UltraLite supports the Palm Computing Platform, Windows CE, and other operating systems used in small devices, such as Java.

UltraLite architecture

If you want to provide a database application for a small device such as a handheld organizer, you may want to use the UltraLite deployment technology. In UltraLite, the database server and the application are part of the same process, and the database server is specific to the application.

An UltraLite application on a single machine.

In this case, the database may not be a file on disk. The storage method for the database depends on the deployment platform.


Comparing Adaptive Server Anywhere and UltraLite

This section highlights the differences between Adaptive Server Anywhere and UltraLite, to help you decide which technology is suited to your needs.

If you know what your resources are already, choosing between Adaptive Server Anywhere and UltraLite may be an easy decision. If, however, you are planning to deploy on a platform supported by both technologies, such as Windows CE, consider the following issues.


Adaptive Server Anywhere

For many years, Adaptive Server Anywhere has provided relational database technology designed specifically for the needs of workgroup, mobile and embedded computing. The product has been designed from the ground up with this market in mind. The advantages of choosing Adaptive Server Anywhere include:

  • Adaptive Server Anywhere is designed to operate efficiently with limited memory, CPU power, and disk space. Core features such as the query optimizer and the data caching mechanism are designed specifically to operate without extravagant use of resources. At the same time, Adaptive Server Anywhere contains the features needed to take advantage of workgroup servers, including support for many users, scalability over multiple CPUs, and advanced concurrency features. If you are deploying mainly to PCs, Adaptive Server Anywhere is built to meet your needs.

  • Adaptive Server Anywhere is a cross-platform solution. The same database runs on Windows (Windows 95 and its successors, Windows NT and its successors, and Windows CE), UNIX including Linux, and Novell NetWare. You can move a database file from one operating system to another.

  • Adaptive Server Anywhere is designed to operate without administration, making it ideal for use as an embedded database. Adaptive Server Anywhere provides a self-tuning query optimizer, built-in scheduling and event-handling capabilities, as well as autostart and autostop mechanisms.

  • Many years of experience working with successful customers have led to a rich set of field-tested features. Not only the standard checklist features of stored procedures, triggers, declarative referential integrity, full transaction processing, and recovery, but all the little extras that can make the difference between a successful project and a failure.

  • SQL Anywhere synchronization technologies (SQL Remote and MobiLink) mean that you can integrate Adaptive Server Anywhere databases into your organization's infrastructure.

  • Adaptive Server Anywhere can be a benefit if you are happier using an interface other than Embedded SQL or Java (such as ODBC or OLE DB) and your target platform is not so resource-constrained as to require UltraLite.


UltraLite: the "small fingerprint" database

UltraLite is a novel technology that uses a reference database and your application source code to generate a relational database engine containing only those features of Adaptive Server Anywhere used by your application. The advantages of choosing UltraLite include:

  • UltraLite database engines include only the code necessary to execute the tasks specified when your application is compiled, so you cannot use dynamic SQL to execute ad hoc queries against an UltraLite database.

    Each UltraLite database and database engine is for use by only a single application: if you want to use more than one application against a single database, you should choose Adaptive Server Anywhere.

  • The programming model for UltraLite enables platform-independent database access code so that you can port the user interface to new platforms and devices without having to alter the underlying data access layer.

  • If you are deploying to small devices such as the Palm Computing Platform, UltraLite will fit the bill.


Introducing Replication Technologies

About this chapter

Data replication is the sharing of data among physically distinct databases. When an application modifies shared data at any one database, the changes are propagated to the other databases in the replication setup. Changes can be propagated by various means and through a variety of channels, allowing flexible replication setups while preserving data integrity. Data replication is also referred to as data synchronization.

Sybase has three replication technologies. MobiLink and SQL Remote are designed for replication between a central database and a large number of remote databases. Replication Server is intended for near-real-time replication between a relatively small number of databases.


Web Links Browse Collapse Expand PDF Previous Next

Introducing SQL Anywhere Studio

Introducing Replication Technologies

Introduction

This section introduces basic concepts in data replication.


Benefits of data replication

Data availability

One of the key benefits of a data replication system is that data is made available locally, rather than through potentially expensive, less reliable, and slow connections to a single central database. Data is accessible locally even in the absence of any connection to a central server, so you are not cut off from data in the event of a failure of a long-distance network connection.

Response time

Replication improves response times for data requests for two reasons. Retrieval rates are faster because requests are processed on a local server, without accessing a wide area network. Also, local processing offloads work from a central database server so that competition for processor time is decreased.


Challenges for replication technologies

Any replication technology must address several challenges that arise as a result of the increased flexibility permitted by replication.

Transactional integrity

One of the challenges of any replication system is to ensure that each database retains transactional integrity at all times.

Replication Server and SQL Remote replicate portions of the transaction log in such a way that transactions are maintained during replication: either a whole transaction is replicated, or none of it is replicated. This ensures transactional integrity at each database in the setup.

MobiLink consolidates changes made in multiple, committed transactions. These changes are applied to another database in a single transaction.

Data consistency

Another challenge to replication systems is to maintain data consistency throughout the setup. Replication systems maintain a loose consistency in the setup as a whole: that is, all changes are replicated to each site over time in a consistent manner, but different sites may have different copies of data at any instant.


Consolidated and remote databases

Both MobiLink and SQL Remote provide data replication between a consolidated database and a set of remote databases.

A consolidated database is a database that contains all the data to be replicated. A remote database is a copy of the consolidated database that may be running either at the same site as the consolidated database or at a physically distant site.

The figure displays a schematic illustration of a small installation.

A single consolidated database and a set of remote databases.
Remote users

A replication installation includes many remote databases. Each remote database contains a subset of the information in the consolidated database. Each remote database is a physically separate database, usually on a separate computer. All remote databases must stay consistent with the consolidated database.

The entire replication setup may be considered a single dispersed database, with the master copy of all shared data being kept at the consolidated database.

Each remote site that submits replications to the consolidated database is considered to be a remote user of the consolidated database. In the case that a remote site is a multi-user server, the entire site is considered to be a single remote user of the consolidated database.


Hierarchical database configurations

For databases in a hierarchical configuration, every database has a single parent database, except the consolidated database, which has no parent.

SQL Remote supports hierarchical configurations of databases; it does not support peer-to-peer replication or other non-hierarchical configurations. MobiLink is also normally used with a hierarchical configuration, but can also be used in other configurations.

For any two databases directly sharing data in a hierarchical configuration, one is always above or below the other in the hierarchy.

Hierarchical database configurations.

Databases in a non-hierarchical configuration do not have a well-defined notion of above or below.

Non-hierarchical database configurations.

In a MobiLink or SQL Remote installation, each database contains all of, or a subset of, the data replicated by the database above it in the hierarchy.

Remote databases can contain tables that are not present at the consolidated database as long as they are not involved in replication. SQL Remote requires that the table and column names in the remote databases match the ones in the consolidated database. In contrast, MobiLink allows data to be stored in different columns and tables in the remote databases than in the consolidated database, allowing greater flexibility.


Two-way replication

All Sybase replication technologies provide two-way replication: changes made at the consolidated database are propagated to remote databases and changes made at remote databases are propagated to the consolidated database and, hence, to other remote databases. Sybase Replication Server requires that a particular piece of data can be modified at only one location. Both SQL Remote and MobiLink allow the same data to be changed simultaneously at multiple locations and provide a means of resolving any conflicts.


Propagation methods

When a transaction modifies shared data at any one database, the transaction or changes must be replicated to the other databases in the replication setup. There are various means by which this task may be accomplished.


Session-based replication: MobiLink

In a session-based replication scheme, synchronization occurs in real time over some sort of direct communications link. For example, the connection could be over a modem, network, or radio modem. Remote sites connect at intervals of minutes, hours, days, or weeks.

A session-based synchronization process is analogous to a telephone conversation in which all outstanding issues at both ends are resolved. The process follows a particular format. A MobiLink remote site begins by opening a connection to a MobiLink synchronization server and uploading a complete list of all the changes made to the remote database since the previous synchronization. Upon receiving this data, the server updates the consolidated database, then sends back all relevant changes. The remote site incorporates the entire set of changes, then sends back a confirmation and closes the connection.


Message-based replication: SQL Remote

SQL Remote exchanges data between databases using messages. Messages are typically files, placed in a particular directory, or specially formatted e-mail messages. A message agent, attached to each database, sends messages regarding changes to its own data. The same agent also receives messages from one or more other databases and modifies the database, according to the contents of the received messages. This system allows replication between databases that have no direct connection: an occasional message-based connection such as e-mail or a periodic dial-up link is sufficient.

In message-based communications, each message carries its destination address and other control information so that no direct connection is necessary between applications exchanging information. For example, an e-mail message contains the destination address; there is no direct connection between the sending server and the recipient.

Message services use store and forward methods

Just as session-based client/server applications rely on network communication protocol stacks, such as TCP/IP or Novell NetWare's SPX, so message-based applications rely on message services such as Internet Simple Mail Transfer Protocol (SMTP), Microsoft's Messaging API (MAPI), Lotus' Vendor Independent Messaging (VIM), or a simple shared file link.

Message services use store-and-forward methods to get each message to its destination: for example, e-mail systems store messages until the recipient opens their mail folder to read their mail, at which time the e-mail system forwards the message.

Building a replication system on top of a message system means that a message-based replication system, such as SQL Remote, does not need to implement a store-and-forward system to get messages to their destination. Just as session-based client/server applications do not implement their own protocol stacks to pass information between client and server, so SQL Remote uses existing message systems to pass the messages.

Message-based data replication.
Guaranteed delivery

To work reliably, a message-based replication system must both guarantee that all messages reach their destination and that the messages are applied in the same order that they are sent. SQL Remote incorporates a protocol to guarantee application of replication updates in the correct order.


Connection-based replication: Replication Server

Some replication technologies rely on the presence of a continuous, or at least almost continuous, connection between the databases. Through this connection, the two databases conduct an ongoing dialogue. These types of systems excel at replicating changes quickly. Indeed, given sufficient resources and channel capacity, replication can occur reliably with a lag time of no more than a few seconds.

Replication server is a near real-time replication system designed primarily for replication between a small number of databases. It is normally used with a continuous, reliable, high-speed connection. It incorporates store-and-forward techniques that allow replication to continue automatically when a connection is lost and later re-established.

The main drawback of this type of system is that a reliable, continuous connection can be expensive to maintain. This restriction makes connection-based technologies suited to replication between two large, fixed databases. In environments where the remote machines are mobile or are only occasionally connected, message-based or session-based technologies provide more flexible solutions.


Sybase replication technologies

Sybase provides three replication technologies:

  • MobiLink is a session-based technology intended for the two-way replication of data between a central, consolidated database and a large number of remote databases. It supports a variety of consolidated database servers, including non-Sybase databases. Administration and resource requirements at the remote sites are minimal, making it well suited to a variety of mobile applications. At the end of each synchronization session, the databases are consistent.

  • SQL Remote is a message-based technology intended for the two-way replication of transactions. It is designed for two-way replication involving a consolidated data server and large number of remote databases. Administration and resource requirements at the remote sites are minimal, making it well suited to mobile databases. This system is message based. Depending on the setup, typical lag times between the consolidated and remote databases can be on the order of seconds, minutes, or hours.

  • Replication Server is a connection-based technology intended for the two-way replication of transactions. It is well suited to replication between a small number of enterprise databases connected by a high-speed network, generally with an administrator at each site. In such a setup, it is possible to achieve lag times as low as a few seconds.

Choosing a replication technology


Choosing a replication technology

Each Sybase replication technology lends itself to particular applications. The following descriptions differentiate the technologies and let you select the one best suited to your needs.

You should consider which of the following elements are important in your application

Your consolidated database system

In a typical replication environment, a large database serves as a central repository for information. Sometimes you can choose a database system that suits your needs. Other times, a central database already exists and you must adapt the replication system to work with it.

MobiLink can work with many popular database servers, including Adaptive Server Anywhere, Sybase Adaptive Server Enterprise, Oracle, Microsoft SQL Server, and IBM DB2.

In a SQL Remote installation, the central database must be either Adaptive Server Anywhere or Sybase Adaptive Server Enterprise.

Your remote database system

Sybase replication technologies also differ in the types of remote databases that they can support. MobiLink allows your remote database to be either Adaptive Server Anywhere or UltraLite.

SQL Remote supports only Adaptive Server Anywhere remote databases.

Network characteristics

MobiLink and SQL Remote are both well suited to occasionally-connected environments, where remote sites must operate for hours or days in isolation, although more frequent synchronization is possible whenever a network connection is available. In contrast, Replication Server is designed for a continuous connection to allow large amounts of data to be replicated promptly.

MobiLink is session based. A real-time connection is required during synchronization. If this connection is interrupted before synchronization is complete, the process will not complete until the next synchronization. In contrast, SQL Remote relays information via messages, which can be sent or received asynchronously. These messages may take the form of files on a hard disk, or e-mail messages. These messages can be processed whenever they are received, allowing replication to occur incrementally.

Frequency of synchronization

In some situations, it may be important that your information is replicated immediately. In others, replication once or twice a day may suffice. In fact, more frequent replication may be impossible when no network connection is available.

Both MobiLink and SQL Remote are primarily intended for situations where replication occurs infrequently; for example every few hours or days. MobiLink and SQL Remote can both handle more frequent synchronization, but resource and network requirements are greater. However, given sufficient resources, MobiLink synchronizations can occur every few minutes. SQL Remote, when run in continuous mode, allows replication to occur every few seconds.

Replication Server is designed for setups requiring near real-time replication.

The number of remote sites

If you have a very large number of remote users, the best options are MobiLink or SQL Remote. The SQL Remote message-based design allows a typical installation to handle thousands of remote users. MobiLink scalability is limited only by the scalability of the consolidated database-management system. Replication Server is designed for only a few sites.

While these numbers are guidelines, there is no hard limit on the maximum number of remote sites with any of these systems. The actual number depends on the amount of information replicated, the frequency of synchronization, and the design of your application.

Transaction ordering

SQL Remote replicates data by scanning the transaction log and preparing messages, as appropriate, for each transaction. It orders these messages and sends them to the remote or consolidated site. When processing receives messages, SQL Remote always processes them in the same order as they were applied to the other database. When necessary, it automatically delays processing a message until all earlier messages have been applied.

MobiLink, in contrast, works by grouping the results of multiple transactions on the remote database into one set of changes to be applied to the consolidated database. Since synchronization always occurs at a transaction boundary, referential integrity is preserved. The order of the individual changes made during the component transactions is not preserved. However, since uncommitted data is never synchronized, data integrity is preserved.

Achieving data consistency at a particular time

Immediately following each MobiLink synchronization session, the data in the two databases is consistent. The ability to guarantee the consistency of the data at a remote site at a particular point in time is an advantage of MobiLink session-based replication. For example, if it is important that the data at a remote site accurately reflect the data in the consolidated database at a particular time, say 10 o'clock in the morning, this objective can be achieved by synchronizing just prior to this time. As long as the synchronization completes successfully, the currency of the data at the remote site is assured.

When changes to the data are replicated through an exchange of messages, it is difficult to guarantee that the data in a particular remote site is completely consistent with the data in the consolidated site at any particular point in time. For example, sometimes a message is lost in transit. SQL Remote automatically recognizes this fault and resends the message, but such interruptions can cause unexpected delays.


Replication technology characteristics summary

The following table summarizes the characteristics of each replication technology. Following sections expand on the entries in this table.

Replication technology | Number of databases | Connection | Frequency | Volume | Database types
MobiLink | Large | Occasional | Medium | Medium | Heterogeneous
SQL Remote | Large | Occasional | Low | Medium | Homogeneous
Replication Server | Small | Continuous | Low | High | Heterogeneous


MobiLink characteristics

MobiLink is designed for replication installations with the following requirements:

  • Large numbers of databases MobiLink is designed to support large numbers of remote databases. It can support thousands of remote databases in a single installation.

  • Occasionally connected MobiLink supports databases that are occasionally connected or indirectly connected to the network on which the server is running. MobiLink scalability is limited only by the scalability of the consolidated database-management system.

  • Flexible synchronization schedule Applications typically connect and synchronize at intervals of minutes, hours, or days.

  • Low to medium volume Download information for remote sites is prepared for one remote site at a time. Large amounts of data in a MobiLink system can cause long connection times, since the remote site cannot disconnect until synchronization is complete.

  • Heterogeneous databases MobiLink supports many of the most popular relational-database systems for use as a consolidated database. The schema of the remote sites can be different from that of the consolidated database because you control the synchronization process by writing scripts.


SQL Remote characteristics

SQL Remote is designed for replication installations with the following requirements:

  • Large numbers of databases SQL Remote is designed to support a large number of remote databases. It can support thousands of remote databases in a single installation because the messages for many remote sites can be prepared simultaneously.

  • Occasionally connected SQL Remote supports databases that are occasionally connected or indirectly connected to the network on which the server is running.

  • Low to high latency High latency means a long lag time between data being entered at one database and being replicated to each database in the installation. With SQL Remote, replication messages are sent typically at periods of seconds, minutes, hours, or days.

  • Low to moderate volume As replication messages are delivered occasionally, a high transaction volume at each remote site can lead to a very large volume of messages. SQL Remote is best suited to systems with a relatively low volume of replicated data per remote database. At the consolidated site, SQL Remote can, however, prepare messages efficiently by preparing messages for multiple sites simultaneously.

  • Homogeneous databases SQL Remote supports Adaptive Server Enterprise and Adaptive Server Anywhere databases. Each database in the system must have a very similar schema.


Replication Server characteristics

Replication Server is designed for replication installations with the following requirements:

  • Small numbers of databases Replication Server is designed to support replication among servers, with installations typically involving fewer than one hundred servers.

  • Continuously connected Connections between primary sites and replicate sites may be over a wide area network, but Replication Server is designed for situations where there is a near-continuous connection path for data exchange among the servers in the installation.

  • Low latency Low latency means a short lag time between data being entered at one database and being replicated to each database in the installation. With Replication Server, replication messages are sent typically within seconds of being entered at a primary site.

  • High volume With near-continuous connections and high performance, Replication Server is designed for a high volume of replication messages.

  • Heterogeneous databases Replication Server supports several leading DBMSs, and allows mapping of object names during replication, so that support for heterogeneous databases is provided.


SQL Anywhere Studio for Windows CE

About this chapter

This chapter includes Windows CE platform-specific information for SQL Anywhere Studio.

The information contained within this chapter is intended to supplement information contained throughout the remainder of the documentation set.

For information about security and databases running on Windows CE, see Keeping your Windows CE database secure.

Getting started
Using the sample applications
Configuring Windows CE databases
Using the database server on Windows CE
Using the administration utilities
SQL Anywhere Studio features not supported on Windows CE


Getting started

This section describes the tasks required to set up SQL Anywhere Studio on your Windows CE device. Completion of these tasks ensures that you can use the features of SQL Anywhere Studio for Windows CE.

Installing SQL Anywhere Studio on a Windows°CE device
Configuring a PC to connect to your Windows CE device
Creating an ODBC data source to connect to your Windows CE device


Installing SQL Anywhere Studio on a Windows°CE device

Requirements

  • SQL Anywhere Studio for Windows CE must be installed from a machine running a supported Microsoft Windows operating system.

    For a list of Microsoft Windows operating systems supported by Adaptive Server Anywhere, see Operating system versions.

  • ActiveSync for your Windows CE device must be installed on the desktop machine.

Windows CE file locations

On Windows CE, all files are installed to the installation directory \Program Files\Sybase\ASA9. No subdirectories are created. The only exception is that all DLLs are installed into the \Windows directory.

toggle To install SQL Anywhere Studio for Windows CE

  1. Connect your Windows CE device to a PC running a supported Microsoft Windows operating system.

  2. Start the installation by running the SQL Anywhere Studio setup.exe program on your PC.

  3. Follow the instructions in the SQL Anywhere Studio 9 Install wizard.

  4. On the Select Components page, select the Adaptive Server Anywhere for Windows CE checkbox under Databases.

    Optionally, if you already have Adaptive Server Anywhere installed on your PC, clear the Adaptive Server Anywhere checkbox under Databases to avoid reinstalling to your PC.

    Select components dialog

  5. Follow the remaining instructions in the wizard.


Configuring a PC to connect to your Windows CE device

This section describes two methods to configure a PC to connect to an Adaptive Server Anywhere database running on your Windows CE device. This is done to allow you to administer your Windows CE database from the administration utilities on a PC.

For more information on Windows CE administration, see Using the administration utilities.

Requirements

  • Microsoft ActiveSync 3.5 or higher.

  • A Windows CE device supported by Adaptive Server Anywhere.

    For a list of Windows CE devices supported by Adaptive Server Anywhere, see Operating system versions.

  • Adaptive Server Anywhere for Windows CE installed on your Windows CE device.

  • A PC running a supported Microsoft Windows operating system.


Determining the IP address of your Windows CE device

You can connect from applications running on a desktop machine, such as Sybase Central or Interactive SQL, to a database server running on a Windows CE device. The connection uses TCP/IP over the ActiveSync link between the desktop machine and the Windows CE device.

If you are using an Ethernet connection between your desktop machine and the Windows CE device the following procedure works. Connecting from the desktop to the Windows CE device is not supported if ActiveSync is using a USB connection.

For information about using a serial cable connection and ActiveSync 3.x, see Using ActiveSync 3.0 and a serial cable.

toggle To determine the IP address of your Windows CE device

  1. Open the File Explorer on your Windows CE device.

    From the Start menu, tap Programs > File Explorer.

  2. Navigate to the Adaptive Server Anywhere directory by tapping Program Files > Sybase > ASA9.

  3. Tap the dbsrv9 icon.

    The Server Startup Options dialog appears.

    Server Startup Options dialog

  4. Specify the database file that you want to start.

    Type /Program Files/Sybase/ASA9/asademo.db to start the sample database running on the device.

  5. Select the Use TCP/IP checkbox.

    A TCP/IP connection is necessary to connect from a desktop machine to the database running on your Windows CE device.

  6. In the Options field of the Server Startup Options dialog, type -z.

    With the -z option, the server writes out its IP address during startup. The address may change if you disconnect your Windows CE device from the network and then re-connect it.

    For more information, see -z server option.

  7. Tap OK to start the sample database running on the network server.

  8. Navigate to the Today screen on your device.

  9. Tap the Server icon located in the bottom right corner of the screen.

    The Server Messages window appears.

  10. Determine the IP address of the server.

    The IP address appears in the Server Messages window. To see the IP address, you may have to scroll up using the scroll bar on the side of the Server Messages window.

Now you can create an ODBC data source to connect from the desktop machine to your Windows CE device.

For more information, see Creating an ODBC data source to connect to your Windows CE device.


Editing the registry
Caution Modifying your registry is dangerous. Modify your registry at your own risk. It is recommended that you back up your system before modifying the registry.
toggle To configure your desktop machine

  1. Stop any Adaptive Server Anywhere database servers running on both the desktop machine and your Windows CE device.

  2. Remove your Windows CE device from its cradle.

  3. Open the Registry Editor on the desktop machine.

    At a command prompt, type regedit.

  4. In the Registry Editor, open the following key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\ProxyPorts.

  5. From the Edit menu, select New > DWORD Value.

    Enter the name ASA.

  6. Double-click the ASA key that you just created.

  7. Give it the Decimal value 2638.

    This is the value of the default TCP/IP port for Adaptive Server Anywhere.

    Note
    Every time your Windows CE device is cradled, ActiveSync forwards traffic on port 2638 to the device. Thus, if you start a server on your desktop machine while your Windows CE device is cradled, it cannot use the default port 2638. If this is problematic, you can choose another port to dedicate to Windows CE traffic.

  8. Click OK.

Now you can create an ODBC data source to connect from the desktop machine to your Windows CE device.

For more information, see Creating an ODBC data source to connect to your Windows CE device.


Creating an ODBC data source to connect to your Windows CE device

The Open Database Connectivity (ODBC) interface is defined by Microsoft Corporation, and is a standard interface for connecting client applications to database-management systems in Windows environments. Connections are made by specifying connection parameters. It is often convenient to collect a set of connection parameters together and store them in an ODBC data source. ODBC data sources are a convenient way of saving connection parameters for repeated use.

For more information, see Working with ODBC data sources.

This section describes how to create an ODBC Data Source on your Windows desktop machine to connect to a database running on your Windows CE device.

toggle To create an ODBC data source to connect to your Windows CE device

  1. Open the ODBC Administrator on the desktop machine.

    From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > ODBC Administrator.

    The ODBC Administrator appears.

  2. On the User DSN tab, click Add.

    The Create New Data Source dialog appears.

  3. Select Adaptive Server Anywhere 9.0, and then click Finish.

    The ODBC Configuration dialog appears.

  4. On the ODBC tab, in the Data Source Name field, type a name for the data source.

    For example, type CEdevice.

  5. On the Login tab, select Supply User ID and Password and leave the User ID and Password fields blank.

    Each time you connect to a database, you need to supply a user ID and password.

    Tip
    When connecting to a database, the default user ID is DBA. The default password is SQL.

  6. On the Database tab, leave the Server Name field blank.

    Each time you connect from a desktop machine, you will have to specify the server name. This name appears in the title bar of the Server Messages window on your Windows CE device.

  7. On the Network tab, select the TCP/IP checkbox.

  8. In the adjacent field, type the connections parameters.

    For example, type Host=127.0.0.1;DoBroadcast=none.

    Host this parameter specifies the IP address that the Windows CE device listens on.

    If you had to edit the registry to connect to your Windows CE device, use the default IP address of 127.0.0.1.

    For more information, see Editing the registry.

    Otherwise, use the IP address of your Windows CE device.

    For more information, see Determining the IP address of your Windows CE device.

    For more information, see Using the TCP/IP protocol.

    DoBroadcast this parameter controls how the TCP/IP connection is made.

    When DoBroadcast=none is specified, the TCP/IP connection is made directly with the port specified. Use this setting if you had to edit the registry to connect to your Windows CE device.

    For more information, see Editing the registry.

    When DoBroadcast=direct is specified, no broadcast is performed to the local subnet to search for a database server. Instead, the Host IP address is required.

    For more information, see Determining the IP address of your Windows CE device.

    For more information, see DoBroadcast protocol option [DOBROAD].

  9. Click OK to create the data source.

You can now use the data source you just created to connect from a desktop machine to a database running on your Windows CE device.

For more information, see Using the administration utilities.


Using the sample applications

This section introduces you to the sample database and the sample applications provided with SQL Anywhere Studio for Windows CE.


The sample database

The sample database represents a small company that makes a limited range of sports clothing. All information in the sample database is fictional.

For more information, see About the sample database.

Where is the sample database stored?

The sample database is stored in a file called asademo.db. This file is located in the \Program Files\Sybase\ASA9 directory on your Windows CE device.

How do I access the sample database?

The following sample applications are included with your SQL Anywhere Studio for Windows CE installation:

  • ASA Server Example
  • ADO.NET Sample
  • ADOCE Sample
  • ESQL Sample
  • ODBC Sample

You can use these applications to access the sample database and examine the capabilities of SQL Anywhere Studio for Windows CE.


The ASA Server Example

The ASA Server Example starts the sample database on a network server using preset server options and connection parameters.

toggle To start the ASA Server Example

  1. Navigate to the Adaptive Server Anywhere installation directory.

    From the Start menu, tap Programs > Sybase > ASA9.

  2. Start the sample database on a network server by tapping the ASA Server Example icon.

    The sample database starts on the network server. Once it is started, the server appears as an icon in the bottom right-hand corner of the Today screen on your Windows CE device. If you would like to view the Server Messages window, tap the icon.

    Server window on Windows CE

The sample database is running on your Windows CE device.

You can now connect to the sample database on your Windows CE device from a desktop machine.

For more information, see Using the administration utilities.

When you are finished using the sample database, you must shut down the server.

toggle To shut down the server

  1. Tap the network server icon located in the bottom right-hand corner of the Today screen.

    The Server Messages window appears.

  2. Tap Shutdown.


The ADO.NET Sample

In order to use the ADO.NET Sample, you must have the Microsoft.NET Compact Framework version 1.0 with Service Pack 2 or higher installed on your device.

You can download this component from the [external link] Microsoft Download Center.

The ADO.NET Sample demonstrates a simple application that uses the ADO.NET programming interface. This application allows you to start the sample database running on the network server, and access and modify data using SQL statements.

The source code for this sample can be found in asa_install_directory\samples\asa\ce_ado_net_sample.

You can load this project in eMbedded Visual C++ from: asa_install_directory\samples\asa\ce_ado_net_sample.

For more information, see The ADO.NET programming interface.

Note
In the ADO.NET Sample user interface, SQL statements must be entered on a single line.
toggle To use the ADO.NET Sample

  1. Start the ADO.NET Sample.

    From the Start menu, tap Programs > Sybase > ASA9 > ADO.NET Sample.

  2. Tap Connect.

    The sample database starts on a network server. The Server Messages window appears briefly, then disappears.

  3. Tap Exec SQL to execute the default SQL statement, SELECT * FROM employee, and then tap Exec SQL.

    All of the data from the Employee table appears in the data window.

  4. Navigate through the data in the employee table using the scroll bars on the side and bottom of the data window.

  5. Access a more specific range of data.

    Type SELECT emp_id, emp_lname FROM employee.

    Tap Exec SQL to execute the SQL statement.

  6. The specified range of data replaces the data that was in the data pane.

  7. Edit data in the table.

    Type SELECT * FROM employee ORDER BY emp_id and tap Exec SQL.

    Notice the employee Matthew Cobb, with the emp_id of 105.

  8. Type UPDATE employee SET emp_lname = 'Jones' WHERE emp_lname = 'Cobb'.

  9. Tap Exec SQL to execute the SQL statement.

  10. Type SELECT * FROM employee ORDER BY emp_id and tap Exec SQL.

    Notice that Matthew's last name has been changed from Cobb to Jones.

  11. Reverse the changes.

    Type UPDATE employee SET emp_lname = 'Cobb' WHERE emp_lname = 'Jones' and tap Exec SQL.

  12. Verify that the changes were reversed.

    Type SELECT * FROM employee ORDER BY emp_id and tap Exec SQL.

    Notice that Matthew's last name has been changed back to Cobb.

  13. Access data from another table.

    In the Exec SQL field, type SELECT * FROM customer.

    Tap Exec SQL.

  14. All of the data from the Customer table appears in the data window, replacing the data from the Employee table.

  15. Shut down the network server by tapping Disconnect.

    The ADO.NET Sample disconnects, and the network server automatically shuts down.

  16. Close the ADO.NET Sample by tapping the × in the top right-hand corner of the window.


The ADOCE Sample

The ADOCE Sample demonstrates a simple application that uses ADOCE, the ADO programming interface for Windows CE development. This application allows you to start the sample database running on the network server, and access data using SQL statements.

The source code for this sample can be found in asa_install_directory\samples\asa\ce_adoce_sample.

You can load this project in eMbedded Visual C++ from asa_install_directory\samples\asa\ce_adoce_sample.

For more information on the ADO programming interface, see The OLE DB and ADO Programming Interfaces.

Note
In the ADOCE Sample user interface, SQL statements must be entered on a single line.
toggle To use the ADOCE Sample

  1. Start the ADOCE Sample.

    From the Start menu, tap Programs > Sybase > ASA9 > ADOCE Sample.

  2. Tap Connect.

    The sample database starts on a network server. The Server Messages window appears briefly, then disappears.

  3. Tap Execute SQL to execute the default SQL statement, SELECT * FROM employee.

    All of the data from the Employee table appears in the data window.

  4. Navigate through the data in the employee table using the scroll bar on the side of the data window.

  5. Access a more specific range of data.

    Type SELECT emp_id, emp_lname FROM employee.

    Tap Execute SQL to execute the SQL statement.

  6. Scroll down to view the data, which appears below the data that is already displayed in the data window.

  7. Access data from another table.

    In the Execute SQL field, type SELECT * FROM customer.

    Tap Execute SQL.

  8. Scroll down to view the data from the Customer table, which appears below the data that is already displayed in the data window.

  9. Shut down the network server by tapping Disconnect.

    The ADOCE Sample disconnects, and the network server automatically shuts down.

  10. Close the ADOCE Sample by tapping the × in the top right-hand corner of the window.


The ESQL Sample

The ESQL Sample demonstrates a simple application that uses the Embedded SQL programming interface. This application allows you to start the sample database running on the network server, and access data using SQL statements.

The source code for this sample can be found in asa_install_directory\samples\asa\ce_esql_sample.

You can load this project file in eMbedded Visual C++ from: asa_install_directory\samples\asa\ce_esql_sample\esql_sample.vcw.

For more information, see The Embedded SQL programming interface.

Note
In the ESQL Sample user interface, SQL statements must be entered on a single line.
toggle To use the ESQL Sample

  1. Start the ESQL Sample.

    From the Start menu, tap Programs > Sybase > ASA9 > ESQL Sample.

  2. Tap Connect to connect to the sample database using the default connection string.

    The sample database starts on a network server. The Server Messages window appears briefly, then disappears.

  3. Tap ExecSQL to execute the default SQL statement, SELECT * FROM employee.

    All of the data from the Employee table appears in the data window.

  4. Navigate through the data in the employee table using the scroll bars on the bottom and side of the data window.

  5. Access data in another table.

    In the ExecSQL field, type SELECT * FROM customer, and then tap ExecSQL.

    All of the data from the Customer table appears in the data window, replacing the data from the Employee table.

  6. Shut down the network server by tapping Disconnect.

    The ESQL Sample disconnects and the network server automatically shuts down.

  7. Close the ESQL Sample by tapping the × in the top right-hand corner of the window.


The ODBC Sample

The ODBC Sample demonstrates a simple application that uses the ODBC programming interface. This application allows you to start the sample database running on the network server, and access data using basic SQL statements.

The source code for this sample can be found in asa_install_directory\samples\asa\ce_odbc_sample.

You can load this project file in eMbedded Visual C++ from: asa_install_directory\samples\asa\ce_odbc_sample\odbc_sample.vcw

For more information, see The ODBC programming interface.

Note
In the ODBC Sample user interface, SQL statements must be entered on a single line.
toggle To use the ODBC Sample

  1. Start the ODBC Sample.

    From the Start menu, tap Programs > Sybase > ASA9 > ODBC Sample.

  2. Tap Connect.

    The sample database starts on a network server. The Server Messages window appears briefly, then disappears.

  3. Tap ExecSQL to execute the default SQL statement, SELECT * FROM employee.

    All of the data from the Employee table appears in the data window.

  4. Navigate through the data in the employee table using the scroll bars on the bottom and side of the data window.

  5. Access data in another table.

    In the ExecSQL field, type SELECT * FROM customer.

    All of the data from the Customer table appears in the data window, replacing the data from the Employee table.

  6. Shut down the network server by tapping Disconnect.

    The ODBC Sample disconnects and the network server automatically shuts down.

  7. Close the ODBC Sample by tapping the × in the top right-hand corner of the window.


Configuring Windows CE databases

This section describes how to configure a database for Windows CE using special features in Sybase Central. You will also learn how to copy an existing Adaptive Server Anywhere database to your Windows CE device, and how to erase Windows CE databases.


Database properties

Most SQL features available in the full version of Adaptive Server Anywhere are available on the Windows CE version as well. These include transaction processing, referential integrity actions, procedures and triggers, and so on. However, the Java features and the remote data access features are not available on Windows CE.

You should be mindful of the unsupported features when setting database properties on a database intended for a Windows CE device.

For more information, see SQL Anywhere Studio features not supported on Windows CE.


The transaction log

The transaction log stores all changes made to a database, in the order in which they are made. In the event of a media failure on a database file, the transaction log is essential for database recovery. It also makes your work more efficient. By default, the transaction log is placed in the same directory as the database file. It is created when the database is started for the first time on your Windows CE device.

When you copy an existing database to your Windows CE device, you can copy both the database and transaction log files. If you do not copy the transaction log file to the device, a new log will be created when you start the database on your Windows CE device. The new log will not contain the information contained in the original transaction log. This can be problematic if the database was not shut down properly the last time it was used, or if the database is involved in synchronization. Thus, the best practice is to copy both the database and the transaction log files to the Windows CE device.

For more information, see The transaction log.


Using jConnect on Windows CE

jConnect is a pure Java JDBC driver for Adaptive Server Anywhere.

Sybase Central gives you the option to enable the jConnect JDBC driver so that Java applications can access Adaptive Server Anywhere databases.

By default, jConnect is not enabled if you specify that the database is being created for Windows CE. However, you can choose to enable jConnect.

Adding jConnect support to a database adds many entries into the system tables. This adds to the size of the database and, more significantly, adds about 200kb to the memory requirements for running the database, even if you do not use any jConnect functionality.

If you are not going to use jConnect, and if you are running in a limited-memory environment like Windows CE, you may not wish to add jConnect support to your database.


Encryption

You can choose to secure your database either with simple or with strong encryption. The only way to change the encryption setting after the database has been initialized is by rebuilding the entire database.

For more information, see Encrypting a database.

For more information, see Keeping your Windows CE database secure.


Additional properties

The following properties are configured during database creation. Once set, these properties can only be changed by rebuilding the database.

  • Case sensitivity or insensitivity

    For more information, see Case sensitivity.

  • Password case sensitivity or insensitivity

    For more information, see Case sensitivity.

  • Treatment of trailing blanks in comparisons

    By default, databases are created with trailing blanks classified as extra characters. For example, 'Dirk' is not the same as 'Dirk '.

    You can create databases with blank padding, so that trailing blanks are ignored.

  • Page size

    For more information, see Table and page sizes.

  • Collation sequence

    When creating databases for Windows CE, you should use a collation based on the same single- or multibyte character set that Windows would use for the language of interest. For example, if you are using English, French, or German, use the 1252Latin1 collation. If you are using Japanese, use the 932JPN collation, and if you are using Korean, use the 949KOR collation.

    For more information, see Understanding collations.


Creating a Windows CE database

There are three methods for creating an Adaptive Server Anywhere database for your Windows CE device. You can use the Sybase Central Create Database wizard to create a database that can be copied directly to your Windows CE device, and you can use the Initialization utility (dbinit) or the CREATE DATABASE statement in Interactive SQL to create a database that can be manually copied to your Windows CE device. This section describes all of these methods.

Creating a Windows CE database using Sybase Central
Creating a Windows CE database using dbinit
Creating a Windows CE database using the CREATE DATABASE statement


Creating a Windows CE database using Sybase Central

Sybase Central has features to make database creation easy for Windows CE. If you have Windows CE services installed on your Windows desktop machine, you have the option to create a Windows CE database using Sybase Central. Sybase Central enforces the requirements for Windows CE databases, and gives you the option of copying the resulting database file to your Windows CE device.

toggle To create a Windows CE database in Sybase Central and copy it directly to your Windows CE device

  1. Start Sybase Central on your desktop machine.

    From the Start menu, choose Programs > SQL Anywhere 9 > Sybase Central.

  2. Start the Create Database wizard.

    From the Tools menu, choose Adaptive Server Anywhere 9 > Create Database.

  3. Choose Create a Database on This Computer, and click Next.

    The database is initialized on the desktop machine before being copied to the Windows CE device.

  4. Specify a file name and directory to store the database on your desktop machine, and click Next.

  5. Select Create This Database for Windows CE, and then click Next.

    This option ensures that the new database conforms to the settings required to run the database on Windows CE.

    When you click Next, Sybase Central attempts to connect to your Windows CE device. Your Windows CE device must be connected to the desktop machine in order to continue to the next step.

  6. Select Copy the Database to Your Windows CE Device to have Sybase Central automatically copy the database to your device once it is initialized.

  7. Specify the Windows CE directory to copy your database files to. The default is the main device directory.

    Tip
    Copy the database to the My Documents directory of your Windows CE device to make it simpler to start the database.

    When starting a database on your Windows CE device using the Server Startup Options dialog, you can use Browse to search for the database file in the My Documents directory only.

    If the database is not stored in the My Documents directory, you must type the path of the database in the Database field of the Server Startup Options dialog.

    Optionally, you can select the Delete the Desktop Database After Copying option.

    If you choose not to delete the desktop copy, a copy of the database file will be stored on your desktop machine in the directory that you specified in step 4.

    Click Next.

  8. If you are saving a copy of the database on your desktop machine, you can specify the directory where you want to save the transaction log file.

    On your Windows CE device, the log file will be created in the same directory as the database file when the database is started on the network server for the first time.

    Click Next.

  9. Leave the Maintain the Following Mirror Log File checkbox blank.

    A mirror log can help in data recovery should the transaction log become corrupt. However, it is not necessary.

  10. Leave the Install jConnect Meta-information Support checkbox blank.

    This option is not necessary, and adds extra memory requirements for running the database.

  11. Set the level of encryption for your database by selecting the appropriate radio button.

    If you select strong encryption, you must specify an encryption key. It is recommended that you choose a value for your key that is at least 16 characters long, contains a mix of upper and lowercase, and includes numbers, letters, and special characters.

    Warning Be sure to store a copy of your key in a safe location. You require the key each time you want to start or modify the database. A lost key will result in a completely inaccessible database, from which there is no recovery.

  12. Follow the remaining instructions in the wizard.

  13. Click Finish to create the database and copy it to your device.

    A dialog appears, tracking the progress of the files being copied to your Windows CE device.

  14. Once the wizard has copied the database to your Windows CE device, you can verify the location of the files.

    From the Start menu, tap Programs > File Explorer and navigate to the Windows CE directory that you copied the database to.

    The database file will be listed. The log file is not listed until the first time you start the database on your Windows CE device.


Creating a Windows CE database using dbinit

The Initialization utility (dbinit) can be used to create databases. However, you cannot copy them directly to a Windows CE device from this utility. You must manually copy databases to your Windows CE device.

For more information, see Copying a database to your Windows CE device.

toggle To create a database using the dbinit utility

  1. At the command prompt, navigate to the directory where you want to store your database.

    For example:

    cd temp

  2. Create your database by typing the following command:

    dbinit database-name.db
    Tip
    You can also configure database properties such as encryption and page size using the dbinit utility.

    For more information, see Creating a database using the dbinit command-line utility.

  3. Verify the successful creation of the database file by typing the following command:

    dir

    The database file that you created is listed in the directory.


Creating a Windows CE database using the CREATE DATABASE statement

The CREATE DATABASE statement can be used to create databases in Interactive SQL on your desktop machine. However, you cannot copy them directly to a Windows CE device from this application. You must manually copy databases to your Windows CE device.

For more information, see Copying a database to your Windows CE device.

toggle To create a database using the CREATE DATABASE statement

  1. Open Interactive SQL on your desktop machine.

    From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > Interactive SQL.

  2. The Connect dialog appears.

    If the Connect dialog does not appear automatically, from the SQL menu, choose Connect.

  3. On the Identification tab, enter the following values:

    • User ID: DBA

    • Password: SQL

  4. Select the ODBC Data Source Name option.

  5. Click Browse, and choose the ASA 9.0 Sample data source.

  6. Click OK to connect to the sample database.

  7. Type the following statement in the SQL Statements pane of Interactive SQL:

    CREATE DATABASE 'c:\\temp\\database-name.db'
TRANSACTION LOG ON
    Tip
    You can also configure database properties such as encryption and page size using the CREATE DATABASE statement.

    For more information, see CREATE DATABASE statement.

  8. From the SQL menu, choose Execute.

    A database and transaction log are created in the c:\temp directory of your desktop machine.


Copying a database to your Windows CE device

Any existing Adaptive Server Anywhere database can be copied to your Windows CE device using the method described in this section. However, you must keep in mind that any database properties that are not supported on Windows CE will not work when you copy the database to your Windows CE device.

For more information, see Database properties.

For more information on creating databases, see Creating a database.

toggle To copy a database to your Windows CE device

  1. Connect the Windows CE device to your desktop machine.

  2. Open Windows Explorer on your desktop machine.

  3. Browse to the directory on your desktop machine containing the database that you want to copy.

  4. Right-click the database file and choose Copy.

  5. Open a second instance of Windows Explorer.

  6. Browse to the directory on your Windows CE device where you want to store the database file.

    Tip
    When starting a database on your Windows CE device using the Server Startup Options dialog, you can use Browse to search for the database file in the My Documents directory only.

    If the database is not stored in the My Documents directory, you must type the path of the database in the Database field of the Server Startup Options dialog.

  7. Right-click an open area of the Windows Explorer window for your Windows CE device and choose Paste.

    The file is copied to the Windows CE device.


Erasing a Windows CE database

Adaptive Server Anywhere for Windows CE does not support the Erase Database wizard, the DROP DATABASE statement, or the Erase utility (dberase). You must manually erase databases from your Windows CE device.

There are two methods for erasing a database from your Windows CE device. You can erase a database through the device interface, or you can connect your device to a desktop machine and erase the database using Windows Explorer. This section describes both methods.


Erasing a database using the device interface
toggle To erase a database using the device interface

  1. From the Start menu, tap Programs > File Explorer and navigate to the directory containing the database file that you want to erase.

  2. Tap and hold on the database file.

    A popup menu appears.

  3. Tap Delete.

  4. Tap Yes to confirm that you do want to delete the file.

Tips
The database must not be running when you attempt to delete it.

After you delete the database, delete the transaction log file. If the database was never started, no transaction log was created.


Erasing a database using Windows Explorer
toggle To erase a database using Windows Explorer

  1. Place your Windows CE device in its cradle and ensure that it connects to the desktop machine via ActiveSync.

  2. Open Windows Explorer on the desktop machine.

  3. Browse to the Windows CE directory where the database file is stored.

  4. Right-click the database file and choose Delete.

    A dialog appears, asking you to confirm that you would like to delete the database file. Click Yes.

Tips
The database must not be running when you attempt to delete it.

After you delete the database, delete the transaction log file. If the database was never started, no transaction log was created.


Using the database server on Windows CE

This section describes the database server, and how to start, stop, and configure the database server on Windows CE.

The database server supplied for Windows CE is the network database server. Its filename is dbsrv9.exe. The network server supports communications over a TCP/IP network link.

The usual client/server arrangement has the database server running on a machine with more power and resources than the client applications. Clearly, this is not the case with Windows CE; instead, the less powerful machine is running the database server.

The advantage of supplying a network server on Windows CE is that you can run administration utilities on a desktop machine to execute tasks on your Windows CE database. For example:

  • You can use Sybase Central on your desktop machine to manage your database.

  • You can use Interactive SQL on your desktop to load and unload data, and carry out queries.

For more information, see Using the administration utilities.


Server and database options

Server and database options are one of the major ways of tuning Adaptive Server Anywhere behavior and performance. You can choose from many options to specify such features as how much memory the cache can use, the level of access needed to start a database on the network server, and the network protocols to use.

On Windows CE, options are set in the Server Startup Options dialog. This is different than other Windows operating systems where database server options are set on the command line. Most server options are available for Windows CE.

For more information about database server options, see The Database Server.

For information on unsupported options, see Server options not supported on Windows CE.


Tutorial: Using the database server on Windows CE

When you have completed this tutorial, you will be able to perform key tasks associated with the database server: starting and stopping the server, and running single and multiple databases.

Requirements

  • Complete all of the tasks in Getting started before attempting this tutorial.

Before you begin

You need to create two Windows CE databases for use in the tutorial.

toggle To create databases for your Windows CE device

  1. Ensure that your Windows CE device is connected to the desktop machine.

  2. Open Sybase Central on your desktop machine.

    From the Start menu, choose Programs > SQL Anywhere 9 > Sybase Central.

    Sybase Central appears.

  3. Start the Create Database wizard.

    From the Tools menu, choose Adaptive Server Anywhere 9 > Create Database.

    The Create Database Wizard appears.

  4. Create a database called Alpha.db.

    Disregard the directory that the database is stored in on the desktop machine, as the desktop copy will be deleted when the database is copied to your Windows CE device.

  5. Click Next.

  6. Select the Create This Database for Windows CE option.

  7. Click Next.

    The wizard tests the connection to your Windows CE device.

  8. Select the Copy the Database to Your Windows CE Device option.

    Copy the database to the My Documents directory on your Windows CE device by typing the following in the Windows CE File Name field: \My Documents\Alpha.db.

  9. Select the Delete the Desktop Database After Copying option.

  10. Click Finish to create the database with the default settings.

    Once the wizard finishes copying the Alpha.db database file to your Windows CE device, continue to the next step.

  11. Repeat steps 3 through 9 to create a database called Beta.db.

    The path in step 7 for the second database is \My Documents\Beta.db.

Once the wizard finishes copying the Beta.db database file to your Windows CE device, you are ready to begin the tutorial.


Lesson 1: Starting the database server

This section describes the simple case of running a single database on Windows CE.

toggle To start a database on the server

  1. Open the File Explorer on your Windows CE device.

    From the Start menu, tap Programs > File Explorer.

  2. Navigate to the Adaptive Server Anywhere directory by tapping Program Files > Sybase > ASA9.

  3. Tap the dbsrv9 icon.

    The Server Startup Options dialog appears.

    Server Startup Options dialog

  4. Specify the database file that you want to start.

    Tap Browse and locate the Alpha.db file in the My Documents directory.

  5. Assign a name to the network server by typing CEserver in the Server field.

  6. Use the default cache size of 600kb.

    Tip
    For the purposes of this tutorial, the default cache size is sufficient. However, a larger cache size can help improve performance for larger databases.

    For more information, see Using the cache to improve performance.

  7. Select the Use TCP/IP checkbox.

    A TCP/IP connection is necessary to connect from a desktop machine to the database running on your Windows CE device. You will need to connect from your desktop machine in a later lesson.

  8. In the Options field of the Server Startup Options dialog, type -gd all.

    The -gd option sets the permissions to allow any user to start additional databases on the network server. This will be necessary in a later lesson.

    For more information, see -gd server option.

  9. Tap OK to start the Alpha database running on the network server.

  10. Navigate to the Today screen on your device.

  11. Tap the Server icon located in the bottom right corner of the screen.

    The Server Messages window appears.

When the message Now accepting requests appears in the Server Messages window, you are ready to proceed to the next lesson.

What's next?

Next, you will learn how to start multiple databases on the network server on Windows CE.


Lesson 2: Starting multiple databases on the server

On Windows CE devices, attempting to start a second Adaptive Server Anywhere server while a first server is already running brings the first server to the foreground. This is standard behavior for Windows CE applications. Because of this behavior, two servers cannot be run at the same time on a Windows CE device. As an alternative to multiple servers, one server can run multiple databases.

To start multiple databases on the server, you must first connect to one database running on your Windows CE device.

toggle To connect to the Alpha database using Sybase Central

  1. Start Sybase Central on your desktop machine.

    From the Start menu, choose Programs > SQL Anywhere 9 > Sybase Central.

  2. Choose Tools > Connect.

    If a dialog prompts you to choose a plug-in, choose Adaptive Server Anywhere 9 and click OK.

    The Connect dialog appears.

  3. On the Identification tab, enter the following values:

    • User ID: DBA

    • Password: SQL

  4. Select the ODBC Data Source Name option.

  5. Click Browse, choose the CEdevice data source that you created in Creating an ODBC data source to connect to your Windows CE device from the Data Source Names dialog, and click OK.

  6. On the Database tab, type the server name in the Server Name field.

    In this example, the server name is CEserver, which you specified in the previous lesson.

  7. Click OK to connect to the Alpha.db database running on your Windows CE device.

Now that you have started the server and connected to the Alpha database, you can start additional databases on your Windows CE device.

toggle To start multiple databases on the network server

  1. In the left pane of Sybase Central, select the CEserver icon.

    This icon represents the network server running on your Windows CE device.

  2. From the File menu, choose Start Database.

    The Start Database dialog appears.

  3. In the Database File field, type the following path: \My Documents\Beta.db

  4. Click OK to start the database on the network server.

The database starts on the network server, but you must initiate a connection from your desktop machine.

toggle To connect to the Beta database

  1. In the left pane of Sybase Central, select the Beta database icon.

    This icon represents the database that you just started on your Windows CE device.

  2. From the File menu, choose Connect.

    The Connect dialog appears.

  3. On the Identification tab, enter the following values:

    • User ID: DBA

    • Password: SQL

  4. Click Browse and choose CEdevice from the Data Source Names dialog.

  5. Click OK.

  6. Click OK to connect to the Beta database running on your Windows CE device.

You can now view and manipulate the data in the Alpha and Beta databases using Sybase Central.

What's next?

Next, you will learn how to disconnect from the databases and shut down the database server on Windows CE.


Lesson 3: Shutting down the server

Before you can shut down the network server on your Windows CE device, you must stop the connections from your desktop machine.

toggle To disconnect from the Windows CE databases

  1. In Sybase Central, from the Tools menu, choose Disconnect.

    The Disconnect dialog appears.

  2. Select the connection that corresponds to the Alpha database.

  3. Click Disconnect.

  4. Repeat steps 1 through 3 for the connection that corresponds to the Beta database.

Now that you have disconnected from the Windows CE databases in Sybase Central, you can shut down the network server.

toggle To shut down the server

  1. Tap the database server icon located in the bottom right corner of the Today screen.

    The Server Messages window appears.

  2. Tap Shutdown.


Using the administration utilities

This section describes specific considerations for using the SQL Anywhere Studio database administration utilities with Windows CE databases.

Backup and recovery on Windows CE
Tutorial: Managing Windows CE databases with Sybase Central
Tutorial: Managing Windows CE databases with Interactive SQL


Backup and recovery on Windows CE

Backup and recovery is vital to ensure you do not lose data in the event of data corruption or media failure. It is best to backup your Windows CE database to a physically separate location to safeguard against data loss due to theft or loss of the Windows CE device, or media failure on the Windows CE device. Most backup and recovery utilities are available on Windows CE. However, these utilities are not useful since you cannot use the utilities on Windows CE to store backups in a physically separate location.

Instead, data can be backed up by copying the entire database file to a desktop machine. You can also use synchronization to maintain an up-to-date copy of your Windows CE database on a desktop machine.

For more information, see Synchronization Basics.


Tutorial: Managing Windows CE databases with Sybase Central

Sybase Central is a database management tool that provides Adaptive Server Anywhere database settings, properties, and utilities in a graphical user interface. Sybase Central can also be used for managing other products, including MobiLink synchronization.

This tutorial provides a brief introduction to using Sybase Central from a desktop machine to manage databases on your Windows CE device. You will learn how to connect to the sample database on your Windows CE device. Once connected, you can use Sybase Central to view and edit data, manage users, and work with stored procedures.

Requirements
  • Complete all of the tasks in Getting started before you begin the tutorial.
  • Connect your Windows CE device to a desktop machine.
Before you begin

Before you begin, be sure to make a copy of the sample database so you can restore it to its original form when you are finished.

toggle To create a backup copy of the sample database

  1. Open the File Explorer on your Windows CE device.

    From the Start menu, tap Programs > File Explorer.

  2. Navigate to the Adaptive Server Anywhere directory by tapping Program Files > Sybase > ASA9.

  3. In an open area of the screen, tap and hold your stylus.

    A popup menu appears.

  4. Tap New Folder.

    Name the new folder Sample Backup.

  5. Tap and hold the asademo database file.

    Two files named asademo may appear in the list. The larger of the two is the database file, while the other is the transaction log file. Be sure to select the correct file.

  6. Once the popup menu appears, tap Copy.

  7. Open the Sample Backup folder that you created by tapping it.

    The folder opens.

  8. Tap and hold a blank area of the screen.

    A popup menu appears.

  9. Tap Paste.

    A copy of the asademo.db file is pasted into the Sample Backup folder.

Tip
Work with the original version of the sample database. Do not change the backup copy.

Lesson 1: Start the sample database
Lesson 2: Start Sybase Central and connect
Where do I go from here?
Tutorial cleanup

Previous Next


Lesson 1: Start the sample database

A database must be running on your Windows CE device if you want to connect to it from Sybase Central.

toggle To start the sample database

  1. Open the File Explorer on your Windows CE device.

    From the Start menu, tap Programs > File Explorer.

  2. Navigate to the Adaptive Server Anywhere directory by tapping Program Files > Sybase > ASA9.

  3. Tap the dbsrv9 icon.

    The Server Startup Options dialog appears.

  4. In the Database field type the path of the sample database: \Program Files\Sybase\ASA9\asademo.db.

  5. Assign a name to the network server by typing CEserver in the Server field.

  6. Use the default cache size of 600kb.

    Tip
    For the purposes of this tutorial, the default cache size is sufficient. However, a larger cache size can help improve performance for larger databases.

    For more information, see Using the cache to improve performance.

  7. Select the Use TCP/IP option.

    A TCP/IP connection is necessary to connect from a desktop machine to the database running on your Windows CE device.

  8. Tap OK to start the sample database running on the network server.

    The Server Messages window appears briefly, then disappears.

  9. Navigate to the Today screen on your device.

  10. Tap the Server icon located in the bottom right-hand corner of the screen.

    The Server Messages window appears.

    When the message Now accepting requests appears in the Server Messages window, you are ready to move on to the next lesson.

What's next?

Next you will learn how to connect from Sybase Central to the database running on your Windows CE device.


Lesson 2: Start Sybase Central and connect

Now that the sample database is running on your Windows CE device, you can connect to it from Sybase Central. This allows you to view and manage the database from your desktop machine.

toggle To connect from Sybase Central to a database on your Windows CE device

  1. Start Sybase Central on your desktop machine.

    From the Start menu, choose Programs > SQL Anywhere 9 > Sybase Central.

  2. Choose Tools > Connect.

    If a dialog prompts you to choose a plug-in, select Adaptive Server Anywhere 9, and then click OK.

    The Connect dialog appears.

  3. On the Identification tab, enter the following values:

    • User ID: DBA

    • Password: SQL

  4. Select the ODBC Data Source Name option.

  5. Click Browse, choose the CEdevice data source that you created in Creating an ODBC data source to connect to your Windows CE device from the Data Source Names dialog, and click OK.

  6. On the Database tab, type the server name in the Server Name field.

    In this example, the server name is CEserver, which you specified in the previous lesson.

  7. Click OK to connect to the sample database running on your Windows CE device.

What's next?

You can now view and manage the data in the sample database from Sybase Central.


Where do I go from here?
Learn more about Sybase Central

You can learn more about Sybase Central through the tutorial Managing Databases with Sybase Central. The tutorial includes lessons on viewing and editing data, managing users, and working with stored procedures.

The tutorial pertains to using Sybase Central with a sample database running on a desktop machine. Thus, the following lessons do not apply when managing Windows CE databases:

  • Lesson 1: Start Sybase Central and connect

    Instead, use the connection procedure that you learned in this tutorial.

  • Lesson 7: Back up your database

    Disregard this lesson. The backup procedure described is not supported on Windows CE.

Administer several databases at once

You can administer several databases at one time by starting multiple databases on the network server on your Windows CE device.

For more information, see Lesson 2: Starting multiple databases on the server.


Tutorial cleanup

When you are finished the tutorial, you need to shut down the server, and restore the sample database from the backup copy that you made.

toggle To shut down the server

  1. Tap the database server icon located in the bottom right corner of the Today screen.

    The Server Messages window appears.

  2. Tap Shutdown.

toggle To restore the sample database

  1. Open the File Explorer on your Windows CE device.

    From the Start menu, tap Programs > File Explorer.

  2. Navigate to the Adaptive Server Anywhere directory by tapping Program Files > Sybase > ASA9.

  3. Tap the Sample Backup folder to open it.

  4. Tap and hold the asademo file.

    A popup menu appears.

  5. Tap Copy.

  6. Navigate back to the ASA9 folder.

    Tap the navigation dropdown list at the top of the window. Then tap ASA9.

    Navigation dropdown list.

  7. Tap and hold a blank area of the screen.

    A popup menu appears.

  8. Tap Paste.

  9. A warning dialog appears.

    Tap OK to replace the existing asademo.db file with the copy you made from the backup.


Tutorial: Managing Windows CE databases with Interactive SQL

Interactive SQL is an application that allows you to query and alter data in your database, and modify the structure of your database. Interactive SQL provides a pane for you to enter SQL statements, as well as panes that display information about how the query was processed and the result set.

This tutorial provides a brief introduction to using Interactive SQL from a desktop machine to manage databases on your Windows CE device. You will learn how to connect to the sample database on your Windows CE device from Interactive SQL. Once connected, you can use Interactive SQL to execute SQL statements.

Before you begin

Before you begin, be sure to make a copy of the sample database so you can restore it to its original form when you are finished.

toggle To create a backup copy of the sample database

  1. Open the File Explorer on your Windows CE device.

    From the Start menu, tap Programs > File Explorer.

  2. Navigate to the Adaptive Server Anywhere directory by tapping Program Files > Sybase > ASA9.

  3. In an open area of the screen, tap and hold your stylus.

    A popup menu appears.

  4. Tap New Folder.

    Name the new folder Sample Backup.

  5. Tap and hold the asademo database file.

    Two files named asademo may appear in the list. The larger of the two is the database file, while the other is the transaction log file. Be sure to select the correct file.

  6. Once the popup menu appears, tap Copy.

  7. Open the Sample Backup folder that you created by tapping it.

    The folder opens.

  8. Tap and hold a blank area of the screen.

    A popup menu appears.

  9. Tap Paste.

    A copy of the asademo.db file is pasted into the Sample Backup folder.

Tip
Work with the original version of the sample database. Do not change the backup copy.

Lesson 1: Start the sample database
Lesson 2: Start Interactive SQL and connect
Where do I go from here?
Tutorial cleanup

Previous Next


Lesson 1: Start the sample database

A database must be running on your Windows CE device if you would like to connect to it from Interactive SQL.

toggle To start the sample database

  1. Open the File Explorer on your Windows CE device.

    From the Start menu, tap Programs > File Explorer.

  2. Navigate to the Adaptive Server Anywhere directory by tapping Program Files > Sybase > ASA9.

  3. Tap the dbsrv9 icon.

    The Server Startup Options dialog appears.

  4. In the Database field, type the path of the sample database: \Program Files\Sybase\ASA9\asademo.db.

  5. Assign a name to the network server by typing CEserver in the Server field.

  6. Set the cache size by typing 5MB in the Cache field.

    The default cache size on Windows CE is 600kb. However, a larger cache size is recommended to help improve performance.

  7. Select Use TCP/IP.

  8. Click OK to start the sample database running on the network server.

    The Server window appears briefly, then disappears.

  9. Navigate to the Today screen on your device.

  10. Tap the Server icon located in the bottom right-hand corner of the screen.

    The Server window appears.

    When the message Now accepting requests appears in the Server window, you are ready to move on to the next lesson.

What's next?

Next you will learn how to connect from Interactive SQL to the database running on your Windows CE device.


Lesson 2: Start Interactive SQL and connect

Now that the sample database is running on your Windows CE device, connect to it from Interactive SQL to view and manage the database from your desktop machine.

toggle To connect from Interactive SQL to a database on your Windows CE device

  1. Start Interactive SQL on your desktop machine.

    From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > Interactive SQL.

  2. The Connect dialog appears automatically when Interactive SQL launches.

    If the Connect dialog does not appear automatically, from the SQL menu, choose Connect.

  3. On the Identification tab, enter the following values:

    • User ID: DBA

    • Password: SQL

  4. Select the ODBC Data Source Name option.

  5. Click Browse, choose the CEdevice data source that you created in Getting started from the Data Source Names dialog, and click OK.

  6. On the Database tab, specify the server name in the Server Name field.

    In this example, the server name is CEserver, which you specified in the previous lesson.

  7. Click OK to connect to the sample database running on your Windows CE device.

What's next?

You can now view and manage the data in the sample database from Interactive SQL.


Where do I go from here?
Learn more about Interactive SQL

You can learn more about Interactive SQL through the tutorial Using Interactive SQL. The tutorial includes lessons on viewing and editing data, and working with SQL statements.

The tutorial pertains to using Interactive SQL with a sample database running on a desktop machine. Thus, the following lesson does not apply when managing Windows CE databases:

  • Lesson 1: Start Interactive SQL

    Instead, use the procedure that you learned in this tutorial.


SQL Anywhere Studio features not supported on Windows CE

This section lists the components and features of SQL Anywhere Studio that are unsupported or have altered functionality on Windows CE. Where available, alternatives to unsupported features are listed.

For more information about supported and unsupported components on Windows CE, see Windows and NetWare operating systems.

Adaptive Server Anywhere features not supported on Windows CE
Adaptive Server Anywhere features limited on Windows CE
SQL Remote features not supported on Windows CE
Administration tools not supported on Windows CE
Server options not supported on Windows CE
SQL statements not supported on Windows CE
Sybase Central wizards not supported on Windows CE


Adaptive Server Anywhere features not supported on Windows CE

The following features are not supported on Windows CE:

Component or feature | Considerations
Personal database server The personal server is called dbeng9. This executable does not support client/server communications across a network. | In lieu of the personal database server, the network database server is provided. The network server is called dbsrv9. This executable supports local connections and client/server communications across a network. For more information, see Running the Database Server.
Open Client Sybase Open Client provides customer applications, third-party products, and other Sybase products with the interfaces needed to communicate with Adaptive Server Anywhere and other Open Servers. | To run Open Client applications, you must install and configure Open Client components on the machine where the application is running. These components are not supported on Windows CE, and thus Open Client cannot function on the platform.
Java in the database Adaptive Server Anywhere is a runtime environment for Java. This means that Java classes can be executed in the database server. | Adaptive Server Anywhere for Windows CE does not act as a runtime environment for Java. Thus, Java classes cannot be executed in the database server on Windows CE.
Remote data access Adaptive Server Anywhere remote data access gives you access to data in other data sources. You can use this feature to migrate data into an Adaptive Server Anywhere database and query data across databases. | This feature is not supported on Windows CE. If you copy a database to your Windows CE device that uses remote data access features, a communication error occurs when you try to access data in a proxy table.
External stored procedures Adaptive Server Anywhere can call a function in an external library from a stored procedure or user-defined function. | Adaptive Server Anywhere for Windows CE does not support the ability to call a procedure from an external library, including system extended stored procedures.
Dynamic cache sizing This feature causes the cache size to increase when necessary, and reduces the cache size when memory is needed for other applications. | Windows CE does not support dynamic cache sizing. On Windows CE, the cache is set on the Server Startup Options dialog and remains static.
SPX protocol SPX is a communication protocol from Novell. | In lieu of the SPX protocol, Windows CE uses the TCP/IP protocol.


Adaptive Server Anywhere features limited on Windows CE

The following features have altered or limited functionality on Windows CE:

Component or feature | Considerations
ODBC clients Microsoft Corporation defines the Open Database Connectivity (ODBC) interface, which is a standard interface for connecting client applications to database-management systems in the Windows 95/98/Me and Windows NT/2000/XP environments. Many client applications, including application development systems, use the ODBC interface to access a wide range of database systems. | ODBC clients function differently than Windows desktop clients because Windows CE does not provide an ODBC driver manager or an ODBC Administrator. On this platform, Adaptive Server Anywhere uses ODBC data sources stored in files. For more information, see Using ODBC data sources on Windows CE.
jConnect The jConnect JDBC driver is a Java implementation of the JavaSoft JDBC standard. It provides Java developers with native database access in multi-tier and heterogeneous environments. | The jConnect driver can be enabled when you create a database for Windows CE. This can be useful if you want to move the database to a desktop machine that supports Java. However, enabling the jConnect driver adds to the size of the database and, more significantly, adds about 200 kb to the memory requirements for running the database. This additional memory requirement should be considered when running the database in a limited-memory environment like Windows CE.
iAnywhere JDBC driver The iAnywhere JDBC driver provides a JDBC driver that has some performance benefits and feature benefits compared to the pure Java jConnect JDBC driver, but which is not a pure-Java solution. | The iAnywhere JDBC driver can only be enabled if you have a Java Virtual Machine installed on your Windows CE device.


SQL Remote features not supported on Windows CE

SQL Remote is supported on Windows CE with the following exceptions:

Component or feature | Considerations
Adaptive Server Anywhere extraction utility (dbxtract) This utility is used to extract a remote Adaptive Server Anywhere database from a consolidated Adaptive Server Enterprise or Adaptive Server Anywhere database. | Windows CE does not support this utility. If necessary, a Windows CE database can be copied to a desktop machine so that the Adaptive Server Anywhere extraction utility can be used.
MAPI message type Microsoft's Messaging Application Programming Interface (MAPI), used in several popular e-mail systems such as Microsoft Mail, can be used to transport messages for SQL Remote messaging. | This message system is not supported on Windows CE. Windows CE supports several other message types used in SQL Remote replication, which are identified in Supported operating systems.
VIM message type Lotus's Vendor Independent Messaging (VIM), used in Lotus Notes and cc:Mail can be used to transport messages for SQL Remote messaging. | This message system is not supported on Windows CE. Windows CE supports several other message types used in SQL Remote replication, which are identified in Supported operating systems.


Administration tools not supported on Windows CE

SQL Anywhere Studio includes several tools for administering databases. These include Sybase Central, Interactive SQL, and command line utilities. None of these administration tools can be deployed to Windows CE. Instead, database administration is performed from a Windows-based desktop machine that is connected to the Windows CE device.

For more information, see Using the administration utilities.


Server options not supported on Windows CE

This section describes those database server options that are not supported or have altered functionality on Windows CE.

Option | Considerations
@data option This option allows you to specify environment variables and configuration files on the command line. | Windows CE does not support environment variables.
-? server option This option is used to display usage information. | Windows CE does not support this option.
-ca option This option is used to enforce a static cache size. | Windows CE does not support dynamic cache sizing.
-ch option This option is used to set a maximum cache size, as a limit to automatic cache growth. | Windows CE does not support dynamic cache sizing.
-cl option This option is used to set a minimum cache size as a lower limit to automatic cache resizing. | Windows CE does not support dynamic cache sizing.
-cs option This option is used to display cache size changes in the Server Messages window. | Windows CE does not support dynamic cache sizing.
-cw option This option is used to enable use of Address Windowing Extensions (AWE) for setting the size of the database server cache. | Windows CE does not support AWE.
-d option This option is used to force the use of POSIX I/O. | Windows CE does not support POSIX I/O.
-ec option This option is used to encrypt all native Adaptive Server Anywhere packets (DBLib, ODBC, and OLE DB) transmitted to and from all clients. TDS packets are not encrypted. | Strong communication encryption is not supported on Windows CE. Only the none and simple settings are supported for this server option.
-gb option This option is used to set the database process priority class. | Windows CE does not support Priority classes.
-ge option This option is used to set stack size for external functions. | Windows CE does not support external functions.
-gss option This option is used to set the stack size per internal execution thread in the server. | This option has no effect on Windows operating systems.
-gx option This option is used to set the maximum number of requests that can concurrently execute blocking system calls. | This option is only of use on Windows NT. On other platforms, including Windows CE, the -gx value is equivalent to the -gt value.
-qi option This option is used to control whether the database server tray icon and window appear. | When running, the network server appears as an icon in the bottom right-hand corner of the Today screen on your Windows CE device. This feature cannot be disabled.
-s option This option is used to set the user ID for syslog messages. | This option only applies to UNIX operating systems.
-sc option This option is used to disable the shared memory communications protocol and use Named Pipes. | Windows CE does not support the Named Pipes protocol.
-tmf option This option is used for recovery from distributed transactions in unusual circumstances. | Windows CE does not support the Distributed Transaction Coordinator.
-tmt option This option is used to set a reenlistment timeout for participation in distributed transactions. | Windows CE does not support the Distributed Transaction Coordinator.
-u option This option is used to open files using the operating system disk cache. | This server option does not apply to Windows CE because the platform does not run on a hard disk.
-ua option This option is used to turn off use of asynchronous I/O. | This option only applies to Linux operating systems.
-ud option This option is used to run the server as a daemon. | This option only applies to UNIX operating systems.
-ut option This option is used to touch temporary files. | This option only applies to UNIX operating systems.
-ux option This option is used to open the Server Startup Options dialog or display the Server Messages window on Linux and Solaris. | This option only applies to Linux and Solaris operating systems.
-y option This option is used to make the server run as a Windows service. | Windows CE does not support Windows services.


SQL statements not supported on Windows CE

When a client application wants to carry out a database task, such as retrieving information using a query or inserting a new row into a table, it does so using Structured Query Language (SQL) statements. This section describes those SQL statements that are not supported on Windows CE, and those that have altered or limited functionality.

For a complete list of SQL statements, see SQL Statements.

The following SQL statements are not supported on Windows CE:

SQL statement | Considerations
ALTER WRITEFILE statement (deprecated) This statement is used to change the name of the read-only database file to which a write file refers. | Windows CE does not support write files, and does not support this statement.
CREATE COMPRESSED DATABASE statement (deprecated) This statement is used to create a compressed database from an existing database file, or to expand a compressed database. | Windows CE does not support compressed databases, and does not support this statement.
CREATE EXISTING TABLE statement This statement is used to create a new proxy table, which represents an existing object on a remote server. | Windows CE does not support proxy tables, and does not support this statement.
CREATE EXTERNLOGIN statement This statement is used to assign an alternate login name and password to be used when communicating with a remote server. | Connecting to a remote server is necessary to map remote objects to a proxy table in the local database. Windows CE does not support proxy tables, and does not support this statement.
CREATE SERVER statement Use this statement to add a server to the SYSSERVERS system table. | Windows CE does not support proxy tables, and does not support this statement.
CREATE WRITEFILE statement (deprecated) This statement is used to create a write file for a database. | Windows CE does not support write files, and does not support this statement.
DROP DATABASE statement This statement is used to delete all database files associated with a database. | The DROP DATABASE statement is not supported on Windows CE.
DROP SERVER statement This statement is used to drop a remote server from the Adaptive Server Anywhere catalog. | Windows CE does not support remote data access, and does not support remote servers. Thus, the DROP SERVER statement is not supported on Windows CE.
INSTALL JAVA statement This statement is used to make Java classes available for use within a database. | Java in the database is not supported on Windows CE. Thus, the INSTALL JAVA statement is not supported on Windows CE.
REMOVE JAVA statement This statement is used to remove a class or a JAR file from a database. When a class is removed it is no longer available for use as a column or variable type. The class or JAR must already be installed. | Java in the database is not supported on Windows CE. Thus, the REMOVE JAVA statement is not supported on Windows CE.
REORGANIZE TABLE statement This statement is used to defragment tables when a full rebuild of the database is not possible due to the requirements for continuous access to the database. | This statement is not supported on Windows CE.
RESTORE DATABASE statement This statement is used to restore a backed up database from an archive. | The archive file is created using the archive method of database backup, which is not supported on Windows CE. Thus, the RESTORE DATABASE statement is not supported on Windows CE.
START JAVA statement This statement is used to start the Java Virtual Machine. | Java in the database is not supported on Windows CE. Thus, the START JAVA statement is not supported.
STOP JAVA statement This statement is used to stop the Java Virtual Machine. | Java in the database is not supported on Windows CE. Thus, the STOP JAVA statement is not supported.

The following SQL statements have altered or limited functionality on Windows CE:

SQL statement | Considerations
ALTER DATABASE statement This statement is used to upgrade a database created with previous versions of the software, or to add Java or jConnect support to a database. | The ALTER DATABASE UPGRADE syntax is used to add Java or jConnect support to the database. Windows CE does not support Java in the database, so it does not support this particular syntax of the ALTER DATABASE statement.
BACKUP statement This statement is used to back up a database and transaction log. | Only the BACKUP DATABASE DIRECTORY syntax is supported on Windows CE.
CREATE DATABASE statement This statement is used to create a database. The database is stored as an operating system file. | The CREATE DATABASE statement is not supported on Windows CE. However, the CREATE DATABASE statement can be used to initialize a database on a desktop machine, which can later be copied to a Windows CE device.
CREATE EVENT statement This statement is used to define an event and its associated handler for automating predefined actions. Also, to define scheduled actions. | DiskSpace event types are not supported on Windows CE. However, you can use this statement to define the GlobalAutoIncrement event type or the ServerIdle event type.
CREATE FUNCTION statement This statement is used to create a new function in the database. | A function using the EXTERNAL NAME clause is a wrapper around a call to a function in an external library. External functions are not supported on Windows CE. Thus, this clause is not supported. However, the CREATE FUNCTION statement can be used on Windows CE to create user-defined SQL functions for use in the database.
CREATE TABLE statement This statement is used to create a new table in the database and, optionally, to create a table on a remote server. | The AT clause creates a remote table on a different server and also a proxy table on the current database that maps to the remote table. Windows CE does not support proxy tables, and so does not support the AT clause of this statement. Otherwise, this statement is supported on Windows CE.


Sybase Central wizards not supported on Windows CE

Sybase Central is a database management tool that provides Adaptive Server Anywhere database settings, properties, and utilities in a graphical user interface. This section presents information on those wizards that are not supported or have altered functionality on Windows CE and provides alternatives where possible.

Wizard | Considerations
Backup Database wizard This wizard creates a single file containing a backup of the database and transaction log files. This type of backup is known as an archive backup. | The archive backup is not supported on Windows CE. The Backup Database wizard is not supported. For more information, see Types of backup. Sybase Central also has the Create Backup Images wizard, which makes a separate backup of the database and transaction log files. This wizard is supported on Windows CE. For more information, see Backing up a database using the Create Backup Images wizard.
Change Log File Settings wizard With the Change Log File Settings wizard, you can display or change the name of the transaction log or transaction log mirror associated with a database. You can also stop a database from maintaining a transaction log or mirror, or start maintaining a transaction log or mirror. | This wizard cannot map to the Windows CE directory where the log files are stored. The Change Log File Settings wizard is not supported.
Compress Database wizard (deprecated) The Compress Database wizard reads the given database file and creates a compressed database file. Compressed databases are usually 40 to 60 per cent of their original size. | Compressed databases are not supported on Windows CE. The Compress Database wizard is not supported on Windows CE.
Create Database wizard With the Create Database wizard, you can initialize (create) a database. A number of database attributes are specified at initialization and cannot be changed later except by unloading, reinitializing, and rebuilding the entire database. | This wizard has features special to Windows CE database creation provided Windows CE services are installed on the desktop machine running Sybase Central. For more information, see Creating a Windows CE database.
Erase Database wizard This wizard is used to delete a database and related transaction log files. | This wizard cannot be executed on a database that is running. In order to administer a Windows CE database from a desktop machine, the database must be running on the network server on the Windows CE device. This wizard also involves mapping to a directory. Windows CE device directories cannot be mapped from this wizard. The Erase Database wizard is not supported on Windows CE.
Service Creation wizard The Service Creation wizard is a tool used to create, delete, and modify Adaptive Server Anywhere services. Installing an application as a Windows service enables it to run even when you log off. | Windows CE cannot be configured to run an application as a service. The Service Creation wizard is not supported on Windows CE.
Translate Log File wizard With the Translate Log File wizard, you can translate a transaction log into a SQL command file. | This wizard involves mapping to a directory. Windows CE device directories cannot be mapped from this wizard. The Translate Log File wizard is not supported on Windows CE.
Uncompress Database wizard With the Uncompress Database wizard, you can expand a compressed database file created by the Compression utility or Compress Database wizard. The Uncompress Database wizard reads the compressed file and restores the database file to its uncompressed state. | Compressed databases are not supported on Windows CE. Thus, the Uncompress Database wizard is not supported on Windows CE.
Unload Database wizard With the Unload Database wizard, you can unload a database and put a set of data files in a named directory. The Unload Database wizard creates an Interactive SQL command file to rebuild your database. It also unloads all of the data in each of your tables into files in the specified directory in comma-delimited format. | This wizard cannot map to the Windows CE directory where the database files are stored. Thus, the Unload Database wizard is not supported. However, you can unload a Windows CE database by copying it to your desktop machine and using the Unload Database wizard.
Upgrade Database wizard The Upgrade wizard upgrades a database from an older version of Adaptive Server Anywhere to a newer version of Adaptive Server Anywhere, and allows you to take advantage of the newer release's list of features. | This wizard is not supported on Windows CE. However, you can upgrade a Windows CE database by copying it to your desktop machine and using this wizard before copying the database back to your Windows CE device. For more information, see Upgrading a database using the Upgrade Database wizard.


SQL Anywhere Studio Supported Platforms

About this chapter

This chapter lists the supported platforms for the individual components of SQL Anywhere Studio.

Supported platform information is also available at [external link] http://www.ianywhere.com/products/supported_platforms_9.html and at [external link] http://www.ianywhere.com/products/supported_platforms.html.

Availability
Listing a platform as supported does not necessarily indicate immediate availability of the software. For example, for a given software version not all platforms are released simultaneously. Features and platform support for unreleased software are subject to change.

Introduction
Windows and NetWare operating systems
UNIX, Linux, and Macintosh operating systems
MobiLink synchronization consolidated databases
iAnywhere Solutions ODBC drivers supported platforms
UltraLite target platforms
Operating system versions


Introduction

SQL Anywhere Studio provides database management and synchronization technologies for a wide variety of operating systems. It includes the following major components:

  • Adaptive Server Anywhere A relational database system for use all the way from a Small and Medium Business (SMB) database server through desktop database applications down to Windows CE devices.

  • UltraLite A relational database designed specifically for small devices. It runs on Palm OS and Windows CE devices.

  • MobiLink A synchronization system that provides two-way synchronization between many Adaptive Server Anywhere or UltraLite databases and a central database server.

  • SQL Remote A synchronization system for Adaptive Server Anywhere and Sybase Adaptive Server Enterprise databases.

  • Administration tools A suite of tools provides management for all components in SQL Anywhere Studio.

This paper lists which components of SQL Anywhere Studio run on which operating systems. The information is organized by component within SQL Anywhere Studio.

This chapter provides information current at the time of writing. For the latest information, see [external link] http://www.ianywhere.com/products/supported_platforms.html.

Overview

The following table summarizes platform support for the major components. The table does not list detailed information such as differences in support for individual features on the listed platforms, or which flavors and versions of UNIX are supported. For detailed information, see the tables in the remainder of this document.

The UNIX platform support is of two kinds.

  • Full edition Complete releases of SQL Anywhere Studio are available on Sun Solaris and Linux.

  • Deployment edition The deployment edition contains core Adaptive Server Anywhere. Some deployment releases contain the MobiLink synchronization server. Deployment edition platforms include HP-UX, IBM AIX, Compaq Tru64, and 64-bit Linux operating systems.

The supported versions of the listed operating systems are as described in more detail in Operating system versions.

Component | Windows (32-bit) | Windows (64-bit) | Mac OS X | UNIX (full) | UNIX (deployment) | NetWare | Windows CE | Palm OS
Adaptive Server Anywhere database server | Y | Y | Y | Y | Y | Y | Y |
Adaptive Server Anywhere clients | Y | Y | Y | Y | Y | Y 1 | Y |
UltraLite databases | Y 2 |  |  |  |  |  | Y | Y
UltraLite development | Y |  |  |  |  |  |  |
MobiLink synchronization server | Y | Y | Y | Y | Y 3 |  |  |
SQL Remote | Y | Y | Y | Y |  | Y | Y |
Replication Agent | Y | 32-bit software |  | Y |  |  |  |
Administration tools | Y | 32-bit JRE | Y | Y |  | Y 4 |  |

1 Embedded SQL only

2 For development and testing only

3 32-bit HP-UX support on PA RISC (9.0.1 and later) and AIX support only

4 Limited set


Windows and NetWare operating systems

The following tables list the supported operating systems for various components and features of SQL Anywhere Studio.

Unless otherwise noted, the supported versions of the listed operating systems are as described in Operating system versions.

Adaptive Server Anywhere

System requirements depend on the database size, workload, and required performance. The following are minimal requirements only.

Adaptive Server Anywhere (both personal database server and network database server) can run with as little as 4 MB of memory with an additional 8 KB per client connection. More memory will improve performance significantly. If you use Java in the database, Adaptive Server Anywhere requires an additional 5 MB of memory. Your computer must have this much memory in addition to the requirements for the operating system.

Component or Feature | Windows (32-bit) | Windows (64-bit) | Windows CE | NetWare
Personal database server | Y | Y |  |
Network database server | Y | Y | Y | Y
ODBC clients | Y | Y | Y 1 |
OLE DB clients | Y | Y | Y |
Embedded SQL clients | Y | Y | Y | Y
Open Client clients | Y | Y |  |
JDBC clients (jConnect) | Y | 32-bit software | Y |
JDBC clients (iAnywhere JDBC driver) | Y | Y |  |
SQL preprocessor | Y | 32-bit software |  |
Java in the database | Y |  |  | Y
Remote data access 2 | Y | Y |  | Y 3
External stored procedures | Y | Y 4 |  | Y
Dynamic cache resizing | Y | Y |  |
Strong encryption | Y | Y | Y | Y
CREATE DATABASE, RESTORE DATABASE, DROP DATABASE statements | Y | Y |  | Y
SPX protocol | Y |  |  | Y
UltraLite development platforms
Component | Windows NT / 2000 / XP | Windows (64-bit) | Windows 98 SE | Windows CE | NetWare
SQL preprocessor (Embedded SQL only) | Y |  | Y |  |
UltraLite generator (static C++ API, static Java API) | Y |  | Y |  |
UltraLite for AppForge MobileVB | Y |  |  |  |
UltraLite ActiveX | Y |  |  |  |
Native UltraLite for Java | Y |  |  |  |
UltraLite.NET | Y 5 |  |  |  |
UltraLite for C++ | Y |  |  |  |

Although most 32-bit software works under emulation in 64-bit Windows, the static Java API is not available on 64-bit Windows.

For information about deployment platforms, see UltraLite target platforms.

Development environments

You can use one of the following development environments to build UltraLite applications for Palm OS:

  • Metrowerks CodeWarrior version 8 or 9.

    CodeWarrior includes a version of the Palm SDK. Depending on the particular devices you are targeting, you may want to upgrade your Palm SDK to a more recent version than that included in the development tool.

  • AppForge MobileVB or Crossfire, using the UltraLite MobileVB component.

MobiLink synchronization server
Component | Windows (32-bit) | Windows (64-bit) | Windows CE | NetWare
MobiLink synchronization server | Y | Y |  |
TCP/IP synchronization | Y | Y |  |
HTTPS synchronization | Y | Y |  |
HTTP synchronization | Y | Y |  |
Transport-Layer Security | Y |  |  |
Java synchronization logic | Y | 32-bit software |  |
.NET synchronization logic | Y | Y |  |
MobiLink with Messaging (QAnywhere) | Y | Y |  |
Server-Initiated Synchronization | Y | Y |  |
MobiLink Adaptive Server Anywhere clients
Component | Windows (32-bit) | Windows (64-bit) | Windows CE | NetWare
ASA MobiLink clients (dbmlsync) | Y | Y | Y |
TCP/IP synchronization | Y | Y | Y |
HTTP synchronization | Y | Y | Y |
HTTPS synchronization | Y | Y | Y |
Transport-layer security | Y | Y | Y |
QAnywhere clients | Y | Y | Y |
MobiLink utilities
Component | Windows (32-bit) | Windows (64-bit) | Windows CE | NetWare
Redirector | Y 6 |  |  |
MobiLink extraction utility (mlxtract) | Y | Y |  |
SQL Remote

SQL Remote components that operate against Adaptive Server Enterprise databases require Sybase Open Client and/or Open Server libraries.

Component | Windows (32-bit) | Windows (64-bit) | Windows CE | NetWare
ASA Message Agent (dbremote) | Y | Y | Y | Y
ASE Message Agent (ssremote) | Y | 32-bit software |  |
ASE stable queue (ssqueue) | Y | 32-bit software |  |
ASA extraction utility (dbxtract) | Y | Y |  |
ASE extraction utility (ssxtract) | Y | 32-bit software |  |
File message type | Y | Y | Y | Y
FTP message type | Y | Y | Y | Y
MAPI message type | Y | Y |  |
SMTP message type | Y | Y | Y | Y
VIM message type | v |  |  |
Replication agent

The Replication Agent requires Sybase Open Client and Open Server libraries.

Component | Windows (32-bit | Windows (64-bit) | Windows CE | NetWare
Replication Agent | Y | 32-bit software |  |
Administration tools
Component | Windows (32-bit) | Windows (64-bit) | Windows CE | NetWare
Command line administration utilities | Y | Y |  | Y
Sybase Central | Y | 32-bit JRE |  |
Interactive SQL | Y | 32-bit JRE |  | Y 7
DBConsole | Y | 32-bit JRE |  | Y 8

With the exception of the command line administration utilities and the tools provided on NetWare, the administration tools employ a Java 2 runtime environment, version 1.4.1.

The following paragraphs are taken from the Java 2 SDK, Standard Edition documentation, and apply to the administration tools:

The Java™ 2 SDK is intended for use on Microsoft Windows 95, 98 (1st or 2nd edition), NT 4.0 with Service Pack 5, Me, 2000 Professional, 2000 Server, 2000 Advanced Server, or XP operating systems running on Intel hardware.

A Pentium 166MHz or faster processor with at least 32 megabytes of physical RAM is required to run graphically based applications. Forty-eight megabytes of RAM is recommended for applets running within a browser using the Java Plug-in product. Running with less memory may cause disk swapping which has a severe effect on performance. Very large programs may require more RAM for adequate performance.

You should have 70 megabytes of free disk space before attempting to install the Java 2 SDK software. If you also want to install the documentation download bundle, you will need an additional 120 megabytes of free disk space.

1 ODBC driver manager may not be available. May have to link directly to ODBC driver.

2 Requires iAnywhere Solutions ODBC driver on Windows. For a list of supported platforms, see iAnywhere Solutions ODBC drivers supported platforms.

3 Requires Java in the database and JDBC driver

4 The older interface to external stored procedures is available only in 32-bit software.

5 Requires Visual Studio.NET or Visual Studio.NET 2003, with .NET Compact Framework version 1.0.5000 or later.

6 Windows NT/2000/XP only

7 A more limited version than is provided on other operating systems

8 A more limited version than is provided on other operating systems


UNIX, Linux, and Macintosh operating systems

Unless otherwise noted, the supported versions of the listed operating systems are as described in Operating system versions.

Adaptive Server Anywhere
Component | Solaris | Linux | Mac OS X | HP-UX | AIX | Tru64
Personal database server | Y | Y | Y | Y | Y | Y
Network database server | Y | Y | Y | Y | Y | Y
ODBC clients 1 | Y | Y | Y | Y | Y | Y
Embedded SQL clients | Y | Y | Y | Y | Y | Y
SQL preprocessor | Y | Y | Y | Y | Y | Y
Open Client clients | Y | Y | Y | Y | Y | Y
JDBC clients (jConnect driver) | Y | Y | Y | Y | Y | Y
Java in the database | Y | Y | Y | Y | Y | Y
Remote data access 2 | Y | Y | Y |  |  |
External stored procedures | Y | Y | Y | Y | Y | Y
iAnywhere JDBC driver 3 | Y | Y | Y | Y | Y | Y

Linux Note for Adaptive Server Anywhere Crashes have been observed under the 2.4.2 SMP kernel when using multiple processors. Under some conditions, the operating system may cause the process memory to be corrupted resulting in subsequent application crashes. Later 2.4.x kernels do not exhibit this problem.

MobiLink synchronization server
Component | Solaris | Linux | Mac OS X | HP-UX | AIX | Tru64
MobiLink synchronization server | Y | Y | Y | Y | Y |
TCP/IP synchronization | Y | Y | Y | Y | Y |
HTTPS synchronization | Y | Y | Y | Y | Y |
HTTP synchronization | Y | Y | Y | Y | Y |
Transport-Layer Security | Y | Y | Y |  |  |
Java synchronization logic | Y | Y | Y | Y | Y |
.NET synchronization logic |  |  |  |  |  |
MobiLink with Messaging (QAnywhere) | Y | Y | Y | Y | Y |
Server-Initiated Synchronization | Y | Y | Y | Y | Y |

MobiLink support for HP-UX is available only on 32-bit PA RISC, and starts with version 9.0.1. Mac OS X support for TLS also starts with 9.0.1.

If you use Java synchronization logic, MobiLink with Messaging, or Server-Initiated Synchronization on HP-UX or AIX, you must set SHLIB_PATH (on HP-UX) or LIBPATH (on AIX) to include the directory containing an installed JRE.

Adaptive Server Anywhere MobiLink client
Component | Solaris | Linux | Mac OS X | HP-UX | AIX | Tru64
ASA MobiLink clients (dbmlsync) | Y | Y | Y |  |  |
TCP/IP synchronization (client) | Y | Y | Y |  |  |
HTTPS synchronization (client) | Y | Y | Y |  |  |
HTTP synchronization (client) | Y | Y | Y |  |  |
MobiLink extraction utility (mlxtract) | Y | Y | Y |  |  |
SQL Remote

SQL Remote components that operate against Adaptive Server Enterprise databases require Sybase Open Client and/or Open Server libraries. These libraries are not available on Compaq Tru64.

Component | Solaris | Linux | Mac OS X | HP-UX | AIX | Tru64
ASA Message Agent (dbremote) | Y | Y | Y |  |  |
ASE Message Agent (ssremote) | Y | Y |  |  |  |
ASE stable queue (ssqueue) | Y | Y |  |  |  |
ASA extraction utility (dbxtract) | Y | Y | Y |  |  |
ASE extraction utility (ssxtract) | Y | Y |  |  |  |
File message type | Y | Y | Y |  |  |
FTP message type | Y | Y | Y |  |  |
MAPI message type |  |  |  |  |  |
SMTP message type | Y | Y | Y |  |  |
VIM message type |  |  |  |  |  |
Replication agent

The Replication Agent requires Sybase Open Client and Open Server libraries.

Component | Solaris | Linux | Mac OS X | HP-UX | AIX | Tru64
Replication Agent | Y | Y |  |  |  |
Administration tools
Component | Solaris | Linux | Mac OS X | HP-UX | AIX | Tru64
Command line administration utilities | Y | Y | Y | Y | Y | Y
Sybase Central | Y | Y | Y |  |  |
Interactive SQL | Y | Y | Y |  |  |

With the exception of the command-line administration utilities, the administration tools employ a Java 2 runtime environment, version 1.3.1.

The following paragraphs are taken from the Java 2 SDK, Standard Edition Version 1.3.1 system requirement for Solaris, and apply to the administration tools:

The Java 2 SDK, Standard Edition, v. 1.3.1 (J2SDK 1.3.1) is intended for use on Solaris 2.6, Solaris 7, Solaris 8, and Solaris 9 Operating Environments.

Prior to installing the Java 2 SDK, you should insure that you have installed the full set of required patches needed for support of this release. To obtain patches, see the SunSolve support web site. You will find a patch cluster for each Solaris operating environment platform. Each patch cluster applies to all supported versions of the Java 2 Standard Edition (J2SE) on the given platform.

See also Solaris Font Package Requirements for information about which font packages should be on your system.

1 ODBC driver manager may not be available. May have to link directly to ODBC driver.

2 JDBC remote data sources require Java in the database and a JDBC driver. ODBC remote data sources requires iAnywhere Solutions ODBC driver. For a list of supported platforms, see iAnywhere Solutions ODBC drivers supported platforms.

3 Requires JRE 1.4 or higher on Itanium chips. Requires JRE 1.3 or higher on other chips.


MobiLink synchronization consolidated databases

MobiLink supports the following consolidated databases:

Database server | Version
Adaptive Server Anywhere | Current
Sybase Adaptive Server Enterprise | 11.5 and later
Oracle | 8i and 9i
Microsoft SQL Server | 7 and 2000
IBM DB2 | 7 and 8 UDB
Dependencies

For a list of supported operating systems, see MobiLink synchronization server and MobiLink synchronization server.

For the MobiLink synchronization server to connect to a consolidated database, an ODBC driver is required. iAnywhere Solutions provides a selection of ODBC drivers described in iAnywhere Solutions ODBC drivers supported platforms. Some database vendors also provide their own ODBC drivers.

For a list of ODBC drivers and their status see Recommended ODBC Drivers for MobiLink at [external link] http://www.ianywhere.com/developer/technotes/odbc_mobilink.html.


iAnywhere Solutions ODBC drivers supported platforms

iAnywhere Solutions ODBC drivers provide ODBC access to third-party databases for the MobiLink synchronization server and for Adaptive Server Anywhere remote data access.

The Adaptive Server Anywhere ODBC driver is not listed in this section. For information on the Adaptive Server Anywhere ODBC driver, see Windows and NetWare operating systems.

iAnywhere Solutions ODBC drivers are available for the following operating system and database combinations:

Operating system | Database
Windows (32-bit) | Sybase Adaptive Server Enterprise 11.5 and later Oracle 8i and 9i IBM DB2 7 and 8 UDB
Solaris 7.0, 8.0, and 9.0 | Sybase Adaptive Server Enterprise 11.5 and later Oracle 8i and 9i
IBM AIX | Sybase Adaptive Server Enterprise 11.5 and later Oracle 8i and 9i IBM DB2 7 and 8 UDB
Linux 1 | Sybase Adaptive Server Enterprise 11.5 and later Oracle 8i and 9i
HP-UX (32-bit PA RISC only) | Adaptive Server Anywhere IBM DB2 7 and 8 UDB

1 Red Hat, SuSE, and Caldera distributions only.


UltraLite target platforms

The following table lists the supported operating systems for UltraLite deployment, including synchronization streams.

For a list of supported development platforms, see UltraLite development platforms.

For an explanation of the column headings, see Operating system versions.

Component | Windows CE | Palm | Windows XP
UltraLite static C/C++ API | Y | Y | Y
UltraLite embedded SQL | Y | Y | Y
UltraLite static Java API1 | Y |  | Y
UltraLite for AppForge MobileVB | Y | Y | Y
UltraLite ActiveX | Y |  | Y
UltraLite .NET | Y 2 |  | Y 3
Native UltraLite for Java | Y 4 |  | Y
UltraLite C++ component | Y | Y | Y
UltraLite for M-Business Anywhere | Y 5 | Y 6 |
TCP/IP synchronization | Y | Y | Y
HTTP synchronization | Y | Y | Y
HTTPS synchronization | Y | Y | Y
HotSync synchronization |  | Y |
ActiveSync synchronization (3.5 and 3.6) | Y 7,8 |  |
Transport-layer security over HTTP or TCP/IP 9 | Y 10 | Y | Y
Notes

UltraLite dynamic memory requirements mean that devices with Palm OS 3.5, or devices with less than 4 MB of memory, may not run for all but very small database schemas.

1 Requires PersonalJava or JDK 1.2.

2 Requires .NET Compact Framework version 1.0.3705 or later.

3 Requires .NET Compact Framework version 1.0.5000 or later.

4 Deployment onto a CE/ARM device requires a Java VM on the device. Native UltraLite for Java should work with any PersonalJava 1.2 (or higher)-based VM, however, only the PersonalJava-based Jeode VM and the CrEme VM (version 3.24 or higher) have been tested.

5 Requires Pocket PC on an ARM processor

6 Requires Palm OS 5

7 Not supported by UltraLite components except Native UltraLite for Java and UltraLite.NET

8 Not supported on Smartphone 2002

9 Not supported by UltraLite components. Static Java API requires JDK 1.2.2 or greater. JDK 1.4 is not supported.

10 Pocket PC required


Operating system versions

Availability
Features and platform support for unreleased software are subject to change. Listing a platform as supported does not necessarily indicate immediate availability of the software.

For example, for a given software version not all platforms are released simultaneously, and information about later platforms is not guaranteed to be correct in earlier releases.

Unless otherwise specified, operating system names correspond to the following versions:

Operating system | 9.0.0 | 9.0.1 | 9.0.2
Microsoft Windows (32-bit) The following are supported:

  • Windows NT 4.0 or later

  • Windows 2000

  • Windows XP, including Windows XP embedded and Windows XP Tablet PC on x86-architecture processors.

  • A list of components required on the Windows XP Embedded image can be found at [external link] http://www.sybase.com/detail?id=1019835.

  • Windows Server 2003, 32-bit versions.

  • Windows 95/98/Me.

 Unchanged from 9.0.0 Unchanged from 9.0.1
Microsoft Windows (64-bit) | Windows Server 2003, 64-bit versions. | Unchanged from 9.0.0 | Unchanged from 9.0.1
Microsoft Windows CE Windows CE 3.0 operating system on any of the following processors:

  • MIPS processor

  • ARM processors, including the XScale series.

  • x86 processor. UltraLite supports the x86 processor for the Pocket PC 2002 emulator; Adaptive Server Anywhere supports x86 devices and emulation.

    The Windows CE emulator is also supported for development purposes.

Windows CE 3.0 includes support for Pocket PC, including Pocket PC 2002, as well as Handheld PC.

Windows CE 4.1 on the XScale (Intel PXA255) processor in ARMV4 mode.

Pocket PC 2003 and other versions of Windows CE 4.2 on the XScale (Intel PXA255) processor in ARMV4 mode.

Windows CE 4.1 running in "Thumb" mode on the ARM processor, known as ARMV4T, is supported starting with version 9.0.1.

UltraLite supports the Smartphone 2002 platform in addition to the other Windows CE platforms.

The Pocket PC 2000 emulator is no longer supported.

 Unchanged from 9.0.1
Novell NetWare | 5.1 with service pack 6, 6.0 with service pack 3, and 6.5. | Unchanged from 9.0.0 | Unchanged from 9.0.1
Palm OS | Palm Computing Platform devices running the Palm OS version 3.5, 4.x, or 5.0. | Unchanged from 9.0.0 | Unchanged from 9.0.1
Linux Linux distributions are all based on defined versions of the kernel, the C library (glibc) and the ncurses library. The supported versions are as follows:

  • kernel 2.4.18 or 2.4.2

  • glibc 2.1.2, 2.1.3, or 2.2

  • ncurses 4.2

The following Linux distributions are among those that meet the above requirements.

  • Red Hat 6.1, 6.2, 7.0, 7.1, 7.2, 7.3, or Advanced Server 2.1.

  • SuSE 6.3, 6.4, 7.0, 7.2, 7.3, or 8.0 (but not 7.1)

  • Caldera 2.4 or 3.e

  • TurboLinux 6.1, 6.5 or 7.0

  • Mandrake 7.2, 8.0, or 8.1

Linux distributions are supported on x86-architecture processors.

The 64-bit deployment edition is available for Red Hat Advanced Server on Itanium 2 processors.

 32-bit Linux distributions with the following versions of the kernel and glibc:

  • Kernel 2.4.2 to 2.4.21 and glibc 2.2.1 to 2.3.2

  • Kernel 2.6.0 and glibc 2.3.2

64-bit Linux distributions on the Itanium chip with the following versions of the kernel and glibc:

  • Kernel 2.4.9 with glibc 2.2.4, (for example, RedHat Advanced Server 2.1)

  • Kernel 2.6.0 with glibc 2.3.2 (for example, RedHat Enterprise Server 3)

 Changes are possible before the release of this version.
Sun Solaris | 7.0 1 , 8.0, or 9.0 32-bit or 64-bit operating systems on SPARC processors. | Unchanged from 9.0.0 | Changes are possible before the release of this version.
Mac OS X Mac OS X version 10.2.n, where n is 2 or higher Version 10.2 and 10.3 on the G4 processor.

Version 10.3 on the G5 processor.

 Changes are possible before the release of this version.
Compaq Tru64 | 4.0D, 5.1, or 5.2 on Alpha processors. | 4.2, 5.1, or 5.2 on Alpha processors. | Changes are possible before the release of this version.
Hewlett Packard HP-UX | 11.0 or 11i, 32-bit version on PA-RISC processors. HP-UX 11i is also supported in a 64-bit version on Itanium 2 processors. | Unchanged from 9.0.0 | Changes are possible before the release of this version.
IBM AIX | 4.3.3, 5.1, or 5.2 on Power PC processors | Unchanged from 9.0.0 | Changes are possible before the release of this version.

1 Patches 106541-14 and 106980-13 recommended to resolve observed SIGIO problems.


The Architecture of Database Applications

About this chapter

This section introduces some of the terms and concepts that are important when talking about relational databases.

Relational database concepts
The pieces of a database system
How the pieces fit together
Multi-tier computing architecture
Using multiple databases
Application programming interfaces
Inside Adaptive Server Anywhere


Relational database concepts

A relational database-management system (RDBMS) is a system for storing and retrieving data, in which the data is organized into interrelated tables.

SQL Anywhere Studio provides two relational database systems. Adaptive Server Anywhere is the primary, full featured RDBMS, with a multitude of uses, from a network database server hosting many clients to a compact embedded database. UltraLite is a small-footprint relational database. The UltraLite deployment technology allows you to use Adaptive Server Anywhere features on even the smallest of devices.


Database tables

In a relational database, all data is held in tables, which are made up of rows and columns.

A database containing several tables.

Each table has one or more columns, and each column is assigned a specific data type, such as an integer, a sequence of characters (for text), or a date. Each row in the table has a single value for each column.

For example, a table containing employee information may look as follows:

emp_ID | emp_lname | emp_fname | emp_phone
10057 | Huong | Zhang | 1096
10693 | Donaldson | Anne | 7821
Characteristics of relational tables

The tables of a relational database have some important characteristics:

  • There is no significance to the order of the columns or rows.

  • Each row contains one and only one value for each column, or contains NULL, which indicates that there is no value for that column.

  • All values for a given column have the same data type.

The following table lists some of the formal and informal relational database terms describing tables and their contents, together with their equivalent in non-relational databases. This manual uses the informal terms.

Informal relational term | Formal relational term | Non-relational term
Table | Relation | File
Column | Attribute | Field
Row | Tuple | Record
What do you keep in each table?

Each table in the database should hold information about a specific thing, such as employees, products, or customers.

By designing a database this way, you can set up a structure that eliminates redundancy and the possible inconsistencies caused by redundancy. For example, both the sales and accounts payable departments might enter and look up information about customers. In a relational database, the information about customers is stored only once, in a table that both departments can access.

For more information about database design, see Designing Your Database.


Relations between tables

You use primary keys and foreign keys to describe relationships between the information in different tables. Primary keys identify each row in a table uniquely, and foreign keys define the relationships between rows in different tables.

Primary keys and foreign keys let you use relational databases to hold information in an efficient manner, without redundancy.


Tables have a primary key

Each table in a relational database should have a primary key. The primary key is a column, or set of columns, that uniquely identifies each row. No two rows in a table may have the same primary key value.

Examples

In the sample database, the employee table stores information about employees. It has a primary key column named emp_id, which holds a unique ID number assigned to each employee. A single column holding an ID number is a common way to assign primary keys, and has advantages over names and other identifiers that may not always be unique.

A more complex primary key can be seen in the sales_order_items table of the sample database. The table holds information about individual items on orders from the company, and has the following columns:

  • id An order number, identifying the order the item is part of.

  • line_id A line number, identifying each item on any order.

  • prod_id A product ID, identifying the product being ordered.

  • quantity A quantity, displaying how many items were ordered.

  • ship_date A ship date, displaying when the order was shipped.

A particular sales order item is identified by the order it is part of, and by a line number on the order. These two numbers are stored in the id and line_id columns. Items may share a single id value (corresponding to an order for more than one item) or they may share a line_id number (all first items on different orders have a line_id of 1). No two items share both values, and so the primary key is made up of these two columns.


Tables are related by foreign keys

The information in one table is related to that in other tables by foreign keys.

Example

The sample database has one table holding employee information and one table holding department information. The department table has the following columns:

  • dept_id An ID number for the department. This is the primary key for the table.

  • dept_name The name of the department.

  • dept_head_id The employee ID for the department manager.

To find the name of a particular employee's department, there is no need to put the name of the employee's department into the employee table. Instead, the employee table contains a column holding a number that matches one of the dept_id values in the department column.

The dept_id column in the employee table is called a foreign key to the department table. A foreign key references a particular row in the table containing the corresponding primary key.

In this example, the employee table (which contains the foreign key in the relationship) is called the foreign table or referencing table. The department table (which contains the referenced primary key) is called the primary table or the referenced table.


Other database objects

There is more to a relational database than simply a set of related tables. You will also find the following objects in a relational database:

  • Indexes Indexes allow quick lookup of information. Conceptually, an index in a database is like an index in a book. In a book, the index relates each indexed term to the page or pages on which that word appears. In a database, the index relates each indexed column value to the physical location at which the row of data containing the indexed value is stored.

    Indexes are an important design element for high performance. You must usually create indexes explicitly, but indexes for primary and foreign keys and for unique columns are created automatically. Once created, the use of indexes is transparent to the user.

  • Views Views are computed tables, or virtual tables. They look like tables to client applications, but they do not hold data. Instead, whenever they are accessed, the information in them is computed from the underlying tables.

    The tables that actually hold the information are sometimes called base tables to distinguish them from views. A view is defined with a SQL query on base tables or other views.

  • Stored procedures and triggers These are routines held in the database itself that act on the information in the database.

    You can create and name your own stored procedures to execute specific database queries and to perform other database tasks. Stored procedures can take parameters. For example, you might create a stored procedure that returns the names of all customers who have spent more than the amount that you specify as a parameter in the call to the procedure.

    A trigger is a special stored procedure that automatically fires whenever a user updates, deletes, or inserts data, depending on how you define the trigger. You associate a trigger with a table or columns within a table. Triggers are useful for automatically maintaining business rules in a database.

  • Users and groups Each user of a database has a user ID and password. You can set permissions for each user so that confidential information is kept private and users are prevented from making unauthorized changes. Users can be assigned to groups in order to make the administration of permissions easier.

  • Java objects You can install Java classes into the database. Java classes provide a powerful way of building logic into your database, and a special class of user-defined data types for holding information.

All of these items together make up a relational database-management system (RDBMS); a system for storing and retrieving data, in which the data is organized into interrelated tables.


The pieces of a database system

Relational database management systems contain the following pieces:

A database Data is stored in a database. In diagrams in the documentation, a database is indicated by a cylinder: The icon for a database: a cylinder.

An Adaptive Server Anywhere database is a file, usually with an extension of .db. Adaptive Server Anywhere includes a sample database for you to work with: this is the file asademo.db in your Adaptive Server Anywhere installation directory.

A database server The database server manages the database. No other application addresses the database file directly; they all communicate with the database server.

In the documentation, a database server is indicated as follows:

The icon for a database server: a box containing a schematic table in a circle.

Adaptive Server Anywhere provides two versions of its database server: the personal database server and the network database server. In addition to the features of the personal server, the network database server also supports client/server communications across a network, while the personal database server can accept connections only from applications running on the same machine. The request-processing engine is identical in both servers.

A programming interface Applications communicate with the database server using a programming interface. You can use ODBC, JDBC, OLE DB, Sybase Open Client, or Embedded SQL.

Many application development tools provide their own programming environment that hides the details of the underlying interface. For example, if you develop an application using Sybase PowerBuilder, you never have to make an ODBC function call. Nevertheless, behind the scenes each of these tools is using one of the programming interfaces.

The programming interface provides a library of function calls for communicating with the database. For ODBC and JDBC, the library is commonly called a driver. The library is typically provided as a shared library on UNIX operating systems or a dynamic link library (DLL) on PC operating systems. The JDBC interface uses the Sybase jConnect driver, which is a zip file of compiled Java classes.

In diagrams in the documentation, a programming interface is indicated as follows:

The icon for a client application: a shaded box with rounded ends.

A client application Client applications use one of the programming interfaces to communicate with the database server.

If you develop an application using a rapid application development (RAD) tool such as Sybase PowerBuilder, you may find that the tool provides its own methods for communicating with database servers, and hides the details of the language interface. Nevertheless, all applications use one of the supported interfaces.

In diagrams in the documentation, a client application is indicated by the following icon:

The icon for a client application: a box containing three triangles in a circle.

UltraLite database servers are custom-generated for each UltraLite application, and are part of the application itself. An UltraLite application together with its database server is indicated as follows:

The icon used in the documentation to indicate an UltraLite application and database.


How the pieces fit together

Database applications can connect to a database server located on the same machine as the application itself, or in the case of the network database server, on a different machine. In addition, with Adaptive Server Anywhere you can build distributed databases, with physically distinct databases on different machines sharing data.


Personal applications and embedded databases

You can use Adaptive Server Anywhere to build a complete application and database on a single computer. In the simplest arrangement, this is a standalone application or personal application: it is self-contained with no connection to other databases. In this case, the database server and the database can be started by the client application, and it is common to refer to the database as an embedded database. As far as the end user is concerned, the database is a part of the application. When a database server is used as an embedded database, it is sometimes called a database engine.

Many relational database management systems require experienced staff for administration. A characteristic of embedded databases is the ability to run entirely without administration.

The Adaptive Server Anywhere personal database server is generally used for standalone applications. A client application connects through a programming interface to a database server running on the same machine:

Standalone applications have the following architecture, with a client application connecting through a programming interface to a database server running on the same machine:

A standalone application on a single machine.

The Adaptive Server Anywhere personal database server is generally used for standalone applications, although you can also use applications on the same machine as the network server.

A standalone application on a single machine.


Client/server applications and multi-user databases

You can use Adaptive Server Anywhere to build an installation with many applications running on different machines, connected over a network to a single database server running on a separate machine. This is a client/server or multi-user database environment, and has the following architecture. The interface library is located on each client machine.

Client/server application architecture.

In this case, the database server is the Adaptive Server Anywhere network database server, which supports network communications.

For a client application to work in a client/server environment, you need only identify the server to which it should connect.

For a client application to work in a client/server environment, you need only identify the server to which it should connect.


Multi-tier computing architecture

In multi-tier computing, application logic is held in an application server, such as Sybase EAServer, which sits between the database server and the client applications. In many situations, a single application server may access multiple databases in addition to non-relational data stores. In the Internet case, client applications are browser-based, and the application server is generally a Web server extension.

Sybase EAServer stores application logic in the form of components, and makes these components available to client applications. The components may be PowerBuilder components, Java beans, or COM components.

Application servers can also provide transaction logic to their client applications—guaranteeing that sets of operations are executed atomically across multiple databases. Adaptive Server Anywhere is well-suited to multi-tier computing, and can participate in distributed transactions coordinated by Microsoft Distributed Transaction Coordinator. Both Sybase Enterprise Application Server and Microsoft Transaction Server use DTC to provide transaction services to their client applications.

For more information, see Three-Tier Computing and Distributed Transactions.


Using multiple databases

This section describes extensions to the Adaptive Server Anywhere architecture described above for the case where you want to use more than one database.


Running multiple databases on a single database server

Both the Adaptive Server Anywhere personal database server and the network database server can manage several databases simultaneously. Each connection from an application must be to a single database, but an application can use separate connections to different databases, or a set of applications can work on different databases, all through the same database server.

One database server running multiple databases.

Databases can be started when the database server is started, or by connecting to a database using the DatabaseFile connection parameter.

For more information, see The database server, and DatabaseFile connection parameter [DBF].


Accessing data in other databases

You can access databases on multiple database servers, or even on the same server, using the Adaptive Server Anywhere Remote Data Access features. The application is still connected to a single database as in the architecture diagrams above, but by defining remote servers, you can use proxy tables that exist on the remote database as if they were in the database to which you are connected.

Remote data access to other database servers.

For more information, see Accessing Remote Data.


Application programming interfaces

The current section describes application architecture in more detail. An overview of database application architecture was given in How the pieces fit together.

Adaptive Server Anywhere supports a wide set of programming interfaces to provide flexibility in the kinds of applications and application development environments you can use.

Supported interfaces and protocols
Communications protocols
ODBC applications
Embedded SQL applications
Open Client applications
JDBC applications
OLE DB applications


Supported interfaces and protocols

The following diagram displays the supported interfaces, and the interface libraries used. In most cases, the interface library is the same name as the interface itself.

The supported database interfaces for Adaptive Server Anywhere.

The applications supplied with SQL Anywhere Studio use several of these interfaces:

Adaptive Server Anywhere with client applications.


Communications protocols

Each interface library communicates with the database server using a communication protocol. Adaptive Server Anywhere supports two communication protocols, Tabular Data Stream (TDS) and Command Sequence. These protocols are internal, and for most purposes it does not matter which one you are using. Your choice of development environment will be governed by your available tools.

The major differences you will see are upon connecting to the database. The Command Sequence applications and TDS applications use different methods to identify a database and database server, and so connection dialogs are different.

TDS This protocol is used by Sybase Adaptive Server Enterprise, Open Client applications, and Java applications that use the jConnect JDBC driver connect using TDS.

Command Sequence This protocol is used by Adaptive Server Anywhere, Adaptive Server IQ, and is used by embedded SQL, ODBC, and OLE DB applications.


ODBC applications

You can develop ODBC applications using a variety of development tools and programming languages, as shown in the figure below.

ODBC applications and Adaptive Server Anywhere.

For example, of the applications supplied with SQL Anywhere Studio, InfoMaker and SQL Modeler use ODBC to connect to the database.


Embedded SQL applications

You can develop C or C++ applications using the embedded SQL programming interface. The command-line database tools are examples of applications developed in this manner.

Embedded SQL is also a programming interface for UltraLite applications.

Embedded SQL applications and Adaptive Server Anywhere.


Open Client applications

Open Client is an interface that is also supported by Sybase Adaptive Server Enterprise. You can develop Open Client applications in C or C++. Other Sybase applications, such as OmniConnect or Replication Server, use Open Client.

Open Client applications and Adaptive Server Anywhere.


JDBC applications

You can develop applications that use JDBC to connect to Adaptive Server Anywhere using Java. Several of the applications supplied with SQL Anywhere Studio use JDBC: the stored procedure debugger, Sybase Central, and Interactive SQL.

JDBC applications and Adaptive Server Anywhere.

Java and JDBC are also important programming languages for developing UltraLite applications.


OLE DB applications

Adaptive Server Anywhere includes an OLE DB driver. You can develop applications using Microsoft's OLE DB interface directly, or using the ActiveX Data Objects (ADO) interface. The ADO interface is included in Visual Basic and other Microsoft programming tools. SQL Anywhere Studio also includes and ADO.NET data provider for Adaptive Server Anywhere.


Inside Adaptive Server Anywhere

While you never need to deal with the internals of the database server, a glimpse behind the scenes may help you understand the process better.


Inside the database server

The Adaptive Server Anywhere database server has an internal structure that allows many requests to be handled efficiently.

  • A communications layer handles the actual exchange of data with client applications. This layer receives requests from client applications, and returns results. The timing of these actions is governed by a negotiation between client and server to make sure that the network traffic is kept to a minimum, but that the data is made available as soon as possible on the client side.

  • The parser checks each SQL statement sent to the database server, and transforms it into an internal form for processing.

  • If the request is a query, an update, or delete statement, there may be many different ways of accessing the data, which may take massively different times. The job of the optimizer is to select from among all these possibilities the best route to getting the required data quickly.

  • A Java Virtual Machine is built into the database server, and any Java operations sent by client applications, or invoked internally by the database server, are handled by the Java VM.

  • The lowest level of the database server is concerned with reading and writing data from the disk, caching data in memory to avoid unnecessary disk access, and balancing the demands of different users.

Internal architecture of Adaptive Server Anywhere.


Inside the database

All the information in an Adaptive Server Anywhere database is usually stored in a single database file, which can be copied from one machine to another. It is possible to make databases of several files, but this is generally only required for very large databases.

In addition to the database file, Adaptive Server Anywhere uses two other files when it is running a database. These are the transaction log and the temporary file.

  • The database file Internally, the database file is composed of pages: fixed size areas of disk. The data access layer reads and writes data one page at a time. Many pages hold the data that is in the database tables, but other pages hold index information, information about the distribution of data within the database, and so on.

  • The transaction log The transaction log is a separate file that contains a record of all the operations performed on the database. Normally, it has the same name as the database file, except that it ends with the suffix .log instead of .db. It has three important functions.

    • Record operations on your data to enable recovery You can recreate your database from a backup together with the transaction log if the database file is damaged.

    • Improve performance By writing information to the transaction log, the database server can safely process your statements without writing to the database file as frequently.

    • Enable database replication SQL Remote and the MobiLink client utility use this file to replicate the changes to your database on portable computers which are occasionally connected to the network.

  • The temporary file The temporary file is opened when the database server starts, and is closed down when the server stops. As its name suggests, the temporary file is used while the server is running to hold temporary information. The temporary file does not hold information that needs to be kept between sessions.

    The temporary file is stored in your temporary directory. The location of this directory is generally identified by your TEMP environment variable.


Selecting Data from Database Tables

About this chapter

This chapter introduces Structured Query Language (SQL) and queries, which retrieve data from a database. It describes how to retrieve data from a single table.

Other parts of the documentation set assume that you are familiar with the concepts introduced in this chapter.

SQL and database computing
SELECT statement
Selecting a complete table
Selecting columns from a table
Ordering query results
Selecting rows from a table


SQL and database computing

When a client application wants to carry out a database task, such as retrieving information using a query or inserting a new row into a table, it does so using Structured Query Language (SQL) statements. SQL is a relational database language that has been standardized by the ANSI and ISO standards bodies.

Depending on how you develop a client application, SQL statements could be supplied in function calls from the programming language. Some application development tools provide user interfaces for building and generating SQL statements.

The programming interface delivers the SQL statement to the database server. The database server receives the statement and executes it, returning the required information (such as query results) back to the application.

Client/server communication protocols carry information between the client application and the database server, and programming interfaces define how an application sends the information. No matter what interface you use, and what network protocol you use, it is SQL statements that are sent to a server, and the results of SQL statements that are returned to the client application.

Example

This SQL statement extracts the last names of all employees from the employee table in the sample database:

SELECT emp_lname
FROM employee

You can send queries like this to the database server using Interactive SQL or you can build the query into your own application.

Example

This SQL statement creates a table called food that lists types of food and the amount in stock in the employee cafeteria:

CREATE TABLE food (
   food_id integer primary key,
   food_type char(20),
   quantity integer
)


Queries

The "Q" in "SQL" stands for query. You query (or retrieve) data from a database with the SELECT statement. The basic query operations in a relational system are projection, restriction, and join. The SELECT statement implements all of them.

Projections and restrictions

A projection is a subset of the columns in a table. A restriction (also called selection) is a subset of the rows in a table, based on some conditions.

For example, the following SELECT statement retrieves the names and prices of all products that cost more than $15:

SELECT name, unit_price
FROM product
WHERE unit_price > 15

This query uses both a projection (SELECT name, unit_price) and a restriction (WHERE unit_price > 15).

Joins

A join links the rows in two or more tables by comparing the values in columns of each table. For example, you might want to select the order item identification numbers and product names for all order items that shipped more than a dozen pieces of merchandise:

SELECT sales_order_items.id, product.name
FROM product JOIN sales_order_items
WHERE sales_order_items.quantity > 12

The product table and the sales_order_items table are joined together based on the foreign key relationship between them.


Other SQL statements

You can do more with SQL than just query. SQL includes statements that create tables, views, and other database objects. It also includes statements that modify tables (the INSERT, UPDATE, and DELETE statements), and statements that perform many other database tasks discussed in this manual.


The system tables

Every Adaptive Server Anywhere database contains a set of system tables. These are special tables that the system uses to manage data and the system. These tables are also sometimes called the data dictionary or the system catalog.

System tables contain information about the database. You never alter the system tables directly in the way that you can alter other tables. The system tables hold information about the tables in a database, the users of a database, the columns in each table, and so on. This information is data about data, or metadata.

For more information about the Adaptive Server Anywhere system tables, see System Tables.


SELECT statement

All interaction between applications (clients) and database servers is carried out by sending SQL statements to the database server, which returns information to the client.

The SELECT statement retrieves information from a database for use by the client application. SELECT statements are also called queries. The information is delivered to the client in the form of a result set. The client application can then process the result set. For example, Interactive SQL displays the result set in the Results pane. Result sets consist of a set of rows, just like tables in the database.

SELECT statements can become highly complex in applications retrieving very specific information from many tables. This chapter uses only simple SELECT statements: more advanced queries are described in later tutorials.

For the full syntax of the SELECT statement, see SELECT statement.

Notes

You should run the Adaptive Server Anywhere software on your computer while you read and work through the examples in this chapter.

Each example instructs you to type commands into Interactive SQL and describes what you will see on your computer screen. If you cannot run the software as you read the tutorials, you will still be able to learn about SQL, but you will not have the opportunity to experiment on your own.

The examples assume that you have started Interactive SQL and are connected to the sample database.


Selecting a complete table

The simplest SELECT statement retrieves all the data in a single table. This SELECT statement has the following syntax:

SELECT * FROM table-name

where table-name should be replaced with the name of the table you are querying. The asterisk (*) is a short form for a list of all columns.

toggle List all products sold by the company

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT * FROM Product

    The SELECT statement retrieves all the rows and columns of the product table, and displays them on the Results tab in the Results pane:

    id | name | description | size | color | quantity | unit_price
    300 | Tee Shirt | Tank Top | Small | White | 28 | 9
    301 | Tee Shirt | V-neck | Medium | Orange | 54 | 14
    302 | Tee Shirt | Crew Neck | One size fits all | Black | 75 | 14
    400 | Baseball Cap | Cotton Cap | One size fits all | Black | 112 | 9
    ... ... ... ... ... ... ...

    The Product table contains seven columns. Each column has a name, such as color or id. There is a row for each product that the company sells, and each row has a single value in each column. For example, the product with ID 301 is a Tee Shirt. It is a V-neck style in medium size, and is orange in color.

Notes

  • Table names are case insensitive The table name Product starts with an upper case P, even though the real table name is all lower case. Adaptive Server Anywhere databases can be created as case-sensitive or case-insensitive in their string comparisons, but are always case insensitive in their use of identifiers such as table names and column names.

    For information on creating databases, see Creating a database, or The Initialization utility.

  • SQL keywords are case insensitive You can enter select or Select instead of SELECT. In the documentation, upper case letters are generally used for SQL keywords.

  • Line breaks are not important You can type the statements all on one line, or break them up by pressing Enter at the end of each line. Some SQL statements, such as the SELECT statement, consist of several parts, called clauses. In many examples, each clause is placed on a separate line for easier reading, so the statement in the example is commonly written as follows in the documentation:

    SELECT *
FROM product

  • Row order in the result set is insignificant There is no guarantee of the order in which rows are returned from the database, and no meaning to the order. If you wish to retrieve rows in a particular order, you must specify the order in the query.

Exercise

Try querying other tables in the sample database, such as the employee, customer, contact, or sales_order tables.


Selecting columns from a table

You can limit the columns that a SELECT statement retrieves by listing the desired columns immediately after the SELECT keyword. This SELECT statement has the following syntax:

SELECT column-name-1, column-name-2,...
FROM table-name

where column-name-1, column-name-2, and table-name should be replaced with the names of the desired columns and table you are querying.

The list of result-set columns is called the select list. It is separated by commas. There is no comma after the last column in the list, or if there is only one column in the list. Limiting the columns in this way is sometimes called a projection.

toggle List the name, description, and color of each product

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT name, description, color
FROM product
    name | description | color
    Tee Shirt | Tank Top | White
    Tee Shirt | V-neck | Orange
    Tee Shirt | Crew Neck | Black
    Baseball Cap | Cotton Cap | Black
    ... ... ...
Rearranging columns

The columns appear in the order in which you type them in the SELECT statement. If you want to rearrange the columns, simply change the order of the column names in the statement. For example, to put the description column on the left, use the following statement:

SELECT description, name, color
FROM product

Using calculated columns


Using calculated columns

The columns of the result set do not need to be just columns in tables. They can also be expressions calculated from the underlying data. You can combine table columns into a single result-set column, and you can use a wide variety of functions and operators to control the results you get.

toggle List the value in stock of each product

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT id, ( unit_price * quantity ) AS value
FROM product
    id | value
    300 | 252
    301 | 756
    302 | 1050
    400 | 1008
    ... ...
Notes

  • Columns can be given an alias By default the column name is the expression listed in the select list, but for calculated columns the expression is cumbersome and not very informative. Here the calculated column is renamed in the select list as value. value is the alias for the column.

  • Other operators are available In the above example, the multiplication operator is used to combine the columns. You can use other operators, including the standard arithmetic operators as well as logical operators and string operators.

    For example, the following query lists the full names of all customers:

    SELECT id, (fname || ' ' || lname ) AS "Full name"
FROM customer

    The || operator concatenates strings. In this query, the alias for the column has spaces, and so must be surrounded by double quotes. This rule applies not only to column aliases, but to table names and other identifiers in the database.

    For a complete list of operators, see Operators.

  • Functions can be used In addition to combining columns, you can use a wide range of built-in functions to produce the results you want.

    For example, the following query lists the product names in upper case:

    SELECT id, UCASE( name )
FROM product
    id | UCASE(product.name)
    300 | TEE SHIRT
    301 | TEE SHIRT
    302 | TEE SHIRT
    400 | BASEBALL CAP
    ... ...

    For a complete list of functions, see Alphabetical list of functions.


Ordering query results

Unless otherwise requested, the database server returns the rows of a table in an order that has no meaning. Often it is useful to look at the rows in a table in a more meaningful sequence. For example, you might like to see products in alphabetical order.

You order the rows in a result set by an ORDER BY clause to the end of the SELECT statement. This SELECT statement has the following syntax:

SELECT column-name-1, column-name-2,...
FROM table-name
ORDER BY order-by-column-name

where column-name-1, column-name-2, and table-name should be replaced with the names of the desired columns and table you are querying, and where order-by-column-name is a column in the table. As before, you can use the asterisk as a short form for all the columns in the table.

toggle List the products in alphabetical order

  • In Interactive SQL, type the following in the SQL Statements pane:

    SELECT id, name, description
FROM product
ORDER BY name
    id | name | description
    400 | Baseball Cap | Cotton Cap
    401 | Baseball Cap | Wool cap
    700 | Shorts | Cotton Shorts
    600 | Sweatshirt | Hooded Sweatshirt
    ... ... ...
Notes

  • The order of clauses is important The ORDER BY clause must follow the FROM clause and the SELECT clause.

  • You can specify either ascending or descending order The default order is ascending. You can specify a descending order by adding the keyword DESC to the end of the clause, as in the following query:

    SELECT id, quantity
FROM product
ORDER BY quantity DESC
    id | quantity
    400 | 112
    700 | 80
    302 | 75
    301 | 54
    600 | 39
    ... ...

  • You can order by several columns The following query sorts first by size (alphabetically), and then by name:

    SELECT id, name, size
FROM product
ORDER BY size, name
    id | name | size
    600 | Sweatshirt | Large
    601 | Sweatshirt | Large
    700 | Shorts | Medium
    301 | Tee Shirt | Medium
    ... ... ...

  • The ORDER BY column does not need to be in the select list The following query sorts products by unit price, even though the price is not included in the result set

    SELECT id, name, size
FROM product
ORDER BY unit_price
    id | name | size
    500 | Visor | One size fits all
    501 | Visor | One size fits all
    300 | Tee Shirt | Small
    400 | Baseball Cap | One size fits all
    ... ... ...

  • If you do not use an ORDER BY clause, and you execute a query more than once, you may appear to get different results This is because Adaptive Server Anywhere may return the same result set in a different order. In the absence of an ORDER BY clause, Adaptive Server Anywhere returns rows in whatever order is most efficient. This means the appearance of result sets may vary depending on when you last accessed the row and other factors. The only way to ensure that rows are returned in a particular order is to use ORDER BY.

Using indexes to improve ORDER BY performance


Using indexes to improve ORDER BY performance

Sometimes there is more than one possible way for the Adaptive Server Anywhere database server to execute a query with an ORDER BY clause. You can use indexes to enable the database server to search the tables more efficiently.

Queries with WHERE and ORDER BY clauses

An example of a query that can be executed in more than one possible way is one that has both a WHERE clause and an ORDER BY clause.

SELECT *
FROM customer
WHERE id > 300
ORDER BY company_name

In this example, Adaptive Server Anywhere must decide between two strategies:

  1. Go through the entire customer table in order by company name, checking each row to see if the customer id is greater than 300.

  2. Use the key on the id column to read only the companies with id greater than 300. The results would then need to be sorted by company name.

If there are very few id values greater than 300, the second strategy is better because only a few rows are scanned and quickly sorted. If most of the id values are greater than 300, the first strategy is much better because no sorting is necessary.

Solving the problem

Creating a two-column index on id and company_name could solve the example above. Adaptive Server Anywhere can use this index to select rows from the table in the correct order. However, keep in mind that indexes take up space in the database file and involve some overhead to keep up to date. Do not create indexes indiscriminately.

For more information, see Using indexes.


Selecting rows from a table

You can limit the rows that a SELECT statement retrieves by adding a WHERE clause to your query. This is sometimes called applying a restriction to the result set. The WHERE clause includes a search condition that specifies the rows to be returned. This SELECT statement has the following syntax:

SELECT column-name-1, column-name-2,...
FROM table-name
WHERE search-condition

where, as before, column-name-1, column-name-2, and table-name should be replaced with the names of the desired columns and table you are querying. The search-condition is described more below. If you use an ORDER BY clause, it must come after the WHERE clause.

toggle List all products colored black

  • In Interactive SQL, type the following in the SQL Statements pane:

    SELECT *
FROM product
WHERE color = 'black'
    id | name | description | size | color | quantity | unit_price
    302 | Tee Shirt | Crew Neck | One size fits all | Black | 75 | 14
    400 | Baseball Cap | Cotton Cap | One size fits all | Black | 112 | 9
    501 | Visor | Plastic Visor | One size fits all | Black | 28 | 7
    ... ... ... ... ... ... ...
Notes

  • The WHERE clause includes a search condition to select rows. In this case the search condition is color = 'black'. Other search conditions are described in the following sections.

    For information on search conditions, see Search conditions.

  • The single quotes around black are required. They indicate that black is a character string. Double quotes have a different meaning. Double quotes can be used to make otherwise invalid strings valid for column names and other identifiers.

    For information about strings, see Strings.

  • The sample database is not case sensitive, so you would get the same results whether you searched for BLACK, black, or Black.

  • How you order clauses is important. The SELECT list is followed by the FROM clause, followed by the WHERE clause, and then the ORDER BY clause. Typing the clauses in a different order gives a syntax error.

Exercise

Try some queries that combine what you have learned in this chapter. Here is one query that lists the names and birth dates of all employees named John.

SELECT ( emp_fname || ' ' || emp_lname) AS Name,
        birth_date
FROM employee
WHERE emp_fname = 'John'
ORDER BY birth_date
Name | birth_date
John Letiecq | 4/27/1939
John Sheffield | 9/25/1955

Comparing dates in search conditions
Pattern matching in search conditions
Matching rows by sound
Using compound search conditions
Shortcuts for compound search conditions


Comparing dates in search conditions

You can use operators other than equals to select a set of rows that satisfy the search condition. The inequality operators (< and >) can be used to compare numbers, dates, and even character strings.

toggle List all employees born before March 13, 1964

  • In Interactive SQL, type the following in the SQL Statements pane:

    SELECT emp_lname, birth_date
FROM employee
WHERE birth_date < 'March 13, 1964'
ORDER BY birth_date DESC
    emp_lname | birth_date
    Ahmed | 12/12/1963
    Dill | 7/19/1963
    Rebeiro | 4/12/1963
    Garcia | ½3/1963
    Pastor | 7/14/1962
    ... ...
Notes

  • Automatic conversion to dates The Adaptive Server Anywhere database server knows that the birth_date column contains dates, and automatically converts the string 'March 13, 1964' to a date.

  • Ways of specifying dates There are many ways of specifying dates. The following are all accepted by Adaptive Server Anywhere:

    'March 13, 1964'
'1964/03/13'
'1964-03-13'

    You can tune the interpretation of dates in queries by setting a database option. Dates in the format yyyy/mm/dd or yyyy-mm-dd are always recognized unambiguously as dates, regardless of the DATE_ORDER setting.

    For information on controlling allowable date formats in queries, see DATE_ORDER option [compatibility], and Setting options.

  • Other comparison operators For a complete list of available comparison operators, see Comparison operators.


Pattern matching in search conditions

Pattern matching is a versatile way of identifying character data. In SQL, the LIKE keyword is used to search for patterns. Pattern matching employs wildcard characters to match different combinations of characters.

toggle List all employees whose last name begins with BR

  • In Interactive SQL, type the following in the SQL Statements pane:

    SELECT emp_lname, emp_fname
FROM employee
WHERE emp_lname LIKE 'br%'
    emp_lname | emp_fname
    Breault | Robert
    Braun | Jane

    The % in the search condition indicates that any number of other characters may follow the letters BR.

toggle List all employees whose last name begins with BR, followed by zero or more letters and a T, followed by zero or more letters

  • In Interactive SQL, type the following in the SQL Statements pane:

    SELECT emp_lname, emp_fname
FROM employee
WHERE emp_lname LIKE 'BR%T%'
    emp_lname | emp_fname
    Breault | Robert

    The first % sign matches the string eaul, while the second % sign matches the empty string (no characters).

Another special character that can be used with LIKE is the _ (underscore) character, which matches exactly one character. For example, the pattern 'BR_U%' matches all names starting with BR and having U as the fourth letter. In Braun the _ character matches the letter A and the % matches N.

For more information, see LIKE conditions.


Matching rows by sound

With the SOUNDEX function, you can match rows by sound. For example, suppose a phone message was left for a name that sounded like "Ms. Brown". Which employees in the company have names that sound like Brown?

toggle List employees with a last name that sound like Brown

  • In Interactive SQL, type the following in the SQL Statements pane:

    SELECT emp_lname, emp_fname
FROM employee
WHERE SOUNDEX( emp_lname ) = SOUNDEX( 'Brown' )
    emp_lname | emp_fname
    Braun | Jane

The algorithm used by SOUNDEX makes it useful mainly for English-language databases.

For more information, see SOUNDEX function [String].


Using compound search conditions

Search conditions can be combined using the AND and OR logical operators to make compound search conditions. Each individual piece of the search condition is sometimes called a predicate.

toggle List all employees born before March 13, 1964, except the employee named Whitney

  • In Interactive SQL, type the following in the SQL Statements pane:

    SELECT emp_lname, birth_date
FROM employee
WHERE birth_date < '1964-3-13'
AND emp_lname <> 'whitney'
    emp_lname | birth_date
    Cobb | 12/4/1960
    Jordan | 12/13/1951
    Breault | 5/13/1947
    Espinoza | 12/14/1939
    Dill | 7/19/1963
    Francis | 9/12/1954


Shortcuts for compound search conditions

Using the short form BETWEEN

SQL has two short forms for compound search conditions. The first, BETWEEN, is used when you are looking for a range of values. For example the following two queries are equivalent:

SELECT emp_lname, birth_date
FROM employee
WHERE birth_date BETWEEN '1963-1-1' AND '1965-3-31'

and

SELECT emp_lname, birth_date
FROM employee
WHERE birth_date >= '1963-1-1'
AND birth_date <= '1965-3-31'
Using the short form IN

The second short form, IN, may be used when looking for one of a number of values. The following two statements are equivalent:

SELECT emp_lname, emp_id
FROM employee
WHERE emp_lname IN ('yeung','bucceri','charlton')

and

SELECT emp_lname, emp_id
FROM employee
WHERE emp_lname = 'yeung'
OR emp_lname = 'bucceri'
OR emp_lname = 'charlton'


Selecting Data from Multiple Tables

About this chapter

This chapter describes database queries that look at information in more than one table. To do this, SQL provides the JOIN operator. There are several different ways to join tables together in queries, and this chapter describes some of the more important ones.

Introduction
Joining tables using the cross product
Using the ON phrase to restrict a join
Joining tables using key joins
Joining tables using natural joins
Joining tables using outer joins


Introduction

Sometimes it is necessary to view data from multiple related tables. This chapter explains how to use a join to view the data in a useful and meaningful way.

Displaying a list of tables


Displaying a list of tables

In Interactive SQL, you can display a list of tables by pressing the F7 key.

The Interactive SQL Lookup Table Name dialog.

Select a table and click Show Columns to see the columns for that table. The Escape key takes you back to the table list, and pressing it again will take you back to the SQL Statements pane. Pressing Enter instead of Escape copies the selected table or column name into the SQL Statements pane at the current cursor position.

Press Escape to leave the list.

For a diagram of the tables in the sample database, see About the sample database.


Joining tables using the cross product

One of the tables in the sample database is sales_order, which lists the orders placed to the company. Each order has a sales_rep column, containing the employee ID of the sales representative responsible for the order. There are 648 rows in the sales_order table and 75 rows in the employee table.

The cross product join is a simple starting point for understanding joins, but not very useful in itself.

toggle List all data in the employee and sales_order tables

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT *
FROM sales_order CROSS JOIN employee

    The results of this query, which appear on the Results tab in the Interactive SQL Results pane, match every row in the employee table with every row in the sales_order table. Since there are 75 rows in the employee table and 648 rows in the sales_order table, there are 75 × 648 = 48,600 rows in the result of the join. Each row consists of all columns from the sales_order table followed by all columns from the employee table. This join is called a full cross product.

Subsequent sections describe how to construct more selective joins. The more selective joins can be thought of as applying a restriction to the cross product table.

For more information, see Cross joins.


Using the ON phrase to restrict a join

The ON phrase applies a restriction to the rows in a join, in much the same way that the WHERE clause applies restrictions to the rows of a query.

The ON phrase allows more useful joins than the CROSS JOIN to be constructed. For example, you can apply the ON phrase to a join of the sales_order and employee table to retrieve only those rows for which the sales_rep in the sales_order table is the same as the one in the employee table in every row of the result. Then each row contains information about an order and the sales representative responsible for it.

toggle List all sales orders with their dates, and the employee responsible for each

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT employee.emp_lname,
       sales_order.id,
       sales_order.order_date
FROM sales_order JOIN employee
   ON sales_order.sales_rep = employee.emp_id
    emp_lname | id | order_date
    Chin | 2008 | 4/2/2001
    Chin | 2020 | 3/4/2001
    Chin | 2032 | 7/5/2001
    Chin | 2044 | 7/15/2000
    Chin | 2056 | 4/15/2001
    ... ... ...
Notes

The table name is given as a prefix to identify the columns. Using the table name prefix clarifies the statement, and is required when two tables have a column with the same name.

The results of this query contain only 648 rows (one for each row in the sales_order table). Of the 48,600 rows in the cross product, only 648 of them have the employee number equal in the two tables.

The ordering of the results has no meaning. You could add an ORDER BY clause to impose a particular order on the query.

The ON clause includes columns that are not included in the final result set.

For more information, see Explicit join conditions (the ON phrase).


Joining tables using key joins

Many common joins are between two tables related by a foreign key. The most common join restricts foreign key values to be equal to primary key values.

The KEY JOIN operator joins two tables based on foreign key relationship. In other words, Adaptive Server Anywhere generates an ON clause that equates the primary key column from one table with the foreign key column of the other.

The example in the previous section restricts foreign key values in the sales_order table to be equal to the primary key values in the employee table.

SELECT employee.emp_lname,
       sales_order.id,
       sales_order.order_date
FROM sales_order JOIN employee
   ON sales_order.sales_rep = employee.emp_id

The query can be more simply expressed using a KEY JOIN:

SELECT employee.emp_lname,
       sales_order.id,
       sales_order.order_date
FROM sales_order KEY JOIN employee

KEY JOIN is just a shortcut for typing the ON clause; the two queries are identical. Key join is the default when you specify JOIN, but do not specify CROSS, NATURAL, KEY, or use an ON clause.

If you look at the diagram of the employee database, lines between tables represent foreign keys. You can use the KEY JOIN operator anywhere two tables are joined by a line in the diagram.

For a diagram of the sample database, see About the sample database.

Joining more than two tables

Two or more tables can be joined using join operators. The following query uses four tables to list the total value of the orders placed by each customer. It connects the four tables customer, sales_order, sales_order_items, and product using the single foreign-key relationships between each pair of these tables.

toggle List companies and the total value of their orders

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT company_name,
       SUM( sales_order_items.quantity *
            product.unit_price) AS value
FROM ( ( customer KEY JOIN sales_order )
   KEY JOIN sales_order_items )
   KEY JOIN product
GROUP BY company_name
    company_name | value
    Bensoul's Boutique | 1332
    Bush Pro Shop | 2940
    Sterling & Co. | 6804
    Ocean Sports | 3744
    ... ...
Notes

Your result set may appear in a different order. There is no significance to the order of the rows in the result set.

The example uses the SUM operator, which is an aggregate function. Aggregate functions work with GROUP BY clauses to return values for each row group. In this example, the sum of sales_order_items.quantity * product.unit_price—that is, the total amount of money paid per product type—is calculated for each company_name, thereby returning each company's sales.

The parentheses in the FROM clause help to clarify the order in which the joins are made.

For more information on complex key joins, see Key joins.


Joining tables using natural joins

The NATURAL JOIN operator joins two tables based on common column names. In other words, Adaptive Server Anywhere generates an ON clause that equates the common columns from each table.

toggle List all employees and their departments

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT emp_lname, dept_name
FROM employee NATURAL JOIN department
    emp_lname | dept_name
    Whitney | R & D
    Cobb | R & D
    Breault | R & D
    Shishov | R & D
    Driscoll | R & D
    ... ...

Adaptive Server Anywhere looks at the two tables and determines that the only column name they have in common is dept_id. The following ON CLAUSE is internally generated and used to perform the join:

FROM employee JOIN department
   ON employee.dept_id = department.dept_id

NATURAL JOIN is just a shortcut for typing the ON clause; the two queries are identical.

Errors using NATURAL JOIN

This join operator can cause problems by equating columns you may not intend to be equated. For example, the following query generates unwanted results:

SELECT *
FROM sales_order NATURAL JOIN customer

The result of this query has no rows. Adaptive Server Anywhere internally generates the following ON clause:

FROM sales_order JOIN customer
   ON sales_order.id = customer.id

The id column in the sales_order table is an ID number for the order. The id column in the customer table is an ID number for the customer. None of them matched. Of course, even if a match were found, it would be a meaningless one.

For more information, see Natural joins.


Joining tables using outer joins

In the previous examples, you created joins that returned rows only if they satisfied the join conditions. These joins are called inner joins, and are the default. Sometimes, you may wish to preserve all the rows in one table. To do this, you use an outer join.

You can specify a right outer join, which preserves all the rows in the right table; a left outer join, which preserves the left table; or a full outer join, which preserves all the rows in both tables.

toggle List all customers, and the dates of any orders they have placed

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT lname, order_date, city
FROM customer KEY LEFT OUTER JOIN sales_order
WHERE customer.state = 'NY'
ORDER BY order_date
    lname | order_date | city
    Thompson | (NULL) | Bancroft
    Reiser | 1993-01-22 | Rockwood
    Clarke | 1993-01-27 | Rockwood
    Mentary | 1993-01-30 | Rockland
    ... ... ...

The statement includes all customers, whether or not they have placed an order. If a particular customer has placed no orders, each column in the result that corresponds to order information contains NULL.

For more information, see Outer joins.


Selecting Data Using Subqueries

About this chapter

This chapter shows how to use the results of one query as part of another SELECT statement. This is a useful tool in building more complex and informative queries.


Introducing subqueries

A relational database allows you to store related data in more than one table. You can extract data from related tables using subqueries—queries that appear in another query's WHERE clause or HAVING clause. Subqueries make some queries easier to write than joins, and there are queries that cannot be written without using subqueries.

Subqueries use the results of one query as part of another query. This section illustrates a situation where subqueries can be used by building a query that lists order items for products that are low in stock.

There are two queries involved in producing this list. This section first describes them separately, and then shows the single query that produces the same result.

toggle List all products for which there are less than 20 items in stock

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT id, description, quantity
FROM product
WHERE quantity < 20
    id | description | quantity
    401 | Wool cap | 12

    The query shows that only wool caps are low in stock.

toggle List all order items for wool caps

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT *
FROM sales_order_items
WHERE prod_id = 401
ORDER BY ship_date DESC
    id | line_id | prod_id | quantity | ship_date
    2082 | 1 | 401 | 48 | 7/9/2001
    2053 | 1 | 401 | 60 | 6/30/2001
    2125 | 2 | 401 | 36 | 6/28/2001
    2027 | 1 | 401 | 12 | 6/17/2001
    ... ... ... ... ...

This two-step process of identifying items low in stock and identifying orders for those items can be combined into a single query using subqueries.

toggle List all order items for items that are low in stock

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT *
FROM sales_order_items
WHERE prod_id IN
   (   SELECT id
       FROM product
       WHERE quantity < 20 )
ORDER BY ship_date DESC
    id | line_id | prod_id | quantity | ship_date
    2082 | 1 | 401 | 48 | 7/9/2001
    2053 | 1 | 401 | 60 | 6/30/2001
    2125 | 2 | 401 | 36 | 6/28/2001
    2027 | 1 | 401 | 12 | 6/17/2001
    ... ... ... ... ...

The subquery in the statement is the phrase enclosed in parentheses:

(   SELECT id
    FROM product
    WHERE quantity < 20 )

The subquery makes a list of all values in the id column in the product table, satisfying the WHERE clause search condition.

The subquery returns a set of rows, but only a single column. The IN keyword treats each value as a member of a set and tests whether each row in the main query is a member of the set.


Single-row and multiple-row subqueries

There are constraints on the number of rows and columns that a subquery may return. If you use IN, ANY, or ALL, the subquery may return several rows, but only one column. If you use other operators, the subquery must return a single value.

A multiple-row subquery

Two tables in the sample database are concerned with financial results. The fin_code table is a small table holding the different codes for financial data and their meanings:

To list the revenue items from the fin_data table, type the following:

SELECT *
FROM fin_data
WHERE fin_data.code IN
    (   SELECT fin_code.code
        FROM fin_code
        WHERE type = 'revenue' )
year | quarter | code | amount
1999 | Q1 | r1 | 1023
1999 | Q2 | r1 | 2033
1999 | Q3 | r1 | 2998
1999 | Q4 | r1 | 3014
2000 | Q1 | r1 | 3114

This example has used qualifiers to clearly identify the table to which the code column in each reference belongs. In this particular example, the qualifiers could have been omitted.

Two other keywords can be used as qualifiers for operators to allow them to work with multiple rows: ANY and ALL.

The following query is identical to the successful query above:

SELECT *
FROM fin_data
WHERE fin_data.code = ANY
   (   SELECT fin_code.code
       FROM fin_code
       WHERE type = 'revenue' )

While the =ANY condition is identical to the IN condition, ANY can also be used with inequalities such as < or > to give more flexible use of subqueries.

The ALL keyword is similar to the word ANY. For example, the following query lists financial data that is not revenues:

SELECT *
FROM fin_data
WHERE fin_data.code <> ALL
   (   SELECT fin_code.code
       FROM fin_code
       WHERE type = 'revenue' )

This is equivalent to the following command using NOT IN:

SELECT *
FROM fin_data
WHERE fin_data.code NOT IN
   (   SELECT fin_code.code
       FROM fin_code
       WHERE type = 'revenue' )
A common error using subqueries

In general, subquery result sets are restricted to a single column. The following example does not make sense because Adaptive Server Anywhere would not know which column from fin_code to compare to the fin_data.code column.

-- this query is incorrect
SELECT *
FROM fin_data
WHERE fin_data.code IN
   (   SELECT fin_code.code, fin_code.type
       FROM fin_code
       WHERE type = 'revenue' )
Single-row subqueries

While subqueries used with an IN condition may return a set of rows, a subquery used with a comparison operator must return only one row. For example the following command results in an error since the subquery returns two rows:

-- this query is incorrect
SELECT *
FROM fin_data
WHERE fin_data.code =
   (   SELECT fin_code.code
       FROM fin_code
       WHERE type = 'revenue' )


Using subqueries instead of joins

Suppose you need a chronological list of orders and the company that placed them, but would like the company name instead of their customer ID. You can get this result using a join as follows:

Using a join

To list the order id, date, and company name for each order since the beginning of 2001, type the following:

SELECT    sales_order.id,
            sales_order.order_date,
            customer.company_name
FROM sales_order
   KEY JOIN customer
WHERE order_date > '2001/01/01'
ORDER BY order_date
id | order_date | company_name
2473 | 1/4/2001 | Peachtree Active Wear
2474 | 1/4/2001 | Sampson & Sons
2106 | 1/5/2001 | Salt & Pepper's
2475 | 1/5/2001 | Cinnamon Rainbow's
2036 | 1/5/2001 | Hermanns
Using a subquery

The following statement obtains the same results using a subquery instead of a join:

SELECT sales_order.id,
   sales_order.order_date,
   (   SELECT company_name FROM customer
       WHERE customer.id = sales_order.cust_id )
FROM sales_order
WHERE order_date > '2001/01/01'
ORDER BY order_date

The subquery refers to the cust_id column in the sales_order table even though the sales_order table is not part of the subquery. Instead, the sales_order.cust_id column refers to the sales_order table in the main body of the statement. This is called an outer reference. Any subquery that contains an outer reference is called a correlated subquery.

A subquery can be used instead of a join whenever only one column is required from the other table. (Recall that subqueries can only return one column.) In this example, you only needed the company_name column so the join could be changed into a subquery.

If the subquery might have no result, this method is called an outer join. The join in previous sections of the tutorial is more fully called an inner join.

Using an outer join

To list all customers in Washington state, together with their most recent order ID, type the following:

SELECT    company_name, state,
   (   SELECT MAX( id )
       FROM sales_order
       WHERE sales_order.cust_id = customer.id )
FROM customer
WHERE state = 'WA'
company_name | state | MAX(sales_order.id)
Custom Designs | WA | 2547
It's a Hit! | WA | (NULL)

The It's a Hit! company placed no orders, and the subquery returns NULL for this customer. Companies who have not placed an order are not listed when inner joins are used.

You could also specify an outer join explicitly. In this case, a GROUP BY clause is also required.

SELECT company_name, state,
   MAX( sales_order.id )
FROM customer
   KEY LEFT OUTER JOIN sales_order
WHERE state = 'WA'
GROUP BY company_name, state


Selecting Aggregate Data

About this chapter

This chapter describes how to construct queries that tell you aggregate information. Examples of aggregate information are as follows:

  • The total of all values in a column.

  • The number of distinct entries in a column.

  • The average value of entries in a column.


Summarizing data

Some queries examine aspects of the data in your table that reflect properties of groups of rows rather than of individual rows. For example, you may wish to find the average amount of money that a customer pays for an order, or to see how many employees work for each department. For these types of tasks, you use aggregate functions and the GROUP BY clause.


A first look at aggregate functions

Aggregate functions return a single value for a set of rows. If there is no GROUP BY clause, an aggregate function returns a single value for all the rows that satisfy other aspects of the query.

toggle List the number of employees in the company

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT COUNT( * )
FROM employee
    COUNT(*)
    75

    The result set consists of only one column, with title COUNT( * ), and one row, which contains the total number of employees.

toggle List the number of employees in the company and the birth dates of the oldest and youngest employee

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT COUNT(*), MIN(birth_date), MAX(birth_date)
FROM employee
    COUNT(*) | MIN(employee.birth_date) | MAX(employee.birth_date)
    75 | ½/1936 | 1/18/1973

The functions COUNT, MIN, and MAX are called aggregate functions, which are functions that summarize information. Other aggregate functions include statistical functions such as AVG, STDDEV, and VARIANCE. All but COUNT have the name of a column as a parameter.

For more information, see Aggregate functions.


Applying aggregate functions to grouped data

In addition to providing information about an entire table, aggregate functions can be used on groups of rows. The GROUP BY clause arranges rows into groups, and aggregate functions return a single value for each group of rows.

Example
toggle List the sales representatives and the number of orders each has taken

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT sales_rep, count( * )
FROM sales_order
GROUP BY sales_rep
ORDER BY sales_rep
    sales_rep | count(*)
    129 | 57
    195 | 50
    299 | 114
    467 | 56
    ... ...

A GROUP BY clause tells Adaptive Server Anywhere to partition the set of all the rows that would otherwise be returned. All rows in each partition, or group, have the same values in the named column or columns. There is only one group for each unique value or set of values. In this case, all the rows in each group have the same sales_rep value.

Aggregate functions such as COUNT are applied to the rows in each group. Thus, this result set displays the total number of rows in each group. The results of the query consist of one row for each sales rep ID number. Each row contains the sales rep ID, and the total number of sales orders for that sales representative.

Whenever GROUP BY is used, the resulting table has one row for each column or set of columns named in the GROUP BY clause.

For more information, see The GROUP BY clause: organizing query results into groups.

A common error with GROUP BY

A common error with GROUP BY is to try to get information that cannot properly be put in a group. For example,

-- This query is incorrect
SELECT sales_rep, emp_lname, COUNT( * )
FROM sales_order KEY JOIN employee
GROUP BY sales_rep

gives the following error:

Function or column reference to 'emp_lname' in the select list must also appear in a GROUP BY

An error is reported because Adaptive Server Anywhere cannot be sure that each of the result rows for an employee with a given ID all have the same last name.

To fix this error, add the column to the GROUP BY clause.

SELECT sales_rep, emp_lname, COUNT( * )
FROM sales_order KEY JOIN employee
GROUP BY sales_rep, emp_lname
ORDER BY sales_rep

If this is not appropriate, you can instead use an aggregate function to select only one value, as shown:

SELECT sales_rep, MAX( emp_lname ), COUNT( * )
FROM sales_order KEY JOIN employee
GROUP BY sales_rep
ORDER BY sales_rep

The MAX function chooses the maximum (last alphabetically) last name from the detail rows for each group. This statement is valid because there can be only one distinct maximum value. In this case, the same last name appears on every detail row within a group.


Restricting groups

You have already seen how to restrict rows in a result set using the WHERE clause. You restrict the rows in groups using the HAVING clause.

toggle List all sales representatives with more than 55 orders

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    SELECT sales_rep, count( * ) AS orders
FROM sales_order KEY JOIN employee
GROUP BY sales_rep
HAVING count( * ) > 55
ORDER BY orders DESC
    sales_rep | orders
    299 | 114
    129 | 57
    1142 | 57
    467 | 56
Order of clauses
A GROUP BY must always appear before a HAVING clause. If both are present, a WHERE clause must appear before a GROUP BY clause.

HAVING clauses and WHERE clauses can both be used in a single query. Conditions in the HAVING clause logically restrict the rows of the result only after the groups have been constructed. Criteria in the WHERE clause are logically evaluated before the groups are constructed, and so save time.

For more information, see The HAVING clause: selecting groups of data.

Combining WHERE and HAVING clauses


Combining WHERE and HAVING clauses

Sometimes you can specify the same set of rows using either a WHERE clause or a HAVING clause. In such cases, one method is not more or less efficient than the other. The optimizer always automatically analyzes each statement you type and selects an efficient means of executing it. It is best to use the syntax that most clearly describes the desired result. In general, that means eliminating undesired rows in earlier clauses.

Example

To list all sales reps with more than 55 orders and an ID of more than 1000, type the following statement.

SELECT sales_rep, count( * )
FROM sales_order KEY JOIN employee
WHERE sales_rep > 1000
GROUP BY sales_rep
HAVING count( * ) > 55
ORDER BY sales_rep

The following statement produces the same results.

SELECT sales_rep, count( * )
FROM sales_order KEY JOIN employee
GROUP BY sales_rep
HAVING count( * ) > 55 AND sales_rep > 1000
ORDER BY sales_rep

Adaptive Server Anywhere detects that both statements describe the same result set, and so executes each efficiently.


Updating the Database

About this chapter

This chapter describes how to make changes to the contents of your database. It includes descriptions of how to add rows, remove rows, and change the contents of rows, as well as how to make changes permanent or correct changes4 you have made.


Introduction

This chapter describes how to make changes to the data in your database. There are three basic operations:

  • Insert You can add rows to tables to include new data.

  • Delete You can delete rows in tables to remove data.

  • Update You can modify existing rows in tables.

Each operation is carried out by executing a SQL statement.


Adding rows to a table

Suppose that the company decides to sell a new product, a brown acrylic vest. This action requires you to add data to the product table of the sample database.

toggle Add a brown acrylic vest to the product table

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    INSERT
INTO product ( id, name, description, size, color,
               quantity, unit_price )
VALUES ( 800, 'Vest', 'Acrylic Vest', 'Extra Large',
         'Brown', 42, 20.00 )

    If you make a mistake and forget to specify one of the columns, Adaptive Server Anywhere reports an error.

You can also add new rows to database tables from the result set in Interactive SQL.

For more information, see Editing table values in Interactive SQL.

NULL values in columns

The NULL value is a special value used to indicate that something is either not known or not applicable. Some columns are allowed to contain the NULL value, and others are not.


Modifying rows in a table

In most databases, you need to update records that are already stored in the database. For example, the manager ID should change when employees are transferred between departments, as well as the department ID.

toggle Transfer employee #195 to department 400 in Interactive SQL

  • In Interactive SQL, type the following in the SQL Statements pane and press F5 to execute the statement.

    UPDATE employee
SET dept_id = 400, manager_id = 1576
WHERE emp_id = 195

    The statement carries out both updates at the same time for employee Marc Dill (employee ID 195).

Since Adaptive Server Anywhere updates all rows that satisfy the conditions of the WHERE clause, sometimes more than one row is updated at one time. For example, if a group of sales employees are transferred into marketing and have their dept_id column updated, the following statement sets the manager_id for all employees in the marketing department to 1576.

UPDATE employee
SET manager_id = 1576
WHERE dept_id = 400

For employees already in the marketing department, no change is made.

You can also modify rows from the result set in Interactive SQL.

For more information, see Editing table values in Interactive SQL.


Deleting rows

Sometimes you will want to remove rows from a table. Suppose Rodrigo Guevara (employee ID 249) leaves the company. The following statement deletes Rodrigo Guevara from the employee table.

DELETE
FROM employee
WHERE emp_id = 249

With UPDATE and DELETE, the search condition can be as complicated as you need. For example, if the employee table is being reorganized, the following statement removes from the employee table all male employees hired between March 3, 1988 and March 3, 1989.

DELETE
FROM employee
WHERE sex = 'm'
    AND start_date BETWEEN '1988-03-03'
    AND '1989-03-03'

You can also delete rows from database tables from the Interactive SQL result set.

For more information, see Editing table values in Interactive SQL.

Since you have made changes to the database that you do not want to keep, you should undo the changes as follows:

ROLLBACK


Grouping changes into transactions

Adaptive Server Anywhere expects you to group your commands into transactions. You commit a transaction to make changes to your database permanent. When you alter your data, your alterations are not made permanent right away. Instead, they are stored in your transaction log and are made permanent when you enter the COMMIT command.

Knowing which commands or actions signify the start or end of a transaction lets you take full advantage of transactions.

Starting transactions

Transactions start with one of the following events:

  • The first statement following a connection to a database.

  • The first statement following the end of a transaction.

Completing transactions

Transactions complete with one of the following events:

  • A COMMIT statement makes the changes to the database permanent.

  • A ROLLBACK statement undoes all the changes made by the transaction.

  • A statement with a side effect of an automatic commit is executed: Database definition commands, such as ALTER, CREATE, COMMENT, and DROP all have the side effect of an automatic commit.

  • A disconnection from a database performs an implicit rollback.

Options in Interactive SQL

Interactive SQL provides you with two options which let you control when and how transactions end:

  • If you set the option AUTO_COMMIT to ON, Interactive SQL automatically commits your results following every successful statement and automatically performs a ROLLBACK after each failed statement.

  • The setting of the option COMMIT_ON_EXIT controls what happens to uncommitted changes when you exit Interactive SQL. If this option is set to ON (the default), Interactive SQL does a COMMIT; otherwise it undoes your uncommitted changes with a ROLLBACK statement.

If you are using a data source
By default, ODBC operates in autocommit mode. Even if you have set the AUTO_COMMIT option to OFF in Interactive SQL, ODBC's setting will override Interactive SQL's. You can change ODBC's setting using the SQL_ATTR_AUTOCOMMIT connection attribute. ODBC autocommit is independent of the CHAINED option.

Adaptive Server Anywhere also supports Transact-SQL commands, such as BEGIN TRANSACTION, for compatibility with Sybase Adaptive Server Enterprise.

For further information, see An overview of Transact-SQL support.


Making changes permanent

The COMMIT statement makes all changes permanent.

You should use the COMMIT statement after groups of statements that make sense together. For example, if you want to transfer money from one customer's account to another, you should add money to one customer's account, then delete it from the other's, and then commit, since in this case it does not make sense to leave your database with less or more money than it started with.

You can instruct Adaptive Server Anywhere to commit your changes automatically by setting the AUTO_COMMIT option to ON. This is an Interactive SQL option. When AUTO_COMMIT is set to ON, Adaptive Server Anywhere must update the database after every insert, update, and delete statement you make to it. This can slow down performance considerably. Therefore, it is a good idea to leave the AUTO_COMMIT option set to OFF.

Use COMMIT with care
When trying the examples in this tutorial, be careful not to COMMIT any changes until you are sure that you want to change the database permanently.

For more information about Interactive SQL options, see Interactive SQL options.


Canceling changes

Any uncommitted change you make can be cancelled. SQL allows you to undo all of the changes you made since your last commit with the ROLLBACK statement.

The ROLLBACK statement undoes all changes you have made to the database since the last time you made changes permanent.

For more information on Interactive SQL options, see Interactive SQL options.


Transactions and data recovery

Suppose that a system failure or power outage suddenly takes your database server down. Adaptive Server Anywhere is carefully designed to protect the integrity of your database in such circumstances. It provides you with a number of independent means of restoring your database. For example, it provides you with a log file which you may store on a separate drive so that should the system failure damage one drive, you still have a means of restoring your data. In addition, when you use a log file, Adaptive Server Anywhere does not have to update your database as frequently, which improves your database's performance.

Transaction processing allows the database server to identify states in which your data is in a consistent state. Transaction processing ensures that if, for any reason, a transaction is not successfully completed, then the entire transaction is undone, or rolled back. The database is left entirely unaffected by failed transactions.

Adaptive Server Anywhere's transaction processing ensures that the contents of a transaction are processed securely, even in the event of a system failure in the middle of a transaction.

For a detailed description of data recovery mechanisms, see Backup and Data Recovery.


Web Links Browse Collapse Expand PDF Previous Next

Introducing SQL Anywhere Studio

Updating the Database

Integrity checking

Adaptive Server Anywhere automatically checks for some common errors in your data.


Inserting duplicate data

For example, suppose you attempt to create a department, but supply a dept_id value that is already in use:

To do this, enter the command:

INSERT
INTO department ( dept_id, dept_name, dept_head_id )
VALUES ( 200, 'Eastern Sales', 902 )

The INSERT is rejected as it would make the primary key for the table not unique. Since dept_id field is a primary key, duplicate values are not permitted.


Inserting values that violate relationships

The following statement inserts a new row in the sales_order table, but incorrectly supplies a sales_rep ID that does not exist in the employee table.

INSERT
INTO sales_order ( id, cust_id, order_date,
 sales_rep)
VALUES ( 2700, 186, '1995-10-19', 284 )

There is a one-to-many relationship between the employee table and the sales_order table, with a join between the sales_rep field of the sales_order table and the emp_id field of the employee table. Only after a record in the table containing the primary key for the join (the employee table) has been entered can a corresponding record on table containing the foreign key (the sales_order table) be inserted.

Foreign keys

The primary key for the employee table is the employee ID number. The sales rep ID number in the sales_rep table is a foreign key for the employee table, meaning that each sales rep number in the sales_order table must match the employee ID number for some employee in the employee table.

When you try to add an order for sales rep 284 you get an error message:

No primary key value for foreign key 'ky_so_employee_id' in table 'sales_order'

There isn't an employee in the employee table with that ID number. This prevents you from inserting orders without a valid sales rep ID. This kind of validity checking is called referential integrity checking as it maintains the integrity of references among the tables in the database.

For more information on primary and foreign keys, see Relations between tables.


Errors on DELETE or UPDATE

Foreign key errors can also arise when doing update or delete operations. For example, suppose you try to remove the R&D department from the department table. The dept_id field, being the primary key of the department table, constitutes the ONE side of a one-to-many relationship (the dept_id field of the employee table is the corresponding foreign key, and hence forms the MANY side). A record on the ONE side of a relationship may not be deleted until all corresponding records on the MANY side are deleted.

DELETE
FROM department
WHERE dept_id = 100
Example: DELETE errors

An error is reported indicating that there are other records in the database that reference the R&D department, and the delete operation is not carried out.

primary key for row in table 'department' is referenced in another table

In order to remove the R&D department, you need to first get rid of all employees in that department:

DELETE
FROM employee
WHERE dept_id = 100

You can now perform the deletion of the R&D department.

You should cancel these changes to the database (for future use) by entering a ROLLBACK statement:

ROLLBACK WORK

All changes made since the last successful COMMIT WORK are undone. If you have not done a COMMIT, then all changes since you started Interactive SQL are undone.

Example: UPDATE errors

Now, suppose you try to change the dept_id field from the employee table. The dept_id field, being the foreign key of the employee table, constitutes the MANY side of a one-to-many relationship (the dept_id field of the department table is the corresponding primary key, and hence forms the ONE side). A record on the MANY side of a relationship may not be changed unless it corresponds to a record on the ONE side. That is, unless it has a primary key to reference.

For example, the following UPDATE statement causes an integrity error:

UPDATE employee
SET dept_id = 600
WHERE dept_id = 100

The error no primary key value for foreign key 'ky_dept_id' in table 'employee' is raised because there is no department with the a primary key of 600 in the department table.

In order to change the value of the dept_id field in the employee table, it must correspond to an existing value in the department table. For example:

UPDATE employee
SET dept_id = 300
WHERE dept_id = 100

This statement can be executed because the dept_id of 300 corresponds to the existing Finance department.

Cancel these changes to the database by entering a ROLLBACK statement:

ROLLBACK WORK
Checking the integrity after the COMMIT WORK is complete

In all of the above examples, the integrity of the database was checked as each command was executed. Any operation that would result in an inconsistent database is not performed.

It is possible to configure the database so that the integrity is not checked until the COMMIT WORK is done. This is important if you want to change the value of a referenced primary key; for example, deleting the R&D department in the employee and department tables. In order to make these deletions, the database has to be inconsistent in between the changes. In this case, you must configure the database to check only on commits.

For more information, see WAIT_FOR_COMMIT option [database].

You can also define foreign keys in such a way that they are automatically modified to be consistent with changes made to the primary key. In the above example, if the foreign key from employee to department were defined with ON DELETE CASCADE, then deleting the department ID would automatically delete the corresponding entries in the employee table.

In the above cases, there is no way to have an inconsistent database committed as permanent. Adaptive Server Anywhere also supports alternative actions if changes would render the database inconsistent.

For more information, see the chapter Ensuring Data Integrity.


The Sample Database

About this chapter

This chapter provides basic information about the database servers and the sample database. It shows you how to make a copy of the sample database, how to start the database server running the sample database, how to view the database server window, and how to shut down the server.

About the sample database
Lesson 1: Make a copy of the sample database
Lesson 2: Start the Adaptive Server Anywhere database server
Lesson 3: Displaying the database server window
Lesson 4: Shut down the database server
Summary


Web Links Browse Collapse Expand PDF Previous Next

Introducing SQL Anywhere Studio

The Sample Database

About the sample database

The Adaptive Server Anywhere database server is the piece of software that manages the database. The database server allows access to databases from client applications, and processes commands in a secure and efficient manner. Only one database server at a time can manage any one database.

All access to your database must be made through a database server.

Two kinds of database server

There are two versions of the Adaptive Server Anywhere database server. The personal server can only accept connections from applications or users running on the same machine. It is intended for single-user, same-machine use.

By contrast, the network server supports client/server communication over a network and is intended for multi-user operation.

The two database servers are exactly the same in their query processing and other internal operations: both the personal database server and the network database server are equivalent.

The sample database

This tutorial focuses on the sample database. The sample database represents a small company that makes a limited range of sports clothing. It contains internal information about the company (employees, departments, and financial data), as well as product information (products) and sales information (sales orders, customers, and contacts). All information in the sample database is fictional.

The following figure displays the tables in the sample database and how they are related to each other. The boxes represent tables, and the arrows represent foreign key relationships. Primary key columns are underlined.

The Adaptive Server Anywhere sample database, including tables, column names, primary keys, and foreign key relationships.


Lesson 1: Make a copy of the sample database

Before you begin, make a copy of the sample database so that you can restore it after you have made changes.

toggle To copy the sample database

  1. Navigate to the directory that contains the sample database file, asademo.db.

    The default installation directory for it is Program Files\Sybase\Adaptive Server Anywhere 9.

  2. Create a sub-directory to hold a copy of asademo.db.

    For example, call it demoback.

  3. Create a copy of asademo.db in the backup directory.

    Work with the original version. Do not change the backup copy.


Lesson 2: Start the Adaptive Server Anywhere database server

In this section you start the Adaptive Server Anywhere database server running the sample database. The sample database is held in a file named asademo.db in your SQL Anywhere installation directory.

Depending on the operating system you are using, you may have a choice of how to start the database server running the sample database.

toggle To start the personal database server running the sample database (Windows)

  • From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > Personal Server Sample.

    This starts a personal server running the sample database. The database server window appears briefly, then quickly disappears. The server then appears as an icon in the system tray, at the opposite end of the Taskbar from the Start button.

toggle To start the database server running the sample database (Command prompt)

  1. Open a command prompt.

  2. Change to the SQL Anywhere installation directory.

    On Windows operating systems, the default installation directory is C:\Program Files\Sybase\SQL Anywhere 9.

  3. Start the database server running the sample database.

    The way you start the database server depends on your operating system, and on whether you wish to connect to the database from other machines on the network.

    • If you wish to connect only from the same machine on Windows or UNIX operating systems, enter the following command to start the personal database server:

      dbeng9 -n asademo9 asademo.db

    • If you wish to connect to the database server from other machines on the network on Windows or UNIX operating systems, enter the following command to start the network database server:

      dbsrv9 -n asademo9 asademo.db

    • On NetWare, only the network database server is provided. Enter the following command:

      load dbsrv9.nlm -n asademo9 asademo.db

    The server appears as an icon in the system tray, at the opposite end of the Taskbar from the Start button.


Lesson 3: Displaying the database server window

At this point, you have successfully started the database server running the sample database. However, you can't see or manipulate the data in the database yet.

In fact, the Adaptive Server Anywhere icon is the only visible indication that anything has happened. You can display the database server window now (or at any time for that matter) in Windows by double-clicking the Adaptive Server Anywhere icon in the system tray.

The Adaptive Server Anywhere database server window.

The server window displays useful information, including the following:

  • The server name The name in the title bar (in this case asademo9) is the server name. A server name is assigned each time a database server is started. This name can be used by applications when they connect to a database.

  • The version and build numbers The numbers following the server name (in this case 9.0.2.2434) are the version and build numbers. The version number represents the specific release of the SQL Anywhere Studio, and the build number relates to the specific instance that the software was compiled.

  • Startup information When a database server starts, it sets aside some memory that it uses when processing database requests. This is called the cache. The amount of cache memory appears in the window. The cache is organized in fixed-size pages, and the page size also appears in the window.

  • Database information The names of the database file and its transaction log file appear in the window.

In this case, the startup cache size and page size are the default values. For many purposes, including those of this tutorial, the default startup options are fine.


Lesson 4: Shut down the database server

You can now shut down the database server you just started.

toggle Shut down the database server running the sample database (Windows)

  1. Double-click the Adaptive Server Anywhere icon in the Windows task bar.

    The database server window appears.

  2. Click Shutdown.


Summary

In this tutorial, you learned how to make a copy of the sample database, how to start the database server running the sample database, and how to view the contents of the database server window. You also learned how to shut the database server down.


Making the Connection

About this chapter

This chapter shows you how to create an ODBC data source, and how to use it to establish a connection between a database and an application. In this case, the application is Sybase Central.

About connections
About ODBC data sources
Lesson 1: Create an ODBC data source
Lesson 2: Connect using the Sample ODBC data source
Lesson 3: Other means of connecting
Lesson 4: Disconnecting from the sample database
Summary


About connections

Any client application that uses a database must establish a connection to that database before any work can be done. The connection forms a channel through which all activity from the client application takes place. For example, your user ID determines permissions to carry out actions on the database—and the database server has your user ID because it is part of the request to establish a connection.


About ODBC data sources

The Open Database Connectivity (ODBC) interface is defined by Microsoft Corporation, and is a standard interface for connecting client applications to database-management systems in Windows environments. Connections are made by specifying connection parameters. It is often convenient to collect a set of connection parameters together and store them in an ODBC data source. ODBC data sources are a convenient way of saving connection parameters for repeated use.

Once you have a data source, your connection string can simply name the data source to use:

DSN=my data source

You can use ODBC data sources to connect to Adaptive Server Anywhere databases from any of the following applications:

  • Sybase Central and Interactive SQL.

  • All the Adaptive Server Anywhere utilities.

  • PowerDesigner and InfoMaker.

  • Any application development environment that supports ODBC, such as Microsoft Visual Basic, Sybase PowerBuilder, and Borland Delphi.

  • Adaptive Server Anywhere client applications on UNIX. On UNIX, the data source is stored as a file.


Lesson 1: Create an ODBC data source

This section describes how to create a simple ODBC data source in Windows.

toggle To create a simple ODBC data source

  1. Start the ODBC Administrator:

    • From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > ODBC Administrator.

    The ODBC Data Source Administrator appears, displaying a list of the data sources you currently have installed on your computer.

    The ODBC Administrator main window.

  2. On the User DSN tab, click Add.

    The Create New Data Source wizard appears.

  3. Select Adaptive Server Anywhere 9.0 from the list of drivers, and click Finish.

    The Configuration dialog appears.

    The ODBC Configuration for Adaptive Server Anywhere dialog where you can specify connection parameters for an ODBC data source.

    Many of the fields in this dialog are optional. Click the Help button at the bottom of each tab for a description of all the fields on that tab. For many purposes you only need to use a few parameters. The following data source parameters are sufficient for the Adaptive Server Anywhere sample database:

    • Data Source Name (ODBC tab) Enter a data source name of Sample. This is the name that appears in the Connect dialog. It can contain spaces, but should be short.

    • User ID (Login tab) Enter the default user ID DBA. This is the database user ID you will use to connect.

    • Password (Login tab) Enter SQL. This is the default password for the DBA user ID.

    • Database File (Database tab) Browse to your SQL Anywhere installation directory, and select the asademo.db file. This is the Adaptive Server Anywhere sample database.

  4. Test the data source.

    On the ODBC tab, click Test Connection.

    If the datasource was created properly, the message Connection Successful appears.

    If the message Connection Failed appears, review the data source settings and make corrections where necessary.

  5. Click OK to create the data source.


Lesson 2: Connect using the Sample ODBC data source

For this example, you will connect to the sample database from Sybase Central, Adaptive Server Anywhere's graphical tool for managing databases.

toggle To connect to the sample database from Sybase Central

  1. From the Start menu, choose Programs > SQL Anywhere 9 > Sybase Central to start Sybase Central.

  2. From the Tools menu, choose Connect to open the Connect dialog.

    If a dialog prompts you to choose a plug-in, choose Adaptive Server Anywhere 9 and click OK.

    The Connect dialog opens.

  3. Select the ODBC Data Source Name option.

  4. In the ODBC Data Source Name box, type Sample, and click OK.

    Alternatively, you could also click Browse and choose the ASA 9.0 Sample from the Data Source Names dialog.

  5. Click OK to connect to the sample database.

    The dialogs disappear, and the database opens in the Sybase Central window.


Lesson 3: Other means of connecting

You can use ODBC data sources to connect to Adaptive Server Anywhere—not only from ODBC applications, but also from embedded SQL applications, such as the administration utilities, and from Interactive SQL and Sybase Central—even though these applications do not use ODBC. The functionality to process ODBC data sources is built into the embedded SQL client library, and into Sybase Central and Interactive SQL.

Adaptive Server Anywhere supports several programming interfaces in addition to ODBC. For more information, see Introduction to connections.

The Connect dialog in Sybase Central and Interactive SQL has fields for entering an ODBC Data Source Name or ODBC Data Source File.


Lesson 4: Disconnecting from the sample database

To complete this tutorial, shut down the database server and close Sybase Central.

toggle To shut down the database server

  • From the Tools menu, choose Disconnect.

    The database server disconnects from the sample database and shuts down.

toggle To close Sybase Central

  • From the File menu, choose Exit.

    Sybase Central shuts down.


Summary

In this tutorial, you learned how to create an ODBC data source, and how to use it to establish a connection between a database and Sybase Central.


Using Interactive SQL

About this chapter

This chapter discusses how to start and use Interactive SQL. Interactive SQL is a utility shipped with Adaptive Server Anywhere that lets you execute SQL statements, build scripts, and display database data.

About Interactive SQL
Lesson 1: Start Interactive SQL
Lesson 2: The Interactive SQL interface
Lesson 3: Displaying data using Interactive SQL
Lesson 4: Working with SQL statements
Summary


About Interactive SQL

You can use Interactive SQL for the following purposes:

  • sending SQL statements to the database server

  • browsing the information in a database

  • trying out SQL statements that you plan to include in an application

  • loading data into a database

  • carrying out administrative tasks

In addition, Interactive SQL can run command files or script files. For example, you can build repeatable scripts to run against a database and then use Interactive SQL to execute those scripts in a batch fashion.


Lesson 1: Start Interactive SQL

In this section you start the Interactive SQL utility, connect to the sample database, and enter a command.

toggle To start Interactive SQL and connect to the sample database (Windows)

  1. From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > Interactive SQL.

    The Connect dialog appears.

  2. Select the ODBC Data Source Name option.

  3. Click Browse, and select ASA 9.0 Sample from the list.

  4. Click OK.

  5. Click OK to connect to the sample database.

toggle To start Interactive SQL and connect to the sample database (Command prompt)

  1. If you are using a Windows or UNIX operating system, enter the following command to start the personal database server:

    dbeng9 -n asademo9

  2. Type the following command at a command prompt to start Interactive SQL and connect to the sample database:

    dbisql -c "DSN=ASA 9.0 Sample"


Lesson 2: The Interactive SQL interface

In this section, you learn about the components of the Interactive SQL main window, Interactive SQL keyboard shortcuts, and tools that are available in Interactive SQL.

Interactive SQL main window description
Using the Interactive SQL toolbar
Opening multiple windows
Interactive SQL keyboard shortcuts
Learning more about Interactive SQL


Interactive SQL main window description

After connecting to the database, the Interactive SQL window appears.

The Interactive SQL main window.

The title bar at the top of the window displays connection information, as follows:

database-name ( userid ) on server-name

For example, if you connect to the sample database using the ASA 9.0 Sample ODBC data source, the title bar is as follows:

asademo ( dba ) on asademo9
The Interactive SQL panes

Interactive SQL has the following panes:

  • SQL Statements This pane provides a place for you to type SQL statements to access and modify your data.

  • Results This tab displays the results of commands that you execute. For example, if you use SQL statements to search for specific data in the database, the Results tab displays the columns and rows that match the search criteria in the pane above. If the information exceeds the size of the pane, scroll bars automatically appear. You can edit the result set on the Results tab.

    For more information about editing the result set, see Editing table values in Interactive SQL.

  • Messages This tab displays messages from the database server about the SQL statements that you execute in Interactive SQL.

  • Plan This tab, as well as the UltraLite Plan tab, displays the query optimizer's execution plan for a SQL statement.

You can set options for the tabs and panes in the main Interactive SQL window from the Options dialog found in the Tools menu.


Using the Interactive SQL toolbar

The Interactive SQL toolbar appears at the top of the Interactive SQL window. It provides you with buttons for executing common commands. With the buttons on this toolbar, you can:

  • Recall the executed SQL statement immediately before your current position in the history list.

  • View a list of up to 50 previously executed SQL statements.

  • Recall the executed SQL statement immediately after your current position in the history list.

  • Execute the SQL statement currently appearing in the SQL Statements pane.

  • Interrupt the execution of the current SQL statement.

As an easy reminder of what these buttons do, you can hold your cursor over each button to see a popup description.


Opening multiple windows

You can open multiple Interactive SQL windows. Each window corresponds to a separate database connection. You can connect simultaneously to two (or more) different databases on different servers, or you can open concurrent connections to a single database.

toggle To open a new Interactive SQL window

  1. From the Window menu, choose New Window.

    The Connect dialog appears.

    Tip
    If the SQLCONNECT environment variable is set, or if you are already connected to a database, the server attempts to use this information to connect to a database before it prompts you for information in. If these attempts fail, or if you are not already connected to a database, the Connect dialog appears.

  2. In the Connect dialog, enter connection options, and click OK to connect.

    The connection information (including the database name, your user ID, and the database server name) appears on the title bar above the SQL Statements pane.

You can also connect to or disconnect from a database with the Connect and Disconnect commands in the SQL menu, or by executing a CONNECT or DISCONNECT statement.


Interactive SQL keyboard shortcuts

Interactive SQL provides the following keyboard shortcuts:

Function key | Description
Alt+F4 | Exits Interactive SQL.
Alt+Left cursor | Displays the previous SQL statement in the history list.
Alt+Right cursor | Displays the next SQL statement in the history list.
Ctrl+Break | Interrupts the SQL statement that is being executed.
Ctrl+C | Copies the selected row(s) and column headings to the clipboard in the Results pane. In the SQL Statements pane, copies the selected text to the clipboard.
Ctrl+End | Moves to the bottom of the current pane.
Ctrl+H | Displays the history of your executed SQL.
Ctrl+Home | Moves to the top of the current pane.
Ctrl+N | Clears the contents of the Interactive SQL window.
Ctrl+P | Prints the contents of the SQL Statements pane. You can configure the appearance of the printed text in the Interactive SQL Options dialog. For information about setting print options, see Print tab.
Ctrl+Q | Displays the Query Editor. The Query Editor helps you build SQL queries. When you have finished building your query, click OK to export it back into the SQL Statements pane.
Ctrl+S | Saves the contents of the SQL Statements pane.
Esc | Clears the SQL Statements pane.
F1 | Opens Help.
F2 | Edits the selected value in the result set. You can tab from column to column within the row.
F5 | Executes all text in the SQL Statements pane. You can also perform this operation by clicking the Execute SQL Statement button on the toolbar.
F7 | Displays the Lookup Table Name dialog. In this dialog, you can find and select a table and then press Enter to insert the table name into the SQL Statements pane at the cursor position. Or, with a table selected in the list, press F7 again to display the columns in that table. You can then select a column and press Enter to insert the column name into the SQL Statements pane at the cursor position.
F8 | Displays the Lookup Procedure Name dialog. In this dialog, you can find and select a procedure and then press Enter to insert the procedure name into the SQL Statements pane at the cursor position.
F9 | Executes the text that is selected in the SQL Statements pane. If no text is selected, all of the statements are executed.
Pgdn | Moves a page down in the current pane.
Pgup | Moves a page up in the current pane.
Shift+F5 | Displays the plan for the statement in the SQL Statements pane without executing the statement.
Shift+F10 | Displays the context menu for the area that has focus. This keyboard shortcut is an alternative to right-clicking on an area.

The following keyboard shortcuts are available when the SQL Statements pane has the focus:

Function key | Description
Ctrl+] | Moves the cursor to the matching brace. Brace matching matches parentheses, braces, brackets, and angle brackets.
Ctrl+Backspace | Deletes the word to the left of the cursor.
Ctrl+Del | Deletes the word to the right of the cursor.
Ctrl+G | Opens the Go To dialog where you can specify the line you want to go to.
Ctrl+L | Deletes the current line from the SQL Statements pane and puts the line onto the clipboard.
Ctrl+Shift+] | Extends the selection to the matching brace. Brace matching matches parentheses, braces, brackets, and angle brackets.
Ctrl+Shift+L | Deletes the current line.
Ctrl+Shift+U | Changes the selection to upper case characters.
Ctrl+U | Changes the selection to lower case characters.
F3 | Finds the next occurrence of the selected text.
Home | Moves the cursor to the start of the current line or to the first word on the current line.
Shift+F3 | Finds the previous occurrence of the selected text.
Shift+Home | Extends the selection to the start of the text on the current line.


Learning more about Interactive SQL

Interactive SQL provides a set of windows that let you configure its appearance and behavior.

For more information, see Interactive SQL Help.

From Interactive SQL you can gain access to an Index Consultant, also available from Sybase Central, that helps you improve query performance.

For more information, see Index Consultant overview.

From Interactive SQL you can also gain access to a Query Editor, which helps you to design, analyze, and test all kinds of queries.

For more information, see Query Editor Help.


Lesson 3: Displaying data using Interactive SQL

One of the principal uses of Interactive SQL is to browse table data. This section shows how to query the information in the sample database. Queries take the form of SQL statements.

You can display database information in Interactive SQL using the SELECT statement. The following example shows the command to type in the SQL Statements pane. Once you have typed the command, you must click the Execute SQL Statement button on the toolbar to carry out the command.

After you execute the statement, the data (called a result set) appears on the Results tab in the Results pane. You can use the scroll bars to see areas of the table that are outside your current view of the pane. By default, row numbers appear to the left of the result set.

toggle To list all the columns and rows of the employee table

  1. Connect to the sample database if you are not already connected.

    For instructions on connecting to the sample database, see Lesson 1: Start Interactive SQL.

  2. In the SQL Statements pane, type the following SQL query.

    SELECT * FROM employee

  3. Press F5 to execute the statement.

    The query displays all the columns of the table named employee. This table contains information about the employees of a fictitious merchandising company. The following appears:

    A result set displayed in Interactive SQL.

Interactive SQL retrieves the information by sending a request to your database server. The database server, in turn, looks up the information in the employee table and returns it to Interactive SQL.

At this point, you may want to look at the data in some of the other tables in the sample database, such as product, department, or sales_order.

You can add, delete, and update rows within the result set.

For more information about editing the result set, see Editing table values in Interactive SQL.


Editing table values in Interactive SQL

Once you execute a query in Interactive SQL, you can edit the result set to modify the database. You can also select rows from the result set and copy them for use in other applications. Interactive SQL supports editing, inserting, and deleting rows. These actions have the same effect as executing UPDATE, INSERT, and DELETE statements.

To edit a row or value in the result set, you must have the proper permissions on the table or column you want to modify values from. For example, if you want to delete a row, then you must have DELETE permission for the table the row belongs to.

You cannot edit a result set if:

  • you select columns from a table with a primary key, but do not select all of the primary key columns.

  • you attempt to edit the result set of a JOIN (for example, if there is data from more than one table in the result set).

Editing the result set may fail if:

  • you attempt to edit a row or column you do not have permission on.

  • you enter an invalid value (for example, a string in a numeric column or a NULL in a column that does not allow NULLs).

When editing fails, an Interactive SQL error message appears explaining the error, and the database table values remain unchanged.

Once you make changes to table values, you must execute a COMMIT statement to make the changes permanent. If you want to undo your changes, you must execute a ROLLBACK statement.

For more information, see COMMIT statement and ROLLBACK statement.

Editing table values from the Interactive SQL result set
Inserting rows into the database from the Interactive SQL result set
Deleting rows from the database using Interactive SQL


Editing table values from the Interactive SQL result set

From Interactive SQL you can change any or all of the values within existing rows in database tables. You must have UPDATE permission on the columns being modified. When you edit the result set, you can only make changes to the values in one row at a time.

toggle To edit a row in the result set

  1. Click the value you want to change.

  2. Right-click the value and choose Edit from the popup menu.

    Alternatively, press F2 to edit the result set.

    A blinking cursor appears in the table cell containing the value.

  3. Enter the new value.

    You cannot enter invalid data types into a column. For example, you cannot enter a string in a column that accepts the INT data type.

    When you are done editing values in the row, press Enter to update the database. If you want to change other values in the row, press Tab or Shift+Tab to move to the other values.

    You can press the Esc key to cancel the change that was made to the selected value.

  4. Execute a COMMIT statement to make your changes to the table permanent.

Editing computed columns

Once you edit values in the result set, the database is updated with the modified values. Computed columns are recalculated based on the modified values whether or not they are part of the result set. If there are computed columns in your result set, and you modify a value in the computed column, the database is updated with the modified value.


Inserting rows into the database from the Interactive SQL result set

Interactive SQL allows you to add new rows to result sets. You tab between columns in the result set to add values to the row. When you add values to the table, characters are stored in the same case as they are entered. You must have INSERT permission on the table to add new rows.

toggle To insert a new row into the result set

  1. Right-click the result set and choose Add from the popup menu.

    Alternatively, press Ctrl+F10 to display the context menu and choose Add.

    A new blank row appears with a blinking cursor in the first value in the row.

    Press Tab to move the cursor from column to column across the row. You can also insert a value by clicking on the value within the selected row.

  2. Enter the new value.

    You cannot enter invalid data types into a column. For example, you cannot enter a string into a column that accepts the INT data type.

  3. Press Tab to move to the next column.

  4. Repeat steps 2 and 3 until all the column values are added.

  5. Press Enter to update the database.

  6. Execute a COMMIT statement to make your changes to the table permanent.

Inserting values into computed columns

If the result set contains a computed column and you do not specify a value for the computed column, the value is calculated when the database is updated. However, if you specify a value for the computed column, the database is updated with the specified value, and a value is not calculated for the computed column.

Inserting new rows using the INPUT statement

An alternative to inserting new rows from the result set in Interactive SQL is to add rows using the INPUT statement with the PROMPT clause. When the PROMPT clause is specified, Interactive SQL prompts you for the value for each column in the table. For example, to add a new row to the product table and be prompted for the values for each column, you would execute the following statement in Interactive SQL:

INPUT INTO product
PROMPT


Deleting rows from the database using Interactive SQL

You can also delete rows from a database table in Interactive SQL. You must have DELETE permission on the table to delete rows. You can select only consecutive rows in the result set.

toggle To delete a row from the result set

  1. Select the row(s) you want to delete. To select a row(s):

    • Press and hold the Shift key while clicking the row(s)

    • Press and hold the Shift key while using the Up or Down arrow

    If you want to delete non-consecutive rows, you must delete each row individually.

  2. Right-click the result set and choose Delete from the popup menu. You can also delete the selected row(s) by pressing the Delete key.

    The selected row(s) are removed from the database table.

  3. Execute a COMMIT statement to make your changes to the table permanent.


Copying rows from the Interactive SQL result set

You can copy rows directly from the result set in Interactive SQL and then paste them into other applications. Copying rows also copies the column headings. Copied data is comma-delimited, which allows other applications, such as Microsoft Excel, to format the copied data correctly. Copied data is in ASCII format, and all of the strings are enclosed in single quotes. You can select only consecutive rows in the result set.

toggle To copy rows from the Interactive SQL result set

  1. Select the row(s) you want to copy. To select a row(s):

    • Press and hold the Shift key while clicking the row(s)

    • Press and hold the Shift key while using the Up or Down arrow

  2. Right-click the result set and choose Copy from the popup menu. You can also copy the selected row(s) by pressing Ctrl+C.

    The selected row(s), including their column headings, are copied to the clipboard. You can paste them into other applications.

Copying individual values from the result set

You can copy a single value from the result set by selecting a value, right-clicking the result set and choosing Copy Cell from the popup menu. When you do this, no column headings are copied—only the data is copied.


Lesson 4: Working with SQL statements

The following sections describe some of the commands you can use in Interactive SQL. This section describes general tasks for working with commands in Interactive SQL.

All SQL statements can be entered as commands in the top pane of the Interactive SQL window. When you are finished typing, you need to execute the statement to view its results.

You can enter any SQL statement against the database from within Interactive SQL. For a complete list of SQL statements, see SQL Statements.

toggle To execute a SQL statement

  • Press the Execute SQL Statement button, or choose SQL > Execute, or press F5.

toggle To clear the SQL Statements pane

  • Choose Edit > Clear SQL or press Escape.

Canceling an Interactive SQL command
Executing multiple statements
Looking up tables, columns, and procedures
Printing SQL statements
Recalling commands
Logging commands


Canceling an Interactive SQL command

The Interrupt button on the Interactive SQL toolbar cancels a command.

A Cancel operation stops the current processing and prompts for the next command. If a command file was being processed, or if there is more than one statement in the SQL Statements pane, you are prompted for an action to take (Stop Command File, Continue, or Exit Interactive SQL). These actions can be controlled with the Interactive SQL ON_ERROR option.

For information about the ON_ERROR option, see ON_ERROR option [Interactive SQL].

Reported messages

When an interruption is detected, one of three different messages is reported depending upon when the interruption is detected.

  1. If the interruption is detected when Interactive SQL is processing the request (as opposed to the database server), then the following message appears:

    ISQL command terminated by user

    Interactive SQL stops processing immediately and the current database transaction is left alone.

  2. If the interruption is detected by the database server while processing a data manipulation command (SELECT, INSERT, DELETE, or UPDATE), then the following message appears:

    Statement interrupted by user.

    The effects of the current command are undone, but the rest of the transaction is left intact.

  3. If the interruption is detected while the database server is processing a data definition command (CREATE, DROP, ALTER, and so on), the following message appears:

    Terminated by user -- transaction rolled back

    Since data definition commands all perform a COMMIT automatically before the command starts, the effect of the ROLLBACK is to just cancel the current command.

    This message also occurs when the database server is running in bulk operations mode executing a command that modifies the database (INSERT, UPDATE, or DELETE). In this case, ROLLBACK cancels not only the current command, but everything that has been done since the last COMMIT. In some cases, it may take a considerable amount of time for the database server to perform the automatic ROLLBACK.


Executing multiple statements

The Interactive SQL environment allows multiple statements to be entered at the same time. This can be done by ending each statement with a command delimiter. The command delimiter is a configurable option in Interactive SQL that you can change using the COMMAND_DELIMITER option. By default, it is a semicolon (;).

For more information, see COMMAND_DELIMITER option [Interactive SQL].

toggle To enter multiple statements in SQL Statements pane

  1. Enter the following three commands into the SQL Statements pane.

    UPDATE employee
SET dept_id = 400,
    manager_id = 1576
WHERE emp_id = 467;

UPDATE employee
SET dept_id = 400,
    manager_id = 1576
WHERE emp_id = 195;

SELECT *
FROM employee
WHERE emp_id IN ( 195, 467 );

  2. On the toolbar, click the Execute SQL Statement button. All three statements are executed. After execution, the commands remain in the SQL Statements pane.

  3. Roll back your changes by typing ROLLBACK in the SQL Statements pane and executing the statement.

Using go as an alternative

An alternative to using the semicolon is to enter go on a line by itself, at the beginning of the line.

UPDATE employee
SET dept_id = 400,
    manager_id = 1576
WHERE emp_id = 467
go

UPDATE employee
SET dept_id = 400,
    manager_id = 1576
WHERE emp_id = 195
go

SELECT *
FROM employee
WHERE emp_id IN ( 195, 467 )
go
Tip
You can press F9 to execute only the selected text in the SQL Statements pane.

Previous Next


Looking up tables, columns, and procedures

While you are entering commands in Interactive SQL, you can look up the names of tables, columns, or procedures stored in the current database and insert them at your cursor position.

toggle To look up the names of tables in the database

  1. Choose Tools > Lookup Table Name or press F7.

  2. Find and select the table.

  3. Click OK to insert the table name into the SQL Statements pane at the current cursor position.

toggle To look up column names in the database

  1. Choose Tools > Lookup Table Name or press F7.

  2. Find and select the table containing the column.

  3. Click Show Columns.

  4. Select the column and click OK to insert the column name into the SQL Statements pane at the current cursor position.

toggle To look up the names of procedures in the database

  1. Choose Tools > Lookup Procedure Name or press F8.

  2. Find and select the procedure.

  3. Click OK to insert the procedure name into the SQL Statements pane at the current cursor position.

In the tables and procedures lookup dialogs, you can enter the first few characters of the table or procedure you are looking for. After you type something in the field, the dialog narrows the list to include only those items that start with the text you entered.

You can use the SQL wildcard characters '%' (percent sign) and '_' (underscore) to help narrow your search. '%' matches any string of zero or more characters, while '_' matches any one character.

For example, to list all the tables that contain the word profile, type %profile%.

If you want to search for a percent sign or underscore within a table name, you must prefix the percent sign or underscore with an escape character. The escape character depends on the JDBC driver that you are using. If you are connected via jConnect, the escape character is '\' (backslash) while the escape character for the iAnywhere JDBC driver is '~' (tilde).


Printing SQL statements

You can print the contents of the SQL Statements pane by pressing Ctrl+P or by choosing Print from the File menu. You can add a header or footer and configure other formatting options in the Interactive SQL Options dialog.

For information about configuring print options, see Print tab.

For information about print graphical plans in Interactive SQL, see Graphical plans.


Recalling commands

When you execute a command, Interactive SQL automatically saves it in a history list that persists between Interactive SQL sessions. Interactive SQL maintains a record of up to 50 of the most recent commands.

You can view the entire list of commands in the Command History dialog. To access the Command History dialog, press Ctrl+H, or click the book icon on the toolbar.

The Interactive SQL command history dialog.

The most recent commands appear at the bottom of the list. To recall a command, select it and then click OK. It appears in the SQL Statements pane of Interactive SQL.

You can also recall commands without the Command History dialog. Use the arrows in the toolbar to scroll back and forward through your commands, or press Alt+Right Arrow and Alt+Left Arrow.

Note
If you execute a SQL statement that contains password information (GRANT CONNECT, GRANT REMOTE DBA, CONNECT, or CREATE EXTERNLOGIN), the password information appears in the Command History dialog for the duration of the current Interactive SQL session.

When the command history is viewed in subsequent Interactive SQL sessions, passwords are replaced with ... in any of these statements that contain password information. For example, if you execute the following statement in Interactive SQL:

GRANT CONNECT TO testuser
 IDENTIFIED BY testpassword

the following appears in the Command History dialog in subsequent Interactive SQL sessions:

GRANT CONNECT TO testuser
 IDENTIFIED BY ...

When Interactive SQL saves the command history between sessions, it removes password information from the statements listed above.

Copying commands from the Command History dialog

You can copy a command to the clipboard by selecting it in the Command History dialog and then pressing Ctrl+C or clicking the Copy button when the dialog has the focus. If you want to copy selected commands to the SQL Statements pane, click OK. When you copy multiple commands, they are separated by the command delimiter (a semicolon by default).

Removing commands from the Command History dialog

The contents of the Command History dialog persist between Interactive SQL sessions. You can remove commands from the dialog in one of two ways:

  • Select one or more commands and click the Delete button or press the Delete key to remove the selected command(s) from the dialog. This action cannot be undone.

  • Remove all the commands from the dialog by clicking the Clear History button. This action cannot be undone.

You can also save commands in text files so that you can use them in a subsequent Interactive SQL session.

toggle To save the command history to a file

  1. Open the Command History dialog.

  2. Click the Save button or press Ctrl+S.

  3. In the Save As dialog, specify a location and name for the file.

    The command history file has a .SQL extension.

  4. Click Save when finished.


Logging commands

With the Interactive SQL logging feature, you can record commands as you execute them. Interactive SQL continues to record until you stop the logging process, or until you end the current session. The recorded commands are stored in a log file.

toggle To begin logging Interactive SQL commands

  1. Choose SQL > Start Logging.

  2. In the Save As dialog, specify a location and name for the log file.

  3. Click Save when finished.

toggle To stop logging Interactive SQL commands

  • Choose SQL > Stop Logging.

Tips
You can also start and stop logging by typing in the SQL Statements pane. To start logging, type and execute START LOGGING 'c:\filename.sql', where c:\filename.sql is the path, name, and extension of the log file. You only need to include the single quotation marks if the path contains embedded spaces. To stop logging, type and execute STOP LOGGING.

Once you start logging, all commands that you try to execute are logged, including ones that do not execute properly.


Summary

In this chapter, you learned how to start Interactive SQL, to execute SQL statements and to display database data.


Managing Databases with Sybase Central

About this chapter

This chapter introduces Sybase Central, the Adaptive Server Anywhere graphical database management tool. It provides a brief introduction to using Sybase Central for managing database properties.

You will learn how to start Sybase Central and connect to the sample database, how to view and edit the sample database, edit tables, manage users and groups, work with stored procedures, and back up your database.

Before you begin, be sure to make a copy of the sample database so you can restore it to its original form when you are finished.

For more information about copying the sample database, see Lesson 1: Make a copy of the sample database.

About Sybase Central
Lesson 1: Start Sybase Central and connect
Lesson 2: The Sybase Central interface
Lesson 3: Viewing the sample database
Lesson 4: Create and edit tables
Lesson 5: Manage users and groups
Lesson 6: View and edit stored procedures
Lesson 7: Back up your database
Restore the sample database
Summary


About Sybase Central

Sybase Central is a database management tool that provides Adaptive Server Anywhere database settings, properties, and utilities in a graphical user interface. Sybase Central can also be used for managing other Sybase products. This chapter describes how to use Sybase Central with the Adaptive Server Anywhere sample database.

Sybase Central provides an easy-to-use interface for two kinds of tasks.

  • Tasks carried out by sending SQL statements to the server.

  • Tasks carried out by Adaptive Server Anywhere utilities.


Lesson 1: Start Sybase Central and connect

This section describes how to start Sybase Central and connect to the sample database using the ASA 9.0 Sample data source.

toggle To start Sybase Central

  • From the Start menu, choose Programs > SQL Anywhere 9 > Sybase Central.

    The Sybase Central window opens.

toggle To connect to the sample database

  1. From the Tools menu, choose Connect.

  2. If a dialog prompts you to choose a plug-in, select Adaptive Server Anywhere 9, and then click OK.

    The Connect dialog appears.

  3. Select the ODBC Data Source Name option.

  4. In the ODBC Data Source Name box, type ASA 9.0 Sample, or select it from the dropdown list if it is already there.

    Alternatively, you can also click Browse and choose the ASA 9.0 Sample from the Data Source Names dialog, and then click OK.

  5. Click OK to connect to the sample database.


Lesson 2: The Sybase Central interface

This section explains how to navigate the Sybase Central user interface.

The Sybase Central main window


The Sybase Central main window

The Sybase Central main window:

The Sybase Central main window.
Panes

The Sybase Central main window is split into two vertically-aligned panes.

The left pane displays a hierarchical view of database objects or containers in a tree-like structure. A container is a database object that can hold other database objects, including other containers.

The right pane displays the contents of the container that is selected in the left pane. You can change the appearance of both panes in the Options dialog (accessed through the Tools menu).

Toolbar

The Sybase Central toolbar provides you with buttons for common commands. To display or hide the toolbar, choose View > Toolbar.

With the main toolbar, you can do the following:

  • Navigate through the object tree.

  • Connect to or disconnect from a database, server, or product module.

  • Access the Connection Profiles dialog (also accessible through the Tools menu).

  • Refresh the view of the current folder. You can also press F5 to refresh the folder.

  • Cut, copy, paste, or delete objects.

  • View the property sheet of a selected object.

As an easy reminder of what these buttons do, you can hold your cursor over each button to see a popup description.

Status bar

The status bar, which appears at the bottom of the main window, displays a brief summary of menu commands as you navigate through the menus. To display or hide the status bar, choose View > Status Bar.


Lesson 3: Viewing the sample database

With Sybase Central you can carry out many database administration tasks, including creating, deleting, and viewing tables, columns, and procedures; managing users and user groups; backing up your database; and modifying data in database tables. This section helps you explore the tables and other objects in the sample database.


View the database schema

The database schema is a collection of all the objects in a database. Sybase Central displays a database schema as a hierarchy of containers and their contents. This section describes how to view the schema of a database.

Expanding a database container

Sybase Central offers a variety of methods for viewing the objects in a database, including the following:

  • Click a container in the left pane to select it. The right pane then displays the contents of the selected container.

  • Click once on the plus or minus icon next to a container in the left pane. This action expands or collapses the container. If no plus or minus icons appear next to a container, it means that the container holds no objects extending beyond the level of that container.

  • Double-click a container in either pane. This action expands the tree in the left pane and displays the contents of the container in the right pane.

The left pane displays container objects only. The right pane displays the contents of the container object selected in the left pane. For example, when you select the Tables folder in the left pane, all of the tables within that folder appear in the right pane.

Viewing the tables in a database

Once you are connected to the sample database, you can open the folders in the left pane to view the tables and other objects that make up the database.

Each table has an owner, who is listed in parentheses beside the table name in the left pane. If you see more tables than appear in the figure, right-click the asademo database, and choose Filter Objects By Owner from the popup menu. Select DBA, and clear the other user IDs in the list. Click OK to restrict the objects displayed to those owned by DBA.

toggle To examine the tables in the sample database

  1. Expand the Tables folder. You may have to expand asademo first.

    Sybase Central, with the Tables folder opened.

  2. Each table in the Tables folder is itself a container. Select a table in the left pane.

  3. Click on the various tabs in the right pane to see the contents of that tab as it relates to the selected table.

    A foreign key relationship displayed in Sybase Central.
Viewing database object properties

The properties of database objects, such as a database or a stored procedure, can be viewed using any of the following methods:

  • Right-click a database object in the left pane and choose Properties from the popup menu.

  • Select a database object and choose File > Properties.

You can navigate through a database schema by clicking or double-clicking items.

Database folders

Every Adaptive Server Anywhere database contains the following folders:

  • Tables base tables and global temporary tables stored in the database.

  • Views computed tables, stored in the database as a query and evaluated when accessed.

  • Indexes indexes in the database that provide an ordering of the rows of a table on the basis of the values in some or all of the columns.

  • Triggers special form of stored procedure executed automatically when a query that modifies data is executed.

  • System Triggers triggers that implement referential integrity actions in the database.

  • Procedures & Functions for using a module-based language consisting of SQL procedures.

  • Events for creating and editing events.

  • Domains for creating non-standard data types.

  • Users & Groups for administering who is permitted to use the database.

  • Integrated Logins for enabling users to connect to a database using their Windows user name and password.

  • SQL Remote Users for administering SQL Remote replication of data in the database.

  • MobiLink Users for managing MobiLink users and data synchronization.

    Publications database objects describing data to be replicated.

  • UltraLite Projects for collecting SQL statements and table definitions used in UltraLite applications.

  • Dbspaces for creating more than one .db file for the database.

  • Remote Servers for identifying remote servers so that local users can execute remote procedure calls or retrieve information from the remote server.

    Web Services a list of web services currently available in the database.

You should explore the sample database until you are comfortable locating database objects in the Sybase Central main window.


View the columns in the table

Each table has tabs in the right pane with information about a table's columns, foreign keys, indexes, triggers, and data. Here, you look only at the columns of the product table in the sample database.

toggle To view information about the columns of the product table

  1. Open the product table.

    In the left pane, expand the Tables folder, and then select the product table in the left pane.

    Information about the product table appears on the tabs in the right pane.

  2. In the right pane, click the Columns tab.

    The name, data type, and other information about each column appears in the right pane.

    Sybase Central, with the product table opened.

  3. View the properties of the color column.

    Select the color column, and then from the File menu, choose Properties.

    The color column property sheet appears. This property sheet contains a detailed description of the column. Some of the properties are useful for advanced users only, and are not described in this book.


View the data in the database

In addition to viewing the database schema, you can view the data in the database tables from Sybase Central.

toggle To view the contents of database tables

  1. Expand the Tables folder.

  2. In the left pane, click the contact table.

  3. In the right pane, click the Data tab.

    The data in the table appears in the right pane.


Lesson 4: Create and edit tables

This lesson takes you through the steps required to add a table to the sample database. This task includes adding columns to an existing table.


Create a table in Sybase Central

In this lesson, you create a table of offices in the sample database.

toggle Create a table named office

  1. In the left pane of Sybase Central, click the Tables folder.

  2. From the File menu, choose New > Table.

    The Table Creation wizard appears.

  3. Follow the instructions in the wizard, naming your table office, and choosing not to assign the table a primary key constraint. Use the default settings in the remainder of the wizard.

  4. Name the first row office_id, and assign a data type of smallint.

  5. From the File menu, choose Save Table.


Edit the Office table

This section describes how to edit an existing table. The steps show you how to add a primary key to the table created in the previous section by turning a column named office_id into a primary key.

toggle Edit the Office table

  1. Open the Tables folder and select the office table.

  2. Place a checkmark in the PKey column to indicate that the column named office_id is the primary key for the table.

    Primary key conditions
    A column with a primary key constraint cannot contain Nulls. Thus, when you select the Primary Key checkbox, the checkmark in the Nulls checkbox is automatically removed from that column.

    Similarly, if you select the Nulls checkbox, the primary key constraint is automatically removed from that column.

  3. From the File menu, choose Save Table.

  4. From the File menu, choose New Column.

  5. Edit the new column so that its name is office_name, its type is char, and its size is 20. Select Nulls so that office_name is allowed to be blank.

  6. From the File menu, choose Save Table.

The column is now in the database, although it contains no data.

Notes

  • All objects in Sybase Central have property sheets, including tables, users, and stored procedures.

  • Whenever you select an object in Sybase Central, commands related to that object appear in several places: in the File menu, in a popup menu that you can access by right-clicking the object, and as buttons on the toolbar.

  • When you click on many of the folders, New item buttons appear in the toolbar. Clicking these buttons creates new objects for the database.

  • Once you open a container, its contents are cached to improve performance. You can access two refresh commands in the View menu to update the view of either the current container or the entire window.


Delete the office table

Tables can be deleted, or dropped, from a database. For example you can delete the office table to restore the sample database to its original state.

toggle To delete the office table from the sample database

  1. Open the Tables folder.

  2. Select the office table and from the Edit menu, choose Delete.

    The Confirm Delete dialog appears.

  3. Click Yes to delete the office table from the database.


Lesson 5: Manage users and groups

In Adaptive Server Anywhere, both users and groups are objects within the database. However, groups are also containers, capable of containing users and other groups. When users are contained within a group, they are members of that group.

In this structure, permissions granted to a group are inherited by all users and groups contained within. Adaptive Server Anywhere allows you to create users and groups with permission to use a database and grant membership to other groups. Users and groups can be members of multiple groups.

This section demonstrates how to create a group for the database, how to create an individual user, and how to make the user a member of the group.


Add a group to the sample database

This section describes how to add a group to the sample database.

toggle To add a group to the sample database

  1. Connect to the sample database.

  2. Select the Users & Groups folder in the left pane.

  3. From the File menu, choose New > Group.

    The Group Creation wizard appears.

  4. Follow the instructions in the wizard, naming the new group Sales, and leaving the rest of the options at their default settings.

The Sales group now appears in both panes.


Add a user to the database

This section describes how to add a user to the sample database.

toggle To add a user to the sample database

  1. Connect to the sample database.

  2. Select the Users & Groups folder in the left pane.

  3. From the File menu, choose New > User.

  4. Follow the instructions in the User Creation wizard, naming the new user Sandy, and using the name Sandy as the password. Leave the rest of the settings at their default values.

An icon for the new user appears in both panes.


Add a user to a group

This section describes how to add two users to a group by copying and pasting them.

toggle To add users to a group

  1. Open the Users & Groups folder in the left pane.

  2. Click the Sales group.

  3. Click the Members tab in the right pane.

  4. From the File menu, choose New > Members.

    The New Members dialog appears.

  5. Choose the user Sandy, then click OK.


Lesson 6: View and edit stored procedures

The Procedures & Functions folder holds stored procedures for a database. This lesson shows how to view and alter the contents of a procedure, as well as how to modify the procedure's properties.


Viewing Stored Procedures

There are several stored procedures included in the sample database. The following steps explain how to view and edit stored procedures.

toggle To view the contents of a stored procedure

  1. In the left pane of Sybase Central, open the Procedures & Functions folder in the sample database.

  2. Click the sp_customer_list stored procedure.

    You can view the text of the procedure called sp_customer_list on the SQL tab in the right pane:

    Viewing stored procedures.

    This procedure is designed to return a set of customer IDs and company names from the customer table.


Edit stored procedure properties

You can edit the properties of stored procedures using the stored procedure's property sheet. In this section, you alter the permissions for a stored procedure so that all salespeople, including the user you created in the previous lesson (Sandy), can execute the procedure to obtain a list of customers.

Stored procedures have permissions associated with them. In order to execute a procedure, you either need to be granted permission to execute it, or you need to be a member of a user group that has permission to execute it.

toggle View and alter the permissions on the sp_customer_list procedure

  1. In the Procedures & Functions folder, select sp_customer_list.

  2. Choose File > Properties.

  3. Click the Permissions tab of the property sheet to see which user IDs have been granted permissions for this procedure. Currently, none have since the only user for the sample database is DBA, who is the owner of the procedure and so automatically has execute permission for the procedure.

  4. Click Grant.

    The Grant Permissions dialog appears:

    The Sybase Central Grant Permission dialog.

  5. In the Grant Permission dialog, select Sales and then click OK to grant this group permission to execute the sp_customer_list procedure.

    Sales is added to the Permissions tab of the Procedure property sheet with a checkmark in the Execute column:

    The Sybase Central stored procedure property sheet.

    You can revoke this group's permission by clicking the checkmark to make it disappear, or by selecting the group and clicking Revoke.

  6. Click OK to accept the changes to the sp_customer_list permissions.


Lesson 7: Back up your database

Sybase Central includes a set of database utilities for carrying out common database administration tasks. Wizards walk you through the steps involved.

Utilities

To see a list of those utilities that can be used on a running database, select the sample database container, and the click the File menu. Several options appear, including Backup Database, Upgrade Database, and Validate Database. Each of these menu items represents a utility.

In this section, you use a wizard to back up the sample database. This can be done on a running database.

toggle To back up a running database

  1. In the left pane, right-click the asademo - DBA icon and choose Backup Database from the popup menu. The Backup Database wizard appears.

  2. Read the introductory page of the wizard and then click Next.

  3. Select asademo from the list of databases you can back up. Click Next.

  4. Select On Disk, In The Following File.

    Type a filename in the text box indicating where you want to back up the database to. As this is a tutorial, you may wish to choose a file in a temporary directory such as c:\temp\backup.

  5. Click Finish to back up the database.

Notes

This kind of backup is called an archive backup. You can also make backups called image backups, which are physical copies of the database file and associated files.

An extension of .1 is added to the filename you specify in the Backup Database wizard.

Wizards are available for several other database administration tasks. You may wish to try creating a database by selecting the server in the left pane and choosing Create Database from the File menu.


Restore the sample database

Now that you have completed this tutorial, you should restore the sample database so that it can be used again in its original form. Replace the version of asademo.db that you just changed with the copy you made before beginning the tutorial. Delete asademo.log.


Summary

In this chapter, you learned how to start Sybase Central and connect to the sample database. You also learned how to view and edit the sample database, edit tables, manage users and groups, work with stored procedures, and back up your database.


Designing and Building a Database

About this chapter

This chapter introduces some principles of database design, and describes how to create a database using Sybase Central. It uses the Adaptive Server Anywhere sample database to illustrate the principles involved, and applies skills acquired in the preceding chapters working with the sample database to creating a brand new database from scratch. You will design and build a very simple database, modeled on the product, sales_order_items, sales_order, and customer tables of the sample database, but simplified.

About designing a new database
Designing and building a simple database
Lesson 1: Create a database file
Lesson 2: Connect to your database
Lesson 3: Design and create a table
Lesson 4: Identify and create primary keys
Lesson 5: Design column properties
Lesson 6: Design and create relationships between tables
Summary


About designing a new database

It is worth spending some time designing even the simplest database: what tables you will have, the keys that relate these tables, and so on.

Designing a database is not a difficult task for small and medium sized databases, but it is an important one. Bad database design can lead to an inefficient and possibly unreliable database system. Database applications are built to work on specific parts of a database, and rely on the database design, so a bad design can be difficult to revise at a later date.

Designing a large database is a complex task. There are formal approaches, such as conceptual data modeling, that help you to create efficient designs. Powerful tools, such as Sybase PowerDesigner and DataArchitect, enable you to apply these techniques to design and maintain large database designs.

This chapter does not attempt to tackle design issues for large databases. Instead, it helps you decide the kind of information you group together in a single table, and the way in which to think about and classify relationships between tables.

For an elementary look at the principles of database design, see Designing Your Database. For more advanced treatments, see the Sybase PowerDesigner documentation or a book devoted to database design.


Designing and building a simple database

When designing a database, you plan what items you want to store information about, and what information you will keep about each item. You also determine how these items are related. You classify the things in your database as entities; the links between these entities are called relationships.


Lesson 1: Create a database file

In this lesson, you create a database file to hold your database.

For more information, see The pieces of a database system.

Concepts

A database file is a container, ready to hold your database. The database file contains system tables and other system objects that are common to all databases, but you must add tables and the data they hold.

The collection of tables, indexes, and so on within the database, and all the relationships between them, make up the database schema. The schema is the database without the data. This tutorial describes how to design and create a very simple database schema.

For a conceptual introduction to some of these pieces, see Relational database concepts.

The name of each object within the database, including tables, columns, and indexes, is an identifier. There are rules governing what you can use as identifiers. You can use any set of letters, numbers, or symbols. However, you must enclose a column name in double quotes if it contains characters other than letters, numbers, or underscores, if it does not begin with a letter, or if it is the same as a keyword.

If the QUOTED_IDENTIFIER database option is set to OFF, double quotes are used to delimit SQL strings and cannot be used for identifiers. However, you can always use square brackets to delimit identifiers, regardless of the setting of QUOTED_IDENTIFIER.

For more information about identifiers, see Identifiers.

Exercise
toggle To create a new database file

  1. Start Sybase Central.

  2. In the left pane, select the Adaptive Server Anywhere plug-in, then click the Utilities tab in the right pane.

  3. In the right pane, double-click Create Database.

    The Create Database wizard opens.

  4. Read the information on the introductory page and click Next.

  5. Select Create A Database On This Computer and click Next.

  6. Choose a location and name for your database file.

    Enter the filename c:\temp\mysample. If your temporary directory is somewhere other than c:\temp, specify the appropriate path.

  7. Click Finish to create the database.

    Other options are available when creating a database, which you could have viewed by clicking Next instead of Finish, but the default choices are good for many purposes.

  8. The Creating Database window displays the progress of the task. When the file is created, click OK to close the window.


Lesson 2: Connect to your database

In this lesson, you connect to the database file you created.

For more information, see How the pieces fit together.

Exercise

Once your database is created, you can connect to it in order to create tables and other database objects.

toggle To connect to your database

  1. Start Sybase Central.

  2. From the Tools menu, choose Connect to open the Connect dialog.

    If you have multiple plug-ins loaded, you may need to choose the Adaptive Server Anywhere plug-in before the Connect dialog opens.

  3. Specify the user ID and password.

    On the Identification tab, enter a User ID of DBA and a Password of SQL. These are the default values for new databases.

    Choose None in the profile options at the bottom of the tab.

  4. Specify your database file.

    Click the Database tab. Enter the full path of your database file in the Database File field. For example, if you followed the suggestion in the previous lesson, you should enter the following:

    c:\temp\mysample.db

  5. Connect to the database.

    Click OK. Sybase Central connects to the database.

    Sybase Central, connected to the mysample database.

  6. Open the database server container in the left pane to see the mysample database.


Lesson 3: Design and create a table

In this lesson, you add a table to your database.

Concepts

Each table in your database should contain information about a single subject. In the language of database design, you are identifying entities. For example, the sample database holds information about employees in one table, and information about products in another table: employees and products are entities within the database design.

For an introduction to tables, see Database tables.

Each column in a table describes a particular characteristic of the thing that you would like to store information about. For example, in the sample database, the employee table has columns that hold an employee ID number, first and last names, an address, and other particular information that pertains to a particular employee.

In database diagrams, each table is depicted by a rectangular box. The name of the table is at the top of the box, and the column names are listed inside the box.

The Product table.

In the product table from the sample database, above, each product is an item of sports clothing.

Exercise

Create a simplified version of the product table, containing only the identifier (id) and name columns.

toggle To create the product table

  1. In Sybase Central, connect to your database if you are not already connected.

  2. Open the Tables folder in your database.

    First open the server and database containers, then open the Tables folder.

  3. From the File menu, choose New > Table.

    The Table Creation wizard appears.

  4. Name your table product.

  5. Click Finish.

  6. The first column of the table automatically appears in the right-hand pane. Define the first column in your table with the following values:

    • PKey Select the checkbox beside the column name so that a checkmark appears, indicating that the column is a primary key.

    • Column Name Give the column a name of id.

    • Data Type Give the column the integer data type.

  7. Create an additional column.

    From the File menu, choose New Column and add a column with the following properties:

    • Column Name Give the column a name of name. This column holds the product name.

    • Data Type Give the column the char data type, which holds character strings.

    • Size Enter a maximum length of 15 in the Size column.

  8. From the File menu, choose Save Table.

You have now created a table in your database. The table data is held in the database file. At present, the table is empty.

The next two lessons have more to say about columns and data types.


Lesson 4: Identify and create primary keys

In this lesson, you learn more about defining primary keys for your tables. There is no exercise associated with this lesson.

For more information, see Tables have a primary key.

Concepts

The primary key is a special column or columns used to uniquely identify a row in a table. In the product table, the id column uniquely identifies each product.

The Product table.

Each row has a unique value for the id column, and the values in each row pertain only to a single product identifier by its id value. Two products might have the same name or the same size, but not the same id number. In the diagram, the id column is underlined to show that it is a primary key.

Creating a column specifically to hold an identifier which has no other meaning is common practice in database design. You will know from your bank, utility, or credit card statements that each account has a unique identifier.

Using an AUTOINCREMENT primary key

You can make entering primary keys simple by assigning a primary key column a default value of AUTOINCREMENT. The value for this column is entered automatically each time a new row is added, and its value is one more than the field's value for the last row added.

toggle To create an AUTOINCREMENT primary key

  1. Select the product table in the left pane, then select the Columns tab in the right pane.

  2. Select the primary key column. From the File menu, choose Properties to open the property sheet for the column.

  3. Click the Value tab.

  4. Select the Default Value option.

  5. Click System-defined, and choose Autoincrement from the dropdown list.

  6. Click OK to close the column property sheet.

  7. From the File menu, choose Save Table.


Lesson 5: Design column properties

In this lesson, you learn more about choosing data types and other attributes for the columns of your tables.

Concepts

Each column has a data type associated with it. The data type defines the type of information the column holds. Choose a data type for the column that is appropriate for the data in the column. For example, identifier columns commonly have an integer data type, while columns holding names or addresses must have character data types.

Data types are organized into the following categories:

  • Numeric data types There are several numeric data types. Some are exact (not affected by round-off errors during operations) and some are approximate.

    The data type of the column affects the maximum size of the column. For example, if you specify SMALLINT, a column can contain a maximum value of 32,767. If you specify INTEGER, the maximum value is 2,147,483,647.

    For a complete list, see Numeric data types.

  • Character data types These are used to hold strings of text, such as names, addresses, and so on. These data types have a length indicating the maximum length of string that can be stored in them.

    For a list, see Character data types.

  • Binary data types These can be useful to hold information that may be meaningful to an application, but is encoded in a binary format.

    For a list, see Binary data types.

  • Date/time data types These hold times of the day, as well as dates.

    For a list, see Date and time data types.

  • Long data types These are sometimes called blobs (binary large objects). They can be used to hold long strings of text (called memo fields in some databases), images, or other binary information.

    For more information, see LONG BINARY data type [BINARY], and LONG VARCHAR data type [Character].

In addition, Adaptive Server Anywhere supports user-defined data types and special Java data types. These are not discussed in this introductory book.

NULL and NOT NULL

If every row must contain a value for this column, you should define the column as being NOT NULL. Otherwise, the column is allowed to contain NULL, which represents a missing value. The default is to allow NULL, but you should explicitly declare columns NOT NULL unless there is a good reason to allow NULL.

For a complete description of the NULL value, see NULL value. For information on its use in comparisons, see Search conditions.

toggle To specify a data type for a column

  1. Select the product table in the left pane, then select the Columns tab in the right pane.

  2. Select the Id column.

  3. From the File menu, choose Properties to open the property sheet for the column.

    The column's property sheet opens.

  4. On the Data Type tab, select Integer from the Built-in Type dropdown list.

  5. Click OK.

Exercise

This lesson and the last lesson have introduced the basic concepts you need to know in order to create database tables. You can put these to work by adding some more tables to your database. These tables will be used in the subsequent lessons in this chapter.

Add the following tables to your database:

  • customer Add a table named customer, with the following columns:

    • id An identification number for each customer. This column has integer data type, and is the primary key. Make this an autoincrement key.

    • company_name The company name. This column is a character data type, with a maximum length of 35 characters.

  • sales_order Add a table named sales_order, with the following columns:

    • id An identification number for each sales order. This column has integer data type, and is the primary key. Make this an autoincrement key.

    • order_date The date on which the order was placed. This column has date data type.

    • cust_id The identification number of the customer who placed the sales order. This column has integer data type.

  • sales_order_items Add a table named sales_order_items to hold line item information, with the following columns:

    • id The identification number of the sales order of which the line item is a part. This column has integer data type, and should be identified as a primary key column.

    • line_id An identification number for each sales order. This column has integer data type, and should be identified as a primary key column.

    • prod_id The identification number for the product being ordered. This column has integer data type.

You have now created four tables in your database. The tables are not yet related in any way. In the next lesson, you define foreign keys to relate the tables to one another.


Lesson 6: Design and create relationships between tables

In this lesson, you learn about designing and creating relationships between tables, using foreign keys.

For more information, see Tables are related by foreign keys.

Concepts

Although each table contains information about a single subject, two or more tables may contain related information. For example, an employee is a member of a department, and a sales order is comprised of a set of products. Relationships in a database may appear as foreign key relationships between tables, or may appear as separate tables themselves. You will see examples of each in this chapter.

You create relationships in your database to encode rules or practices that govern the data in your tables. Once a relationship is built into the structure of the database, there is no provision for exceptions.

Relationships among tables are classified as follows.

  • One-to-one relationships Each item in one entity corresponds to either zero or one entity in another. For example, in the sample database, one employee manages one department. There is nowhere to put a second department manager. Duplicating the department entry would involve duplicating the department ID, which is not possible because it is the primary key.

    It is often appropriate to combine the items in a one-to-one relationship into a single table. There is a column in the department table for a manager, rather than having a separate table named manager.

    For cases where it is appropriate to keep the items separate, see Designing Your Database.

  • Many-to-one relationships A many-to-one relationship becomes a foreign key relationship between tables. In a many-to-one relationship, the primary key in the one entity appears as a new foreign key column in the many table.

    For example, in the database you just created, one customer can place many orders, but only one customer places each order. To represent the one-to-many relationship, you need a foreign key column in the sales_order table (cust_id) that maps to the primary key column in the customer table (id). It is often convenient to give the two columns the same name.

    A many-to-one relationship between the employee table and the department table.

    Each entry in the cust_id column of the sales_order table must match one of the entries in the id column of the customer table. The sales_order table (which contains the foreign key in the relationship) is called the foreign table or referencing table. The customer table (which contains the referenced primary key) is called the primary table or the referenced table.

  • Many to many relationships A many-to-many relationship is represented by an intermediate table, and there is a foreign key relationship from the intermediate table to each of the related entities.

    For example, in the sample database, there is a many-to-many relationship between products and sales orders. One sales order can be for many products, and one product can appear on many sales orders.

    A many-to-many relationship between the sales_order and product tables.

    In some cases, the intermediate table (sales_order_items) contains additional information, such as the number of items of the product that were ordered and the date they were shipped. In this case, the intermediate table holds no additional information.

Exercise

Add foreign keys to relate the tables in your database.

toggle To create a foreign key

  1. Select the table for which you wish to create a foreign key.

  2. Select the Foreign Keys tab in the right pane.

  3. From the File menu, choose New > Foreign Key to open the Foreign Key Creation wizard.

  4. Follow the instructions in the wizard to add the following foreign key:

    • A foreign key from the id column in sales_order_items, referencing the id column in sales_order. This key builds the many-to-one relationship between sales orders and sales order items into the database.

  5. Repeat steps 1 through 4 to create the following foreign keys:

    • A foreign key from the prod_id column in sales_order_items, referencing the id column in product. This key builds the many-to-one relationship between sales order items and products into the database.

    • A foreign key from the cust_id column in sales_order, referencing the id column in customer. This key builds the many-to-one relationship between sales orders and customers into the database.

The first two foreign keys taken together build the many-to-many relationship between sales orders and products into the database.

This completes this introductory section on designing and building relational databases. Remaining chapters in the book describe how to add and retrieve data from databases. These chapters use the Adaptive Server Anywhere sample database, which is a bigger database than the one you have just created.


Summary

In this chapter, you learned the principles of database design. You then applied those principles of design in creating a brand new database using Sybase Central.


Synchronizing Databases with MobiLink

About this chapter

This chapter provides a tutorial to guide you through the process of synchronizing two Adaptive Server Anywhere databases via MobiLink. One of these databases is the consolidated database, and the other is a remote database. In this tutorial, you create these databases and then synchronize the two.

About MobiLink
Introduction
Lesson 1: Create your databases
Lesson 2: Prepare the databases for synchronization
Lesson 3: Start the MobiLink synchronization server
Lesson 4: Run the MobiLink synchronization client utility
Summary


About MobiLink

Data replication is the sharing of data among physically distinct databases. Sybase provides three distinct technologies for data replication:

  • MobiLink

  • SQL Remote

  • Replication Server

MobiLink synchronization enables replication between an ODBC-compliant consolidated database and Adaptive Server Anywhere or UltraLite remote databases. In this tutorial an Adaptive Server Anywhere remote database is used. The consolidated database can be made by Sybase Adaptive Server Anywhere, Sybase Adaptive Server Enterprise, Oracle, Microsoft SQL Server, or IBM DB2.

MobiLink is designed for synchronization involving a consolidated data server and large numbers of remote databases, typically including many mobile databases. Administration and resource requirements at the remote sites are minimal. The system is connection-based and a remote site can connect as often as desired. At the end of each connection, the databases are fully synchronized.

MobiLink works by lumping the results of multiple transactions on the remote database into one set of changes applied to the consolidated database. Since synchronization always occurs at a transaction boundary, referential integrity is preserved. The order of the individual changes made during the component transactions is not preserved: since uncommitted data is never replicated, data integrity is preserved.

> For more information about synchronization strategies, including complete MobiLink documentation, see the MobiLink Administration Guide.

> For an introduction to SQL Remote synchronization, see Replicating Data with SQL Remote.


Introduction

In this tutorial, you create a consolidated database and a remote database. You write synchronization publications and subscriptions. You then synchronize these databases using MobiLink synchronization technology.

Requirements

The tutorial requirements are given below.

Requirement | Discussion
Timing | The tutorial should take 50 minutes.
Software

  • A full Adaptive Server Anywhere 9 installation.

  • A full installation of MobiLink synchronization server.
Competencies and experience Knowledge and/or experience with command processing.

Competent at connecting to your database using ODBC and Sybase Central.

For more information on ODBC, see Lesson 1: Create an ODBC data source.
Goals

The goals for the tutorial are to gain competence and familiarity with:

  • The MobiLink synchronization server and client as an integrated system

  • Executing MobiLink synchronization server and client commands

  • The MobiLink synchronization server and client commands and options.

Key concepts

The MobiLink synchronization server connects to the consolidated database using the ODBC interface. The MobiLink synchronization client connects to your remote database. The MobiLink synchronization server and client function as a pair, managing the upload and download of data from one database to another.

Important concepts you will learn in this tutorial include:

  • MobiLink synchronization server, MobiLink synchronization client

  • ODBC connection, ODBC data source, synchronization subscription and publication, consolidated server, remote databases.


Lesson 1: Create your databases

MobiLink synchronization requires that you have compatible consolidated and remote databases, data in database tables, and ODBC data sources for each database.

Create your database files

The first step is to create each of the databases. In this procedure, you build a consolidated database and a remote database using the dbinit executable from the command prompt.

Tip
Creating a database file using dbinit is similar to formatting a disk — you have a database file with no user tables or procedures. You create your database schema when you define, within the newly initialized file, various user-defined tables and procedures.

For more information on the dbinit utility, see Creating a database using the dbinit command-line utility.

toggle To create your database files

  1. Create the directory where all of the tutorial files will be stored.

    From the C:\ drive, at the command prompt type:

    mkdir MLTutorial

  2. Go to the directory you made.

    At the command prompt type:

    cd MLTutorial

  3. Create a file for your consolidated database.

    At a command prompt type:

    dbinit consol.db

  4. Create a file for your remote database.

    At a command prompt type:

    dbinit remote.db

  5. Verify the successful creation of these database files by typing the following at a command prompt:

    dir

    Your database files should appear in the directory listing. If not, review your procedures and repeat Steps 1 or 2 as needed.

Create ODBC data sources

You are now ready to build ODBC data sources through which you can connect to your Adaptive Server Anywhere databases.

For more information on creating ODBC data sources see The Data Source utility.

toggle To create ODBC data sources

  1. Create your ODBC data source for a consolidated database by typing the following from a command prompt:

    dbdsn -w test_consol -y -c "uid=DBA;pwd=SQL;dbf=C:\MLTutorial\consol.db;eng=Consol"

  2. Create an ODBC data source for a remote database by typing the following from a command prompt:

    dbdsn -w test_remote -y -c "uid=DBA;pwd=SQL;dbf=C:\MLTutorial\remote.db;eng=remote"

Now you can verify your data sources.

toggle To verify your new data sources

  1. Start the ODBC Administrator.

    From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > ODBC Administrator.

    The ODBC Data Source Administrator appears.

  2. Click the User DSN tab.

  3. Scroll through the list to find your new data sources.

  4. Select a data source and click Configure.

    The ODBC Configuration for Adaptive Server Anywhere dialog opens.

  5. On the ODBC tab, test your data source by clicking the Test Connection button.

The MobiLink synchronization server and the MobiLink synchronization client use the ODBC data sources to connect to the consolidated and remote databases, respectively.

Populate your databases

You can now create tables for each of your newly initialized databases by executing SQL statements in scripts using Interactive SQL. The scripts contain SQL statements that create tables in the consolidated and remote databases and insert data. The scripts also create synchronization subscriptions and publications on the remote.

toggle To run scripts from Interactive SQL

  1. Start Interactive SQL.

    From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > Interactive SQL

    or

    From a command prompt, type dbisql.

  2. Connect to the consolidated database.

    From the SQL menu, select Connect.

    Type the default user ID DBA and the default password SQL in the appropriate fields.

    Select the ODBC Data Source Name option and use Browse to select the test_consol data source.

    Click OK to connect to the database.

  3. Create a table in the consolidated database and add some rows to the table:

    • Enter the following instructions:

      CREATE TABLE cust (
   cust_id int default autoincrement primary key,
   emp_id int,
   cust_name varchar( 128 )
   );
-- add data to cust table
INSERT INTO cust ( emp_id, cust_name ) VALUES ( 1, 'cust1' );
INSERT INTO cust ( emp_id, cust_name ) VALUES ( 1, 'cust2' );
INSERT INTO cust ( emp_id, cust_name ) VALUES ( 2, 'cust3' );
COMMIT;

  4. Verify the successful creation of the table:

    Enter the following command and verify that three rows are returned:

    SELECT * FROM cust

  5. Now repeat steps 2, 3, and 4 for the remote database remote.db, using the following SQL statements. No rows are added to the table in the remote database.

    CREATE TABLE cust (cust_id int default autoincrement primary key,
   emp_id int,
   cust_name varchar( 128 )
   )

    The query SELECT * FROM cust should display no rows.

  6. Close both instances of Interactive SQL.

Tip
If you need to start your database at any time, the following commands, for the consolidated and remote databases, can be used from the C:\MLTutorial directory: dbeng9 c:\MLTutorial\consol.db and dbeng9 c:\MLTutorial\remote.db

Previous Next


Lesson 2: Prepare the databases for synchronization

Synchronization is governed by the following:

  • Synchronization publications, users, and subscriptions These are defined in each remote database.

  • Synchronization scripts These are written in SQL and held in the consolidated database. Alternatively, you can write synchronization scripts in Java and store them in a location accessible by the MobiLink synchronization server. In this tutorial we use SQL scripts.

You can write, view and modify synchronization scripts as well as publications and subscriptions using Sybase Central.

Create a synchronization subscription and publication

The MobiLink synchronization publication, user, and subscription are necessary for MobiLink synchronization to happen. Each is defined in the remote database.

toggle To add a publication and synchronization subscription to the remote database

  1. Start Sybase Central and connect to your remote database:

    • From the Start menu, select Programs > SQL Anywhere 9 > Sybase Central.

    • In the left pane, select the Adaptive Server Anywhere 9 plug-in.

      From the Tools menu, choose Connect.

    • Enter an ODBC data source name of test_remote and click OK to connect.

  2. Add a publication to the remote database:

    • In Sybase Central, open the remote database.

    • Open the Publications folder.

    • From the File menu, choose New > Publication. The Publication Creation wizard appears.

    • Name the publication Customer and click Next.

    • Double-click the table cust to add it to the list of selected tables and click Finish to create the publication.

  3. Add a MobiLink user name to the remote database:

    • In Sybase Central, open the remote database.

    • Open the MobiLink Users folder.

    • From the File menu, choose New > MobiLink User. The MobiLink User Creation wizard appears.

    • Name the user ml_user and click Finish to create the user.

  4. Subscribe the MobiLink user to the publication:

    • In the left pane, expand the Publications folder so that the Customer publication is visible.

    • In the left pane, expand the MobiLink Users folder so that the ml_user MobiLink user is visible.

    • Drag the MobiLink user onto the Customer publication.

    • You are asked whether to subscribe the user to the publication. Click OK.

  5. Add address information to the subscription:

    Address information is used to enable the MobiLink client to locate the correct MobiLink synchronization server.

    • In the left pane, select the MobiLink user ml_user and from the File menu, choose Properties.

    • On the Connection tab, enter the following information, leaving the other fields blank:

      • Host localhost.

        If the MobiLink synchronization server were running on a different machine, you would enter the machine name or IP number instead of localhost.

    • Ensure that the Enable Certicom Security checkbox is clear.

    • Click OK to add the address information.

This completes the preparation of the remote database. The next step is to add synchronization scripts for the consolidated database.

Add synchronization scripts to the consolidated database

Each script belongs to a designated script version. You must add a script version to the consolidated database before you add scripts.

toggle To add a script version

  1. Start Sybase Central and connect to the test_consol data source using the MobiLink plug-in.

  2. Expand the test_consol folder.

  3. Open the Versions folder.

  4. Double-click Add Version. Name the new version default.

toggle To add synchronized tables to your consolidated database

  1. Open the Tables folder beneath the test_consol icon.

  2. Open the DBA container.

  3. From the File menu, select Add to Synchronized Tables.

Now that you have designated these tables as tables to be synchronized, you can add a new table script for each upload and download to the consolidated database.

toggle To add table scripts to each synchronized table

  1. Open the Synchronized Tables folder, and double-click the cust table.

  2. Double-click Add Table Script in the right pane.

    The Add Synchronizing Table Script wizard appears.

  3. Select the upload_insert event from the dropdown list.

  4. Click Finish.

  5. In the right pane, double-click the default table script.

    A dialog appears.

  6. Type the following code into the dialog:

    INSERT INTO cust ( cust_id, emp_id, cust_name )
VALUES ( ?, ?, ? )

  7. Save the script and close the dialog.

  8. Repeat this step for the download_cursor event, using the following script:

    SELECT cust_id, emp_id, cust_name
FROM cust

You have now generated scripts that perform a snapshot synchronization of your database, uploading new rows to the consolidated database and downloading rows from the consolidated database to the remote. In a complete MobiLink installation, you would add scripts for other events.


Lesson 3: Start the MobiLink synchronization server

In this lesson you start the MobiLink synchronization server so that you can synchronize the data in the consolidated and remote database.

toggle To start the MobiLink synchronization server

  • From the command prompt type:

    dbmlsrv9 -c "dsn=test_consol" -o mlserver.mls -v+ -dl -zu+

For a detailed explanation of the meaning of the options, see MobiLink Synchronization Server Options.

Once you have executed the MobiLink synchronization server command, the output below appears.

The MobiLink synchronization server window.

You can check to see that this screen appears to ensure you are ready to proceed to the next lesson in the tutorial.


Lesson 4: Run the MobiLink synchronization client utility

In this lesson you start the MobiLink synchronization client. You specify connection parameters at the command prompt using the -c option with the dbmlsync client utility. These parameters are for the remote database.

toggle To run the MobiLink synchronization client

  1. Ensure the MobiLink synchronization server is started.

  2. At the command prompt type:

    dbmlsync -c "dsn=test_remote" -o dbmlsync.out -v

    For more information see MobiLink synchronization client.

Once you have executed the MobiLink synchronization remote database command, the output below appears.

A MobiLink output screen, with a bar-type display showing a successful synchronization.

Check to see that this screen indicates that your synchronization has succeeded. You can then connect to the remote database and confirm that the cust table has three rows in it. These rows were added at the consolidated database.

You may wish to add more rows at the remote and consolidated database, and synchronize them.

Clean up
Be sure to delete all tutorial-related data sources and databases once you have finished this tutorial.

Previous Next


Summary

Now that you have two databases and have synchronized their contents, you can do so any time by running the synchronization server and client.

During this tutorial, you accomplished the following tasks.

  • Created new Adaptive Server Anywhere databases to serve as consolidated and remote databases

  • Wrote synchronization publication and subscription definitions

  • Created scripts to control data upload and download.

  • Started a MobiLink synchronization server, the MobiLink synchronization client, and synchronized the remote database with the consolidated database

Learning accomplishments

In this tutorial you:

  • Gained familiarity with the MobiLink synchronization server and client as an integrated system and learned MobiLink synchronization server and client commands and options

  • Acquired competence in executing MobiLink synchronization server and client commands

  • Became competent at writing synchronization scripts.

What's next?

You may need to learn more about MobiLink functioning to get the most out of MobiLink. The following areas are good starting points for further reading:

  • Try the next tutorial in our series Introduction.

  • Read the introductory chapter on MobiLink Introducing MobiLink Synchronization.

  • Read the chapter on running the MobiLink synchronization server Running MobiLink Outside the Current Session.

  • Get to know the MobiLink client utility MobiLink synchronization client.


Replicating Data with SQL Remote

About this chapter

This chapter shows you how to set up a simple replication system using SQL Remote.

About SQL Remote
Lesson 1: Getting Started
Lesson 2: Set up the consolidated database
Lesson 3: Set up the remote database
Lesson 4: Replicate data
Lesson 5: Restore the database and database settings
Summary


About SQL Remote

Data replication is the sharing of data among physically distinct databases. Changes made to shared data in any one database are replicated in the other databases. Sybase provides three distinct strategies for data replication:

  • SQL Remote

  • MobiLink

  • Replication Server

SQL Remote is designed for two-way replication involving a consolidated data server and a very large number of remote databases, typically including many mobile databases. Administration and resource requirements at the remote sites are minimal. This system is message-based.

In a SQL Remote installation, the central database must be either Sybase Adaptive Server Anywhere or Sybase Adaptive Server Enterprise.

SQL Remote replicates data by scanning the transaction log and preparing messages, as appropriate, for each transaction. It orders these messages and sends them to the remote or consolidated site. When processing received messages, SQL Remote always processes them in the same order as they were applied to the other database. When necessary, it automatically delays processing a message until all earlier messages have been applied.

For more information about synchronization strategies, including complete SQL Remote documentation, see the About This Manual.

For an introduction to MobiLink synchronization, see Synchronizing Databases with MobiLink.


Lesson 1: Getting Started

This tutorial describes how to set up a simple SQL Remote replication system.

With SQL Remote, you can carry out two-way replication between a central database (called the consolidated database) and a set of remote databases. These remote databases may be on laptop computers, while the consolidated database may be on a network in an office. All the setup and administration is carried out at the consolidated database.

This tutorial describes a very simple case, replicating one table from the sample database to a single remote database on the same machine.

In the tutorial, you act as the system administrator of a consolidated Adaptive Server Anywhere database. The replication system consists of a simple table from the sample database. The table we replicate is the department table, which is one of the simplest in the database.

The tutorial takes you through the following steps:

  1. Setting up the consolidated database.

  2. Creating a file-sharing replication system with a single remote database.

  3. Replicating data between the two databases.

Create directories for the tutorial


Create directories for the tutorial

Before you start, you need to create directories to hold the databases and other files you create during the tutorial. You should also create a copy of the sample database in case you need to recreate it in its original form.

toggle Prepare for the tutorial

  1. Create a directory to hold the files you make during this tutorial, for example, c:\tutorial.

  2. Create two subdirectories of tutorial called DBA and field, for example, c:\tutorial\DBA and c:\tutorial\field. These subdirectories hold messages for each of the two user IDs in the replication system.

  3. Create a copy of the sample database. Create a new folder for the copy, for example, demoback, and copy asademo.db into it.

What next?

Now you're ready to create the consolidated database.


Lesson 2: Set up the consolidated database

This section shows you how to prepare the consolidated database of a simple SQL Remote replication system. You require DBA authority to do this.

To prepare a consolidated database for replication, this lesson takes you through the following steps:

  1. Create a message type to use for replication.

  2. Grant PUBLISH permissions to a user ID to identify the source of outgoing messages.

  3. Grant REMOTE permissions to all user IDs that are to receive messages.

  4. Create a publication describing the data to be replicated.

  5. Create subscriptions describing who is to receive the publication.


Add a SQL Remote message type

All messages sent as part of replication use a message type. A message type description has two parts:

  • A message link supported by SQL Remote. In this tutorial, we use the FILE link. This is a file sharing method, where the messages are left in a file on disk, and read by the intended recipient. SQL Remote also supports ftp and e-mail protocols.

  • An address for this message link, to identify the source of outgoing messages. In this tutorial we use a file path to specify where the messages will be left.

Message types are created in all new databases, but you do need to supply an address for the message type you will use.

toggle Add an address to a message type

  1. From Sybase Central, connect to the sample database as user ID DBA using the password SQL, and open the sample database container (asademo) in the left pane.

  2. Click the SQL Remote Users folder in the left pane.

  3. Click the Message Types tab in the right pane.

  4. Click the FILE message type, and from the File menu choose Properties.

  5. Enter a publisher address to provide a return address for remote users. The publisher address is the directory you created in Lesson 1 to hold messages for the consolidated database (DBA). For example, c:\tutorial\DBA.

  6. Click OK to save the message type.


Add the publisher to the database

Each database in a SQL Remote replication system needs a single user ID that identifies the publisher of the data. Here, we make the DBA user ID the publisher.

toggle Set the publisher

  1. Click the Users & Groups folder in the left pane.

  2. Click DBA in the right pane, and from the File menu, choose Change to Publisher from the popup menu.

    Publisher appears in the Type column beside DBA.

A database can have only one publisher. You can find out who the publisher is at any time by opening the Users & Groups folder.


Add a remote user to the database

Each remote database is identified in the consolidated database by a user ID with REMOTE permissions.

When a remote user is added to a database, the message system they use and their address under that message system need to be stored along with their database user ID.

toggle Add a remote user

  1. Click the SQL Remote Users folder in the left pane.

  2. From the File menu, choose New > SQL Remote User.

    The Remote User Creation wizard appears.

  3. Type the name field as the name of the new remote user, and click Next.

  4. Ensure that the user is allowed to connect, and type the password field. Confirm the password by entering it again. Click Next.

  5. Select DBA permissions as well as Remote DBA permissions for the remote user. Click Next.

  6. Select the File message type and enter the remote address field in the text box. Click Next.

  7. Select Send Then Close. Click Next.

  8. Click Finish to create the remote user.

    The remote user field appears in the SQL Remote Users folder.

Notes

If you forget to set DBA permission in the wizard, you can set it by clicking on the user, then selecting Properties from the File menu, and checking DBA on the Authorities tab.

You have now created the users who will use this system.


Add publications and subscriptions

This section describes how to add a publication to a database, and how to add a subscription to that publication for a user. The publication replicates all rows of the table department.

toggle Add a publication

  1. Click the Publications folder in the left pane.

  2. From the File menu, choose New > Publication.

    The Publication Creation wizard appears.

  3. Type the name DepartmentPub as the name of the new publication, and click Next.

  4. Select department from the list of Available Tables. Click Add.

    The table appears in the list of Selected Tables on the right.

  5. Click Finish to create the publication.

Add a subscription

Each user ID that is to receive changes to a publication must have a subscription to that publication. Subscriptions can only be created for a valid remote user. You need to add a subscription to the DepartmentPub publication for the remote database user field.

toggle Add a subscription

  1. Expand the Publications folder in the left pane.

  2. Select the DepartmentPub publication in the left pane.

  3. Click the SQL Remote Subscriptions tab in the right pane.

  4. From the File menu, choose New > SQL Remote Subscription.

    The Create a New SQL Remote Subscription dialog appears.

  5. Click the user field in the dialog.

  6. Click Finish to create the subscription.

You have now set up the consolidated database.

What next?

You can now create the remote database.


Lesson 3: Set up the remote database

The remote database needs to be created and configured in order to send and receive messages and participate in a SQL Remote setup.

The database extraction utility enables you to carry out all the steps needed to create a remote database complete with subscriptions and required user IDs.


Create the remote database

You need to extract a database from the consolidated database for remote user field.

toggle Extract the remote database

  1. Click the sample database asademo (DBA) in the left pane, and from the File menu, choose Extract Database from the popup menu.

    The Extract Database wizard appears.

  2. Click Next on the introductory page of the wizard.

  3. Click asademo in the dialog. Click Next.

  4. Set the isolation level to 3. Click Next.

  5. Click the user field, and select the Start Subscriptions Automatically option. Click Next.

  6. Choose Extract and Reload into a new database. Click Next.

  7. Save the database to the file c:\tutorial\field\field.db. Click Next.

  8. Choose Extract the structure and data.

  9. Select the Order Data by Primary Key option. Click Next.

  10. Select the Foreign Keys, Procedures & Functions, Triggers, and Views checkboxes.

  11. Clear the Extract fully qualified publication definitions checkbox. Click Next.

  12. Clear the Connect to the new database checkbox.

  13. Click Finish to extract the remote database.

    The Extracting Database window appears, displaying the progress of the extraction. When completed, close the window.

Note

In a proper SQL Remote setup, the remote database field would be loaded on to the computer, together with a database server and any client applications required. For this tutorial, we leave the database where it is and use Interactive SQL to input and replicate data.


Verify that the database is created properly

To see what the extraction utility has done, connect to the field database and confirm that all the database objects are created.

toggle Browse through the remote database

  1. In Sybase Central, click the Connect button.

    The New Connection dialog appears.

  2. Choose Adaptive Server Anywhere 9 and click OK.

  3. On the Identification tab, enter the User ID field and Password field.

  4. On the Database tab, enter the database path c:\tutorial\field\field.db.

  5. Click OK to connect to the database.

    The database field appears in the left pane of Sybase Central.

  6. Expand the Tables folder in the left pane. The department table, owned by user DBA, is in the list.

  7. In the left pane, click the Department table.

  8. In the right pane, click the Data tab to show the five rows of the department table.

  9. Open the SQL Remote Users folder.

    On the SQL Remote tab, you will see that user DBA is designated as a consolidated user. This means DBA is the publisher of the consolidated database, and therefore above the field database in the hierarchy.

  10. Click the Message Types tab in the right pane.

    Field is designated as the publisher's address. Any data sent from this database comes from the user field, just as any data from the consolidated database comes from the user DBA.

  11. Open the Publications folder. You will see that the DepartmentPub publication is present.

What next?

The system is now ready for replication.


Lesson 4: Replicate data

You now have a replication system in place. In this section, data is replicated from the consolidated database to the remote database, and from the remote database to the consolidated database.


Add data to the consolidated database

First, enter a row in the consolidated database.

toggle Enter data in the consolidated database

  1. In the left pane, expand the Tables folder of the consolidated database (asademo).

  2. Select the department table in the left pane.

  3. Click the Data tab in the right pane.

  4. Click the plus sign in the toolbar to add a row.

  5. Enter the following values:

    Column | Value
    dept_id | 202
    dept_name | Eastern Sales
    dept_head_id | Leave as (NULL)

  6. Press Enter.

    If a confirmation dialog appears, click OK to update the row.

The next step is to send the new row to the remote database.

To send data to the remote database, you run the Message Agent at the consolidated database. The dbremote program is the Message Agent for Adaptive Server Anywhere.

toggle Send the data to the remote database

  1. At a command prompt, navigate to your tutorial directory. For example, navigate to c:\tutorial.

  2. To run the Message Agent against the consolidated database, execute the following command:

    dbremote -c "dbn=asademo;uid=DBA;pwd=SQL"

    The SQL Remote window appears, and displays messages about the status of replication.

  3. When SQL Remote displays the message Execution completed, click Shutdown.

To receive the insert statement at the remote database, you must run the Message Agent, dbremote, at the remote database.

toggle Receive data at the remote database

  1. At a command prompt, change to your tutorial directory. For example, navigate to c:\tutorial.

  2. Execute the following command to run the Message Agent against the field database:

    dbremote -c "dbn=field;uid=field;pwd=field"

    The SQL Remote window appears, informing you of the status of replication. The window indicates that a message was received from DBA.

  3. When SQL Remote displays the message Execution completed, click Shutdown.

Notes

  • The SQL Remote window displays status information while running. This information can be output to a log file for record keeping. You will see that the Message Agent first receives a message from asademo, and then sends a message. This return message contains confirmation of successful receipt of the replication update; such confirmations are part of the SQL Remote message tracking system that ensures message delivery even in the event of message system errors.

  • Depending on the current status of the database, there are three different connectivity parameters you can use to connect to a database:

    • dbf Connect to the database using the database file. This parameter requires you to specify the database file itself. If no server is currently running, a server will be started and the database will be loaded onto it. If a server is already running, the database will be loaded onto the default server.

    • dbn Connect to the database using the database name. This parameter requires you to specify the name of the database. You can only use this parameter when the database is already running.

    • dsn Connect to the database using the database source. A data source is a collection of parameters stored in the system registry or in a set of files. The source is referenced simply by its name.

      For more information about data sources, see DataSourceName connection parameter [DSN].


Verify that the data has arrived

From Sybase Central, inspect the department table to verify that the row has been received.

toggle Verify that the data has arrived

  1. Open the field database container.

  2. In the left pane, select the department table. In the right pane, click the Data tab to view the rows in the table.

    You will see that the department table contains the Eastern Sales department entered at the consolidated database.


Replicate from the remote database to the consolidated database

Now try entering data at the remote database and sending it to the consolidated database. Only the outlines are presented here.

toggle Replicate data from the remote database to the consolidated database

  1. Insert a row at the remote database, for a department with a dept_id of 203 and a dept_name of Western Sales.

  2. Run dbremote to send the message to the consolidated database:

    dbremote -c "dbn=field;uid=field;pwd=field"

  3. Run dbremote to receive the message at the consolidated database:

    dbremote -c "dbn=asademo;uid=DBA;pwd=SQL"

  4. Display the data in the department table at the consolidated database: It contains the Western Sales row.

What next?

The tutorial is now complete, but you should continue to the next section to restore the sample database to its original form.


Lesson 5: Restore the database and database settings

Once you have completed the tutorial it is important to undo any changes you have made to the sample database. Make sure that the following steps are completed in order to ensure that the settings are reset properly.

toggle Delete the remote user

  1. In the left pane, click the Users & Groups folder for the sample database.

  2. Click the user field, and from the Edit menu, choose Delete. Click Yes to remove the user from the list.

toggle Delete the publication

  1. Click the Publications folder in the left pane.

  2. Click DepartmentPub in the left pane, and from the Edit menu, choose Delete. Click Yes to confirm the deletion.

toggle Revoke the publishing status from the sample database

  1. Click the Users and Groups folder in the left pane.

  2. Click the DBA user in the left pane, and from the File menu, select Revoke Publisher.

Revoking a status while running the database
The status of a user cannot be modified while the user is running the database. Make sure that the user is idle before revoking or invoking a status.
toggle Restore the original message type settings

  1. Select the SQL Remote Users folder and click the Message Types tab in the right pane.

  2. Right-click the File message type in the right pane and choose Properties.

  3. Delete the publisher address and click OK to restore the settings.

toggle Shut down the remote database

  1. In the left pane, select the field database container.

  2. From the Tools menu, select Disconnect.

    The Disconnect dialog appears.

  3. Select the connection that corresponds to the field database.

  4. Click Disconnect.

toggle Delete the remote database

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Erase Database.

    The Erase Database wizard appears.

  4. Follow the instructions in the wizard to erase the field database.

  5. Enter the name of the database you want to erase or click Browse to search for the database. For example, enter c:\tutorial\field\field.db. Click Finish to erase the database file.

Notes

Now that the tutorial is complete, it might be a good idea to delete the tutorial directory (c:\tutorial) in order to save space.

Restore the data in the database


Restore the data in the database

The most important part of the cleanup process is to ensure that the changes to the sample database are reversed. The integrity of the sample database is very important in order to carry out other tutorials in later chapters of the manual.

toggle Delete the inserted data from the sample database

  1. From Sybase Central, display the data in the department table of the asademo database.

  2. Delete the rows with dept_id values of 202 and 203 to restore the table to its original state.


Summary

In this tutorial you learned how to

  • Prepare the consolidated database of a simple replication system.

  • Create and configure a remote database.

  • Replicate data in both directions between the two databases.

  • Restore your database and database settings.

  • Verify all the steps.

Where do I go from here?


Where do I go from here?

For more information about SQL Remote, see the About This Manual.

For an introduction to MobiLink synchronization, see Synchronizing Databases with MobiLink.


Designing Databases with PowerDesigner

About this chapter

SQL Anywhere Studio includes PowerDesigner Physical Architect, a module of Sybase's powerful database design tool, PowerDesigner. This module provides ways to generate and modify databases using a graphical representation of the database structure. You can optimize your database by customizing tables, columns, indexes, referential integrity, views, physical storage, triggers, and stored procedures.


About PowerDesigner

The structure of your database, such as the tables, relationships, views, and triggers, is called the database schema. You use SQL statements to create and arrange these elements to your liking, but doing so without a graphical tool can be confusing.

PowerDesigner gives you a graphical representation of the structure of your database. Better still, you can modify the structure of the database or create an entirely new one simply by drawing new tables or entering information. Once your design is complete, PowerDesigner can generate a SQL script to generate your new database.

The following diagram, which displays the structure of the sample database, is easily created using PowerDesigner.

The Adaptive Server Anywhere sample database, including tables, column names, primary keys, and foreign key relationships.

The performance of your database depends heavily on your design. In general, you should store information about different distinct types of objects, such as employees or products, in separate tables.

You can identify relationships between these tables using references, meaning that foreign keys in one table identify particular rows in another table. Many-to-one and one-to-many relationships can be represented by a reference. Many-to-many relationships require two references and another table.

For more information about database design, see Designing Your Database.

For more information about PowerDesigner, click Help on the toolbar of the PowerDesigner main window to access three books: PowerDesigner General Features Guide, PowerDesigner PDM User's Guide, and PowerDesigner Report User's Guide.

For more PowerDesigner tutorials, open PowerDesigner. From the Help menu, choose Where to Start > PDM Getting Started. This accesses the book Physical Data Model Getting Started.


Lesson 1: Getting Started

PowerDesigner can read the structure of a database from a script file that creates the database. However, it is generally easier to just connect to your database from PowerDesigner and let it extract the design directly with the reverse engineering feature.

The following tutorial uses the sample database as a starting point. The tutorial illustrates PowerDesigner by implementing a modification that improves the design of the sample database.

Currently, the price of each product is always read from the product table. As a result, updating the price effectively changes the sale price of that item on all previous orders. Adding a unit_price column to the sales_order_items table will correct this problem. The actual selling price to each customer can then be stored separately. The price in the product table records the current list price.

toggle To start PowerDesigner

  1. From the Start menu, choose Programs > SQL Anywhere 9 > PowerDesigner 9 > PowerDesigner.

    The PowerDesigner main window appears:

    The PowerDesigner main window.

    The PowerDesigner main window includes an object browser docked to the left, and an output window docked at the bottom.

  2. From the File menu, choose New.

    The New dialog appears.

  3. In the New dialog, choose Physical Data Model and then click OK.

    The New Physical Data Model dialog appears.

  4. On the General tab, from the dropdown list choose Sybase AS Anywhere 9.

  5. Use the default settings for the remaining options, and then click OK.

    The model name PhysicalDataModel_1 appears in the browser and in the title bar.

Reverse engineer the database


Reverse engineer the database

In this section, you generate a Physical Data Model (PDM) of the sample database by reverse engineering it.

toggle To reverse engineer the database

  1. Click the diagram window (the large central pane of PowerDesigner).

  2. From the Database menu, choose Reverse Engineering Database.

    The Database Reverse Engineering dialog appears:

    The PowerDesigner Database Reverse Engineering dialog.

  3. Ensure that Using an ODBC Data Source is selected, and that the data source is ASA 9.0 Sample.

    If ASA 9.0 Sample does not appear, click the icon to the right of the data source field. The Connect to an ODBC Data Source dialog appears. Select Machine Data Source and choose ASA 9.0 Sample from the dropdown list. Enter user ID DBA and password SQL. Click Connect to return to the Database Reverse Engineering dialog.

  4. In the Database Reverse Engineering dialog, click OK.

    The ODBC Reverse Engineering dialog appears:

    The PowerDesigner ODBC Reverse Engineering dialog.

    In the lower half of the dialog, there are seven checkboxes for selecting keys, indexes, and so on. These are the reverse engineering options. Ensure that all options are selected, except for the Permissions checkbox (the default). You should also ensure that all tables are selected (also the default).

  5. Click OK to reverse engineer the database.

    A graphic representation of the sample database appears in the diagram window, and the model objects appear in the browser:

    The Adaptive Server Anywhere sample database displayed in PowerDesigner.

  6. From the Tools menu, choose Display Preferences to see ways you can modify the display. Click each option on the left to see pages of display preference parameters. Click Help at the bottom of each page for complete information.

    Examine the diagram. You can use F6 to zoom in and F7 to zoom out to make the tables more readable.

    Each table in the database is represented by a box. The name of the table appears at the top of the box. Below is a list of the columns. Column names that are underlined are part of the primary key for that table. The data type of each column appears on the right. Some of the tables may overlap after reverse engineering. From the Symbol menu, choose Auto-Layout to reorganize them.

    References between tables are represented with arrows. The arrows point toward the parent table, which is the table that contains the primary key. An equation appears next to each arrow that identifies the reference.

  7. Rearrange the tables so that the diagram is easier to read. To do this, drag them with your mouse. The reference arrows follow automatically. You can select multiple objects by holding down the Shift key while clicking.

    One possible arrangement appears below:

    One arrangement for the Adaptive Server Anywhere sample database tables in PowerDesigner.


Lesson 2: Add a column

You are now ready to add the unit_price column to the sales_order_items table. You can accomplish this task by accessing the list of columns through the Table property sheet.

toggle To add a column

  1. Select the sales_order_items table.

  2. From the View menu, choose Properties.

    The Table Properties dialog appears.

    The PowerDesigner Table Properties dialog.

  3. Click the Columns tab.

    The list of columns appears.

    The PowerDesigner Table Properties sheet, showing the Columns tab.

  4. Add a new column to hold the unit price.

    Click the Insert a Row button.

    An arrow appears at the beginning of the line and a column with a default name (Column_6) appears.

  5. Type unit_price in the name column. The name is automatically duplicated as the code.

    In the Data Type column, choose Numeric from the dropdown list.

    The Data field may be too narrow to read. You can pull the sides of the column to expand it.

  6. The column properties P, F, and M stand for Primary Key, Foreign Key, and Mandatory, as follows:

    • Primary key designates a column whose values uniquely identify a row in the table.

    • Foreign key designates a column that depends on and migrates from a primary key column in another table.

    • Mandatory indicates a column that must be assigned a value.

  7. Select Mandatory and then click OK.

  8. Examine the effect of your changes on the diagram of the database.

    The sales_order_items table now includes a new column called unit_price.


Lesson 3: Check your work

PowerDesigner lets you quickly detect database design errors in your new model.

toggle To check your new schema

  1. From the Tools menu, choose Check Model.

    The Check Model Parameters dialog appears. You can use the default parameters.

  2. Click OK.

    The results of Check Model appear in the Result List dialog.


Lesson 4: Save changes and generate database

In PowerDesigner, models that depict the physical components of your database design, including tables and columns, are called Physical Data Models (PDM). PowerDesigner stores these in files with the extension .PDM.

toggle To save the physical data model (PDM)

  1. From the File menu, choose Save As.

  2. Type the file name c:\Temp\NewDemo.pdm.

  3. Click Save.

You can use PowerDesigner to generate a SQL script that implements all the components of your model. You can then use the SQL script to generate a database.

toggle To generate a SQL script to create your new database

  1. From the Database menu, choose Generate Database.

    The Database Generation dialog appears:

    The PowerDesigner Database Generation dialog.

  2. Type c:\Temp\ in the Directory field and NewDemo.sql in the File Name field.

  3. Ensure that Script Generation is selected.

  4. Click the Database tab, and ensure that Create Database is selected.

    Explore the other tabs to observe options that give you control over many other properties of the generated script.

  5. Click OK.

    When the script is created, the Result dialog appears.

  6. Click Edit to view the script.

    Check that your changes are reflected in the script. For example, the definition of the new office table appears below.

    /* ========================================= */
/*   Table: office                           */
/* ========================================= */
create table office
(
   id            integer         not null
      default autoincrement
      check (
         id >= 100),
   name          char(15)        not null,
   street        char(30)        not null,
   city          char(20)        not null,
   state         char(2)         not null,
   zip           char(5)         not null,
   phone         char(10)                ,
   fax           char(10)                ,
   primary key (id)
);

  7. When you are finished, close the dialog by clicking Close in the Result dialog.

You can now create your new database from Interactive SQL.

toggle To create the new database

  1. Start Interactive SQL.

    From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > Interactive SQL.

  2. Connect to the sample database using the ASA 9.0 Sample ODBC data source.

  3. Create an empty database:

    • Execute the following SQL statement, substituting any convenient directory.

      CREATE DATABASE 'c:\\Temp\\newdemo.db'
      Tip
      To execute a SQL statement in Interactive SQL, type or copy the statement in the SQL Statements pane, and then press F5. Alternatively, from the SQL menu, choose Execute.

  4. Close the connection to the sample database.

    From the SQL menu, choose Disconnect.

  5. Connect to the new database.

    From the SQL menu, choose Connect.

    • Enter DBA as the User ID

    • Enter SQL as the Password

    • Click the Database tab, and in the Database File box, enter the full path and file name of the new database file.

    • Click OK.

  6. Use the read statement. Remember that this statement demands that you enclose the file name in double quotes.

    • Execute the SQL statement:

      READ "c:\\Temp\\newdemo.SQL"

You can use these basic steps to modify other databases.


Summary

This tutorial introduced only some of the basic features of PowerDesigner. In fact, it is capable of handling the complete design or modification of your database schema, including all tables, views, indexes, references, triggers, and procedures.

Domains

Other features greatly simplify the task of designing larger databases. For example, you can specify domains. A domain holds a particular type of data, such as a phone number. It has a data type associated with it, but is more specific. For example, you can create a domain of identification numbers. Whenever you need an identification number in a table, you can associate that column with the identification number domain. All properties and checks associated with that domain are attached automatically.

Domains reduce repetitive definitions. In doing so, they not only reduce your work, but also reduce the chance that you will erroneously use a different type definition or check procedure. Rather than identify a column simply as an integer, you specify what specific type of data that column contains. All instances of that data type share a common definition.

For more information, see Using domains.

Business rules

A business rule is a written expression of the way a business operates. For example, the order shipped date must be greater than or equal to the order date is a business rule.

Business rules fall into four categories:

  • Definition Expresses inherent properties of an object. Definitions typically describe entities.

  • Fact Expresses certainty or existence. Facts typically describe relationships.

  • Validation A constraint on a value.

  • Formula Calculation used to produce values.

Business rules are particularly handy because they relate directly to the task that a customer requires a database to perform. By recording business rules and attaching them to particular objects, you can ensure that a database performs the required tasks.

Where do I go from here?


Where do I go from here?

For more information about PowerDesigner, select Help on the toolbar of the PowerDesigner main window to access three books: PowerDesigner General Features Guide, PowerDesigner PDM User's Guide, and PowerDesigner Report User's Guide.

For more PowerDesigner tutorials, open PowerDesigner. From the Help menu, choose Where to Start > PDM Getting Started. This accesses the book Physical Data Model Getting Started.

For more information about database design, see Designing Your Database.


Creating Reports with InfoMaker

About this chapter

This chapter includes a brief tutorial of InfoMaker report making that gets you started and teaches you the basic skills required to be productive in the InfoMaker environment.


About InfoMaker

InfoMaker is a powerful reporting and data maintenance tool. With InfoMaker, you can create the following objects:

  • Reports to view data.

  • Forms to view and change data.

  • Queries to automatically retrieve data for reports or forms.

  • Pipelines to pipe data from one database (or DBMS) to another.

  • Applications to bundle reports and forms and distribute them to users.

InfoMaker provides built-in connectivity to a broad range of desktop and server-based databases. When you work in InfoMaker, you work in a graphical environment—and working with data in this environment means that you don't need to understand SQL. InfoMaker creates all SQL statements behind the scenes as you build your reports and other objects graphically.

For more information about InfoMaker, from the Start menu, choose Programs > Sybase > InfoMaker 9.0 > Online Help Files. Complete documentation is also available within the application by accessing the Help menu.


Lesson 1: Getting Started

To use this InfoMaker tutorial, you must be connected to the Adaptive Server Anywhere sample database. To connect to the SQL Anywhere Studio 9.0 sample database you need to create a database profile.

toggle To start InfoMaker

  • From the Start menu, choose Programs > Sybase > InfoMaker 9.0 > InfoMaker.

    The InfoMaker main window appears. It includes the PowerBar, which has buttons for accessing the InfoMaker painters and online Help.

toggle To create a database profile for the SQL Anywhere Studio sample database with InfoMaker

  1. In InfoMaker, open the Database Profiles dialog.

    From the Tools menu, choose Database Profile.

  2. Select ODB ODBC and then click New.

    The Database Profile Setup dialog appears.

  3. On the Connection tab, enter the following values:

    • Profile Name Anywhere

    • Data Source ASA 9.0 Sample

    • User ID DBA

    • Password SQL

  4. Click OK.

    The profile Anywhere should now be listed under ODB ODBC.

toggle To connect to the Adaptive Server Anywhere sample database once a data source has been created

  1. If it is not already open, open the Database Profiles window by choosing Database Profile from the Tools menu.

  2. Select Anywhere from the ODBC group and then click Connect.

What next?

Next, you will create a report using an InfoMaker wizard.


Lesson 2: Create a basic report

This section shows you how to create a basic report, how to preview and save it, and how to change the settings in your design environment.


Create a report

There are many types of reports that you can create. This section shows you how to create a report from a single table.

toggle To create the report

  1. From the File menu, choose New.

  2. In the New dialog, click the Object tab.

  3. Double-click the icon labeled Tabular to select the tabular presentation style.

    The Tabular Report Generator wizard appears.

  4. Select the Quick Select data source, and ensure that Retrieve on Preview is selected. Click Next.

    The Quick Select dialog appears. This allows you to select a database table and some or all of the table's columns.

  5. Select the contact table.

  6. Select the following columns: last_name, first_name, title, phone, and fax. (You may need to scroll down.)

    InfoMaker moves the columns you select to the grid at the bottom of the dialog. You can use this grid for reordering the columns, and for providing sort and selection criteria.

  7. Click OK.

    The Select Color and Border Settings dialog appears.

  8. Click Next to use the default settings.

    A dialog summarizing your specifications appears.

  9. Click Finish.


Preview your report

In this section you will view your report to see what it looks like before printing it.

The main InfoMaker window has toolbars in the top section. Underneath the toolbars is the preview pane, which occupies the rest of the window. At the top of the preview pane is a title bar. At the left of the title bar is the name of the report you are previewing, and at the right are Minimize/Maximize buttons for adjusting the size of the preview pane.

toggle To preview your report

  1. Position your pointer in the upper right corner of the preview pane and click the Maximize icon.

    The Preview pane fills the entire window. Notice that it now contains the header information for the report, as well as information about the database.

  2. If you want to turn the rulers on or off, click inside the section that contains the data. Then, from the File menu, choose Print Preview Rulers.

  3. Click the Minimize icon in the upper right corner of the preview pane to return the preview pane to its original size and location.


Save the report

toggle To save the report

  1. From the File menu, choose Save.

    The Save Report dialog appears.

  2. In the Reports field, type contacts_by_jobrole. This becomes the name of the report.

  3. Optionally, you can add further detail about this report by adding notes in the Comments box.

    Click in the Comments box and type This report shows my contacts grouped by job role..

  4. Click OK to save the report.


Set up the design environment

In this section you make modifications to the controls, grid, and ruler.

toggle To set up the design environment

  1. From the Design menu, choose Options.

    The Report Options dialog appears.

  2. Make sure that the following options are selected: Show Grid, Show Ruler, Show Edges, and Retrieve on Preview.

  3. Make sure that Snap to Grid is not selected.

  4. You can click Help to see descriptions of all options.

  5. Click OK.

What next?

You are now ready to customize the look of your report.


Lesson 3: Enhance your report

In this section you'll learn how to make a number of enhancements to your report, including the following:

  • Sorting the data.

  • Creating and formatting headers and titles.

  • Adding computed fields such as dates, page numbers, and totals.


Define sorting and grouping

In this section you group contacts by title. To do this, you sort the data by title and then specify grouping by title.

First, you define the sorting.

toggle To sort contacts

  1. From the Rows menu, choose Sort.

    The Specify Sort Columns dialog appears.

  2. Drag title from the Source Data box to the Columns box.

  3. Drag last_name and then first_name into the Columns box.

  4. Leave the checkboxes selected to accept the default Ascending sort order.

  5. Click OK.

Next, you define the grouping based on the title column, so that all contacts with the same title are grouped together:

toggle To group contacts

  1. From the Rows menu, choose Create Group.

    The Specify Group Columns dialog appears.

  2. Drag title to the Columns box and then click OK.

The grouping is completed. Maximize the Preview pane, and you will see that the data is sorted. The grouping does not yet appear.


Enhance the report

In this section you enhance the report by rearranging controls, adding a title and date, adding page numbers, and adding a total.

toggle To adjust the group header

  1. Place your mouse pointer on the gray bar called Header Group Title.

    The pointer changes to a double-arrow.

  2. Drag the band down by five grid dots.

  3. Drag the title column from the bottom of the preview pane into the bottom of the band for the group header.

  4. With the title column still selected, click B and I on the style bar.

  5. Review the report in the Preview view.

toggle To arrange the headers

  1. Drag the First Name and Last Name text boxes into the right side of the header band to fill the empty space.

  2. Drag the first_name and last_name columns into the right side of the detail band to fill the empty space.

  3. From the Edit menu, choose Select > Select Text.

    This selects all the headers. It may be difficult to see that they are selected, because the band is so narrow.

  4. On the stylebar, click the Left Justification button. If your headers are not already bold, click the Bold button.

  5. Review the report in the Preview pane.

toggle To add a title to the report

  1. Drag the gray bar marked Header down about 10 grid dots.

  2. From the Edit menu, choose Select > Select Text. This selects all the headers.

  3. Drag all the headers down close to the gray band.

  4. From the Insert menu, choose Control > Text.

  5. Move the point of the pointer above the First Name box and down one grid dot from the top of the page. Click once. This positions the text box for the title.

  6. Type My Contacts

  7. Select size 14 from the dropdown list in the stylebar.

toggle To add a date to the report

  1. From the Insert menu, choose Control > Today().

  2. Move the point of the pointer to the upper left corner of the report and click. This adds the date to the report.

toggle To add page numbers to the report

  1. Drag the gray bar marked Footer down about four grid dots. If necessary, use the scrollbar to make room at the bottom of the Design view. Dragging down the footer bar makes space for the page number in the footer band.

  2. From the Insert menu, choose Control > Page n of n.

  3. Place the pointer about two grid dots below the center of the footer band. Click.

  4. Select size 10 in the stylebar.

toggle To add a total by counting the number of last names

  1. Drag the gray bar marked Summary down about six grid dots. This makes space for the total.

  2. From the Insert menu, choose Control > Computed Field.

  3. Place the pointer about four grid dots below the center of the summary band. Click.

    The Modify Expression dialog appears.

  4. In the Functions box, click Count( #x for all ).

  5. In the Columns box, click last_name.

  6. Click Verify.

    You receive a message stating that your expression is OK. Click OK.

  7. Click OK to complete the definition of the expression for the computed field.

toggle To format the total

  1. From the Insert menu, choose Control > Text.

  2. Position the pointer to the left of the computed field and click.

  3. Type Total contacts:

  4. Drag the text box to line it up with the computed field.

  5. Lasso the text and computed field by circling them with the pointer while pressing the left mouse button, and then releasing the mouse button.

  6. On the Stylebar, select the font size 10, and click B and I.

toggle To print, save, and close the report

  1. From the File menu, choose Print Report.

  2. In the Windows Print dialog, click OK.

  3. From the File menu, click Close.

  4. If you are prompted to save changes, click Yes.


Summary

In this tutorial you learned how to

  • Connect to InfoMaker.

  • Create a basic report.

  • Preview your report.

  • Format the report by sorting the data, and adding headers, titles, dates, page numbers and a total.

Where do I go from here?


Where do I go from here?

In addition to reports, InfoMaker provides functionality for creating graphs, queries, and data entry forms.

For more information about InfoMaker, choose Start > Programs > Sybase SQL Anywhere 9 > InfoMaker 9.0 > Online Help Files. Complete documentation is also available within the application by clicking the Help menu.


Microsoft Visual Basic Quick Start

About this chapter

This chapter describes how to develop a simple database application using Adaptive Server Anywhere and Microsoft Visual Basic.

Tutorial: Developing a Visual Basic application


Tutorial: Developing a Visual Basic application

This brief tutorial is based on Visual Basic 6.0. The complete application can be found in the Visual Basic project Samples\ASA\VBStarter\ASAStarter.vbp.

Visual Basic provides several data access technologies. In this tutorial, we use the Microsoft ADO Data Control with the Adaptive Server Anywhere OLE DB provider to access the Adaptive Server Anywhere sample database from Visual Basic.

toggle To develop a database application with Visual Basic

  1. Start Visual Basic, choosing a Standard Executable project.

  2. Add the Microsoft ADO Data Control 6.0 to your tool palette:

    • From the Project menu, choose Components.

    • Select the Microsoft ADO Data Control 6.0 component from the list.

      The Visual Basic Components list.

    • Click OK to add the control to the palette.

  3. Add the ADO Data Control to the form, as follows:

    The Visual Basic form with an ADO Data Control added.

  4. Configure the ADO Data Control:

    Property | Value
    ConnectionString | Provider=ASAPROV;DSN=ASA 9.0 Sample
    CursorLocation | 2 - asUseServer
    CursorType | 1 - adOpenKeyset
    RecordSource | SELECT * FROM EMPLOYEE

    The ConnectionString uses the Adaptive Server Anywhere OLE DB Provider (ASAProv) to connect to the ASA 9.0 Sample data source. The cursor settings take advantage of Adaptive Server Anywhere cursors rather than using the client-side cursors.

  5. Add two text boxes to the form, as follows:

    The Visual Basic form with text controls added.

  6. Bind the text boxes to the ADO Data Control:

    • Set the DataSource property for each to be Adodc1.

    • Set the DataField property for the left-hand text box to emp_fname, which is the column holding the employee's first name.

    • Set the DataField property for the right-hand text box to emp_lname, which is the column holding the employee's last name.

  7. Save the project.

  8. Run the sample:

    • Choose Run > Start to run the application.

      The application connects to the Adaptive Server Anywhere sample database and puts the name of the first employee in the text boxes, as follows:

      The Visual Basic application, with an employee name displayed.

    • You can use the buttons on the ADO Data Control to scroll through the rows of the result set.

    You have now created a simple Visual Basic application that works with Adaptive Server Anywhere.


Glossary

Web Links Browse Collapse Expand PDF Previous Next

Introducing SQL Anywhere Studio

Adaptive Server Anywhere (ASA)

The relational database server component of SQL Anywhere Studio, intended for use in mobile and embedded environments or as a server for small and medium-sized businesses.

article

In SQL Remote or MobiLink, an article is a database object that represents a whole table, or a subset of the columns and rows in a table. Articles are grouped together in a publication.

See also: replication, publication.

atomic transaction

A situation when commands in the transaction do not process properly and changes are undone or rolled back.

base table

A permanent table for data. Tables are sometimes called base tables to distinguish them from temporary tables and views.

See also: temporary table, view.

business rule

A guideline based on real-world requirements. Business rules are typically implemented through check constraints, user-defined data types, and the appropriate use of transactions.

See also: constraint, user-defined data type.

check constraint

A restriction that enforces specified conditions on a column or set of columns.

See also: constraint, foreign key constraint, primary key constraint, unique constraint.

checkpoint

The point at which all changes to the database are saved to the database file. At other times, committed changes are saved only to the transaction log.

client/server

A software architecture where one application (the client) obtains information from and sends information to another application (the server). The two applications often reside on different computers connected by a network.

collation

A combination of a character set and a sort order that defines the properties of text in the database. For Adaptive Server Anywhere databases, the default collation is determined by the operating system and language on which the server is running; for example, the default collation on English Windows systems is 1252LATIN1. A collation, also called a collating sequence, is used for comparing and sorting strings.

command file

A text file containing SQL statements. Command files can be built manually, or they can be built automatically by database utilities. The dbunload utility, for example, creates a command file consisting of the SQL statements necessary to recreate a given database.

communication stream

In MobiLink, the network protocol used for communication between the MobiLink client and the MobiLink synchronization server.

compressed database file

A database file that has been compressed to a smaller physical size using the dbshrink utility. Compressed databases are read-only. To make changes to a compressed database file, you must use an associated write file. You can expand compressed database files into normal database files using the dbexpand utility.

concurrency

The simultaneous execution of two or more independent, and possibly competing, processes. Adaptive Server Anywhere automatically uses locking to isolate transactions and ensure that each concurrent application sees a consistent set of data.

See also: transaction, lock, isolation level.

conflict trigger

In SQL Remote replication, a trigger that fires when an update conflict is detected, before the update is applied. Conflict triggers are fired when the values in the VERIFY clause of an UPDATE statement fail to match the current values in the database.

See also: replication, trigger.

connection ID

A unique number that identifies a given connection between a client application and the database. You can determine the current connection ID using the following SQL statement:

SELECT connection_property( 'Number' )

connection profile

A set of parameters that are required to connect to a database, such as user name, password, and server name, that is stored and used as a convenience.

consolidated database

In database replication, a database that stores the master copy of the data. The consolidated database contains all of the data, while remote databases usually contain only subsets of the data. In case of conflict or discrepancy, the consolidated database is considered to have the primary copy of all data.

In MobiLink, the consolidated database can be Oracle, IBM DB2, Microsoft SQL Server, Adaptive Server Anywhere, or Adaptive Server Enterprise.

See also: replication.

constraint

A restriction on the values contained in a particular database object, such as a table or column. For example, a column may have a uniqueness constraint, which requires that all values in the column be different. A table may have a foreign key constraint, which specifies how the information in the table relates to data in some other table.

See also: check constraint, foreign key constraint, primary key constraint, unique constraint.

contention

The act of competing for resources. For example, in database terms, two or more users trying to edit the same row of a database contend for the rights to edit that row.

convoy

A situation where all database connections but one are waiting for a shared resource.

correlation name

The name of a table or view that is used in the FROM clause of a query—either its original name, or an alias that is defined in the FROM clause.

cursor

A named linkage to a result set, used to access and update rows from a programming interface. In Adaptive Server Anywhere, cursors support forward and backward movement through the query results. Cursors consist of two parts: the cursor result set, typically defined by a SELECT statement; and the cursor position.

See also: cursor result set, cursor position.

cursor position

A pointer to one row within the cursor result set.

See also: cursor, cursor result set.

cursor result set

The set of rows resulting from a query that is associated with a cursor.

See also: cursor, cursor position.

data definition language (DDL)

The subset of SQL statements for modeling the structure of a database. DDL statements create, modify, and remove database objects, including users.

data type

The format of data, such as CHAR or NUMERIC. In the ANSI SQL standard, data types can also include a restriction on size, character set, and collation.

See also: user-defined data type.

data manipulation language (DML)

The subset of SQL statements for retrieving and updating the contents of a database.

database

A collection of tables that are related by primary and foreign keys. The tables hold the information in the database. The tables and keys together define the structure of the database. A database-management system accesses this information.

See also: foreign key, primary key, database-management system (DBMS), relational database-management system (RDBMS).

database administrator (DBA)

The user with the permissions required to maintain the database. The DBA is generally responsible for all changes to a database schema, and for managing users and user groups. The role of database administrator is automatically built into databases as user ID DBA with password SQL.

database connection

A communication channel between a client application and the database. A valid user ID and password are required to establish a connection. The privileges granted to the user ID determine the actions that can be carried out during the connection.

database file

A database is held in one or more database files. There is an initial file, and subsequent files are called dbspaces. Each table, including its indexes, must be contained within a single database file.

See also: dbspace.

database-management system (DBMS)

A collection of programs that allow you to create and use databases.

See also: relational database-management system (RDBMS).

database name

The name given to a database when it is loaded by a server. The default database name is the root of the initial database file.

See also: database file.

database object

A component of a database that contains or receives information. Tables, indexes, views, procedures, and triggers are database objects.

database owner (dbo)

A special user that owns the system objects not owned by SYS.

See also: database administrator (DBA), SYS.

database server

A computer program that regulates all access to information in a database. Adaptive Server Anywhere provides two types of servers: network servers and personal servers.

DBA authority

The level of permission that enables a user to carry out administrative activity in the database. The DBA user has DBA authority by default.

See also: database administrator (DBA).

dbspace

An additional database file that creates more space for data. A database can be held in up to 13 separate files (an initial file and 12 dbspaces). Each table, together with its indexes, must be contained in a single database file. The SQL command CREATE DBSPACE adds a new file to the database.

See also: database file.

deadlock

A state where a set of transactions arrives at a place where none can proceed.

download

The stage in synchronization where data is transferred from the consolidated database to a remote database.

embedded SQL

A programming interface for C programs. Adaptive Server Anywhere embedded SQL is an implementation of the ANSI and IBM standard.

external login

An alternate login name and password used when communicating with a remote server. By default, Adaptive Server Anywhere uses the names and passwords of its clients whenever it connects to a remote server on behalf of those clients. However, this default can be overridden by creating external logins. External logins are alternate login names and passwords used when communicating with a remote server.

extraction

In SQL Remote replication, the act of unloading the appropriate structure and data from the consolidated database. This information is used to initialize the remote database.

In MobiLink synchronization, the act of unloading the appropriate structure and data from a reference database.

See also: replication.

failover

Switching to a redundant or standby server, system, or network on failure or unplanned termination of the active server, system, or network. Failover happens automatically, and is often built-in to continuously available systems.

FILE

In SQL Remote replication, a message system that uses shared files for exchanging replication messages. This is useful for testing and for installations without an explicit message-transport system (such as MAPI).

See also: replication, MAPI.

file-based download

In MobiLink, a way to synchronize data in which downloads are distributed as files, allowing offline distribution of synchronization changes.

foreign key

One or more columns in a table that duplicate the primary key values in another table. Foreign keys establish relationships between tables.

See also: primary key, foreign table.

foreign key constraint

A restriction on a column or set of columns that specifies how the data in the table relates to the data in some other table. Imposing a foreign key constraint on a set of columns makes those columns the foreign key.

See also: constraint, check constraint, primary key constraint, unique constraint.

foreign table

The table containing the foreign key.

See also: foreign key.

full backup

A backup of the entire database, and optionally, the transaction log. A full backup contains all the information in the database and thus provides protection in the event of a system or media failure.

See also: incremental backup.

generated join condition

A restriction on join results based on the keyword KEY or NATURAL. For a natural join, the generated join condition is based on common column names in the two tables. For a key join, the condition is based on a foreign key relationship between the two tables.

See also: join, join condition.

global temporary table

A type of temporary table for which data definitions are visible to all users until explicitly dropped. Global temporary tables let each user open their own identical instance of a table. By default, rows are deleted on commit, and rows are always deleted when the connection is ended.

See also: temporary table, local temporary table.

grant option

The level of permission that allows a user to grant permissions to other users.

identifier

A string of characters used to reference a database object, such as a table or column. An identifier may contain any character from A through Z, a through z, 0 through 9, underscore (_), at sign (@), number sign (#), or dollar sign ($).

incremental backup

A backup of the transaction log only, typically used between full backups.

See also: transaction log.

index

A sorted set of keys and pointers associated with one or more columns in a base table. An index on one or more columns of a table can improve performance.

InfoMaker

A reporting and data maintenance tool that lets you create sophisticated forms, reports, graphs, cross-tabs, and tables, as well as applications that use these reports as building blocks.

inner join

A join in which rows appear in the result set only if both tables satisfy the join condition. Inner joins are the default.

See also: join, outer join.

integrated login

A login feature that allows the same single user ID and password to be used for operating system logins, network logins, and database connections.

integrity

Adherence to rules that ensure that data is correct and accurate, and that the relational structure of the database is intact.

See also: referential integrity.

Interactive SQL

An Adaptive Server Anywhere application that allows you to query and alter data in your database, and modify the structure of your database. Interactive SQL provides a pane for you to enter SQL statements, as well as panes that display information about how the query was processed and the result set.

isolation level

The degree to which operations in one transaction are visible to operations in other concurrent transactions. There are four isolation levels, numbered 0 through 3. Level 3 provides the highest level of isolation. Level 0 is the default setting.

JAR file

Java archive file. A compressed file format consisting of a collection of one or more packages used for Java applications. It includes all the resources necessary to install and run a Java program in a single compressed file.

Java class

The main structural unit of code in Java. It is a collection of procedures and variables grouped together because they all relate to a specific, identifiable category.

jConnect

A Java implementation of the JavaSoft JDBC standard. It provides Java developers with native database access in multi-tier and heterogeneous environments.

See also: JDBC.

JDBC

Java Database Connectivity. A SQL-language programming interface that allows Java applications to access relational data.

join

A basic operation in a relational system that links the rows in two or more tables by comparing the values in specified columns.

join condition

A restriction that affects join results. You specify a join condition by inserting an ON clause or WHERE clause immediately after the join. In the case of natural and key joins, Adaptive Server Anywhere generates a join condition.

See also: join, generated join condition.

join type

Adaptive Server Anywhere provides four types of joins: cross join, key join, natural join, and joins using an ON clause.

See also: join.

local temporary table

A type of temporary table that exists only for the duration of a compound statement or until the end of the connection. Local temporary tables are useful when you need to load a set of data only once. By default, rows are deleted on commit.

See also: temporary table, global temporary table.

lock

A concurrency control mechanism that protects the integrity of data during the simultaneous execution of multiple transactions. Adaptive Server Anywhere automatically applies locks to prevent two connections from changing the same data at the same time, and to prevent other connections from reading data that is in the process of being changed.

You control locking by setting the isolation level.

See also: isolation level, concurrency, integrity.

log file

A log of transactions maintained by Adaptive Server Anywhere. The log file is used to ensure that the database is recoverable in the event of a system or media failure, to improve database performance, and to allow data replication using SQL Remote.

See also: transaction log, transaction log mirror, full backup.

LTM

Log Transfer Manager. See Replication Agent.

MAPI

Microsoft's Messaging Application Programming Interface. A message system used in several popular e-mail systems such as Microsoft Mail.

message system

In SQL Remote replication, a protocol for exchanging messages between the consolidated database and a remote database. Adaptive Server Anywhere includes support for the following message systems: FILE, MAPI, FTP, SMTP, and VIM.

See also: replication, FILE, MAPI.

message type

In SQL Remote replication, a database object that specifies how remote users communicate with the publisher of a consolidated database. A consolidated database may have several message types defined for it; this allows different remote users to communicate with it using different message systems.

See also: replication, consolidated database, MAPI.

metadata

Data about data. Metadata describes the nature and content of other data.

See also: schema.

MobiLink

A session-based synchronization technology designed to synchronize UltraLite and Adaptive Server Anywhere databases with many industry-standard SQL database-management systems from Sybase and other vendors.

See also: UltraLite.

MobiLink client

There are two kinds of MobiLink clients. For Adaptive Server Anywhere remote databases, the MobiLink client is the dbmlsync command line utility. For UltraLite remote databases, the MobiLink client is built in to the UltraLite runtime library.

MobiLink user

A MobiLink user is a name that uniquely identifies a MobiLink remote database in the synchronization system. The client supplies this name and, optionally, an associated password when it connects to the MobiLink synchronization server. MobiLink user names are entirely independent of database user names.

NetWare

A widely-used network operating system defined by Novell. NetWare generally employs the IPX/SPX protocol, although the TCP/IP protocol may also be used.

network server

A database server that accepts connections from computers sharing a common network.

See also: personal server.

normalization

The refinement of a database structure to eliminate redundancy and improve organization according to rules based on relational database theory.

object tree

In Sybase Central, the hierarchy of database objects. The top level of the object tree shows all products that your version of Sybase Central supports. Each product expands to reveal its own sub-tree of objects.

See also: Sybase Central.

ODBC

Open Database Connectivity. A standard Windows interface to database-management systems. ODBC is one of several interfaces supported by Adaptive Server Anywhere.

ODBC Administrator

A Microsoft program included with Windows operating systems for setting up ODBC data sources.

ODBC data source

A specification of the data a user wants to access via ODBC, and the information needed to get to that data.

outer join

A join that preserves all the rows in a table. Adaptive Server Anywhere supports left, right, and full outer joins. A left outer join preserves the rows in the table to the left of the join operator, and returns a null when a row in the right table does not satisfy the join condition. A full outer join preserves all the rows from both tables.

See also: join, inner join.

package

In Java, a collection of sets of related classes.

passthrough

In SQL Remote replication, a mode by which the publisher of the consolidated database can directly change remote databases with SQL statements. Passthrough is set up for specific remotes. In normal passthrough mode, all database changes made at the consolidated database are passed through to the selected remote databases. In passthrough only mode, the changes are made at the remote databases, but not at the consolidated database.

performance statistic

A value reflecting the performance of the database system. The CURRREAD statistic, for example, represents the number of file reads issued by the engine that have not yet completed.

personal server

A database server that runs on the same computer as the client application. A personal database server is typically used by a single user on a single computer, but it can support several concurrent connections from that user.

plug-in module

In Sybase Central, a way to access and administer a product. Plug-ins are usually installed and registered automatically with Sybase Central when you install the respective product. Typically, a plug-in appears as a top-level container, in the Sybase Central main window, using the name of the product itself; for example, Adaptive Server Anywhere.

See also: Sybase Central.

PowerDesigner

A database modeling application. PowerDesigner provides a structured approach to designing a database or data warehouse.

PowerDynamo

A Sybase product for building and managing a Web application linked to a database.

PowerJ

A Sybase product for developing Java applications.

predicate

A conditional expression that is optionally combined with the logical operators AND and OR to make up the set of conditions in a WHERE or HAVING clause. In SQL, a predicate that evaluates to UNKNOWN is interpreted as FALSE.

primary key

A column or list of columns whose values uniquely identify every row in the table.

See also foreign key.

primary key constraint

A uniqueness constraint on the primary key columns. A table can have only one primary key constraint.

See also: constraint, check constraint, foreign key constraint, unique constraint, integrity.

primary table

The table containing the primary key in a foreign key relationship.

proxy table

A local table containing metadata used to access a table on a remote database server as if it were a local table.

See also: metadata.

publication

In SQL Remote or MobiLink, a database object that identifies replicated data. In MobiLink, publications exist only on the clients. A publication consists of articles. Periodically, the changes made to each publication are replicated to all subscribers to that publication. SQL Remote users can receive a publication by subscribing to it. MobiLink users can synchronize a publication by creating a synchronization subscription to it.

See also: replication, article, publication update.

publication update

In SQL Remote replication, a list of changes made to one or more publications in one database. A publication update is sent periodically as part of a replication message to the remote database(s).

See also: replication, publication.

publisher

In SQL Remote replication, the single user in a database who can exchange replication messages with other replicating databases.

See also: replication.

query

A SQL statement or group of SQL statements that access and/or manipulate data in a database.

See also: SQL.

Redirector

A web server plug-in that routes requests and responses between a client and the MobiLink synchronization server. This plug-in also implements load-balancing and failover mechanisms.

reference database

In MobiLink, an Adaptive Server Anywhere database used in the development of UltraLite clients. You can use a single Adaptive Server Anywhere database as both reference and consolidated database during development. Databases made with other products cannot be used as reference databases.

referential integrity

Adherence to rules governing data consistency, specifically the relationships between the primary and foreign key values in different tables. To have referential integrity, the values in each foreign key must correspond to the primary key values of a row in the referenced table.

See also: primary key, foreign key.

relational database-management system (RDBMS)

A type of database-management system that stores data in the form of related tables.

See also: database-management system (DBMS).

remote database

In SQL Remote replication or MobiLink synchronization, a database that exchanges data with a consolidated database. Remote databases may share all or some of the data in the consolidated database.

See also: replication, consolidated database.

remote DBA authority

In SQL Remote, a level of permission required by the Message Agent. In MobiLink, a level of permission required by the Adaptive Server Anywhere synchronization client (dbmlsync). When the Message Agent or synchronization client connects as a user who has this authority, it has full DBA access. The user ID has no additional permissions when not connected through the Message Agent or synchronization client.

See also: DBA authority.

remote permission

In SQL Remote replication, the permission to exchange replication messages with the publishing database. Granting remote permissions to a user makes that user a remote user. You must specify a message type, an appropriate remote address, and a replication frequency. In general terms, remote permissions can also refer to any user involved in SQL Remote replication (for example, the consolidated publisher and remote publisher).

See also: replication.

remote user

In SQL Remote replication, a database user in the consolidated database that has been granted remote permissions and is associated with one particular remote database in the replication setup. To create a remote user, an ordinary database user is granted remote permissions. Doing so not only identifies the existence of a particular remote database, but also specifies the message type and address with which to communicate with that particular remote site.

When remote databases are created by means of extraction from a consolidated database, each remote user in the consolidated database becomes the publisher of the data in one particular remote database.

See also: SQL Remote, consolidated database, publisher.

replication

The sharing of data among physically distinct databases. Sybase has three replication technologies: MobiLink, SQL Remote, and Replication Server.

Replication Agent

In Replication Server, the program, also called Log Transfer Manager (LTM), that reads a database transaction log and sends committed changes to Replication Server.

replication frequency

In SQL Remote replication, a setting for each remote user that determines how often the publisher's message agent should send replication messages to that remote user.

See also: replication, remote user.

replication message

In SQL Remote or Replication Server, a communication sent between a publishing database and a subscribing database. Messages contain data, passthrough statements, and information required by the replication system.

See also: passthrough, replication, publication update.

Replication Server

A Sybase connection-based replication technology that works with Adaptive Server Anywhere and Adaptive Server Enterprise. It is intended for near-real time replication between a small number of databases.

role

In conceptual database modeling, a verb or phrase that describes a relationship from one point of view. You can describe each relationship with two roles. Examples of roles are "contains" and "is a member of."

role name

The name of a foreign key. This is called a role name because it names the relationship between the foreign table and primary table. By default, the role name is the table name, unless another foreign key is already using that name, in which case the default role name is the table name followed by a three-digit unique number. You can also create the name yourself.

See also: foreign key.

rollback log

A record of the changes made during each uncommitted transaction. In the event of a ROLLBACK request or a system failure, uncommitted transactions are reversed out of the database, returning the database to its former state. Each transaction has a separate rollback log, which is deleted when the transaction is complete.

See also: transaction.

row-level trigger

A trigger that executes once for each row that is changed.

See also: trigger, statement-level trigger.

schema

The structure of a database, including tables, columns, and indexes, and the relationships between them.

scripts

In MobiLink, code written to handle MobiLink events. Scripts programmatically control data exchange to meet business needs.

server-initiated synchronization

A way to initiate MobiLink synchronization programmatically from the consolidated database.

service

In Windows operating systems, a way of running applications when the user ID running the application is not logged on.

session-based synchronization

A type of synchronization where synchronization results in consistent data representation across both the consolidated and remote databases. MobiLink is session-based.

SQL

The language used to communicate with relational databases. ANSI has defined standards for SQL, the latest of which is SQL-99 (also called SQL3). SQL stands, unofficially, for Structured Query Language.

SQL Remote

A message-based replication technology for two-way replication between consolidated and remote databases. The consolidated database must be Adaptive Server Anywhere or Adaptive Server Enterprise. The remote databases must be Adaptive Server Anywhere.

SQL statement

A string containing SQL keywords designed for passing instructions to a DBMS.

See also: schema, SQL, database-management system (DBMS).

statement-level trigger

A trigger that executes after the entire triggering statement is completed.

See also: trigger, row-level trigger.

stored procedure

A program comprised of a sequence of SQL instructions, stored in the database and used to perform a particular task.

subquery

A SELECT statement that is nested inside another SELECT, INSERT, UPDATE, or DELETE statement, or another subquery.

There are two types of subquery: correlated and nested.

subscription

In SQL Remote replication, a link between a publication and a remote user, allowing the user to exchange updates on that publication with the consolidated database.

In MobiLink synchronization, a synchronization subscription is a link in a client database between a publication and a MobiLink user allowing the data described by the publication to be synchronized.

See also: publication, remote user, MobiLink user.

Sybase Central

A database management tool that provides Adaptive Server Anywhere database settings, properties, and utilities in a graphical user interface. Sybase Central can also be used for managing other Sybase products, including MobiLink.

synchronization

The process of replicating data between databases using MobiLink technology.

In SQL Remote, synchronization is used exclusively to denote the process of initializing a remote database with an initial set of data.

See also: MobiLink, SQL Remote.

SYS

A special user that owns most of the system objects. You cannot log in as SYS.

system object

Database objects owned by SYS or dbo.

system table

A table, owned by SYS or dbo, that holds metadata. System tables, also known as data dictionary tables, are created and maintained by the database server.

system view

A type of view, included in every database, that presents the information held in the system tables in an easily understood format.

temporary table

A table that is created for the temporary storage of data. There are two types: global and local.

See also: local temporary table, global temporary table.

transaction

A sequence of SQL statements that comprise a logical unit of work. A transaction is processed in its entirety or not at all. Adaptive Server Anywhere supports transaction processing, with locking features built in to allow concurrent transactions to access the database without corrupting the data. Transactions end either with a COMMIT statement, which makes the changes to the data permanent, or a ROLLBACK statement, which undoes all the changes made during the transaction.

transaction log

A file storing all changes made to a database, in the order in which they are made. It improves performance and allows data recovery in the event the database file is damaged. For best results, the transaction log should be kept on a different device from the database files.

transaction log mirror

An optional identical copy of the transaction log file, maintained simultaneously. Every time a database change is written to the transaction log file, it is also written to the transaction log mirror file.

A mirror file should be kept on a separate device from the transaction log, so that if either device fails, the other copy of the log keeps the data safe for recovery.

See also: transaction log.

transactional integrity

In MobiLink, the guaranteed maintenance of transactions across the synchronization system. Either a complete transaction is synchronized, or no part of the transaction is synchronized.

trigger

A special form of stored procedure executed automatically when a user executes a query that modifies the data.

See also: row-level trigger, statement-level trigger, conflict trigger, integrity.

UltraLite

A deployment technology for Adaptive Server Anywhere databases, aimed at small, mobile, and embedded devices. Intended platforms include cell phones, pagers, and personal organizers.

unique constraint

A restriction on a column or set of columns requiring that all non-null values are different. A table can have multiple unique constraints.

See also: foreign key constraint, primary key constraint, constraint.

unload

Unloading a database exports the structure and/or data of the database to text files (SQL command files for the structure, and ASCII comma-separated files for the data). You unload a database with the Unload utility.

In addition, you can unload selected portions of your data using the UNLOAD statement.

upload

The stage in synchronization where data is transferred from a remote database to a consolidated database.

user-defined data type

A data type that users create to specify a base data type, and optionally a default value, check condition, and nullability. User-defined data types, also called user-defined domains, can be applied to columns to enforce consistency throughout the database.

See also: data type.

validate

To test for particular types of file corruption of a database, table, or index.

view

A SELECT statement that is stored in the database as an object. It allows users to see a subset of rows or columns from one or more tables. Each time a user uses a view of a particular table, or combination of tables, it is recomputed from the information stored in those tables. Views are useful for security purposes, and to tailor the appearance of database information to make data access straightforward.

Windows

The Microsoft Windows family of operating systems, including Windows 95, Windows 98, Windows Me, Windows CE, Windows NT, Windows 2000, and Windows XP.

Windows CE

A family of operating systems produced by Microsoft for mobile devices.

work table

An internal storage area for interim results during query optimization.

write file

A file used to record changes to a read-only database. Often used with compressed databases.

See also: compressed database file.


Web Links Browse Collapse Expand PDF Previous Next

What's New in SQL Anywhere Studio

Version 9.0.2

DC38121-01-0902-01

October 2004

Copyright
About This Manual
Welcome to SQL Anywhere Studio Version 9
What's New in Version 9.0.2
What's New in Version 9.0.1
What's New in Version 9.0.0
What's New in Version 8.0.2
What's New in Version 8.0.1
What's New in Version 8.0.0
What's New in Version 7.0.3
What's New in Version 7.0.2
What's New in Version 7.0.1
What's New in Version 7.0.0
What's New in Version 6.0.3
What's New in Version 6.0.2
What's New in Version 6.0.1
Upgrading Software and Databases
Upgrading Version 5 Applications


About This Manual

Subject

This book describes new features in SQL Anywhere Studio version 9 and in previous releases of the software.

Audience

This manual is for users of previous versions who want to find out what is new and different in this release of the software.

SQL Anywhere Studio documentation
Documentation conventions
The Adaptive Server Anywhere sample database
The CustDB sample database
Finding out more and providing feedback


SQL Anywhere Studio documentation

This book is part of the SQL Anywhere documentation set. This section describes the books in the documentation set and how you can use them.

The SQL Anywhere Studio documentation

The SQL Anywhere Studio documentation is available in a variety of forms: in an online form that combines all books in one large help file; as separate PDF files for each book; and as printed books that you can purchase. The documentation consists of the following books:

  • Introducing SQL Anywhere Studio This book provides an overview of the SQL Anywhere Studio database management and synchronization technologies. It includes tutorials to introduce you to each of the pieces that make up SQL Anywhere Studio.

  • What's New in SQL Anywhere Studio This book is for users of previous versions of the software. It lists new features in this and previous releases of the product and describes upgrade procedures.

  • Adaptive Server Anywhere Database Administration Guide This book covers material related to running, managing, and configuring databases and database servers.

  • Adaptive Server Anywhere SQL User's Guide This book describes how to design and create databases; how to import, export, and modify data; how to retrieve data; and how to build stored procedures and triggers.

  • Adaptive Server Anywhere SQL Reference Manual This book provides a complete reference for the SQL language used by Adaptive Server Anywhere. It also describes the Adaptive Server Anywhere system tables and procedures.

  • Adaptive Server Anywhere Programming Guide This book describes how to build and deploy database applications using the C, C++, and Java programming languages. Users of tools such as Visual Basic and PowerBuilder can use the programming interfaces provided by those tools. It also describes the Adaptive Server Anywhere ADO.NET data provider.

  • Adaptive Server Anywhere SNMP Extension Agent User's Guide This book describes how to configure the Adaptive Server Anywhere SNMP Extension Agent for use with SNMP management applications to manage Adaptive Server Anywhere databases.

  • Adaptive Server Anywhere Error Messages This book provides a complete listing of Adaptive Server Anywhere error messages together with diagnostic information.

  • SQL Anywhere Studio Security Guide This book provides information about security features in Adaptive Server Anywhere databases. Adaptive Server Anywhere 7.0 was awarded a TCSEC (Trusted Computer System Evaluation Criteria) C2 security rating from the U.S. Government. This book may be of interest to those who wish to run the current version of Adaptive Server Anywhere in a manner equivalent to the C2-certified environment.

  • MobiLink Administration Guide This book describes how to use the MobiLink data synchronization system for mobile computing, which enables sharing of data between a single Oracle, Sybase, Microsoft or IBM database and many Adaptive Server Anywhere or UltraLite databases.

  • MobiLink Clients This book describes how to set up and synchronize Adaptive Server Anywhere and UltraLite remote databases.

  • MobiLink Server-Initiated Synchronization User's Guide This book describes MobiLink server-initiated synchronization, a feature of MobiLink that allows you to initiate synchronization from the consolidated database.

  • MobiLink Tutorials This book provides several tutorials that walk you through how to set up and run MobiLink applications.

  • QAnywhere User's Guide This manual describes MobiLink QAnywhere, a messaging platform that enables the development and deployment of messaging applications for mobile and wireless clients, as well as traditional desktop and laptop clients.

  • iAnywhere Solutions ODBC Drivers This book describes how to set up ODBC drivers to access consolidated databases other than Adaptive Server Anywhere from the MobiLink synchronization server and from Adaptive Server Anywhere remote data access.

  • SQL Remote User's Guide This book describes all aspects of the SQL Remote data replication system for mobile computing, which enables sharing of data between a single Adaptive Server Anywhere or Adaptive Server Enterprise database and many Adaptive Server Anywhere databases using an indirect link such as e-mail or file transfer.

  • SQL Anywhere Studio Help This book includes the context-sensitive help for Sybase Central, Interactive SQL, and other graphical tools. It is not included in the printed documentation set.

  • UltraLite Database User's Guide This book is intended for all UltraLite developers. It introduces the UltraLite database system and provides information common to all UltraLite programming interfaces.

  • UltraLite Interface Guides A separate book is provided for each UltraLite programming interface. Some of these interfaces are provided as UltraLite components for rapid application development, and others are provided as static interfaces for C, C++, and Java development.

In addition to this documentation set, PowerDesigner and InfoMaker include their own online documentation.

Documentation formats

SQL Anywhere Studio provides documentation in the following formats:

  • Online documentation The online documentation contains the complete SQL Anywhere Studio documentation, including both the books and the context-sensitive help for SQL Anywhere tools. The online documentation is updated with each maintenance release of the product, and is the most complete and up-to-date source of documentation.

    To access the online documentation on Windows operating systems, choose Start > Programs > SQL Anywhere 9 > Online Books. You can navigate the online documentation using the HTML Help table of contents, index, and search facility in the left pane, as well as using the links and menus in the right pane.

    To access the online documentation on UNIX operating systems, see the HTML documentation under your SQL Anywhere installation.

  • PDF books The SQL Anywhere books are provided as a set of PDF files, viewable with Adobe Acrobat Reader.

    The PDF books are accessible from the online books, or from the Windows Start menu.

  • Printed books The complete set of books is available from Sybase sales or from eShop, the Sybase online store, at [external link] http://eshop.sybase.com/eshop/documentation.


The CustDB sample database

Many of the examples in the MobiLink and UltraLite documentation use the UltraLite sample database.

The reference database for the UltraLite sample database is held in a file named custdb.db, and is located in the Samples\UltraLite\CustDB subdirectory of your SQL Anywhere directory. A complete application built on this database is also supplied.

The sample database is a sales-status database for a hardware supplier. It holds customer, product, and sales force information for the supplier.

The following diagram shows the tables in the CustDB database and how they are related to each other.

The UltraLite sample database, including tables, column names, primary keys, and foreign key relationships.


Finding out more and providing feedback

Finding out more

Additional information and resources, including a code exchange, are available at the iAnywhere Developer Network at [external link] http://www.ianywhere.com/developer/.

If you have questions or need help, you can post messages to the iAnywhere Solutions newsgroups listed below.

When you write to one of these newsgroups, always provide detailed information about your problem, including the build number of your version of SQL Anywhere Studio. You can find this information by typing dbeng9 -v at a command prompt.

The newsgroups are located on the forums.sybase.com news server. The newsgroups include the following:

  • [external link] sybase.public.sqlanywhere.general

  • [external link] sybase.public.sqlanywhere.linux

  • [external link] sybase.public.sqlanywhere.mobilink

  • [external link] sybase.public.sqlanywhere.product_futures_discussion

  • [external link] sybase.public.sqlanywhere.replication

  • [external link] sybase.public.sqlanywhere.ultralite

  • [external link] ianywhere.public.sqlanywhere.qanywhere

Newsgroup disclaimer
iAnywhere Solutions has no obligation to provide solutions, information or ideas on its newsgroups, nor is iAnywhere Solutions obliged to provide anything other than a systems operator to monitor the service and ensure its operation and availability.

iAnywhere Solutions Technical Advisors as well as other staff assist on the newsgroup service when they have time available. They offer their help on a volunteer basis and may not be available on a regular basis to provide solutions and information. Their ability to help is based on their workload.

Feedback

We would like to receive your opinions, suggestions, and feedback on this documentation.

You can e-mail comments and suggestions to the SQL Anywhere documentation team at [external link] iasdoc@ianywhere.com. Although we do not reply to e-mails sent to that address, we read all suggestions with interest.

In addition, you can provide feedback on the documentation and the software through the newsgroups listed above.


Welcome to SQL Anywhere Studio Version 9

About this chapter

This chapter provides a high-level overview of the new features in version 9 of SQL Anywhere Studio.

For a complete listing of new features, see the following:

  • What's New in Version 9.0.2
  • What's New in Version 9.0.1
  • What's New in Version 9.0.0


Overview

SQL Anywhere Studio is a complete relational database management system. It includes the following major components:

  • Adaptive Server Anywhere A self-managing relational database with high reliability, high performance out of the box, and a full range of SQL features. It is available for Windows, Windows CE, Linux, NetWare, and several flavors of UNIX.

  • UltraLite A database system for small devices, including Palm OS, Pocket PC, and Java-based devices. Designed especially for restricted environments, the UltraLite database management system provides full transaction-processing support, a choice of development models, and synchronization with enterprise data stores.

  • MobiLink A synchronization technology for sharing information among relational databases. It integrates physically separate databases into a single information system, maintaining the integrity of transactions across the entire system.

  • SQL Remote A synchronization technology specifically for message-based synchronization. Dial-up links, e-mail, and FTP systems can be used to connect your databases.

SQL Anywhere Studio has many uses in the small and medium business (SMB) market, in mobile computing, and in embedded systems.

  • SMB server As a self-tuning, easy to manage, scalable and secure database server, Adaptive Server Anywhere is an ideal choice for an SMB database server. It scales all the way from handheld devices to databases in the tens of gigabytes accessed by hundreds of concurrent connections.

  • Mobile computing Adaptive Server Anywhere runs well in environments with restricted resources, making it ideal for desktop and laptop use, as well as on Windows CE devices. UltraLite provides a database with an even smaller footprint for Windows CE and Palm OS devices. MobiLink provides a scalable and secure synchronization system that ties many remote databases together into a single integrated system.

  • Embedded systems Adaptive Server Anywhere and UltraLite have self-management features that make them ideal for use in zero-administration environments such as embedded systems. MobiLink's server-initiated synchronization (new in this release) makes it possible to synchronize embedded databases from a central location.

Version 9

SQL Anywhere Studio version 9 brings a host of new features to the product, while maintaining the ease of use and self-management features for which it is known.

Web services and .NET

With this release, SQL Anywhere Studio introduces XML and web services features. A web server is built directly in to the database. A flexible interface lets you retrieve data as XML and store XML data in the database. Integration with Microsoft Visual Studio .NET rounds out the web services offerings.

Version 9 takes advantage of the Microsoft .NET architecture. With the XML and web services features, an ADO.NET provider for Adaptive Server Anywhere, a .NET scripting capability for MobiLink synchronization, and an UltraLite .NET component for development of handheld database applications, SQL Anywhere is built to work with .NET.

Rapid application development for small devices

The UltraLite .NET component is just one of a suite of UltraLite components that makes it easy to develop powerful database applications for small devices. Other components provide integration with rapid application development from a number of tools, including Pocket IE, eMbedded Visual Basic, AppForge MobileVB and Crossfire, and Borland JBuilder.

MobiLink synchronization

MobiLink synchronization ties UltraLite or Adaptive Server Anywhere databases into an enterprise system, using configurable two-way synchronization. In this release, MobiLink provides such enhancements as server-initiated synchronization and file-based downloads.

Performance

Version 9 continues to improve performance in the Adaptive Server Anywhere database. Improved cache management and other internal changes provide scalability to large numbers of users and more processors, and innovative algorithms in the optimizer provide better handling of complex queries. What's more, a 64-bit version of the software is available or planned for Linux, HP-UX, and for 64-bit Windows operating systems.

For those who really need to get the most performance out of their database, a graphical Index Consultant makes performance tuning easy. This is just one feature included in a redesigned Sybase Central administration tool. The new look puts more information within easy reach than ever before, and provides a suite of powerful design and administration tools, including the query editor, and a redesigned stored procedure debugger.


Adaptive Server Anywhere highlights

Here are some of the highlights in this release of the Adaptive Server Anywhere database.

  • Scalability and performance In this release, Adaptive Server Anywhere has taken more major strides in scalability and performance. A redesign of the cache management system makes for much-improved concurrency at high numbers of users. Customers already run Adaptive Server Anywhere with several hundred simultaneous users, and this release looks to raise the bar on the scale that can be handled.

    Query processing has also taken another big step forward. Innovative new algorithms make many queries run in a fraction of the time of previous releases.

    While many of the performance improvement changes are built into the internals of the database server, a new Index Consultant provides administrators with an easy-to-use way of optimizing performance by guiding them through the selection of appropriate indexes.

  • Web services This release sees a web server built right into to the database. You can now access Adaptive Server Anywhere databases over HTTP as well as the usual client/server network protocols. Adaptive Server Anywhere now provides web services, including support for SOAP requests. Close integration into Microsoft Visual Studio .NET makes the development of web services applications straightforward.

  • XML in the database Client applications can now get result sets as XML, or can take XML data and store it in the database in relational form. Developers have control over the format of the XML data, which eases integration into other systems.

  • .NET integration Adaptive Server Anywhere version 9 is built to work with Microsoft's .NET architecture. In addition to the web services and XML features, an ADO .NET provider enables data access from Visual Studio .NET.

  • Even richer SQL Adaptive Server Anywhere's SQL language has been extended to enable you to do more with your data. You can carry out simple OLAP features such as ROLLUP queries, execute recursive union queries to get at hierarchical "bill of materials" data, and carry out set operations such as INTERSECT and EXCEPT.

For a complete list of new features in Adaptive Server Anywhere, see Adaptive Server Anywhere new features.


UltraLite highlights

UltraLite is a relational database for small devices running Palm OS or Windows CE. This version brings the benefits of relational data storage to a wider range of application developers than ever.

  • UltraLite components Components provide integration with popular programming languages and tools. UltraLite now provides components for the following development platforms:

    • An ActiveX component brings UltraLite development to Microsoft eMbedded Visual Basic and Pocket IE (using JavaScript).

    • An AppForge MobileVB component brings UltraLite development to this powerful extension to Visual Basic. AppForge MobileVB brings rapid application development using Visual Basic to both Palm OS and Windows CE devices.

    • A .NET component brings UltraLite development in either C# or Visual Basic to the .NET Framework and .NET Compact Framework.

    • A Native Java component provides a Java development model for small devices.

    • A C++ interface makes features of other UltraLite components accessible to C++ developers, including access to a version of the UltraLite runtime that supports access from multiple applications.

  • Dynamic SQL UltraLite components provide a table-based API for straightforward data access, and also support dynamic SQL for more flexible operations, including multi-table joins.

For a complete list of new features in UltraLite, see UltraLite new features.


MobiLink highlights

  • Server-initiated synchronization In previous releases of the software, synchronization had to be initiated by the client. It is now possible to initiate synchronization from the server, making it possible to push urgent changes to remote databases. Server-initiated synchronization is also ideal when the client database is running in an embedded system.

  • File-based download Synchronization updates can now be distributed as files, enabling offline distribution of synchronization changes.

  • More selective synchronization Adaptive Server Anywhere clients can now choose upload-only and download-only synchronization. In addition, new scripts provide additional control over the synchronization process.

For a complete list of new features in MobiLink, see MobiLink new features.


Administration tools highlights

Sybase Central is the administration tool for Adaptive Server Anywhere databases and MobiLink consolidated databases. This release includes several new features:

  • Interface redesign The interface has been redesigned to bring you more quickly to the information you need.

  • Stored procedure debugger The stored procedure debugger has been integrated into Sybase Central and redesigned for easier use.

  • Faster start-up Quicker start-up times make access to Sybase Central and Interactive SQL more convenient.

For a complete list of new features in the administration tools, see Adaptive Server Anywhere new features.


New feature samples

These and other samples can be found at [external link] http://ianywhere.codexchange.sybase.com/servlets/ProjectDocumentList?folderID=0.


UltraLite samples

The UltraLite samples are located at [external link] http://ianywhere.codexchange.sybase.com/servlets/ProjectDocumentList?folderID=283

UL.NET sample

This sample demonstrates the new UltraLite.NET component. In this sample, you create an UltraLite database based on a .USM (UltraLite schema file). The schema file stores database information such as tables, columns, indexes, and so on. You do not alter the schema of an UltraLite database directly. Instead, you modify a schema file (which typically has the file extension .USM) and upgrade the database schema from that file using a built-in UltraLite function in your application. After the database is created, data is downloaded through MobiLink. Finally, a SQL query, which displays a result set in a list box, is executed.

ULFoundation

ULFoundation was developed as a base platform on which to start the development of a new UltraLite application and as a learning tool. The goal of this project is to help developers understand the portions of an application that directly relate to UltraLite. Platform-specific functionality has been kept to a minimum. The code has been written to be platform-independent where possible. Additional modules are being developed that guide you through adding new features to the basic ULFoundation program. This is an effective tool for demonstrating how UltraLite works and can be used in a variety of applications. There are many ways to go about setting up ULFoundation. Following the instructions in the text files are recommended, but not necessary.

UltraLite Dynamic SQL sample

This sample illustrates the addition of Dynamic SQL queries within the UltraLite Component Suite. For this sample, an application was written using the UltraLite.NET API. During the sample, an application is deployed to a CE device along with a pre-created UltraLite database. From this sample, a user can type in any valid SQL SELECT query and the results appear in a list box.

UltraLite Engine sample

In this sample, two applications (ULapp1 and ULapp2) access the same database on your device using the new multi-process access feature. The first application creates a database. The UltraLite engine starts, allowing you to open the second application, which also connects to the newly created database. The engine remains open as long as at least one of the two applications is open. The engine shuts down automatically when both applications are closed.


MobiLink samples

The MobiLink samples are located at [external link] http://ianywhere.codexchange.sybase.com/servlets/ProjectDocumentList?folderID=319

.NET Remoting sample

.NET remoting enables you to build widely distributed applications easily, whether application components are all on one computer or spread out across the world. You can build client applications that use objects in other processes on the same computer or on any other computer that is reachable over its network. You can also use .NET remoting to communicate with other application domains in the same process.

Reference: [external link] http://msdn.microsoft.com/library/default.asp?url=/library

The following Visual Basic.NET and C# samples use MobiLink to invoke a .NET remoting service. The server.cs/servclass.cs files produce a simple remoting service. This service opens a local port on 1095 and listens to requests. When methods of the remoting service are invoked the remoting server posts messages to the console

ASP.NET sample

ASP.NET is a component of the .NET Framework for building, deploying, and running web applications and distributed applications. ASP.NET provides support for web services through the use of .ASMX files. A web service is a protocol that enables computers to work together by exchanging messages. Web services are based on the standard protocols of XML, SOAP, and WSDL, which allow them to interoperate across platforms and programming languages.

This sample provides integration between MobiLink and ASP.NET through the invocation of web services. In this sample, the file sample.asmx is a sample web service that is copied into IIS home/root directory (likely c:\inetpup\wwwroot). During synchronization, the MobiLink server attempts to invoke ASP.NET, which then attempts to write to a file name data.bin in the IIS home/root directory.

File Sync sample

This sample demonstrates the capabilities of the MobiLink server to send a file that contains a list of changes to be applied to a remote database. The remote database takes this file, applies it, and lets you verify that the changes were applied.


Adaptive Server Anywhere samples

The Adaptive Server Anywhere samples are located at [external link] http://ianywhere.codexchange.sybase.com/servlets/ProjectDocumentList?folderID=282

ADO.NET - Simple XML sample

The Simple XML example provides sample code to obtain XML data from Adaptive Server Anywhere via ADO.NET.

ASP.NET tutorial

This tutorial is intended to give a brief understanding of how to use ASP.NET to access an Adaptive Server Anywhere 9.0 database using ADO.NET. For this example, you can use either Visual Studio.NET 2002 or 2003, with Visual Basic.NET as the development tool. In this tutorial, we walk through all of the steps required to build a sample ASP.NET application to query the Adaptive Server Anywhere database and return the results into a list box all within the browser.

HTTP Server - Show Table sample

This Show Table sample is an example of a web-based administration tool that displays database information, such as:

  • Table list

  • Table contents

  • Web services available

  • Database history

This sample helps illustrate the capabilities of the HTTP server to serve HTML and XML data using XML style sheets. During the demonstration, two Adaptive Server Anywhere web services are created:

  1. show_html_table

  2. show_xml_table

HTTP Server - Simple Select sample

This sample shows how easy it is to create a web service within Adaptive Server Anywhere that takes any SQL query and returns a result set in either HTML or XML format. The SQL commands executed to create this service include:

  • CREATE SERVICE qhtml TYPE 'html' AUTHORIZATION ON USER DBA SECURE OFF

  • CREATE SERVICE qxml TYPE 'xml' AUTHORIZATION ON USER DBA SECURE OFF

When the user enters a URL (for example, http://localhost/websample/qhtml?select * from sysusers), the Adaptive Server Anywhere web server receives the URL and parses the text.

This query is executed and as the qhtml service specifies, it returns the results in HTML format.

HTTP Server - SOAP Dataset sample

This sample illustrates how data returned in a SOAP request from Adaptive Server Anywhere can easily be displayed in a .NET DataGrid component. SOAP is a lightweight protocol for exchange of information in a decentralized, distributed environment. It is an XML-based protocol that consists of three parts:

  • an envelope that defines a framework for describing what is in a message and how to process it

  • a set of encoding rules for expressing instances of application-defined data types

  • a convention for representing remote procedure calls and responses

SOAP can potentially be used in combination with a variety of other protocols; however, the only bindings defined in this document describe how to use SOAP in combination with HTTP and HTTP Extension Framework.

The DataGrid is a commonly used data bound list control available within Visual Studio.NET 2003. The DataGrid displays items from a data source in a table that lets you select, sort, and edit these items. The SOAP request from the application connects to the Adaptive Server Anywhere 9.0 Sample database and the results are returned as a .NET DataSet object. Next, the DataSet is used as the DataSource for the DataGrid component. To walk through the demonstration from scratch using the source code, see the file Walkthrough.doc.


What's New in Version 9.0.2

About this chapter

This chapter provides an overview of the new features and behavior changes introduced in SQL Anywhere Studio version 9.0.2.


New features in version 9.0.2

This section lists the new features introduced in components of SQL Anywhere Studio version 9.0.2.

Adaptive Server Anywhere new features
MobiLink new features
SQL Remote new features
UltraLite new features
QAnywhere new features
Documentation enhancements


Adaptive Server Anywhere new features

This section introduces the new features in Adaptive Server Anywhere version 9.0.2. It provides an exhaustive listing of major and minor new features, with cross references to locations where each feature is discussed in detail.

SQL enhancements

  • UNIQUEIDENTIFIER native data type The UNIQUEIDENTIFIER data type is now a native data type rather than a domain defined on BINARY(16). As a result, Adaptive Server Anywhere automatically carries out type conversions as needed, so that the STRTOUUID and UUIDTOSTR conversion functions are not needed to handle UNIQUEIDENTIFIER values.

    To use the UNIQUEIDENTIFIER data type in databases created before this release, you must upgrade the database file format by unloading and reloading the database.

    For more information, see UNIQUEIDENTIFIER data type [Binary].

  • Conflict function for RESOLVE UPDATE triggers The CONFLICT function can be used in conflict resolution triggers to determine if a particular column is a source of conflict for an UPDATE being performed on a SQL Remote consolidated database.

    For more information, see CONFLICT function [Miscellaneous].

  • Procedure profiling enhancements Profiling information can now be filtered per user and per connection using the sa_server_option stored procedure.

    For more information, see Enabling procedure profiling and sa_server_option system procedure.

  • Remote servers can be tested before they are created or modified The Remote Server Creation wizard in Sybase Central has a Test Connection button that allows you to test whether the connection information supplied in the remote server definition allows you to successfully connect before the remote server is created.

    The Remote Server property sheet in Sybase Central also has a Test Connection button that allows you to test whether you can successfully connect to a remote server if its properties are changed.

    For more information, see Creating remote servers using Sybase Central.

  • INPUT and OUTPUT statements accept the ESCAPES clause The ESCAPES clause allows you to specify that characters are recognized and interpreted as special characters by the database server.

    For more information, see INPUT statement [Interactive SQL] and OUTPUT statement [Interactive SQL].

  • WAITFOR can wake up when it receives a message from another connection The WAITFOR statement can now wake up when it receives a message from another connection using the MESSAGE statement.

    For more information, see WAITFOR statement.

  • Derived tables appear in query plans Derived tables now appear as nodes in query execution plans.

    For more information, see Derived table.

  • ALTER DOMAIN statement The ALTER DOMAIN statement allows you to rename user-defined domains and data types.

    For more information, see ALTER DOMAIN statement.

  • NO RESULT SET clause for procedures Declaring a stored procedure NO RESULT SET can be used when external environments need to know that the stored procedure does not return a result set.

    For more information, see CREATE PROCEDURE statement.

  • Column statistics updated during index creation The CREATE INDEX statement now has the side effect that column statistics are updated for the indexed columns.

    For more information, see CREATE INDEX statement.

Programming interface enhancements

  • PHP module The SQLAnywhere PHP module allows access to Adaptive Server Anywhere databases from the PHP scripting language.

    For more information, see Using the SQLAnywhere PHP module.

  • Web service clients In addition to acting as a web-service provider, Adaptive Server Anywhere can now act as a web-service client, making it possible to create stored procedures and stored functions that access Adaptive Server Anywhere web services, as well as standard web services available over the internet.

    For more information, see Creating web service client functions and procedures.

  • Multiple web service formats supported The format of the WSDL file provided by a DISH service, as well as that of data payloads returned of part of SOAP responses, can now be selected to best suit the needs of the client applications. You can now choose between DNET for Microsoft .NET, CONCRETE for clients that automatically generate interfaces, and a general-purpose XML format.

    For more information, see Creating SOAP and DISH web services.

  • ODBC_DESCRIBE_BINARY_AS_VARBINARY option This option allows you to choose whether you want all BINARY and VARBINARY columns to be described to your application as BINARY or VARBINARY.

    For more information, see ODBC_DESCRIBE_BINARY_AS_VARBINARY [database].

  • New PREFETCH option value The PREFETCH option now has an additional value of ALWAYS. This value means that cursor results are prefetched even for SENSITIVE cursor types and cursors that involve a proxy table.

    For more information, see PREFETCH option [database].

  • db_locate_servers_ex function This function provides programmatic access to the information displayed by the dblocate -n option, listing all the Adaptive Server Anywhere database servers on a specific host.

    For more information, see db_locate_servers_ex function.

Administrative enhancements

  • SNMP Agent Adaptive Server Anywhere can now be monitored from Simple Network Management Protocol (SNMP) applications.

    For more information, see ASA SNMP Extension Agent User's Guide.

  • Deadlock reporting You can now obtain information about connections involved in deadlock using a new database option, LOG_DEADLOCKS, and a new system stored procedure, sa_report_deadlocks. When you turn on the LOG_DEADLOCKS option, the database server records information about deadlocks in an internal buffer. You can obtain deadlock information from this internal buffer by calling sa_report_deadlocks.

    For more information, see Determining who is blocked.

  • New collations The following collations have been added in this release:

    • 1252SWEFIN has been added to support Swedish and Finnish. On Swedish and Finnish systems, the database server will choose 1252SWEFIN as the default collation for a new database if no collation is specified..

    • 1255HEB has been added to support Hebrew. On Hebrew Windows systems, the database server will choose 1255HEB as the default collation for a new database if no collation is specified.

    • 1256ARA has been added to support Arabic. On Arabic Windows systems, the database server will choose 1256ARA as the default collation for a new database if no collation is specified.

    • 950ZHO_HK and 950ZHO_TW have been added to support Chinese. 950ZHO_HK provides support for the Windows Traditional Chinese character set cp950 plus the Hong Kong Supplementary Character Set (HKSCS). The 950ZHO_TW collation provides support for the Windows Traditional Chinese character set cp950, but doesn't support HKSCS. Ordering is based on a byte-by-byte ordering of the Traditional Chinese characters. These collations supercede the deprecated 950TWN collation.

    • 1252SPA has been added to support Spanish. On Spanish Windows systems, the database server will choose 1252SPA as the default collation for a new database if a collation is not specified.

    • 874THAIBIN has been added to support Thai. This is the recommended collation for Thai on both Windows and UNIX systems.

    For more information, see Supplied and recommended collations.

  • New Service Creation (dbsvc) utility options The Service Creation utility (dbsvc) supports the following new options:

    • -cm option This option displays the command used to create the specified service. This may be useful for deploying services, or for restoring them to their original state.

    • -sd option This option allows you to provide a description of the service, which appears in the Windows Service Manager.

    • -sn option This option allows you to provide a name for the service, which appears in the Windows Service Manager.

    For more information, see Service creation utility options.

  • New Data Source (dbdsn) utility options The Data Source utility (dbdsn) supports the following new options:

    • -cm option This option displays the command used to create the specified data source. This may be useful for deploying data sources, or for restoring them to their original state.

    • Driver connection parameter You can use the Driver connection parameter to specify a driver for an ODBC data source when creating data sources using the Data Source utility (dbdsn) on Windows. On UNIX, if you do not specify the Driver connection parameter, the Data Source utility automatically adds a Driver entry with the full path of the Adaptive Server Anywhere ODBC driver based on the setting of the ASANY9 environment variable.

    For more information, see Data Source utility options.

  • Disk full callback support The -fc database server option allows you to specify a DLL containing a callback function that can be used to notify users, and possibly take corrective action, when a file system full condition is encountered.

    For more information, see -fc server option.

  • Validate Database wizard enhancements When you validate a database using the Validate Database wizard in Sybase Central, the wizard indicates the current table being validated, as well as the overall progress of the validation operation. In addition, for databases with checksums enabled, you can validate both tables and checksums at the same time.

    For more information, see Validating a database.

  • Unloading table data in Sybase Central You can now unload data from one or more tables in Sybase Central in one step using the Unload Data dialog.

    For more information, see Using the Unload Data dialog.

  • New columns added to sa_index_density and sa_index_levels Three new columns have been added to the result sets returned by the sa_index_density and sa_index_levels stored procedures: TableId, IndexId, and IndexType. If you want to revert to the old behavior of these stored procedures, you can drop the stored procedure and recreate it with the columns that were included in the result set in previous versions of the software.

    For more information, see sa_index_density system procedure and sa_index_levels system procedure.

  • HISTORY option for BACKUP and RESTORE DATABASE statements The HISTORY option allows you to control whether BACKUP and RESTORE DATABASE operations are recorded in the backup.syb file.

    For more information, see BACKUP statement and RESTORE DATABASE statement.

  • Support for integrated logins using Windows user groups In addition to creating integrated logins for individual users on Windows NT/2000/XP, you can now create integrated login mappings to user groups on Windows NT/2000/XP. It is recommended that you upgrade your database before using this feature.

    For more information, see Creating integrated logins for Windows user groups.

  • Managing the size of the request log The -zn database server option allows you to specify how many request log files should be retained.

    For more information, see -zn server option.

  • Free pages at the end of the transaction log are removed when the file is renamed by a backup Transaction log files are grown in fixed-size increments for better performance. When the transaction log is renamed as part of a backup, the free pages at the end of the log are removed, which helps free up disk space.

  • Remote server connections can now be explicitly closed In previous releases, connections from Adaptive Server Anywhere to remote servers were disconnected only when a user disconnected from Adaptive Server Anywhere. You can now explicitly disconnect Adaptive Server Anywhere from a remote server using the new CONNECTION CLOSE clause of the ALTER SERVER statement.

    For more information, see ALTER SERVER statement.

Security enhancements

  • Initialization files can be obfuscated with dbfhide The File Hiding utility (dbfhide) can now be used to obfuscate the contents of .ini files used by Adaptive Server Anywhere and its utilities.

    For more information, see Hiding the contents of .ini files.

  • FIPS-certified security On all supported Windows platforms except Windows CE, you can now use secure communication with FIPS 140-2 certified software from Certicom.

    For more information, see Starting the database server with transport-layer security.

    Strong database encryption using FIPS140-2 certified software from Certicom is also available on supported 32-bit Windows platforms.

    For more information, see Encrypting a database.

Miscellaneous enhancements

  • New connection properties The following connection properties have been added:

    • ClientPort

    • LoginTime

    • ServerPort

    For more information, see Connection-level properties.

  • Proper formatting Event Viewer messages When deploying Adaptive Server Anywhere databases, you should set a registry entry that controls the formatting of messages in the event viewer.

    For more information, see Deploying database servers.

  • LOG_DEADLOCKS option This option allows you to control whether the database server logs information about deadlocks in an internal buffer. This option can be used with the sa_report_deadlocks procedure to obtain information about deadlock.

    For more information, see LOG_DEADLOCKS option [database].

  • ROLLBACK_ON_DEADLOCK option This option allows you to control whether a transaction is automatically rolled back if it encounters a deadlock.

    For more information, see ROLLBACK_ON_DEADLOCK [database].

  • TEMP_SPACE_LIMIT_CHECK option This option allows you to control what happens when a connection requests more than its quota of temporary file space.

    For more information, see TEMP_SPACE_LIMIT_CHECK option [database].

  • New system stored procedures Several new system stored procedures have been added:

    • sa_rowgenerator procedure The sa_rowgenerator system procedure is provided as an alternative to the RowGenerator table for returning a result set with rows between a specified start and end value.

      You can use this procedure for such tasks as generating a result set with rows for every value in a range or generating test data for a known number of rows in a result set.

      For more information, see sa_rowgenerator system procedure.

    • sa_send_udp stored procedure This procedure sends a UDP packet to the specified address and can be used with MobiLink server-initiated synchronization to wake up the Listener utility (dblsn.exe).

      For more information, see sa_send_udp system procedure.

    • sa_verify_password stored procedure This procedure is used by the sp_password stored procedure to verify the current user's password.

      For more information, see sa_verify_password system procedure.

      For more information, see sa_verify_password system procedure.

  • Maximum cache size on Windows CE In previous releases of SQL Anywhere Studio, the maximum cache size on Windows CE was 32 MB. This limit has been removed and the cache size is now limited by the amount of available memory on the device.

  • New database server options for UNIX The following database server options have been added for UNIX:

    • -uc starts the database server in console mode on UNIX.

      For more information, see -uc server option.

    • -ui attempts to display the Server Startup Options dialog and Server Messages window when you start a database server on Linux and Solaris with X Windows support. If the server cannot find a usable display, the server starts in console mode.

      For more information, see -ui server option.

    • -ux displays the Server Startup Options dialog and Server Messages window when you start a database server on Linux and Solaris with X Windows support.

      For more information, see -ux server option.


MobiLink new features

Following is a list of changes and additions to the software introduced in version 9.0.2.

  • New Redirectors There is a new native Redirector for Apache. In addition, there is now an M-Business Anywhere Redirector. Both are available on Windows, Solaris and Linux.

    See Apache Redirector and M-Business Anywhere Redirector.

  • Protocols can now be configured to ignore specified hosts A new option, ignore, can be used to specify hosts that should be ignored by the MobiLink synchronization server when they connect.

    See ignore in -x option.

  • Prevent clients from waiting to synchronize when the MobiLink server is busy You can now prevent clients from waiting to synchronize when the server is busy.

    For more information, see backlog in -x option

  • Version stored in the consolidated database The SQL Anywhere Studio version and build numbers are now stored in the MobiLink system table ml_property. For these entries, the component_name is ML, the property_set_name is server_info, the property_name is release_version, and the property_value is of the form version.build; for example, 9.0.2.1234.

    For more information about the MobiLink system table, see ml_property.

  • MobiLink synchronization server supports the new uniqueidentifier data type The UNIQUEIDENTIFIER data type is now a native data type rather than a domain defined on BINARY(16). As a result, MobiLink remote databases now automatically carry out type conversions as needed, so that the String to UUID and UUID to String conversion functions are not needed to handle UNIQUEIDENTIFIER values.

    For information about the mapping of this data type to the supported consolidated databases, see DataType Conversions.

Security enhancements

  • FIPS-certified security streams On Windows devices, you can now use secure communication with FIPS 140-2 certified software from Certicom.

    For more information, see Starting the MobiLink synchronization server with transport-layer security.

  • Connection options now shown in output log MobiLink now displays the connection string and options in the output log, with passwords replaced with asterisks.

  • Deprecated security features See MobiLink behavior changes.

MobiLink client enhancements

  • New synchronization setup tool for UltraLite The UltraLite Schema Painter can now generate MobiLink synchronization scripts, as well as database tables and triggers for Adaptive Server Anywhere consolidated databases.

    See The UltraLite Schema Painter and Tutorial: Working with UltraLite Databases.

  • Now easier to delete a remote database and recreate it The first synchronization of an Adaptive Server Anywhere client subscription now always works.

    See Progress offsets.

  • New dbmlsync hook is called when connections to MobiLink fail A new event hook has been added, sp_hook_dbmlsync_connect_failed, that allows you to program ways to recover from failed synchronization connections.

    See sp_hook_dbmlsync_connect_failed.

  • Improved integration of MobiLink clients into HTTP infrastructure You can now synchronize using HTTP when a proxy and/or web server requires RFC 2617 Basic or Digest authentication.

    See:

    • http_password
    • http_userid
    • http_proxy_password
    • http_proxy_userid

    In addition, two new client connection parameters allow you to specify custom HTTP headers and custom cookies. In order to respect session cookies, HTTP clients now recognize all Set-Cookie and Set-Cookie2 HTTP headers that they receive in server replies and will send these cookies back up with all future HTTP requests. If the name of a cookie matches an existing cookie, the client will replace its old value with the new one. Cookies are not remembered between synchronizations: they are discarded at the end of the synchronization.

    See custom_header and set_cookie.

  • Assistance in detecting connection errors MobiLink clients now issue a warning message when invalid connection parameters are specified.

  • Mirror log location When dbmlsync is run on a different machine from the remote database, or when mirror logs are located in a different directory from mirror transaction logs, dbmlsync is now able to automatically delete old log files when you specify the location of old mirror logs using this new extended option.

    See MirrorLogDirectory (mld) extended option.

Server-initiated synchronization enhancements

  • Enhanced functionality for connection-initiated synchronization In addition to _BEST_IP_CHANGED_, Windows Listeners now also generate the internal message _IP_CHANGED_ to help you initiate synchronization when there is a change in connectivity.

    See Connection-initiated synchronization.

  • Listener post action enhancements When you specify Listener post actions, you can now optionally use a Windows message ID to specify the window message, and can optionally use the window title instead of the window class. You can also use single quotes around the window class name or message if your message or title include non-alphanumeric characters such as spaces or punctuation marks.

    See post in The Listener utility.

  • New action variables There are several new action variables:

    • $request_id

    • $best_ip

    • $best_adapter_name

    • $best_adapter_mac

    • $best_network_name

    See Action variables.

  • More device support The Palm Listener now supports Kyocera 7135 and Treo 600 smartphones.

    See Listeners for Palm Devices.


SQL Remote new features

Following is a list of changes and additions to the software introduced in version 9.0.2.

  • Mirror log location When dbremote is run on a different machine from the remote database, or when mirror logs are located in a different directory from mirror transaction logs, dbremote can automatically delete old log files if you specify the location of old mirror logs using the new -ml option.

    For more information, see The Message Agent.

  • Conflict function for RESOLVE UPDATE triggers The CONFLICT function can be used in conflict resolution triggers to determine if a particular column is a source of conflict for an UPDATE being performed on a SQL Remote consolidated database.

    For more information, see CONFLICT function [Miscellaneous].


UltraLite new features

Following is a list of changes and additions to the software introduced in version 9.0.2.

Component new features

  • ADO.NET interface in UltraLite.NET UltraLite.NET now supports the ADO.NET programming interface in the new namespace iAnywhere.Data.UltraLite. ADO.NET provides an industry-standard interface to UltraLite, and also provides an easy migration path to Adaptive Server Anywhere for large applications.

    The ADO.NET interface is recommended over the previous UltraLite.NET interface (iAnywhere.UltraLite namespace), which is now deprecated.

    For more information, see Tutorial: Build an UltraLite.NET Application and iAnywhere.Data.UltraLite namespace.

  • UltraLite for MobileVB enhancements UltraLite for MobileVB now supports Visual Basic .NET programming using AppForge Crossfire.

    For more information, see UltraLite for MobileVB User's Guide.

  • UltraLite for M-Business Anywhere enhancements The following enhancements have been made to UltraLite for M-Business Anywhere:

    • UltraLite for M-Business Anywhere now supports the client/server UltraLite engine. Your application can use the DatabaseManager.runtimeType property to inspect whether the engine or the runtime library is being used.

      See Using the UltraLite engine.

    • UltraLite for M-Business Anywhere applications can now synchronize both data and web content with a single operation.

      See One-button synchronization.

    • You can use a MobiLink Redirector to synchronize both data and web content through a single M-Business Anywhere server. For synchronization from outside firewalls, this reduces the number of ports that need to be accessible.

      See Synchronizing data via M-Business Anywhere and M-Business Anywhere Redirector.

    • M-Business Anywhere 5.5 on Windows XP is now a supported platform. The connection parameters databaseOnDesktop and schemaOnDesktop support this environment.

      See Class ConnectionParms.

    • Additional methods have been added to the API that enable you to gather information about data using the column ID rather than the column name.

      See Class ResultSetSchema and Class TableSchema.

    For more information, see UltraLite for M-Business Anywhere User's Guide.

  • Native UltraLite for Java enhancements The following enhancements have been made to Native UltraLite for Java:

    • Column schema info accessible by columnID instead of just name.

    • New SyncProgressData ErrorMessage property and improved sync error reporting.

    • PreparedStatement.[get]Plan added.

    • ResultSet, ResultSetSchema keep PreparedStatement alive while in use.

    For more information, see Native UltraLite for Java API Reference.

  • UltraLite.NET component enhancements The following functions are supported by UltraLite.NET. It is recommended that these functions be used as part of the ADO.NET interface (iAnywhere.Data.UltraLite namespace).

    • New ULCursorSchema.Name, ULResultSetSchema.Name read-only properties.

    • New ULSyncProgressData ErrorMessage property and improved sync error reporting.

    • ULCommand.Plan read-only property.

    For more information, see iAnywhere.Data.UltraLite namespace.

  • Palm developers can now use a version-independent prefix file In previous releases, the UltraLite prefix file depended on the version of Palm OS for which you were developing. You can now use ulpalmos.h for any version of Palm OS.

    See Using the UltraLite plug-in for CodeWarrior.

  • Palm developers can now use expanded mode CodeWarrior supports a code generation mode called expanded mode, which improves memory use for global data. You can now use an expanded mode version of the UltraLite runtime library.

    For more information, see Building Expanded Mode applications.

  • Trusted certificates can be retrieved from permanent storage In previous releases of the software, the trusted certificate for secure synchronization was embedded in the database schema. On Windows and Windows CE platforms, it can now be stored externally and accessed via the trusted_certificates option.

    For more information, see trusted_certificates and Security Parameters synchronization parameter.

SQL and runtime enhancements

  • Dynamic SQL enhancements The following enhancements have been made to the UltraLite dynamic SQL support:

    • Query optimization improvement In previous versions of the software, the order in which tables were accessed was the order in which they appeared in the query. In this version, UltraLite optimizes the query to find an efficient order in which to access tables. As long as you have defined appropriate indexes in the database, the optimizer helps to improve query execution performance.

      For more information, see Query optimization.

    • Query plan viewing Query access plans now include the index name instead of an index number, for clarity. Access plans can be seen, for example, from the new UltraLite Interactive SQL utility.

    • IF and CASE expressions The range of expressions supported by UltraLite has been extended by adding these two conditional expressions.

      For more information, see IF expressions and CASE expressions.

    • Table names can have owner names UltraLite tables do not have owners. Support has been added for owner.table-name as a convenience for existing SQL and for programmatically-generated SQL. UltraLite accepts but ignores owner.

      For more information, see Dynamic SQL.

  • UNIQUEIDENTIFIER data type introduced The UNIQUEIDENTIFIER data type is now a native data type rather than a domain defined on BINARY(16). As a result, UltraLite automatically carries out type conversions as needed, so that the String to UUID and UUID to String conversion functions are not needed to handle UNIQUEIDENTIFIER values.

    For more information, see UNIQUEIDENTIFIER data type [Binary].

  • UltraLite query plan descriptions enhanced UltraLite query plan descriptions, which can be viewed in UltraLite Interactive SQL, have been enhanced to be easier to read for better diagnosis of performance issues.

    For more information, see Query optimization.

Administration enhancements

  • UltraLite Interactive SQL utility An UltraLite Interactive SQL utility is now provided for testing SQL statements against UltraLite databases and for modifying UltraLite data. It also displays query plans so that you can diagnose performance problems.

    For more information, see The UltraLite Interactive SQL utility and Tutorial: Working with UltraLite Databases.

  • Command line utilities for database management A set of command line utilities makes database management tasks easier for UltraLite files on Windows machines. These utilities are particularly useful during application development.

    Each of the new utilities carries out a subset of the tasks that the ulconv utility provides. In future versions of the software, the ulconv utility will be replaced by these newer single-task utilities.

    For more information, see:

    • The ulcreate utility
    • The ulload utility
    • The ulsync utility
    • The ulunload utility
Synchronization enhancements

  • Improved integration of MobiLink clients into HTTP infrastructure Two new client connection parameters allow you to specify custom headers and custom cookies.

    For more information, see custom_header and set_cookie.

  • Synchronization script generation from the Schema Painter The UltraLite Schema Painter now provides the ability to generate synchronization scripts for Adaptive Server Anywhere consolidated databases. This capability makes it easier to extend UltraLite applications to a synchronized architecture.

    For more information, see The UltraLite Schema Painter and Tutorial: Working with UltraLite Databases.

  • Synchronization notifications on referential integrity violations Support synchronization callback functions to report referential integrity violations - currently, rows that fail RI are silently deleted.

    For more information, see Referential integrity and synchronization.


QAnywhere new features

  • Failover servers The QAnywhere agent now can take a list of MobiLink server connection protocol options rather than just one.

    See Setting up a failover mechanism.

  • Emulator support QAnywhere client applications on the Pocket PC 2002 and Pocket PC 2003 now support x86 emulators. Only "scheduled" policy for the QAnywhere Agent is supported on these emulators.

  • New RDBMSs supported as server message stores All supported MobiLink consolidated databases can now be used in QAnywhere applications as server message stores: Adaptive Server Anywhere, Adaptive Server Enterprise, Microsoft SQL Server, Oracle, and DB2.

  • QAnywhere .NET client library for the .NET Compact Framework now supports message listeners. QAnywhere .NET client library for the .NET Compact Framework now supports message listeners.

Transmission rule enhancements

  • Remote message store properties now synchronized When you set remote message store properties, those properties are now synchronized to the server message store so that they can be used in transmission rules.

    For more information, see Custom client store properties.

  • Enhanced message store properties The ias_Network property now contains fields you can use to access detailed network information.

    See Client store properties.

    In addition, you can now create customized message store properties.

    See Custom client store properties.

  • Rules for deleting messages You can now specify transmission rules for the persistence of messages in the message stores. You can delete messages on the client side and server side.

    For more information, see Transmission rules.

QAnywhere Agent enhancements

  • Connection string To start the local message store, you can now specify a connection string with the qaagent -c option. This allows you to use Adaptive Server Anywhere connection string parameters.

    See -c option.

  • Quiet mode The QAnywhere Agent now supports two flavors of quiet mode, which can avoid problems on some Windows CE devices.

    See -q option and -qi option.

  • QAstop utility When you start the QAnywhere Agent in quiet mode with the -qi option, you must use the new qastop utility to stop it.

    See -qi option.

  • Enhanced verbosity You can now specify output log file names with the -o or -ot option, and regulate the size of the output files with the -os and -ot options. In addition, the -v option replaces the old -verbose option. With -v, you have greater control over logging output.

    See:

    • -o option
    • -ot option
    • -on option
    • -os option
    • -v option

  • Initialize database for use as a remote message store You can use the new qaagent -si option to set up a remote message store. For more information, see -si option.

  • Upgrade from version 9.0.1 The QAnywhere Agent has a new option, -su, that upgrades a remote message store from version 9.0.1 to 9.0.2.

    See -su option.

QAnywhere MobiLink system tables

All QAnywhere MobiLink system tables are now owned by ml_qa_user_group. Previously, they were owned by DBO.

Two new MobiLink system tables have been added. For more information, see:

  • ml_qa_delivery

  • ml_qa_delivery_client

There are changes to the schema of several MobiLink system tables. For more information, see:

  • ml_qa_global_props

  • ml_qa_global_props_client

  • ml_qa_repository

  • ml_qa_repository_client

  • ml_qa_repository_props

  • ml_qa_repository_client

The following MobiLink system tables are not generated for 9.0.2 clients:

  • ml_qa_repository_staging_client

  • ml_qa_status_staging_client

The following MobiLink system table is not generated for 9.0.2 servers:

  • ml_qa_repository_content


Documentation enhancements

This section introduces enhancements made to the appearance, organization, or navigation of the Adaptive Server Anywhere documentation for version 9.0.2. It provides an exhaustive listing of major changes.

New documentation

The documentation for existing features has been enhanced in several areas, including the following:

  • SNMP Agent documentation A new book has been added that describes the Adaptive Server Anywhere SNMP Agent.

    See The Adaptive Server Anywhere SNMP Extension Agent .

  • Windows CE starting points A chapter containing starting points for Windows CE users has been added.

    See SQL Anywhere Studio for Windows CE.

  • DBTools interface to the MobiLink synchronization client A sample and other information about how to use dbmlsync from DBTools has been added.

    See DBTools Interface for dbmlsync.

  • QAnywhere enhancements The QAnywhere documentation has been expanded, with new information about how to integrate messaging with JMS messaging systems and MobiLink data synchronization, and enhanced information about setting up QAnywhere applications.

    See QAnywhere User's Guide.

  • Server-initiated synchronization SDKs The documentation for the SDKs has been expanded, and a new section on the Palm Listener SDK has been added.

    See MobiLink Listener SDKs.

Documentation enhancements

  • MobiLink reorganization The MobiLink books have been reorganized so that there is now a client guide, an administration guide, and a book of tutorials. As well as covering Adaptive Server Anywhere clients, the client guide includes synchronization parameters and synchronization connection parameters for UltraLite clients, which were previously in the UltraLite Database User's Guide.

  • UltraLite API and QAnywhere API references The UltraLite.NET, UltraLite C++ API, QAnywhere .NET, and QAnywhere C++ API material is now available in the same form as the remainder of the documentation. As a result, it is available as PDF as well as in the HTML-based documentation.


Behavior changes in version 9.0.2

This section lists the behavior changes introduced in components of SQL Anywhere Studio version 9.0.2. It also lists deprecated features, which are supported in the current software but will not be supported in the next major release of SQL Anywhere Studio.

Deprecated feature lists subject to change
As with all forward-looking statements, the lists of deprecated features are not guaranteed to be complete and are subject to change.

Adaptive Server Anywhere behavior changes
MobiLink behavior changes
SQL Remote behavior changes
UltraLite behavior changes
QAnywhere behavior changes

Previous Next


Adaptive Server Anywhere behavior changes

Deprecated and discontinued features

The following is a list of features that are no longer supported or are deprecated, and that may impact existing applications.

  • MIN_TABLE_SIZE_FOR_HISTOGRAM option removed The database server no longer uses the MIN_TABLE_SIZE_FOR_HISTOGRAM option. In previous versions of the software, this option allowed you to specify the minimum table size for which histograms were created. Now Adaptive Server Anywhere automatically creates histograms for all tables with five or more rows. You can create histograms for all tables, regardless of size, using the CREATE STATISTICS statement.

    For more information, see Updating column statistics.

  • Deprecated database options The following database options are no longer supported:

    • TRUNCATE_DATE_VALUES

    • ASSUME_DISTINCT_SERVERS

  • Old database formats deprecated In the next major release of SQL Anywhere Studio, databases created under old versions of the software will not be supported. Migration tools will be provided.

  • Non-threaded DBTools library for UNIX deprecated The non-threaded DBTools library for UNIX (libdbtool9.so) is deprecated: it is fully supported in the current software but will not be supported in the next major release of SQL Anywhere Studio.

  • 950TWN collation no longer supported The 950TWN has been superceded by the following collations: 950ZHO_HK and 950ZHO_TW.

    For more information, see Supplied and recommended collations.

Other behavior changes

The following is a list of behavior changes from previous versions of the software.

  • Restrictions on the Transaction Log utility (dblog) when removing the transaction log When removing a transaction log using the -n option, you must also specify the corresponding ignore transaction log offset option (-il for the Log Transfer Manager, -ir for SQL Remote, or -is for dbmlsync).

    For information, see Transaction log utility options.

  • Database utilities running in quiet mode When performing any of the following operations with the –q option (quiet mode) specified, you must also specify the –y option:

    • modifying or deleting a service with the Service Creation (dbsvc) utility

    • modifying or deleting a datasource with the Data Source (dbdsn) utility

    • erasing a file with the Erase (dberase) utility

    • translating a transaction log with the Log Translation (dbtran) utility

  • Certificate name and password must be supplied when using ECC_TLS or RSA encryption The default values for the certificate, certificate_password, and trusted_certificates parameters have been removed. These defaults utilized the sample certificates that are provided in the win32 directory of your SQL Anywhere Studio installation. The sample certificates are useful only for testing and development purposes and do not provide security.

    In addition, the -ec all server option is no longer supported.

    For more information, see -ec server option.

  • -xs server option change The -xs all server option is no longer supported to listen for web requests on both HTTP and HTTPS ports.

    For more information, see -xs server option.

  • TCP/IP port number must be specified for network database servers on Mac OS X, HP-UX, and Tru64 when the default port is not in use If you are starting a database server on Mac OS X, HP-UX, or Tru64, you must specify a port number using the ServerPort [PORT] protocol option if the default port (2638) is already in use or if you do not wish to use the default port.

    For more information, see ServerPort protocol option [PORT].

  • Dbspace file names are changed for databases unloaded and reloaded with the Unload utility (dbunload) When a database is unloaded and reloaded using the -an option of the Unload utility (dbunload), the dbspace file names for the new database have an R appended to the end of the file name. This is done to prevent naming conflicts when the new dbspace files are placed in the same directory as the original dbspace files. Dbspace file names also have an R appended to the file name when you unload and reload data using the Unload Database wizard in Sybase Central.

    For more information, see Unload utility options.

  • Property functions now return LONG VARCHAR values Previously, the following functions returned a VARCHAR(254) value. They now return a VARCHAR(maxpropsize) value, where maxpropsize is based on the maximum page size specified for the server.

    • CONNECTION_PROPERTY

    • DB_EXTENDED_PROPERTY

    • DB_PROPERTY

    • EVENT_PARAMETER

    • PROPERTY

  • STRTOUUID function change In previous releases, if STRTOUUID was passed an invalid UUID value it returned NULL. It now returns a conversion error unless the CONVERSION_ERROR option is set to OFF, in which case it returns NULL.


MobiLink behavior changes

The following is a list of behavior changes from previous versions of the software.

Security behavior changes

  • HTTP+TLS security deprecated in favor of HTTPS Transport-layer security is deprecated for clients connecting over HTTP. To use transport-layer security over HTTP, you should use HTTPS.

    For information about server-side security, see Starting the MobiLink synchronization server with transport-layer security.

    For information about client-side security, see Configuring MobiLink clients to use transport-layer security.

  • Certificate name and password must be supplied when using ECC_TLS or RSA encryption with MobiLink The default values for the certificate, certificate_password, and trusted_certificates synchronization parameters have been removed. These defaults utilized the sample certificates that are provided in the win32 directory of your SQL Anywhere Studio installation. The sample certificates are useful only for testing and development purposes and do not provide security.

    For more information, see -x option.

Other MobiLink behavior changes

  • No polling interval for UDP listening On the Listener, there is now no polling interval for UDP connections. The Listener processes messages immediately.

    For more information, see -I option in The Listener.

  • Support for MobiLink Palm Listener on Treo 180 and Kyocera 6035 smartphones deprecated For information about supported devices for the Palm Listener, see Listeners for Palm Devices.


SQL Remote behavior changes

Deprecated and discontinued features

The following is a list of features that are no longer supported or are deprecated, and that may impact existing applications.

  • SQL Remote for Adaptive Server Enterprise deprecated In the next major release of SQL Anywhere Studio, SQL Remote for Adaptive Server Enterprise will not be present. MobiLink provides a more flexible and scalable solution for data synchronization between Adaptive Server Enterprise and Adaptive Server Anywhere databases.

Other behavior changes

The following is a list of behavior changes from previous versions of the software.

  • The Extraction (dbxtract) utility When extracting a remote database with dbxtract, if the –q option (quiet mode) is specified, you should also specify the –y option so that dbxtract will automatically replace the existing command file without confirmation.

    For more information, see The extraction utility.

  • IPM_Receive message control parameter The default value for the MAPI IPM_Receive message control parameter has been changed to YES. Setting this value to YES ensures that both IPC and IPM messages are picked up by SQL Remote.

    For more information, see The MAPI message system.


UltraLite behavior changes

The next major release of UltraLite will enhance development using industry standard APIs and will enhance development using the component model as opposed to the original static interfaces. These changes will have several benefits for users, including making it easier to develop applications using UltraLite.

As a result of these plans, several UltraLite APIs are deprecated with this release, meaning that they continue to be fully supported in the current software but will not be supported in the next major release. Assistance in migrating applications that use deprecated interfaces will be provided in the next major release.

As with all forward-looking statements, the list of deprecated and discontinued features provided here is subject to change.

Deprecated and discontinued features

The following features are deprecated or discontinued.

  • Static interfaces deprecated The next major release of SQL Anywhere Studio will not support the static C++ API or the static Java API. An embedded SQL interface will be available, but not through the current generated code mechanism.

  • UltraLite.NET component interface to be superseded by ADO.NET In this release, UltraLite.NET supports ADO.NET development in the new iAnywhere.Data.UltraLite namespace. ADO.NET provides the benefits of an industry standard interface and of an easy migration path to Adaptive Server Anywhere for large applications. The UltraLite.NET component API (iAnywhere.UltraLite namespace) is deprecated in this release and will not be provided in the next major release.

  • Native UltraLite for Java component interface to be superseded by JDBC The current Native UltraLite for Java interface is scheduled to be superseded by a JDBC interface.

Other behavior changes

The following is a list of behavior changes from previous versions of the software.

  • New warning for referential integrity deletes during download UltraLite automatically deletes rows as needed to maintain referential integrity during download. It now raises a warning for each row deleted in this way.

    For more information, see Referential integrity and synchronization.

  • Native UltraLite for Java behavior changes Cursor.getRowCount() method has been changed to return an int. No application changes are required.

  • UltraLite.NET component behavior changes Cursor.getRowCount() method has been changed to return an int. No application changes are required.

  • Handling invalid synchronization parameters In previous releases, the UltraLite runtime ignored all invalid synchronization parameters. Misspelled parameters were therefore ignored and a default value used instead.

    In this release, if the runtime encounters an invalid parameter, synchronization fails and the SQL code SQLE_UNRECOGNIZED_OPTION is set. If an error callback has been provided, it will be called once for each invalid parameter. Duplicates continue to be ignored.

  • New libraries for secure synchronization The security options for synchronization have been moved into separate libraries. If you use either of the ULSecureCerticomTLSStream or ULSecureRSATLSStream security options for encrypted synchronization, you must now link separately against a corresponding static library, or ship a separate DLL.

    For more information, see Security synchronization parameter.

  • UltraLite for MobileVB integration with Crossfire If you have existing projects that use the UltraLite for MobileVB integration with Crossfire from an earlier version of the software, you must change the reference to Interop.UltraLiteAFLib.dll to iAnywhere.UltraLiteForAppForge.dll.

    For more information, see Tutorial: A Sample Application for AppForge Crossfire.


QAnywhere behavior changes

Deprecated and discontinued features

  • QAnywhere Agent options The following QAnywhere Agent (qaagent) options have been deprecated and replaced.

    Deprecated qaagent option... | Replaced with qaagent option...
    -agent_id id | -id id
    -dbauser user | -c "UID=user"
    -dbeng name | -c "ENG=name"
    -dbfile filename | -c "DBF=filename"
    -dbname name | -c "DBN=name"
    -ek key | -c "DBKEY=key"
    -password password | -c "PWD=password"
    -sv | -c "Start={ dbeng9 | dbsrv9 }"
    -verbose | -v[levels]

    In addition, the following qaagent options are no longer required and have been deprecated:

    • -e
    • -rb

    For more information, see QAnywhere Agent syntax.

  • QAnywhere Agent no longer creates the client message store You must now create the message store database yourself before running qaagent. There is a new option, -si, that initializes the database with system objects that are required by QAnywhere.

    See Setting up the client message store.

Other behavior changes

  • QAnywhere client library message overhead is reduced The ias_MessageType property is no longer set for regular messages. It is still set for network status and other system messages that are sent to the system queue.


What's New in Version 9.0.1

About this chapter

This chapter provides an overview of the new features and behavior changes introduced in SQL Anywhere Studio version 9.0.1.


New features in version 9.0.1

This section lists the new features introduced in components of SQL Anywhere Studio version 9.0.1.


Adaptive Server Anywhere new features

This section introduces the new features in Adaptive Server Anywhere version 9.0.1. It provides an exhaustive listing of major and minor new features, with cross references to locations where each feature is discussed in detail.

OLAP enhancements

  • OLAP query extensions A set of online analytical processing (OLAP) features enable more detailed analysis of the data in your database. The enhancements include the ability to add subtotal rows into result sets in a flexible way using CUBE and using GROUPING SETS, as well as windowing functions that provide rolling averages and other advanced features.

    Support for these OLAP features is built in to the Query Editor, which lets you build queries that use ROLLUP, CUBE, and GROUPING SETS operations.

    For more information, see the following:

    • Using OLAP
    • Using ROLLUP
    • Using CUBE
    • Using GROUPING SETS
    • Working with OLAP functions Using CUBE

  • New statistical functions Several statistical functions have been added.

    For more information, see:

    • COS function [Numeric]
    • COVAR_POP function [Aggregate]
    • COVAR_SAMP function [Aggregate]
    • CUME_DIST function [Aggregate]
    • DENSE_RANK function [Aggregate]
    • PERCENT_RANK function [Aggregate]
    • RANK function [Aggregate]
    • REGR_AVGX [Aggregate]
    • REGR_AVGY [Aggregate]
    • REGR_COUNT [Aggregate]
    • REGR_INTERCEPT [Aggregate]
    • REGR_R2 [Aggregate]
    • REGR_SLOPE [Aggregate]
    • REGR_SXX [Aggregate]
    • REGR_SXY [Aggregate]
    • REGR_SYY [Aggregate]
    • ROW_NUMBER function [Aggregate]

  • New string functions The following string functions have been added:

    • BASE64_DECODE function [String]
    • BASE64_ENCODE function [String]
    • COMPRESS function [String]
    • DECOMPRESS function [String]
    • DECRYPT function [String]
    • ENCRYPT function [String]
    • HASH function [String]
Statement enhancements

  • LOAD TABLE enhancements The LOAD TABLE statement now has a clause that allows you to limit the statistics that are created, allowing faster table loading. It also has a SKIP option that allows you to ignore the first few lines of a file.

    For more information, see LOAD TABLE statement.

  • SELECT ... INTO base-table This new SELECT syntax creates a base table and fills that table with data from a query.

    For more information, see SELECT statement.

  • Extended support for variables in SQL statements Several statements have been made more flexible by permitting variables as well as constants in some locations. This is especially useful in stored procedures and batches, where variables can be declared and used. It provides functionality previously only available, in more cumbersome form, in EXECUTE IMMEDIATE.

    The following statements have this extended support for variables:

    • The TOP clause of the SELECT statement can now reference integer variables as well as constants. See SELECT statement.

    • BACKUP statement backup-directory and archive-root. See BACKUP statement.

    • RESTORE statement filename, archive-root, and new dbspace-name. See RESTORE DATABASE statement.

    • LOAD TABLE statement filename. See LOAD TABLE statement.

    • UNLOAD statement and UNLOAD TABLE statement filename. See UNLOAD statement and UNLOAD TABLE statement.

  • SET statement enhancement The SET statement now accepts the option ANSI_NULLS (equivalent to the ANSINULLS option) for compatibility with Microsoft SQL Server.

    For information, see SET statement [T-SQL].

  • ALTER TABLE statement enhancement ALTER TABLE can now add a NOT NULL column with a default value to a non-empty table. This feature provides increased flexibility when modifying existing tables.

    For more information, see ALTER TABLE statement.

  • ALTER VIEW statement enhancements The ALTER VIEW statement now supports a RECOMPILE clause that allows you to re-create view definitions when the columns in the underlying tables are modified.

    For more information, see ALTER VIEW statement.

  • MESSAGE statement enhancements A FOR CONNECTION clause has been added to the MESSAGE statement.

    Also, a DEBUG ONLY clause has been added to the MESSAGE statement. When the DEBUG_MESSAGES option is set to ON, debugging messages appear for all stored procedures and triggers that contain a MESSAGE statement that includes the DEBUG ONLY clause.

    For more information, see MESSAGE statement and DEBUG_MESSAGES option [database].

Security enhancements

  • Database page checksums Database page checksums are used to detect whether a database page has been modified on disk. When a database is created with checksums enabled, a checksum is calculated for each page before it is written to disk. When a page is read from disk, its checksum is calculated again and compared to the stored checksum. If the values are different, the page has been modified or otherwise corrupted while on disk. Existing databases must be unloaded and reloaded into a database with checksums enabled to use this feature. You can check whether checksums are enabled for a database using the Checksum property.

    For more information about creating databases with checksums, see CREATE DATABASE statement, The Initialization utility, and Database-level properties.

    Checksums can also be used to validate a database.

    For more information, see VALIDATE CHECKSUM statement, The Validation utility, and sa_validate system procedure.

Performance enhancements

Many enhancements have been made to provide better performance for a wide range of tasks, including complex queries. Some of these enhancements are purely internal. Others are listed here:

  • Parallel index scans On volumes with multiple disk spindles, such as hardware or software RAID arrays, the query optimizer can now scan tables using an index in parallel.

    For more information, see Parallel index scans.

  • Clustered Hash Group By algorithm For better performance, the Adaptive Server Anywhere query optimizer can use a new algorithm that is particularly useful for certain classes of GROUP BY queries where the HAVING clause returns a small proportion of rows.

    For more information, see Clustered Hash Group By algorithm, and OPTIMIZATION_WORKLOAD option [database].

  • Database server cache warming Three new database server command line options have been added to support cache warming. Cache warming is designed to help reduce the execution times of the initial queries executed against a database by pre-loading the database server's cache with database pages that were referenced the last time the database was started. Using cache warming can improve performance when the same queries are executed against the database each time it is started.

    For more information, see -cc server option, -cr server option, -cv server option, and Using cache warming.

  • Optimizer hints WITH (XLOCK) is a new table hint feature in the FROM clause. XLOCK indicates that rows processed by the statement from the hinted table are to be locked exclusively. The affected rows remain locked until the end of the transaction. It works at all isolation levels.

    The WITH INDEX hint forces the optimizer to use a specified index during query optimization. This is an advanced feature that may lead to poor performance if used incorrectly, and so should be used by experienced users only.

    For more information, see FROM clause and Use indexes for frequently-searched columns.

  • Increased default stack size for internal execution threads on NetWare The default stack size for internal execution threads on NetWare has been increased to 128K.

    For more information, see -gss server option.

Programming interface enhancements

  • Perl interface The Perl new DBD::ASAny driver for the Perl DBI module allows you to access and modify Adaptive Server Anywhere databases from Perl scripts.

    For more information, see The DBD::ASAny Perl Interface.

  • InstallShield projects SQL Anywhere studio now includes InstallShield Merge Module Projects and Object Projects. These projects allow InstallShield to generate Merge Modules and Objects with which you can redeploy the software currently installed on your machine. Previous versions of SQL Anywhere included the Merge Modules and Objects. These allowed you to redeploy the original software, but provided no convenient means of deploying after you had applied an EBF.

    For more information, see Using InstallShield for deployment

Administration enhancements

  • BACKUP enhancements The BACKUP statement now includes an ON EXISTING ERROR clause for image backups. When this clause is specified, an error occurs if any of the files to be created during the backup already exist.

    The archive backup form of the BACKUP statement has been extended to support options previously available only with image backups.

    For more information, see BACKUP statement.

    The Backup utility can now create a backup on the server machine. Previously, the utility could only create backups on the client machine.

    The Backup utility.

  • Unload utility (dbunload) enhancements The Unload utility now automatically handles view dependencies when unloading databases. The -j option that was used in previous versions of the software to output view definitions multiple times to the reload.sql file has been deprecated. Now, the Unload utility automatically handles unloading view definitions that depend on other views.

    The Unload utility also allows you to change the database page size when unloading into a new database.

    For more information, see Unloading a database using the dbunload command-line utility.

  • Server Location (dblocate) utility enhancements The Server Location [dblocate] utility now allows you to supply a host name or IP address to limit the search for database servers to a specific machine. As well, it supports a -n option that specifies that IP addresses are not to be resolved into machine names, which results in better performance.

    For more information ,see The Server Location utility.

  • Adaptive Server Anywhere Console utility supports integrated logins When you connect to the Adaptive Server Anywhere Console [dbconsole] utility on Windows NT/2000/XP, the Connect dialog allows you to use an integrated login to connect to the database.

    For more information, see Connect dialog: Identification tab.

  • The request log file size can be changed without restarting the database server On starting the database server, you can specify the size of the request log file with the -zs server option. You can use the sa_server_option system procedure to change the size of the request log file without restarting the database server.

    For more information, see sa_server_option system procedure.

  • Additional information added for profiling system triggers The sa_procedure_profile system procedure and sa_procedure_profile_summary system procedure now return extra information about system triggers when procedure profiling is turned on in the database.

    For more information, see sa_procedure_profile system procedure and sa_procedure_profile_summary system procedure.

  • New system table A new system table has been added that maintains information about the different versions of the software and platforms a database has been started with.

    For more information, see SYSHISTORY system table.

  • New collations There are two new collations available: one to support Lithuanian (1257LIT, ANSI Code Page 1257) and one to support Turkish (1254TRKALT). This Turkish collation considers I-dot and I-no-dot equal.

    For more information, see Supplied and recommended collations and Alternative Turkish collation 1254TRKALT.

  • DEDICATED_TASK option When specified, a request handling task is dedicated to handling requests from a single connection. This pre-established connection allows you to gather information about the state of the database server if it becomes otherwise unresponsive.

    For more information, see DEDICATED_TASK option [database].

Interactive SQL enhancements

  • Interactive SQL allows you to specify the encoding used to read and write files The Interactive SQL READ, INPUT, and OUTPUT statements now support an optional encoding clause that allows you to specify the character encoding that is used to read or write the file. The DEFAULT_ISQL_ENCODING option has been added to allow you to specify the character encoding that is used for subsequent READ, INPUT, and OUTPUT statements.

    For more information, see DEFAULT_ISQL_ENCODING option [Interactive SQL], READ statement [Interactive SQL], INPUT statement [Interactive SQL], and OUTPUT statement [Interactive SQL].

    You can also specify the character encoding used to read or write the file when using the Interactive SQL import and export wizards.

    For more information, see Importing and Exporting Data and Export wizard.

  • Interactive SQL supports integrated logins When you connect to Interactive SQL on Windows NT/2000/XP, the Connect dialog allows you to use an integrated login to connect to the database.

    For more information, see Connect dialog: Identification tab.

  • Interactive SQL allows you to configure the font used for displaying result sets You can choose the font, font style, and point size for data that appears in the Results pane in Interactive SQL.

    For information about configuring the Results pane in Interactive SQL, see Options dialog: Results tab.

  • Interactive SQL allows you to specify the initial folder used for file browsing When browsing for files in Interactive SQL, you can specify whether Interactive SQL uses the current directory (as defined by the operating system) for the initial directory, or the last folder where a file was opened.

    For more information, see Options dialog: General tab.

Sybase Central enhancements

  • Sybase Central allows you to configure the font used for displaying result sets You can choose the font, font style, and point size for data that appears on the Data tab in Sybase Central when a table is selected.

    For information about configuring the Data tab in Sybase Central, see Plug-in Preferences dialog: Table Data tab.

  • Remote Server Creation wizard now supports creating external login for current user The Remote Server Creation wizard now allows you to create an external login for the current user so that you do not have to create an external login before you create the remote server.

    For more information, see Creating remote servers using Sybase Central.

  • Sybase Central supports integrated logins When you connect to Sybase Central on Windows NT/2000/XP, the Connect dialog allows you to use an integrated login to connect to the database.

    For more information, see Connect dialog: Identification tab.

  • Columns can be sorted using the View menu in Sybase Central The Sybase Central View menu has a Sort item that allows you to sort columns in the right pane as an alternative to clicking the column headings in the right pane.

  • Foreign key settings can be modified from the foreign key property sheet You can change foreign key settings in Sybase Central from the Foreign Key property sheet.

    For more information, see Change Settings dialog.

  • Proxy Table wizard now displays primary key column information Previously, when creating a proxy table using the Proxy Table wizard, there was no way to determine which columns belonged to the remote table's primary key. Now, the columns in the primary key are identified in the wizard.

  • Utility wizards can be cancelled The Upgrade Database wizard, Backup Database wizard, Restore Database wizard, Validate Database wizard, Compress Database wizard, Uncompress Database wizard, and the Create Backup Images wizard can be cancelled. They also include a messages dialog that displays status information about whether the operation has succeeded or failed.

  • Sybase Central supports account names of the form domain\user when creating and editing services The Service Creation wizard and Service property sheet now allow you to enter account names of the form domain\user when creating and editing services. You can enter the account name in the Other Account field on the Account tab of the Service property sheet or in the Service Creation wizard.

Miscellaneous enhancements

  • Database server uses asynchronous I/O on Linux platforms When running the database server on Linux, the database server uses asynchronous I/O by default when possible. The -ua database server option allows you to turn off the use of asynchronous I/O.

    For more information, see -ua server option.

  • OPENXML supports equality predicates The OPENXML function allows you to use equality predicates in the XPath expression. This feature allows you to locate nodes within the XML document using attribute values.

    For more information, see OPENXML function [String].

  • TransactionStartTime connection property This property returns the time the database was first modified after a COMMIT or ROLLBACK.

    For more information, see Connection-level properties.

  • UserAppInfo property This property returns the portion of a connection string specified with the AppInfo connection parameter.

    For more information, see Connection-level properties.

  • ConsoleLogFile server property This property returns the name of the file where messages from the database server window are logged when the -o server option is specified.

    For more information, see Server-level properties.

  • DriveType database property for UNIX platforms The DriveType database property has been extended to UNIX platforms.

    For more information, see Database-level properties.

  • Connection IDs start at 1 and are incremented for each new connection to the database server When the database server is started, each connection to the server is assigned a connection ID, starting with 1, and the connection number is incremented with each new connection to the server. The connection IDs are logged in the -z server output and the LOGFILE connection parameter output. They are also used by the CONNECTION_PROPERTY, NEXT_CONNECTION, NEXT_DATABASE, and DROP CONNECTION functions, and by request logging.

    For more information, see CONNECTION_PROPERTY function [System], NEXT_CONNECTION function [System], NEXT_DATABASE function [System], and Request logging.

  • Improved cache management on NetWare and UNIX When the cache size specified with -c is greater than the amount of available memory on UNIX or NetWare, the database server now calculates the maximum cache size based on available memory.

    For more information about how the database server calculates the maximum cache size in these circumstances, see -c server option.

  • ODBC_DISTINGUISH_CHAR_AND_VARCHAR option The ODBC_DISTINGUISH_CHAR_AND_VARCHAR option controls how the Adaptive Server Anywhere ODBC driver describes CHAR columns.

    For more information, see ODBC_DISTINGUISH_CHAR_AND_VARCHAR option [database].


MobiLink new features

Following is a list of changes and additions to the software introduced in version 9.0.1.

  • QAnywhere messaging MobiLink QAnywhere provides application-to-application messaging capabilities. It allows you to write applications that exchange messages with remote applications located on a variety of devices running on Windows or Windows CE operating systems.

    For more information, see QAnywhere User's Guide.

  • External authentication MobiLink user authentication has been enhanced so that you can easily authenticate users using LDAP servers and other external sources such as POP3 e-mail servers.

    For more information, see Authenticating to external servers.

  • New MobiLink system tables There are several new MobiLink system tables. The existence of new MobiLink system tables means that you need to upgrade your Adaptive Server Anywhere databases and run upgrade scripts for other consolidated databases.

    For more information, see MobiLink System Tables.

  • Configurable script versions You can use the new ml_property MobiLink system table to store properties for script versions.

    For more information, see ml_property and ml_add_property.

  • iAnywhere ODBC drivers There is now an iAnywhere ODBC driver for DB2 available on Windows. This is a wire protocol driver, so DB2 client software is not required.

    For more information, see Introduction to iAnywhere Solutions ODBC Drivers.

  • IBM DB2 setup scripts have version numbers Multiple versions of the MobiLink synchronization server can now use the same DB2 server instance. This is possible because the two Java class files that MobiLink uses for DB2 stored procedures now include the SQL Anywhere Studio version number. For the 9.0.1 release they are called SyncDB2_901.class and SyncDB2Long_901.class.

    For more information, see IBM DB2 consolidated database.

  • New -us server option A new server option improves performance by preventing MobiLink from invoking unnecessary table scripts.

    For more information, see -us option.

  • ActiveSync provider now generates an activity log file The ActiveSync provider can now generate a log of its activities.

    For more information, see ActiveSync provider installation utility.

Adaptive Server Anywhere client enhancements

  • Improved application integration for Adaptive Server Anywhere clients A new integration component for dbmlsync provides an easier and more customizable way to create applications with Adaptive Server Anywhere remote databases on Windows platforms.

    For more information, see Dbmlsync Integration Component.

  • Resuming failed downloads You can now avoid lengthy retransmission of data when downloads fail for both Adaptive Server Anywhere and UltraLite remote databases. After a partial transmission of a download, failed downloads may be resumed.

    For more information, see Resuming failed downloads.

  • Transaction-level uploads for Adaptive Server Anywhere clients You can now choose to preserve transactions on the remote database in your upload, and you can do this per synchronization.

    For more information, see -tu option.

  • New way to specify extended options You can use the new hook sp_hook_dbmlsync_set_extended_options to programmatically customize the behavior of an upcoming synchronization.

    For more information, see sp_hook_dbmlsync_set_extended_options.

Server-initiated synchronization

  • Automatic device tracking Automated device tracking simplifies the Notification process.

    For more information, see Device tracking.

  • Sybase Central configuration You can now configure notification using the Sybase Central MobiLink plug-in.

    For more information, see Setting properties.

  • Optional delivery confirmation You can now configure your notification so that a confirmation is automatically sent to the consolidated database when a message is received.

    For more information, see The Listener utility.

  • New Listener options The Listener has several new command line options, including the ability to listen on more than one channel at a time.

    For more information, see The Listener.

  • Palm configuration There is now a Palm Listener configuration utility (dblsncfg) that simplifies configuration of Palm devices.

    For more information, see Listeners for Palm Devices.

MobiLink Monitor

  • Exporting Monitor data Monitor data can now be exported to a relational database or Excel file.

  • Enhanced information in Monitor You can now customize which columns are shown in the table. In addition, there are new columns containing information that was previously available only from synchronization property sheets, and a new column to uniquely identify synchronizations for a Monitor session.

  • Improved sorting Sorting for the Monitor table has been improved. The sort order is now maintained when data is added or updated.

  • Enhanced user interface There are new menus and tool bar buttons to zoom in, zoom out, or zoom to selection in the chart. In addition, pausing now controls whether the chart automatically scrolls.

For more information, see MobiLink Monitor.

New web server support

  • Redirector supports Apache web servers There is a new native Redirector for Apache web servers. Tomcat is no longer a requirement if you want to use an Apache web server.

    For more information, see Synchronizing Through a Web Server With the Redirector.


UltraLite new features

UltraLite 9.0.1 introduces several new features:

  • UltraLite.NET controls A set of controls are added to your Visual Studio.NET 2003 toolbox to make it easier to specify connection parameters and to monitor synchronization from UltraLite.NET applications.

    For more information, see Tutorial: Build an UltraLite.NET Application.

  • UltraLite for M-Business Anywhere. A new component is available for iAnywhere M-Business Anywhere, previously known as AvantGo M-Business Server.

    For more information, see UltraLite for M-Business Anywhere User's Guide.

  • CREATE and DROP statements in dynamic SQL CREATE/DROP TABLE and CREATE/DROP INDEX statements are now available in dynamic SQL. For users of UltraLite components, these statements provide a way of changing the schema of an UltraLite database.

    For more information, see CREATE INDEX statement, and CREATE TABLE statement.

  • Transaction control from dynamic SQL COMMIT and ROLLBACK statements are now available in dynamic SQL. For users of UltraLite components, these statements provide a way of using SQL statements to control transactions. They provide an alternative to the commit and rollback methods on the connection object.

    For more information, see COMMIT statement, and ROLLBACK statement.

  • Dynamic SQL SELECT enhancements Subqueries can be used in search conditions in the WHERE clause or the HAVING clause. They can also be used as derived tables in the FROM clause.

    For more information, see SELECT statement and Dynamic SQL search conditions.

    The HAVING clause is now supported. See SELECT statement.

  • ODBC interface to UltraLite UltraLite now supports a subset of the ODBC programming interface.

    For more information, see Tutorial: Build an Application Using ODBC, and UltraLite ODBC API Reference.

  • Mixing C++ interfaces The UltraLite C/C++ based interfaces (embedded SQL, the static C++ API, and the C++ Component) may be used in the same application.

    Of particular interest is adding C++ Component dynamic SQL to an existing embedded SQL or static C++ API application, or using embedded SQL to execute general SQL in a primarily C++ Component-based application.

    For more information, see Combining UltraLite C/C++ interfaces. The new functions include db_start_database function (embedded SQL) and StartDatabase method.

  • CodeWarrior stationery for UltraLite C++ component The stationery Palm OS UltraLite C++ Component App is provided as part of the UltraLite plug-in for CodeWarrior. It assists in building C++ Component applications using CodeWarrior for Palm OS.

    The files for the UltraLite plug-in for CodeWarrior are placed on your disk during UltraLite installation, but the plug-in is not available for use without an additional installation step.

    For more information, see Developing UltraLite applications with Metrowerks CodeWarrior.

  • Improved UltraLite C/C++ error handling An error callback is now supported for all UltraLite C/C++ interfaces. The callback allows the application to be notified of all errors, and so provides developers with invaluable information during development.

    For more information, see ULRegisterErrorCallback function and Callback function for ULRegisterErrorCallback.

  • UltraLite components can use the engine The UltraLite database engine, which can accept connections from more than one application, is now available to UltraLite components as an alternative deployment option.

    This option is not available to UltraLite for MobileVB or UltraLite ActiveX.

    For more information about the UltraLite engine, see Using the UltraLite engine.

  • Database conversion tool The ulconv utility is a command line tool for carrying out numerous operations on UltraLite databases, including unloading databases to XML files, loading new databases from XML files, and converting database formats.

    For more information, see The ulconv utility.

  • Additional synchronization progress event An additional event is available to the synchronization observer, when an error has occurred and the downloaded changes are being rolled back.

    For more information, see the ULSyncState structure or object for the API you are using.

  • Schema upgrade monitoring Schema upgrades can be a long operation. New schema upgrade events provides a mechanism for applications to monitor the progress of a schema upgrade.

    For more information, see Monitoring schema upgrades.

  • Restartable downloads UltraLite can now restart downloads that fail due to communications errors or user cancellation through the synchronization observer.

    For more information, see Resuming failed downloads.

  • New Windows CE platform support UltraLite now supports the Smartphone 2002 platform. ActiveSync synchronization is not supported on this platform.

    UltraLite also supports Windows CE 4.1 on ARM chips in V4T ("thumb") mode.

    For more information, see UltraLite target platforms.

  • Multi-database support UltraLite components can address multiple databases from a single application by issuing multiple connection requests specifying different database filenames or creator IDs.

    There are some extensions to the connection parameters as a result of this feature.

    For more information, see Database Name connection parameter.

  • ULPalmLaunch and ULPalmExit no longer required UltraLite now supports additional connection-related primitives that provide easier support for maintaining state when an application is closed. As a result of these new features, Palm OS applications no longer require special Palm-specific primitives, including ULPalmLaunch and ULPalmExit.

    For more information, see Saving state in UltraLite Palm applications, Maintaining state in UltraLite Palm applications and Connecting to a database.

  • UltraLite database properties Properties of the UltraLite database are now available to UltraLite component applications. The case sensitivity, collation, and database ID used for global autoincrement values are all available as properties or methods of the Connection object, depending on the API.


Documentation enhancements

This section introduces enhancements made to the appearance, organization, or navigation of the Adaptive Server Anywhere documentation for version 9.0.1. It provides an exhaustive listing of major changes.

New documentation

  • MobiLink Server-Initiated Synchronization The MobiLink server-initiated synchronization feature has been moved into its own book.

    For more information, see MobiLink Server-Initiated Synchronization User's Guide.

  • QAnywhere Messaging There is now a book describing the new MobiLink messaging application, QAnywhere.

    For more information, see QAnywhere User's Guide

  • New MobiLink tutorials There are new tutorials describing how to use Java and .NET scripting logic with Adaptive Server Anywhere remote databases.

    For more information, see Tutorial: Java Synchronization Logic With Adaptive Server Anywhere and Tutorial: .NET Synchronization Logic With Adaptive Server Anywhere.

  • New chapter describing the dbmlsync integration component For more information, see Dbmlsync Integration Component.

  • Combined UltraLite C/C++ books The documentation for UltraLite C/C++ interfaces (embedded SQL, Static C++ API, and the C++ Component) has been combined into a single book, together with the new ODBC interface.

    See UltraLite C/C++ User's Guide.

  • UltraLite for M-Business Anywhere The new UltraLite for M-Business Anywhere component has its own book.

    See UltraLite for M-Business Anywhere User's Guide.

Documentation enhancements

  • Adaptive Server Anywhere Getting Started and Introducing SQL Anywhere Studio books merged The Adaptive Server Anywhere Getting Started and Introducing SQL Anywhere Studio books have been merged into one book. The new book is called Introducing SQL Anywhere Studio.

  • Enhanced PDF books Some people find PDF to be a useful alternative to HTML-based online books, particularly for conceptual material. The PDF version of the online books is now installed by default, and can be accessed from the Windows start menu or from the online books by clicking the PDF item at the top of each topic.

    The PDF files feature clickable links not only within a book, but to other books and to material on web sites. The behavior of these features depends on whether you read the files from within a browser plugin or directly from Acrobat Reader. For the best experience, use Acrobat Reader directly.

  • Help on help A new section describes the differences between the online books in Windows HTML Help format, and the online books in PDF format. It also describes how to use the various help features to navigate the documentation and access the information you are looking for.

    For more information, see Accessing information online .


Behavior changes in version 9.0.1

This section lists the behavior changes introduced in components of SQL Anywhere Studio version 9.0.1.


Adaptive Server Anywhere behavior changes

Deprecated and discontinued features

This list includes features that are no longer supported or are deprecated, and that may impact existing applications.

  • MDSR encryption discontinued Previously, both MDSR and AES strong encryption were supported in Adaptive Server Anywhere. Currently, the only type of strong encryption now supported is AES encryption. This change means that the -ea option is no longer required when using encryption with the Initialization utility, the Extract utility, or the Unload utility. It also removes the algorithm parameter from both the Create Database statement and the Create Encrypted File statement.

  • Write files deprecated The use of write files is deprecated with this release.

    See The Write File utility (deprecated) and CREATE WRITEFILE statement (deprecated).

  • Compressed database files deprecated The use of compressed database files is deprecated with this release.

    See The Compression utility (deprecated) and CREATE COMPRESSED DATABASE statement (deprecated).

  • Unload utility (dbunload) -j option deprecated As a result of enhancements to the Unload utility, the -j Unload utility option is no longer supported.

  • Language utility (dblang) -d option deprecated The -d option for the Language utility, which was used to change the Adaptive Server Anywhere registry setting, is no longer supported.

Other behavior changes

The following is a list of behavior changes from previous versions of the software.

  • CURRENT_TIMESTAMP and CURRENT_USER special values added The CURRENT_TIMESTAMP (equivalent to CURRENT TIMESTAMP) and CURRENT_USER (equivalent to CURRENT USER) special values have been added for compatibility with Microsoft SQL Server.

    For more information, see CURRENT TIMESTAMP special value and CURRENT USER special value.

  • db_start_engine returns SQLCODE 0 if database server is already running db_start_engine now returns non-zero and sets the SQLCODE to 0 if the database server is already running. Previously, db_start_engine returned non-zero, but set the SQLCODE to SQLE_ENGINE_ALREADY_RUNNING.

    For more information, see db_start_engine function.

  • db_start_database returns non-zero and SQLCODE 0 if database is already running db_start_database now returns non-zero and set the SQLCODE to 0 if the database is already running. Previously, db_start_database returned 0 (indicating failure) and set the SQLCODE to SQLE_ALIAS_CLASH.

    For more information, see db_start_database function and db_start_database function.

  • Default algorithm changed for the validation utility The Validation utility (dbvalid) now uses the express check -fx option) algorithm by default. The express check algorithm performs significantly faster for large tables that have several indexes where the table does not completely fit in the server's cache. You can specify the -fn option if you wish to use the validation algorithm that was used in previous versions of Adaptive Server Anywhere.

    For more information, see Validating a database using the dbvalid command-line utility.

  • Entering multibyte characters in the Connect dialog In order to conform to Windows security practices, you can no longer use an Input Method Editor (IME) to type Japanese and other Asian language multibyte characters in the Password field of the Connect dialog used in Sybase Central, Interactive SQL, and the Adaptive Server Anywhere Console utility.

    If you have an existing database that includes these characters in passwords, you can type your password in the Additional Connection Parameters field on the Advanced tab of both the Connect dialog and the ODBC Configuration dialog. However, you should note that when the password is typed on the Advanced tab, it is not obscured and is visible in plain text. When upgrading your database, it is recommended that you change your passwords so they do not include multibyte characters.

  • Owner name cannot be specified in DECLARE LOCAL TEMPORARY TABLE statements In previous versions of the software, if an owner name was specified in DECLARE LOCAL TEMPORARY TABLE and the owner was not the same as the current user, it was possible to create more than one temporary table with the same name. A syntax error now occurs if an owner name is specified.

  • MIN_TABLE_SIZE_FOR_HISTOGRAM option default setting changed The MIN_TABLE_SIZE_FOR_HISTOGRAM option specifies the minimum table size for which histograms are created. The default value has been changed to 100 rows. In previous versions of the software, the default value was 1 000 rows. This setting can be changed in databases created with earlier versions of the software using the SET OPTION statement.

  • NULL constants data type conversion change In previous versions, when converting a NULL constant to a CHAR, VARCHAR, LONG VARCHAR, BINARY, VARBINARY, or LONG BINARY type, the size of the column would be initialized to 32767 if no length was provided. Now, the size is initialized to 0.

    For example, the following queries previously returned a column described as length 32767:

    SELECT CAST( NULL AS CHAR )
-- This now returns a CHAR(0) column
    SELECT 'abc'
UNION ALL
SELECT NULL
-- This now returns a CHAR(3) column
    SELECT ''
UNION ALL
SELECT NULL
-- This now returns a CHAR(0) column
    SELECT IF 1=1 THEN 'abc' ELSE NULL ENDIF
-- This now returns a CHAR(3) column

  • UPDATE statements and errors when ORDER BY clauses use ordinal values UPDATE statements containing an ORDER BY clause that uses ordinal values now return a syntax error.

  • Restrictions on identifiers You can no longer use double backslashes or double quotes in identifiers. Backslashes are permitted in identifiers only if used as an escape character.

    For more information, see Identifiers.

  • EXECUTE IMMEDIATE statement default setting WITH RESULT SET clause The EXECUTE IMMEDIATE statement can return a result set when you specify the WITH RESULT SET ON clause. The default setting is WITH RESULT SET OFF.

    For more information, see EXECUTE IMMEDIATE statement [SP].


MobiLink behavior changes

The following is a list of behavior changes from previous versions of the software.

  • Change in the order hooks are called The order in which event hooks are called has been changed. This means that incremental uploads are now more efficient, as the upload events are the only part of the synchronization sequence that is repeated for each incremental update.

    For more information, see Synchronization event hook sequence.

  • Fix to row-wise partitioning for publications for Adaptive Server Anywhere clients Publications containing a WHERE clause now only replicate rows that meet the WHERE condition. From versions 8.0.0 through 9.0.0, a bug existed that caused rows to be replicated when the WHERE clause evaluated to an unknown value. For example, if a publication WHERE clause had "WHERE val = 1", rows where val was NULL would also be replicated. This bug affected both SQL Remote and ASA MobiLink clients.


UltraLite behavior changes

The following is a list of behavior changes from previous versions of the software.

  • Palm OS state management For Palm OS applications using embedded SQL or the static C++ API, the ULPalmExit (ULData::PalmExit) and ULPalmLaunch (ULData::PalmLaunch) functions are no longer needed to manage state and synchronization information, and are now deprecated. The ULData and ULConnection Reopen methods are also deprecated.

    Applications on Palm OS now use the same sequence of initialization, connection, and closing functions as other applications. The ULSetSynchInfo method controls HotSync synchronization.

    For more information, see Adding HotSync synchronization to Palm applications.

  • Palm OS 3.0 no longer supported The earliest version of supported in this release is Palm OS 3.5.

  • ULEnableGenericSchema function deprecated UltraLite C/C++ applications that require schema upgrades no longer need to call ULEnableGenericSchema. Instead, use the function ULRegisterSchemaUpgradeObserver.

    For more information, see Monitoring schema upgrades.

  • UltraLite components Table API The Delete method of the Table object no longer automatically refreshes the row after deleting. To maintain previous behavior, refetch the row using Relative(0) after the Delete operation.

  • Native UltraLite for Java casting of column IDs and parameter IDs no longer required All methods that accepted column IDs and parameter IDs, and some methods that accepted other short-typed parameters have been changed to accept integers. This eliminates the need for casting numeric constants in your code. For example, instead of table.getString( (short)1 ); you can now use table.getString( 1 );.

    As a result of this change, Native UltraLite for Java applications must be recompiled to work with 9.0.1 software. No code changes are required.


What's New in Version 9.0.0

About this chapter

This chapter provides an overview of the new features and behavior changes introduced in SQL Anywhere Studio version 9.


New features in version 9.0.0

This section lists the new features introduced in components of SQL Anywhere Studio version 9.0.


Adaptive Server Anywhere new features

This section introduces the new features in Adaptive Server Anywhere version 9.0. It provides an exhaustive listing of major and minor new features, with cross references to locations where each feature is discussed in detail.

Highlighted new features

  • XML support Adaptive Server Anywhere 9.0 includes a broad range of support for XML, including storing XML documents, exporting relational data as XML, importing XML, and returning XML from queries on relational data.

    • FOR XML clause The SELECT statement supports a FOR XML clause with three modes, RAW, AUTO, and EXPLICIT, that allow you to obtain query results as an XML document. Each mode allows you a different level of control over the format of the XML that is generated.

      For more information, see Obtaining query results as XML and SELECT statement.

    • FOR_XML_NULL_TREATMENT option You can use the FOR_XML_NULL_TREATMENT option to control how NULL values are returned by a query that includes the FOR XML clause.

      For more information, see FOR_XML_NULL_TREATMENT option [database].

    • OPENXML procedure For more information, see OPENXML function [String].

    • SQL/XML support SQL/XML is a draft standard that describes the ways SQL can be used in conjunction with XML. As part of its SQL/XML support, Adaptive Server Anywhere includes an XML data type that can be used to store XML documents in the database.

      For more information, see XML data type [Character].

      Adaptive Server Anywhere also supports the following SQL/XML functions that provide an alternative method to the FOR XML clause for generating XML documents from your relational data:

      • XMLAGG function This aggregate function generates a forest of XML elements from a collection of XML elements.

        For more information, see XMLAGG function [String].

      • XMLCONCAT function This function generates a forest of XML elements by concatenating together the XML values that are passed in to it.

        For more information, see XMLCONCAT function [String].

      • XMLELEMENT function This function generates an XML element for which you can optionally specify element content, attributes, and attribute content.

        For more information, see XMLELEMENT function [String].

      • XMLFOREST function This function generates a forest of XML elements.

        For more information, see XMLFOREST function [String].

      • XMLGEN function This function generates an XML value based on an XQuery Constructor.

        For more information, see XMLGEN function [String].

  • HTTP server in the database Adaptive Server Anywhere database servers can now act as web servers, allowing you to write and run web-based applications using only an Adaptive Server Anywhere database and a web browser of your choice.

    This feature allows the database server to handle standard HTTP and HTTPS requests, as well as standard SOAP requests. Service types available are HTTP, HTTPS, XML, RAW, SOAP, and DISH. DISH is a SOAP service handler.

    To gain the benefits of this enhancement on databases created before this release, you must upgrade the database using the Upgrade utility.

    For more information, see Using Web Services.

  • Index Consultant The Index Consultant is a tool to assist you in proper selection of indexes. It analyzes either a single query or a set of operations, and recommends indexes to add to your database and to remove from the database.

    To gain the benefits of this enhancement on databases created before this release, you must upgrade the database using the Upgrade utility.

    For more information, see Index Consultant overview.

  • 64-bit version available A full 64-bit version of the software is available for Windows Server 2003 on Itanium II chips. A deployment release is available on 64-bit Linux and HP-UX operating systems.

    For details of platform support, see SQL Anywhere Studio Supported Platforms.

SQL enhancements

  • The WITH clause can now be used before a select to specify common table expressions Common table expressions are temporary view definitions that exist only within the scope of a SELECT statement. They can be recursive, or non-recursive. They sometimes let you write queries in a more elegant manner. They also permit you to perform multiple levels of aggregation within a single query. They can be used only within a top-level SELECT statement, within the top-level SELECT statement within a view definition, or within the top-level statement within an INSERT statement.

    For more information, see Common Table Expressions.

  • Recursive union can now be performed using a common table expression of a particular form Recursive common table expressions allow you to write recursive queries. These are particularly useful when querying tables that represent hierarchical data structures or directed graphs. Each recursive common table expression contains an initial subquery, which is executed first, and a recursive subquery. The A reference to the view, which must appear within the FROM clause of the recursive subquery, references the rows added to the view during the previous iteration. You must be particularly careful to provide conditions that stop the recursion if the data structure you are querying may contain cycles.

    For more information, see Recursive common table expressions.

  • INTERSECT and EXCEPT operations are now supported These operations compute the intersection and difference between two or more result sets. They complement the UNION operation.

    For more information, see the following:

    • Using EXCEPT and INTERSECT

    • Set operators and NULL

    • EXCEPT operation

    • INTERSECT operation

  • SELECT statements can operate on stored procedure result sets In SELECT statements, a stored procedure call can now appear anywhere a base table or view is allowed.

    If you want statistics on stored procedure calls to be stored, you must upgrade the database using the Upgrade utility. Without statistics, you may get bad plans if you try to join the result of a stored procedure call.

    For more information, see FROM clause.

  • Online analytical processing features added Several OLAP features have been added to the allowed SQL language:

    • ROLLUP operation For queries with a GROUP BY clause, the ROLLUP operation adds subtotal rows into the result set. Each subtotal row provides an aggregate over a set of rows in the GROUP BY result set.

      For more information, see Using ROLLUP

    • The LIST function can include ordered lists The LIST function has been extended to provide sorted lists of items.

      For more information, see LIST function [Aggregate].

    • Additional aggregate functions Functions have been added to compute sample-based and population-based standard deviations and variances.

      For more information, see Aggregate functions.

  • The CREATE INDEX statement permits an index to be created on a built-in function This feature is a convenience method that adds a new computed column to a table, and creates an index on that column.

    For more information, see CREATE INDEX statement, and Creating indexes.

  • ORDER BY clause allowed in all contexts In previous releases, many SELECT statements in view definitions, in subqueries, or in UNION operations were not allowed to use an ORDER BY clause. This restriction has now been removed.

    In some cases, particularly when combined with the FIRST or TOP clause, using a SELECT with an ORDER BY clause does affect the results of a view definition or a set operation. In other contexts, the ORDER BY clause is allowed but makes no difference to the operation.

  • SELECT statements can now include START AT as part of the TOP clause START AT provides additional flexibility in queries that explicitly limit the result set.

    For more information, see SELECT statement.

  • Constraints can now be named Check constraints, unique constraints, and referential integrity constraints can now be assigned names. This permits modification of table and column constraints by changing individual constraints, rather than by modifying an entire table constraint.

    To gain the benefits of this enhancement on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

    For more information, see ALTER TABLE statement, CREATE TABLE statement, and Using table and column constraints.

  • Lateral derived tables permit outer references in the FROM clause Outer references can now be made from derived tables and from stored procedures in the FROM clause. To indicate that an outer reference is being made, the LATERAL keyword is used.

    For more information, see FROM clause.

  • EXECUTE IMMEDIATE allows more flexible escape character processing A new option WITH ESCAPES OFF allows escape character processing to be suppressed. This feature makes it easier to construct dynamic statements that include file paths.

    For more information, see EXECUTE IMMEDIATE statement [SP].

  • EXECUTE IMMEDIATE supports queries that return result sets This new feature allows more dynamic construction of statements inside stored procedures.

    For more information, see Using the EXECUTE IMMEDIATE statement in procedures, and EXECUTE IMMEDIATE statement [SP].

  • CREATE FUNCTION and ALTER FUNCTION now permit Transact-SQL syntax You can now create user-defined functions in the Transact-SQL dialect that return a scalar value to the calling environment.

    For more information, see CREATE FUNCTION statement.

  • Values of autoincrement columns are now available when inserting multiple rows When inserting rows through a value-sensitive (keyset driven) cursor, the newly inserted rows appear at the end of the cursor result set.

    A consequence of this change is that the value of an autoincrement column for the most recent row inserted can be found by selecting the last row in the cursor. For example, in embedded SQL the value could be obtained using FETCH ABSOLUTE -1 cursor-name.

    For more information, see Modifying rows through a cursor.

  • Remote Data Access now handles UUID/GUID columns Remote Data Access can now manage SQL Server unique identifier columns.

    For more information, see Data type conversions: Microsoft SQL Server, and UNIQUEIDENTIFIERSTR data type [Character].

  • Remote Data Access now names remote connections Remote Data Access connections made via ODBC are now given names, so that they can be dropped.

    For more information, see Managing remote data access connections.

  • New function returns data type of an expression The EXPRTYPE function returns the data type of an expression.

    For more information, see EXPRTYPE function [Miscellaneous].

  • EXIT statement enhanced The Interactive SQL EXIT statement can now set an exit code for Interactive SQL.

    For more information, see EXIT statement [Interactive SQL].

  • OUTPUT statement accepts ASIS keyword When ASIS is specified, values are written to the file without any escaping.

    For more information, see OUTPUT statement [Interactive SQL].

  • Indexes and foreign keys can be altered The ALTER INDEX statement allows indexes and foreign keys to be renamed. It also allows an index type to be changed to clustered or nonclustered for user-created indexes as well as primary or foreign key indexes.

    To gain the benefits of clustered indexes on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

    For more information, see ALTER INDEX statement.

  • Multiple distinct aggregates permitted in queries Aggregate functions can take DISTINCT column-name as an argument. In previous versions of the software, only one aggregate function with a DISTINCT argument could be included in a query. Now, multiple such functions can be used. The following query is permitted in version 9, but not in earlier versions of the software:

    SELECT count( DISTINCT first_name ),
       count( DISTINCT last_name )
FROM contact

  • Full length and abbreviated day names are recognized in all supported languages for event schedules When creating events, the database server recognizes both full-length and abbreviated day names in any of the languages supported by Adaptive Server Anywhere. Previously, schedules in non-English languages required full day names.

    For more information, see CREATE EVENT statement.

  • Hide procedure text to keep your logic confidential You can obscure the logic contained in stored procedures, functions, triggers and views using the SET HIDDEN option. This allows applications and databases to be distributed without revealing the logic in stored procedures, functions, triggers, and views.

    To gain the benefits of this enhancement on databases created before this release, you must upgrade the database using the Upgrade utility.

    For more information, see Hiding the contents of procedures, functions, triggers and views.

Administration and scalability enhancements

  • The Validation utility gives more detailed return codes The Validation utility (dbvalid) gives more specific return codes to indicate the reason a failure occurs.

    For more information, see Validating a database using the dbvalid command-line utility.

  • Two new server properties Two new server properties have been added. CommandLine gives you the line that was used to start the server, and CompactPlatformVer gives a condensed version of the PlatformVer server property.

    For more information, see Server-level properties.

  • New sp_remote_primary_keys stored procedure In order to obtain primary key information about remote tables using remote data access, a new stored procedure called sp_remote_primary_keys has been added.

    To gain the benefits of this enhancement on databases created before this release, you must upgrade the database using the Upgrade utility.

    For more information, see sp_remote_primary_keys system procedure.

  • New connection_property returns the name of the communication link for the connection The new CommNetworkLink connection property returns the name of the communication link for the connection.

    For more information, see Connection-level properties.

  • NetWare now supports full character set conversion In 8.x, NetWare supported single-byte-to-single-byte character set conversion, but in 9.0, all character sets supported by the other platforms are also supported on NetWare.

    For more information, see -ct server option.

  • Unload utility can unload column lists The Unload utility (dbunload) can now unload the column list for the LOAD TABLE statements that it generates in the reload.sql file, facilitating easier reordering of the columns in a table

    For more information, see The Unload utility.

  • Database server registers with LDAP The database server can now register itself with an LDAP server, so that clients and the Locate Utility (dblocate) can query the LDAP server to find it. This allows clients running over a WAN or through a firewall to find servers without specifying the IP address to find such servers. LDAP is only used with TCP/IP, and only on network servers.

    For more information, see Connecting using an LDAP server or LDAP protocol option [LDAP].

  • Improved handling of a large number of connections The liveness timeout value now increases automatically when there are more than 200 connections in an effort to better handle a large number of connections.

    For more information, see -tl server option and LivenessTimeout connection parameter [LTO].

  • Request log filtering, host variable support Output to the request log can now be filtered to include only requests from a specific connection or for a specific database. As well, host variable values can now be output to a request log.

    For more information, see sa_server_option system procedure, Monitoring and Improving Performance, sa_get_request_times system procedure, and -zr server option.

  • BACKUP statement and dbbackup allow renaming of log copy You can use the BACKUP statement and the Backup utility [dbbackup] to rename the log copy.

    For more information, see The Backup utility and the BACKUP statement.

  • START DATABASE statement allows log truncation on checkpoint and read-only mode The START DATABASE statement now allows a database to be started either with log truncation on checkpoint enabled, or in read-only mode.

    For more information, see START DATABASE statement [Interactive SQL].

  • Adaptive Server Anywhere supports different auditing options In previous versions of Adaptive Server Anywhere, you could choose to turn auditing on or off. Now you can specify which options you want to audit.

    For more information, see sa_disable_auditing_type or sa_enable_auditing_type.

  • Three new values can be passed to the event_parameter function Three new values can be passed to the event_parameter function. ScheduleName returns the name of the schedule which fired the event. AppInfo returns the value of the connection_property('AppInfo') for the connection which caused the event. DisconnectReason returns a string indicating why the connection terminated.

    For more information, see EVENT_PARAMETER function [System].

  • New server property specifies how many concurrent users are connected to the network server The new LicensesInUse property determines the numbers of concurrent users currently connected to the network server. Each concurrent user is determined by the number of unique client network addresses connected to the server, not the number of connections. For example, if three client machines are connected to a server, and each client machine has two connections, select property( 'LicensesInUse' ) is '3'.

    For more information, see Server-level properties.

  • The Service Creation [dbsvc] utility can now start and stop services Two new options have been added to the Service Creation [dbsvc] utility. Dbsvc -u <service_name> starts the service named service_name, and dbsvc -x <service_name> stops the service named service_name.

    For more information, see Managing services using the dbsvc command-line utility.

  • The network server supports the LocalOnly protocol option [LOCAL] You can use the LocalOnly protocol option [LOCAL] with the server. Running a server with the LocalOnly protocol option set to YES allows the network server to run as a personal server without experiencing connection or CPU limits.

    For more information, see LocalOnly protocol option [LOCAL].

  • New minimum database server cache size when using Address Windowing Extensions The minimum size of the database server cache when using Address Windowing Extensions (AWE) on Windows 2000, Windows XP, and Windows Server 2003 is now 2 Mb. In previous releases, the minimum cache size when using AWE was 3 Gb-256 Mb.

    For more information, see -cw server option.

  • New database property specifies drive type The new DriveType database property provides information about the drive on which the database file is located.

    For more information, see Database properties.

  • Adaptive Server Anywhere NetWare now faster The Adaptive Server Anywhere server for NetWare now uses LibC rather than CLIB. LibC is a C runtime library that allows better interaction with the new kernel of the NetWare operating system than the legacy CLIB library. All client-side software for NetWare (including dblib, dbisql, dbconsole, and dbremote) still uses CLIB. This has the benefit of increasing the maximum file size on NetWare to the same as NTFS, allowing multiple CPUs if available, and allowing TCP and SPX to use Winsock, which is faster than previous versions.

    For more information, see Physical Limitations and Behavior changes in version 9.0.

  • External function enhancements on NetWare External functions or external stored procedures on NetWare can now use multiple NLMs without naming conflicts.

    For more information, see External function prototypes.

  • Connections can specify language of error messages Each connection to the database server can now request the language in which the database server reports error messages and various other strings. The language used by the connection is independent of the language used by the server. The database server also uses the language requested by the connection to interpret date strings.

  • Two new server properties identify processor type Two new server-level properties have been added. ProcessorArchitecture identifies the processor type, and on platforms where a processor can be emulated NativeProcessorArchitecture identifies the native processor type.

    For more information, see Server-level properties.

  • Database password case sensitivity is independent of database case sensitivity The CREATE DATABASE statement, Initialization [dbinit] utility, and Create Database wizard allow you to specify whether passwords are to be case sensitive or case insensitive. The case sensitivity setting for passwords is independent of the database case sensitivity setting used for string comparisons. The new CaseSensitivePasswords database property allows you to check the password case sensitivity setting for a database.

    For more information, see CREATE DATABASE statement and The Initialization utility.

Performance enhancements (Query optimization)

The new features listed here are query optimization enhancements that require no user action to use. They take effect without user intervention. If you study query execution plans, you may see the effect of these optimizations.

The optimization enhancements do not require a database upgrade, but they do operate most effectively on a database created using version 9 software.

  • Cost-based subquery optimization The optimizer has greatly extended the scope of optimizations that are available for subqueries. In previous releases, subqueries were either rewritten as joins during semantic query optimization or were optimized separately from the remainder of a query. Now subqueries that are too complex to be rewritten as joins can still be optimized as an integral part of the query.

  • Buffered row fetching improves performance of sequential scans When reading rows from a database page for a sequential table scan, Adaptive Server Anywhere can now copy rows into a buffer before returning them to the consumer. Depending on the complexity of the query, this can provide significant time savings.

  • Top N queries executed more efficiently A new algorithm for executing queries that use the TOP N clause permits faster execution.

    For more information, see Sort Top N.

  • New algorithm for determining which frequencies are kept in histograms Previously, column histograms created singleton buckets for values with selectivity > 1%. Now, the condition for singleton buckets is relaxed, and instead the histogram tries to keep a minimum number of singleton buckets.

    For more information, see Optimizer estimates and histograms.

  • Property QueryCachedPlans shows how many query plans are currently cached The new property, QueryCachedPlans, shows how many query execution plans are currently cached for a given connection, or across all connections. It can be used in combination with QueryCachePages, QueryOptimized, QueryBypassed, and QueryReused to determine the best setting for the MAX_PLANS_CACHED option.

    For more information, see Connection-level properties and Database properties.

  • Plans are cached faster for procedure statements The scope of statements for which access plans are cached has been extended to include queries within stored procedures whose result sets are returned by the procedure to the calling environment. This enhancement eliminates the need to re-optimize some statements.

    For more information, see Access plan caching.

  • Index statistics maintained as each index is updated Statistics are maintained for all indexes, including those on catalog tables, as each index is updated, providing accurate statistics to the optimizer at virtually no performance cost. Statistics persist in SYSATTRIBUTE in the form of one row for each statistic for an index.

    To gain the benefits of this enhancement on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

    For more information, see SYSATTRIBUTE system table.

Performance enhancements (Server operation)

  • New performance monitor statistics Two new performance monitor statistics, Comm: Licenses in Use, and Connection Count, have been added to allow users to track the number of connections in use.

    For more information, see Communications statistics and Miscellaneous statistics.

  • The option APPEND { ON | OFF } has been added to the UNLOAD and UNLOAD TABLE statements A new APPEND option allows unloaded data to be appended to the end of the specified file.

    For more information, see the UNLOAD statement or the UNLOAD TABLE statement.

  • Temporary tables can now be declared as NOT TRANSACTIONAL When NOT TRANSACTIONAL is used, the table is not affected by COMMIT or ROLLBACK. This extension is useful when procedures that access the table are called repeatedly without a COMMIT.

    For more information, see CREATE TABLE statement, and DECLARE LOCAL TEMPORARY TABLE statement.

  • Persistent index statistics Maintaining accurate statistics about the physical properties of candidate indexes facilitates the optimizer's cost based decisions about which indexes to use. Statistics now persist in SYSATTRIBUTE, and are maintained as each index is updated. Additionally, the VALIDATE statement verifies that the statistics on the specified index(es) are accurate and generates an error if they are not. This provides accurate statistics to the optimizer at virtually no performance cost.

    To gain the benefits of this enhancement on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

    For more information, see SYSATTRIBUTE system table and the VALIDATE INDEX statement

  • New OPTIMISTIC_WAIT_FOR_COMMIT option added This option is meant to mimic 5.x locking behavior when transactions add foreign rows before primary rows. While it is not intended for general use, it can be helpful when migrating 5.x applications to version 8.x or later.

    For more information, see WAIT_FOR_COMMIT option [database].

  • New extended property function added The new db_extended_property() is similar to db_property() except that it also allows an optional property-specific string parameter to be specified.

    For more information, see DB_EXTENDED_PROPERTY function [System].

  • Two new properties added Two new properties have been added: FileSize and FreePages. Each of these properties can take an optional argument which specifies the dbspace for which the property is being requested.

    For more information, see Database properties.

  • Server's quiet mode enhanced The server's quiet mode and error logging switches have been enhanced to allow the server to suppress a variety of messages. Additionally, the -qw option has replaced the -q option, and the -qi option has replaced the -Q option.

Development and administration tools

  • Adaptive Server Anywhere plug-in changes The Adaptive Server Anywhere plug-in for Sybase Central has been reorganized. Much of the information that was previously available in property sheets, dialog boxes, and folders in the left pane is now available on tabs in the right pane. For example, to view information about a foreign key, you now select the table that has the foreign key in the left pane and then select the Foreign Keys tab in the right pane. In previous versions, there was a separate Foreign Keys folder in the left pane.

    Several other changes have been made to the plug-in, including the following:

    • The Table Editor is no longer a separate window. Now you edit tables directly in the right pane of Sybase Central.

    • You can edit stored procedures, functions, triggers, and events in the right pane of Sybase Central or in a separate Code Editor window if you wish to have multiple windows open at one time.

    • The toolbar buttons now change to include options specific to the object selected.

    • The SQL Statements log and server messages (the same information that appears in the Server Messages window) can now be viewed directly in the Sybase Central main window. To view this information, in Sybase Central choose File > Design Details. The Design Details pane appears at the bottom of the main Sybase Central window.

    • The Adaptive Server Anywhere plug-in provides several new wizards to guide you through tasks, including creating tables, unique constraints, and web services.

  • Enhanced clipboard support in the Adaptive Server Anywhere plug-in Clipboard support has been enhanced in the Adaptive Server Anywhere plug-in so you can copy and paste most objects within Sybase Central into other applications, such as Interactive SQL or a text editor. When you copy objects into other applications, depending on the object you select, either the object name or the SQL for the object appears. For example, if you copy an index in Sybase Central and paste it into a text editor, the CREATE INDEX statement for that index appears.

    For more information, see Copying database objects in Sybase Central.

  • Debugger changes The database object debugger that lets you debug both stored procedures and Java classes has been integrated into Sybase Central. The user interface has been redesigned.

    For more information, see Debugging Logic in the Database.

  • Sybase Central, Interactive SQL, and the Adaptive Server Anywhere Console utility include an option to automatically check for software updates Sybase Central, Interactive SQL, and the Adaptive Server Anywhere Console utility can be configured to automatically check for software updates. This option can be set from the Options dialog in Interactive SQL and the Adaptive Server Anywhere Console utility, and can be set from the Help menu in Sybase Central when the Adaptive Server Anywhere plug-in is loaded. In previous releases, you had to go to a web site to obtain this information.

    For more information, see Options dialog: Check for Updates tab.

  • Enhancements made to the Adaptive Server Anywhere Console utility There have been a number of enhancements to the Adaptive Server Anywhere Console utility, including changes to the interface, support for multiple connections, sorting, and drag and drop.

  • Fast launching of Sybase Central and Interactive SQL On Windows, Sybase Central and Interactive SQL include a fast launcher that is designed to reduce application startup time when you start Sybase Central or Interactive SQL. Running Adaptive Server Anywhere 9.0 starts two background processes, an instance of dbisqlg.exe and an instance of scjview.exe, which are the fast launcher processes for Interactive SQL and Sybase Central, respectively. Both of these executables are started when the user logs in.

    For more information, see Options dialog: General tab.

  • Syntax highlighting editor in Interactive SQL You can configure the appearance of syntax typed in the SQL Statements pane of Interactive SQL using the Interactive SQL Options dialog.

    For more information, see Options dialog: Editor tab.

  • Printing from Interactive SQL You can print the contents of the SQL Statements pane and of the graphical plan in Interactive SQL.

    For more information, see Interactive SQL main window description.

  • Graphical plan enhancements The graphical query access plan display has been enhanced in several ways:

    • The number of rows that passes from one operator to another is indicated by varying line thickness.

    • Slow operations are highlighted by a red border.

    • The statistics display has been extended and reorganized.

    • You can now print the access plan.

  • Database utilities accept @filename parameters All of the database administration utilities except Interactive SQL [dbisql], the Language utility [dblang], and the Adaptive Server Anywhere Console utility [dbconsole] now accept parameters contained within a file using the @file syntax. The filename can occur at any point in the command line, and parameters contained in the file are inserted at that point. Multiple files can be specified, and the file specifier can be used with command line switches. Note that the @file syntax is not recursive.

    For more information, see the @data server option.

  • Row numbers can appear beside results in Interactive SQL Interactive SQL has an option to display row numbers beside results. This option can be set on the Results tab of the Interactive SQL options dialog.

    For more information, see Options dialog: Results tab.

  • Interactive SQL can be set as the default editor for .SQL files On Windows platforms, you can create a file association for .SQL files so that when you double-click the file, Interactive SQL is used to open the file.

    For more information, see The Interactive SQL utility.

  • Interactive SQL Command History dialog enhancements You can now copy and delete commands from the Command History dialog in Interactive SQL, as well as select multiple commands in the window. The command history now persists between Interactive SQL sessions.

    For more information, see Printing SQL statements.

  • Warning messages now have W prefix Prior to version 9.0, all warning and error messages had a prefix of I or E. Warning messages now have a prefix of W. This change affects dbmlsrv9, dbmlsync, dbremote, ssremote, dbltm, and ssqueue.


MobiLink new features

Following is a list of changes and additions to the software introduced in version 9.0.0.

  • Server-initiated synchronization Server-initiated synchronization allows you to initiate MobiLink synchronization from the consolidated database. This means you can push data updates to remote databases. The MobiLink component (the Notifier) provides programmable options for determining what changes in the consolidated database will initiate synchronization and how remotes are chosen to receive update messages. The remote component (the Listener) determines how remotes respond.

    For more information, see Introducing Server-Initiated Synchronization.

  • File-based downloads Downloads can now be processed as a file that can be distributed in any way that files are distributed, such as e-mail, ftp, disk, or multicast file distribution. For this release, this feature can be used only with Adaptive Server Anywhere remote databases.

    For more information, see File-Based Downloads.

Enhancements to the MobiLink synchronization server

  • New connection scripts begin_publication and end_publication Two new scripts have been added. One of their uses is implementing file-based downloads.

    For more information, see begin_publication connection event and end_publication connection event.

  • New connection script authenticate_parameters A new script has been added that allows custom authentication. The new script is invoked during authentication, before the begin_synchronization script.

    For more information, see authenticate_parameters connection event.

  • New option removes blank padding of strings For columns of type VARCHAR or LONG VARCHAR, the dbmlsrv9 -b option removes trailing blanks from strings during synchronization.

    For more information, see -b option.

  • Option starts new log file with .old extension The dbmlsrv9 -on option allows you to set a hard limit on the amount of disk space used by the MobiLink server log.

    For more information, see -on option.

  • Log progress offsets The MobiLink synchronization server can now report progress offsets, last upload time, and last download time. To obtain this information, use the dbmlsrv9 options -vp or -v+.

    For more information, see -v option.

  • Handling errors and warnings in .NET and Java synchronization logic You can now add logic to deal with errors and warnings at the MobiLink synchronization server.

    For more information, see Handling MobiLink server errors in Java and Handling MobiLink server errors with .NET.

  • Additions to MobiLink system tables Two new columns have been added to both the ml_user and ml_subscription tables. They are last_upload_time and last_download_time. The default is NOT NULL with a default time of January 1, 1900 00:00:00.

    In addition, a subscription_id column has been added to ml_subscription. The publication_name column now contains the publication name.

    For more information, see ml_user and ml_subscription.

Enhancements for Adaptive Server Anywhere clients

  • Upload-only synchronization You can now choose to perform an upload-only synchronization.

    For more information, see the dbmlsync -uo option.

  • Download-only synchronization You can now choose to perform a download-only synchronization.

    For more information, see -ds option and DownloadOnly (ds) extended option.

  • Window messages can initiate synchronization You can now wake up dbmlsync and perform a synchronization by registering a window message as dbas_synchronize and sending it to the dbmlsync top level window.

  • Load dlls on startup (for Windows CE) The new dbmlsync option -pd specifies DLLs that should be loaded on startup. This option should be used by everyone using dbmlsync on Windows CE.

    For more information, see -pd option.

  • New way to upgrade or revise schema The hook sp_hook_dbmlsync_schema_upgrade stored procedure has been added to replace the dbmlsync option -i and extended option SiteScriptName (sn).

    For more information, see sp_hook_dbmlsync_schema_upgrade.

  • MobiLink return codes To help you track and log the success and failure of your synchronizations, especially when you have multiple synchronizations in a dbmlsync session, there is a new client event hook procedure, sp_hook_dbmlsync_process_return_code. In addition, a new value, return code, is set in the #hook_dict table for the sp_hook_dbmlsync_abort hook.

    For more information, see sp_hook_dbmlsync_process_return_code and sp_hook_dbmlsync_abort.

  • Enhancements to scheduling When scheduling is specified, you can reduce the amount of time spent scanning the log by using the new extended option HoverRescanThreshold (hrt) or the new hook sp_hook_dbmlsync_log_rescan.

    For more information, see HoverRescanThreshold (hrt) extended option and sp_hook_dbmlsync_log_rescan.

    Languages other than English now support the use of abbreviated day names in schedules. Previously, schedules in non-English languages required full day names.

    Two new keywords have been added to scheduling syntax: INFINITE instructs dbmlsync to wait indefinitely to be signalled for the next synchronization, and 0 as a day of the month specifies the last day of the month.

    For more information, see Schedule (sch) extended option.

Enhancements for UltraLite clients

  • Additional troubleshooting assistance for HotSync conduit You can configure the HotSync conduit to record troubleshooting information in the HotSync log.

    For more information, see HotSync log files.

Performance and monitoring enhancements

  • Better dbmlsync performance when there are no schema changes Dbmlsync no longer loads schema information before every synchronization by default. This typically speeds up synchronization on slower handheld devices by 20 seconds.

    For more information, see -sc option.

  • Better dbmlsync performance on Windows CE Dbmlsync no longer uses dbtool9.dll on Windows CE. This means that it uses less memory.

  • MobiLink Monitor command line options The MobiLink Monitor can now be started from the command line with a variety of options.

    For more information, see Starting the MobiLink Monitor.

  • Enhancements to Redirector A new parameter, LOG_LEVEL, has been added to allow you to control the verbosity level.

    For more information, see Configuring Redirector properties (all versions).

  • Improved liveness When connecting over TCP/IP, dropped connections are detected more quickly. This frees up MobiLink worker threads more quickly when a connection is dropped, improving throughput.

Miscellaneous

  • Warning messages now have W prefix Prior to version 9.0, all warning and error messages had a prefix of I or E. Warning messages now have a prefix of W. This change affects dbmlsrv9, dbmlsync, dbremote, ssremote, dbltm, and ssqueue.


SQL Remote new features

SQL Remote version 9.0 includes the following new features.

  • Warning messages now have W prefix Prior to version 9.0, all warning and error messages had a prefix of I or E. Warning messages now have a prefix of W. This change affects dbmlsrv9, dbmlsync, dbremote, ssremote, dbltm, and ssqueue.


UltraLite new features

UltraLite development is possible using two kinds of programming interface:

  • UltraLite components UltraLite components bring UltraLite database and synchronization features to users of rapid application development tools. They provide a familiar interface for each supported development tool. UltraLite components provide a simple table-based data access interface and also dynamic SQL for more complex queries.

    The UltraLite components were introduced in version 8.0.2.

    For an overview of the components, see Introduction to UltraLite.

  • Static development models Embedded SQL, the static C++ API, and the static Java API are still available. These are now referred to in the documentation as static interfaces to distinguish them from the components.

In particular, note the following:

  • Native UltraLite for Java is an UltraLite component, which uses a C/C++ UltraLite runtime. The UltraLite static Java API is a pure Java solution, available in previous releases, in which queries must be specified at compile time.

  • UltraLite for C++ is a component interface. The UltraLite static C++ API is a static interface, available in previous releases, in which queries must be specified at compile time.

  • Embedded SQL is a static interface, in which queries must be specified at compile time.

Following is a list of changes and additions to the software introduced in version 9.0.

  • New components In addition to the components for AppForge MobileVB, eMbedded Visual Basic, and Java, the following components have been introduced:

    • UltraLite .NET A component for development using the Visual Studio .NET environment. Applications built with this component can be deployed to devices that support the .NET Compact Framework (version 1.05.0000 or later).

      For more information, see Introduction to UltraLite.NET.

    • C++ component A component for development using C++ compilers.

      For more information, see Introduction to UltraLite for C/C++ Developers.

  • Pocket IE support The eMbedded Visual Basic component has been upgraded to an ActiveX component. Support has been added for development using JScript, for applications that run from Pocket IE on Windows CE devices.

    For more information, see Introduction to UltraLite ActiveX.

  • Dynamic SQL In addition to the table-based data access interface provided in version 8.0.2, the UltraLite components can now use Dynamic SQL for more complex queries, including multi-table joins.

    For more information, see Dynamic SQL.

  • Connection parameters Connection parameters for the UltraLite components (except C++) are now exposed as individual properties rather than as a single string. This design makes debugging connection issues easier and makes connection management more straightforward.

    For more information, see Connection Parameters.

  • Drag and drop MobileVB component The MobileVB component can now be dragged on to a form. The properties of the component can be set in the design environment as well as in code.

    For more information, see UltraLite for MobileVB architecture.

  • Multi-process access The C++ component supports access from more than one process. To develop an application using this model, a separate UltraLite database engine and the application must be linked against a different UltraLite runtime library.

    For more information, see Compiling and linking your application.

  • Concurrent synchronization In previous releases, all access to data was prevented during synchronization. Full access to the data is now provided during the download phase of synchronization. Read-only access is provided during the upload phase.

    For more information, see Understanding concurrency in UltraLite.

  • Palm OS enhancements On the Palm OS the structure of the UltraLite code has been reorganized to make better use of Palm database segments.

  • Extended error information More error information is available to applications built using the UltraLite components.

  • Unicode library available on Windows NT/2000/XP A Unicode version of the UltraLite runtime library is provided for embedded SQL and static C++ API applications. This version is used by the UltraLite components. When using this library, UltraLite database files are compatible between Windows CE and desktop operating systems.

    For more information, see Character sets in UltraLite.

  • Windows XP supported as a deployment platform UltraLite application deployment is now supported on Windows XP.


Behavior changes in version 9.0

This section lists the behavior changes introduced in components of SQL Anywhere Studio version 9.0.


Adaptive Server Anywhere behavior changes

The following is a list of behavior changes from previous versions of the software.

  • Java objects in the database not supported Support has been removed for storing data as Java objects. Support is maintained for Java stored procedures.

    For a description of the current support for Java in the database, see Introduction to Java in the Database.

  • New Greek collation for Windows environment Greek collations for OEM/DOS character sets existed in previous versions, however, a new Greek collation, 1253ELL, has been added for Windows. When creating a new database in a Greek Windows environment, 1253ELL will be selected automatically if a collation is not specified.

    For more information, see Supplied and recommended collations.

  • New connection limit The database server now allows one extra DBA connection above the connection limit, to allow a DBA to connect and drop other connections in case of an intentional or accidental denial-of-service.

    For more information, see -gm server option.

  • Personal database server limited to a single processor In previous versions of the software, the personal database server used a maximum of two CPUs for request processing. Now, the personal server is limited to a single processor.

  • References to table expressions preceding in the FROM clause may now be used in ON clauses of nested outer joins. In previous releases, outer references in the ON phrase were permitted. Such outer references must now be indicated by use of the LATERAL keyword. The restriction enforces clarity and conforms to the SQL/99 standard.

    The following query is an example of one that is no longer valid, as it contains an outer reference (highlighted) without use of the LATERAL keyword:

    SELECT *
FROM T1,
   T2 LEFT OUTER JOIN
                  ( T3 LEFT OUTER JOIN T4 ON T1.col1 = T2.col2 )
   ON T1.col2 = T2.col2

    For more information, see FROM clause.

  • Unqualified table references with multiple matches are reported as syntax errors In previous releases, if a query contained a reference to a table without an owner name specified (an unqualified table reference) and if more than one match was possible on that table, the first match found was used. Unqualified table references now cause an error. See Table name '%1' is ambiguous.

  • LIKE operator with NULL escape character now evaluates to NULL LIKE predicates containing a NULL escape character now evaluate to NULL. Previously, a LIKE predicate with a NULL escape character was evaluated as if there were no escape character. The new behavior matches the ISO/ANSI specification.

  • Properties and statistics removed The ServerIdleWaits database property, and the TaskSwitch and CurrTaskSwitch connection properties have been removed, along with their corresponding performance monitor statistics: Context Switches, Server Idle Waits/sec, Request Queue Waits/sec.

  • Column statistics are updated on INSERT/UPDATE/DELETE Statistics are now updated when executing an INSERT, UPDATE, or DELETE statement results in changing a significant amount of data.

  • Statistics no longer updated during recovery The server no longer updates statistics during recovery or when executing simple DELETE and UPDATE statements. Simple statements are those that are not optimized and executed directly by the server.

  • Histogram ranges displayed as the correct data type The sa_get_histogram() system procedure and the histogram [dbhist] utility previously displayed outputted ranges in hash values. Now, outputted histogram ranges match the data in the corresponding column, and are displayed as the correct data type.

    For more information, see The Histogram utility and the sa_get_histogram system procedure.

  • Only one consolidated user permitted per remote database It is no longer possible to define multiple consolidated users on the same remote database.

    For more information, see GRANT CONSOLIDATE statement [SQL Remote] or REVOKE CONSOLIDATE statement [SQL Remote].

  • CommLinks connection parameter uses shared memory if not explicitly specified Now, connections that do not specify a CommLinks connection parameter always attempt to connect over shared memory.

    For more information, see CommLinks connection parameter [LINKS].

  • CommLinks connection parameter always attempts shared memory protocol first When you specify CommLinks=all, Adaptive Server Anywhere always attempts to connect using the shared memory protocol before attempting to connect using other protocols.

    For more information, see CommLinks connection parameter [LINKS].

  • Connection errors abort process Previously, connection protocols listed in the CommLinks connection parameter were attempted one by one until a connection occurred. Now, if a connection error occurs during the process, it aborts the connection process immediately, regardless of whether or not all the listed protocols were tried.

    For more information, see CommLinks connection parameter [LINKS].

  • Default value for PREVENT_ARTICLE_PKEY_UPDATE changed The default value for the PREVENT_ARTICLE_PKEY_UPDATE database option has been changed to ON to reflect the fact that updating primary key values should be avoided. The new default setting disallows primary key updates on primary keys that are part of a publication. You can override this feature by setting the value to OFF.

    For more information, see PREVENT_ARTICLE_PKEY_UPDATE option [database].

  • Some functions treated as non-deterministic The RAND, NEWID, and GET_IDENTITY functions are treated as non-deterministic. A consequence is that these functions are not cached during query execution.

    For more information, see Function caching.

  • Performance messages now display database name The engine performance advice messages now display the database name. This is especially helpful when running more than one database. As well, messages starting with the word Note indicate that they are advice messages.

  • NetWare clients using Adaptive Server Anywhere versions prior to 9.0 require upgrade As a result of enhancements to NetWare support in Adaptive Server Anywhere, NetWare clients using Adaptive Server Anywhere versions prior to 9.0 cannot connect to 9.0 servers using shared memory unless they have a specific EBF installed. The build numbers are: 7.0.4.3400, 8.0.0.2358, 8.0.1.3088, and 8.0.2.4095. Clients with build numbers before these will simply not find the 9.x server.

  • Change in syntax for ALTER DATABASE CALIBRATE The syntax for ALTER DATABASE CALIBRATE TEMPORARY DBSPACE has been changed to ALTER DATABASE CALIBRATE DBSPACE TEMPORARY to make the syntax consistent with other, similar statements.

    For more information, see the ALTER DATABASE statement.

  • Dynamic cache sizing more aggressive Dynamic cache sizing is now more aggressive at resizing the cache after a new database is started or when a file grows significantly. Prior to this change, statistics were sampled and the cache was resized at most once per minute. Now, after a database is started or a file grows significantly, statistics are sampled and the cache may be resized every five seconds for thirty seconds.

    For more information, see Using the cache to improve performance.

  • Determining the language for interfaces and messages Two new environment variables, ASLANG and ASCHARSET, control languages used in interfaces (such as Sybase Central or Interactive SQL) and messages. ASLANG specifies the language, and ASCHARSET specifies the character set.

    For more information, see the ASLANG environment variable or the ASCHARSET environment variable.

  • Rowcount setting now limits the rows returned The rowcount setting now limits the rows returned by a cursor from the top. It is no longer possible to position to the beginning of the results using an absolute fetch.

    You can use the new feature, TOP N / START AT to emulate this behavior if it is needed.

    For more information see Sort Top N.

Deprecated and unsupported features

Adaptive Server Anywhere -d server option no longer supported As a result of enhancements to NetWare support in Adaptive Server Anywhere, the -d server option is no longer supported.

NetWare 4.x no longer supported As a result of enhancements to NetWare support in Adaptive Server Anywhere, Adaptive Server Anywhere will only run on NetWare version 5.1 SP6 or higher, or version 6.0 SP3 or higher. The correct service packs must be installed or the Adaptive Server Anywhere server will display an error message.

SQLLOCALE environment variable no longer supported SQLLOCALE environment variable has been replaced by two new environment variables, ASLANG and ASCHARSET.

For more information, see Behavior changes in version 9.0.


MobiLink behavior changes

The following is a list of behavior changes from previous versions of the software.

  • dbmlsync option -i and extended option SiteScriptName are no longer supported dbmlsync -i and dbmlsync -e sc are no longer supported. They are replaced with a new hook called sp_hook_dbmlsync_schema_upgrade.

    For more information, see sp_hook_dbmlsync_schema_upgrade.

  • Download acknowledgement is now OFF by default For Adaptive Server Anywhere remotes, the SendDownloadAck extended option now defaults to OFF. For UltraLite remotes, the send_download_ack field of the ul_synch_info struct now defaults to ul_false.

    When you upgrade to version 9, you must explicitly set this option ON if the application depends on knowing that the remote has applied a download before the commit of the download transaction.

    For more information, see SendDownloadACK (sa) extended option and Send Download Acknowledgement synchronization parameter.

  • Some dbmlsync hooks may not work by default on Windows CE devices The dbmlsync extended option LockTables has been modified to allow you to specify whether tables are locked in shared mode or exclusive mode. The default setting for LockTables, ON, continues to lock tables in shared mode for all platforms other than Windows CE. However, on Windows CE devices, ON now means that tables are locked in exclusive mode. This change provides significant performance enhancements for Windows CE applications.

    The dbmlsync event hooks sp_hook_dbmlsync_download_com_error, sp_hook_dbmlsync_download_fatal_sql_error, and sp_hook_dbmlsync_download_log_ri_violation are all executed on separate connections. They will not be able to execute correctly if they attempt to access any synchronization tables that are locked in exclusive mode. If your deployment uses any of these hooks on Windows CE, you may need to set LockTables to SHARE.

    For more information, see LockTables (lt) extended option, sp_hook_dbmlsync_download_com_error, sp_hook_dbmlsync_download_fatal_sql_error, and sp_hook_dbmlsync_download_log_ri_violation.

  • MobiLink synchronization server error codes The MobiLink synchronization server now provides more information about errors. All MobiLink server error codes are less than -10000, starting at -10001. For dbmlsync, the error appears in the GUI and the output file. For UltraLite, the error is available as a string in the ul_synch_info struct.

    For more information, see MobiLink Synchronization Server Error Messages.

  • Upload cursors deprecated The following scripts are deprecated: upload_cursor, new_row_cursor, and old_row_cursor. You should use statement-based scripts for the upload stream.

    For more information, see Writing scripts to upload rows.

  • -zac and -zec deprecated The MobiLink synchronization server options for generating cursor-based scripts, -zac and -zec, have been deprecated. You can continue to use -za and -ze to automatically generate statement-based scripts.

    For more information, see -za option and -ze option.

  • -zd removed The MobiLink synchronization server option -zd, which caused the last_download timestamp to be passed last, has been removed. This parameter is now always passed first.

  • mlxtract deprecated The mlxtract utility is deprecated.

    For information, see Creating a remote database.

  • end_synchronization scripts always called Prior to version 9.0, the end_synchronization script might not be called if synchronization failed. Now, the script is always called if a begin_synchronization script is called. This means that any cleanup activities you have placed in the end_synchronization script will be performed regardless of whether the synchronization was successful.

    In addition, end_synchronization scripts have a new parameter, sync_ok, that indicates whether the synchronization was successful (1), or failed (0).

    For more information, see end_synchronization connection eventand end_synchronization table event.

  • Stream dlls and shared objects renamed The names of stream dlls and shared objects have been changed to improve consistency with Adaptive Server Anywhere. The following table details the changes:

    Old name | New name
    dbhttp9 | dbmlhttp9
    dbhttps9 | dbmlhttps9
    dbjrsa9 | dbmljrsa9
    dbjtls9 | dbmljtls9
    dbrsa9 | dbmlrsa9
    dbsock9 | dbmlsock9
    dbtls9 | dbmltls9

    For more information, see Deploying MobiLink Applications.

  • ScoutSync no longer supported ScoutSync is no longer supported.

  • Schema information no longer reloaded at each synchronization Prior to version 9.0, dbmlsync reloaded schema information from the database before each synchronization. It now reloads schema information only at dbmlsync startup. You can revert to the old behavior using the dbmlsync -sc option. If you do not use -sc, dbmlsync should be shut down before any schema changes are made to remote databases. Making schema changes without shutting down dbmlsync could lead to synchronization errors or other unexpected behavior.

    For more information, see -sc option.

  • Synchronization now aborts if key scripts are missing Prior to version 9.0, synchronization would continue even if certain scripts were missing that might result in the loss of data. MobiLink now aborts in this instance. You can use the dbmlsrv9 -fr option to cause an error to be generated instead of failure.

    For more information, see -fr option.

  • keep_alive synchronization parameter is always ON The keep_alive synchronization parameter for TCP/IP and HTTP protocols is now ignored and is always set to ON. This was previously the default setting. To control liveness for TCP/IP connections, you can use the liveness_timeout parameter.

    For more information, see the liveness_timeout parameter in CommunicationAddress (adr) extended option or -x option.


UltraLite behavior changes

The following is a list of behavior changes from previous versions of the software.

  • Supported platform changes The following changes have been made to the supported UltraLite deployment platforms.

    • ScoutSync no longer supported Support has been dropped for ScoutSync synchronization software.

    • VxWorks no longer supported The VxWorks operating system is no longer supported.

    • JDK 1.1.8 required for pure Java UltraLite The pure Java static development model requires JDK 1.1.8 or later, rather than JDK 1.1.4 or later.

    • Palm OS changes Changes to the UltraLite architecture for Palm OS provides better performance on newer devices. A consequence is that UltraLite requires more dynamic memory than in previous releases. For anything other than very small databases, it is recommended that Palm OS version 3.5 or later be used, with 4 MB or more of memory.

    • MobileBuilder and PRC Tools no longer supported UltraLite development is no longer supported on the PenRight! MobileBuilder platform. Development using the GNU PRC Tool chain is also no longer supported.

  • Development platform changes Application development for UltraLite components is now supported on Windows NT/2000/XP only. Development using the static interfaces is also supported on Windows 98 SE. Other members of the Windows 95/98/Me family are not supported for development purposes.

    The supported Metrowerks CodeWarrior versions are now 8 and 9.

  • Documentation terminology change The introduction of the UltraLite components requires new names in order to distinguish the different interfaces. The older UltraLite interfaces (Embedded SQL, the C++ API, and the Java API) are now named static interfaces, as the queries they use must be specified at compile time. The components provide access to dynamic SQL.

  • UltraLite runtime library on Windows NT/2000/XP The ActiveX and MobileVB components now use a Unicode runtime library on Windows. This runtime library is compatible with version 8.0.2 UltraLite database (.udb) files for Windows, but not with version 8.0.2 UltraLite database files built on other Windows operating systems.

  • file_name parameter In previous versions of the software, the file_name parameter used to specify the UltraLite database file name on the desktop would also be used to specify the file name on a device if no platform-specific parameter was supplied. The file_name parameter is now ignored except for on desktop operating systems.

    For more information, see Database Identification parameters.

  • Static Java API changes The static Java API has changed. The following methods that were on the JdbcDatabase object have been moved to the JdbcConnection object:

    • countUploadRows

    • getLastDownloadTimeDate

    • getLastDownloadTimeLong

    The grant and revoke methods have been added to JdbcConnection for use by applications that do not have an explicit JdbcManager object.

    For more information, see Class JdbcConnection.

  • Error code changes Some UltraLite error codes have changed to more specific and useful values. If you test for individual error codes in your application, check the new codes after upgrade.

    For example, if you check for SQLE_DATABASE_NOT_FOUND (or the equivalent in one of the UltraLite interfaces) when connecting to a database, you should change this to SQLE_ULTRALITE_DATABASE_NOT_FOUND.

    For a list of error codes, see the SQL error object in the interface you are using.

  • UL_STORE_PARMS change for embedded SQL The UL_STORE_PARMS macro is now evaluated during the EXEC SQL CONNECT statement. The database is no longer started during the dbinit call, but rather on connect. This means that UL_STORE_PARMS could be evaluated a different number of times if you use multiple connections. It also means that UL_STORE_PARMS must be defined before any EXEC SQL CONNECT statements.


What's New in Version 8.0.2

About this chapter

This chapter provides an overview of the new features and behavior changes introduced in SQL Anywhere Studio version 8.0.2.


New features in version 8.0.2

This section lists the new features introduced in components of SQL Anywhere Studio version 8.0.2.


Adaptive Server Anywhere new features

This section introduces the new features in Adaptive Server Anywhere version 8.0.2. It provides an exhaustive listing of major and minor new features, with cross references to locations where each feature is discussed in detail.

Highlighted new features

  • Clustered index support Creating a clustered index on a table causes the rows in that table to be stored in approximately the same order as they appear in the index. You can use the LOAD TABLE statement to load a table with information in the clustered order. As you insert information into the table, the clustering characteristics of the table degrade. You can use the REORGANIZE TABLE statement to reestablish the clustering order. Clustered indexes can improve performance.

    To use clustered indexes on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

    For more information, see Using clustered indexes.

  • Unique identifier support Adaptive Server Anywhere supports unique identifiers (UUIDs and GUIDs). UUIDs (universally unique identifiers) and GUIDs (globally unique identifiers) are a mechanism for uniquely identifying rows, even across distinct databases in a synchronization environment.

    For more information, see The NEWID default.

  • Update existing rows with ON EXISTING clause You can use the ON EXISTING clause of the INSERT statement to update existing rows with new values, as long as the table has a primary key.

    For more information, see Changing data using INSERT, or the INSERT statement.

  • BACKUP statement supported on Windows CE Adaptive Server Anywhere allows you to create image backups of databases operating on the Windows CE platform, or to rename or truncate the database's transaction log.

    For more information, see Types of backup, or the BACKUP statement.

  • Graphical plan enhancements The graphical plan has been enhanced to include more information, resulting in a new look.

    For more information, see Graphical plans.

  • Use of work tables is now explicit The use of work tables is now postponed until as late as possible in the plan. When work tables are used, they now appear explicitly in the graphical plan.

    For more information, see Graphical plans or Use of work tables in query processing.

  • New joins added New joins added to this release include the nested loops semijoin, the nested loops anti-semijoin, the hash semijoin and the hash anti-semijoin.

    For more information, see Join algorithms.

Function enhancements

  • Obtain plan for SQL queries of a specific cursor-type You can now obtain plans for SQL queries based on their cursor type, using the PLAN, EXPLANATION, GRAPHICAL_PLAN functions.

    For more information, see GRAPHICAL_PLAN function [Miscellaneous], EXPLANATION function [Miscellaneous], or PLAN function [Miscellaneous].

    For information about setting these plan options in Interactive SQL, see Options dialog: Plan tab.

  • Character set conversion function A new function CSCONVERT is available to convert strings between character sets.

    For more information, see CSCONVERT function [String].

  • Variable test function A new function VAREXISTS is available to test whether a user-defined variable has been created or declared with a given name. After this test, the variable can be created if necessary, and then used safely.

    For more information, see VAREXISTS function [Miscellaneous].

Statement enhancements

  • Hide procedure text to keep your logic confidential You can obscure the logic contained in stored procedures, functions, triggers and views using the SET HIDDEN option. This is allows applications and databases to be distributed without revealing the logic in stored procedures, functions, triggers, and views.

    For more information, see Hiding the contents of procedures, functions, triggers and views.

  • LOAD TABLE now accepts delimiters of more than 1 byte The LOAD TABLE statement now supports delimiters that are up to 255 bytes.

    For more information, see the LOAD TABLE statement.

  • New statement provides compatibility for Adaptive Server Enterprise and Microsoft SQL Server You can use the DEALLOCATE statement to release resources associated with a cursor. This statement is provided for Adaptive Server Enterprise and Microsoft SQL Server compatibility.

    For more information, see the DEALLOCATE statement.

  • ALTER DATABASE statement behaves like dblog utility You can use the ALTER DATABASE statement to change the transaction log and mirror log names associated with a database file. Previously, you could only do this using the Transaction Log (dblog) utility.

    For more information, see the ALTER DATABASE statement.

  • LOAD TABLE can be used for both global and local temporary tables Adaptive Server Anywhere now supports the LOAD TABLE statement on declared local temporary tables. Previously, only global temporary tables were supported.

    For more information, see the LOAD TABLE statement.

  • SET statement can be used to assign variable values You can now assign values to variables using the SET statement in Transact-SQL procedures.

  • INSERT statement now supports WITH AUTO NAME If you specify WITH AUTO NAME in an INSERT statement, the names of the items in the SELECT list determine the associations of values to destination columns.

    For more information, see INSERT statement.

  • EXIT statement enhanced The Interactive SQL EXIT statement can now set an exit code for Interactive SQL.

    For more information, see EXIT statement [Interactive SQL].

  • Specify the optimization goal for a query in the FROM clause You can use the FASTFIRSTROW table hint to set the optimization goal for the query without setting the OPTIMIZATION_GOAL option to first-row.

    For more information, see FROM clause.

Security Enhancements

  • New utility allows you to hide the contents of files Configuration files, also known as command files, sometimes contain passwords. As an enhanced security feature, Adaptive Server Anywhere has a new utility, called the File Hiding utility, that allows you to hide the contents of configuration files using simple encryption.

    For more information, see The File Hiding utility

  • Certicom encryption changes Security has been enhanced to support two types of Certicom encryption, ECC_TLS and RSA_TLS. The encryption known in previous versions of Adaptive Server Anywhere as Certicom encryption has been renamed to ECC_TLS encryption. The Certicom parameter is still accepted and is equivalent to ECC_TLS encryption. Adaptive Server Anywhere now also supports RSA_TLS encryption.

    For more information, see the -ec server option or the Encryption connection parameter [ENC].

Performance Enhancements

  • New connection parameters can improve network responsiveness The LazyClose and PrefetchOnOpen network connection parameters can improve performance on networks with poor latency or with applications that process many requests.

    For information about these parameters, see the LazyClose connection parameter [LCLOSE] and the PreFetchOnOpen connection parameter

  • Scattered reads now used on Windows NT/2000/XP Previously, sequential scans of large tables copied pages to a 64K buffer and then into the cache. Now, providing you are running in a Windows NT Service Patch 2 or higher environment, or in a Windows 2000/XP environment, and provided your page size is at least 4K, scattered reads copy the pages directly to the cache, thus saving time and improving performance.

    For more information, see Use an appropriate page size.

  • Improved time resolution in request logging The times obtained using procedure profiling or request logging now have a resolution of 1 millisecond. This change primarily affects servers running on Windows operating systems.

  • Running multiple versions of the Performance Monitor If you run multiple versions of Adaptive Server Anywhere simultaneously, you can also run multiple versions of the Windows Performance Monitor simultaneously.

    For more information about the Windows Performance Monitor, see Monitoring database statistics from Windows Performance Monitor.

Miscellaneous Enhancements

  • Changing server's temp folder via a registry setting On Windows CE platforms, you can use the registry to specify which temporary directory the server uses.

    For more information, see Registry settings on Windows CE.

  • New iAnywhere JDBC driver This robust and high-performance JDBC driver enjoys the benefits of ODBC data sources and the Command Sequence client/server protocol. It is an alternative to the jConnect JDBC driver.

    For information on the iAnywhere JDBC driver, see Using the iAnywhere JDBC driver.

    For information on choosing a JDBC driver, see Choosing a JDBC driver.

  • Triggers can discriminate among the actions that caused a trigger to fire You can now carry out different actions depending on whether the trigger was fired by an UPDATE, INSERT, or DELETE operation. This feature enables you to share logic among the different events within a single trigger, and yet carry out some actions in an action-dependent manner.

    For more information, see Trigger operation conditions.

  • RETURN_DATE_TIME_AS_STRING is no longer TDS specific All connections can now use the RETURN_DATE_TIME_AS_STRING option.

    For more information about this option, see RETURN_DATE_TIME_AS_STRING option [database].

  • Units can be specified when adding space to a dbspace You can extend database files by a specific size, in units of pages, kilobytes, megabytes, gigabytes, or terabytes.

    For more information, see the ALTER DBSPACE statement

  • sa_make_object system procedure This system procedure can be used in a SQL script to ensure that a skeletal instance of an object exists before executing an ALTER statement which provides the actual definition.

    For more information, see sa_make_object system procedure.

  • New global variable compatible with Microsoft SQL Server A new global variable has been introduced to allow for Microsoft SQL Server compatibility. The @@fetch_status global variable is the same as the @@sqlstatus global variable, except that it returns the status of the most recent fetch in different values.

    For more information, see Global variables.

  • Character set conversion supported on NetWare NetWare now supports character set translation.

    For more information, see -ct server option.

  • Information utility reports the version of installed Java classes The dbinfo utility and a_db_info structure now report the version of the Java classes installed in a database.

    For more information, see The Information utility and a_db_info structure.

  • Suppress warnings on fetch operations Versions 8.0 and later of the database server return a wider range of fetch warnings than earlier versions of the software. The ODBC Configuration for Adaptive Server Anywhere dialog allows you to suppress warning messages returned from the database server to ensure that they are handled properly for applications that are deployed with earlier versions of the software.

    For more information, see ODBC Configuration dialog: ODBC tab.

  • Controlling updates to primary key columns Setting the new prevent_article_pkey_update option to ON disallows updates to the primary key columns of tables that are part of a publication. This option helps ensure data integrity, especially in a replication and synchronization environment.

    For more information, see the PREVENT_ARTICLE_PKEY_UPDATE option [database].


MobiLink new features

Following is a list of changes and additions to the software introduced in version 8.0.2.

  • Support for .NET MobiLink now supports Visual Studio .NET programming languages for writing synchronization scripts.

    For more information, see Writing Synchronization Scripts in .NET, -sl dnet option, ml_add_dnet_connection_script, and ml_add_dnet_table_script.

  • Start classes You can now write Java and .NET code that executes at the time the MobiLink server starts the JVM or CLR, before the first synchronization.

    For more information, see User-defined start classes.

  • Maintain unique primary keys using UUIDs A new way to maintain unique primary keys on remote databases is introduced with Universally Unique IDs (UUIDs, also known as GUIDs).

    For more information, see Maintaining unique primary keys using UUIDs.

  • New way to handle referential integrity violations Two new client stored procedures, sp_hook_dbmlsync_download_ri_conflict and sp_hook_dbmlsync_download_log_ri_contlict, are introduced to help you manage referential integrity violations during download.

    For more information, see sp_hook_dbmlsync_download_ri_violation and sp_hook_dbmlsync_download_log_ri_violation.

  • Simpler way to delete all rows in a remote table You can now delete all the data in a remote table by including one row in the download_delete_cursor that has NULL in every primary-key column.

    For more information, see Writing download_delete_cursor scripts.

Performance and monitoring enhancements

  • MobiLink Monitor A graphical tool, the MobiLink Monitor, has been introduced to allow you to see the time taken by every aspect of the synchronization, sorted by MobiLink user or by worker thread.

    For more information, see MobiLink Monitor.

  • Users can estimate number of upload rows to dbmlsync A new dbmlsync command line option has been created, -urc, which allows you to improve synchronization performance by providing an estimate of the number of rows that will be uploaded.

    For more information, see -urc option.

  • Users can specify persistent HTTP/HTTPS connections You can use the persistent option to tell MobiLink to attempt to use the same connection for all HTTP requests in a synchronization. This setting may improve performance. It should only be used when you are connecting directly to MobiLink, and not through an intermediate agent such as a proxy or redirector.

    For more information, see CREATE SYNCHRONIZATION USER statement [MobiLink].

  • New ways to control warning messages Three new dbmlsrv9 command line options have been created: -zw, -zwd, and -zwe. With -zw, you can control which levels of warning message you want reported. With -zwd, you can disable specific warning codes. With -zwe, you can enable specific that are disabled with -zw.

    For more information, see -zw option, -zwd option and -zwe option.

  • New verbose logging options The dbmlsync -v command line option has been altered and expanded. Now, using -v alone causes minimum verbosity. To get maximum verbosity, use -v+. There are also several new levels that can be specified to fine tune the information that is logged. These options are also available as extended options.

    For more information, see -v option.

Connection enhancements

  • Ping support The remote database can now ping the MobiLink synchronization server.

    For more information, see -pi option and Ping synchronization parameter.

  • New synchronization stream MobiLink now supports the HTTPS protocol. This new stream implements HTTP over SSL/TLS using RSA encryption, and is compatible with any other HTTPS server.

    For more information, see -x option and CREATE SYNCHRONIZATION USER statement [MobiLink].

  • New buffer_size option You can now specify a maximum buffer size for a fixed length HTTP message with the buffer_size option.

    For more information, see CREATE SYNCHRONIZATION USER statement [MobiLink].

  • Auto-dial for MobiLink clients MobiLink clients running on Pocket PC 2002 or Windows desktop computers can now connect through dial-up network connections. Using scheduling, your remote can synchronize unattended. The new synchronization stream parameters are network_name, network_connect_timeout, and network_leave_open.

    For more information, see CREATE SYNCHRONIZATION USER statement [MobiLink].

New Web server support

  • Servlet Redirector MobiLink now supports Web servers that support the Java servlet API 2.2, including Apache Tomcat.

    For more information, see Synchronizing Through a Web Server With the Redirector.

Security enhancements

  • RSA cipher suite supported You can now use RSA encryption as well as the existing elliptical-curve encryption for synchronization security. The utilities gencert and readcert support the RSA certificates as well as elliptical-curve certificates.

    For more information, see MobiLink Transport-Layer Security.

  • gencert can sign pregenerated certificate requests The certificate generation utility gencert has a new command line option that allows you to sign pregenerated certificate requests.

    For more information, see Certificate generation utility.


SQL Remote new features

SQL Remote version 8.0.2 includes the following new features.

  • Error logs sent to consolidated database For improved troubleshooting of errors at remote sites, log information can be collected at the consolidated database.

    For more information, see Troubleshooting errors at remote sites.


UltraLite new features

UltraLite 8.0.2 introduces several new features:

  • UltraLite Components UltraLite database technology can now be used from new development platforms in an easy-to-use fashion. UltraLite Components bring UltraLite technology to users of eMbedded Visual Basic, AppForge MobileVB, and Java. The component for Java is an alternative to the UltraLite for Java described in this book. The component is not a 100% pure Java implementation, but instead uses native classes for better performance.

    The UltraLite Component documentation is available in the online books. For a starting point, see UltraLite Database User's Guide.

  • Upgrading UltraLite databases When deploying a new version of an application, you can now choose to upgrade the schema of UltraLite database to the schema of the new application.

    For more information, see ULEnableGenericSchema function (deprecated).

    In 9.0.1, ULEnableGenericSchema was replaced by ULRegisterSchemaUpgradeObserver. See ULRegisterSchemaUpgradeObserver function.

  • Java runtime is thread-safe The UltraLite Java runtime is now thread-safe, enabling the development of multi-threaded UltraLite applications.

  • Deleting UltraLite database files You can delete an UltraLite database file from an application using the ULDropDatabase function.

    For more information, see the following:

    • Embedded SQL: ULDropDatabase function

    • C++ API: Drop method

    • Java: drop method

  • Universally unique identifiers UltraLite databases can now use the UNIQUEIDENTIFIER Adaptive Server Anywhere data type. This type is a BINARY(16) used for storing universally unique identifiers (UUIDs or GUIDs). UNIQUEIDENTIFIER columns that use the NEWID function as a default value can guarantee unique primary keys across a whole MobiLink installation, as an alternative to GLOBAL AUTOINCREMENT.

    For more information, see The NEWID default.

  • New security options for synchronization Two new secure synchronization protocols are introduced in this release. HTTPS is HTTP implemented over a transport-layer security protocol, and RSA is a form of transport-layer security encryption used over HTTP or TCP/IP networks.

    These security options use Certicom technology. Use of Certicom technology requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations. For more information on this option, see Welcome to SQL Anywhere Studio.

    For more information about RSA encryption, see Security synchronization parameter. For information about using RSA encryption from Java, see Initializing the synchronization parameters.

    For more information about HTTPS synchronization, see Stream Type synchronization parameter and HTTPS protocol options.

  • Reset last download time To resynchronize previously downloaded data, for example to set an application to a clean state, you can reset the last download timestamp.

    For more information, see ULResetLastDownloadTime function, and ResetLastDownloadTime method.

  • Troubleshooting previous synchronizations Functions are now available to obtain information about the success or failure of the most recent synchronization. This feature is particularly useful for Palm OS applications that use HotSync, in which case the synchronization is carried out externally to the application.

    For more information, see GetSynchResult method, and ULGetSynchResult function. This feature is not yet available for UltraLite Java applications.

  • Generate more and smaller files The -x option causes the UltraLite generator to write out more and smaller files for C/C++ projects. This option is to help in cases where the generated code is too large for the compiler to handle in a single file.

    For more information, see The UltraLite Generator.

  • Improved synchronization observer The synchronization observer function has been enhanced. More states and fields have been added to the interface to enable the design of more responsive and informative synchronization dialogs.


Behavior changes in version 8.0.2

This section lists the behavior changes introduced in components of SQL Anywhere Studio version 8.0.2.


Adaptive Server Anywhere behavior changes

The following is a list of behavior changes from previous versions of the software.

  • Windows CE 2.11 no longer supported Support has been dropped for the Windows CE 2.11 platform.

  • SH3 and SH4 chips no longer supported Support for Windows CE devices using the SH3 and SH4 chips has been dropped.

    For a list of supported platforms, see Operating system versions, and Windows and NetWare operating systems.

  • OPTIMIZATION_GOAL setting The default setting for the OPTIMIZATION_GOAL option is set to all-rows rather than first-row. This affects the execution plan chosen for some queries and so will change performance characteristics.

    For more information, see OPTIMIZATION_GOAL option [database].

  • xp_cmdshell displays a command window on Windows operating systems It is now possible to control whether xp_cmdshell starts a new window. The behavior change applies to databases created with or upgraded to version 8.0.2 or later. On older databases, the previous behavior of not displaying a command window is maintained. The new behavior is compatible with other databases such as Adaptive Server Enterprise and Microsoft SQL Server.

    You can hide the command window by specifying a second parameter in the call to xp_cmdshell.

    For more information, see xp_cmdshell system procedure.

  • Full-length English day names are recognized regardless of the language used by the database server When creating events, the full-length English day names are recognized by the database server, regardless of the language (German, Chinese, etc.) the database server is using. This means that event definitions in the reload script will be recognized by a server running with a different language.

    Events that use the abbreviated English day names (Mon, Tue, and so on) are not recognized by servers running in languages other than English.

    For more information, see CREATE EVENT statement.

  • OPTION settings validated Integer options with minimum and maximum values are now validated. Setting an option to an invalid value gives the error Invalid setting for option '%1'.

    If you unload and reload a database that contains invalid option settings, they are set to the closest legal value.

    The affected options are as follows. The square brackets indicate an inclusive range.

    Option | Range
    ISOLATION_LEVEL | [ 0, 3 ]
    PRECISION | [ 0, 127 ]
    SCALE | [ 0, 127 ]
    NEAREST_CENTURY | [ 0, 100 ]
    MAX_HASH_SIZE | [ 2, 64 ]
    MAX_WORK_TABLE_HASH_SIIZE | [ 2, 64 ]
    FIRST_DAY_OF_WEEK | [ 1, 7 ]
    DEFAULT_TIMESTAMP_INCREMENT | [ 1, 60 000 000 ]

  • Renamed joins The names of two joins have changed, both in the graphical plan and in the documentation. Nested loops join not exists (JNE) are now called Nested loops antisemijoin (JNLA), and nested loops exists joins (JE) are now called nested loops semijoins (JNLS)

    For more information, see Join algorithms.

Deprecated and unsupported features

This list includes features that are no longer supported and that impact existing applications.

  • -d server option deprecated on Windows When used on NetWare, the -d option forces the use of POSIX I/O rather than DFS (Direct File System) I/O. In Windows, the option is still allowed on the command line, but is ignored.

    For more information, see -d server option.


MobiLink behavior changes

The following is a list of behavior changes from previous versions of the software.

  • serial communications protocol no longer supported The serial protocol is no longer supported. In its place, you can use HTTP, HTTPS, or TCP/IP.

  • Certicom no longer a certificate-issuing authority You can no longer obtain transport-layer security certificates from Certicom. However, you can continue to use the Certicom reqtool utility to generate certificate requests, and you can purchase the certificates from a variety of other sources, including VeriSign and Entrust Technologies.

    For more information, see [external link] http://www.verisign.com/ or [external link] http://www.entrust.com/certificate_services/index.htm.

  • dbmlsrv option -vw deprecated The -vw dbmlsrv command line option, which was used to suppress warning messages, has been deprecated. In its place, you can use -zw or -zwd.

    For more information, see -zw option and -zwd option.

  • dbmlsync option -v behavior change The -v dbmlsync command line option has been altered and expanded. Now, using -v alone causes minimum verbosity.

    For more information, see -v option.

  • Full-length English day names are recognized regardless of the language used by the synchronization server When creating schedules for MobiLink users, publications, and subscriptions, or when specifying scheduling information on the dbmlsync command line, you must use the full-length form of English day names (such as Monday) if you want the schedule to be recognized by a synchronization server running in a language other than English.

    Schedules that use the abbreviated English day names (such as Mon) are not recognized by synchronization servers running in languages other than English.

    For more information, see CREATE SYNCHRONIZATION USER statement [MobiLink].

  • Better support for long data in dbmlsync DBMLSync now handles BLOBs in a much more efficient way while building the upload stream. BLOBs are now read into memory in pieces, so the ability to handle long BLOBs is no longer limited by available memory. When multiple publications are synchronized at one time, BLOB data is stored one time and shared between the upload streams. The output log now prints the size of the BLOB and its first 32 bytes.

  • HTTP option use_cookies removed The use_cookies option has been removed. If you use it, the option is ignored. MobiLink now automatically detects when it needs cookies.


UltraLite behavior changes

The following is a list of behavior changes from previous versions of the software.

  • Windows CE 2.11 no longer supported Support has been dropped for the Windows CE 2.11 platform.

  • SH3 and SH4 chips no longer supported Support for Windows CE devices using the SH3 and SH4 chips has been dropped.

    For a list of supported platforms, see Operating system versions, and Windows and NetWare operating systems.

  • serial communications protocol no longer supported The serial protocol is no longer supported. The major use of serial synchronization was from clients on the Palm Computing Platform. These clients can use HotSync synchronization instead.

  • No transport-layer security on VxWorks The Certicom libraries that provide transport-layer security for synchronization are no longer supported on the VxWorks operating system.

  • VxWorks 5.5 not supported VxWorks 5.3 and 5.4 are the supported versions of the VxWorks operating system.

    VxWorks unsupported in version 9
    Support for the VxWorks platform is dropped entirely in version 9.

  • Certicom libraries require JDK 1.2 The Certicom security libraries have been updated with this release. The new libraries for Java applications require JDK 1.2, rather than JDK 1.1.4.


What's New in Version 8.0.1

About this chapter

This chapter provides an overview of the new features and behavior changes introduced in Adaptive Server Anywhere version 8.0.1.


New features in version 8.0.1

This section lists the new features introduced in components of SQL Anywhere Studio version 8.0.1.


Adaptive Server Anywhere new features

This section introduces the new features in Adaptive Server Anywhere version 8.0.1. It provides an exhaustive listing of major and minor new features, with cross references to locations where each feature is discussed in detail.

  • Specify space to be reserved in table pages You can reduce table fragmentation by specifying the percentage of free space that should be reserved in table pages.

    For more information, see Table fragmentation and ALTER TABLE statement.

To specify the percentage of space to be allocated on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

  • New system tables Two new system tables, SYSATTRIBUTE and SYSATTRIBUTENAME, have been added.

    For more information, see SYSATTRIBUTE system table and SYSATTRIBUTENAME system table.

  • sa_disk_free_space system procedure This procedure allows you to determine the space available for your dbspaces, temporary file, transaction log, and transaction log mirror.

    For more information, see sa_disk_free_space system procedure.

  • sa_flush_statistics system procedure Database administrators can use this procedure to ensure that cost model statistics that exist only in the database server cache are flushed out.

    For more information, see sa_flush_statistics system procedure.

  • New ways to obtain server message window contents There is a new system procedure and three new properties that return information from the server window.

    For more information, see sa_get_server_messages system procedure; and MessageText, MessageTime, and MessageWindowSize in Server-level properties.

  • Determine ANSI equivalency of non-ANSI statements The REWRITE function accepts a new argument, ANSI, which causes the function to return the ANSI equivalent of any SELECT, UPDATE, or DELETE statement.

    For more information, see REWRITE function [Miscellaneous].

  • Variable assignment allowed in UPDATE statement The SET clause of the UPDATE statement can now be used to assign a value to a variable, in addition to updating the table. This feature is compatible with Adaptive Server Enterprise.

    For more information, see UPDATE statement.

  • Alternative to autoincrement The GET_IDENTITY function is provided as an alternative for allocating identity values to autoincrement columns.

    For more information, see GET_IDENTITY function [Miscellaneous].

  • Square brackets can delimit identifiers You can use square brackets to delimit identifiers. Square brackets can always be used, regardless of the setting of the QUOTED_IDENTIFIER option.

    For more information, see Identifiers.

  • Specify isolation level in FROM clause You can use the WITH table-hint argument to specify a locking method for a particular table or view for a particular SELECT, UPDATE, or DELETE statement.

    For more information, see FROM clause.

  • Data Migration wizard The Data Migration wizard allows you to migrate remote tables to an Adaptive Server Anywhere database from Sybase Central.

    You cannot migrate foreign keys if the target database is version 8.0.0 or earlier. To migrate foreign keys, you must upgrade the target database's file format by unloading and reloading the database.

    For more information, see Migrating databases to Adaptive Server Anywhere.

  • Unload a version 5.x or 6.x database from Sybase Central Sybase Central now allows you to connect to a version 5.x of 6.x database in order to upgrade the database file format using the Unload Database wizard. To do this, you must run the database on a version 8.0.0 or later server.

    For more information, see Upgrading Adaptive Server Anywhere.

  • Back up and shut down your database from the Upgrade Database wizard You can now back up your database files, including the main database file, the transaction log, and dbspaces from the Sybase Central Upgrade Database wizard. The wizard also allows you to shut down your database when the upgrade is complete.

    For more information, see Upgrading a database.

  • sa_migrate enhancement The sa_migrate procedure has an optional argument, migrate_fkeys that allows you to specify whether or not you want to migrate foreign key mappings when you migrate tables from a remote database. In previous releases, foreign key mappings were always migrated when you used the sa_migrate procedure.

    For more information, see sa_migrate system procedure.

    To use this feature on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

  • New SORT_COLLATION database option The SORT_COLLATION database option allows implicit use of the SORTKEY function on ORDER BY expressions. When the value of this option is set to a valid collation name or collation ID, any string expression in the ORDER BY clause is treated as if the SORTKEY function had been invoked.

    For more information, see SORT_COLLATION option [database].

  • Use an IP address/port to connect to a server You can use the VerifyServerName=NO protocol option to skip the verification of the server name and allow Adaptive Server Anywhere clients to connect to an Adaptive Server Anywhere server if they know only an IP address/port. The VerifyServerName parameter is only used if DoBroadcast=NONE is specified.

    For more information, see VerifyServerName protocol option [VERIFY] .

  • New LocalOnly protocol option controls broadcasts You can use the LocalOnly protocol option to connect only to a server on the local machine, if one exists. Setting LocalOnly=YES uses the regular broadcast mechanism, except that broadcast responses from servers on other machines are ignored.

    For more information, see LocalOnly protocol option [LOCAL].

  • Specify how much of the cache is used for pinning cursors You can use the PINNED_CURSOR_PERCENT_OF_CACHE option to adjust the amount of cache that can be used for pinning cursors. Lowering the limit can improve performance in low memory environments.

    For more information, see PINNED_CURSOR_PERCENT_OF_CACHE option [database].

  • Monitor database file and log file fragmentation You can use the DBFileFragments and LogFileFragments database properties to choose monitor file fragmentation. Fragmentation of the transaction log file is usually not a significant concern; however, fragmentation of the database file can be a cause of reduced performance and may warrant use of a disk defragmentation utility.

    For more information, see Database-level properties.

  • New connection properties. Two new connection properties have been added. LivenessTimeout returns the liveness timeout of the connection, and IdleTimeout returns the idle timeout of the connection.

    For more information, see Connection-level properties.

  • New server properties The new IdleTimeout server property returns the default idle timeout value.

    For more information, see Server-level properties.

  • Non-deterministic functions Functions that modify underlying data, or that rely on underlying data that may change during the course of query execution, can be declared NOT DETERMINISTIC. Functions that are declared this way are re-evaluated each time they are called during query execution. Otherwise, the function value is cached and re-used for better performance.

    For more information, see CREATE FUNCTION statement.

  • Ensure all transactions in backup are complete By default, the BACKUP statement renames or truncates the transaction log without waiting for open transactions to complete. You can now ensure that all transactions contained in a backup are complete by specifying a WAIT AFTER END clause.

    For more information, see BACKUP statement


MobiLink new features

Following is a list of changes and additions to the software introduced in version 8.0.1.

  • Full error context reporting The MobiLink synchronization server now shows the full error context in its output file when an error occurs during synchronization.

    For more information, see -o option.

  • User ID mapping MobiLink now allows you to more readily find a database user ID or map a MobiLink username to a user ID.

    For more information, see modify_user connection event.

  • Set address and type as client options The MobiLink client now allows you specify the communication type and address on the command line to connect to the MobiLink synchronization server.

    For more information, see dbmlsync extended options.

  • Log MobiLink-issued ODBC statements You can instruct MobiLink to log to an ODBC output file all the ODBC statements issued by MobiLink.

    For more information, see -t option.

  • Modify the download timestamp You can modify the last download timestamp or the next last download timestamp in two new events.

    For more information, see modify_last_download_timestamp connection event and modify_next_last_download_timestamp connection event.

  • Automatic timestamp conflict tolerance In the event of a timestamp conflict between the consolidated and remote database, this option allows timestamp values with a precision higher than the lowest-precision to be used for conflict detection purposes.

    For more information, see -zp option.


SQL Remote new features

SQL Remote version 8.0.1 includes the following new features.

  • SMTP user authentication Parameters are provided for separate user authentication on SMTP servers when using the SMTP/POP message system.

    For more information, see The SMTP message system.


UltraLite new features

UltraLite 8.0.1 introduces several new features:

  • CodeWarrior 8 support This release supports CodeWarrior version 8.

  • Support for multi-threaded applications UltraLite applications can now be multi-threaded on platforms that support this kind of application.

  • Pocket PC 2002 support Pocket PC 2002 is added to the list of supported platforms.

  • JDBC ResultSet methods added The ResultSet.findColumn and ResultSet.getType methods are now supported.

    For more information, see JDBC features in UltraLite.

  • Access to information from UltraLite Java The JdbcConnection.getLastIdentity method, getLastDownLoadTime method, and JdbcDatabase.countUploadRows method allow access to useful information. These features were previously available only in C/C++ applications.

    For more information, see Class JdbcConnection.

  • User authentication in UltraLite Java The Java version of UltraLite now supports user authentication.

    For more information, see Adding user authentication to your application, Class JdbcSupport, and Class JdbcDatabase.

  • HotSync synchronization progress displayed The status field of the HotSync Progress dialog on your desktop computer now shows the progress of synchronization with UltraLite applications.

  • HotSync configuration You can configure the HotSync conduit from Palm Desktop.

    For more information, see Configuring the MobiLink HotSync conduit.

  • Automatic scripting from UltraLite applications UltraLite applications can now provide column names to the MobiLink synchronization server so that synchronization scripts can be automatically generated.

  • Get SQL data type of a column from the C++ API The GetColumnSQLType method returns the data type of a column.

    For more information, see GetColumnSQLType method.

  • Optional checkpoint during synchronization Synchronizations that download large numbers of updates can cause the UltraLite database to grow significantly in size. This growth can be limited by carrying out checkpoints during synchronization. The new checkpoint_store synchronization parameter controls checkpointing. By default, no checkpoints are carried out.

    For more information, see Checkpoint Store synchronization parameter.


Behavior changes in version 8.0.1

This section lists the behavior changes introduced in components of SQL Anywhere Studio version 8.0.1.


Adaptive Server Anywhere behavior changes

The following is a list of behavior changes from previous versions of the software.

  • New naming convention for renamed transaction log files Double digits at the end of transaction log files renamed during backup have been changed to double characters. For example, the renamed log file from the first backup on December 10, 2000, is now named 001210AA.log instead of 00121001.log. The first two digits indicate the year, the second two digits indicate the month, the third two digits indicate the day of the month, and the final two characters distinguish among different backups made on the same day. This increases the number of backups possible in a day from 100 to 676.

  • LOAD TABLE now recalculates computed columns LOAD TABLE now detects computed columns and evaluates them for each row inserted into the table.

  • DBCONSOLE now allows connections to be reconnected Previously a DBConsole session only allowed one connection. Connections can now be disconnected and reconnected without exiting the application.

Deprecated and unsupported features

This list includes features that are no longer supported and that impact existing applications.

  • DEBUG connection parameter deprecated The DEBUG connection parameter has been deprecated. You can still use LOG parameter to create a log file containing the debug information. From version 8.0.1 on, LOG=filename does what DEBUG=YES;LOG=filename used to do.

    For more information, see Connection parameters.

  • AGENT connection parameter deprecated The AGENT connection parameter has been deprecated. You can use the CommLinks parameter with appropriate protocol options to achieve the same behavior.

    For more information, see Connection parameters.

  • Port connection property removed The port connection parameter has been removed.

  • Adaptive Server Anywhere Translation Driver removed Use of translation drivers is no longer recommended. The server automatically handles character set translation.

  • SharedMemory tried first The ports specified in the LINKS= connection parameter were tried in the order in which they were specified. Now, if the sharedmemory (shmem) port is specified, it is tried first, followed by the other ports specified in the order in which they appear.

  • GLOBAL AUTOINCREMENT The default value has been changed from 0 to 2147483647. GLOBAL_DATABASE_ID can now be set to 0 and will cause values to be generated starting at 1.


MobiLink behavior changes

  • Timestamp mismatch notification When the timestamps between consolidated and remote databases are at variance, the MobiLink synchronization server will log a warning with each synchronization.

  • GLOBAL AUTOINCREMENT The default value has been changed from 0 to 2147483647. GLOBAL_DATABASE_ID can now be set to 0 and will cause values to be generated starting at 1.

    It is still the case that if GLOBAL_DATABASE_ID is not set, or is set to the default value, attempts to cause a global autoincrement value to be generated result in a NULL. This commonly gives an error when attempting to insert the value into a non-nullable primary key column and is the indication that the GLOBAL_DATABASE_ID option has not been set.

    Disallowing a setting of 0 for GLOBAL_DATABASE_ID prevented generation of values starting at 1. Instead, values would start at the partition size specified for the column.

    For more information, see GLOBAL_DATABASE_ID option [database].

  • dbmlstop performs soft shutdown By default (if none of -w, -f, -h or -t are specified), dbmlstop does a soft shutdown. This means that it stops accepting new connections and exits when the current synchronizations are complete.

For more information, see MobiLink stop utility.


UltraLite behavior changes

  • Palm database backup In previous releases, if the ULUtil application was used to backup a database, the database would be backed up on each subsequent HotSync operation.

    Most UltraLite data is effectively backed up by synchronization. As the most common use of an explicit backup is to create an initial database for deployment, continuing to make backups on HotSync is not the desired behavior in most cases. Now, each time an UltraLite application starts, it disables backups on future HotSync operations.

    If you wish to explicitly require backups for databases every time a HotSync is performed, you can do so by setting the palm_all_backup parameter in the UL_STORE_PARMS macro.

    For more information, see UL_STORE_PARMS macro.

Deprecated and unsupported features

UltraLite support for synchronization on the Palm Computing Platform using ScoutSync technology is deprecated. Version 8.0.x will continue to support ScoutSync up to version 3.6, but the next major release of SQL Anywhere Studio will not support ScoutSync.


What's New in Version 8.0.0

About this chapter

This chapter provides an overview of the new features and behavior changes introduced in Adaptive Server Anywhere version 8.0.0.


New features in version 8

This section lists the new features introduced in components of SQL Anywhere Studio version 8.


Adaptive Server Anywhere new features

This section introduces the new features in Adaptive Server Anywhere version 8.0. It provides an exhaustive listing of major and minor new features, with cross references to locations where details of each feature appear in the manuals.

If you have the printed version of this book, and if you do not have the complete SQL Anywhere Studio documentation set, you should look in the online documentation for a detailed description of each feature.

Some new features require that you upgrade the database to version 8, or that you upgrade the database file format by unloading and reloading the database. If a database upgrade or file format upgrade is required to access a particular feature, the requirement is indicated in the description below.

For information on how to carry out these tasks, see Upgrading Adaptive Server Anywhere.

The Adaptive Server Anywhere new features are grouped under the following headings:

  • Query processing and database performance

  • Security

  • SQL features

  • Development and administration tools

  • Application development

  • Administration and troubleshooting

  • Client/server connections

  • Java in the database

  • Documentation

  • Miscellaneous

Query processing and database performance
Security
SQL features
Development and administration tools
Application development
Administration and troubleshooting
Client/server connections
Java in the database
Documentation
Miscellaneous


Query processing and database performance

  • Improved query processing This version includes enhancements to the query execution engine and the optimizer, resulting in a significant improvement in performance, especially for complex queries. Enhancements to Adaptive Server Anywhere query processing include the following:

    • More sophisticated internal processing of joins.

    • Improvements to the optimizer's cost model used to assess alternative access plans.

    • Improvements to the execution model.

      Most of these changes are internal. Documentation is provided in Query Optimization and Execution.

    An effect of these changes is that it is no longer the case that the materialization of results is necessarily inefficient. Use of temporary work tables may be a very efficient way to execute a query. For more information, see Use of work tables in query processing.

    The optimizer now performs cost-based selection of indexes, and does not solely rely on predicate selectivities as was the case with prior releases.

    Much of the improved query processing does not require an upgraded database. To use the new cost model on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

  • New index type A new type of index has been added that improves performance for multiple column indexes and for indexes that include wide columns. It is a compressed B-tree index.

    Adaptive Server Anywhere automatically creates the appropriate type of index based on index width (the sum of the width of all columns in the index). A compressed B-tree index is created when the width of the index is greater than nine bytes and less than one-eighth of the page size to a maximum of 256 bytes; otherwise, Adaptive Server Anywhere creates hash B-tree indexes.

    The WITH HASH SIZE clause of the CREATE INDEX statement is deprecated.

    For more information about these indexes, see Types of index.

    To use the new index types on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

    A new limitation is imposed: foreign key indexes must have the same size and type as the corresponding primary key index.

    dbunload now omits the hash size specification if it was originally specified with the default (WITH HASH SIZE 10).

  • New database option OPTIMIZATION_GOAL Determines whether query processing is optimized towards returning the first row quickly, or minimizing the cost of returning the complete result set. The default is to optimize for the first rows.

    For more information, see OPTIMIZATION_GOAL option [database].

  • Performance enhancements for table scans Databases created in Adaptive Server Anywhere 8.0 with 2K, 4K, or 8K pages have performance-enhancements for queries that require sequential table scans. Adaptive Server Anywhere creates bitmaps, also known as page maps, for large tables. A bitmap lists all of the pages containing data for a given table. This feature permits searching large tables in only one I/O operation.

    For more information, see Table and page sizes.

    To gain the benefits of this enhancement on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

  • Improved storage of checkpoint log The checkpoint log is now stored in consecutive pages at the end of the database file. This leads to improved performance by allowing sequential scans and multipage writes of the material in the checkpoint log.

    For more information about the checkpoint log, see Checkpoints and the checkpoint log.

    To gain the benefits of this enhancement on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

  • Plan caching Adaptive Server Anywhere now caches execution plans for queries and INSERT, UPDATE and DELETE statements performed inside stored procedures, user-defined functions, and triggers. The maximum number of plans to cache is specified with the option setting MAX_PLANS_CACHED. To disable plan caching, set this option to 0.

    For more information, see Access plan caching.

  • Overriding the default I/O cost model You can now override the default I/O cost model using the ALTER DATABASE statement with the CALIBRATE clause.

    For more information, see ALTER DATABASE statement.

  • New database option MAX_PLANS_CACHED Sets the maximum number of execution plans that are stored in cache.

    For more information, see MAX_PLANS_CACHED option [database].

  • New database option MIN_TABLE_SIZE_FOR_HISTOGRAM This option sets the minimum table size for which histograms are created. Histograms store information about the distribution of values in a column, and the optimizer uses them to choose an efficient execution plan.


Security

  • Strong encryption over TCP/IP Adaptive Server Anywhere now supports certificate-based encryption over TCP/IP ports on Solaris, Linux, NetWare, and all supported Windows operating systems with the exception of Windows CE. Strong encryption protects the confidentiality and integrity of network packets as they pass between the client and the server. This encryption is also called Transport Layer Security (TLS).

    The database server -ec command line option allows you to set the server's connection parameters and replaces the -e command line option in previous versions of Adaptive Server Anywhere. You can set the client connection parameters with the encryption connection parameter.

    For more information, see -ec server option and Encryption connection parameter [ENC].

    To use this feature, you must use version 8 software at both the client and the server. You do not need to upgrade the database.

  • Strong encryption of the database file The database file itself can now be strongly encrypted for greater security, especially on notebook and laptop computers prone to theft.

    For more information, see the following locations:

    • Creating a database using the dbinit command-line utility

    • -ek database option

    • -ep server option

    • CREATE DECRYPTED FILE statement.

      You must use version 8 software to create encrypted database files.


SQL features

  • Full outer joins Full outer joins are now supported. In addition, the keyword OUTER is now optional for right, left, and full outer joins.

    For more information, see Outer joins.

  • CASE statements The ANSI standard allows two forms of CASE statements. Adaptive Server Anywhere 8.0 supports both syntaxes.

    For more information, see CASE statement.

  • WAITFOR statement This statement delays processing for the current connection for a specified amount of time or until a given time.

    For more information, see WAITFOR statement.

  • RAISERROR statement allows connections to be disallowed This statement can now be used to disallow or limit connections.

    For more information, see RAISERROR statement [T-SQL].

  • Timezone adjustment To permit easier coordination of date/time values across time zones, the following new features have been added:

    • CURRENT UTC TIMESTAMP Adjusts the time zone value by the server's time zone adjustment value.

    • DEFAULT UTC TIMESTAMP Specifies a default value for INSERTs and sets updated columns to the value.

    • TimeZoneAdjustment property returns the number of minutes that must be added to the Coordinated Universal Time (UTC) to display the new local time.

    • TIME_ZONE_ADJUSTMENT option Allows a connection's time zone adjustment to be modified.

  • New collation functions The SORTKEY function generates values that can be used to sort character data. SORTKEY allows you to perform sorting beyond the default behavior of Adaptive Server Anywhere collation.

    The COMPARE function allows you to directly compare two character strings based on alternate collation rules.

    For more information, see SORTKEY function [String] and COMPARE function [String].

  • ERRORMSG function The new SQL function ERRORMSG can be used to obtain error messages.

    For more information, see ERRORMSG function [Miscellaneous].

  • Data type conversion functions The ISDATE and ISNUMERIC functions test if a string can be converted to a date or number, respectively.

    For more information, see ISDATE function [Data type conversion], and ISNUMERIC function [Miscellaneous]


Development and administration tools

  • Accessibility features SQL Anywhere Studio is compliant with Section 508 of the US Federal Rehabilitation Act. The user interfaces and documentation have been prepared in compliance with the act. An accessibility enablement component provides software that enables the use of accessibility tools. The accessibility enablement component is not installed by default.

    For more information, see Welcome to SQL Anywhere Studio.

  • Query Editor A graphical query editor has been added to Interactive SQL. With the Query Editor, you can create or edit SELECT statements without using SQL code. You can open the Query Editor in Interactive SQL by clicking Tools > Edit Query.

    For more information, see Introducing the Query Editor.

  • Editable data in Interactive SQL and Sybase Central You can update the database by editing Interactive SQL result sets, and by editing tables and views in Sybase Central. You can copy, edit, insert, and delete row values.

    Data displayed in Sybase Central can be copied to the clipboard.

    For more information, see Editing table values in Interactive SQL.

  • Interactive SQL supports SQL escape syntax handling Interactive SQL now supports JDBC escape syntax that allows you to access a library of functions implemented by the JDBC driver.

    For more information, see Using JDBC escape syntax.

  • Procedure profiling Sybase Central contains a Profile tab that displays information about the number of calls and execution times for stored procedures, functions, events, and triggers. You can also view information about the execution speed for each line within a procedure. Profiling information is available through Sybase Central and SQL stored procedures.

    For more information about viewing procedure profiling information in Sybase Central, see Profiling database procedures.

    For more information about obtaining procedure profiling information with SQL stored procedures, see sa_procedure_profile_summary system procedure and sa_procedure_profile system procedure.

    To use this feature, you must upgrade the database.

  • Improved information for access plans There are two new ways to view the plan, a graphical display and a graphical display with statistics. These new plans provide more information about the processing cost of your query, and allow you to examine the cost of subsets of the query. The default access plan is now the graphical plan. The long and short plans are now based on the Ariadne syntax used by Adaptive Server Enterprise, and have new abbreviations.

    For more information, see Reading access plans.

  • Results pane displays query execution plan The Interactive SQL Results pane now has a Results tab. The Results tab displays the results of your query, and the Plan tab displays the execution plan for the query. Previously, the query execution plan appeared in the Interactive SQL Messages pane.

    For more information, see Options dialog: Results tab.

  • Results pane displays UltraLite plan The Interactive SQL Results pane now has an UltraLite Plan tab. This tab displays the UltraLite plan optimization strategy in XML format, as a string.

    For more information, see GRAPHICAL_ULPLAN function [Miscellaneous].

  • XML export using the OUTPUT statement You can export query results as XML format. The output has an embedded DTD. Binary values are encoded in CDATA blocks with the binary data rendered as two-hexadecimal-digit strings.

    For more information, see OUTPUT statement [Interactive SQL].

  • Interactive SQL batch options Additional control is given to Interactive SQL when running batch files, through the -codepage and -onerror command line options. Also, the -d1 command line option provides feedback useful for debugging batch files.

    For more information, see The Interactive SQL utility.


Application development

  • New cursor types The cursors supplied by Adaptive Server Anywhere have been enhanced to provide cleaner semantics, to better match new cursor types such as keyset-driven cursors, and to take advantage of the new query optimization possibilities.

    For more information, see Adaptive Server Anywhere cursors.

  • Improved fetching for long columns The amount of data that can be fetched in a single operation has been increased from 32 kb to a configurable value with a default of 256 kb. In ODBC the value can be set using the SQL_ATTR_MAX_LENGTH statement attribute. In embedded SQL, use the DT_LONGVARCHAR and DT_LONGBINARY types.

    For more information, see Retrieving data, and Sending and retrieving long values.

  • New embedded SQL function to obtain database properties The function db_get_property can be used to obtain database properties.

    For more information, see db_get_property function. For information on database properties, see Database properties.

  • BLOCKING_TIMEOUT option The new BLOCKING_TIMEOUT option lets you control how long a transaction waits to obtain a lock.

    For more information, see BLOCKING_TIMEOUT option [database].

  • RETURN_DATE_TIME_AS_STRING option The RETURN_DATE_TIME_AS_STRING option allows you to control how date, time, and timestamp values are returned over jConnect and Open Client.

    For more information, see RETURN_DATE_TIME_AS_STRING option [database].


Administration and troubleshooting

In addition to the administration enhancements added to Sybase Central, listed above, version 8 includes the following administration enhancements.

  • Improve table performance without disrupting access The REORGANIZE TABLE statement can be used to improve performance when a full rebuild of the database is not possible, due to the requirements for continuous access to the database. Use this statement to defragment rows in a table, or to compress indexes which have become sparse due to DELETEs. It can also reduce the total number of pages used to store the table and its indexes, as well as reduce the number of levels in an index tree.

    To reorganize tables based on a primary key, foreign key, or index, the database must be Adaptive Server Anywhere version 7 or above.

    For more information, see REORGANIZE TABLE statement.

  • Fast database validation A new type of validation check has been added that reduces the amount of time it takes to validate a database. This option is of particular interest to people who need to validate large databases with small cache sizes. Affected tools include the sa_validate system procedure, the Validation utility (dbvalid) and the VALIDATE TABLE statement.

    For more information, see Improving performance when validating databases.

    To use this feature on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

  • Backup does not need to wait for outstanding transactions to complete If a backup instruction requires the transaction log to be truncated or renamed, uncommitted transactions are carried forward to the new transaction log. This means that the server no longer waits for outstanding transactions to be committed or rolled back before initiating a backup.

    For more information, see Translating a transaction log using the dbtran command-line utility and Backup internals.

    To use this feature on databases created before this release, you must upgrade the database file format by unloading and reloading the database.

  • Obtaining fragmentation statistics File, table, and index fragmentation can all decrease performance. In Adaptive Server Anywhere 8.0 when you start a database on Windows NT, the server automatically displays information about the number of file fragments in each dbspace.

    The new system procedures, sa_table_fragmentation and sa_index_density, allow database administrators to obtain information about the fragmentation in a database's tables and indexes.

    For more information about file fragmentation, see File fragmentation.

    For more information about table fragmentation, see Table fragmentation and sa_table_fragmentation system procedure.

    For more information about index fragmentation, see Index fragmentation and sa_index_density system procedure.

  • Obtain the most recently prepared SQL statement for a connection The database server -zl command line option turns on capturing of the most recently prepared SQL statement for each connection to databases on a server. You can also turn on this feature using the sa_server_option stored procedure with the remember_last_statement setting.

    When this feature is turned on, the LastStatement property function and the sa_conn_activity system procedure return the most recently prepared SQL statement for the current connection and all connections to databases on a server respectively.

    For more information, see -zl server option, sa_conn_activity system procedure, and sa_server_option system procedure.

  • -cw command line option This server option lets you use cache sizes up to 64 Gb on Windows 2000, Windows XP, and Windows Server 2003.

    For more information, see -cw server option.

  • -qp option This server option lets you suppress messages about performance in the database server window.

    For more information, see -qp server option.

  • Improved debugging server log The information logged in the connection debugger has been improved to give more context about the portion of the connection being attempted; to remove the CONN: prefix; to increase the number of TCP/IP messages.

  • Databases can hold more procedures The primary key values for the SYSPROCEDURE, SYSPROCPARM, SYSPROCPERM, and SYSTRIGGER system tables have been changed from SMALLINT to UNSIGNED INT. This change increases the number of procedures that a database can hold.

    For more information about the number of procedures a database can hold, see Size and number limitations.

    To use this feature, you must upgrade the database file format.

  • Monitoring query performance New system procedures and utilities have been included to measure query performance.

    For more information, see sa_get_request_profile system procedure, sa_get_request_times system procedure, and Monitoring query performance.

  • New diagnostic properties Properties allow you to obtain information about connections, databases, and the current database server. The following connection properties have been added in this release:

    • UtilCmdsPermitted property

    • TempTablePages property

    • LastStatement property

    • PacketSize property

    • Max_plans_cached property

    • QueryCachePages property

    • QueryLowMemoryStrategy property

      For more information, see Connection-level properties.

    The following database properties have been added in this release:

    • DBFileFragments property

    • LogFileFragments property

    • BlobArenas property

    • SeparateForeignKeys property

    • VariableHashSize property

    • TableBitMaps property

    • FreePageBitMaps property

    • SeparateCheckpointLog property

    • Histograms property

    • LargeProcedureIDs property

    • PreserveSource property

    • TransactionsSpanLogs property

    • Capabilities property

    • TempTablePages property

    • CompressedBTrees property

    • ProcedurePages property

    • QueryCachePages property

    • QueryLowMemoryStrategy property

      For more information, see Database-level properties.

    The following server properties have been added in this release:

    • MachineName property

    • IsJavaAvailable property

    • PlatformVer property

      For more information, see Server-level properties.

  • Additional performance monitor statistics Several performance monitor statistics have been added for this release.

    For more information, see Database performance statistics.

  • Login procedure allows connections to be disallowed The LOGIN_PROCEDURE option allows a stored procedure to be called for each new connection. This procedure can now be used to disallow database connections.

    For more information, see LOGIN_PROCEDURE option [database].

  • dbsvc enhancements The dbsvc command line utility for managing Windows services has been extended to list service name used to start and stop the service with the system net start and net stop commands, and to handle dependencies on other services and groups.

    For more information, see The Service Creation utility.

  • Source format preserved for stored procedures The source format, including spaces and line breaks, is now stored in the database as a comment. This comment is used for procedure profiling.


Client/server connections

  • Improved buffer size negotiation Buffer sizes can now be specified separately for both the client and the server.

    To use this feature, you must use version 8 software at both the client and the server. You do not need to upgrade the database.

  • Communication compression A new type of communication compression can lead to improved performance if you are transferring data across networks with limited bandwidth, including some wireless networks, some modems, serial links and some WANs.

    For more information, see Adjusting communication compression settings to improve performance.

    To use this feature, you must use version 8 software at both the client and the server. You do not need to upgrade the database.

  • Enhanced dbping The dbping utility has additional options to help diagnose connection problems. These include the ability to use ODBC to connect, and the ability to report connection, database, and server properties upon connection.

    For more information, see The Ping utility.

  • Suppress TDS debugging option The SUPPRESS_TDS_DEBUGGING option controls whether TDS debugging information appears in the server window.

    For more information, see SUPPRESS_TDS_DEBUGGING option [database].

  • PrefetchBuffer connection parameter This connection parameter lets you specify the maximum amount of memory for storing prefetched rows.

    For more information, see PrefetchBuffer connection parameter [PBUF].

  • PrefetchRows connection parameter The PrefetchRows connection parameter lets you specify the maximum number of rows to prefetch when querying the database. In some circumstances, increasing the number of rows prefetched from the database server by the client can improve query performance.

    For more information, see PrefetchRows connection parameter [PROWS].

  • Client can specify idle timeout Each client can specify its own idle timeout using the IDLE connection parameter. Previously, all connections to a server used the same idle timeout which was specified by the -ti server command line option.

    For more information, see Idle connection parameter [IDLE].


Java in the database

Java in the database includes the following new features:

  • Java 2 support Java in the database can now use classes from Java 2 (JDK 1.2 and 1.3) and Java.

    For more information, see Java-enabling a database.

    To use this feature, you must upgrade the database using ALTER DATABASE or by using the dbupgrad command line utility and supplying the -jdk option.

  • JDBC 2.0 Java classes in the database can now use the JDBC 2.0 interface to access data.

    For more information, see JDBC in the database features.

    To use this feature, you must upgrade the database using ALTER DATABASE or by using the dbupgrad command line utility and supplying the -jdk option.

  • Diagnostic procedure A new system procedure, sa_java_loaded_classes, lists all classes loaded by the Java virtual machine.

    For more information, see sa_java_loaded_classes system procedure.

    To use this feature, you must upgrade the database.

  • Security manager You can use a built-in security manager or provide your own implementation to control access to security-sensitive Java features.

    For more information, see Security management for Java.


Documentation

Several new features have been added to the Adaptive Server Anywhere documentation set to help you find, access and use the information more quickly.

  • Re-organized books There have been two major changes to the documentation set since the last release:

    • The Replication and Synchronization Guide has been split into two books, describing each of the two synchronization technologies separately. These new books are the MobiLink Synchronization User's Guide and the SQL Remote User's Guide.

    • The Adaptive Server Anywhere User's Guide, Programming Interfaces Guide, and Reference Manual have been replaced by a Database Administration Guide, a SQL User's Guide, a SQL Reference Manual, and a Programming Guide. The database error messages have been moved into their own book. The new organization makes each book a more manageable size in printed form.

  • New context-sensitive Help All the user-interface tools, including Sybase Central, Interactive SQL, the Adaptive Server Anywhere debugger, and the Query Editor, share a common cross-platform context-sensitive help system, complete with links to the online books.

  • Enhanced online books The HTML Help version of the online books includes a menu bar for quick access to SQL Anywhere Web links, tutorials, procedures, and more.


Miscellaneous

  • Connections persist across hibernation times Connections from embedded SQL, ODBC or OLE DB clients now persist while a computer hibernates. Previously, TCP/IP connections between a client and a server on the same machine would be dropped when the machine was woken from hibernation if the machine hibernated for longer than the liveness or idle timeout time.

  • Viewing current license information The dblic utility now accepts an argument that allows you to view current license information for a server executable without starting the server.

    For more information, see The License utility.

  • Viewing collation label and name for custom collations The dbinfo command line utility now returns the collation label and name for custom collations. As well, two new fields, collationnamebuffer and collationnamebufsize, have been added to the a_db_info structure in dbtools.h.

    For more information, see Obtaining database information using the dbinfo command-line utility and a_dbtools_info structure.

  • sp_remote_tables system procedure A new argument, tabletype, has been added to the sp_remote_tables stored procedure. This argument returns the remote table's type.

    For more information about the tabletype argument, see sp_remote_tables system procedure.

  • -ct command line option Using the -ct command line option, you can turn character set translation on and off. Character set translation is now enabled by default, and to turn it off, you can specify -ct-. To turn character set translation on, use -ct+.

    For more information, see -ct server option.

  • Obtain remote table foreign key information Two new stored procedures, sp_remote_exported_keys and sp_remote_imported_keys, allow you to obtain information about foreign keys and their corresponding primary keys for remote tables.

    For more information, see sp_remote_exported_keys system procedure and sp_remote_imported_keys system procedure.

  • xp_sendmail There are now extended stored procedures for sending email over SMTP as well as MAPI. For more information, see xp_startsmtp system procedure and xp_stopsmtp system procedure.

    The xp_sendmail stored procedure now accepts messages of any length. The length of the long VARCHAR parameters for the procedure is limited to the amount of memory available on your system.

    For more information, see xp_sendmail system procedure.

  • Replication Server 12 feature for the log transfer manager The qualify_table_owner parameter in the LTM configuration file provides support for the Replication Server 12 feature allowing the table names, owners, and column names in the primary databases to be different from the replication databases.

    For more information, see The LTM configuration file.

  • ASANYSH8 environment variable A new environment variable, ASANYSH8, has been added. Interactive SQL, Sybase Central, the Adaptive Server Anywhere Console utility, and the debugger use this environment variable to located the shared components directory.

    For more information about the ASANYSH8 environment variable, see Setting environment variables.


MobiLink new features

The following is a list of changes and additions to the software introduced in version 8.0.

Flexibility

  • Java synchronization logic Synchronization scripts can now be implemented in Java instead of or in addition to the SQL language. These scripts are run in an external JRE using the MobiLink Java environment.

    For more information see Writing Synchronization Scripts in Java.

  • Synchronization using publications All the data in a MobiLink client no longer needs to be synchronized at the same time. Rather, data can be organized into publications and each publication synchronized independently. A new syntax for publications and synchronization subscriptions is provided, that is simpler and more precise than the previous syntax.

    For more information see Adaptive Server Anywhere Clients.

  • Configuring Web servers to handle MobiLink synchronization You can now carry out HTTP synchronization with the MobiLink synchronization server behind a firewall. A Web server plug-in for popular Web servers allows you to carry out HTTP synchronization through Web servers.

    For more information, see Synchronizing Through a Web Server With the Redirector.

  • ActiveSync support for Windows CE clients Both Adaptive Server Anywhere and UltraLite Windows CE MobiLink clients can use the Windows CE ActiveSync synchronization software.

    For more information, see Using ActiveSync synchronization.

  • Enhanced client command line functionality You can specify extended options in both CREATE/ALTER SYNCHRONIZATION SUBSCRIPTION statements and on the command line.

    For more information see MobiLink synchronization client.

  • Extended options can be stored in the database Using the CREATE/ALTER SYNCHRONIZATION SUBSCRIPTION statements it is possible to store extended options and connection parameters in the database and associate them with subscriptions, users or publications. Dbmlsync now reads this information from the database.

    For more information see MobiLink synchronization client.

Performance

  • Statement-based uploads MobiLink now allows statement-based uploads that are not only more intuitive than cursor-based uploads, but also significantly faster. Statement-based uploads employ the upload_insert, upload_delete, upload_update, upload_new_row_insert, and upload_old_row_insert events. upload_fetch script is used for conflict resolution.

    For more information see Writing scripts to upload rows.

  • Multi-processor administration MobiLink has a new option for setting the maximum number of processors to use. The -zt option provides for greater control of the resources used by the MobiLink synchronization server. It can also help to discover and/or work around an ODBC driver with multi-processor issues.

    For more information see -zt option.

  • Optional download acknowledgement The MobiLink synchronization client can now synchronize without a download acknowledgement, so that the MobiLink synchronization server worker thread does not need to wait for the client to apply the download, freeing up the worker thread sooner for its next synchronization. Download acknowledgement is now an option. Eliminating the download acknowledgement can improve throughput, particularly for slower clients. Note that without a download acknowledgement, the consolidated side will not know that the download succeeded until the next synchronization.

    For more information, see dbmlsync extended options.

  • Buffered download stream The MobiLink synchronization server now buffers the download stream in a download cache. Since acknowledgement is not required from the client to commit the download transaction, the buffered download stream is sent to the client after the commit. The download transaction is no longer potentially held up by network delays.

    For more information, see -d option.

    The download stream can also be buffered at Adaptive Server Anywhere clients. The size of the buffer available can be set using the dbmlsync DownloadBufferSize extended option.

    For more information, see dbmlsync extended options.

  • Bulk loading of connection and table scripts The first connection or table script requested for a specific table to version_id pairing will cause a bulk load of all the scripts into the cache. The result is improved performance by getting all the scripts in bulk rather than individually.

  • MobiLink synchronization server shutdown enhancements You can tell dbmlstop to wait until the MobiLink synchronization server is completely shutdown before proceeding. You can also use dbmlstop to stop a specific MobiLink synchronization server by name.

    For more information see MobiLink stop utility.

  • Connection timeout MobiLink database connections that are unused for a specified amount of time are now disconnected automatically by the server. The timeout can be set using the -ct (connection timeout) command line option.

    For more information see -ct option.

  • Maximum number of concurrent uploaders option The -wu command line option can set the maximum number of worker threads allowed to upload concurrently, resulting in, for some deployments, increased throughput.

    For more information see -wu option.

Security

  • MobiLink user authentication A password-based system for user authentication adds additional security to your MobiLink installation. Now, using -zu, you can allow automatic addition of users when the authenticate_user script is undefined. This allows for user schema information to be used as MobiLink authentication.

    For more information, see Authenticating MobiLink Users.

  • MobiLink user administration The dbmluser utility has been extended to allow users to be deleted from the system as well as added. Other refinements have been made to this utility. The dbmluser command line options -pf, -pp, and -pu have been deprecated and replaced with -f, -p, and -u respectively.

    For more information, see MobiLink user authentication utility.

Enhanced reporting

  • Statistical scripts MobiLink now has scripts for tracking synchronization statistics. Once gathered, these synchronization statistics may be used for monitoring the performance of your synchronizations.

    For more information, see synchronization_statistics connection event, synchronization_statistics table event, upload_statistics connection event, and upload_statistics table event.

  • Detailed network error information The MobiLink synchronization server and client now display detailed error information along with error codes to help you better resolve any errors as they arise. You will see the network layer reporting the error, the network operation being performed, the error itself and a system-specific error code.

  • Remote Adaptive Server Anywhere output log sent to MobiLink synchronization server on error Troubleshooting synchronization problems is simplest when both the remote log and the MobiLink synchronization server log are available for inspection. This new feature sends the ASA remote's output log up to the MobiLink synchronization server when a client-side error occurs.

    For more information see -e option.

  • Log messages identify the worker thread Messages displayed to the MobiLink synchronization server log now indicate the worker thread that logged the message. This makes it possible to distinguish messages that are due to the same user attempting to synchronize concurrently. It also helps distinguish messages when the same user synchronizes twice without delay.

  • Verbose logging You can use additional modifiers on the MobiLink synchronization server -v command line option to configure MobiLink synchronization server logging.

    For more information see -v option.

  • Ignored rows are reported to clients If the MobiLink synchronization server ignores any uploaded rows because of absent scripts, a messages is returned to the client. The message is displayed as a warning by Adaptive Server Anywhere clients, and in the ignored_rows synchronization parameter in UltraLite clients.

    For more information, see Ignored Rows synchronization parameter.

Ease of use

  • Last download timestamp The last download timestamp is written to the MobiLink client database automatically.

  • Automatic synchronization script generation MobiLink can be instructed to generate scripts suitable for snapshot synchronization. The -za option controls creation and activation of these scripts.

    For more information see Generating scripts automatically

  • Example synchronization script generation MobiLink can be instructed to generate example synchronization scripts. The -ze command line option is used to control whether example scripts are to be generated.

    For more information, see Generating example scripts

Adaptability

  • Support for popular RDBMSs As consolidated databases, MobiLink now supports Oracle 8i and 9i, Microsoft SQL Server 7, Microsoft SQL Server 2000, IBM's DB2 and more.

    For more information, see ODBC drivers supported by MobiLink.

  • Liveness detection in TCP/IP streams The TCP/IP-based streams that are used during MobiLink synchronization now accept a new parameter, both on the client and server side, called keep_alive, that enables liveness checking.

    For more information, see -x option.


UltraLite new features

UltraLite 8.0 introduces the following new features:

Security

  • User authentication In previous releases, UltraLite databases had no user authentication mechanism to govern access. In this release, a built-in user authentication mechanism is provided. Unlike user IDs for most relational database-management systems, the UltraLite user IDs do not imply any ownership of tables and other database objects.

    For more information, see User authentication in UltraLite.

  • Database encryption You can improve the security of your data by encrypting your database. Two methods are supplied.

    • Strong encryption The database can be encrypted using a strong encryption algorithm for maximum security. There is a performance penalty to pay for this security. The encryption is key-based and uses the AES 128-bit algorithm.

    • Database obfuscation You can improve the security of your data by obfuscating the database. Without obfuscation, the data in the database is viewable using a tool such as a hex editor. Obfuscation prevents casual attempts at viewing data but does not offer the watertight protection of strong encryption. Obfuscation does not have the performance penalty that strong encryption carries.

      For more information, see Encrypting UltraLite databases.

  • Secure synchronization for UltraLite Java applications Secure synchronization using Certicom transport-layer security was previously available only from C/C++ UltraLite applications. It is now available from UltraLite Java applications.

    For more information, see Using transport-layer security.

Synchronization

  • ActiveSync synchronization UltraLite applications on Windows CE devices can use ActiveSync to synchronize.

    For more information, see Adding ActiveSync synchronization to your application.

  • More flexible synchronization Several new features have been added to enable more efficient and flexible selection of data to synchronize:

    • You can use publications to partition your data into different sets, which can be synchronized separately. This permits the efficient synchronization of time-sensitive data, perhaps over slow connection links, while other data can be synchronized at a more convenient time.

    • Download-only synchronization permits you to add read-only tables to your UltraLite database, and to synchronize them efficiently using a download-only synchronization.

      For more information, see Including read-only tables in an UltraLite database.

    • You can mark a table to be synchronized each time, whether or not the data in the table has changed. This feature allows you to maintain user-configurable information on the UltraLite client that controls synchronization.

      For more information, see Using client-specific data to control synchronization.

  • Global autoincrement default column values This feature provides a straightforward way of maintaining primary key uniqueness in a synchronizing database.

    For more information, see Declaring default global autoincrement columns.

  • Additional control for UltraLite generator New command line options have been added for the ulgen and sqlpp executables:

    • Script version You can associate a script version with generated synchronization scripts.

    • Log query execution plans The query execution plans for generated queries can be exported and displayed in Interactive SQL.

      For more information, see The UltraLite Generator, and The SQL Preprocessor.

  • Error reporting The stream_error field on the ul_synch_info structure can be used to determine the cause of synchronization errors.

    For more information, see Stream Error synchronization parameter.

Database management

  • Re-use of existing databases In previous releases of UltraLite, any change to a database application required a rebuild and synchronization of the database. With this release, you can continue to use an UltraLite database with a new version of your application as long as the database schema does not change. Changes to queries do not of themselves require a new database, unless they reference new columns and so change the schema of the generated database.

  • Database defragmentation The UltraLite store is designed to efficiently reuse free space, so that explicit defragmentation is not required under normal circumstances. For applications with extremely strict space requirements, an explicit defragmentation function is provided.

    For more information, see Defragmenting UltraLite databases.

  • Choice of page size You can choose to use 2 kb page sizes as an alternative to the default 4 kb pages.

    For more information, see UL_STORE_PARMS macro.

Development features

  • CodeWarrior 7 support The UltraLite plugin for CodeWarrior now supports CodeWarrior version 7.

  • eMbedded Visual C++ Development using this tool is supported, and an eMbedded Visual C++ project is supplied for the CustDB sample application.

  • Palm OS 4.0 and file-based data storage UltraLite now supports version 4.0 of the Palm Computing Platform. Beginning with Palm 4.0, a variety of secondary storage schemes is introduced. You can use a file-based UltraLite data store on an expansion card for a Palm 4.0 device.

    For more information, see ULEnableFileDB function.

  • Improved synchronization for Palm Computing Platform A new and simplified synchronization mechanism for HotSync and ScoutSync synchronization on the Palm Computing Platform has several benefits over previous synchronization mechanisms:

    • Launch and exit times are fast.

    • No extra storage is required on the Palm device during synchronization.

    • The application can be synchronized several times without launching.

    • No stream parameter needs to be specified.

    The ULPalmDBStream and ULConduitStream functions are deprecated.

    For more information, see Adding HotSync synchronization to Palm applications.

  • Easier deployment on the Palm Computing Platform You can deploy initial copies of the UltraLite database to your end users so that the first synchronization does not have to download an initial copy of the data for each user.

    For more information, see Deploying Palm applications.

  • Improved handling of Palm segments When developing for the Palm Computing Platform, application code must be divided into segments of limited size.

    The segmentation method provided in earlier versions of the software allowed no user control over the segmentation of the UltraLite generated code, and tended to assign too many segments (which could degrade performance). A new mechanism generates fewer segments and provides customers with control over the assignment of segments.

    For more information, see Enabling multi-segment code generation.

  • LONG values in embedded SQL You can use host variables for long values (between 32 kb and 64 kb) using the DECL_LONGVARCHAR and DECL_LONGBINARY.

  • Analyzer hooks in the reference database The UltraLite generator now invokes stored procedures before and after the analysis process.

    For more information, see The SQL Preprocessor, and The UltraLite Generator.

  • Query plan information The UltraLite generator can now output the access plan to be used for queries in UltraLite applications. Also, you can view the access plan that would be used for UltraLite from Interactive SQL.

    For more information, see The UltraLite Generator.

  • Script version control You can specify the script version to be used for synchronization on the UltraLite generator command line.

    For more information, see The UltraLite Generator.

  • Additional SQL and API features The following features are now available to UltraLite applications.

    • @@identity supported The @@identity global variable is now supported by UltraLite. This feature is useful in the context of global autoincrement default column values. In the C++ API, use the ULConnection::GetLastIdentity() method.

      For more information, see GetLastIdentity method.

    • Number of rows in a table From the C++ API programming interface you can determine the number of rows in a table using the ULTable::GetRowCount() method. Embedded SQL users continue to use the SELECT COUNT(*) FROM table-name statement.

      For more information, see GetRowCount method.

    • Delete all rows in a table From the C++ API programming interface you can delete all rows in a table using the ULTable::DeleteAllRows() method. Embedded SQL users continue to use the DELETE FROM table-name statement.

      For more information, see DeleteAllRows method.

    • Number of rows affected From embedded SQL you can determine the number of rows affected by the last INSERT, UPDATE, or DELETE statement using the SQLCOUNT macro.

    • Number of rows to be uploaded You can determine the number of rows that need to be synchronized.

      For more information, see ULCountUploadRows function, and CountUploadRows method.

    • Last download time You can obtain the last download time of a publication from the UltraLite application.

      For more information, see ULGetLastDownloadTime function and GetLastDownloadTime method.

    • Additional cursor operations The ULTable class of the C++ API has additional methods (FindFirst, FindNext, FindPrevious, FindLast) to locate rows in a result set.

      For more information, see ULTable class.

    • Queries from DUMMY system table Queries of the form SELECT ... FROM DUMMY are now supported.

    • Updating multiple tables Cursors over multiple tables can now accept updates that modify more than one table.

    • Improved LONG data type handling for embedded SQL The DECL_LONGVARCHAR and DECL_LONGBINARY host variable types can be used to send or retrieve data over 32 kb in a single operation.

      For more information, see Data types in embedded SQL.


SQL Remote new features

  • Event-hook procedures A set of event-hook procedures have been added to enable customization of the replication process. By writing stored procedures with specified names, you can add customizations at several points in the actions the Message Agent takes during replication.

    For more information, see SQL Remote event-hook procedures.


Behavior changes in version 8

This section lists the behavior changes introduced in components of SQL Anywhere Studio version 8.


Adaptive Server Anywhere behavior changes

The following are behavior changes from previous versions of the software.

For a list of newly deprecated and unsupported features, see Deprecated and unsupported features.

  • Java in the database separately licensable As a consequence, the default behavior when creating a database is to exclude support for Java in the database.

    Java in the database is no longer needed in UltraLite reference databases, as the UltraLite generator has been changed to use an external Java VM.

    For more information, see Welcome to SQL Anywhere Studio.

  • Aggregate functions and outer references Adaptive Server Anywhere version 8 follows new SQL/99 standards for clarifying the use of aggregate functions when they appear in a subquery. These changes affect the behavior of statements written for previous versions of the software: previously correct queries may now produce error messages, and result sets may change.

    For more information, see Aggregate functions and outer references.

  • User-supplied selectivity estimates Adaptive Server Anywhere allows you to specify explicit selectivity estimates to guide the choice of access plan. These estimates were most useful as workarounds to performance problems where the software-selected access plan was poor. The new USER_ESTIMATES connection option controls whether the optimizer uses or ignores user-supplied selectivity estimates.

    If you have used these estimates as a workaround to performance problems, we recommend setting the USER_ESTIMATES option to OFF because an explicit estimate may become inaccurate and may force the optimizer to select poor plans. This version includes query processing enhancements such as internal join algorithms which provide a significant improvement in query performance.

    For more information about user-supplied selectivity estimates, see USER_ESTIMATES option [database] and Explicit selectivity estimates.

  • Row ordering A side-effect of improvements to query processing for version 8.0 is that row ordering is less deterministic. In the absence of an ORDER BY clause, Adaptive Server Anywhere returns rows in whatever order is most efficient. This means the appearance of result sets may vary depending on when you last accessed the row and other factors. The only way to ensure that rows are returned in a particular order is to use ORDER BY.

    The LIST function is among those functions particularly affected by this change.

  • Access plan changes The access plans selected by this release of Adaptive Server Anywhere are less likely to use indexes than previous releases of the software. Improvements to the efficiency of table scans, together with a more selective cost model used in comparing the cost of access plans, leads to a more accurate assessment of the usefulness of indexes than in previous versions of the software.

  • Cursor changes A side effect of cursor enhancements is that the cursors in this version provide behavior closer to defined standards than before. This may produce cursor sensitivity changes for some cursors, as Adaptive Server Anywhere supplies behavior that better matches the expectations of ODBC and other interfaces. For example, embedded SQL SCROLL cursors now disallow prefetching, so that value changes are reflected in the cursor.

    This change may affect existing applications that check return codes only for SQL_SUCCESS and not SQL_SUCCESS_WITH_INFO. Applications that check for SQL_SUCCESS_WITH_INFO receive a warning if the cursor behavior is different from that requested. The warning is SQLCODE=121, SQLSTATE 01S02.

    Insensitive cursors are not updatable.

    For more information, see Insensitive cursors.

  • Stored procedure storage Stored procedures are now stored as written. Adaptive Server Anywhere does create an internal representation of the procedure, which is used for profiling.

  • OPEN CURSOR on insert not supported The ability to open a cursor on an INSERT statement has been dropped. Opening an updateable cursor on a SELECT statement gives the same capabilities in an industry-standard manner.

  • User-defined functions User defined function parameters and return values are now cached. If a function is used several times within a SQL statement, the cached parameter values may result in the cached result being used, instead of the function being evaluated again. In previous releases, user-defined functions were re-evaluated each time they were needed. The new behavior provides better performance and more consistent results, but may change results compared to previous releases of the software.

  • NUMBER(*) function changes The use of the NUMBER function has been restricted to avoid problematic behavior. NUMBER is intended for use in the select-list of a query, to provide a sequential row-numbering of the result set, and this use is still permitted.

    The NUMBER function may now give negative numbers in cases where it previously did not, such as if you carry out an absolute fetch with a value of -1 and then move backward through the cursor. The new behavior corresponds to the ISO/ANSI fetch offset.

    Use of the NUMBER function in many circumstances, such as a WHERE clause or a HAVING clause, now gives an error.

    For more information, see NUMBER function [Miscellaneous].

  • Custom collation changes Previously, the -d option in the Collation utility accepted three parameters; now it accepts only two parameters. The cust-map-file parameter is no longer accepted. The syntax for the Collation utility is

    dbcollat -d coll-defn-file custom-file

    As well, the script files collsqmp.sql and custmap.sql are no longer present and cannot be used for built-in or custom collations, respectively.

    For newly-created databases, the SYSCOLLATIONMAPPINGS table contains only one row with the collation mapping. For databases created with previous versions of Adaptive Server Anywhere, this table contains a row for each built-in collation.

    For more information, see The Collation utility and SYSCOLLATIONMAPPINGS system table.

  • Trigger name changes Trigger names no longer need to be unique across a database. They only need to be unique within the table to which they apply. The syntax of DROP TRIGGER and COMMENT ON TRIGGER has consequently changed so that you can only specify an owner if you also specify a table. This means that older scripts that qualify triggers with only an owner will now result in a "Table not found" error.

  • Addresses changed in sample database The addresses in the Adaptive Server Anywhere 9.0 Sample database are different from those in previous releases.

  • JAR file name for internal JDBC driver changed The internal JDBC driver classes are now installed as a JAR file named ASAJRT instead of ASAJDBC.

  • RESTORE DATABASE statement permissions A connection to the utility database is no longer required to execute a RESTORE DATABASE statement. The permissions required to execute a RESTORE DATABASE statement are controlled by the -gu command line option.

    For more information, see RESTORE DATABASE statement.

  • Return empty string as a NULL string for TDS connections The TDS_EMPTY_STRING_IS_NULL option controls whether the server returns empty strings as a string containing one blank character or a NULL string for TDS connections.

    For more information, see TDS_EMPTY_STRING_IS_NULL option [database].

  • COMMENT statement changed Previously, the syntax for COMMENT ON INDEX included an optional owner name of the index. The index name can now optionally include the owner and table. The syntax for COMMENT ON INDEX is now

    COMMENT ON INDEX [ [ owner.]table.]index-name IS comment

    For more information, see COMMENT statement.

  • Character set translation enabled by default In previous versions of Adaptive Server Anywhere, character set translation was turned off by default and you had to specify the -ct command line option to enable character set translation. Character set translation is now enabled by default, but can be disabled using the -ct- command line option.

    When the server determines that the connection's character set differs from the database's character set, the server applies character set translation to all the character strings sent to and from the server for that connection.

    The server disables character set translation for a connection when it determines that the database and the connection have equivalent character sets.

    In most cases, character set translation should be enabled. One possible change in behavior occurs when binary data is inserted into a database and is fetched as character data, or vice versa. In this case, the data may not be returned exactly as it was entered because the server applies character set translation only to character data. To avoid this problem, applications should not send or fetch character data using a binary type.

    For more information, see -ct server option and Turning off character set translation on a database server.

  • CONVERT, TIMESTAMP_FORMAT and DATE_FORMAT When using the TIMESTAMP_FORMAT or DATE_FORMAT options, if you specify a character symbol in mixed case (such as Mmm), Adaptive Server Anywhere now chooses the case that is appropriate for the language that is being used. In addition, the CONVERT function now converts character dates into the case that is appropriate to the language that is being used. For example, in English the appropriate case is May, while in French it is mai.

    For more information, see DATE_FORMAT option [compatibility], TIMESTAMP_FORMAT option [compatibility], and CONVERT function [Data type conversion].

  • Change to three-valued Boolean logic Two-valued Boolean logic applies only to cases of expr = NULL, where expr refers to a base column or an expression over a base column. Otherwise, three-valued logic applies. The ANSINULL option now affects only this specific case in the query's WHERE clause.

  • Sybase Central and Interactive SQL accept COMMLINKS connection parameter In previous versions of Adaptive Server Anywhere, Sybase Central and Interactive SQL (the dbisql utility) ignored the COMMLINKS connection parameter. Sybase Central and Interactive SQL now accept this parameter.

    As a result of this change, some connection strings may behave differently than in previous versions of Adaptive Server Anywhere. Specifically, if you do not supply COMMLINKS=tcpip, Interactive SQL and Sybase Central do not look for servers on the network.

    For more information, see CommLinks connection parameter [LINKS].

  • Clients ignore SQLLOCALE environment variable Clients can use the CharSet connection parameter to specify the character set to be used on a connection. In previous versions of Adaptive Server Anywhere, the CHARSET parameter of the SQLLOCALE environment variable was used to change the client's default character set if the CharSet connection parameter was not supplied. Clients now ignore the SQLLOCALE environment variable.

  • Unsupported character sets cause connection failure Clients can use the CharSet connection parameter to specify the character set to be used on a connection. However, if the server does not support the requested character set, the connection fails. When a client requested an unsupported character set in previous versions of Adaptive Server Anywhere, the connection succeeded with a warning. If the client does not specify a character set, but the client's local character set is unsupported by the server, the connection succeeds, but with a warning that the character set is not supported.

    This behavior occurs in version 8 clients connecting to version 6.x, version 7.x, and version 8 database servers.

  • Default packet size change The default packets size for client/server communications has been changed from 1024 bytes to 1460 bytes.

    For more information on packet size, see CommBufferSize connection parameter [CBSIZE], and -p server option.

  • dbdsn utility manages Adaptive Server Anywhere data sources only The dbdsn command line utility for managing Adaptive Server Anywhere ODBC data sources is now explicitly restricted to Adaptive Server Anywhere data sources only.

  • LOGIN_PROCEDURE option requires DBA authority The LOGIN_PROCEDURE option can only be set by a user with DBA authority. In previous versions of Adaptive Server Anywhere, DBA authority was not required to set this option. A user with DBA authority can change the setting of this option for other users, but users without DBA authority cannot change their own setting of this option. As a result of this change, the DBA can ensure that a common procedure, if necessary, is executed when a user connects.

    For more information, see LOGIN_PROCEDURE option [database].

  • ESTIMATE_SOURCE returns new values The ESTIMATE_SOURCE function returns more detailed values than previously.

    For more information, see ESTIMATE_SOURCE function [Miscellaneous].

Deprecated and unsupported features

This list includes features that are no longer supported and that impact existing applications.

  • NetWare 4.10 unsupported Novell NetWare version 4.11 and later is still supported. Versions 3.x and 4.10 are unsupported.

  • NetBios unsupported The NetBios port is no longer supported. If you use NetBios, you should switch to TCP/IP or SPX.

  • IPX unsupported The IPX port is no longer supported. If you use IPX, you should switch to SPX or TCP/IP.

  • Deprecated collations The following collations are no longer supported. Where indicated, they have been superceded by different collations:

    Deprecated | Superceded by
    437 | 437LATIN1
    850 | 850LATIN1
    852 | 852LATIN2
    860 | 860LATIN1
    863 | 863LATIN1
    865 | 865NOR
    SJIS | 932JPN
    SJIS2 | 932JPN
    WIN_LATIN1 | 1252LATIN1
    WIN_LATIN5 | 1254TRK
    Internal | 850LATIN1
    437EBCDIC

  • -e option no longer supported The -e command line option and the -e option in the Data Source Utility, used to encrypt client/server communications, are no longer supported. The -ec option has replaced them. On the server, -ec simple uses the same encryption algorithm as -e in previous versions of Adaptive Server Anywhere.

  • NONE parameter deprecated The NONE parameter for the ISQL_PLAN option is no longer supported. The query optimization plan now appears on the Plan tab in the Results pane. When you click the Plan tab, a plan always appears. Previously, the plan appeared in the Messages pane.

  • WITH HASH SIZE n clause deprecated The WITH HASH SIZE clause is no longer supported.

  • MAX_WORK_TABLE_HASH_SIZE option deprecated The MAX_WORK_TABLE_HASH_ SIZE option is no longer supported.

  • MAX_HASH_SIZE option deprecated The MAX_HASH_SIZE option is no longer supported.

  • SATMP environment variable deprecated The SATMP environment variable used by UNIX versions of Adaptive Server Anywhere to indicate a directory where temporary files are kept is no longer supported. On UNIX, the ASTMP environment variable can be used to indicate where temporary files are kept.

    For more information, see ASTMP environment variable.

  • dbtran -id option removed The -id command line option on the dbtran command line utility is not present in this software.


MobiLink behavior changes

  • MobiLink Adaptive Server Anywhere client setup MobiLink clients are now configured using publications and synchronization subscriptions, rather than synchronization definitions.

    For more information, see Adaptive Server Anywhere Clients.

  • Last download timestamp parameter changes scripts The addition of a new parameter to many scripts makes timestamp-based synchronization easier to implement. The new parameter breaks existing scripts, as it is supplied as the first parameter to many scripts. To continue using existing scripts, change the behavior to supply the last download timestamp as the final parameter by supplying the -zd MobiLink synchronization server command line option.

  • MobiLink shutdown Previously, dbmlstop commands from a remote connection could cause the MobiLink synchronization server to shut down. Now only dbmlstop requests from the same machine as the MobiLink synchronization server will cause the MobiLink synchronization server to shut down. The -zs option, which would allow dbmlstop to stop the server, is no longer required.

  • Default setting for liveness detection in TCP/IP streams has changed The default setting for keep_alive is now 1 (ON).

  • MobiLink can hide dbmluser information The amount of information displayed when the dbmluser command line utility is used, such as timestamp, copyright, and other MobiLink synchronization server messages no longer appear by default.

  • MobiLink user authentication You must use the -zu+ option on the MobiLink synchronization server command if you do not use MobiLink user authentication.

  • Default log extension now .mls Each file is now named DDMMYYNN.MLS where DD is the day of the month, MM is the month number, and YY is the year in the century. NN is a sequence number that starts at 1 with the first file.


UltraLite behavior changes

  • Required code change for Palm applications Your code must specify whether to use standard record-based database storage or to use the file-based expansion card storage for Palm Computing Platform version 4.x. You must add a single function call before calling ULPalmLaunch (embedded SQL) or ULData.PalmLaunch (C++ API). The function calls are as follows:

    ULEnablePalmRecordDB( &sqlca );

    or

    ULEnableFileDB( & sqlca );

    Supply ULEnablePalmRecordDB if you use record-based storage, and ULEnableFileDB for file-based storage. If the device does not support file-based storage, ULPalmLaunch sets SQLCODE -82.

The following platforms are no longer supported by UltraLite:

  • DOS target platform DOS is no longer a supported platform.

  • Metrowerks CodeWarrior 5 development platform CodeWarrior 6 is now required for UltraLite development.

  • Palm 2.x no longer supported UltraLite no longer supports development for Palm OS 2.x devices such as the PalmPilot Professional. Version 3.0 or later is required.

  • ULPalmDBStream and ULConduitStream deprecated The new synchronization stream for HotSync or ScoutSync synchronization on the Palm Computing Platform means that the ULPalmDBStream and ULConduitStream functions are obsolete. They are still accepted, but have no effect.

  • UltraLite generator uses external Java VM The UltraLite Analyzer now runs external to the database engine, and so can be used against reference databases even if they are not Java-enabled.

  • UltraLite JDBC package name changed The package name for the UltraLite JDBC functions has been changed from com.sybase.asa.ultralite.jdbc to ianywhere.ultralite.jdbc. This requires a change to the import statements used for UltraLite applications.

  • All changes must be committed before download synchronization Download-only synchronization is no longer an exception to the rule that all changes must be committed before synchronization.

  • dbmlsync StreamCompression extended option deprecated This option is now ignored.

You should also check Adaptive Server Anywhere behavior changes, as some may have an impact on your application. For more information, see Adaptive Server Anywhere behavior changes.


What's New in Version 7.0.3

About this chapter

This chapter provides an overview of the new features and behavior changes introduced in SQL Anywhere Studio version 7.0.3.


New features

This section introduces the new features in Adaptive Server Anywhere version 7.0.3. It provides a listing of major and minor new features, with cross references to locations where each feature is discussed in detail.

  • Database properties for blank padding and case sensitivity You can now use two new properties to determine if your database uses blank padding when comparing strings (BlankPadding) or if your database is case sensitive (CaseSensitive).

    For more information see Database-level properties.

  • Server property for C2 security mode You can now use the new C2 server property to determine whether the database server was started using the -sc option. The -sc option is intended for use in a C2-certified environment.

    For more information see Server-level properties.

  • Login procedure allows connections to be blocked The login_procedure option allows a stored procedure to be called for each new connection. This procedure can now be used to disallow database connections.

    For more information see LOGIN_PROCEDURE option [database].

  • FileDSN now supported on UNIX The FileDSN connection parameter for ODBC data sources is now supported on UNIX.


Behavior changes

The following is a behavior changes from previous versions of the software.

  • Load table semantics changed The LOAD TABLE command now has improved semantics if a column list is specified. A column list must specify each of the columns that exist in the file in the order in which they appear. Column names that do not appear in the list are set to NULL, zero, an empty string, or a default value, depending on the column nullability, data type, and default behavior.

    Columns that exist in the input file but which are to be ignored by LOAD TABLE can be specified using the column name filler().

    For more information see LOAD TABLE statement.


What's New in Version 7.0.2

About this chapter

This chapter provides an overview of the new features and behavior changes introduced in Adaptive Server Anywhere version 7.0.2.


New features in version 7.0.2

This section lists the new features introduced in components of SQL Anywhere Studio version 7.0.2.


Adaptive Server Anywhere new features

This section introduces the new features in Adaptive Server Anywhere version 7.0.2. It provides an exhaustive listing of major and minor new features, with cross references to locations where each feature is discussed in detail.

  • Dynamic cache sizing On Windows 95/98, the size of the database server cache increases and decreases depending on the load on the database server and the other demands on system memory. This feature removes the need for choosing an explicit cache size in many circumstances, and can also boost performance.

    For more information, see Dynamic cache sizing (Windows NT/2000/XP, Windows 95/98/Me).

  • Viewing current license information The License [dblic] utility now accepts an argument that allows you to view current license information for a server executable without starting the server.

    For more information, see The License utility.

  • Additional collations There are three new collations available: one to support Russian and Ukrainian (1251CYR, ANSI Code Page 1251), one to support Turkish (1254TRK, ANSI Code Page 1254) and one to support specialty requirements for some German users (1252DEU, ANSI Code Page 1252).

    The 1252LATIN1 collation continues to be the recommended German collation. 1252DEU is a specialty collation only, and should not be used without understanding its sorting and comparison properties.

    For a complete list of available collations, see Choosing collations.

  • Interactive SQL return codes When run from the command prompt, Interactive SQL now sets a program exit code indicating the success or otherwise of the operations in the session.

    For more information, see The Interactive SQL utility.

  • DELETE_OLD_LOGS enhancement The DELETE_OLD_LOGS database option is used in management of offline transaction logs in a replication environment. The option has been enhanced to permit more control over when processed transaction logs are deleted.

    For more information, see DELETE_OLD_LOGS option [replication].

  • Connection troubleshooting and enhancements The following changes have been made to permit better troubleshooting and tuning of client/server communications:

    • The APPINFO string is now added to the client debug log file.

      For more information, see AppInfo connection parameter [APP].

    • Two new connection parameters can be used to tune prefetching of rows.

      For more information, see PrefetchRows connection parameter [PROWS] and PrefetchBuffer connection parameter [PBUF].

    • The ConnectionName connection parameter value was previously overridden for ODBC clients. You can now use the ConnectionName parameter from ODBC clients.

      For a list of connection parameters, see Connection parameters.

  • Language utility The Language [dblang] utility allows you to report and modify the language registry for the Adaptive Server Anywhere messages and Sybase Central interface elements.

    For more information, see The Language utility.

  • dbspawn enhancement The Spawn [dbspawn] utility optionally reports the operating system process ID of the database server.

    For more information, see The Spawn utility.

  • First day of week option The default first day of week is now 7, which is Sunday. This value affects the result of DATEPART when obtaining a weekday value. You can change the first day of week using the DATEFIRST option in the Transact-SQL SET statement. You can set it permanently using SET OPTION FIRST_DAY_OF_WEEK=n.

    For more information, see SET statement [T-SQL], or FIRST_DAY_OF_WEEK option [database].

  • New migration tool You can migrate (import) remote Oracle, DB2, Microsoft SQL Server, Sybase Adaptive Server Enterprise, Sybase Adaptive Server Anywhere and Microsoft Access databases into Adaptive Server Anywhere using the new sa_migrate set of stored procedures.

    For more information, see Migrating databases to Adaptive Server Anywhere.

  • Event handlers Adaptive Server Anywhere can now determine how many instances of a particular event handler is executing at any given time. This is useful for limiting event handlers to only one instance at a time.

    For more information, see EVENT_PARAMETER function [System].

  • New connection property A new connection property helps distinguish between internal connections used to run event handlers.

    For more information, see CONNECTION_PROPERTY function [System].

  • Dbdsn supports user and system specifiers The Data Source [dbdsn] utility now supports the u (user) and s (system) options.

    For more information, see The Data Source utility.

  • Support for comments in @filename files Adaptive Server Anywhere now supports comment lines in @filename files.

    For more information, see @data server option.

  • Truncate timestamp option To allow for greater compatibility with non-Adaptive Server Anywhere databases, you can now truncate timestamp values.

    For more information, see TRUNCATE_TIMESTAMP_VALUES option [database].

  • Obtaining licensing information Engine properties have been added to help you obtain accurate licensing information about your copy of Adaptive Server Anywhere.

    For more information, see Server-level properties.

  • Resetting the autoincrement value The sa_reset_identity system procedure allows you to reset an autoincrement value for the next row.

    For more information, see sa_reset_identity system procedure.


MobiLink new features

  • Maximum number of threads applying upload streams To reduce database contention, the -wu command line option can now be used to set the maximum number of worker threads allowed to upload concurrently. The upload requests are processed in first-come, first-serve order.

  • For more information, see MobiLink Synchronization Server Options.


Behavior changes in version 7.0.2

This section lists the behavior changes introduced in components of SQL Anywhere Studio version 7.0.2.

Adaptive Server Anywhere behavior changes


Adaptive Server Anywhere behavior changes

The following are behavior changes from previous versions of the software.

  • Aliases must be defined before first reference In earlier versions of SQL Anywhere, it was possible to refer to an alias in a SELECT list before the definition of the alias had appeared. An attempt to do so will now generate the error "Definition for alias alias-name must appear before its first reference". To prevent this error, the SELECT list must be re-ordered so that the alias definition appears before its first use.


What's New in Version 7.0.1

About this chapter

This chapter provides an overview of the new features and behavior changes introduced in Adaptive Server Anywhere version 7.0.1.

New features in version 7.0.1


New features in version 7.0.1

This section lists the new features introduced in components of SQL Anywhere Studio version 7.0.1.


Adaptive Server Anywhere new features

This section introduces the new features in Adaptive Server Anywhere version 7.0.1. It provides an exhaustive listing of major and minor new features, with cross references to locations where each feature is discussed in detail.

  • New Service Creation utility Running a database server as a service under NT allows databases to keep running without tying up the machine on which they are running. Previously, you added services using the Create a New Service wizard from Sybase Central. In Version 7 of Adaptive Server Anywhere, you can now also manage ASA services on Windows NT using a the Service Creation [dbsvc] utility. A variety of options allow you to add or delete a service, list all ASA services, or display the details of a particular service. This feature is particularly useful for embedding the creation of a service in installations.

    For more information about the Service Creation utility, see The Service Creation utility.

  • Windows CE 3.0 support In addition to Windows CE 2.11, Adaptive Server Anywhere now supports Windows CE 3.0 on the following processors:

    • MIPS

    • Hitachi SH3.

    • ARM.

    Support for Windows CE 2.11 is provided on a wider range of platforms. For more information, see Windows and NetWare operating systems.

    With support for Windows CE 3.0, the OLE DB driver on CE works without installing any additional software.

  • Embedded SQL enhancements A new function, db_locate_servers, provides a programmatic way of locating Adaptive Server Anywhere database servers listening on TCP/IP.

    For more information, see db_locate_servers function.

    A new callback function, DB_CALLBACK_CONN_DROPPED, provides a way of adding logic when the database server is about to drop a connection.

    For more information, see db_register_a_callback function.

  • Connection-level Debug and Logfile connection parameters The DBG and LOG client-side connection parameters are now connection-specific, so you can configure debug information separately for different connections, even from the same application.

    For more information, see Logfile connection parameter [LOG].

  • New database property The LTMGeneration property has been added for users of the Replication Agent, or LTM. This property is primarily for use in technical support cases.

    For more information, see Database-level properties.

  • New deployment feature Users of InstallShield Professional 5.5 and up can use the new SQL Anywhere Studio InstallShield Template Projects to deploy their own application. This feature allows you to quickly build your application's installation using the entire template project, or just the parts that apply to your install.

    For more information, see Using InstallShield for deployment.

  • New backup statement feature When using the Backup statement, you can specify an empty string as a directory to rename or truncate the log without copying it first. This is particularly useful in a replication environment where space is a concern. You can use this feature with an event handler on transaction log size to rename the log when it reaches a given size, and with the DELETE_OLD_LOGS option to delete the log when it is no longer needed.

    For more information, see the BACKUP statement.


MobiLink new features

Following is a list of changes and additions to the software introduced in version 7.0.1.

  • User authentication A password-based system for user authentication adds additional security to your MobiLink installation.

    For more information, see Authenticating MobiLink Users.

  • Extensive documentation of transport-layer security The transport-layer security documentation has been extended to describe a variety of architectures possible with this powerful security mechanism.

    For more information, see MobiLink Transport-Layer Security.

  • Customizing synchronization and synchronization-related processes The Adaptive Server Anywhere synchronization client dbmlsync now supports a set of events. You can add stored procedures to your Adaptive Server Anywhere database to program event-based actions. This adds flexibility to the synchronization process, including the ability to schedule synchronization.

    For more information, see Customizing the client synchronization process.

  • Synchronization optimizations You can optimize the following aspects of the synchronization process.

    • UltraLite client applications can specify that a synchronization includes only uploads, and that no download phase should be attempted.

      This option lessens the overall synchronization time when only uploads are needed.

    • Adaptive Server Anywhere clients can specify an incremental upload option to reduce memory requirements for large uploads.

      For more information, see Customizing synchronization.

    • Adaptive Server Anywhere clients can permit concurrent modification of rows during synchronization.

      For more information, see Concurrency during synchronization.

  • Scheduling synchronization You can use an extended option to configure the dbmlsync utility or a synchronization definition to synchronize according to a schedule.

    For more information, see Scheduling synchronization.

  • Adaptive Server Anywhere client synchronization utility enhancements There are several enhancements to the dbmlsync utility:

    • You can supply the -mp and -mn options to supply or change the MobiLink password.

    • You can supply repeated -n options to synchronize more than one synchronization definition.

    • The -v option now generates more useful information, including options set in the synchronization definition.

    • The -r option is extended to allow more flexibility in uploads when the recorded progress indicators in the client and consolidated databases do not match.

    • The -x option renames and restarts the transaction log. This option is useful if you use the consolidated database as a backup of the data at the client, so that client-side backups are not required.

    • If you do not specify connection parameters on the command line, dbmlsync displays a dialog on which you can provide connection parameters and startup options.

    • The dbmlsync window displays synchronization progress, and allows you to cancel synchronization.

      For more information, see MobiLink synchronization client.

  • New MobiLink synchronization server options The MobiLink synchronization server provides additional options.

    For more information, see MobiLink Synchronization Server Options.

  • New script events New scripts have been added for handling and reporting errors arising from the ODBC Driver Manager, and to provide additional flexibility when designing synchronization techniques.

    For more information, see the following:

    • handle_odbc_error connection event

    • prepare_for_download connection event

    • report_odbc_error connection event

  • Interface to dbmlsync features Developers using the C programming language can add features of the dbmlsync utility to their application.

    For more information, see Initiating synchronization from an application.


SQL Remote new features

SQL Remote version 7.0.1 includes the following new features.

  • More message links on Novell NetWare You can now use the FTP and SMTP/POP message links on Novell NetWare.

  • Enhanced verbose mode Verbose mode for the Message Agent now writes out full connection information, with user IDs and passwords replaced by asterisks.


UltraLite new features

UltraLite 7.0.1 introduces several new features:

  • New synchronization stream for Palm Computing Platform In addition to the current ULPalmDBStream synchronization stream, a new synchronization stream is available for the Palm Computing Platform in this release. The new stream is called ULConduitStream, and in many circumstances this stream can provide dramatic performance improvements for HotSync synchronization.

    This feature superceded
    A new conduit-based synchronization stream introduced in version 8.0.0 supercedes both ULPalmDBStream and ULConduitStream.

  • Monitoring and canceling synchronization You can view synchronization status and build the ability to cancel synchronization into your UltraLite applications.

  • User authentication in MobiLink MobiLink synchronization now has its own user authentication scheme. Password fields and methods have been added to the UltraLite synchronization parameters to take advantage of this scheme.

    For more information, see Network protocol options for UltraLite synchronization clients.

  • New platforms for secure synchronization You can now use the transport-layer security features for synchronization from a wider range of target platforms, including Windows CE on the Hitachi SH4 chip, and VxWorks on Intel x86 chips and on the Windows VxSim emulator.

    For more information, see the following:

    • SQL Anywhere Studio Supported Platforms.

    • Network protocol options for UltraLite synchronization clients.

    • Synchronization on Windows CE.

      VxWorks unsupported in version 9
      Support for the VxWorks platform is dropped entirely in version 9.

  • Non-synchronizing tables You can include tables in the reference database that are included in the UltraLite database, but are not synchronized. Other than synchronization, the tables can be used like any other table in the remote database.

    For more information, see Including non-synchronizing tables in UltraLite databases.

  • Windows CE emulator support enhancements You can now run UltraLite applications under Windows CE x86 emulators.

  • Synchronization optimization Client applications can specify that a synchronization includes only uploads, and that no download phase should be attempted. This option lessens the overall synchronization time when only uploads are needed, especially over slow communication links.

    For more information, see Network protocol options for UltraLite synchronization clients.

  • Automatic HTTP version detection The MobiLink synchronization server now detects and uses the HTTP version used by each client. This capability renders the version parameter on the MobiLink synchronization server -x option redundant.

    For information on the MobiLink synchronization server command line, see MobiLink Synchronization Server Options.

  • Client port specification You can specify, at a client, a range of ports used by a client during synchronization. This feature can be useful when synchronizing from a client inside a firewall to a MobiLink synchronization server outside.

    For more information, see Network protocol options for UltraLite synchronization clients.


What's New in Version 7.0.0

About this chapter

This chapter provides an overview of the new features and behavior changes introduced in Adaptive Server Anywhere version 7.0.0.


New features in version 7.0.0

The primary format for the documentation is HTML Help. The HTML Help Home Page gives you easy access to the new features, information about how to contact Sybase, and other starting points for this release.

If you do not have Internet Explorer 4.0 or HTML Help installed on your machine, you will install Windows Help instead of HTML Help. The content is the same except for the HTML Help home page, which is not present in Windows Help.

If you are using Windows Help, you should look at Chapter 1 of Getting Started with Adaptive Server Anywhere for information on Adaptive Server Anywhere new features, and at the first chapters of the UltraLite Developer's Guide and the Replication and Synchronization Guide for information on new features in those technologies.


Adaptive Server Anywhere new features

This section introduces the new features in Adaptive Server Anywhere version 7.0. It provides an exhaustive listing of major and minor new features, with cross references to locations where details of each feature appear in the manuals.

If you have the printed version of this book, and if you do not have the complete SQL Anywhere Studio documentation set, you should look in the online documentation for the detailed description of each feature. To locate the information in the online documentation, go to the index and enter the specified title.

Administration and ease of use enhancements

  • Task scheduling and event handling in the database You can now add scheduled operations to the database. This can be useful for automatic backups, periodic reports to fill summary tables, and other tasks.

    The database server can also be instructed to execute event handlers when certain events occur, including disk space thresholds on the drives holding the database file or the transaction log file, or failed connection attempts.

    Event handlers can be created and altered using Sybase Central, and can be debugged using the Adaptive Server Anywhere debugger.

    For more information see Automating Tasks Using Schedules and Events, and CREATE EVENT statement.

  • Updated Sybase Central Sybase Central has been rewritten and contains significant new features. In particular, Sybase Central is now available from any supported platform, and not just Windows operating systems.

  • Updated Interactive SQL The Interactive SQL [dbisql] utility has been enhanced and is now available as a windowed-application from any supported platform.

  • New validation features Additional validation of databases is provided by the new VALIDATE INDEX statement and by enhancements to the VALIDATE TABLE statement. This statement is called both by the Validation [dbvalid] utility, and by the sa_validate system procedure. The enhancements are available through all these routes.

    For more information, see VALIDATE INDEX statement, and VALIDATE TABLE statement.

  • Lock troubleshooting A new system procedure, sa_locks, provides information on locks in the database. If lock issues are identified, information on the connection processes involved can be found using the AppInfo connection property.

    For more information, see sa_locks system procedure, and AppInfo connection parameter [APP].

  • Unloading result sets The new UNLOAD SQL statement allows query result sets to be unloaded into a comma-delimited text file.

    For more information, see UNLOAD statement.

  • Validate backup copies of databases If you backup a database using the WAIT BEFORE START clause, the backup copy is created in such a fashion that it can be started in read-only mode and validated.

    For more information, see BACKUP statement.

  • Default global autoincrement This feature provides an easy way to generate integer keys which are unique across all databases in a SQL Remote replication environment.

Integration with distributed computing architectures

  • Distributed transactions and three-tiered computing Distributed transactions include operations on more than one server in a single transaction. A transaction server controls the commit and rollback behavior of distributed transactions.

    In this release, Adaptive Server Anywhere can participate in distributed transactions coordinated by the Microsoft Distributed Transaction Coordinator (DTC). Products such as Sybase Enterprise Application Server and Microsoft Transaction Server can use DTC for transaction coordination, so DTC support enables Adaptive Server Anywhere to participate in three-tiered computing with these products.

    For more information, see Three-Tier Computing and Distributed Transactions.

Integration with COM

  • OLE DB provider OLE DB is a data access model from Microsoft. It uses the Component Object Model (COM) interfaces and, unlike ODBC, OLE DB does not assume that the data source uses a SQL query processor. While it has been possible to access Adaptive Server Anywhere via OLE DB using an OLE DB/ODBC bridge provided by Microsoft, this release of Adaptive Server Anywhere includes an OLE DB provider. This provider brings several benefits:

    • OLE DB is the principal data access option for the forthcoming version of Windows CE.

    • Some features, such as updating through a cursor, are not available using the OLE DB/ODBC bridge.

    • If you use the Adaptive Server Anywhere OLE DB provider, ODBC is not required in your deployment.

      For more information, see The OLE DB and ADO Programming Interfaces.

Connectivity enhancements

  • Java connectivity improvements If you use jConnect to connect to Adaptive Server Anywhere from a Java application, you can now take advantage of many of the features previously available only to ODBC and Embedded SQL applications, such as autostarting of database servers, and detailed control over network communications using protocol options.

  • TCP/IP connectivity Establishing a client/server connection over TCP/IP is now simpler. Clients no longer need to specify the port number when attempting to connect, even if the server is running on a port other than the default port number (2638). If the default port number is in use when a database server is started, the server acquires an unused port number from the operating system.

    If you are trying to connect through a firewall (using UseUDP=NO), and if the database server is not running on port 2638, you must still specify a port number. For more information on this scenario, see Connecting across a firewall.

    The Server Location [dblocate] utility displays all Adaptive Server Anywhere database servers running TCP/IP on a network. For more information, see The Server Location utility.

  • SPX connectivity You can use the SPX protocol for connecting to databases. This feature is particularly useful in Novell NetWare environments with IPX/SPX as the primary network protocol. SPX is recommended over IPX.

    For more information on SPX at the client, see CommLinks connection parameter [LINKS]. For information on SPX on the server, see -x server option. For network protocol options that you can use with SPX, see Network protocol options.

Performance enhancements

  • Dynamic cache sizing On Windows NT and UNIX, the size of the database server cache increases and decreases depending on the load on the database server and the other demands on system memory. This feature removes the need for choosing an explicit cache size under in many circumstances, and can also boost performance. On Windows 95/98, a less comprehensive cache resizing is implemented.

    For more information, see Using the cache to improve performance.

  • Indexing enhancements Additional flexibility has been added to control the amount of information stored in indexes (the hash size) to improve index selectivity. Also, the architecture of primary and foreign key indexes has been altered.

    For indexes on multiple columns, or for indexes on columns in which the first set of characters or digits are similar across many rows, control over hash size provides a way of increasing the selectivity of indexes, and so improving performance.

    For more information, see Using indexes, CREATE INDEX statement, and CREATE TABLE statement.

    For information on how to find the number of levels in an index, see sa_index_levels system procedure.

    In previous releases, primary and foreign keys have had a single index automatically associated with them, which describes all primary key values and all the related foreign key entries. In some situations, this architecture lead to poor performance. The new index organization separates these indexes, which leads to improved performance in some situations.

    For more information on key indexes, see Using keys to improve query performance.

    Your database must be unloaded and reloaded to take advantage of variable hash size indexes, and separate key indexes. Running the Upgrade [dbupgrad] utility is not sufficient.

  • Separate storage for string extensions The physical storage of values longer than 255 characters has been reorganized. The pages allocated for a table are now divided into two disjoint sets. The first set contain only rows. Where a column value in a row contains a string longer than 255 characters, only a prefix of the string (up to 255 characters) and a reference to a string extension are stored in the row. For strings longer than 255 characters, the string extensions are allocated in the second set of table pages. This change improves performance on queries requiring scans of tables storing long values because a sequential scan of a table only needs to traverse the pages in the first set.

    Your database must be unloaded and reloaded to take advantage of this feature.

  • New database page-sizes In addition to 1K, 2K, and 4K page sizes, you can now create databases with page sizes of 8K, 16K or 32K.

    Large page sizes can improve performance in some cases, particularly for large databases. However, there are additional memory requirements with large page sizes, and so they should only be used after investigation of the costs and benefits.

    For more information, see Creating a database using the dbinit command-line utility, and CREATE DATABASE statement.

    For information on the number of indexes per table and how it depends on page size, see Size and number limitations.

  • Optimizer tuning You can use the OPTIMIZATION_GOAL option to instruct the optimizer to optimize for the time it takes to return the first row of a query, or the overall time it takes to return all rows. The default is to optimize for the first row. If you are using applications such as PowerBuilder DataWindow applications, which require a complete result set, you may wish to change this option setting.

    For more information, see OPTIMIZATION_GOAL option [database].

  • Optimizer enhancements Further enhancements to the optimizer have been implemented to assist with performance of queries that use internal temporary tables and that use primary and foreign key indexes. These enhancements require no user action.

Miscellaneous enhancements

  • Larger numbers of users and other identifiers Many identifiers in the system tables identifying database objects have been changed from SMALLINT to UNSIGNED INTEGER. This change increases the number of objects that can be held in a database without violating an absolute limit.

  • Inserting and exporting images and documents Two new system external functions allow you to read and write the contents of files. These functions allow direct inserting of images, documents, and so on into tables from environments such as Interactive SQL.

    For more information, see Inserting documents and images, xp_read_file system procedure, and xp_write_file system procedure.

  • New interface for external functions Stored procedures and user-defined functions that reference external libraries now use a new interface. The new interface provides a wider range of operating systems (including UNIX), a wider range of data types, removes the restriction that returned data fit into 255 bytes, and supports NULL as a valid value for arguments. The older interface is still supported, but should not be used for new development work.

    For more information, see Creating procedures and functions with external calls.

  • START DATABASE, STOP DATABASE and STOP ENGINE statements These statements were previously available only from Interactive SQL. They are now available from all applications.

    For more information, see START DATABASE statement [Interactive SQL], STOP DATABASE statement, and STOP ENGINE statement.

  • FIRST and TOP clause in updates and deletes The FIRST and TOP clauses can be used to update or delete only the first one or more of any set of rows satisfying a WHERE clause.

    For more information, see DELETE statement, and UPDATE statement.

  • Explicit table locking The LOCK TABLE statement allows direct control over concurrency at a table level, independent of the current isolation level.

    For more information, see LOCK TABLE statement.

  • Expressions in Transact-SQL outer joins The *= and =* operators in a WHERE clause provide a way of specifying outer joins for users who wish to use the Transact-SQL dialect. In previous releases, only column names could be used in such joins. Now as long as each side of the join operator refers to a single table, any expression can be used in these joins. For example, the following query is now possible:

    select *
from customer, sales_order
where substr( customer.id, 1, 1 ) *=
      substr( sales_order.cust_id, 1, 1)

  • Cursors in stored procedures can reference variables In stored procedures and user-defined functions, you can declare a cursor on a variable using the following syntax:

    DECLARE cursor-name CURSOR USING variable-name

    where variable-name is a string variable containing the SELECT statement for the cursor.

    For more information, see DECLARE CURSOR statement [ESQL] [SP].

  • Additional database and server properties The following properties have been added:

    • PageSize The database server uses a single page size from startup until it is closed down. This page size is the maximum page size database that can be mounted by the database server. You can now obtain this page size using the PageSize server-level property function:

      select property( 'PageSize' )

    • AppInfo This function provides identification information for a client application. It is a connection property:

      select connection_property( 'AppInfo' )

      For more information, see AppInfo connection parameter [APP].

    • IsRuntimeServer This function returns YES if the database server is a limited desktop runtime personal database server. Otherwise, it returns NO.

    • Log truncation points Properties for replication-specific log offsets have been added. The properties LTMTrunc, RemoteTrunc, and SyncTrunc return the minimal confirmed log offset for the Replication Agent, SQL Remote, and MobiLink dbmlsync replication, respectively. These offsets are also known as truncation points because they indicate the point at which the transaction log can be truncated. The property CurrentRedoPos returns the current offset in the log file, where the next database operation is to be logged.

      For a complete list of property functions and information on how to access them, see Database properties.

  • Referential integrity checks before commit A new system procedure (sa_check_commit) allows you to check for referential integrity conflicts before committing changes to a database.

    For more information, see sa_check_commit system procedure.

  • SQL function enhancements The following functions have been added or enhanced.

    • REPLACE function This new function replaces all occurrences of a substring with another substring.

      For more information, see REPLACE function [String].

    • LIST function enhancement The LIST function now accepts an optional second value, which is the delimiter string that separates the list items.

      For more information, see LIST function [Aggregate].

  • Output redirection change The output redirection functionality in Interactive SQL has been extended to include three new Interactive SQL statements and an Export option in the File menu.

    You can now use an OUTPUT TO statement to redirect content from the Results pane to a new file. You can add an APPEND clause to append the content to the end of an existing file, or you can add a VERBOSE clause to include the content of the Messages pane with the output.

    In earlier versions, output redirection in Interactive SQL could only be done with the symbols >#, >>#, >&, and >>&. You can still use these symbols, but the new Interactive SQL statements allow for more precise output and code that is easier to read.

    For more information, see Exporting query results in the ASA User's Guide.

  • Embedded SQL enhancements A new function, db_string_ping_server, has been introduced to test that a database server can be located with a specified current connection string.

    For more information, see db_string_ping_server function.

  • New LOAD TABLE / UNLOAD TABLE format A new format has been added to the UNLOAD TABLE statement to allow data to be output in BCP format and to the LOAD TABLE statement to allow the import of Adaptive Server Enterprise generated BCP out files containing blobs.

    For more information, see LOAD TABLE statement or UNLOAD TABLE statement.

  • Last default timestamp The new global variable @@dbts returns a TIMESTAMP value that represents the last value generated for a column using DEFAULT TIMESTAMP.

    For more information, see Global variables.

  • Troubleshooting enhancements On starting the database server, you can log operations executed by the server to a file using the –zr option. You can use the sa_server_option procedure to control the same behavior while the server is running.

    For more information, see sa_server_option system procedure, and -zr server option.

  • Archive backup on NetWare The archive backup format is now supported on NetWare. Archive backups to tape require NetWare 5.

    For more information, see BACKUP statement.

  • Added filtering for dbtran The command version of the Log Translation [dbtran] utility allows further filtering of the output.

    For more information, see Log translation utility options.

  • Faster table truncation The TRUNCATE TABLE statement is much faster for version 7.0 databases, for tables with foreign keys.

  • Suppressing event log messages If you run the database server as a Windows NT service, you can suppress event log messages using a registry entry.

    For more information, see Suppressing Windows event log messages.


SQL Remote new features

SQL Remote version 7.0 includes the following new features.

  • Globally unique primary keys You can now use a DEFAULT GLOBAL AUTOINCREMENT column in an Adaptive Server Anywhere database, together with a GLOBAL_DATABASE_ID option setting in each database, to guarantee unique primary keys throughout a SQL Remote installation of Adaptive Server Anywhere databases. This is a more convenient method than the more manual primary key pool technique.

    For more information, see Using global autoincrement default column values.

  • Internal unload for dbxtract The Extract [dbxtract] utility now uses the UNLOAD statement introduced in Adaptive Server Anywhere version 7.0 by default, rather than the slower OUTPUT statement. Options have been introduced to allow you to choose a combination of internal (server-side) and external (client-side) unload and load operations.

    For a complete listing of options, see The extraction utility.


MobiLink and UltraLite new features

Following is a list of changes and additions to the software since version 6.0.3.

  • Adaptive Server Anywhere clients MobiLink technology now supports Adaptive Server Anywhere as a client, as well as UltraLite applications.

    For more information, see Adaptive Server Anywhere Clients.

  • mlxtract creates Adaptive Server Anywhere client databases mlxtract creates Adaptive Server Anywhere databases, suitable for use as MobiLink clients, using an Adaptive Server Anywhere reference database as a template.

  • Synchronization script versions Synchronization scripts can now be grouped by assigning a script version name with each script. This feature allows the MobiLink synchronization server to respond differently when synchronizing different types of applications, or different versions of the same application.

  • New data types LONG BINARY and LONG VARCHAR data types can now be replicated using MobiLink technology.

  • New HotSync conduit A new HotSync conduit allows HotSync synchronization with a centrally located MobiLink synchronization server. The MobiLink synchronization server no longer needs to be on the same machine as the HotSync manager is.

  • ScoutSync conduit UltraLite applications for the Palm Computing Platform can now synchronize using ScoutSync technology, available from Riverbed Technologies.

  • report_error script A new script provides a convenient way to report errors during synchronization. The report_error script also makes debugging the behavior of the handle_error script much easier. The report_error script has the same parameters as the handle_error script, except that the first parameter is the action code returned by handle_error.


Behavior changes in version 7.0.0

This section lists deprecated and unsupported features, and behavior changes from previous versions of the software.


Adaptive Server Anywhere behavior changes

Deprecated and unsupported features

This list includes features that are no longer supported and that impact existing applications.

  • Windows 3.x and Windows CE 2.0 no longer supported Windows 3.1 and Windows 3.11 are no longer supported. Windows CE 2.0 is no longer supported.

  • DDE protocol no longer supported The DDE protocol was used to communicate from 16-bit Windows 3.x applications to a Windows 95/98 database server on the same machine. It is no longer required: Windows 3.x applications based on older versions of the software can use TCP/IP to communicate with the version 7.0 database server.

  • IPX protocol deprecated Although communications using IPX are still supported in the present release, it is highly recommended that you use the SPX protocol instead. The protocol options are the same as for IPX, and performance is better. Support for IPX will be dropped in a future release.

    By default, both the database server and the client software do not start the IPX protocol unless you instruct it to do so explicitly using the –x option or the CommLinks connection parameter. The SPX protocol is started by default.

    For information on using SPX from the client side, see CommLinks connection parameter [LINKS]. For information on using SPX from the server side, see -x server option.

  • Deprecated network protocol options The Broadcast and CommAutoStop protocol options are still allowed, but have no effect. They will not be supported in future versions of Adaptive Server Anywhere.

  • No dbclient compatibility executable In version 6, the dbcli6.exe utility provided easier compatibility with version 5 client connection methods. There is no comparable utility in version 7.

Behavior changes

This list includes behavior changes in existing features that may impact applications or have an impact during development or database management.

  • Interactive SQL changes The new version of Interactive SQL has some changes from previous versions. As it is an interactive tool, most do not need documentation.

    The supported formats for INPUT and OUTPUT statements have changed, and now include:

    • INPUT ASCII, DBASE, DBASEII, DBASEIII, EXCEL, FIXED, FOXPRO, LOTUS

    • OUTPUT ASCII, DBASE, DBASEII, DBASEIII, EXCEL, FIXED, FOXPRO, HTML, LOTUS, SQL

  • Server name space change It is now disallowed for more than one database server with the same name to be running on TCP/IP anywhere on the network. Previously, multiple servers with the same name were allowed as long as they were on separate ports.

  • Mirrored logs deleted when DELETE_OLD_LOGS is ON Previously, any mirror of an old transaction log was not deleted, although the primary copy of the old transaction log was deleted.

  • ODBC SQLDescribeCol behavior A SQLDescribeCol call on the @@identity field now returns SQL_BIGINT. In earlier versions, it returned SQL_INTEGER.

  • Update constraints A new ANSI_UPDATE_CONSTRAINTS option has been added. Setting this option to CURSORS, or STRICT, restricts updates to those allowed by the ANSI standard. Setting this option to OFF, which is the historical behavior, allows a greater range of updates.

    For more information, see ANSI_UPDATE_CONSTRAINTS option [compatibility], and UPDATE statement.

  • Identifier length limit Long identifiers are treated more consistently than in the past. Identifiers longer than 128 bytes were sometimes accepted and sometimes not, depending on the type of database object being named. Now any attempt to define identifiers longer than 128 bytes reports an error.

    For more information, see Identifiers.

  • jConnect connections If you use the REMOTEPWD field to connect via jConnect to a named database on an Adaptive Server Anywhere database server, you must assign the field in a different manner for jConnect version 4.2 and above, included with this software.

    For more information, see Supplying a URL for the server.

  • User-defined errors Within procedures and triggers, you can declare exceptions in the range 99000 to 99999 as user-defined errors in compound statements. You can use the SIGNAL statement to handle these errors.

    For more information, see BEGIN statement, and SIGNAL statement.

  • LOAD TABLE and UNLOAD TABLE security A database server option has been added to control the permissions required to execute the LOAD TABLE and UNLOAD TABLE statements.

    For more information, see -gl server option.

  • @@identity in triggers If a table (T1) with an autoincrement column has an insert trigger which causes an insert into a second table (T2) also having an autoincrement column, it was not previously possible to obtain the autoincrement value assigned for T1 after the insert had completed. At that point, the value of @@identity would be the value assigned to T2. The behavior of @@identity has been altered to make the value accessible.

    For the new behavior of @@identity within triggers, see @@identity global variable.

  • Embedded SQL DECL_FIXCHAR In previous releases, the SQL preprocessor converted a type DECL_FIXCHAR to an array. For example, DECL_FIXCHAR(12) was converted to char name_fixchar[12].

    In the current release, the SQL preprocessor converts DECL_FIXCHAR declarations to DECL_FIXCHAR(12) name_fixchar, and references are of the form name_fixchar.array[i].


SQL Remote behavior changes

The following behavior has changed in version 7.0:

  • dbxtract uses internal unload The default behavior of dbxtract is now to use the UNLOAD statement to unload data on the server side, rather than the OUTPUT statement to unload data on the client side. The –ii, -ix, –xi, -xx options allow you to choose which combination of internal and external operations to use, and replace the options –i and –x available in previous releases.

    For a complete listing of options, see The extraction utility.


MobiLink and UltraLite behavior changes

  • New table and script names The tables that hold synchronization scripts and related information in the consolidated database now have new names. Previously, these table names began with the prefix ul_. This prefix has been changed to ml_. Older consolidated databases must be upgraded for compatibility with version 7.0.

    Similarly, the stored procedure that facilitates adding table scripts has been renamed from sp_table_script to ml_add_table_script and the stored procedure that facilitates adding connection scripts has been renamed from sp_connection_script to ml_add_connection_script.

    Under DB2, these names are truncated to 18 characters.

  • Synchronization scripts require a version name Synchronization scripts must now be assigned a script version name. Script version names allow the MobiLink synchronization server to treat different clients differently.


What's New in Version 6.0.3

About this chapter

This chapter provides an overview to the new features and behavior changes introduced in Adaptive Server Anywhere 6.0.3.


New features in version 6.0.3

This section lists the new features introduced in components of SQL Anywhere Studio version 6.0.3.


Adaptive Server Anywhere new features

In addition to bug fixes, Adaptive Server Anywhere version 6.0.3 includes new features in both the software and the documentation.

  • Combined stored procedure and Java debugger The Java debugger that was provided in previous releases has been upgraded. The new version of the debugger is able to debug not only Java classes within the database, but also SQL stored procedures and triggers.

    For information on how to use the debugger, see Debugging Logic in the Database.

  • Read-only databases You can designate a database as read only when you start a database server. This feature makes deployment of databases on read-only media, such as CD-ROMs, more straightforward.

    The ReadOnly database property returns ON for read-only databases, and OFF for databases that are not being run in read-only mode.

    For more information on read-only databases, see -r server option.

  • Computed column extensions New flexibility has been added to computed columns. You can now add computed columns to non-empty tables, and change the expression associated with a computed column. Computed columns are recalculated in a number of circumstances to ensure that the values are reliable.

    For more information, see Working with computed columns, and Inserting and updating computed columns.

    For information on syntax, see ALTER TABLE statement.

  • Support for the euro Collations have been added that include the euro currency symbol. These collations are the 1252LATIN1 and ISO9LATIN1 collations.

    For more information, see The 1252LATIN1 collation, and The ISO9LATIN1 collation.

  • Additional collations Other collations have been added to the list of supplied collations, including 852POL (OEM Code Page 852 (Latin 2), with Polish ordering), 1250POL (Windows Latin2 code page 1250 with Polish ordering), 1250Latin2 (Windows Latin2 Code page 1250). 932JPN (Japanese), 936ZHO (similar to EUC_CHINA), and 950TAI (similar to EUC_TAIWAN).

    For a complete list, see Choosing collations.

  • New Windows CE platforms The SH4 and ARM processors are now supported under Windows CE 2.1x.

    For a list of supported devices, chips, and operating system versions, see Windows and NetWare operating systems.

  • ALTER TABLE extensions The ALTER TABLE statement has been extended to provide SQL/92-compliant clauses to set and drop defaults on columns. These clauses are an alternative to the existing MODIFY clause.

    ALTER column-name SET DEFAULT default-value
| ALTER column-name DROP DEFAULT

    For more information, see ALTER TABLE statement.

  • LOAD TABLE extensions You can now load specific columns of a table using the LOAD TABLE statement. A new CHECK CONSTRAINTS option has been introduced to address rebuild issues.

    For more information, see LOAD TABLE statement.

  • Easier connections across firewalls A set of protocol options has been introduced to allow easier connections across firewalls.

    For more information, see Connecting across a firewall.

  • BACKUP statement extended The MATCH keyword has been introduced to allow renaming of the backup copy of the transaction log to a filename of the form YYMMDDnn.log. If you use this keyword, you can execute the same statement multiple times without writing over data.

    For more information, see BACKUP statement.

  • Easier unload and reload The Unload [dbunload] utility has been enhanced (-ar option) to allow a single-step unload and reload of a database that can be used whether or not your database is involved in replication.

    For more information, see Unload utility options, and Rebuilding databases.

  • Temporary file location The database server checks for a new environment variable, ASTMP, when deciding on the location of the temporary file. This allows you to use directories other than system temporary directories for the temporary file.

    For more information, see ASTMP environment variable.

  • New system procedures New system procedures allow DBA users to override some database server options (sa_server_option), and to flush the database server cache (sa_flush_cache).

    For more information, see System and catalog stored procedures.

  • Character set translation tuning You can control the application locale used in character set translation for an individual connection using the new CharSet connection parameter.

    For more information, see CharSet connection parameter [CS].

  • Re-organized Performance Monitor statistics The statistics made available to the Windows NT Performance Monitor have been organized into areas. Some statistics have been added, and ones of little use have been removed.

    For a list of available statistics, see Monitoring database statistics from Windows Performance Monitor.

  • Database properties from the utility database You can now execute SELECT statements, with no tables, against the utility database. This is primarily of use for retrieving database and connection properties.

    For more information, see Using the utility database.

  • New database properties The following properties are available using the property function.

    • IsNetworkServer Returns YES if connected to a network database server, and NO if connected to a personal database server.

      For more information, see Server-level properties.

    • DefaultCollation You can use the new DefaultCollation property to find the default collation to be used when creating a database.

      For more information, see Finding the default collation, and Server-level properties.

    • MultiByteCharSet You can use the MultiByteCharSet database property to determine whether a database is using a multi-byte or single-byte collation.

      For information on this property, see Database-level properties.

  • Support for some JDBC 2.0 functions in internal JDBC The internal server-side JDBC driver now supports functions from the JDBC 2.0 interface. Server-side Java applications can now use features such as such as scrollable, updateable result sets and batch updates. A side effect is that you can now access result sets from Java methods from Interactive SQL.

    For more information, see JDBC in the database features.

  • Using the main method in Java classes You can now execute a main method of a Java class from SQL.

    For more information, see Calling the main method.

  • User-defined functions using Java classes You can wrap a Java method in a SQL user-defined function.

    For more information, see CREATE FUNCTION statement.

  • Extensions to stored procedures using Java methods You can use OUT and INOUT parameters in stored procedures that are wrappers for Java methods.

    For more information, see Returning values from Java via stored procedures.

  • Multi-threaded Java classes in the database Support has been added for the package java.lang.thread.

    For more information, see Using threads in Java applications.

  • File access from Java Support has been added for all the classes in the package java.io, including those that enable file access from classes in the database. For security reasons, a new option has been introduced, which must be set by the DBA to enable this feature.

    This feature is supported on Windows NT only.

    For more information, see JAVA_INPUT_OUTPUT option [database].

  • CONVERT function extensions The date and time styles supported by the CONVERT function have been extended.

    For more information, see CONVERT function [Data type conversion].

  • Database server startup dialog On 32-bit Windows operating systems, if you start a database server with no arguments, a window appears where you can specify a database file and additional parameters.

    For more information, see Starting the server.

  • Log Translation [dbtran] utility enhancements The Log Translation [dbtran] utility permits filtering of the transaction log operations to isolate subsets of operations.

    For more information, see Translating a transaction log using the dbtran command-line utility.

  • Transaction Log [dblog] utility enhancements The Transaction Log [dblog] utility now displays additional summary information, including offset information.

    For more information, see Managing log files using the dblog command-line utility.

  • Spawn [dbspawn] utility enhancements The Spawn [dbspawn] utility has a -f option to force a server to start even if one is already running. This option uses a ForceStart connection parameter, used only by the db_start_engine Embedded SQL function.

    For more information, see The Spawn utility, and db_start_engine function.

  • Replication Agent runs as a daemon On UNIX operating systems, you can run the Replication Agent as a daemon by supplying the -ud option.

    For more information, see The Log Transfer Manager.


SQL Remote new features

In addition to bug fixes, SQL Remote version 6.0.3 includes the following new features. Some features in Adaptive Server Anywhere that are particularly relevant to SQL Remote are also included in this list:

  • FTP and SMTP/POP support on UNIX The range of message systems supported on UNIX operating systems has been expanded to include FTP and SMTP/POP.

    For a listing of supported operating and message systems, see Supported Platforms and Message Links.

  • Message link options stored in the database The message link parameters that control SQL Remote behavior over each message system can now be stored in the database as opposed to the registry. This simplifies deployment and management issues related to message link parameters.

    For more information, see Setting message type control parameters, SET REMOTE OPTION statement, and sp_link_option procedure.

  • Date and time replication formats You can now specify database options that instruct SQL Remote what format to use when replicating dates and times. These options are SR_time_format, SR_date_format, and SR_timestamp_format.

    For more information, see Replication of dates and times, and SQL Remote options.

  • Message Agent and SQL Remote Open Server run as a daemon On UNIX operating systems you can run these applications as a daemon using the -ud option.

    For more information, see The Message Agent, and The SQL Remote Open Server.

  • Easier unload and reload of Adaptive Server Anywhere databases The Unload [dbunload] utility has been enhanced (-ar option) to allow a single-step unload and reload of a database that can be used whether or not your database is involved in replication.

    For more information, see Unload utility options, and Rebuilding databases.

  • Enhanced transaction log [dblog] output The Transaction Log [dblog] utility now displays additional summary information, including offset information.

    For more information, see Managing log files using the dblog command-line utility.

  • Log Translation [dbtran] utility enhancements The Log Translation [dbtran] utility permits filtering of the transaction log operations to isolate subsets of operations. This is of particular use to SQL Remote administrators.

    For more information, see Translating a transaction log using the dbtran command-line utility.


MobiLink and UltraLite new features

Following is a list of changes and additions to the software since version 6.0.2.

  • New data types Real and double data types are now fully supported.

  • Character set translation The MobiLink synchronization server now translates all uploaded characters to Unicode and passes them to the consolidated database using the Unicode ODBC API. Conversely, it translates all downloaded characters from Unicode to the character set of your UltraLite application. Character set translation within the consolidated database server can influence the results, but the new system allows more consistent behavior across multiple platforms.

    For more information, see Controlling ODBC driver character set translation.

  • MobiLink synchronization server runs as a Windows NT service When you run the MobiLink synchronization server as a service, you can configure it to continue running when you log off the Windows NT workstation.

    For more information, see Running MobiLink Outside the Current Session.

  • DB2 setup scripts provided To make it easier to use IBM DB2 as a consolidated database, a DB2 setup script has been added to the available set scripts.

    For a list of setup scripts, see Setting up a consolidated database.


Behavior changes in version 6.0.3

This section lists the behavior changes introduced in components of SQL Anywhere Studio version 6.0.3.


Adaptive Server Anywhere behavior changes

  • Adding columns with default values When an added column has a default value, the entire column is populated with the default. In previous releases, the column was populated with NULL.

  • Permissions of referential integrity actions When changes are made to a primary table, referential integrity actions such as cascading deletes or updates can take place on a secondary table. These actions are implemented using system triggers. The triggers now execute with the permissions of the owner of the secondary table. Previously, they executed with permissions of the owner of the primary table. The new behavior means that cascaded operations can take place between tables with different owners, without additional permissions having to be granted.

  • datediff, MONTHS, and YEARS functions The number of months between two dates is now calculated as the number of first-of-the-months between the dates. For example, the difference between January 25 and February 2 is 1; the difference between January 1 and January 31 is 0. The number of years is now calculated as the number of first-of-the-years between the dates.

    This changes the results of these functions by one number, in some cases. The change was made for compatibility with Adaptive Server Enterprise.

    For the smaller time units there are overflow values to the DATEDIFF function that are now imposed. Previous versions of the software gave incorrect answers if the limit was exceeded.

    For a full description, see DATEDIFF function [Date and time].

  • Default page size The default page size for databases is now 2048 bytes. This choice is a better choice for many users.

  • Default database collation The default collation used when creating databases has changed. The default depends on your operating system settings.

    For information on how to find the default collation, see Finding the default collation.

  • SQL Preprocessor default collation If no collation is explicitly specified, the Embedded SQL Preprocessor now uses locale information to choose a default collation. If the locale information is unavailable, then 850LATIN1 will be used. The collation used is reported following the banner. Previous behavior was to use 850.

    For information on the preprocessor, see The SQL preprocessor.

  • Enforced server name length The server name is checked on startup, and is truncated to a maximum value of 40 characters. On NetBIOS, it is truncated to 16 characters. From the client side, the value of the EngineName parameter is also truncated to 40 characters.

    For more information, see EngineName connection parameter [ENG].

  • Agent connection parameter The Agent connection parameter behavior has been changed. The meaning of this parameter changed from version 5 to version 6, as the need for the dbclient executable was removed. The parameter meaning has changed to be more useful in a Version 6 environment.

    The Agent connection parameter is deprecated as of version 8.0.1.


SQL Remote behavior changes

The following behavior has changed in SQL Remote version 6.0.3:

  • Message link parameters stored in the database By default, the message link parameters are now moved into the database when the Message Agent is run for the first time with the new version of the software. If you have software that explicitly accesses these parameters in their old locations external to the database, it will be affected by this change. You can continue using the old behavior by setting the External_remote_options database option to ON.

  • Passwords stored When a password is entered for a message link, it was not stored in previous versions of the software. As the parameters are now held in the database, a saved password is not held on disk and so is more secure. Passwords are now saved by default. You can continue using the old behavior by setting the Save_remote_passwords option to OFF.


What's New in Version 6.0.2

About this chapter

This chapter provides an overview to the new features and behavior changes introduced in Adaptive Server Anywhere 6.0.2.


New features in version 6.0.2

This section lists the new features introduced in components of SQL Anywhere Studio version 6.0.2.


Adaptive Server Anywhere new features

In addition to bug fixes, Adaptive Server Anywhere version 6.0.2 includes new features in both the software and the documentation.

Cross references
The printed documentation is not necessarily updated with each maintenance release. Cross references in this section may not be valid in the printed documents. For current information, see the online documentation.

  • UltraLite deployment option UltraLite databases for small devices such as the PalmPilot and Windows CE computers can be developed with this version of the software.

    For information, see the book UltraLite Developer's Guide.

  • Backup and Restore SQL statements Adding BACKUP and RESTORE as SQL statements provides server side backup and automation of backups using SQL scripts.

    The BACKUP statement provides direct backup to tape.

    For more information, see BACKUP statement.

  • Security features New security features have been added.

    • Auditing Database administrators can keep track of activity performed on a database by turning on the AUDITING option. The record of activities is kept in the transaction log. By turning on auditing, you increase the amount of data saved in the transaction log to include login attempts, accurate timestamps of all events, all permissions checks, and all actions requiring DBA authority.

      For more information, see Auditing database activity.

    • Minimum password length Database administrators can specify a minimum password length, to discourage easily discovered passwords.

      For more information, see MIN_PASSWORD_LENGTH option [database].

  • Locating servers A utility is provided for troubleshooting connections.

    For more information, see The Ping utility.

  • Starting databases from jConnect connections Database connections over TDS, including connections from Java applications over jConnect, can start a database on a server.

    For more information, see Supplying a URL for the server.

  • ODBC 3.51 The ODBC driver has been updated to ODBC 3.51. This version of ODBC includes support for Unicode applications.

    For more information, see ODBC conformance.

  • Control of allowed JOIN syntax In previous releases, some multi-table queries have been allowed that have ambiguous join clauses. In the present release, you can set an option to disallow such queries.

    For more information, see EXTENDED_JOIN_SYNTAX option [database].

  • Administration utility enhancements Options have been added to the administration utilities to provide additional features.

    • Transaction Log [dbtran] utility If you use the new -d option, dbtran puts each operation as it occurs in the transaction log file. This makes transaction log output easier to read. This has been added primarily for auditing purposes.

      For more information, see Translating a transaction log using the dbtran command-line utility.

    • Transaction Log [dbtran] utility You can run dbtran against a running database server instead of against a log file. This feature has been added to increase the security of the transaction log—there is now no need to access the transaction log directly.

      For more information, see Translating a transaction log using the dbtran command-line utility.

    • Log Transfer Manager [dbltm] utility logging New options allow you to tune message logging from these utilities.

      For more information, see The Log Transfer Manager.

    • New Log Transfer Manager [dbltm] utility options New options enable you to replicate only backed up transactions (backup_only), and to shut down as soon as all data is replicated (continuous).

      For more information, see The LTM configuration file.


SQL Remote new features

In addition to bug fixes, SQL Remote version 6.0.2 includes the following new features:

  • Performance enhancements A major enhancement of the Adaptive Server Anywhere Message Agent (dbremote) operational model for scanning the transaction log and sending messages greatly improves the range of achievable replication turnaround times.

    Minimum lag times between entering data at one site and its replication to another site were limited in earlier versions to times on the order of ten minutes. With the new operational model, minimum lag times on the order of seconds can be achieved in some circumstances.

    When the Message Agent message-sending process runs in continuous mode, it now stays (hovers) at the end of the active transaction log while waiting for more data to be committed, instead of rescanning the transaction log each time. This allows you to poll more frequently, which can significantly reduce time for replication.

    For more information, see Tuning Message Agent performance.

  • SQL Remote message logging New options allow you to tune message logging from these utilities.

    For more information, see The Message Agent.


Behavior changes in version 6.0.2

This section lists behavior changes in the components of SQL Anywhere Studio.

Adaptive Server Anywhere behavior changes


Adaptive Server Anywhere behavior changes

The following are behavior changes from previous versions of the software.

  • Permissions required to debug Java In order to use the Java debugger, you must either have DBA authority, or be granted membership in the SA_DEBUG group. The SA_DEBUG group does not exist in databases created prior to 6.0.2, and in these older databases any user can use the Java debugger. The SA_DEBUG group was added to close a potential security hole.

    For more information, see Requirements for using the debugger.

  • Default packet size change The default packets size for client/server communications has been changed from 512 bytes to 1000 bytes. This change improves performance for multi-row fetches and fetches of large rows. It also increases the memory requirements.

    For more information on packet size, see CommBufferSize connection parameter [CBSIZE], and -p server option.


What's New in Version 6.0.1

About this chapter

This chapter provides an overview to the new features introduced in Adaptive Server Anywhere 6.0.1


New features in version 6.0.1

This section introduces the new features in Adaptive Server Anywhere version 6.0.1. It provides a listing of major new features, with cross references to locations where each feature is discussed in detail.


Adaptive Server Anywhere for Windows CE

The Microsoft Windows CE operating system developed for handheld computing devices and embedded devices custom-built to carry out a specific task.

Starting with Version 6.0.1, Adaptive Server Anywhere is available for Windows CE. The Windows CE version of Adaptive Server Anywhere has the following characteristics:

  • Full-featured database All SQL features in other versions of Adaptive Server Anywhere are available in the Windows CE version, including transaction processing, referential integrity actions, procedures and triggers, and so on.

    The Java features and the remote data access features are not available in Windows CE.

  • Administer from your desktop When running Windows CE on a device that can be attached to a network or directly to a PC, you can administer your Windows CE database from a Sybase Central running on the PC.

  • ODBC and Embedded SQL applications You can use either of these interfaces to develop client applications.

  • SQL Remote replication The SQL Remote file link is implemented to be compatible with Windows CE ActiveSync synchronization.


Remote data access

Remote data access gives you access to data on external data sources, as if they were stored on the local database.

For information about remote data access, see the chapter Accessing Remote Data and the chapter Server Classes for Remote Data Access.


Character set translation

Character set translation has been added to translate strings automatically between different character sets as data is passed between client applications and the database server. This enables more flexibility in mixed character-set environments.

Character set translation can be carried out among character sets that represent the same characters, but at different values. There needs to be a degree of compatibility between the character sets for this to be possible. For example, character set translation is possible between EUC-JIS and Shift-JIS character sets, but not between EUC-JIS and OEM code page 850.

To enable character-set translation, you must start the database server using the new -ct option. For example:

dbeng9 -ct asademo.db

Most of the character set translation features occur automatically, with little user intervention required.

For a description of character set translation features, see Starting a database server using character set translation. For more detailed information, see Understanding character set translation.


New Java features

There are some changes made to the Java support. These include the following:

  • Compressed jar files You can now install compressed jar files and zip files into the database. However, you should not use the jar utility that comes with the Sun JDK. Other zip utilities do produce suitable files.

  • Result sets from Java procedures You can wrap Java methods in a stored procedure, which can return a result set or multiple result sets to the calling environment.

    For information on this feature, see Returning result sets from Java methods.

  • Default internal connection When a database connection is established for internal JDBC operations, it is now recommended that you use the following URL:

    jdbc:default:connection

    In version 6.0.0, an empty string was used to establish this connection. While the empty string does still work, it is deprecated. The new URL corresponds to the SQLJ1 proposed standard.


Additional new features

Several other features have been added to Adaptive Server Anywhere 6.0.1. These include the following:

  • jConnect 4.0 The version of jConnect included in this product has been updated to version 4.0.

  • AutoStart connection parameter This parameter prevents a personal server from starting if no network connection is successful.

    For a description, see AutoStart connection parameter [ASTART].

  • MESSAGE statement Extensions to the MESSAGE statement allow messages to be directed to the client, the server window, or a log file.

    For a description, see MESSAGE statement.

  • Message callbacks Windows Embedded SQL applications can handle messages received from the server while a request is being processed by registering a message callback function.

    For more information, see Implementing request management.

  • More control over operating system threads A new database server option (-gx) controls the number of operating system threads that are in use. The existing -gt option controls how many can be in use at one time, effectively controlling the number of CPUs that can be exploited.

    For more information, see The database server.

  • Connection property system procedures Two additional system procedures provide alternative ways of querying connection information.

    For more information, see sa_conn_properties_by_conn system procedure, and sa_conn_properties_by_name system procedure.

  • NULLIF function This provides an abbreviated form of the CASE expression. NULLIF compares the values of the two expressions. If the first expression equals the second expression, NULLIF returns NULL. If the first expression does not equal the second expression, NULLIF returns the first expression. The NULLIF function provides a short way to write some CASE expressions.

    For more information, see Miscellaneous functions.


New features in SQL Remote

Several features have been added to SQL Remote.

  • Minimized Message Agent The Message Agent can be made to start with a minimized window using the -q option.

  • Message Agent request to resend messages The point at which the Message Agent requests that a missing message be resent is now user-configurable using the -rp option.

    For information on these options, see The Message Agent and Tuning incoming message polling.

  • Cleaning the stable queue For Adaptive Server Enterprise, the new -fq option on the Message Agent assists administration by cleaning confirmed messages from the stable queue.

    For information, see The Message Agent.


Behavior changes

This section describes behavior changes between version 6.0.0 and 6.0.1.

Java system table changes The system tables used to record Java class information (SYSJAR, SYSJARCOMPONENT, and SYSJAVACLASS ) had SMALLINT primary keys. These data types have been altered to use INTEGER primary keys. This change allows more Java classes to be stored in a database, and more changes to the Java classes in the database.

This change takes effect for new databases and databases upgraded using the Upgrade [dbupgrad] utility from this or future releases.

Parentheses in -x command line In previous releases, database server command lines using the -x option have used the brace character ({) to surround options. The same applies to the string in the CommLinks connection parameter. For example:

dbsrv9 -x tcpip{Localhost=demo}

Existing command lines that use braces are still supported, but it is now recommended that you use parentheses to surround the options. Use of parentheses provides support for multi-byte character set identifiers in the database server command line and the CommLinks connection parameter.

dbsrv9 -x tcpip(Localhost=demo)

ANSINULL default for Transact-SQL and jConnect connections This has been changed to ON, which matches Adaptive Server Enterprise default behavior.

Database server -v option Prior to Version 6, this option produced verbose output to the transaction logs. This is obsolete, and -v is now used to supply version information.

Database server -gss option The behavior of the -gs server option, used to set the stack size, was complicated. The -gs option is now deprecated, and -gss provides the same functionality in a clearer way.

For more information, see The database server.

Character set conversion in Interactive SQL Formerly, when the CHAR_OEM_TRANSLATION option was set to DETECT, Interactive SQL would fetch the collation label from the database to determine whether or not OEM to ANSI character set translation would be turned on. If the collation label started with a string that indicated an ANSI code page, translation would be turned off. Otherwise it would be turned on. When the option was set to DETECT, Interactive SQL would display a message in the status window indicating the collation label of the database and the display translation setting.

The new behavior is as follows. If the option is set to DETECT, Interactive SQL will obtain the CharacterSet connection property from the server. This is the character set that the server is using for sending all character strings on this connection. If this character set indicates an ANSI code page, then OEM to ANSI translation is turned off. Otherwise it is turned on. A new message is displayed, indicating the collation label of the database, the character set used for communication over this connection, and the display translation setting.


Upgrading Software and Databases

About this chapter

This chapter describes how to upgrade your software and databases.

There are additional concerns when upgrading Adaptive Server Anywhere version 5 applications. For more information, see Upgrading Version 5 Applications.


Upgrading Adaptive Server Anywhere

Running multiple versions

You can run multiple versions of Adaptive Server Anywhere (for example version 8.0 and version 9.0) simultaneously, provided that only one of the versions uses SPX.

Compatibility with existing software

Adaptive Server Anywhere database servers work with older databases. There is no need to upgrade your database in order to continue working with existing applications.

You should not use older versions of the Adaptive Server Anywhere database server with newer databases.

For Adaptive Server Anywhere software version 6.0.0 or later, you can upgrade the database server without upgrading client software.

  • Version 9 database servers support connections from client applications using software from version 6.0.0 or later.

  • Management of old databases and old database servers from the current version of Sybase Central is provided as follows:

    • Full management of version 7 and later databases running on version 7 and later servers.

    • You can connect to a version 5 or 6 database on a version 8 or later database server only to upgrade the database file format using the Unload Database wizard.

    • There is no support for version 6 and earlier databases running on version 7 and older database servers.

For information on upgrading client/server installations from Version 5 and earlier, see Upgrading Version 5 Applications.

Reasons to upgrade

You must upgrade your database if you wish to use some of the new features in this version of the software.

There are two kinds of upgrade possible with version 9:

  • Upgrade the database Use the Upgrade [dbupgrad] utility to upgrade your database. This process updates the system tables, provides new database options, adds or modifies system procedures.

    Upgrading the database can be done in-place on your existing database file. It does not require that you unload and reload your database.

    See Upgrading a database.

  • Upgrade the database file format Some features, such as new index types, require a new database file format. The Upgrade [dbupgrad] utility does not change the format of the database file.

    To upgrade the database file format, you must unload and reload your database.

    See Upgrading the database file format.


Upgrading a database

Upgrading a database adds and modifies system tables, system procedures and database options to enable version 9 features. It does not change the file format used to store and access data on disk and so does not give access to all new features and performance enhancements in the latest version of the software.

For information on upgrading the database file format, see Upgrading the database file format.

toggle To upgrade a database (Sybase Central)

  1. Carry out the standard precautions for upgrading software.

    See Standard upgrade precautions.

  2. Start a version 9 database server running the database you wish to upgrade.

  3. From Sybase Central, connect to the database you wish to upgrade.

  4. Right click the database and choose Upgrade Database from the popup menu. The Upgrade a Database wizard appears.

  5. Follow the instructions in the wizard.

  6. Shut down the database and archive the transaction log before using the upgraded database.

toggle To upgrade a database (Command line)

  1. Carry out the standard precautions for upgrading software.

    See Standard upgrade precautions.

  2. Ensure that you have exclusive access to the database to be upgraded.

  3. Ensure that the version 9 utilities are ahead of other utilities in your system path.

    See Using the utilities.

  4. Execute the Upgrade [dbupgrad] utility against the database:

    dbupgrad -c "connection-string"

    The connection-string must connect to the database to be unloaded, with DBA authority.

    For more information, see Upgrading a database using the dbupgrad command-line utility.

  5. Shut down the database and archive the transaction log before using the upgraded database.

toggle To upgrade a database (SQL)

  1. Connect to the database from Interactive SQL or another application that can execute SQL statements.

  2. Execute the ALTER DATABASE statement. Use the JAVA clause to specify whether you wish to upgrade the JDK level used by Java applications in the database.

    For example, the following statement upgrades a database without altering the JDK level:

    ALTER DATABASE UPGRADE

    For more information, see ALTER DATABASE statement.


Upgrading the database file format

This section describes how to use unload and reload your database to upgrade the file format of a database.

Caution Unloading and reloading a large database can be both time consuming and require a large amount of disk space. The process requires access to disk space approximately twice the size of your database to hold the unloaded data and the new database file.
Special considerations

If you are upgrading the file format for a database that is involved in SQL Remote replication or that is a remote database in a MobiLink installation, and if you use the utility, you must be sure to use the -ar or -an option. The option ensures that the transaction log offsets for the new database are set to match those of the old database. In Sybase Central, following the instructions below ensures that the option is used.

When unloading and reloading a database that has proxy tables, you must create an external login to map the local user to the remote user, even if the user has the same password on both the local and remote databases. If you do not have an external login, the reload may fail because you cannot connect to the remote server.

Users of version 5 who wish to unload and reload databases involved in replication should follow the instructions in Unloading and reloading a database participating in replication, rather than those in this section.

The unload/reload procedure
toggle To upgrade the database file format (Sybase Central)

  1. Carry out the standard precautions for upgrading software.

    See Standard upgrade precautions.

  2. Start a version 9 database server on the database you wish to upgrade. For example:

    dbeng9 mydatabase.db

  3. Start Sybase Central.

    From the Start menu, choose Programs > SQL Anywhere 9 > Sybase Central.

  4. Connect to the database you wish to upgrade.

    When you connect to a version 5.x or version 6.x database, a dialog appears asking you whether you want to use the Unload Database wizard to unload and reload your database. Click Yes. Once the wizard completes, the connection to the database is closed.

  5. Right-click the database and choose Unload Database from the popup menu.

    The Unload Database wizard appears.

  6. Read the text on the first page of the wizard and then click Next.

  7. Choose to unload the database to which you are connected. Click Next.

  8. Select Unload and Reload into a New Database. Click Next.

  9. Specify a new filename for the database. Click Next.

    You can specify the page size for the new database. The default page size is 2048 bytes.

    You can encrypt the database file if you wish. You need the encryption key each time you want to start the database.

    For more information about database file encryption, see Encrypting a database.

  10. Choose to unload structure and data. Click Next.

  11. Choose to unload all database objects. Click Next.

  12. Specify whether you wish to connect to the new database when the unload/reload is complete.

  13. Click Finish to start the process. You will need to examine the new database to confirm that the upgrade is completed properly.

toggle To upgrade the database file format (Command line)

  1. Carry out the standard precautions for upgrading software.

    See Standard upgrade precautions.

  2. Ensure that you have exclusive access to the database to be unloaded and reloaded. No other users can be connected.

  3. Ensure that the version 9 utilities are ahead of other utilities in your system path.

    See Using the utilities.

  4. Execute the Unload [dbunload] utility using the -ar option to create a new database.

    dbunload -ar -c "connection-string"

    The connection-string must connect to the database to be unloaded with DBA authority. This command replaces the existing database with an upgraded database. To use the -ar option, you must connect to a personal server, or to a network server on the same machine as the Unload [dbunload] utility.

    For information on other Unload [dbunload] utility options, see Unloading a database using the dbunload command-line utility.

  5. Shut down the database and archive the transaction log before using the reloaded database.

    If you want to change the characteristics of the database during unload and reload (for example, change a case-sensitive database to a case-insensitive database), the procedure is more involved. For more information, see Rebuilding databases.


Standard upgrade precautions

There are several precautions you should take before upgrading any application, and these apply to Adaptive Server Anywhere upgrades just as to any other software.

  • Check the behavior changes Before upgrading, you should confirm that none of the documented behavior changes in Version 9.0 affect your application.

    For more information, see Adaptive Server Anywhere behavior changes.

  • Test You should test your application in a Version 9 environment thoroughly before upgrading any applications in production use.

  • Backup You should back up your existing software and data before upgrading. In addition, as recovery cannot happen across a database upgrade, you should make a backup after upgrading to ensure recoverability going forward.

    For databases involved in synchronization, such as UltraLite databases or Adaptive Server Anywhere remote databases in MobiLink or SQL Remote installations, you should synchronize all outstanding changes before upgrading.

  • Test your upgrade procedure If you are upgrading many end users, test your upgrade procedure carefully before carrying it out.

SQL Anywhere is used in so many different configurations that no upgrade guidelines can be guaranteed for all cases.


Using the utilities

If you have multiple versions of Adaptive Server Anywhere on your machine, you must pay attention to your system path when using utilities. Since setup adds the most recently installed version executable directory to the end of your system path, it's possible to install a new version of the software, and still inadvertently be running the previously installed version.

For example, if an Adaptive Server Anywhere Version 7 executable directory is ahead of the Version 9 executable directory in your path and you use the dbinit command, you will use the Version 7 utility, and consequently create a Version 7 database.

toggle To use the version 9.0 utilities

  • Change to the version 9.0 executable directory before executing your command,

    or

    Modify your system path so that the version 9.0 executable directory is ahead of any previous version Adaptive Server Anywhere executable directory.


Upgrading MobiLink

If you are upgrading an existing MobiLink installation, you must upgrade the components in the following order:

  1. Shut down the MobiLink server.

  2. Upgrade the consolidated database.

    See Upgrading your consolidated database.

  3. Upgrade the MobiLink synchronization server.

    See Upgrading the MobiLink synchronization server.

  4. Start the MobiLink server.

  5. Upgrade the MobiLink clients.

    For information on Adaptive Server Anywhere remote databases, see Upgrading Adaptive Server Anywhere MobiLink clients. For information on UltraLite applications, see Upgrading UltraLite applications.

New MobiLink clients are incompatible with older versions of the MobiLink synchronization server, however, the new MobiLink synchronization server is compatible with older clients.

Before upgrading, you should check for behavior changes that may affect you and carry out standard upgrade precautions.

For more information, see Behavior changes in version 8, and Standard upgrade precautions.


Upgrading your consolidated database

You must upgrade the MobiLink system tables in your consolidated database before you can use the new MobiLink synchronization server.

If you are using an Adaptive Server Anywhere consolidated database, the usual upgrade process upgrades the MobiLink system tables—do not carry out the instructions in this section.

For more information on upgrading Adaptive Server Anywhere databases, see Upgrading a database.

The upgrade procedure is slightly different depending on whether you are upgrading from MobiLink version 6 or MobiLink version 7.

toggle To upgrade a consolidated database (not DB2)

  1. Only if you are upgrading from MobiLink version 6, create the MobiLink system tables and stored procedures by running the setup SQL script MobiLink\setup\syncxxx.sql, where xxx is ora (Oracle), ase (ASE), or mss (Microsoft SQL Server).

  2. Locate the upgrade script for your database-management system.

    The upgrade scripts are held in the MobiLink/upgrade/version directory beneath the SQL Anywhere directory: The directory refers to the version of MobiLink from which you are upgrading.

  3. Apply the upgrade script for your database management system.

    Use an administration or Interactive SQL utility for your database management system to apply the SQL script.

toggle To upgrade a DB2 consolidated database

  1. Copy the MobiLink\setup\SyncDB2Long_901.class file to the SQLLIB\FUNCTION directory on the DB2 server machine. You probably need to restart the instance. For details, see your DB2 documentation.

  2. Only if you are upgrading from MobiLink version 6, create the MobiLink system tables and stored procedures by running the setup SQL script MobiLink\setup\syncdb2long.sql.

  3. Locate the DB2 upgrade script.

    The upgrade script is called upgrade_db2tolong.sql and is held in the MobiLink/upgrade/version directory beneath the SQL Anywhere directory. The directory refers to the version of MobiLink from which you are upgrading.

  4. Copy upgrade_db2tolong.sql and modify the copy. Change the CONNECT statement at the start of the script so it will work with the instance you want to connect to. Apply the copied SQL script to the consolidated database.

    If an error occurs because the ml_add_user script is not defined when it is dropped, you may safely ignore the error.


Upgrading the MobiLink synchronization server

Before using the version 9 MobiLink synchronization server instead of your earlier version, you should check the behavior changes to see if any affect you.

For a list of behavior changes, see MobiLink behavior changes.


Upgrading Adaptive Server Anywhere MobiLink clients

In a production environment, you should only upgrade Adaptive Server Anywhere remote databases after you have upgraded both the consolidated database and the MobiLink synchronization server.

There are several kinds of upgrade to consider:

  • Upgrading the software.

  • Upgrading the remote database itself.

  • Upgrading the whole application.

Before any upgrade, you should synchronize all outstanding operations as a way of backing up the data in the remote database.

Upgrading the software

It is recommended that you upgrade the dbmlsync MobiLink client and the Adaptive Server Anywhere database engine at the same time. You must upgrade the remote database before running the new dbmlsync utility.

Version 9 MobiLink clients require a MobiLink version 9 synchronization server for synchronization. Version 9 MobiLink clients do not synchronize with a MobiLink synchronization server older than version 9. For information on upgrading MobiLink, see Upgrading MobiLink.

Upgrading the remote database

You can upgrade the Adaptive Server Anywhere remote database by running the Upgrade [dbugrad] utility or, for a more complete upgrade, you can upgrade the database file format.

Both of these operations can be carried out as described for Adaptive Server Anywhere databases. For instructions, see Upgrading a database, and Upgrading the database file format.

Upgrading applications

When deploying a new version of a MobiLink application, it is recommended that you use a new version name for the synchronization scripts. For example, if the existing application uses a script version called v1, then the upgraded application could use a script version called v2. Both script versions can be in use at the same time. This makes it easier to upgrade the remote databases incrementally, rather than all at once.

For versions 9.0.0 and later, the dbmlsrv -zd option has been removed. If your deployment uses the -zd option and you want to upgrade, you must change your download scripts to accept the last download timestamp as the first parameter.


Upgrading UltraLite applications

To upgrade to version 9, you must rebuild your UltraLite application with version 9 software. This includes running the version 9 UltraLite generator and linking against the version 9 libraries.

To run the version 9 UltraLite generator, either explicitly include the path in your command line, or ensure that the version 9 directory appears ahead of older version directories in your system path.

To take advantage of added Palm code segmentation you must upgrade your reference database. Otherwise, all Palm code will go in the same segment. If you are developing for platforms other than the Palm Computing Platform, you do not need to upgrade your reference database to version 9 to generate a version 9 application.

Palm C/C++ development

When working with version 8 or version 9 software, you must add a function call before calling db_init (embedded SQL) or ULData::Open (Static C++ API), to indicate the storage type to use. The function calls are as follows:

ULEnablePalmRecordDB( &sqlca );

or

ULEnableFileDB( &sqlca );

Call ULEnablePalmRecordDB to use primary record-based storage, and ULEnableFileDB for secondary file-based storage.

Upgrading deployed databases

Before upgrading a deployed UltraLite database, you should ensure all changes are synchronized. For Palm applications, it is recommended that you use a new Creator ID for each version of your application, install a new application, and delete the old application and database from the Palm device. If you use the same Creator ID, you should delete the existing application first.

The UltraLite software can upgrade databases subject to some conditions. For more information, see Upgrading UltraLite database schemas, and Upgrading UltraLite software.

UltraLite version 9 applications require a MobiLink version 9 synchronization server for synchronization. UltraLite version 9 applications do not synchronize with a MobiLink synchronization server older than version 9. For information on upgrading MobiLink, see Upgrading MobiLink.

When deploying a new version of a MobiLink application, it is recommended that you use a new version name for the synchronization scripts. This makes it easier to upgrade the remote databases incrementally, rather than all at once.


Upgrading SQL Remote

If you are upgrading an existing SQL Remote installation from version 6 or later, you must upgrade each database server before or along with its message agent (dbremote and ssremote). You can upgrade message agents in any order.

Version 5 users should follow the instructions in Upgrading version 5 SQL Remote installations instead of this section.

  • No need to upgrade databases Although it is not essential to upgrade databases, it is recommended for best performance that you upgrade the database file format by unloading and reloading your database. There is no need for all databases to be upgraded at the same time.

    For information on upgrading your databases, see Upgrading a database, and Upgrading the database file format.

  • Software upgrades can be one site at a time Older Message Agents can exchange messages with Version 9 Message Agents as long as the COMPRESSION database option is set to a value of -1 (minus one). There is no need to upgrade software throughout the installation simultaneously.

  • Message Agent and database server can be upgraded separately The database server can be upgraded before the Message Agent. It is, however, recommended that you upgrade your Message Agent at the same time as the database server for performance reasons.


Upgrading Version 5 Applications

About this chapter

The client/server communication protocol changed between SQL Anywhere version 5 and Adaptive Server Anywhere Version 9. This chapter provides upgrade instructions for those users upgrading from Version 5 to a newer release of the software.

This chapter describes upgrade procedures that apply to the change in communication protocol for users of SQL Anywhere Versions 5.0 and 5.5, and users of Watcom SQL 4.0. In particular, it addresses the problem of stepwise upgrades of client/server installations.

Understanding version 5 upgrades
Review of SQL Anywhere Version 5 architecture
Upgrading embedded SQL applications
Upgrading ODBC applications
Using the compatibility library
Capturing dbclient command information
Upgrading databases
Upgrading version 5 SQL Remote installations


Understanding version 5 upgrades

A database application and DBMS consists of several components. If your organization has a large SQL Anywhere installation, you may have many client machines, possibly running several applications, connected to more than one server.

When upgrading your system, you need to decide which components to upgrade, and in which order. This chapter guides you in making those choices and carrying out the upgrade.

SQL Anywhere Version 5
In this chapter, SQL Anywhere Version 5 refers to both versions 5.0 and 5.5 of SQL Anywhere.

In order to upgrade Version 5 applications, it is helpful to understand how connections work with later versions of the software. For information, see Connecting to a Database.


The components in your system

If you are currently running SQL Anywhere Version 5, you will have some or all of the following components in your system:

  • Application Your application, aside from the SQL Anywhere components.

  • Connection parameters SQL Anywhere Version 5.0 connection parameters. These may be assembled from an ODBC data source, or in some other way.

  • Driver manager The ODBC driver manager, for ODBC applications.

  • ODBC driver The SQL Anywhere Version 5 ODBC driver, for ODBC applications. For network applications, the ODBC driver is on the client machine.

  • Interface library The SQL Anywhere Version 5 interface library is used by ODBC and embedded SQL applications. For network applications, the interface library is on the client machine.

  • SQL Anywhere client The dbclient.exe executable and its command line, for network applications. The command line may specify the server name, and a set of network protocol options. It may be stored in a batch file or an ODBC data source Start Line parameter. For network applications, the SQL Anywhere client is on the client machine.

  • The database server The SQL Anywhere Version 5 database server. For network applications, this may be on a separate machine from the client components.

  • The database A SQL Anywhere Version 5 database. This is on the same machine as the database server.

    Database upgrades not required
    You do not need to upgrade your database in order to use newer database server with an existing application.

Previous Next


Major upgrading issues

The major issues in upgrading from version 5 arise from the change in client/server communication protocol. This change means that the Version 5 interface library is not able to communicate with more recent database servers.

To help with this issue, Adaptive Server Anywhere includes a compatibility library. This DLL allows communications to both Version 5 and current database servers.

Behavior changes

You should also check the behavior change lists elsewhere in this book for versions since version 5 for any changes that may affect your application.

In addition, applications using Transact-SQL outer joins should note the following incompatibility with newer releases:

The null-supplying table in a Transact-SQL outer join cannot also participate in another regular or outer join. For example, in the following query, table S violates this limitation as it is the null-supplying table in R.x *= S.x, and participates in another join.

-- invalid query
SELECT *
FROM R, S, T
WHERE R.x *= S.x
AND S.y = T.y


When to upgrade your database

There is no need to upgrade your Version 5 database itself when you start using the current release of the software. You do need to upgrade the database if you wish to take advantage of many of the features introduced since Version 5.

For more information on upgrading databases, see Upgrading Software and Databases.


Running more than one version of the software

The SQL Anywhere Studio software is designed so that both separate versions can be run if you install them in separate directories. This is the default behavior of the SQL Anywhere Setup program.


Review of SQL Anywhere Version 5 architecture

This section reviews the architecture for SQL Anywhere Version 5 applications connecting to a SQL Anywhere Version 5 database.

This information helps you to understand the changes needed when upgrading to more recent versions. If you are familiar with SQL Anywhere Version 5 architecture, you do not need to read this section.


Standalone components for Version 5 (embedded SQL)

If you are using SQL Anywhere Version 5 as a personal server, with an embedded SQL client application, you are using the following components on your machine:

  • A SQL Anywhere Version 5 database.

  • The SQL Anywhere Version 5 database engine (personal database server).

  • The SQL Anywhere Version 5 interface library.

  • A SQL Anywhere Version 5.0 connection string.

The following figure illustrates how these pieces fit together.

Embedded SQL standalone architecture for version 5.

Here, the question mark in dbl50?.dll represents a single character indicating the operating system. The interface library is named dlb50t.dll on Windows operating systems.

Embedded SQL client applications make calls to the interface library. The interface library is referenced by name, so that the name dbl50t.dll is a part of the client application.


Standalone components for Version 5 (ODBC)

If you are using SQL Anywhere Version 5 as a personal server, with an ODBC client application, you are using the following components on your machine:

  • A SQL Anywhere Version 5 database.

  • The SQL Anywhere Version 5 database engine.

  • The SQL Anywhere Version 5 interface library.

  • The SQL Anywhere Version 5 ODBC driver.

  • The ODBC driver manager.

  • A SQL Anywhere Version 5.0 connection description. This may be an ODBC data source, or a connection string from an application.

The following figure illustrates how these pieces fit together. The client application passes a data source name to the ODBC driver manager. The ODBC driver manager looks up the appropriate driver in ODBCINST.INI. The driver looks up the connection information in ODBC.INI and, via the interface library, connects to the SQL Anywhere Version 5 database engine.

ODBC standalone architecture for version 5.


Client/server components for Version 5

If you are using SQL Anywhere as a network server, you have the following components on your server machine:

  • A SQL Anywhere Version 5 database

  • The SQL Anywhere Version 5 database server

You have the following components on your client machine:

  • The SQL Anywhere Version 5 Client executable

  • The SQL Anywhere Version 5 interface library.

  • The SQL Anywhere ODBC driver, if your application uses ODBC.

  • A SQL Anywhere Version 5.0 connection description. This may be an ODBC data source, or a connection string from an application.

    The data source may contain connection information in the start option, corresponding to a SQL Anywhere Client command line. You may also have connection strings in your application, and batch files that start a client with a particular set of parameters and options.

The architecture of a Version 5 embedded SQL client/server connection is illustrated in the figure. For ODBC applications the ODBC driver manager and ODBC driver stand between the application and the interface library.

Embedded SQL client/server architecture for version 5.


Upgrading embedded SQL applications

You can upgrade a SQL Anywhere Version 5 standalone application to use newer versions of the database server by upgrading the database server and the interface library. You do not need to upgrade the database or the client application itself.

The upgrade procedure uses the compatibility library. The compatibility library is a dynamic library (a DLL on PCs, shared library on UNIX) that enables embedded SQL applications to work with both Version 5 and newer versions of the database server.

For a description of the compatibility library, see Using the compatibility library.

StartLine connection parameter
If your application connection string uses a StartLine parameter that explicitly provides a dbclient.exe or dbeng50.exe command line, and this is hard coded into your application, there are additional upgrade considerations.

For information on upgrading applications that use StartLine connection parameters, see Start parameters and the compatibility library.

Components upgraded

The following figure illustrates the changes you need to make in your setup in order to upgrade:

Changes needed for upgrading version 5 embedded SQL applications.

For a description of the compatibility library, see Using the compatibility library.


Upgrade procedures for embedded SQL applications

This section provides step-by-step procedures for different kinds of embedded SQL applications:

  • Applications using an embedded database are standalone applications using the personal database server (dbeng50.exe for Version 5, dbeng9.exe for Version 9).

  • Client/server applications connect across a network to the network database server. In Version 5, these applications use the dbclient.exe executable.

toggle To upgrade embedded SQL applications that use an embedded database

  1. Install the current version of the software Newer versions of the software contain components that enable Version 5 applications to continue working. You can either install into a separate directory or over the top of your Version 5 software.

    The installation places the new executable directory ahead of the Version 5 executable directory in your system path.

  2. Ensure that your application is using the compatibility DLL If necessary, copy the compatibility library dbl50?.dll from your Adaptive Server Anywhere executable directory to a place where your application will locate it.

    For example, you could copy the compatibility library to the same directory as the module of your application that loads it. The file dbl50?o.dll is installed into your Adaptive Server Anywhere executable directory. This directory must be in your path as this library is required by the compatibility library.

    At this stage, your Version 5 application should continue to work as before. However, it will be connecting to your database through the compatibility library rather than directly through the Version 5 interface library.

    If you have any problems at this stage, you need to check how your application locates the interface library. For information, see File locations and the compatibility library.

  3. Create a new connection description If your application obtains its connection parameters from configuration files, batch files, or the system registry, you should prepare a new description that uses the current version of the database server. For example, Sybase Central stores connection descriptions in the system registry.

    • If you store a connection string that uses the DBF parameter to start the default database server, then the new database server is started automatically by the compatibility library, instead of the Version 5 database server. In this case, no new connection description is needed.

    • If you store a connection string that uses a Start Line parameter specifying dbeng50.exe, you must replace this with one specifying dbeng9.exe. If your application contains a hard-coded connection string, you need to take extra steps at this point.

      For more information on upgrading StartLine parameters, see Start parameters and the compatibility library.

    • If the database server is started in some other way, such as by a batch file or using a Windows NT service, you must reconfigure this so that the new version of the database server is started instead.

  4. Use the new connection description With this step, you are using all current software and have completed your upgrade. The database itself does not need to be upgraded to work with existing applications.

toggle To upgrade embedded SQL client/server applications

  1. Prepare for the upgrade This step must be carried out at each client machine. You prepare for the upgrade by installing the current version of the software.

    Ensure that the installation places the current executable directory ahead of the Version 5 executable directory in your system path.

  2. Ensure that your application is using the compatibility DLL This step must be carried out at each client machine. If necessary, copy the compatibility library dbl50?.dll from your Adaptive Server Anywhere executable directory to a place where your application will locate it.

    For example, you could copy the compatibility library to the same directory as the module of your application that loads it. The file dbl50?o.dll is installed into your Adaptive Server Anywhere executable directory. This directory must be in your path as this library is required by the compatibility library.

    At this stage, your Version 5 application should continue to work as before. However, it will be connecting to your database through the compatibility library rather than directly through the Version 5 interface library.

    If you have any problems at this stage, you need to check how your application locates the interface library. For information, see File locations and the compatibility library.

  3. Create a new connection description This step must be carried out at each client machine. If your application obtains its connection parameters from configuration files, batch files, or the system registry, you should prepare a new description that uses the newer database server. This description is for use when the server is upgraded.

    If you store a connection string that uses a StartLine connection parameter specifying dbclient.exe, you must replace this with a new one. The new connection description should contain all the dbclient information as a set of parameters. If your application contains a hard-coded connection string, you need to take extra steps at this point.

    For more information on upgrading StartLine parameters, see Start parameters and the compatibility library.

    For more information about creating connection descriptions that capture the dbclient command information, see Capturing dbclient command information.

  4. Upgrade the database server This step must be carried out at the server machine.

    • As with any software upgrade, back up your database before upgrading.

    • Install Adaptive Server Anywhere on the server machine.

    • Start the new database server on the database.

  5. Use the new connection description This step must be carried out at each client machine. You need to use the new connection description to connect to the newer version of the database server. With this step, you are using all current software and have completed your upgrade. The database itself does not need to be upgraded to work with existing applications.


Using the version 5 utilities with Adaptive Server Anywhere

For the Version 5 database utilities, connection strings are supplied interactively. The Version 5 database utilities such as Interactive SQL are embedded SQL applications that search for the interface library in the following order:

  1. The current directory

  2. The Version 5 executable directory

  3. The system path

For these applications, even though the compatibility library is ahead of the Version 5 interface library in the system path, the Version 5 compatibility library is located.

toggle To use Version 5 utilities with Adaptive Server Anywhere Version 9

  1. Make a backup copy of your interface library file.

  2. Copy the compatibility library from your Version 9 executable directory to your Version 5 directory. For example, on Windows 95 and Windows NT, copy the file dbl50t.dll from the win32 subdirectory of your Version 9 installation to the win32 subdirectory of your Version 5 installation.

  3. You can now run your Version 5 utilities against both Version 5 and Version 9 database servers.


Upgrading ODBC applications

You can upgrade Version 5 ODBC applications in the following ways:

  • Replace the Version 5 ODBC data source with a current ODBC data source. This approach is a complete upgrade, and is described in this section.

  • Use the compatibility library to connect to a current version of the database server. If you choose this route, your application continues to use the Version 5 ODBC driver, so this is not a complete upgrade. The procedure for upgrading in this way is the same as for embedded SQL applications.

    For information about upgrading in this manner, see Upgrading embedded SQL applications.

    StartLine parameter
    If your ODBC data source contains a start line specifying the Version 5 standalone engine (dbeng50.exe) or the SQL Anywhere client (dbclient.exe), you cannot upgrade using the compatibility library.
Components upgraded

The following figure illustrates the changes you must make when upgrading an ODBC standalone application.

Changes needed for upgrading version 5 ODBC applications.
Data sources

The ODBC data source specifies which ODBC driver to use. When an ODBC data source is created as an Adaptive Server Anywhere Version 9 data source, it uses the Version 9 ODBC driver.

Data source must be current version
ODBC applications require the version of the ODBC data source to be the same as that of the ODBC driver.

Upgrade procedures for ODBC applications
Upgrade notes for PowerBuilder and InfoMaker users

Previous Next


Upgrade procedures for ODBC applications

This section provides step-by-step procedures for different kinds of ODBC applications:

  • Applications using an embedded database are standalone applications using the personal database server (dbeng50.exe for Version 5, dbeng9.exe for Version 9).

  • Client/server applications connect across a network to the network database server. In Version 5, these applications use the dbclient.exe executable.

Some applications allow you to change the ODBC data source name you use. Other applications use a fixed data source name. You can upgrade either kind of application.

toggle To upgrade ODBC applications that use an embedded database

  1. Install the current software The current version of the software contains components that enable Version 5 ODBC applications to continue working. You can either install into a separate directory or over the top of your Version 5 software.

    Your application should be unaffected by installation of the current version of the software.

  2. Create a Version 9 ODBC data source The changes you make depend on the connection parameters you use in the data source.

    • If you start the default database server using the DBF parameter, you can use the same connection parameters in your new data source as your old one.

    • If you store a connection string that uses a Start Line parameter specifying dbeng50.exe, you must replace this with one specifying dbeng9.exe.

      For more information on upgrading StartLine parameters, see Start parameters and the compatibility library.

    • If the database server is started in some other way, such as by a batch file or using a Windows NT service, you must reconfigure this so that the newer version of the database server is started instead.

      For information on creating data sources, see Working with ODBC data sources.

  3. Use the new data source With this step, you are using all current software and have completed your upgrade. The database itself does not need to be upgraded to work with existing applications.

Some applications may have the data source name hard wired. In this case, you need to replace the Version 5 data source with a Version 9 data source of the same name. It is recommended that you rename, rather than delete, your Version 5 data source.

toggle To upgrade ODBC client/server applications

  1. Prepare for the upgrade This step must be carried out at each client machine. You prepare for the upgrade by installing the current version of the software.

    Your application should be unaffected by installation of the current version of the software.

  2. Create a Version 9 ODBC data source This step must be carried out at each client machine. The changes you make depend on the connection parameters you use in the data source.

    • If you start the default database server using the DBF parameter, you can use the same connection parameters in your new data source as your old one.

    • If you store a connection string that uses a StartLine connection parameter specifying dbclient.exe, you must replace this with a new one. The new connection description should contain all the dbclient information as a set of parameters. If your application contains a hard-coded connection string, you need to take extra steps at this point.

      For more information on upgrading StartLine parameters, see Start parameters and the compatibility library.

      For more information about creating connection descriptions that capture the dbclient command information, see Capturing dbclient command information.

    • If the database server is started in some other way, such as by a batch file or using a Windows NT service, you must reconfigure this so that the newer version of the database server is started instead.

      For information on creating Version 9 data sources, see Working with ODBC data sources.

  3. Upgrade the database server This step must be carried out at the server machine.

    • As with any software upgrade, back up your database before upgrading.

    • Install Adaptive Server Anywhere on the server machine.

    • Start the Version 9 database server on the database.

  4. Use the new data source This step must be carried out at each client machine. You need to use the new connection description to connect to the newer version of the database server. With this step, you are using all current software and have completed your upgrade. The database itself does not need to be upgraded to work with existing applications.


Upgrade notes for PowerBuilder and InfoMaker users

Users of Sybase PowerBuilder and InfoMaker should make some changes in order to obtain full functionality with Adaptive Server Anywhere Version 9.

The pbodb80.ini file

PowerBuilder and InfoMaker use a file named pbodb80.ini to hold ODBC data source information. The 80 in the file name may be different, depending on the version you have. For each ODBC driver it provides such things as DDL syntax, default DBParm options, valid function names and special data types.

If your pbodb80.ini file does not have a Adaptive Server Anywhere section, PowerBuilder and InfoMaker default to a core syntax. This limits the operations you can carry out using these tools. For example you cannot create, alter, or drop primary and foreign keys.

Upgrading your pbodb80.ini file

To obtain complete functionality with PowerBuilder and InfoMaker, you need to upgrade your pbodb80.ini file.

toggle To upgrade your pbodb80.ini file

  1. Make a backup copy of your existing pbodb80.ini file.

  2. Add an Adaptive Server Anywhere section to the working copy of the file containing the same information as the existing Sybase SQL Anywhere section:

    [Adaptive Server Anywhere]
PBSyntax='WATCOM50_SYNTAX'
PBDateTime='STANDARD_DATETIME'
PBFunctions='WATCOM_FUNCTIONS'
PBDefaultValues='autoincrement,current date,current time,current timestamp,timestamp,null,user'
PBDefaultCreate='YES'
PBDefaultAlter='YES'
PBDefaultExpressions='YES'
DelimitIdentifier='YES'
PBDateTimeInvalidInSearch='NO'
PBTimeInvalidInSearch='YES'
PBQualifierIsOwner='NO'
PBSpecialDataTypes='WATCOM_SPECIALDATATYPES'
IdentifierQuoteChar='"'
PBSystemOwner='sys,dbo,rs_systabgroup'
PBUseProcOwner='YES'
SQLSrvrTSName='YES'
SQLSrvrTSQuote='YES'
SQLSrvrTSDelimit='YES'
ForeignKeyDeleteRule='Disallow if Dependent Rows Exist (RESTRICT),Delete any Dependent Rows (CASCADE),Set Dependent Columns to NULL (SET NULL)'
TableListType='GLOBAL TEMPORARY'


Using the compatibility library

The compatibility library is a dynamic library (a DLL on PCs, shared library on UNIX) that enables embedded SQL applications to work with both Version 5 and Version 9 database servers. This section describes how the compatibility library works.

Who needs to read this section?
You should read this section if you are upgrading SQL Anywhere Version 5 to Adaptive Server Anywhere Version 9, and have existing embedded SQL applications that you need to work with the Version 9 server.

The Version 5 embedded SQL interface library
How Version 5 client applications locate the interface library
Using the compatibility library
How the compatibility library works
File locations and the compatibility library
Start parameters and the compatibility library


The Version 5 embedded SQL interface library

All client machines running SQL Anywhere Version 5 applications, whether connecting over a network or to a personal server, have a SQL Anywhere Version 5 interface library.

For Windows operating systems, this library is a DLL named dbl50t.dll.


How Version 5 client applications locate the interface library

Version 5 client applications locate the interface library in one of the following ways:

  • ODBC applications ODBC applications connect to a SQL Anywhere database using the SQL Anywhere ODBC driver. The SQL Anywhere Version 5 ODBC driver calls functions in the Version 5 embedded SQL interface library.

  • Embedded SQL applications Embedded SQL applications for Windows operating systems call into the interface library. In these calls, the interface library is referenced by name—dbl50t.dll for Windows 95 and NT.

    The SQL Anywhere Version 5 ODBC driver is an embedded SQL application.


Using the compatibility library

Using the compatibility library

The compatibility library is optionally installed as part of the Version 9 client software. It provides support for two interface libraries at the same time. You should check your installation to confirm that it is installed.

The setup program should ensure that your application calls the compatibility library instead of the Version 5 interface library.

The setup program carries out the following steps to ensure that applications call the interface library.

  • The compatibility library has the same name as the SQL Anywhere Version 5 interface library. For example, on Windows NT, the compatibility library is named dbl50t.dll.

  • The compatibility library is installed into the same directory as other Version 9 software.

  • The Version 9 installation directory is placed ahead of the Version 5 directory in the system path. This ensures that applications locate the compatibility library ahead of the Version 5 interface library.

  • A Version 5 interface library is installed into the same directory as the compatibility library, but with the name dbl50to.dll. When the compatibility library is accessing Version 5 servers, it calls this interface library.

  • The Version 9 interface library is installed into the same directory as the compatibility library. It has the name dblib9.dll on Windows NT. When the compatibility library is accessing Version 9 servers, it calls this interface library.

If you have problems using the compatibility library, you should check the order of the directories in your path, and ensure that the Version 9 location is ahead of the Version 5 location in the path.


How the compatibility library works

Using the supplied connection string, the compatibility library attempts to connect to an Adaptive Server Anywhere database using the Adaptive Server Anywhere Version 9 interface library. If this attempt fails, it attempts to connect to a SQL Anywhere database using the SQL Anywhere Version 5 library.

The following figure illustrates how the compatibility library enables communications to both a SQL Anywhere Version 5 and an Adaptive Server Anywhere Version 9 database server. The number in the lower right hand corner of the boxes indicates the version of the software component.

The compatibility library

The following figure illustrates the algorithm used by the compatibility library to connect to a server:

The algorithm used by the compatibility library to connect to a database server:


File locations and the compatibility library

The compatibility library and the Version 5 interface library have the same file name (dbl50.dll). For your application to use the compatibility library, it must locate it ahead of the Version 5 interface library when it searches for DLLs.

To ensure that your application locates the compatibility library ahead of the Version 5 interface library you must understand how your application searches for DLLs.

Searching for DLLs

The Version 9 installation program does not necessarily place the Version 9 executable directory ahead of the Version 5 directory in the system path, so any application that uses the path to searching for dbl50.dll may have to be changed to find the compatibility library ahead of the Version 5 interface library.

The Version 5 ODBC driver is in the same directory as the Version 5 interface library, and so locates this library instead of the Version 9 library. To enable Version 5 ODBC applications to connect to Version 9 database servers, you can either rename the Version 5 interface library, or copy the Version 9 compatibility library along with dbl50to.dll into your Version 5 directory.

Testing to see which library is located

You can test to see which library is located in the following ways:

  • Attempt to connect to a Version 9 database server. You cannot connect using the Version 5 interface library.

  • Specify a database file parameter (DBF) and no start line in your connection string. If the Version 5 interface library is located, the SQL Anywhere Version 5 standalone database engine is started. If the compatibility library is located, the Version 9.0 personal database server is started.


Start parameters and the compatibility library

Applications using a connection string that includes a StartLine connection parameter face some additional issues in upgrading.

The StartLine parameter provides explicit instructions for starting the database engine or the SQL Anywhere Client executable. Sample StartLine parameters are as follows:

  • Standalone application A sample StartLine parameter for a Version 5 standalone application is as follows:

    dbeng50.exe -c 8M

  • Network client application A sample StartLine parameter for a Version 5 network client application is as follows:

    dbclient.exe -x tcpip

In the current version of the software, the dbeng50.exe executable is replaced by the personal database server dbeng9.exe. The dbclient.exe executable is no longer required.

toggle To upgrade StartLine parameters

  • The procedure depends on where your connection parameters are stored.

    • If your connection parameters are stored outside the application itself, then you need to alter the connection parameters to use the appropriate dbeng9.exe executable name instead of dbeng50.exe.

      All the information on the dbclient command line can be rephrased in terms of other connection parameters. For information, see Connection Parameters and Network Protocol Options.

    • If your connection parameters are hard-wired into your application, you must relink your application with a new connection string.

      There are many possible configurations of client command lines and connection parameters. Be sure you test any solution thoroughly before deploying.


Capturing dbclient command information

Version 5 client applications that connect to a database server do so via the SQL Anywhere Client, an executable named dbclient.exe. The client executable command line contains information needed to locate a server, including the following:

  • Default server name The server name on the client command line is the default server name. When a client executable is running, the application does not need to supply a server name in order to connect to the default server.

  • Network protocol options A listing of network protocols to use together with a set of protocol options specifies where the client executable is to look as it attempts to locate a server.

  • Client/Server communication tuning A set of parameters allows the packet size, buffer size, and so on to be tuned for optimum performance.

In Version 9, this information is held in an ODBC data source along with other connection information. As there is no longer a client executable, there is no longer a client command line. In Version 9, embedded SQL applications can use ODBC data sources as a source of connection parameters.

Client command line scope

Only one Version 5 client executable can be run at a time, and it may be used by more than one application and handle connections to more than one server. The command information is therefore global to the machine.

How to capture client command information


How to capture client command information

During upgrade to Version 9, you must ensure that Version 5 dbclient command information is captured in such a way that the Version 9 ODBC or embedded SQL applications can use it. You can do this in one of the following ways:

  • Place the information in an ODBC data source If the information can be placed in a data source, you can use it with Version 9 ODBC or embedded SQL applications.

  • Use the SQLCONNECT environment variable The SQLCONNECT environment variable contains a connection string. It is searched early in the process of establishing which connection parameters to use. You may be able to use SQLCONNECT settings to override connection parameters.

The way to capture client command information depends on where the information is located.

Where command information is located

Your existing command line information may be held in one of the following places.

  • ODBC data source The ODBC data source contains a START parameter that can hold a client executable command.

  • As a connection string Your application may obtain client information (for example from an initialization file), and supply it in a connection string as the START parameter.

  • A batch file You may have a batch file that includes a client executable command line as part of your startup process.

  • Under an icon You may have a client executable command line under an icon on your desktop.

How to capture the information

  • From an ODBC data source The ODBC data source upgrade captures the information in an ODBC data source START parameter.

  • From a batch file or under an icon You can move the dbclient.exe parameters into your CommLinks connection parameter.

  • Hard-wired connection strings Only if you have a hard-wired connection string in your application (that is, one that cannot be edited), you must alter the source of the application and recompile.


Upgrading databases

To use some of the new features of Adaptive Server Anywhere, you need to upgrade your database file.

Caution Ensure that you back up your database before upgrading.
Supported versions

You can upgrade your database from any of the following versions of the software to the format of the current version:

  • SQL Anywhere Version 5 Including versions 5.0 and 5.5, all patch levels.

  • Watcom SQL Version 4 All patch levels.

  • Watcom SQL Version 3.2 Only patch level e and above.

What the Upgrade [dbupgrad] utility does

The Upgrade [dbupgrad] utility carries out the following tasks:

  • Adds new system tables.

  • Adds new columns to existing system tables.

  • Adds database options.

For instructions on upgrading databases, see Upgrading Software and Databases.


Upgrading version 5 SQL Remote installations

SQL Remote installations include a consolidated database and many remote databases, together with a Message Agent at each site.

At each site, the Message Agent handles the sending and receiving of messages. The messages take the form of SQL statements, and the database server handles the actual execution of those SQL statements.

The upgrade requirements for SQL Remote are as follows:

  • No need to upgrade databases Although it is not essential to upgrade databases for Version 9, it is recommended for best performance that you upgrade the database file format by unloading and reloading your database. There is no need for all databases to be upgraded at the same time.

    For instructions on unloading and reloading the database, see Unloading and reloading a database participating in replication. For instructions on upgrading the database version, see Upgrading a database.

  • Software upgrades can be one site at a time Version 5 Message Agents can exchange messages with Version 9 Message Agents as long as the COMPRESSION database option is set to a value of -1 (minus one). There is no need to upgrade software throughout the installation simultaneously.

  • Message Agent and server can be upgraded separately The Message Agent is an embedded SQL application. Therefore, the database server can be upgraded before the Message Agent as long as the compatibility library is used. It is, however, recommended that you upgrade your Message Agent at the same time as the database server for performance reasons.

    The Message Agent cannot be upgraded before the database server, as a new client application cannot work with a Version 5 server.

    Replication is based on the transaction log, and when a database is unloaded and reloaded, the old transaction log is no longer available. For this reason, good backup practices are especially important when participating in replication.

Example

One approach to upgrading is as follows:

  1. Upgrade the consolidated database server and Message Agent. Set the COMPRESSION database option to -1 so that all messages are compatible with the Version 5 software at remote sites.

  2. Over time, upgrade remote database servers and Message Agents. You can set the COMPRESSION database option to a value other than -1 to take advantage of compression and encoding on messages being sent to the consolidated database server.

  3. When all remote database servers and Message Agents are upgraded, set the COMPRESSION database option at the consolidated site to a value other than -1.


Web Links Browse Collapse Expand PDF Previous Next

ASA Database Administration Guide

Version 9.0.2

DC38123-01-0902-01

October 2004

Copyright
About This Manual
Running the Database Server
Connecting to a Database
Client/Server Communications
Adaptive Server Anywhere as an Open Server
The Database Server
Connection Parameters and Network Protocol Options
Using Web Services
File Locations and Installation Settings
Working with Database Files
Automating Tasks Using Schedules and Events
International Languages and Character Sets
Backup and Data Recovery
Managing User IDs and Permissions
Replicating Data with Replication Server
Database Administration Utilities
Database Options
Database Performance and Connection Properties
Physical Limitations


About This Manual

Subject

This book covers material related to running, managing, and configuring databases. It describes database connections, the database server, database files, security, backup procedures, and replication with the Replication Server, as well as administration utilities and options.

Audience

This manual is for all users of Adaptive Server Anywhere. It is to be used in conjunction with other manuals in the documentation set.


Running the Database Server

About this chapter

This chapter describes how to start and stop the Adaptive Server Anywhere database server, and the options available to you on startup under different operating systems.

Introduction
Starting the server
Some common options
Stopping the database server
Starting and stopping databases
Running the server outside the current session
Troubleshooting server startup


Introduction

Adaptive Server Anywhere provides two versions of the database server:

  • The personal database server This executable does not support client/server communications across a network. Although the personal database server is provided for single-user, same-machine use—for example, as an embedded database server—it is also useful for development work.

    On Windows operating systems, except Windows CE, the name of the personal server executable is dbeng9.exe. Windows CE does not support the personal server. On UNIX operating systems its name is dbeng9.

  • The network database server Intended for multi-user use, this executable supports client/server communications across a network.

    On Windows operating systems, including Windows CE, the name of the network server executable is dbsrv9.exe. On Novell NetWare the name is dbsrv9.nlm and on UNIX operating systems it is dbsrv9.

    It is recommended that you run the network database server on Windows NT/2000/XP or Windows 2003, rather than Windows 95/98/Me, to ensure better performance and reliability.

Server differences

The request-processing engine is identical in both servers. Each one supports exactly the same SQL, and exactly the same database features. The main differences include:

  • Network protocol support Only the network server supports communications across a network.

  • Number of connections The personal server has a limit of ten simultaneous connections. The limit for the network server depends on your license.

  • Number of CPUs With per-seat licensing, the network database server uses all CPUs available on the machine (the default). With CPU-based licensing, the network database server uses only the number of processors you are licensed for. In addition, the personal database server and runtime database server are both limited to a single processor.

  • Default number of internal threads You can configure the number of requests the server can process at one time using the -gn option. The personal and network database servers have a default of 20 threads, except on Windows CE, where the default is 3 threads.

    For more information about database server options, see The database server.

  • Startup defaults To reflect their use as a personal server and a network server for many users, the startup defaults are slightly different for each.


First steps

You can start a personal server running on a single database very simply. For example, you can start both a personal server and a database called test.db by typing the following command in the directory where test.db is located:

dbeng9 test
Where to specify commands

You can specify commands in several ways, depending on your operating system. For example, you can:

  • type the command at a command prompt.

  • place the command in a shortcut or desktop icon.

  • run the command in a batch file.

  • include the command as a StartLine (START) connection parameter in a connection string.

    For more information, see StartLine connection parameter [START].

There are slight variations in how you specify the basic command from platform to platform. These are described in the following section.

You can also start a personal server using a database file name in a connection string.

For more information, see Connecting to an embedded database.

Start the database server


Start the database server

The way you start the database server varies slightly depending on the operating system you use. This section describes how to specify commands for the simple case of running a single database with default settings on each supported operating system.

Notes

  • Except where otherwise noted, these commands start the personal server (dbeng9). To start a network server, simply replace dbeng9 with dbsrv9.

  • If the database file is in the starting directory for the command, you do not need to specify path.

  • If you do not specify a file extension in database-file, the extension .db is assumed.

toggle To start the personal database server using default options (Windows except Windows CE)

  1. Open a command prompt.

  2. Type the following command:

    start dbeng9 path\database-file

    If you omit the database file, the Server Startup Options dialog appears, where you can locate a database file using a Browse button.

For information about starting a database server on Windows CE, see Starting the database server on Windows CE.

toggle To start the personal database server using default options (UNIX)

  1. Open a command prompt.

  2. Type the following command:

    dbeng9 path/database-file

There is no personal server for Novell NetWare, just a network server. The following command starts the network server on NetWare.

toggle To start the database server using default options (NetWare)

  • The database server for NetWare is a NetWare Loadable Module (NLM) (dbsrv9.nlm). A NLM is a program that you can run on your NetWare server. Load a database server on your NetWare server as follows:

    load dbsrv9.nlm path\database-file

    The database file must be on a NetWare volume. A typical filename is of the form DB:\database\sales.db.

    You can load the server from a client machine using the Novell remote console utility. See your Novell documentation for details.

    You can put the command into your Novell autoexec.ncf file so that Adaptive Server Anywhere loads automatically each time you start the NetWare server.


What else is there to it?

Although you can start a personal server in the simple way described in the previous section, there are many other aspects to running a database server in a production environment. For example,

  • You can choose from many options to specify such features as how much memory to use as cache, how many CPUs to use (on multi-processor machines running a network database server), and the network protocols to use (network server only). The options are one of the major ways of tuning Adaptive Server Anywhere behavior and performance.

  • You can run the server as a Windows service. This allows it to continue running even when you log off the machine.

  • You can start the personal server from an application and shut it down when the application has finished with it. This is typical when using the database server as an embedded database.

The remainder of this chapter describes these options in more detail.


Starting the server

The general form for the server command is as follows:

executable [ server-options ] [ database-file [ database-options ], ...]

If you supply no options and no database file, then on Windows operating systems a dialog appears, allowing you to use a Browse button to locate your database file.

The elements of the database server command include the following:

  • Executable This can be either the personal server or the network server.

    For the file names on different operating systems, see Introduction.

    In this chapter, unless discussing network-specific options, the personal server is used in sample commands. The network server takes a very similar set of options.

    • Server options These options control the behavior of the database server for all running databases.

  • Database file You can specify zero, one, or more database file names. Each of these databases starts and remains available for applications.

    Caution The database file and the transaction log file must be located on the same physical machine as the database server. Database files and transaction log files located on a network drive can lead to poor performance and data corruption.

    • Database options For each database file you start, you can provide database options that control certain aspects of its behavior.

For full reference information on each of these options, see The database server.

In examples throughout this chapter where there are several options, they appear on separate lines for clarity, as they could be written in a configuration file. If you type them directly at the command prompt, you must type them all on one line.

Case sensitivity

Database and server options are generally case sensitive. You should type all options in lower case.

Listing available options
toggle To list the database server options

  1. Open a command prompt.

  2. Type the following command:

dbeng9 -?

Starting the database server on Windows CE


Starting the database server on Windows CE

The database server supplied for Windows CE is the network database server (dbsrv9.exe). The network server supports communications over a TCP/IP network link.

The usual client/server arrangement has the database server running on a machine with more power and resources than the client applications. Clearly, this is not the case with Windows CE; instead, the less powerful machine is running the database server.

The advantage to supplying a network server on Windows CE is that you can run database applications on your desktop computer to carry out tasks on your Windows CE database. For example:

  • You can use Sybase Central on your desktop PC to manage your database.

  • You can use Interactive SQL on your desktop to load and unload data, and carry out queries.

  • You can use InfoMaker to produce reports.

The Windows CE database server does not start the TCP/IP network link unless it is explicitly requested.

For more information about starting a database server on Windows CE, see Lesson 1: Starting the database server.

On Windows CE, attempting to start a second Adaptive Server Anywhere database server while a first server is already running brings the first server to the foreground. This is standard behavior for Windows CE applications. Because of this, two database servers cannot be run at the same time on a Windows CE device. As an alternative to running multiple database servers, one database server can run more than one database if necessary. Note that -gd all is required to autostart a database on a running server.

For more information about the -gd option, see -gd server option.


Some common options

This section describes some of the most common options, and points out when you may wish to use them. They are:

  • Using configuration files

  • Naming the server and the databases

  • Performance

  • Permissions

  • Maximum page size

  • Special modes

  • Threading

  • Network communications (network server only)

Using configuration files to store server startup options
Naming the server and the databases
Controlling performance and memory from the command line
Controlling permissions from the command line
Setting a maximum page size
Running in special modes
Controlling threading from the command line
Selecting communications protocols


Using configuration files to store server startup options

If you use an extensive set of options, you can store them in a configuration file and invoke that file in a server command. The configuration file can contain options on several lines. For example, the following configuration file starts the personal database server and the sample database. It sets a cache of 10 Mb, and names this instance of the personal server Elora. Lines with # as the first character in the line are treated as comments.

# Configuration file for server Elora
-n Elora
-c 10M
path\asademo.db

In the example, path is the name of your SQL Anywhere directory. On UNIX, you would use a forward slash instead of the backslash in the file path.

If you name the file sample.cfg, you could use these options as follows:

dbeng9 @sample.cfg

For more information, see @data server option and Using configuration files.


Naming the server and the databases

You can use –n as a server option (to name the server) or as a database option (to name the database).

The server and database names are among the connection parameters that client applications may use when connecting to a database. The server name appears on the desktop icon and in the title bar of the server window.

The following are invalid for database server and database names:

  • names that begin with white space or single or double quotes

  • names that end with white space

  • names that contain semicolons

Naming the server

Providing a database server name helps avoid conflicts with other server names on your network. It also provides a meaningful name for users of client applications. The server keeps its name for its lifetime (until it is shut down). If you don't provide a server name, the server is given the name of the first database started.

You can name the server by supplying a –n option before the first database file. For example, the following command starts a server on the asademo database and gives the server the name Cambridge:

dbeng9 –n Cambridge asademo.db

If you supply a server name, you can start a database server with no database started. The following command starts a server named Galt with no database started:

dbeng9 –n Galt

For more information about starting databases on a running server, see Starting and stopping databases.

Naming databases

You may want to provide a meaningful database name for users of client applications. The database is identified by that name until it is stopped.

If you don't provide a database name, the default name is the root of the database file name (the file name without the .db extension). For example, in the following command the first database is named asademo, and the second sample.

dbeng9 asademo.db sample.db

You can name databases by supplying a –n option following the database file. For example, the following command starts the sample database and names it MyDB:

dbeng9 asademo.db -n MyDB
Case sensitivity

Server names and database names are case insensitive as long as the character set is single-byte.

For more information, see Connection strings and character sets.


Controlling performance and memory from the command line

Several options can have a major impact on database server performance, including:

  • Cache size The –c option controls the amount of memory that Adaptive Server Anywhere uses as a cache. This can be a major factor in affecting performance.

    Generally speaking, the more memory made available to the database server, the faster it performs. The cache holds information that may be required more than once. Accessing information in cache is many times faster than accessing it from disk. The default initial cache size is computed based on the amount of physical memory, the operating system, and the size of the database files. On Windows and UNIX operating systems, the database server automatically grows the cache when the available cache is exhausted.

    For more information about performance tuning, see Monitoring and Improving Performance.

    For information on controlling cache size, see Cache size.

  • Number of processors If you are running on a multi-processor machine using a network database server, you can set the number of processors with the -gt option.

    For more information, see -gt server option and Controlling threading from the command line.

  • Other performance-related options There are several options available for tuning network performance, including -gb (database process priority), and -u (buffered disk I/O).

    For more information about startup options, see The database server.


Controlling permissions from the command line

Some options control the permissions required to carry out certain global operations, including permissions to start and stop databases, load and unload data, and create and delete database files.

For more information, see Running the database server in a secure fashion.


Setting a maximum page size

The database server cache is arranged in pages—fixed-size areas of memory. Since the server uses a single cache for its lifetime (until it is shut down), all pages must have the same size.

A database file is also arranged in pages, with a size that is specified on the command line. Every database page must fit into a cache page. By default, the server page size is the same as the largest page size of the databases on the command line. Once the server starts, you cannot start a database with a larger page size than the server.

To allow databases with larger page sizes to be started after startup, you can force the server to start with a specified page size using the –gp option. If you use larger page sizes, remember to increase your cache size. A cache of the same size will accommodate only a fraction of the number of the larger pages, leaving less flexibility in arranging the space.

The following command starts a server that reserves an 8 Mb cache and can accommodate databases of page sizes up to 4096 bytes.

dbsrv9 –gp 4096 –c 8M –n myserver


Running in special modes

You can run Adaptive Server Anywhere in special modes for particular purposes.

  • Read-only You can run databases in read-only mode by supplying the -r option.

    For more information, see -r server option.

  • Bulk load This is useful when loading large quantities of data into a database using the Interactive SQL INPUT command. Do not use the –b option if you are using LOAD TABLE to bulk load data.

    For more information, see -b server option, and Importing and Exporting Data.

  • Starting without a transaction log Use the -f database option for recovery—either to force the database server to start after the transaction log has been lost, or to force the database server to start using a transaction log it would otherwise not find. Note that -f is a database option, not a server option.

    Once the recovery is complete, you should stop your server and restart without the -f option.

    For more information, see The database server.


Controlling threading from the command line

Adaptive Server Anywhere can use multiple operating system threads to handle requests. This allows different requests to run simultaneously on separate CPUs. Each request runs on a single thread and no request is executed concurrently on multiple CPUs.

For a list of options that control threading, see Controlling threading behavior.


Threading in Adaptive Server Anywhere

To understand how threading support works, you need to understand requests and tasks.

Requests

Suppose Adaptive Server Anywhere is being used concurrently by two users, or by two connections from a single application. Each connection submits a query (or other SQL statement) to Adaptive Server Anywhere. Each of these SQL statements is a separate request to the server.

Tasks

A task picks up a request and handles that request until it is complete. On Windows NT/2000/XP, tasks are lightweight threads called fibers; on all other platforms, tasks are threads. The number of tasks determines the number of requests that Adaptive Server Anywhere can handle concurrently.


Tasks on Windows 95/98/Me, NetWare, and UNIX

On Windows 95/98/Me, NetWare, and UNIX machines, each task is an operating system thread. When Adaptive Server Anywhere receives a request, an operating system thread picks up the request. The operating system thread runs until the request is complete.

If the server receives a request while the first request is running, the second request is assigned to a different thread. If a thread is blocked while completing a task, it does not pick up another request; instead, it waits until it can complete the current request.


Tasks on Windows NT/XP/2000

On Windows NT/2000/XP, tasks are lightweight threads called fibers. When Adaptive Server Anywhere receives a request, a fiber picks up the request and runs until the request is complete. If the database server receives another request while the first request is running, the second request is assigned to a different fiber. If a fiber blocks while processing a request, it yields control to another fiber until it can proceed: it does not pick up another request.

Threads host fibers, and the fibers are scheduled co-operatively. A fiber must explicitly yield control to another fiber when it is waiting to process a request, for example, while waiting for an I/O operation to complete. If a fiber blocks and does not yield control, it blocks the thread that is hosting it and prevents other fibers from running on that thread. If more than one thread is hosting fibers, only the thread that is hosting the waiting fiber is blocked: other threads are still free to run fibers.

You can set the number of threads used to run fibers with the -gx option. Unless you are using Java or remote data access, you should need only one thread per CPU.

Setting the number of threads when using Java or remote data access

When you use Java or remote data access and the fiber running Java or remote data access blocks, that fiber may not yield control to another fiber, which in turn blocks the thread. For this reason, the number of operating system threads assigned to the database server defaults to one more thread than the number of CPUs on the machine. This ensures that there is at least one thread available to host fibers if the thread being used by Java or remote data access is blocked. Specifying a higher number of threads than the default by using the -gx option has a minimal impact on performance.


Controlling threading behavior

There are four database server options that control threading behavior. Not all of these options are required on every platform.

  • Number of tasks The -gn option controls the number of tasks used to process requests. Effectively, this is the number of requests that can be handled concurrently. Each request uses a task. When there are more requests than there are tasks, any outstanding requests must wait until a currently-running task completes. By default, there are 20 tasks for the network database server and 10 tasks for the personal database server. There is no benefit to setting a number of tasks that is greater than the maximum number of server connections.

    For more information, see -gn server option.

  • Stack size per internal execution thread You can set the stack size per internal execution thread in the server using the -gss option. The -gss option allows you to lower the memory usage of the database server in environments with limited memory. This option has no effect on Windows operating systems.

    For more information, see -gss server option.

  • Number of processors If you have more than one processor, you can control how many processors the threads exploit by specifying the -gt option. By default, all processors available on the machine are used.

    For more information, see -gt server option.

  • Number of threads assigned to the database server process On Windows NT/2000/XP, the -gx option controls the number of threads that are dedicated to hosting fibers to service requests. By default, this is set to one more than the number of CPUs on the machine. On UNIX, NetWare, and Windows 95/98/Me where each task is its own thread, this option is not needed.

    For more information, see -gx server option.


Selecting communications protocols

Any communication between a client application and a database server requires a communications protocol. Adaptive Server Anywhere supports a set of communications protocols for communications across networks and for same-machine communications.

By default, the database server starts up all available protocols. You can limit the protocols available to a database server using the –x option. On the client side, many of the same options can be controlled using the CommLinks (LINKS) connection parameter.

For more information on running the server using these options, see Supported network protocols.

Available protocols for the personal server

The personal database server (dbeng9.exe) supports the following protocols:

  • Shared memory This protocol is for same-machine communications, and always remains available. It is available on all platforms.

  • TCP/IP This protocol is for same-machine communications only from TDS clients, Open Client, or the jConnect JDBC driver. You must run TCP/IP if you wish to connect from Open Client or jConnect.

    For more information on TDS clients, see Adaptive Server Anywhere as an Open Server.

  • Named Pipes This protocol is provided on Windows NT only. Named Pipes is for same-machine communications for applications that wish to run under a certified security environment.

Available protocols for the network server

The network database server (dbsrv9.exe) supports the following protocols:

  • Shared memory This protocol is for same-machine communications, and always remains available. It is available on all platforms.

  • SPX This protocol is supported on all platforms except for UNIX.

  • TCP/IP This protocol is supported on all platforms.

  • Named Pipes This protocol is supported on Windows NT only. Named Pipes is for same-machine communications for applications that wish to run under a certified security environment.

Specifying protocols

You can instruct a server to use only some of the available network protocols when starting up using the –x option. The following command starts the asademo database using the TCP/IP and SPX protocols:

dbsrv9 –x "tcpip,spx" path\asademo.db

Although not strictly required in this example, the quotes are necessary if there are spaces in any of the arguments to –x.

You can add additional parameters to tune the behavior of the server for each protocol. For example, the following command (typed all on one line) instructs the server to use two network cards, one with a specified port number.

dbsrv9 -x "tcpip{MyIP=192.75.209.12:2367,192.75.209.32}" path\asademo.db

For more information about available network protocol options that can serve as part of the –x option, see Network protocol options.


Stopping the database server

You can stop the database server by:

  • Clicking Shutdown on the database server window.

  • Using the dbstop utility.

    The dbstop utility is particularly useful in batch files, or for stopping a server on another machine. It requires a connection string in its command.

    For more information on dbstop options, see Stopping a database server using the dbstop command-line utility.

  • Letting it shut down automatically by default when the application disconnects. (This only works if the server is a personal server started by an application connection string.)

  • Pressing Q when the server display window has the focus on UNIX or NetWare machines.

Examples
toggle To stop a server using the dbstop utility

  1. Start a server. For example, the following command executed from the Adaptive Server Anywhere installation directory starts a server named Ottawa using the sample database:

    dbsrv9 –n Ottawa asademo.db

  2. Stop the server using dbstop:

    dbstop –c "eng=Ottawa;uid=DBA;pwd=SQL"


Who can stop the server?

When you start a server, you can use the –gk option to set the level of permissions required for users to stop the server with dbstop. The default level of permissions required is DBA, but you can also set the value to all or none. (Interactively, of course, anybody at the machine can click Shutdown on the server window.)


Shutting down operating system sessions

If you close an operating system session where a database server is running, or if you use an operating system command to stop the database server, the server shuts down, but not cleanly. The next time the database loads, recovery is required, and happens automatically.

For more information about recovery, see Backup and Data Recovery.

It is better to stop the database server explicitly before closing the operating system session. On NetWare, however, shutting down the NetWare server machine properly does stop the database server cleanly.

Examples of commands that will not stop a server cleanly include:

  • Stopping the process in the Windows Task Manager.

  • Using a UNIX slay or kill command.


Starting and stopping databases

A database server can have more than one database loaded at a time. You can start databases and start the server at the same time, as follows:

dbeng9 asademo sample
Caution The database file must be on the same machine as the database server. Managing a database file that is located on a network drive can lead to file corruption.
Starting a database on a running server

You can also start databases after starting a server in one of the following ways:

  • Connect to a database using a DatabaseFile (DBF) connection parameter while connected to a server. The DatabaseFile (DBF) connection parameter specifies a database file for a new connection. The database file is started on the current server.

    For more information, see Connecting to an embedded database, or DatabaseFile connection parameter [DBF].

  • Use the START DATABASE statement, or choose Start Database from the File menu in Sybase Central when you have a server selected.

    For more information, see START DATABASE statement [Interactive SQL].

Limitations

  • The server holds database information in memory using pages of a fixed size. Once a server has been started, you cannot start a database that has a larger page size than the server.

  • The -gd server option decides the permissions required to start databases.

Stopping a database

You can stop a database by:

  • Disconnecting from a database started by a connection string. Unless you explicitly set the AutoStop (ASTOP) connection parameter to NO, this happens automatically.

    For more information, see AutoStop connection parameter [ASTOP].

  • Using the STOP DATABASE statement from Interactive SQL or embedded SQL.

    For more information, see STOP DATABASE statement.


Running the server outside the current session

When you log on to a computer using a user ID and a password, you establish a session. When you start a database server, or any other application, it runs within that session. When you log off the computer, all applications associated with the session terminate.

It is common to require database servers to be available all the time. To make this easier, you can run Adaptive Server Anywhere for Windows NT/2000/XP and for UNIX in such a way that, when you log off the computer, the database server remains running. The way you do this depends on your operating system.

  • UNIX daemon You can run the UNIX database server as a daemon using the -ud option, enabling the database server to run in the background, and to continue running after you log off.

    For more information, see Running the UNIX database server as a daemon.

  • Windows service You can run the Windows database server as a service. This has many convenient properties for running high availability servers.

    For more information, see Understanding Windows services.

Running the UNIX database server as a daemon
Understanding Windows services
Programs that can be run as Windows services
Managing services
Adding a service
Removing a service
Configuring services
Setting the service polling frequency
Starting, stopping, and pausing services
The Windows Service Manager
Running more than one service


Running the UNIX database server as a daemon

To run the UNIX database server in the background, and to enable it to run independently of the current session, you run it as a daemon.

Do not use '&' to run the database server in the background
If you use the UNIX & (ampersand) command to run the database server in the background, it will not work—the server will hang. You must instead run the database server as a daemon.

As well, attempting to start a server in the background from within a program using the typical fork()-exec() sequence will not work.

You can run the UNIX database server as a daemon in one of the following ways:

  1. Use the -ud option when starting the database server. For example:

    dbsrv9 -ud asademo

  2. Use the dbspawn tool to start the database server, for example:

    dbspawn dbsrv9 asademo

    One advantage of using dbspawn is that the dbspawn process does not terminate until it has confirmed that the daemon has started and is ready to accept requests. If for any reason the daemon fails to start, the exit code for dbspawn will be non-zero.

    When you start the daemon directly using the -ud option, the dbeng9 and dbsrv9 commands create the daemon process and return immediately (exiting and allowing the next command to be executed) before the daemon initializes itself or attempts to open any of the databases specified in the command.

    Using dbspawn can be useful when writing a script or other automated process that needs to start a server as a daemon prior to running one or more applications that will user the server because you want to ensure that the daemon is running before starting the applications. The following is an example of how to test this using a csh script.

    #!/bin/csh
# start the server as a daemon and ensure that it is
running before we start any applications
dbspawn dbsrv9 asademo
if ( $status != 0 ) then
   echo Failed to start asademo server
   exit
endif
# ok, now we can start the applications
...

    This example uses an sh script to test whether the daemon is running before starting the applications.

    #!/bin/sh
# start the server as a daemon and ensure that it is
running before we start any applications
dbspawn dbsrv9 asademo
if [ $? != 0 ]; then
   echo Failed to start asademo server
   exit
fi
# ok, now we can start the applications
...

  3. Spawn a daemon from within a C program, for example:

    ...
if( fork() == 0 ) {
      /* child process = start server daemon */
      execl( "/opt/sybase/SYBSsa9/bin/dbsrv9",
"dbsrv9", "-ud", "asademo" );
   exit(1);
}
/* parent process */
...

    Note that the -ud option is used.

For more information, see -ud server option and The Spawn utility.


Understanding Windows services

Although you can run the database server like any other Windows NT/2000/XP program rather than as a service, there are limitations to running it as a standard program, particularly in multi-user environments.

Limitations of running as a standard executable

When you start a program, it runs under your Windows NT/2000/XP login session, which means that if you log off the computer, the program terminates. Only one person logs onto Windows NT/2000/XP (on any one computer) at one time. This restricts the use of the computer if you wish to keep a program running much of the time, as is commonly the case with database servers. You must stay logged onto the computer running the database server for the database server to keep running. This can also present a security risk as the Windows NT/2000/XP computer must be left in a logged on state.

Advantages of services

Installing an application as a Windows service enables it to run even when you log off.

When you start a service, it logs on using a special system account called LocalSystem (or another account that you specify). Since the service is not tied to the user ID of the person starting it, the service remains open even when the person who started it logs off. You can also configure a service to start automatically when the Windows computer starts, before a user logs on.

Managing services

Sybase Central provides a more convenient and comprehensive way of managing Adaptive Server Anywhere services than the Windows services manager.


Programs that can be run as Windows services

You can run the following programs as services:

  • Network database server (dbsrv9.exe)

  • Personal database server (dbeng9.exe)

  • SQL Remote Message Agent (dbremote.exe)

  • The MobiLink synchronization server (dbmlsrv9.exe)

  • A sample application

Not all these applications are supplied in all editions of Adaptive Server Anywhere.


Managing services

You can carry out the following service management tasks from the command line, or on the Services tab in Sybase Central:

  • Add, edit, and remove services.

  • Start, stop, and pause services.

  • Modify the parameters governing a service.

  • Add databases to a service so you can run several databases at one time.

The service icons in Sybase Central display the current state of each service using a traffic light icon (running, paused, or stopped).

Sybase Central main window, showing a stopped service. The stopped status is indicated by a red traffic light icon.


Adding a service

This section describes how to set up services using Sybase Central and the Service Creation utility.

toggle To add a new service (Sybase Central)

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Services tab.

  3. From the File menu, choose New > Service.

  4. Follow the instructions in the wizard.

toggle To add a new service (Command line)

  1. Open a command prompt.

  2. Execute the Service Creation utility using the -w option.

    For example, to create a personal server service called myserv, which starts the specified server with the specified parameters type the following. The server runs as the LocalSystem user, enter the following command, all on one line:

    dbsvc -as -w myserv "C:\Program Files\Sybase\SQL Anywhere 9\win32\dbeng9.exe" -n william -c 8m "C:\Program Files\Sybase\SQL Anywhere 9\sample.db"

For more information about the Service Creation utility and options, see The Service Creation utility.

Notes

  • Service names must be unique within the first eight characters.

  • If you choose to start a service automatically, it starts whenever the computer starts Windows. If you choose to start the service manually, you need to start the service from Sybase Central each time. You may want to select Disabled if you are setting up a service for future use.

  • Type options for the executable, without the executable name itself, in the window. For example, if you want a network server to run using the sample database with a cache size of 20 Mb and the name myserver, you would type the following in the Parameters box of the Service Creation wizard in Sybase Central:

    -c 20M
-n myserver c:\Program Files\Sybase\SQL Anywhere 9\asademo.db

    Line breaks are optional.

    For information on valid options, see the description of each program in Database Administration Utilities.

  • Choose the account under which the service will run: the special LocalSystem account or another user ID.

    For more information about this choice, see Setting the account options.

  • If you want the service to be accessible from the Windows desktop, check Allow Service to Interact with Desktop. If this option is cleared, no icon appears in the System Tray and neither do any windows appear on the desktop.

For more information on the configuration options, see Configuring services.


Removing a service

Removing a service removes the server name from the list of services. Removing a service does not remove any software from your hard disk.

If you wish to re-install a service you previously removed, you need to re-type the options.

toggle To remove a service (Sybase Central)

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

    In the right pane, click the Services tab.

  2. In the right pane, select the service you want to remove and from the File menu, choose Delete.

toggle To remove a service (Command line)

  1. Open a command prompt.

  2. Execute the Service Creation utility using the -d option.

    For example, to delete the service called myserv, without prompting for confirmation, type the following command:

    dbsvc -y -d myserv

For more information about the Service Creation utility and options, see The Service Creation utility.


Configuring services

A service runs a database server or other application with a set of options.

For a full description of the options for each of the administration utilities, see Database Administration Utilities.

In addition to the options, services accept other parameters that specify the account under which the service runs and the conditions under which it starts.

toggle To change the parameters for a service

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, select the service you want to change.

  3. From the File menu, choose Properties.

  4. Alter the parameters as needed on the tabs of the Service property sheet.

  5. Click OK when finished.

Changes to a service configuration take effect the next time someone starts the service. The Startup option is applied the next time Windows is started.


Setting the startup option

The following options govern startup behavior for Adaptive Server Anywhere services. You can set them on the General tab of the Service property sheet.

  • Automatic If you choose the Automatic setting, the service starts whenever the Windows operating system starts. This setting is appropriate for database servers and other applications running all the time.

  • Manual If you choose the Manual setting, the service starts only when a user with Administrator permissions starts it. For information about Administrator permissions, see your Windows documentation.

  • Disabled If you choose the Disabled setting, the service will not start.


Specifying options

The Configuration tab of the Service property sheet provides a Parameters text box for specifying options for a service. Do not type the name of the program executable in this box.

Examples

  • To start a network server service named my_server running two databases, with a cache size of 20 Mb, you would type the following in the Parameters box:

    -c 20M
-n my_server
c:\Program Files\Sybase\SQL Anywhere 9\db_1.db
c:\Program Files\Sybase\SQL Anywhere 9\db_2.db

  • To start a SQL Remote Message Agent service connecting to the sample database as user ID DBA, you would type the following:

    -c "uid=DBA;pwd=SQL;dbn=asademo"

The following figure illustrates a sample Service property sheet.

Configuration tab of the Service property sheet, showing the file name and parameters for the executable the service runs.

The options for a service are the same as those for the executable. For a full description of the options for each program, see The Database Server.


Setting the account options

You can choose under which account the service runs. Most services run under the special LocalSystem account, which is the default option for services. You can set the service to log on under another account by opening the Account tab on the Service property sheet, and typing the account information.

If you choose to run the service under an account other than LocalSystem, that account must have the Log On As A Service privilege. This can be granted from the Windows User Manager application under Advanced Privileges.

When an icon appears in the System Tray

Whether or not an icon for the service appears in the System Tray or desktop depends on the account you select, and whether Allow Service to Interact with Desktop is selected, as follows:

  • If a service runs under LocalSystem, and Allow Service to Interact with Desktop is selected on the Service property sheet, an icon appears on the desktop of every user logged in to Windows on the computer running the service. Consequently, any user can open the application window and stop the program running as a service.

  • If a service runs under LocalSystem, and Allow Service to Interact with Desktop is cleared on the Service property sheet, no icon appears on the desktop for any user. Only users with permissions to change the state of services can stop the service.

  • If a service runs under another account, no icon appears on the desktop. Only users with permissions to change the state of services can stop the service.


Changing the executable file

To change the program executable file associated with a service, click the Configuration tab on the Service property sheet and type the new path and file name in the File Name text box.

If you move an executable file to a new directory, you must modify this entry.


Adding new databases to a service

Each network server or personal server can run more than one database. If you wish to run more than one database at a time, we recommend that you do so by attaching new databases to your existing service, rather than by creating new services.

toggle To add a new database to an existing service

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Services tab.

  3. Select the service and then from the File menu, choose Properties.

  4. Click the Configuration tab.

  5. Add the path and filename of the new database to the end of the list of options in the Parameters box.

  6. Click OK to save the changes.

    The new database starts the next time the service starts.

Databases can be started on running servers by client applications, such as Interactive SQL.

For more information about how to start a database on a server from Interactive SQL, see START DATABASE statement [Interactive SQL].

For more information about how to implement this function in an embedded SQL application, see db_start_database function.

Starting a database from an application does not attach it to the service. If the service is stopped and restarted, the additional database will not be started automatically.


Setting the service polling frequency

Sybase Central can poll at specified intervals to check the state (started, stopped, or paused) of each service, and update the icons to display the current state. By default, polling is off. If you leave it off, you must click Refresh Folder to see changes to the state.

toggle To set the Sybase Central polling frequency

  1. In the left pane, click the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Services tab.

  3. Select the service and then from the File menu, choose Properties.

  4. Click the Polling tab.

  5. Select Enable Polling.

  6. Set the polling frequency.

    The frequency applies to all services, not just the one selected. The value you set in this window remains in effect for subsequent sessions, until you change it.

  7. Click OK.


Starting, stopping, and pausing services

toggle To start, stop, or pause a service

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Services tab.

  3. Select the service and then from the File menu, choose Start, Stop, or Pause.

    To resume a paused service, choose Continue from the popup menu.

If you start a service, it keeps running until you stop it. Closing Sybase Central or logging off does not stop the service.

Stopping a service closes all connections to the database and stops the database server. For other applications, the program shuts down.

Pausing a service prevents any further action being taken by the application. It does not shut the application down or (in the case of database server services) close any client connections to the database. Most users do not need to pause their services.


The Windows Service Manager

You can use Sybase Central to carry out all the service management for Adaptive Server Anywhere. Although you can use the Windows NT Service Manager in the Control Panel for some tasks, you cannot install or configure an Adaptive Server Anywhere service from the Windows NT Service Manager.

If you open the Windows Service Manager (from the Windows Control Panel), a list of services appears. The names of the Adaptive Server Anywhere services are formed from the Service Name you provided when installing the service, prefixed by Adaptive Server Anywhere. All the installed services appear together in the list.


Web Links Browse Collapse Expand PDF Previous Next

ASA Database Administration Guide

Running the Database Server

Running the server outside the current session

Running more than one service

This section describes some topics specific to running more than one service at a time.


Service dependencies

In some circumstances you may wish to run more than one executable as a service, and these executables may depend on each other. For example, you may wish to run a server and a SQL Remote Message Agent or Log Transfer Manager to assist in replication.

In cases such as these, the services must start in the proper order. If a SQL Remote Message Agent service starts up before the server has started, it fails because it cannot find the server.

You can prevent these problems by using service groups, which you manage from Sybase Central.


Service groups overview

You can assign each service on your system to be a member of a service group. By default, each service belongs to a group, as listed in the following table.

Service | Default group
Network server | ASANYServer
Personal server | ASANYEngine
SQL Remote Message Agent | ASANYRemote
MobiLink synchronization server | ASANYMobiLink
Replication Agent | ASANYLTM

Before you can configure your services to ensure that they start in the correct order, you must check that your service is a member of an appropriate group. You can check which group a service belongs to, and change this group, from Sybase Central.

toggle To check and change which group a service belongs to

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Services tab.

  3. Select the service and then from the File menu, choose Properties.

  4. Click the Dependencies tab. The top text box displays the name of the group the service belongs to.

  5. Click Change to display a list of available groups on your system.

  6. Select one of the groups, or type a name for a new group.

  7. Click OK to assign the service to that group.


Managing service dependencies

With Sybase Central you can specify dependencies for a service. For example:

  • You can ensure that at least one member of each of a list of service groups has started before the current service.

  • You can ensure that any number of services start before the current service. For example, you may want to ensure that a particular network server has started before a SQL Remote Message Agent that is to run against that server starts.

toggle To add a service or group to a list of dependencies

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. Right-click the service and choose Properties from the popup menu.

  3. Click the Dependencies tab.

  4. Click Add Services or Add Service Groups to add a service or group to the list of dependencies.

  5. Select one of the services or groups from the list.

  6. Click OK to add the service or group to the list of dependencies.


Troubleshooting server startup

This section describes some common problems that may occur when starting the database server.

Ensure that your transaction log file is valid
Ensure that you have sufficient disk space for your temporary file
Ensure that network communication software is running
Debugging network communications startup problems
Make sure you're using the right asasrv.ini file
Create a debug log file


Ensure that your transaction log file is valid

The server won't start if the existing transaction log is invalid. For example, during development you may replace a database file with a new version, without deleting the transaction log at the same time. This causes the transaction log file to be different than the database, and results in an invalid transaction log file.


Ensure that you have sufficient disk space for your temporary file

Adaptive Server Anywhere uses a temporary file to store information while running. This file is usually stored in the directory pointed to by the ASTMP environment variable, typically c:\temp.

If you do not have sufficient disk space available to the temporary directory, you will have problems starting the server.

For more information, see ASTMP environment variable.


Ensure that network communication software is running

Appropriate network communication software must be installed and running before you run the database server. If you are running reliable network software with just one network installed, this should be straightforward.

If you experience problems, if you are running non-standard software, or if you are running multiple networks, you may want to read the full discussion of network communication issues in Client/Server Communications.

You should confirm that other software requiring network communications is working properly before running the database server.

If you are running under the TCP/IP protocol, you may want to confirm that ping and Telnet are working properly. The ping and Telnet applications are provided with many TCP/IP protocol stacks.


Debugging network communications startup problems

If you are having problems establishing a connection across a network, you can use debugging options at both the client and the server to diagnose problems. On the server, you use the -z option. The startup information appears on the database server window: you can use the -o option to log the results to an output file.

For more information, see -z server option and -o server option.


Make sure you're using the right asasrv.ini file

If you are having problems establishing a connection to the correct server across a network, try deleting the asasrv.ini file. This file contains server information, including server name, protocol, and address. It is possible that the server information in this file is overriding information you specified in the connection string. Deleting this file causes Adaptive Server Anywhere to create a new asasrv.ini file containing the information you specify in the connection string. The asasrv.ini file should be located in your Adaptive Server Anywhere executable directory (the same directory as the ODBC/DBLib DLL).

If you continue to experience problems establishing a connection, you should also delete any copy of asasrv.ini located in any of the following places:

  • the win32 or win64 subdirectory of your SQL Anywhere installation directory (you can find this in the directory listed in the HKEY_LOCAL_MACHINE\SOFTWARE\Sybase\Adaptive Server Anywhere\9.0\Location registry key)

  • Windows directory

  • Windows system directory

  • anywhere else in your path

For more information about the asasrv.ini file, see .Server name caching for faster connections.


Create a debug log file

You can use the LogFile connection parameter to create a debug log file. Log files can provide more detailed information about where a connection failure occurred, thereby helping you troubleshoot and correct the problem.

For more information about log files, see Logfile connection parameter [LOG].


Connecting to a Database

About this chapter

This chapter describes how client applications connect to databases. It contains information about connecting to databases from ODBC, OLE DB, ADO.NET, iAnywhere JDBC driver, and embedded SQL applications. It also describes connecting from Sybase Central and Interactive SQL.

For more information on connecting to a database from Sybase Open Client applications, see Adaptive Server Anywhere as an Open Server.

For more information on connecting via JDBC (if you are not working in Sybase Central or Interactive SQL), see JDBC Programming.

Introduction to connections
Connecting from Sybase Central or Interactive SQL
Simple connection examples
Working with ODBC data sources
Connecting from desktop applications to a Windows CE database
Connecting to a database using OLE DB
Connection parameter tips
Troubleshooting connections
Using integrated logins


Introduction to connections

Any client application that uses a database must establish a connection to that database before any work can be done. The connection forms a channel through which all activity from the client application takes place. For example, your user ID determines permissions to carry out actions on the database—and the database server has your user ID because it is part of the request to establish a connection.

When a user connects to a database, the database server assigns the connection a unique connection ID. For each new connection to the database server, the server increments the connection ID value by 1. These connection IDs are logged in the -z server output and the client LOGFILE connection parameter output. The connection ID can be used to filter request logging information, identify which connection has a lock on the database, or track the total number of connections to a server since it started and the order in which those connections were made.

For information about request logging, see Request logging.

For information about locks, see How locking works.

How connections are established

To establish a connection, the client application calls functions in one of the Adaptive Server Anywhere interfaces. Adaptive Server Anywhere provides the following interfaces:

  • ODBC ODBC connections are discussed in this chapter.

  • ADO.NET ADO.NET connections are discussed in this chapter.

    For more information about ADO.NET connections, see The ADO.NET programming interface.

  • Sybase Open Client Open Client connections are not discussed in this chapter.

    For information on connecting from Open Client applications, see Adaptive Server Anywhere as an Open Server.

  • jConnect JDBC driver Sybase Central and Interactive SQL have the connection logic described in this chapter built into them. Other applications using jCOnnect cannot use the connection logic discussed in this chapter.

    For more information on connecting via JDBC, see JDBC Programming.

The interface uses connection information included in the call from the client application, perhaps together with information held in a data source, the SQLCONNECT environment variable, or the server address cache, to locate and connect to a server running the required database. The following figure is a simplified representation of the pieces involved.

A client connection to a database, showing the client application, the interface library, and the database server running the database.
What to read

The following table identifies where you can find answers to questions.

If you want... | Consider reading...
An overview of connecting from Sybase Central or Interactive SQL (including a description of the drivers involved) | Connecting from Sybase Central or Interactive SQL
Some examples to get started quickly, including Sybase Central and Interactive SQL scenarios | Simple connection examples
To learn about data sources | Working with ODBC data sources
To learn what connection parameters are available | Connection parameters
To see an in-depth description of how connections are established | Troubleshooting connections
To learn about network-specific connection issues | Client/Server Communications
To learn about character set issues affecting connections | Connection strings and character sets


How connection parameters work

When an application connects to a database, it uses a set of connection parameters to define the connection. Connection parameters include information such as the server name, the database name, and a user ID.

A keyword-value pair (of the form parameter=value) specifies each connection parameter. For example, you specify the password connection parameter for the default password as follows:

Password=SQL

Connection parameters are assembled into connection strings. In a connection string, a semicolon separates each connection parameter, as follows:

ServerName=asademo9;DatabaseName=asademo

There are a number of connection parameters that affect how a server is started. It is recommended that you use the following connection parameters instead of providing the corresponding server options within the StartLine (START) connection parameter:

  • EngineName (ENG)

  • DatabaseFile (DBF)

  • DatabaseSwitches (DBS)

  • DatabaseName (DBN)

Representing connection strings

This chapter has many examples of connection strings represented in the following form:

parameter1=value1
parameter2=value2
...

This is equivalent to the following connection string:

parameter1=value1;parameter2=value2

You must type a connection string on a single line with the parameter settings separated by semicolons.


Connection parameters passed as connection strings

Connection parameters are passed to the interface library as a connection string. This string consists of a set of parameters, separated by semicolons:

parameter1=value1;parameter2=value2;...

In general, the connection string built by an application and passed to the interface library does not correspond directly to the way a user enters the information. Instead, a user may fill in a dialog, or the application may read connection information from an initialization file.

Many of the Adaptive Server Anywhere utilities accept a connection string as the -c option and pass the connection string on to the interface library without change. For example, the following is a typical Collation utility (dbcollat) command line (which should be typed all on one line):

dbcollat –c "uid=DBA;pwd=SQL;dbn=asademo" c:\temp\asademo.col


Saving connection parameters in ODBC data sources

Many client applications, including application development systems, use the ODBC interface to access Adaptive Server Anywhere. When connecting to the database, ODBC applications typically use ODBC data sources. An ODBC data source is a set of connection parameters, stored in the registry or in a file.

For more information on ODBC data sources, see Working with ODBC data sources.

For Adaptive Server Anywhere, ODBC data sources can be used by all client interfaces, except Open Client and jConnect. On UNIX and Windows CE, the data source is stored in a file. ODBC data sources cannot be used on NetWare.

Interactive SQL, Sybase Central, and the Adaptive Server Anywhere Console utility (dbconsole) can use ODBC data sources, even when connecting over jConnect.


Connecting from Sybase Central or Interactive SQL

To use Sybase Central or Interactive SQL for managing your database, you must first connect to it. In the Connect dialog, you tell Sybase Central or Interactive SQL what database you want to connect to, where it is located, and how you want to connect to it.

The connection process depends on your situation. For example, if you have a server already running on your machine and this server contains only one database, all you have to do in the Connect dialog is provide a user ID and a password for that database. Sybase Central or Interactive SQL then knows to connect immediately to the database on the running server.

If this running server has more than one database loaded on it, if it is not yet running, or if it is running on another machine, you need to provide more detailed information in the Connect dialog so that Sybase Central or Interactive SQL knows which database to connect to.

This section describes how to access the Connect dialog in Sybase Central and Interactive SQL.

For more information about connection examples, including examples for Sybase Central and Interactive SQL, see Simple connection examples.


Opening the Connect dialog

A common Connect dialog is available in both Sybase Central and Interactive SQL to let you connect to a database.

When you start Sybase Central, you need to manually display this dialog. When you start Interactive SQL, the dialog automatically appears; you can also make it appear by choosing SQL > Connect.

toggle To open the Connect dialog (Sybase Central)

  • In Sybase Central, choose Tools > Connect.

    If you have more than one Sybase Central plug-in installed, choose Adaptive Server Anywhere 9 from the list.

    You can also click the Connect button on the main toolbar or press F11 to open the Connect dialog.

Tip
You can make subsequent connections to a given database easier and faster using a connection profile.
toggle To open the Connect dialog (Interactive SQL)

  • In Interactive SQL, choose SQL > Connect.

    Alternatively, you can press F11 to open the Connect dialog.

Once the Connect dialog appears, you must specify the connection parameters you need to connect. For example, you can connect to the Adaptive Server Anywhere sample database by choosing ASA 9.0 Sample from the ODBC Data Source Name list on the Identification tab and then clicking OK.


Specifying a driver for your connection

When you are working with a database, all your requests and commands go through a driver to the database itself. Sybase Central and Interactive SQL support two main JDBC drivers: jConnect and the iAnywhere JDBC driver. Both are included with Adaptive Server Anywhere.

The iAnywhere JDBC driver

The iAnywhere JDBC driver is, in many cases, the preferred driver. It is the default driver for Interactive SQL and Sybase Central. Sybase jConnect is a platform-independent JDBC driver.

When you connect to a database in the Connect dialog, you can choose which driver you want to use for the connection on the Advanced tab. This is an optional configuration; the iAnywhere JDBC driver is the preferred driver and is automatically used for all connections unless you specify otherwise.

For more information on JDBC drivers, see Choosing a JDBC driver, Using the jConnect JDBC driver, and Working with ODBC data sources.

Data sources and the jConnect driver

As a general rule, the jConnect driver cannot use ODBC data sources. However, Sybase Central and Interactive SQL are special cases. When you use the jConnect driver in either of them, you can specify an ODBC data source to establish a connection. For example, you can connect to the sample database using the ASA 9.0 Sample data source, even if you are using the jConnect driver.

This customized functionality is only available while you are working in Sybase Central or Interactive SQL. If you are constructing a JDBC application using jConnect, do not try to use an ODBC data source to connect to a database.

toggle To specify a driver for the connection (Sybase Central)

  1. In Sybase Central, choose Tools > Connect to open the Connect dialog.

  2. Configure the necessary settings on the Identification and Database tabs of the dialog.

  3. On the Advanced tab of the dialog, select either jConnect 5 or iAnywhere JDBC driver.


Working with the Connect dialog

The Connect dialog lets you define parameters for connecting to a server or database. The same dialog is used in both Sybase Central and Interactive SQL. The information entered in the Connect dialog is not preserved between sessions.

The Connect dialog has the following tabs:

  • The Identification tab lets you identify yourself to the database and specify a data source.

  • The Database tab lets you identify a server and/or database to connect to.

  • The Advanced tab lets you add additional connection parameters and specify a driver for the connection.

After you connect successfully in Sybase Central, the database name appears in the left pane of the main window, under the server that it is running on. The user ID for the connection appears after the database name.

In Interactive SQL, the connection information (including the database name, your user ID, and the database server) appears in the title bar above the SQL Statements pane.


Simple connection examples

Although the connection model for Adaptive Server Anywhere is configurable, and can become complex, in many cases connecting to a database is very simple.

Who should read this section?

This section describes some simple cases of applications connecting to an Adaptive Server Anywhere database. This section may be all you need to get started.

For more information about available connection parameters and their use, see Connection parameters.

Connecting to the sample database from Sybase Central or Interactive SQL
Connecting to a database on your own machine from Sybase Central or Interactive SQL
Connecting to an embedded database
Connecting using a data source
Connecting to a server on a network
Using default connection parameters
Connecting from Adaptive Server Anywhere utilities


Connecting to the sample database from Sybase Central or Interactive SQL

Many examples and exercises throughout the documentation start by connecting to the sample database from Sybase Central or Interactive SQL.

toggle To connect to the sample database (Sybase Central)

  1. Start Sybase Central: from the Start menu, choose Programs > Sybase SQL Anywhere 9 > Sybase Central.

  2. Open the Connect dialog: from the Tools menu, choose Connect.

  3. Select the ODBC Data Source Name option and click Browse.

  4. Select ASA 9.0 Sample and click OK.

toggle To connect to the sample database (Interactive SQL)

  1. Start Interactive SQL: from the Start menu, choose Programs > Sybase > SQL Anywhere 9 > Adaptive Server Anywhere > Interactive SQL.

  2. Open the Connect dialog: from the SQL menu, choose Connect.

  3. Select the ODBC Data Source Name option and click Browse.

  4. Select ASA 9.0 Sample and click OK.

    The database name, user ID, and server name appear in the title bar above the SQL Statements pane.

Note

You do not need to type a user ID and a password for this connection because the data source already contains this information.


Connecting to a database on your own machine from Sybase Central or Interactive SQL

The simplest connection scenario is when the database you want to connect to resides on your own machine. If this is the case for you, ask yourself the following questions:

  • Is the database already running on a server? If not, you need to identify the database file so that Sybase Central or Interactive SQL can start it for you. If so, you can specify fewer parameters in the Connect dialog.

  • Are there multiple databases running on your machine? If there is only one, Sybase Central or Interactive SQL assumes that it is the one you want to connect to, and you don't need to specify it in the Connect dialog. If so, you need to tell Sybase Central or Interactive SQL which database in particular to connect to.

The procedures below depend on your answers to these questions.

toggle To connect to a database on an already-running local server

  1. Start Sybase Central or Interactive SQL and open the Connect dialog (if it doesn't appear automatically).

  2. On the Identification tab of the dialog, type a user ID and a password for the currently-running database.

  3. Do one of the following:

    • If the server only contains the one database, click OK to connect to it.

    • If the server contains multiple databases, click the Database tab of the dialog and specify a database name. This is usually the database file name, without the path or extension.

toggle To start and connect to a database

  1. Start Sybase Central or Interactive SQL and open the Connect dialog (if it doesn't appear automatically).

  2. On the Identification tab of the dialog, type a user ID and a password.

  3. Click the Database tab.

  4. Specify a file in the Database File field (including the full path, name, and extension). You can search for a file by clicking Browse.

  5. If you want the database name for subsequent connections to be different from the file name, type a name in the Database Name field (without including a path or extension).

Tips
If the database is already loaded (started) on the server, you only need to provide a database name for a successful connection. The database file is not necessary.

You can connect using a data source (a stored set of connection parameters) for either of the above scenarios by selecting the appropriate data source option at the bottom of the Identification tab of the Connect dialog.

For information about using data sources in conjunction with the jConnect JDBC driver, see Specifying a driver for your connection.

See also
  • Simple connection examples


Connecting to an embedded database

An embedded database, designed for use by a single application, runs on the same machine as the application and is largely hidden from the application's user.

When an application uses an embedded database, the personal server is generally not running when the application connects. In this case, you can start the database using the connection string, and by specifying the database file in the DatabaseFile (DBF) parameter of the connection string.

Using the DBF parameter

The DatabaseFile (DBF) parameter specifies which database file to use. The database file automatically loads onto the default server, or starts a server if none are running.

The database unloads when there are no more connections to the database (generally when the application that started the connection disconnects). If the connection started the server, it stops once the database unloads.

The following connection parameters show how to load the sample database as an embedded database:

dbf=path\asademo.db
uid=DBA
pwd=SQL

where path is the name of your Adaptive Server Anywhere installation directory.

Using the StartLine [Start] parameter

The following connection parameters show how you can customize the startup of the sample database as an embedded database. This is useful if you wish to use options, such as the cache size:

Start=dbeng9 -c 8M
dbf=path\asademo.db
uid=DBA
pwd=SQL
See also
  • Opening the Connect dialog
  • Simple connection examples


Connecting using a data source

You can save sets of connection parameters in a data source. All Adaptive Server Anywhere interfaces, except Open Client and jConnect, can use data sources. The only exception is that Sybase Central, Interactive SQL, and the Adaptive Server Anywhere Console utility (dbconsole) can use data sources when connecting using jConnect.

For more information, see Specifying a driver for your connection.

toggle To connect from using a data source (Sybase Central or Interactive SQL)

  1. Start Sybase Central or Interactive SQL and open the Connect dialog (if it doesn't appear automatically).

  2. On the Identification tab, type a user ID and password.

  3. On the lower half of the Identification tab, do one of the following:

    • Select the ODBC Data Source Name option and specify a data source name (equivalent to the DataSourceName (DSN) connection parameter, which references a data source in the Windows registry). You can view a list of data sources by clicking Browse.

    • Select the ODBC Data Source File option and specify a data source file (equivalent to the FileDataSourceName (FILEDSN) connection parameter, which references a data source held in a file). You can search for a file by clicking Browse.

The ASA 9.0 Sample data source holds a set of connection parameters, including the database file and a StartLine (START) parameter to start the database.

See also
  • Opening the Connect dialog
  • Simple connection examples


Connecting to a server on a network

To connect to a database running on a network server somewhere on a local or wide area network, the client software must locate and connect to the database server. Adaptive Server Anywhere provides a network library to handle this task.

Network connections occur over a network protocol. TCP/IP is available on all platforms, and SPX is available on some platforms.

For more information about client/server communications over a network, see Client/Server Communications.

A client connection to a network database server, showing the client using an Interface library to connect to a server running on the network.
Specifying the server

Adaptive Server Anywhere server names must be unique on a local domain for a given network protocol. The following connection parameters provide a simple example for connecting to a server running elsewhere on a network:

eng=svr_name
dbn=db_name
uid=user_id
pwd=password
CommLinks=all

When CommLinks=all is specified, the client library first looks for a personal server of the given name, and then looks on the network for a server of the given name.

For information, see CommLinks connection parameter [LINKS].

Specifying the protocol

If several protocols are available, you can instruct the network library which ones to use to improve performance. The following parameters use only the TCP/IP protocol:

eng=svr_name
dbn=db_name
uid=user_id
pwd=password
CommLinks=tcpip

The network library searches for a server by broadcasting over the network, which can be a time-consuming process. Once the network library locates a server, the client library stores its name and network address in a file (asasrv.ini), and reuses this entry for subsequent connection attempts to that server using the specified protocol. Subsequent connections are normally faster than a connection achieved by broadcast.

Many other connection parameters are available to assist Adaptive Server Anywhere in locating a server efficiently over a network.

For more information, see Network protocol options.

For more information, see Connecting across a firewall.

toggle To connect to a database on a network server ( Sybase Central or Interactive SQL )

  1. Start Sybase Central or Interactive SQL and open the Connect dialog (if it does not appear automatically).

  2. On the Identification tab of the dialog, type a user ID and a password.

  3. On the Database tab of the dialog, type the Server Name. You can search for a server by selecting the Search Network for Database Servers option and then clicking Find.

  4. Identify the database by specifying a Database Name.

Tips
You can connect using a data source (a stored set of connection parameters) by selecting the appropriate data source option at the bottom of the Identification tab of the Connect dialog.

For information about using data sources in conjunction with the jConnect JDBC driver, see Specifying a driver for your connection.

By default, all network connections in Sybase Central and Interactive SQL use the TCP/IP network protocol.

See also
  • Opening the Connect dialog
  • Simple connection examples


Using default connection parameters

You can leave many connection parameters unspecified, and instead use the default behavior to make a connection. Be cautious about relying on default behavior in production environments, especially if you distribute your application to customers who may install other Adaptive Server Anywhere applications on their machine.

Default database server and database

If a single personal server is running, with a single loaded database, you can connect using entirely default parameters:

uid=user_id
pwd=password
Default database server

If more than one database is loaded on a single personal server, you can leave the server as a default, but you need to specify the database you wish to connect to:

dbn=db_name
uid=user_id
pwd=password
Default database

If more than one server is running, you need to specify which server you wish to connect to. If only one database is loaded on that server, you do not need to specify the database name. The following connection string connects to a named server, using the default database:

eng=server_name
uid=user_id
pwd=password
No defaults for a local server

The following connection string connects to a named local server, using a named database:

eng=server_name
dbn=db_name
uid=user_id
pwd=password

For more information about default behavior, see Troubleshooting connections.

No defaults for a network server

To connect to a network server running on a different machine:

eng=server_name
dbn=dbn
uid=user_id
pwd=password
CommLinks=tcpip

If CommLinks is not specified, only local shared memory connections are attempted.

If you are connecting from Sybase Central, Interactive SQL, or the Adaptive Server Anywhere Console utility (dbconsole), you can select the Search Network for Database Servers option on the Connect dialog to attempt a network connection.

For more information about default behavior, see Troubleshooting connections.


Connecting from Adaptive Server Anywhere utilities

All Adaptive Server Anywhere database utilities that communicate with the server (rather than acting directly on database files) do so using embedded SQL. They follow the procedure outlined in Troubleshooting connections when connecting to a database.

How database tools obtain connection parameter values

Many of the administration utilities obtain the connection parameter values by:

  1. Using values specified on the command line (if there are any). For example, the following command starts a backup of the default database on the default server using the user ID DBA and the password SQL:

    dbbackup -c "uid=DBA;pwd=SQL" c:\backup

    For more information about options for each database tool, see the chapter Database Administration Utilities.

  2. Using the SQLCONNECT environment variable settings if any values are missing. Adaptive Server Anywhere does not set this variable automatically.

    For more information about the SQLCONNECT environment variable, see Environment variables.


Working with ODBC data sources

Microsoft Corporation defines the Open Database Connectivity (ODBC) interface, which is a standard interface for connecting client applications to database-management systems in the Windows 95/98/Me and Windows NT/2000/XP environments. Many client applications, including application development systems, use the ODBC interface to access a wide range of database systems.

Where data sources are held

You connect to an ODBC database using an ODBC data source. You need an ODBC data source on the client computer for each database you want to connect to.

The ODBC data source contains a set of connection parameters. You can store sets of Adaptive Server Anywhere connection parameters as an ODBC data source, in either the Windows registry or as files.

If you have a data source, your connection string can simply name the data source to use:

  • Data source Use the DataSourceName (DSN) connection parameter to reference a data source in the Windows registry:

    DSN=my data source

  • File data source Use the FileDataSourceName (FILEDSN) connection parameter to reference a data source held in a file:

    FileDSN=mysource.dsn

For Adaptive Server Anywhere, the use of ODBC data sources goes beyond Windows applications using the ODBC interface:

  • Adaptive Server Anywhere client applications on UNIX can use ODBC data sources, as well as those on Windows operating systems.

  • ODBC data sources can be used by all Adaptive Server Anywhere client interfaces except jConnect and Open Client.

  • Interactive SQL, Sybase Central, and the Adaptive Server Anywhere Console utility (dbconsole) can use ODBC data sources, even when using jConnect.


Creating an ODBC data source

You can create ODBC data sources on Windows 95/98/Me and Windows NT/2000/XP operating systems using the ODBC Administrator, which provides a central place for creating and managing ODBC data sources.

Adaptive Server Anywhere also includes a cross-platform utility named dbdsn to create data sources.

Before you begin

This section describes how to create an ODBC data source. Before you create a data source, you need to know which connection parameters you want to include in it.

For more information, see Simple connection examples.

ODBC Administrator

On Windows 95/98/Me and Windows NT/2000/XP, you can use the Microsoft ODBC Administrator to create and edit data sources. You can work with User Data Sources, File Data Sources, and System Data Sources in this utility.

toggle To create an ODBC data source (ODBC Administrator)

  1. Start the ODBC Administrator: In Sybase Central, choose Tools > Adaptive Server Anywhere 9 > Open ODBC Administrator.

    Alternatively, from Start menu, choose Programs > Sybase > SQL Anywhere 9 > Adaptive Server Anywhere > ODBC Administrator.

    The ODBC Data Source Administrator dialog appears.

  2. Click Add.

    The Create New Data Source wizard appears.

  3. From the list of drivers, choose Adaptive Server Anywhere 9.0, and click Finish.

    The ODBC Configuration for Adaptive Server Anywhere dialog appears.

    The ODBC Configuration for Adaptive Server Anywhere dialog where you can specify connection parameters for an ODBC data source.

    Most of the fields in this window are optional. Click the Help button to find more information about the fields on each tab.

    For more information about the fields in the dialog, see ODBC Configuration Dialog Help.

  4. When you have specified the parameters you need, click OK to close the window and create the data source.

To edit a data source, find and select the desired data source in the ODBC Administrator main window and click Configure.

Creating an ODBC data source from the command line

You can create User and System Data Sources using the dbdsn utility. You cannot create File Data Sources or System Data Sources in this way. File and System Data Sources are limited to Windows operating systems only, and you can use the ODBC Administrator to create File Data Sources.

toggle To create an ODBC data source (Command line)

  1. Open a command prompt.

  2. Type a dbdsn command, specifying the connection parameters you wish to use.

    For example, the following command creates a data source for the Adaptive Server Anywhere sample database. The command must be typed on one line:

dbdsn –w "My DSN" "uid=DBA;pwd=SQL;dbf=c:\Program Files\Sybase\SQL Anywhere 9\asademo.db"

For more information on the dbdsn utility, see The Data Source utility.


Using file data sources on Windows

On Windows operating systems, ODBC data sources are typically stored in the system registry. File data sources are an alternative, which are stored as files. In Windows, file data sources typically have the extension .dsn. They consist of sections, each section starting with a name enclosed in square brackets.

To connect using a File Data Source, use the FileDataSourceName (FILEDSN) connection parameter. You cannot use both DataSourceName (DSN) and FileDataSourceName (FILEDSN) in the same connection.

File data sources can be distributed

One benefit of file data sources is that you can distribute the file to users. If the file is placed in the default location for file data sources, it is picked up automatically by ODBC. In this way, managing connections for many users can be made simpler.

toggle To create an ODBC file data source (ODBC Administrator)

  1. Start the ODBC Administrator, click the File DSN tab and then click Add.

  2. Select Adaptive Server Anywhere 9.0 from the list of drivers, and then click Next.

  3. Follow the instructions to create the data source.


Using ODBC data sources on UNIX

On UNIX operating systems, ODBC data sources are held in a file named .odbc.ini. A sample file looks like this:

[My Data Source]
ENG=myserver
CommLinks=tcpip(Host=hostname)
uid=DBA
pwd=SQL

You can type any connection parameter in the .odbc.ini file.

For a complete list or connection parameters, see Connection parameters.

Network protocol options are added as part of the CommLinks (LINKS) parameter.

For a complete list of network protocol options, see Network protocol options.

You can create and manage ODBC data sources on UNIX using the dbdsn utility.

For more information, see Creating an ODBC data source, and The Data Source utility.

Caution You should not add simple encryption to the .odbc.ini system information file with the File Hiding utility (dbfhide) on UNIX unless you will only be using Adaptive Server Anywhere data sources. If you plan to use other data sources (for example, for MobiLink synchronization), then obfuscating the contents of the .odbc.ini file may prevent other drivers from functioning properly.
File location

The database server looks for the .odbc.ini file in the following locations:

  1. ODBCINI environment variable

  2. ODBCHOME and HOME environment variables

  3. The user's home directory

  4. The path


Using ODBC data sources on Windows CE

Windows CE does not provide an ODBC driver manager or an ODBC Administrator. On this platform, Adaptive Server Anywhere uses ODBC data sources stored in files. You can specify either the DSN or the FILEDSN keyword to use these data source definitions—on Windows CE (only), DSN and FILEDSN are synonyms.

Data source location

Windows CE searches for the data source files in the following locations:

  1. The directory from which the ODBC driver (dbodbc9.dll ) was loaded. This is usually the Windows directory.

  2. The directory specified in Location key of the Adaptive Server Anywhere section of the registry. This is usually the same as the Adaptive Server Anywhere installation directory. The default installation directory is:

    \Program Files\Sybase\ASA

Each data source itself is held in a file. The file has the same name as the data source, with an extension of .dsn.

For more information about file data sources, see Using file data sources on Windows.


Connecting from desktop applications to a Windows CE database

You can connect from applications running on a desktop PC, such as Sybase Central or Interactive SQL, to a database server running on a Windows CE device. The connection uses TCP/IP over the ActiveSync link between the desktop machine and the Windows CE device.

If you are using an Ethernet connection between your desktop machine and the Windows CE device the following procedure works. Connecting from the desktop to the CE device is not supported if ActiveSync is using a USB connection.

For information about using a serial cable connection and ActiveSync 3.x, see Using ActiveSync 3.0 and a serial cable.

toggle To connect from a desktop application to a Windows CE database server

  1. Determine the IP address of the server. Start the server on the Windows CE device with the -z option (output extra debug information).

    For example:

    dbsrv9 -z -x tcpip -n TestServer asademo.db

    With the -z option, the server writes out its IP address during startup. The address may change if you disconnect your CE device from the network and then re-connect it.

    To change between static and dynamic IP assignment for the CE device, configure the settings in the Windows Control Panel. Open Network, and choose the Services tab. Select Remote Access Service and click Properties > Network > TCP/IP Configuration.

  2. Create an ODBC profile on your desktop machine.

    Open the ODBC Administrator, and click Add. Choose Adaptive Server Anywhere 9.0 from the list of drivers and click Finish. The ODBC Configuration for Adaptive Server Anywhere dialog appears.

    • On the Login tab, type a user ID and password.

    • On the Database tab, type the server name.

    • On the Network tab, check TCP/IP, and type the following in the adjacent field:

      dobroadcast=DIRECT;host=XXX.XXX.XXX.XXX

      where XXX.XXX.XXX.XXX is the server IP address.

    • On the ODBC tab, click Test Connection to confirm that your ODBC data source is properly configured.

  3. Exit the ODBC Administrator.

  4. Ensure the database server is running on your Windows CE machine.

  5. On your desktop machine, start an application such as Interactive SQL and select the ODBC data source you have created. The application connects to the Windows CE database.

Using ActiveSync 3.0 and a serial cable


Using ActiveSync 3.0 and a serial cable

To connect to a Windows CE device from your desktop over a serial cable, Adaptive Server Anywhere uses the TCP/IP protocol. For TCP/IP to work in this context, your ActiveSync installation must be set up to provide a Remote Access Service (RAS) link between desktop machine and Windows CE device.

For information, see Connecting from desktop applications to a Windows CE database.

ActiveSync 3.x does not install and configure RAS. You must install RAS yourself to obtain TCP/IP connectivity to your device over a serial connection.

Instructions for installing RAS are provided by Microsoft. They are available at [external link] http://support.microsoft.com/support/kb/articles/Q241/2/16.ASP (Microsoft Knowledge Base article Q241216). You must follow these instructions exactly, including re-installing any Windows NT service packs, and granting your user account dial-in access using User Manager.

As you follow the instructions, where it says to install your modem, choose Dial-up Networking Serial Cable between 2 PCs instead.

Using RAS with ActiveSync

The following list includes suggestions for enabling ActiveSync 3.0 connections over a serial connection using RAS:

  1. In the ActiveSync Connection Settings, select the checkbox Allow network (Ethernet) and Remote Access Service (RAS) server connection with desktop computer. You may need to turn off the checkbox Allow serial cable or infrared connection to this COM port.

  2. On the desktop, using Remote Access Administrator (under Administrative Tools on Windows NT), start RAS on COM1.

  3. On the Windows CE device, run the ActiveSync client (repllog.exe on a Windows CE PC). Choose Serial Connection.

  4. Wait for a connection to be established.

  5. As a test, run the ipconfig utility on Windows NT, and see the 192.168.55.100 static IP of the device. This is the IP you would use when connecting to an Adaptive Server Anywhere database server (for example) running on the CE device.

  6. If you switch devices, Stop and Restart the RAS service (or reboot).

  7. If everything is set up as above, but you still fail to get a connection from the device to the desktop, you should make sure your Port settings match the baud rates in the Modems Control Panel applet.


Connecting to a database using OLE DB

OLE DB uses the Component Object Model (COM) to make data from a variety of sources available to applications. Relational databases are among the classes of data sources that you can access through OLE DB.

This section describes how to connect to an Adaptive Server Anywhere database using OLE DB from the following environments:

  • Microsoft ActiveX Data Objects (ADO) provides a programming interface for OLE DB data sources. You can access Adaptive Server Anywhere from programming tools such as Microsoft Visual Basic.

  • Sybase PowerBuilder can access OLE DB data sources, and you can use Adaptive Server Anywhere as a PowerBuilder OLE DB database profile.

This section is an introduction to how to use OLE DB from Sybase PowerBuilder and Microsoft ADO environments such as Visual Basic. It is not complete documentation on how to program using ADO or OLE DB. The primary source of information on development topics is your development tool documentation.

For more information about OLE DB, see Introduction to OLE DB.


OLE DB providers

You need an OLE DB provider for each type of data source you wish to access. Each OLE DB provider is a dynamic-link library. There are two OLE DB providers you can use to access Adaptive Server Anywhere:

  • Sybase ASA OLE DB provider The Adaptive Server Anywhere OLE DB provider provides access to Adaptive Server Anywhere as an OLE DB data source without the need for ODBC components. The short name for this provider is ASAProv.

    When the ASAProv provider is installed, it registers itself. This registration process includes making registry entries in the COM section of the registry so that ADO can locate the DLL when the ASAProv provider is called. If you change the location of your DLL, you must re-register it.

    For more information about OLE DB providers, see Introduction to OLE DB.

  • Microsoft OLE DB provider for ODBC Microsoft provides an OLE DB provider with a short name of MSDASQL.

    The MSDASQL provider makes ODBC data sources appear as OLE DB data sources. It requires the Adaptive Server Anywhere ODBC driver.


Connecting from ADO

ADO is an object-oriented programming interface. In ADO, the Connection object represents a unique session with a data source.

You can use the following Connection object features to initiate a connection:

  • The Provider property that holds the name of the provider. If you do not supply a Provider name, ADO uses the MSDASQL provider.

  • The ConnectionString property that holds a connection string. This property holds an Adaptive Server Anywhere connection string, which is used in the same way as the ODBC driver. You can supply ODBC data source names, or explicit UserID, Password, DatabaseName, and other parameters, just as in other connection strings.

  • The Open method initiates a connection.

For more information about ADO, see ADO programming with Adaptive Server Anywhere.

Example

The following Visual Basic code initiates an OLE DB connection to Adaptive Server Anywhere:

' Declare the connection object
Dim myConn as New ADODB.Connection
myConn.Provider = "ASAProv"
myConn.ConnectionString = "Data Source=ASA 9.0 Sample"
myConn.Open


Connection parameter tips

Connection parameters often provide more than one way of accomplishing a given task. This is particularly the case with embedded databases, where the connection string starts a database server. For example, if your connection starts a database, you can specify the database name using the DatabaseName (DBN) connection parameter or using the DatabaseSwitches (DBS) parameter. The Database Name (DBN) connection parameter is recommended.

Here are some recommendations and notes for situations where connection parameters conflict:

  • Specify database files using DBF You can specify a database file on the StartLine (START) parameter or using the DatabaseFile (DBF) connection parameter (recommended).

  • Specify database names using DBN You can specify a database name on the StartLine (START) parameter, the DatabaseSwitches (DBS) connection parameter, or using the DatabaseName (DBN) connection parameter (recommended).

  • Use the Start parameter to specify cache size Even though you use the DatabaseFile (DBF) connection parameter to specify a database file, you may still want to tune the way in which it starts. You can use the StartLine (START) connection parameter to do this.

    For example, if you are using the Java features of Adaptive Server Anywhere, you should provide additional cache memory on the StartLine (START) connection parameter. The following sample set of embedded database connection parameters describes a connection that may use Java features:

    DBF=path\asademo.db
dbn=Sample
ENG=Sample Server
uid=DBA
pwd=SQL
Start=dbeng9 -c 8M

For a list of connection parameters, see Connection Parameters and Network Protocol Options.

For character set issues in connection strings, see Connection strings and character sets.

Notes about connection parameters

  • Boolean values Boolean (true or false) arguments are either YES, ON, 1, or TRUE if true, or NO, OFF, 0, or FALSE if false.

  • Case sensitivity

    Connection parameters are case insensitive.

  • The connection parameters used by the interface library can be obtained from the following places (in order of precedence):

    • Connection string You can pass parameters explicitly in the connection string.

    • SQLCONNECT environment variable The SQLCONNECT environment variable can store connection parameters.

    • Data sources ODBC data sources can store parameters.

  • Character set restrictions The server name must be composed of the ASCII character set in the range 1 to 127. There is no such limitation on other parameters.

    For more information on the character set issues, see Connection strings and character sets.

  • Priority

    The following rules govern the priority of parameters:

    • The entries in a connect string are read left to right. If the same parameter is specified more than once, the last one in the string applies. ODBC and OLE DB are an exception to this: if the same parameter is specified more than once, the first string applies.

    • If a string contains a data source or file data source entry, the profile is read from the configuration file, and the entries from the file are used if they are not already set. For example, if a connection string contains a data source name and sets some of the parameters contained in the data source explicitly, then in case of conflict the explicit parameters are used.


Troubleshooting connections

Who needs to read this section?

In many cases, establishing a connection to a database is straightforward using the information presented in the first part of this chapter.

However, if you are having problems establishing connections to a server, you may need to understand the process by which Adaptive Server Anywhere establishes connections in order to resolve your problems. This section describes how Adaptive Server Anywhere connections work.

For more information about network-specific issues, including connections across firewalls, see Client/Server Communications.

The software follows exactly the same procedure for each of the following types of client application:

  • ODBC Any ODBC application using the SQLDriverConnect function, which is the common method of connection for ODBC applications. Many application development systems, such as Sybase PowerBuilder, belong to this class of application. The SQLConnect function is also available to ODBC applications.

  • Embedded SQL Any client application using embedded SQL and using the recommended function for connecting to a database (db_string_connect).

    In addition, The SQL CONNECT statement is available for embedded SQL applications and in Interactive SQL. It has two forms: CONNECT AS... and CONNECT USING. All the database administration tools, including Interactive SQL, use db_string_connect.

  • OLE DB Any ADO application using the ADODB Connection object. The Provider property is used to locate the OLE DB driver. The Connection String property may use DataSource as an alternative to DataSourceName and User ID as an alternative to UserID.

  • JDBC Applications using the iAnywhere JDBC driver pass the URL jdbc:odbc: followed by a standard connection string as a parameter to the Driver Manager.GetConnection method. The connection string must include DataSource= and name an Adaptive Server Anywhere data source or include Driver=Adaptive Server Anywhere 9.0 (this parameter is specified as Driver=libdbodb9 on UNIX and Linux).

For more troubleshooting tips, see Troubleshooting server startup, and Troubleshooting network communications.

The steps in establishing a connection
Locating the interface library
Assembling a list of connection parameters
Locating a server
Locating the database
Server name caching for faster connections
Interactive SQL connections
Testing that a server can be found


The steps in establishing a connection

To establish a connection, Adaptive Server Anywhere carries out the following steps in order:

  1. Locate the interface library The client application must locate the interface library.

  2. Assemble a list of connection parameters Since connection parameters may appear in several places (such as data sources, a connection string assembled by the application, or an environment variable) Adaptive Server Anywhere assembles the parameters into a single list.

  3. Locate a server Using the connection parameters, Adaptive Server Anywhere locates a database server on your machine or over a network.

  4. Locate the database Adaptive Server Anywhere locates the database you want to connect to.

  5. Start a personal server If Adaptive Server Anywhere fails to locate a server, it attempts to start a personal database server and load the database.

The following sections describe each of these steps in detail.


Locating the interface library

The client application makes a call to one of the Adaptive Server Anywhere interface libraries. In general, the location of this DLL or shared library is transparent to the user. Here we describe how to locate the library in case of problems.

ODBC driver location

For ODBC, the interface library is also called an ODBC driver. An ODBC client application calls the ODBC driver manager, and the driver manager locates the Adaptive Server Anywhere driver.

The ODBC driver manager looks in the supplied data source in the .odbc.ini file or registry to locate the driver. When you create a data source using the ODBC Administrator, Adaptive Server Anywhere fills in the current location for your ODBC driver.

Embedded SQL interface library location

Embedded SQL applications call the interface library by name. The name of the Adaptive Server Anywhere embedded SQL interface library is as follows:

  • Windows NT/2000/XP and Windows 95/98/Me dblib9.dll

  • UNIX dblib9 with an operating-system-specific extension

  • NetWare dblib9.nlm

OLE DB driver location

The provider name (ASAProv) is used to locate the ASAOLEDB DLL based on entries in the registry. The entries are created when the ASAProv provider is installed or if it is reregistered.

iAnywhere JDBC driver location

The Java package jodbc.jar must be in the classpath when you run your application. The native DLLs or shared objects must be in the system path.

  • PC operating systems On PC operating systems such as Windows, files are looked for in the current directory, in the system path, and in the Windows and Windows\system directories.

  • UNIX operating systems On UNIX, files are looked for in the system path and the user library path.

  • NetWare On NetWare, files are looked for in the search path, and in the sys:system directory.

When the library is located

Once the client application locates the interface library, it passes a connection string to it. The interface library uses the connection string to assemble a list of connection parameters, which it uses to establish a connection to a server.


Assembling a list of connection parameters

The following figure illustrates how the interface libraries assemble the list of connection parameters they use to establish a connection.

Flowchart of the interface libraries assembling a list of connection parameters.
Notes

Key points from the figure include:

  • Precedence Parameters held in more than one place are subject to the following order of precedence:

    1. Connection string

    2. SQLCONNECT

    3. Data source

    That is, if a parameter is supplied both in a data source and in a connection string, the connection string value overrides the data source value.

  • Failure Failure at this stage occurs only if you specify in the connection string or in SQLCONNECT a data source that does not exist.

  • Common parameters Depending on other connections already in use, some connection parameters may be ignored, including:

    • AutoStop Ignored if the database is already loaded.

    • DatabaseFile Ignored of DatabaseName is specified and a database with this name is already running.

The interface library uses the completed list of connection parameters to attempt to connect.


Locating a server

In the next step towards establishing a connection, Adaptive Server Anywhere attempts to locate a server. If the connection parameter list includes a server name (EngineName (ENG) connection parameter), it carries out a search for a server of that name. If no EngineName (ENG) connection parameter is supplied, and LINKS is not specified or LINKS includes Shared Memory, Adaptive Server Anywhere looks for a default server.

Flowchart of Adaptive Server Anywhere attempting to start a personal server.

If Adaptive Server Anywhere locates a server, it tries to locate or load the required database on that server.

For information, see Locating the database.

If Adaptive Server Anywhere cannot locate a server, it may attempt to start a personal server, depending on the connection parameters.

Notes

  • For local connections, locating a server is simple. For connections over a network, you can use the CommLinks (LINKS) connection parameter to tune the search in many ways by supplying network protocol options.

  • The network search involves a search over one or more of the protocols supported by Adaptive Server Anywhere. For each protocol, the network library starts a single port. All connections over that protocol at any one time use a single port.

  • You can specify a set of network protocol options for each network port in the argument to the CommLinks (LINKS) connection parameter.

  • Each attempt to locate a server involves two steps. First, Adaptive Server Anywhere looks in the server name cache to see if a server of that name is available (this step is skipped if the value of DoBroadcast is none). Second, it uses the available connection parameters to attempt a connection.

  • If the server is autostarted, information from the START, DBF, DBKEY, DBS, DBN, ENG, and AUTOSTOP connection parameters are used to construct the options for the autostarted server.


Locating the database

If Adaptive Server Anywhere successfully locates a server, it then tries to locate the database. For example:

Flowchart of Adaptive Server Anywhere locating a database once it has located a server.


Server name caching for faster connections

When the DoBroadcast (DOBROAD) protocol option is set to DIRECT or ALL, the network library looks for a database server on a network by broadcasting over the network using the CommLinks (LINKS) connection parameter.

Tuning the broadcast

The CommLinks (LINKS) parameter takes as argument a string listing the protocols to use and, optionally for each protocol, a variety of network protocol options that tune the broadcast.

For more information about network protocol options, see Network protocol options.

Caching server information

Broadcasting over large networks searching for a server of a specific name can be time-consuming. Caching server addresses speeds up network connections by saving the protocol the first connection to a server was found on, and its address, to a file and using that information for subsequent connections.

The server information is saved in a cached file named asasrv.ini. The file contains a set of sections, each of the following form:

[Server name]
Link=protocol_name
Address=address_string

The asasrv.ini file is located in your Adaptive Server Anywhere executable directory (the same directory as the ODBC/ DBLib DLL).

You can obfuscate the contents of the asasrv.ini file with simple encryption using the File Hiding utility.

For more information, see Hiding the contents of .ini files.

Note:
It is very important that each server has a unique name. Giving different servers the same name can lead to identification problems.
How the cache is used

If the server name and protocol in the cache match the connection string, Adaptive Server Anywhere tries to connect using the cached address first. If that fails, or if the server name and protocol in the cache do not match the connection string, the connection string information is used to search for the server using a broadcast. If the broadcast is successful, the server name entry in the cache is overwritten. If no server is found, the server name entry in the cache is removed. If the DoBroadcast protocol option is set to none, any cached addresses are ignored.


Interactive SQL connections

The Interactive SQL utility has a different behavior from the default embedded SQL behavior when a CONNECT statement is issued while already connected to a database. If no database or server is specified in the CONNECT statement, Interactive SQL connects to the current database, rather than to the default database. This behavior is required for database reloading operations.

For more information, see CONNECT statement [ESQL] [Interactive SQL].


Testing that a server can be found

The dbping utility is provided to help in troubleshooting connections. In particular, you can use it to test if a server with a particular name is available on your network.

The dbping utility takes a connection string as an option, but by default only those pieces required to locate a server are used. By default, it does not attempt to start a server, but may if the -d option is specified.

Examples

The following command line tests to see if a server named Waterloo is available over a TCP/IP connection:

dbping -c "eng=Waterloo;CommLinks=tcpip"

The following command tests to see if a default server is available on the current machine.

dbping

For more information on dbping options, see The Ping utility.


Using integrated logins

The integrated login feature allows you to maintain a single user ID and password for both database connections and operating system and/or network logins. This section describes the integrated login feature.

Operating systems supported

Integrated login capabilities are available for Windows NT/2000/XP servers only. It is possible for Windows 95/98/Me clients, as well as Windows NT/2000/XP clients, to use integrated logins to connect to a network server running on Windows NT/2000/XP.

Benefits of an integrated login

An integrated login is a mapping from one or more Windows users or Windows user group profiles to an existing user in a database. A user who has successfully navigated the security for that user profile or group and logged in to a machine can connect to a database without providing an additional user ID or password.

To accomplish this, the database must be configured to use integrated logins and a mapping must have been granted between the user or group profile used to log in to the machine and/or network, and a database user.

Using an integrated login is more convenient for the user and permits a single security system for database and network security. Its advantages include:

  • When connecting to a database using an integrated login, the user does not need to type a user ID or password.

  • If you use an integrated login, the user authentication is done by the operating system, not the database: a single system is used for database security and machine or network security.

  • Multiple user or group profiles can be mapped to a single database user ID.

  • The name and password used to login to the Windows NT/2000/XP machine do not have to match the database user ID and password.

Caution Integrated logins offer the convenience of a single security system, but there are important security implications that database administrators should be familiar with.

For more information about security and integrated logins, see Security concerns: unrestricted database access.

Creating integrated logins for Windows user groups
Setting up integrated logins
Security concerns: unrestricted database access
Setting temporary public options for added security
Network aspects of integrated logins
Creating a default integrated login user


Creating integrated logins for Windows user groups

In addition to creating integrated logins for individual Windows users, you can create integrated logins for Windows user groups.

When a user logs in, if the supplied Windows user does not have an explicit integrated login mapping, but belongs to a Windows user group for which there is an integrated login mapping, the user connects to the database as the database user or group specified in the Windows user group's integrated login mapping.

Caution Creating an integrated login for a Windows user group allows any user that is a member of the group to connect to the database without knowing a user ID or password.

For ways to prevent particular users that are members of a Windows user group from connecting to a database, see Preventing members of Windows user groups from connecting to a database.

Members of multiple groups

If the Windows user belongs to more than one Windows user group, and more than one Windows user group on the machine has an integrated login mapping in the database, then the integrated login only succeeds if all of the Windows user groups on the machine have integrated login mappings to the same database user ID or group. If multiple Windows user groups have integrated login mappings to different database user IDs or groups, an error is returned and the integrated login fails.

For example, consider a database with two user IDs, dbuserA and dbuserB, and the Windows user windowsuser who belongs to the Windows user groups ntgroupA and ntgroupB.

This SQL statement... Allows...
GRANT INTEGRATED LOGIN windowsuser
AS USER dbuserA
 windowsuser to connect to the database using the integrated login mapping set explicitly for windowsuser.
GRANT INTEGRATED LOGIN ntgroupA
AS USER dbuserB
 windowsuser to connect to the database using the integrated login mapping granted to ntgroupA.
GRANT INTEGRATED LOGIN ntgroupA
AS USER dbuserB
GRANT INTEGRATED LOGIN ntgroupb
AS USER dbuserB
 windowsuser to connect to the database because both Windows user groups that windowsuser belongs to have an integrated login mapping to the same database user.
GRANT INTEGRATED LOGIN ntgroupA
AS USER dbuserA
GRANT INTEGRATED LOGIN ntgroupb
AS USER dbuserB
 no connection to the database. When windowsuser attempts to connect to the database, the integrated login fails because each Windows user group has an integrated login mapping to a different database user and windowsuser is a member of both Windows user groups.
Domain Controller locations

By default, the machine the Adaptive Server Anywhere database server is running on is used to verify Windows user group membership. If the Domain Controller server is a different machine than the one the database server is running on, you can specify the name of the Domain Controller server using the INTEGRATED_SERVER_NAME option. For example:

SET PUBLIC.OPTION INTEGRATED_SERVER_NAME = '\\myserver-1'

For more information, see INTEGRATED_SERVER_NAME option [database].

Preventing members of Windows user groups from connecting to a database


Preventing members of Windows user groups from connecting to a database

Creating an integrated login for a Windows user group allows any user that is a member of the group to connect to the database without knowing a database user ID or password. There are two methods you can use to prevent a user who is a member of a Windows user group that has an integrated login from connecting to a database using the group integrated login:

  1. Create an integrated login for the user to a database user ID that does not have a password.

  2. Created a stored procedure that is called by the LOGIN_PROCEDURE option to check whether a user is allowed to log in, and raise an exception when a disallowed user tries to connect.

You can use either of these methods to prevent members of Windows user groups from connecting to a database.

Creating an integrated login to a user ID with no password

When a user is a member of a Windows user group that has an integrated login, but also has an explicit integrated login for their user ID, the user's integrated login is used to connect to the database. To prevent a user from connecting to a database using their Windows user group integrated login, you can create an integrated login for the Windows user to a database user ID without a password. Database user IDs that do not have a password cannot connect to a database.

toggle To create an integrated login to a user ID with no password

  1. Add a user to the database without a password. For example:

    GRANT CONNECT TO db_user_no_password

  2. Create an integrated login for the Windows user that maps to the database user without a password. For example:

    GRANT INTEGRATED LOGIN TO WindowsUser
AS USER db_user_no_password
Creating a procedure to prevent Windows users from connecting

The LOGIN_PROCEDURE option specifies a stored procedure to be called each time a connection to the database is attempted. By default, the dbo.sp_login_environment procedure is called. You can set the LOGIN_PROCEDURE option to call a procedure you have written that prevents specific users from connecting to the database.

The following example creates a procedure named login_check that is called by the LOGIN_PROCEDURE option. The login_check procedure checks the supplied user name against a list of users that are not allowed to connect to the database. If the supplied user name is found in the list, the connection fails. In this example, users named Joe, Harry, or Martha are not allowed to connect. If the user is not found in the list, the database connection proceeds as usual and calls the sp_login_environment procedure.

CREATE PROCEDURE DBA.user_login_check()
   BEGIN
      DECLARE INVALID_LOGON EXCEPTION FOR SQLSTATE '28000';
      // Disallow certain users
      IF( CURRENT USER IN ('Joe','Harry','Martha') ) THEN
        SIGNAL INVALID_LOGON;
      ELSE
         CALL sp_login_environment;
      END IF;
   END
go
GRANT EXECUTE ON DBA.user_login_check TO PUBLIC
go
SET OPTION PUBLIC.LOGIN_PROCEDURE='DBA.user_login_check'
go


Setting up integrated logins

Several steps must be implemented in order to connect successfully via an integrated login.

toggle To use an integrated login

  1. Enable the integrated login feature in a database by setting the value of the LOGIN_MODE database option to either Mixed or Integrated (the option is case insensitive), in place of the default value of Standard. This step requires DBA authority.

  2. Create an integrated login mapping between a Windows user or group profile and an existing database user. This can be done using a SQL statement or a wizard in Sybase Central. In Sybase Central, all users with integrated login permission appear in the Integrated Logins folder.

  3. Connect from a client application in such a way that the integrated login facility is triggered.

Each of these steps is described in the sections below.


Enabling the integrated login feature

The LOGIN_MODE database option determines whether the integrated login feature is enabled. As database options apply only to the database in which they are found, different databases can have a different integrated login setting even if they are loaded and running within the same server.

The LOGIN_MODE database option accepts one of following three values (which are case insensitive).

  • Standard With this setting, integrated logins are not permitted. This is the default setting. An error occurs if an integrated login connection is attempted.

  • Mixed With this setting, both integrated logins and standard logins are allowed.

  • Integrated With this setting, all logins to the database must be made using integrated logins.

    Caution Setting the LOGIN_MODE database option to Integrated restricts connections to only those users who have been granted an integrated login mapping. Attempting to connect using a user ID and password generates an error. The only exception to this is users with DBA authority (full administrative rights).
Example

The following SQL statement sets the value of the LOGIN_MODE database option to Mixed, allowing both standard and integrated login connections:

SET OPTION Public.LOGIN_MODE = Mixed


Creating an integrated login

User profiles can only be mapped to an existing database user ID. When that database user ID is removed from the database, all integrated login mappings based on that database user ID are automatically removed.

A user or group profile does not have to exist for it to be mapped to a database user ID. More than one user profile can be mapped to the same user ID.

Only users with DBA authority are able to create or remove an integrated login mapping.

An integrated login mapping is made either using a wizard in Sybase Central or a SQL statement.

toggle To map an integrated login (Sybase Central)

  1. Connect to a database as a user with DBA authority.

  2. Click the Integrated Logins folder in the left pane.

  3. From the File menu, choose New > Integrated Login.

  4. On the first page of the wizard, specify the name of the system (computer) user or group for whom the integrated login is to be created.

    Also, select the database user ID this user maps to. The wizard displays the available database users. You must select one of these. You cannot add a new database user ID.

  5. Follow the remaining instructions in the wizard.

toggle To map an integrated login (SQL)

  1. Connect to a database with DBA authority.

  2. Execute a GRANT INTEGRATED LOGIN TO statement.

Example

The following SQL statement allows Windows NT users fran_whitney and matthew_cobb to log in to the database as the user DBA, without having to know or provide the DBA user ID or password.

GRANT INTEGRATED LOGIN
TO fran_whitney, matthew_cobb
AS USER DBA

For more information, see GRANT statement.

The following SQL statement allows Windows NT users who are members of the Windows NT group mywindowsusers to log in to the database as the user DBA, without having to know or provide the DBA user ID or password.

GRANT INTEGRATED LOGIN
TO mywindowsusers
AS USER DBA

For more information about creating integrated logins for Windows NT groups, see .


Revoking integrated login permission

You can remove an integrated login mapping using either Sybase Central or Interactive SQL.

toggle To revoke an integrated login permission (Sybase Central)

  1. Connect to a database with DBA authority.

  2. Open the Integrated Logins folder.

  3. In the right pane, right-click the user/group you would like to remove the integrated login permission from and choose Delete from the popup menu.

toggle To revoke an integrated login permission (SQL)

  1. Connect to a database with DBA authority.

  2. Execute a REVOKE INTEGRATED LOGIN FROM statement.

Example

The following SQL statement removes integrated login permission from the Windows NT user pchin.

REVOKE INTEGRATED LOGIN
FROM pchin

For more information, see the REVOKE statement.


Connecting from a client application

A client application can connect to a database using an integrated login in one of the following ways:

  • Set the Integrated (INT) parameter in the list of connection parameters to YES.

  • Specify neither a user ID nor a password in the connection string or Connect dialog.

If Integrated=YES is specified in the connection string, an integrated login is attempted. If the connection attempt fails and the LOGIN_MODE database option is set to Mixed, the server attempts a standard login.

If an attempt to connect to a database is made without providing a user ID or password, an integrated login is attempted. The attempt succeeds or fails depending on whether the current user profile name matches an integrated login mapping in the database.

Interactive SQL examples

For example, a connection attempt using the following Interactive SQL statement will succeed, providing the user has logged on with a user profile name that matches a integrated login mapping in a default database of a server:

CONNECT USING 'INTEGRATED=yes'

The Interactive SQL statement CONNECT can connect to a database if all the following are true:

  • A server is currently running.

  • The default database on the current server is enabled to accept integrated login connections.

  • An integrated login mapping has been created that matches the current user's user profile name or for a Windows user group to which the user belongs.

  • If the user is prompted with a dialog by the server for more connection information (such as occurs when using the Interactive SQL utility), the user clicks OK without providing more information.


Security concerns: unrestricted database access

The integrated login feature works using the login control system of Windows NT/2000/XP in place of the Adaptive Server Anywhere security system. Essentially, the user passes through the database security if they can log in to the machine hosting the database, and if other conditions, outlined in Using integrated logins, are met.

If the user successfully logs in to the Windows NT/2000/XP server as "dsmith", they can connect to the database without further proof of identification provided there is either an integrated login mapping or a default integrated login user ID.

When using integrated logins, database administrators should give special consideration to the way Windows NT/2000/XP enforces login security in order to prevent unwanted access to the database.

In particular, be aware that by default a "Guest" user profile is created and enabled when Windows NT Workstation or Server is installed.

Caution Leaving the user profile Guest enabled can permit unrestricted access to a database that is hosted by that server.

If the Guest user profile is enabled and has a blank password, any attempt to log in to the server will be successful. It is not required that a user profile exist on the server, or that the login ID provided have domain login permissions. Literally any user can log in to the server using any login ID and any password: they are logged in by default to the Guest user profile.

This has important implications for connecting to a database with the integrated login feature enabled.

Consider the following scenario, which assumes the Windows NT server hosting a database has a Guest user profile that is enabled with a blank password.

  • An integrated login mapping exists between the user fran_whitney and the database user ID DBA. When the user fran_whitney connects to the server with her correct login ID and password, she connects to the database as DBA, a user with full administrative rights.

    But anyone else attempting to connect to the server as fran_whitney will successfully log in to the server regardless of the password they provide because Windows NT will default that connection attempt to the Guest user profile. Having successfully logged in to the server using the fran_whitney login ID, the unauthorized user successfully connects to the database as DBA using the integrated login mapping.

Disable the Guest user profile for security
The safest integrated login policy is to disable the Guest user profile on any Windows NT/2000/XP machine hosting an Adaptive Server Anywhere database. This can be done using the Windows User Manager utility.

Previous Next


Setting temporary public options for added security

Setting the value of the LOGIN_MODE option for a given database to Mixed or Integrated using the following SQL statement permanently enables integrated logins for that database.

SET OPTION Public.LOGIN_MODE = Mixed

If the database is shut down and restarted, the option value remains the same and integrated logins are still enabled.

Changing the LOGIN_MODE option temporarily will still allow user access via integrated logins. The following statement will change the option value temporarily:

SET TEMPORARY OPTION Public.LOGIN_MODE = Mixed

If the permanent option value is Standard, the database will revert to that value when it is shut down.

Setting temporary public options can be considered an additional security measure for database access since enabling integrated logins means that the database is relying on the security of the operating system on which it is running. If the database is shut down and copied to another machine (such as a user's machine) access to the database reverts to the Adaptive Server Anywhere security model and not the security model of the operating system of the machine where the database has been copied.

For more information on using the SET OPTION statement see SET OPTION statement.


Network aspects of integrated logins

If the database is located on a network server, then one of two conditions must be met for integrated logins to be used:

  • The user profile used for the integrated login connection attempt must exist on both the local machine and the server. As well as having identical user profile names on both machines, the passwords for both user profiles must also be identical.

    For example, when the user jsmith attempts to connect using an integrated login to a database loaded on a network server, identical user profile names and passwords must exist on both the local machine and application server hosting the database. jsmith must be permitted to login to both the local machine and the server hosting the network server.

  • If network access is controlled by a Microsoft Domain, the user attempting an integrated login must have domain permissions with the Domain Controller server and be logged in to the network. A user profile on the network server matching the user profile on the local machine is not required.


Creating a default integrated login user

A default integrated login user ID can be created so that connecting via an integrated login will be successful even if no integrated login mapping exists for the user profile currently in use.

For example, if no integrated login mapping exists for the user profile name JSMITH, an integrated login connection attempt will normally fail when JSMITH is the user profile in use.

However, if you create a user ID named Guest in a database, an integrated login will successfully map to the Guest user ID if no integrated login mapping explicitly identifies the user profile JSMITH.

The default integrated login user permits anyone attempting an integrated login to successfully connect to a database if the database contains a user ID named Guest. The authorities granted to the Guest user ID determine the permissions and authorities granted to the newly-connected user.


Client/Server Communications

About this chapter

Each network environment has its own peculiarities. This chapter describes those aspects of network communication that are relevant to the proper functioning of your database server, and provides some tips for diagnosing network communication problems. It describes how networks operate, and provides hints on running the network database server under each protocol.

Network database server only
The material in this chapter applies only to the network server. You do not need to read this chapter if you are using the personal database server.

Supported network protocols
Using the TCP/IP protocol
Using the SPX protocol
Using Named Pipes
Adjusting communication compression settings to improve performance
Troubleshooting network communications


Supported network protocols

Properly configured Adaptive Server Anywhere servers run under the following networks and protocols:

  • Windows NT/2000/XP and Windows 95/98/Me TCP/IP or SPX protocols.

  • Windows CE TCP/IP protocol.

  • NetWare TCP/IP or SPX protocol.

  • UNIX TCP/IP protocol.

In addition, the Named Pipes protocol is provided for communication from a client application running on the same machine.

  • Windows NT/2000/XP/Server 2003 Named Pipes is used for same-machine communication between any application and the server, but is generally not recommended for this purpose. Named Pipes is not used for network communications, but can be used to run Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration.

The client library for each platform supports the same protocols as the corresponding server. In order for Adaptive Server Anywhere to run properly, the network protocols (TCP/IP and/or SPX) must be installed and configured properly on both the client and server computers.


Using the TCP/IP protocol

TCP/IP is a suite of protocols originally implemented by the University of California at Berkeley for BSD UNIX. TCP/IP has gained widespread use with the expansion of the Internet and the world wide web.

UDP is a transport layer protocol that sits on top of IP. Adaptive Server Anywhere uses UDP on top of IP to do initial server name resolution and TCP for connection and communication after that.

When you use the TCP/IP protocol, you can secure client/server communications using transport-layer security and ECC_TLS (formerly Certicom) or RSA_TLS encryption technology.

For more information, see Adaptive Server Anywhere Transport-Layer Security.

Using TCP/IP with Windows
Tuning TCP/IP performance
Connecting across a firewall
Connecting on a dial-up network connection
Encrypting client/server communications over TCP/IP
Connecting using an LDAP server


Using TCP/IP with Windows

The TCP/IP implementation for database servers on all Windows platforms uses Winsock 2.0. The implementation for clients on Windows NT/2000/XP also uses Winsock 2.0. Clients on Windows 95/98/Me use Winsock 1.1 by default. Clients on Windows CE use the Winsock 1.1 standard.

If you do not have TCP/IP installed, you can install the TCP/IP protocol from the Control Panel by double-clicking Network Settings.

For more information, see DLL protocol option.


Tuning TCP/IP performance

Increasing the packet size may improve query response time, especially for queries transferring a large amount of data between a client and a server process. You can set the packet size using the -p option in the database server command, or by setting the CommBufferSize (CBSIZE) connection parameter in your connection profile.

For more information, see -p server option, or CommBufferSize connection parameter [CBSIZE].


Connecting across a firewall

There are restrictions on connections when the client application is on one side of a firewall, and the server is on the other. Firewall software filters network packets according to network port. Also, it is common to disallow UDP packets from crossing the firewall.

When connecting across a firewall, you must use a set of protocol options in the CommLinks (LINKS) connection parameter of your application's connection string.

  • Host Set this parameter to the host name on which the database server is running. You can use the short form IP.

  • ServerPort If your database server is not using the default port of 2638, you must specify the port it is using. You can use the short form Port. This option may not be necessary depending on the firewall's configuration.

  • ClientPort Set this parameter to a range of allowed values for the client application to use. You can use the short form CPort.

  • DoBroadcast=NONE Set this parameter to prevent UDP from being used when connecting to the server.

The firewall must be configured to allow TCP/IP traffic between the Adaptive Server Anywhere server's address and all the Adaptive Server Anywhere clients' addresses. The Adaptive Server Anywhere server's address is the IP address of the machine running the Adaptive Server Anywhere server (the HOST parameter) and the Adaptive Server Anywhere server's IP port number (the ServerPort protocol option, default 2638). Each Adaptive Server Anywhere client's address consists of the IP address of the client machine, and the range of the client IP ports (the ClientPort protocol option). For simplest configuration, all client ports can be allowed. If only specific client ports are allowed, specify a range with more ports than the maximum number of concurrent connections from each client machine, since there is a several minute timeout before a client port can be refused.

For more information, see ClientPort protocol option [CPORT].

Example

The following connection string fragment restricts the client application to ports 5050 through 5060, and connects to a server named myeng running on the machine at address myhost using the server port 2020. No UDP broadcast is carried out because of the DoBroadcast option.

Eng=myeng;Links=tcpip(ClientPort=5050-5060;Host=myhost;Port=2020;DoBroadcast=NONE)
See also
  • CommLinks connection parameter [LINKS]
  • ClientPort protocol option [CPORT]
  • ServerPort protocol option [PORT]
  • Host protocol option [IP]
  • DoBroadcast protocol option [DOBROAD]


Connecting on a dial-up network connection

You can use connection and protocol options to assist with connecting to a database across a dial-up link.

On the client side, you should specify the following protocol options:

  • Host parameter You should specify the host name or IP address of the database server using the Host (IP) protocol option.

    For more information, see Host protocol option [IP].

  • DoBroadcast parameter If you specify the Host (IP) protocol option, there is no need to do a broadcast search for the database server. For this reason, use direct broadcasting.

    For more information, see DoBroadcast protocol option [DOBROAD].

  • MyIP parameter You should set MyIP=NONE on the client side.

    For more information, see MyIP protocol option [ME].

  • TIMEOUT parameter Set the TIMEOUT (TO) protocol option to increase the time the client will wait while searching for a server.

For more information, see the Timeout protocol option [TO].

A typical CommLinks (LINKS) connection parameter may look as follows:

Links=tcpip(MyIP=NONE;DoBroadcast=DIRECT;Host=server_ip)


Encrypting client/server communications over TCP/IP

By default, communication packets are not encrypted; this poses a potential security risk. You can secure communications between client applications and the database server over TCP/IP using simple encryption or transport-layer security. Transport-layer security provides server authentication, strong encryption using ECC_TLS (formerly Certicom) or RSA_TLS encryption technology, and other features for protecting data integrity.

For more information, see Adaptive Server Anywhere Transport-Layer Security.


Connecting using an LDAP server

You can specify a central LDAP server to keep track of all servers in an enterprise if you are operating on a Windows (except CE and Win64), UNIX or NetWare platform. When the database server registers itself with an LDAP server, clients can query the LDAP server and find the server they are looking for regardless of whether they are on a WAN or LAN, or going through firewalls. They do not need to specify an IP address (HOST=), either. The Server Location utility (dblocate) can use the LDAP server to find other such servers as well.

LDAP is only used with TCP/IP, and only on network servers.

To enable this feature, a file containing information on how to find and connect to the LDAP server must be created on both the server machine and on each client machine. By default the name of this file is asaldap.ini, but it is configurable. If this file doesn't exist, LDAP support is silently disabled.

The file must be located in the same directory as the Adaptive Server Anywhere executables (for example, %asany%\win32 on Windows) unless a full path is specified with the LDAP parameter. The file must be in the following format:

[LDAP]
server=<machine running LDAP server>
port=<port number of LDAP server>
basedn=<Base DN>
authdn=<Authentication DN>
password=<password for authdn>
search_timeout=<age of timestamps to be ignored>
update_timeout=<frequency of timestamp updates>

You can add simple encryption to obfuscate the contents of the asaldap.ini file using the File Hiding utility (dbfhide).

For more information, see Hiding the contents of .ini files.

server the name or IP address of the machine running the LDAP server. This value is required on NetWare and UNIX. If this entry is missing on Windows, Windows looks for an LDAP server running on the local domain controller.

port the port number used by the LDAP server. The default is 389.

basedn the domain name of the subtree where the Adaptive Server Anywhere entries are stored. This defaults to the root of the tree.

authdn the authentication domain name. The domain name must specify an existing user object in the LDAP directory that has write access to the basedn. This is required for the server, and ignored on the client.

password the password for authdn. This is required for the server, and ignored on the client.

search_timeout the age of timestamps at which the timestamp will be ignored by the client and/or the Server Location [dblocate] utility. A value of 0 disables this option so that all entries are assumed to be current. The default is 600 seconds (10 minutes).

update_timeout the frequency of timestamp updates in the LDAP directory. A value of 0 disables this option so that the server never updates the timestamp. The default is 120 seconds (2 minutes).

Example

The following is a sample asaldap.ini file:

[LDAP]
server=ldapserver
basedn=dc=iAnywhere,dc=com
authdn=cn=ASAServer,ou=iAnywhereASA,dc=iAnywhere,dc=com
password=secret

The entries are stored in a subtree of the basedn called iAnywhereASA. This entry must be created before Adaptive Server Anywhere can use LDAP. To create the subtree, you can use the LDAPADD utility, supplying the following information:

dn: ou=iAnywhereASA,<basedn>
objectClass: organizationalUnit
objectClass: top
ou: iAnywhereASA

When the server starts up, it checks for an existing entry with the same name in the LDAP file. If one is found, it is replaced if either

  • the location entries in LDAP match the server attempting to start, or

  • the timestamp field in the LDAP entry is more than 10 minutes old (the timeout value is configurable)

If neither of these is true, then there is another server running with the same name as the one attempting to start, and startup fails.

To ensure that entries in LDAP are up-to-date, the server updates a timestamp field in the LDAP entry every 2 minutes. If an entry's timestamp is older than 10 minutes, clients ignore the LDAP entry. Both of these values are configurable.

On the client, the LDAP directory is searched before doing any broadcasting, so if the server is found, no broadcasts are sent. The LDAP search is very fast, so if it fails, there is no discernible delay.

The Server Location utility (dblocate) also uses LDAP—all servers listed in LDAP are added to the list of servers returned. This allows the Server Location utility (dblocate) to list servers that wouldn't be returned normally, for example, those which broadcasts wouldn't reach. Entries with timestamps older than 10 minutes are not included.


Using the SPX protocol

SPX is a protocol from Novell. Adaptive Server Anywhere for NetWare, Windows NT/2000/XP, and Windows 95/98/Me can all employ the SPX protocol. This section provides some tips for using SPX under different operating systems.

SPX is not supported on 64-bit operating systems.

Connecting via SPX

Some machines can use the NetWare bindery. These machines are NetWare servers or Windows NT/2000/XP or Windows 95/98/Me machines where the Client Service for NetWare is installed. A client application on one of these machines does not need to use broadcasts to connect to the server if the server to which it is connecting is also using the bindery.

Applications running on machines not using the bindery must connect using one of the following:

  • An explicit address You can specify an explicit address using the HOST (IP) protocol option.

    For more information, see the Host protocol option [IP].

  • Broadcast If a server is not found in the bindery, the client will attempt to find it using a broadcast. This can be disabled with by setting the DoBroadcast (DOBROAD) protocol option to NONE (client-side) or NO (server-side).

    For more information, see the DoBroadcast protocol option [DOBROAD].


Using Named Pipes

Named Pipes is a facility for interprocess communication. Named Pipes can be used for communication between processes on the same computer or on different computers.

Adaptive Server Anywhere for Windows NT/2000/XP can use local Named Pipes for same-machine communication.

For more information, see Supported network protocols.

Note that shared memory (the default protocol) is more efficient than Named Pipes. The Named Pipes protocol should be used when using Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration.

Adaptive Server Anywhere does not use Named Pipes for client/server communications between different machines.


Adjusting communication compression settings to improve performance

Enabling compression for one or all connections, as well as setting the minimum size at which packets are compressed, can significantly improve Adaptive Server Anywhere performance in some circumstances.

To determine if enabling compression will help in your particular situation, we recommend that you conduct a performance analysis on your particular network and using your particular application before using communication compression in a production environment. Performance results will vary according to the type of network you are using, your applications, and the data you transfer.

The most basic way of tuning compression is as simple as enabling or disabling the Compression (COMP) connection parameter on either the connection or server level. More advanced methods of fine tuning compression performance include adjusting the CommBufferSize (CBSIZE) and/or the CompressionThreshold (COMPTH) connection parameters.

Enabling compression increases the quantity of information stored in data packets, thereby reducing the number of packets required to transmit a particular set of data. By reducing the number of packets, the data can be transmitted more quickly.

For more information about performance analysis, see Performance Monitor statistics, or sa_conn_compression_info system procedure.

Enabling compression

Enabling compression for a connection (or all connections) can significantly improve Adaptive Server Anywhere performance under some circumstances, including:

  • when used over slow networks such as some wireless networks, some modems, serial links and some WANs.

  • when used in conjunction with Adaptive Server Anywhere encryption over a slow network with built-in compression, since packets are compressed before they are encrypted.

Enabling compression, however, can sometimes also cause slower performance. For instance,

  • communication compression uses more memory and more CPU. It may cause slower performance, especially for LANs and other fast networks.

  • most modems and some slow networks already have built-in compression. In these cases, Adaptive Server Anywhere communication compression will not likely provide additional performance benefits unless you are also encrypting the data.

For more information about compression, see Compress connection parameter [COMP], -pc server option.

Modifying the CommBufferSize setting

While CommBufferSize (CBSIZE) is not a compression parameter in itself, adjusting this parameter can benefit compression, especially if you are transferring a large amount of data between a client and server. A larger packet size can improve performance for multi-row fetches and fetches of larger rows, as well as inserting or retrieving BLOBs.

As always, however, there are tradeoffs with performance improvements. Since each connection has its own pool of buffers, a large buffer size also increases the memory usage. Be sure to analyze your particular situation to make sure that the benefits of increasing the CommBufferSize outweigh the costs.

For more information see Tuning TCP/IP performance, the CommBufferSize connection parameter [CBSIZE], or the -p server option.

Modifying the compression threshold

You can also adjust the compression threshold to improve Adaptive Server Anywhere performance. For most networks, the compression threshold does not need to be changed.

When compression is enabled, individual packets may or may not be compressed, depending on their size. For example, Adaptive Server Anywhere does not compress packets smaller than the compression threshold, even if communication compression is enabled. As well, small packets (less than about 100 bytes) usually do not compress at all. Since CPU time is required to compress packets, attempting to compress small packets could actually decrease performance.

Generally speaking, lowering the compression threshold value may improve performance on very slow networks, while raising the compression threshold may improve performance by reducing CPU usage. However, since lowering the compression threshold value will increase CPU usage on both the client and server, a performance analysis should be done to determine whether or not changing the compression threshold is beneficial.

For more information see CompressionThreshold connection parameter [COMPTH] and -pt server option.

toggle To adjust Adaptive Server Anywhere compression settings

  1. Enable communication compression.

    Large data transfers with highly compressible data and larger packet sizes tend to get the best compression rates.

    For more information about enabling compression, see Compress connection parameter [COMP] and -pc server option.

  2. Adjust the CommBufferSize setting.

    Increasing Adaptive Server Anywhere's packet size can improve compression performance.

    For more information about adjusting the CommBufferSize setting, see CommBufferSize connection parameter [CBSIZE] or -p server option.

  3. Adjust the CompressionThreshold setting.

    Lowering the compression threshold value may improve performance on very slow networks, while raising the compression threshold may improve performance by reducing CPU usage.

    For more information about adjusting the CompressionThreshold (COMPTH) connection parameter, see CompressionThreshold connection parameter [COMPTH] and -pt server option.


Troubleshooting network communications

Network software involves several different components, increasing the likelihood of problems. Although we provide some tips concerning network troubleshooting here, the primary source of assistance in network troubleshooting should be the documentation and technical support for your network communications software, as provided by your network communications software vendor.

Ensure that you are using compatible protocols
Ensure that you have current drivers
Testing the TCP/IP protocol
Diagnosing wiring problems
A checklist of common problems
Adjusting timeout values


Ensure that you are using compatible protocols

Ensure that the client and the database server are using the same protocol. The -x option for the server selects a list of protocols for the server to use, and the CommLinks (LINKS) connection parameter does the same for the client application.

You can use these options to ensure that each application is using the same protocol.

By default, the network database server uses all available protocols. The server supports client requests on any active protocol. By default, the client only uses the shared memory protocol. The client can use all available protocols by setting the CommLinks (LINKS) connection parameter to all.

For more information about the -x option, see the -x server option.

For information about the CommLinks (LINKS) connection parameter, see CommLinks connection parameter [LINKS].


Ensure that you have current drivers

Old network adapter drivers can be a source of communication problems. You should ensure that you have the latest version of your network adapter. You should be able to obtain current network adapter drivers from the manufacturer or supplier of the card.


Testing the TCP/IP protocol

The ping utility can be useful for testing that TCP/IP is installed and configured properly.

Using ping to test the IP layer

Each IP layer has an associated address—a four-integer, period-separated number (such as 191.72.109.12). Ping takes as an argument an IP-address and attempts to send a single packet to the address.

First, determine if your own machine is configured correctly by pinging yourself. If your IP-address is 191.72.109.12, you would type:

ping 191.72.109.12

at the command prompt and wait to see if the packets are routed at all. If they are, the output will appear similar to the following:

c:> ping 191.72.109.12
Pinging 191.72.109.12 with 32 bytes of data:
Reply from 191.72.109.12: bytes=32 time<.10ms TTL=32
Reply from 191.72.109.12: bytes=32 time<.10ms TTL=32
Reply from 191.72.109.12: bytes=32 time<.10ms TTL=32
...

If this works, it means that the computer is able to route packets to itself. This is reasonable assurance that the IP layer is set up correctly. You could also ask someone else running TCP/IP for their IP address and try pinging them.

You should ensure that you can ping the computer running the database server from the client computer before proceeding.


Diagnosing wiring problems

Faulty network wiring or connectors can cause problems that are difficult to track down. Try recreating problems on a similar machine with the same configuration. If a problem occurs on only one machine, it may be a wiring problem or a hardware problem.


A checklist of common problems

The following list presents some common problems and their solutions.

For information about troubleshooting connections to the database or database server, see Troubleshooting connections and Troubleshooting server startup.

If you receive the message Database server not found when trying to connect, the client cannot find the database server on the network. Check for the following problems:

  • Under the TCP/IP protocol, clients search for database servers by broadcasting a request. Such broadcasts will typically not pass through gateways, so any database server on a machine in another (sub)network, will not be found. If this is the case, you must supply the host name of the machine on which the server is running using the HOST (IP) protocol option.

  • A firewall between the client and server may be preventing the connection.

    For more information, see Connecting across a firewall.

  • Your network drivers are not installed properly or the network wiring is not installed properly.

  • If you receive the message Unable to initialize requested communication links, one ore more links failed to start. The probable cause is that your network drivers have not been installed. Check your network documentation to find out how to install the driver you wish to use.

  • The server use the TCP/IP protocol if you are connecting via jConnect.

  • If you are trying to connect to a database server on your local machine, make sure the Search Network For Database Servers option on the Database tab of the Connect dialog is cleared. You can select this option if you are trying to connect to a database server running on a machine other than your local machine.

For more information about network protocol options, see Network protocol options.


Adjusting timeout values

If you are experiencing problems with connections unexpectedly terminating, consider adjusting either the liveness or the idle timeout values.

For more information about liveness timeout values, see LivenessTimeout connection parameter [LTO], and the -tl server option.

For more information about connection timeouts, see the Idle connection parameter [IDLE], and the -ti server option.


Adaptive Server Anywhere as an Open Server

About this chapter

Adaptive Server Anywhere can appear to client applications as an Open Server. This feature enables Sybase Open Client applications to connect natively to Adaptive Server Anywhere databases.

This chapter describes how to use Adaptive Server Anywhere as an Open Server, and how to configure Open Client and Adaptive Server Anywhere to work together.

For information on developing Open Client applications for use with Adaptive Server Anywhere, see The Open Client Interface.

Open Clients, Open Servers, and TDS
Setting up Adaptive Server Anywhere as an Open Server
Configuring Open Servers
Characteristics of Open Client and jConnect connections


Open Clients, Open Servers, and TDS

This chapter describes how Adaptive Server Anywhere fits into the Sybase Open Client/Open Server client/server architecture. This section describes the key concepts of this architecture, and provides the conceptual background for the rest of the chapter.

If you simply wish to use a Sybase application with Adaptive Server Anywhere, you do not need to know any details of Open Client, Open Server, or TDS. However, an understanding of how these components fit together may be helpful for configuring your database and setting up applications. This section explains how the components fit together, but avoids any discussion of the internal features of the components.

Open Clients and Open Servers

Adaptive Server Anywhere and other members of the Adaptive Server family act as Open Servers. This means you can develop client applications using the Open Client libraries available from Sybase. Open Client includes both the Client Library (CT-Library) and the older DB-Library interfaces.

Tabular Data Stream

Open Clients and Open Servers exchange information using an application protocol called the tabular data stream (TDS). All applications built using the Sybase Open Client libraries are also TDS applications because the Open Client libraries handle the TDS interface. However, some applications (such as Sybase jConnect) are TDS applications even though they do not use the Sybase Open Client libraries—they communicate directly using the TDS protocol.

While many Open Servers use the Sybase Open Server libraries to handle the interface to TDS, some applications have a direct interface to TDS of their own. Sybase Adaptive Server Enterprise and Adaptive Server Anywhere both have internal TDS interfaces. They appear to client applications as an Open Server, but do not use the Sybase Open Server libraries.

Programming interfaces and application protocols

Adaptive Server Anywhere supports two application protocols. Open Client applications and other Sybase applications such as Replication Server and OmniConnect use TDS. ODBC and embedded SQL applications use a separate application protocol specific to Adaptive Server Anywhere.

TDS uses TCP/IP

Application protocols such as TDS sit on top of lower-level communications protocols that handle network traffic. Adaptive Server Anywhere supports TDS only over the TCP/IP network protocol. In contrast, the Adaptive Server Anywhere-specific application protocol supports several network protocols, as well as a shared memory protocol designed for same-machine communication.

Sybase applications and Adaptive Server Anywhere


Sybase applications and Adaptive Server Anywhere

The ability of Adaptive Server Anywhere to act as an Open Server enables Sybase applications such as Replication Server and OmniConnect to work with Adaptive Server Anywhere.

Replication Server support

The Open Server interface enables support for Sybase Replication Server: Replication Server connects through the Open Server interface, enabling Adaptive Server Anywhere databases to act as replicate sites in Replication Server installations.

For your database to act as a primary site in a Replication Server installation, you must also use the Replication Agent for Sybase Adaptive Server Anywhere, also called a Log Transfer Manager.

For information on the Replication Agent, see Replicating Data with Replication Server.

OmniConnect support

Sybase OmniConnect provides a unified view of disparate data within an organization, allowing users to access multiple data sources without having to know what the data looks like or where to find it. In addition, OmniConnect performs heterogeneous joins of data across the enterprise, enabling cross-platform table joins of targets such as DB2, Sybase Adaptive Server Enterprise, Oracle, and VSAM.

Using the Open Server interface, Adaptive Server Anywhere can act as a data source for OmniConnect.


Setting up Adaptive Server Anywhere as an Open Server

This section describes how to set up an Adaptive Server Anywhere server to receive connections from Open Client applications.


System requirements

There are separate requirements at the client and server for using Adaptive Server Anywhere as an Open Server.

Server-side requirements

You must have the following elements at the server side to use Adaptive Server Anywhere as an Open Server:

  • Adaptive Server Anywhere server components You must use the network server (dbsrv9.exe) if you want to access an Open Server over a network. You can use the personal server (dbeng9.exe) as an Open Server only for connections from the same machine.

  • TCP/IP You must have a TCP/IP protocol stack to use Adaptive Server Anywhere as an Open Server, even if you are not connecting over a network.

Client-side requirements

You need the following elements to use Sybase client applications to connect to an Open Server (including Adaptive Server Anywhere):

  • Open Client components The Open Client libraries provide the network libraries your application needs to communicate via TDS if your application uses Open Client.

  • jConnect If your application uses JDBC, you need jConnect and a Java runtime environment.

  • DSEdit You need DSEdit, the directory services editor, to make server names available to your Open Client application. On UNIX platforms, this utility is called sybinit.

    DSEdit is not included with SQL Anywhere Studio, but is included with Open Server software.


Starting the database server as an Open Server

If you wish to use Adaptive Server Anywhere as an Open Server, you must ensure that you start it using the TCP/IP protocol. By default, the server starts all available communications protocols, but you can limit the protocols started by listing them explicitly in the command. For example, the following commands are both valid:

dbsrv9 -x tcpip,spx asademo.db
dbsrv9 -x tcpip -n myserver asademo.db

The first command uses both TCP/IP and SPX protocols, of which TCP/IP is available for use by Open Client applications. The second line uses only TCP/IP.

You can use the personal database server as an Open Server for communications on the same machine because it supports the TCP/IP protocol.

The server can serve other applications through the TCP/IP protocol or other protocols using the Adaptive Server Anywhere-specific application protocol at the same time as serving Open Client applications over TDS.

Port numbers

Every application using TCP/IP on a machine uses a distinct TCP/IP port so that network packets end up at the right application. The default port for Adaptive Server Anywhere is port 2638. It is recommended that you use the default port number as Adaptive Server Anywhere has been granted that port number by the Internet Assigned Numbers Authority (IANA). If you wish to use a different port number, you can specify which one using the ServerPort (PORT) protocol option:

dbsrv9 -x tcpip(ServerPort=2629) -n myserver asademo.db

You may also need to supply an EngineName if more than one local database server is running, or if you wish to connect to a network server.

Open Client settings

To connect to this server, the interfaces file at the client machine must contain an entry specifying the machine name on which the database server is running, and the TCP/IP port it uses.

For details on setting up the client machine, see Configuring Open Servers.


Configuring Open Servers

Adaptive Server Anywhere can communicate with other Adaptive Servers, Open Server applications, and client software on the network. Clients can talk to one or more servers, and servers can communicate with other servers via remote procedure calls. For products to interact with one another, each needs to know where the others reside on the network. This network service information is stored in the interfaces file.

The interfaces file
Using the DSEdit utility
Starting DSEdit
Opening a Directory Services session
Adding a server entry
Adding or changing the server address
Verifying the server address
Renaming a server entry
Deleting server entries
Configuring servers for JDBC


The interfaces file

The interfaces file is usually named sql.ini on PC operating systems and interfaces, or interfac on UNIX operating systems.

Like an address book, the interfaces file lists the name and address of every database server known to Open Client applications on your machine. When you use an Open Client program to connect to a database server, the program looks up the server name in the interfaces file and then connects to the server using the address.

The name, location, and contents of the interfaces file differ between operating systems. Also, the format of the addresses in the interfaces file differs between network protocols.

When you install Adaptive Server Anywhere, the setup program creates a simple interfaces file that you can use for local connections to Adaptive Server Anywhere over TCP/IP. It is the System Administrator's responsibility to modify the interfaces file and distribute it to users so that they can connect to Adaptive Server Anywhere over the network.


Using the DSEdit utility

The DSEdit utility is a Windows utility that allows you to configure the interfaces file (SQL.ini). The following sections explain how to use the DSEdit utility to configure the interfaces file.

These sections describe how to use DSEdit for those tasks required for Adaptive Server Anywhere. It is not complete documentation for the DSEdit utility.

For more information on DSEdit, see the Utility Programs book for your platform, included with other Sybase products.


Starting DSEdit

The DSEdit executable is located in the SYBASE\bin directory, which is added to your path on installation. You can start DSEdit either from a command prompt or from the Explorer in the standard fashion.

When you start DSEdit, the Select Directory Service dialog appears.

The Select Directory Service dialog showing the Directory Service name highlighted.


Opening a Directory Services session

The Select Directory Service window allows you to open a session with a directory service. You can open a session to edit the interfaces file (SQL.ini), or any directory service that has a driver listed in the libtcl.cfg file.

toggle To open a session

  • Click the local name of the directory service you want to connect to, as listed in the DS Name box, and click OK.

    For Adaptive Server Anywhere, select the InterfacesDriver.

SYBASE environment variable must be set
The DSEdit utility uses the SYBASE environment variable to locate the libtcl.cfg file. If the SYBASE environment variable is incorrect, DSEdit cannot locate the libtcl.cfg file.
The Interfaces Driver window showing fields where you can provide attributes and values for servers.

You can add, modify, or delete entries for servers, including Adaptive Server Anywhere servers, in this window.


Adding a server entry

toggle To add a server entry

  1. Choose Add from the Server Object menu.

    The Input Server Name window appears.

  2. Type a server name in the Server Name box, and click OK to enter the server name.

    The server name entry must match the server name you used to start Adaptive Server Anywhere. The server address is used to identify and locate the server. The server name field is an identifier for Open Client. For Adaptive Server Anywhere, if the server has more than one database loaded, the DSEdit server name entry identifies which database to use.

    The server entry appears in the Server box. To specify the attributes of the server, you must modify the entry.


Adding or changing the server address

Once you have entered a Server Name, you need to modify the Server Address to complete the interfaces file entry.

toggle To enter a Server Address

  1. Select a server entry in the Server box.

  2. Right-click the Server Address in the Attributes box.

  3. Choose Modify Attribute from the popup menu. A window appears, showing the current value of the address. If you have no address entered, the box is empty.

    The Network Address Attribute window, showing the Protocol Network Address box where the server address appears.

  4. Click Add.

    The Input Network Address for Protocol window appears.

  5. Select NLWNSCK from the Protocol list box (this is the TCP/IP protocol) and enter a value in the Network Address text box.

    The Input Network Address for Protocol dialog showing the network address for the NLWNSCK protocol.

    For TCP/IP addresses, use one of the following two forms:

    • computer name, port number

    • IP-address, portnumber

    The address or computer name is separated from the port number by a comma.

Machine name

A name (or an IP address) identifies the machine on which the server is running. On Windows operating systems, you can find the machine name in Network Settings, in the Control Panel.

If your client and server are on the same machine, you must still enter the machine name. In this case, you can use localhost to identify the current machine.

Port number

The port number you enter must match the port number you used to start the Adaptive Server Anywhere database server with, as described in Starting the database server as an Open Server. The default port number for Adaptive Server Anywhere servers is 2638. This number has been assigned to Adaptive Server Anywhere by the Internet Adapter Number Authority (IANA), and use of this port is recommended unless you have good reasons for explicitly using another port.

The following are valid server address entries:

elora,2638
123.85.234.029,2638


Verifying the server address

You can verify your network connection using the Ping command from the Server Object menu.

Database connections not verified
Verifying a network connection confirms that a server is receiving requests on the machine name and port number specified. It does not verify anything about database connections.
toggle To ping a server

  1. Ensure that the database server is running.

  2. Click the server entry in the Server box of the DSEdit session window.

  3. Choose Ping Server from the Server Object menu.

    The Ping window appears.

  4. Select the address you want to ping. Click Ping.

    A message box appears, notifying you whether or not the connection is successful. A message box for a successful connection states that both Open Connection and Close Connection succeeded.


Renaming a server entry

You can rename server entries from the DSEdit session window.

toggle To rename a server entry

  1. Select a server entry in the Server box.

  2. Choose Rename from the Server Object menu.

    The Input Server Name window appears.

  3. Type a new name for the server entry in the Server Name box.

  4. Click OK to make the change.


Deleting server entries

You can delete server entries from the DSEdit session window.

toggle To delete a server entry

  1. Click a server entry in the Server box.

  2. Choose Delete from the Server Object menu.


Configuring servers for JDBC

The JDBC connection address (URL) contains all the information required to locate the server.

For information on the JDBC URL, see Supplying a URL for the server.


Characteristics of Open Client and jConnect connections

When Adaptive Server Anywhere is serving applications over TDS, it automatically sets relevant database options to values compatible with Adaptive Server Enterprise default behavior. These options are set temporarily, for the duration of the connection only. The client application can override them at any time.

Default settings

The database options set on connection using TDS include:

Option | Set to
ALLOW_NULLS_BY_DEFAULT | OFF
ANSI_BLANKS | ON
ANSINULL | OFF
AUTOMATIC_TIMESTAMP | ON
CHAINED | OFF
CLOSE_ON_ENDTRANS | OFF
DATE_FORMAT | YYYY-MM-DD
DATE_ORDER | MDY
ESCAPE_CHARACTER | OFF
FLOAT_AS_DOUBLE | ON
ISOLATION_LEVEL | 1
ON_TSQL_ERROR | CONTINUE
QUOTED_IDENTIFIER | OFF
TIME_FORMAT | HH:NN:SS.SSS
TIMESTAMP_FORMAT | YYYY-MM-DD HH:NN:SS.SSS
TSQL_HEX_CONSTANT | ON
TSQL_VARIABLES | ON
How the startup options are set

The default database options are set for TDS connections using a system procedure named sp_tsql_environment. This procedure sets the following options:

SET TEMPORARY OPTION Allow_nulls_by_default='OFF';
SET TEMPORARY OPTION Ansi_blanks='ON';
SET TEMPORARY OPTION Ansinull='OFF';
SET TEMPORARY OPTION Automatic_timestamp='ON';
SET TEMPORARY OPTION Chained='OFF';
SET TEMPORARY OPTION Close_on_endtrans='OFF';
SET TEMPORARY OPTION Date_format='YYYY-MM-DD';
SET TEMPORARY OPTION Date_order='MDY';
SET TEMPORARY OPTION Escape_character='OFF';
SET TEMPORARY OPTION Float_as_double='ON';
SET TEMPORARY OPTION Isolation_level='1';
SET TEMPORARY OPTION On_tsql_error='CONTINUE';
SET TEMPORARY OPTION Quoted_identifier='OFF';
SET TEMPORARY OPTION Time_format='HH:NN:SS.SSS';
SET TEMPORARY OPTION Timestamp_format='YYYY-MM-DD HH:NN:SS.SSS';
SET TEMPORARY OPTION Tsql_hex_constant='ON';
SET TEMPORARY OPTION Tsql_variables='ON';
Do not edit the sp_tsql_environment procedure
Do not alter the sp_tsql_environment procedure yourself. It is for system use only.

The procedure sets options only for connections that use the TDS communications protocol. This includes Open Client and JDBC connections using jConnect. Other connections (ODBC and embedded SQL) have the default settings for the database.

You can change the options for TDS connections.

toggle To change the option settings for TDS connections

  1. Create a procedure that sets the database options you want. For example, you could use a procedure such as the following:

    CREATE PROCEDURE my_startup_procedure()
BEGIN
  IF connection_property('CommProtocol')='TDS' THEN
    SET TEMPORARY OPTION QUOTED_IDENTIFIER='OFF';
  END IF
END

    This particular procedure example changes only the QUOTED_IDENTIFIER option from the default setting.

  2. Set the LOGIN_PROCEDURE option to the name of a new procedure:

    SET OPTION LOGIN_PROCEDURE= 'DBA.my_startup_procedure'

Future connections will use the procedure. You can configure the procedure differently for different user IDs.

For more information about database options, see Database Options.


The Database Server

About this chapter

This chapter describes the command line options for the Adaptive Server Anywhere database server.

The database server


The Database Server

The database server

Function

Start a personal database server or network database server.

Syntax

{ dbeng9 | dbsrv9 }
[ server-options ] [ database-file [ database-options ] ...]

NetWare syntax

load dbsrv9 [ server-options ] [ database-file [ database-options ] ...]

Server options
Server option | Description
@@data | Read in options from a configuration file or environment variable. See @data server option.
-? | Display usage information. See -? server option.
-b | Run in bulk operations mode. See -b server option.
-c size | Set initial cache size. See -c server option.
-ca 0 | Disable dynamic cache sizing [Windows NT/2000/XP, Windows 95/98/Me, UNIX]. See -ca server option.
-cc { + | - } | Collect information about database pages to be used for cache warming. See -cc server option.
-ch size | Set the cache size upper limit [Windows NT/2000/XP, Windows 95/98/Me]. See -ch server option.
-cl size | Set the cache size lower limit [Windows NT/2000/XP]. See -cl server option.
-cr { + | - } | Warm the cache with database pages. See -cr server option.
-cs | Display cache usage in database server window. See -cs server option.
-ct { + | - } | Turn character-set translation on and off [not NetWare or Windows CE]. See -ct server option.
-cv { + | - } | Control the appearance of messages about cache warming in the database server window. See -cv server option.
-cw | Enable use of Address Windowing Extensions on Windows 2000, Windows XP, and Windows Server 2003 for setting the size of the database server cache. See -cw server option.
-d | Use POSIX I/O [NetWare]. See -d server option.
-ec encryption-options | Enable packet encryption [network server]. See -ec server option.
-ep | Prompt for encryption key. See -ep server option.
-fc | Specify the filename of a DLL containing the file system full callback function. See -fc server option.
-fips | Requires that only FIPS-approved algorithms should be used for strong database and communication encryption. See -fips server option.
-ga | Automatically unload the database after the last connection closed. In addition, shut down after the last database is closed [not NetWare]. See -ga server option.
-gb level | Set database process priority class to level [Windows NT/2000/XP]. See -gb server option.
-gc num | Set maximum checkpoint timeout period to num minutes. See -gc server option.
-gd level | Set database starting permission. See -gd server option.
-ge size | Set the stack size for threads that run external functions. See -ge server option.
-gf | Disable firing of triggers. See -gf server option.
-gk level | Set the permission required to stop the server. See -gk server option.
-gl level | Set the permission required to load or unload data. See -gl server option.
-gm num | Set the maximum number of connections. See -gm server option.
-gn num | Set the maximum number of concurrent requests the database server can handle at one time. See -gn server option.
-gp size | Set the maximum page size to size bytes. See -gp server option.
-gr minutes | Set the maximum recovery time to num minutes. See -gr server option.
-gss size | Set the thread stack size to size bytes [not applicable to Windows]. See -gss server option.
-gt num | Set the number of operating processors used by the database server to num processors. See -gt server option.
-gu level | Set the permission level for utility commands: utility_db, all, none, or DBA. See -gu server option.
-gx | Set the number of operating system threads assigned to the database server process [Windows NT/2000/XP, Windows 95/98/Me]. See -gx server option.
-m | Truncate the transaction log after each checkpoint for all databases. See -m server option.
-n name | Use name as the name of the database server. Note that the -n option is positional. See -n server option.
-o filename | Output messages to the specified file. See -o server option.
-oe filename | Specify file to log startup errors, fatal errors and assertions to. See -oe server option.
-os size | Limit the size of the log file for messages. See -os server option.
-p packet-size | Set the maximum network packet size [network server]. See -p server option.
-pc | Compress all connections except same-machine connections. See -pc server option.
-pt size_in_bytes | Set the minimum network packet size to compress. See -pt server option.
-qi | Do not display database server tray icon or screen. See -qi server option.
-qp | Suppress messages about performance in the database server window. See -qp server option.
-qs | Suppress startup error dialogs. See -qs server option.
-qw | Do not display the database server screen. See -qw server option.
-r | Opens database in read-only mode. See -r server option.
-s | Set the syslog facility ID [UNIX]. See -s server option.
-sb { 0 | 1 } | Specify how the server reacts to broadcasts. See -sb server option.
-sc | Disable the shared memory port, and enable Named Pipes. [Windows NT/2000/XP]. See -sc server option.
-ti minutes | Client idle time before shutdown—default 240 minutes. See -ti server option.
-tl seconds | Default liveness timeout for clients in seconds—default 120 seconds. See -tl server option.
-tmf | Force transaction manager recovery for distributed transactions [Windows NT/2000/XP]. See -tmf server option.
-tmt milliseconds | Set the reenlistment timeout for distributed transactions [Windows NT/2000/XP]. See -tmt server option.
-tq time | Set quitting time [network server]. See -tq server option.
-u | Use buffered disk I/O. See -u server option.
-ua | Turn off use of asynchronous I/O [Linux]. See -ua server option.
-uc |
-ud | Run as a daemon [UNIX]. See -ud server option.
-ui |
-ut minutes | Touch temporary files every min minutes [UNIX]. See -ut server option.
-ux | Display the Server Messages window and Server Startup Options dialog [Linux and Solaris only]. See -ux server option.
-v | Display database server version and stop. See -v server option.
-x list | Comma-separated list of communication links to try. See -x server option.
-xs | Specify server side web services communications protocols. See -xs server option.
-y | Run as a Windows 95/98/Me service [Windows 95/98/Me]. See -y server option.
-z | Provide diagnostic information on communication links [network server]. See -z server option.
-zl | Turn on capturing of the most recently-prepared SQL statement for each connection. See -zl server option.
-zn | Specifies the number of request log file copies to retain. See -zn server option.
-zo filename | Redirect request logging information to a separate file. See -zo server option.
-zr { all | SQL | none } | Turn on logging of SQL operations. The default is NONE. See -zr server option.
-zs size | Limit the size of the log file used for request logging. See -zs server option.
Recovery options
Recovery Option | Description
-a filename | Apply the named transaction log file. See -a recovery option.
-f | Force the database to start without a transaction log. See -f recovery option.
Database options
Database Option | Description
-ek key | Specify encryption key. See -ek database option.
-m | Truncate (delete) the transaction log after each checkpoint for the specified database. See -m database option.
-n name | Name the database. Note that the -n option is positional. See -n database option.
-r | Open the specified database(s) in read-only mode. Database modifications not allowed. See -r database option.
Description

The dbeng9 command starts a personal database server. The dbsrv9 command starts a network database server.

Cache size

The amount of cache memory available to the database server can be a key factor in affecting performance. The database server takes an initial amount of cache memory that is either specified by the -c option or is a default value.

For information on the default cache size, see -c server option.

On Windows NT/2000/XP, Windows 95/98/Me, and UNIX, the database server automatically takes more memory for use in the cache as needed, as determined by a heuristic algorithm.

For more information, see Using the cache to improve performance.

You can use database options to configure the upper cache limit: see -ch server option. As well, you can force the cache to remain at its initial amount: see -ca server option.

Server differences

The personal database server has a maximum of ten concurrent connections, uses at most one CPU for request processing, and does not support network client/server connections.

In addition, there are other minor differences, such as the default permission level that is required to start new databases, or the permissions required to execute the CHECKPOINT statement.

Platform availability

Both personal and network database servers are supplied for each supported operating system, with the following exceptions:

  • Novell NetWare Only the network server is supplied.

  • Windows CE Only the network server is supplied. The support for TCP/IP in the network server enables you to carry out tasks from your desktop machine, including database management, with Sybase Central.

Note
It is recommended that you run the network database server on Windows NT/2000/XP or Windows 2003, rather than Windows 95/98/Me, to ensure better performance and reliability.
NetWare notes

In NetWare, the database file and the transaction log file must be on a NetWare volume, and the paths must be fully specified. NetWare allows you to have volumes that span two or more hard disks.

Database file The database-file specifies the database filename. If database-file is specified without a file extension, Adaptive Server Anywhere looks first for database-file with extension .wrt (a write file), followed by database-file with extension .db.

If you use a relative path, it is read relative to the current working directory. You can supply a full path. Also, you can supply a path that conforms to the Universal Naming Convention (UNC) format:

\\server\volume\path\file.ext
Suppressing Windows event log messages

If you run the database server as a Windows service, you can suppress Windows event log entries by setting a registry entry. The registry entry is

Software\Sybase\Adaptive Server Anywhere\9.0

To control event log entries, set the EventLogMask key, which is of type REG_DWORD. The value is a bit mask containing the internal bit values for the different types of event messages:

errors        EVENTLOG_ERROR_TYPE         0x0001
warnings    EVENTLOG_WARNING_TYPE         0x0002
information EVENTLOG_INFORMATION_TYPE  0x0004

For example, if the EventLogMask key is set to zero, no messages appear at all. A better setting would be 1, so that informational and warning messages do not appear, but errors do. The default setting (no entry present) is for all message types to appear.

See also
  • Running the Database Server
  • Network protocol options
Operating quietly

The database server supports quiet mode. You determine how quiet you want the server to operate, ranging from suppressing messages or the icon in the system tray, to complete silence. To operate a completely silent database server on Windows, specify the -qi and -qs options. With these options set, there is no visual indication that the server is running as all icons and all possible startup error messages are suppressed. If you run the database server in quiet mode, you can use either (or both) the -o or -oe options to diagnose errors.

Note that the -qi and -qs options do not suppress error dialogs caused by the -v (version) and -ep (prompt for database encryption password) server options.


Database server options

These options apply to the server as a whole, not just to an individual database.

@data server option
-? server option
-b server option
-c server option
-ca server option
-cc server option
-ch server option
-cl server option
-cr server option
-cs server option
-ct server option
-cv server option
-cw server option
-d server option
-ec server option
-ep server option
-fc server option
-fips server option
-ga server option
-gb server option
-gc server option
-gd server option
-ge server option
-gf server option
-gk server option
-gl server option
-gm server option
-gn server option
-gp server option
-gr server option
-gss server option
-gt server option
-gu server option
-gx server option
-m server option
-n server option
-o server option
-oe server option
-os server option
-p server option
-pc server option
-pt server option
-qi server option
-qp server option
-qs server option
-qw server option
-r server option
-s server option
-sb server option
-sc server option
-ti server option
-tl server option
-tmf server option
-tmt server option
-tq server option
-u server option
-ua server option
-uc server option
-ud server option
-ui server option
-ut server option
-ux server option
-v server option
-x server option
-xs server option
-y server option
-z server option
-zl server option
-zn server option
-zo server option
-zr server option
-zs server option


@data server option
Function

Read in options from the specified environment variable or configuration file

Syntax

{ dbsrv9 | dbeng9 } @data ...

Applies to

All operating systems and servers, as well as all database utilities except Interactive SQL (dbisql), the Language utility (dblang), the Adaptive Server Anywhere Console utility (dbconsole), the Rebuild utility (rebuild), the Certificate Generation utility (gencert), the Certificate Reader utility (readcert), the ActiveSync provider install utility (dbasinst), and the File Hiding utility (dbfhide).

Description

Use this option to read in command-line options from the specified environment variable or configuration file. If both exist with the same name that is specified, the environment variable is used.

Configuration files can contain line breaks, and can contain any set of options.

For more information about using configuration files, see Using configuration files.

If you want to protect the information in a configuration file (for example, because it contains passwords) you can use the File Hiding (dbfhide) utility to obfuscate the contents of configuration files.

For more information about the File Hiding utility, see The File Hiding utility.

The @data parameter can occur at any point in the command line, and parameters contained in the file are inserted at that point. Multiple files can be specified, and the file specifier can be used with command line options.

All @data parameters will be left untouched if they occur after the -w option. This can be useful, for example, if you want to use the Service Creation utility [dbsvc] to create a service where the database server reads the parameter file itself.

Examples

The following reads all parameters from dbinit.in.

dbinit @dbinit.in

The following example is the same as dbinit -q -ja -p 2048 -b new.db

echo "-ja -p 2048" > dbinit.in
dbinit -q @dbinit.in -b new.db

In the following example, dbsvc_parms will be read by dbsvc, but dbsrv_parms will not. The service will be created with the command line dbsrv9.exe @dbsrv_parms.

dbsvc @dbsvc_parms -w mysvc dbsrv9.exe @dbsrv_parms

The following configuration file holds a set of options for a server named myserver that starts with a cache size of 4 Mb and loads the sample database:

-c 4096
-n myserver
"c:\Program Files\Sybase\SQL Anywhere 9\asademo.db"

If this configuration file is saved as c:\config.txt, it can be used in a command as follows:

dbsrv9 @c:\config.txt

The following configuration file contains comments:

#This is the server name:
-n MyServer
#These are the protocols:
-x tcpip
#This is the database file
my.db

The following statement, entered all on one line, sets an environment variable that holds options for a database server that starts with a cache size of 4 Mb and loads the sample database.

set envvar=-c 4096 "c:\Program Files\Sybase\SQL Anywhere 9\asademo.db"

This statement starts the database server using an environment variable named envvar.

dbsrv9 @envvar


-? server option
Function

Display usage information.

Syntax

{ dbsrv9 | dbeng9 } -?

Applies to

All operating systems and servers.

Description

Displays a short description of each server option. The database does not carry out any other task.


-b server option
Function

Use bulk operation mode.

Syntax

{ dbsrv9 | dbeng9 } -b ...

Applies to

All operating systems and servers.

Description

This is useful for using the Interactive SQL INPUT command to load large quantities of data into a database.

The -b option should not be used if you are using LOAD TABLE to bulk load data.

When you use this option, the database server allows only one connection by one application. It keeps a rollback log, but it does not keep a transaction log. The multi-user locking mechanism is turned off.

When you first start the database server after loading data with the -b option, you should use a new log file.

Bulk operation mode does not disable the firing of triggers.


-c server option
Function

Set the initial memory reserved for caching database pages and other server information.

Syntax

{ dbsrv9 | dbeng9 } -c { integer | integer G | integer K | integer M | integer P } ...

Applies to

All operating systems and servers.

Description

The amount of memory available for use as a database server cache is one of the key factors controlling performance. You can set the initial amount of cache memory using the -c server option

The more cache memory that can be given the server, the better its performance.

The units G, K, and M can be either lower case or upper case. If G, K, or M is not supplied, any integer less than 10 000 is assumed to be in kilobytes, and any integer 10 000 or greater is assumed to be in bytes. For example, -c 4096 means 4096 kb or 4 194 304 bytes, whereas -c 200 000 means (an unreasonably small) cache of 200 000 bytes.

The unit P is a percentage of the physical system memory, and if you use this, the argument is a percentage. You can use % as an alternative to P, but as most non-UNIX operating systems use % as an environment variable escape character, you must escape the % character. To use 50 percent of the physical system memory, you would use the following:

dbeng9 -c 50%% ...

On NetWare and UNIX operating systems, if the cache size specified with -c is greater than the amount of available memory, the database server uses a maximum cache size that is calculated as follows:

95% of (available memory - 5 MB)

On Windows CE, if the cache size specified with -c is greater than the amount of available memory, the database server uses a maximum cache size that is calculated as follows:

95% of (available memory - 2 MB)

If no -c option is provided, the database server computes the initial cache allocation as follows:

  1. It uses the following operating-system-specific default cache sizes:

    • Windows CE 600K

    • Windows NT/2000/XP, Windows 95/98/Me, NetWare 2 Mb

    • UNIX 8 Mb

  2. It computes a runtime-specific minimum default cache size, which is the lesser of the following items:

    • 25% of the machine's physical memory

    • The sum of the sizes of the main database files specified on the command line. Additional dbspaces apart from the main database files are not included in the calculation. If no files are specified, this value is zero.

  3. It allocates the greater of the two values computed.

NetWare database server
There is a tradeoff between memory for the database server and memory for the NetWare file system buffers. A larger database server cache will improve database server performance at the expense of NetWare file system performance. If the database server cache is too big, NetWare will report an error that there is insufficient memory for cache buffers.

NetWare memory requirements increase with every new directory and file on the file server. To track memory usage on the NetWare server, load monitor.nlm (if it is not already loaded) and select "Resource Utilization". Extra memory for your NetWare server computer could improve database performance and/or file server performance dramatically.

Example

The following example, entered all on one line, starts a server named myserver that starts with a cache size of 3 Mb and loads the sample database:

dbeng9 -c 3M -n myserver "C:\Program Files\Sybase\SQL Anywhere 9\asademo.db"
See also
  • -ch server option


-ca server option
Function

Enforce a static cache size. The zero argument is required.

Syntax

{ dbsrv9 | dbeng9 } -ca 0 ...

Applies to

Windows NT/2000/XP, Windows 95/98/Me, UNIX

Description

You can disable automatic cache increase because of high server load by specifying -ca 0 on the command line. If you do not set -ca 0, the database server automatically takes additional cache as needed. The cache size still increases if the database server would otherwise run into the error Fatal Error: dynamic memory exhausted, or if the Java VM requires memory that would lead to a fatal error.

This server option should be used only in the form -ca 0. If 0 is omitted, automatic cache growth is enabled.

Example

The following example starts a server named myserver that has a static cache that is 40% of the available physical memory and loads the sample database:

dbsrv9 -c 40P -ca 0 -n myserver "C:\Program Files\Sybase\SQL Anywhere 9\asademo.db"
See also
  • -c server option
  • -ch server option


-cc server option
Function

Collect information about database pages to be used for cache warming the next time the database is started.

Syntax

{ dbsrv9 | dbeng9 } -cc { + | - } ...

Applies to

All operating systems and servers.

Description

By default, page collection is turned on. When collection is turned on, the database server keeps track of each database page that is requested. Collection stops when the maximum number of pages has been collected, the database is shut down, or the collection rate falls below the minimum value. Note that you cannot configure the maximum number of pages collected or specify the value for the collection rate (the value is based on cache size and database size). Once collection stops, information about the requested pages is recorded in the database so those pages can be used to warm the cache the next time the database is started with the -cr option. Collection of referenced pages is turned on by default.

See also
  • -cr server option
  • -cv server option
  • Using cache warming


-ch server option
Function

Sets a maximum cache size, as a limit to automatic cache growth.

Syntax

{ dbsrv9 | dbeng9 } -ch { integer | integer G | integer K | integer M | integer P } ...

Applies to

Windows NT/2000/XP, Windows 95/98/Me, UNIX

Description

This option limits the cache that the database server can take during automatic cache growth. By default the upper limit is approximately the lower of 256 Mb and 90% of the physical memory of the machine.

The units G, K, and M can be either lower case or upper case. If G, K, or M is not supplied, any integer less than 10 000 is assumed to be in kilobytes, and any integer 10 000 or greater is assumed to be in bytes. For example, -ch 4096 means 4096 kb or 4 194 304 bytes, whereas -ch 200 000 means (an unreasonably small) maximum cache of 200 000 bytes.

The unit P is a percentage of the physical system memory, and if you use this, the argument is a percentage. You can use % as an alternative to P, but as most non-UNIX operating systems use % as an environment variable escape character, you must escape the % character. To use limit the cache to 50 percent of the physical system memory, you would use the following:

dbeng9 -ch 50%% ...
Example

The following example starts a server named silver that has a maximum cache size of 2 Mb and loads the sample database:

dbeng9 -ch 2M -n silver "C:\Program Files\Sybase\SQL Anywhere 9\asademo.db"
See also
  • -c server option
  • -ca server option
  • -cl server option


-cl server option
Function

Set a minimum cache size as a lower limit to automatic cache resizing.

Syntax

{ dbsrv9 | dbeng9 } -cl { integer | integer G | integer K | integer M | integer P } ...

Applies to

Windows NT/2000/XP, Windows 95/98/Me, UNIX

Description

This option sets a lower limit to the cache. The default minimum cache size is the initial cache size.

The units G, K, and M can be either lower case or upper case. If G, K, or M is not supplied, any integer less than 10 000 is assumed to be in kilobytes, and any integer 10 000 or greater is assumed to be in bytes. For example, -cl 4096 means 4096 kb or 4 194 304 bytes, whereas -cl 200 000 means a minimum cache of 200 000 bytes.

The unit P is a percentage of the physical system memory, and if you use this, the argument is a percentage. You can use % as an alternative to P, but as most non-UNIX operating systems use % as an environment variable escape character, you must escape the % character. To set the minimum cache size to 50 percent of the physical system memory, you would use the following:

dbeng9 -cl 50%% ...
Example

The following example starts a server named silver that has a minimum cache size of 5 Mb and loads the sample database:

dbeng9 -cl 5M -n silver "C:\Program Files\Sybase\SQL Anywhere 9\asademo.db"
See also
  • -c server option
  • -ca server option
  • -ch server option


-cr server option
Function

Reload (warm) the cache with database pages using information collected the last time the database was run.

Syntax

{ dbsrv9 | dbeng9 } -cr { + | - } ...

Applies to

All operating systems and servers.

Description

You can instruct the database server to warm the cache using pages that were referenced the last time the database was started (page collection is turned on using the -cc option). Cache warming is turned on by default. When a database is started, the server checks the database to see if it contains a collection of pages requested the last time the database was started. If the database contains this information, the previously-referenced pages are then loaded into the cache.

Warming the cache with pages that were referenced the last time the database was started can improve performance when the same query or similar queries are executed against a database each time it is started.

See also
  • -cc server option
  • -cv server option
  • Using cache warming


-cs server option
Function

Display cache size changes in the database server window.

Syntax

{ dbsrv9 | dbeng9 } -cs ...

Applies to

All platforms with dynamic cache sizing.

Description

For troubleshooting purposes, display cache information in the database server window whenever the cache size changes.


-ct server option
Function

Turn character set translation on and off.

Syntax

{ dbsrv9 | dbeng9 } -ct { + | - } ...

Applies to

All operating systems except Windows CE.

Description

By default, character set translation is turned on. Character set translation converts strings between character sets that represent the same characters, but at different values. This is useful when the client machine and the database use different character sets. Character set translation is disabled with the -ct- server option. If this argument is supplied as -ct+, character set translation is turned on.

In version 7.x and earlier of Adaptive Server Anywhere, the + or - values are not accepted: specifying the -ct option enabled character set translation.

Example

The following example starts a server with character set translation disabled and loads the sample database:

dbeng9 -ct- "C:\Program Files\Sybase\SQL Anywhere 9\asademo.db"
See also
  • Turning off character set translation on a database server
  • Starting a database server using character set translation


-cv server option
Function

Control the appearance of messages about cache warming in the database server window.

Syntax

{ dbsrv9 | dbeng9 } -cv { + | - } ...

Applies to

All operating systems and servers.

Description

When -cv+ is specified, a message appears in the database server window when any of the following cache warming activities occur:

  • collection of requested pages starts or stops (controlled by the -cc server option)

  • page reloading starts or stops (controlled by the -cr server option)

By default, this option is turned off.

Example

The following command starts a database called mydatabase.db with database page collection and page loading turned on, and logs messages about these activities to the database server window:

dbsrv9 -cc+ -cr+ -cv+ mydatabase.db
See also
  • -cc server option
  • -cr server option
  • Using cache warming


-cw server option
Function

Enable use of Address Windowing Extensions (AWE) on Windows 2000, Windows XP, and Windows Server 2003 for setting the size of the database server cache.

Syntax

{ dbsrv9 | dbeng9 } -cw ...

Applies to

Windows 2000, Windows XP, Windows Server 2003, and later.

Description

The amount of memory available for use as a database server cache is one of the key factors controlling performance. Because Windows 2000, Windows XP, and Windows Server 2003 support Address Windowing Extensions, you can use the -cw option to take advantage of large cache sizes based on the maximum amount of physical memory in the system.

Operating system | Maximum non-AWE cache size | Maximum amount of physical memory supported by Windows
Windows 2000 Professional | 1.8 Gb | 4 Gb
Windows 2000 Server | 1.8 Gb | 4 Gb
Windows 2000 Advanced Server | 2.7 Gb* | 8 Gb
Windows 2000 Datacenter Server | 2.7 Gb* | 64 Gb
Windows XP Home Edition | 1.8 Gb | 2 Gb
Windows XP Professional | 1.8 Gb | 4 Gb
Windows Server 2003, Web Edition | 1.8 Gb | 2 Gb
Windows Server 2003, Standard Edition | 1.8 Gb | 4 Gb
Windows Server 2003, Enterprise Edition | 2.7 Gb* | 32 Gb
Windows Server 2003, Datacenter Edition | 2.7 Gb* | 64 Gb

*You must boot the operating system using the /3GB option to use a cache of this size.

When using an AWE cache, almost all of the available physical memory in the system can be allocated for the cache.

If you can set a cache of the desired size using a non-AWE cache, this is recommended because AWE caches allocate memory that can only be used by the database server. This means that while the database server is running, the operating system and other applications cannot use the memory allocated for the database server cache. AWE caches do not support dynamic cache sizing. Therefore, if an AWE cache is used and you specify the -ch or -cl options to set the upper and lower cache size, they are ignored.

For information about specifying the cache size, see -c server option.

To start a database server with an AWE cache, you must do the following:

  • Have at least 130 Mb of memory available on your system.

  • If your system has between 2 Gb and 16 Gb of memory, add the /3GB option to the Windows boot line in the "[operating systems]" section of the boot.ini file.

    If your system has more than 16 Gb of memory, do not add the /3GB option to the Windows boot line in the "[operating systems]" section of the boot.ini file because Windows will not be able to address memory beyond 16 Gb.

  • If your system has more than 4 Gb of memory, add the /PAE option to the Windows boot line in the "[operating systems]" section of the boot.ini file.

  • Grant the "Lock pages in memory" privilege to the user ID under which the server is run. The following steps explain how to do this on Windows 2000.

    1. Log on to Windows as Administrator.

    2. From the Start menu, choose Settings > Control Panel.

    3. Open the Administrative Tools folder.

    4. Double-click Local Security Policy.

    5. Open Local Policies in the left pane.

    6. Double-click User Rights Assignment in the left pane.

    7. Double-click the Lock Pages In Memory policy in the right pane.

      The Local Security Policy Setting dialog appears.

    8. In the Local Security Policy Setting dialog, click Add.

      The Select Users or Groups dialog appears.

    9. Select the user ID from the list and click Add.

    10. In the Local Security Policy Setting dialog, click OK.

    11. Restart the computer for the setting to take effect.

If you specify the -cw option and the -c option on the command line, the database server attempts the initial cache allocation as follows:

  1. The AWE cache is no larger than the cache size specified by the -c option. If the value specified by the -c option is less than 2 Mb, AWE is not used.

  2. The AWE cache is no larger than all available physical memory less 128 Mb.

  3. The AWE cache is no smaller than 2 Mb. If this minimum amount of physical memory is not available, an AWE cache is not used.

When you specify the -cw option and do not specify the -c option, the database server attempts the initial cache allocation as follows:

  1. The AWE cache uses 100% of all available memory except for 128 Mb that is left free for the operating system.

  2. The AWE cache is no larger than the sum of the sizes of the main database files specified on the command line. Additional dbspaces apart from the main database files are not included in the calculation. If no files are specified, this value is zero.

  3. The AWE cache is no smaller than 2 Mb. If this minimum amount of physical memory is not available, an AWE cache is not used.

When the server uses an AWE cache, the cache page size is at least 4 kb and dynamic cache sizing is disabled. On 64-bit Windows platforms, the cache page size is at least 8 kb.

For more information about dynamic cache sizing, see Using the cache to improve performance.

Example

The following example starts a server named myserver that starts with a cache size of 12 Gb and loads the sample database:

dbeng9 -c 12G -cw asademo.db
See also
  • -c server option


-d server option
Function

Use POSIX I/O.

Syntax

{ dbsrv9 | dbeng9 } -d ...

Applies to

NetWare. The use of this option on Windows platforms has been deprecated.

Description

The -d option forces the use of POSIX I/O rather than DFS (Direct File System) I/O. This option is provided as a workaround for bugs in old versions of DFS. Note that asynchronous I/O is not available when using POSIX I/O.

This option applies to NetWare systems only.


-ec server option
Function

Use transport-layer security or simple encryption to encrypt all native Adaptive Server Anywhere packets (DBLib, ODBC, and OLE DB) transmitted to and from all clients. TDS packets are not encrypted.

Syntax

{ dbsrv9 | dbeng9 } -ec encryption-options ...

encryption-options:

{ NONE
|SIMPLE
|ECC_TLS (CERTIFICATE=filename;
CERTIFICATE_PASSWORD=password )
|RSA_TLS (CERTIFICATE=filename;
CERTIFICATE_PASSWORD=password )
| RSA_TLS_FIPS (CERTIFICATE=filename;
CERTIFICATE_PASSWORD=password ) } , ...

Description

You can use this option to secure communication packets between client applications and the database server using transport-layer security.

For more information, see Adaptive Server Anywhere Transport-Layer Security.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

The -ec option instructs the database server to accept only connections from ODBC, OLE DB, or embedded SQL interfaces that are encrypted using one of the specified types. Connections over the TDS protocol, which include Java applications using jConnect, are always accepted regardless of the usage of the -ec option, and are never encrypted. Setting the TDS connection parameter to NO disallows these unencrypted TDS connections.

See TDS protocol option for more information.

By default, communication packets are not encrypted, which poses a potential security risk. If you are concerned about the security of network packets, use the -ec option. Encryption affects performance only marginally. The -ec option controls the server's encryption settings and requires one of the following parameters in a comma-separated list:

none accepts connections that are not encrypted.

simple accepts connections that are encrypted with simple encryption. This type of encryption is supported on all platforms, as well as on previous versions of Adaptive Server Anywhere. Simple encryption does not provide server authentication, strong elliptic-curve or RSA encryption, or other features of transport-layer security.

ECC_TLS accepts connections that are encrypted using the elliptic curve-based Certicom encryption technology. For backwards compatibility, ecc_tls can also be specified as CERTICOM. To use this type of encryption, both the server and the client must be operating on Solaris, Linux, NetWare, Mac OS X, or any supported Windows platform except Windows CE, and the connection must be over the TCP/IP port. UNIX platforms, except Solaris, Linux, and Mac OS X, do not recognize the client or server ECC_TLS parameter. This parameter accepts the following required arguments:

  • certificate the file name of the server certificate.

    This is the server certificate containing the server's private key. This server certificate can be self-signed or signed by an enterprise root certificate or Certificate Authority.

  • certificate_password the password for the server certificate's private key.

In order to use ECC_TLS, you must generate your certificates using the ECC cipher.

For more information about creating certificates, see Creating digital certificates.

RSA_TLS accepts connections that are encrypted using RSA-based encryption technology. To use this type of encryption, both the server and the client must be operating on Solaris, Linux, NetWare, Mac OS X, or any supported Windows platform except Windows CE, and the connection must be over the TCP/IP port. UNIX platforms, except for Solaris, Linux, and Mac OS X, do not recognize the client or server RSA_TLS parameter. This parameter accepts the following required arguments:

  • certificate the file name of the server certificate.

    This is the server certificate containing the server's private key. This server certificate can be self-signed or signed by an enterprise root certificate or Certificate Authority.

  • certificate_password the password for the server certificate's private key.

You must generate your certificates using the RSA cipher.

For more information about creating certificates, see Creating digital certificates.

RSA_TLS_FIPS accepts connections that are encrypted using FIPS-approved RSA encryption technology. RSA_TLS_FIPS uses a separate approved library, but is compatible with clients specifying RSA_TLS with Adaptive Server Anywhere 9.0.2 or later. To use this type of encryption, both the server and the client must be operating on a supported 32-bit Windows operating system, and the connection must be over the TCP/IP port. This parameter accepts the following required arguments:

  • certificate the file name of the server certificate.

    This is the server certificate containing the server's private key. This server certificate can be self-signed or signed by an enterprise root certificate or Certificate Authority.

  • certificate_password the password for the server certificate's private key.

If you are using FIPS-approved RSA encryption, you must generate your certificates using the RSA cipher.

For more information about creating certificates, see Creating digital certificates.

The dbecc9.dll and dbrsa9.dll files contain the ECC and RSA code used for encryption and decryption. dbrsa9f.dll contains the code for the FIPS-approved RSA algorithm. When you connect to the server, if the appropriate file cannot be found, or if an error occurs, a message appears on the server window. The server does not start if the types of encryption specified cannot be initiated.

The client's and the server's encryption settings must match or the connection will fail. However, if -ec simple is specified, on the server, but -ec none is not, then connections that do not request encryption can connect and automatically user simple encryption.

Examples

The following example specifies the elliptic-curve server certificate sample.crt at the dbsrv9 command line.

dbsrv9 -ec ecc_tls(certificate=sample.crt; certificate_password=tJ1#m6+W) -x tcpip asademo.db

The following example specifies the RSA server certificate rsaserver.crt at the dbsrv9 command line.

dbsrv9 -ec rsa_tls(certificate=rsaserver.crt; certificate_password=test) -x tcpip asademo.db

The following example specifies the RSA server certificate rsaserver.crt at the dbsrv9 command line. The rsa_tls_fips parameter is used for the FIPS-approved RSA algorithm.

dbsrv9 -ec rsa_tls_fips(certificate=rsaserver.crt; certificate_password=test) -x tcpip asademo.db
See also
  • Starting the database server with transport-layer security
  • Encryption connection parameter [ENC]


-ep server option
Function

Prompt the user for the encryption key upon starting a strongly encrypted database.

Syntax

{ dbsrv9 | dbeng9 } -ep ...

Description

The -ep option instructs the database server to display a dialog box for the user to enter the encryption key. This server option provides an extra measure of security by never allowing the encryption key to be seen in clear text.

When used with supported tools, this option always prompts the user for the encryption key, even if a key is not necessary. If the dialog box prompt appears and you know that a key is not necessary, you can click Cancel to continue.

When used with the server, this option prompts the user for the encryption key only if all of the following are true:

  • the -ep option is specified

  • the server is a Windows personal server, or the server is just starting up

  • a key is required to start a database

  • the server is either not a Windows service, or it is a Windows service with the interact with desktop option turned ON

  • the server is not a daemon (UNIX)

If you want to secure communication packets between client applications and the database server use the -ec server option and transport-layer security.

For more information, see Adaptive Server Anywhere Transport-Layer Security.

Example

The user is prompted for the encryption key when the myencrypted.db database is started:

dbsrv9 -ep -x tcpip myencrypted.db
See also
  • -ek database option
  • DatabaseKey connection parameter [DBKEY]


-fc server option
Function

Specify the filename of a DLL (or shared object on UNIX) containing the File System Full callback function.

Syntax

{ dbsrv9 | dbeng9 } -fc filename ...

Applies to

All operating systems and servers.

Description

This option can be used to notify users, and possibly take corrective action, when a file system full condition is encountered. If you use the -fc option, the database server attempts to load the specified DLL and resolve the entry point of the callback function during startup. If the Adaptive Server Anywhere database server cannot find both the DLL and the entry point, the database server returns an error and shuts down. The DLL is user-supplied and can use the callback to, among other things, invoke a batch file (or shell script on UNIX) you have supplied to take diagnostic or corrective action. Alternatively, the callback function itself can perform such an action.

A sample disk full callback function is located in Samples\Asa\DiskFull.

Adaptive Server Anywhere searches for the callback function DLL in the same locations as it searches for other DLLs and files.

For information about where Adaptive Server Anywhere searches for files, see How Adaptive Server Anywhere locates files.

When the database server detects a disk full condition, it invokes the callback function (if one has been provided), passing it the following information:

  • the name of the dbspace where the condition was triggered

  • the operating system-specific error code from the failed operation

The return code from the call to xp_out_of_disk indicates whether the operation that caused the condition should be aborted or retried. If a non-zero value is returned, the operation is aborted, otherwise it is retried. The callback function is invoked repeatedly as long as it returns zero and the file system operation fails.

On Windows platforms, if the database server has been started with a Server Messages window (neither -qi nor -qw have been specified), and a callback DLL has not been provided, a dialog appears when a disk full condition occurs. This dialog contains the dbspace name and error code, and allows the user to choose whether the operation that caused the disk full condition should be retried or aborted.

On all other operating systems, when -fc is not specified and a disk full condition is encountered, a fatal error occurs.

You can create system events to track the available disk space of devices holding the database file, the log file, or the temporary file and alert administrators in case of a disk space shortage.

For more information, see CREATE EVENT statement.

Example

When the database server starts, it attempts to load the diskfull.dll DLL.

dbeng9 -fc diskfull.dll
See also
  • Using callback functions
  • Choosing a system event
  • TEMP_SPACE_LIMIT_CHECK option [database]


-fips server option
Function

Requires that only FIPS-approved algorithms should be used for strong database and communication encryption.

Syntax

{ dbsrv9 | dbeng9 } -fips ...

Description

Specifying this option enforces all server encryption to use FIPS-approved algorithms. This option applies to strong database encryption, client/server transport-layer security, and web services transport-layer security. You can still use unencrypted connections and databases when the -fips option is specified, but you cannot use simple encryption.

Separately licensable option required
Transport-layer security and strong database encryption using AES_FIPS requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

For strong database encryption, the -fips option causes new databases to use the AES_FIPS type, even if AES is specified in the ALGORITHM clause of the CREATE DATABASE statement. When the database server is started with -fips, you can run databases encrypted with AES or AES_FIPS strong encryption, but not databases encrypted with simple encryption. Unencrypted databases can also be started on the server when -fips is specified.

The SQL Anywhere Studio security option must be installed on any machine used to run a database encrypted with AES_FIPS.

For Adaptive Server Anywhere transport-layer security, the -fips option causes the server to use the RSA_TLS_FIPS, even if RSA_TLS is specified. If ECC_TLS is specified, an error occurs because a FIPS-approved elliptic-curve algorithm is not available.

For transport-layer security for web services, the -fips option causes the server to use HTTPS_FIPS, even if HTTPS is specified.

See also
  • Strong encryption
  • Adaptive Server Anywhere Transport-Layer Security
  • Using transport-layer security for web services


-ga server option
Function

Unload database after last connection is dropped.

Syntax

{ dbsrv9 | dbeng9 } -ga ...

Applies to

All operating systems except NetWare.

Description

Specifying this option on the network server causes each database to be unloaded after the last connection to it is dropped. In addition to unloading each database after the last connection is dropped, the personal server shuts down when the last database is stopped.


-gb server option
Function

Set the database process priority class.

Syntax

{ dbsrv9 | dbeng9 } -gb { idle | normal | high | maximum } ...

Applies to

Windows NT/2000/XP

Description

Set the database process priority class. The value idle is provided for completeness, and maximum may interfere with the running of your computer. Normal and high are the commonly-used settings.


-gc server option
Function

Set maximum desired interval between checkpoints.

Syntax

{ dbsrv9 | dbeng9 } -gc integer ...

Applies to

All operating systems and servers.

Description

Set the maximum desired length of time in minutes that the database server runs without doing a checkpoint on each database.

The default value is 60 minutes.

When a database server is running with multiple databases, the checkpoint time specified by the first database started is used unless overridden by this option. If a value of 0 is entered, the default value of 60 minutes is used.

Checkpoints generally occur more frequently than the specified time.

For more information, see How the database server decides when to checkpoint.

See also
  • CHECKPOINT_TIME option [database]
  • Checkpoints and the checkpoint log


-gd server option
Function

Set permissions required to start or stop a database.

Syntax

{ dbsrv9 | dbeng9 } -gd { DBA | all | none } ...

Applies to

All operating systems and servers.

Description

This is the permission required for a user to cause a new database file to be loaded by the server, or to stop a database on a running database server. The level can be one of the following:

  • DBA Only users with DBA authority can start or stop databases.

  • all All users can start or stop databases.

  • none Starting and stopping databases is not allowed apart from when the database server itself is started and stopped.

The default setting is ALL for the personal database server and DBA for the network database server. Both upper case and lower case syntax is acceptable.

Note that when this option is set to DBA, the client application must already have a connection to the server in order to start or stop a database. Providing a DBA username and password on a new connection is not sufficient.

Example

The following steps illustrates how to use the -gd option for the network database server.

  1. Enter a password in the util_db.ini file in the directory that holds the database server executable:

    [UTILITY_DB]
pwd=mypwd

  2. Start the network database server:

    dbsrv9 -x tcpip -n myserver -gd DBA

  3. Connect to the utility database from Interactive SQL.

    The following command assumes that myserver is the default database server:

    dbisql -c "uid=DBA;pwd=mypwd;dbn=utility_db "

  4. Start a database:

    start database asademo
on myserver;

  5. Connect to the database you have started:

    connect
to myserver
database asademo
user DBA identified by SQL


-ge server option
Function

Set stack size for external functions.

Syntax

{ dbsrv9 | dbeng9 } -ge integer ...

Applies to

Windows 95/98/Me, Windows NT/2000/XP, NetWare

Description

Sets the stack size for threads running external functions, in bytes. The default is 32K.


-gf server option
Function

Disable firing of triggers by the server.

Syntax

{ dbsrv9 | dbeng9 } -gf ...

Applies to

All operating systems and servers.

Description

The -gf server option instructs the server to disable the firing of triggers.

See also
  • FIRE_TRIGGERS option [compatibility]


-gk server option
Function

Set the permission required to stop the network server and personal server using dbstop.

Syntax

{ dbsrv9 | dbeng9 } -gk { DBA | all | none } ...

Applies to

All operating systems and servers.

Description

The allowed values include:

  • DBA Only users with DBA authority can use dbstop to stop the server. This is the default for the network server.

  • all All users can use dbstop to stop the server. This is the default for the personal server.

  • none The server cannot be stopped using dbstop.

Both upper case and lower case syntax is acceptable.


-gl server option
Function

Set the permission required to load data using LOAD TABLE, and to unload data using UNLOAD or UNLOAD TABLE.

Syntax

{ dbsrv9 | dbeng9 } -gl { DBA | all | none } ...

Applies to

All operating systems and servers.

Description

Using the UNLOAD TABLE or UNLOAD statement places data in files on the database server machine, and the LOAD TABLE statement reads files from the database server machine.

To control access to the file system using these statements, the -gl server option allows you to control the level of database permission that is required to use these statements.

The allowed values are as follows:

  • DBA Only users with DBA authority can load or unload data from the database.

  • all All users can load or unload data from the database.

  • none Data cannot be unloaded or loaded.

Both upper case and lower case syntax is acceptable.

The default settings are all for personal database servers on non-UNIX operating systems, and DBA for the network database server and the UNIX personal server. These settings reflect the fact that, on non-UNIX platforms, the personal database server is running on the current machine, and so the user already has access to the file system.


-gm server option
Function

Limit the number of concurrent connections to the server.

Syntax

{ dbsrv9 | dbeng9 } -gm integer ...

Applies to

All operating systems and servers.

Description

Defines the connection limit for the server. If this number is greater than the number that is allowed under licensing and memory constraints, it has no effect.

The database server allows one extra DBA connection above the connection limit to allow a DBA to connect to the server and drop other connections in an emergency.


-gn server option
Function

Set the maximum number of active requests (both user and system) that the database server can handle concurrently.

Syntax

{ dbsrv9 | dbeng9 } -gn integer ...

Applies to

All operating systems and servers.

Description

Set the number of active user and system requests that the database server can handle concurrently. If the maximum number of active requests are already in use when the database server receives an additional request, the new request must wait until another request is completed.

Each connection uses a thread for each request, and when the request is completed the thread is returned to the pool for use by other connections. As no connection can have more than one request in progress at one time, no connection uses more than one thread at a time. An exception to this rule is if a Java application uses threads. Each thread in the Java application is a database server execution thread.

The default is 20 threads for the network database server and for the personal database server, except on Windows CE where the default is 3 threads.

On Windows NT/2000/XP, you may want investigate the Performance Monitor readings for Requests: Active and Requests: Unscheduled. If the number of active requests is always less than -gn, you can lower -gn. If the number of total requests (active + unscheduled) is often larger than -gn, then you might want to increase -gn. The Performance Monitor is not available for UNIX or Linux platforms.

See also
  • Controlling threading from the command line


-gp server option
Function

Set the maximum allowed database page size.

Syntax

{ dbsrv9 | dbeng9 } -gp { 1024 | 2048 | 4096 | 8192 | 16384 | 32768 } ...

Applies to

All operating systems and servers.

Description

Database files with a page size larger than the page size of the server cannot be loaded. This option explicitly sets the page size of the server, in bytes.

If you do not use this option, then the page size of the first database on the command line is used.

The minimum page size on all UNIX platforms is 2048 bytes. You can still use databases with smaller page sizes, but cache memory is used very inefficiently. If you do not use this option and start a server with no databases loaded, the default value is 2048.

On all other platforms, if you do not use this option and start a server with no databases loaded, the default value is 1024.


-gr server option
Function

Set the maximum length of time (in minutes) for recovery from system failure.

Syntax

{ dbsrv9 | dbeng9 } -gr integer ...

Applies to

All operating systems and servers.

Description

When a database server is running with multiple databases, the recovery time that is specified by the first database started is used unless overridden by this option.

For more information, see RECOVERY_TIME option [database].


-gss server option
Function

Set the stack size per internal execution thread in the server.

Syntax

{ dbsrv9 | dbeng9 } -gss { integer | integer K | integer M } ...

Applies to

This option has no effect on Windows operating systems.

Description

The number of internal execution threads is controlled by the -gn option, and has a default value of 20. The -gss option allows you to lower the memory usage of the database server in environments with limited memory.

On NetWare, the default, and minimum, stack size per internal execution thread is 128 kb, and the maximum stack size is 1 Mb. On UNIX, the default stack size per internal execution thread is 64 kb, the minimum stack size is 500 kb, and the maximum stack size is 4 Mb.

See also
  • Controlling threading from the command line


-gt server option
Function

Set the maximum number of requests that can be run simultaneously by the database server. This option is only useful on multiprocessor systems.

Syntax

{ dbsrv9 | dbeng9 } -gt integer ...

Applies to

All operating systems and servers except NetWare.

Description

With per-seat licensing, the network database server uses all CPUs available on the machine (the default). With CPU-based licensing, the network database server uses only the number of processors you are licensed for. In addition, the personal database server and runtime database server are both limited to a single processor.

See also
  • Controlling threading from the command line


-gu server option
Function

Set permission levels for utility commands.

Syntax

{ dbsrv9 | dbeng9 } -gu { all | none | DBA | utility_db } ...

Applies to

All operating systems and servers.

Description

Sets permission levels for utility commands such as CREATE DATABASE and DROP DATABASE. The level can be set to one of the following: utility_db, all, none, DBA. The default is DBA.

The utility_db level restricts the use of these commands to only those users who can connect to the utility database. The all, none, and DBA levels permit all users, no users, or users with DBA authority to execute utility commands.


-gx server option
Function

Set the maximum number of requests that can concurrently execute blocking system calls.

Syntax

{ dbsrv9 | dbeng9 } -gx integer ...

Applies to

Windows 95/98/Me, Windows NT/2000/XP

Description

This option is only of use on Windows NT. On other platforms the -gx value is equivalent to the -gt value.

Meaningful values are in the range specified by the -gt option value and the -gn option value. By default, this option is set to a value one greater than the number of CPUs on the machine. The additional process permits the use of remote data access between databases on a single database server.

The primary cost of increasing -gx is reduced address space (not physical memory) available for the cache. This option is only of use if you are using remote data access, Java, or external stored procedures (and in the case of Java/external stored procedures, if those features are being used to implement servers). If you are using remote data access/Java/external stored procedures and the server hangs for no apparent reason, increasing -gx might solve the problem. Setting the -gx option beyond the -gn option has no benefit.

You may want to increase the option setting beyond the default to reserve capacity for external tasks, separate from standard database tasks. For example, you may want to increase the value of -gx by one for each concurrent connection using remote data access, or for connections using Java in the database to listen on an external port. In other circumstances, this option should be left at the default value.

On UNIX, each task is executed in its own thread, so that the number of tasks (-gn) also determines the number of threads.

See also
  • Controlling threading from the command line


-m server option
Function

Delete the transaction log when a checkpoint is done.

Syntax

{ dbsrv9 | dbeng9 } -m ...

Applies to

All operating systems and servers.

Description

This option deletes the transaction log when a checkpoint is done, either at shutdown or as a result of a checkpoint scheduled by the server.

Caution When this option is selected, there is no protection against media failure on the device that contains the database files.

This provides a way to automatically limit the growth of the transaction log. Checkpoint frequency is still controlled by the CHECKPOINT_TIME and RECOVERY_TIME options (which you can also set on the command line).

The -m option is useful for limiting the size of the transaction log in situations where high volume transactions requiring fast response times are being processed, and the contents of the transaction log are not being relied upon for recovery or replication. The -m option provides an alternative to operating without a transaction log at all, in which case a checkpoint would be required following each COMMIT and performance would suffer as a result. When the -m option is selected, there is no protection against media failure on the device that contains the database files. Other alternatives for managing the transaction log (for example, using the BACKUP statement and events) should be considered before using the -m option.

To avoid database file fragmentation, it is recommended that where this option is used, the transaction log be placed on a separate device or partition from the database itself.

Replicated and synchronized databases
Do not use the -m option with databases that are being replicated or synchronized. Replication and synchronization, used by SQL Remote and MobiLink, inherently rely on transaction log information.

Previous Next


-n server option
Function

Set the name of the database server.

Syntax

{ dbsrv9 | dbeng9 } -n database-file-name...

Applies to

All operating systems and servers.

Description

By default, the database server receives the name of the database file with the path and extension removed. For example, if the server is started on the file c:\Program Files\Sybase\SQL Anywhere 9\asademo.db and no -n option is specified, the name of the server is asademo.

The server name is interpreted according to the character set of the machine, as no database collation exists at startup time. Multi-byte characters are not recommended in server names.

Names must be a valid identifier. Long server names are truncated to different lengths depending on the protocol.

Protocol | Truncation Length
UNIX shared memory | 31 bytes
non-UNIX shared memory | 40 bytes
TCP/IP | 40 bytes
SPX | 32 bytes
Named Pipes | 8 bytes

The following are invalid for database server names:

  • names that begin with white space or single or double quotes

  • names that end with white space

  • names that contain semicolons

The server name specifies the name to be used in the EngineName (ENG) connection parameter of client application connection strings or profiles. With shared memory, there is a default database server that will be used if no server name is specified provided that at least one database server is running on the computer.

Running multiple servers with the same name is not recommended.

There are two -n options
The -n option is positional. If it appears before a database file name, it is a server option and names the server. If it appears after a database file name, it is a database option and names the database.

For example, the following command names the server SERV and the database DATA:

dbsrv9 -n SERV asademo.db -n DATA

For more information, see -n database option.

See also
  • Identifiers
  • EngineName connection parameter [ENG]


-o server option
Function

Print all server window output to a file.

Syntax

{ dbsrv9 | dbeng9 } -o filename ...

Applies to

All operating systems and servers.

Description

Print all server message window output to a file. You can obtain the name of the file by executing the following command:

SELECT property ( 'ConsoleLogFile' )


-oe server option
Function

Specify a filename to log startup errors, fatal errors, and assertions.

Syntax

{ dbsrv9 | dbeng9 } -oe filename ...

Applies to

All operating systems and servers.

Description

Each line in this file is prefixed with the date and time. Startup errors include such errors as:

  • Could not open/read database file: <database file>

  • A database server with that name has already started

Fatal errors and assertions are logged to the Windows Application Event Log (except on Window CE) or the UNIX system log regardless of whether -oe is specified.


-os server option
Function

Limit the file size for the server window output.

Syntax

{ dbsrv9 | dbeng9 } -os { integer | integer G | integer K | integer M } ...

Applies to

All operating systems and servers.

Description

Limits the size of the log file used by the -o option. The units G, K, and M can be either lower case or upper case. If G, K, or M is not supplied, any integer less than 10 000 is assumed to be in kilobytes, and any integer 10 000 or greater is assumed to be in bytes.

See also
  • -o server option


-p server option
Function

Set the maximum size of communication packets.

Syntax

{ dbsrv9 | dbeng9 } -p integer ...

Applies to

All operating systems and servers.

Description

The default is 1460 bytes. The minimum value is 300 bytes and the maximum is 16 000.

See also
  • CommBufferSize connection parameter [CBSIZE]


-pc server option
Function

Compress all connections except for same-machine connections.

Syntax

{ dbsrv9 } -pc ...

Applies to

All operating systems and network servers.

Description

The packets sent between an Adaptive Server Anywhere client and server can be compressed using the -pc option. Compressing a connection may improve performance under some circumstances. Large data transfers with highly compressible data tend to get the best compression rates. This option can be overridden for a particular client by specifying COMPRESS=NO in the client's connection parameters.

The default is not to compress connections. Specifying the -pc option compresses all connections except same-machine connections and TDS connections. TDS connections (including jConnect) do not support Adaptive Server Anywhere communication compression.

Same-machine connections over any communication link will not enable compression, even if the -pc option or COMPRESS=YES connection parameter is used.

See also
  • Adjusting communication compression settings to improve performance
  • Compress connection parameter [COMP]
  • Try using Adaptive Server Anywhere's compression features


-pt server option
Function

Increase or decrease the size limit at which packets are compressed.

Syntax

{ dbsrv9 } -pt size_in_bytes ...

Applies to

All operating systems and network servers.

Description

This parameter takes an integer value representing the minimum byte-size of packets to be compressed. Values less than 80 are not recommended. The default is 120 bytes.

Under some circumstances, changing the compression threshold can help performance of a compressed connection by allowing you to compress packets only when compression will increase the speed at which the packets are transferred. The default setting should be appropriate for most cases.

If both client and server specify different compression threshold settings, the client setting applies.

See also
  • Adjusting communication compression settings to improve performance
  • CompressionThreshold connection parameter [COMPTH]
  • Try using Adaptive Server Anywhere's compression features


-qi server option
Function

Control whether database server tray icon and window appear.

Syntax

{ dbsrv9 | dbeng9 } -qi ...

Applies to

Windows platforms, excluding Windows CE.

Description

This option leaves no visual indication that the server is running, other than possible startup error dialogs. You can use either (or both) the -o or -oe logs to diagnose errors.


-qp server option
Function

Do not display messages about performance in the database server window.

Syntax

{ dbsrv9 | dbeng9 } -qp ...

Applies to

All operating systems and servers.

Description

Do not display messages about performance in the database server window. Messages that are suppressed include the following:

  • No unique index or primary key for table 'table_name'

  • Database file "mydatabase.db" consists of nnn fragments


-qs server option
Function

Suppress startup error dialogs.

Syntax

{ dbsrv9 | dbeng9 } -qs ...

Applies to

Windows only.

Description

This option suppresses startup error dialogs. Startup errors include errors such as:

  • Could not open/read database file: <database file>

  • A database server with that name has already started

On Windows platforms, if the server is not being autostarted, these errors appear in a dialog and must be cleared before the server stops. These dialogs do not appear if the -qs option is used.

If there is an error loading the language DLL, no dialog appears if -qs was specified on the command line and not in @data. This error is not logged to the -o or -oe logs, but rather to the Windows Application Event Log (except on Windows CE).

Usage errors are suppressed if -qs is on the command line, but not in @data expansion.


-qw server option
Function

Do not display database server screen.

Syntax

{ dbsrv9 | dbeng9 } -qw ...

Applies to

All operating systems and servers except NetWare.

Description

This option suppresses the database server window (Windows platforms) and display messages on the console (non-Windows platforms).


-r server option
Function

Force all databases that start on the server to be read-only. No changes to the database(s) are allowed: the server does not modify the database file(s) and transaction log files.

Syntax

{ dbsrv9 | dbeng9 } -r ...

Applies to

All operating systems and servers.

Description

Opens all database files as read-only with the exception of the temporary file when the option is specified before any database names on the command line. If the -r server option is specified after a database name, only that specific database is read-only. You can make changes on temporary tables, but ROLLBACK has no effect, since the transaction and rollback logs are disabled.

Databases distributed on CD-ROM devices, and compressed databases are examples of database files that cannot be modified. You can either create a write file to allow changes to the database outside the database file, or run in read-only mode.

If you attempt to modify the database, for example with an INSERT or DELETE statement, a SQLSTATE_READ_ONLY_DATABASE error is returned.

Databases that require recovery cannot be started in read-only mode. For example, database files created using an online backup cannot be started in read-only mode if there were any open transactions when the backup was started, since these transactions would require recovery when the backup copy is started.

Example

To open two databases in read-only mode

dbeng9 -r database1.db database2.db

To open only the first of two databases in read-only mode.

dbeng9 database1.db -r database2.db


-s server option
Function

Set the user ID for syslog messages.

Syntax

{ dbsrv9 | dbeng9 } -s { none | user | daemon | localn } ...

Applies to

UNIX

Description

Sets the system user ID used in messages to the syslog facility. The default is user for database servers that are started in the foreground, and daemon for those that are run in the background (for example, started by dbspawn, autostarted by a client, or started with the -ud database server option).

A value of none prevents any syslog messages from being logged. The localn argument allows you to use a facility identifier to redirect messages to a file. You can specify a number between 0 and 7, inclusive, for n. Refer to the UNIX syslog(3) man page for more information.

The following steps illustrate how to redirect messages on Solaris, but you can also do this on Linux, AIX, and Mac OS X. Note that on other platforms, including DEC and HP, the syslog.conf file is found in a different location. You can place the /var/adm/sqlanywhere file in whatever location you want.

toggle To redirect messages to a file using a facility identifier

  1. Choose a unique facility identifier that is not already being used by another application that is running on your system.

    You can do this by looking in the /etc/syslog.conf file to see of any of the localn facilities are referenced.

  2. Edit the /etc/syslog.conf file and add the following line, where localn is the facility identifier you chose in step 1:

    localn.err;localn.info;localn.notice  /var/adm/sqlanywhere

  3. Create the /var/adm/sqlanywhere file:

    touch /var/adm/sqlanywhere

  4. Tell the syslogd process that you have modified the syslog.conf file by finding the process ID of syslogd:

    ps -ef | grep syslogd

    and then executing the following command where <pid> is the process ID of syslogd:

    kill -HUP <pid>

  5. Start your Adaptive Server Anywhere database server with the following command, where localn is the facility identifier you chose in step 1:

    dbeng9 -s localn ...

    Now any messages that the Adaptive Server Anywhere database server reports to syslog are redirected to the /var/adm/sqlanywhere file.


-sb server option
Function

Specify how the server reacts to broadcasts.

Syntax

{ dbsrv9 | dbeng9 } -sb { 0 | 1 } ...

Applies to

SPX, TCP/IP

Description

Using -sb 0 causes the server not to start up any TCP/UDP broadcast listeners. In addition to forcing clients to use the DoBroadcast=NONE and HOST= options to connect to the server, this option causes the server to be unlisted when using dblocate.

Using -sb 1 causes the server to not respond to broadcasts from dblocate, while leaving connection logic unaffected. You can connect to the server by specifying LINKS=tcpip and ENG=<name>.


-sc server option
Function

Disable the shared memory communications protocol and use Named Pipes.

Syntax

{ dbsrv9 | dbeng9 } -sc ...

Applies to

Windows NT/2000/XP

Description

This option disables the shared memory communications protocol that is used for same-machine communications, and starts the Named Pipes protocol.

This option is implemented as part of an initiative to obtain C2 security certification. It is likely to be of general use only for customers wanting to run in a C2-certified environment.


-ti server option
Function

Disconnect inactive connections.

Syntax

{ dbsrv9 | dbeng9 } -ti minutes ...

Applies to

All operating systems and servers.

Description

Disconnect connections that have not submitted a request for the specified number of minutes. The default is 240 (4 hours). The maximum value is 32767. A client machine in the middle of a database transaction holds locks until the transaction is ended or the connection is terminated. The -ti option is provided to disconnect inactive connections, freeing their locks.

The -ti option is very useful when used in conjunction with dbsrv9 since most connections will be over network links (TCP or SPX).

The -ti option is useful with dbeng9 only for local TCP/IP connections. Using -ti has no effect on connections to a local server using shared memory.

Setting the value to zero disables checking of inactive connections, so that no connections are disconnected.

See also
  • sa_server_option system procedure


-tl server option
Function

Set the period at which to send liveness packets.

Syntax

{ dbsrv9 | dbeng9 } -tl seconds ...

Applies to

All database servers using TCP/IP or SPX.

See also
  • sa_server_option system procedure
Description

A liveness packet is sent periodically across a client/server TCP/IP or SPX communications protocol to confirm that a connection is intact. If the server runs for a LivenessTimeout period (default 2 minutes) without detecting a liveness packet on a connection, the communication is severed, and the server drops the connection associated with that client. UNIX non-threaded clients and TDS connections do not do liveness checking.

The -tl option on the server sets the LivenessTimeout value for all clients that do not specify a liveness period.

Liveness packets are sent when a connection has not sent any packets for between one third and two thirds of the LivenessTimeout value.

When there are more than 200 connections, the server automatically calculates a higher LivenessTimeout value based on the stated LivenessTimeout value. This enables the server to handle a large number of connections more efficiently. Liveness packets are sent between one third and two thirds of the LivenessTimeout on each idle connection. Large numbers of liveness packets are not sent at the same time. If liveness packets take a long time to send (depending on the network, the machine's hardware, and the CPU and network load on the machine), it is possible that liveness packets will sent after two thirds of the LivenessTimeout. A warning appears in the server console if the liveness sends take a long time. If this warning occurs, consider increasing the LivenessTimeout value.

Although it is not generally recommended, you can disable liveness by specifying the following:

dbsrv9 -tl 0

Rather than disabling the LivenessTimeout option, consider increasing the value to 1 hour as follows:

dbsrv9 -tl 3600


-tmf server option
Function

Use for recovery from distributed transactions in unusual circumstances.

Syntax

{ dbsrv9 | dbeng9 } -tmf ...

Applies to

Windows NT/2000/XP only

Description

Used during recovery of distributed transactions when the distributed transaction coordinator is not available. It could also be used if starting a database with distributed transactions in the transaction log, on a platform where the distributed transaction coordinator is not available.

Caution If you use this option, distributed transactions are not recovered properly. It is not for routine use.


-tmt server option
Function

Set a reenlistment timeout for participation in distributed transactions.

Syntax

{ dbsrv9 | dbeng9 } -tmt milliseconds ...

Applies to

Windows NT/2000/XP only

Description

Used during recovery of distributed transactions. The value specifies how long the database server should wait to be reenlisted. By default there is no timeout (the database server waits indefinitely).


-tq server option
Function

Shut down the server at a specified time.

Syntax

{ dbsrv9 | dbeng9 } -tq { datetime | time } ...

Applies to

All operating systems and servers.

Description

This is useful for setting up automatic off-line backup procedures (see Backup and Data Recovery). The format for the time is in hh:mm (24 hour clock), and can be preceded by an optional date. If a date is specified, the date and time must be enclosed in double quotes and be in the format YYYY/MM/DD HH:MM.

See also
  • sa_server_option system procedure


-u server option
Function

Open files using the operating system disk cache.

Syntax

{ dbsrv9 | dbeng9 } -u ...

Applies to

Windows NT/2000/XP, Windows 95/98/Me, UNIX

Description

Files are opened using the operating system disk cache in addition to the database cache.

While the operating system disk cache may improve performance in some cases, in general better performance is obtained without this option, using the database cache only.

If the server is running on a dedicated machine, you should not use the -u option, as the database cache itself is generally more efficient. You may want to use the -u option if the server is running on a machine with several other applications (so that a large database cache may interfere with other applications) and yet IO-intensive tasks are run intermittently on the server (so that a large cache will improve performance).


-ua server option
Function

Turn off use of asynchronous I/O.

Syntax

{ dbsrv9 | dbeng9 } -ua ...

Applies to

Linux

Description

By default, the database server uses asynchronous I/O on Linux when possible. In order to use asynchronous I/O, the following conditions must be met:

  1. The library libaio.so can be loaded at run time.

  2. The kernel has asynchronous I/O support.

If you want to turn off the use of asynchronous I/O, specify the -ua option on the database server command line.


-uc server option
Function

Start the database server in console mode. This is the default.

Syntax

{ dbsrv9 | dbeng9 } -uc

Applies to

UNIX

Description

Starts the database server in console mode. You should only specify one of -uc, -ui, or -ux.

For information about starting the database server as a daemon, see -ud server option.

See also
  • -ui server option
  • -ux server option
Example

Previous Next


-ud server option
Function

Run as a daemon.

Syntax

{ dbsrv9 | dbeng9 } -ud ...

Applies to

UNIX

Description

Using this option lets you run the server so that it continues running after the current operating system session ends.


-ui server option
Function

Open the Server Startup Options dialog and display the Server Messages window, or start the database server in console mode if a usable display is not available on Linux and Solaris.

Syntax

{ dbsrv9 | dbeng9 } -ui

Applies to

Linux and Solaris, with X Windows Server support

Description

The -ui option allows you to use the Server Startup Options dialog to specify server options when starting the database server and display the Server Messages window once the server has started.

When the -ux option is the only option specified on the server command line, the Server Startup Options dialog appears where you can enter options for starting the database server. The Server Messages dialog appears once the server starts.

If you specify other server options in addition to -ux, then the Server Messages window appears once the database server starts.

When -ui is specified, the server attempts to find a usable display. If it cannot find one, for example because the DISPLAY environment variable is not set or because X Windows Server is not running, then the database server starts in console mode. You should specify the -ux option if you do not want the database server to start when it cannot locate a usable display. You should only specify one of -uc, -ui, or -ux.

For information about starting the database server as a daemon, see -ud server option.

See also
  • -uc server option
  • -ux server option


-ut server option
Function

Touch temporary files.

Syntax

{ dbsrv9 | dbeng9 } -ut minutes ...

Applies to

UNIX

Description

This option causes the server to touch temporary files at specified intervals.


-ux server option
Function

Open the Server Startup Options dialog or display the Server Messages window on Linux and Solaris.

Syntax

{ dbsrv9 | dbeng9 } -ux

Applies to

Linux and Solaris, with X Windows Server support

Description

The -ux option allows you to do two things when starting the database server: use the Server Startup Options dialog to specify server options when starting the database server and display the Server Messages window once the server has started.

When the -ux option is the only option specified on the server command line, the Server Startup Options dialog appears where you can enter options for starting the database server.

If you specify other server options in addition to -ux, then the Server Messages window appears once the database server is started. You should only specify one of -uc, -ui, or -ux.

The server must be able to find a usable display when -ux is specified. If it cannot find one, for example because the DISPLAY environment variable is not set or because X Windows Server is not running, then the database server fails to start.

For information about starting the database server as a daemon, see -ud server option.

See also
  • -uc server option
  • -ux server option
Example

The following command displays the Server Startup Options dialog where you can enter options for starting the database server:

dbeng9 -ux

The following command starts the database server and displays the Server Messages window:

dbeng9 -ux sample.db


-v server option
Function

Display the software version.

Syntax

{ dbsrv9 | dbeng9 } -v ...

Applies to

All operating systems and servers.

Description

Supplies the database server version in a message box, and then stops.


-x server option
Function

Specify server side network communications protocols.

Syntax 1

dbsrv9 -x { all | none | srv-protocols } ...

srv-protocols:
{ [ namedpipes | spx | tcpip ] parmlist },...
parmlist:
( parm=value;...)

Syntax 2

dbeng9 -x { all | none | eng-protocols } ...

eng-protocols:
{ namedpipes | tcpip [ parmlist ] },...
parmlist:
( parm=value;...)

Applies to

All operating systems and servers.

Description

Use the -x option to specify which communications protocols, in addition to shared memory, you want to use to listen for client connection broadcasts.

If you do not specify the -x option, the server attempts to listen for client connection broadcasts using all protocols supported by the database server running on your operating system, including shared memory.

If you specify the -x option with one or more protocols, the server attempts to listen for client connection broadcasts using the specified protocol(s) and also using a shared-memory protocol.

If you are running Windows CE and specify the -x option, the server only attempts to listen for client connection broadcasts using the TCP/IP protocol unless you explicitly request otherwise.

Regardless of which settings you choose for the -x option, the server always listens for connection broadcasts using the shared memory protocol. In addition to the shared memory protocol, you can also specify the following:

  • ALL Listen for connection attempts by the client using all communications protocols that are supported by the server on this platform, including shared memory. This is the default.

  • NamedPipes (NP) Listen for connection attempts by the client using the NamedPipes protocol. NamedPipes is supported on Windows NT/2000/XP as an alternative means of same-machine communication.

  • NONE Listen for connection attempts by the client using only the shared memory protocol.

  • SPX Listen for connection attempts by the client using the SPX protocol. The SPX protocol is supported by NetWare, Windows NT/2000/XP, and Windows 95/98/Me network servers.

  • TCPIP (TCP) Attempt to connect to the client using the TCP/IP protocol. The TCP/IP protocol is supported by the network server on all operating systems, and by the personal database server for same-machine communications.

By default, the database server listens for broadcasts on port 2638, and redirects them to the appropriate port. This ensures a connection in most cases.

You can override this default and cause the server not to listen on port 2638 by setting the option -sb 0, or by turning off the BroadcastListener option (BroadcastListener=0). Additionally, if the client and server are communicating through a firewall, the client must send the packet to the exact port the server is listening on by specifying DoBroadcast=None and Host=.

For information, see ServerPort protocol option [PORT].

For some protocols, additional parameters may be provided, in the format

-x tcpip(PARM1=value1;PARM2=value2;...)

For a description of available parameters, see Network protocol options.

For UNIX, quotation marks are required if more than one parameter is supplied:

-x "tcpip(PARM1=value1;PARM2=value2;...)"
Example

Allow only shared memory, TCP/IP, and SPX communications:

-x tcpip,spx
See also
  • CommLinks connection parameter [LINKS]


-xs server option
Function

Specify server-side web services communications protocols.

Syntax

{ dbeng9 | dbsrv9 } -xs { none | web-protocols } ...

web-protocols :
{ http ( parmlist ) | https (parmlist ) |https_fips ( parmlist ) } , ...
parmlist:
( parm=value;...)

Applies to

All operating systems and servers.

Description

Use the -xs option to specify which web protocols you want to use to listen for requests.

If you do not specify the -xs option, the server does not attempt to listen for web requests.

If you specify the -xs option with one or more protocols, the server attempts to listen for web requests using the specified protocol(s).

You can use the https or the FIPS-approved HTTPS_FIPS protocols for transport-layer security.

For more information, see Using transport-layer security for web services.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Regardless of which settings you specify with the -xs option, the server always listens for connection broadcasts using the shared memory protocol. You can specify any of the following:

  • HTTP Listen for web requests by the client using the HTTP protocol. The default port on which to listen is 80.

  • HTTPS Listen for web requests by the client using the HTTPS protocol. The default port on which to listen is 443.

  • HTTPS_FIPS Listen for web requests by the client using the HTTPS protocol and FIPS-approved algorithms for encryption. HTTPS_FIPS uses a separate approved library but is compatible with HTTPS. The default port on which to listen is 443.

    Note
    If you want to start both https and https_fips at the same time, then you must change the port for one of them since they both have the same default port.

  • NONE Do not listen for web requests. This is the default.

For a description of available parameters, see Network protocol options.

For UNIX, quotation marks are required if more than one parameter is supplied:

-xs "http(PARM1=value1;PARM2=value2;...)"
Example

Listen for HTTP web requests on port 80:

dbeng9 web.db -xs http(port=80)


-y server option
Function

Run as a Windows service.

Syntax

{ dbsrv9 | dbeng9 } -y ...

Applies to

Windows 95/98/Me

Description

If the server registered as a Windows service, it continues to operate whether users log on or off, and shutdown commands are ignored.


-z server option
Function

Display communications operations on startup for troubleshooting purposes.

Syntax

{ dbsrv9 | dbeng9 } -z ...

Applies to

All operating systems and servers.

Description

This should only be used when tracking problems. The information appears in the database server window.


-zl server option
Function

Turn on capturing of the most recently-prepared SQL statement for each connection to databases on the server.

Syntax

{ dbsrv9 | dbeng9 } -zl ...

Applies to

All operating systems and servers.

Description

This feature can also be turned on using the RememberLastStatement server setting. You can obtain the most recently-prepared SQL statement for a connection using the LastStatement value of the connection_property function. The sa_conn_activity stored procedure allows you to obtain the most recently-prepared SQL statement for all current connections to databases on the server.

For stored procedure calls, only the outermost procedure call appears, not the statements within the procedure.

Caution When -zl is specified or when the RememberLastStatement server setting is turned on, any user can call the sa_conn_activity system procedure or obtain the value of the LastStatement connection property to find out the most recently-prepared SQL statement for any other user. This option should be used with caution and turned off when it is not required.
See also
  • Connection-level properties
  • sa_conn_activity system procedure
  • sa_server_option system procedure


-zn server option
Function

Specifies the number of request log file copies to retain.

Syntax

{ dbsrv9 | dbeng9 } -zn integer

Applies to

All operating systems and servers.

Description

If request logging is enabled over a long period of time, the request log file can become large. The -zn option allows you to specify the number of request log file copies to retain. It only takes effect if -zs is also specified. The -zs option allows you to create a new log file and rename the original log file when the original log file reaches a specified size.

For more information about the -zs option, see -zs server option.

For example, if you redirect request logging information to the file req.out, and specify five request log file copies using the -zn option, the server creates files in the following order: req.out.1, req.out.2, req.out.3, req.out.4, and req.out.5. When these files exist and the active request log fills again, the following happens:

  • req.out.1 is deleted

  • the files req.out.2 to req.out.5 are renamed req.out.1 to req.out.4

  • the copy of the active log is renamed req.out.5

Request logging is turned on using the -zr option and redirected to a separate file using the -zo option. You can also set the number of request logs using the sa_server_option system procedure where nn specifies the number of request log file copies:

CALL sa_server_option('RequestLogNumFiles',nn)
Example

In the following example, entered all on one line, request logging information is output to a request log file named mydatabase.log, which has a maximum size of 10 KB, and three copies of the request log are kept:

dbeng9 "C:\Program Files\Sybase\SQL Anywhere 9\asademo.db" -zr all -zn 3
 -zs 10 -zo mydatabase.log
See also
  • -zo server option
  • -zr server option
  • -zs server option
  • sa_server_option system procedure


-zo server option
Function

Redirect request logging information to a file separate from the regular log file.

Syntax

{ dbsrv9 | dbeng9 } -zo filename...

Applies to

All operating systems and servers.

Description

Request logging is turned on using the -zr option. You can direct the output from this file to a separate file from that specified with the -zo option.

This option also prevents request logging from appearing in the console.

See also
  • -zn server option
  • -zr server option
  • -zs server option


-zr server option
Function

Enable request logging of operations.

Syntax

{ dbsrv9 | dbeng9 } -zr { all | SQL | none | SQL+hostvars } ...

Applies to

All operating systems and servers.

Description

This should only be used when tracking problems. The information appears in the database server window or is sent to the logging file.

See also
  • sa_server_option system procedure
  • -zn server option
  • -zo server option


-zs server option
Function

Limit the size of the request logging file.

Syntax

{ dbsrv9 | dbeng9 } -zs { integer | integer G | integer K | integer M } ...

Applies to

All operating systems and servers.

Description

Request logging is turned on using the -zr option, and redirected to a separate file using the -zo option. You can limit the size of the file using the -zs option.

The units G, K, and M can be either lower case or upper case. If G, K, or M is not supplied, any integer less than 10 000 is assumed to be in kilobytes, and any integer 10 000 or greater is assumed to be in bytes.

When the request log file reaches the size specified by either the -zs option or the sa_server_option system procedure, the file is renamed with the extension .old appended (replacing an existing file with the same name if one exists). The request log file is then restarted.

See also
  • -zn server option
  • -zo server option
  • -zr server option
  • sa_server_option system procedure
Example

The following example shows how the -zs option is used to control log file size. Suppose you start a database server with the following command line:

dbeng9 -zr all -zs 10 -zo mydatabase.log

A new log file mydatabase.log is created. When this file reaches 10K in size, any existing mydatabase.old files are deleted, mydatabase.log is renamed to mydatabase.old, and a new mydatabase.log file is started. This process is repeated each time the mydatabase.log file reaches the specified size (in this case 10K).


Web Links Browse Collapse Expand PDF Previous Next

ASA Database Administration Guide

The Database Server

The database server

Recovery options

These options are for use in recovery situations only.


-a recovery option
Function

Apply the named transaction log.

Syntax

{ dbsrv9 | dbeng9 } -a log-filename ...

Applies to

All operating systems and servers.

Description

This is used to recover from media failure on the database file. When this option is specified, the database server applies the log and then terminates—it will not continue to run.

Specifying a cache size when starting the server can reduce recovery time.

For information on recovery, see Backup and Data Recovery.

Example

The following example, entered all on one line, applies the log file asademo.log to the sample database.

dbeng9 "C:\Program Files\Sybase\SQL Anywhere 9\asademo.db" -a "C:\backup\asademo.log"


-f recovery option
Function

Force the database server to start after the transaction log has been lost.

Syntax

{ dbsrv9 | dbeng9 } -f ...

Applies to

All operating systems and servers.

Description

If there is no transaction log, the database server carries out a checkpoint recovery of the database and then terminates—it does not continue to run. You can then restart the database server without the -f option for normal operation.

If there is a transaction log in the same directory as the database, the database server carries out a checkpoint recovery, and a recovery using the transaction log, and then terminates—it does not continue to run. You can then restart the database server without the -f option for normal operation.

During recovery, you should use the same server that you use in production. For example, if you use the network database server (dbsrv9.exe) during production, then you should use the network server for recovery because you may encounter problems as a result of the personal server's 10 connection limit. Specifying a cache size when starting the server can reduce recovery time.

For more information, see Backup and Data Recovery.

Example

The following command forces the database server to start and carry out a recovery of the sample database.

dbeng9 "c:\Program Files\Sybase\SQL Anywhere 9\asademo.db" -f


Web Links Browse Collapse Expand PDF Previous Next

ASA Database Administration Guide

The Database Server

The database server

Database options

These options are entered after the database name, and apply only to that database.


-ek database option
Function

Specify the key for a strongly encrypted database.

Syntax

{ dbsrv9 | dbeng9 } [ server-options ] database-file -ek key ...

Description

The -ek database option must be provided after a database filename on the command line. You must provide the KEY value with the -ek option to start an encrypted database. The KEY is a string, including mixed cases, numbers, letters, and special characters.

If you want to type the encryption key in a dialog so it cannot be seen in clear text, use the -ep server option.

For more information, see -ep server option.

If you want to secure communication packets between client applications and the database server use the -ec server option and transport-layer security.

For more information, see Adaptive Server Anywhere Transport-Layer Security.

Example

The following example starts the sample database and specifies the encryption key on the command line.

dbsrv9 -x tcpip asademo.db -ek "Akmm9u70y"
See also
  • -ep server option
  • DatabaseKey connection parameter [DBKEY]


-m database option
Function

Truncate the transaction log when a checkpoint is done.

Syntax

{ dbsrv9 | dbeng9 } [ server-options ] database-file -m ...

Applies to

All operating systems and servers.

Description

Truncate (delete) the transaction log when a checkpoint is done, either at shutdown or as a result of a checkpoint scheduled by the server. This provides a way to automatically limit the growth of the transaction log. Checkpoint frequency is still controlled by the CHECKPOINT_TIME and RECOVERY_TIME options (which you can also define on the command line).

The -m option is useful where high volume transactions requiring fast response times are being processed, and the contents of the transaction log are not being relied upon for recovery or replication. When this option is selected, there is no protection against media failure on the device that contains the database files.

To avoid database file fragmentation, it is recommended that where this option is used, the transaction log be placed on a separate device or partition from the database itself.

This option is the same as the -m server option, but applies only to the current database or the database identified by the database-file variable.

Replicated databases
Do not use the -m option with databases that are being replicated. Replication inherently relies on transaction log information.
Example

The following example starts a database server named silver and loads the sample database. When a checkpoint is done, the transaction log is truncated.

dbsrv9 -n silver "c:\Program Files\Sybase\SQL Anywhere 9\asademo.db" -m


-n database option
Function

Set the name of the database.

Syntax

{ dbsrv9 | dbeng9 } [ server-options ] database-file -n string ...

Applies to

All operating systems and servers.

Description

Both database servers and databases can be named. Since a database server can load several databases, the database name is used to distinguish the different databases.

By default, the database receives the name of the database file with the path and extension removed. For example, if the database is started on c:\asa\asademo.db and no -n option is specified, the name of the database is asademo.

The following are invalid for database server names:

  • names that begin with white space or single or double quotes

  • names that end with white space

  • names that contain semicolons

Example

The following example starts the database server with a cache size of 3 Mb, loads the sample database, and names the sample database "test".

dbsrv9 -c 3Mb "c:\Program Files\Sybase\SQL Anywhere 9\asademo.db" -n "test"
There are two -n options
The -n option is positional. If it appears before a database file name, it is a server option and names the server. If it appears after a database file name, it is a database option and names the database.

For example, the following command names the server SERV and the database DATA:

dbsrv9 -n SERV asademo.db -n DATA

For more information, see -n server option.


-r database option
Function

Start the named database as read-only. No changes to the database(s) are allowed: the server does not modify the database file(s) and transaction log files. This option is position dependent.

Syntax

{ dbsrv9 | dbeng9 } -r ...

Applies to

All operating systems and servers.

Description

Opens all database files as read-only with the exception of the temporary file when the option is specified before any database names on the command line. If the -r server option is specified after a database name, only that specific database is read-only. You can make changes on temporary tables, but ROLLBACK has no effect, since the transaction and rollback logs are disabled.

Databases distributed on CD-ROM devices, and compressed databases are examples of database files that cannot be modified. You can either create a write file to allow changes to the database outside the database file, or run in read-only mode.

If you attempt to modify the database, for example with an INSERT or DELETE statement, a SQLSTATE_READ_ONLY_DATABASE error is returned.

Databases that require recovery cannot be started in read-only mode. For example, database files created using an online backup cannot be started in read-only mode if there were any open transactions when the backup was started, since these transactions would require recovery when the backup copy is started.

Example

To open two databases in read-only mode

dbeng9 -r database1.db database2.db

To open only the first of two databases in read-only mode.

dbeng9 database1.db -r database2.db


Connection Parameters and Network Protocol Options

About this chapter

This chapter provides a reference for the parameters that establish and describe connections from client applications to a database.


Connection parameters

This section describes each connection parameter. Connection parameters are included in connection strings. They can be entered in the following places:

  • In an application's connection string.

    For more information, see Assembling a list of connection parameters.

  • In an ODBC data source.

    For more information, see Working with ODBC data sources.

  • In the Adaptive Server Anywhere Connect dialog.

    For more information, see Connecting from Adaptive Server Anywhere utilities.

The ODBC configuration dialog and the Adaptive Server Anywhere Connect dialog for Windows operating systems share a common format. Some of the parameters correspond to checkboxes and fields in these dialogs, while others can be entered in the text box on the Advanced tab.

Notes

  • Connection parameters are case insensitive.

  • The Usage for each connection parameter describes the circumstances under which the parameter is to be used. Common usage entries include the following:

    • Embedded databases When Adaptive Server Anywhere is used as an embedded database, the connection starts a personal server and loads the database. When the application disconnects from the database, the database is unloaded and the server stops.

    • Running local databases This refers to the case where an Adaptive Server Anywhere personal server is already running, and the database is already loaded on the server.

    • Network servers When Adaptive Server Anywhere is used as a network server, the client application must locate a server already running somewhere on the network and connect to a database.

  • You can use the dbping utility to test connection strings. For example, if a personal server with the name asademo is running the database asademo (which can be started with the command dbeng9 asademo.db)

    The following string returns the message Ping database successful:

    dbping -d -c "eng=asademo;dbn=asademo;uid=db;pwd=sql"

    The following command, however, returns the message Ping database failed – Database server not running:

    dbping -d -c "eng=other_engine;uid=dba;pwd=sql"

    For more information, see The Ping utility.

AppInfo connection parameter [APP]
AutoStart connection parameter [ASTART]
AutoStop connection parameter [ASTOP]
CharSet connection parameter [CS]
CommBufferSize connection parameter [CBSIZE]
CommLinks connection parameter [LINKS]
Compress connection parameter [COMP]
CompressionThreshold connection parameter [COMPTH]
ConnectionName connection parameter [CON]
DatabaseFile connection parameter [DBF]
DatabaseKey connection parameter [DBKEY]
DatabaseName connection parameter [DBN]
DatabaseSwitches connection parameter [DBS]
DataSourceName connection parameter [DSN]
DisableMultiRowFetch connection parameter [DMRF]
EncryptedPassword connection parameter [ENP]
Encryption connection parameter [ENC]
EngineName connection parameter [ENG]
FileDataSourceName connection parameter [FILEDSN]
ForceStart connection parameter [FORCESTART]
Idle connection parameter [IDLE]
Integrated connection parameter [INT]
Language connection parameter [LANG]
LazyClose connection parameter [LCLOSE]
LivenessTimeout connection parameter [LTO]
Logfile connection parameter [LOG]
Password connection parameter [PWD]
PrefetchBuffer connection parameter [PBUF]
PreFetchOnOpen connection parameter
PrefetchRows connection parameter [PROWS]
ServerName connection parameter [ENG]
StartLine connection parameter [START]
Unconditional connection parameter [UNC]
Userid connection parameter [UID]


AppInfo connection parameter [APP]

Function

To assist administrators in identifying the origin of particular client connections from a database server.

Usage

Anywhere

Values

String

Default

Empty string

Description

This connection parameter is sent to the database server from embedded SQL, ODBC, OLE DB, or ADO.NET clients and from applications using the iAnywhere JDBC driver. It is not available from Open Client or jConnect applications.

It consists of a generated string that holds information about the client process, such as the IP address of the client machine, the operating system it is running on, and so on. The string is associated in the database server with the connection, and you can retrieve it using the following statement:

SELECT connection_property( 'AppInfo' )

Clients can also specify their own string, which is appended to the generated string. The AppInfo property string is a sequence of semicolon-delimited key=value pairs. The valid keys are as follows:

  • API DBLIB, ODBC, OLEDB, or ADO.NET (ODBC is returned of the iAnywhere JDBC driver).

  • APPINFO If you specified AppInfo in the connection string, the string entered.

  • EXE The name of the client executable (Windows and NetWare only).

  • HOST The host name of the client machine.

  • IP The IP address of the client machine (UNIX and NetWare only).

  • OS The operating system name and version number (for example, Windows 2000, NetWare 5.1).

  • PID The process ID of the client (Windows and UNIX only).

  • THREAD The thread ID of the client (Windows and UNIX only).

  • TIMEZONEADJUSTMENT The number of minutes that must be added to the Coordinated Universal Time (UTC) to display time local to the connection.

  • VERSION The version of the connection protocol in use, including major and minor values, and a build number (for example 9.0.00.3642).

If you specify a debug log file in your client connection parameters, the APPINFO string is added to the file.

See also
  • How connection parameters work
  • Connection parameter tips
Examples

  • Connect to the sample database from Interactive SQL (the iAnywhere JDBC driver is used by default):

    dbisql -c "uid=DBA;pwd=SQL;dbf=C:\Program Files\Sybase\SQL Anywhere 9\asademo.db"

    View the application information:

    SELECT connection_property('appinfo')

    The result is as follows (in a single string):

    HOST=machine-name;OS=Windows 2000 Build 2195 Service Pack 3;PID=0x724;THREAD=0x6bc;EXE=C:\Program Files\Sybase\SQL Anywhere 9\win32\dbisqlg.exe;VERSION=9.0.00.3642;API=ODBC;TIMEZONEADJUSTMENT=-300

  • Connect to the sample database from Interactive SQL, appending your own information to the AppInfo property:

    dbisql -c "uid=DBA;pwd=SQL;dbf=C:\Program Files\Sybase\SQL Anywhere 9\asademo.db;app=ISQL connection"

    View the application information:

    SELECT connection_property('appinfo')

    The result is as follows (in a single string):

    HOST=machine-name;OS=Windows 2000 Build 2195 Service Pack 3;PID=0x8d0;THREAD=0xd74;EXE=C:\Program Files\Sybase\SQL Anywhere 9\win32\dbisqlg.exe;VERSION=9.0.00.3642;API=ODBC;TIMEZONEADJUSTMENT=-300;APPINFO=ISQL connection


AutoStart connection parameter [ASTART]

Function

To prevent a local database server from being started if no connection is found.

Usage

Anywhere

Values

YES, NO

Default

YES

Description

By default, if no server is found during a connection attempt, and a database file, database name, or the START connection parameter is specified, then a database server is started on the same machine. You can turn this behavior off by setting the AutoStart (ASTART) connection parameter to NO or OFF in the connection string.

See also
  • How connection parameters work
  • Connection parameter tips


AutoStop connection parameter [ASTOP]

Function

To prevent a database from being stopped as soon as there are no more open connections.

Usage

Embedded databases

Values

YES, NO

Default

YES

Description

By default, any server that is started from a connection string is stopped when there are no more connections to it. Also, any database that is loaded from a connection string is unloaded as soon as there are no more connections to it. This behavior is equivalent to AutoStop=YES.

If you supply AutoStop=NO, any database that you start in that connection remains running when there are no more connections to it. As a consequence, the database server remains operational as well.

The AutoStop (ASTOP) connection parameter is used only if you are connecting to a database that is not currently running. It is ignored if the database is already started.

See also
  • How connection parameters work
  • Connection parameter tips


CharSet connection parameter [CS]

Function

To specify the character set to be used on this connection.

Usage

Anywhere

Values

String

Default

The local character set.

For information on how this is determined, see Determining locale information.

Description

If you supply a value for CharSet, the specified character set is used for the current connection. Setting CharSet=none disables character set conversion for the connection.

For a list of valid character set values, see Character set labels.

See also
  • How connection parameters work
  • Connection parameter tips


CommBufferSize connection parameter [CBSIZE]

Function

To set the maximum size of communication packets, in bytes.

Usage

Anywhere

Values

Integer

Default

If no CommBufferSize value is set, the CommBufferSize is controlled by the setting on the server, which defaults to 1460 bytes.

Description

The CommBufferSize (CBSIZE) connection parameter specifies the size of communication packets, in bytes. The minimum value of CommBufferSize is 300, and the maximum is 16 000.

The protocol stack sets the maximum size of a packet on a network. If you set the CommBufferSize to be larger than that permitted by your network, the largest buffers are broken up by the network software. You should set the buffer size to be somewhat smaller than that allowed by your network because the network software may add information to each buffer before sending it over the network. The default of 1460 allows an ethernet packet to be completely filled when using TCP/IP.

A larger packet size may improve performance for multi-row fetches and fetches of larger rows, but it also increases memory usage for both the client and the server.

If CommBufferSize is not specified on the client, the connection uses the server's buffer size. If CommBufferSize is specified on the client, the connection uses the CommBufferSize value.

Using the -p database server option to set the CommBufferSize causes all clients that do not specify their own CommBufferSize to use the size specified by the -p database server option.

See also
  • How connection parameters work
  • Connection parameter tips
Example

  • To set the buffer size to 400 bytes:

    ...
CommBufferSize=400
...

    Alternatively, you can set this parameter by entering its value in the Buffer Size text box on the Network tab of the ODBC Configuration dialog.


CommLinks connection parameter [LINKS]

Function

To specify client side network protocol options.

Usage

Anywhere. The CommLinks (LINKS) connection parameter is optional for connections to a personal server, and required for connections to a network server.

Values

String

Default

Use only the shared memory communication protocol to connect.

Description

If you do not specify a CommLinks (LINKS) connection parameter, the client searches for a server on the current machine only, and only using a shared memory connection. This is the default behavior, and is equivalent to CommLinks=ShMem. The shared memory protocol is the fastest communication link between a client and server running on the same machine, as is typical for applications connecting to a personal database server.

If you specify CommLinks=ALL, the client searches for a server using all available communication protocols. Since there may be an impact on performance if you specify CommLinks=ALL, use this setting only when you don't know which protocol to use.

If you specify one or more protocols in the CommLinks (LINKS) connection parameter, the client uses the named communication protocol(s), in the order specified, to search for a network database server. A connection error appears and the connection attempt aborts if the connection fails to connect using a specified protocol, even if there are protocols remaining in the list to try.

CommLinks (LINKS) connection parameter values are case insensitive, and include:

  • SharedMemory (ShMem) Start the shared memory protocol for same-machine communication. This is the default setting. The client tries shared memory first if it appears in a list of protocols, regardless of the order in which protocols appear.

  • ALL Attempt to connect using the shared memory protocol first, followed by all remaining and available communication protocols. Use this setting if you are unsure of which communication protocol(s) to use.

  • NamedPipes (NP) For C2 security purposes, connect from a Windows NT/2000/XP client to a database server on the same machine that was started with the –sc option.

  • TCPIP (TCP) Start the TCP/IP communication protocol. TCP/IP is supported on all operating systems.

  • SPX Start the SPX communication protocol. The SPX protocol is supported for Windows and NetWare clients.

Each of these values can have additional network protocol options supplied.

For a list of parameters, see Network protocol options.

You may want to use a specific protocol, as opposed to ALL, for the following reasons:

  • The network library starts slightly faster if the client uses only necessary network protocols.

  • Connecting to the database may be faster.

  • You must specify the protocol explicitly if you want to tune the broadcast behavior of a particular protocol by providing additional network protocol options.

The CommLinks (LINKS) connection parameter corresponds to the database server –x option.

See also
  • Network protocol options
  • Client/Server Communications
  • -x server option
  • How connection parameters work
  • Connection parameter tips
Examples

  • The following connection string fragment starts the TCP/IP protocol only:

    CommLinks=tcpip

  • The following connection string fragment starts the shared memory protocol and searches for the database server over shared memory. If the search fails, it then starts the TCP/IP port and searches for the server on the local network. If that fails, it starts the SPX port and searches for the server over SPX.

    CommLinks=tcpip,shmem,spx

  • The following connection string fragment starts the SPX port and searches for the server over SPX. If the search fails, it then starts the TCP port and searches for the server on the local network, as well as the host kangaroo. Note that if the server is found over SPX, the TCP port is not started.

    CommLinks=spx,tcpip(HOST=kangaroo)


Compress connection parameter [COMP]

Function

To turn compression ON or OFF for a connection. Compressing a connection may improve performance under some circumstances.

Usage

Anywhere except with TDS connections. TDS connections (including jConnect) do not support Adaptive Server Anywhere communication compression.

Values

YES, NO

In the case of a difference between client and server settings, the client setting applies.

Default

NO

If no Compress value is set, the compression status is controlled by the setting on the server, which defaults to no compression.

Description

The packets sent between an Adaptive Server Anywhere client and server can be compressed using the Compress (COMP) connection parameter. Large data transfers with highly compressible data tend to get the best compression rates.

Available values of the Compress (COMP) connection parameter are case insensitive, and include:

  • YES Turn communication compression on for this connection.

  • NO Turn communication compression off for this connection.

To save yourself time and possible disappointment, it is wise to conduct a performance analysis on the particular network and using the particular application before using communication compression in a production environment.

To enable compression for all remote connections on the server, use the -pc server option.

Note that same-machine connections over any communication link will not enable compression, even if the -pc option or COMPRESS=YES parameter is used.

See also
  • -pc server option
  • Adjusting communication compression settings to improve performance
  • How connection parameters work
  • Connection parameter tips
Examples

  • The following connection string fragment turns packet compression ON:

    Compress=YES

  • The following connection string fragment turns packet compression OFF:

    Compress=NO


CompressionThreshold connection parameter [COMPTH]

Function

To increase or decrease the size limit at which packets are compressed. Changing the compression threshold can help performance of a compressed connection by allowing you to only compress packets when compression will increase the speed at which the packets are transferred.

Usage

Anywhere except TDS. Only applies to compressed connections.

Values

Integer, representing the minimum byte-size of packets to be compressed. Values less than 80 are not recommended.

If both client and server specify different compression threshold settings, the client setting applies.

Default

120

If no CompressionThreshold value is set, the compression threshold value is controlled by the setting on the server, which defaults to 120 bytes.

Description

When compression is enabled, individual packets may or may not be compressed, depending on their size. For example, Adaptive Server Anywhere does not compress packets smaller than the compression threshold, even if communication compression is enabled. As well, small packets (less than about 100 bytes) usually do not compress at all. Since CPU time is required to compress packets, attempting to compress small packets could actually decrease performance.

Generally speaking, lowering the compression threshold value may improve performance on very slow networks, while raising the compression threshold may improve performance by reducing CPU. However, since lowering the compression threshold value will increase CPU usage on both the client and server, a performance analysis should be done to determine whether or not changing the compression threshold is beneficial.

See also
  • -pt server option
  • Adjusting communication compression settings to improve performance
  • How connection parameters work
  • Connection parameter tips
Example

  • Connect, with a compression threshold of 100 bytes.

CompressionThreshold=100


ConnectionName connection parameter [CON]

Function

Names a connection, to make switching to it easier in multi-connection applications.

Usage

Anywhere.

Values

String

Default

No connection name.

Description

An optional parameter, providing a name for the particular connection you are making. You may leave this unspecified unless you are going to establish more than one connection, and switch between them.

The connection name is not the same as the data source name.

See also
  • How connection parameters work
  • Connection parameter tips
Example

  • Connect, naming the connection First_Con:

CON=First_Con


DatabaseFile connection parameter [DBF]

Function

For use when starting a database that is not already running. The DatabaseFile connection parameter indicates which database file you want to load and connect to.

If you want to connect to an already running database, use the DatabaseName (DBN) parameter.

Usage

Embedded databases

Values

String

Default

There is no default setting.

Description

The DatabaseFile (DBF) connection parameter is used to load and connect to a specific database file that is not already running on a database server.

  • If the database you want to connect to is not already running, use the DatabaseFile (DBF) connection parameter so the database can be started.

  • If the filename does not include an extension, Adaptive Server Anywhere looks for a file with the .db extension.

  • The path of the file is relative to the working directory of the database server. If you start the server from a command prompt, the working directory is the directory that you are in when entering the command. If you start the server from an icon or shortcut, it is the working directory that the icon or shortcut specifies. It is recommended that you supply a complete path and file name.

  • If you specify both the database file and the database name, an attempt is made to connect to a running database with the specified name (the database file is ignored), and if that fails, an attempt is made to autostart a database using both the database file and database name.

You can also use UNC filenames and Novell NetWare Directory Services file names.

For information about using UNC filenames and Novell NetWare Directory Services file names, see The database server.

Caution
The database file must be on the same machine as the database server. Starting a database file that is located on a network drive can lead to file corruption.
See also
  • DatabaseName connection parameter [DBN]
  • How connection parameters work
  • Connection parameter tips
Example

  • The DatabaseFile (DBF) connection parameter in the following example loads and connects to the sample database, asademo.db, installed in the directory c:\Program Files\Sybase\SQL Anywhere 9:

    DBF=c:\Program Files\Sybase\SQL Anywhere 9\asademo.db

  • The following two examples assume that you have started a database file named cities.db, and renamed the database Kitchener as follows:

    dbeng9 cities.db -n Kitchener

    • To successfully start and connect to a database and name it Kitchener:

      DBN=Kitchener;DBF=cities.db

    • Specifying DBF=cities.db would fail to connect to the running database named Kitchener.


DatabaseKey connection parameter [DBKEY]

Function

To start an encrypted database with a connect request.

Usage

Anywhere

Values

String

Default

None

Description

You must specify this parameter when you start an encrypted database with a connect request. You do not need to specify this parameter if you are connecting to an encrypted database that is already running.

The encryption key is a string, including mixed cases, numbers, letters, and special characters.

If you want to secure communication packets between client applications and the database server use the -ec server option and transport-layer security.

For more information, see Adaptive Server Anywhere Transport-Layer Security.

See also
  • -ek database option
  • -ep server option
  • How connection parameters work
  • Connection parameter tips
Example

The following fragment illustrates the use of the DatabaseKey (DBKEY) connection parameter:

"UID=dba;PWD=sql;ENG=myeng;DBKEY=V3moj3952B;DBF=C:\Program Files\Sybase\SQL Anywhere 9\asademo.db"


DatabaseName connection parameter [DBN]

Function

For use when connecting to a database that is already running. Identifies a loaded database to which a connection needs to be made.

If you want to connect to a database that is not already running, use the DatabaseFile (DBF) parameter.

Usage

Running local databases or network servers.

Values

String

Default

There is no default setting.

Description

Whenever a database is started on a server, it is assigned a database name, either by the administrator using the -n option, or by the server using the base of the filename with the extension and path removed.

Note
The DatabaseName (DBN) connection parameter is recommended for naming databases, rather than using the -n option with the DatabaseSwitches (DBS) connection parameter.

If the database you want to connect to is already running, you should specify the database name rather than the database file.

A connection will only occur if the name of the running database matches the name that is specified in the DatabaseName (DBN) parameter.

Note
If you specify both the database file and the database name, an attempt is made to connect to a running database with the specified name (the database file is ignored), and if that fails, an attempt is made to autostart a database using both the database file and database name.
See also
  • How connection parameters work
  • Connection parameter tips
Example

  • To start a database file named cities.db and rename the database Kitchener, you can use the following command:

    dbeng9 cities.db -n Kitchener

  • Assuming you have run the above command, you can successfully connect to the running database named Kitchener as follows:

    DBN=Kitchener

  • Alternatively, you could use the following to successfully connect to the running database named Kitchener:

    DBN=Kitchener;DBF=cities.db

  • However, specifying the following would fail to connect to the database named Kitchener:

    DBF=cities.db


DatabaseSwitches connection parameter [DBS]

Function

To provide database-specific options (switches) when starting a database.

Usage

Connecting to a server when the database is not loaded. This connection parameter autostarts a server with the specified database and options if a server is not already running.

Values

String

Default

No options

Description

You should supply DatabaseSwitches only if you are connecting to a database that is not currently running. When the server starts the database specified by DatabaseFile, the server uses the supplied DatabaseSwitches to determine startup options for the database.

Only database options (switches) can be supplied using this parameter. Server options must be supplied using the StartLine connection parameter.

For information about database options, see Database options.

Note
The DatabaseName (DBN) connection parameter is recommended for naming databases, rather than using the -n option with the DatabaseSwitches (DBS) connection parameter.
See also
  • The database server
  • StartLine connection parameter [START]
  • How connection parameters work
  • Connection parameter tips
Example

  • The following command, entered all on one line at a command prompt, connects to the default database server, loads the database file asademo.db (DatabaseFile (DBF) connection parameter), names it my_db (DatabaseName (DBN) connection parameter) and starts it in read-only mode (-r option).

    dbisql -c "uid=DBA;pwd=SQL;dbf=c:\Program Files\Sybase\SQL Anywhere 9\asademo.db;dbn=my_db;dbs=-r"


DataSourceName connection parameter [DSN]

Function

Tells the ODBC driver manager or embedded SQL library where to look in the .odbc.ini file or registry to find ODBC data source information.

Usage

Anywhere

Values

String

Default

There is no default data source name.

Description

It is common practice for ODBC applications to send only a data source name to ODBC. The ODBC driver manager and ODBC driver locate the data source, which contains the remainder of the connection parameters.

In Adaptive Server Anywhere, embedded SQL applications can also use ODBC data sources to store connection parameters.

See also
  • FileDataSourceName connection parameter [FILEDSN]
  • How connection parameters work
  • Connection parameter tips
Example

  • The following parameter uses a data source name:

DSN=Dynamo Demo


DisableMultiRowFetch connection parameter [DMRF]

Function

To turn off multi-row fetches across the network

Usage

Anywhere

Values

YES, NO

Default

NO

Description

By default, when the database server gets a simple fetch request, the application asks for extra rows. You can disable this behavior by setting this parameter to ON.

For more information, see Using cursors in procedures and triggers.

Setting the DisableMultiRowFetch (DMRF) connection parameter to ON is equivalent to setting the PREFETCH database option to OFF.

For more information, see Prefetching rows.

See also
  • How connection parameters work
  • Connection parameter tips
Example

  • The following connection string fragment prevents prefetching:

    DMRF=YES


EncryptedPassword connection parameter [ENP]

Function

To provide a password, stored in an encrypted fashion in a data source.

Usage

Anywhere

Values

String

Default

None

Description

Data sources are stored on disk as a file or in the registry. Storing passwords on disk may present a security problem. For this reason, when you enter a password into a data source, it is stored in an encrypted form.

If both the Password (PWD) connection parameter and the EncryptedPassword (ENP) connection parameter are specified, Password (PWD) takes precedence.

See also
  • How connection parameters work
  • Connection parameter tips


Encryption connection parameter [ENC]

Function

To encrypt packets sent between the client application and the server using transport-layer security or simple encryption.

Usage

For ECC_TLS (Certicom), RSA_TLS, RSA_TLS, RSA_TLS_FIPS, TCP/IP only.

For NONE or SIMPLE, anywhere.

Values

String

Default

NONE

If an Encryption value is not set, encryption is controlled by the setting on the server.

For information about the server's encryption setting, see -ec server option.

Description

You can use this parameter if you want to secure communications between client applications and the database server using transport-layer security.

For more information, see Adaptive Server Anywhere Transport-Layer Security.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

The Encryption (ENC) connection parameter accepts the following arguments:

  • none accepts communication packets that are not encrypted. This value is equivalent to NO in previous versions of Adaptive Server Anywhere.

  • simple accepts communication packets that are encrypted with simple encryption supported on all platforms and on previous versions of Adaptive Server Anywhere. This value is equivalent to YES in previous versions of Adaptive Server Anywhere. Simple encryption does not provide server authentication, strong elliptic-curve or RSA encryption, or other features of transport-layer security.

  • ECC_TLS accepts communication packets that are encrypted using elliptic-curve based Certicom encryption technology. For backwards compatibility, ecc_tls can also be specified as CERTICOM. To use this type of encryption, both the server and the client must be operating on Solaris, Linux, NetWare, Mac OS X, or any supported Windows operating system except Windows CE, and the connection must be over the TCP/IP port. UNIX platforms, except for Solaris, Linux, and Mac OS X, do not recognize the client or server ECC_TLS parameter. The client can use the following arguments to verify the field values in the server's public certificate:

    • trusted_certificates specify the certificate file the client uses to authenticate the server. This is the only required parameter.

    • certificate_company specify the value for the organization field of the certificate.

    • certificate_unit specify the value for the organization unit field of the certificate.

    • certificate_name specify the certificate's common name.

      For more information about verifying certificate fields for server authentication, see Verifying certificate fields.

      For more information about using digital certificates, see Creating digital certificates.

  • RSA_TLS accepts communication packets that are encrypted using RSA encryption technology. To use this type of encryption, both the server and the client must be operating on Solaris, Linux, NetWare, Mac OS X, or any supported Windows operating system except Windows CE, and the connection must be over the TCP/IP port. UNIX platforms, except for Solaris, Linux, and Mac OS X, do not recognize the client or server RSA_TLS parameter. The client can use the following arguments to verify the field values in the server's public certificate:

    • trusted_certificates specify the certificate file the client uses to authenticate the server. This is the only required parameter.

    • certificate_company specify the value for the organization field of the certificate

    • certificate_unit specify the value for the organization unit field of the certificate.

    • certificate_name specify the certificate's common name.

      For more information about verifying certificate fields for server authentication, see Verifying certificate fields.

      For more information about using digital certificates, see Creating digital certificates.

  • RSA_TLS_FIPS accepts communication packets that are encrypted using FIPS-approved RSA encryption technology. RSA_TLS_FIPS uses a separate approved library, but is compatible with servers specifying RSA_TLS with Adaptive Server Anywhere 9.0.2 or later. To use this type of encryption, both the client and the server must be operating on a supported 32-bit Windows operating system, and the connection must be over the TCP/IP port. The client can use the following arguments to verify the field values in the server's public certificate:

    • trusted_certificates specify the certificate file the client uses to authenticate the server. This is the only required parameter.

    • certificate_company specify the value for the organization field of the certificate.

    • certificate_unit specify the value for the organization unit field of the certificate.

    • certificate_name specify the certificate's common name.

      For more information about verifying certificate fields for server authentication, see Verifying certificate fields.

      For more information about using digital certificates, see Creating digital certificates.

If you are using FIPS-approved RSA encryption, you must generate your certificates using the RSA cipher.

For information about certificates, see Creating digital certificates.

You can use the connection_property system function to retrieve the encryption settings for the current connection. The function returns one of five values: none, simple, ecc_tls, rsa_tls, or rsa_tls_fips depending which type of encryption is being used.

For information about using the connection_property system function, see CONNECTION_PROPERTY function [System].

See also
  • Configuring client applications to use transport-layer security
  • -ec server option
  • How connection parameters work
  • Connection parameter tips
Examples

The following connection string fragment connects to a database server myeng with a TCP/IP link, using transport-layer security and elliptic-curve encryption:

"ENG=myeng;LINKS=tcpip;Encryption=ECC_TLS (trusted_certificates=sample.crt)"

The following connection string fragment connects to a database server myeng with a TCP/IP link, using transport-layer security and RSA encryption:

"ENG=myeng;LINKS=tcpip;Encryption=RSA_TLS (trusted_certificates=sample.crt)"

The following connection string fragment connects to a database server myeng with a TCP/IP link, using simple encryption:

"ENG=myeng;LINKS=tcpip;Encryption=SIMPLE"


EngineName connection parameter [ENG]

Function

Synonym for ServerName. The name of a running database server to which you want to connect.

Usage

Network servers or running personal servers.

Values

String

Default

The default local database server.

Description

EngineName is not needed if you want to connect to the default local database server.

You only need to supply an EngineName if more than one local database server is running, or if you want to connect to a network server. In the Connect dialog, and in the ODBC Administrator, this is the Server Name field.

If you are autostarting a server, you can provide a server name using this parameter.

The server name is interpreted according to the character set of the client machine. Multi-byte characters are not recommended in server names.

Names must be a valid identifier. Long server names are truncated to different lengths depending on the protocol.

Protocol | Truncation Length
UNIX shared memory | 31 bytes
non-UNIX shared memory | 40 bytes
TCP/IP | 40 bytes
SPX | 32 bytes
Named Pipes | 8 bytes
Note
It is recommended that you include the EngineName parameter in connection strings for deployed applications. This ensures that the application connects to the correct server in case a machine is running multiple Adaptive Server Anywhere database servers and can help prevent timing-dependent connection failures.
See also
  • Identifiers
  • -n server option
  • How connection parameters work
  • Connection parameter tips
Example

  • Connect to a server named Guelph:

    ENG=Guelph


FileDataSourceName connection parameter [FILEDSN]

Function

Tells the client library there is an ODBC file data source holding information about the database to which you want to connect.

Usage

Anywhere

Values

String

Default

There is no default name.

Description

File data sources hold the same information as ODBC data sources stored in the registry. File data sources can be easily distributed to end users so that connection information does not have to be reconstructed on each machine.

Both ODBC and embedded SQL applications can use File data sources.

See also
  • DataSourceName connection parameter [DSN]
  • How connection parameters work
  • Connection parameter tips


ForceStart connection parameter [FORCESTART]

Function

To start a server without attempting to connect to one.

Usage

Only with the db_start_engine function

Values

YES, NO

Default

NO

Description

By setting ForceStart=YES, the db_start_engine function starts a server without attempting to connect to one, even if there is one already running.

See also
  • db_start_engine function
  • How connection parameters work
  • Connection parameter tips


Idle connection parameter [IDLE]

Function

To specify the connection's idle timeout period.

Usage

Anywhere except with TDS and Shared Memory connections. Shared Memory and TDS connections (including jConnect) ignore the Adaptive Server Anywhere Idle (IDLE) connection parameter.

Values

Integer

Default

240

Description

The Idle (IDLE) connection parameter applies only to the current connection. You can have multiple connections on the same server set to different timeout values.

If no connection idle timeout value is set, the idle timeout value is controlled by the setting on the server, which defaults to 240 minutes. In case of a conflict between timeout values, the connection timeout value supercedes any server timeout value whether specified or unspecified.

See also
  • -ti server option
  • How connection parameters work
  • Connection parameter tips
Example

  • The following connection string fragment sets the timeout value for this connection to 10 minutes:

    "ENG=myeng;LINKS=tcpip;IDLE=10"


Integrated connection parameter [INT]

Function

To use the integrated login facility.

Usage

Anywhere

Values

YES, NO

Default

NO

Description

The Integrated (INT) connection parameter has the following settings:

  • YES An integrated login is attempted. If the connection attempt fails and the LOGIN_MODE option is set to Mixed, a standard login is attempted.

  • NO This is the default setting. No integrated login is attempted.

For a client application to use an integrated login, the server must be running with the LOGIN_MODE database option set to Mixed or Integrated.

See also
  • LOGIN_MODE option [database]
  • How connection parameters work
  • Connection parameter tips
Example

  • The following data source fragment uses an integrated login:

    INT=YES


Language connection parameter [LANG]

Function

Specifies the language of the connection.

Usage

Anywhere

Values

The two-letter combination representing a language. For example, setting LANG=DE sets the default language to German.

Default

The language specified by (in order) the ASLANG environment variable, the dblang utility, or the installer.

Description

This connection parameter establishes the language for the connection. Any errors or warnings from the server are delivered in the specified language, assuming that the server supports the language.

If no language is specified, the default language is used. The default language is the language specified by, in order, the ASLANG environment variable, the dblang utility, or the installer.

For a list of language codes, see Understanding the locale language.

This connection parameter only affects the connection. Messages returned from Adaptive Server Anywhere's various tools and utilities appear in the default language, while the messages returned from the server appear in the connection's language.

See also
  • How connection parameters work
  • Connection parameter tips


LazyClose connection parameter [LCLOSE]

Function

Enabling this option causes the CLOSE cursor-name database request to be queued, and then sent to the server with the next database request. This eliminates a network request each time a cursor is closed.

Usage

Anywhere

Values

YES, NO

Default

NO

Description

When this parameter is enabled, cursors are not actually closed until the next database request. Any isolation level 1 cursor stability locks still apply to the cursor while the CLOSE cursor-name database request is queued.

Enabling this option can improve performance if your:

  • network exhibits poor latency

  • application sends many cursor open and close requests

Note that in rare circumstances, canceling the next request after the CLOSE cursor-name database request can leave the cursor in a state where it appears to be closed on the client side, but is not actually closed on the server side. Subsequent attempts to open another cursor with the same name will fail. Using LazyClose is not recommended if your application cancels requests frequently.

See also
  • How connection parameters work
  • Connection parameter tips


LivenessTimeout connection parameter [LTO]

Function

To control the termination of connections when they are no longer intact.

Usage

Network server only.

All platforms except non-threaded UNIX applications.

Values

Integer (in seconds)

Default

120

If no LivenessTimeout value is set, the LivenessTimeout is controlled by the setting on the server, which defaults to 120 seconds.

Description

A liveness packet is sent periodically across a client/server TCP/IP or SPX communication protocol to confirm that a connection is intact. If the client runs for the LivenessTimeout period without detecting a liveness request or response packet, the communication is severed.

Liveness packets are sent when a connection has not sent any packets for between one third and two thirds of the LivenessTimeout value.

When there are more than 200 connections to a server, the server automatically calculates a higher LivenessTimeout value based on the stated LivenessTimeout value. This enables the server to handle a large number of connections more efficiently.

Alternatively, you can set this parameter by entering its value in the LivenessTimeout text box of the Network tab of the ODBC Configuration dialog.

See also
  • How connection parameters work
  • Connection parameter tips
Example

  • The following sets a LivenessTimeout value of 10 minutes

    LTO=600


Logfile connection parameter [LOG]

Function

To send client error messages and debugging messages to a file.

Usage

Anywhere

Values

String

Default

No log file

Description

If you want to save client error messages and debugging messages in a file, use the Logfile (LOG) connection parameter.

If the file name includes a path, it is relative to the current working directory of the client application.

The LogFile (LOG) connection parameter is connection-specific, so from a single application you can set different LogFile arguments for different connections.

Typical log file contents are as follows:

Fri Oct 27 2000 11:45
Application information:
"HOST=NAME-PC;OS=Windows NT 4.0 (Service Pack 5);PID=0x14b;THREAD=0x148;EXE=C:\ASA90\WIN32\DBPING.EXE;VERSION=9.0.0.1271;API=DBLIB;TIMEZONEADJUSTMENT=-300"
Attempting to connect using:
UID=dba;PWD=***;ENG=name;DBG=YES;LOG=c:\temp\cli.out;LINKS=shmem,tcpip
Attempting to connect to a running server...
Trying to start SharedMemory link ...
    SharedMemory link started successfully
Attempting SharedMemory connection (no asasrv.ini cached address)
Failed to connect over SharedMemory
Trying to start TCPIP link ...
Loading wsock32.dll
Loading ws2_32.dll
TCP using Winsock version 2.0
My IP address is 172.31.142.196
My IP address is 127.0.0.1
    TCPIP link started successfully
Attempting TCPIP connection (address 172.31.143.196:2638 found in asasrv.ini cache)
Trying to find server at cached address 172.31.143.196:2638 without broadcasting
    Server not found (no reply received)
Looking for server with name NAME
I am in a class B network
Sending broadcast to find server
Using broadcast address of: 172.31.255.255:2638
I am in a class A network
Sending broadcast to find server
Using broadcast address of: 127.255.255.255:2638
Found database server at address 172.31.142.196:2638
Found database server NAME on TCPIP link
Connected to server over TCPIP at address 172.31.142.196:2638
Writing server address 172.31.142.196:2638 to asasrv.ini cache
   Liveness timeout 120, liveness retransmit period 30
Connected to the server, attempting to connect to a running database...
Connected to database successfully
See also
  • How connection parameters work
  • Connection parameter tips
Example

The following command line starts Interactive SQL, connecting to the ASA 9.0 Sample data source with a LogFile (LOG) connection parameter:

dbisql -c "DSN=ASA 9.0 Sample;LOG=d:\logs\test.txt"


Password connection parameter [PWD]

Function

To provide a password for a connection.

Usage

Anywhere

Values

String

Default

No password provided.

Description

Every user of a database has a password. The password must be supplied for the user to be allowed to connect to the database. Passwords have a maximum length of 255 bytes.

The Password (PWD) connection parameter is not encrypted. If you are storing passwords in a data source, you should use the EncryptedPassword (ENP) connection parameter. Sybase Central and the Adaptive Server Anywhere ODBC configuration tool both use encrypted parameters.

If both Password (PWD) connection parameter and the EncryptedPassword (ENP) connection parameter are specified, the Password (PWD) connection parameter takes precedence.

Alternatively, you can set this parameter in the Password text box in the Connect dialog and ODBC Administrator dialog.

See also
  • EncryptedPassword connection parameter [ENP]
  • GRANT statement
  • Case sensitivity
  • How connection parameters work
  • Connection parameter tips
Example

  • The following connection string fragment supplies the user ID DBA and password SQL.

    UID=DBA;PWD=SQL


PrefetchBuffer connection parameter [PBUF]

Function

Set the maximum amount of memory for buffering rows, in kilobytes.

Usage

Anywhere

Values

Integer

Default

16 (Windows CE) 64 (all other platforms)

Description

The PrefetchBuffer (PBUF) connection parameter controls the memory allocated on the client to store prefetched rows. In some circumstances, increasing the number of rows prefetched from the database server by the client can improve query performance. You can increase the number of rows prefetched using the PrefetchRows (PROWS) and PrefetchBuffer (PBUF) connection parameters.

Increasing the PrefetchBuffer (PBUF) connection parameter increases the amount of memory used to buffer GET DATA requests. This may improve performance for some applications that process many GET DATA (SQLGetData) requests.

For more information, see PrefetchRows connection parameter [PROWS].

See also
  • How connection parameters work
  • Connection parameter tips
Examples

  • The following connection string fragment could be used to determine if the PrefetchBuffer memory limit is reducing the number of rows prefetched.

    ...PrefetchRows=100;Debug=YES;Logfile=c:\client.txt

  • The following string could be used to increase the memory limit to 256 K:

    ...PrefetchRows=100;PrefetchBuffer=256


PreFetchOnOpen connection parameter

Usage

ODBC

Values

YES, NO

Default

NO

Description

Enabling this option sends a prefetch request with a cursor open request, thereby eliminating a network request to fetch rows each time a cursor is opened. Columns must already be bound in order for the prefetch to occur on the open. Rebinding columns between the cursor open and the first fetch when using PrefetchOnOpen will cause reduced performance.

Calling ODBC's SQLExecute or SQLExecDirect on a query or stored procedure which returns a result set causes a cursor open.

Enabling this option can improve performance if your:

  • network exhibits poor latency

  • application sends many cursor open and close requests


PrefetchRows connection parameter [PROWS]

Function

Set the maximum number of rows to prefetch when querying the database.

Usage

Anywhere

Values

Integer

Default

10

Description

Increasing the number of rows prefetched from the database server by the client can improve performance on cursors that only fetch relative 0 or 1, with either single row or wide fetches. Wide fetches include embedded SQL array fetches and ODBC block fetches.

Improvements occur particularly under the following conditions:

  • The application fetches many rows (several hundred or more) with very few absolute fetches.

  • The application fetches rows at a high rate, and the client and server are on the same machine or connected by a fast network.

  • Client/server communication is over a slow network, such as a dial-up link or wide area network.

The number of rows prefetched is limited both by the PrefetchRows (PROWS) connection parameter and the PrefetchBuffer (PBUF) connection parameter, which limits the memory available for storing prefetched rows.

For more information, see PrefetchBuffer connection parameter [PBUF].

See also
  • How connection parameters work
  • Connection parameter tips
Example

  • The following connection string fragment sets the number of prefetched rows to 100:

    ...PrefetchRows=100;...


ServerName connection parameter [ENG]

This is a synonym for the EngineName (ENG) connection parameter.

For more information, see EngineName connection parameter [ENG].


StartLine connection parameter [START]

Function

To start a personal database server running from an application.

Usage

Embedded databases

Values

String

Default

No StartLine parameter

Description

You should supply a StartLine (START) connection parameter only if you are connecting to a database server that is not currently running. The StartLine (START) connection parameter is a command line to start a personal database server.

For a detailed description of available command line options, see The database server.

See also
  • How connection parameters work
  • Connection parameter tips
Example

  • The following data source fragment starts a personal database server with a cache of 8 Mb.

    StartLine=dbeng9 -c 8M;dbf=asademo.db


Unconditional connection parameter [UNC]

Function

To stop a server using dbstop, even when there are connections to the server.

Usage

Anywhere

Values

YES, NO

Default

NO

Description

The dbstop utility shuts down a database server. If you specify UNC=YES in the connection string, the server is shut down even if there are active connections. If Unconditional is not set to YES, then the server is shut down only if there are no active connections.

See also
  • Stopping a database server using the dbstop command-line utility
  • How connection parameters work
  • Connection parameter tips
Example

  • The following command line shuts down the server unconditionally:

    dbstop -c "UID=DBA;PWD=SQL;ENG=server-name;UNC=YES"


Userid connection parameter [UID]

Function

The user ID with which you log on to the database.

Usage

Anywhere

Values

String

Default

None

Description

You must always supply a user ID when connecting to a database.

See also
  • How connection parameters work
  • Connection parameter tips
Example

  • The following connection string fragment supplies the user ID DBA and password SQL:

    uid=DBA;pwd=SQL


Network protocol options

Network protocol options (for both the client and the server) enable you to work around peculiarities of different network protocol implementations.

You can supply the network protocol options in the server command. For example:

dbsrv9 -x tcpip(PARM1=value1;PARM2=value2;. . .),SPX

From the client side, you enter the protocol options as the CommLinks (LINKS) connection parameter:

CommLinks=tcpip(PARM1=value1;PARM2=value2;. . .),SPX

If there are spaces in a parameter, the network protocol options must be enclosed in quotation marks to be parsed properly by the system command interpreter:

dbsrv9 -x "tcpip(PARM1=value 1;PARM2=value 2;...),SPX"
CommLinks="tcpip(PARM1=value 1;PARM2=value 2;...),SPX"

The quotation marks are required under UNIX if more than one parameter is given because UNIX interprets the semicolon as a command separator.

Boolean parameters are turned on with YES, ON, TRUE, or 1, and are turned off with any of NO, OFF, FALSE, and 0. The parameters are case insensitive.

The examples provided should all be entered on a single line; you can also include them in a configuration file and use the @ server option to invoke the configuration file.

TCP/IP, HTTP, HTTPS, and SPX protocol options

The options currently available for TCP/IP, HTTP, HTTPS, and SPX are as follows.

TCP/IP | HTTP & HTTPS | SPX
Broadcast [BCAST] | Certificate | BroadcastListener [BLISTENER]
BroadcastListener [BLISTENER] | Certificate_Password | DLL
ClientPort [CPORT] | DatabaseName [DBN] | DoBroadcast [DOBROAD]
DLL | LocalOnly [LOCAL] | ExtendedName [ENAME]
DoBroadcast [DOBROAD] | LogFile [LOG] | Host [IP]
Host [IP] | LogMaxSize [LSize] | RegisterBindery [REGBIN]
LocalOnly [LOCAL] | LogOptions [LOpt] | SearchBindery [BINSEARCH]
LDAP [LDAP] | LogFormat [LF] | Timeout [TO]
MyIP [ME] | MaxConnections [MaxConn] |
ReceiveBufferSize [RCVBUFSZ] | MaxRequestSize [MaxSize] |
SendBufferSize [SNDBUFSZ] | MyIP [ME] |
ServerPort [PORT] | ServerPort [PORT] |
TDS | Timeout [TO] |
Timeout [TO] |  |
VerifyServerName [VERIFY] |  |

Broadcast protocol option [BCAST]
BroadcastListener protocol option [BLISTENER]
Certificate protocol option
Certificate_Password protocol option
ClientPort protocol option [CPORT]
DatabaseName protocol option [DBN]
DLL protocol option
DoBroadcast protocol option [DOBROAD]
ExtendedName protocol option [ENAME]
Host protocol option [IP]
LDAP protocol option [LDAP]
LocalOnly protocol option [LOCAL]
LogFile protocol option [LOG]
LogFormat protocol option [LF]
LogMaxSize protocol option [LSIZE]
LogOptions protocol option [LOPT]
MaxConnections protocol option [MAXCONN]
MaxRequestSize protocol option [MAXSIZE]
MyIP protocol option [ME]
ReceiveBufferSize protocol option [RCVBUFSZ]
RegisterBindery protocol option [REGBIN]
SearchBindery protocol option [BINSEARCH]
SendBufferSize protocol option [SNDBUFSZ]
ServerPort protocol option [PORT]
TDS protocol option
Timeout protocol option [TO]
VerifyServerName protocol option [VERIFY]


Broadcast protocol option [BCAST]

Usage

TCP/IP

Values

String (in the form of an IP address)

Default

Broadcasts to all addresses on the same subnet

Description

BROADCAST specifies the IP address that should be used to send broadcast messages. The default broadcast address is created using the local IP address and subnet mask. The subnet mask indicates which portion of the IP address identifies the network, and which part identifies the host.

For example, for a subnet of 10.24.98.x, with a mask of 255.255.255.0, the default broadcast address would be 10.24.98.255.


BroadcastListener protocol option [BLISTENER]

Usage

SPX, TCP/IP, Server side

Values

YES, NO

Default

YES

Description

This option allows you to turn broadcast listening OFF for this port.

Using -sb 0 is the same as specifying BroadcastListener=NO on both TCP/IP and SPX.

See also
  • -sb server option
Example

  • Start a server that accepts both TCP/IP and SPX connections, but require that TCP/IP connections use the HOST protocol option:

    dbsrv9 -x tcpip(BroadcastListener=NO),spx ...


Certificate protocol option

Usage

HTTPS

Values

String

Default

There is no default certificate name.

Description

This option allows you to specify the name of an encryption certificate. The password for this certificate must be specified with the Certificate_Password parameter.

Example

  • Start a server that requires web connections to use a particular encryption certificate.

    dbsrv9 -xs https(Certificate=cert.file;Certificate_Password=secret) ...


Certificate_Password protocol option

Usage

HTTPS

Values

String

Default

There is no default certificate password.

Description

This option allows you to specify the password that matches the encryption certificate specified by the Certificate parameter.

Example

  • Start a server that requires web connections to use a particular encryption certificate.

    dbsrv9 -xs https(Certificate=cert.file;Certificate_Password=secret) ...


ClientPort protocol option [CPORT]

Usage

TCP/IP (Client side only)

Values

Integer

Default

Assigned dynamically per connection by the networking implementation. If you do not have firewall restrictions, it is recommended that you do not use this parameter.

Description

This option is provided for connections across firewalls, as firewall software filters according to TCP/UDP port. It is recommended that you do not use this parameter unless you need to for firewall reasons.

The ClientPort option designates the port number on which the client application communicates using TCP/IP. You may specify a single port number, or a combination of individual port numbers and ranges of port numbers.

It is best to specify a list or a range of port numbers if you want to make multiple connections using a given Data Source or a given connect string. If you specify a single port number, then your application will be able to maintain only one connection at a time. In fact, even after closing the one connection, there is a several minute timeout period during which no new connection can be made using the specified port. When you specify a list and/or range of port numbers, the application keeps trying port numbers until it finds one to which it can successfully bind.

See also
  • Host protocol option [IP]
  • DoBroadcast protocol option [DOBROAD]
  • ServerPort protocol option [PORT]
  • Connecting across a firewall
Examples

  • The following connection string fragment makes a connection from an application using port 6000 to a server named my_server using port 5000:

CommLinks=tcpip(ClientPort=6000;ServerPort=5000); ServerName=my_server

  • The following connection string fragment makes a connection from an application that can use ports 5050 through 5060, as well as ports 5040 and 5070 for communicating with a server named my_server using the default server port:

CommLinks=tcpip(ClientPort=5040,5050-5060,5070);
gServerName=my_server


DatabaseName protocol option [DBN]

Usage

HTTP, HTTPS

Values

AUTO, REQUIRED, database-name

Default

AUTO

Description

Specifies the name of a database to use when processing web requests, or uses the REQUIRED or AUTO keyword to specify whether database names are required as part of the URI.

If this parameter is set to REQUIRED, the URI must specify a database name.

If this parameter is set to AUTO, the URI may specify a database name, but does not need to do so. If the URI contains no database name, the default database on the server is used to process web requests. Since the server must guess whether or not the URI contains a database name when set to AUTO, you should design your web site so as to avoid ambiguity.

If this parameter is set to the name of a database, that database is used to process all web requests. The URI must not contain a database name.

Example

  • The following command starts two databases, but permits only one of them to be accessed via HTTP.

    dbsrv9 -xs http(dbn=web) asademo.db web.db


DLL protocol option

Usage

TCP/IP, SPX (Windows 95/98/Me, Windows NT/2000/XP)

Values

String

Default

  • For database servers on all Windows platforms, including Windows CE, the default is ws2_32.dll (Winsock 2.0).

  • For clients on Windows NT/2000/XP, the default is ws2_32.dll (Winsock 2.0).

  • For clients on Windows 95/98/Me and Windows CE, the default is wsock32.dll (Winsock 1.1).

Description

To support untested TCP/IP protocol stacks where the required networking interface functions are in DLLs that differ from the default protocol stack. The client or server looks for its required functionality in the named DLLs.

Winsock 2.0 is required for database servers on all Windows platforms.

Example

  • The following command on Windows 98 uses Winsock 2.0:

    dbping -c "eng=my_eng;links=tcpip(dll=ws2_32.dll)"


DoBroadcast protocol option [DOBROAD]

Usage

TCP/IP, SPX

Values

ALL, NONE, DIRECT (Client side)

YES, NO (Server side)

Default

ALL (Client side), YES (Server side)

Description

Client usage With DoBroadcast=ALL (formerly DoBroadcast=YES) a broadcast is performed to search for a server. The broadcast goes first to the local subnet. If HOST= is specified, broadcast packets are also sent to each of the hosts. For TCP, all broadcast packets are UDP packets. For SPX, the broadcast is only performed if the server is not found in the bindery. For SPX, all broadcast packets are IPX packets.

With DoBroadcast=DIRECT (formerly DoBroadcast=NO), no broadcast is performed to the local subnet to search for a database server. Broadcast packets are sent only to the hosts listed in the HOST (IP) protocol option. If you specify DoBroadcast=DIRECT, the HOST (IP) protocol option is required.

Specifying DoBroadcast=NONE causes no UDP or IPX broadcasts to be used and the server address cache (asasrv.ini) is ignored. A TCP/IP or SPX connection is made directly with the HOST/PORT specified, and the server name is verified. With TCP/IP, you can choose not to verify the server name by setting the VerifyServerName (VERIFY) protocol option to NO. The HOST (IP) protocol option is a required parameter, while the ServerPort (PORT) protocol option is optional.

For DIRECT and NONE, you must specify the server host with the HOST option.

Server usage Setting DoBroadcast=NO prevents the database server from broadcasting to find other servers with the same name when starting up. This is useful in certain rare circumstances, but it is not generally recommended.

Example

  • The following command starts a client without broadcasting to search for a database server. Instead, the server is looked for only on the computer named silver.

    CommLinks=tcpip(DOBROADCAST=DIRECT;HOST=silver) asademo


ExtendedName protocol option [ENAME]

Usage

SPX (platforms other than Windows 95/98/Me or Windows NT/2000/XP)

Values

YES, NO

Default

NO

Description

According to the Novell standard for legal SAP names, the following characters are not allowed:

\ / : ; , * ? + -

If you start a server named asademo-1, the default behavior is to strip out the - and try to start a server asademo1. By turning on ExtendedName, the name is left untouched.

This is an SPX port parameter and is only useful when starting a server.

Caution Users should be wary of using this option as it is contrary to the SAP standard.
Example

  • The following command starts a NetWare server with the name asademo-1.

    load dbsrv9.nlm -x spx(ExtendedName=YES) asademo-1


Host protocol option [IP]

Usage

TCP/IP, SPX (all platforms) Server and client sides

Values

String

Default

No additional machines.

Description

HOST specifies additional machines outside the immediate network to be searched by the client library. On the server, the search is carried out to avoid starting a server with a duplicate name.

For TCP/IP, the HOST value the hostname or a dot-separated IP address may be used. You may optionally specify a PORT value as well.

For SPX, an address of the form a:b:c:d:e:f/g:h:i:j is used, where a:b:c:d:e:f is the node number (Ethernet card address) of the server, and g:h:i:j is the network number.

The server prints addressing information to the database server window during startup if the -z option is used. In addition, the application writes this information to its logfile if LogFile is specified.

You can use a comma-separated list of addresses to search for more than one machine. You can also append a port number to an IP address, using a colon as separator. Alternatively, you can specify the host and server ports explicitly, as in HOST=myhost;PORT=5000.

To specify multiple values for a single parameter, use a comma-separated list. When you specify multiple ports and servers, you can associate a particular port with a specific server by specifying the port in the HOST (IP) protocol option instead of the PORT parameter.

IP and HOST are synonyms when using TCP/IP. For SPX, you must use HOST.

See also
  • ClientPort protocol option [CPORT]
Examples

  • The following connection string fragment instructs the client to look on the machines kangaroo and 197.75.209.222 (port 2369) to find a database server:

    LINKS=tcpip(IP=kangaroo,197.75.209.222:2369)

  • The following connection string fragment instructs the client to look on the machines my_server and kangaroo to find a database server. A connection is attempted to the first host that responds.

    LINKS=tcpip(HOST=my_server,kangaroo;PORT=2639)

  • The following connection string fragment instructs the client to look for a server on host1 running on port 1234 and for a server on host2 running on port 4567. The client does not look on host1 on port 4567 or on host2 on port 1234.

    LINKS=tcpip(HOST=host1:1234,host2:4567)


LDAP protocol option [LDAP]

Usage

TCP/IP

Values

YES, NO, or filename

Default

ON

The default filename is asaldap.ini

Description

Having the database server register itself with an LDAP server allows clients (and the Locate utility [dblocate]) to query the LDAP server. This allows clients running over a WAN or through a firewall to find servers without specifying the IP address. It also allows the Locate utility [dblocate] to find such servers.

Specifying LDAP=filename turns LDAP support on and uses the specified file as the configuration file. Specifying LDAP=YES turns LDAP support on and uses asaldap.ini as the configuration file.

You can hide the contents of the asaldap.ini file with simple encryption using the File Hiding utility.

For more information, see Hiding the contents of .ini files.

LDAP is only used with TCP/IP.

See also
  • Connecting using an LDAP server


LocalOnly protocol option [LOCAL]

Usage

TCP/IP, HTTP, HTTPS

Values

YES, NO

Default

NO

Description

The LocalOnly (LOCAL) protocol option allows a client to choose to connect only to a server on the local machine, if one exists. If no server with the matching server name is found on the local machine, a server will not be autostarted.

The LocalOnly (LOCAL) protocol option is only useful if DoBroadcast=ALL (the default) is also specified.

LocalOnly=YES uses the regular broadcast mechanism, except that broadcast responses from servers on other machines are ignored.

You can use the LocalOnly (LOCAL) protocol option with the server to restrict connections to the local machine. Connection attempts from remote machines will not find this server, and the Locate [dblocate] utility will not see this server. Running a server with the LocalOnly (LOCAL) protocol option set to YES allows the network server to run as a personal server without experiencing connection or CPU limits.

See also
  • Broadcast protocol option [BCAST]


LogFile protocol option [LOG]

Usage

HTTP, HTTPS

Values

Filename

Default

None

Description

Specify the name of the file to which the database server is to write information about web requests.

See also
  • LogFormat protocol option [LF]
  • LogMaxSize protocol option [LSIZE]
  • LogOptions protocol option [LOPT]


LogFormat protocol option [LF]

Usage

HTTP, HTTPS

Values

Format-string

Default

@T - @W - @I - @P - "@M @U @V" - @R - @L - @E

Description

This parameter controls the format of messages written to the log file and which fields appear in them. If they appear in the string, the current values are substituted for the following codes as each message is written.

  • @@ The @ character.

  • @B Date and time that processing of the request started, unless the request could not be queued due to an error.

  • @C Date and time that the client connected.

  • @D Name of the database associated with the request.

  • @E Text of the error message, if an error occurred.

  • @F Date and time that processing of the request finished.

  • @I IP address of the client.

  • @L Length of the response, in bytes, including headers and body.

  • @M HTTP request method.

  • @P Listener port associated with the request.

  • @Q Date and time that the request was queued for processing, unless the request could not be queued due to an error.

  • @R Status code and description of the HTTP response.

  • @S HTTP status code.

  • @T Date and time that the current log entry was written.

  • @U Requested URI.

  • @V Requested HTTP version.

  • @W Time taken to process the request (@F – @B), or 0.000 if the request was not processed due to an error.

See also
  • LogFile protocol option [LOG]
  • LogMaxSize protocol option [LSIZE]
  • LogOptions protocol option [LOPT]


LogMaxSize protocol option [LSIZE]

Usage

HTTP, HTTPS

Values

Size

Default

0

Description

When the log file reaches the stated size, it is renamed and another log file is created. If LogMaxSize is zero, the log file size is unlimited.

See also
  • LogFile protocol option [LOG]
  • LogFormat protocol option [LF]
  • LogOptions protocol option [LOPT]


LogOptions protocol option [LOPT]

Usage

HTTP, HTTPS

Values

NONE, OK, INFO, ERRORS, ALL, status-codes, REQHDRS, RESHDRS, HEADERS

Default

ALL

Description

The values available include keywords that select particular types of messages, and HTTP status codes. Multiple values may be specified, separated by commas.

The following keywords control which categories of messages are logged:

  • NONE Log nothing.

  • OK Log requests that complete successfully (20x HTTP status codes).

  • INFO Log requests that return over or not modified status codes (30x HTTP status codes).

  • ERRORS Log all errors (40x and 50x HTTP status codes)

  • ALL Log all requests.

The following common HTTP status codes are also available. They can be used to log requests that return particular status codes:

  • C200 OK

  • C400 Bad request

  • C401 Unauthorized

  • C403 Forbidden

  • C404 Not found

  • C408 Request timeout

  • C501 Not implemented

  • C503 Service unavailable

In addition, the following keywords may be used to obtain more information about the logged messages:

  • REQHDRS When logging requests, also write request headers to the log file.

  • RESHDRS When logging requests, also write response headers to the log file.

  • HEADERS When logging requests, also write both request and response headers to the log file (same as REQHDRS,RESHDRS).

See also
  • LogFile protocol option [LOG]
  • LogFormat protocol option [LF]
  • LogMaxSize protocol option [LSIZE]


MaxConnections protocol option [MAXCONN]

Usage

HTTP, HTTPS

Values

Size

Default

5 (personal server) or number of licensed connections (network server)

Description

The number of simultaneous connections accepted by the server. The value 0 indicates no limit.

See also
  • MaxRequestSize protocol option [MAXSIZE]


MaxRequestSize protocol option [MAXSIZE]

Usage

HTTP, HTTPS

Values

Size in bytes

Default

100 kb

Description

The size of the largest request accepted by the server. If the size of a request exceeds this limit, the connection is closed and a 413 ENTITY TOO LARGE response is returned to the client. This value limits only the size of the request, not that of the response. The value 0 disables this limit, but should be used with extreme caution. Without this limit, a rogue client could overload the server or cause it to run out of memory.

See also
  • MaxConnections protocol option [MAXCONN]


MyIP protocol option [ME]

Usage

TCP/IP, HTTP, HTTPS

Values

String

Description

The MyIP (ME) protocol option is provided for machines with more than one network adapter.

Each adapter has an IP address. By default, the database server uses every network interface it finds. If you don't want your database server to listen on all network interfaces, specify the address of each interface you want to use in the MyIP (ME) protocol option.

If the keyword NONE is supplied as the IP number, no attempt is made to determine the addressing information. The NONE keyword is intended for clients on machines where this operation is expensive, such as machines with multiple network cards or remote access (RAS) software and a network card. It is not intended for use on the server.

Under Windows 95/98/Me or Windows NT/2000/XP, this option can be used multiple times for machines with multiple IP addresses.

Separate multiple IP addresses with commas.

Example

  • The following command line (entered all on one line) instructs the server to use two network cards.

    dbsrv9 -x tcpip(MyIP=192.75.209.12,192.75.209.32) "c:\Program Files\Sybase\SQL Anywhere 9\asademo.db"

  • The following connection string fragment instructs the client to make no attempt to determine addressing information.

    LINKS= tcpip(MyIP=NONE)


ReceiveBufferSize protocol option [RCVBUFSZ]

Usage

TCP/IP

Values

Integer in bytes

Default

Machine-dependent

Description

Sets the size for a buffer used by the TCP/IP protocol stack. You may want to increase the value if BLOB performance over the network is important.


RegisterBindery protocol option [REGBIN]

Usage

SPX

Server side only.

Values

YES, NO

Default

YES

Description

The database server attempts to register its name with any active binderies on the network when loading the SPX link. To disable this name registration, set RegisterBindery to NO. In this case, the client library must be able to locate the database server over SPX by broadcasting packets.


SearchBindery protocol option [BINSEARCH]

Usage

SPX

Values

YES, NO

Default

YES

Description

With SEARCHBINDERY=NO, no NetWare bindery is searched for a database server.


SendBufferSize protocol option [SNDBUFSZ]

Usage

TCP/IP

Values

Integer in bytes

Default

Machine-dependent

Description

Sets the size for a buffer used by the TCP/IP protocol stack. You may want to increase the value if BLOB performance over the network is important.


ServerPort protocol option [PORT]

Usage

TCP/IP, HTTP, HTTPS

Values

Integer

Default

The default value for TCP/IP is 2638. The default value for HTTP is 80. The default value for HTTPS is 443.

Description

The Internet Assigned Numbers Authority has assigned the Adaptive Server Anywhere database server port number 2638 to use for TCP/IP communications. However, other applications are not disallowed from using this reserved port, and this may result in an addressing collision between the database server and another application.

In the case of the database server, the ServerPort protocol option designates the port number on which to communicate using TCP/IP.

The database server always listens on UDP port 2638 on most operating systems, even if you specify a different port using a network protocol option. Hence, applications can connect to the database server without specifying a port number.

For a client, the ServerPort protocol option informs the client of the port or ports on which database servers are listening for TCP/IP communication. The client broadcasts to every port that is specified by the ServerPort (PORT) protocol option to find the server.

If you using a web server, by default, the database server listens on the standard HTTP and HTTPS ports of 80 and 443, respectively.

If you start a database server using TCP/IP port number 2638 (the default), then the server also listens to UDP port 2638. The database server listens to UDP ports and responds to requests on these ports so that clients can locate the database server by server name.

If the database server's TCP/IP port number is not 2638, then the server listens to the same UDP port as the TCP/IP port. On Mac OS X, HP-UX, and Tru64, the server does not listen to UDP port 2638, while servers on other platforms do additionally listen on UDP port 2638. On the Mac OS X, HP-UX, and Tru64 platforms, UDP port 2638 must remain available in case a second database server starts on TCP/IP port 2638.

Differences on Mac OS X, HP-UX, and Tru64
Mac OS X, HP-UX, and Tru64 do not allow multiple processes to bind to the same UDP port. When the database server is running on one of these platforms, it only listens to the specified UDP port or port 2638 if no port is specified.

This means that clients must specify the TCP/IP port number if the server is not using the default port (2638).

For example if the database server is started with the command dbsrv9 -n MyASAServer asademo.db, a client on the same subnet can find the server using the following connection parameters ENG=MyASAServer;LINKS=tcpip. If another server is started on Mac OS X, HP-UX, or Tru64 with the following command dbsrv9 -n SecondASAServer -x tcpip(PORT=7777) asademo.db, a client on the same subnet can find the server using the connection parameters ENG=SecondASAServer;LINKS=tcpip(PORT=7777). Note that if the database server was running on a platform other than Mac OS X, HP-UX, or Tru64, then the client would not need to specify the PORT parameter.

Additionally, on Mac OS X, HP-UX, and Tru64, if an Adaptive Server Anywhere database server is already using port 2638, and a second network database server was started without the PORT protocol option, the second network server would fail to start. The reason for this is users need to know and specify the server's port number in their connection parameters. Personal servers start successfully, even if port 2638 is in use, because shared memory is normally used to connect to personal servers.

Example

The following example shows how to use the PORT protocol option to specify the port the server starts on.

  1. Start a network database server:

    dbsrv9 -x tcpip -n server1

    Port number 2638 is now taken.

  2. Attempt to start another database server:

    dbsrv9 -x tcpip -n server2

    The default port is currently allocated, and so the server starts on another port. (On Mac OS X, HP-UX, and Tru64, this will fail).

  3. If another web server on your machine is already using port 80 or you do not have permission to start a server on this low of a port number, you may want to start a server that listens on an alternate port, such as 8080:

    dbsrv9 -xs http(port=8080) -n server3 web.db


TDS protocol option

Usage

TCP/IP, NamedPipes

Server side only

Values

YES, NO

Default

YES

Description

To disallow TDS connections to a database server, set TDS to NO. If you want to ensure that only encrypted connections are made to your server, these port options are the only way to disallow TDS connections.

Example

  • The following command starts a database server using the TCP/IP protocol, but disallowing connections from Open Client or jConnect applications.

    dbsrv9 -x tcpip(TDS=NO) ...


Timeout protocol option [TO]

Usage

TCP/IP, SPX, HTTP, HTTPS

Values

Integer, in seconds

Default

5 for TCP/IP, 30 for HTTP and HTTPS

Description

Timeout specifies the length of time, in seconds, to wait for a response when establishing communications. It also specifies the length of time to wait for a response when disconnecting. You may want to try longer times if you are having trouble establishing TCP/IP or SPX communications.

When using HTTP or HTTPS on the server, this parameter specifies the maximum idle time permitted when receiving a request. If this limit is reached, the connection is closed and a 408 REQUEST TIMEOUT is returned to the client. The value 0 disables idle timeout, but should be used with extreme caution. Without this limit, a rogue client could consume the server's resources and prevent other clients from connecting.

Example

  • The following data source fragment starts a TCP/IP communication link only, with a timeout period of twenty seconds.

    ...
CommLinks=tcpip(TO=20)
...


VerifyServerName protocol option [VERIFY]

Usage

TCP/IP

Client side only

Values

YES, NO

Default

YES

Description

When connecting over TCP using the DoBroadcast=NONE parameter, the client makes a TCP connection, then verifies that the name of the server found is the same as the one it's looking for. Specifying VerifyServerName=NO skips the verification of the server name. This allows Adaptive Server Anywhere clients to connect to an Adaptive Server Anywhere server if they know only an IP address/port.

The server name must still be specified in the connection string, but it is ignored. The VerifyServerName (VERIFY) protocol option is used only if DoBroadcast=NONE is specified.

Note
It is recommended that you only use this parameter in the rare circumstances when it is not possible to give each server a unique server name, and use that unique name to connect. Giving each server a unique server name, and connecting to the server using that name is still the best way to connect.
See also
  • DoBroadcast protocol option [DOBROAD]


Using Web Services

About this chapter

Adaptive Server Anywhere contains a built-in HTTP server that allows you to provide web services, and to access web services in other Adaptive Server Anywhere databases and standard web services available over the internet. SOAP is the standard used for this purpose, but the built-in HTTP server in Adaptive Server Anywhere also lets you handle standard HTTP and HTTPS requests from client applications. This chapter describes how to create and use both types of web services.

About web services
Quick start
Creating web services
Starting a database server that listens for web requests
How URLs are interpreted
Creating SOAP and DISH web services
Tutorial: Accessing web services from Java JAX-RPC
Creating web service client functions and procedures
Procedures that provide HTML documents
Automatic character set conversion
Errors


About web services

The term web service has been used to mean a variety of things. Commonly, it refers to software that facilitates inter-machine data transfer and interoperability. Essentially, web services make segments of business logic avalable over the internet. The Simple Object Access Protocol (SOAP) is the standard protocol used in this application and may be incorporated into any application capable of communicating with XML over HTTP.

The acronym SOAP refers to the flexible message exchange protocol accessible from applications such as those written in Java or Visual Studio .NET. SOAP messages define the services that a server provides. Actual data transfer generally takes places using HTTP to exchange XML documents structured so as to efficiently encode relevant information. Any application, such as a client or server, that participates in SOAP communication is called a SOAP node or SOAP endpoint. Such applications may transmit, receive, or process SOAP messages. You can create SOAP nodes with Adaptive Server Anywhere.

Web services and SQL Anywhere

In the context of SQL Anywhere, the term web services means that Adaptive Server Anywhere has the ability to listen for and handle standard SOAP requests. Web services in Adaptive Server Anywhere provide client applications an alternative to such traditional intefaces as JDBC and ODBC. They can be accessed from client applications written in a variety of languages and running on a variety of platforms. Even common scripting languages such as Perl and Python provide access to web services. You create web services in a database using the CREATE SERVICE statement.

Adaptive Server Anywhere can also function as a SOAP or HTTP client, permitting applications running within the database access to standard web services available over the internet, or provided by other Adaptive Server Anywhere databases. This client functionality is accessed through stored functions and procedures.

In addition, the term also refers to applications that use the built-in web server to handle HTTP requests from clients. These applications generally function like traditional database-backed web applications, but can be more compact and are easier to write as the data and the entire application can reside within a database. In this application, the web service typically returns documents in HTML format. GET, HEAD, and POST methods are supported.

The collection of web services within your database together define the available URLs. Each service provides a set of web pages. Typically, the content of these pages is generated by procedures that you write and store in your database, although they can be a single statement or, optionally, allow users to execute statements of their own. These web services become available when you start the database server with switches that enable it to listen for HTTP requests.

Since the HTTP server that handles web service requests is embedded in the database, performance is good. Applications that use web services are easily deployed, since no additional components are needed, beyond the database and database server.

For more information about the SOAP standards, see [external link] www.w3.org/TR/SOAP.


Quick start

The following procedure describes how to create a new database, start an Adaptive Server Anywhere database with the HTTP server enabled, and access this database using any popular web browser.

toggle To create and access a simple XML web service

  1. To create a new database to be used for this demonstration, execute the following statement at a command prompt.

    dbinit web.db

  2. Execute the following statement to start a personal web server. The -xs http(port=80) switch tells the database engine to listen for HTTP requests. If you already have a web server running on port 80, use another port number such as 8080 for this demonstration.

    dbeng9 -xs http(port=80) web.db

  3. Start Interactive SQL. Connect to the web database using the user name DBA and password SQL. Execute the following statement.

    CREATE SERVICE mytables
TYPE 'XML'
AUTHORIZATION OFF
USER DBA
AS SELECT * FROM SYSTABLE

    This statement creates a web service named mytables. This simple service returns the results of the statement SELECT * FROM SYSTABLE, automatically converting the output into XML format.

  4. Start a web browser. Browse to the URL http://localhost:80/web/mytables. Use the port number you specified when starting the database server.

    Your web browser will show you the body of the XML document returned by the database server. As no formatting information has been included, you see the raw XML, including tags and attributes.

  5. You can also access the mytables routine from common programming languages. For example, the following short C# program uses the mytable web service:

    static void Main(string[] args) {
  XmlTextReader reader = new XmlTextReader( "http://localhost/mytables" );

  while( reader.Read() ) {
    switch( reader.NodeType ) {
    case XmlNodeType.Element:
      if( reader.Name == 'row' ) {
        Console.writeline(reader.GetAttribute("table_id");
        Console.writeline(reader.GetAttribute("table_name");
      }
      break;
    }
  }

  6. In addition, you can access the same web service from Python, as in the following example code:

    import xml.sax

class DocHandler( xml.sax.ContentHandler ):
  def startElement( self, name, attrs ):
    if name == 'row':
      table_id = attrs.getValue( 'table_id' )
      table_name = attrs.getValue( 'table_name' )
      print '%s %s' % ( table_id, table_name )

parser = xml.sax.makd_parser()
parser.setContentHandler( DocHandler() )
parser.parse( 'http://localhost/mytables' )
toggle To set up a simple HTML web service

  1. Ensure that you have no web server already running on port 80, or choose a different port number to use for the rest of this procedure.

  2. Navigate to a convenient directory and create a new database named web.

    dbinit web.db

  3. Start a personal database server to run this new database. The -xs option tells the database server to start all communication protocols, including HTTP.

    dbeng9 web.db -xs http(port=80)

  4. Start Interactive SQL and connect to your new database using the user ID DBA and the password SQL.

  5. Using Interactive SQL, execute the following SQL statement, which adds an HTML service that exposes the SYS.SYSTABLE to HTTP users. Because authorization is off, no permissions are required to access the table from a web browser.

    CREATE SERVICE tables TYPE 'HTML'
AUTHORIZATION OFF USER DBA
AS SELECT * FROM SYS.SYSTABLE

  6. Start a web browser. Browse to the URL http://localhost:80/web/tables. Use the port number you specified when starting the database server.

Many properties of the service are controlled by parameters to the -xs command-line option.

For more information, see Network protocol options.

As well as starting the database server with the appropriate -xs option parameters, you must create web services to respond to incoming requests. These are defined using the CREATE SERVICE statement.

For more information, see Creating web services and CREATE SERVICE statement.

Examples

Samples are included in the Samples\ASA\HTTP subdirectory of your SQL Anywhere Studio installation.

Other examples are available on CodeXchange at [external link] http://ianywhere.codexchange.sybase.com/.


Creating web services

Services, created and stored in databases, define which URLs are valid and what they do. A single database can define multiple services. It is possible to define services in different databases so that they appear to be part of a single web site.

The following statements permit you to create, alter, and delete web services:

  • CREATE SERVICE

  • ALTER SERVICE

  • DROP SERVICE

  • COMMENT ON SERVICE

The general syntax of the CREATE SERVICE statement is as follows:

CREATE SERVICE service-name TYPE service-type-string [ attributes ] [ AS statement ]

Service names

As service names will form part of the URL used to access them, they are flexible in terms of what characters they can contain. In addition to the standard alpha-numeric characters, the following characters are permitted: "-", "_", ".", "!", "*", " ' ", "(", and ")".

In addition, service names may contain the slash, "/", but some restrictions apply because this character is a standard URL delimiter and affects how Adaptive Server Anywhere interprets your URLs. It cannot be the first character of a service name. In addition, service names cannot contain two consecutive slashes.

The same characters are permitted in group names, which apply to DISH services, as to service names.

Service types

The following service types are supported:

  • SOAP The result set is returned as a SOAP response. The format of the data is determined by the FORMAT clause. A request to a SOAP service must be a valid SOAP request, not just a simple HTTP request.

  • DISH A DISH service (Determine SOAP Handler) acts as a proxy for those SOAP services identified by the GROUP clause, and generates a WSDL (Web Services Description Language) file for each of these SOAP services.

  • XML The result set is returned as XML. If the result set is already XML, no additional formatting is applied. If it is not already XML, it is automatically formatted as XML. The effect is similar to that of using the FOR XML RAW clause in a SELECT statement.

  • HTML The result set of a statement or procedure are automatically formatted into an HTML document that contains a table.

  • RAW The result set is sent to the client without any further formatting. You can produce formatted documents by generating the required tags explicitly within your procedure.

Of all the service types, RAW gives you the most control over the output. However, it does require that you do more work as you must explicitly output all the necessary tags. The output of XML services can be adjusted by applying the FOR XML clause to the service's statement. The output of SOAP services can be adjusted using the FORMAT attribute of the CREATE or ALTER SERVICE statement.

For more information, see CREATE SERVICE statement.

Statements

The statement is the command, usually a stored procedure, that is called when someone accesses the service. If you define a statement, this is the only statement that can be run through this service. The statement is mandatory for SOAP services, and ignored for DISH services. The default is NULL, which means no statement.

You can create services that do not include statements. The statement is taken from the URL. Services configured in this way can be useful when you are testing a service, or want a general way of accessing information. To do so, either omit the statement entirely or use the phrase AS NULL in place of the statement.

Services without statements are a serious security risk as they permit web clients to execute arbitrary commands. When creating such services, you must enable authorization, which forces all clients to provide a valid username and password. Even so, only services that define statements should be run in a production system.

Attributes

The following attributes are available. In general, all are optional. However, some are interdependent.

  • AUTHORIZATION This attribute controls which users can use the service. The default setting is ON. Authorization must be ON if no statement is provided. In addition, the authorization setting affects how user names, defined by the USER attribute, are interpreted.

  • SECURE When set to ON, only secure connections are permitted. All connections received on the HTTP port are automatically redirected to the HTTPS port. The default is OFF, which enables both HTTP and HTTPS requests, provided these ports are enabled using the appropriate options when the database server is started.

  • USER The USER clause controls which database user accounts can be used to process service requests. However, the interpretation of this setting depends on whether authorization is ON or OFF.

    When authorization is set to ON, all clients must provide a valid user name and password when they connect. When authorization is ON, the USER option may be NULL, a database user name, or the name of a database group. If it is NULL, any database user can connect and make requests. Requests are run using the account and permissions of that user. If a group name is specified, only those users who belong to the group can run requests. All other database users are denied permission to use the service.

    If authorization is OFF, a statement must be provided. In addition, a user name must be provided. All requests are run using that user's account and permissions. Thus, if the server is connected to a public network, the permissions of the named user account should be minimal to limit the damage that could be caused through malicious use.

  • GROUP The GROUP clause, which applies to DISH services only, determines which SOAP services are exposed by the DISH service. Only SOAP services whose names begin with the name of the group name of a DISH service are exposed by that DISH service. Thus, the group name is a common prefix among the exposed SOAP services. For example, specifying GROUP xyz exposes only SOAP services xyz/aaaa, xyz/bbbb, or xyz/cccc, but does not expose abc/aaaa or xyzaaaa. If no group name is specified, the DISH service exposes all the SOAP services in the database. The same characters are permitted in group names as in service names.

    SOAP services may be exposed by more than one DISH service. In particular, this feature permits a single SOAP service to supply data in multiple formats. The service type, unless specified in a SOAP service, is inherited from the DISH service. Thus, you can create a SOAP service that declares no format type, then include it in multiple DISH services, each of which specifies a different format.

  • FORMAT The FORMAT clause, which applies to DISH and SOAP services only, controls the output format of the SOAP or DISH response. Output formats compatible with various types of SOAP clients, such as .NET or Java JAX-RPC, are available. If the format of a SOAP service is not specified, the format is inherited from the service's DISH service declaration. If the DISH service also does not declare a format, it defaults to DNET, which is compatible with .NET clients. A SOAP service that does not declare a format may be used with different types of SOAP clients by defining multiple DISH services, each having a different FORMAT type.

  • URL The URL clause controls the interpretation of URLs and applies to XML, HTML, and RAW service types only. In particular, it determines whether URL paths are accepted and, if so, how they are processed. If the service name ends with the character "/", the URL must be set to OFF.

    For more information, see CREATE SERVICE statement.


Starting a database server that listens for web requests

When you want a database server to listen for web service requests over HTTP or HTTPS, you must specify for which types of web requests it is to listen on the command line when you start the server. By default, database servers do not listen for web service requests, leaving no way for clients to access any services that may be defined in your database.

You can also specify various properties of an HTTP or HTTPS service on the command line, such as on which port they are to listen.

You must also create web services within the database. For more information, see Creating web services.

You use the -xs option to enable protocols. The two available web service protocols are http and https. Optional parameters, placed within parentheses after the protocol name, let you customize access to each type of web service.

The general syntax of the option is as follows:

-xs { protocol [ (option=value; ...) ], ... }

Protocols

The following web service protocol values are available:

  • http Listen for HTTP connections.

  • https Listen for HTTPS connections.

  • https_fips Listen for HTTPS FIPS connections.

  • none Do not listen for web service requests. This is the default setting.

Options

The following are some of the options that are available:

  • ServerPort [PORT] The port on which to listen for web requests. By default, Adaptive Server Anywhere listens on port 80 for HTTP requests and on port 443 for secure HTTP (HTTPS) requests.

    For example, if you already have a web server running on port 80, you could use the following options to start the a database server that listens for web requests on port 8080:

    dbeng9 web.db -xs http(port=8080)

    As another example, the following command starts the secure server with the sample certificate included with SQL Anywhere. It should be entered on a single line.

    dbsrv9 -xs https(certificate=rsaserver.crt;
                 certificate_password=test)
    Caution The sample certificate is intended for use only during testing and development. It provides no protection because it is a standard part of SQL Anywhere. Replace it with your own certificate before deploying your application.

  • DatabaseName [DBN] Specifies the name of a database to use when processing web requests, or uses the REQUIRED or AUTO keyword to specify whether database names are required as part of the URL.

    If this parameter is set to REQUIRED, the URL must specify the database name.

    If this parameter is set to AUTO, the URL may specify a database name, but does not need to do so. If the URL contains no database name, the default database on the server is used to process web requests.

    If this parameter is set to the name of a database, that database is used to process all web requests. The URL must not contain a database name.

  • LocalOnly [LOCAL] When set to YES, this parameter causes a network database server to reject all connections from clients running on different machines. This option has no effect on personal database servers, which never accept web service requests from other machines. The default value is NO, which means accept requests from clients no matter where they are located.

  • LogFile [LOG] The name of the file to which the database server is to write information about web requests.

  • LogFormat [LF] Controls the format of messages written to the log file and which fields appear in them. If they appear in the string, current values are substituted for the codes, such as @T, when each message is written.

    The default value is @T - @W - @I - @P - "@M @U @V" - @R - @L - @E, which produces messages such as the following:

    06/15 01:30:08.114 - 0.686 - 127.0.0.1 - 80
 - "GET /web/show_table HTTP/1.1" - 200 OK - 55133 -

    The format of the log file is compatible with Apache, so the same tools may be used to analyze it.

  • LogOptions [LOPT] Allows you to specify keyword and error numbers that control which messages, or types of messages, are written to the log file.

    For more information, see LogOptions protocol option [LOPT].

For a complete list of the available options and detailed information about them, see Network protocol options.


How URLs are interpreted

Universal Resrouce Locators, or URLs, identify documents, such as HTML pages, available from SOAP or HTTP web services. Those used in Adaptive Server Anywhere follow the patterns familiar to you from browsing the web. Users browsing through a database server need not be aware that their requests are not being handled by a traditional stand-alone web server.

Athough standard in format, Adaptive Server Anywhere database servers interpret URLs differently than standard web servers. The options you specify when you start the database server also affect their interpretation.

The general syntax of the URL is as follows:

{ http | https } :// [ user:password@ ] host [ :port ] [ /dbn ] /service-name [ parameters ] [ ?query ]

User and password

When a web service requires authentication, the user name and password may be passed directly as part of the URL by separating them with a colon and prepending them to the host name, much like an e-mail address.

Host and port

Like all standard HTTP requests, the start of the URL contains the host name or IP number and, optionally, a port number. The IP address or host name, and port, should be the one on which your server is listening. The IP address will be the address of a network card in the machine running Adaptive Server Anywhere. The port number will be the port number you specified using the -xs option when you started the database server. If you did not specify a port number, the default port number for that type of service is used. For example, the server listens by default on port 80 for HTTP requests.

For more information, see Network protocol options.

Database name

The next token, between the slashes, is usually the name of a database. This database must be running on the server and must contain web services.

The default database is used if no database name appears in the URL and the database name was not specified using the DBN connection parameter to the -xs option.

The database name can be omitted only if the database server is running only one database, or if the database name was specified using the DBN connection parameter to the -xs option.

Service name

The next portion of the URL is the service name. This service must exist in the specified database. The service name may extend beyond the next slash character because web service names can contain slash characters. Adaptive Server Anywhere matches the remainder of the URL with the defined services.

If the URL provides no service name, the database server looks for a service named root. If the named service, or the root service, is not defined, the server returns a 404 Not Found error.

Parameters

Depending on the type of the target service, parameters can be supplied in different ways. Parameters to HTML, XML, and RAW services can be passed in any of the following ways:

  • appended to the URL

  • supplied as an explicit parameters list

  • supplied as POST data in a POST request

Parameters to SOAP services must be included as part of a standard SOAP request. Values supplied in other ways are ignored.

To access parameter values, parameters must be given names. These host variable names, prefixed with a colon (:), may be included in the statement that forms part of the web service definition.

For example, a statement that calls the procedure place_order may require product identification number and quantity parameters:

call place_order( :product, :quantity )

Parameters may also be accessed using the HTTP_VARIABLE function. For more information, see HTTP_VARIABLE function [HTTP].

Query

The query is a list of name=value pairs separated by the & character. This list is introduced by a question mark. GET requests are formatted in this manner. If present, the named variables are defined and assigned the corresponding values.

If you have URL PATH set to ON or ELEMENTS, additional variables are defined. However, the two are otherwise independent. You can allow variables to be used in requested URLs by setting PATH to ON, or ELEMENTS, or both.

For more information about variables, see Working with variables.


Creating SOAP and DISH web services

SOAP and Web services are the means by which you create standard SOAP web services that can be accessed by standard SOAP clients, such as those written with Microsoft .NET or Java JAX-RPC.

SOAP services

SOAP services are the mechanism for constructing web services in SQL Anywhere that accept and process standard SOAP requests.

To declare a SOAP service, specify that the service is to be of type SOAP. The body of a standard SOAP request is SOAP envelope, meaning an XML document with a specific format. Adaptive Server Anywhere parses and processes these requests using the procedures you provide. The response is automatically formatted in the form of a standard SOAP response, which is also an SOAP envelope, and returned to the client.

The syntax of the statement used to create SOAP services is as follows:

CREATE SERVICE service-name
TYPE 'SOAP'
[ FORMAT { 'DNET' | 'CONCRETE' | 'XML' | NULL } ]
[ common-attributes ]
AS statement

DISH services

Dish services act as proxies for groups of SOAP services. In addition, they automatically construct WSDL documents that describe the SOAP services that they currently expose.

When you create a DISH service, the name given in the GROUP clause determines which SOAP services that DISH service exposes. Every SOAP service whose name is prefixed with the name of the DISH service is exposed. For example, specifying GROUP xyz exposes SOAP services xyz/aaaa, xyz/bbbb, or xyz/cccc. It does not expose SOAP services named abc/aaaa or xyzaaaa. SOAP services may be exposed by more than one DISH service. If no group name is specified, the DISH service exposes all the SOAP services in the database. The same characters are permitted in group names as in service names.

The syntax of the statment used to create DISH services is as follows:

CREATE SERVICE service-name
TYPE 'DISH'
[ GROUP { group-name | NULL } ]
[ FORMAT { 'DNET' | 'CONCRETE' | 'XML' | NULL } ]
[ common-attributes ]

SOAP and DISH service formats

The FORMAT clause of the CREATE SERVICE statement customizes the SOAP service data payload to best suit the various types of SOAP clients, such as .NET and Java JAX-RPC. The FORMAT clause affects the content of the WDSL document returned by a DISH service and the format of data payloads returned in SOAP responses.

The default format, DNET, is a native format for use with .NET SOAP client applications, which expect a .NET DataSet format.

The CONCRETE format is for use with clients such as Java JAX-RPC and .NET that automatically generate interfaces based on the format of the returned data structures. When you specify this format, the WSDL document returned by Adaptive Server Anywhere exposes an ASADataset element that describes a result set in concrete terms. This element is a containment hierarchy of a rowset composed of an array of rows, each containing an array of column elements.

The XML format is for use with SOAP clients that accept the SOAP response as one large string, and use an XML parser to locate and extract the required elements and values. This format is generally the most portable between different types of SOAP clients.

If the format of a SOAP service is not specified, the format is inherited from the service's DISH service declaration. If the DISH service also does not declare a format, it defaults to DNET, which is compatible with .NET clients. A SOAP service that does not declare a format may be used with different types of SOAP clients by defining multiple DISH services, each having a different FORMAT type.

Creating Homogeneous DISH services

SOAP services need not specify a format type—in other words, set the format type to NULL. When they do so, the format is inherited from the DISH service that act as proxies for them. More than one DISH service can act as a proxy for each SOAP service, and these DISH services need not be of the same type. These facts mean that it is possible to use a single SOAP service with different types of SOAP clients, such as .NET and Java JAX-RPC, by using multiple DISH services, each of a different type. Such DISH services are said to be homogeneous because they expose the same data payloads for the same SOAP services, but in different formats.

For example, consider the following two SOAP services, neither of which specifies a format:

CREATE SERVICE "abc/hello"
TYPE 'SOAP'
AS CALL hello(:student)
CREATE SERVICE "abc/goodbye"
TYPE 'SOAP'
AS CALL goodbye(:student)

Since neither of these services includes a FORMAT clause, the format, by default, is NULL. It is thus inherited from the DISH service that is acting as a proxy. Now, consider the following to DISH services:

CREATE SERVICE "abc_xml"
TYPE 'DISH'
GROUP "abc"
FORMAT 'XML'
CREATE SERVICE "abc_concrete"
TYPE 'DISH'
GROUP "abc"
FORMAT 'CONCRETE'

Since both DISH services specify the same group name, "abc", they act as proxies for the same SOAP services, namely all SOAP services whose names have the prefix "abc/".

However, when either of the two SOAP services is accessed through the abc_xml dish service, the SOAP service inherits the XML format type; when accessed throught he abc_concrete SOAP service, the CONCRETE format.

Homogeneous DISH services provide a means of avoiding duplicate services whenever you want to give types of SOAP clients access to the SOAP web services you create.


Tutorial: Accessing web services from Java JAX-RPC

The following tutorial demonstrates how to access web services from Java JAX-RPC. To access SQL Anywhere SOAP web services from JAX-RPC, the service should be declared to be of format CONCRETE.

toggle Create SOAP and DISH services.

  1. From a command prompt, run the following command to create a new database to be used for this tutorial.

    dbinit jaxrpc.db

  2. Start this new database. Use the -xs http flag so that the database server will listen for and handle HTTP requests. The -xs http(port=80) switch tells the database engine to accept HTTP requests. If you already have a web server running on port 80, use another port number such as 8080 for this tutorial.

    dbsrv9 -xs http(port=80) jaxrpc.db

  3. Start Interactive SQL. Connect to the web database using the user name DBA and password SQL. Execute the following statements:

    1. Create a simple hello procedure to be used by the SOAP service.

      CREATE PROCEDURE "hello_proc"(IN user_name char(64))
RESULT (result_out long varchar)
BEGIN
   SELECT 'hello' || ' ' || user_name || '\n';
END

    2. Define a SOAP service that calls the hello stored procedure.

      CREATE SERVICE "sample/hello"
TYPE 'SOAP'
AUTORIZATION OFF
SECURE OFF
USER DBA
AS CALL hello_proc(:user_name)

      As authorization has been turned off, anyone can use this service without supplying a user name and password. The commands will be run as user DBA. This arrangement is simple, but insecure.

    3. Create a DISH service to act as a proxy for the SOAP service and generate the WSDL.

      CREATE SERVICE "sample/dish_service"
TYPE 'DISH'
GROUP "sample"
FORMAT 'CONCRETE'
AUTHORIZATION OFF
SECURE OFF
USER DBA

      The SOAP and DISH service must be of type CONCRETE. In this example, the FORMAT clause was omitted when the SOAP service was created. As a result, the SOAP service inherits the concrete format from the DISH service.

  4. Take a look at the WSDL that the dish service automatically creates. To do so, open a web browser and browse to the following URL: [external link] http://localhost:80/jaxrpc/sample/dish_service. The DISH service automatically generates the following WSDL document.

    In particular, observe the ASADataset object that is exposed because the format of this service is CONCRETE. In a later step, the wscompile.bat application will use this information to generate a SOAP 1.1 client interface for this these services.

    <?xml version="1.0" ?>
<definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" name="sample/dish_service" targetNamespace="http://localhost/jax/sample/dish_service" xmlns:s3="http://localhost/jax/sample/dish_service" xmlns="http://schemas.xmlsoap.org/wsdl/">
 <types>
  <s:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://localhost/jax/sample/dish_service">
   <s:import namespace="http://www.w3.org/2001/XMLSchema" />
   <s:complexType name="ASADataset">
    <s:sequence>
     <s:element name="rowset">
      <s:complexType>
       <s:sequence>
    <s:element name="row" minOccurs="0" maxOccurs="unbounded">
         <s:complexType>
          <s:sequence>
           <s:any minOccurs="0" maxOccurs="unbounded"/>
          </s:sequence>
         </s:complexType>
        </s:element>
       </s:sequence>
      </s:complexType>
    </s:element>
    </s:sequence>
   </s:complexType>
   <s:element name="error" type="s:string" />
   <s:element name="hello">
    <s:complexType>
     <s:sequence>
      <s:element minOccurs="0" maxOccurs="1" name="user_name" nillable="true" type="s:string" />
     </s:sequence>
    </s:complexType>
   </s:element>
   <s:element name="helloResponse">
    <s:complexType>
     <s:sequence>
      <s:element minOccurs="1" maxOccurs="1" name="helloResult" type="s3:ASADataset" />
      <s:element name="sqlcode" type="s:int" />
     </s:sequence>
    </s:complexType>
    </s:element>
  </s:schema>
 </types>
 <message name="helloIn">
  <part name="parameters" element="s3:hello" />
 </message>
 <message name="helloOut">
  <part name="parameters" element="s3:helloResponse" />
 </message>
    <message name="ASAFaultMessage">
    <part name="error" element="s3:error" />
   </message>
 <portType name="sample/dish_serviceSoapPort" >
  <operation name="hello">
   <input message="s3:helloIn" />
   <output message="s3:helloOut" />
   <fault message="s3:ASAFaultMessage" name="error" />
  </operation>
    </portType>
 <binding name="sample/dish_serviceSoapBinding" type="s3:sample/dish_serviceSoapPort">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
  <operation name="hello">
   <soap:operation soapAction="http://localhost/jax/sample/hello" style="document" />
   <input>
    <soap:body use="literal" />
   </input>
   <output>
    <soap:body use="literal" />
   </output>
   <fault name="error">
    <soap:fault name="error" use="literal" />
   </fault>
  </operation>
 </binding>
<service name="sample/dish_service">
 <port name="sample/dish_serviceSoap"  binding="s3:sample/dish_serviceSoapBinding">
    <soap:address location="http://localhost/jax/sample/dish_service" />
  </port>
 </service>
</definitions>

In the next section of this tutorial, you access these services from Java. To do so, you need to use the wscompile tool available from Sun.

To download the Java JAX-RPC tools, including wscompile, see [external link] http://java.sun.com/xml/downloads/jaxrpc.html.

toggle To generate and use a JAX-RPC interface for these web services

  1. The first step is to create a simple XML document that tells wscompile what to do. Samples of this configuration document are available from Sun. You need only replace the location attribute of the wsdl element with the URL of your dish service. Optionally, you may also specify a package name. The package name causes the generated .java and .class files to be placed in subdirectory of the same name.

    Using a text editor, create an XML document named config.xml with the following content:

    <?xml version="1.0" encoding="UTF-8"?>
<configuration
    xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
    <wsdl
        location="http://localhost:80/jaxrpc/sample/dish_service"
        packageName="asa" />
</configuration>

    In this case, the location specified is the URL of the dish service. In addition, the optional packageName attribute has been added so that all the generated files will be placed in a new subdirectory named asa.

  2. At a command prompt, enter the following command.

    wscompile -gen -keep config.xml

    The -gen flag tells wscompile to retrieve the WSDL document from the given URL and generate and compile an interface for it. The -keep flag tells wscompile not to delete the .java files. Without this flag, these files are deleted after the corresponding .class files have been generated. Saving these files makes it easer to examine the makeup of the interface.

    If the wscompile command is not found, make sure that you have wscompile on your machine and that it is in your path.

    Once this command completes, you should discover a new subdirectory named asa that contains the following Java files, along with the compiled .class versions of each.

    • ASADataset.java
    • ASADataset_LiteralSerializer.java
    • ASAFaultMessage.java
    • Dish_service.java
    • Dish_serviceSoapPort.java
    • Dish_serviceSoapPort_Stub.java
    • Dish_serviceSoapPort_hello_Fault_SOAPBuilder.java
    • Dish_serviceSoapPort_hello_Fault_SOAPSerializer.java
    • Dish_service_Impl.java
    • Dish_service_SerializerRegistry.java
    • Hello.java
    • HelloResponse.java
    • HelloResponse_LiteralSerializer.java
    • Hello_LiteralSerializer.java
    • Row.java
    • Row_LiteralSerializer.java
    • Rowset.java
    • Rowset_LiteralSerializer.java

  3. Save the following Java source code into a text file, and compile.

    // HelloTest.java illustrates a web service client
// that calls the dish_service and prints out the data:
    import java.util.*;
import asa.*;
    public class HelloTest
{
    public static void main( String[] args )
    {
        try {
            Dish_service_Impl service = new Dish_service_Impl();
            Dish_serviceSoapPort port = service.getDish_serviceSoap();
      // this is the soap service call to hello...
            HelloResponse response = port.hello("New User");
            ASADataset result = response.getHelloResult();
            Rowset rowset = result.getRowset();
            Row[] row = rowset.getRow();
    for ( int i = 0; i < row.length; i++ ) {
          // column data is contained as a SOAPElement...
                javax.xml.soap.SOAPElement[] col = row[i].get_any();
                for ( int j = 0; j < col.length; j++ ) {
                    System.out.print("<" + col[j].getLocalName() + ">" +
                        col[j].getValue() );
                }
                System.out.println();
            }
    }
        catch (Exception x) {
            x.printStackTrace();
        }
    }
}

  4. Run the above application. The following output should be generated.

    <result_out>hello New User


Creating web service client functions and procedures

As well as providing web services, an Adaptive Server Anywhere database can consume web services. These can be standard web services available over the internet, or can be provided by Adaptive Server Anywhere databases, as long as the web service is not in the same database as the client procedure or function.

Adaptive Server Anywhere can act as both HTTP and SOAP web service clients. This functionality is provided through stored functions and stored procedures.

Client functions and procedures are created and manipulated using the following SQL statements

  • CREATE FUNCTION statement
  • CREATE PROCEDURE statement
  • ALTER FUNCTION statement
  • ALTER PROCEDURE statement
  • DROP statement

For example, the syntax of the CREATE FUNCTION and CREATE PROCEDURE statements, as used to create web service client functions, are as follows:

CREATE PROCEDURE [ owner.]procedure-name ( [ parameter, ... ] )
URL url-string
[ proc-attributes ]

CREATE FUNCTION [ owner.]procedure-name ( [ parameter, ... ] )
RETURNS data-type
URL url-string
[ proc-attributes ]

Key to this syntax is the URL clause, which is used to provide the URL of the web service that you want the procedure to access. The basic syntax of the URL clause is as follows:

url-string :
'{HTTP|HTTPS}://[user:password@]hostname[:port][/path]'

The optional user and password information permits you to access web services that require authentication. The hostname may be the name or the IP address of the machine providing the web service.

The port number is required only if the server is listening on a port number other than the default. The default port numbers are 80 for HTTP services and 443 for HTTPS services.

The path identifies the resource or web service on the server.

A request can be sent to any web service, whether it is provided by another Adaptive Server Anywhere database or available over the internet. The web service may be provided by the same database server, but must not reside in the same database as the client function. Attempting to access a web service in the same database results in the error 403 Forbidden.

Because it is used for parameter substitution, exclamation marks that appear in strings anywhere in the procedure definition must be escaped. For more information, see Escaping the ! character.

Common clauses

The additional clauses that let you supply more detailed information about the procedure call are as follows:

proc-attributes :
[ TYPE { 'HTTP[:{GET|POST}]' | 'SOAP[:{RPC|DOC}]' } ]
[ NAMESPACE namespace-string ]
[ CERTIFICATE certificate-string ]
[ CLIENTPORT clientport-string ]
[ PROXY proxy-string ]

The TYPE clause is important because it tells Adaptive Server Anywhere how to format the request to the web service provider. Standard SOAP types RPC and DOC are available. The standard HTTP methods of GET and POST are available, specified as HTTP:GET and HTTP:POST, respectively. Specifying HTTP implies HTTP:POST.

If type SOAP is chosen, the Adaptive Server Anywhere automatically formats the request as an XML document in the standard format necessary for SOAP requests. Since an SOAP request is always an XML document, this an HTTP POST request is always implicitly used to send the SOAP request document to the server whenever type SOAP is chosen. Type SOAP implies SOAP:RPC.

Names for web service client functions and procedures

The procedure name is used as the SOAP operation name when building the outgoing SOAP request. In addition, the names of any parameters also appear in in tagnames in the SOAP request envelope. Therefore specifying these names correctly, as the SOAP server expects to see it, is an important part of defining a SOAP stored procedure. This fact places restrictions on the name of SOAP procedures and functions, beyond the general rules that apply to procedure and function names in SQL Anywhere.

The following procedure definition demonstrates what happens.

CREATE PROCEDURE MyOperation (a INTEGER, b CHAR(128) )
URL 'HTTP://localhost'
TYPE 'SOAP:DOC'

When this procedure is called, such as by the following statement, a SOAP request in generated:

CALL MyOperation( 123, 'abc' )

The procedure name, which in this example is MyOperation, is appears in the <m:MyOperation> tag name within the request body. Furthermore, the two parameters to the procedure, a and b, become <m:a> and <m:b>, respectively.

<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:m="http://localhost">
  <SOAP-ENV:Body>
    <m:MyOperation>
      <m:a>123</m:a>
      <m:b>abc</m:b>
    </m:MyOperation>
  </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>
Namespace URIs

All SOAP requests require a method namespace URI. The SOAP processor on the server side uses this URI to understand the names of the various entities in the message body of the request.

When creating a SOAP function or procedure, of either SOAP:DOC or SOAP:RPC, you will likely be required to specify a namespace URI before the call will succeed. You can obtain the required namespace value from the WSDL description document, or from other available documentation for the service. The NAMESPACE clause applies only to SOAP functions and procedures. The default namespace value is the procedure's URI, up to but not including the optional path component and excluding any user and password values.

HTTPS requests

In order to issue a secure HTTPS request, the client must have access to the server's certificate, or the certificate used to sign the server's certificate. This certificate tells Adaptive Server Anywhere how to encrypt the request. Certificate values are also be required when a request directed to a insecure server may be redirected to a secure one.

There are two ways to provide the certificate information. You may either place the certificate in a file and provide the filename, or you may provide the entire certificate as a string value. You may not do both.

The certificate attributes are supplied as a string value constructed as key=value pairs separated by semicolons:

certificate-string :
{ file=filename | certificate=string } ; company=company ; unit=company-unit ; name= common-name

The following keys are available:

Key | Abbreviation | Description
file |  | The filename of the certificate.
certificate | cert | The certificate itself, Base64 encoded.
company | co | The company specified in the certificate.
unit |  | The company unit specified in the certificate.
name |  | The common name specified in the certificate.

For example, the following statement creates a procedure that makes a secure request to a web service located on the same machine as the client:

CREATE PROCEDURE test ()
URL 'HTTPS://localhost/myservice'
CERTIFICATE 'file=C:\srv_cert.crt;co=iAnywhere;
             unit=ASA;name=JohnSmith'

Since no TYPE clause was provided, the request is assumed to be of type SOAP:RPC. The server's public certificate is located in the file C:\srv_cert.crt.

Client ports

When accessing web services through a firewall, it is sometimes necessary to tell Adaptive Server Anywhere which ports to use when opening a connection to the server. Ordinarily, port numbers are obtained dynamically, and you should rely on the default behavior unless your firewall restricts access to a particular range of ports.

The ClientPort option designates the port number on which the client application communicates using TCP/IP. You may specify a single port number, or a combination of individual port numbers, and ranges of port numbers, as demonstrated in the following example:

CREATE PROCEDURE test ()
URL 'HTTPS://localhost/myservice'
CLIENTPORT '5040,5050-5060,5070'

It is best to specify a list or a range of port numbers. If you specify a single port number, then only one connection will be maintained at a time. In fact, even after closing the one connection, there is a several minute timeout period during which no new connection can be made to the same remote server and port. When you specify a list and/or range of port numbers, the application keeps trying port numbers until it finds one to which it can successfully bind.

This feature is similar to the ClientPort Network Protocol option. For more information, see ClientPort protocol option [CPORT].

Using proxies

Some web service requests may need to be made through a proxy server. When this is the case, the URL of the proxy server must be supplied using the PROXY clause.

The format of the value is the same as for URL clause, although any user, password or path values are ignored:

url-string :
'{HTTP|HTTPS}://[user:password@]hostname[:port][/path]'

When a proxy is specified, Adaptive Server Anywhere formats the request and sends it to the proxy server using the supplied proxy URL. The proxy server forwards the request to the final destination, obtains the response, and forwards the response back to Adaptive Server Anywhere.


Return values and result sets

Web service client calls may be made with either stored functions, or stored procedures. If made from a function, the return type of the function must be of a character data type, such as CHAR, VARCHAR, or LONG VARCHAR. The value returned is the body of the HTTP response. No header information is included. Additional information about the request, including the HTTP status information, is returned by procedures. Thus, procedures are prefered when access to this additional information is desirable.

SOAP procedures

The response from a SOAP function is an XML document that contains the SOAP response.

Since SOAP responses are structured XML documents, Adaptive Server Anywhere by default attempts to exploit this information and construct a more useful result set. Each of the top-level tags within the returned response document is extracted and used as a column name. The contents of the subtree below each of these tags is used as the row value for that column.

For example, given the SOAP response shown below, Adaptive Server Anywhere would construct the shown data set:

<SOAP-ENV:Envelope
  xmlns:SOAPSDK1="http://www.w3.org/2001/XMLSchema"
  xmlns:SOAPSDK2="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:SOAPSDK3="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Body>
     <ElizaResponse xmlns:SOAPSDK4="SoapInterop">
        <Eliza>Hi, I'm Eliza. Nice to meet you.</Eliza>
     <ElizaResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Eliza
Hi, I'm Eliza. Nice to meet you.

In this example, the response document is delimited by the ElizaResponse tags that appear within the SOAP-ENV:Body tags.

Result sets have as many columns as there are top-level tags. This result set has only one column because there is only one top-level tag in the SOAP response. This single top-level tag, Eliza, becomes the name of the column.

XML processing facilities

Information within XML result sets, including SOAP responses, can also be accessed using the built-in Open XML processing capabilities.

The following example uses the OPENXML function to extract portions of a SOAP response. This example uses a web service to expose the contents of the SYSWEBSERVICE table as a SOAP service:

CREATE SERVICE get_webservices
TYPE 'SOAP'
AUTHORIZATION OFF
USER DBA
AS SELECT * FROM SYSWEBSERVICE

The following stored function, which must be created in a second Adaptive Server Anywhere database, issues a call to this webservice. The return value of this function is the entire SOAP response document. The response is in the .NET DataSet format, as DNET is the default SOAP service format.

CREATE FUNCTION get_webservices ()
RETURNS LONG VARCHAR
URL 'HTTP://localhost/get_webservices'
TYPE 'SOAP:DOC'

The following statement demonstrates how two columns of the result set can be extracted with the aid of the OPENXML function. These are the service_name and secure_required columns, which indicate which SOAP services are secure and hence require HTTPS.

SELECT *
FROM OPENXML( get_webservice(), '//row' )
WITH ("Name"    char(128) 'service_name',
      "Secure?" char(1)   'secure_required' )

This statement works by selecting the decendants of the row node. The WITH clause constructs the result set based on the two elements of interest. Assuming only the get_webservices service exists, this function returns the following result set:

Name | Secure?
get_webservices | N

For more information about the XML processing facilities available in Adaptive Server Anywhere, see Using XML in the Database.

Other types of procedures

Procedures of other types return all the information about a response in a two-column result set. This result set includes the response status, header information and body. The first column, is named Attribute and the second Value. Both are of data type LONG VARCHAR.

The result set has one row for each of the response header fields, as well as a row for the HTTP status line (Status attribute) and a row for the response body (Body attribute).

The following example represents a typical response:

Attribute | Value
Status | HTTP /1.0 200 OK
Body | <!DOCTYPE HTML ... ><HTML> ... </HTML>
Content-Type | text/html
Server | GWS/2.1
Content-Length | 2234
Date | Mon, 18 Oct 2004, 16:00:00 GMT


Selecting from result sets

The SELECT statement is used to retrieve values from results sets. Once retrieved, these values may be stored in tables or used to set variables.

CREATE PROCEDURE test( INOUT parm CHAR(128) )
URL 'HTTP://localhost/test'
TYPE 'HTTP'

As it is of type HTTP, this procedure returns the two-column result set described in the previous section. In the first column is an attribute name; in the second column the attribute value. The keywords are as in the HTTP response header fields. A Body attribute contains the body of the message, which is typically an HTML document.

One approach is to insert the result sets into a table, such as the following one:

CREATE TABLE StoredResults(
     Attribute LONG VARCHAR,
     Value       LONG VARCHAR
)

Result sets can be inserted into this table as follows:

INSERT INTO StoredResults SELECT *
FROM test('Storing into a table')
WITH (Attribute LONG VARCHAR, Value LONG VARCHAR)

You can add clauses according to the usual syntax of the SELECT statement. For example, if you want only a specific row of the result set you can add a WHERE clause to limit the results of the select to only one row:

SELECT Value
FROM test('Calling test for the status code')
WITH (Attribute LONG VARCHAR, Value LONG VARCHAR)
WHERE Attribute = 'Status'

This statement selects only the status information from the result set. It can thus be used to verify that the call was successful.


Parameters

Stored functions and stored procedures that act as web service clients may be declared with parameters, just as may other types of function or procedures. These parameters values, unless used during parameter substitution, are passed as part of the HTTP or SOAP request.

In addition, parameters can be used to replace placeholders within the body of the stored function or stored procedure at the time the function or procedure is called. If no placeholders for a particular variable exist, the parameter and its value are passed as part of the request. Parameters and values used for substitution in this manner are not passed as part of the web service request.


Passed parameters

All parameters to a function or procedure, unless used during parameter substitution, are passed as part of the web service request. The format in which they are passed depends on the type of the web service request.

HTTP requests

Parameters to requests of type HTTP:GET are encoded in the URL. For example, the following procedure declares two parameters:

CREATE PROCEDURE test ( a INTEGER, b CHAR(128) )
URL 'HTTP://localhost/myservice'
TYPE 'HTTP:GET'

If this procedure is invoked with the two values 123 and "xyz", then URL used for the request is equivalent to that shown below:

HTTP://localhost/myservice?a=123&b=xyz

If the type is HTTP:POST, the parameters and their values instead become part of the body of the request. In the case of the two parameter and values, the following text appears, after the headers, in the body of the HTTP request:

a=123&b=xyz
SOAP requests

Parameters passed to SOAP requests are bundled as part of the request body, as required by the SOAP specifications:

<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:m="http://localhost">
  <SOAP-ENV:Body>
    <m:test>
      <m:a>123</m:a>
      <m:b>abc</m:b>
    </m:test>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>


Parameter substitution

Declared parameters to the stored procedure or stored function are automatically substituted for placeholders within the stored function or stored procedure definition each time the procedure or function is executed. Any substrings that contain an exclamation mark ("!") followed by the name of one of the declared parameters are replaced by that parameter's value.

For example, the following procedure definition permits the entire URL to be passed as a parameter. Different values may be used each time this procedure is called.

CREATE PROCEDURE test ( url CHAR(128) )
URL '!url'
TYPE 'HTTP:POST'

For example, you could then use the procedure as follows:

CALL test ( 'HTTP://localhost/myservice' )
Hiding user and password values

One useful application of parameter substitution is to avoid making sensitive values, such as user names and passwords, part of a web service client function or procedure definition. When such values are specified as literals in the procedure or function definition, they are stored in the system tables, making them readily accessible to all users of the database. Passing these values as parameters circumvents this problem.

For example, the following procedure definition includes the user name and password as plain text as part of the procedure definition:

CREATE PROCEDURE test
URL 'HTTP://DBA:SQL@localhost/myservice'

This string appears as plain text in the system tables, permitting easy access to the authentication values. To avoid this problem, you can declare user and password as parameters. Doing so permits the user and password values to be supplied only when the procedure is invoked.

CREATE PROCEDURE test ( uid CHAR(128), pwd CHAR(128) )
URL 'HTTP://!uid:!pwd@localhost/myservice'

This procedure is called as follows:

CALL test ( 'DBA', 'SQL' )

As another example, you can use parameter substitution to pass encryption certificates from a file and pass them to a stored procedure or stored function:

CREATE PROCEDURE secure( cert LONG VARCHAR )
URL 'https://localhost/secure'
TYPE 'HTTP:GET'
CERTIFICATE 'cert=!cert;company=test;unit=test;name=RSA Server'

When you call this procedure, you supply the certificate as a string. In the following example call, the certificate is read from a file. This is done for illustration only, as the certificate can be read directly from a file using the file= keyword for the CERTIFICATE clause.

CALL secure( xp_read_file('C:\asainstalldir\win32\rsaserver.crt') )
Escaping the ! character

As the exclamation mark "!" is used to identify placeholders for parameter subsitution in the context of web service client stored functions and stored procedures, it must be escaped whenever you want to include this character as part of any of the procedure attribute strings string. To do so, prefix the the exclamation mark with a second exclamation mark. Hence, all occurances of "!!" in strings within a web service client or web service function definition are replaced by "!".

Parameter names used as placeholders must contain only alphanumeric characters. In addition, placeholders must be followed by a non-alphanumeric character to avoid ambiguity. Placeholders with no matching parameter name are automatically deleted. For example, the parameter size would not be substituted for the placeholder in the following procedure:

CREATE PROCEDURE orderitem ( size CHAR(18) )
URL 'HTTP://salesserver/order?size=!sizeXL'
TYPE 'SOAP:RPC'

Instead, !sizeXL is always deleted because it is a valid placeholder for which there is no matching parameter.


Parameter data type conversion

Parameter values that are not of character or binary data types are converted to a string representation before being added to the request. This process is equivalent to casting the value to a character type. The conversion is done in accordance with the data type formatting option settings at the time the function or procedure is invoked. In particular, the conversion may be affected by such options as PRECISION, SCALE, and TIMESTAMP_FORMAT.


Procedures that provide HTML documents

[ ]

Generally, it is easiest to write a procedure that handles the requests sent to a particular service. Such a procedure should return a web page. Optionally the procedure can accept arguments, passed as part of the URL, to customize its output.

The following example, however, is much simpler. It demonstrates how simple a service can be. This web service simply returns the phrase "Hello world!".

CREATE SERVICE hello TYPE 'RAW'
      AUTHORIZATION OFF USER DBA
      AS select 'Hello world!'

Start a server with the -xs option to enable handling of web requests, then request the URL http://localhost/hello from any web browser. The words Hello world! will appear in an otherwise plain page.

HTML pages

The above page appears in your browser in plain text. This happens because the default HTTP Content-Type is text/plain. To create a more normal web page, formatted in HTML, you must do two things:

  • Set the HTTP Content-Type header field to text/html so that the browsers will expect HTML.

  • Include HTML tags in the output.

You can write tags to the output in two ways. One way is to use the phrase TYPE HTML in the CREATE SERVICE statement. Doing so asks Adaptive Server Anywhere to add HTML tags for you. This can work quite well if, for example, you are returning a table.

The other way is to use TYPE RAW and write out all the necessary tags yourself. This second method provides the most control over the output. Note that specifying type RAW does not necessarily mean the output is not in HTML or XML format. It only tells Adaptive Server Anywhere that it can pass the return value directly to the client without adding tags itself.

The following procedure generates a fancier version of Hello world. For convenience, the body of the work is done in the following procedure, which formats the web page.

The built-in procedure sa_set_http_header is used to set the HTTP header type so browsers will correctly interpret the result. If you omit this statement, your browser will display all the HTML codes, rather than use them to format the document.

CREATE PROCEDURE hello_pretty_world ()
RESULT (html_doc long varchar)
BEGIN
  call dbo.sa_set_http_header( 'Content-Type', 'text/html' );
  select '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">\n'
    || '<html>\n'
    || '<head>\n'
    || '  <title>Hello Pretty World</title>\n'
    || '</head>\n'
    || '<body>\n'
    || '  <h1>Hello Pretty World!</h1>\n'
    || '  <p>(If you see the tags in your browser, check that\n'
    || '      the Content-Type header is set to text/html.)\n'
    || '</body>\n'
    || '</html>';
END

The following statement creates a service that uses this procedure. The statement calls the above procedure, which generates the Hello Pretty World web page.

CREATE SERVICE hello_pretty_world TYPE 'RAW'
      AUTHORIZATION OFF USER DBA
      AS call hello_pretty_world()

Once you have created the procedure and the service, you are ready to access the web page. Ensure that your database server was started with the correct -xs option values, then open the URL http://localhost/hello_pretty_world in a web browser.

You see the results formatted in a simple HTML page, with the title Hello Pretty World. You can make the web page as fancy as you wish by including more content, using more tags, using style sheets, or including scripts that run in the browser. In all cases, you create the necessary services to handle the browser's requests.

For more information about built-in stored procedures, see System and catalog stored procedures.

Root services

When no service name is included in a URL, Adaptive Server Anywhere looks for a web service named root. The role of root pages is analogous to the role of index.html pages in many traditional web servers.

Root services are handy for creating home pages because they can handle URL requests that contain only the address of your web site. For example, the following procedure and service implement a simple web page to be displayed when you browse to the URL http://localhost.

CREATE PROCEDURE home_page
RESULT (html_doc long varchar)
BEGIN
  call dbo.sa_set_http_header( 'Content-Type', 'text/html' );
  select '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">\n'
      || '<html>\n'
      || '<head>\n'
      || '  <title>My Home Page</title>\n'
      || '</head>\n'
      || '<body>\n'
      || '  <h1>My home on the web<h1>\n'
      || '  <p>Thank you for visiting my web site!\n'
      || '</body>\n'
      || '</html>';
END

Now create a service that uses this procedure:

CREATE SERVICE root TYPE 'RAW'
AUTHORIZATION OFF USER DBA
AS call home_page()

You can access this web page by browsing to the URL http://localhost, as long as you do not specify that database names are mandatory when you start the database server.

Examples

For example, the request in the Quick Start example includes no database name and no parameters. In this request, /tables identifies the service.

http://localhost:80/tables

More extensive examples are included in the Samples/ASA/HTTP subdirectory of your SQL Anywhere Studio installation.

Working with variables


Working with variables

Variables in HTTP requests come from one of two sources. First, the URL may include a query, which includes various name-value pairs. HTTP GET requests are formatted in this manner.

The second way is through the URL path. Setting the URL PATH to either ON or ELEMENTS causes the portion of the path following the service name to be interpreted as variable values. This option allows URLs to appear to be requesting a file in a particular directory, as would be the case on a traditional file-based web site, rather than something stored inside a database.

For example, the URL http://localhost/gallery/sunset.jpg appears to request the file sunset.jpg from a directory named gallery, but instead asks the gallery service to retrieve a picture from a database table.

The parameter passed in HTTP requests depends on the setting of URL PATH.

  • OFF No path parameters are permitted after the service name.

  • ON All path elements after the service name are assigned to the variable URL.

  • ELEMENTS The remainder of the URL path is split at the slash characters into a list of up to 10 elements. These values are assigned the variables URL1, URL2, URL3, ..., URL10. If there are fewer than 10 values, the remaining variables are set to NULL. Specifying more than ten variables causes an error.

Apart from the location in which they are defined, there is no difference between variables. You access and use all HTTP variables the same way. For example, the values of variables such as url1 are accessed in the same way as parameters that appear as part of a query, such as ?picture=sunset.jpg.

Accessing parameters

There are two main ways to access variables. The first is to mention variables in the statement of the service declaration. For example, the following statement passes the value of multiple variables to the show_table stored procedure:

CREATE SERVICE show_table TYPE 'RAW'
AUTHORIZATION ON
AS CALL show_table( :user_name, :table_name, :limit, :start )

The other way is to use the built-in functions next_http_variable and http_variable within the stored procedure that handles the request. If you do not know which variables are defined, you can use the next_http_variable to find out. The http_variable function returns the variable values.

The next_http_variable function allows you to iterate through the names of the defined variables. The first time you call it, you pass in the NULL value. This returns the name of one variable. Calling it subsequent times, each time passing in the name of the previous variable, returns the next variable name. When the name of the last variable is passed to this function, it returns NULL.

Iterating through the variable names in this manner guarantees that each variable name will be returned exactly once. However, the order that the values are returned may not be the same as the order that they appear in the request. In addition, if you iterate through the names a second time, they may be returned in a different order.

To get the value of each variable, use the http_variable function. The first parameter is the name of the variable. Additional parameters are optional. In the case that multiple values were supplied for a variable, the function returns the first value if supplied with only one parameter. Supplying an integer as the second parameter allows you to retrieve additional values.

The third parameter allows you to retrieve variable header-field values from multi-part requests. Supply the name of a header field to retrieve its value. For example, the following SQL statements retrieve three variable values, then retrieve the header-field values of the image variable.

SET v_id    = http_variable( 'id' );
SET v_title = http_variable( 'title' );
SET v_descr = http_variable( 'descr' );
SET v_name = http_variable( 'image', NULL, 'Content-Disposition' );
SET v_type = http_variable( 'image', NULL, 'Content-Type' );
SET v_image = http_variable( 'image', NULL, '@BINARY' );


Automatic character set conversion

By default, character set conversion is performed automatically on outgoing result sets of type text. Result sets of other types, such as binary objects, are not translated. The character set of the request is converted to the database character set, and the result set is converted from the database character set to the client character set, as required, except on binary columns in the result set. When the request lists multiple character sets that it can handle, the server takes the first suitable one from the list.

Character-set conversion can be enabled or disabled by setting the HTTP option CharsetConversion. The allowed values are ON and OFF. The default value is ON. The following statement turns automatic character-set conversion off:

call dbo.sa_set_http_option( 'CharsetConversion', 'OFF' )

For more information about built-in stored procedures, see System and catalog stored procedures.


Errors

When web service requests fail, the database server generates standard errors that appear in your browser. These errors are assigned numbers consistent with the protocol standards.

If the service is a SOAP service, faults are returned as to the client as SOAP faults, following the SOAP as defined in the SOAP version 1.1 standard:

  • When an error in the application handling the request generates a SQLCODE, a SOAP Fault is returned with a faultcode of Client, possibly with a sub-category, such as Client.Procedure. The faultstring element within the SOAP Fault is set to a detailed explanation of the error and a detail element contains the numeric SQLCODE value.

  • In the event of a transport protocol error, the faultcode is set to either Client or Server, depending on the error. faultstring is set to the HTTP transport message, such as 404 Not Found, and the detail element contains the numeric HTTP error value.

  • SOAP Fault messages generated due to application errors that return an SQLCODE value are returned with an HTTP status of 200 OK.

If the client cannot be identified as a SOAP client, then the appropriate HTTP error is returned in a generated HTML document.

The following are some of the more typical errors that you may encounter:

Number | Name | SOAP fault | Description
301 | Moved permanently | Server | The requested page has been permanently moved. The server will automatically redirect the request to the new location.
304 | Not Modified | Server | The server has decided, based on information in the request, that the requested data has not been modified since the last request and so does not need to be sent again.
307 | Temporary Redirect | Server | The requested page has been moved, but this change may not be permanent. The server will automatically redirect the request to the new location.
400 | Bad Request | Client.BadRequest | The HTTP request is incomplete or malformed.
401 | Authorization Required | Client.Authorization | Authorization is required to use the service, but a valid user name and password were not supplied.
403 | Forbidden | Client.Forbidden | You do not have permission to access the database.
404 | Not Found | Client.NotFound | The named database is not running on the server, or the named web service does not exist.
408 | Request Timeout | Server.RequestTimeout | The maximum connection idle time was exceeded while receiving the request.
411 | HTTP Length Required | Client.LengthRequired | The server requires that the client include a Content-Length specification in the request. Typically occurs when uploading data to the server.
413 | Entity Too Large | Server | The request exceeds the maximum permitted size.
414 | URI Too Large | Server | The length of the URI exceeds the maximum allowed length.
500 | Internal Server Error | Server | An internal error occurred. The request could not be processed.
501 | Not Implemented | Server | The HTTP request method is not GET, HEAD, or POST.
502 | Bad Gateway | Server | The document requested resides on a third-party server and the server received an error from the third-party server.
503 | Service Unavailable | Server | The number of connections exceeds the allowed maximum.


File Locations and Installation Settings

About this chapter

This chapter describes the installation and operating system settings used by Adaptive Server Anywhere. Depending on the operating system, these settings may be stored as environment variables, initialization file entries, or registry settings.


Installation directory structure

When you install Adaptive Server Anywhere, several directories may be created. Some of the files in these directories are essential, and others are not. This section describes the directory structure.

Adaptive Server Anywhere software, whether you receive it as a product or bundled as part of another product, is installed under a single installation directory. The tools provided with the Adaptive Server Anywhere product, however, are installed in other directories. This section describes only the installation directory structure for Adaptive Server Anywhere itself.

The Adaptive Server Anywhere installation directory

The Adaptive Server Anywhere installation directory itself holds several items, including the following:

  • The sample database The sample database is held in the file asademo.db.

  • Read Me First A Read Me First file named readme.txt holds late-breaking information.

For platforms other than Novell NetWare and Windows CE, there are several directories under the installation directory:

  • Executable directories There is a separate directory for each operating system, which holds executables, dynamic link libraries, and help files.

    On Windows, except Windows CE, these files are installed in the win32 or win64 directory. If you are using UNIX, they are installed in the bin and lib directories. On NetWare, the executables are stored in the installation directory itself.

    You will not have all these directories on your machine; you will have only the ones required for the operating system version you installed.

  • Java directory Java base classes are stored in this directory.

  • Scripts directory The scripts directory contains SQL scripts that are used by the database administration utilities and as examples. With the exception of the custom.sql script, do not edit these scripts. If the scripts directory is not present, the administration utilities will not work.

  • Samples directories This holds separate directories for a variety of samples.

  • h directory The h directory contains header files for ESQL and ODBC database development. ON UNIX, this directory is called include.

Novell NetWare file locations

On Novell NetWare, all files are installed to a single directory on the server. Throughout this documentation, when reference is made to files in subdirectories of the installation directory, the file on NetWare is in the installation directory itself.

Windows CE file locations

On Windows CE, all files are installed to the installation directory \Program Files\Sybase\ASA9. No subdirectories are created. The exception is that all DLLs are installed into the \Windows directory.


How Adaptive Server Anywhere locates files

The client library and the database server need to locate files for two main purposes:

  • DLLs and initialization files are required to run Adaptive Server Anywhere. If an incorrect DLL is located, there is the possibility of version mismatch errors.

  • Some files are specified in SQL statements and need to be located at run time, such as INSTALL or LOAD TABLE.

Examples of SQL statements that use file names include the following:

  • INSTALL JAVA statement The name of the file that holds Java classes.

  • LOAD TABLE and UNLOAD TABLE statements The name of the file from which data should be loaded or to which the data should be unloaded.

  • CREATE DATABASE statement A file name is needed for this statement and similar statements that can create files.

In some cases, Adaptive Server Anywhere uses a simple algorithm to locate files. In other cases, a more extensive search is carried out.

Simple file searching

In many SQL statements (such as LOAD TABLE, or CREATE DATABASE), the file name is interpreted as relative to the current working directory of the database server.

Also, when a database server is started and a database file name (DatabaseFile (DBF) parameter) is supplied, the path is interpreted as relative to the current working directory.

Extensive file searching

Adaptive Server Anywhere programs, including the database server and administration utilities, carry out a more extensive search for required files, such as DLLs or shared libraries. In these cases, Adaptive Server Anywhere programs look for files in the following order:

  1. Executable directory Holds the program executable file.

  2. Related directories Holds directories with the following paths relative to the program executable directory:

    • Parent of the executable directory.

    • A child of the parent directory named scripts. The UNIX server does not search in this location.

  3. Current working directory When a program is started, it has a current working directory (the directory from which it is started). This directory is searched for required files.

  4. Location registry entry When installing onto Windows, Adaptive Server Anywhere adds a Location registry entry. The indicated directory is searched, followed by:

    • A child named scripts

    • A child with the operating system name (win32, win64, and so on)

  5. System-specific directories This includes directories where common operating system files are held, such as the Windows directory and the Windows\system32 directory on Windows operating systems.

  6. CLASSPATH directories For Java files, directories listed in the CLASSPATH environment variable are searched to locate files.

  7. PATH directories Directories in the system path and the user's path are searched to locate files.

  8. Library path (UNIX only) On UNIX, the operating system requires that the library path be set. The corresponding environment variable that must be set should be one of the following:

    • LD_LIBRARY_PATH (Linux, Solaris, DEC)

    • DYLD_LIBRARY_PATH (Mac OS X)

    • SHLIB_PATH (HP-UX)

    • LIBPATH (AIX)


Environment variables

Adaptive Server Anywhere uses a set of environment variables to store various types of information. These environment variables are listed in this section. Not all variables need to be set in all circumstances.

Setting environment variables
ASANY9 environment variable
ASANYSH9 environment variable
ASCHARSET environment variable
ASLANG environment variable
ASLOGDIR environment variable
ASTMP environment variable
LD_LIBRARY_PATH environment variable [UNIX]
PATH environment variable
SQLCONNECT environment variable
SQLLOCALE environment variable
SQLPATH environment variable
SQLREMOTE environment variable
SYBASE environment variable
TEMP environment variable


Setting environment variables

The way you set an environment variable depends on the operating system you are using.

toggle To set an environment variable (Windows NT)

  1. Right-click My Computer and choose Properties from the popup menu.

  2. Click the Environment tab. If the environment variable does not already exist, type variable and its value in the spaces provided, and click Set.

    If the variable does exist, select it from the list of System Variables or User Variables, and make any modifications in the Value field. Click Set to make the setting.

toggle To set an environment variable (Windows 2000)

  1. Right-click My Computer and choose Properties from the popup menu.

  2. Click the Advanced tab.

  3. Click the Environment Variables button.

    The Environment Variables dialog opens. If the environment variable does not already exist, click New and type the variable name and its value in the spaces provided, and then click OK.

    If the variable does exist, select it from the list of System Variables or User Variables, click Edit and make any modifications in the Variable Value field. Click OK to make the setting.

toggle To set an environment variable (Windows XP)

  1. From the Start menu, choose Control Panel > System.

  2. Click the Advanced tab.

  3. Click the Environment Variables button.

    The Environment Variables dialog opens. If the environment variable does not already exist, click New and type the variable name and its value in the spaces provided, and then click OK.

    If the variable does exist, select it from the list of System Variables or User Variables, click Edit and make any modifications in the Variable Value field. Click OK to make the setting.

toggle To set an environment variable (UNIX)

  • In one of your startup files (.cshrc, .shrc, .login), add a line that sets the variable.

    In some shells (such as sh, bash, or ksh) the line is as follows:

    export VARIABLE=value

    In other shells (such as csh, or tsch) the line is as follows:

    setenv VARIABLE value


ASANY9 environment variable

Syntax

ASANY9=directory-name

Default

C:\Program Files\Sybase\SQL Anywhere 9

Description

On installation, the ASANY9 environment variable is set to your SQL Anywhere directory.

This environment variable must be set for several reasons. Among the list, samples require this environment variable in order to locate SQL Anywhere applications.


ASANYSH9 environment variable

Syntax

ASANYSH9=directory-name

Default

None.

Description

Interactive SQL, Sybase Central, and the Adaptive Server Anywhere Console utility (dbconsole) use this variable to determine the location of the shared components directory. ASANYSH9 is set to the location of the shared directory. You set the shared directory location during installation. The default shared components directory is C:\Program Files\Sybase\Shared.


ASCHARSET environment variable

Syntax

ASCHARSET=charset

Description

Charset is a character set name. For example, setting ASCHARSET=cp1252 sets the default character set to cp1252.

The first of the following methods that returns a value determines the default character set.

  • check ASCHARSET environment variable

  • query of the operating system

If no character set information is specified, use iso_1 for UNIX, or cp850 otherwise.

This environment variable is not supported on Windows CE or NetWare.


ASLANG environment variable

Syntax

ASLANG=language_code

Description

Language_code is the two-letter combination representing a language. For example, setting ASLANG=DE sets the default language to German.

The first of the following methods that returns a value determines the default language.

  • ASLANG environment variable check

  • registry check (Windows only) as set by the installer or dblang.exe

  • query of the operating system for language information

If no language information is set, English is the default.

This environment variable is not supported on Windows CE or NetWare.


ASLOGDIR environment variable

Syntax

ASLOGDIR=directory-name

Description

If the ASLOGDIR environment variable is set, it is assumed to contain the path for a directory containing the backup history file, backup.syb. This file is updated each time you execute a BACKUP or RESTORE statement.

Windows

On Windows, if the ASLOGDIR environment variable is not set, the server attempts to find the backup.syb file in the directory where the server executable normally resides. For example, on 32-bit Windows platforms, this is C:\Program Files\Sybase\SQL Anywhere 9\win32. The install directory is determined using the HKLM\Software\Sybase\Adaptive Server Anywhere\9.0\Location registry key. If this directory does not exist, an error is given. If the Location registry key does not exist, the path used for the server executable is examined, if one was specified. If no path was specified to start the server, the backup.syb file is placed in the root directory of the current drive.

UNIX

On UNIX, if the ASLOGDIR environment variable is not set, the server checks for a HOME environment variable. If HOME is set, the server places the backup.syb file in that directory. Otherwise, it attempts to place the file in the Home directory for the user who started the server. If that cannot be determined, it attempts to place the backup.syb file in the directory where the server was started.

See also
  • BACKUP statement


ASTMP environment variable

Syntax

ASTMP=directory-name

Default

None.

Description

The database server checks the value of the ASTMP environment variable to determine where to hold the temporary file. If the ASTMP environment variable does not exist, then the first of the TMP, TMPDIR, and TEMP environment variables to exist is used. On UNIX, if none of the above environment variables exist, /tmp is used.

In many circumstances, ASTMP is not needed. It can be of use in security-conscious environments when running the database server as a service to enable you to hold the temporary file in a directory that cannot be accessed by other programs.

On UNIX, files that are used for shared memory access are included in the Adaptive Server Anywhere temporary files. If an application is connecting to the database server using shared memory, then the ASTMP environment variable must be set to the directory where the Adaptive Server Anywhere temporary files are located.

On Windows CE, you can specify which directory you want to use as the server's temporary directory, in the registry.

For information about the temporary file location on Windows CE, see Registry settings on Windows CE.

See also
  • TEMP environment variable


LD_LIBRARY_PATH environment variable [UNIX]

Syntax

LD_LIBRARY_PATH=installation_path/lib

Description

The LD_LIBRARY_PATH environment variable is used on UNIX only. It is modified by the installation program to include the directories where Adaptive Server Anywhere libraries are located.

The libraries are located in the lib subdirectory of the installation directory (for example, /opt/SYBSasa9/lib).

On Mac OS X, the DYLD_LIBRARY_PATH environment variable is used and on AIX, the LIBPATH environment variable is used.


PATH environment variable

Syntax

PATH=installation_path

Description

The PATH environment variable is modified by the installation program to include the directories where Adaptive Server Anywhere executables are located.

The executables are located in a subdirectory of the installation directory.

In addition, if you are using other Sybase applications, the SYBASE\bin and SYBASE\dll directories are added to your path.

On UNIX, each user must have the directory holding the executables (/opt/SYBSasa9/bin) added to their path.


SQLCONNECT environment variable

Syntax

SQLCONNECT=parameter=value; ...

Description

The SQLCONNECT environment variable is optional, and is not set by the installation program.

SQLCONNECT specifies connection parameters that are used by several of the database administration utilities when connecting to a database server. This string is a list of parameter settings, of the form parameter=value, delimited by semicolons.

The number sign (#) is an alternative to the equal sign, and should be used if you are setting the connection parameters string in the SQLCONNECT environment variable. Using = inside an environment variable setting is a syntax error.

For a description of the connection parameters, see Connection parameters.


SQLLOCALE environment variable

The SQLLOCALE environment variable is no longer supported. It has been replaced by the ASLANG and ASCHARSET environment variables.

For information about the ASLANG environment variable, see ASLANG environment variable.

For information about the ASCHARSET environment variable, see ASCHARSET environment variable.


SQLPATH environment variable

Syntax

SQLPATH=path; ...

Description

The SQLPATH environment variable is optional, and is not set by the installation program.

Interactive SQL searches along SQLPATH for command files and Help files before searching the system path.


SQLREMOTE environment variable

Syntax

SQLREMOTE=path

Description

The SQLREMOTE environment variable is optional, and is not set by the installation program.

Addresses for the FILE message link in SQL Remote are subdirectories of the SQLREMOTE environment variable. This variable should point to a shared directory.

On 32-bit Windows operating systems, an alternative to setting the SQLREMOTE environment variable is to set the SQL Remote\Directory registry entry to the proper root directory.


SYBASE environment variable

Syntax

SYBASE=path

Description

The SYBASE variable marks the home directory for installation of some Sybase applications, including Adaptive Server Enterprise and utilities such as DSEdit. You need this variable only if you are using Adaptive Server Anywhere together with other members of the Adaptive Server family.


TEMP environment variable

Syntax

ASTMP=path

TMP=path

TMPDIR=path

TEMP=path

Description

The database server creates a temporary file for various operations such as sorting and performing unions. Temporary files are placed in the directory specified by the ASTMP, TMP, TMPDIR, or TEMP environment variable. Adaptive Server Anywhere takes the first one of these that it finds, in that order.

If none of the environment variables is defined, temporary files are placed in the current working directory of the server. On UNIX only, if none of these environment variables are found, then /tmp is used.

On Windows CE, you can specify which directory you want to use as the server's temporary directory, in the registry.

For more information about setting the temporary directory value, see Registry settings on Windows CE.

ASTMP is only used by the database server (dbeng9 or dbsrv9). The command-line utilities that require a temporary directory only use TMP, TMPDIR, and TEMP on all supported platforms.


Registry and INI files

On Windows operating systems (except Windows CE), Adaptive Server Anywhere uses several registry settings. On UNIX and NetWare, these settings are held in initialization files instead.

The software makes these settings for you, and in general operation you should not need to access the registry. The settings are provided here for those people who make modifications to their operating environment.

The contents of .ini files used by Adaptive Server Anywhere can be obfuscated with simple encryption using the File Hiding utility.

For more information, see Hiding the contents of .ini files.

Caution You should not add simple encryption to the .odbc.ini system information file with the File Hiding utility (dbfhide) on UNIX unless you will only be using Adaptive Server Anywhere data sources. If you plan to use other data sources (for example, for MobiLink synchronization), then obfuscating the contents of the .odbc.ini file may prevent other drivers from functioning properly.


Current user and local machine settings

Some operating systems, such as Windows NT, hold two levels of system settings. Some settings are specific to an individual user and are used only when that user is logged on; these settings are called current user settings. Some settings are global to the machine, and are available no matter which user is logged on; these are called local machine settings. You must have administrator permissions on your machine to change local machine settings.

Adaptive Server Anywhere respects both current user and local machine settings. On Windows NT, for example, these are held in the HKEY_CURRENT_USER key and the HKEY_LOCAL_MACHINE key, respectively.

Current user takes precedence

If a setting is made in both the current user and local machine registries, the current user setting takes precedence over the local machine setting.

When local machine settings are needed

If you are running an Adaptive Server Anywhere program as a service, you should ensure that the settings are made at the local machine level.

Services can continue to run under a special account when you log off a machine as long as you do not shut the machine down entirely. They can be made independent of individual accounts, and therefore need access to local machine settings.

In addition to Adaptive Server Anywhere programs, some web servers run as services. You must set local machine settings in order for PowerDynamo to work with such a web server.

In general, the use of local machine settings is recommended.


Registry structure

On Windows (except Windows CE), you can access the registry directly with the registry editor. The Adaptive Server Anywhere registry entries are held in either the HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE keys, in the following location:

Software
   Sybase
      Adaptive Server Anywhere
         9.0
      Sybase Central
         4.3
         Profiles
         Providers


Registry settings on installation

The installation program makes the following registry settings in the Sybase registry:

  • Location In the Adaptive Server Anywhere\9.0 registry key, this entry holds the installation directory location. For example:

    Location  "c:\Program Files\Sybase\SQL Anywhere 9"

  • Language In the Adaptive Server Anywhere\9.0 registry key, this entry holds a two-letter code indicating the current language for messages and errors. For example:

    Language "EN"

    The default setting is English (EN). The installation program sets this entry only if the software is installed for a language other than English.


Registry settings on Windows CE

You can specify which directory you want to use as the server's temporary directory on Windows CE by setting the

HKEY_CURRENT_USER\Software\Sybase\Adaptive Server Anywhere\9.0\TempFolder

value in the registry, where TempFolder is the name of the temporary directory you want to use. The server will either:

  • use the specified directory if it exists, or

  • attempt to create the specified directory if it does not already exist, as long as the parent directory already exists.

If the specified directory does not exist and cannot be created, the server will:

  • use the \Temp directory if it exists, or

  • attempt to create a \Temp directory if it does not already exist.

If the \Temp directory does not exist and cannot be created, the server uses the current directory.


Working with Database Files

About this chapter

This chapter describes how to create, and work with database and associated files.


Overview of database files

Basic database files

Each database has the following files associated with it.

  • The database file This file holds the database information. It typically has the extension .db.

    For information on creating databases, see Working with databases.

  • The transaction log This file holds a record of the changes made to the database, and is necessary for recovery and replication. It typically has the extension .log.

    For information on the transaction log, see The transaction log.

  • The temporary file

    The database server uses the temporary file to hold information needed during a database session. The database server disregards this file once the database shuts down—even if the server remains running. The file has a server-generated name with the extension .tmp.

    The temporary file is held in a location determined by an environment variable.

    The following environment variables are checked, in order:

    • ASTMP

    • TMP

    • TMPDIR

    • TEMP

    If none of these is defined, Adaptive Server Anywhere places its temporary file in the current directory on Windows operating systems, or in the /tmp/.SQLAnywhere directory on UNIX.

    The server creates, maintains, and removes the temporary file. You only need to ensure that there is enough free space available for the temporary file. You can obtain information about the space available for the temporary file using the sa_disk_free_space procedure.

    For more information, see sa_disk_free_space system procedure.

Additional files

Other files can also become part of a database system, including:

  • Additional database files You can spread your data over several separate files. These additional files are called dbspaces.

    For information on dbspaces, see CREATE DBSPACE statement.

  • Transaction log mirror files For additional security, you can create a mirror copy of the transaction log. This file typically has the extension .mlg.

    For information on mirrored transaction logs, see Transaction log mirrors.


Using additional dbspaces

This section describes how to use additional database files, known as dbspaces.

Typically needed for large databases
For most databases, a single database file is sufficient. However, for users of large databases, additional database files are sometimes necessary. Additional database files are also convenient tools for clustering related information in separate files.

When you initialize a database, it contains one database file. This first database file is called the main file. All database objects and all data are placed, by default, in the main file.

Each database file has a maximum allowable size of 256M database pages. For example, a database file created with a database page size of 4 KB can grow to a maximum size of one terabyte (256M*4 KB). However, in practice, the maximum file size allowed by the physical file system in which the file is created affects the maximum allowable size significantly.

While many commonly-employed file systems restrict file size to a maximum of 2 GB, some, such as the Windows NT/2000/XP file system, allow you to exploit the full database file size. In scenarios where the amount of data placed in the database exceeds the maximum file size, it is necessary to divide the data into more than one database file. As well, you may wish to create multiple dbspaces for reasons other than size limitations, for example to cluster related objects.

Splitting existing databases

If you wish to split existing database objects among several dbspaces, you need to unload your database and modify the generated command file for rebuilding the database. To do so, add IN clauses to specify the dbspace for each table you do not wish to place in the main file.

For more information, see UNLOAD TABLE statement.


Creating a dbspace

You create a new database file, or dbspace, either from Sybase Central, or using the CREATE DBSPACE statement. The database file for a new dbspace may be on the same disk drive as the main file or on another disk drive. You must have DBA authority to create dbspaces.

For each database, you can create up to twelve dbspaces in addition to the main dbspace.

Placing tables in dbspaces

A newly-created dbspace is empty. When you create a new table you can place it in a specific dbspace with an IN clause in the CREATE TABLE statement. If you don't specify an IN clause, the table appears in the main dbspace.

Each table is entirely contained in the dbspace it is created in. By default, indexes appear in the same dbspace as their table, but you can place them in a separate dbspace by supplying an IN clause.

toggle To create a dbspace (Sybase Central)

  1. Open the Dbspaces folder for that database.

  2. From the File menu, choose New > Dbspace.

    The Dbspace Creation wizard appears.

  3. Follow the instructions in the wizard.

    The new dbspace then appears in the Dbspaces folder.

toggle To create a dbspace (SQL)

  • Execute a CREATE DBSPACE statement.

Examples

The following command creates a new dbspace called library in the file library.db in the same directory as the main file:

CREATE DBSPACE library
AS 'library.db'

The following command creates a table LibraryBooks and places it in the library dbspace.

CREATE TABLE LibraryBooks (
title char(100),
author char(50),
isbn char(30)
) IN library
See also
  • CREATE DBSPACE statement
  • Creating tables
  • CREATE INDEX statement


Pre-allocating space for database files

Adaptive Server Anywhere automatically grows database files as needed. Rapidly-changing database files can lead to excessive file fragmentation on the disk, resulting in potential performance problems. Unless you are working with a database with a high rate of change, you do not need to worry about explicitly allocating space for database files. If you are working with a database with a high rate of change, you may pre-allocate disk space for dbspaces or for transaction logs using either Sybase Central or the ALTER DBSPACE statement.

You must have DBA authority to alter the properties of a database file.

Performance Tip
Running a disk defragmentation utility after pre-allocating disk space helps ensure that the database file is not fragmented over many disjoint areas of the disk drive. Performance can suffer if there is excessive fragmentation of database files.
toggle To pre-allocate space (Sybase Central)

  1. Open the Dbspaces folder.

  2. Right-click the desired dbspace and choose Pre-allocate Space from the popup menu.

  3. Enter the amount of space to add to the dbspace. You can add space in units of pages, kilobytes (KB), megabytes (MB), gigabytes (GB), or terabytes (TB).

  4. Click OK.

toggle To pre-allocate space (SQL)

  1. Connect to a database.

  2. Execute an ALTER DBSPACE statement.

Examples

  • Increase the size of the SYSTEM dbspace by 200 pages.

    ALTER DBSPACE system
ADD 200

  • Increase the size of the SYSTEM dbspace by 400 megabytes.

    ALTER DBSPACE system
ADD 400 MB
See also
  • Creating a dbspace
  • ALTER DBSPACE statement


Deleting a dbspace

You can delete a dbspace using either Sybase Central or the DROP DBSPACE statement. Before you can delete a dbspace, you must delete all tables that use the dbspace. You must have DBA authority to delete a dbspace.

toggle To delete a dbspace (Sybase Central)

  1. Open the Dbspaces folder.

  2. Right-click the desired dbspace and choose Delete from the popup menu.

toggle To delete a dbspace (SQL)

  1. Connect to a database.

  2. Execute a DROP DBSPACE statement.

See also
  • Deleting tables
  • DROP statement


Working with write files (deprecated)

Deprecated feature
The use of write files is deprecated.

If you have a read-only database file (for example, if you distribute a database on a CD-ROM), you can use a write file to make local changes to the database.

You create a write file using the Create Write File utility [dbwrite] or using the CREATE WRITEFILE statement. In this section, the examples use the utility.

For a description of the CREATE WRITEFILE statement, see CREATE WRITEFILE statement (deprecated).

For more information about opening a database as read-only to prevent local changes to the database, see -r server option.

toggle To use a write file

  1. Create the write file for your database.

    For example, to create a write file for the sample database, execute the following command in a directory containing a copy of the sample database file asademo.db:

    dbwrite -c asademo.db

    This command creates a write file named asademo.wrt, with a transaction log named asademo.wlg.

  2. Start a database server and load the write file. By default, the server locates files with the extension .wrt first, so the following command starts the personal server running the sample database write file:

    dbeng9 asademo

    Messages on the server window indicate which file starts.

  3. Connect to the database using Interactive SQL. You can use the user ID DBA and the password SQL, as the sample database is the default.

  4. Execute queries as usual. For example, the following query lists the contents of the department table.

    SELECT *
FROM department

    The data for the department table is obtained from the database file asademo.db.

  5. Try inserting a row. The following statement inserts a row into the department table:

    INSERT
INTO department (dept_id, dept_name)
VALUES (202, 'Eastern Sales')

    If you committed this change, it would be written to the asademo.wlg transaction log, and when the database checkpoints, the changes are written to the asademo.wrt write file.

    If you now query the department table, the results come from the write file and the database file.

  6. Try deleting a row. Set the WAIT_FOR_COMMIT option to avoid referential integrity complaints here:

    SET TEMPORARY OPTION wait_for_commit = 'on' ;
DELETE
FROM department
WHERE dept_id = 100

    If you committed this change, the deletion would be marked in the write file. No changes occur to the database file.

For some purposes, it is useful to use a write file with a shared database. If, for example, you have a read-only database on a network server, each user could have their own write file. In this way, they could add local information, which would be stored on their own machine, without affecting the shared database. This approach can be useful for application development also.

Deleting a write file

You can use the dberase utility to delete a write file and its associated transaction log.


Using the utility database

The utility database is a phantom database with no physical representation. The utility database has no database file, and therefore it cannot contain data.

The utility database feature allows you to execute database file administration statements such as CREATE DATABASE without first connecting to an existing physical database.

For example, executing the following statement after having connected to the utility database creates a database named new.db in the directory C:\temp.

CREATE DATABASE 'C:\\temp\\new.db'

For more information on the syntax of these statements, see CREATE DATABASE statement.

You can also retrieve values of connection properties and server properties using the utility database.

For example, executing the following statement against the utility database returns the default collation sequence, which will be used when creating a database:

SELECT property( 'DefaultCollation' )

For a list of connection properties and server properties, see Database properties.

Allowed statements for the utility database

The following statements are the only ones allowed when connected to the utility database:

  • ALTER DATABASE dbfile MODIFY TRANSACTION LOG

  • CREATE DATABASE

  • CREATE DECRYPTED FILE

  • CREATE ENCRYPTED FILE

  • DROP DATABASE

  • RESTORE DATABASE

  • START DATABASE

  • STOP DATABASE

  • STOP ENGINE

  • SELECT (with no FROM or WHERE clauses)


Connecting to the utility database

You can start the utility database on a database server by specifying utility_db as the database name when connecting to the server. The user ID and password requirements are different for the personal server and the network server.

For the personal database server, there are no security restrictions for connecting to the utility database. It is assumed that anybody who can connect to the personal database server can access the file system directly so no attempt is made to screen users based on passwords.

For more information, see Utility database passwords.

toggle To connect to the utility database on the personal server (Interactive SQL)

  1. Start a database server with the following command:

    dbeng9.exe -n TestEng

  2. Start Interactive SQL.

  3. In the Connect dialog, enter DBA as the user ID, and enter any non-blank password. The password itself is not checked, but it must be non-empty.

  4. On the Database tab, enter utility_db as the database name and TestEng as the server name.

  5. Click OK to connect.

    Interactive SQL connects to the utility database on the personal server named TestEng, without loading a real database.

For the network server, there are security restrictions on connections. A password is held in the file util_db.ini in the same directory as the database server executable.

To protect the contents of the util_db.ini file from casual direct access, you can add simple encryption to the file using the File Hiding utility (dbfhide).

For more information about obfuscating .ini files, see Hiding the contents of .ini files.

toggle To connect to the utility database on the network server (Interactive SQL)

  1. Add a password to the file util_db.ini in the same directory as the database server executable. For example, the following util_db.ini file has the password ASA.

    [UTILITY_DB]
PWD=ASA

  2. Start a database server with the following command:

    dbsrv9.exe -n TestEng

  3. Start Interactive SQL.

  4. In the Connect dialog, enter DBA as the user ID, and enter the password held in the file util_db.ini.

  5. On the Database tab, enter utility_db as the database name.

  6. Click OK to connect.

    Interactive SQL connects to the utility database on the network server named TestEng, without loading a real database.

For more information, see Connecting to a Database.


Utility database server security

There are two aspects to utility database server security:

  • Who can connect to the utility database? This is controlled by the use of passwords.

  • Who can execute file administration statements? This is controlled by database server options.


Utility database passwords

The personal server and the network server have different security models for connections.

For the personal server, you must specify the user ID DBA. You must also specify a password, but it can be any password. Since the personal server is for single machine use, security restrictions (for example passwords) are unnecessary.

For the network server, you must specify the user ID DBA, and the password that is held in the util_db.ini file, stored in the same directory as the database server executable file. As this directory is on the server, you can control access to the file, and thereby control who has access to the password.

The util_db.ini file

The util_db.ini file has the following contents:

[UTILITY_DB]
PWD=password

Use of the utility_db security level relies on the physical security of the computer hosting the database server, since the util_db.ini file can be easily read using a text editor.

To help protect the contents of the util_db.ini file, you can obfuscate it with simple encryption using the File Hiding utility (dbfhide).

For more information about obfuscating .ini files, see Hiding the contents of .ini files.


Permission to execute file administration statements

A level of security is provided for the ability to execute certain administration tasks. The -gu database server option controls who can execute the file administration statements.

There are four levels of permission for the use of file administration statements. These levels include: all, none, DBA, and utility_db. The utility_db level permits only a person with authority to connect to the utility database to use the file administration statements.

-gu option | Effect | Applies to
All | Anyone can execute file administration statements | Any database including utility database
None | No one can execute file administration statements | Any database including utility database
Dba | Only DBA-authority users can execute file administration statements | Any database including utility database
Utility_db | Only the users who can connect to utility database can execute file administration statements | Only the utility database

For more information on the database server –gu option, see -gu server option.

Examples

  • To prevent the use of the file administration statements, start the database server using the none permission level of the –gu option. The following command starts a database server and names it TestSrv. It loads the sample database, but prevents anyone from using that server to create or delete a database, or execute any other file administration statement regardless of their resource creation rights, or whether or not they can load and connect to the utility database.

    dbsrv9.exe –n TestSrv -gu none asademo.db

  • To permit only the users knowing the utility database password to execute file administration statements, start the server at the command prompt with the following command.

    dbsrv9 –n TestSrv –gu utility_db

    Assuming the utility database password has been set during installation to asa, the following command starts the Interactive SQL utility as a client application, connects to the server named TestSrv, loads the utility database, and connects the user.

    dbisql -c "uid=DBA;pwd=asa;dbn=utility_db;eng=TestSrv"

    Having executed the above command successfully, the user connects to the utility database, and can execute file administration statements.


Automating Tasks Using Schedules and Events

About this chapter

This chapter describes how to use scheduling and event handling features of Adaptive Server Anywhere to automate database administration and other tasks.

Introduction
Understanding events
Understanding schedules
Understanding system events
Understanding event handlers
Schedule and event internals
Event handling tasks


Introduction

Many database administration tasks are best carried out systematically. For example, a regular backup procedure is an important part of proper database administration procedures.

You can automate routine tasks in Adaptive Server Anywhere by adding an event to a database, and providing a schedule for the event. Whenever one of the times in the schedule passes, the database server executes a sequence of actions called an event handler.

Database administration also requires taking action when certain conditions occur. For example, it may be appropriate to e-mail a notification to a system administrator when a disk containing the transaction log is filling up so that the administrator can handle the situation. These tasks too can be automated by defining event handlers for one of a set of system events.

Chapter contents

This chapter contains the following material:

  • An introduction to scheduling and event handling (this section).

  • Concepts and background information to help you design and use schedules and event handlers:

    • Understanding schedules.

    • Understanding system events.

  • A discussion of techniques for developing event handlers:

    • Developing event handlers.

  • Internals information:

    • Schedule and event internals.

  • Step by step instructions for how to carry out automation tasks.

    • Event handling tasks.

Questions and answers
To answer the question... | Consider reading...
What is a schedule? | Understanding schedules.
What is an event? | Understanding events
What is a system event? | Understanding system events
What is an event handler? | Understanding event handlers
How do I debug event handlers? | Developing event handlers
How does the database server use schedules to trigger event handlers? | How the database server checks for scheduled events
How can I schedule regular backups? | For an example, see Understanding schedules.
What kind of system events can the database server use to trigger event handlers? | Understanding system events. CREATE EVENT statement.
What connection do event handlers get executed on? | How event handlers are executed.
How do event handlers get information about what triggered them? | Developing event handlers EVENT_PARAMETER function [System]


Understanding events

There are three types of events:

  • Scheduled events have an associated schedule and execute at specified times.

  • System events are associated with a particular type of condition that is tracked by the database server.

  • Manual events are fired explicitly using the TRIGGER EVENT statement.

Each event type is described in more detail in the following sections.


Understanding schedules

By scheduling activities you can ensure that a set of actions is executed at a set of preset times. The scheduling information and the event handler are both stored in the database itself.

Although this is not usually necessary, you can define complex schedules by associating more than one schedule with a named event. For example, a retail outlet might want an event to occur once per hour during hours of operation, where the hours of operation vary based on the day of the week. You can achieve the same effect by defining multiple events, each with its own schedule, and by calling a common stored procedure.

The following examples give some ideas for scheduled actions that may be useful.

When scheduling events, you can use either full-length English day names (Monday, Tuesday, and so on) or the abbreviated forms of the day (Mon, Tue, and so on). Note that you must use the full-length English day names if you want the day names to be recognized by a server running in a language other than English.

For more information, see CREATE EVENT statement.

Examples

Carry out an incremental backup daily at 1:00 am:

CREATE EVENT IncrementalBackup
SCHEDULE
   START TIME '1:00 AM' EVERY 24 HOURS
HANDLER
BEGIN
   BACKUP DATABASE DIRECTORY 'c:\\backup'
   TRANSACTION LOG ONLY
   TRANSACTION LOG RENAME MATCH
END

Summarize orders at the end of each business day:

CREATE EVENT Summarize
SCHEDULE
   START TIME '6:00 pm'
   ON ( 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
      'Friday' )
HANDLER
BEGIN
   INSERT INTO DBA.OrderSummary
      SELECT current date,
             count( * ),
             sum( amount )
      FROM DBA.Orders
      WHERE date_ordered = current date
END

Defining schedules


Defining schedules

Schedule definitions have several components to them, to permit flexibility:

  • Name Each schedule definition has a name. You can assign more than one schedule to a particular event, which can be useful in designing complex schedules.

  • Start time You can define a start time for the event, which is the time that it is first executed.

  • Range As an alternative to a start time, you can specify a range of times for which the event is active. The event occurs between the start and end time specified. Frequency is determined by the specified recurrence.

  • Recurrence Each schedule can have a recurrence. The event is triggered on a frequency that can be given in hours, minutes, or seconds on a set of days that can be specified as days of the week or days of the month. Recurring events include an EVERY or ON clause.


Understanding system events

The database server tracks several kinds of system events. Event handlers are triggered when the system event is checked by the database server, and satisfies a provided trigger condition.

By defining event handlers to execute when a chosen system event occurs and satisfies a trigger condition that you define, you can improve the security and safety of your data, and help ease administration.

For more information on the available system events, see Choosing a system event.

For more information on trigger conditions, see Defining trigger conditions for events.


Choosing a system event

Adaptive Server Anywhere tracks several system events. Each system event provides a hook on which you can hang a set of actions. The database server tracks the events for you, and executes the actions (as defined in the event handler) when needed.

The available system events include the following:

  • Backup

    You can use the BackupEnd event type to take action at the end of a backup.

  • DatabaseStart

    You can use the DatabaseStart event type to take action when a database is started.

  • Connection events

    When a connection is made (Connect) or when a connection attempt fails (ConnectFailed). You may want to use these events for security purposes.

  • Disconnect

    You can use the Disconnect event to take action when a user or application disconnects.

  • Free disk space

    Tracks the available disk space on the device holding the database file (DBDiskSpace), the log file (LogDiskSpace), or temporary file (TempDiskSpace). This system event is not available on the following operating systems:

    • Windows 95 before OSR2

    • Windows CE

    You may want to use disk space events to alert administrators in case of a disk space shortage.

    You can specify the -fc option when starting the database server to implement a callback function when the database server encounters a file system full condition.

    For more information, see -fc server option.

  • File size

    The file reaches a specified size. This can be used for the database file (GrowDB), the transaction log (GrowLog), or the temporary file (GrowTemp).

    You may want to use file size events to track unusual actions on the database, or monitor bulk operations.

  • GlobalAutoIncrement

    When the number of remaining values for a column defined with GLOBAL AUTOINCREMENT is less than a percentage of its range, the GlobalAutoIncrement event fires. This can be used to request a new value for the GLOBAL_DATABASE_ID option based on the table and number of remaining values that are supplied as parameters to this event. You can use the event_condition function with RemainingValues as an argument for this event type.

  • SQL errors

    When an error is triggered, you can use the RAISERROR event type to take actions.

  • Idle time

    The database server has been idle for a specified time (ServerIdle). You may want to use this event type to carry out routine maintenance operations at quiet times.

For information about creating events, see CREATE EVENT statement.


Defining trigger conditions for events

Each event definition has a system event associated with it. It also has one or more trigger conditions. The event handler is triggered when the trigger conditions for the system event are satisfied.

The trigger conditions are included in the WHERE clause of the CREATE EVENT statement, and can be combined using the AND keyword. Each trigger condition is of the following form:

event_condition( condition-name ) comparison-operator value

The condition-name argument is one of a set of preset strings, which are appropriate for different event types. For example, you can use DBSize (the database file size in megabytes) to build a trigger condition suitable for the GrowDB system event. The database server does not check that the condition-name matches the event type: it is your responsibility to ensure that the condition is meaningful in the context of the event type.

Examples

  • Limit the transaction log size to 10 Mb:

    CREATE EVENT LogLimit
TYPE GrowLog
WHERE event_condition( 'LogSize' ) > 10
HANDLER
BEGIN
  IF event_parameter( 'NumActive' ) <= 1 THEN
   BACKUP database
     DIRECTORY 'c:\\logs'
     TRANSACTION LOG ONLY
     TRANSACTION LOG RENAME MATCH;
  END IF;
END

  • Notify an administrator when free disk space on the device containing the database file falls below 10%, but do not execute the handler more than once every five minutes (300 seconds):

    CREATE EVENT LowDBSpace
TYPE DBDiskSpace
WHERE event_condition( 'DBFreePercent' ) < 10
AND event_condition( 'Interval' ) >= 300
HANDLER
BEGIN
   CALL xp_sendmail( recipient='DBAdmin',
            subject='Low disk space',
            "message"='Database free disk space '
            || event_parameter( 'DBFreeSpace' ) );
END

  • Notify an administrator of a possible attempt to break into the database:

    CREATE EVENT SecurityCheck
TYPE ConnectFailed
HANDLER
BEGIN
   DECLARE num_failures INT;
   DECLARE mins INT;
       INSERT INTO FailedConnections( log_time )
   VALUES ( current timestamp );

   SELECT count( * ) INTO num_failures
   FROM FailedConnections
   WHERE log_time >= dateadd( minute, -5,
      current timestamp );
       IF( num_failures >= 3 ) THEN
      SELECT datediff( minute, last_notification,
         current timestamp ) INTO mins
      FROM Notification;
          IF( mins > 30 ) THEN
         UPDATE Notification
         SET last_notification = current timestamp;
       CALL xp_sendmail( recipient='DBAdmin',
                     subject='Security Check',
                  "message"=
   'over 3 failed connections in last 5 minutes' )
      END IF
   END IF
END

  • Run a process when the server has been idle for ten minutes. Do not execute more frequently than once per hour:

    CREATE EVENT Soak
TYPE ServerIdle
WHERE event_condition( 'IdleTime' ) >= 600
AND event_condition( 'Interval' ) >= 3600
HANDLER
BEGIN
   MESSAGE ' Insert your code here ... '
END


Understanding event handlers

Event handlers execute on a separate connection from the action that triggered the event, and so do not interact with client applications. They execute with the permissions of the creator of the event.

Developing event handlers


Developing event handlers

Event handlers, whether for scheduled events or for system event handling, contain compound statements, and are similar in many ways to stored procedures. You can add loops, conditional execution, and so on, and you can use the Adaptive Server Anywhere debugger to debug event handlers.

Context information for event handlers

One difference between event handlers and stored procedures is that event handlers do not take any arguments. Certain information about the context in which an event was triggered is available through the event_parameter function, which supplies information about the connection that caused an event to be triggered (connection ID, user ID), as well as the event name and the number of times it has been executed.

For more information, see EVENT_PARAMETER function [System].

Testing event handlers

During development, you want event handlers to be triggered at convenient times. You can use the TRIGGER EVENT statement to explicitly cause an event to execute, even when the trigger condition or scheduled time has not occurred. However, TRIGGER EVENT does not cause disabled event handlers to be executed.

For more information, see TRIGGER EVENT statement.

While it is not good practice to develop event handlers on a production database, you can disable event handlers from Sybase Central or explicitly using the ALTER EVENT statement.

It can be useful to use a single set of actions to handle multiple events. For example, you may want to take a notification action if disk space is limited on any of the devices holding the database or log files. To do this, create a stored procedure and call it in the body of each event handler.

Debugging event handlers

Debugging event handlers is very similar to debugging stored procedures. The event handlers appear in the events list.

You can also determine how many instances of a particular event handler are currently active using the NumActive event parameter. This function is useful if you want to limit an event handler so that only one instance executes at any given time.

For more information about the NumActive event parameter, see EVENT_PARAMETER function [System].

For more information about step-by-step instructions, see Debugging an event handler.


Web Links Browse Collapse Expand PDF Previous Next

ASA Database Administration Guide

Automating Tasks Using Schedules and Events

Schedule and event internals

This section describes how the database server processes schedules and event definitions.


How the database server checks for system events

System events are classified according to their event type, as specified directly in the CREATE EVENT statement or using Sybase Central. There are two kinds of event types:

  • Active event types Some event types are the result of action by the database server itself. These active event types include growing database files, or the start and end of different database actions (BackupEnd and so on) or RAISERROR.

    When the database server takes the action, it checks to see whether the trigger conditions defined in the WHERE clause are satisfied, and if so, triggers any events defined for that event type.

  • Polled event types Some event types are not triggered solely by database actions. The free disk space types (DBDiskSpace and so on), as well as the IdleTime type, are of this kind.

    For these types of events, the database server polls every thirty seconds, starting approximately thirty seconds after the database server is started.

    For the IdleTime event type, the database server checks whether the server has been idle for the entire thirty seconds. If no requests have started and none are currently active, it adds the idle check interval time in seconds to the idle time total; otherwise, the idle time total is reset to 0. The value for IdleTime is therefore always a multiple of thirty seconds. When IdleTime is greater than the interval specified in the trigger condition, event handlers associated with IdleTime are fired.


How the database server checks for scheduled events

The calculation of scheduled event times is done when the database server starts, and each time a scheduled event handler completes.

The calculation of the next scheduled time is based on the increment specified in the schedule definition, with the increment being added to the previous start time. If the event handler takes longer to execute than the specified increment, so that the next time is earlier than the current time, the database server increments until the next scheduled time is in the future.

An event handler that takes sixty-five minutes to execute and is requested to run every hour between 9:00 and 5:00 will run every two hours, at 9:00, 11:00, 1:00, and so on.

To run a process such that it operates between 9:00 and 5:00 and delays for some period before the next execution, you could define a handler to loop until its completion time has passed, with a WAITFOR statement between each iteration.

If you are running a database server intermittently, and it is not running at a scheduled time, the event handler does not run at startup. Instead, the next scheduled time is computed at startup. If, for example, you schedule a backup to take place every night at one o'clock, but regularly shut down the database server at the end of each work day, the backup never takes place.

If the next scheduled execution of an event is more than one hour away, the database server will recalculate its next scheduled time on an hourly basis. This allows events to fire when expected when the system clock is adjusted because of a change to or from Daylight Saving Time.


How event handlers are executed

When an event handler is triggered, a temporary internal connection is made on which the event handler is executed. The handler is not executed on the connection that caused the handler to be triggered, and consequently statements such as MESSAGE ... TO CLIENT, which interact with the client application, are not meaningful within event handlers. Similarly, statements that return result sets are not permitted.

The temporary connection on which the handler is executed does not count towards the connection limit for licensing purposes.

Event creation requires DBA authority, and events execute with the permissions of their creator. If you wish event handlers to execute with non-DBA authority, you can call a procedure from within the handler, as stored procedures run with the permissions of their creator.

Any event errors are logged to the server console.


Web Links Browse Collapse Expand PDF Previous Next

ASA Database Administration Guide

Automating Tasks Using Schedules and Events

Event handling tasks

This section collects together instructions for tasks related to automating tasks with events.


Adding an event to a database

Events are handled in a similar fashion, both from Sybase Central and in SQL.

For more information, see Understanding schedules, and Understanding system events.

toggle To add an event to a database (Sybase Central)

  1. Connect to the database as a user with DBA authority.

  2. Click the Events folder for your database.

  3. From the File menu, choose New > Event.

    The Event Creation wizard appears.

  4. Follow the instructions in the wizard.

    The wizard contains many options, depending on the event you wish to create. These are explained in detail in other tasks.

toggle To add an event to a database (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute a CREATE EVENT statement.

    The CREATE EVENT statement contains many options, depending on the event you wish to create. These are explained in detail in other tasks.

    For more information, see CREATE EVENT statement.


Adding a manually-triggered event to a database

If you create an event handler without a schedule or system event to trigger it, it is executed only when manually triggered.

toggle To add a manually-triggered event to a database (Sybase Central)

  1. Connect to the database as a user with DBA authority.

  2. Click the Events folder for your database.

  3. From the File menu, choose New > Event.

    The Event Creation wizard appears.

  4. Type a name for the event, and click Next.

  5. Select Manually, and click Next.

  6. Type the SQL statements for your event handler, and click Next.

  7. Select Enable This Event, and select Execute at All Locations, and click Next.

  8. Type a comment describing the event, and click Finish to add the event to the database.

If you wish to accept the default values for all remaining options, you can click Finish at an earlier stage in the wizard.

toggle To add a manually-triggered event to a database (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute a CREATE EVENT statement with no schedule or WHERE clause. The restricted syntax of the CREATE EVENT is as follows:

    CREATE EVENT event-name HANDLER BEGIN ...
    event handler END

If you are developing event handlers, you can add schedules or system events to control the triggering of an event later, either using Sybase Central or the ALTER EVENT statement.

See also:

  • For information on triggering events, see Triggering an event handler.

  • For information on altering events, see ALTER EVENT statement.


Triggering an event handler

Any event handler can be triggered manually, in addition to those occasions when it executes because of a schedule or system event. Triggering events manually can be useful during development of event handlers, and also, for certain events, in production environments. For example, you may have a monthly sales report scheduled, but from time to time you may want to obtain a sales report for a reason other than the end of the month.

For more information on developing event handlers, see Developing event handlers.

toggle To trigger an event handler (Sybase Central)

  1. Connect to the database as a user with DBA authority.

  2. Open the Events folder for your database.

  3. Right-click the event you wish to trigger and choose Trigger from the popup menu. (The event must be enabled before you can select Trigger from the popup menu. You can enable the event on the General tab of the Event property sheet.)

    The Trigger Event dialog appears.

  4. Supply any parameters the event handler requires, in a comma-separated list, as follows:

    parameter=value,parameter=value

    Click OK to trigger the event handler.

toggle To trigger an event handler (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute the TRIGGER EVENT statement, supplying the name of the event. For example:

    TRIGGER EVENT sales_report_event

    For more information, see TRIGGER EVENT statement.


Debugging an event handler

Debugging is a regular part of any software development. Event handlers can be debugged during the development process.

For more information on developing event handlers, see Developing event handlers.

For more information on using the debugger, see Debugging Logic in the Database.

toggle To debug an event handler

  1. Start Sybase Central.

    From the Start menu, choose Programs > SQL Anywhere 9 > Sybase Central.

  2. Connect to your database.

  3. Change to Debug mode.

    From the Task menu, choose Debug. The Debugger Details pane appears at the bottom of the Sybase Central main window.

  4. In the Folders pane, open the Events folder.

  5. Click the name of the event you wish to debug.

  6. In the SQL pane, click the left margin beside the line where you want to add a breakpoint. A red stop signs appears, to indicate that a breakpoint has been set. Alternatively, you can press F9 to set a breakpoint.

  7. From Interactive SQL or another application, trigger the event handler using the TRIGGER EVENT statement.

  8. The execution stops at the breakpoint you have set. You can now use the debugger features to trace execution, local variables, and so on.


International Languages and Character Sets

About this chapter

This chapter describes how to configure your Adaptive Server Anywhere installation to handle international language issues.

Introduction to international languages and character sets
Understanding character sets in software
Understanding locales
Understanding collations
Understanding character set translation
Collation internals
International language and character set tasks
Code page and character set reference


Introduction to international languages and character sets

This section provides an introduction to the issues you may face when working in an environment that uses more than one character set, or when using languages other than English.

When you create a database, you specify a collating sequence, or collation, for the database to use. A collation is a combination of a character set and a sort order for characters in the database.

Localized versions of Adaptive Server Anywhere
Adaptive Server Anywhere international features
Using the default collation
Character set questions and answers


Localized versions of Adaptive Server Anywhere

Adaptive Server Anywhere is available in the following fully localized (packages, software, documentation, books) languages:

  • English

  • German

  • French

  • Japanese

  • Simplified Chinese

As well, Adaptive Server Anywhere is available in the following deployment (software only) languages:

  • Italian

  • Korean

  • Lithuanian

  • Polish

  • Portuguese (Brazilian)

  • Russian

  • Spanish

  • Traditional Chinese

  • Ukrainian


Adaptive Server Anywhere international features

Adaptive Server Anywhere provides two sets of features that are of particular interest when setting up databases for languages.

  • Collations You can choose from a wide selection of supplied collations when you create a database. By creating your database with the proper collation, you ensure proper sorting of data.

    Whenever the database compares strings, sorts strings, or carries out other string operations such as case conversion, it does so using the collation sequence. The database carries out sorting and string comparison when statements such as the following are executed:

    • Queries with an ORDER BY clause.

    • Expressions that use string functions, such as LOCATE, SIMILAR, and SOUNDEX.

    • Conditions using the LIKE keyword.

    • Queries that use index lookups on character data.

    The database also uses collations to identify valid or unique identifiers (column names and so on).

  • Character set translation You can set up Adaptive Server Anywhere to convert data between the character set encoding on your server and client systems, thus maintaining the integrity of your data, even in mixed character set environments.

    Character set translation is provided between client and server, as well as by the Adaptive Server Anywhere ODBC driver. OLE DB and ADO.NET also provide it; all are Unicode-enabled.


Using the default collation

If you use the default actions when creating a database, the Initialization utility infers a collation from the character set and language used by the operating system on the machine on which you create the database.

For more information on how to find the default collation in your environment, see Finding the default collation.

If all the machines in your environment share the same character set, then the default collation minimizes the requirement for character set conversion. As long as the collation provides a proper character set and sort order for your data, using this default setting is a simple way of ensuring that characters are represented consistently throughout the system.

If it is not possible to set up your system in this default manner, you need to decide which collation to use in your database, and whether to use character set translation to ensure that data is exchanged consistently between the pieces of your database system. This chapter provides the information you need to make and implement these decisions.


Character set questions and answers

The following table identifies where you can find answers to questions.

To answer the question... | Consider reading...
How do I set up my computing environment to treat character sets properly? | Configuring your character set environment
How do I decide which collation to use for my database? | Understanding collations
How are characters represented in software, and Adaptive Server Anywhere in particular? | Understanding character sets in software
What collations does Adaptive Server Anywhere provide? | Choosing collations
How do I ensure that error and informational messages sent from the database server to client applications are sent in the proper language and character set for my application? | Character translation for database messages
I have a different character set on client machines from that in use in the database. How can I get characters to be exchanged properly between client and server? | Starting a database server using character set translation
What character sets can I use for connection strings? | Connection strings and character sets
How do I create a collation that is different from the supplied ones? | Creating a database with a custom collation
How do I change the collation sequence of an existing database? | Changing a database from one collation to another
How do I create a database for Windows CE? | Creating databases for Windows CE


Understanding character sets in software

This section provides general information about software issues related to international languages and character sets.

Pieces in the character set puzzle
Language issues in client/server computing
Code pages
Multibyte character sets
Sorting characters using collations
International aspects of case sensitivity


Pieces in the character set puzzle

There are several distinct aspects to character storage and display by computer software:

  • Each piece of software works with a character set. A character set is a set of symbols, including letters, digits, spaces, and other symbols.

  • To handle these characters, each piece of software employs a character set encoding, in which each character is mapped onto one or more bytes of information, typically represented as hexadecimal numbers. This encoding is also called a code page.

  • Database servers, which sort characters (for example, list names alphabetically), use a collation. A collation is a combination of a character encoding (a map between characters and hexadecimal numbers) and a sort order for the characters. There may be more than one sort order for each character set; for example, a case sensitive order and a case insensitive order, or two languages may sort characters in a different order.

  • Characters are printed or displayed on a screen using a font, which is a mapping between characters in the character set and its appearance. Fonts are handled by the operating system.

  • Operating systems also use a keyboard mapping to map keys or key combinations on the keyboard to characters in the character set.


Language issues in client/server computing

Database users working at client applications may see or access strings from the following sources:

  • Data in the database Strings and other text data are stored in the database. The database server processes these strings when responding to requests.

    For example, the database server may be asked to supply all the last names beginning with a letter ordered less than N in a table. This request requires string comparisons to be carried out, and assumes a character set ordering.

    The database server receives strings from client applications as streams of bytes. It associates these bytes with characters according to the database character set. If the data is held in an indexed column, the index is sorted according to the sort order of the collation.

  • Database server software messages Applications can cause database errors to be generated. For example, an application may submit a query that references a column that does not exist. In this case, the database server returns a warning or error message. This message is held in a language resource library, which is a DLL or shared library called by Adaptive Server Anywhere.

  • Client application The client application interface displays text, and internally the client application may process text.

  • Client software messages The client library uses the same language library as the database server to provide messages to the client application.

  • Operating system The client operating system has text displayed on its interface, and may also process text.

For a satisfactory working environment, all these sources of text must work together. Loosely speaking, they must all be working in the user's language and/or character set.


Code pages

Many languages have few enough characters to be represented in a single-byte character set. In such a character set, each character is represented by a single byte: a two-digit hexadecimal number.

At most, 256 characters can be represented in a single byte. No single-byte character set can hold all of the characters used internationally, including accented characters. This problem was addressed by the development of a set of code pages, each of which describes a set of characters appropriate for one or more national languages. For example, code page 1253 contains the Greek character set, and code page 1252 contains an international character set suitable for representing many characters in a variety of languages. There are many code pages, and many names for code pages. The above examples are code pages for Microsoft Windows.

Upper and lower pages

With few exceptions, characters 0 to 127 are the same for all the single-byte code pages. The mapping for this range of characters is called the ASCII character set. It includes the English language alphabet in upper and lower case, as well as common punctuation symbols and the digits. This range is often called the seven-bit range (because only seven bits are needed to represent the numbers up to 127) or the lower page. The characters from 128 to 255 are called extended characters, or upper code-page characters, and vary from code page to code page.

Problems with code page compatibility are rare if the only characters used are from the English alphabet, as these are represented in the ASCII portion of each code page (0 to 127). However, if other characters are used, as is generally the case in any non-English environment, there can be problems if the database and the application use different code pages.

Example

Suppose a database holding French language strings uses code page 850, and the client operating system uses code page 437. The character À (upper case A grave) is held in the database as character \xB7 (decimal value 183). In code page 437, character \xB7 is a graphical character. The client application receives this byte and the operating system displays it on the screen, the user sees a graphical character instead of an A grave.

ANSI and OEM code pages in Windows


ANSI and OEM code pages in Windows

For PC users, the issue is complicated because there are at least two code pages in use on most PCs. Applications using the Windows graphical user interface use the Windows code pages. These code pages are compatible with ISO character sets, and also with ANSI character sets. They are often referred to as ANSI code pages.

Character-mode applications (those using the console or command prompt window) in Windows 95/98/Me and Windows NT/200/XP, use code pages that were used in DOS. These are called OEM code pages (Original Equipment Manufacturer) for historical reasons.

Adaptive Server Anywhere supports collations based on both OEM and ANSI code pages.

Example

Consider the following situation:

  • A PC is running a Windows operating system with ANSI code page 1252.

  • The code page for character-mode applications is OEM code page 437.

  • Text is held in a database created using the collation UTF8.

An upper case A grave in the database is stored as hex byes C380. In a Windows application, the same character is represented as hex CO. In a DOS application, it is represented as hex B7.

Adaptive Server Anywhere provides character set conversion to handle these differences in representation.

For more information about choosing a collation for your database, see Understanding collations.


Multibyte character sets

Some languages, such as Japanese and Chinese, have many more than 256 characters. These characters cannot all be represented using a single byte, but can be represented in multibyte character sets. In addition, some character sets use the much larger number of characters available in a multibyte representation to represent characters from many languages in a single, more comprehensive, character set.

Multibyte character sets are of two types. Some are variable width, in which some characters are single-byte characters, others are double-byte, and so on. Other sets are fixed width, in which all characters in the set have the same number of bytes.

For more information on the multibyte character sets, see Using multibyte collations.

Example

As an example, characters in the Shift-JIS character set are either one or two bytes in length. If the value of the first byte is in the range of hexadecimal values from \x81 to \x9F or from \xE0 to \xEF (decimal values 129-159 or 224-239) the character is a two-byte character and the subsequent byte (called a follow byte) completes the character. A follow byte is any byte(s) other than the first byte.

If the first byte is outside this range, the character is a single-byte character and the next byte is the first byte of the following character.

  • The properties of any Shift-JIS character can be read from its first byte also. Characters with a first byte in the range \x09 to \x0D, or \x20 are space characters.

  • Characters in the ranges \x41 to \x5A, \x61 to \x7A, \x81 to \x9F or \xE0 to \xEF are considered to be alphabetic (letters).

  • Characters in the range \x30 to \x39 are digits.


Sorting characters using collations

The database collation sequence includes the notion of alphabetic ordering of letters, and extends it to include all characters in the character set, including digits and space characters.

Associating more than one character with each sort position

More than one character can be associated with each sort position. This is useful if you wish, for example, to treat an accented character the same as the character without an accent.

Two characters with the same sort position are considered identical in all ways by the database. Therefore, if a collation assigns the characters a and e to the same sort position, then a query with the following search condition:

WHERE col1 = 'want'

is satisfied by a row for which col1 contains the entry went.

At each sort position, lower case and upper case forms of a character can be indicated. For case sensitive databases, the lower case and upper case characters are not treated as equivalent. For case insensitive databases, the lower case and upper case versions of the character are considered equivalent.

First-byte collation orderings for multibyte character sets


First-byte collation orderings for multibyte character sets

A sorting order for characters in a multibyte character set can be specified only for the first byte. Characters that have the same first byte are sorted according to the hexadecimal value of the following bytes.


International aspects of case sensitivity

Adaptive Server Anywhere is always case preserving and case insensitive for identifiers, such as table names and column names. This means that the names are stored in the case in which they are created, but any access to the identifiers is done in a case insensitive manner.

For example, the names of the system tables are stored in upper case (SYSDOMAIN, SYSTABLE, and so on), but access is case insensitive, so that the two following statements are equivalent:

SELECT *
FROM systable

SELECT *
FROM SYSTABLE

The equivalence of upper and lower case characters is defined in the collation. There are some collations where particular care is required when assuming case insensitivity of identifiers. In particular, Turkish collations have a case-conversion behavior that can cause unexpected and subtle errors. The most common error is that a system object containing a letter I or I is not found.

Turkish character sets and collations


Turkish character sets and collations

The Turkish language has two forms of what appears to be the letter I. One form, referred to as I-dot, appears as the following:

Uppercase I-dot and lowercase I-dot.

The second form, referred to as I-no-dot, appears as the following:

Uppercase I-no-dot and lowercase I-no-dot.

Even though these letters appear as variations of the same letter, in the Turkish alphabet they are considered to be distinct letters.

Turkish rules for case conversion of these characters are incompatible with ANSI SQL standard rules for case conversion. For example, Turkish says that the lower-case equivalent of I is

while ANSI says that it is

I

For this reason, correct case-insensitive matching is dependent on whether or not the text being matched is Turkish or English/ANSI. In many contexts, there is not enough information to make such a distinction, which leads to some non-standard behaviors in such databases.

For example, consider the statements:

SELECT statements where the first table name uses I-no-dot and the other uses I-dot.

The first statement references a system object and must use ANSI SQL rules to match the name, while the second statement references a user object and must use the Turkish rules.

However, there is no context that the database server can use to determine which rules to use until after the object is found. So, to find the object, the case conversion rules must be known. To know the rules, the object must be found. The situation cannot be resolved properly for both system and user objects.

In this instance, Adaptive Server Anywhere uses the Turkish rules. The first statement will fail, while the second statement will succeed.

The incompatibility of Turkish and ANSI standards requires that system object references in Turkish databases specify the object name in the correct case, that is, the case used to create the object. The first statement above should be written as

SELECT * FROM SYSINFO

In fact, only the letter I must be in the correct case.

As an alternative, it is acceptable, although unusual, to write the statement as

SELECT statement using lower-case I-no-dot.

Note that keywords, such as INSERT, are case-insensitive even in Turkish databases. Adaptive Server Anywhere knows that all keywords use only English letters, so it uses ANSI case conversion rules when matching keywords. Adaptive Server Anywhere also applies this knowledge for certain other identifiers, such as built-in functions. However, objects whose names are stored in the catalog must be specified using the correct case or letter, as described above.


Data in case-insensitive Turkish databases

Similar rules govern data in case-insensitive Turkish databases. For example if a data value is

The word fig written with uppercase I-no-dot.

then a lower-case reference to that data should be

fig

so that the same I-dot character is used in both forms.


Alternative Turkish collation 1254TRKALT

For some application developers, the Turkish letter I problem can cause significant problems. While the correct solution is to ensure that all object references are in the proper case or that the proper form of the letter I is used, in some cases it may be more expedient to make a decision to violate the Turkish rules in favor of the ANSI rules.

In earlier versions of Adaptive Server Anywhere, this could be done by creating a custom collation and making I-dot and I-no-dot equivalent characters. Adaptive Server Anywhere provides the collation 1254TRKALT, which is identical to 1254TRK, except that it makes I-dot and I-no-dot equivalent characters.

It is important to understand the consequences of this change. In a 1254TRKALT database, the following strings are equal:

The word Fig written with lowercase I-dot and I-no-dot.

This is not correct for a Turkish user, but may be acceptable in some cases.

The second issue appears when using ORDER BY. Consider the following strings:

Strings in the order I-dot a, I-no-dot a, I-no-dot s, and I-dot s.

In a 1254TRK database, an ORDER BY of the strings would produce the following:

Strings sorted in the order I-no-dot a, I-no-dot s, I-dot a, I-dot s.

because I-no-dot is less than I-dot. In a 1254TRKALT database, the order would be

The strings sorted in the order: I-dot a, I-no-dot a, I-no-dot s, I-dot s.

because I-no-dot is equal to I-dot.


Understanding locales

Both the database server and the client library recognize their language and character set environment using a locale definition.


Introduction to locales

The application locale, or client locale, is used by the client library when making requests to the database server, to determine the character set in which results should be returned. If character set translation is enabled (the default), the database server compares its own locale with the application locale to determine whether character set translation is needed. Different databases on a server may have different locale definitions.

The locale consists of the following components:

  • Language The language is a two-character string using the ISO-639 standard values: DE for German, FR for French, and so on. Both the database server and the client have language values for their locale.

    The database server uses the locale language to determine the following behavior:

    • Which language library to load.

    • The language is used together with the character set to determine which collation to use when creating databases, if no collation is explicitly specified.

    The client library uses the locale language to determine the following behavior:

    • Which language library to load.

    • Which language to request from the database.

      For more information, see Understanding the locale language.

  • Character set The character set is the code page in use. The client and server both have character set values, and they may differ. If they differ, character set translation may be required to enable interoperability.

    For machines that use both OEM and ANSI code pages, the ANSI code page is the value used here.

    For more information, see Understanding the locale character set.


Understanding the locale language

The locale language is an indicator of the language being used by the user of the client application, or expected to be used by users of the database server.

For more information about how to find locale settings, see Determining locale information.

The client library determines the language component of the locale as follows:

  1. On Windows, it checks the Adaptive Server Anywhere language registry entry, as described in Registry settings on installation.

  2. On other operating systems, or if the registry setting is not present, it checks the operating system language setting.

The database server determines the language component of the locale as follows:

  1. It checks the ASLANG environment variable, if it exists.

    For more information, see ASLANG environment variable.

  2. On Windows, it checks the Adaptive Server Anywhere language registry entry, as described in Registry settings on installation.

  3. Queries the operating system.

  4. If the language cannot be determined by the above settings, it defaults to English.

Language label values

The following table displays the valid language label values, together with the equivalent ISO 639 labels:

Language label | Alternative label | ISO_639 language code
chinese | simpchin | ZH
czech | N/A | CS
danish | N/A | DA
dutch | N/A | NL
finnish | N/A | FI
french | N/A | FR
german | N/A | DE
greek | N/A | EL
hebrew | N/A | HE
hungarian | N/A | HU
italian | N/A | IT
japanese | N/A | JA
korean | N/A | KO
lithuanian | N/A | LT
norwegian | norweg | NO
polish | N/A | PL
portuguese | portugue | PT
russian | N/A | RU
spanish | N/A | ES
swedish | N/A | SV
tchinese | tradchin | TW
turkish | N/A | TR
ukrainian | N/A | UK
us_english | english | EN


Understanding the locale character set

Both application and server locale definitions have a character set. The application uses its character set when requesting character strings from the server. If character set translation is enabled (the default), the database server compares its character set with that of the application to determine whether character set translation is needed.

For more information about how to find locale settings, see Determining locale information.

The client library determines the character set as follows:

  1. If the connection string specifies a character set, it is used.

    For more information, see CharSet connection parameter [CS].

  2. Open Client applications check the locales.dat file in the Sybase locales directory.

  3. Character set information from the operating system is used to determine the locale:

    • On Windows operating systems, Windows ANSI character set.

    • On UNIX, default to ISO8859-1.

    • On other platforms, use code page 1252.

The database server determines the character set for a connection as follows:

  1. The character set specified by the client is used if it is supported.

    For more information, see CharSet connection parameter [CS].

  2. The database's character set is used if the client specifies a character set that is not supported.


Understanding collations

This section describes the supplied collations, and provides suggestions as to which collations to use under certain circumstances.

For more information about how to create a database with a specific collation, see Creating a database with a named collation and The Initialization utility.

For information on changing a database from one collation to another, see Changing a database from one collation to another.

Choosing collations
Supplied and recommended collations
Alternate collations
Creating databases for Windows CE
Notes on ANSI collations
Using multibyte collations


Choosing collations

When you create a database, Adaptive Server Anywhere chooses a default collation based on operating system language and character set settings. In most cases, the default collation is a suitable choice, but you can also explicitly choose a collation to match your needs from the wide selection of supplied collations.

In some cases, Adaptive Server Anywhere supports more than one collation for a particular language. Different collations vary in the characters they include and in the way they sort special characters, including ligatures (characters consisting of two or more characters joined together) and accented characters. You should choose a collation that uses a character set and sort order that are appropriate for the data in your database.

For more information about sorting of data and international features, see Adaptive Server Anywhere international features.

How Adaptive Server Anywhere chooses the collation for a new database

When a new database is created, and the collation is not explicitly specified, then Adaptive Server Anywhere uses the language and character set to determine the collation.

  • The language comes from the ASLANG environment variable (if it exists) or the operating system.

  • The character set comes from the ASCHARSET environment variable (if it exists) or the operating system.

Last resort collation
If Adaptive Server Anywhere cannot locate a specific collation based on your operating system's character set and language, the Adaptive Server Anywhere registry setting, or the ASCHARSET environment variable, ISO_BINENG becomes the default, regardless of which operating system you are using.

If this is not suitable for your requirements, you can rebuild the database and choose a different collation.

For more information about changing collations, see Changing a database from one collation to another.

For information about creating a database with a specific collation, see Creating a database with a named collation.


Supplied and recommended collations

The following collations are supplied with Adaptive Server Anywhere. You can obtain the list of main collations by typing the following command at the command prompt:

dbinit -l
Collation label | Description
874THAIBIN | Code Page 874, Windows Thai
932JPN | Code Page 932, Japanese Shift-JIS with Microsoft extensions
936ZHO | Code Page 936, Simplified Chinese, PRC GBK 2312-80 8-bit encoding
949KOR | Code Page 949, Korean KS C 5601-1987 encoding, Wansung
950ZHO_HK | Code Page 950, Traditional Chinese, Big 5 encoding with HKSCS
950ZHO_TW | Code Page 950, Traditional Chinese, Big 5 encoding
1250LATIN2 | Code Page 1250, Windows Latin 2, Central/Eastern European
1250POL | Code Page 1250, Windows Latin 2, Polish
1251CYR | Code Page 1251, Cyrillic
1252LATIN1 | Code Page 1252, Windows Latin 1, Western
1252SPA | Code Page 1252, Windows Latin 1, Spanish
1252SWEFIN | Code Page 1252, Windows Latin 1, Swedish/Finnish
1253ELL | Code Page 1253, Windows Greek, ISO8859-7 with extensions
1254TRK | Code Page 1254, Windows Latin 5, Turkish, ISO 8859-9 with extensions
1255HEB | Code Page 1255, Windows Hebrew, ISO8859-8 with extensions
1256ARA | Code Page 1256, Windows Arabic, ISO8859-6 with extensions
1257LIT | Code Page 1257, Lithuanian
EUC_JAPAN | Japanese EUC JIS X 0208-1990 and JIS X 0212-1990 Encoding
EUC_CHINA | Simplified Chinese GB 2312-80 Encoding
EUC_TAIWAN | Taiwanese Big 5 Encoding
EUC_KOREA | Korean KS C 5601-1992 Encoding, Johab
ISO_1 | ISO8859-1, Latin 1, Western
ISO_BINENG | Binary ordering, English ISO/ASCII 7-bit letter case mappings
ISO1LATIN1 | ISO8859-1, ISO Latin 1, Western, Latin 1 Ordering
ISO9LATIN1 | ISO8859-15, ISO Latin 9, Western, Latin 1 Ordering
UTF8 | Unicode Transformation Format-8, 8-bit multibyte encoding for Unicode

The following collations are recommended because they provide the most likely match to the character set being used by the application: they have an appropriate sort order and support for the symbols and accented characters required for each specific language. Some languages do not have a recommended UNIX collation.

Language | Windows collations | UNIX collations
Western European (including English, French, German, Italian, Portuguese, and Spanish) | 1252LATIN1 | ISO9LATIN1, ISO1LATIN1
Eastern European (including Croatian, Czech, Hungarian, Romanian, Serbian, Slovakian, and Slovenian) | 1250LATIN2 |
Arabic | 1256ARA |
Greek | 1253ELL |
Hebrew | 1255HEB |
Japanese | 932JPN | EUC_JAPAN
Korean | 949KOR | EUC_KOREA
Lithuanian | 1257LIT |
Polish | 1250POL |
Russian and Ukrainian | EUC_CHINA |
Simplified Chinese | 936ZHO | EUC_CHINA
Spanish | 1252SPA | ISOLATIN1, ISO9LATIN1
Thai | 874THAIBIN | 874THAIBIN
Traditional Chinese | 950ZHO_TW |
Traditional Chinese + HKSCS | 950ZHO_HK |
Turkish | 1254TRK |
Tip
Any code that selects a collation for German should select 1252LATIN1, not 1252DEU. 1252DEU differentiates between characters with and without an umlaut, while 1252LATIN1 does not. 1252LATIN1 considers Muller and Müller equal, but 1252DEU does not consider them equal. Because 1252DEU views characters with umlauts as separate characters, it has the following alphabetic ordering: ob, öa.

Previous Next


Alternate collations

Alternate collations are available for compatibility with older versions of Adaptive Server Anywhere, or for special purposes. You can obtain a list of alternate collations by typing the following command at the command prompt:

dbinit -l+

Specifying the -l+ option lists the following collations, in addition to the list of recommended collations:

Collation label | Type | Description
437LATIN1 | OEM | Code Page 437, Latin 1, Western
437ESP | OEM | Code Page 437, Spanish
437SVE | OEM | Code Page 437, Swedish/Finnish
819CYR | ANSI | Code Page 819, Cyrillic
819DAN | ANSI | Code Page 819, Danish
819ELL | ANSI | Code Page 819, Greek
819ESP | ANSI | Code Page 819, Spanish
819ISL | ANSI | Code Page 819, Icelandic
819LATIN1 | ANSI | Code Page 819, Latin 1, Western
819LATIN2 | ANSI | Code Page 819, Latin 2, Central/Eastern European
819NOR | ANSI | Code Page 819, Norwegian
819RUS | ANSI | Code Page 819, Russian
819SVE | ANSI | Code Page 819, Swedish/Finnish
819TRK | ANSI | Code Page 819, Turkish
850CYR | OEM | Code Page 850, Cyrillic, Western
850DAN | OEM | Code Page 850, Danish
850ELL | OEM | Code Page 850, Greek
850ESP | OEM | Code Page 850, Spanish
850ISL | OEM | Code Page 850, Icelandic
850LATIN1 | OEM | Code Page 850, Latin 1, Western
850LATIN2 | OEM | Code Page 850, Latin 2, Central/Eastern European
850NOR | OEM | Code Page 850, Norwegian
850RUS | OEM | Code Page 850, Russian
850SVE | OEM | Code Page 850, Swedish/Finnish
850TRK | OEM | Code Page 850, Turkish
852LATIN2 | OEM | Code Page 852, Latin 2, Central/Eastern European
852CYR | OEM | Code Page 852, Cyrillic
852POL | OEM | Code Page 852, Polish
855CYR | OEM | Code Page 855, Cyrillic
856HEB | OEM | Code Page 856, Hebrew
857TRK | OEM | Code Page 857, Turkish
860LATIN1 | OEM | Code Page 860, Latin 1, Western
861ISL | OEM | Code Page 861, Icelandic
862HEB | OEM | Code Page 862, Hebrew
863LATIN1 | OEM | Code Page 863, Latin 1, Western
865NOR | OEM | Code Page 865, Norwegian
866RUS | OEM | Code Page 866, Russian
869ELL | OEM | Code Page 869, Greek
920TRK | ANSI | Code Page 920, Turkish, ISO-8859-9
1252DEU | ANSI | Code Page 1251, Windows Specialty German, Umlaut characters not equal
1254TRKALT | ANSI | Code Page 1254, Windows Specialty Turkish, I-dot and I-no-dot are equal For more information, see Turkish character sets and collations.


Creating databases for Windows CE

Windows CE is a Unicode-based operating system. The Adaptive Server Anywhere ODBC driver supports either ASCII (8-bit) or Unicode strings, and carries out character set translation as needed. If you are developing embedded SQL applications, you can use Windows API functions to get the Unicode versions of strings from the database.

When creating databases for Windows CE, you should use a collation based on the same single- or multibyte character set that Windows would use for the language of interest. For example, if you are using English, French, or German, use the 1252Latin1 collation. If you are using Japanese, use the 932JPN collation, and if you are using Korean, use the 949KOR collation.


Notes on ANSI collations

The ISO_1 collation

ISO_1 is provided for compatibility with the Adaptive Server Enterprise default ISO_1 collation. The differences are as follows:

  • The lower case letter sharp s (\xDF) sorts with the lower case s in Adaptive Server Anywhere, but after ss in Adaptive Server Enterprise.

  • The ligatures corresponding to AE and ae (\xC6 and \xE6) sort after A and a respectively in Adaptive Server Anywhere, but after AE and ae in Adaptive Server Enterprise.

The 1252LATIN1 collation

This collation includes the euro currency symbol and several other characters (Z-with-caron and z-with-caron). This collation is recommended for Windows users using English or Western European languages.

The euro symbol sorts with the other currency symbols.

The ISO1LATIN1 collation

This collation is the same as ISO_1, but with sorting for values in the range A0-BF. For compatibility with Adaptive Server Enterprise, the ISO_1 collation has no characters for 0xA0-0xBF. However the ISO Latin 1 character set on which it is based does have characters in these positions. The ISO1LATIN1 collation reflects the characters in these positions.

If you are not concerned with Adaptive Server Enterprise compatibility, ISO1LATIN1 is generally recommended instead of ISO_1.

ISO1LATIN1 is recommended for UNIX users using English or Western European languages.

The ISO9LATIN1 collation

This collation is the same as ISO1LATIN1, but it includes the euro currency symbol and the other new characters included in the 1252LATIN1 collation.

If your machine uses the ISO Latin 9 character set, then you should use this collation.


Using multibyte collations

This section describes how multibyte character sets are handled. The description applies to the supported collations and to any multibyte custom collations you may create.

Adaptive Server Anywhere provides collations for several multibyte character sets.

For more information, see Understanding collations.

Adaptive Server Anywhere supports variable width 8-bit character sets. In these sets, some characters are represented by one byte, and some by more than one, to a maximum of four bytes. The value of the first byte in any character indicates the number of bytes used for that character, and also indicates whether the character is a space character, a digit, or an alphabetic (alpha) character.

For the UTF8 collation, UTF-8 characters are represented by one to four bytes. For other multibyte collations, one or two bytes are used. For all provided multibyte collations, characters comprising two or more bytes are considered to be "alphabetic", such that they can be used in identifiers without requiring double quotes.

All client libraries other than embedded SQL are Unicode-enabled, using the UTF-16 encoding. Translation occurs between the client and the server.


Understanding character set translation

Adaptive Server Anywhere can carry out character set translation among character sets that represent the same characters, but at different positions in the character set or code page. There needs to be a degree of compatibility between the character sets for this to be possible. For example, character set translation is possible between EUC-JIS and Shift-JIS character sets, but not between EUC-JIS and OEM code page 850.

This section describes how Adaptive Server Anywhere carries out character set translation. This information is provided for advanced users, such as those who may be deploying applications or databases in a multi-character-set environment.


Character translation for database messages

Error and other messages from the database software are held in a language resource library. Localized versions of this library are provided with localized versions of Adaptive Server Anywhere.

Client application users may see messages from the database, as well as data from the database.

Messages are always translated into the database character set, regardless of whether character set translation is turned on or off.

A further character set translation is carried out if character set translation is turned on (the default) for the database server, and if the client character set is different from that used in the database collation.


Connection strings and character sets

Connection strings present a special case for character set translation. The connection string is parsed by the client library, in order to locate or start a database server. This parsing is done with no knowledge of the server character set or language.

The interface library parses the connection string as follows:

  1. It is broken down into its keyword=value components. This can be done independently of the character set, as long as you do not use curly braces {} around CommLinks (LINKS) connection parameters. Instead, use the recommended parentheses (). Curly braces are valid follow bytes (bytes other than the first byte) in some multibyte character sets.

  2. The server is located. The server name is interpreted according to the character set of the client machine. In the case of Windows operating systems, the ANSI character set is used. Extended chars can be used unless they cause character set conversion issues between the client and server machines.

    For maximum compatibility among different machines, you should use server names built from alphabetic or numeric ASCII characters 0 to 127 (or 33 to 126) and the underscore, using no punctuation characters. Server names are truncated at 40 characters.

  3. The DatabaseName (DBN) or DatabaseFile (DBF) connection parameters are interpreted in the database server character set.

  4. Once the database is located, the remaining connection parameters are interpreted converted to the database's character set.


Avoiding character set translation

There is a performance cost associated with character set translation. If you can set up an environment such that no character set translation is required, then you do not have to pay this cost, and your setup is simpler to maintain. Adaptive Server Anywhere disables character set conversion if the client's character set is the same as the server's character set.

If you work with a single-byte character set and are concerned only with seven-bit ASCII characters (values 0 through 127), then you do not need character set translation. Even if the code pages are different in the database and on the client operating system, they are compatible over this range of characters. Many English-language installations meet these requirements. In Adaptive Server Anywhere 9.0 and later, character set translation is turned on by default. You can turn it off using the -ct- option.

For more information, see Turning off character set translation on a database server.

If you do require the use of extended characters, there are other steps you may be able to take:

  • If the code page on your client machine operating system matches that used in the database, no character set translation is needed for data in the database.

    For example, in many environments it is appropriate to use the 1252LATIN1 collation in your database, which corresponds to the ANSI code page in many single-byte environments.

  • If you are able to use a version of Adaptive Server Anywhere built for your language, and if you use the code page on your operating system, no character set translation is needed for database messages. The character set used in the Adaptive Server Anywhere message strings is as follows:

    Language | Windows character set
    English | cp1252
    French | cp1252
    German | cp1252
    Italian | cp1252
    Japanese | cp932 (Shift-JIS)
    Korean | cp949
    Lithuanian | cp1257
    Polish | cp1250
    Portuguese | cp1252
    Russian | cp1251
    Simplified Chinese | cp936
    Spanish | cp1252
    Traditional Chinese | cp950
    Ukrainian | cp1251

Also, recall that client/server character set translation takes place by default. You can turn it off using the -ct- option.

For more information, see -ct server option.


Collation internals

This section describes internal technical details of collations, including the file format of collation files.

This section is of particular use if you want to create a database using a custom collation. The file format described in this section is used for viewing or editing a collation. The file is then converted into a format that can be used by the database server.

For information on the steps involved, see Creating a custom collation, and Creating a database with a custom collation.

You can create a database using a collation different from the supplied collations. This section describes how to build databases using such custom collations.

In building multibyte custom collations, you can specify which ranges of values for the first byte signify single- and double-byte (or more) characters, and which specify space, alpha, and digit characters.

Collation files may include the following elements:

  • comment lines, which are ignored by the database.

  • a title line.

  • a Collation section.

  • an Encodings section.

  • a Properties section.


Web Links Browse Collapse Expand PDF Previous Next

ASA Database Administration Guide

International Languages and Character Sets

Collation internals

Comment lines

In the collation file, spaces are generally ignored. Comment lines start with either the percent sign (%) or two dashes (–).


The title line

The first non-comment line must be of the form:

Collation collation_label (collation_name) (ase_charset) (ase_so_sensitive) (ase_so_insensitive) (java_charset)

Argument descriptions
Argument | Description
Collation | A required keyword.
collation_label | The collation label, which appears in the system tables as SYS.SYSCOLLATION.collation_label and SYS.SYSINFO.default_collation. The label must contain no more than 10 characters.
collation_name | A text description of the collation, usually describing the character set and ordering of the collation.
ase_charset | The Adaptive Server Enterprise name of a character set matching the character set of this collation. This name is used to make character set mappings when server character set translation is enabled (the default).
ase_so_sensitive | The name of an Open Client or Adaptive Server Enterprise case sensitive collation matching this collation.
ase_so_insensitive | The name of an Open Client or Adaptive Server Enterprise case insensitive collation matching this collation.
java_charset | The name of a Java character set matching the character set of this collation. This name is used when converting character data between the Java virtual machine and the database.

For example, the 932JPN collation file contains the following collation line, with label 932JPN and name Code Page 932, Japanese Shift-JIS with Microsoft extensions:

Collation 932JPN (Code Page 932, Japanese Shift-JIS with Microsoft extensions) (cp932) (bin_cp932) (bin_cp932) (SJIS)


The Collation section

After the title line, each non-comment line describes one position in the collation. The ordering of the lines determines the sort ordering used by the database, and determines the result of comparisons. Characters on lines appearing higher in the file (closer to the beginning) sort before characters that appear later.

The form of each line in the sequence is:

[sort-position] : character [ [, character ] ...]

or

[sort-position] : character [lowercase uppercase]

Argument descriptions
Argument | Description
sort-position | Optional. Specifies the position at which the characters on that line will sort. Smaller numbers represent a lesser value, so will sort closer to the beginning of the sorted set. Typically, the sort-position is omitted, and the characters sort immediately following the characters from the previous sort position.
character | The character whose sort-position is being specified.
lowercase | Optional. Specifies the lower case equivalent of the character. If not specified, the character has no lower case equivalent.
uppercase | Optional. Specifies the upper case equivalent of the character. If not specified, the character has no upper case equivalent.

Multiple characters may appear on one line, separated by commas (,). In this case, these characters are sorted and compared as if they were the same character.

Specifying character and sort position

Each character and sort position is specified in one of the following ways:

Specification | Description
\d nnn | Decimal number, using digits 0-9 (such as \d001)
\x hh | Hexadecimal number, using digits 0-9 and letters a-f or A-F (such as \xB4)
'c' | Any character in place of c (such as ',')
c | Any character other than quote ('), back-slash (\), colon (:) or comma (,). These characters must use one of the previous forms.

The following are some sample lines for a collation:

% Sort some special characters at the beginning:
: ' '
: _
: \xF2
: \xEE
: \xF0
: -
: ','
: ;
: ':'
: !
% Sort some letters in alphabetical order
: A a A
: a a A
: B b B
: b b B
% Sort some E's from code page 850,
% including some accented extended characters:
: e e E, \x82 \x82 \x90, \x8A \x8A \xD4
: E e E, \x90 \x82 \x90, \xD4 \x8A \xD4
Other syntax notes

For databases using case insensitive sorting and comparison (no -c specified in the dbinit command), the lower case and upper case mappings are used to find the lower case and upper case characters that are sorted together.

For multibyte character sets, the first byte of a character is listed in the collation sequence, and all characters with the same first byte are sorted together, and ordered according to the value of the following bytes. For example, the following is part of the Shift-JIS collation file:

: \xfb
:  \xfc
:  \xfd

In this collation, all characters with first byte \xfc come after all characters with first byte \xfb and before all characters with first byte \xfd. The two-byte character \xfc \x01 would be ordered before the two-byte character \xfc \x02.

Any characters omitted from the collation are added to the end of the collation. The tool that processes the collation file issues a warning.


The Encodings section

The encodings section is optional, and follows the collation sequence. It is not useful for single-byte character sets.

The encodings section lists which byte values are lead-bytes, for multibyte character sets, and which byte values are valid follow-bytes.

For example, the Shift-JIS encodings section is as follows:

Encodings:
[\x00-\x80,\xa0-\xdf,\xf0-\xff]
[\x81-\x9f,\xe0-\xef][\x40-\xff]

The first line following the section title lists valid single-byte characters. The square brackets enclose a comma-separated list of ranges. Each range is listed as a hyphen-separated pair of values. In the Shift-JIS collation, values \x00 to \x80 are valid single-byte characters, but \x81 is not a valid single-byte character.

The second line following the section title lists valid multibyte characters. The brackets represent ranges. Any combination of one byte from the first range followed by one byte from the second range may be a valid character.


The Properties section

The properties section is optional, and follows the encodings section.

If a properties section is supplied, an encodings section must also be supplied.

The properties section lists values for the first byte of each character that represent alphabetic characters, digits, or spaces.

The Shift-JIS properties section is as follows:

Properties:
space: [\x09-\x0d,\x20]
digit: [\x30-\x39]
alpha: [\x41-\x5a,\x61-\x7a,\x81-\x9f,\xe0-\xef]

This indicates that characters with first bytes \x09 to \x0d, as well as \x20, are to be treated as space characters, digits are found in the range \x30 to \x39 inclusive, and alphabetic characters in the four ranges \x41-\x5a, \x61-\x7a, \x81-\x9f, and \xe0-\xef.


International language and character set tasks

This section groups together the tasks associated with international language and character set issues.

Finding the default collation
Configuring your character set environment
Determining locale information
Setting locales
Creating a database with a named collation
Starting a database server using character set translation
Turning off character set translation on a database server
Creating a custom collation
Creating a database with a custom collation
Changing a database from one collation to another


Finding the default collation

If you do not explicitly specify a collation when creating a database, a default collation is used. The default collation depends on the operating system you are working on.

toggle To find the default collation for your machine

  1. Start Interactive SQL. Connect to the sample database.

  2. Enter the following query:

    SELECT PROPERTY( 'DefaultCollation' )

    The default collation is returned.

    For more information about this collation, see Choosing collations.


Configuring your character set environment

This section describes how to set up your computing environment so that character set issues are handled properly. If you set your locale environments properly, then you do not need to explicitly choose collations for your databases, and you can disable character set translation between client and server.

For more information about turning off character set translation, see Turning off character set translation on a database server.

toggle To configure your character set environment

  1. Determine the default locale of each computing platform in your environment. The default locale is the character set and language of each computer. On Windows operating systems, the character set is the ANSI code page.

    For more information about how to find locale information, see Determining locale information.

  2. Decide whether the locale settings are appropriate for your environment.

    For more information, see Understanding collations.

  3. If the default settings are inappropriate, decide on a character set, language, and database collation that match your data and avoid character set translation.

    For more information, see Avoiding character set translation.

  4. Set locales on each of the machines in the environment to these values.

    For more information, see Setting locales.

  5. Create your database using the default collation. If the default collation does not match your needs, create a database using a named collation.

    For more information, see Creating a database with a named collation, and Changing a database from one collation to another.

When choosing the collation for your database, consider the following:

  • Choose a collation that uses a character set and sort order appropriate for the data in the database. It is often the case that there are several alternative collations that meet this requirement.

  • There is a performance cost, as well as extra complexity in system configuration, when you use character set translation. Choose a collation that avoids the need for character set translation. Character set translation is disabled automatically if the database server and client use the same character set.

    You can avoid character set translation by using a collation sequence in the database that matches the character set in use on your client machine operating system. In the case of Windows operating systems on the client machine, choose the ANSI character set. Character set translation is enabled by default for database servers that are version 8.0 or higher of Adaptive Server Anywhere. You can turn off character set translation using the -ct- option.

    For more information, see Avoiding character set translation.


Determining locale information

You can determine locale information using system functions.

For more information, see System functions.

toggle To determine the locale of a database server

  1. Start Interactive SQL, and connect to a database server.

  2. Execute the following statement to determine the database server character set:

    SELECT PROPERTY( 'CharSet' )

    The query returns one of the supported character sets listed in Character set labels.

  3. Execute the following statement to determine the database server language:

    SELECT PROPERTY( 'Language' )

    The query returns one of the supported languages listed in Language label values.

  4. Execute the following statement to determine the database server default collation:

    SELECT PROPERTY( 'DefaultCollation' )

    The query returns one of the collations listed in Choosing collations.

Notes

To obtain client locale information, connect to a database server running on the client machine.

To obtain the character set for an individual database, execute the following statement:

SELECT DB_PROPERTY ( 'CharSet' )


Setting locales

You can use the default locale on your operating system, or explicitly set a locale for use by the Adaptive Server Anywhere components on your machine.

toggle To set the Adaptive Server Anywhere locale

  1. If the default locale is appropriate for your needs, you do not need to take any action.

    For more information about how to find out the default locale of your operating system, see Determining locale information.

  2. If you need to change the locale, you can set either or both of the ASLANG and ASCHARSET environment variables:

    ASCHARSET=charset;
ASLANG=language_code

    where charset is a character set label from the list in Character set labels, and language_code is a language label from the list in Language label values

    For more information on how to set environment variables on different operating systems, see Setting environment variables.


Creating a database with a named collation

You may specify the collation for each database when you create the database. The default collation is inferred from the code page and language of the database server's computer's operating system.

toggle To specify a database collation when creating a database (Sybase Central)

  • You can use the Create Database wizard in Sybase Central to create a database. The wizard has a page where you choose a collation from a list.

    Create Database wizard, showing the page where you choose the collation sequence for a new database.
toggle To specify a database collation when creating a database (command prompt)

  1. List the recommended collation sequences by typing the following at a command prompt:

    dbinit -l

    The first column of the list is the collation label, which you supply when creating the database.

    437LATIN1  Code Page 437, Latin 1, Western
437ESP     Code Page 437, Spanish
437SVE     Code Page 437, Swedish/Finnish
819CYR     Code Page 819, Cyrillic
819DAN     Code Page 819, Danish
...

  2. Create a database using the dbinit utility, specifying a collation sequence using the -z option. The following command creates a database with a Greek collation.

    dbinit -z 1253ELL mydb.db
toggle To specify a database collation when creating a database (SQL)

  • You can use the CREATE DATABASE statement to create a database. The following statement creates a database with a Greek collation:

    CREATE DATABASE 'mydb.db'
COLLATION '1253ELL'


Starting a database server using character set translation

Character set translation takes place if the client and server locales are different. Character set translation is enabled by default for database servers that are Adaptive Server Anywhere version 8.0 or higher. For database servers that are version 7.x or earlier, you must explicitly enable character set conversion in the database server command.

toggle To enable character set translation on a database server

  • Start the database server using the -ct+ option. For example:

    dbsrv9 -ct+ asademo.db


Turning off character set translation on a database server

Character set translation is enabled by default. If you do not require character set translation, you can disable it in the database server command using the -ct- option.

toggle To disable character set translation on a database server

  • Start the database server using the -ct- option. For example:

    dbsrv9 -ct- asademo.db

For more information, see -ct server option.


Creating a custom collation

If none of the supplied collations meet your needs, you can modify a supplied collation to create a custom collation. You can then use this custom collation when creating a database.

For more information about supplied collations, see Choosing collations.

toggle To create a custom collation

  1. Decide on a starting collation You should choose a collation as close as possible to the one you want to create as a starting point for your custom collation.

    For a listing of recommended collations, see Understanding collations.

    Alternatively, run dbinit with the -l (lower case L) option:

    dbinit -l

  2. Create a custom collation file You do this using the Collation [dbcollat] utility. The output is a collation file.

    For example, the following statement extracts the 1252LATIN1 collation into a file named mycustomcol.col:

    dbcollat -z 1252LATIN1 mycustomcol.col

  3. Edit the custom collation file Open the collation file (in this case mycustomcol.col) in a text editor.

  4. Change the collation label Make the changes you wish in the custom collation file to define the collation label. For example, if you wanted to make a custom version of the 1252LATIN1 collation, you could change the Collation line from:

    Collation 1252LATIN1 (Code Page 1252, Windows Latin 1, Western) (cp1252) (dictionary_iso_1) (nocase_iso_1) (Cp1252)

    to

    Collation MyOrdering (Code Page 1252, My Company Ordering) (cp1252) (dictionary_iso_1) (nocase_iso_1) (Cp1252)

    The other entries on this line relate the Adaptive Server Anywhere collation label to the names that Java and the Sybase TDS interface give to the same collation information. If you are not using these interfaces you do not need to alter these entries.

    The Collation line takes the following form:

    Collation collation_label (collation_name) (ase_charset) (ase_so_sensitive) (ase_so_insensitive) (java_charset)

    where character set label (ase_charset) and the two sort-order labels (ase_so_sensitive and ase_so_insensitive) state which Open Client character set and sort order is the closest to the current collation. The java_charset label is the closest character set known to Java.

    You should edit this line to provide a new label. The label you need to change is the collation_label: in the example in step two, it is 1252LATIN1.

  5. Change the collation definition Make the changes you wish in the custom collation file to define your new collation.

    For more information about the collation file contents and format, see Collation internals.

  6. Convert the file to a SQL script You do this using the dbcollat utility using the -d option.

    For example, the following command creates the mycustom.SQL file from the mycustomcol.col collation file:

    dbcollat -d mycustomcol.col mycustom.SQL

  7. Add the SQL script to the script in your installation The script used when creating databases is held in the scripts subdirectory of your Adaptive Server Anywhere installation directory. Append the contents of mycustom.SQL to the end of custom.SQL.

    The new collation is now in place, and can be used when creating a database.


Creating a database with a custom collation

If none of the supplied collations meet your needs, you can create a database using a custom collation. The custom collation is used in indexes and any string comparisons.

toggle To create a database with a custom collation

  1. Create a custom collation.

    You must have a custom collation in place to use when creating a database.

    For more information about how to create custom collations, see Creating a custom collation.

  2. Create the new database.

    Use the Initialization [dbinit] utility, specifying the name of your custom collation.

    For example, the following command creates a database named temp.db using the custom collation sequence newcol.

    dbinit -z newcol temp.db

    You can also use the Initialization utility from Sybase Central.


Changing a database from one collation to another

Changing your database from one collation to another may be a good idea for any number of reasons. It can be especially useful, for example, when:

  • you want to avoid character set translation across your setup.

  • the characters in your database don't match the collation in your database. Using the same character set defined in your database is especially important for sorting purposes.

  • you want to use a different character set. You may, for example, want to move from an OEM character set to a Windows character set.

Simply modifying the collation in an existing database is not permitted since it would invalidate all the indexes for that database. In order to change the collation for a database, you must rebuild the database. Rebuilding a database creates a new database with new settings (including collation settings), using the old database's data.

When you change the collation for a database, there are two main scenarios to consider. The difference between the two lies in whether the character set of the data needs to be changed.

Example 1

In the first example, the data in the database is in the wrong character set for the collation. Only the collation needs to be changed; the data should not change character sets. To resolve the collation issue, you need to rebuild the database with new collation settings using the old data.

In an English environment, consider an old database using the 850LATIN1 collation. If the database contains data inserted from a Windows 'windowed' application, it is likely that the data is actually from the CP1252 character set, which does not match CP850 used by the 850LATIN1 collation. This situation will often be discovered when an ORDER BY clause seems to sort accented characters incorrectly. To correct this problem, you would create a new database using the 1252LATIN1 collation, and move the data from the old database to the new database without translation, since the data is already in the character set (CP1252) that matches the new database's collation.

The simplest way to ensure that translation does not occur is to start the server with the -ct- option. Then, rebuild the database normally.

For more information about rebuilding a database, see Rebuilding databases.

For more information about specifying collations when creating databases, see Creating a database with a named collation.

Example 2

In the second situation, both the collation and the character set need to be changed. To resolve the collation and character set issues, you need to rebuild the database with the new collation settings, and change the character set of the data.

Suppose that the 850LATIN1 database had been used properly such that it contains characters from the CP850 character set. However, you want to update both the collation and the character set, perhaps to avoid character set translation. You would create a new database using 1252LATIN1, and move the data from the old database to the new database with translation, thus converting the CP850 characters to CP1252.

The translation of the database data from one character set to another occurs using the client-server translation feature of the server, which translates the character data during the communication between the client application and the server. The database's collation determines the character set for the database server side of the communication. The locale of the operating system determines the client's default character set, however, the client's character set can be overridden by the CharSet (CS) connection parameter.

For more information about the CharSet (CS) connection parameter, see CharSet connection parameter [CS].

Since character set translation takes place during the communication between the client application and the server, an external unload or reload is necessary. An internal unload and reload does not do character set translation.

toggle To convert a database from one collation to another, and translate the data's character set (using translation on reload)

  1. Unload the data from the source database.

    You can use the Unload utility to produce a reload.SQL file and a set of data files in the character set of the source database. Since we do not want any translation during this phase, ensure that character set translation is not enabled on the server running the source database. For servers before version 8, ensure that -ct is not specified. If you are using a server that is version 8 or higher, ensure that -ct- (no character set translation) is specified when the server is started.

    If the unload/reload is occurring on a single machine, use the -ix option to do an internal unload and an external reload. If the unload/reload occurs across machines, use the Unload utility with the -xx option to force an external unload and an external reload.

    Remember that an "external" unload or reload means that an application (the dbunload and dbisql utilities) opens a cursor on the database and either reads or writes the data to disk. Character set translation occurs. An "internal" unload or reload means that an UNLOAD TABLE or LOAD TABLE is used so that the server reads or writes the data itself. Character set translation does not occur.

    If you want to unload data from specific tables, use the -t option, or the Interactive SQL OUTPUT statement.

    For more information on the Unload utility, see The Unload utility.

  2. Create a target database with the appropriate collation using the Initialization utility including the -z option to specify the collation sequence for the target database.

    The database should be created and reloaded using the version of the server and tools corresponding to the server that they will use to run it.

    For more information on specifying collations when creating databases, see Creating a database with a named collation.

  3. Start the target database using the server running with character set translation. You can also specify the -z option.

    The –z option, while not required, allows for verification of the character sets that will be used, and that translation will occur. The server window will show character set translation settings for each connection. However, using the –z server option can cause slower performance during the reload.

    For more information, see Starting a database server using character set translation.

  4. If you generated a reload.SQL file in step 1, you can run the file in a command shell using a command such as the following.

    dbisql -c "uid=dba;pwd=sql;charset=cp1252" -codepage 850 reload.sql

    You must supply the appropriate connection parameters for your database, as well as the code page (850 in the example above) that was used to generate the reload.SQL file.

    If you exported only table data in step 1, you can import the data using the INPUT statement in Interactive SQL.

    For more information about the INPUT statement, see INPUT statement [Interactive SQL].


Code page and character set reference

The following sections provide information about supported code pages and character sets for Adaptive Server Anywhere.


Supported code pages

The following table lists code pages supported in Interactive SQL.

For more information, see Opening Interactive SQL using the dbisql command-line utility or Interactive SQL utility options.

Code Page | Description
1252 | Windows Latin-1
037 | USA, Canada (Bilingual, French), Netherlands, Portugal, Brazil, Australia
273 | IBM Austria, Germany
277 | IBM Denmark, Norway
278 | IBM Finland, Sweden
280 | IBM Italy
284 | IBM Catalan/Spain, Spanish Latin America
285 | IBM United Kingdom, Ireland
297 | IBM France
420 | IBM Arabic
424 | IBM Hebrew
437 | MS-DOS United States, Australia, New Zealand, South Africa
500 | EBCDIC 500V1
737 | PC Greek
775 | PC Baltic
838 | IBM Thailand extended SBCS
850 | MS-DOS Latin-1
852 | MS-DOS Latin-2
855 | IBM Cyrillic
856 | IBM Hebrew
857 | IBM Turkish
858 | Variant of Cp850 with Euro character
860 | MS-DOS Portuguese
861 | MS-DOS Icelandic
862 | PC Hebrew
863 | MS-DOS Canadian French
864 | PC Arabic
865 | MS-DOS Nordic
866 | MS-DOS Russian
868 | MS-DOS Pakistan
869 | IBM Modern Greek
870 | IBM Multilingual Latin-2
871 | IBM Iceland
874 | IBM Thai
875 | IBM Greek
918 | IBM Pakistan (Urdu)
921 | IBM Latvia, Lithuania (AIX, DOS)
922 | IBM Estonia (AIX, DOS)
930 | Japanese Katakana-Kanji mixed with 4370 UDC, superset of 5026
933 | Korean Mixed with 1880 UDC, superset of 5029
935 | Simplified Chinese Host mixed with 1880 UDC, superset of 5031
937 | Traditional Chinese Host mixed with 6204 UDC, superset of 5033
939 | Japanese Latin Kanji mixed with 4370 UDC, superset of 5035
942 | IBM OS/2 Japanese, superset of Cp932
942 | C Variant of Cp942
943 | IBM OS/2 Japanese, superset of Cp932 and Shift-JIS
943 | C Variant of Cp943
948 | OS/2 Chinese (Taiwan) superset of 938
949 | PC Korean
949 | C Variant of Cp949
950 | PC Chinese (Hong Kong, Taiwan)
964 | AIX Chinese (Taiwan)
970 | AIX Korean
1006 | IBM AIX Pakistan (Urdu)
1025 | IBM Multilingual Cyrillic: Bulgaria, Bosnia, Herzegovinia, Macedonia (FYR)
1026 | IBM Latin-5, Turkey
1046 | IBM Arabic - Windows
1097 | IBM Iran (Farsi)/Persian
1098 | IBM Iran (Farsi)/Persian (PC)
1112 | IBM Latvia, Lithuania
1122 | IBM Estonia
1123 | IBM Ukraine
1124 | IBM AIX Ukraine
1140 | Variant of Cp037 with Euro character
1141 | Variant of Cp273 with Euro character
1142 | Variant of Cp277 with Euro character
1143 | Variant of Cp278 with Euro character
1144 | Variant of Cp280 with Euro character
1145 | Variant of Cp284 with Euro character
1146 | Variant of Cp285 with Euro character
1147 | Variant of Cp297 with Euro character
1148 | Variant of Cp500 with Euro character
1149 | Variant of Cp871 with Euro character
1250 | Windows Eastern European
1251 | Windows Cyrillic
1253 | Windows Greek
1254 | Windows Turkish
1255 | Windows Hebrew
1256 | Windows Arabic
1257 | Windows Baltic
1258 | Windows Vietnamese
1381 | IBM OS/2, DOS People's Republic of China (PRC)
1383 | IBM AIX People's Republic of China (PRC)
33722 | IBM-eucJP - Japanese (superset of 5050)
ASCII | American Standard Code for Information Interchange
ISO8859_1 | ISO 8859-1, Latin alphabet No. 1
UnicodeBig | Sixteen-bit Unicode Transformation Format, big-endian byte order, with byte-order mark
UnicodeBigUnmarked | Sixteen-bit Unicode Transformation Format, big-endian byte order
UnicodeLittle | Sixteen-bit Unicode Transformation Format, little-endian byte order, with byte-order mark
UnicodeLittleUnmarked | Sixteen-bit Unicode Transformation Format, little-endian byte order
UTF8 | Eight-bit Unicode Transformation Format
UTF-16 | Sixteen-bit Unicode Transformation Format, byte order specified by a mandatory initial byte-order mark
Big5 | Big5, Traditional Chinese
Big5_HKSCS | Big5 with Hong Kong extensions, Traditional Chinese
Big5_Solaris | Big5 with seven additional Hanzi ideograph character mappings for the Solaris zh_TW.BIG5 locale
EUC_CN | GB2312, EUC encoding, Simplified Chinese
EUC_JP | JIS X 0201, 0208, 0212, EUC encoding, Japanese
EUC_KR | KS C 5601, EUC encoding, Korean
EUC_TW | CNS11643 (Plane 1-3), EUC encoding, Traditional Chinese
GB18030 | Simplified Chinese, PRC standard
GBK | GBK, Simplified Chinese
ISCII91 | ISCII91 encoding of Indic scripts
ISO2022CN | ISO 2022 CN, Chinese (conversion to Unicode only)
ISO2022CN_CNS | CNS 11643 in ISO 2022 CN form, Traditional Chinese (conversion from Unicode only)
ISO2022CN_GB | GB 2312 in ISO 2022 CN form, Simplified Chinese (conversion from Unicode only)
ISO2022JP | JIS X 0201, 0208 in ISO 2022 form, Japanese
ISO2022KR | ISO 2022 KR, Korean
ISO8859_2 | ISO 8859-2, Latin alphabet No. 2
ISO8859_3 | ISO 8859-3, Latin alphabet No. 3
ISO8859_4 | ISO 8859-4, Latin alphabet No. 4
ISO8859_5 | ISO 8859-5, Latin/Cyrillic alphabet
ISO8859_6 | ISO 8859-6, Latin/Arabic alphabet
ISO8859_7 | ISO 8859-7, Latin/Greek alphabet
ISO8859_8 | ISO 8859-8, Latin/Hebrew alphabet
ISO8859_9 | ISO 8859-9, Latin alphabet No. 5
ISO8859_13 | ISO 8859-13, Latin alphabet No. 7
ISO8859_15_FDIS | ISO 8859-15, Latin alphabet No. 9
JIS0201 | JIS X 0201, Japanese
JIS0208 | JIS X 0208, Japanese
JIS0212 | JIS X 0208, Japanese
JISAutoDetect | Detects and converts from Shift-JIS, EUC-JP, ISO 2022 JP (conversion to Unicode only)
Johab | Johab, Korean
KOI8_R | KOI8-R, Russian
MS874 | Windows Thai
MS932 | Windows Japanese
MS936 | Windows Simplified Chinese
MS949 | Windows Korean
MS950 | Windows Traditional Chinese
MacArabic | Macintosh Arabic
MacCentralEurope | Macintosh Latin-2
MacCroatian | Macintosh Croatian
MacCyrillic | Macintosh Cyrillic
MacDingbat | Macintosh Dingbat
MacGreek | Macintosh Greek
MacHebrew | Macintosh Hebrew
MacIceland | Macintosh Iceland
MacRoman | Macintosh Roman
MacRomania | Macintosh Romania
MacSymbol | Macintosh Symbol
MacThai | Macintosh Thai
MacTurkish | Macintosh Turkish
MacUkraine | Macintosh Ukraine
SJIS | Shift-JIS, Japanese
TIS620 | TIS620, Thai


Character set labels

The following table displays the valid character set label values, together with the equivalent IANA labels and a description:

Character set label | IANA label | Description
big5 | <N/A> | Traditional Chinese (cf. CP950)
cp437 | <N/A> | IBM CP437 - U.S. code set
cp850 | <N/A> | IBM CP850 - European code set
cp852 | <N/A> | PC Eastern Europe
cp855 | <N/A> | IBM PC Cyrillic
cp856 | <N/A> | Alternate Hebrew
cp857 | <N/A> | IBM PC Turkish
cp860 | <N/A> | PC Portuguese
cp861 | <N/A> | PC Icelandic
cp862 | <N/A> | PC Hebrew
cp863 | <N/A> | IBM PC Canadian French code page
cp864 | <N/A> | PC Arabic
cp865 | <N/A> | PC Nordic
cp866 | <N/A> | PC Russian
cp869 | <N/A> | IBM PC Greek
cp874 | <N/A> | Microsoft Thai SB code page
cp932 | windows-31j | Microsoft CP932 = Win31J-DBCS
cp936 | </N/A> | Simplified Chinese
cp949 | <N/A> | Korean
cp950 | <N/A> | PC (MS) Traditional Chinese
cp1250 | <N/A> | MS Windows Eastern European
cp1251 | <N/A> | MS Windows Cyrillic
cp1252 | <N/A> | MS Windows US (ANSI)
cp1253 | <N/A> | MS Windows Greek
cp1254 | <N/A> | MS Windows Turkish
cp1255 | <N/A> | MS Windows Hebrew
cp1256 | <N/A> | MS Windows Arabic
cp1257 | <N/A> | MS Windows Baltic
cp1258 | <N/A> | MS Windows Vietnamese
deckanji | <N/A> | DEC UNIX JIS encoding
euccns | <N/A> | EUC CNS encoding: Traditional Chinese with extensions
eucgb | <N/A> | EUC GB encoding = Simplified Chinese
eucjis | euc-jp | Sun EUC JIS encoding
eucksc | <N/A> | EUC KSC Korean encoding (cf. CP949)
greek8 | <N/A> | HP Greek-8
iso_1 | iso_8859-1:1987 | ISO 8859-1 Latin-1
iso15 | <N/A> | ISO 8859-15 Latin-1 with Euro, etc.
iso88592 | iso_8859-2:1987 | ISO 8859-2 Latin-2 Eastern Europe
iso88595 | iso_8859-5:1988 | ISO 8859-5 Latin/Cyrillic
iso88596 | iso_8859-6:1987 | ISO 8859-6 Latin/Arabic
iso88597 | iso_8859-7:1987 | ISO 8859-7 Latin/Greek
iso88598 | iso_8859-8:1988 | ISO 8859-8 Latin/Hebrew
iso88599 | iso_8859-9:1989 | ISO 8859-9 Latin-5 Turkish
koi8 | <N/A> | KOI-8 Cyrillic
mac | macintosh | Standard Mac coding
mac_cyr | <N/A> | Macintosh Cyrillic
mac_ee | <N/A> | Macintosh Eastern European
macgrk2 | <N/A> | Macintosh Greek
macturk | <N/A> | Macintosh Turkish
roman8 | hp-rpman8 | HP Roman-8
sjis | shift_jis | Shift JIS (no extensions)
tis620 | <N/A> | TIS-620 Thai standard
turkish8 | <N/A> | HP Turkish-8
utf8 | utf-8 | UTF-8 treated as a character set


Backup and Data Recovery

About this chapter

This chapter describes how to protect your data against operating system crashes, file corruption, disk failures, and total machine failure.

The chapter describes how to make backups of your database, how to restore data from a backup, and how to run your server so that validation, performance, and data protection concerns are addressed.

Introduction to backup and recovery
Understanding backups
Designing backup procedures
Configuring your database for data protection
Backup and recovery internals
Backup and recovery tasks


Introduction to backup and recovery

A backup is a copy of the information in a database, held in some physically separate location from your database. If the database becomes unavailable, perhaps because of damage to a disk drive, you can restore it from the backup. Depending on the nature of the damage, it is often possible to restore from backups all committed changes to the database up to the time it became unavailable.

Restoring databases from a backup is one aspect of database recovery. The other aspect is recovery from operating system or database server crashes, and improper shutdowns. The database server checks on database startup whether the database was shut down cleanly at the end of the previous session. If it was not, the server executes an automatic recovery process to restore information. This mechanism recovers all changes up to the most recently committed transaction.

Questions and answers
To answer the question... | Consider reading...
What is a backup? | Introduction to backup and recovery
What is recovery? | Introduction to backup and recovery
What is a transaction log? | The transaction log
What are media and system failure? | Protecting your data against failure
From what kinds of failure do backups protect my data? | Protecting your data against failure
What tools are available for backups? | Ways of making backups
What types of backup are available? | Types of backup
What type of backup should I use? | Designing backup procedures
If my database file or transaction log becomes corrupt, what data may be lost? | Protecting your data against media failure
How are backups executed? | Understanding backups
How often do I carry out backups? | Scheduling backups
Can I schedule automatic backups? | Scheduling backups
My database is involved in replication. How does this affect my backup strategy? | A backup scheme for databases involved in replication Backup methods for remote databases in replication installations
How can I backup to tape? | Backing up a database directly to tape
How do I plan a backup schedule? | Designing a backup and recovery plan
Can I automate backups? | Automating Tasks Using Schedules and Events
How can I be sure that my database file is not corrupt? | Ensuring your database is valid Validating a database
How can I be sure that my transaction log is not corrupt? | Validating the transaction log on database startup Validating a transaction log
How can I run my database for maximum protection against failures? | Configuring your database for data protection
How can I ensure high availability and machine redundancy? | Protecting against total machine failure Making a live backup
How do I carry out a backup? | Making a full backup
How do I restore data from backups when a failure occurs? | Recovering from media failure on the database file Recovering from media failure on an unmirrored transaction log Recovering from media failure on a mirrored transaction log


Protecting your data against failure

If your database has become unusable, you have experienced a database failure. Adaptive Server Anywhere provides protection against the following categories of failure:

Media failure The database file and/or the transaction log become unusable. This may occur because the file system or the device storing the database file becomes unusable, or it may be because of file corruption.

For example:

  • The disk drive holding the database file or the transaction log file becomes unusable.

  • The database file or the transaction log file becomes corrupted. This can happen because of hardware problems or software problems.

Backups protect your data against media failure.

For more information, see Understanding backups.

System failure A system failure occurs when the computer or operating system goes down while there are partially completed transactions. This could occur when the computer is inappropriately turned off or rebooted, when another application causes the operating system to crash, or because of a power failure.

For example:

  • The computer or operating system becomes temporarily unavailable while there are partially completed transactions, perhaps because of a power failure or operating system crash, or because the computer is inappropriately rebooted.

After a system failure occurs, the database server recovers automatically when you next start the database. The results of each transaction committed before the system error are intact. All changes by transactions that were not committed before the system failure are canceled.

For more information about the recovery mechanism, see Backup and recovery internals.

It is possible to recover uncommitted changes manually. For information, see Recovering uncommitted operations.


Ways of making backups

There are several distinct ways of making backups. This section introduces each of the major approaches, but does not address any issues of appropriate options.

You can make backups in the following ways:

  • Sybase Central You can use the Backup Database wizard in Sybase Central to make a backup. You can access the wizard by selecting a database and choosing Backup Database from the File menu (or from the popup menu).

    For more information, see Backing up a database directly to tape.

  • Backup utility The dbbackup command-line utility makes backups. For example, executing the following command at the command prompt makes backup copies of the database and transaction log in the directory c:\backup on the client machine:

    dbbackup –c "connection-string" c:\backup

    You can make a backup copy of the database and transaction log in the director c:\backup on the server machine by specifying the -s option:

    dbbackup –c "connection-string" -s c:\backup

    For more information, see The Backup utility.

  • SQL Statement You can use a SQL statement to make the database server execute a backup operation. For example, the following statement places backup copies of the database file and transaction log into the directory c:\backup on the server machine.

    BACKUP DATABASE
DIRECTORY 'c:\\backup'

    For more information, see BACKUP statement.

  • Offline backup The above examples are all online backups, executed against a running database. You can make offline backups by copying the database files when the database is not running.

    For more information, see Types of backup.

Notes

You must have DBA authority or REMOTE DBA authority to make online backups of a database.


Understanding backups

To understand what files you need to back up, and how you restore databases from backups, you need to understand how the changes made to the database are stored on disk.


The database file

When a database is shut down, the database file holds a complete and current copy of all the data in the database. When a database is running, however, the database file is generally not current or complete.

The only time a database file is guaranteed to hold a complete and current copy of all data is immediately after a checkpoint completes. Following a checkpoint, all the contents of the database cache are on disk.

The database server checkpoints a database under the following conditions:

  • As part of the database shutdown operations

  • When the amount of time since the last checkpoint exceeds the database option CHECKPOINT_TIME

  • When the estimated time to do a recovery operation exceeds the database option RECOVERY_TIME

  • When the database server is idle long enough to write all dirty pages

  • When a connection issues a CHECKPOINT statement

  • When the database server is running without a transaction log and a transaction is committed

Between checkpoints, you need both the database file and another file, called the transaction log, to ensure that you have a complete copy of all committed transactions.

For more information about checkpoints, see Checkpoints and the checkpoint log, and How the database server decides when to checkpoint.


The transaction log

The transaction log is a separate file from the database file. It stores all changes to the database. Inserts, updates, deletes, commits, rollbacks, and database schema changes are all logged. The transaction log is also called the forward log or the redo log.

The transaction log is a key component of backup and recovery, and is also essential for data replication using SQL Remote or the Replication Agent.

By default, all databases use transaction logs. Using a transaction log is optional, but you should always use a transaction log unless you have a specific reason not to. Running a database with a transaction log provides much greater protection against failure, better performance, and the ability to replicate data.

For more information on how to use a transaction log to protect against media failure, see Protecting against media failure on the database file.

When changes are forced to disk

Like the database file, the transaction log is organized into pages: fixed size areas of memory. When a change is recorded in the transaction log, it is made to a page in memory. The change is forced to disk when the earlier of the following happens:

  • The page is full.

  • A COMMIT is executed.

In this way, completed transactions are guaranteed to be stored on disk, while performance is improved by avoiding a write to the disk on every operation.

Configuration options are available to allow advanced users to tune the precise behavior of the transaction log. For more information, see COOPERATIVE_COMMITS option [database], and DELAYED_COMMITS option [database].

Transaction log mirrors

A transaction log mirror is an identical copy of the transaction log, maintained at the same time as the transaction log. If a database has a mirrored transaction log, every database change is written to both the transaction log and the transaction log mirror. By default, databases do not have transaction log mirrors.

A transaction log mirror provides extra protection for critical data. It enables complete data recovery in the case of media failure on the transaction log. A mirrored transaction log also enables a database server to carry out automatic validation of the transaction log on database startup.

For more information, see Protecting against media failure on the transaction log.


Protecting your data against media failure

Backups protect your data against media failure.

For an overview of data protection mechanisms, see Protecting your data against failure.

The practical aspects of recovery from media failure depend on whether the media failure is on the database file or the transaction log file.

Media failure on the database file If your database file is not usable, but your transaction log is still usable, you can recover all committed changes to the database as long as you have a proper backup procedure in place. All information since the last backed up copy of the database file is held in backed up transaction logs, or in the online transaction log.

For more information on how to configure your database system, see Protecting against media failure on the database file.

Media failure on the transaction log file Unless you use a mirrored transaction log, you cannot recover information entered between the last database checkpoint and a media failure on the transaction log. For this reason, it is recommended that you use a mirrored transaction log in setups such as SQL Remote consolidated databases, where loss of the transaction log can lead to loss of key information, or the breakdown of a replication system.

For more information, see Protecting against media failure on the transaction log.


Designing backup procedures

When you make a backup, you have a set of choices to make about how to manage transaction logs. The choices you make depend on a set of factors including the following:

  • Is the database involved in replication?

    In this chapter, replication means SQL Remote replication, or MobiLink synchronization where dbmlsync.exe is running, or a database using the Replication Agent. Each of these replication methods requires access to the transaction log, and potentially to old transaction logs.

  • How fast is the transaction log file growing relative to your available disk space? If the transaction log is growing quickly, you may not be able to afford to keep transaction logs available.

Types of backup
Scheduling backups
A backup scheme for when disk space is plentiful
A backup scheme for databases not involved in replication
A backup scheme for databases involved in replication
Backup methods for remote databases in replication installations
Backing up a database to a tape drive
Designing a backup and recovery plan
Ensuring your database is valid


Types of backup

This section assumes that you are familiar with basic concepts related to backups.

For more information about concepts related to backups, see Introduction to backup and recovery, and Understanding backups.

Backups can be categorized in several ways:

  • Full backup and incremental backup A full backup is a backup of both the database file and of the transaction log. An incremental backup is a backup of the transaction log only. Typically, full backups are interspersed with several incremental backups.

    For more information on making backups, see Making a full backup, and Making an incremental backup.

  • Server-side backup and client-side backup You can execute an online backup from a client machine using the Backup utility. To execute a server side backup, you execute the BACKUP statement; the database server then carries out the backup.

    You can easily build server side backup into applications because it is a SQL statement. Also, server-side backup is generally faster because the data does not have to be transported across the client/server communications system.

    Instructions for server-side and client-side backups are given together for each backup procedure.

  • Archive backup and image backup

    An archive backup copies the database file and the transaction log into a single archive file, typically on a tape drive. An image backup makes a copy of the database file and/or the transaction log, each as separate files. You can only carry out archive backups as server-side backups, and you can only make full backups.

    You should use an archive backup if you are backing up directly to tape. Otherwise, an image backup has more flexibility for transaction log file management.

    Archive backups are supported on Windows NT/2000/XP and UNIX platforms only. On Windows CE, only image backups are permitted.

    For more information on archive backups, see Backing up a database directly to tape.

  • Online and offline backup Backing up a running database provides a snapshot of a consistent database, even though other users are modifying the database. An offline backup consists simply of copying the files. You should only carry out an offline backup when the database is not running, and when the database server was shut down properly.

    The information in this chapter focuses on online backups.

  • Live backup A live backup is a continuous backup of the database that helps protect against total machine failure.

    For more information on when to use live backups, see Protecting against total machine failure.

    For more information on how to make a live backup, see Making a live backup.


Scheduling backups

Most backup schedules involve periodic full backups interspersed with incremental backups of the transaction log. There is no simple rule for deciding how often to make backups of your data. The frequency with which you make backups depends on the importance of your data, how often it changes, and other factors.

Most backup strategies involve occasional full backups, interspersed by several incremental backups. A common starting point for backups is to carry out a weekly full backup, with daily incremental backups of the transaction log. Both full and incremental backups can be carried out online (while the database is running) or offline, on the server side or the client side. Archive backups are always full backups.

The kinds of failure against which a backup schedule protects you depends not only on how often you make backups, but also on how you operate your database server.

For more information, see Configuring your database for data protection.

You should always keep more than one full backup. If you make a backup on top of a previous backup, a media failure in the middle of the backup leaves you with no backup at all. You should also keep some of your full backups offsite to protect against fire, flood, earthquake, theft, or vandalism.

You can use the event scheduling features of Adaptive Server Anywhere to perform online backups automatically at scheduled times.

For more information on scheduling operations such as backups, see Automating Tasks Using Schedules and Events.


A backup scheme for when disk space is plentiful

If disk space is not a problem on your production machine (where the database server is running) then you do not need to worry about choosing special options to manage the transaction log file. In this case, you can use a simple form of backup that makes copies of the database file and transaction log, and leaves the transaction log in place. All backups leave the database file in place.

A full backup of this kind is illustrated in the figure below. In an incremental backup, only the transaction log is backed up.

In a full backup, the database file and log file are copied to the backup directory. The backup leaves the database file and log file in place.

For more information on how to carry out backups of this type, see Making a backup, continuing to use the original transaction log.


A backup scheme for databases not involved in replication

In many circumstances, disk space limitations make it impractical to let the transaction log grow indefinitely. In this case, you can choose to delete the contents of the transaction log when the backup is complete, freeing the disk space. You should not choose this option if the database is involved in replication because replication requires access to the transaction log.

A full backup, which truncates the log file, is illustrated in the figure below. In an incremental backup, only the transaction log is backed up.

In a full backup where the log file is truncated, the database file and log file are copied to the backup directory. Once the backup is complete, the log file is truncated. The backup leaves the database file in place.

Deleting the transaction log after each incremental backup makes recovery from a media failure on the database file a more complex task as there may then be several different transaction logs since the last full backup. Each transaction log needs to be applied in sequence to bring the database up to date.

You can use this kind of backup at a database that is operating as a MobiLink consolidated database because MobiLink does not rely on the transaction log. If you are running SQL Remote or the MobiLink dbmlsync.exe application, you must use a scheme suitable for preserving old transaction logs, as described in A backup scheme for databases involved in replication.

For more information on how to carry out a backup of this type, see Making a backup, deleting the original transaction log.


A backup scheme for databases involved in replication

If your database is part of a SQL Remote installation, the Message Agent needs access to old transactions. If it is a consolidated database, it holds the master copy of the entire SQL Remote installation, and thorough backup procedures are essential.

If your database is a primary site in a Replication Server installation, the Replication Agent requires access to old transactions. However, disk space limitations often make it impractical to let the transaction log grow indefinitely.

If your database is participating in a MobiLink setup using the dbmlsync.exe executable, the same considerations apply. However, if your database is a MobiLink consolidated database, you do not need old transaction logs and can use a scheme for databases not involved in replication, as described in the previous section.

In these cases, you can choose backup options to rename and restart the transaction log. This kind of backup prevents open-ended growth of the transaction log, while maintaining information about the old transactions for the Message Agent and the Replication Agent.

This kind of backup is illustrated in the figure below.

For a database involved in replication, the database file and log file are copied to the backup directory. The transaction log is renamed and the database file is left in place. Information about old transactions is still available for the Message Agent and the Replication Agent.

For more information on how to carry out a backup of this kind, see Making a backup, renaming the original transaction log.

Offline transaction logs

In addition to backing up the transaction log, the backup operation renames the online transaction log to a filename of the form YYMMDDxx.log. This file is no longer used by the database server, but is available for the Message Agent and the Replication Agent. It is called an offline transaction log. A new online transaction log is started with the same name as the old online transaction log.

There is no Year 2000 issue with the two-digit year in the YYMMDDxx.log filenames. The names are used for distinguishability only, not for ordering. For example, the renamed log file from the first backup on December 10, 2000, is named 001210AA.log. The first two digits indicate the year, the second two digits indicate the month, the third two digits indicate the day of the month, and the final two characters distinguish among different backups made on the same day.

The Message Agent and the Replication Agent can use the offline copies to provide the old transactions as needed. If you set the DELETE_OLD_LOGS database option to ON, then the Message Agent and Replication Agent delete the offline files when they are no longer needed, saving disk space.


Backup methods for remote databases in replication installations

Backup procedures are not as crucial at remote databases as at the consolidated database. You may choose to rely on replication to the consolidated database as a data backup method. In the event of a media failure, the remote database would have to be re-extracted from the consolidated database, and any operations that have not been replicated would be lost. (You could use the Log Translation utility to attempt to recover lost operations.)

For more information about the Log Translation utility, see The Log Translation utility.

Even if you do choose to rely on replication to protect remote database data, backups may still need to be done periodically at remote databases to prevent the transaction log from growing too large. You should use the same option (rename and restart the log) as at the consolidated database, running the Message Agent so that it has access to the renamed log files. If you set the DELETE_OLD_LOGS option to ON at the remote database, the old log files will be deleted automatically by the Message Agent when they are no longer needed.

Automatic transaction log renaming

You can use the -x Message Agent option to eliminate the need to rename the transaction log on the remote computer when the database server is shut down. The -x option renames the transaction log after it has been scanned for outgoing messages.


Backing up a database to a tape drive

All the types of backup described above are image backups. The backup copy of each file is also a file. To make backups to tape using an image backup, you have to take each backup copy and put it on tape using a disk backup utility.

You can carry out direct backup to a tape drive using an archive backup. Archive backups are always full backups. An archive backup makes copies of both the database file and the transaction log, but these copies are placed into a single file.

You can make archive backups using the BACKUP statement. For information, see Backing up a database directly to tape, and BACKUP statement.

You can restore the backup using the RESTORE statement. For information, see Restoring an archive backup, and RESTORE DATABASE statement.


Designing a backup and recovery plan

For reliable protection of your data, you should develop and implement a backup schedule. You should also ensure that you have a set of tested recovery instructions.

Typical schedules call for occasional full backups interspersed with several incremental backups. The frequency of each depends on the nature of the data that you are protecting.

If you use internal backups, you can use the scheduling features in Adaptive Server Anywhere to automate the task. Once you specify a schedule, the backups are carried out automatically by the database server.

For more information on automating backups, see Automating Tasks Using Schedules and Events.

The length of time your organization can function without access to the data in your database imposes a maximum recovery time, and you should develop and test a backup and recovery plan that meets this requirement.

You should verify that you have the protection you need against media failure on the database file and on the transaction log file. If you are running in a replication environment, you should consider using a mirrored transaction log.

For more information about media failure, see Protecting your data against media failure.

Factors that affect recovery time

External factors such as available hardware, the size of database files, recovery medium, disk space, and unexpected errors can affect your recovery time. When planning a backup strategy, you should allow additional recovery time for miscellaneous tasks that must be performed, such as entering recovery commands or retrieving and loading tapes.

Adding more files into the recovery scenario increases the places where recovery can fail. As the backup and recovery strategy develops, you should consider checking your recovery plan.

For more information about how to implement a backup and recovery plan, see Implementing a backup and recovery plan.


Ensuring your database is valid

Database file corruption may not be apparent until applications try to access the affected part of the database. As part of your data protection plan, you should periodically check that your database has no errors. You can do this by validating the database. This task requires DBA authority.

Database validation includes a scan of every row in every table and a look-up of each row in each index on the table. Validation requires exclusive access to each table in turn. For this reason, it is best to validate when there is no other activity on the database. Database validation does not validate data, continued row references, or foreign key relationships unless you perform a full validation using the -f option.

If you created your database with checksums enabled, you can check the validity of the disk pages. For databases with checksums enabled, a checksum is calculated for each database page and this value is stored when the page is written to disk. You can use the Validation utility (dbvalid) or the Validate Database wizard in Sybase Central to perform checksum validation, which consists of reading the database pages from disk and calculating the checksum for the page. If the calculated checksum does not match the stored checksum for a page, the page has been modified or corrupted while on disk. If one or more pages has been corrupted, an error is returned and information about the invalid pages appears in the database server window.

For more information about checksum validation, see VALIDATE CHECKSUM statement or The Validation utility.

Caution Backup copies of the database and transaction log must not be changed in any way. If there were no transactions in progress during the backup, you can check the validity of the backup database using read-only mode. However, if transactions were in progress, the database server must carry out recovery on the database when you start it. Recovery modifies the backup copy, which is not desirable.

If you can be sure that no transactions are in progress when the backup is being made, the database server does not need to carry out the recovery steps. In this case, you can carry out a validity check on the backup using the read-only database option.

Tip
Using the BACKUP statement with the WAIT BEFORE START clause ensures that no transactions are in progress when you make a backup.

If a base table in the database file is corrupt, you should treat the situation as a media failure, and recover from your previous backup. If an index is corrupt, you may want to unload the database without indexes, and reload.

For more information, see Validating a database, and Validating a transaction log.

For more information on read-only databases, see -r server option.


Configuring your database for data protection

There are several ways in which you can configure your database and the database server to provide protection against media failure while maintaining performance.

Protecting against media failure on the database file
Protecting against media failure on the transaction log
Protecting against total machine failure
Differences between live backups and transaction log mirrors
Controlling transaction log size


Protecting against media failure on the database file

When you create a database, by default the transaction log is put on the same device and in the same directory as the database. This arrangement does not protect against all kinds of media failure, and you should consider placing the transaction log in another location for production use.

For comprehensive protection against media failure, you should keep the transaction log on a different device from the database file. Some machines with two or more hard drives have only one physical disk drive with several logical drives or partitions: if you want reliable protection against media failure, make sure that you have a machine with at least two storage devices.

Placing the transaction log on a separate device can also result in improved performance by eliminating the need for disk head movement between the transaction log and the main database file.

You should not place the transaction log on a network directory. Reading and writing pages over a network gives poor performance and may result in file corruption.

For more information on creating databases, see Creating a database.

For more information on how to change the location of a transaction log, see Changing the location of a transaction log.


Protecting against media failure on the transaction log

It is recommended that you use a transaction log mirror when running high-volume or extremely critical applications. For example, at a consolidated database in a SQL Remote setup, replication relies on the transaction log, and if the transaction log is damaged or becomes corrupt, data replication can fail.

If you are using a mirrored transaction log, and an error occurs while trying to write to one of the logs (for example, if the disk is full), the database server stops. The purpose of a transaction log mirror is to ensure complete recoverability in the case of media failure on either log device; this purpose would be lost if the server continued with a single log.

You can specify the -fc option when starting the database server to implement a callback function when the database server encounters a file system full condition.

For more information, see -fc server option.

Where to store the transaction log mirror

There is a performance penalty for using a mirrored log as each database log write operation must be carried out twice. The performance penalty depends on the nature and volume of database traffic and on the physical configuration of the database and logs.

A transaction log mirror should be kept on a separate device from the transaction log. This improves performance. Also, if either device fails, the other copy of the log keeps the data safe for recovery.

Alternatives to a transaction log mirror

Alternatives to a mirrored transaction log are to use a disk controller that provides hardware mirroring, or operating-system level software mirroring, as provided by Windows NT/2000/XP and NetWare. Generally, hardware mirroring is more expensive, but provides better performance.

For more information

Live backups provide additional protection that has some similarities to transaction log mirroring.

For more information, see Differences between live backups and transaction log mirrors.

For information on creating a database with a mirrored transaction log, see The Initialization utility.

For information on changing an existing database to use a mirrored transaction log, see The Transaction Log utility.


Protecting against total machine failure

You can use a live backup to provide a redundant copy of the transaction log that is available for restart of your system on a secondary machine in case the machine running the database server becomes unusable.

A live backup runs continuously, terminating only if the server shuts down. If you suffer a system failure, the backed up transaction log can be used for a rapid restart of the system. However, depending on the load that the server is processing, the live backup may lag behind and may not contain all committed transactions.

For more information on making a live backup, see Making a live backup.

For information on restarting database using a live backup, see Recovering from a live backup.


Differences between live backups and transaction log mirrors

Both a live backup and a transaction log mirror appear to provide a secondary copy of the transaction log. However, there are several differences between using a live backup and using a transaction log mirror:

  • In general, a live backup is made to a different machine Running a transaction log mirror on a separate machine is not recommended. It can lead to performance and data corruption problems, and stops the database server if the connection between the machines goes down.

    By running the Backup utility on a separate machine, the database server does not do the writing of the backed up log file, and the data transfer is done by the Adaptive Server Anywhere client/server communications system. Therefore, performance impact is decreased and reliability is greater.

  • A live backup provides protection against a machine becoming unusable Even if a transaction log mirror is kept on a separate device, it does not provide immediate recovery if the whole machine becomes unusable. You could consider an arrangement where two machines share access to a set of disks.

  • A live backup may lag behind the database server A mirrored transaction log contains all the information required for complete recovery of committed transactions. Depending on the load that the server is processing, the live backup may lag behind and may not contain all the committed transactions.

Live backups and regular backups

The live backup of the transaction log is always the same length or shorter than the active transaction log. When a live backup is running, and another backup restarts the transaction log (dbbackup -r or dbbackup -x), the live backup automatically truncates the live backup log and restarts the live backup at the beginning of the new transaction log.

For more information about how to make a live backup, see Making a live backup.


Controlling transaction log size

The size of the transaction log can determine what kind of backup is right for you, and can also affect recovery times.

You can control how fast the transaction log file grows by ensuring that all your tables have compact primary keys. If you carry out updates or deletes on tables that do not have a primary key or a unique index not allowing NULL, the entire contents of the affected rows are entered in the transaction log. If a primary key is defined, the database server needs to store only the primary key column values to uniquely identify a row. If the table contains many columns or wide columns, the transaction log pages fill up much faster if no primary key is defined. In addition to taking up disk space, this extra writing of data affects performance.

If a primary key does not exist, the server looks for a UNIQUE NOT NULL index on the table (or a UNIQUE constraint). A UNIQUE index that allows NULL is not sufficient.


Backup and recovery internals

This section describes the internal mechanisms used during backup and during automatic recovery mechanism from system failures.

Backup internals
Restrictions during backup and recovery
Checkpoints and the checkpoint log
Transactions and the rollback log
The automatic recovery process
How the database server decides when to checkpoint
Validating the transaction log on database startup
Improving performance when validating databases


Backup internals

When you issue a backup instruction, the database may be in use by many people. If you later need to use your backup to restore your database, you need to know what information has been backed up, and what has not.

The database server carries out a backup as follows:

  1. Issue a checkpoint. Further checkpoints are disallowed until the backup is complete. While the backup is taking place, any pages modified by other connections are saved before modification in the temporary file, instead of the database file, so that the backup image is made as of the checkpoint.

  2. Make a backup of the database file, if the backup instruction is for a full backup.

  3. Make a backup of the transaction log.

    The backup includes all operations recorded in the transaction log before the final page of the log is read. This may include instructions issued after the backup instruction was issued.

    The backup copy of the transaction log is generally smaller than the online transaction log. The database server allocates space to the online transaction logs in multiples of 64K, so the transaction log file size generally includes empty pages. However, only the non-empty pages are backed up.

  4. On a database created with version 8.0 or later of Adaptive Server Anywhere, if the backup instruction requires the transaction log to be truncated or renamed, uncommitted transactions are carried forward to the new transaction log.

    On a database created with version 7.x or earlier of Adaptive Server Anywhere, if the backup instruction requires the transaction log to be truncated or renamed, then the database server waits until there are no uncommitted transactions before truncating or renaming the log file. If the database is busy, this wait may be significant.

    For more information about renaming and truncating the transaction log, see Designing backup procedures.

  5. Mark the backup image of the database to indicate that recovery is needed. This causes any operations that happened since the start of the backup to be applied. It also causes operations that were incomplete at the checkpoint to be undone if they were not committed.


Restrictions during backup and recovery

The database server prevents the following operations from being executed while a backup is in progress:

  • Another backup, with the exception of a live backup.

  • A checkpoint, other than the one issued by the backup instruction itself.

  • Any statement that causes a checkpoint. This includes data definition statements, as well as the LOAD TABLE and TRUNCATE TABLE statements.

During recovery, including restoring backups, no action is permitted by other users of the database.


Checkpoints and the checkpoint log

The database file is composed of pages: fixed size portions of hard disk. The checkpoint log is located at the end of the database file. Pages are added to the checkpoint log as necessary during a session, and the entire checkpoint log is deleted at the end of the session.

Before any page is updated (made dirty), the database server carries out the following operations:

  • It reads the page into memory, where it is held in the database cache.

  • It makes a copy of the original page. These copied pages are the checkpoint log.

The database server reads page A into memory where it is held in the cache. Then page A is added to the checkpoint log.

Changes made to the page are applied to the copy in the cache. For performance reasons they are not written immediately to the database file on disk.

Changes made to page A are applied to the copy in the cache, now called page B. The changes to page A are recorded in the transaction log.

When the cache is full, the changed page may get written out to disk. The copy in the checkpoint log remains unchanged.

Page B is written to the database, but the copy of page A remains unchanged in the checkpoint log. The transaction log contains the changes made to page A since the checkpoint.

A checkpoint is a point at which all dirty pages are written to disk and therefore represents a known consistent state of the database on disk. Following a checkpoint, the contents of the checkpoint log are deleted. The empty checkpoint log pages remain in the checkpoint log within a given session and can be reused for new checkpoint log data. As the checkpoint log increases in size, so does the database file.

At a checkpoint, all the data in the database is held on disk in the database file. The information in the database file matches that in the transaction log. During recovery, the database is first recovered to the most recent checkpoint, and then changes since that checkpoint are applied.

The entire checkpoint log, including all empty checkpoint log pages, is deleted at the end of each session. Deleting the checkpoint log causes the database to shrink in size.

For more information, see How the database server decides when to checkpoint.


Transactions and the rollback log

As changes are made to the contents of a database, a rollback log is kept for the purpose of canceling changes if a transaction is rolled back or if a transaction is uncommitted when a system failure occurs. There is a separate rollback log for each connection. When a transaction is committed or rolled back, the rollback log contents for that connection are deleted. The rollback logs are stored in the database, and rollback log pages are copied into the checkpoint log along with other pages that are changed.

The rollback log is also called the undo log.

For more information about transaction processing, see Using Transactions and Isolation Levels.


The automatic recovery process

When a database is shut down during normal operation, the database server carries out a checkpoint so that all the information in the database is held in the database file. This is a clean shutdown.

Each time you start a database, the database server checks whether the last shutdown was clean or the result of a system failure. If the database was not shut down cleanly, it automatically takes the following steps to recover from a system failure:

  1. Recover to the most recent checkpoint All pages are restored to their state at the most recent checkpoint by copying the checkpoint log pages over the changes made since the checkpoint. Page A, the checkpoint log copy of the page, is copied to the database file to overwrite the dirty page. The transaction log contains changes made to page A since the checkpoint.

  2. Apply changes made since the checkpoint Changes made between the checkpoint and the system failure, which are held in the transaction log, are applied.

  3. Rollback uncommitted transactions Any uncommitted transactions are rolled back, using the rollback logs.


How the database server decides when to checkpoint

The priority of writing dirty pages to the disk increases as the time and the amount of work since the last checkpoint grows. The priority is determined by the following factors:

  • Checkpoint Urgency The time that has elapsed since the last checkpoint, as a percentage of the checkpoint time setting of the database. The server -gc option controls the maximum desired time, in minutes, between checkpoints. You can also set the desired time using the CHECKPOINT_TIME option.

    For more information, see -gc server option.

  • Recovery Urgency A heuristic to estimate the amount of time required to recover the database if it fails right now. The server -gr option controls the maximum desired time, in minutes, for recovery in the event of system failure. You can also set the desired time using the RECOVERY_TIME option.

    For more information, see -gr server option.

The checkpoint and recovery urgencies are important only if the server does not have enough idle time to write dirty pages.

Frequent checkpoints make recovery quicker, but also create work for the server writing out dirty pages.

There are two database options that allow you to control the frequency of checkpoints. CHECKPOINT_TIME controls the maximum desired time between checkpoints and RECOVERY_TIME controls the maximum desired time for recovery in the event of system failure.

For more information, see CHECKPOINT_TIME option [database] and RECOVERY_TIME option [database].

The writing of dirty pages to disk is carried out by a task within the server called the idle I/O task. This task shares processing time with other database tasks.

There is a threshold for the number of dirty pages, below which writing of database pages does not take place.

When the database is busy, the urgency is low, and the cache only has a few dirty pages, the idle I/O task runs at a very low priority and no writing of dirty pages takes place.

Once the urgency exceeds 30%, the priority of the idle I/O task increases. At intervals, the priority is increased again. As the urgency becomes high, the server shifts its primary focus to writing dirty pages until the number gets below the threshold again. However, the server only writes out pages during the idle I/O task if the number of dirty pages is greater than the threshold.

If, because of other activity in the database, the number of dirty pages falls to zero, and if the urgency is 50% or more, then a checkpoint takes place automatically since it is a convenient time.

Both the checkpoint urgency and recovery urgency values increase in value until the checkpoint occurs, at which point they drop to zero. They do not decrease otherwise.


Validating the transaction log on database startup

When a database using a transaction log mirror starts up, the database server carries out a series of checks and automatic recovery operations to confirm that the transaction log and its mirror are not corrupt, and to correct some problems if corruption is detected.

On startup, the server checks that the transaction log and its mirror are identical by carrying out a full comparison of the two files; if they are identical, the database starts as usual. The comparison of log and mirror adds to database startup time.

If the database stopped because of a system failure, it is possible that some operations were written into the transaction log but not into the mirror. If the server finds that the transaction log and the mirror are identical up to the end of the shorter of the two files, the remainder of the longer file is copied into the shorter file. This produces an identical log and mirror. After this automatic recovery step, the server starts as usual.

If the check finds that the log and the mirror are different in the body of the shorter of the two, one of the two files is corrupt. In this case, the database does not start, and an error message is generated saying that the transaction log or its mirror is invalid.


Improving performance when validating databases

The VALIDATE TABLE statement can be slow when used on large databases running on servers with a cache size too small to contain the table and its largest index. It is often the case that all pages in the table are read at least once for each index. As well, if full compares are required for index lookups, the number of page reads can be proportional to the number of rows (not pages) in the table.

If you want to reduce the time taken to validate, you can use the WITH EXPRESS CHECK option with the VALIDATE TABLE statement, or the -fx option with the dbvalid utility. Depending on the size of your database, the size of your cache, and the type of validation you require, these two features can significantly reduce the time taken to perform validation.

Express validation causes each row of the table to be read and all columns evaluated, as is done with traditional validation using the WITH DATA CHECK clause. Each index is completely scanned once, and checks are done to ensure that the rows referenced in the index exist in the table. The express check option also does checks on the validity of individual index pages. The number of rows in the table must match the number of entries in the index. The express option saves time because it does not perform individual index lookups for each row.

Because the express check feature does not perform individual lookups, it is possible (though unlikely) for some form of index corruption to go unnoticed by the express validation feature. If index corruption should occur, data can be recovered by unloading and rebuilding the database since validation has confirmed that all of the data can be read.

Express validation is only supported for databases created with Adaptive Server Anywhere 7.0 or later.

For more information about the express check option, see the VALIDATE TABLE statement, Validating a database using the dbvalid command-line utility, and the sa_validate system procedure.


Backup and recovery tasks

This section collects together instructions for tasks related to backup and recovery.

Implementing a backup and recovery plan
Making a full backup
Making an incremental backup
Validating a database
Validating a single table
Validating a transaction log
Making a backup, continuing to use the original transaction log
Making a backup, deleting the original transaction log
Making a backup, renaming the original transaction log
Determining which connection has an outstanding transaction
Renaming the backup copy of the transaction log during backup
Backing up a database directly to tape
Making a live backup
Recovering from media failure on the database file
Recovering from media failure on an unmirrored transaction log
Recovering from media failure on a mirrored transaction log
Recovering from a live backup
Restoring an archive backup
Recovering uncommitted operations
Recovering from multiple transaction logs
Changing the location of a transaction log
Creating a database with a transaction log mirror
Starting a transaction log mirror for an existing database


Implementing a backup and recovery plan

Regular backups and tested recovery commands are part of a comprehensive backup and recovery plan.

For more information, see Designing a backup and recovery plan.

toggle To implement a backup and recovery plan

  1. Create and verify your backup and recovery commands.

  2. Measure the time it takes to execute backup and recovery commands.

  3. Document the backup commands and create written procedures outlining where your backups are kept and identify any naming convention used, as well as the kind of backups performed.

  4. Set up your backup procedures on the production server.

  5. Monitor backup procedures to avoid unexpected errors. Make sure any changes in the process are reflected in your documentation.

For more information about carrying out backups, see Making a full backup, and Making an incremental backup.


Making a full backup

A full backup is a backup of the database file and the transaction log file.

For more information about the difference between a full backup and an incremental backup, see Types of backup.

toggle To make a full backup (overview)

  1. Ensure that you have DBA authority on the database.

  2. Perform a validity check on your database to ensure that it is not corrupt. You can use the Validation utility or the sa_validate stored procedure.

    For more information, see Validating a database.

  3. Make a backup of your database file and transaction log.

    For information on how to carry out the backup operation, see the following:

    • Making a backup, continuing to use the original transaction log.

    • Making a backup, deleting the original transaction log.

    • Making a backup, renaming the original transaction log.

Notes

Validity checking requires exclusive access to entire tables on your database. For more information and alternative approaches, see Ensuring your database is valid.

If you validate your backup copy of the database, make sure that you do so in read-only mode. Start the database server with the –r option to use read-only mode.


Making an incremental backup

An incremental backup is a backup of the transaction log file only. Typically, you should make several incremental backups between each full backup.

For more information about the difference between a full backup and an incremental backup, see Types of backup.

toggle To make an incremental backup (overview)

  1. Ensure that you have DBA authority on the database.

  2. Make a backup of your transaction log only, not your database file.

For more information about how to carry out the backup operation, see the following:

  • Making a backup, continuing to use the original transaction log.

  • Making a backup, deleting the original transaction log.

  • Making a backup, renaming the original transaction log.

Notes

The backup copies of the database file and transaction log file have the same names as the online versions of these files. For example, if you make a backup of the sample database, the backup copies are called asademo.db and asademo.log. When you repeat the backup statement, choose a new backup directory to avoid overwriting the backup copies.

For more information about how to make a repeatable incremental backup command by renaming the backup copy of the transaction log, see Renaming the backup copy of the transaction log during backup.


Validating a database

Validating a database is a key part of the backup operation. For information, see Ensuring your database is valid.

For an overview of the backup operation, see Making a full backup.

Caution Validating a table or an entire database should be performed while no connections are making changes to the database; otherwise, spurious errors may be reported indicating some form of database corruption even though no corruption actually exists.
toggle To check the validity of an entire database (Sybase Central)

  1. Connect to the database as a user with DBA authority.

  2. In the left pane of Sybase Central, select the database.

  3. From the File menu, choose Validate Database

    The Validate Database wizard appears.

  4. Follow the instructions in the wizard.

    A message box indicates whether the database is valid or not.

toggle To check the validity of an entire database (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute the sa_validate stored procedure:

    call sa_validate

    The procedure returns a single column, named Messages. If all tables are valid, the column contains No errors detected.

    For more information, see sa_validate system procedure.

toggle To check the validity of an entire database (Command line)

  1. Connect to the database as a user with DBA authority.

  2. Run the dbvalid utility:

    dbvalid -c "connection_string"

    For more information, see The Validation utility.

Notes

If you are checking the validity of a backup copy, you should run the database in read-only mode so that it is not modified in any way. You can only do this when there were no transactions in progress during the backup.

For information on running databases in read-only mode, see -r server option.


Validating a single table

You can check the validity of a single table either from Sybase Central or using a SQL statement. You must have DBA authority or be the owner of a table to check its validity.

toggle To check the validity of a table (Sybase Central)

  1. Open the Tables folder.

  2. Right-click the table and choose Validate from the popup menu.

    A message box indicates whether the table is valid or not.

toggle To check the validity of a table (SQL)

  • Execute the VALIDATE TABLE statement:

    VALIDATE TABLE table_name
Notes

If errors are reported, you can drop all of the indexes and keys on a table and recreate them. Any foreign keys to the table will also need to be recreated. Another solution to errors reported by VALIDATE TABLE is to unload and reload your entire database. You should use the dbunload -u option so that it does not try to use a possibly corrupt index to order the data.


Validating a transaction log

The process for validating a transaction log file depends on whether it is in use on a production database (online) or is not in use (offline, or a backup copy).

toggle To validate an online transaction log

  • Run your database with a mirrored transaction log. The database server automatically validates the transaction log each time the database is started.

toggle To validate an offline or backed up transaction log

  • Run the Log Translation utility (dbtran) against the log file. If the Log Translation utility can successfully read the log file, it is valid.


Making a backup, continuing to use the original transaction log

This task describes the simplest kind of backup, which leaves the transaction log untouched.

For more information about when to use this type of backup, see A backup scheme for when disk space is plentiful.

toggle To make a backup, continuing to use the original transaction log (Sybase Central)

  1. Start Sybase Central. Connect to the database as a user with DBA authority.

  2. Right-click the database and choose Create Backup Images from the popup menu.

    The Create Backup Images wizard appears.

  3. Click Next on the introductory page of the wizard.

  4. Select the database that you want to back up.

  5. On the next page, enter the name of a directory to hold the backup copies, and choose whether to carry out a complete backup (all database files) or an incremental backup (transaction log file only).

  6. On the next page, select the option Continue To Use The Same Transaction Log.

  7. Click Finish to start the backup.

The procedure describes a client-side backup. There are more options available for this kind of backup.

If you choose a server-side backup, and the server is running on a different machine from Sybase Central, you cannot use the Browse button to locate a directory in which to place the backups. The Browse button browses the client machine, while the backup directory is relative to the server.

toggle To make a backup, continuing to use the original transaction log (SQL)

  • If you are using the BACKUP statement, use the following clauses only:

    BACKUP DATABASE
DIRECTORY directory_name
[ TRANSACTION LOG ONLY ]

    Include the TRANSACTION LOG ONLY clause if you are making an incremental backup.

toggle To make a backup, continuing to use the original transaction log (Command line)

  • If you are using the dbbackup utility, use the following syntax:

    dbbackup -c "connection_string" [ -t ] backup_directory

    Include the -t option only if you are making an incremental backup.


Making a backup, deleting the original transaction log

If your database is not involved in replication, and if you have limited disk space on your online machine, you can delete the contents of the online transaction log (truncate the log) when you make a backup. In this case, you need to use every backup copy made since the last full backup during recovery from media failure on the database file.

For more information about when to use this type of backup, see A backup scheme for databases not involved in replication.

toggle To make a backup, deleting the transaction log (Sybase Central)

  1. Start Sybase Central. Connect to the database as a user with DBA authority.

  2. Right-click the database and choose Create Backup Images from the popup menu.

    The Create Backup Images wizard appears.

  3. Click Next on the introductory page of the wizard.

  4. Select the database that you want to back up.

  5. On the next page, enter the name of a directory to hold the backup copies, and choose whether to carry out a complete backup (all database files) or an incremental backup (transaction log file only).

  6. On the next page, select the option Truncate the Transaction Log.

  7. Click Finish to start the backup.

toggle To make a backup, deleting the transaction log (SQL)

  • Use the BACKUP statement with the following clauses:

    BACKUP DATABASE
DIRECTORY backup_directory
[ TRANSACTION LOG ONLY ]
TRANSACTION LOG TRUNCATE

    Include the TRANSACTION LOG ONLY clause only if you are making an incremental backup.

    The backup copies of the transaction log and database file are placed in backup_directory. If you enter a path, it is relative to the working directory of the database server, not your client application.

toggle To make a backup, deleting the transaction log (Command line)

  • From the command prompt, enter the following command:

    dbbackup -c "connection_string" -x [ -t ] backup_directory

    Include the -t option only if you are making an incremental backup.

    The backup copies of the transaction log and database file are placed in backup_directory. If you enter a path, it is relative to the directory from which you run the command.

Notes

Before the online transaction log can be erased, all outstanding transactions must terminate. If there are outstanding transactions, your backup cannot complete.

For information, see Backup internals.

You can determine which connection has an outstanding transaction using the sa_conn_info system procedure. If necessary, you can disconnect the user with a DROP CONNECTION statement.

For more information, see Determining which connection has an outstanding transaction.


Making a backup, renaming the original transaction log

This set of backup options is typically used for databases involved in replication. In addition to making backup copies of the database file and transaction log, the transaction log at backup time is renamed to an offline log, and a new transaction log is started with the same name as the log in use at backup time.

For more information about when to use this set of backup options, see A backup scheme for databases involved in replication.

toggle To make a backup, renaming the transaction log (Sybase Central)

  1. Start Sybase Central. Connect to the database as a user with DBA authority.

  2. Right-click the database and choose Create Backup Images from the popup menu.

    The Create Backup Images wizard appears.

  3. Click Next on the introductory page of the wizard.

  4. Select the database that you want to back up.

  5. On the next page, enter the name of a directory to hold the backup copies, and choose whether to carry out a complete backup (all database files) or an incremental backup (transaction log file only).

  6. On the next page, select the option Rename the Transaction Log.

  7. Click Finish to start the backup.

toggle To make a backup, renaming the transaction log (SQL)

  • Use the BACKUP statement with the following clauses:

    BACKUP DATABASE
DIRECTORY backup_directory
[ TRANSACTION LOG ONLY ]
TRANSACTION LOG RENAME

    Include the TRANSACTION LOG ONLY clause only if you are making an incremental backup.

    The backup copies of the transaction log and database file are placed in backup_directory. If you enter a path, it is relative to the working directory of the database server, not your client application.

toggle To make a backup, renaming the transaction log (Command line)

  • From a command prompt, enter the following command. You must enter the command on a single line:

    dbbackup -c "connection_string" -r [ -t ] backup_directory

    Include the -t option if you are making an incremental backup.

    The backup copies of the transaction log and database file are placed in backup_directory. If you enter a path, it is relative to the directory from which you run the command.

Notes

Before the online transaction log can be renamed, all outstanding transactions must terminate. If there are outstanding transactions, your backup will not complete.

For information, see Backup internals.

You can determine which connection has an outstanding transaction using the sa_conn_info system procedure. If necessary, you can disconnect the user with a DROP CONNECTION statement.

For more information, see Determining which connection has an outstanding transaction.


Determining which connection has an outstanding transaction

If you are carrying out a backup that renames or deletes the transaction log on a database created with version 8.0 or later of Adaptive Server Anywhere, incomplete transactions are carried forward to the new transaction log.

If you are carrying out a backup that renames or deletes the transaction log on a database created with version 7.x or earlier of Adaptive Server Anywhere, however, and if there are outstanding transactions, the backup must wait until those transactions are complete before it can complete.

You can use a system procedure to determine which user has outstanding transactions. If there are not too many connections, you can also use the Adaptive Server Anywhere Console utility to determine which connection has outstanding connections.

toggle To determine which connection has an outstanding transaction (SQL)

  1. Connect to the database from Interactive SQL or another application that can call stored procedures.

  2. Execute the sa_conn_info system procedure:

    CALL sa_conn_info

  3. Inspect the UncmtOps column to see which connection has uncommitted operations.

    For more information, see sa_conn_info system procedure.

toggle To determine which connection has an outstanding transaction (Adaptive Server Anywhere Console utility)

  1. Connect to the database from the Adaptive Server Anywhere Console utility.

    For example, the following command connects to the default database using user ID DBA and password SQL:

    dbconsole -c "uid=DBA;pwd=SQL"

    For more information, see The Adaptive Server Anywhere Console utility.

  2. Double-click each connection, and inspect the Uncommitted Ops entry to see which users have uncommitted operations. If necessary, you can disconnect the user to enable the backup to finish.


Renaming the backup copy of the transaction log during backup

By default, the backup copy of the transaction log file has the same name as the online file. For each backup operation, you must assign a different name or location for the backup copy, or you must move the backup copy before the next backup is done.

You can make a repeatable incremental backup command by renaming the backup copy of the transaction log.

toggle To rename the backup copy of the transaction log (SQL)

  • Use the MATCH keyword in the BACKUP statement. For example, the following statement makes an incremental backup of the asademo database to the directory c:\backup. The backup copy of the transaction log is called YYMMDDxx.log, where YYMMDD is the date and xx is a counter, starting from AA.

    BACKUP DATABASE
DIRECTORY 'c:\\backup'
TRANSACTION LOG ONLY
TRANSACTION LOG RENAME MATCH
toggle To rename the backup copy of the transaction log (Command line)

  • Supply the -n option to dbbackup. For example, the following command makes an incremental backup of the sample database, renaming the backup copy of the transaction log.

    dbbackup -c "uid=DBA;pwd=SQL;dbn=asademo" -r -t -n c:\backup
Notes

The backup copy of the transaction log is named YYMMDDxx.log, where YY is the year, MM is the month, DD is the day of the month, and xx runs from AA to ZZ, incrementing if there is more than one backup per day. There is no Year 2000 issue with the two-digit year in the YYMMDDxx.log filenames. The names are used for distinguishability only, not for ordering.


Backing up a database directly to tape

An archive backup makes a copy of the database file and transaction log file in a single archive destination. Only server-side, full backups can be made in this manner. When you make an archive backup in Sybase Central, you have the option of backing up the database directly to tape or to disk.

For more information, see Types of backup.

toggle To make an archive backup to tape (Sybase Central)

  1. Start Sybase Central. Connect to the database as a user with DBA authority.

  2. Right-click the database and choose Backup Database from the popup menu.

    The Backup Database wizard appears.

  3. Click Next on the introductory page of the wizard.

  4. Select the database that you want to back up to tape.

  5. On the second page of the wizard, select the On Tape to the Following Device option and type the tape drive in the text box below.

  6. Click Finish to start the backup.

toggle To make an archive backup to tape (SQL)

  • Use the BACKUP statement, with the following clauses:

    BACKUP DATABASE
TO archive_root
[ ATTENDED { ON | OFF } ]
[ WITH COMMENT comment string ]

    If you set the ATTENDED option to OFF, the backup fails if it runs out of tape or disk space. If ATTENDED is set to ON, you are prompted to take an action, such as replacing the tape, when there is no more space on the backup archive device.

Notes

The BACKUP statement makes an entry in the text file backup.syb, in the same directory as the server executable.

For more information about restoring from an archive backup, see Restoring an archive backup.

Example

The following statement makes a backup to the first tape drive on a Windows NT machine:

BACKUP DATABASE
TO '\\\\.\\tape0'
ATTENDED OFF
WITH COMMENT 'May 6 backup'

The first tape drive on Windows NT is \\.\tape0. Because the backslash is an escape character in SQL strings, each backslash is preceded by another.

The following statement makes an archive file on disk named c:\backup\archive.1.

BACKUP DATABASE
TO 'c:\\backup\\archive'


Making a live backup

You carry out a live backup of the transaction log using the dbbackup utility with the -l option.

For more information about live backups, see Protecting against total machine failure.

toggle To make a live backup

  1. Set up a secondary machine from which you can run the database if the online machine fails. For example, ensure that you have Adaptive Server Anywhere installed on the secondary machine.

  2. Periodically, carry out a full backup to the secondary machine.

  3. Run a live backup of the transaction log to the secondary machine.

    dbbackup -l path\filename.log -c "connection_string"

You should normally run the dbbackup utility from the secondary machine.

If the primary machine becomes unusable, you can restart your database using the secondary machine. The database file and the transaction log hold the information needed to restart.


Recovering from media failure on the database file

The recovery process depends on whether you leave the transaction log untouched on incremental backup in your backup process. If your backup operation deletes or renames the transaction log, you may have to apply changes from several transaction logs. If your backup operation leaves the transaction log untouched, you need to use only the online transaction log in recovery.

For more information about the backup types discussed here, see Designing backup procedures.

toggle To recover from media failure on the database file

  1. Make an extra backup copy of the current transaction log. The database file is gone, and the only record of changes since the last backup is in the transaction log.

  2. Create a recovery directory to hold the files you use during recovery.

  3. Copy the database file from the last full backup to the recovery directory.

  4. Apply the transactions held in the backed up transaction logs to the recovery database.

    For each log file, in chronological order,

    • Copy the log file into the recovery directory.

    • Start the database server with the apply transaction log (-a) option, to apply the transaction log:

      dbeng9 db_name.db -a log_name.log

      The database server shuts down automatically once the transactions have been applied.

  5. Copy the online transaction log into the recovery directory. Apply the transactions from the online transaction log to the recovery database.

    dbeng9 db_name.db -a db_name.log

  6. Perform validity checks on the recovery database.

    For more information, see Validating a database.

  7. Make a post-recovery backup.

  8. Move the database file to the production directory.

  9. Allow user access to the production database.


Recovering from media failure on an unmirrored transaction log

If your database is a primary site in a Replication Server installation, or a consolidated database in a SQL Remote installation, you should use a mirrored transaction log, or hardware equivalent.

For more information, see Protecting against media failure on the transaction log.

toggle To recover from media failure on an unmirrored transaction log (partial recovery)

  1. Make an extra backup copy of the database file immediately. With the transaction log gone, the only record of the changes between the last backup and the most recent checkpoint is in the database file.

  2. Delete or rename the transaction log file.

  3. Restart the database with the -f option.

    dbeng9 asademo.db -f
    Caution This command should only be used when the database is not participating in a SQL Remote or Replication Server replication system. If your database is a consolidated database in a SQL Remote replication system, you may have to re-extract the remote databases.

    Without the -f option, the server reports the lack of a transaction log as an error. With the option, the server restores the database to the most recent checkpoint and then rolls back any transactions that were not committed at the time of the checkpoint. A new transaction log is then created.


Recovering from media failure on a mirrored transaction log

toggle To recover from media failure on a mirrored transaction log

  1. Make an extra copy of the backup of your database file taken at the time the transaction log was started.

  2. Identify which of the two files is corrupt. Run the Log Translation utility on the transaction log and on its mirror to see which one generates an error message. The Log Translation utility is accessible from Sybase Central or as the dbtran utility.

    The following command line translates a transaction log named asademo.log, placing the translated output into asademo.SQL:

    dbtran asademo.log

    The Log Translation utility properly translates the intact file, and reports an error while translating the corrupt file.

  3. Copy the correct file over the corrupt file so that you have two identical files again.

  4. Restart the server.


Recovering from a live backup

A live backup is made to a separate machine from the primary machine that is running your production database. To restart a database from a live backup, you must have Adaptive Server Anywhere installed on the secondary machine.

For more information about live backups, see Protecting against total machine failure.

toggle To restart a database using a live backup

  1. Start the database server on the secondary machine with the apply transaction log (-a) option to apply the transaction log and bring the database up to date:

    dbeng9 asademo.db -a filename.log

    The database server shuts down automatically once the transaction log is applied.

  2. Start the database server in the normal way, allowing user access. Any new activity is appended to the current transaction log.


Restoring an archive backup

If you use an archive backup (typically to tape), you use the RESTORE statement to recover your data.

For more information about making archive backups, see Backing up a database directly to tape.

toggle To restore a database from an archive backup (Sybase Central)

  1. In Sybase Central, connect to a database with DBA authority.

  2. In the left pane, select the Adaptive Server Anywhere plug-in, and click the Utilities tab in the right pane.

  3. In the right pane, double-click Restore Database.

    The Restore Database wizard appears.

  4. Follow the instructions in the wizard.

toggle To restore a database from an archive backup (Interactive SQL)

  1. Start a personal database server. Use a command such as the following, which starts a server named restore:

    dbeng9 -n restore

  2. Start Interactive SQL. On the Identification tab of the Connect dialog, enter a user ID of DBA and a password of SQL. Leave all other fields on this tab blank.

  3. Click the Database tab and enter a database name of utility_db. Leave all other fields on this tab blank.

  4. Click OK to connect.

  5. Execute the RESTORE statement, specifying the archive root. At this time, you can choose to restore an archived database to its original location (default), or to a different machine with different device names using the RENAME clause.

    For more information, see RESTORE DATABASE statement.

Example

The following statement restores a database from a tape archive to the database file c:\newdb\newdb.db.

RESTORE DATABASE 'c:\\newdb\\newdb.db'
FROM '\\\\.\\tape0'

The following statement restores a database from an archive backup in file c:\backup\archive.1 to the database file c:\newdb\newdb.db. The transaction log name and location are specified in the database.

RESTORE DATABASE 'c:\\newdb\\newdb.db'
FROM 'c:\\backup\\archive'

For more information, see RESTORE DATABASE statement.


Recovering uncommitted operations

When recovering from media failure on the database file, the transaction log is intact. Recovery reapplies all committed transactions to the database. In some circumstances, you may wish to find information about transactions that were incomplete at the time of the failure.

toggle To recover uncommitted operations from a transaction log (Sybase Central)

  1. Do one of the following:

    • If you are connected to a database, in the left pane, select the Adaptive Server Anywhere plug-in, and then click the Utilities tab in the right pane. In the right pane, double-click Translate Log File.

    • If you are not connected to a database, click Tools > Adaptive Server Anywhere 9 > Translate Log File.

      The Translate Log File wizard appears.

  2. Follow the instructions in the wizard.

  3. Edit the translated log (SQL command file) in a text editor and identify the instructions you need.

toggle To recover uncommitted operations from a transaction log (Command line)

  1. Run dbtran to convert the transaction log into a SQL command file, using the -a option to include uncommitted transactions. For example, the following command uses dbtran to convert a transaction log:

    dbtran -a sample.log changes.SQL

  2. Edit the translated log (SQL command file) in a text editor and identify the instructions you need.

    For more information on the Log Translation utility, see The Log Translation utility.

Note

The transaction log may or may not contain changes right up to the point where a failure occurred. It does contain any changes made before the end of the most recently committed transaction that made changes to the database.


Recovering from multiple transaction logs

Adaptive Server Anywhere 8.0.0 and later allow transactions to span multiple transaction log files. If a database is backed up part way through a transaction, the transaction may span two transaction log files. When this occurs, the first part of the transaction is contained in the offline transaction log, while the second part of the transaction is contained in the online transaction log.

If you need to recover your database and you have multiple transaction logs, you must apply the transaction log files to the backup copy of your database in the correct order in case there are transactions that span multiple transaction logs. If the transaction logs are not applied in the correct order, then portions of transactions that span multiple transaction logs will be rolled back.

You can determine the order in which transaction log files were generated using the dbtran utility. The SQL scripts it generates display the earliest log offset in the transaction log, which can be an effective method for determining the order in which multiple log files were generated to ensure that you apply them in the correct order. You can also use the scripts to determine if your transaction logs contain transactions that span transaction logs.

For more information, see The Transaction Log utility.

In order to maintain the integrity of your data when recovering a database from multiple transaction logs, you can either use the -a server option to apply each log individually to the backup copy of the database, or use the Log Translation utility (dbtran) to translate one or more transaction logs into a .SQL file that can be applied to the backup copy of the database.

Recovering from multiple transaction logs using the -a server option

The -a server option is used recover a database by applying a single transaction log file to the backup copy of a database. When this option is specified, the database server applies the log and then terminates—it will not continue to run. If you have multiple transaction logs, you must apply them one at a time in the correct order (from oldest to most recent.

toggle To recover from multiple transaction logs using the -a server option

  1. Start the database server using -a to apply the backup transaction log to the backup copy of your database.

  2. Start the database server and apply the current transaction log to the backup copy of your database.

For more information, see -a recovery option.

Example

The following example applies the offline (backup) and current transaction log to the backup copy of the sample database using the -a database server option.

  1. Start the database server and apply a backup transaction log called backupasademo.log to the backup copy of a database called backupasademo.db:

    dbeng9 -a backupasademo.log backupasademo.db

    The database server applies the backup transaction log to the backup copy of the database and then shuts down.

  2. Start the database server and apply the current transaction log called asademo.log to the backup copy of the database:

    dbeng9 -a asademo.log backupasademo.db

    The database server applies the current transaction log to the backup copy of the database and then shuts down.

Recovering from multiple transaction logs using the dbtran utility

To maintain the integrity of your data when you use dbtran to translate multiple transaction logs, you must specify both the -m and -n options. The -m option instructs the Log Translation utility to generate a file (named by -n) containing all the transactions from the logs in the specified directory.

You need to use -m because if you translate each log individually using dbtran, any transactions that span transaction log files could be rolled back. This is because when dbtran translates a log, it adds a ROLLBACK statement to the end of the log to undo any uncommitted transactions. In cases where a transaction spans two logs, the COMMIT for the transaction occurs in the second log file. Operations at the end of the first log file would be rolled back by dbtran because the file does not contain a COMMIT for the transaction. Translating all the transaction log files in a directory using -m ensures that all your transactions are translated.

For more information, see The Transaction Log utility.

toggle To recover from multiple transaction logs using the dbtran utility

  1. Run the Log Translation utility (dbtran) against the directory containing the transaction log files and output the resulting SQL statements into a .SQL file.

  2. Start the backup copy of your database.

  3. Apply the .SQL file generated by dbtran in step 1 to the backup copy of your database from Interactive SQL.

Example

The following example uses the dbtran utility to apply the backup and current transaction logs to the backup copy of the database.

  1. Run the Log Translation utility against the c:|backup directory and output the SQL statements into a file called recoverylog.sql:

    dbtran -m "c:\backup" -n recoverylog.sql

  2. Start the backup copy of the database called backupasademo.db:

    dbeng9 backupasademo.db

  3. Apply the recoverylog.sql file to the database from Interactive SQL:

    dbisql "uid=dba;pwd=sql;eng=backupasademo" READ recoverylog.sql


Changing the location of a transaction log

The database must not be running when you change the location of a transaction log.

For more information about how to choose the location of a transaction log, see Protecting against media failure on the database file.

toggle To change the location of a transaction log (Sybase Central)

  1. Do one of the following:

    • If you are already connected to the database associated with the log file, select the Adaptive Server Anywhere plug-in in the left pane and then open the Utilities tab in the right pane. In the right pane, double-click Change Log File Settings.

    • If you are not connected to the database, click Tools > Adaptive Server Anywhere 9 > Change Log File Settings.

      The Change Log File Settings wizard appears.

  2. Follow the instructions in the wizard.

toggle To change the location of a transaction log mirror for an existing database (Command line)

  1. Ensure that the database is not running.

  2. Enter the following command at the command prompt:

    dblog -t new-log-file database-file

    For more information about dblog options, see Transaction log utility options.


Creating a database with a transaction log mirror

You can choose to maintain a transaction log mirror when you create a database. This option is available either from the CREATE DATABASE statement, from Sybase Central, or from the dbinit utility.

For more information about why you may wish to use a transaction log mirror, see Protecting against media failure on the transaction log.

toggle To create a database that uses a transaction log mirror (Sybase Central)

  1. Do one of the following:

    • If you are connected to a database, in the left pane, select the Adaptive Server Anywhere plug-in and then open the Utilities tab in the right pane. In the right pane, double-click Create Database.

    • If you are not connected to a database, click Tools > Adaptive Server Anywhere 9 > Create Database.

      The Create Database wizard appears.

  2. Follow the instructions in the wizard.

toggle To create a database that uses a transaction log mirror (SQL)

  • Use the CREATE DATABASE statement, with the TRANSACTION LOG clause.

    For more information, see CREATE DATABASE statement.

toggle To create a database that uses a transaction log mirror (Command line)

  • Use the dbinit utility with the -m option. For example, the following command (which should be entered on one line) initializes a database named company.db, with a transaction log kept on a different device and a mirror on a third device.

    dbinit -t d:\log_dir\company.log -m
e:\mirr_dir\company.mlg c:\db_dir\company.db

    For more information about initialization options, see Initialization utility options.


Starting a transaction log mirror for an existing database

Using the Transaction Log utility, you can choose to maintain a transaction log mirror for an existing database any time the database is not running. This option is available from either Sybase Central or the dblog utility.

For more information about why you may wish to use a transaction log mirror, see Protecting against media failure on the transaction log.

toggle To start a transaction log mirror for an existing database (Sybase Central)

  1. Do one of the following:

    • If you are already connected to the database associated with the log mirror, in the left pane, select the Adaptive Server Anywhere plug-in, and then open the Utilities tab in the right pane. In the right pane, double-click Change Log File Settings.

    • If you are not connected to the database, click Tools > Adaptive Server Anywhere 9 > Change Log File Settings.

      The Change Log File Settings wizard appears.

  2. Follow the instructions in the wizard.

toggle To start a transaction log mirror for an existing database (Command line)

  1. Ensure that the database is not running.

  2. Enter the following command at the command prompt:

    dblog -m mirror-file database-file

    For more information about dblog options, see Transaction log utility options.

You can also use the dblog utility and Sybase Central to stop a database from using a transaction log mirror.


Managing User IDs and Permissions

About this chapter

Each user of a database must have a name they type when connecting to the database, called a user ID. This chapter describes how to manage user IDs.

Database permissions overview
Setting user and group options
Managing individual user IDs and permissions
Managing connected users
Managing groups
Database object names and prefixes
Using views and procedures for extra security
Changing ownership on nested objects
How user permissions are assessed
Managing the resources connections use
Users and permissions in the system tables


Database permissions overview

Proper management of user IDs and permissions lets users of a database carry out their jobs effectively, while maintaining the security and privacy of information within the database.

You use SQL statements for assigning user IDs to new users of a database, granting and revoking permissions for database users, and finding out the current permissions of users.

Database permissions are assigned to user IDs. Throughout this chapter, the term user is used as a synonym for user ID. Remember, however, that you grant and revoke permissions for each user ID.

Setting up individual user IDs

Even if there are no security concerns regarding a multi-user database, there are good reasons for setting up an individual user ID for each user. The administrative overhead is very low if a group with the appropriate permissions is set up. This chapter discusses groups of users.

You may want to use individual user IDs since:

  • The log translation utility can selectively extract the changes made by individual users from a transaction log. This is very useful when troubleshooting or piecing together what happened if data is incorrect.

  • Sybase Central displays much more useful information with individual user IDs as you can tell which connections are which users.

  • Row locking messages (with the BLOCKING option set to OFF) are more informative.


DBA authority overview

When you create a database, you also create a single usable user ID. This first user ID is DBA, and the password is initially SQL. The DBA user ID automatically has DBA authority within the database. This level of permission enables DBA users to carry out any activity in the database. They can create tables, change table structures, create new user IDs, revoke permissions from users, and so on.

Users with DBA authority

A user with DBA authority becomes the database administrator. In this chapter, references made to the database administrator, or DBA, include any user or users with DBA authority.

Although DBA authority may be granted or transferred to other user IDs, this chapter assumes that the DBA user ID is the database administrator, and that the abbreviation DBA means both the DBA user ID and any user ID with DBA authority.

Adding new users

The DBA has the authority to add new users to the database. As the DBA adds users, they are also granted permissions to carry out tasks on the database. Some users may need to simply look at the database information using SQL queries, others may need to add information to the database, and others may need to modify the structure of the database itself. Although some of the responsibilities of the DBA may be handed over to other user IDs, the DBA is responsible for the overall management of the database by virtue of the DBA authority.

The DBA has authority to create database objects and assign ownership of these objects to other user IDs.


RESOURCE authority overview

RESOURCE authority is the permission to create database objects, such as tables, views, stored procedures, and triggers. RESOURCE authority may be granted only by the DBA.

To create a trigger, a user needs both RESOURCE authority and ALTER permissions on the table to which the trigger applies.


Ownership permissions overview

The creator of a database object becomes the owner of that object. Ownership of a database object carries with it permissions to carry out actions on that object. These permissions are not assigned to users in the same way that other permissions in this chapter are assigned.

Owners

A user who creates a new object within the database is called the owner of that object, and automatically has permission to carry out any operation on that object. The owner of a table may modify the structure of that table, for instance, or may grant permissions to other database users to update the information within the table.

The DBA has permission to modify any component within the database, and so could delete a table created by another user. The DBA has all the permissions regarding database objects that the owners of each object have. As well, the DBA can also create database objects for other users. In this case, the owner of an object is not the user ID that executed the CREATE statement. A use for this ability is discussed in Groups without passwords. Despite this possibility, this chapter refers interchangeably to the owner and creator of database objects as the same person.


Table and views permissions overview

There are several distinct permissions you may grant to user IDs concerning tables and views:

Permission | Description
ALTER | Permission to alter the structure of a table or create a trigger on a table
DELETE | Permission to delete rows from a table or view
INSERT | Permission to insert rows into a table or view
REFERENCES | Permission to create indexes on a table and to create foreign keys that reference a table
SELECT | Permission to look at information in a table or view
UPDATE | Permission to update rows in a table or view. This may be granted on a set of columns in a table only
ALL | All the above permissions


Group permissions overview

Setting permissions individually for each user of a database can be a time-consuming and error-prone process. For most databases, permission management based on groups, rather than on individual user IDs, is a much more efficient approach.

You can assign permissions to a group in exactly the same way as to an individual user. You can then assign membership in appropriate groups to each new user of the database, and they gain a set of permissions by virtue of their group membership.

Example

For example, you may create groups for different departments in a company database (sales, marketing, and so on) and assign these groups permissions. Each salesperson becomes a member of the sales group, and automatically gains access to the appropriate areas of the database.

Each user ID can be a member of multiple groups, and they inherit all permissions from each of the groups.


Setting user and group options

In Sybase Central, configurable options for users and groups are located in the User Options and Group Options dialogs (the same dialog as for setting database options). In Interactive SQL, you can specify an option in a SET OPTION statement.

toggle To set options for a user or group (Sybase Central)

  1. Connect to a database and open the Users & Groups folder.

  2. Right-click the desired user or group and choose Options from the popup menu.

  3. Edit the desired values.

  4. Click Set Permanent Now.

toggle To set the options for a user or group (SQL)

  • Specify the desired properties within a SET OPTION statement.

See also
  • Setting properties for database objects
  • Database Options


Managing individual user IDs and permissions

This section describes how to create new users and grant permissions to them. For most databases, the bulk of permission management should be carried out using groups, rather than by assigning permissions to individual users one at a time. However, as a group is simply a user ID with special properties, you should read and understand this section before moving on to the discussion of managing groups.

Creating new users
Setting a password
Changing a password
Granting DBA and RESOURCE authority
Granting permissions on tables
Granting permissions on views
Granting users the right to grant permissions
Granting permissions on procedures
Execution permissions of triggers
Granting and revoking remote permissions
Revoking user permissions
Deleting users from the database


Creating new users

You can create new users in both Sybase Central and Interactive SQL. In Sybase Central, you manage users or groups in the Users & Groups folder. In Interactive SQL, you can add a new user using the GRANT CONNECT statement. For both tools, you need DBA authority to create new users.

All new users are automatically added to the PUBLIC group. Once you have created a new user, you can:

  • add it to other groups

    For more information, see Granting group membership to existing users or groups.

  • set its permissions on tables, views, and procedures

    For more information, see Managing individual user IDs and permissions.

  • set it as the publisher or as a remote user of the database

    For more information, see Managing SQL Remote permissions.

Initial permissions for new users

By default, the permissions assigned to new users include:

  • the ability to connect to the database (assuming a password has been specified for the user)

  • the ability to view system tables

  • the ability to execute most system stored procedures

To access tables in the database, new users need to be assigned permissions.

The DBA can set the permissions granted automatically to new users by assigning permissions to the special PUBLIC user group, as discussed in Special groups.

toggle To create a new user (Sybase Central)

  1. Open the Users & Groups folder.

  2. From the File menu, choose New > User.

    The User Creation wizard appears.

  3. Follow the instructions in the wizard.

toggle To create a new user (SQL)

  1. Connect to a database as a user ID with DBA authority.

  2. Execute a GRANT CONNECT TO statement.

Example

Add a new user to the database with the user ID of M_Haneef and a password of welcome.

GRANT CONNECT TO M_Haneef
IDENTIFIED BY welcome
See also
  • GRANT statement


Setting a password

A user must have a password to be able to connect to the database. Passwords cannot be more than 255 bytes in length, and cannot contain semicolons.

It is recommended that passwords be composed of 7-bit ASCII characters as 8-bit ASCII characters above 127 may not work correctly when character set translation is turned on and the character sets do not match.

If you want to use passwords with characters above 127, you should do one of the following:

  • specify CharSet=none in your connection string to turn off character set translation

  • specify the character set using the CharSet connection parameter

    For more information about the character sets you can specify, see Character set labels.

  • specify the -ct- option to turn off character set translation on the database server

    For more information, see -ct server option.


Changing a password

Using the GRANT statement, you can change your password or that of another user if you have DBA authority. For example, the following command changes the password for user ID M_Haneef to new_password:

GRANT CONNECT TO M_Haneef
IDENTIFIED BY new_password
Changing the DBA password

The default password for the DBA user ID for all databases is SQL. You should change this password to prevent unauthorized access to your database. The following command changes the password for user ID DBA to new_password:

GRANT CONNECT TO DBA
IDENTIFIED BY new_password


Granting DBA and RESOURCE authority

You can grant DBA and RESOURCE authority in the same manner.

toggle To grant RESOURCE authority to a user ID

  1. Connect to the database as a user with DBA authority.

  2. Type and execute the SQL statement:

    GRANT RESOURCE TO userid

For DBA authority, the appropriate SQL statement is:

GRANT DBA TO userid
Notes

  • Only the DBA may grant DBA or RESOURCE authority to database users.

  • DBA authority is very powerful: anyone with this authority has the ability to carry out any action on the database, as well as access to all the information in the database. It is wise to grant DBA authority to only a few people.

  • Consider giving users with DBA authority two user IDs, one with DBA authority and one without, so that they connect as DBA only when necessary.

  • RESOURCE authority allows the user to create new database objects, such as tables, views, indexes, procedures, or triggers.


Granting permissions on tables

You can assign a set of permissions on individual tables and grant users combinations of these permissions to define their access to a table.

You can use either Sybase Central or Interactive SQL to set permissions. In Interactive SQL, you can use the GRANT statement to grant the following permissions on tables:

  • The ALTER permission allows a user to alter the structure of a table or to create triggers on a table. The REFERENCES permission allows a user to create indexes on a table and to create foreign keys. These permissions grant the authority to modify the database schema, and so will not be assigned to most users. These permissions do not apply to views.

  • The DELETE, INSERT, and UPDATE permissions grant the authority to modify the data in a table. Of these, the UPDATE permission may be restricted to a set of columns in the table or view.

  • The SELECT permission grants authority to look at data in a table, but does not give permission to alter it.

  • ALL permission grants all the above permissions.

toggle To grant permissions on tables or columns (Sybase Central)

  1. Connect to the database.

  2. Open the Tables folder for that database.

  3. Right-click a table and choose Properties from the popup menu.

  4. On the Permissions tab of the Table property sheet, configure the permissions for the table:

    • Click Grant to select users or groups to which to grant permissions.

    • Click the fields beside the user or group to set specific permissions. Permissions are indicated by a check mark, and grant options are indicated by a check mark with two '+' signs.

    • Select a user and click the Change button beside References, Select, or Update to set that type of permission on individual columns.

    • Select a user or group in the list and click Revoke to revoke all permissions.

Tips
You can also assign permissions from the user/group property sheet. To assign permissions to many users and groups at once, use the table's property sheet. To assign permissions to many tables at once, use the user's property sheet.
toggle To grant permissions on tables or columns (SQL)

  1. Connect to the database with DBA authority or as the owner of the table.

  2. Execute a GRANT statement to assign the permission.

    For more information, see GRANT statement.

Example 1

All table permissions are granted in a very similar fashion. You can grant permission to M_Haneef to delete rows from the table named sample_table as follows:

  1. Connect to the database as a user with DBA authority, or as the owner of sample_table.

  2. Type and execute the following SQL statement:

    GRANT DELETE
ON sample_table
TO M_Haneef
Example 2

You can grant permission to M_Haneef to update the column_1 and column_2 columns only in the table named sample_table as follows:

  1. Connect to the database as a user with DBA authority, or as the owner of sample_table.

  2. Type and execute the following SQL statement:

    GRANT UPDATE (column_1, column_2)
ON sample_table
TO M_Haneef

Table permissions are limited in that they generally apply to all the data in a table, although SELECT and UPDATE permissions may be granted to a subset of columns. You can fine-tune user permissions by creating procedures that carry out actions on tables, and then granting users the permission to execute the procedure.

See also
  • GRANT statement


Granting permissions on views

Setting permissions on views is similar to setting them on tables.

For more information about the SQL statements involved, see Granting permissions on tables.

A user may perform an operation through a view if one or more of the following are true:

  • The appropriate permission(s) on the view for the operation has been granted to the user by a DBA.

  • The user has the appropriate permission(s) on all the base table(s) for the operation.

  • The user was granted appropriate permission(s) for the operation on the view by a non-DBA user. This user must be either the owner of the view or have WITH GRANT OPTION of the appropriate permission(s) on the view. The owner of the view must be either:

    • a DBA.

    • a non-DBA, but also the owner of all the base table(s) referred to by the view.

    • a non-DBA, and not the owner of some or all of the base table(s) referred to by the view. However, the view owner has SELECT permission WITH GRANT OPTION on the base table(s) not owned and any other required permission(s) WITH GRANT OPTION on the base table(s) not owned for the operation.

      Instead of the owner having permission(s) WITH GRANT OPTION on the base table(s), permission(s) may have been granted to PUBLIC. This includes SELECT permission on system tables.

UPDATE permissions can be granted only on an entire view. Unlike tables, UPDATE permissions cannot be granted on individual columns within a view.

toggle To grant permissions on views (Sybase Central)

  1. Connect to the database.

  2. Open the Views folder for that database.

  3. Right-click a view and choose Properties from the popup menu.

  4. On the Permissions tab of the View property sheet, configure the permissions for the view:

    • Click Grant to select users or groups to which to grant full permissions.

    • Click in the fields beside the user or group to set specific permissions. Permissions are indicated by a check mark, and grant options are indicated by a check mark with two '+' signs.

    • Select a user or group in the list and click Revoke to revoke all permissions.

Tip
You can also assign permissions from the User or Group property sheet. To assign permissions to many users and groups at once, use the view's property sheet. To assign permissions to many views at once, use the User's or Group's property sheet.
See also
  • GRANT statement


Granting users the right to grant permissions

You can assign each of the table and view permissions described in Granting permissions on tables with the WITH GRANT OPTION. This option gives the right to pass on the permission to other users. In the context of groups, you can read about this feature in section Permissions of groups.

In Sybase Central, you can specify a grant option by displaying the property sheet of a user, group, or table, clicking the Permissions tab, and double-clicking in the fields provided so that a check mark with two '+' signs appears.

Example

You can grant permission to M_Haneef to delete rows from the table named sample_table, and the right to pass on this permission to other users, as follows:

  1. Connect to the database as a user with DBA authority, or as the owner of sample_table:

  2. Type and execute the SQL statement:

    GRANT DELETE ON sample_table
TO M_Haneef
WITH GRANT OPTION

For more information, see GRANT statement


Granting permissions on procedures

The DBA or the owner of the procedure (the user ID that created the procedure) may grant permission to execute stored procedures. The EXECUTE permission is the only permission that may be granted on a procedure.

The method for granting permissions to execute a procedure is similar to that for granting permissions on tables and views, discussed in Granting permissions on tables. However, the WITH GRANT OPTION clause of the GRANT statement does not apply to the granting of permissions on procedures.

You can use either Sybase Central or Interactive SQL to set permissions.

toggle To grant permissions on procedures (Sybase Central)

  1. Connect to the database.

  2. Open the Procedures & Functions folder for that database.

  3. Right-click a procedure and choose Properties from the popup menu.

  4. On the Permissions tab of the Procedure property sheet, configure the permissions for the procedure:

    • Click Grant to select users or groups to which to grant full permissions.

    • Click beside users in the Execute column to toggle between granting or not granting permission.

    • Select a user or group in the list and click Revoke to revoke all permissions.

Tip
You can also assign permissions from the User or Group property sheet. To assign permissions to many users and groups at once, use the procedure's property sheet. To assign permissions to many procedures at once, use the User's or Group's property sheet.
toggle To grant permissions on procedures (SQL)

  1. Connect to the database with DBA authority or as the owner of the procedure.

  2. Execute a GRANT EXECUTE ON statement.

Example

You can grant M_Haneef permission to execute a procedure named my_procedure, as follows:

  1. Connect to the database as a user with DBA authority or as owner of my_procedure procedure.

  2. Execute the SQL statement:

    GRANT EXECUTE
ON my_procedure
TO M_Haneef
Execution permissions of procedures

Procedures execute with the permissions of their owner. Any procedure that updates information in a table will execute successfully only if the owner of the procedure has UPDATE permissions on the table.

As long as the procedure owner has the proper permissions, the procedure executes successfully when called by any user assigned permission to execute it, whether or not they have permissions on the underlying table. You can use procedures to allow users to carry out well-defined activities on a table, without having any general permissions on the table.

See also
  • GRANT statement


Execution permissions of triggers

The server executes triggers in response to a user action. Triggers do not require permissions to be executed. When a trigger executes, it does so with the permissions of the creator of the table with which it is associated.

For more information on trigger permissions, see Trigger execution permissions.


Granting and revoking remote permissions

In Sybase Central, you can manage the remote permissions of both users and groups. Remote permissions allow normal users and groups to become remote users in a SQL Remote replication setup in order to exchange replication messages with the publishing database.

Granting remote permissions

You cannot grant remote permissions to a user until you define at least one message type in the database.

To grant remote permissions to a group, you must explicitly grant remote permissions to each user in the group. Remote permissions are not inherited by members of a group.

Revoking remote permissions

Revoking remote permissions reverts a remote user to a normal user. Revoking these permissions also automatically unsubscribes that user from all publications.

toggle To grant remote permissions to users (Sybase Central)

  1. Connect to a database.

  2. Open the Users & Groups folder.

  3. Right-click the desired user and choose Change to Remote User from the popup menu.

    The Change User to Remote User dialog appears.

  4. In the resulting dialog, enter the desired values.

Once you have granted remote permissions to a user, you can subscribe it to publications:

toggle To revoke remote permissions from remote users

  1. Open either the Users & Groups folder or the SQL Remote Users folder.

  2. Right-click the desired remote user and choose Revoke Remote from the popup menu.

For more information, see SQL Remote Concepts.


Revoking user permissions

Any user's permissions are a combination of those that have been granted and those that have been revoked. By revoking and granting permissions, you can manage the pattern of user permissions on a database.

The REVOKE statement is the exact converse of the GRANT statement. To disallow M_Haneef from executing my_procedure, the command is:

REVOKE EXECUTE
ON my_procedure
FROM M_Haneef

The DBA or the owner of the procedure must issue this command.

Permission to delete rows from sample_table may be revoked by issuing the following command:

REVOKE DELETE
ON sample_table
FROM M_Haneef
See also
  • Granting permissions on tables
  • Granting permissions on views
  • Granting permissions on procedures


Deleting users from the database

You can delete a user from the database using both Sybase Central and Interactive SQL. The user being removed cannot be connected to the database during this procedure.

Deleting a user also deletes all database objects (such as tables) that they own.

Only the DBA can delete a user.

toggle To delete a user from the database (Sybase Central)

  1. Open the Users & Groups folder.

  2. Right-click the desired user and choose Delete from the popup menu.

toggle To delete a user from the database (SQL)

  • Execute a REVOKE CONNECT FROM statement.

Example

Remove the user M_Haneef from the database.

REVOKE CONNECT FROM M_Haneef
See also
  • REVOKE statement
  • Revoking user permissions
  • Deleting groups from the database


Managing connected users

If you are working with Sybase Central, you can keep track of all users connected to the database. You can view properties of these connected users, and you can disconnect them if you want.

toggle To display a list of all users connected to a database

  • Select the database in the left pane, and click the Connected Users tab in the right pane.

    This tab displays all users currently connected to a given database (including yourself), regardless of the application that they used to connect (Sybase Central, Interactive SQL, a custom client application, etc.).

toggle To inspect the properties of a user's connection to a database

  1. Select the database in the left pane, and click the Connected Users tab in the right pane.

  2. Right-click the desired user and choose Properties from the popup menu.

  3. Inspect the desired properties.

toggle To disconnect users from a database

  1. Select the database in the left pane, and click the Connected Users tab in the right pane.

  2. Right-click the desired user and choose Disconnect from the popup menu.


Managing groups

Once you understand how to manage permissions for individual users (as described in the previous section), working with groups is straightforward. A user ID identifies a group, just like it does a single user. However, a group user ID has the permission to have members.

DBA, RESOURCE, and GROUP permissions

When you grant permissions to a group or revoke permissions from a group for tables, views, and procedures, all members of the group inherit those changes. The DBA, RESOURCE, and GROUP permissions are not inherited: you must assign them individually to each of the individual user IDs requiring them.

A group is simply a user ID with special permissions. You grant permissions to a group and revoke permissions from a group in exactly the same manner as any other user, using the commands described in Managing individual user IDs and permissions.

You can construct a hierarchy of groups, where each group inherits permissions from its parent group. That means that a group can also be a member of a group. As well, each user ID may belong to more than one group, so the user-to-group relationship is many-to-many.

The ability to create a group without a password enables you to prevent anybody from connecting to the database using the group user ID.

For more information about this security feature, see Groups without passwords.

For more information on altering database object properties, see Setting properties for database objects.

For more information about granting remote permissions for groups, see Granting and revoking remote permissions.

Creating groups
Granting group membership to existing users or groups
Revoking group membership
Permissions of groups
Referring to tables owned by groups
Groups without passwords
Special groups
Deleting groups from the database


Creating groups

You can create a new group in both Sybase Central and Interactive SQL. You need DBA authority to create a new group.

toggle To create a new group (Sybase Central)

  1. Click the Users & Groups folder.

  2. From the File menu, choose New > Group.

    The Group Creation wizard appears.

  3. Follow the instructions in the wizard.

toggle To create a new group (SQL)

  • Execute a GRANT GROUP TO statement. If the user ID you cite in this statement has not already been created, you need to create it first.

Example

Create the user ID personnel.

GRANT CONNECT
TO personnel
IDENTIFIED BY group_password

Make the user ID personnel a group.

GRANT GROUP TO personnel
See also
  • GRANT statement
  • Creating new users


Granting group membership to existing users or groups

You can add existing users to groups or add groups to other groups in both Sybase Central and Interactive SQL. In Sybase Central, you can control group membership on the property sheets of users or groups. In Interactive SQL, you can make a user a member of a group with the GRANT statement.

When you assign a user membership in a group, they inherit all the permissions on tables, views, and procedures associated with that group.

Only the DBA can grant membership in a group.

toggle To add a user or group to another group (Sybase Central)

  1. Open the Users & Groups folder.

  2. Select the user/group that you want to add to another group and from the File menu, choose New > Memberships.

    The New Memberships dialog appears.

  3. Select the desired group and click OK.

  4. The group membership appears on the Memberships tab in the right pane for the selected user/group.

toggle To add a user or group to another group (SQL)

  • Execute a GRANT MEMBERSHIP IN GROUP statement, specifying the desired group and the users involved.

Example

Grant the user M_Haneef membership in the personnel group:

GRANT MEMBERSHIP
IN GROUP personnel
TO M_Haneef
See also
  • GRANT statement
  • Creating new users


Revoking group membership

You can remove users or groups from a group in both Sybase Central and Interactive SQL.

Removing a user or group from a group does not delete them from the database (or from other groups). To do this, you must delete the user/group itself.

Only the DBA can revoke membership in a group.

toggle To remove a user or group from another group (Sybase Central)

  1. Open the Users & Groups folder.

  2. Select the desired user/group and click the Memberships tab in the right pane.

  3. Right-click the desired group and choose Remove Membership from the popup menu.

    The user or group is then removed from this desired group.

Tip
You can perform this action by selecting the group, clicking the Members tab in the right pane, and then right-clicking the user/group you wish to remove and choosing Remove Member from the popup menu.
toggle To remove a user or group from another group (SQL)

  • Execute a REVOKE MEMBERSHIP IN GROUP statement, specifying the desired group and the users involved.

Example

Remove the user M_Haneef from the personnel group:

REVOKE MEMBERSHIP
IN GROUP personnel
FROM M_Haneef
See also
  • REVOKE statement
  • Creating new users
  • Deleting users from the database
  • Deleting groups from the database


Permissions of groups

You may grant permissions to groups in exactly the same way as to any other user ID. Permissions on tables, views, and procedures are inherited by members of the group, including other groups and their members. Some complexities to group permissions exist that database administrators need to keep in mind.

Notes

Members of a group do not inherit the DBA, RESOURCE, and GROUP permissions. Even if the personnel user ID has RESOURCE authority, the members of personnel do not have RESOURCE authority.

Ownership of database objects is associated with a single user ID and is not inherited by group members. If the user ID personnel creates a table, then the personnel user ID is the owner of that table and has the authority to make any changes to the table, as well as to grant privileges concerning the table to other users. Other user IDs who are members of personnel are not the owners of this table, and do not have these rights. Only granted permissions are inherited. For example, if the DBA or the personnel user ID explicitly grants SELECT permission on a table to the personnel user ID, all group members inherit select access to the table.


Referring to tables owned by groups

Groups are used for finding tables and procedures in the database. For example, the query

SELECT * FROM SYSGROUPS

always finds the view SYS.SYSGROUPS, because all users belong to the PUBLIC group, and PUBLIC belongs to the SYS group which owns the SYSGROUPS view. (The SYSGROUPS view contains a list of group_name, member_name pairs representing the group memberships in your database.)

If a table named employees is owned by the user ID personnel, and if M_Haneef is a member of the personnel group, then M_Haneef can refer to the employees table simply as employees in SQL statements. Users who are not members of the personnel group need to use the qualified name personnel.employees.

Creating a group to own the tables

A good practice to follow, that allows everyone to access the tables without qualifying names, is to create a group whose only purpose is to own the tables. Do not grant any permissions to this group, but make all users members of the group. You can then create permission groups and grant users membership in these permission groups as warranted.

For an example, see the section Database object names and prefixes.


Groups without passwords

Users connected to a group's user ID have certain permissions. This user ID can grant and revoke membership in the group. Also, this user would have ownership permissions over any tables in the database created in the name of the group's user ID.

It is possible to set up a database so that only the DBA handles groups and their database objects, rather than permitting other user IDs to make changes to group membership. You can do this by disallowing connection as the group's user ID when creating the group. To do this, type the GRANT CONNECT statement without a password. Thus:

GRANT CONNECT
TO personnel

creates a user ID personnel. This user ID can be granted group permissions, and other user IDs can be granted membership in the group, inheriting any permissions that have been given to personnel. However, nobody can connect to the database using the personnel user ID because it has no valid password.

The user ID personnel can be an owner of database objects, even though no user can connect to the database using this user ID. The CREATE TABLE statement, CREATE PROCEDURE statement, and CREATE VIEW statement all allow the owner of the object to be specified as a user other than that executing the statement. Only the DBA can carry out this assignment of ownership.


Special groups

When you create a database, the SYS, PUBLIC, and dbo groups are also automatically created. None of these groups has passwords, so it is not possible to connect to the database as SYS, PUBLIC, or dbo. However, these groups serve important functions in the database.

The SYS group

The SYS group owns the system tables and views for the database, which contain the full description of database structure, including all database objects and all user IDs.

For more information about the system tables and views, together with a description of access to the tables, see the chapters System Tables, and System Views.

The PUBLIC group

The PUBLIC group has SELECT permission on the system tables. As well, the PUBLIC group is a member of the SYS group, and has read access for some of the system tables and views, so any user of the database can find out information about the database schema. If you wish to restrict this access, you can REVOKE PUBLIC's membership in the SYS group.

Any new user ID is automatically a member of the PUBLIC group and inherits any permissions specifically granted to that group by the DBA. You can also REVOKE membership in PUBLIC for users if you wish.

The dbo group

The dbo group owns many system stored procedures and views. The dbo group is a member of the SYS group. The PUBLIC group is a member of the dbo group. The dbo group also owns tables used for UltraLite and MobiLink.


Deleting groups from the database

You can delete a group from the database using both Sybase Central and Interactive SQL.

Deleting users or groups from the database is different from removing them from other groups. Deleting a group from the database does not delete its members from the database, although they lose membership in the deleted group.

Only the DBA can delete a group.

toggle To delete a group from the database (Sybase Central)

  1. Open the Users & Groups folder.

  2. Right-click the desired group and choose Delete from the popup menu.

toggle To delete a group from the database (SQL)

  1. Connect to a database.

  2. Execute a REVOKE CONNECT FROM statement.

Example

Remove the group personnel from the database.

REVOKE CONNECT FROM personnel
See also
  • REVOKE statement
  • Revoking user permissions
  • Deleting users from the database


Database object names and prefixes

The name of every database object is an identifier.

For information about the rules for valid identifiers, see Identifiers.

In queries and sample SQL statements throughout this guide, database objects from the sample database are generally referred to using their simple name. For example:

SELECT *
FROM employee

Tables, procedures, and views all have an owner. The owner of the tables in the sample database is the user ID DBA. In some circumstances, you must prefix the object name with the owner user ID, as in the following statement.

SELECT *
FROM DBA.employee

The employee table reference is said to be qualified. In other circumstances it is sufficient to give the object name. This section describes when you need to use the owner prefix to identify tables, views and procedures, and when you do not.

When referring to a database object, you require a prefix unless:

  • You are the owner of the database object.

  • The database object is owned by a group ID of which you are a member.

Example

Consider the following example of a corporate database. The user ID company created all the tables, and since this user ID belongs to the database administrator, it therefore has DBA authority.

GRANT CONNECT TO company
IDENTIFIED BY secret;
GRANT DBA TO company;

The company user ID created the tables in the database.

CONNECT USER company IDENTIFIED BY secret;
CREATE TABLE company.Customers ( ... );
CREATE TABLE company.Products ( ... );
CREATE TABLE company.Orders ( ... );
CREATE TABLE company.Invoices ( ... );
CREATE TABLE company.Employees ( ... );
CREATE TABLE company.Salaries ( ... );

Not everybody in the company should have access to all information. Consider two user IDs in the sales department, Joe and Sally, who should have access to the Customers, Products, and Orders tables. To do this, you create a Sales group.

GRANT CONNECT TO Sally IDENTIFIED BY xxxxx;
GRANT CONNECT TO Joe IDENTIFIED BY xxxxx;
GRANT CONNECT TO Sales IDENTIFIED BY xxxxx;
GRANT GROUP TO Sales;
GRANT ALL ON Customers TO Sales;
GRANT ALL ON Orders TO Sales;
GRANT SELECT ON Products TO Sales;
GRANT MEMBERSHIP IN GROUP Sales TO Sally;
GRANT MEMBERSHIP IN GROUP Sales TO Joe;

Now Joe and Sally have permission to use these tables, but they still have to qualify their table references because the table owner is company, and Sally and Joe are not members of the company group:

SELECT *
FROM company.Customers

To rectify the situation, make the Sales group a member of the company group.

GRANT GROUP TO company;
GRANT MEMBERSHIP IN GROUP company TO Sales;

Now Joe and Sally, being members of the Sales group, are indirectly members of the company group, and can reference their tables without qualifiers. The following command now works:

SELECT *
FROM Customers
Note

Joe and Sally do not have any extra permissions because of their membership in the company group. The company group has not been explicitly granted any table permissions. (The company user ID has implicit permission to look at tables like Salaries because it created the tables and has DBA authority.) Thus, Joe and Sally still get an error executing either of these commands:

SELECT *
FROM Salaries;
SELECT *
FROM company.Salaries

In either case, Joe and Sally do not have permission to look at the Salaries table.


Using views and procedures for extra security

For databases that require a high level of security, defining permissions directly on tables has limitations. Any permission granted to a user on a table applies to the whole table. There are many cases when users' permissions need to be shaped more precisely than on a table-by-table basis. For example:

  • It is not desirable to give access to personal or sensitive information stored in an employee table to users who need access to other parts of the table.

  • You may wish to give sales representatives update permissions on a table containing descriptions of their sales calls, but limit such permissions to their own calls.

In these cases, you can use views and stored procedures to tailor permissions to suit the needs of your organization. This section describes some of the uses of views and procedures for permission management.

For more information about how to create views, see Working with views.

For more information about view permissions, see Granting permissions on views.


Using views for tailored security

Views are computed tables that contain a selection of rows and columns from base tables. Views are useful for security when it is appropriate to give a user access to just one portion of a table. The portion can be defined in terms of rows or in terms of columns. For example, you may wish to disallow a group of users from seeing the salary column of an employee table, or you may wish to limit a user to see only the rows of a table they have created.

Example

The Sales manager needs access to information in the database concerning employees in the department. However, there is no reason for the manager to have access to information about employees in other departments.

This example describes how to create a user ID for the sales manager, create views that provide the information she needs, and grant the appropriate permissions to the sales manager user ID.

  1. Create the new user ID using the GRANT statement. While logged in as a user ID with DBA authority, enter the following:

    CONNECT DBA
IDENTIFIED by SQL ;

GRANT CONNECT
TO SalesManager
IDENTIFIED BY sales

  2. Define a view which only looks at sales employees as follows:

    CREATE VIEW emp_sales AS
  SELECT emp_id, emp_fname, emp_lname
  FROM DBA.employee
  WHERE dept_id = 200

    The table should therefore be identified as DBA.employee, with the owner of the table explicitly identified, for the SalesManager user ID to be able to use the view. Otherwise, when SalesManager uses the view, the SELECT statement refers to a table that user ID does not recognize.

  3. Give SalesManager permission to look at the view:

    GRANT SELECT
ON emp_sales
TO SalesManager

    You use exactly the same command to grant permission on views and on tables.

Example 2

The next example creates a view which allows the Sales Manager to look at a summary of sales orders. This view requires information from more than one table for its definition:

  1. Create the view.

    CREATE VIEW order_summary AS
  SELECT order_date, region, sales_rep, company_name
  FROM DBA.sales_order
    KEY JOIN DBA.customer

  2. Grant permission for the Sales Manager to examine this view.

    GRANT SELECT
ON order_summary
TO SalesManager

  3. To check that the process has worked properly, connect to the SalesManager user ID and look at the views you created:

    CONNECT SalesManager
IDENTIFIED BY sales;
SELECT *
FROM DBA.emp_sales;
SELECT *
FROM DBA.order_summary;

No permissions have been granted to the Sales Manager to look at the underlying tables. The following commands produce permission errors.

SELECT * FROM DBA.employee;
SELECT * FROM DBA.sales_order
Other permissions on views

The previous example shows how to use views to tailor SELECT permissions. You can grant INSERT, DELETE, and UPDATE permissions on views in the same way.

For more information about allowing data modification on views, see Using views.


Using procedures for tailored security

While views restrict access on the basis of data, procedures restrict the actions a user may take. As described in Granting permissions on procedures, a user may have EXECUTE permission on a procedure without having any permissions on the table or tables on which the procedure acts.

Strict security

For strict security, you can disallow all access to the underlying tables, and grant permissions to users or groups of users to execute certain stored procedures. This approach strictly defines the manner in which data in the database can be modified.


Changing ownership on nested objects

Views and procedures can access underlying objects that are owned by different users. For example, if usera, userb, userc, and userd were four different users, userd.viewd could be based on userc.viewc, which could be based on userb.viewb, which could be based on usera.tablea. Similarly for procedures, userd.procd could call userc.procc, which could call userb.procb, which could insert into usera.tablea.

The following Discretionary Access Control (DAC) rules apply to nested views and tables:

  • To create a view, the user must have SELECT permission on all of the base objects (for example tables and views) in the view.

  • To access a view, the view owner must have been granted the appropriate permission on the underlying tables or views with the GRANT OPTION and the user must have been granted the appropriate permission on the view.

  • Updating with a WHERE clause requires both SELECT and UPDATE permission.

  • If a user owns the tables in a view definition, the user can access the tables through a view, even if the user is not the owner of the view and has not been granted access on the view.

The following DAC rules apply to nested procedures:

  • A user does not require any permissions on the underlying objects (for example tables, views or procedures) to create a procedure.

  • For a procedure to execute, the owner of the procedure needs the appropriate permissions on the objects that the procedure references.

  • Even if a user owns all the tables referenced by a procedure, the user will not be able to execute the procedure to access the tables unless the user has been granted EXECUTE permission on the procedure.

Following are some examples that describe this behavior.

Example 1: User1 creates table1, and user2 creates view2 on table1
Example 2: User2 creates procedure2 that accesses table1
Example 3: User1 creates table1, user2 creates table2, and user3 creates view3 joining table1 and table2


Example 1: User1 creates table1, and user2 creates view2 on table1

  • User1 can always access table1, since user1 is the owner.

  • User1 can always access table1 through view2, since user1 is the owner of the underlying table. This is true even if user2 does not grant permission on view2 to user1.

  • User2 can access table1 directly or through view2 if user1 grants permission on table1 to user2.

  • User3 can access table1 if user1 grants permission on table1 to user3

  • User3 can access table1 through view2 if user1 grants permission on table1 to user2 with grant option and user2 grants permission on view2 to user3.


Example 2: User2 creates procedure2 that accesses table1

  • User1 can access table1 through procedure2 if user2 grants EXECUTE permission on procedure2 to user1. Note that this is different from the case of view2, where user1 did not need permission on view2.


Example 3: User1 creates table1, user2 creates table2, and user3 creates view3 joining table1 and table2

  • User3 can access table1 and table2 through view3 if user1 grants permission on table1 to user3 and user2 grants permission on table2 to user3.

  • If user3 has permission on table1 but not on table2, then user3 cannot use view3, even to access the subset of columns belonging to table1.

  • User1 or user2 can use view3 if (a) user1 grants permission with grant option on table1 to user3, (b) user2 grants permission with grant option on table2 to user3, and ©) user3 grants permission on view3 to that user.


How user permissions are assessed

Groups do introduce complexities in the permissions of individual users. Suppose user M_Haneef has SELECT and UPDATE permissions on a specific table individually, but is also a member of two groups. Suppose one of these groups has no access to the table at all, and one has only SELECT access. What are the permissions in effect for this user?

Adaptive Server Anywhere decides whether a user ID has permission to carry out a specific action in the following manner:

  1. If the user ID has DBA authority, the user ID can carry out any action in the database.

  2. Otherwise, permission depends on the permissions assigned to the individual user. If the user ID has been granted permission to carry out the action, then the action proceeds.

  3. If no individual settings have been made for that user, permission depends on the permissions of each of the groups to which the member belongs. If any of these groups has permission to carry out the action, the user ID has permission by virtue of membership in that group, and the action proceeds.

This approach minimizes problems associated with the order in which permissions are set.


Managing the resources connections use

Building a set of users and groups allows you to manage permissions on a database. Another aspect of database security and management is to limit the resources an individual user can use.

For example, you may wish to prevent a single connection from taking too much of the available memory or CPU resources, so you can avoid a having a connection slow down other users of the database.

Adaptive Server Anywhere provides a set of database options that the DBA can use to control resources. These options are called resource governors.

Setting options

You can set database options using the SET OPTION statement, with the following syntax:

SET [ TEMPORARY ] OPTION ... [ userid. | PUBLIC. ]option-name = [ option-value ]

For more information about options, see Database Options.

For information on the SET OPTION statement, see SET OPTION statement.

Resources that can be managed

You can use the following options to manage resources:

  • JAVA_HEAP_SIZE Sets the maximum size (in bytes) of the memory allocated to Java applications on a per connection basis.

  • MAX_CURSOR_COUNT Limits the number of cursors for a connection.

  • MAX_STATEMENT_COUNT Limits the number of prepared statements for a connection.

  • BACKGROUND_PRIORITY Limits the impact requests on the current connection have on the performance of other connections.

Database option settings are not inherited through the group structure.


Users and permissions in the system tables

The database system tables and system views store information about the current users of a database and about their permissions.

For more information about each of these tables, see System Tables.

The special user ID SYS owns the system tables. You cannot connect using the SYS user ID.

The DBA has SELECT access to all system tables, just as to any other tables in the database. The access of other users to some of the tables is limited. For example, only the DBA has access to the SYS.SYSUSERPERM table, which contains all information about the permissions of users of the database, as well as the encrypted passwords of each user ID. However, SYS.SYSUSERPERMS is a view containing all information in SYS.SYSUSERPERM except for the password, and by default all users have SELECT access to this view. You can fully modify all permissions and group memberships set up in a new database for SYS, PUBLIC, DBA, and dbo.

The following table summarizes the system tables containing information about user IDs, groups, and permissions. The user ID SYS owns all of the listed tables and views, and so their qualified names are SYS.SYSUSERPERM and so on.

Appropriate SELECT queries on these tables generates all the user ID and permission information stored in the database.

Table | Default | Contents
SYSUSERPERM | DBA only | Database-level permissions and password for each user ID
SYSGROUP | PUBLIC | One row for each member of each group
SYSTABLEPERM | PUBLIC | All permissions on table given by the GRANT commands
SYSCOLPERM | PUBLIC | All columns with SELECT or UPDATE permission given by the GRANT command
DUMMY | PUBLIC | Dummy table that can be used to find the current user ID
SYSPROCPERM | PUBLIC | Each row holds one user granted permission to use one procedure

The following table summarizes the system views containing information about user IDs, groups, and permissions.

Views | Default | Contents
SYSUSERAUTH | DBA only | All information in SYSUSERPERM except for user numbers
SYSUSERPERMS | PUBLIC | All information in SYSUSERPERM except for passwords
SYSUSERLIST | PUBLIC | All information in SYSUSERAUTH except for passwords
SYSGROUPS | PUBLIC | Information from SYSGROUP in a more readable format
SYSTABAUTH | PUBLIC | Information from SYSTABLEPERM in a more readable format
SYSCOLAUTH | PUBLIC | Information from SYSCOLPERM in a more readable format
SYSPROCAUTH | PUBLIC | Information from SYSPROCPERM in a more readable format

In addition to these, there are tables and views that contain information about each object in the database.


Replicating Data with Replication Server

About this chapter

This chapter describes how you can use Replication Server to replicate data between an Adaptive Server Anywhere database and other databases. Other databases in the replication system may be Adaptive Server Anywhere databases or other kinds of database.

Before you begin

Replication Server administrators who are setting up Adaptive Server Anywhere to take part in their Replication Server installation will find this chapter especially useful. You should have knowledge of Replication Server documentation, and familiarity with the Replication Server product. This chapter does not describe Replication Server itself.

For information about Replication Server, including design, commands, and administration, see your Replication Server documentation.


Introduction to replication

Data replication is the sharing of data among physically distinct databases. Changes made to shared data at any one database are copied precisely to the other databases in the replication system.

Data replication brings some key benefits to database users.

Data availability

Replication makes data available locally, rather than through potentially expensive, less reliable, and slower connections to a single, central database. Since data is accessible locally, you are always have access to data, even in the event of a long-distance network connection failure.

Response time

Replication improves response times for data requests for two reasons. First, retrieval rates are faster since requests are processed on a local server without accessing some wide area network. Second, competition for processor time decreases since local processing offloads work from a central database server.


Sybase replication technologies

Sybase provides the following replication technologies for Adaptive Server Anywhere:

  • MobiLink MobiLink is designed for two-way replication involving a consolidated database and large numbers of remote databases, typically including many mobile databases.

  • SQL Remote Like MobiLink, SQL Remote is designed for two-way replication involving a consolidated database and large numbers of remote databases, typically including many mobile databases. Administration and resource requirements at the remote sites are minimal.

  • Replication Server Replication Server is designed for replication among relatively small numbers of data servers, with a typical time lag between primary data and replicate data of a few seconds, and generally with an administrator at each site.

Each replication technology has its own documentation. This chapter describes how to use Adaptive Server Anywhere with Replication Server.

For information about SQL Remote, see the book SQL Remote User's Guide.

For information about MobiLink, see the book MobiLink Synchronization User's Guide.


Replicate sites and primary sites

In a Replication Server installation, the data to be shared among databases is arranged in replication subscriptions.

For each replication definition, there is a primary site, where changes to the data in the replication occur. The sites that receive the data in the replication are called replicate sites.


Replicate site components

You can use Adaptive Server Anywhere as a replicate site with no additional components.

The following diagram illustrates the components required for Adaptive Server Anywhere to participate in a Replication Server installation as a replicate site.

The replication site components consist of Replication Server, the Adaptive Server Anywhere database server, and the database.

  • Replication Server receives data changes from primary site servers.

  • Replication Server connects to Adaptive Server Anywhere to apply the changes.

  • Adaptive Server Anywhere makes the changes to the database.

Asynchronous procedure calls

The Replication Server can use asynchronous procedure calls (APC) at replicate sites to alter data at a primary site database. If you are using APCs, the above diagram does not apply. Instead, the requirements are the same as for a primary site.


Primary site components

To use an Adaptive Server Anywhere database as a primary site, you need to use the Log Transfer Manager (LTM), or Replication Agent. The LTM supports Replication Server version 10.0 and greater.

The following diagram illustrates the components required for Adaptive Server Anywhere to participate in a Replication Server installation as a primary site. The arrows in the diagram represent data flow.

The primary site components consist of the database, the Adaptive Server Anywhere Database server, the Adaptive Server Anywhere Log Transfer Manager, and Replication Server.

  • The Adaptive Server Anywhere database server manages the database.

  • The Adaptive Server Anywhere Log Transfer Manager connects to the database. It scans the transaction log to pick up changes to the data, and sends them to Replication Server.

  • Replication Server sends the changes to replicate site databases.


Tutorial: Replicate data using Replication Server

This section provides a step-by-step tutorial describing how to replicate data from a primary database to a replicate database. Both databases in the tutorial are Adaptive Server Anywhere databases.

Replication Server assumed

This section assumes you have a running Replication Server.

For more information about how to install or configure Replication Server, see the Replication Server documentation.

What is in the tutorial

This tutorial describes how to replicate only tables.

For information about replicating procedures, see Preparing procedures and functions for replication.

The tutorial uses a simple example of a (very) primitive office news system: a single table with an ID column holding an integer, a column holding the user ID of the author of the news item, and a column holding the text of the news item. The id column and the author column make up the primary key.

Before you work through the tutorial, create a directory (for example, c:\tutorial) to hold the files you create in the tutorial.

Lesson 1: Set up the Adaptive Server Anywhere databases
Lesson 2: Start the database servers
Lesson 3: Set up the Open Servers in your system
Lesson 4: Confirm that the Open Servers are configured properly
Lesson 5: Add Replication Server information to the primary database
Lesson 6: Create the table for the primary database
Lesson 7: Add Replication Server information to the replicate database
Lesson 8: Create the tables for the replicate database
Lesson 9: Set up Replication Server
Lesson 10: Enter data at the primary site for replication


Lesson 1: Set up the Adaptive Server Anywhere databases

This section describes how to create and set up the Adaptive Server Anywhere databases for replication.

You can create a database using Sybase Central or the dbinit utility. For this tutorial, we use the dbinit utility.

toggle Create the primary site database

  • Enter the following command from the tutorial directory you created (for example, c:\tutorial).

    dbinit primedb

    This creates a database file primedb.db in the current directory.

toggle Create the replicate site database

  • Enter the following command from the tutorial directory you created (for example c:\tutorial).

    dbinit repdb

    This creates a database file repdb.db in the current directory.

What's next?

Next, you have to start database servers running on these databases.


Lesson 2: Start the database servers

You need to run the primary site database server, with the primary database loaded.

toggle Start the primary site database server

  1. Change to the tutorial directory.

  2. Enter the following command to start a network database server running the primedb database. You should be using the TCP/IP network communication protocol on the default communications port (2638):

    dbsrv9 -x tcpip primedb.db
toggle Start the replicate site database server

  1. Change to the tutorial directory.

  2. Enter the following command to start a network database server running the repdb database, but on a different port:

    dbsrv9 -x tcpip(port=2639) -n REPSV repdb.db
What's next?

Next, you have to make entries for each of the Adaptive Server Anywhere servers in an interfaces file, so Replication Server can communicate with these database servers.


Lesson 3: Set up the Open Servers in your system

You need to add a set of Open Servers to the list of Open Servers in your system.

Adding Open Servers

Open Servers are defined in your interfaces file (SQL.ini) using the DSEdit utility. For NetWare and UNIX users, the interfaces file is named interfaces, and the utility is named sybinit.

For full instructions on how to add definitions to your interfaces file, see Configuring Open Servers.

Required Open Servers

For each Open Server definition, you must provide a name and an address. Do not alter the other attributes of the definition. You need to add an Open Server entry for each of the following:

  • The primary database Create an entry named PRIMEDB with address as follows:

    • Protocol NLWNSCK

    • Network address localhost,2638

  • The replicate database Create an entry named REPDB with address as follows:

    • Protocol NLWNSCK

    • Network address localhost,2639

  • The LTM at the primary database This is necessary so you can shut down the LTM properly. Create an entry named PRIMELTM with address as follows:

    • Protocol NLWNSCK

    • Network address localhost,2640

  • Your Replication Server This tutorial assumes you already have the Replication Server Open Server defined.

What's next?

Next, confirm that the Open Servers are configured properly.


Lesson 4: Confirm that the Open Servers are configured properly

You can confirm that each Open Server is available by selecting ServerObject > Ping Server from the DSEdit utility.

Alternatively, you can confirm that each Open Server is configured properly by connecting to the database using an Open Client application such as the isql utility.

To start isql running on the primary site database, type

isql -U DBA -P SQL -S PRIMEDB

The Open Client isql utility is not the same as the Adaptive Server Anywhere Interactive SQL utility.


Lesson 5: Add Replication Server information to the primary database

You need to add Replication Server tables and procedures to the primary site database for the database to participate in a Replication Server installation. You also need to create two user IDs for use by Replication Server. The SQL command file rssetup.sql comes with Adaptive Server Anywhere and carries out these tasks.

The rssetup.sql command file must be run on the Adaptive Server Anywhere server from the Interactive SQL utility.

toggle Run the rssetup script

  1. From Interactive SQL, connect to the Adaptive Server Anywhere database as user ID DBA using password SQL.

  2. Run the rssetup script using the following command:

    read "path\rssetup.sql"

    where path is your Adaptive Server Anywhere installation directory.

    You can alternatively use File > Run Script, and browse to the file.

Actions carried out by rssetup.sql

The rssetup.sql command file carries out the following functions:

  • Creates a user named dbmaint, with password dbmaint and with DBA permissions. This is the maintenance user name and password required by Replication Server to connect to the primary site database.

  • Creates a user named sa, with password sysadmin and with DBA permissions. This is the user ID used by Replication Server when materializing data.

  • Adds sa and dbmaint to a group named rs_systabgroup.

Passwords and user IDs

While the hard-wired user IDs (dbmaint and sa) and passwords are useful for test and tutorial purposes, you should change the password and perhaps also the user IDs when running databases that require security. Users with DBA permissions have full authority in an Adaptive Server Anywhere database.

The user ID sa and its password must match that of the system administrator account on the Replication Server. Adaptive Server Anywhere does not currently accept a NULL password.

Permissions

The rssetup.sql script carries out a number of operations, including some permissions management. The permissions changes made by rssetup.sql are outlined here. You do not have to make these changes yourself.

For replication, ensure that the dbmaint and sa users can access this table without explicitly specifying the owner. To do this, the table owner user ID must have group membership permissions, and the dbmaint and sa users must be members of the table owner group. To grant group permissions, you must have DBA authority.

For example, if user DBA owns the table, you should grant group permissions to the DBA user ID:

GRANT GROUP
TO DBA

You should then grant the dbmaint and sa users membership in the DBA group. To grant group membership, you must either have DBA authority or be the group ID.

GRANT MEMBERSHIP
IN GROUP "DBA"
TO dbmaint ;
GRANT MEMBERSHIP
IN GROUP "DBA"
TO sa ;


Lesson 6: Create the table for the primary database

In this section, you create a single table in the primary site database, using isql. First, make sure you are connected to the primary site database:

isql -U DBA -P SQL -S PRIMEDB

Next, create a table in the database:

CREATE TABLE news (
  ID int,
  AUTHOR char( 40 ) DEFAULT CURRENT USER,
  TEXT char( 255 ),
  PRIMARY KEY ( ID, AUTHOR )
)
go
Identifier case sensitivity
In Adaptive Server Anywhere, all identifiers are case insensitive. In Adaptive Server Enterprise, identifiers are case sensitive by default. Even in Adaptive Server Anywhere, ensure the case of your identifiers matches in all parts of the SQL statement to ensure compatibility with Adaptive Server Enterprise.

In Adaptive Server Anywhere, the database determines password case sensitivity unless you explicitly set the case sensitivity for passwords. You can have a case sensitive database with case insensitive passwords, and vice versa. Extended characters used in passwords are case sensitive, regardless of the password case sensitivity setting. User IDs, being identifiers, are case insensitive in all Adaptive Server Anywhere databases.

For more information, see CREATE DATABASE statement.

For news to act as part of a replication primary site, you must set the REPLICATE flag to ON for the table using an ALTER TABLE statement:

ALTER TABLE news
REPLICATE ON
go

This is equivalent to running the sp_setreplicate or sp_setreptable procedure on the table in Adaptive Server Enterprise. You cannot set REPLICATE ON in a CREATE TABLE statement.


Lesson 7: Add Replication Server information to the replicate database

You should run the rssetup.sql command file on the replicate database in exactly the same manner as it ran on the primary database. Also ensure that the dbmaint and sa users can access this table without explicitly specifying the table owner.

These tasks are the same as those carried out on the primary database. For a complete explanation, see Lesson 5: Add Replication Server information to the primary database.


Lesson 8: Create the tables for the replicate database

The replicate site database needs to have tables to hold the data it receives. Now is a good time to create these tables. As long as the database elements are in place, no extra statements are necessary for them to act as a replicate site in a Replication Server installation. In particular, you do not need to set the REPLICATE flag to ON, which is necessary only at the primary site.

Replication Server allows replication between tables and columns with different names. As a simple example, however, create a table in the replicate database identical in definition to that in the primary database (except for the REPLICATE flag, which is not set to ON in the replicate database). The table creation statement for this is:

CREATE TABLE news (
   ID int,
   AUTHOR char( 40 ) DEFAULT CURRENT USER,
   TEXT char( 255 ),
   PRIMARY KEY ( ID, AUTHOR )
)
go

For the tutorial, the CREATE TABLE statement must be exactly the same as that at the primary site.

You must ensure that the users dbmaint and sa can access this table without specifying the owner name. Also, these user IDs must have SELECT and UPDATE permissions on the table.


Lesson 9: Set up Replication Server

You need to carry out the following tasks on the Replication Server:

  • Create a connection for the primary site data server.

  • Create a connection for the replicate site data server.

  • Create a replication definition.

  • Create a subscription to the replication.

This section describes each of these tasks. It also describes starting the Adaptive Server Anywhere LTM.

Create a connection for the primary site
Create a connection for the replicate site.
Create a replication definition
Configure and start the Adaptive Server Anywhere LTM
Create a subscription for your replication


Create a connection for the primary site

Using isql, connect to Replication Server and create a connection to the primary site Adaptive Server Anywhere database.

The following command creates a connection to the primedb database on the PRIMEDB Open Server.

create connection to PRIMEDB.primedb
set error class rs_sqlserver_error_class
set function string class rs_sqlserver_function_class
set username dbmaint
set password dbmaint
with log transfer on
go

If you have changed the dbmaint user ID and password in the rssetup.sql command file, make sure you replace the dbmaint username and password in this command.

Replication Server does not actually use the primedb database name; instead, the database name is read from the command line of the PRIMEDB Open Server. You must, however, include a database name in the CREATE CONNECTION statement to conform to the syntax.

For a full description of the create connection statement, see the chapter "Replication Server Commands" in the Replication Server Reference Manual.


Create a connection for the replicate site.

Using isql, connect to Replication Server and create a connection to the replicate site Adaptive Server Anywhere database.

The following command creates a connection to the repdb database on the REPDB Open Server.

create connection to REPDB.repdb
set error class rs_sqlserver_error_class
set function string class rs_sqlserver_function_class
set username dbmaint
set password dbmaint
go

This statement differs from the primary site server statement in that there is no with log transfer on clause in this statement.

If you have changed the dbmaint user ID and password in the rssetup.sql command file, make sure you replace the dbmaint username and password in this command.


Create a replication definition

Using isql, connect to Replication Server and create a replication definition. The following statement creates a replication definition for the news table on the primedb database:

create replication definition news
with primary at PRIMEDB.primedb
( id int, author char(40), text char(255) )
primary key ( id, author )
go

For a full description of the CREATE REPLICATION DEFINITION statement, see your Replication Server Reference Manual.

If you set the qualify_table_owner option to on in the LTM configuration file, you must specify the table owner in the statement, for all replicating tables.


Configure and start the Adaptive Server Anywhere LTM

For replication to take place, the Adaptive Server Anywhere LTM must be running against the primary site server. Before you start the Adaptive Server Anywhere LTM, make sure it is properly configured by editing an LTM configuration file.

Below is a sample configuration file for the primedb database. If you are following the examples, you should make a copy of this file as primeltm.cfg:

#
# Configuration file for 'PRIMELTM'
#
SQL_server=PRIMEDB
SQL_database=primedb
SQL_user=sa
SQL_pw=sysadmin
RS_source_ds=PRIMEDB
RS_source_db=primedb
RS=your_rep_server_name_here
RS_user=sa
RS_pw=sysadmin
LTM_admin_user=DBA
LTM_admin_pw=SQL
LTM_charset=cp850
scan_retry=2
APC_user=sa
APC_pw=sysadmin
SQL_log_files=C:\TUTORIAL

If you have changed the user ID and password in the rssetup.sql command file from sa and sysadmin, you should use the new user ID and password in this configuration.

To start the Adaptive Server Anywhere LTM running on the primary site server, enter the following command:

dbltm -S PRIMELTM -C primeltm.cfg

The connection information is in primeltm.cfg. In this command, PRIMELTM is the server name of the LTM.

You can find usage information about the Adaptive Server Anywhere LTM by typing the following statement:

dbltm -?

You can run the Adaptive Server Anywhere LTM as a Windows service.

For information on running programs as services, see Running the server outside the current session.


Create a subscription for your replication

Using isql, connect to Replication Server and create a subscription for the replication.

The following statement creates a subscription for the news replication defined in Create a replication definition with replicate site as the repdb database.

create subscription NEWS_SUBSCRIPTION
for news
with replicate at REPDB.repdb
go

You have now completed your installation. Try replicating data to confirm that the setup is working properly.


Lesson 10: Enter data at the primary site for replication

You can now replicate data from the primary database to the replicate database. As an example, connect to the primary database using the isql utility, and enter a row in the news table.

insert news (id, text)
values (1, 'Test news item.' )
commit
go

The Adaptive Server Anywhere LTM sends only committed changes to the Replication Server. The data change is replicated next time the LTM polls the transaction log.

Tutorial complete

You have now completed the tutorial.


Configuring databases for Replication Server

Each Adaptive Server Anywhere database that participates in a Replication Server installation needs to be configured before it can do so. Configuring the database involves the following tasks:

  • Selecting a secure user ID for the maintenance user and the name used by Replication Server when materializing data.

  • Setting up the database for Replication Server.

  • Configuring the language and character set, where necessary.

Configuring the LTM

Each primary site Adaptive Server Anywhere database requires an LTM to send data to Replication Server. Each primary or replicate site Adaptive Server Anywhere database requires an Open Server definition so that Replication Server can connect to the database.

For information on configuring the LTM, see Configuring the LTM.


Setting up the database for Replication Server

Once you have created your Adaptive Server Anywhere database and created the necessary tables and so on within the database, you can make database ready for use with Replication Server. You do this using a setup script supplied with the Adaptive Server Anywhere Replication Agent product. The script is named rssetup.sql.

When you need to run the setup script

You need to run the setup script at any Adaptive Server Anywhere database that is taking part in a Replication Server installation, whether as a primary or a replicate site.

What the setup script does

The setup script creates user IDs required by Replication Server when connecting to the database. It also creates a set of stored procedures and tables used by Replication Server. The tables begin with the characters rs_, and the procedures begin with the characters sp_. Procedures include some that are important for character set and language configuration.


Prepare to run the setup script

Replication Server uses a special data server maintenance user login name for each local database containing replicated tables. This allows Replication Server to maintain and update the replicated tables in the database.

The maintenance user

The setup script creates a maintenance user with name dbmaint and password dbmaint. The maintenance user has DBA permissions in the Adaptive Server Anywhere database, which allows it full control over the database. For security reasons, you should change the maintenance user ID and password.

toggle To change the maintenance user ID and password

  1. Open the rssetup.sql setup script in a text editor. The script is held in the scripts subdirectory of your Adaptive Server Anywhere installation directory.

  2. Change all occurrences of the dbmaint user ID to the new maintenance user ID of your choice.

  3. Change the dbmaint password to the new maintenance user password of your choice. The password occurs in the following place at the top of the setup script file:

    GRANT CONNECT TO dbmaint
IDENTIFIED BY dbmaint
The materialization user ID

When Replication Server connects to a database to materialize the initial copy of the data in the replication, it does so using the Replication Server system administrator account.

The Adaptive Server Anywhere database must have a user ID and password that match the Replication Server system administrator user ID and password. Adaptive Server Anywhere does not accept a NULL password.

The setup script assumes a user ID of sa and a password of sysadmin for the Replication Server administrator. You should change this to match the actual name and password.

toggle To change the system administrator user ID and password

  1. Open the rssetup.sql setup script in a text editor.

  2. Change all occurrences of the sa user ID to match the Replication Server system administrator user ID.

  3. Change the sa password to match the Replication Server system administrator password. The password has the initial setting of sysadmin.


Run the setup script

Once you have modified the setup script to match the user IDs and passwords appropriately, you can run the setup script to create the maintenance and system administrator users in the Adaptive Server Anywhere database.

toggle To run the setup script

  1. Start the Adaptive Server Anywhere database on an Adaptive Server Anywhere database server.

  2. Start the Interactive SQL utility, and connect to the database as a user with DBA authority. When you create an Adaptive Server Anywhere database, it has a user with user ID DBA and password SQL, which has DBA authority.

  3. Run the script by entering the following command in the SQL Statements pane:

    read path\rssetup.sql

    where path is the path to the setup script.


Character set and language issues

Upon creation, each Adaptive Server Anywhere database is assigned a specific collation (character set and sort order). Replication Server uses a different set of identifiers for character sets and sort orders.

Set the character set and language parameters in the LTM configuration file. If you are unsure of the characters set label to specify, you can do the following to determine the character set of the server:

toggle To determine the character set

  • Execute the following command:

    exec sp_serverinfo csname

The language is one of the language labels listed in Language label values.


Using the LTM

Since the Adaptive Server Anywhere LTM relies on information in the Adaptive Server Anywhere transaction log, take care not to delete or damage the log without storing backups (for example, using a transaction log mirror).

For more information about transaction log management, see the section Transaction log and backup management.

You cannot substitute an Adaptive Server Anywhere LTM for an Adaptive Server Enterprise LTM since the transaction logs have different formats.

The Adaptive Server Anywhere LTM supports replication of inserts, updates, and deletes, as well as replication of Transact-SQL dialect stored procedure calls.

The Adaptive Server Enterprise LTM sends data changes to the Replication Server before they are committed. The Replication Server holds the changes until a COMMIT statement arrives. By contrast, the Adaptive Server Anywhere LTM sends only committed changes to Replication Server. For long transactions, this may lead to some added delay in replication, since all changes have to go through the Replication Server before distribution.

Configuring tables for replication
Preparing procedures and functions for replication
SQL Statements for controlling procedure replication
Asynchronous procedures
Configuring the LTM
Language and character set issues
Transaction log and backup management
Replicating an entire database
Stopping the LTM


Configuring tables for replication

Adaptive Server Anywhere does not support the sp_setreplicate system procedure. Instead, a table is identified as a primary data source using the ALTER TABLE statement with a single clause:

ALTER TABLE table-name
SET REPLICATE ON
The effects of setting REPLICATE ON for a table

Setting REPLICATE ON places extra information into the transaction log. Whenever an UPDATE, INSERT, or DELETE action occurs on the table. The Adaptive Server Anywhere Replication Agent uses this extra information to submit the full pre-image of the row, where required, to Replication Server for replication.

Even if only some of the data in the table needs to be replicated, all changes to the table are submitted to Replication Server. It is Replication Server's responsibility to distinguish the data to be replicated from that which is not.

When you update, insert, or delete a row, the pre-image of the row is the contents of the row before the action, and the post-image is the contents of the row after the action. For INSERTS, only the post-image is submitted (the pre-image is empty). For DELETES, the post-image is empty and only the pre-image is submitted. For UPDATES, both the pre-image and the updated values are submitted.

The following data types are supported for replication:

Data type | Description ( Open Client/Open Server type )
Exact integer data types | int, smallint, tinyint
Exact decimal data types | decimal, numeric
Approximate numeric data types | float (8-byte), real
Money data types | money, smallmoney
Character data types | char(n), varchar(n), text
Date and time data types | datetime, smalldatetime
Binary data types | binary(n), varbinary(n), image
Bit data types | bit
Notes

Adaptive Server Anywhere supports data of zero length that is not NULL. However, non-null long varchar and long binary data of zero length is replicated to a replicate site as NULL.

If a primary table has columns with unsupported data types, you can replicate the data if you create a replication definition using a compatible supported data type. For example, to replicate a DOUBLE column, you could define the column as FLOAT in the replication definition.

Side effects of setting REPLICATE ON for a table

There can be a replication performance hit for heavily updated tables. You could consider using replicated procedures if you experience performance problems that may be related to replication traffic, since replicated procedures send only the call to the procedure instead of each individual action.

Since setting REPLICATE ON sends extra information to the transaction log, this log grows faster than for a non-replicating database.

Minimal column replication definitions

The Adaptive Server Anywhere LTM supports the Replication Server replicate minimal columns feature. This feature is enabled at Replication Server.

For more information on replicate minimal columns, see your Replication Server documentation.


Preparing procedures and functions for replication

You can use stored procedures to modify the data in tables. Updates, inserts, and deletes execute from within the procedure.

Replication Server can replicate procedures as long as they satisfy certain conditions. The first statement in a procedure must carry out an update for the procedure to be replicated.

For a full description of how Replication Server replicates procedures, see your Replication Server documentation.

Adaptive Server Anywhere supports two dialects for stored procedures: the Watcom-SQL dialect, based on the draft ISO/ANSI standard, and the Transact-SQL dialect. You must use Transact-SQL to write stored procedures for replication.

Function APC format

The Adaptive Server Anywhere LTM supports the Replication Server function APC format. To make use of these functions, set the configuration parameter rep_func to on (the default is off).

The LTM interprets all replicated APCs as either table APCs or function APCs. A single Adaptive Server Anywhere database cannot combine function APCs with other table APCs.

For more information about replicate functions, see your Replication Server documentation.


SQL Statements for controlling procedure replication

A procedure can be configured to act as a replication source using the ALTER PROCEDURE statement.

The following statement makes the procedure MyProc act as a replication source.

ALTER PROCEDURE MyProc
REPLICATE ON

The following statement prevents the procedure MyProc from acting as a replication source.

ALTER PROCEDURE MyProc
REPLICATE OFF

These statements have the same effect as running sp_setreplicate or sp_setrepproc 'table' on the procedure in Adaptive Server Enterprise. The sp_setrepproc 'function' syntax is not supported.

The effects of setting REPLICATE ON for a procedure

When a procedure is used as a replication data source, calling the procedure sends extra information to the transaction log.


Asynchronous procedures

A procedure called at a replicate site database to update data at a primary site database is an asynchronous procedure. The procedure carries out no action at the replicate site, but rather, the call to the procedure is replicated to the primary site, where a procedure of the same name executes. This is called an asynchronous procedure call (APC). The changes made by the APC are then replicated from the primary to the replicate database in the usual manner.

For information about APCs, see your Replication Server documentation.

The APC_user and APC support

Support for APCs in Adaptive Server Anywhere is different from that in Adaptive Server Enterprise. In Adaptive Server Enterprise, each APC executes using the user ID and password of the user who called the procedure at the replicate site. In Adaptive Server Anywhere, however, the transaction log does not store the password, and so it is not available at the primary site. To work around this difference, the LTM configuration file holds a single user ID with associated password, and this user ID (the APC_user) executes the procedure at the primary site. The APC_user must, therefore, have appropriate permissions at the primary site for each APC that may be called.


Configuring the LTM

You control LTM behavior by modifying the LTM configuration file, which is a plain text file created and edited using a text editor. The LTM configuration file contains information the LTM needs, such as the Adaptive Server Anywhere server it transfers a log from, the Replication Server it transfers the log to. You need a valid configuration file to run the LTM.

Creating a configuration file

You must create a configuration file, using a text editor, before you can run the LTM. The -C LTM command specifies the name of the configuration file to use, and has a default of dbltm.cfg.

Configuration file format

The LTM configuration file shares the same format as the Replication Server configuration file described in your Replication Server Administration Guide. In summary:

  • The configuration file contains one entry per line.

  • An entry consists of a parameter, followed by the = character, followed by the value:

    Entry=value

  • Lines beginning with a # character are comments ignored by the LTM.

  • The configuration file cannot contain leading blanks.

  • Entries are case sensitive.

For the full list of available configuration file parameters, see The LTM configuration file.

Example configuration file

  • The following is a sample Adaptive Server Anywhere LTM configuration file.

    # This is a comment line
# Names are case sensitive.
SQL_user=sa
SQL_pw=sysadmin
SQL_server=PRIMESV
SQL_database=primedb
RS_source_ds=PRIMESV
RS_source_db=primedb
RS=MY_REPSERVER
RS_user=sa
RS_pw=sysadmin
LTM_admin_user=DBA
LTM_admin_pw=SQL
LTM_charset=cp850
scan_retry=2
SQL_log_files=e:\logs\backup
APC_user=sa
APC_pw=sysadmin

Replicating transactions in batches


Replicating transactions in batches
Effects of buffering transactions

The LTM allows buffering of replication commands to Replication Server. Buffering the replication commands and sending them in batches results in fewer messages being sent, and can significantly increase overall throughput, especially on high volume installations.

How batch mode works

By default, the LTM buffers transactions. The buffer flushes (the transactions sent to Replication Server when the buffer:

  • Reaches maximum number of commands The batch_ltl_sz parameter sets the maximum number of LTL (log transfer language) commands stored in the buffer before it flushes. The default setting is 200.

  • Reaches maximum memory used The batch_ltl_mem parameter sets the maximum memory that the buffer can occupy before flushes. The default setting is 256K.

  • Completes transaction log processing If there are no more entries in the transaction log to process (that is, the LTM is up to date with all committed transactions), then the buffer flushes.

Turning off buffering

You can turn off buffering of transactions by setting the batch_ltl_cmds parameter to off:

batch_ltl_cmds=off


Language and character set issues

Language and character set issues are an important consideration in many replication sites. Each database and server in the system uses a specific collation (character set and sorting order) for storing and ordering strings. Adaptive Server Anywhere character set support is carried out in a different manner to character set support in Adaptive Server Enterprise and other Open Client/Open Server based applications.

This section describes how to configure the Adaptive Server Anywhere LTM such that data in an Adaptive Server Anywhere database can be shared with Replication Server and hence with other databases.

The LTM automatically uses the default Open Client/Open Server language, sort order, and character set. You can override these defaults by adding entries to the LTM configuration file.


Open Client/Open Server collations

Adaptive Server Enterprise, Replication Server, and other Open Client/Open Server applications share a common means of managing character sets.

For information on Open Client/Open Server character set support, see the chapter "Configuring Character Sets, Sort Orders, and Languages" in the Adaptive Server Enterprise System Administration Guide.

For more information about character set issues in Replication Server, see the chapter "International Replication Design Considerations" in the Replication Server Design Guide.

This section provides a brief overview of Open Client/Open Server character set support.

Internationalization files

Files that support data processing in a particular language are called internationalization files. Several types of internationalization files come with Adaptive Server Enterprise and other Open Client/Open Server applications.

There is a directory named charsets under your Sybase directory. Charsets has a set of subdirectories, including one for each character set available to you. Each character set contains a set of files, as described in the following table

File | Description
Charset.loc | Character set definition files that define the lexical properties of each character such as alphanumeric, punctuation, operand, upper or lower case.
*.srt | Defines the sort order for alphanumeric and special characters.
*.xlt | Terminal-specific character translation files for use with utilities.


Character set settings in the LTM configuration file

Three settings in the LTM configuration file refer to character set issues:

  • LTM_charset The character set for the LTM to use. You can specify any Sybase-supported character set.

  • LTM_language The language used by the LTM to print its messages to the error log and to its clients. You can choose any language to which the LTM has been localized, as long as it is compatible with the LTM character set.

    The Adaptive Server Anywhere LTM has been localized to several languages.

Notes

Character set In an Open Client/Open Server environment, an LTM should use the same character set as the data server and Replication Server attached to it.

Adaptive Server Anywhere character sets are specified differently than Open Client/Open Server character sets. Consequently, the requirement is that the Adaptive Server Anywhere character set be compatible with the LTM character set.

Language The locales.dat file in the locales subdirectory of the Sybase release directory contains valid map settings. However, the LTM output messages in the user interface are currently available in those languages to which the LTM has been localized.

Sort order All sort orders in your replication system should be the same. You can find the default entry for your platform in the locales.dat file in the locales subdirectory of the Sybase release directory.

Example

  • The following settings are valid for a Japanese installation:

    LTM_charset=SJIS
LTM_language=Japanese


Transaction log and backup management

One of the differences between the Adaptive Server Enterprise LTM and the Adaptive Server Anywhere LTM is that while the Adaptive Server Enterprise LTM depends on a temporary recovery database for access to old transactions, the Adaptive Server Anywhere LTM depends on access to old transaction logs. No temporary recovery database exists for the Adaptive Server Anywhere LTM.

Replication depends on access to operations in the transaction log, and for Adaptive Server Anywhere primary site databases, sometimes access to old transaction logs. This section describes how to set up backup procedures at an Adaptive Server Anywhere primary site to ensure proper access to old transaction logs.

Consequences of lost transaction logs

Good backup practices at Adaptive Server Anywhere primary database sites are crucial. A lost transaction log could mean rematerializing replicate site databases. At primary database sites, a transaction log mirror is recommended.

For information on transaction log mirrors and other backup procedure information, see Backup and Data Recovery.

The LTM configuration file contains a directory entry, which points to the directory where backed up transaction logs are kept. This section describes how to set up a backup procedure to ensure that such a directory stays in proper shape.

Backup utility options

With the Backup utility, you have the option of renaming the transaction log on backup and restart. For the dbbackup utility, this is the -r option. It is recommended that you use this option when backing up the consolidated database and remote database transaction logs.

For example, consider a database named primedb.db, in directory c:\prime, with a transaction log in directory d:\primelog\primedb.log. Backing up this transaction log to a directory e:\primebak using the rename and restart option carries out the following tasks:

  1. Backs up the transaction log, creating a backup file e:\primebak\primedb.log.

  2. Renames the existing transaction log to d:\primelog\YYMMDDxx.log, where xx are sequential characters ranging from AA to ZZ.

  3. Starts a new transaction log, as d:\primelog\primedb.log.

After several backups, the directory d:\primelog will contain a set of sequential transaction logs. The log directory should not contain any transaction logs other than the sequence of logs generated by this backup procedure.


Using the DELETE_OLD_LOGS option

The DELETE_OLD_LOGS Adaptive Server Anywhere database option's default is OFF. If you set the default to ON, then the LTM automatically deletes the old transaction logs when Replication Server no longer needs access to the transactions. This option can help to manage disk space in replication setups.

You set the DELETE_OLD_LOGS option for the PUBLIC group:

SET OPTION PUBLIC.DELETE_OLD_LOGS = 'ON'

For more information, see DELETE_OLD_LOGS option [replication].


The Unload utility and replication

If a database participates in replication, care must be taken when unloading and reloading in order to avoid needing to re-materialize the database. Replication is based on the transaction log, and unloading and reloading a database deletes the old transaction log. For this reason, good backup practices are especially important when participating in replication.


Replicating an entire database

Adaptive Server Anywhere provides a shortcut for replicating an entire database, so you don't have to set each table in the database as a replicated table.

You can set a PUBLIC database option called REPLICATE_ALL using the SET OPTION statement. You can designate a whole database for replication using the following command:

SET OPTION PUBLIC.Replicate_all='ON'

You require DBA authority to change this and other PUBLIC option settings. You must restart the database for the new setting to take effect. The REPLICATE_ALL option has no effect on procedures.

For more information, see REPLICATE_ALL option [replication].


Stopping the LTM

You can shut down the LTM from the user interface in Windows NT/2000/XP, or in other circumstances by issuing a command.

toggle To stop the LTM in Windows NT/2000/XP, when the LTM is not running as a service

  • Click Shutdown on the user interface.

toggle To stop the LTM by issuing a command

  1. Connect to the LTM from isql using the LTM_admin_user login name and password in the LTM configuration file. The user ID and password are case sensitive.

  2. Stop the LTM using the SHUTDOWN statement.

Example

  • The following statements connect isql to the LTM PRIMELTM, and shut it down:

    isql -SPRIMELTM -UDBA -PSQL
1> shutdown
2> go


Database Administration Utilities

About this chapter

Adaptive Server Anywhere includes a set of utility programs for backing up databases and performing other database administration tasks. This chapter provides reference information for each of the database administration utilities.

Administration utilities overview
The Adaptive Server Anywhere Console utility
The Backup utility
The Collation utility
The Compression utility (deprecated)
The Data Source utility
The Erase utility
The File Hiding utility
The Histogram utility
The Information utility
The Initialization utility
The Interactive SQL utility
The Language utility
The License utility
The Log Transfer Manager
The Log Translation utility
The Ping utility
The Rebuild utility
The Server Location utility
The Service Creation utility
The Spawn utility
The Stop utility
The Transaction Log utility
The Uncompression utility (deprecated)
The Unload utility
The Upgrade utility
The Validation utility
The Write File utility (deprecated)


Administration utilities overview

This chapter presents reference information on the programs and database administration utilities that are part of Adaptive Server Anywhere. Each of the utilities can be accessed from one or more of Sybase Central, Interactive SQL, or at a command prompt.

For comprehensive documentation on Sybase Central, see the Sybase Central online help. For an introduction to the Sybase Central database administration tool, see Managing Databases with Sybase Central.

The administration utilities use a set of system environment variables. These variables are described in Environment variables.

Database file administration statements

A set of SQL statements are available that carry out some of the tasks that the administration utilities carry out. These statements are listed in SQL Statements.

Using configuration files


Using configuration files

Many of the utilities provided with SQL Anywhere Studio allow you to store command line options in a configuration file. If you use an extensive set of options, you may find it useful to store them in a configuration file.

The @data option allows you to specify environment variables and configuration files on the command line. To specify a configuration file, replace data with the path and name of the configuration file.

Configuration files can contain line breaks, and can contain any set of options, including the @data option. You can use the number sign (#) to designate lines as comments.

The @data parameter can occur at any point in the command line, and parameters contained in the file are inserted at that point. You can use @data multiple times on one command line to specify multiple configuration files.

Utilities read the command line by expanding the specified configuration files and reading the entire command line from left to right. If you specify options that are overridden by other options in the command line, the option closer to the end of the line wins. In some cases, conflicting options result in an error.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information about obfuscating the contents of a configuration file, see Hiding the contents of files using the dbfhide command-line utility.

Example

The following configuration file holds a set of options for the Validation utility (dbvalid):

#Connect to the sample database as user ASA with password SQL
-c "uid=DBA;pwd=SQL;dbf=c:\Program Files\Sybase\SQL Anywhere 9\asademo.db"
#Perform a full check on each table
-f
#Log output messages to the specified file
-o "c:\validationlog.txt

If this configuration file is saved as c:\config.txt, it can be used in a command as follows:

dbvalid @c:\config.txt


The Adaptive Server Anywhere Console utility

The Adaptive Server Anywhere Console provides administration and monitoring facilities for database server connections.

The Adaptive Server Anywhere Console is available on all supported platforms except Windows CE, AIX, HP-UX, HP-UX Itanium, Linux Itanium, and Compaq Tru64. On these platforms, you can use the connection-level, server-level, and database-level properties to obtain information or you can monitor your server from a machine running an operating system that supports the Adaptive Server Anywhere Console (such as Windows 95/98/Me, Windows NT/2000/XP, Mac OS X, or Linux).

For more information about obtaining property values, see Database Performance and Connection Properties.

Monitoring connections using the dbconsole utility


Monitoring connections using the dbconsole utility

Syntax

dbconsole [ options ]

Option | Description
-c "keyword=value; ..." | Database connection parameters.
Description

The Adaptive Server Anywhere Console allows you to monitor the server from a client machine. You can use it to track who is logged on to a database server elsewhere on your network. You can also display both server and client statistics on your local client screen, disconnect users, and configure the database server. The Adaptive Server Anywhere Console can display information for multiple connections.

toggle To disconnect a user from a database

  1. Connect to the database from the Adaptive Server Anywhere Console.

  2. In the User ID column, right-click the user and choose Disconnect.

    You can configure the columns that appear in the Adaptive Server Anywhere Console in the Options dialog, which can be accessed by choosing File > Options.

This utility does not accept the @data parameter to read in options from a configuration file.

Console utility options

-c "keyword=value; ..."

Specify connection parameters.

For a description of supported connection parameters, see Connection parameters.


The Backup utility

You can use the Backup utility to back up the database files and transaction logs for running databases.

You can access the Backup utility in the following ways:

  • From Sybase Central, using the Create Backup Images wizard.

  • At a command prompt, using the dbbackup command. This is useful for incorporating backup procedures into batch or command files.

  • From Interactive SQL, using the BACKUP DATABASE statement.

The Backup utility makes a backup copy of all the files for a single database. A simple database consists of two files: the main database file and the transaction log. More complicated databases can store tables in multiple files, with each file as a separate dbspace. All backup filenames are the same as the database filenames.

Running the Backup utility on a running database is equivalent to copying the database files when the database is not running. Thus, you can back up the database while other applications or users are using it.

Exit codes are 0 (success) or non-zero (failure).

For a description of suggested backup procedures, see Backup and Data Recovery.


Backing up a database using the Create Backup Images wizard

toggle To back up a database file or a running database

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Create Backup Images.

    The Create Backup Images wizard appears.

  4. Follow the instructions in the wizard.

For full information on backing up a database from Sybase Central, see Backup and Data Recovery.

Tip
You can also access the Create Backup Images Database wizard from within Sybase Central using any of the following methods:

  • Choosing Tools > Adaptive Server Anywhere 9 > Create Backup Images.

  • Selecting a database in the left pane, and choosing Create Backup Images from the File menu.

  • Right-clicking a database, and choosing Create Backup Images from the popup menu.


Backing up a database using the dbbackup command-line utility

Syntax

dbbackup [ options ] target-directory

Option | Description
@data | Read options from the specified environment variable or configuration file.
-c "keyword=value; ..." | Supply database connection parameters.
-d | Only back up the main database file.
-l file | Live backup of the transaction log to a file.
-n | Change the naming convention for the backup transaction log.
-o filename | Log output messages to a file.
-q | Quiet mode—do not print messages.
-r | Rename and start a new transaction log.
-s | Perform an image backup on the server using the BACKUP statement.
-t | Back up only the transaction log.
-w | Back up only the write file.
-x | Delete and restart the transaction log.
-xo | Delete and restart the transaction log without making a backup.
-y | Replace files without confirmation.
target-directory | The directory to which the backup files are copied.
Description

If neither of the options -d or -t are used, all database files are backed up.

If -s is specified, the backup is created on the server using the BACKUP statement. Otherwise, the backup is made on the client machine.

Backup utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Connection parameters (-c)

If the connection parameters are not specified, connection parameters from the SQLCONNECT environment variable are used, if set. The user ID must have DBA authority or REMOTE DBA authority.

For a description of the connection parameters, see Connection parameters.

For example, the following command backs up the asademo database running on the server sample_server, connecting as user ID DBA with password SQL, into the asabackup directory:

dbbackup -c "eng=sample_server;dbn=asademo;uid=DBA;pwd=SQL" asabackup

Back up main database only (-d)

Back up the main database files only, without backing up the transaction log file, if one exists.

Live backup (-l lower-case L)

This option is provided to enable a secondary system to be brought up rapidly in the event of a server crash. A live backup does not terminate, but continues running while the server runs. It runs until the primary server becomes unavailable. At that point, it is shut down, but the backed up log file is intact and can be used to bring a secondary system up quickly.

If you specify -l, then you cannot use -s to create an image back up on the server.

For more information about live backups, see Differences between live backups and transaction log mirrors and Making a live backup.

Change backup transaction log naming convention (-n)

This option is used in conjunction with -r. It changes the naming convention of the backup transaction log file to yymmddxx.log, where xx are sequential letters ranging from AA to ZZ and yymmdd represents the current year, month, and day.

The backup copy of the transaction log file is stored in the directory specified in the command, and with the yymmddxx.log naming convention. This allows backups of multiple versions of the transaction log file to be kept in the same backup directory.

You can also use the both the -x option and the -n option to rename the log copy. For example

dbbackup -x -n

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not display output messages. This option is available only when you run this utility from a command prompt.

Rename and start new transaction log (-r)

This option forces a checkpoint and the following three steps to occur:

  1. The current working transaction log file is copied and saved to the directory specified in the command.

  2. The current transaction log remains in its current directory, but is renamed using the format yymmddxx.log, where xx are sequential characters starting at AA and running through to ZZ, and yymmdd represents the current year, month, and day. This file is then no longer the current transaction log.

  3. A new transaction log file is generated that contains no transactions. It is given the name of the file that was previously considered the current transaction log, and is used by the database server as the current transaction log.

Perform an image backup on the server (-s)

This option allows you to create an image backup on the server using the BACKUP statement. If you specify the -s option, the -l option (to create a live backup of the transaction log) cannot be used. The directory specified is a directory relative to the server's current directory, so it is recommended that you specify a full pathname. In addition, the server must have write permissions on the specified directory. When -s is specified, the Backup utility does not display progress messages and does not prompt you when it overwrites existing files. If you want to be prompted when an attempt is made to overwrite an existing file, you should not specify -s or -y.

Back up the transaction log file only (-t)

This can be used as an incremental backup since the transaction log can be applied to the most recently backed up copy of the database file(s).

Back up the database write file only (-w)

For a description of database write files, see The Write File utility (deprecated).

Delete and restart the transaction log (-x)

Back up the existing transaction log, then delete the original log and start a new transaction log.

Delete and restart the transaction log without a backup (-xo)

Delete the current transaction log and start a new one. This operation does not carry out a backup; its purpose is to free up disk space in non-replication environments.

Operate without confirming actions (-y)

Choosing this option creates the backup directory or replaces a previous backup file in the directory without confirmation. If you want to be prompted when an attempt is made to overwrite an existing file, you should not specify -s or -y.

Target-directory

The directory to which the backup files are copied. If the directory does not exist, it is created. However, the parent directory must exist.


The Collation utility

With the Collation utility, you can extract a collation (sorting sequence) into a file suitable for creating a database using a custom collation.

The file that is produced can be modified and used with Sybase Central or the -z option of dbinit to create a new database with a custom collation.

Exit codes are 0 (success) or non-zero (failure).

You must change the label on the following line in the collation file. If you do not, the custom collation will conflict with the original collation on which it is based.

Collation label (name)

For more information about custom collation sequences, see Creating a database with a custom collation.

You can access the Collation utility in the following ways:

  • From Sybase Central, using the Create Custom Collation wizard.

  • At a command prompt, using the dbcollat command.


Extracting a collation using the Create Custom Collation wizard

toggle To use the Create Custom Collation wizard

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Create Custom Collation.

    The Create Custom Collation wizard appears.

  4. Follow the instructions in the wizard.

Tip
You can also access the Create Custom Collation wizard from within Sybase Central using any of the following methods:

  • Choosing Tools > Adaptive Server Anywhere 9 > Create Custom Collation.

  • Selecting a database in the left pane, and choosing Create Custom Collation from the File menu.

  • Right-clicking a database, and choosing Create Custom Collation from the popup menu.


Extracting a collation using the dbcollat command-line utility

Syntax

dbcollat [ options ] output-file

Options | Description
@data | Read options from the specified environment variable or configuration file.
-c "keyword=value; ..." | Supply database connection parameters.
-d collation-file | Convert the definition file to INSERT statements with collation mapping placed in output-file.
-e | Include empty mappings.
-o filename | Log output messages to a file.
-q | Quiet mode—do not print messages.
-x | Use hex for extended characters (7F-FF).
-y | Replace the file without confirmation.
-z col-seq | Specify a collation sequence label.
Collation utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Connection parameters (-c)

For a description of the connection parameters, see Connection parameters. If the connection parameters are not specified, connection parameters from the SQLCONNECT environment variable are used, if set.

For example, the following command extracts a collation file from the asademo database that is running on the sample_server server, and connects as user ID DBA with password SQL:

dbcollat -c "eng=sample_server;dbn=asademo;uid=DBA;pwd=SQL" c:\sample\col

Convert the collation definition file to INSERT statements that describe the collation (-d)

When a database is created, the collation is inserted into the SYS.SYSCOLLATION system table. A mapping from the collation to character sets and Sybase TDS collations is also inserted into the SYS.SYSCOLLATIONMAPPINGS system table. This collation is selected from the set of provided collations in the collseqs.sql file or from the custom collations in the custom.sql file in the scripts subdirectory of your Adaptive Server Anywhere installation directory.

For more information about the SYSCOLLATIONMAPPINGS system table, see SYSCOLLATIONMAPPINGS system table.

Custom collations are added to the custom.sql script. The -d option converts the collation definition file that you provide into INSERT statements that can be copied into custom.sql.

For example, you can use the -d option with the dbcollat command as follows:

dbcollat -d coll-defn-file custom-file

The coll-defn-file is read and parsed as a collation definition. Output is written to custom-file. The custom-file contents must be added to custom.sql.

For more information about creating a custom collation using the -d option, see Creating a custom collation.

Include empty mappings (-e)

Normally, collations don't specify the actual value that a character is to sort to. Instead, each line of the collation sorts to one position higher than the previous line. However, older collations have gaps between some sort positions. Normally, the Collation utility skips the gaps and writes the next line with an explicit sort-position. This option causes the Collation utility to write empty mappings (consisting of just a colon (:)) for each line in the gap.

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not display output messages. This option is available only when you run this utility from a command prompt.

Use hexadecimal for extended characters [ 7F to FF ] (-x)

Extended single-byte characters (whose value is greater than hex 7F) may or may not appear correctly on your screen, depending on whether the code page on your computer is the same as the code page of the collation that you are extracting. This option causes the Collation utility to write any character from hex 7F or above as a two-digit hexadecimal number, in the form \xdd. For example:

\x80, \xFE

Without the -x option, only characters from \x00 to \x1F, \x7F and \xFF are written in hexadecimal form.

Operate without confirming actions (-y)

Choosing this option automatically replaces an existing collation file without prompting for confirmation.

Specify a collation sequence label (-z)

Specify the label of the collation to be extracted. The names of the recommended collation sequences can be found by executing the following command:

dbinit -l

If the -z option is specified with one of the available collation labels, then dbcollat does not connect to a database. Otherwise, it connects to a database and extracts the collation of that database. If the collation label does not match the collation label of the database, an error is returned.


The Compression utility (deprecated)

With the Compression utility you can compress a database file. The Compression utility reads the given database file and creates a compressed database file. Compressed databases are usually 40 to 60 per cent of their original size. The database server cannot update compressed database files: they must be used as read-only files, in conjunction with write files.

Deprecated feature
The use of compressed databases is deprecated.

The Compression utility does not compress files other than the main database file. The database to be compressed must not be running.

Exit codes are 0 (success) or non-zero (failure).

You can access the Compression utility in the following ways:

  • From Sybase Central, using the Compress Database wizard.

  • At a command prompt, using the dbshrink command. This is useful for incorporating into batch or command files.

Caution Compressing an encrypted database removes encryption from the database.


Compressing a database using the Compress Database wizard

toggle To compress a database file

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Compress Database.

    The Compress Database wizard appears.

  4. Follow the instructions in the wizard.

Tip
You can also access the Compress Database wizard from within Sybase Central by right-clicking a database, and choosing Compress Database from the popup menu, or by choosing any of the following options:

  • Choosing Tools > Adaptive Server Anywhere 9 > Compress Database.

  • Selecting a database in the left pane, and choosing Compress Database from the File menu.

  • Right-clicking a database, and choosing Compress Database from the popup menu.


Compressing a database using the dbshrink command-line utility

Syntax

dbshrink [ options ] database-file [ compressed-database-file ]

Option | Description
@data | Read options from the specified environment variable or configuration file.
-ek key | Specify encryption key.
-ep | Prompt for encryption key.
-o filename | Log output messages to a file.
-q | Quiet mode—do not print messages.
-y | Replace an existing output file without confirmation.
Description

The dbshrink utility reads database-file and creates a compressed database file. The compressed filename defaults to the same name as the original database file, but with an extension of .cdb. The output filename (with extension) must not be same as the input filename (with extension).

Compression utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Specify encryption key (-ek)

This option allows you to specify the encryption key for strongly encrypted databases directly in the command. If you have a strongly encrypted database, you must provide the encryption key to use the database or transaction log in any way. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify a key for a strongly encrypted database.

Prompt for encryption key (-ep)

This option allows you to specify that you want to be prompted for the encryption key. This option causes a dialog box to appear, in which you enter the encryption key. It provides an extra measure of security by never allowing the encryption key to be seen in clear text. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify a key for a strongly encrypted database.

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not display output messages. This option is available only when you run this utility from a command prompt.

Operate without confirming actions (-y)

Choosing this option automatically replaces existing compressed database file(s) without requesting confirmation.


The Data Source utility

The Data Source utility is a cross-platform alternative to the ODBC Administrator for creating, deleting, describing, and listing Adaptive Server Anywhere ODBC data sources.

For information about creating a data source using the ODBC Administrator, see Working with ODBC data sources.

Managing ODBC data sources using the dbdsn command-line utility


Managing ODBC data sources using the dbdsn command-line utility

Syntax

dbdsn [ modifier-options ]
{ -l[ u | s ] [ -qq ]
| -d[ u | s ] dsn
| -g[ u | s ] dsn
| -w[ u | s ] dsn [details-options;...]
| -cl[ -qq ] }

Parameters
Major option | Description
@data | Read options from the specified environment variable or configuration file.
-l[ u | s ] [ -qq ] | List either all Adaptive Server Anywhere user or system data sources. By default, user data sources are listed. Using -qq with this option lists the DSNs without any banner or titles.
-d[ u | s ] dsn | Delete the named Adaptive Server Anywhere user or system data source. User data sources is the default.
-g[ u | s ] dsn | List (get) details about the named Adaptive Server Anywhere user or system data source. User data sources is the default.
-w[ u | s ] dsn [ details-options ] | Create (write) a user or system data source definition. User data sources is the default.
-cl[ -qq ] | List available connection parameters. Using -qq with this option lists the available connection parameters without any banner or titles.
Modifier-options | Description
-b | Brief. Print connection string for the data source.
-cm | Display the data source creation command.
-q | Quiet. Do not print banner.
-v | Verbose. Print connection parameters in tabular form.
-y | Delete or overwrite data source without confirmation.
Details-options | Description
-cw | Ensure that the DBF parameter (specified using -c) is an absolute filename. If the value of DBF is not an absolute filename, the Data Source utility prepends the current working directory (CWD).
-c "keyword=value;..." | Supply database connection parameters.
-ec encryption type | Encrypt all network packets.
-o filename | Write client messages to filename.
-p size | Set maximum network packet size.
-r | Disable multiple record fetching.
-tl seconds | Client liveness timeout period.
-x list | List network drivers to run.
-z | Display debugging information.
server-name | Connect to named database server.
See also
  • Working with ODBC data sources
  • Using ODBC data sources on UNIX
Description

The Data Source utility is a cross-platform alternative to the ODBC Administrator for creating, deleting, describing, and listing Adaptive Server Anywhere ODBC data sources. The utility is useful for batch operations. On Windows operating systems, the data sources are held in the registry.

On UNIX operating systems, the data sources are held in the .odbc.ini file. When you use the Data Source utility to create or delete Adaptive Server Anywhere ODBC data sources on UNIX, the utility automatically updates the [ODBC Data Sources] section of the .odbc.ini file. If you do not specify the Driver connection parameter using the -c option on UNIX, the Data Source utility automatically adds a Driver entry with the full path of the Adaptive Server Anywhere ODBC driver based on the setting of the ASANY9 environment variable.

For more information about the .odbc.ini file, see The system information file (.odbc.ini).

Caution You should not obfuscate the odbc.ini system information file with the File Hiding utility (dbfhide) on UNIX unless you will only be using Adaptive Server Anywhere data sources. If you plan to use other data sources (for example, for MobiLink synchronization), then obfuscating the odbc.ini file may prevent other drivers from functioning properly.

The modifier options can occur before or after the major option specification.

Exit codes are 0 (success) or non-zero (failure).

Data Source utility options

When you use the Data Source utility, you can choose from major options, modifier options, and details options.

Major options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

List available connection parameters (-cl)

This convenience option lists the connection parameters supported by the dbdsn utility.

For descriptions of the Adaptive Server Anywhere connection parameters supported by the Data Source utility (dbdsn), see Connection parameters.

The Data Source utility (dbdsn) supports the following ODBC connection parameters. Boolean (true or false) arguments are either YES or 1 if true, or NO or 0 if false.

Name | Description
Delphi | Delphi cannot handle multiple bookmark values for a row. When you set this value to NO, one bookmark value is assigned to each row, instead of the two that are otherwise assigned. Setting this option to YES can improve scrollable cursor performance.
DescribeCursor This parameter lets you specify how often you want a cursor to be redescribed when a procedure is executed. The default setting is If Required.

  • Never Specify 0, N, or NO if you know that your cursors do not have to be redescribed. Redescribing cursors is expensive and can decrease performance.

  • If required Specify 1, Y, or YES if you want the ODBC driver to determine whether a cursor must be redescribed. The presence of a RESULT clause in your procedure prevents ODBC applications from redescribing the result set after a cursor is opened. This is the default setting.

  • Always If you specify 2, A, or ALWAYS, the cursor is redescribed each time it is opened. If you use Transact-SQL procedures or procedures that return multiple result sets, you must redescribe the cursor each time it is opened.
Description | This parameter allows you to provide a description of the ODBC data source.
Driver This parameter allows you to specify an ODBC driver for the connection, as follows: Driver=<driver-name>. By default, the driver that is used is Adaptive Server Anywhere 9.0. The driver-name must be Adaptive Server Anywhere X.0, where X is the major version number of the software. If the driver-name does not begin with Adaptive Server Anywhere, it cannot be read by the Data Source utility (dbdsn).

On UNIX, this parameter specifies the fully-qualified path to the shared object. If you do not specify the Driver connection parameter on UNIX, the Data Source utility automatically adds a Driver entry with the full path of the Adaptive Server Anywhere ODBC driver based on the setting of the ASANY9 environment variable.
GetTypeInfoChar | When this option is set to YES, CHAR columns are returned as SQL_CHAR instead of SQL_VARCHAR. By default, CHAR columns are returned as SQL_VARCHAR.
InitString | InitString allows you to specify a command that is executed immediately after the connection is established. For example, you may with to set a database option or execute a stored procedure.
IsolationLevel You can specify one of the following values to set the initial isolation level for this data source:

  • 0 This is also called the read uncommitted isolation level. This is the default isolation level. It provides the maximum level of concurrency, but dirty reads, non-repeatable reads, and phantom rows may be observed in result sets.

  • 1 This is also called the read committed level. This provides less concurrency than level 0, but eliminates some of the inconsistencies in result sets at level 0. Non-repeatable rows and phantom rows may occur, but dirty reads are prevented.

  • 2 This is also called the repeatable read level. Phantom rows may occur. Dirty reads and non-repeatable rows are prevented.

  • 3 This is also called the serializable level. This provides the least concurrency, and is the strictest isolation level. Dirty reads, non-repeatable reads, and phantom rows are prevented.

For more information, see Choosing isolation levels.
KeysInSQLStatistics | Specify YES if you want the SQLStatistics function to return foreign keys. The ODBC specification states that SQLStatistics should not return primary and foreign keys; however, some Microsoft applications (such as Visual Basic and Access) assume that primary and foreign keys are returned by SQLStatistics.
LazyAutocommit | Setting this parameter to YES delays the commit operation until a statement closes.
PrefetchOnOpen | When PrefetchOnOpen is set to YES, a prefetch request is sent with a cursor open request. The prefetch eliminates a network request to fetch rows each time a cursor is opened. Columns must already be bound for the prefetch to occur on the open. This connection parameter can help reduce the number of client/server requests to help improve performance over a LAN or WAN.
PreventNotCapable | The Adaptive Server Anywhere ODBC driver returns a Driver not capable error because it does not support qualifiers. Some ODBC applications do not handle this error properly. Set this parameter to YES to prevent this error code from being returned, allowing these applications to work.
SuppressWarnings | Set this parameter to YES if you want to suppress warning messages that are returned from the database server on a fetch. Versions 8.0 and later of the database server return a wider range of fetch warnings than earlier versions of the software. For applications that are deployed with an earlier version of the software, you can select this option to ensure that fetch warnings are handled properly.
TranslationDLL | This option is provided for backwards compatibility. The use of translators is not recommended.
TranslationName | This option is provided for backwards compatibility. The use of translators is not recommended.
TranslationOption | This option is provided for backwards compatibility. The use of translators is not recommended.

Delete the named data source (-d)

Deletes the named Adaptive Server Anywhere data source. You can modify the option using the u (user) or s (system) specifiers. The default specifier is u. If you supply -y, any existing data source is deleted without confirmation.

List (get) details of the named data source (-g)

List the definition of the named Adaptive Server Anywhere data source. You can modify the format of the output using the -b or -v options. You can modify the option using the u (user) or s (system) specifiers. The default specifier is u.

List defined data sources (-l)

Lists the available Adaptive Server Anywhere ODBC data sources. You can modify the list format using the -b or -v options. You can modify the option using the u (user) or s (system) specifiers. The default specifier is u.

Create (write) a data source definition (-w)

Creates a new data source, or overwrites one if one of the same name exists. You can modify the option using the u (user) or s (system) specifiers. The default specifier is u. If you supply -y, any existing data source is overwritten without confirmation.

Modifier options

Print connection string for the data source (-b) Format the output of the list as a single line connection string.

Display the data source creation command (-cm)

Displays the command used to create the data source. This option can be used to output the creation command to a file, which can be used to add the data source to another machine or can be used to restore a data source to its original state if changes have been made to it. You must specify the -g option or -l option with -cm or the command fails. Specifying -g displays the creation command for the specified data source, while specifying -l displays the creation command for all data sources.

If the specified data source does not exist, the command to delete the data source is generated. For example, if the mydsn data source does not exist on the machine, dbdsn -cm -g mydsn would return the following command to delete the mydsn data source:

dbdsn -y -du "mydsn"

Do not print banner (-q)

Suppress the informational banner. If you specify -q when deleting or modifying a data source, you must also specify -y.

Do not print banner or titles (-qq)

Suppress both the informational banner and titles. This option can only be used with the -l and the -cl options.

Print connection parameters in tabular form (-v)

Format the output of the list over several lines, as a table.

Delete or overwrite data source without confirmation (-y)

Automatically delete or overwrite each data source without prompting you for confirmation. If you specify -q when deleting or modifying a data source, you must also specify -y.

Details options

Connection parameters (-c)

Specify connection parameters as a connection string.

For more information, see Connection parameters.

Absolute filenames (-cw)

Ensure that the DBF parameter (specified using -c) is an absolute filename. If the value of DBF is not an absolute filename, dbdsn will prepend the current working directory (CWD). This option is useful because some operating systems (Win 9x) do not have CWD information readily available in batch files.

Encrypt network packets (-ec)

Encrypt packets sent between the client application and the server.

For more information, see Encryption connection parameter [ENC].

Log output messages to file (-o)

Write output messages to the named file. By default, messages are written to the console.

For more information, see Logfile connection parameter [LOG].

Set maximum network packet size (-p)

The maximum packet size for network communications, in bytes. The value must be greater than 300, and less than 16000. The default setting is 1460.

For more information, see CommBufferSize connection parameter [CBSIZE].

Disable multiple-record fetching (-r)

By default, when the database server gets a simple fetch request, the application asks for extra rows. You can disable this behavior using this option.

For more information, see DisableMultiRowFetch connection parameter [DMRF].

Set client liveness timeout (-tl)

Terminates connections when they are no longer intact. The value is in seconds.

The default is server setting, which in turn has a default value of 120 seconds.

For more information, see LivenessTimeout connection parameter [LTO].

Set communications links (-x)

A comma separated list of network drivers to run.

For more information, see CommLinks connection parameter [LINKS].

Display debugging information (-z)

Provide diagnostic information on communications links on startup.

server-name

Connect to the named server. Only the first 40 characters are used.

For more information, see The Database Server.

Examples

Write a definition of the data source newdsn. Do not prompt for confirmation if the data source already exists.

dbdsn -y -w newdsn -c "uid=DBA;pwd=SQL;LINKS=TCPIP" -v

or, with a different option order,

dbdsn -w newdsn -c "uid=DBA;pwd=SQL;LINKS=TCPIP" -y

List all known user data sources, one data source name per line:

dbdsn -l

List all known system data sources, one data source name per line:

dbdsn -ls

List all data sources along with their associated connection string:

dbdsn -l -b

Report the connection string for user data source MyDSN:

dbdsn -g MyDSN

Report the connection string for system data source MyDSN:

dbdsn -gs MyDSN

Delete the data source BadDSN, but first list the connection parameters for BadDSN and prompt for confirmation:

dbdsn -d BadDSN -v

Delete the data source BadDSN without prompting for confirmation.

dbdsn -d BadDSN -y

Create a data source named NewDSN for the database server MyServer:

dbdsn -w NewDSN -c "uid=DBA;pwd=SQL;eng=MyServer"

If a NewDSN already exists, the previous definition is overwritten.

List all connection parameter names and their aliases:

dbdsn -cl

List all user DSNs (without banner and titles):

dbdsn -l -qq

List all connection parameter names (without banner and titles):

dbdsn -cl -qq

Specify an absolute filename. When the DSN is created, it will contain dbf=E:\asa90\my.db.

E:\asa90> dbdsn -w testdsn -cw -c uid=dba;pwd=sql;eng=asa;dbf=my.db

Generate the command to create the ASA 9.0 Sample data source and output it to a file called restoredsn.bat:

dbdsn -cm -g "ASA 9.0 Sample" > restoredsn.bat

The restoredsn.bat file contains the following:

dbdsn -y -wu "ASA 9.0 Sample" -c "UID=dba;PWD=sql;
DBF=C:\Program Files\Sybase\SQL Anywhere 9\asademo.db;
ENG=asademo9;START=C:\Program Files\Sybase\SQL Anywhere 9\
win32\dbeng9.exe -c 8m;ASTOP=yes;
Description=Adaptive Server Anywhere Sample Database"


The Erase utility

With the Erase utility, you can erase a database file and its associated transaction log, or you can erase a transaction log file or transaction log mirror file. All database files and transaction log files are marked read-only to prevent accidental damage to the database and accidental deletion of the database files.

Deleting a database file that references other dbspaces does not automatically delete the dbspace files. If you want to delete the dbspace files on your own, change the files from read-only to writable, and then delete the files individually. As an alternative, you can use the DROP DATABASE statement to erase a database and its associated dbspace files.

If you erase a database file, the associated transaction log and transaction log mirror are also deleted. If you erase a transaction log for a database that also maintains a transaction log mirror, the mirror is not deleted.

The database to be erased must not be running when this utility is used.

Exit codes are 0 (success) or non-zero (failure).

You can access the Erase utility in the following ways:

  • From Sybase Central, using the Erase Database wizard.

  • At a command prompt, using the dberase command. This is useful for incorporating into batch or command files.

For more information, see the DROP DATABASE statement.


Erasing a database using the Erase Database wizard

toggle To erase a database file

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Erase Database

    The Erase Database wizard appears.

  4. Follow the instructions in the wizard.

For full information on erasing a database from Sybase Central, see Erasing databases.

Tip
You can also access the Erase Database wizard from within Sybase Central using any of the following methods:

  • Choosing Tools > Adaptive Server Anywhere 9 > Erase Database.

  • Selecting a server in the left pane, and choosing Erase Database from the File menu.

  • Right-clicking a server, and choosing Erase Database from the popup menu.


Erasing a database using the dberase command-line utility

Syntax

dberase [ options ] database-file

Option | Description
@data | Read options from the specified environment variable or configuration file.
-ek key | Specify encryption key.
-ep | Prompt for encryption key.
-o filename | Log output messages to a file.
-q | Operate quietly—do not print messages.
-y | Erase files without confirmation.
Description

The database-file may be a database file or transaction log file. The full filename must be specified, including extension. If a database file is specified, the associated transaction log file (and mirror, if one is maintained) is also erased.

Note
The Erase utility does not erase dbspaces. If you want to erase a dbspace, you can do so with the DROP DATABASE statement or using the Erase Database wizard in Sybase Central.
Erase utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Specify encryption key (-ek)

This option allows you to specify the encryption key for strongly encrypted databases directly in the command. If you have a strongly encrypted database, you must provide the encryption key to use the database or transaction log in any way. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify the correct key for a strongly encrypted database.

Prompt for encryption key (-ep)

This option allows you to specify that you want to be prompted for the encryption key. This option causes a dialog box to appear, in which you enter the encryption key. It provides an extra measure of security by never allowing the encryption key to be seen in clear text. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify the correct key for a strongly encrypted database.

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not display output messages. If you specify this option, you must also specify -y or the operation will fail.

Operate without confirming actions (-y)

Choosing this option automatically deletes each file without prompting you for confirmation. If you specify -q, you must also specify -y or the operation will fail.


The File Hiding utility

With the File Hiding utility you can add simple encryption to configuration files and initialization files to hide the contents of each file.

Hiding the contents of files using the dbfhide command-line utility


Hiding the contents of files using the dbfhide command-line utility

Syntax

dbfhide original-configuration-file encrypted-configuration-file

Option | Description
original-configuration-file | Name of the original file.
encrypted-configuration-file | Name for the new obfuscated file.
Description

Configuration files are used by some utilities to hold command-line options. These options may contain a password. You can use the File Hiding utility to add simple encryption to configuration files, as well as to .ini files used by Adaptive Server Anywhere and its utilities, and thereby obfuscate the contents of the file. The original file will not be modified. Once you add simple encryption to a file, there is no way to remove it. In order to make changes to an obfuscated file, you must keep a copy of the original file that you can modify and obfuscate again.

Hiding the contents of .ini files

In many cases, Adaptive Server Anywhere expects a .ini file to have a particular name. When you want to add simple encryption to a file whose name is important (such as asaldap.ini), you need to save a copy of the original file with a different name when you add simple encryption to the file. If you do not keep a copy of the original file, then you cannot modify the contents of the file once it has been obfuscated. The following steps explain how to add simple encryption to a .ini file.

toggle To hide the contents of .ini files

  1. Save the file with a different name.

    rename asaldap.ini asaldap.ini.org

  2. Obfuscate the file with the File Hiding utility, giving the obfuscated file the required file name:

    dbfhide asaldap.ini.org asaldap.ini

  3. Protect the asaldap.ini.org file using file system or operating system protection, or store the file in a secure location.

    To make a change to the asaldap.ini file, edit the asaldap.ini.org file and repeat step 2.

Caution You should not add simple encryption to the .odbc.ini system information file with the File Hiding utility (dbfhide) on UNIX unless you will only be using Adaptive Server Anywhere data sources. If you plan to use other data sources (for example, for MobiLink synchronization), then obfuscating the contents of the .odbc.ini file may prevent other drivers from functioning properly.

This utility does not accept the @data parameter to read in options from a configuration file.

Examples

Create a configuration file that starts the personal database server and the sample database. It should set a cache of 10 Mb, and name this instance of the personal server Elora. The configuration file would be written as follows:

# Configuration file for server Elora
-n Elora
-c 10M
path\asademo.db

(Note that lines beginning with # are treated as comments.)

Name the file sample.txt. If you wanted to start the database using this configuration file, your command line would be:

dbeng9 @sample.txt

Now, add simple encryption to the configuration.

dbfhide sample.txt encrypted_sample.txt

Use the encrypted_sample.txt file to start a database.

dbsrv9 @encrypted_sample.txt

For more information about encryption, see Keeping Your Data Secure.

For more information about using configuration files, see Using configuration files to store server startup options.

The following command adds simple encryption to the asaldap.ini file:

dbfhide asaldap.ini encrypted_asaldap.ini


The Histogram utility

The Histogram utility converts a histogram into a Microsoft Excel chart containing information about the selectivity of predicates. The utility only works with Excel 97 and later, and only on Windows.

Converting a histogram using the dbhist command-line utility


Converting a histogram using the dbhist command-line utility

Syntax

dbhist [ options ] -t table-name [ excel-output-name ]

Parameters
Option | Description
@data | Read options from the specified environment variable or configuration file.
-c options | Connection string.
-n colname | Column to associate with the histogram.
-t table-name | The name of the table to generate histograms for.
-u owner | The table owner.
excel-output-name: | The name of the generated Excel file.
Description

Histograms are stored in the SYSCOLSTAT system table and can also be retrieved with the sa_get_histogram stored procedure. The Histogram utility converts a histogram into a Microsoft Excel chart containing information about the selectivity of predicates. The utility only works with Excel 97 and later, and only on Windows.

To determine the selectivity of a predicate over a string column, you should use the ESTIMATE or ESTIMATE_SOURCE functions. Attempting to retrieve a histogram from string columns causes both sa_get_histogram and the Histogram utility to generate an error.

Exit codes are 0 (success) or non-zero (failure).

For more information about the sa_get_histogram stored procedure, see sa_get_histogram system procedure.

Histogram utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Specify a connection string (-c)

Specify connection parameters.

For a description of the connection parameters, see Connection parameters.

Specify a column (-n)

Specify the name of the column to associate the histogram with. If you do not specify a column, all columns that have histograms in the table are returned.

Specify a table name (-t)

Specify the name of the table to generate histograms for.

Specify an owner (-u)

Specify the owner of the table.

excel-output-name The name of the generated Excel file. If no name is specified, Excel prompts you to enter one with a Save As dialog.

Example

Assuming that a histogram has been created for the column, the following statement (entered all on the same line) generates an Excel chart for the column prod_id in the table sales_order_items for database asademo.db, and saves it as histgram.xls.

dbhist -c "uid=DBA;pwd=SQL;dbf=asademo.db"
      -n prod_id -t sales_order_items histgram.xls

The following statement generates charts for every column with a histogram in the table sales_order, assuming that asademo is already loaded. This statement also attempts to connect using uid=dba, pwd=sql. No output file name is specified, so Excel prompts you to enter one.

dbhist -t sales_order -c "UID=DBA;PWD=SQL"


The Information utility

The Information utility can display information about a database.

Obtaining database information using the dbinfo command-line utility


Obtaining database information using the dbinfo command-line utility

Syntax

dbinfo [ options ]

Option | Description
@data | Read options from the specified environment variable or configuration file.
-c "keyword=value; ..." | Database connection parameters.
-o filename | Log output messages to a file.
-q | Operate quietly.
-u | Output page usage statistics.
Description

The dbinfo utility displays information about a database. It reports the time when the database was created, the name of any transaction log file or log mirror, the page size, the version of installed Java classes, the collation name and label, and other information. Optionally, it can also provide table usage statistics and details.

Exit codes are 0 (success) or non-zero (failure).

Information utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Connection parameters (-c)

Specify connection parameters.

For a description of the connection parameters, see Connection parameters.

Any valid user ID can run the Information utility, but to obtain page usage statistics you need DBA authority.

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not display output messages.

Page usage statistics (-u)

Display information about the usage and size of all tables, including system and user-defined tables.

You can only request page usage statistics if no other users are connected to the database and you have DBA authority.


The Initialization utility

With the Initialization utility, you can initialize (create) a database. A number of database attributes are specified at initialization and cannot be changed later except by unloading, reinitializing, and rebuilding the entire database. These database attributes include:

  • Case sensitivity or insensitivity

  • Password case sensitivity or insensitivity

  • Storage as an encrypted file

  • Treatment of trailing blanks in comparisons

  • Page size

  • Collation sequence

In addition, the choice of whether to use a transaction log and a transaction log mirror is made at initialization. This choice can be changed later using the Transaction Log utility.

Exit codes are 0 (success) or non-zero (failure).

You can access the Initialization utility in the following ways:

  • From Sybase Central, using the Create Database wizard.

  • From Interactive SQL, using the CREATE DATABASE statement.

  • At a command prompt, using the dbinit command. This is useful for incorporating into batch or command files.

For more information about creating a database, see CREATE DATABASE statement.


Creating a database using the Create Database wizard

toggle To create a database

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Create Database.

    The Create Database wizard appears.

  4. Follow the instructions in the wizard.

Tip
You can also access the Create Database wizard from within Sybase Central using any of the following methods:

  • Choosing Tools > Adaptive Server Anywhere 9 > Create Database.

  • Selecting a server in the left pane, and choosing Create Database from the File menu.

  • Right-clicking a server, and choosing Create Database from the popup menu.

For full information on creating a database in Sybase Central, see Creating a database.


Creating a database using the dbinit command-line utility

Syntax

dbinit [ options ] new-database-file

Option | Description
@data | Read options from the specified environment variable or configuration file.
-b | Blank padding of strings for comparisons and fetching.
-c | Case sensitivity for all string comparisons.
-cp | Case sensitivity of passwords.
-e | Encrypt the database using simple encryption.
-ea algorithm | Specify which strong encryption algorithm to encrypt your database with: you can choose AES or AES_FIPS.
-ek key | Specify encryption key for strong encryption.
-ep | Prompt for encryption key for strong encryption.
-i | Do not install Sybase jConnect support.
-ja | Install default runtime Java classes.
-jdk version | Install entries for the named version of the Java Development Kit.
-k | Omit Watcom SQL compatibility views SYS.SYSCOLUMNS and SYS.SYSINDEXES.
-l | List the recommended collation sequences.
-m file-name | Use a transaction log mirror (default is no mirror).
-n | No transaction log.
-o filename | Log output messages to a file.
-p page-size | Set page size.
-q | Quiet mode—do not print messages.
-s | Use checksums when writing pages to disk.
-t log-name | Transaction log filename (default is the database name with .log extension).
-z col-seq | Collation sequence used for comparisons.
Description

For example, the database test.db can be created with 4096 byte pages as follows:

dbinit -p 4096 test.db
Initialization utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Blank padding (-b)

Ignore trailing blanks for comparison purposes and pad strings that are fetched into character arrays. For example, the two strings

'Smith'
'Smith   '

would be treated as equal in a database created with blank-padding.

This option is provided for compatibility with the ISO/ANSI SQL standard, which is to ignore trailing blanks in comparisons. The default is that blanks are significant for comparisons.

Case sensitivity for all string comparisons (-c)

For databases created with this option, all values are considered to be case sensitive in comparisons and string operations. Identifiers in the database are case insensitive, even in case sensitive databases.

This option is provided for compatibility with the ISO/ANSI SQL standard. The default is that all comparisons are case insensitive.

Case sensitivity for passwords (-cp)

By default, the case sensitivity of passwords is the same as the case sensitivity of the database. However, if you specify the -cp option, then passwords are case sensitive, regardless of the database case sensitivity. To specify that passwords are case insensitive, specify -cp-.

User ID and password
All databases are created with at least one user ID, DBA, with password SQL. Extended characters used in passwords are case sensitive regardless of the database sensitivity setting. User IDs, like other identifiers, are case insensitive even in case sensitive databases.

Encrypt the database using simple encryption (-e)

Simple encryption makes it more difficult for someone to decipher the data in your database using a disk utility to look at the file. File compaction utilities cannot compress encrypted database files as much as unencrypted ones.

This simple encryption is equivalent to obfuscation and is intended only to keep data hidden in the event of casual direct access of the database file. For greater security, you can use strong encryption by supplying the -ea and -ek options.

Specify encryption algorithm (-ea)

This option allows you to choose a strong encryption algorithm to encrypt your new database. You can choose either AES (the default) or AES_FIPS for the FIPS-approved algorithm. AES_FIPS uses a separate library and is not compatible with AES. AES_FIPS is only available on all supported 32-bit Windows platforms. Algorithm names are case insensitive. If you specify the -ea option, you must also specify -ep or -ek.

For more information, see Strong encryption.

Separately licensable option required
Strong database encryption using AES_FIPS requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Specify encryption key (-ek)

This option allows you to create a strongly encrypted database by specifying an encryption key directly in the command. The algorithm used to encrypt the database is AES or AES_FIPS as specified by the -ea option. If you specify the -ek option without specifying -ea, the AES algorithm is used.

Caution Protect your key! Be sure to store a copy of your key in a safe location. A lost key will result in a completely inaccessible database, from which there is no recovery.

The following are invalid for database encryption keys:

  • keys that begin with white space or single or double quotes

  • keys that end with white space

  • keys that contain semicolons

For more information, see Strong encryption.

Prompt for encryption key (-ep)

This option allows you to specify that you want to create a strongly encrypted database by inputting the encryption key in a dialog box. This provides an extra measure of security by never allowing the encryption key to be seen in clear text.

You must input the encryption key twice to confirm that it was entered correctly. If the keys don't match, the initialization fails.

For more information, see Strong encryption.

Do not install Sybase jConnect support (-i)

If you want to use the Sybase jConnect JDBC driver to access system catalog information, you need to install jConnect support. Use this option if you want to exclude the jConnect system objects. You can still use JDBC, as long as you do not access system information. If you want, you can add Sybase jConnect support at a later time using Sybase Central or the ALTER DATABASE statement.

For more information, see Installing jConnect system objects into a database.

Install runtime Java classes (-ja)

If you want to use Java in your database, you must install the runtime Java classes. Specifying -ja installs version 1.3 of the JDK into the database.

For example, the following command creates a database that supports JDK 1.3 applications in the database.

dbinit -ja java2.db

The runtime classes add several megabytes to the size of a database, so if you do not intend to use Java classes, you can omit the -ja option to avoid installing them.

You can add the runtime Java classes at a later time using the Upgrade Database wizard, or the ALTER DATABASE statement.

For more information, see Java-enabling a database and ALTER DATABASE statement.

Install support for the named version of the JDK (-jdk)

If you want to install a version of Java other than 1.3 into your database, use the -jdk option followed by the version number. Currently, the only other version of Java supported is 1.1.8.

For example, the following command creates a database that supports JDK 1.1.8 applications in the database.

dbinit -jdk 1.1.8 java2.db

The runtime classes add several megabytes to the size of a database, so if you do not intend to use Java classes, you can omit the -jdk option to avoid installing them.

The -jdk option implies the -ja option.

You can add the runtime Java classes at a later time using the Upgrade Database wizard, or the ALTER DATABASE statement.

For more information, see Java-enabling a database and ALTER DATABASE statement.

Omit Watcom SQL compatibility views (-k)

By default, database creation generates the views SYS.SYSCOLUMNS and SYS.SYSINDEXES for compatibility with system tables that were available in Watcom SQL (versions 4 and earlier of this software). These views will conflict with the Sybase Adaptive Server Enterprise compatibility views dbo.syscolumns and dbo.sysindexes.

List the available collation sequences (-l)

When you specify this option, dbinit lists the recommended collation sequences and then stops. No database is created. A list of available collation sequences is automatically presented in the Sybase Central Create Database wizard.

Use a transaction log mirror (-m)

A transaction log mirror is an identical copy of a transaction log, usually maintained on a separate device, for greater protection of your data. By default, Adaptive Server Anywhere does not use a mirrored transaction log.

Do not use a transaction log (-n)

Creating a database without a transaction log saves disk space. The transaction log is required for data replication and provides extra security for database information in case of media failure or system failure. Databases that do not use transaction logs typically run slower than databases that use transaction logs.

Log output messages to file (-o)

Write output messages to the named file.

Page size (-p)

The page size for a database can be (in bytes) 1024, 2048, 4096, 8192, 16384, or 32768, with 2048 being the default. Any other value for the size will be changed to the next larger size.

Large databases usually benefit from a larger page size. For example, the number of I/O operations required to scan a table is generally lower, as a whole page is read in at a time. Also, the number of levels in an index may be reduced as more entries can be stored on each page.

However, there are additional memory requirements for large page sizes. Also, the maximum number of rows stored on a page is 255, so that tables with small rows will not fill each page. For example, with 8 kb pages the average row size must be at least 32 bytes to fully use each page. For most applications, 16 kb or 32 kb page sizes are not recommended. You should not use page sizes of 16 kb or 32 kb in production systems unless you can be sure that a large database server cache is always available, and only after you have investigated the tradeoffs of memory and disk space with its performance characteristics.

Operate quietly (-q)

Do not display output messages.

Use checksums (-s)

Checksums are used to determine whether a database page has been modified on disk. When you create a database with checksums enabled, a checksum is calculated for each page just before it is written to disk. The next time the page is read from disk, the page's checksum is recalculated and compared to the checksum stored on the page. If the checksums are different, then the page has been modified or corrupted on disk.

Set the transaction log filename (-t)

The transaction log is a file where the database server logs all changes, made by all users, no matter what application is being used. The transaction log plays a key role in backup and recovery (see The transaction log), and in data replication. If the filename has no path, it is placed in the same directory as the database file. If you run dbinit without specifying -t or -n, a transaction log is created with the same filename as the database file, but with extension .log.

Collation sequence (-z)

The collation sequence is used for all string comparisons in the database.

If -z is not specified, Adaptive Server Anywhere chooses a default collation based on operating system language and character set settings.

For more information, see Choosing collations.

In order to change the collation that an existing database uses, it is necessary to unload the database, create a new database using the appropriate collation, and then reload the database. It may be necessary to translate the data as well.

If you want to create a custom collation, use the Collation utility to create a file containing the collation. Once you have modified the collation and inserted it into the appropriate scripts, you use the Initialization utility to create the database and specify the new collation.

You must change the collation label in the custom collation file. Otherwise, the Initialization utility prevents the insertion of the new collation, since it conflicts with an existing collation.

For more information on custom collation sequences, see International Languages and Character Sets.

For information on the Collation utility, see The Collation utility.


The Interactive SQL utility

Interactive SQL provides an interactive environment for database browsing and for sending SQL statements to the database server.

You can start Interactive SQL in the following ways:

  • from Sybase Central, using the Open Interactive SQL menu item.

  • from the Start menu by choosing Start > Programs > SQL Anywhere 9 > Adaptive Server Anywhere > Interactive SQL.

  • at a command prompt, using the dbisql command.

SQL statements used only from Interactive SQL

The following is a list of the SQL statements that can be used only from Interactive SQL:

CLEAR statement [Interactive SQL]

CONFIGURE statement [Interactive SQL]

CONNECT statement [ESQL] [Interactive SQL]

DISCONNECT statement [ESQL] [Interactive SQL]

EXIT statement [Interactive SQL]

HELP statement [Interactive SQL]

INPUT statement [Interactive SQL]

OUTPUT statement [Interactive SQL]

PARAMETERS statement [Interactive SQL]

READ statement [Interactive SQL]

SET CONNECTION statement [Interactive SQL] [ESQL]

SET OPTION statement [Interactive SQL]

START DATABASE statement [Interactive SQL]

START ENGINE statement [Interactive SQL]

START LOGGING statement [Interactive SQL]

STOP LOGGING statement [Interactive SQL]

SYSTEM statement [Interactive SQL]


Starting Interactive SQL from Sybase Central

toggle To open Interactive SQL from Sybase Central

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. Double-click Open Interactive SQL in the right pane.

    The Interactive SQL window appears.

Tip
You can also access Interactive SQL from within Sybase Central as follows:

  • Choosing Tools > Adaptive Server Anywhere 9 > Open Interactive SQL.

  • Selecting a database in the left pane, and choosing Open Interactive SQL from the File menu.

  • Right-clicking a database, and choosing Open Interactive SQL from the popup menu.

  • Right-clicking a stored procedure, and choosing Execute from Interactive SQL from the popup menu. Interactive SQL opens with a CALL to the procedure in the SQL Statements pane and executes the stored procedure.

  • Right-clicking a table and choosing View Data in Interactive SQL. Interactive SQL opens with a SELECT * FROM table-name and executes the query.


Opening Interactive SQL using the dbisql command-line utility

Syntax

dbisql [ options ] [ dbisql-command | command-file ]

Option | Description
-c "keyword=value; ..." | Supply database connection parameters.
-codepage codepage | Specify a codepage to use when reading or writing files.
-d delimiter | Use the given string as the command delimiter.
-d1 | Print statements as they are executed [command-prompt mode only].
-datasource dsn-name | Specify an ODBC data source to connect to.
-f filename | Open (without running) the file called filename.
-host hostname | Specify the hostname or IP address of the machine running a database server.
-jConnect | Use jConnect to connect to the database.
-nogui | Run in command-prompt mode.
-ODBC | Use the iAnywhere JDBC Driver to connect to the database.
-onerror { continue | exit } | Override the ON_ERROR option for all users.
-port portnumber | Look on the specified port number for the database server.
-q | Quiet mode—no windows or messages (note that this does not suppress error messages).
-x | Syntax check only—no commands executed.
Description

Interactive SQL allows you to type SQL commands or run command files. It also provides feedback about the number of rows affected, the time required for each command, the execution plan of queries, and any error messages.

If dbisql-command is specified, Interactive SQL executes the command. You can also specify a command file name. If no dbisql-command or command-file argument is specified, Interactive SQL enters interactive mode, where you can type a command into a command window.

Exit codes are 0 (success) or non-zero (failure).

Interactive SQL requires that the QUOTED_IDENTIFIER database option be set to ON since a number of database functions, including some statements, rely on this setting to function properly. Interactive SQL automatically sets it ON when connecting to a database.

This utility does not accept the @data parameter to read in options from a configuration file.

Interactive SQL utility options

Connection parameters (-c)

Specify connection parameters. See Connection parameters for a description of the connection parameters. If Interactive SQL cannot connect, you are presented with a dialog where you can enter the connection parameters.

Codepage (-codepage)

Specify the codepage to use when reading or writing files. The default code page is the default code page for the platform you are running on.

For example, on an English Windows NT machine, Interactive SQL uses the 1252 (ANSI) code page. If you want Interactive SQL to read files created using the 297 (IBM France) code page, specify the following option.

-codepage 297

For a list of supported code pages, see Supported code pages.

Command delimiter (-d)

Specify a command delimiter. Quotation marks around the delimiter are optional, but are required when the command shell itself interprets the delimiter in some special way.

Command delimiters are used for all connections in that Interactive SQL session, regardless of the setting stored in the database (for the user, or the PUBLIC setting).

Echo statements (-d1)

(The final character is a number 1, not a lower-case L). Interactive SQL echoes all statements it executes to the Command window (STDOUT). This can provide useful feedback for debugging SQL scripts, or when Interactive SQL is processing a long SQL script.

Data source (-datasource)

Specify an ODBC data source to connect to. You do not need to be using the iAnywhere JDBC driver to use this option.

Open file using Interactive SQL (-f)

Open (but do not run) the file called filename. The file name can be enclosed in quotation marks, and must be enclosed in quotation marks if the file name contains a blank. If the file does not exist, or if it's really a directory instead of a file, Interactive SQL prints an error message to the console and then quits. If the file name does not include a full drive and path specification, it is assumed to be relative to the current directory.

Host (-host)

Specify the hostname or IP address of the computer on which the database server is running. You can use the name localhost to represent the current machine.

Use jConnect (-jConnect)

Use the Sybase jConnect JDBC driver to connect to the database.

Run in command-prompt mode (-nogui)

Run Interactive SQL in a command-prompt mode, with no windowed user interface. This is useful for batch operations. If you specify either dbisql-command or command-file, then -nogui is assumed.

In this mode, Interactive SQL sets the program exit code to indicate success or failure. On Windows operating systems, the environment variable ERRORLEVEL is set to the program exit code. The exit codes are as follows:

Program exit code | Description
0 | Success.
1 | General failure. At some point, a SQL or Interactive SQL statement did not execute successfully and the user chose to stop executing SQL statements. Alternatively, Interactive SQL noted an internal error.
5 | The user terminated interactive SQL. When an error occurs during execution, the user is prompted to ignore it, stop, or exit Interactive SQL. If the user opts to exit, the program returns code 5. Code 5 is also returned if an error occurs and the Interactive SQL option ON_ERROR is set to EXIT.
9 | Unable to connect.
255 | Bad command. The command contained incomplete or invalid options.

Use iAnywhere JDBC driver (-ODBC)

Connect using the iAnywhere JDBC driver. This is the default method, and is recommended in most circumstances.

Override the ON_ERROR option setting (-onerror)

Controls what happens if an error is encountered while reading statements from a command file. This option overrides the ON_ERROR setting. It is useful when using Interactive SQL in batch operations.

For more information, see ON_ERROR option [Interactive SQL].

Database server port (-port)

Specify the port number on which the database server is running. The default port number for Adaptive Server Anywhere is 2638.

Operate quietly (-q)

Do not display output messages. This is useful only if you start Interactive SQL with a command or command file. Note that specifying this option does not suppress error messages.

Syntax check only (-x)

Scan commands but do not execute them. This is useful for checking long command files for syntax errors.

For detailed descriptions of SQL statements and Interactive SQL commands, see SQL Language Elements.

Examples

The following command, entered at a command prompt, runs the command file mycom.sql against the current default server, using the user ID DBA and the password SQL. If there is an error in the command file, the process terminates.

dbisql -c "uid=DBA;pwd=SQL" -onerror exit mycom.sql

The following command, when entered on a single line at a command prompt, adds a user to the current default database:

dbisql -c "uid=DBA;pwd=SQL" grant connect to joe identified by passwd


The Language utility

The Language utility reports and changes the registry settings that control the languages used by Adaptive Server Anywhere and Sybase Central.

Managing languages using the dblang command-line utility


Managing languages using the dblang command-line utility

Syntax

dblang [options] [ language-code ]

Option | Description
-q | Operate quietly—do not print messages.
Language code | Language
DE | German
EN | English
ES | Spanish
FR | French
IT | Italian
JA | Japanese
KO | Korean
LT | Lithuanian
PL | Polish
PT | Portuguese
RU | Russian
TW | Traditional Chinese
UK | Ukrainian
ZH | Simplified Chinese
Description

The utility is installed only when the International Resources Deployment Kit (IRDK) is selected during installation.

Running the dblang utility without a language code reports the current settings. These settings are as follows:

  • Adaptive Server Anywhere A key from HKEY_LOCAL_MACHINE that holds a two-letter language code from the table above.

    This setting controls which language resource library is used to deliver informational and error messages from the Adaptive Server Anywhere database server. The language resource library is a DLL with a name of the form dblgXX9.dll, where XX is a two-letter language code.

    Ensure that you have the appropriate language resource library on your machine when you change the settings.

  • Sybase Central A key from HKEY_LOCAL_MACHINE that holds a two-letter language code from the table above.

    This setting controls the resources used to display user interface elements for Sybase Central and Interactive SQL. You must have purchased the appropriate localized version of SQL Anywhere Studio for this setting to take effect.

Exit codes are 0 (success) or non-zero (failure).

This utility does not accept the @data parameter to read in options from a configuration file.

Language utility options

Operate quietly (-q)

Do not display output messages.

Examples

If you selected the International Resources Deployment Kit (IRDK) during installation, the following command displays a dialog box containing the current settings:

dblang
The dblang dialog showing the current language keys.

The following command changes the settings to French, and displays a dialog containing the previous and new settings:

dblang FR


The License utility

The License utility adds licensed users to your network database server.

Managing licenses using the dblic command-line utility


Managing licenses using the dblic command-line utility

Syntax

dblic [ options ] executable-name user-name company-name

Option | Description
@data | Read options from the specified environment variable or configuration file.
-l type | Specify the license type. Allowed values are perseat or processor.
-o filename | Log output messages to a file.
-p operating-system | Specify the target operating system. Allowed values are WIN32, WIN64, NetWare, and UNIX.
-q | Operate quietly—do not print messages.
-u license-number | Specify the total number of users or processors for license.
executable-name | Specify the executable to be licensed, with path relative to the current directory. This should be either an Adaptive Server Anywhere network database server or a MobiLink synchronization server.
user-name | Specify the user name for the license.
company-name | Specify the company name for the license.
Description

The License utility adds licensed users to your network database server. You must only use this utility in accordance with your Sybase license agreement to license the number of users to which you are entitled. Running this command does not grant you license. You can also use this utility to view the current license information for a server without starting the server.

Repeated running of the dblic command updates the license information.

Exit codes are 0 (success) or non-zero (failure).

On UNIX, the dbsrv9 and dbmlsrv9 executables are not writable by default, and so using the license [dblic] utility with those executables will fail. Make sure the dbsrv9 and dbmlsrv9 executables are writable (for example, using chmod +w) before you use the License utility.

The License utility is not supported on NetWare. To license Adaptive Server Anywhere executables on NetWare, you must make sure that the Adaptive Server Anywhere database server on NetWare is not running, and then run the License utility from a Windows machine that can access the NetWare volume containing the Adaptive Server Anywhere software.

License utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

License type (-l)

Enter the license type that matches the licensing model described in your software license agreement. Valid entries are perseat and processor.

Log output messages to file (-o)

Write output messages to the named file.

Operating system (-p)

Enter the operating system for which you are licensed. Allowed values are as follows:

  • NetWare A Novell NetWare operating system.

  • UNIX A UNIX operating system.

  • WIN32 A Windows 95/98/Me, Windows NT/2000/XP, or Windows CE operating system.

  • WIN64 A 64-bit Windows operating system.

Operate quietly (-q)

Do not display output messages.

License number (-u)

The total number of users or processors for the license. If you are adding extra licenses, this is the total, not the number of additional licenses.

Executable name

Enter the path and file name of the network database server executable (dbsrv9.exe) or MobiLink synchronization server (dbmlsrv9.exe) you are licensing. The path must be either absolute or relative to the current working directory.

You can view the current license information for a server executable without starting the server by entering only the executable name.

User name

A user name for the license. This name appears on the database server window on startup. If there are spaces in the name, enclose it in double quotes.

Company name

The company name for the license. This name appears on the database server window on startup. If there are spaces in the name, enclose it in double quotes.

Example

The following command, executed in the same directory as the database server executable, applies a license for 50 users, in the name of Sys Admin, for company My Co, to a Windows NT network database server. The command must be entered all on one line:

dblic -l perseat -p WIN32 -u 50 dbsrv9.exe "Sys Admin" "My Co"

The following message appears on the screen to indicate the success of the license:

Licensed nodes: 50
User: Sys Admin
Company: My Co


The Log Transfer Manager

The Log Transfer Manager (LTM) is also known as a replication agent.

The LTM is required for any Adaptive Server Anywhere database that participates in a Replication Server installation as a primary site.


Using the dbltm command-line utility

Syntax

dbltm [ options ]

Parameters
Option | Description
@data | Read options from the specified environment variable or configuration file.
-A | Do not filter updates.
-C config_file | Use the named configuration file.
-I interface_file | Use the named interface file.
-M | Recovery mode.
-S LTM_name | Specify an LTM name.
-dl | Display log messages on screen.
-ek key | Specify encryption key.
-ep | Prompt for encryption key.
-o filename | Log output messages to a file.
-os size | Maximum size of output file.
-ot file | Truncate file, and log output messages to file.
-q | Run in minimized window.
-s | Show Log Transfer Language (LTL) commands.
-ud | Run as a daemon [UNIX].
-v | Verbose mode.
Description

The Adaptive Server Anywhere LTM reads a database transaction log and sends committed changes to Replication Server. The LTM is not required at replicate sites.

The LTM sends committed changes to Replication Server in a language named Log Transfer Language (LTL).

By default, the LTM uses a log file named DBLTM.LOG to hold status and other messages. You can use options to change the name of this file and to change the volume and type of messages that are sent to it.

Exit codes are 0 (success) or non-zero (failure).

Log Transfer Manager utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Do not filter updates (-A)

Do not filter updates. By default, all changes made by the maintenance user are not replicated. If the -A option is set, these changes are replicated. This may be useful in non-hierarchical Replication Server installations, where a database acts as both a replicate site and as a primary site.

Use configuration file (-C)

Use the configuration file config_file to determine the LTM settings. The default configuration file is dbltm.cfg.

For a description of the configuration file, see The LTM configuration file.

Display Log Transfer Language messages (-dl)

Display all messages in the LTM window or at a command prompt, as well as in the log file (if specified).

Specify encryption key (-ek)

This option allows you to specify the encryption key for strongly encrypted databases directly in the command. If you have a strongly encrypted database, you must provide the encryption key to use the database or transaction log in any way, including offline transaction logs. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command fails if you do not specify a key for a strongly encrypted database.

Prompt for encryption key (-ep)

This option allows you to specify that you want to be prompted for the encryption key. This option causes a dialog box to appear, in which you enter the encryption key. It provides an extra measure of security by never allowing the encryption key to be seen in clear text. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command fails if you do not specify a key for a strongly encrypted database.

Use interface file (-I)

(Upper case I.) Use the named interfaces file. The interfaces file is the file created by SQLEDIT and holds the connection information for Open Servers. The default interfaces file is SQL.ini in the ini subdirectory of your Sybase directory.

Recover mode (-M)

This is used to initiate recovery actions. The LTM starts reading logs from the earliest available position. If the offline directory is specified in the configuration file, the LTM reads from the oldest offline log file.

Log output messages to file (-o)

Use a log file different from the default (dbltm.log). Write output messages from log transfer operations to this file.

Limit size of output file (-os)

Specify the maximum size of the output file, in bytes. The minimum value is 10000 (ten thousand). If the log file grows to the point where it would exceed this limit, it is renamed to yymmddxx.ltm. The value of xx in yymmddxx.ltm is incremented for each file created on a given day.

Truncate log file and use named log file (-ot)

Use a log file different from the default (dbltm.log), and truncate the log file (all existing content is deleted) when the LTM starts. Output messages from log transfer operations are sent to this file for later review.

Operate quietly (-q)

Minimize the window when the LTM is started.

Specify LTM name (-S) Provides the server name for this LTM. The default LTM name is DBLTM_LTM. The LTM name must correspond to the Open Server name for the LTM that was entered in SQLEDIT.

Log all LTL commands (-s)

Log all LTL commands that are generated by the LTM. This should be used only to diagnose problems, and is not recommended in a production environment. It carries a significant performance penalty.

Run as a daemon (-ud)

You can run the LTM as a daemon on UNIX operating systems. If you run in this manner, output is logged to the log file.

Operate in verbose mode (-v)

Displays messages, other than LTL messages, for debugging purposes.


The LTM configuration file

The Adaptive Server Anywhere and Adaptive Server Enterprise LTM configuration files are very similar. This section describes the entries in the Adaptive Server Anywhere LTM configuration file, and the differences from the Adaptive Server Enterprise LTM configuration file.

The configuration file that an LTM uses is specified using the -C option.

LTM configuration file parameters

The following table describes each of the configuration parameters that the LTM recognizes. Parameters that are used by the Adaptive Server Enterprise LTM but not by the Adaptive Server Anywhere LTM are included in this list, and marked as either ignored (in which case they may be present in the configuration file, but have no effect) or as unsupported (in which case they will cause an error if present in the configuration file).

Parameter | Description
APC_pw | The password for the APC_user login name. This entry is present only in Adaptive Server Anywhere LTM configuration files.
APC_user | A user ID that is used when executing asynchronous procedures at the primary site. This user ID must have permissions appropriate for all asynchronous procedures at the primary site. This entry is present only in Adaptive Server Anywhere LTM configuration files.
backup_only | By default, this is off. If set to on, the LTM will replicate only backed-up transactions.
batch_ltl_cmds | Set to on (the default) to use batch mode. Batch mode can increase overall throughput, but may lead to longer response times.
batch_ltl_sz | The number of commands that are saved in the buffer before being sent to Replication Server, when batch_ltl_cmds is on. The default is 200.
batch_ltl_mem | The amount of memory that the buffer can use before its contents are sent to Replication Server, when batch_ltl_cmds is on. The default is 256 Kb.
Continuous | By default, this is on. When set to off, the LTM automatically shuts down as soon as all committed data has been replicated.
LTM_admin_pw | The password for the LTM_admin_user login name.
LTM_admin_user | The system administrator LTM login name that is used to log in to the LTM. This parameter is required so that the LTM can check whether a user logging on to the LTM to shut it down has the correct login name.
LTM_charset | The Open Client/Open Server character set for the LTM to use.
LTM_language | The Open Client/Open Server language for the LTM to use.
LTM_sortorder | The Open Client/Open Server sort order for the LTM to use to compare user names. You can specify any Adaptive Server Enterprise-supported sort order that is compatible with the LTM's character set. All sort orders in your replication system should be the same. The default sort order is a binary sort.
maint_cmds_to_skip | [ ignored ]
qualify_table_owner | Set to on for the LTM to send LTLs with table names and columns names, as well as table owners to Replication Server. The setting applies to all replicating tables, and the create replication definition statements must match this setting. The default is off.
rep_func | Set to on to use asynchronous procedure calls (APCs). The default is off.
Retry | The number of seconds to wait before retrying a failed connection to an Adaptive Server Anywhere database server or Replication Server. The default is 10 seconds.
RS | The name of the Replication Server to which the LTM is transferring the log.
RS_pw | The password for the RS_user login name.
RS_source_db | The name of the database whose log the LTM transfers to the Replication Server. This name must match the name of the database as defined within the Replication Server connection definitions. Most configurations use the same setting for both RS_Source_db and SQL_database configuration options.
RS_source_ds | The name of the server whose log the LTM transfers to the Replication Server. This name must match the name of the server as defined within the Replication Server connection definitions. Most configurations use the same setting for both RS_Source_ds and SQL_server configuration options.
RS_user | A login name for the LTM to use to log into Replication Server. The login name must have been granted connect source permission in the Replication Server.
scan_retry | The number of seconds that the LTM waits between scans of the transaction log. This parameter is somewhat different in meaning to that of the Adaptive Server Enterprise LTM. The Adaptive Server Anywhere server does not wake up and scan the log when records arrive in the log. For this reason, you may want to set the scan_retry value to a smaller number then that for an Adaptive Server Enterprise LTM.
skip_ltl_cmd_err | [ ignored ]
SQL_database | The primary site database name on the server SQL_server to which the LTM connects. For Adaptive Server Enterprise during recovery, this is the temporary database whose logs the LTM will transfer to Replication Server. The Adaptive Server Anywhere LTM uses the SQL_log_files parameter to locate offline transaction logs.
SQL_log_files | A directory that holds off-line transaction logs. The directory must exist when the LTM starts up. This entry is present only in Adaptive Server Anywhere LTM configuration files.
SQL_pw | The password for the SQL_user user ID.
SQL_server | The name of the primary site Adaptive Server Anywhere server to which the LTM connects. For Adaptive Server Enterprise during recovery, this is a data server with a temporary database whose logs the LTM will transfer to Replication Server. The LTM uses the SQL_log_files parameter to locate offline transaction logs.
SQL_user | The login name that the LTM uses to connect to the database specified by RS_source_ds and RS_source_db.
Example configuration file

  • The following is a sample LTM configuration file.

    # This is a comment line
# Names are case sensitive.
SQL_user=sa
SQL_pw=sysadmin
SQL_server=PRIMESV
SQL_database=primedb
RS_source_ds=PRIMEOS
RS_source_db=primedb
RS=MY_REPSERVER
RS_user=sa
RS_pw=sysadmin
LTM_admin_user=DBA
LTM_admin_pw=SQL
LTM_charset=cp850
scan_retry=2
SQL_log_files=e:\logs\backup
APC_user=sa
APC_pw=sysadmin


The Log Translation utility

With the Log Translation utility, you can translate a transaction log into a SQL command file.

You can access the Log Translation utility in the following ways:

  • From Sybase Central, using the Translate Log File wizard.

  • At a command prompt, using the dbtran command. This is useful for incorporating into batch or command files.


Translating a transaction log using the Translate Log File wizard

toggle To translate a transaction log into a command file

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Translate Log File.

    The Translate Log File wizard appears.

  4. Follow the instructions in the wizard.

Tip
You can also access the Translate Log File wizard from within Sybase Central using any of the following methods:

  • Choosing Tools > Adaptive Server Anywhere 9 > Translate Log File.

  • Selecting a database in the left pane, and choosing Translate Log File from the File menu.

  • Right-clicking a database, and choosing Translate Log File from the popup menu.


Translating a transaction log using the dbtran command-line utility

Syntax

Running against a transaction log:

dbtran [ options ] [ transaction-log ] [ SQL-file ]

Running against a database server:

dbtran [ options ]

Option | Description
@data | Read options from the specified environment variable or configuration file.
-a | Include uncommitted transactions.
-c "keyword=value; ..." | Supply database connection parameters—cannot be used with a transaction log name.
-d | Display output in chronological order.
-ek key | Specify encryption key.
-ep | Prompt for encryption key.
-f | Output only since the last checkpoint.
-g | Include audit records in output.
-ir offset1,offset2 | Include only the portion of the log between the two specified offsets.
-is source,... | Include only rows originating from the specified sources.
-it user.table,... | Include only operations on specified tables by specifying a comma-delimited list of user.table.
-j date/time | Output from the last checkpoint prior to the given time.
-m | Specify transaction logs directory (requires -n option).
-n filename | Output SQL file, when used against a database server.
-o filename | Log output messages to a file.
-q | Run quietly, do not print messages.
-r | Remove uncommitted transactions (default).
-rsu username,... | Override default Replication Server user names.
-s | Produce ANSI standard SQL UPDATE transactions.
-sr | Generate SQL Remote comments.
-t | Include trigger-generated transactions in output.
-u userid,... | Translate transactions for listed users only.
-x userid,... | Exclude transactions for listed users.
-y | Replace file without confirmation.
-z | Include trigger-generated transactions as comments only.
transaction-log | Log file to be translated.
SQL-file | Output file containing the translated information.
Description

The dbtran utility takes the information in a transaction log and places it as a set of SQL statements and comments into an output file. The utility can be run in the following ways:

  • Against a database server Run in this way, the utility is a standard client application. It connects to the database server using the connection string specified following the -c option, and places output in a file specified with the -n option. DBA authority is required to run in this way.

    The following command translates log information from the server asademo9 and places the output in a file named asademo.SQL.

    dbtran -c "eng=asademo9;dbn=asademo;uid=DBA;pwd=SQL" -n asademo.sql

  • Against a transaction log file Run in this way, the utility acts directly against a transaction log file. You should protect your transaction log file from general access if you want to prevent users from having the capability of running this statement.

    dbtran asademo.log asademo.sql

When the dbtran utility runs, it displays the earliest log offset in the transaction log. This can be an effective method for determining the order in which multiple log files were generated.

If -c is used, dbtran attempts to translate the online transaction log file, as well as all the offline transaction log files in the same directory as the online transaction log file. If the directory contains transaction log files for more than one database, dbtran may give an error. To avoid this problem, ensure that each directory contains transaction log files for only one database.

A transaction can span multiple transaction logs. If transaction log files contain transactions that span logs, translating a single transaction log file (for example dbtran asademo.log) can cause the spanning transactions to be lost. In order for dbtran to generate complete transactions, use the -c or -m options with the transaction log files in the directory.

For more information about recovering with transactions that span multiple log files, see Recovering from multiple transaction logs.

Exit codes are 0 (success) or non-zero (failure).

Log translation utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Include uncommitted transactions (-a)

The transaction log contains any changes made before the most recent COMMIT by any transaction. Changes made after the most recent commit are not present in the transaction log.

If -a is not used, only committed transactions appear in the output file. If -a is used, any committed transactions found in the transaction log are output followed by a ROLLBACK statement.

Connection string (-c)

When running the utility against a database server, this parameter specifies the connection string.

DBA authority is required to run dbtran.

For a description of the connection parameters, see Connection parameters.

Output in chronological order (-d)

Transactions are output in order from earliest to latest. This feature is provided primarily for use when auditing database activity: the output of this command should not be applied against a database.

Specify encryption key (-ek)

This option allows you to specify the encryption key for strongly encrypted databases directly in the command. If you have a strongly encrypted database, you must provide the encryption key to use the database or transaction log in any way.

For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify the correct key for a strongly encrypted database.

If you are running against a database server (using the -c option), make sure you specify the key using a connection parameter, not using the -ek option. For example, the following command gets the transaction log information about database enc.db from server sample, and saves its output in log.sql.

dbtran -n log.sql -c eng=sample;dbf=enc.db;uid=dba;pwd=sql;dbkey=mykey

Prompt for encryption key (-ep)

This option allows you to specify in the command that you want to be prompted for the encryption key. This option causes a dialog box to appear, in which you enter the encryption key. It provides an extra measure of security by never allowing the encryption key to be seen in clear text.

For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify the correct key for a strongly encrypted database.

If you are running against a database server (using the -c option), make sure you specify the key using a connection parameter, not using the -ep option. For example, the following command gets the transaction log information about database enc.db from server sample, and saves its output in log.sql.

dbtran -n log.sql -c eng=sample;dbf=enc.db;uid=dba;pwd=sql;dbkey=mykey

Output from last checkpoint only (-f)

Only transactions that were completed since the last checkpoint are output.

Include audit information (-g)

If the AUDITING database option is turned on, auditing information is added to the transaction log. You can include this information as comments in the output file using this option.

For more information, see AUDITING option [database].

The -g option implies the -a, -d, and -t options.

Include offset range (-ir)

Output a portion of the transaction log between two specified offsets.

Include rows from specified sources (-is)

Output operations on rows that have been modified by operations from one or more of the following sources, specified as a comma-separated list:

  • All All rows. This is the default setting.

  • SQLRemote Include only rows that were modified using SQL Remote. You can also use the short form SR.

  • RepServer Include only rows that were modified using the Replication Agent (LTM) and Replication Server. You can also use the short form RS.

  • Local Include only rows that are not replicated.

Include specified tables (-it)

Output those operations on the specified, comma-separated list of tables. Each table should be specified as owner.table.

Output from the last checkpoint prior to a given date (-j)

Only transactions from the most recent checkpoint prior to the given date and/or time are translated. The user-provided argument can be a date, time or date and time enclosed in quotes. If the time is omitted, the time is assumed to be the beginning of the day. If the date is omitted, the current day is assumed. The following is an acceptable format for the date and time: "YYYY/MMM/DD HH:NN".

Transaction logs directory (-m)

Use this option to specify a directory that contains transaction logs. This option must be used in conjunction with the -n option.

Output file (-n)

When you run the dbtran utility against a database server, use this option to specify the output file that holds the SQL statements.

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not display output messages. This option is available only when you run this utility from a command prompt. If you specify this option, you must also specify the -y option, or the operation will fail.

Do not include uncommitted transactions (-r)

Remove any transactions that were not committed. This is the default behavior.

Override Replication Server user names (-rsu)

By default, the -is option assumes the default Replication Server user names of dbmaint and sa. You can override this assumption using the -rsu option with a comma-separated list of user names.

Generate ANSI standard SQL UPDATE (-s)

If the option is not used, and there is no primary key or unique index on a table, the Log Translation utility generates UPDATE statements with a non-standard FIRST keyword in case of duplicate rows. If the option is used, the FIRST keyword is omitted for compatibility with the SQL standard.

Generate SQL Remote comments (-sr)

Place generated comments in the output file describing how SQL Remote distributes operations to remote sites.

Include transactions generated by triggers (-t)

By default, actions carried out by triggers are not included in the command file. If the matching trigger is in place in the database, when the command file is run against the database, the trigger will carry out the actions automatically. Trigger actions should be included if the matching trigger does not exist in the database against which the command file is to be run.

Output transactions for listed users only (-u)

This option allows you to limit the output from the transaction log to include only specified users.

Output transactions except for listed users (-x)

This option allows you to limit the output from the transaction log to exclude specified users.

Operate without confirming actions (-y)

Choosing this option automatically replaces existing command file(s) without prompting you for confirmation. If you specify -q, you must also specify -y or the operation will fail.

Include transactions generated by triggers as comments only (-z) Transactions that were generated by triggers will be included only as comments in the output file.

transaction-log Log file to be translated. Cannot be used together with -c or -m options.

SQL-file Output file containing the translated information. For use with transaction-log only.


The Ping utility

The Ping utility is provided to assist in troubleshooting connection problems.

Troubleshooting connections using the dbping command-line utility


Troubleshooting connections using the dbping command-line utility

Syntax

dbping [ options ]

Option | Description
@data | Read options from the specified environment variable or configuration file.
-c "keyword=value; ..." | Database connection parameters.
-d | Make a database connection if the server is found.
-l library | Load specified ODBC driver or library.
-m | Use ODBC driver manager.
-o filename | Log output messages to a file.
-pc property,... | Report specified connection properties.
-pd property,... | Report specified database properties.
-ps property,... | Report specified database server properties.
-q | Operate quietly—do not print messages.
-z | Display debugging information.
Description

The dbping utility is a tool to help debug connection problems. It takes a full or partial connection string and returns a message indicating whether the attempt to locate a server or database, or to connect, was successful.

The utility can be used for embedded SQL or ODBC connections. It cannot be used for jConnect (TDS) connections.

Exit codes are 0 (success) or non-zero (failure).

Ping utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Connection parameters (-c)

For a description of the connection parameters, see Connection parameters. If the connection parameters are not specified, connection parameters from the SQLCONNECT environment variable are used, if set.

Make database connection (-d)

Ping the database, not just the server.

If you do not supply the -d option, then dbping reports success if it finds the server specified by the -c option. If you do supply the -d option, then dbping reports success only if connects to the server and also connects to a database.

For example, if you have a server named blair running the database sample, the following succeeds:

dbping -c "ENG=blair;DBN=asademo"

The following command fails, with the message Ping database failed -- specified database not found:

dbping -c "ENG=blair;DBN=asademo" -d

Load specified library (-l)

Specify the library to use (without its file extension). This option avoids the use of the ODBC driver manager, and so is particularly useful on UNIX operating systems.

For example, the following command loads the ODBC driver directly:

dbping -m -c "dsn=ASA 9.0 Sample" -l dbodbc9

On UNIX, if you want to use a threaded connection library, you must use the threaded version of the Ping utility, dbping_r.

Use ODBC to connect (-m)

Establish a connection using ODBC. By default, the utility connects using the embedded SQL interface.

Log output messages to file (-o) Write output messages to the named file.

Report connection properties (-pc)

Upon connection, display the specified connection properties. Supply the properties in a comma-separated list. You must specify enough connection information to establish a database connection if you use this option.

For a list of connection properties, see Connection-level properties.

For example, the following command displays the DIVIDE_BY_ZERO_ERROR option setting, which is available as a connection property.

dbping -c ... -pc Divide_by_zero_error

Report database properties (-pd)

Upon connection, display the specified database properties. Supply the properties in a comma-separated list.

For a list of database properties, see Database-level properties.

For example, the following command displays the Java version in use by the database:

dbping -c ... -pd JDKVersion

Report database server properties (-ps)

Upon connection, display the specified database server properties. Supply the properties in a comma-separated list. You must specify enough connection information to establish a database connection if you use this option.

For a list of database server properties, see Server-level properties.

For example, the following command displays the number of licensed seats or processors for the database server:

dbping -c ... -ps LicenseCount

Operate quietly (-q)

If dbping fails, a message is always displayed. If dbping succeeds, no message appears if -q is specified.

Display debugging information (-z)

This option is available only when an embedded SQL connection is being attempted. That is, it cannot be combined with -m or -l. It displays the network communication protocols used to attempt connection, and other diagnostic messages.


The Rebuild utility

Databases can be rebuilt using the Rebuild batch file, command file, or shell script, which invokes a series of utilities to rebuild a database, or as part of the unload process using the Unload Database wizard in Sybase Central.

For more information about the Unload Database wizard, see The Unload utility.

Rebuilding a database using the rebuild batch or command file


Rebuilding a database using the rebuild batch or command file

Syntax

rebuild old-database new-database [ DBA-password ]

See also
  • Unloading a database using the dbunload command-line utility
  • Creating a database using the dbinit command-line utility
  • The Interactive SQL utility
Description

This batch file, command file, or shell script uses dbunload to rebuild old-database into new-database. This is a simple script, but it helps document the rebuilding process, and provides a basis for customization. Both database names should be specified without extensions. An extension of .db is automatically added.

You can use dbunload with the -ar option to carry out unloading and reloading without using the rebuild batch file.

The DBA-password must be specified if the password to the DBA user ID in the old-database is not the initial password SQL.

Rebuild runs the dbunload, dbinit, and Interactive SQL commands with the default options. If you need different options, you will need to run the three commands separately.

Exit codes are 0 (success) or non-zero (failure).

This utility does not accept the @data parameter to read in options from a configuration file.


The Server Location utility

The Server Location utility is provided to assist in diagnosing connection problems by locating database servers on the immediate TCP/IP network.

Locating servers using the dblocate command-line utility


Locating servers using the dblocate command-line utility

Syntax

dblocate [ options ] [ server-name ]

Option | Description
@data | Read options from the specified environment variable or configuration file.
-n | Do not resolve IP addresses into machine names.
-o filename | Log output messages to a file.
-q | Operate quietly—do not print messages.
server-name | A host name or IP address to restrict the list to servers running on the specified machine.
Description

The dblocate utility locates any Adaptive Server Anywhere database servers running over TCP/IP on the immediate network. It prints a list of database servers and their addresses.

Depending on your network, the utility may take several seconds before printing its results.

Exit codes are 0 (success) or non-zero (failure).

The database server can register itself with an LDAP server, which keeps track of all servers in an enterprise. This allows both clients and the Server Location utility (dblocate) to find them regardless of whether they are on a WAN or LAN, through firewalls, and without specifying an IP address. LDAP is only used with TCP/IP, and only on network servers.

For more information about LDAP, see Connecting using an LDAP server.

If the same database server name is found more than once, the Server Location utility displays the IP address of each host, even if the -n option is not specified. The same server name could be found in cases where a server is running on a machine with multiple IP addresses (for example, if the machine has multiple network cards), or if a network server is running on a remote machine and a personal server with the same server name is running on the local machine.

Server location utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Do not resolve IP addresses into machine names (-n)

List IP addresses in the output, rather than machine names. This may increase performance because looking up machine names may be slow.

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not display output messages.

server-name

List only database servers running on the machine with the specified IP address or host name. If you specify the -n option, the server-name value must be an IP address. If you do not specify -n, then you must supply a host name for the server-name. For example, the following command looks for servers on the machine jfrancis:

dblocate jfrancis


The Service Creation utility

The Service Creation utility is a tool used to create, delete, and modify Adaptive Server Anywhere services. You can access the Service Creation utility in the following ways:

  • From Sybase Central, using the Service Creation wizard.

  • At a command prompt, using the dbsvc command.


Creating services using the Service Creation wizard

toggle To create a service

  1. In the left pane of Sybase Central, select the Adaptive Server Anywhere 9 plug-in.

  2. In the right pane, click the Services tab.

  3. From the File menu, choose New > Service.

    The Service Creation wizard appears.


Managing services using the dbsvc command-line utility

Syntax

dbsvc [ -q ] [-y ] -d <svc>

dbsvc [ -q ] -g <svc>

dbsvc [ -q ] -l

dbsvc [ -q ] [ -y ] <creation options> -w <svc> <details>

dbsvc [ -q ] -u <svc>

dbsvc [ -q ] -x <svc>

details:

<full-executable-path> [ options ]

Major option | Description
@data | Read options from the specified environment variable or configuration file.
-d service_name | Delete a service.
-g service_name | Get details of a service.
-l | List all Adaptive Server Anywhere services.
-u service_name | Starts the service named service_name.
-w executable parameters | Creates service.
-x service_name | Stops the service named service_name.
Creation option | Description
-a acct | Account name to use (used with -p).
-as | Use local system account.
-I | Allow service to interact with desktop.
-p | Password for account (used with -a).
-rg dependency,... | Specify group dependencies when creating a service.
-rs dependency,... | Specify service dependencies when creating a service.
-s startup | Startup option (default manual)—you must specify automatic, manual, or disabled.
-sd description | Provide a description of the service.
-sn name | Specify a name for the service.
-t type | Specify the type of service.
Modifier option | Description
-cm | Display the service creation command.
-q | Do not print banner.
-y | Delete or overwrite service without confirmation.
Description

A service runs a database server or other application with a set of options. This utility provides a comprehensive way of managing Adaptive Server Anywhere services on Windows. The Service Creation utility provides the same functionality as the Service Creation wizard in Sybase Central.

You must be a member of the Administrators group on the local machine to use the Service Creation utility.

Exit codes are 0 (success) or non-zero (failure).

For more information about services, see Understanding Windows services.

Service creation utility options

When you use the Service Creation utility, you can choose from major options, modifier options, and details options.

Major options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Delete a service (-d)

Removes the named service from the list of services. If you supply -y, any service is deleted without confirmation.

Get details of a service (-g)

Lists the definition of the service, not including the password.

List all Adaptive Server Anywhere services (-l)

Lists the available Adaptive Server Anywhere services.

Start a service (-u)

Starts a service named service_name.

Create service (-w)

Creates a new service, or overwrites one if one of the same name exists. If you supply -y, any existing service is overwritten without confirmation.

You must supply the full path to the executable that you want to use as a service, as the account under which the service is running may not have the appropriate SQL Anywhere directory in its path.

You must supply parameters appropriate for the service you are creating. For more information, see the following locations:

  • dbsrv9 and dbeng9 The database server.

  • dbmlsrv9 MobiLink Synchronization Server Options.

  • dbmlsync MobiLink synchronization client

  • dbremote The Message Agent.

Stop a service (-x)

Stops a service named service_name.

Creation options

Account name (-a)

All services run under a Windows account. If you run under an account you've created, you must name the account with the -a option and supply a password with the -p option.

Use local system account (-as)

All services run under a Windows account. Using the -as option, the service will run under the Windows LocalSystem account. No password is required. On of -a or -as must be used.

Allow service to interact with desktop (-I)

Displays an icon that you can double-click to display the server window.

Password for account (-p)

Use this option with the -a option to specify the password for the account the service runs under.

Set group dependencies (-rg)

At least one service from each of the groups in the list must be started before the service being created is allowed to start.

Set service dependencies (-rs)

All the services in the list must have started before the service being created is allowed to start.

Startup option (-s)

Sets startup behavior for Adaptive Server Anywhere services. You can set startup behavior to Automatic, Manual, or Disabled. The default is Manual.

Service description (-sd)

Use this option to provide a description of the service. The description appears in the Windows Service Manager.

Service name (-sn)

Use this option to provide a name for the service. This name appears in the Windows Service Manager. If you do not specify the -sn option, the default service name is Adaptive Server Anywhere - <svc>. For example, the following service is named Adaptive Server Anywhere - myserv by default.

dbsvc -as -w myserv
"C:\Program Files\Sybase\SQL Anywhere 9\win32\dbeng9.exe"

In order to have the service name myserv appear in the Windows Service Manager, you need to execute the following (entered all on one line):

dbsvc -as -sn myserv -w myserv
"C:\Program Files\Sybase\SQL Anywhere 9\win32\dbeng9.exe"

Type of service (-t)

Specifies the type for this service. You can choose from the following types:

Type | Description
Network | Adaptive Server Anywhere network database server (dbsrv9)
Standalone | Adaptive Server Anywhere personal database server (dbeng9)
DBRemote | SQL Remote Message Agent (dbremote)
MobiLink | MobiLink synchronization server (dbmlsrv9)
DBMLSync | MobiLink synchronization client (dbmlsync)

The default setting is Standalone.

Modifier options

Display the service creation command (-cm)

Displays the command used to create the service. This option can be used to output the creation command to a file, which can be used to add the service on another machine or can be used to restore a service to its original state if changes have been made to it. You must specify the -g option or -l option with -cm or the command fails. Specifying -g displays the creation command for the specified service, while specifying -l displays the creation command for all services.

If the specified service does not exist, the command to delete the service is generated. For example, if service_1 does not exist on the machine, dbsvc -cm -g service_1 would return the following command to delete the service_1 service:

dbsvc -y -d "service_1"

If the service does not use the LocalSystem account, there is no way to retrieve the password, so it is not included in the command that is generated. If you created the service with -a user -p password, only -a user is included in the output.

Do not print banner (-q)

Suppress the informational banner. If you specify this option when modifying or deleting an existing service, you must also specify -y or the operation will fail.

Delete or overwrite service without confirmation (-y)

Automatically carries out the action without prompting for confirmation. This option can be used with the -w or -d options. If you specify -q when modifying or deleting an existing service, you must also specify -y or the operation will fail.

Examples

Create a personal server service called myserv, which starts the specified server with the specified parameters. The server runs as the LocalSystem user:

dbsvc -as -w myserv "C:\Program Files\Sybase\SQL Anywhere 9\win32\dbeng9.exe" -n myeng -c 8m "C:\Program Files\Sybase\SQL Anywhere 9\sample.db"

Create a network server service called mynetworkserv. The server runs under the local account, and starts automatically when the machine is booted:

dbsvc -as -s auto -t network -w mynetworkserv "C:\Program Files\Sybase\SQL Anywhere 9\win32\dbsrv9.exe" -x tcpip -c 8m "C:\Program Files\Sybase\SQL Anywhere 9\sample.db"

List all details about service myserv:

dbsvc -g myserv

Delete the service called myserv, without prompting for confirmation:

dbsvc -y -d myserv

Create a service dependent on the Workstation service and the TDI group:

dbsvc -rs Workstation -rg TDI -w ...

Create a service called mysyncservice:

dbsvc -as -s manual -t dbmlsync -w mysyncservice "C:\Program Files\Sybase\SQL Anywhere 9\win32\dbmlsync.exe" -c "dsn=ultralite 9.0 sample"

Generate the command to create the service_1 service and output it to a file called restoreservice.bat:

dbsvc -cm -g service_1 > restoreservice.bat

The restoreservice.bat file contains the following:

dbsvc -t Standalone -s Manual -as -y -w "service_1"
"C:\Program Files\Sybase\SQL Anywhere 9\win32\dbeng9.exe"


The Spawn utility

This utility is provided to start a database server in the background.

Running a server in the background using the dbspawn command-line utility


Running a server in the background using the dbspawn command-line utility

Syntax

dbspawn [ options ] server-command

Option | Description
@data | Read options from the specified environment variable or configuration file.
-f | Do not check for a running server.
-p | Report operating system process ID.
-q | Quiet mode—do not print messages.
server-command | Specifies the command line for starting the database server.
Description

The dbspawn utility is provided to start a server in the background. dbspawn starts the server in the background and returns with an exit code of 0 (success) or non-zero (failure). If the server specified in server-command is already running, dbspawn reports failure.

The dbspawn utility is useful for starting a server from a batch file, especially when subsequent commands in the batch file require a server that is accepting requests.

If the specified path includes at least one space, and if you are executing the spawn utility from a batch file, you must enclose the path in one set of double quotes. For example,

dbspawn dbeng9 "C:\Program Files\Sybase\SQL Anywhere 9\asademo.db"

If the specified path includes at least one space, and if you are executing the spawn utility at a command prompt, you must provide an extra set of quotes, and escape the quotes around the database file. For example,

dbspawn dbeng9 "\"C:\Program Files\Sybase\SQL Anywhere 9\asademo.db\""

If the specified path does not contain spaces, then quotes are not required.

Spawn utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Do not check for a running server (-f)

If a database server is already running, the dbspawn command may use it. This option forces dbspawn to start a new database server each time it is run.

Report process ID (-p)

The operating system process ID of the database server process. For example:

dbspawn -p dbeng9 -n newserver

reports a message of the following form to a command prompt:

New process id is 306

Operate quietly (-q)

Do not display output messages.

server-command Specifies the command line for starting the database server.

For a description of the server commands, see The database server.


The Stop utility

The Stop utility stops a database server. You can use the -d option to stop a specified database.

The Stop utility can only be run at a command prompt. In windowed environments, you can stop a database server by clicking Shutdown on the Server Messages window.

The Stop utility (dbstop) is not available on NetWare.

Stopping a database server using the dbstop command-line utility


Stopping a database server using the dbstop command-line utility

Syntax

dbstop [ options ] [ server-name ]

Option | Description
@data | Read options from the specified environment variable or configuration file.
-c "keyword=value; ..." | Connection parameters.
-d | Stop specified database only.
-o filename | Log output messages to a file.
-q | Quiet mode—do not print messages.
-x | Do not stop if there are active connections.
-y | Stop without prompting even if there are active connections.
server-name | Name of a local database server to stop.
Description

Options let you control whether a server is stopped, even if there are active connections, and whether to stop a server or only a database.

Exit codes are 0 (success) or non-zero (failure).

The Stop [dbstop] utility is not available on NetWare.

Stop utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Connection parameters (-c)

When stopping a network server, you must supply a connection string with a user ID that has permissions to stop the server. By default, DBA permission is required on the network server, and all users can shut down a personal server, but the -gk server option can be used to change this.

The behavior of dbstop can be controlled if there are active connections on a server. If there are active connections, dbstop provides a prompt asking if you want to shut down the server. If you specify unconditional=YES, the server is shut down without prompting, even if there are active connections.

If you supply connection parameters, do not supply a server name as well.

For more information, see Connection parameters, Unconditional connection parameter [UNC], and -gk server option.

Stop database only (-d)

Do not stop the database server. Instead, only stop the database specified in the connection string.

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not print a message if the database was not running.

Do not stop if there are active connections (-x)

Do not stop the server if there are still active connections to the server.

Stop without prompting (-y)

Stop the server even if there are still active connections to the server.

server-name

The name of a database server running on the current machine. The database server must be started so that no permissions are required to shut it down. The personal database server starts in this mode by default. For the network database server, you must supply the -gk all option.

If you supply a server name, do not supply connection parameters as well.

For more information, see -gk server option.

Examples

You are running the server named myserver without a database. To stop the server, specify the utility database as a DatabaseName (DBN) connection parameter:

dbstop -c "uid=DBA;pwd=SQL;eng=myserver;dbn=utility_db"

You are running the server named myserver with the database asademo.db started. To stop the server and database:

dbstop -c "uid=DBA;pwd=SQL;eng=myserver"


The Transaction Log utility

With the Transaction Log utility, you can display or change the name of the transaction log or transaction log mirror associated with a database. You can also stop a database from maintaining a transaction log or mirror, or start maintaining a transaction log or mirror.

A transaction log mirror is a duplicate copy of a transaction log, maintained by the database in tandem.

The name of the transaction log is first set when the database is initialized. The Transaction Log utility works with database files. The database server must not be running on that database when the transaction log filename is changed (or an error message appears).

You can access the Transaction Log utility in the following ways:

  • From Sybase Central, using the Change Log File Settings wizard.

  • From Interactive SQL, using the ALTER DATABASE dbfile MODIFY LOG statement.

    For more information, see ALTER DATABASE statement.

  • At a command prompt, using the dblog command.


Managing log files using the Change Log File Settings wizard

toggle To change a transaction log file name

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Change Log File Settings.

    The Change Log File Settings wizard appears.

  4. Follow the instructions in the wizard.

Tip
You can also access the Change Log File Settings wizard by choosing Tools > Adaptive Server Anywhere 9 > Change Log File Settings.

Previous Next


Managing log files using the dblog command-line utility

Syntax

dblog [ options ] database-file

Option | Description
@data | Read options from the specified environment variable or configuration file.
-ek key | Specify encryption key.
-ep | Prompt for encryption key.
-g n | Sets the LTM generation number to n.
-il | Ignores the LTM truncation offset stored in the database.
-ir | Ignores the SQL Remote truncation offset stored in the database.
-is | Ignores the dbmlsync truncation offset stored in the database.
-m mirror-name | Set transaction log mirror name.
-n | No longer use a transaction log or mirror log.
-o file-name | Log output messages to a file.
-q | Quiet mode—do not print messages.
-r | No longer use a transaction log mirror.
-t log-name | Set the transaction log name.
-x n | Set the transaction log current relative offset to n.
-z n | Set the transaction log starting offset to n.
Description

The dblog utility allows you to display or change the name of the transaction log or transaction log mirror associated with a database. You can also stop a database from maintaining a transaction log or mirror, or start maintaining a transaction log or mirror.

The utility displays additional information about the transaction log, including the following:

  • Version number

  • Starting offset, for use in replication

  • Ending offset, for use in replication

  • Page size

  • Total number of pages

  • Number of empty pages

  • Percentage of the log file in use

Exit codes are 0 (success) or non-zero (failure).

Transaction log utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Specify encryption key (-ek)

This option allows you to specify the encryption key for strongly encrypted databases directly in the command. If you have a strongly encrypted database, you must provide the encryption key to use the database or transaction log in any way. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify the correct key for a strongly encrypted database.

Prompt for encryption key (-ep)

This option allows you to specify that you want to be prompted for the encryption key. This option causes a dialog box to appear, in which you enter the encryption key. It provides an extra measure of security by never allowing the encryption key to be seen in clear text. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify the correct key for a strongly encrypted database.

Set the generation number (-g)

Use this option if you are using the Log Transfer Manager to participate in a Replication Server installation. It can be used after a backup is restored, to set the generation number. It performs the same function as the following Replication Server function:

dbcc settrunc( 'ltm', 'gen_id', n )

For information about generation numbers and dbcc, see your Replication Server documentation.

Ignore the LTM truncation offset (-il)

This option can be used if you have stopped using the Log Transfer Manager to participate in a Replication Server installation on this database, but continue to use SQL Remote or MobiLink synchronization. It resets the Log Transfer Manager log offset that is kept for the DELETE_OLD_LOGS option, allowing transaction logs to be deleted when they are no longer needed.

It performs the same function as the following Replication Server function:

dbcc settrunc( 'ltm', 'ignore' )

For information about dbcc, see your Replication Server documentation.

Ignore the SQL Remote truncation offset (-ir)

This option can be used if you have stopped using SQL Remote on this database, but continue to use the Log Transfer Manager or MobiLink synchronization. It resets the SQL Remote log offset that is kept for the DELETE_OLD_LOGS option, allowing transaction logs to be deleted when they are no longer needed.

Ignore the dbmlsync truncation offset (-is)

This option can be used if you have stopped using MobiLink synchronization on this database, but continue to use the Log Transfer Manager or SQL Remote. It resets the MobiLink log offset that is kept for the DELETE_OLD_LOGS option, allowing transaction logs to be deleted when they are no longer needed.

Set the name of the transaction log mirror file (-m)

This option sets a filename for a new transaction log mirror. If the database is not currently using a transaction log mirror, it starts using one. If the database is already using a transaction log mirror, it changes to using the new file as its transaction log mirror.

No longer use a transaction log (-n)

Stop using a transaction log, and stop using a mirror log. Without a transaction log, the database can no longer participate in data replication or use the transaction log in data recovery. If a SQL Remote, Log Transfer Manager, or dbmlsync truncation offset exists, the transaction log cannot be removed unless the corresponding ignore option (-il for the Log Transfer Manager, -ir for SQL Remote, or -is for dbmlsync) is also specified.

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not display output messages.

No longer use a transaction log mirror (-r)

For databases that maintain a mirrored transaction log, this option changes their behavior to maintain only a single transaction log.

Set the name of the transaction log file (-t)

This option sets a filename for a new transaction log. If the database is not currently using a transaction log, it starts using one. If the database is already using a transaction log, it changes to using the new file as its transaction log.

Set the current log offset (-x)

For use when reloading a SQL Remote consolidated database. This option resets the current log offset so that the database can take part in replication.

For information on how to use this option, see Unloading and reloading a database participating in replication.

Set the starting log offset (-z)

For use when reloading a SQL Remote consolidated database. This option resets the starting log offset so that the database can take part in replication.

For information on how to use this option, see Unloading and reloading a database participating in replication.


The Uncompression utility (deprecated)

With the Uncompression utility, you can expand a compressed database file created by the Compression utility. The Uncompression utility reads the compressed file and restores the database file to its uncompressed state.

You can access the Uncompression utility in the following ways:

  • From Sybase Central, using the Uncompress Database wizard.

  • At a command prompt, using the dbexpand command. This is useful for incorporating into batch or command files.

Deprecated feature
The use of compressed databases is deprecated.

Uncompressing a database using the Uncompress Database wizard
Uncompressing a database using the dbexpand command-line utility

Previous Next


Uncompressing a database using the Uncompress Database wizard

toggle To uncompress a compressed database file

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Uncompress Database.

    The Uncompress Database wizard appears.

  4. Follow the instructions in the wizard.

Tip
You can also access the Uncompress Database wizard by choosing Tools > Adaptive Server Anywhere 9 > Uncompress Database.

Previous Next


Uncompressing a database using the dbexpand command-line utility

Syntax

dbexpand [ options ] compressed-database-file [ database-file ]

Option | Description
@data | Read options from the specified environment variable or configuration file.
-ek key | Specify encryption key.
-ep | Prompt for encryption key.
-o filename | Log output messages to a file.
-q | Operate quietly—do not print messages.
-y | Erase an existing output file without confirmation.
Description

The input filename extension defaults to cdb. The output filename (with extension) must not have the same name as the input filename (with extension).

Exit codes are 0 (success) or non-zero (failure).

Uncompression utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Specify encryption key (-ek)

This option allows you to specify the encryption key for strongly encrypted databases directly in the command. If you have a strongly encrypted database, you must provide the encryption key to use the database or transaction log in any way. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify a key for a strongly encrypted database.

Prompt for encryption key (-ep)

This option allows you to specify that you want to be prompted for the encryption key. This option causes a dialog box to appear, in which you enter the encryption key. It provides an extra measure of security by never allowing the encryption key to be seen in clear text. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify a key for a strongly encrypted database.

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not display output messages. This option is available only when you run this utility from a command prompt.

Operate without confirming actions (-y)

Choosing this option automatically replaces an existing database file without prompting you for confirmation.


The Unload utility

With the Unload utility, you can unload a database and put a set of data files in a named directory. The Unload utility creates an Interactive SQL command file to rebuild your database. It also unloads all of the data in each of your tables into files in the specified directory in comma-delimited format. Binary data is properly represented with escape sequences.

You can also use the Unload utility to directly create a new database from an existing one. This avoids potential security problems with the database contents being written to ordinary disk files.

If you only want to unload table data, you can do so in one step using the Unload Data dialog in Sybase Central.

For more information, see Using the Unload Data dialog.

Accessing the Unload utility

You can access the Unload utility in the following ways:

  • From Sybase Central, using the Unload Database wizard.

  • At a command prompt, using the dbunload command. This is useful for incorporating into batch or command files.

The Unload utility should be run from a user ID with DBA authority. This is the only way you can be sure of having the necessary privileges to unload all the data. In addition, the reload.sql file should be run from the DBA user ID. (Usually, it is run on a new database where the only user ID is DBA with password SQL.)

The database server -gl option controls the permissions required to unload data from the database.

For information, see -gl server option.

Objects owned by dbo

The dbo user ID owns a set of Adaptive Server Enterprise-compatible system objects in a database.

The Unload utility does not unload the objects that were created for the dbo user ID during database creation. Changes made to these objects, such as redefining a system procedure, are lost when the data is unloaded. Any objects that were created by the dbo user ID since the initialization of the database are unloaded by the Unload utility, and so these objects are preserved.

Unloading and replication

There are special considerations for unloading databases involved in replication.

For information, see Unloading and reloading a database participating in replication and Upgrading the database file format.


Unloading a database using the Unload Database wizard

The Unload Database wizard walks you through the steps for unloading a database in Sybase Central. When using this wizard to unload your database, you can choose to unload all the tables in a database, or only a subset of tables from the database. Only tables for users selected in the Filter Objects by Owner dialog appear in the Unload Database wizard. If you want to view tables belonging to a particular database user, right-click the database you are unloading, choose Filter Objects by Owner from the popup menu, and then select the desired user in the resulting dialog.

The Unload Database wizard also gives you the option to reload into an existing database, rather than into a reload file. In order to do this, you must be connected to both the database you are unloading and the database you are reloading into in Sybase Central.

toggle To unload a database file or a running database

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Unload Database.

    The Unload Database wizard appears.

  4. Follow the instructions in the wizard.

Tip
You can also access the Unload Database wizard from within Sybase Central using any of the following methods:

  • Choosing Tools > Adaptive Server Anywhere 9 > Unload Database.

  • Selecting a database in the left pane, and choosing Unload Database from the File menu.

  • Right-clicking a database, and choosing Unload Database from the popup menu.

For full information on unloading a database from Sybase Central, see Exporting databases.


Unloading a database using the dbunload command-line utility

Syntax

dbunload [ options ] [ directory ]

Option | Description
@data | Read options from the specified environment variable or configuration file.
-ac "keyword=value; ..." | Supply connection parameters for the reload.
-an database | Create a database file with the same settings as the database being unloaded, and automatically reloads it.
-ap size | Specify the page size of the new database (-an or -ar must also be specified).
-ar [directory] | Rebuild and replace database.
-c "keyword=value; ..." | Supply database connection parameters for unload.
-d | Unload data only.
-e table, ... | Do not unload listed tables.
-ea algorithm | Specify which strong encryption algorithm to encrypt your database with: you can choose AES or AES_FIPS.
-ek key | Specify encryption key for new database.
-ep | Prompt for encryption key for new database.
-ii | Internal unload, internal reload (default).
-ix | Internal unload, external reload.
-jr | Ignore Java when unloading or reloading.
-m | Do not preserve user ids for a replicating database.
-n | No data—schema definition only.
-o filename | Log output messages to a file.
-p char | Specify the escape character for external unloads (default "\").
-q | Quiet mode—no windows or messages.
-r reload-file | Specify the name and directory of generated reload Interactive SQL command file (default reload.sql).
-t table,... | Unload only the listed tables.
-u | Unordered data. Do not use indexes to unload data.
-v | Verbose messages.
-xi | External unload, internal reload.
-xx | External unload, external reload.
-y | Replace the command file without confirmation.
Description

The directory is the destination directory where the unloaded data is to be placed. The reload.sql command file is always relative to the current directory of the user.

In the default mode, or if -ii or -ix is used, the directory used by dbunload to hold the data is relative to the database server, not to the current directory of the user.

For details of how to supply a filename and path in this mode, see UNLOAD TABLE statement.

If -xi or -xx is used, the directory is relative to the current directory of the user.

If no list of tables is supplied, the whole database is unloaded. If a list of tables is supplied, only those tables are unloaded.

Unloaded data includes the column list for the LOAD TABLE statements generated in the reload.sql file. Unloading the column list facilitates reordering of the columns in a table. Tables can be dropped or recreated, and then repopulated using reload.sql.

Exit codes are 0 (success) or non-zero (failure).

There are special considerations for unloading databases involved in replication. For information, see Unloading and reloading a database participating in replication.

Password case sensitivity

When a database is unloaded using -an or -ar, the password case sensitivity setting is preserved. For example, if you unloaded a database with case sensitive passwords and specified -an or -ar, the newly-created database would also have case-sensitive passwords. When you do not specify -an or -ar, password case sensitivity is determined as follows:

  • if the password was originally entered into a database that used case sensitive passwords, then the password remains case sensitive, even when reloaded into a case-insensitive database.

  • if the password was originally entered into a database with case insensitive passwords, then the lowercase version of the password must be used if the password is reloaded into a case sensitive database.

Encrypted databases

If you want to unload a strongly encrypted database, you must provide the encryption key. You can use the DatabaseKey (DBKEY) connection parameter to provide the key in the command. Alternatively, if you want to be prompted for the encryption key rather than entering it in plain view, you can use the -ep server option as follows:

dbunload -c "dbf=enc.db;start=dbeng9 -ep"

If you are using dbunload -an to unload a database and reload into a new one, and you want to use the -ek or -ep options to set the encryption key for the new database, keep the following in mind:

  • If the original database is strongly encrypted, you need to specify the key for the original database using the DatabaseKey (DBKEY) connection parameter in the -c option, not using -ek or -ep.

  • Using the -ek and -ep options, it is possible to unload an unencrypted database and reload into a new, strongly encrypted database. When you use -ep and -an, you must confirm the key correctly or the unload fails.

  • If the original database is strongly encrypted, but the -ek and -ep options are not used, then the new database will be encrypted with simple encryption.

  • The -ek and -ep options are ignored if -an is not specified.

For more information about encryption, see -ep server option or the DatabaseKey connection parameter [DBKEY].

Rebuilding a database

To unload a database, start the database server with your database, and run the Unload utility with the DBA user ID and password.

To reload a database, create a new database and then run the generated reload.sql command file through Interactive SQL.

On Windows 95/98/Me, Windows NT/2000/XP, and UNIX, there is a file (rebuild.bat, rebuild.cmd, or rebuild) that automates the unload and reload process.

For more information, see The Rebuild utility.

Unload utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Connection parameters for reload database (-ac)

This option causes the Unload utility to connect to an existing database and reload the data directly into it. You can combine the operation of unloading a database and reloading the results into an existing database using this option.

Typically, you would create a new database using the Initialization utility, and then reload it using this option. This method is useful when you want to change initialization options, such as page size or collation. If you are changing collations, the -xx option should also be used to ensure that character set translation occurs properly for both the old and new databases.

For example, the following command (which should be entered all on one line) loads a copy of the asademo.db database into an existing database file named newdemo.db:

dbunload -c "uid=DBA;pwd=SQL;dbf=asademo.db" -ac "uid=DBA;pwd=SQL;dbf=newdemo.db"

If you use this option, no interim copy of the data is created on disk, so you do not specify an unload directory in the command. This provides greater security for your data.

Create a database for reloading (-an)

You can combine the operations of unloading a database, creating a new database, and loading the data using this option. This option applies to personal server connections, and network server connections over shared memory. When you specify -an, the case sensitivity setting for passwords is preserved.

Typically, you would use this option when you do not want to change the initialization options of your database. The options specified when you created the source database are used to create the new database.

For example, the following command (which should be entered all on one line) creates a new database file named asacopy.db and copies the schema and data of asademo.db into it:

dbunload -c "uid=DBA;pwd=SQL;dbf=asademo.db" -an asacopy.db

If you use this option, no interim copy of the data is created on disk, so you do not specify an unload directory in the command. This provides greater security for your data, but at some cost for performance.

You do not need to specify a directory for this option.

When the new database is created, the dbspace file names have an R appended to the file name to prevent file name conflicts if the dbspace file for the new database is created in the same directory as the dbspace for the original database. For example, if an unloaded database has a dbspace called library in the file library.db, then the library dbspace for the new database is library.dbR.

Set page size for the new database (-ap)

This option allows you to set the page size of the new database. The page size for a database can be (in bytes) 1024, 2048, 4096, 8192, 16384, or 32768, with 2048 being the default. You must specify either -an or -ar with this option. If there are already databases running on the database server, the server's page size (set with the -gp option) must be large enough to handle the new page size.

For more information, see -gp server option.

Rebuild and replace database (-ar)

This option creates a new database with the same settings as the old database, reloads it, and replaces the old database. If you use this option, there can be no other connections to the database, and the database connection must be local, not over a network. When you specify -an, the case sensitivity setting for passwords is preserved.

If you specify an optional directory, the transaction log offsets are reset for replication purposes, and the transaction log from the old database is moved to the specified directory. The named directory should be the directory that holds the old transaction logs used by the Message Agent and the Replication Agent. The transaction log management is handled only if the database is used in replication: if there is no SQL Remote publisher or LTM check, then the old transaction log is not needed and is deleted instead of being copied to the specified directory.

For more information on transaction log management, see Backup methods for remote databases in replication installations.

Connection parameters for source database (-c)

For a description of the connection parameters, see Connection parameters. The user ID should have DBA authority, to ensure that the user has permissions on all the tables in the database.

For example, the following statement unloads the asademo database running on the sample_server server, connecting as user ID DBA with password SQL. The data is unloaded into the c:\unload directory.

dbunload -c "eng=sample_server;dbn=asademo;uid=DBA;pwd=SQL" c:\unload

Unload data only (-d)

With this option, none of the database definition commands are generated (CREATE TABLE, CREATE INDEX, and so on); reload.sql contains statements to reload the data only.

No data output for listed tables (-e)

This option is accessible only when you run this utility at a command prompt. If you want to unload almost all of the tables in the database, the -e option unloads all tables except the specified tables. A reload.sql file created with the -e option should not be used to rebuild a database because the file will not include all the database tables.

Specify encryption algorithm (-ea)

This option allows you to choose which strong encryption algorithm used to encrypt your new database. You can choose either AES (the default) or AES_FIPS for the FIPS-approved algorithm. AES_FIPS uses a separate library and is not compatible with AES. Algorithm names are case insensitive. If you specify the -ea option, you must also specify -ep or -ek. If you specify -ea without specifying -an, the -ea option is ignored.

For more information about strong database encryption, see Strong encryption.

Separately licensable option required
Strong database encryption using AES_FIPS requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Specify encryption key (-ek)

This option allows you to specify an encryption key for the new database created if you unload and reload a database (using the -an option). If you create a strongly encrypted database, you must provide the encryption key to use the database or transaction log in any way. The algorithm used to encrypt the database is AES or AES_FIPS as specified by the -ea option. If you specify the -ek option without specifying -ea, the algorithm used will be AES. If you specify -ek without specifying -an, the -ek option is ignored.

Caution Protect your key! Be sure to store a copy of your key in a safe location. A lost key will result in a completely inaccessible database, from which there is no recovery.

For more information about strong database encryption, see Strong encryption.

Prompt for encryption key (-ep)

This option prompts you to specify an encryption key for the new database created if you unload and reload your database (using the -an option). It provides an extra measure of security by never allowing the encryption key to be seen in clear text. If you specify -ep without specifying -an, the -ep option is ignored. If you specify -ep and -an, you must input the encryption key twice to confirm that it was entered correctly. If the keys don't match, the unload fails.

For more information about strong database encryption, see Strong encryption.

Internal versus external unloads and reloads
The following options offer combinations of internal and external unloads and reloads: -ii, -ix, -xi, and -xx. A significant performance gain can be realized using internal commands (UNLOAD/LOAD) versus external commands (Interactive SQL's INPUT and OUTPUT statements). However, internal commands are executed by the server so that file and directory paths are relative to the location of the database server. Using external commands, file and directory paths are relative to the current directory of the user.

In Sybase Central, you can specify whether to unload relative to the server or client.

For more information on filenames and paths for the Unload utility, see UNLOAD TABLE statement.

Use internal unload, internal reload (-ii)

This option uses the UNLOAD statement to extract data from the database, and uses the LOAD statement in the reload.sql file to repopulate the database with data. This is the default.

Use internal unload, external reload (-ix)

This option uses the UNLOAD statement to extract data from the database, and uses the Interactive SQL INPUT statement in the reload.sql file to repopulate the database with data.

Ignore Java (-jr)

With this option, Java is ignored when unloading or reloading the database.

-m

With this option, user IDs are not preserved for a replicating database.

Unload schema definition only (-n)

With this option, none of the data in the database is unloaded; reload.sql contains SQL statements to build the structure of the database only.

Log output messages to file (-o)

Write output messages to the named file.

Escape character (-p)

The default escape character (\) for external unloads (dbunload -x option) can be replaced by another character using this option. This option is available only when you run this utility from a command prompt.

Operate quietly (-q)

Do not display output messages. This option is available only when you run this utility from a command prompt. If you specify -q, you must also specify -y or the unload will fail.

Specify reload filename (-r)

Modify the name and directory of the generated reload Interactive SQL command file. The default is reload.sql in the current directory. The directory is relative to the current directory of the client application, not the server.

Unload only listed tables (-t)

Provide a list of tables to be unloaded. By default, all tables are unloaded. Together with the -n option, this allows you to unload a set of table definitions only.

Output unordered data (-u)

Normally, the data in each table is ordered by the primary key. Use this option if you are unloading a database with a corrupt index, so that the corrupt index is not used to order the data.

Enable verbose mode (-v)

The table name of the table currently being unloaded, and how many rows have been unloaded, appears. This option is available only when you run this utility from a command prompt.

Use external unloading, internal reload (-xi)

This option unloads data to the dbunload client, and uses the LOAD statement in the generated reload command file, reload.sql, to repopulate the database with data.

Use external unloading, external reload (-xx)

This option unloads data to the dbunload client, and uses the Interactive SQL INPUT statement in the generated reload command file, reload.sql, to repopulate the database with data.

Operate without confirming actions (-y)

Choosing this option replaces existing command files without prompting you for confirmation. If you specify -q, you must also specify -y or the unload will fail.


The Upgrade utility

While you can run a database created with an older version of Adaptive Server Anywhere on a newer release of Adaptive Server Anywhere, the new features are only available if the database is upgraded.

The Upgrade utility upgrades a database from an older version of Adaptive Server Anywhere to a newer version of Adaptive Server Anywhere, and allows you to take advantage of the newer release's list of features.

Upgrading a database does not require you to unload and reload your database.

If you want to use replication on an upgraded database, you must also archive your transaction log and start a new one on the upgraded database.

You can access the Upgrade utility in the following ways:

  • From Sybase Central, using the Upgrade Database wizard.

  • From Interactive SQL, using the ALTER DATABASE UPGRADE statement.

    For more information, see ALTER DATABASE statement.

  • At a command prompt, using the dbupgrad command.

Back up before upgrading
As with any software, it is recommended that you make a backup of your database before upgrading.

Upgrading a database using the Upgrade Database wizard
Upgrading databases that are too old for the Upgrade utility
Upgrading a database using the dbupgrad command-line utility


Upgrading a database using the Upgrade Database wizard

toggle To upgrade a database

  1. Connect to the database.

  2. In the left pane, select the Adaptive Server Anywhere plug-in.

  3. In the right pane, click the Utilities tab.

  4. In the right pane, double-click Upgrade Database.

    The Upgrade Database wizard appears.

  5. Follow the instructions in the wizard.

Tip
You can also access the Upgrade Database wizard by:

  • Choosing Tools > Adaptive Server Anywhere 9 > Upgrade Database.

  • Right-clicking the database, and choosing Upgrade Database from the popup menu.

  • Selecting a database in the left pane, and choosing Upgrade Database from the File menu.


Upgrading databases that are too old for the Upgrade utility

toggle To upgrade a database created with a version of Adaptive Server Anywhere that is too old to be upgraded

  1. Unload the database using the Unload utility.

  2. Create a database with the name you want to use for the upgraded version using the Initialization utility.

  3. Connect to the new database from Interactive SQL as the DBA user ID, and read the reload.sql command file to build the new database.

You can also use the dbunload utility to directly rebuild.

For more information about using the dbunload utility, see Rebuilding a database.


Upgrading a database using the dbupgrad command-line utility

Syntax

dbupgrad [ options ]

Option | Description
@data | Read options from the specified environment variable or configuration file.
-c "keyword=value; ..." | Supply database connection parameters.
-I | Do not install Sybase jConnect support.
-j | Do not upgrade runtime Java classes.
-ja | Add runtime Java classes.
-jdk version | Install entries for the named version of the Java Development Kit.
-jr | Remove runtime Java classes.
-o filename | Log output messages to a file.
-q | Quiet mode—no windows or messages.
Description

The dbupgrad utility upgrades a database created with earlier versions of the software to enable features from the current version of the software. The earliest version that can be upgraded is Watcom SQL 3.2. While later versions of the database server do run against databases were created with earlier releases of the software, some of the features introduced since the version that created the database are unavailable unless the database is upgraded.

Exit codes are 0 (success) or non-zero (failure).

Not all features made available
Features that require a physical reorganization of the database file are not made available by dbupgrad. Such features include index enhancements and changes in data storage. To obtain the benefits of these enhancements, you must unload and reload your database.

For more information, see Upgrading the database file format.

Java in the database

By default, Java in the database is not included in new databases. Java in the database is removed from the database during an upgrade if all of the following are true:

  • the database is Java-enabled, but Java in the database is not being used

  • the Java VM cannot be loaded by the database server

  • you did not specify any Java-related options to the upgrade

The runtime classes add several megabytes to the size of a database. If you do not intend to use Java classes, you can specify the -j option to avoid including these classes in the upgraded database. If you want, you can add Sybase runtime Java classes later from Sybase Central or using the ALTER DATABASE statement.

For more information, see Java-enabling a database.

Java in the database is a separately-licensable component. These classes are installed during upgrade only if you have installed the Java-in-the-database option or if the Java classes were in use in the database being upgraded.

Upgrade utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Connection parameters (-c)

For a description of the connection parameters, see Connection parameters. The user ID must have DBA authority.

For example, the following command upgrades a database called sample80 to a version 9 format, connecting as user DBA with password SQL:

dbupgrad -c "uid=DBA;pwd=SQL;dbf=c:\asa80\sample80.db"

The dbupgrad utility must be run by a user with DBA authority.

Do not install Sybase jConnect support (-I)

If you want to use the Sybase jConnect JDBC driver to access system catalog information, you need to install jConnect support. Use this option if you want to exclude the jConnect system objects. You can still use JDBC, as long as you do not access system information. If you want, you can add Sybase jConnect support later using Sybase Central or the ALTER DATABASE UPGRADE statement.

For more information, see Installing jConnect system objects into a database.

Do not install runtime Java classes (-j)

If you do not intend to use Java classes, you can specify either no Java option, or the -j option to avoid including these classes in the database.

Install runtime Java classes (-ja)

Add Java in the database to the upgraded database. Specifying -ja installs version 1.3 of the JDK into the database.

Install support for the named version of the JDK (-jdk)

If you want to install a version of Java, use the -jdk option followed by the version number. Valid values are 1.1.8, and 1.3.

For example, the following command upgrades a database to support JDK 1.1.8 applications in the database.

dbupgrad -jdk 1.1.8 java2.db

The -jdk option implies the -ja option.

Remove runtime Java classes (-jr)

Remove Java in the database from the upgraded database.

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not display output messages.


The Validation utility

With the Validation utility, you can validate the indexes and keys on some or all of the tables in the database. The Validation utility scans the entire table, and looks up each record in every index and key defined on the table.

This utility can be used in combination with regular backups (see Backup and Data Recovery) to give you confidence in the integrity of the data in your database.

You can access the Validation utility in the following ways:

  • From Sybase Central, using the Validate Database wizard

  • From Interactive SQL, using the sa_validate stored procedure or the VALIDATE TABLE statement.

  • At a command prompt, using the dbvalid command. This is useful for incorporating into batch or command files.

For more information on validating tables, see VALIDATE TABLE statement.

Caution Validating a table or an entire database should be performed while no connections are making changes to the database; otherwise, spurious errors may be reported indicating some form of database corruption even though no corruption actually exists.


Validating a database using the Validate Database wizard

You can validate a database or individual tables from Sybase Central.

toggle To validate a database

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Validate Database.

    The Validate Database wizard appears.

  4. Follow the instructions in the wizard.

toggle To validate a running database

  1. Connect to the database.

  2. Right-click the database and choose Validate Database from the popup menu.

    The Validate Database wizard appears.

  3. Follow the instructions in the wizard.

toggle To validate an individual table

  1. Connect to the database.

  2. Locate the table you want to validate.

  3. Right-click the table and choose Validate from the popup menu.

Tip
You can also access the Validate Database wizard from within Sybase Central using any of the following methods:

  • Choosing Tools > Adaptive Server Anywhere 9 > Validate Database.

  • Right-clicking the database, and choosing Validate Database from the popup menu.

  • Selecting a database in the left pane, and choosing Validate Database from the File menu.


Validating a database using the dbvalid command-line utility

Syntax

dbvalid [ options ] [ object-name, ... ]

Option | Description
@data | Read options from the specified environment variable or configuration file.
-c "keyword=value; ..." | Supply database connection parameters.
-f | Validate tables with full check.
-fd | Validate tables with data check.
-fi | Validate tables with index check.
-fn | Validate tables with the historical validation algorithm (used in versions 9.0.0 and earlier of the software).
-fx | Validate tables with express check.
-I | Each object-name is an index.
-o filename | Log output messages to a file.
-q | Quiet mode—do not print messages.
-s | Validate database pages using checksums.
-t | Each object-name is a table.
object-name | The name of a table or an index to validate.
Description

With the Validation utility, you can validate the indexes and keys on some or all of the tables in the database. This utility scans the entire table, and confirms that each row in the table exists in the appropriate indexes. It is equivalent to running the VALIDATE TABLE statement on each table.

By default, the Validation utility uses the express check option. However, the express check option is not used if you specify -f, -fd, -fi, -fn, or -I, or if the database was created with a version of the software earlier than version 7.0.

Exit codes are:

Program Exit Code | Description
0 | Database validated successfully.
1 | General failure in utility.
2 | Error validating database.
7 | Unable to find database to connect to (database name is wrong).
8 | Unable to connect to database (user ID/password is wrong).
11 | Unable to find server to connect to (server name is wrong).
12 | Incorrect encryption key for starting database.

For information on specific checks made during validation, see VALIDATE TABLE statement.

Validation utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Connection parameters (-c)

For a description of the connection parameters, see Connection parameters. The user ID must have DBA authority or REMOTE DBA authority.

For example, the following validates the sample database, connecting as user DBA with password SQL:

dbvalid -c "uid=DBA;pwd=SQL;dbf=c:\asa\asademo.db"

Full check for each table (-f)

In addition to the default validation checks, carry out both data checks (-fd) and index checks (-fi). This corresponds to the WITH FULL CHECK option on the VALIDATE TABLE statement. Depending on the contents of your database, this option may significantly extend the time required to validate it.

Data check for each table (-fd)

In addition to the default validation checks, check that all of each LONG BINARY, LONG VARCHAR, TEXT, or IMAGE data type can be read. This corresponds to the WITH DATA CHECK option of the VALIDATE TABLE statement. Depending on the contents of your database, this option may significantly extend the time required to validate it.

Index check for each table (-fi)

In addition to the default validation checks, validate each index on the table. This corresponds to the WITH INDEX CHECK option on the VALIDATE TABLE statement. Depending on the contents of your database, this option may significantly extend the time required to validate it.

Use historical validation algorithm to check each table (-fn)

Use the validation algorithm that was used in versions 9.0.0 and earlier of the software instead of the express check algorithm.

Express check for each table (-fx)

In addition to the default and data checks (-fd), check that the number of rows in the table matches the number of entries in the index. This corresponds to the WITH EXPRESS CHECK option on the VALIDATE TABLE STATEMENT. This option does not perform individual index lookups for each row. Using this option can significantly improve performance when validating large databases with a small cache. The express check option is on by default.

Validate specified indexes (-I)

Instead of validating tables, validate indexes. In this case, for dbvalid, each of the object-name values supplied represents an index rather than a table, and has a name of the following form:

[ [ owner.]table-name.]index-name

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not display output messages.

Validate database using page checksums (-s)

Checksums are used to determine whether a database page has been modified on disk. If you created a database with checksums enabled, you can validate the database using checksums. Checksum validation reads each page of the database from disk and calculates its checksum. If the calculated checksum is different from the checksum stored on the page, the page has been modified on disk and an error is returned. The page numbers of any invalid pages appear in the server messages window. The -s option cannot be used in conjunction with -I, -t, or any of the -f options.

Validate tables (-t)

The list of object-name values represents a list of tables. This is also the default behavior.

object-name The name of a table to validate.

If -I is used, object-name refers to an index to validate instead.


The Write File utility (deprecated)

The Write File utility is used to manage database write files. A write file is a file associated with a particular database. All changes are written into the write file, leaving the database file unchanged.

Deprecated feature
The use of write files is deprecated.
Using write files for development

Write files can be used effectively for testing when you do not want to modify the production database. They can also be used in network environments where read-only access to a database is desired, or when you distribute on CD-ROM a database that you want users to be able to modify.

Compressed databases

If you are using a compressed database, you must use a write file; compressed database files cannot be accessed directly. The write file name is then used in place of the database name when connecting to the database, or when loading a database on the database server command line.

You can access the Write File utility in the following ways:

  • From Sybase Central, using the Create Write File wizard.

  • At a command prompt, using the dbwrite command. This is useful for incorporating into batch or command files.

The Write File utility runs against a database file. The database must not be running on a server when you run the Write File utility.

The database file cannot be modified after the write file is created, otherwise the write file becomes invalid.


Creating a write file using the Create Write File wizard

toggle To create a write file for a database

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Create Write File.

    The Create Write File wizard appears.

  4. Follow the instructions in the wizard.

Tip
You can also access the Create Write File wizard from within Sybase Central using any of the following methods:

  • Choosing Tools > Adaptive Server Anywhere 9 > Create Write File.

  • Right-clicking the server, and choosing Create Write File from the popup menu.

  • Selecting a server in the left pane, and choosing Create Write File from the File menu.


Creating a write file using the dbwrite command-line utility

Syntax

dbwrite [ options ] database-file [ write-name ]

Option | Description
@data | Read options from the specified environment variable or configuration file.
-c | Create a new write file.
-d database-file | Point a write file to a different database.
-ek key | Specify encryption key.
-ep | Prompt for encryption key.
-f database-file | Force the write file to point at a file.
-m mirror-name | Set the transaction log mirror name.
-o filename | Log output messages to a file.
-q | Quiet mode—do not print messages.
-s | Report the write file status only.
-t log-name | Set the transaction log name.
-y | Erase old files without confirmation.
Description

If any changes are made to the original database (not using the write file), the write file will no longer be valid. This happens if you start the server using the original database file, so you should create your write file from an archived copy of a database.

If a write file becomes invalid, you can discard all of your changes and create a new write file with the following command.

dbwrite -c db-name write-name

The log-name and mirror-name parameters are used only when creating a new write file. The write-name parameter is used only with the -c and -d parameters. Note that the database-file parameter must be specified before the write-name parameter.

Exit codes are 0 (success) or non-zero (failure).

Write file utility options

@data

Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Create a new write file (-c)

If an existing write already exists, any information in the old write file will be lost. If no write file name is specified in the command, the write filename defaults to the database name with the extension wrt. If no transaction log name is specified, the log file name will default to the database name with the extension wlg.

Change the database file to which an existing write file points (-d)

If a database file is moved to another directory, or renamed, this option allows you to maintain the link between the write file and the database file. This option is available only when you run this utility from a command prompt.

Specify encryption key (-ek)

This option allows you to specify the encryption key for strongly encrypted databases directly in the command. If you have a strongly encrypted database, you must provide the encryption key to use the database or transaction log in any way. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify a key for a strongly encrypted database.

Prompt for encryption key (-ep)

This option allows you to specify that you want to be prompted for the encryption key. This option causes a dialog box to appear, in which you enter the encryption key. It provides an extra measure of security by never allowing the encryption key to be seen in clear text. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify a key for a strongly encrypted database.

Force a write file to point to a file (-f)

This option is available only when you run this utility from a command prompt. This option is for use when a write file is being created and the database file is held on a Novell NetWare or other network path, for operating systems on which they cannot be entered directly. By providing the full Novell path name for the database file (for example: SYS:\asademo.db), you can avoid dependencies on local mappings of the NetWare path. Unlike with the -d option, no checking is done on the specified path.

Set mirror name (-m)

Set the name of the transaction log mirror file. This can only be used in conjunction with -c.

Log output messages to file (-o)

Write output messages to the named file.

Operate quietly (-q)

Do not display output messages. This option is available only when you run this utility from a command prompt.

Report the write file status only (-s)

This displays the name of the database to which the write file points. This option is available only when you run this utility from a command prompt.

Set the transaction log filename (-t)

If you are creating a new write file (-c), you can use this option to set the name of the transaction log file.

Operate without confirming actions (-y)

Choosing this option replaces the existing write file without prompting you for confirmation.


Database Options

About this chapter

This chapter describes the database, replication, compatibility and Interactive SQL options that can be set to customize and modify database behavior.


Introduction to database options

Database options control many aspects of database behavior. For example, you can use database options for the following purposes:

  • Compatibility You can control how much like Adaptive Server Enterprise your Adaptive Server Anywhere database operates, and whether SQL that does not conform to SQL/92 generates errors.

  • Error handling You can control what happens when errors such as dividing by zero, or overflow errors, occur.

  • Concurrency and transactions You can control the degree of concurrency, and details of COMMIT behavior.

Setting options
Finding option settings
Scope and duration of database options
Setting public options
Deleting option settings
Option classification
Initial option settings


Setting options

You set options with the SET OPTION statement. It has the following general syntax:

SET [ EXISTING ] [ TEMPORARY ] OPTION
[ userid. | PUBLIC. ]option-name = [ option-value ]

Specify a user ID or group name to set the option for that user or group only. Every user belongs to the PUBLIC group. If no user ID or group is specified, the option change is applied to the currently logged on user ID that issued the SET OPTION statement.

For example, the following statement applies an option change to the user DBA, if DBA is the user that issues it:

SET OPTION login_mode = mixed

The following statement applies a change to the PUBLIC user ID, a user group to which all users belong.

SET OPTION Public.login_mode = standard

If option-value is omitted, the specified option setting will be deleted from the database. If it was a personal option setting, the value will revert back to the PUBLIC setting. If a TEMPORARY option is deleted, the option setting will revert back to the permanent setting.

Caution Changing option settings while fetching rows from a cursor is not supported because it can lead to ill-defined behavior. For example, changing the DATE_FORMAT setting while fetching from a cursor would lead to different date formats among the rows in the result set. Do not change option settings while fetching rows.

For more information, see SET OPTION statement.


Finding option settings

You can obtain a list of option settings, or the values of individual options, in a variety of ways.

Getting a list of option values

  • Current option settings for your connection are available as a subset of connection properties. You can list all connection properties using the sa_conn_properties system procedure.

    CALL sa_conn_properties

    To order this list, you can call sa_conn_properties_by_name.

    If you want to filter the result or order by anything other than name, you could also use a SELECT statement. For example:

    SELECT *
FROM sa_conn_properties()
WHERE PropDescription like '%cache%'
ORDER BY PropNum

    For more information, see sa_conn_properties_by_name system procedure, and sa_conn_properties system procedure.

  • In Interactive SQL, the SET statement with no arguments lists the current setting of options.

    SET

  • In Sybase Central, right-click a database, and choose Options from the popup menu.

  • Use the following query on the SYSOPTIONS system view:

    SELECT *
FROM SYSOPTIONS

    This displays all PUBLIC values, and those USER values that have been explicitly set.

Getting individual option values

You can obtain a single setting using the connection_property system function. For example, the following statement reports the value of the ANSI_INTEGER_OVERFLOW option:

SELECT CONNECTION_PROPERTY ('ANSI_INTEGER_OVERFLOW')

For more information, see CONNECTION_PROPERTY function [System].


Scope and duration of database options

You can set options at 3 levels of scope: public, user, and temporary.

Temporary options take precedence over user and public settings. User level options take precedence over public settings. If you set a user level option for the current user, the corresponding temporary option is set as well.

Some options (such as COMMIT behavior) are database-wide in scope. Setting these options requires DBA permissions. Other options (such as ISOLATION_LEVEL) can also be applied to just the current connection, and need no special permissions.

Changes to option settings take place at different times, depending on the option. Changing a global option such as RECOVERY_TIME takes place the next time the server is started.

Generally, only options that affect the current connection take place immediately. You can change option settings in the middle of a transaction, for example. One exception to this is that changing options when a cursor is open can lead to unreliable results. For example, changing DATE_FORMAT may not change the format for the next row when a cursor is opened. Depending on the way the cursor is being retrieved, it may take several rows before the change works its way to the user.

Setting temporary options

Adding the TEMPORARY keyword to the SET OPTION statement changes the duration of the change. Ordinarily an option change is permanent. It does not change until it is explicitly changed using the SET OPTION statement.

When the SET TEMPORARY OPTION statement is executed, the new option value takes effect only for the current connection, and only for the duration of the connection.

When the SET TEMPORARY OPTION is used to set a PUBLIC option, the change is in place for as long as the database is running. When the database is shut down, temporary options for the PUBLIC user ID revert back to their permanent value.

Setting an option for the PUBLIC user ID temporarily offers a security advantage. For example, when the LOGIN_MODE option is enabled, the database relies on the login security of the system on which it is running. Enabling it temporarily means that a database relying on the security of a Windows NT/2000/XP domain will not be compromised if the database is shut down and copied to a local machine. In this case, the LOGIN_MODE option will revert to its permanent value, which could be Standard, a mode where integrated logins are not permitted.


Setting public options

DBA authority is required to set an option for the PUBLIC user ID.

Changing the value of an option for the PUBLIC user ID sets the value of the option for all users who have not SET their own value. An option value cannot be set for an individual user ID unless there is already a PUBLIC user ID setting for that option.

Some options which can only be set for the PUBLIC user take effect immediately for existing connections, even though the changed setting will not be visible to users via the connection_property() function. An example of this is the GLOBAL_DATABASE_ID option. For this reason, PUBLIC-only options should not be changed while other users are connected to the database.


Deleting option settings

If option-value is omitted, the specified option setting will be deleted from the database. If it was a personal option setting, the value reverts back to the PUBLIC setting. If a TEMPORARY option is deleted, the option setting reverts back to the permanent setting.

For example, the following statement resets the ANSI_INTEGER_OVERFLOW option to its default value:

SET OPTION ANSI_INTEGER_OVERFLOW =

For more information, see SET OPTION statement.


Option classification

Adaptive Server Anywhere provides many options. It is convenient to divide them into a few general classes. The classes of options are:

  • Database options

  • Compatibility options

  • Replication options

  • Interactive SQL options


Initial option settings

Connections to Adaptive Server Anywhere can be made through the TDS protocol (Open Client and jConnect JDBC connections) or through the Adaptive Server Anywhere protocol (ODBC and embedded SQL).

If you have users who use both TDS and the Adaptive Server Anywhere-specific protocol, you can configure their initial settings using stored procedures. As it is shipped, Adaptive Server Anywhere uses this method to set Open Client connections and jConnect connections to reflect default Adaptive Server Enterprise behavior.

The initial settings are controlled using the LOGIN_PROCEDURE option. This option names a stored procedure to run when users connect. The default setting is to use the sp_login_environment system procedure. If you wish to change this behavior, you can do so.

In turn, sp_login_environment checks to see if the connection is being made over TDS. If it is, it calls the sp_tsql_environment procedure, which sets several options to new "default" values for the current connection.

For more information, see LOGIN_PROCEDURE option [database], sp_login_environment system procedure, and sp_tsql_environment system procedure.


Database Options

Database options

This section lists all database options.

OPTION | VALUES | DEFAULT
AUDITING option [database] | ON, OFF | OFF
BACKGROUND_PRIORITY option [database] | ON, OFF | OFF
BLOCKING option [database] | ON, OFF | ON
BLOCKING_TIMEOUT option [database] | Integer | 0
CHECKPOINT_TIME option [database] | Number of minutes | 60
CIS_OPTION option [database] | 0, 7 | 0
CIS_ROWSET_SIZE option [database] | Integer | 50
COOPERATIVE_COMMIT_TIMEOUT option [database] | Integer | 250
COOPERATIVE_COMMITS option [database] | ON, OFF | ON
DEBUG_MESSAGES option [database] | ON, OFF | OFF
DEDICATED_TASK option [database] | ON, OFF | OFF
DEFAULT_TIMESTAMP_INCREMENT option [database] | Integer | 1
DELAYED_COMMIT_TIMEOUT option [database] | Integer | 500
DELAYED_COMMITS option [database] | ON, OFF | OFF
EXCLUDE_OPERATORS option [database] | reserved | reserved
EXTENDED_JOIN_SYNTAX option [database] | ON, OFF | ON
FIRST_DAY_OF_WEEK option [database] | 1, 2, 3, 4, 5, 6, 7 | 7
FOR_XML_NULL_TREATMENT option [database] | EMPTY, OMIT | OMIT
FORCE_VIEW_CREATION option [database] | reserved | reserved
GLOBAL_DATABASE_ID option [database] | Integer | 2147483647
INTEGRATED_SERVER_NAME option [database] | String | NULL
JAVA_HEAP_SIZE option [database] | Number of bytes | 1 000 000
JAVA_INPUT_OUTPUT option [database] | ON, OFF | OFF
JAVA_NAMESPACE_SIZE option [database] | Number of bytes | 4 000 000
LOG_DEADLOCKS option [database] | ON, OFF | OFF
LOGIN_MODE option [database] | STANDARD, MIXED, INTEGRATED | STANDARD
LOGIN_PROCEDURE option [database] | String | sp_login_environment
MAX_CURSOR_COUNT option [database] | Integer | 50
MAX_HASH_SIZE option [database] (deprecated) | Integer | 10
MAX_PLANS_CACHED option [database] | Integer | 20
MAX_RECURSIVE_ITERATIONS option [database] | Integer | 100
MAX_STATEMENT_COUNT option [database] | Integer >=0 | 50
MAX_WORK_TABLE_HASH_SIZE option [database] (deprecated) | Integer | 20
MIN_PASSWORD_LENGTH option [database] | Integer | 0
ODBC_DESCRIBE_BINARY_AS_VARBINARY [database] | ON, OFF | OFF
ODBC_DISTINGUISH_CHAR_AND_VARCHAR option [database] | ON, OFF | OFF
ON_CHARSET_CONVERSION_FAILURE option [database] | IGNORE, WARNING, ERROR | IGNORE
OPTIMIZATION_GOAL option [database] | First-row or all-rows | all-rows
OPTIMIZATION_LEVEL option [database] | 0–15 | 9
OPTIMIZATION_WORKLOAD option [database] | Mixed, OLAP | Mixed
PINNED_CURSOR_PERCENT_OF_CACHE option [database] | 0–100 | 10
PRECISION option [database] | Number of digits | 30
PREFETCH option [database] | OFF, CONDITIONAL, ALWAYS | CONDITIONAL
PRESERVE_SOURCE_FORMAT option [database] | ON, OFF | ON
PREVENT_ARTICLE_PKEY_UPDATE option [database] | ON, OFF | ON
READ_PAST_DELETED option [database] | ON, OFF | ON
RECOVERY_TIME option [database] | Number of minutes | 2
REMOTE_IDLE_TIMEOUT option [database] | Number of seconds | 15
RETURN_DATE_TIME_AS_STRING option [database] | ON, OFF | OFF
RETURN_JAVA_AS_STRING option [database] | ON, OFF | OFF
ROLLBACK_ON_DEADLOCK [database] | ON, OFF | ON
ROW_COUNTS option [database] | ON, OFF | OFF
SCALE option [database] | Number of digits | 6
SORT_COLLATION option [database] | any valid collation_name or collation_ID | Internal
SUBSUME_ROW_LOCKS option [database] | ON, OFF | ON
SUPPRESS_TDS_DEBUGGING option [database] | ON, OFF | OFF
TDS_EMPTY_STRING_IS_NULL option [database] | ON, OFF | OFF
TEMP_SPACE_LIMIT_CHECK option [database] | ON, OFF | OFF
TIME_ZONE_ADJUSTMENT option [database] | Integer, or Negative integer enclosed in quotation marks, or String representing time in hours and minutes, preceded by + or - | Set by either the client's or the server's time zone, depending on the client's connection type
TRUNCATE_DATE_VALUES option [database] (deprecated) | ON, OFF | ON (post version 7 databases) OFF (pre version 7 databases)
TRUNCATE_TIMESTAMP_VALUES option [database] | ON, OFF | OFF
TRUNCATE_WITH_AUTO_COMMIT option [database] | ON, OFF | OFF
UPDATE_STATISTICS option [database] | ON, OF | ON
USER_ESTIMATES option [database] | ENABLED, OVERRIDE-MAGIC, DISABLED | OVERRIDE-MAGIC
WAIT_FOR_COMMIT option [database] | ON, OFF | OFF
WEBSERVICE_NAMESPACE_HOST option [database] | String, NULL | NULL


Compatibility options

The following options allow Adaptive Server Anywhere behavior to be made compatible with Adaptive Server Enterprise, or to support both old behavior and allow ISO SQL/92 behavior.

For further compatibility with Adaptive Server Enterprise, some of these options can be set for the duration of the current connection using the Transact-SQL SET statement instead of the Adaptive Server Anywhere SET OPTION statement.

For a listing, see SET statement [T-SQL].

Default settings

The default setting for some of these options differs from the Adaptive Server Enterprise default setting. For compatibility, you should explicitly set the options to ensure compatible behavior.

When a connection is made using the Open Client or JDBC interfaces, some option settings are explicitly set for the current connection to be compatible with Adaptive Server Enterprise. These options are listed in the following table.

For information on how the settings are made, see System and catalog stored procedures.

Options for Open Client and JDBC connection compatibility with Adaptive Server Enterprise
Option | Setting
ALLOW_NULLS_BY_DEFAULT | OFF
ANSI_BLANKS | ON
ANSINULL | OFF
CHAINED | OFF
CONTINUE_AFTER_RAISERROR | ON
DATE_FORMAT | YYYY-MM-DD
DATE_ORDER | MDY
ESCAPE_CHARACTER | OFF
FLOAT_AS_DOUBLE | ON
ISOLATION_LEVEL | 1
ON_TSQL_ERROR | CONDITIONAL
QUOTED_IDENTIFIER | OFF
TIME_FORMAT | HH:NN:SS.SSS
TIMESTAMP_FORMAT | YYYY-MM-DD HH:NN:SS.SSS
TSQL_HEX_CONSTANT | ON
TSQL_VARIABLES | ON
Transact-SQL and SQL/92 compatibility options

The following table lists the compatibility options, their allowed values, and their default settings.

OPTION | VALUES | DEFAULT
ALLOW_NULLS_BY_DEFAULT option [compatibility] | ON, OFF | ON
ANSI_BLANKS option [compatibility] | ON, OFF | OFF
ANSI_CLOSE_CURSORS_ON_ROLLBACK option [compatibility] | ON, OFF | OFF
ANSI_INTEGER_OVERFLOW option [compatibility] | ON, OFF | OFF
ANSI_PERMISSIONS option [compatibility] | ON, OFF | ON
ANSI_UPDATE_CONSTRAINTS option [compatibility] | OFF, CURSORS, STRICT | CURSORS
ANSINULL option [compatibility] | ON, OFF | ON
AUTOMATIC_TIMESTAMP option [compatibility] | ON, OFF | OFF
CHAINED option [compatibility] | ON, OFF | ON
CLOSE_ON_ENDTRANS option [compatibility] | ON, OFF | ON
CONTINUE_AFTER_RAISERROR option [compatibility] | ON, OFF | ON
CONVERSION_ERROR option [compatibility] | ON, OFF | ON
DATE_FORMAT option [compatibility] | String | YYYY-MM-DD
DATE_ORDER option [compatibility] | MDY, YMD, DMY | YMD
DIVIDE_BY_ZERO_ERROR option [compatibility] | ON, OFF | ON
ESCAPE_CHARACTER option [compatibility] | System use | OFF
FIRE_TRIGGERS option [compatibility] | ON, OFF | ON
FLOAT_AS_DOUBLE option [compatibility] | ON, OFF | OFF
ISOLATION_LEVEL option [compatibility] | 0, 1, 2, 3 | 0 1 for Open Client and JDBC connections
NEAREST_CENTURY option [compatibility] | Integer | 50
NON_KEYWORDS option [compatibility] | Comma-separated keywords list | No keywords turned off
ON_TSQL_ERROR option [compatibility] | STOP, CONDITIONAL, CONTINUE | CONDITIONAL
OPTIMISTIC_WAIT_FOR_COMMIT option [compatibility] | ON, OFF | OFF
PERCENT_AS_COMMENT option [compatibility] | ON, OFF | ON
QUERY_PLAN_ON_OPEN option [compatibility] | ON, OFF | OFF
QUOTED_IDENTIFIER option [compatibility] | ON, OFF | ON
RI_TRIGGER_TIME option [compatibility] | BEFORE, AFTER | AFTER
SQL_FLAGGER_ERROR_LEVEL option [compatibility] | E, I, F, W | W
SQL_FLAGGER_WARNING_LEVEL option [compatibility] | E, I, F, W | W
STRING_RTRUNCATION option [compatibility] | ON, OFF | OFF
TIME_FORMAT option [compatibility] | String | HH:NN:SS.SSS
TIMESTAMP_FORMAT option [compatibility] | String | YYYY-MM-DD HH:NN:ss.SSS
TSQL_HEX_CONSTANT option [compatibility] | ON, OFF | ON
TSQL_VARIABLES option [compatibility] | ON, OFF | OFF


Replication options

The following options are included to provide control over replication behavior. Some replication options are useful for SQL Remote replication, and some are relevant for use with Sybase Replication Server.

OPTION | VALUES | DEFAULT
BLOB_THRESHOLD option [replication] | Integer | 256
COMPRESSION option [replication] | Integer, from -1 to 9 | 6
DELETE_OLD_LOGS option [replication] | ON, OFF | OFF
QUALIFY_OWNERS option [replication] | ON, OFF | ON
QUOTE_ALL_IDENTIFIERS option [replication] | ON, OFF | OFF
REPLICATE_ALL option [replication] | ON, OFF | OFF
REPLICATION_ERROR option [replication] | Procedure-name | (no procedure)
REPLICATION_ERROR_PIECE option [replication] | Procedure-name | (no procedure)
SUBSCRIBE_BY_REMOTE option [replication] | ON, OFF | ON
VERIFY_ALL_COLUMNS option [replication] | ON, OFF | OFF
VERIFY_THRESHOLD option [replication] | Integer | 1 000


Interactive SQL options

Syntax 1

SET [ TEMPORARY ] OPTION

[ userid. | PUBLIC. ]option-name = [ option-value ]

Syntax 2

SET PERMANENT

Syntax 3

SET

Parameters

userid: identifier, string, or host-variable

option-name: identifier, string, or host-variable

option-value: host-variable (indicator allowed), string, identifier, or
number

Description

SET PERMANENT (syntax 2) stores all current Interactive SQL options in the SYSOPTION system table. These settings are automatically established every time Interactive SQL is started for the current user ID.

Syntax 3 is used to display all of the current option settings. If any options have temporary settings for Interactive SQL or the database server, these are displayed; otherwise, the permanent option settings are displayed.

OPTION | VALUES | DEFAULT
AUTO_COMMIT option [Interactive SQL] | ON, OFF | OFF
AUTO_REFETCH option [Interactive SQL] | ON, OFF | ON
BELL option [Interactive SQL] | ON, OFF | ON
COMMAND_DELIMITER option [Interactive SQL] | String | ' ; '
COMMIT_ON_EXIT option [Interactive SQL] | ON, OFF | ON
DEFAULT_ISQL_ENCODING option [Interactive SQL] | String | (empty string)
DESCRIBE_JAVA_FORMAT option [Interactive SQL] | Varchar, binary | Varchar
ECHO option [Interactive SQL] | ON, OFF | ON
INPUT_FORMAT option [Interactive SQL] | ASCII, DBASE, DBASEII, DBASEIII, EXCEL, FIXED, FOXPRO, LOTUS | ASCII
ISQL_COMMAND_TIMING option [Interactive SQL] | ON, OFF | ON
ISQL_ESCAPE_CHARACTER option [Interactive SQL] | Character | ' \ '
ISQL_FIELD_SEPARATOR option [Interactive SQL] | String | ' , '
ISQL_LOG option [Interactive SQL] | File-name | (empty string)
ISQL_PLAN option [Interactive SQL] | NONE, SHORT, LONG, GRAPHICAL, GraphicalWithStatistics | SHORT
ISQL_PRINT_RESULT_SET option [Interactive SQL] | LAST, ALL, NONE | LAST
ISQL_QUOTE option [Interactive SQL] | String | '
NULLS option [Interactive SQL] | String | '(NULL)'
ON_ERROR option [Interactive SQL] | STOP, CONTINUE, PROMPT, EXIT, NOTIFY_CONTINUE, NOTIFY_STOP, NOTIFY_EXIT | PROMPT
OUTPUT_FORMAT option [Interactive SQL] | ASCII, DBASEII, DBASEIII, EXCEL, FIXED, FOXPRO, HTML, LOTUS, SQL, XML, | ASCII
OUTPUT_LENGTH option [Interactive SQL] | Integer | 0
OUTPUT_NULLS option [Interactive SQL] | String | 'NULL'
STATISTICS option [Interactive SQL] | 0,3,4,5,6 | 3
TRUNCATION_LENGTH option [Interactive SQL] | Integer | 256


Alphabetical list of options

This section lists options alphabetically.

ALLOW_NULLS_BY_DEFAULT option [compatibility]
ANSI_BLANKS option [compatibility]
ANSI_CLOSE_CURSORS_ON_ROLLBACK option [compatibility]
ANSI_INTEGER_OVERFLOW option [compatibility]
ANSI_PERMISSIONS option [compatibility]
ANSI_UPDATE_CONSTRAINTS option [compatibility]
ANSINULL option [compatibility]
AUDITING option [database]
AUTO_COMMIT option [Interactive SQL]
AUTO_REFETCH option [Interactive SQL]
AUTOMATIC_TIMESTAMP option [compatibility]
BACKGROUND_PRIORITY option [database]
BELL option [Interactive SQL]
BLOB_THRESHOLD option [replication]
BLOCKING option [database]
BLOCKING_TIMEOUT option [database]
CHAINED option [compatibility]
CHECKPOINT_TIME option [database]
CIS_OPTION option [database]
CIS_ROWSET_SIZE option [database]
CLOSE_ON_ENDTRANS option [compatibility]
COMMAND_DELIMITER option [Interactive SQL]
COMMIT_ON_EXIT option [Interactive SQL]
COMPRESSION option [replication]
CONTINUE_AFTER_RAISERROR option [compatibility]
CONVERSION_ERROR option [compatibility]
COOPERATIVE_COMMIT_TIMEOUT option [database]
COOPERATIVE_COMMITS option [database]
DATE_FORMAT option [compatibility]
DATE_ORDER option [compatibility]
DEBUG_MESSAGES option [database]
DEDICATED_TASK option [database]
DEFAULT_ISQL_ENCODING option [Interactive SQL]
DEFAULT_TIMESTAMP_INCREMENT option [database]
DELAYED_COMMIT_TIMEOUT option [database]
DELAYED_COMMITS option [database]
DELETE_OLD_LOGS option [replication]
DESCRIBE_JAVA_FORMAT option [Interactive SQL]
DIVIDE_BY_ZERO_ERROR option [compatibility]
ECHO option [Interactive SQL]
ESCAPE_CHARACTER option [compatibility]
EXCLUDE_OPERATORS option [database]
EXTENDED_JOIN_SYNTAX option [database]
FIRE_TRIGGERS option [compatibility]
FIRST_DAY_OF_WEEK option [database]
FLOAT_AS_DOUBLE option [compatibility]
FOR_XML_NULL_TREATMENT option [database]
FORCE_VIEW_CREATION option [database]
GLOBAL_DATABASE_ID option [database]
INPUT_FORMAT option [Interactive SQL]
INTEGRATED_SERVER_NAME option [database]
ISOLATION_LEVEL option [compatibility]
ISQL_COMMAND_TIMING option [Interactive SQL]
ISQL_ESCAPE_CHARACTER option [Interactive SQL]
ISQL_FIELD_SEPARATOR option [Interactive SQL]
ISQL_LOG option [Interactive SQL]
ISQL_PLAN option [Interactive SQL]
ISQL_PRINT_RESULT_SET option [Interactive SQL]
ISQL_QUOTE option [Interactive SQL]
JAVA_HEAP_SIZE option [database]
JAVA_INPUT_OUTPUT option [database]
JAVA_NAMESPACE_SIZE option [database]
LOG_DEADLOCKS option [database]
LOGIN_MODE option [database]
LOGIN_PROCEDURE option [database]
MAX_CURSOR_COUNT option [database]
MAX_HASH_SIZE option [database] (deprecated)
MAX_PLANS_CACHED option [database]
MAX_RECURSIVE_ITERATIONS option [database]
MAX_STATEMENT_COUNT option [database]
MAX_WORK_TABLE_HASH_SIZE option [database] (deprecated)
MIN_PASSWORD_LENGTH option [database]
NEAREST_CENTURY option [compatibility]
NON_KEYWORDS option [compatibility]
NULLS option [Interactive SQL]
ODBC_DESCRIBE_BINARY_AS_VARBINARY [database]
ODBC_DISTINGUISH_CHAR_AND_VARCHAR option [database]
ON_CHARSET_CONVERSION_FAILURE option [database]
ON_ERROR option [Interactive SQL]
ON_TSQL_ERROR option [compatibility]
OPTIMISTIC_WAIT_FOR_COMMIT option [compatibility]
OPTIMIZATION_GOAL option [database]
OPTIMIZATION_LEVEL option [database]
OPTIMIZATION_WORKLOAD option [database]
OUTPUT_FORMAT option [Interactive SQL]
OUTPUT_LENGTH option [Interactive SQL]
OUTPUT_NULLS option [Interactive SQL]
PERCENT_AS_COMMENT option [compatibility]
PINNED_CURSOR_PERCENT_OF_CACHE option [database]
PRECISION option [database]
PREFETCH option [database]
PRESERVE_SOURCE_FORMAT option [database]
PREVENT_ARTICLE_PKEY_UPDATE option [database]
QUALIFY_OWNERS option [replication]
QUERY_PLAN_ON_OPEN option [compatibility]
QUOTE_ALL_IDENTIFIERS option [replication]
QUOTED_IDENTIFIER option [compatibility]
READ_PAST_DELETED option [database]
RECOVERY_TIME option [database]
REMOTE_IDLE_TIMEOUT option [database]
REPLICATE_ALL option [replication]
REPLICATION_ERROR option [replication]
REPLICATION_ERROR_PIECE option [replication]
RETURN_DATE_TIME_AS_STRING option [database]
RETURN_JAVA_AS_STRING option [database]
RI_TRIGGER_TIME option [compatibility]
ROLLBACK_ON_DEADLOCK [database]
ROW_COUNTS option [database]
SCALE option [database]
SORT_COLLATION option [database]
SQL_FLAGGER_ERROR_LEVEL option [compatibility]
SQL_FLAGGER_WARNING_LEVEL option [compatibility]
STATISTICS option [Interactive SQL]
STRING_RTRUNCATION option [compatibility]
SUBSCRIBE_BY_REMOTE option [replication]
SUBSUME_ROW_LOCKS option [database]
SUPPRESS_TDS_DEBUGGING option [database]
TDS_EMPTY_STRING_IS_NULL option [database]
TEMP_SPACE_LIMIT_CHECK option [database]
TIME_FORMAT option [compatibility]
TIME_ZONE_ADJUSTMENT option [database]
TIMESTAMP_FORMAT option [compatibility]
TRUNCATE_DATE_VALUES option [database] (deprecated)
TRUNCATE_TIMESTAMP_VALUES option [database]
TRUNCATE_WITH_AUTO_COMMIT option [database]
TRUNCATION_LENGTH option [Interactive SQL]
TSQL_HEX_CONSTANT option [compatibility]
TSQL_VARIABLES option [compatibility]
UPDATE_STATISTICS option [database]
USER_ESTIMATES option [database]
VERIFY_ALL_COLUMNS option [replication]
VERIFY_THRESHOLD option [replication]
WAIT_FOR_COMMIT option [database]
WEBSERVICE_NAMESPACE_HOST option [database]


ALLOW_NULLS_BY_DEFAULT option [compatibility]

Function

Controls whether new columns that are created without specifying either NULL or NOT NULL are allowed to contain NULL values.

Allowed values

ON, OFF

Default

ON

OFF for Open Client and JDBC connections

Description

The ALLOW_NULLS_BY_DEFAULT option is included for Transact-SQL compatibility.

For more information, see Setting options for Transact-SQL compatibility.


ANSI_BLANKS option [compatibility]

Function

Controls behavior when character data is truncated at the client side.

Allowed values

ON, OFF

Default

OFF

ON for Open Client and JDBC connections

Description

The ANSI_BLANKS option has no effect unless the database was created with the -b command-line option. It forces a truncation error whenever a value of data type CHAR(N) is read into a C char(M) variable for values of N greater than or equal to M. With ANSI_BLANKS set to OFF, a truncation error occurs only when at least one non-blank character is truncated.

For embedded SQL, if ANSI_BLANKS is ON when you supply a value of data type DT_STRING, you must set the sqllen field to the length of the value, including space for the terminating null character. With ANSI_BLANKS off, the length is determined solely by the position of the null character.

The ANSI_BLANKS setting persists for the life of a connection. Changing it after a connection has been established does not affect that connection.


ANSI_CLOSE_CURSORS_ON_ROLLBACK option [compatibility]

Function

Controls whether cursors that were opened WITH HOLD are closed when a ROLLBACK is performed.

Allowed values

ON, OFF

Default

OFF

Description

The draft SQL/3 standard requires all cursors be closed when a transaction is rolled back. By default, on a rollback Adaptive Server Anywhere closes only those cursors that were opened without a WITH HOLD clause. This option allows you to force closure of all cursors.

The CLOSE_ON_ENDTRANS option overrides the ANSI_CLOSE_CURSORS_ON_ROLLBACK option.


ANSI_INTEGER_OVERFLOW option [compatibility]

Function

Controls what happens when an arithmetic expression causes an integer overflow error.

Allowed values

ON, OFF

Default

OFF

Description

The ISO SQL/92 standard requires integer overflow should result in a SQLSTATE = 22003 - overflow error. Adaptive Server Anywhere behavior was previously different from this. The ANSI_INTEGER_OVERFLOW option can be set to OFF to maintain compatibility with previous releases of the software.


ANSI_PERMISSIONS option [compatibility]

Function

Controls permissions checking for DELETE and UPDATE statements.

Allowed values

ON, OFF

Scope

Can be set for the PUBLIC group only. Takes effect immediately. DBA authority is required to set this option.

Default

ON

Description

With ANSI_PERMISSIONS ON, the SQL/92 permissions requirements for DELETE and UPDATE statements are checked. The default value is OFF in Adaptive Server Enterprise. The following table outlines the differences.

SQL statement | Permissions required with ANSI_PERMISSIONS off | Permissions required with ANSI_PERMISSIONS on
UPDATE | UPDATE permission on the columns where values are being set | UPDATE permission on the columns where values are being set SELECT permission on all columns appearing in the WHERE clause SELECT permission on all columns on the right side of the set clause
DELETE | DELETE permission on the table | DELETE permission on the table SELECT permission on all columns appearing in the WHERE clause

The ANSI_PERMISSIONS option can be set only for the PUBLIC group. No private settings are allowed.


ANSI_UPDATE_CONSTRAINTS option [compatibility]

Function

Controls the range of updates that are permitted.

Allowed values

OFF, CURSORS, STRICT

Default

CURSORS in new databases

OFF in databases created before version 7.0

Description

Adaptive Server Anywhere provides several extensions that allow updates which are not permitted by the ANSI SQL standard. These extensions provide powerful, efficient mechanisms for performing updates. However, in some cases, they cause behavior that is not intuitive. This behavior can produce anomalies such as lost updates if the user application is not designed to expect the behavior of these extensions.

The ANSI_UPDATE_CONSTRAINTS option controls whether updates are restricted to those permitted by the SQL/92 standard.

If the option is set to STRICT, the following updates are prevented:

  • Updates of cursors containing JOINS

  • Updates of columns that appear in an ORDER BY clause

  • The FROM clauses is not allowed in UPDATE statements

If the option is set to CURSORS, these same restrictions are in place, but only for cursors. If a cursor is not opened with FOR UPDATE or FOR READ ONLY, the database server chooses updatability based on the SQL/92 standard. If the ANSI_UPDATE_CONSTRAINTS option is CURSORS or STRICT, cursors containing an ORDER BY clause default to FOR READ ONLY; otherwise, they continue to default to FOR UPDATE.

See also

UPDATE statement


ANSINULL option [compatibility]

Function

Controls the interpretation of NULL values.

Allowed values

ON, OFF

Default

ON

Description

This option is implemented primarily for Transact-SQL (Adaptive Server Enterprise) compatibility. ANSINULL affects the results of comparison predicates with NULL constants, and also affects warnings issued for grouped queries over NULL values.

With ANSINULL ON, ANSI three-valued logic is used for all comparison predicates in a WHERE or HAVING clause, or in an ON condition. Any comparisons with NULL using = or != evaluate to unknown.

Setting ANSINULL to OFF means that Adaptive Server Anywhere uses two-valued logic for the following four conditions:

<expr> = NULL

<expr > != NULL

<expr> = @var // @var is a procedure variable, or a host variable

<expr> != @var

In each case, the predicate evaluates to either true or false—never unknown. In such comparisons, the NULL value is treated as a special value in each domain, and an equality (=) comparison of two NULL values will yield true. Note that the expression expr must be a relatively simple expression, referencing only columns, variables, and literals; subqueries and functions are not permitted.

With ANSINULL ON, the evaluation of any aggregate function, except COUNT(*), on an expression that contains at least one NULL value, may generate the warning null value eliminated in aggregate function (SQLSTATE=01003). With ANSINULL OFF, this warning does not appear.

Limitations

  • Setting ANSINULL to OFF affects only WHERE, HAVING, or ON predicates in SELECT, UPDATE, DELETE, and INSERT statements. The semantics of comparisons in a CASE or IF statement, or in IF expressions, are unaffected.

  • Adaptive Server Enterprise 12.5 introduced a change in behavior for LIKE predicates with a NULL pattern string when ANSINULL is OFF. In Adaptive Server Anywhere, LIKE predicates remain unaffected by the setting of ANSINULL.


AUDITING option [database]

Function

Enables and disables auditing in the database.

Allowed values

ON, OFF

Scope

Can be set for the PUBLIC group only. Takes effect immediately. DBA permissions are required to set this option.

Default

OFF

Description

This option turns auditing on and off.

Auditing is the recording of detailed information about many events in the database in the transaction log. Auditing provides some security features, at the cost of some performance.

For the AUDITING option to work, you must set the AUDITING option to ON, and also specify which types of information you want to audit using the sa_enable_auditing_type system procedure. Auditing will not take place if either of the following are true:

  • AUDITING is set to OFF

  • Auditing options have been disabled

If you set AUDITING ON, and do not specify auditing options, all types of auditing information are recorded. Alternatively, you can choose to record any combination of the following: audit permission checks, connection attempts, DDL statements, public options, and triggers.

See also

sa_enable_auditing_type

sa_disable_auditing_type

Example

  • Turn on auditing

    SET OPTION PUBLIC.AUDITING = 'ON'


AUTO_COMMIT option [Interactive SQL]

Function

Controls whether a COMMIT is performed after each statement.

Allowed values

ON, OFF

Default

OFF

Description

If AUTO_COMMIT is ON, a database COMMIT is performed after each successful statement.

By default, a COMMIT or ROLLBACK is performed only when the user issues a COMMIT or ROLLBACK statement or a SQL statement that causes an automatic commit (such as the CREATE TABLE statement).


AUTO_REFETCH option [Interactive SQL]

Function

Controls whether query results are fetched again after deletes, updates, and inserts.

Allowed values

ON, OFF

Default

ON

Description

If AUTO_REFETCH is on, the current query results that appear on the Results tab in the Interactive SQL Results pane will be refetched from the database after any INSERT, UPDATE, or DELETE statement. Depending on how complicated the query is, this may take some time. For this reason, it can be turned off.


AUTOMATIC_TIMESTAMP option [compatibility]

Function

Controls interpretation of new columns with the TIMESTAMP data type.

Allowed values

ON, OFF

Default

OFF

Description

Controls whether any new columns with the TIMESTAMP data type that do not have an explicit default value defined are given a default value of the Transact-SQL timestamp value as a default. The AUTOMATIC_TIMESTAMP option is included for Transact-SQL compatibility. The default is OFF.

For more information, see Setting options for Transact-SQL compatibility.


BACKGROUND_PRIORITY option [database]

Function

To limit impact on the performance of connections other than the current connection.

Allowed values

ON, OFF

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

If you set this option temporarily, that setting applies to the current connection only. Different connections under the same user ID can have different settings for this option.

Default

OFF

Description

When set to ON, it requests that the current connection have minimal impact on the performance of other connections. This option allows tasks for which responsiveness is critical to coexist with other tasks for which performance is not as important.


BELL option [Interactive SQL]

Function

Controls whether the bell sounds when an error occurs.

Allowed values

ON, OFF

Default

ON

Description

Set this option according to your preference.


BLOB_THRESHOLD option [replication]

Function

Controls the size of value that the Message Agent treats as a long object (BLOB).

Allowed values

Integer, in kilobytes

Default

256

Description

Any value longer than the BLOB_THRESHOLD option is replicated as a BLOB. That is, it is broken into pieces and replicated in chunks before being reconstituted using a SQL variable and concatenating the pieces at the recipient site.

If you set BLOB_THRESHOLD to a high value in remote Adaptive Server Anywhere databases, BLOBs are not broken into pieces, and operations can be applied to Adaptive Server Enterprise by the Message Agent. Each SQL statement must fit within a message, so this only allows replication of small BLOBs.


BLOCKING option [database]

Function

Controls the behavior in response to locking conflicts.

Allowed values

ON, OFF

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

ON

Description

If BLOCKING is ON, any transaction attempting to obtain a lock that conflicts with an existing lock held by another transaction waits until every conflicting lock is released. At that time, the write goes through. If BLOCKING is OFF, the transaction that attempts to obtain a conflicting lock receives an error.

For more information, see Two-phase locking.


BLOCKING_TIMEOUT option [database]

Function

To control how long a transaction waits to obtain a lock.

Allowed values

Integer, in milliseconds

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

0

Description

When BLOCKING is ON, any transaction attempting to obtain a lock that conflicts with an existing lock waits for BLOCKING_TIMEOUT milliseconds for the conflicting lock to be released. If the lock is not released within BLOCKING_TIMEOUT milliseconds, then an error is returned for the waiting transaction.

Setting this option to 0 forces all transactions attempting to obtain a lock to wait until all conflicting transactions release their locks.

See also

BLOCKING option [database]


CHAINED option [compatibility]

Function

Controls transaction mode in the absence of a BEGIN TRANSACTION statement.

Allowed values

ON, OFF

Default

ON

OFF for Open Client and JDBC connections

Description

Controls the Transact-SQL transaction mode. In Unchained mode (CHAINED = OFF), each statement is committed individually unless an explicit BEGIN TRANSACTION statement is executed to start a transaction. In chained mode (CHAINED = ON) a transaction is implicitly started before any data retrieval or modification statement.


CHECKPOINT_TIME option [database]

Function

Set the maximum number of minutes that the database server will run without doing a checkpoint.

Allowed values

Integer

Scope

Can be set for the PUBLIC group only. DBA authority is required to set the option. You must shut down and restart the database server for the change to take effect.

Default

60

Description

This option is used with the RECOVERY_TIME option to decide when checkpoints should be done.

For information on checkpoints, see Checkpoints and the checkpoint log.

See also

RECOVERY_TIME option [database]


CIS_OPTION option [database]

Function

Controls whether debugging information for remote data access appears in the server window.

Allowed values

0, 7

Scope

Can be set for an individual connection or for the PUBLIC group.

Default

0

Description

This option controls whether information about how queries are executed on a remote database appears in the server window when using remote data access. Set this option to 7 to see debugging information in the server window. When this option is set to 0 (the default), debugging information for remote data access does not appear in the server window.

Once you have turned on remote tracing, the tracing information appears in the database server window. You can log this output to a file by specifying the - o filename server option when you start the database server.

For more information about the -o server option, see -o server option.


CIS_ROWSET_SIZE option [database]

Function

Set the number of rows that are returned from remote servers for each fetch.

Allowed values

Integer

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect when a new connection is made to a remote server.

Default

50

Description

This option sets the ODBC FetchArraySize value when using ODBC to connect to a remote database server.


CLOSE_ON_ENDTRANS option [compatibility]

Function

Controls the closing of cursors at the end of a transaction.

Allowed values

ON, OFF

Default

ON

Description

When CLOSE_ON_ENDTRANS is set to ON, cursors are closed whenever a transaction is committed unless the cursor was opened WITH HOLD. The behavior when a transaction is rolled back is governed by the ANSI_CLOSE_CURSORS_AT_ROLLBACK option.

When CLOSE_ON_ENDTRANS is set to OFF, cursors are not closed at either a commit or a rollback, regardless of the ANSI_CLOSE_CURSORS_AT_ROLLBACK option setting or whether the cursor was opened WITH HOLD or not.

Setting this to OFF provides Adaptive Server Enterprise compatible behavior.


COMMAND_DELIMITER option [Interactive SQL]

Function

Sets the string that indicates the end of a statement in Interactive SQL.

Allowed values

String

Default

Semi-colon (;)

Description

You can specify a command delimiter to indicate the end of a SQL statement. This command delimiter can be any sequence of characters (including numbers, letters, and punctuation), but it cannot contain embedded blanks. As well, it can contain a semicolon, but only as the first character.

If the command delimiter is set to a string beginning with a character that is valid in identifiers, the command delimiter must be preceded by a space. This command delimiter is case sensitive. You must enclose the new command delimiter in single quotation marks.

Note that if the command delimiter is a semicolon (the default), no space is required before the semicolon.

See also

The Interactive SQL utility

Examples
SET OPTION COMMAND_DELIMITER='~'
SET TEMPORARY OPTION command_delimiter = 'select';
message 'hello' select

You can also use Interactive SQL's -d command line option to set the command delimiter without including a SET TEMPORARY OPTION COMMAND_DELIMITER statement in a .sql file. For example, if you have a script file named test.sql which uses tildes (~) as command delimiters, you could run:

dbisql -d "~" test.sql


COMMIT_ON_EXIT option [Interactive SQL]

Function

Controls behavior when Interactive SQL disconnects or terminates.

Allowed values

ON, OFF

Default

ON

Description

Controls whether a COMMIT or ROLLBACK is done when you leave Interactive SQL. When COMMIT_ON_EXIT is set to ON, a COMMIT is done.


COMPRESSION option [replication]

Function

Set the level of compression for SQL Remote messages.

Allowed values

Integer, from -1 to 9

Default

6

Description

The values have the following meanings:

  • -1 Send messages in Version 5 format. Message Agents (both dbremote and ssremote) from previous versions of SQL Remote cannot read messages sent in Version 6 format. You should ensure that COMPRESSION is set to -1 until all Message Agents in your system are upgraded to Version 6.

  • 0 No compression.

  • 1 to 9 Increasing degrees of compression. Creating messages with high compression can take longer than creating messages with low compression.


CONTINUE_AFTER_RAISERROR option [compatibility]

Function

Controls behavior following a RAISERROR statement.

Allowed values

ON, OFF

Default

OFF for databases created with Version 5.x.

ON for databases created with Version 6 or later.

Description

The RAISERROR statement is used within procedures and triggers to generate an error. When this option is set to OFF, the execution of the procedure or trigger is stopped whenever the RAISERROR statement is encountered.

If you set the CONTINUE_AFTER_RAISERROR option to ON, the RAISERROR statement no longer signals an execution-ending error. Instead, the RAISERROR status code and message are stored and the most recent RAISERROR is returned when the procedure completes. If the procedure that caused the RAISERROR was called from another procedure, the RAISERROR is not returned until the outermost calling procedure terminates.

Intermediate RAISERROR statuses and codes are lost after the procedure terminates. If, at return time, an error occurs along with the RAISERROR, then the information for the new error is returned and the RAISERROR information is lost. The application can query intermediate RAISERROR statuses by examining the @@error global variable at different execution points.

The setting of the CONTINUE_AFTER_RAISERROR option is used to control behavior following a RAISERROR statement only if the ON_TSQL_ERROR option is set to CONDITIONAL (the default). If you set the ON_TSQL_ERROR option to STOP or CONTINUE, the ON_TSQL_ERROR setting takes precedence over the CONTINUE_AFTER_RAISERROR setting.

See also

ON_TSQL_ERROR option [compatibility]


CONVERSION_ERROR option [compatibility]

Function

Controls the reporting of data type conversion failures on fetching information from the database.

Allowed values

ON, OFF

Default

ON

Description

This option controls whether data type conversion failures, when data is fetched from the database or inserted into the database, are reported by the database as errors (CONVERSION_ERROR set to ON) or as a warning (CONVERSION_ERROR set to OFF).

When CONVERSION_ERROR is set to ON, the SQLE_CONVERSION_ERROR error is generated. If the option is set to OFF, the warning SQLE_CANNOT_CONVERT is produced.

If conversion errors are reported as warnings only, the NULL value is used in place of the value that could not be converted. In embedded SQL, an indicator variable is set to -2 for the column or columns that cause the error.


COOPERATIVE_COMMIT_TIMEOUT option [database]

Function

Governs when a COMMIT entry in the transaction log is written to disk.

Allowed values

Integer, in milliseconds

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

250

Description

This option has meaning only when COOPERATIVE_COMMITS is set to ON. The database server waits for the specified number of milliseconds for other connections to fill a page of the log before writing to disk. The default setting is 250 milliseconds.


COOPERATIVE_COMMITS option [database]

Function

Controls when commits are written to disk.

Allowed values

ON or OFF

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

ON

Description

If COOPERATIVE_COMMITS is set to OFF, a COMMIT is written to disk as soon as the database server receives it, and the application is then allowed to continue.

If COOPERATIVE_COMMITS is set to ON (the default) and if there are other active connections, the database server does not immediately write the COMMIT to the disk. Instead, the application waits for up to the maximum length set by the COOPERATIVE_COMMIT_TIMEOUT option for something else to put on the pages before they are written to disk.

Setting COOPERATIVE_COMMITS to ON, and increasing the COOPERATIVE_COMMIT_TIMEOUT setting, increases overall database server throughput by cutting down the number of disk I/Os, but at the expense of a longer turnaround time for each individual connection.

If both COOPERATIVE_COMMITS and DELAYED_COMMITS are set to ON, and the COOPERATIVE_COMMIT_TIMEOUT interval passes without the pages getting written, the application is resumed (as if the commit had worked), and the remaining interval (DELAYED_COMMIT_TIMEOUT - COOPERATIVE_COMMIT_TIMEOUT) is used as a DELAYED_COMMIT interval. The pages will then be written, even if they are not full.


DATE_FORMAT option [compatibility]

Function

Sets the format for dates retrieved from the database.

Allowed values

String

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

'YYYY-MM-DD'. This corresponds to ISO date format specifications.

Description

The format is a string using the following symbols:

Symbol | Description
yy | Two digit year
yyyy | Four digit year
mm | Two digit month, or two digit minutes if following a colon (as in hh:mm)
mmm[m...] | Character short form for months—as many characters as there are "m"s
d | Single digit day of week, (0 = Sunday, 6 = Saturday)
dd | Two digit day of month
ddd[d...] | Character short form for day of the week
hh | Two digit hours
nn | Two digit minutes
ss[.ss..] | Seconds and parts of a second
aa | AM or PM (12 hour clock)
pp | PM if needed (12 hour clock)
jjj | Day of the year, from 1 to 366

Each symbol is substituted with the appropriate data for the date that is being formatted.

For symbols that represent character data (such as mmm), you can control the case of the output as follows:

  • Type the symbol in all upper case to have the format appear in all upper case. For example, MMM produces JAN.

  • Type the symbol in all lower case to have the format appear in all lower case. For example, mmm produces jan.

  • Type the symbol in mixed case to have Adaptive Server Anywhere choose the appropriate case for the language that is being used. For example, in English, typing Mmm produces May, while in French it produces mai.

For symbols that represent numeric data, you can control zero-padding with the case of the symbols:

  • Type the symbol in same-case (such as MM or mm) to allow zero padding. For example, yyyy/mm/dd could produce 2002/01/01.

  • Type the symbol in mixed case (such as Mm) to suppress zero padding. For example, yyyy/Mm/Dd could produce 2002/1/1.

Examples

  • The following table illustrates DATE_FORMAT settings, together with the output from the following statement, executed on Thursday May 21, 2001.

    SELECT CURRENT DATE
    DATE_FORMAT | SELECT CURRENT DATE
    yyyy/mm/dd/ddd | 2001/05/21/thu
    jjj | 141
    mmm yyyy | May 1998
    mm-yyyy | 05-1998


DATE_ORDER option [compatibility]

Function

Controls the interpretation of date formats.

Allowed values

'MDY', 'YMD', 'DMY'

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

YMD. This corresponds to ISO date format specifications.

For Open Client and JDBC connections, the default is set to MDY.

Description

The database option DATE_ORDER is used to determine whether 10/11/12 is Oct 11 1912, Nov 12 1910, or Nov 10 1912. The option can have the value 'MDY', 'YMD', or 'DMY'.


DEBUG_MESSAGES option [database]

Function

Controls whether or not MESSAGE statements that include a DEBUG ONLY clause are executed.

Allowed values

ON, OFF

Default

OFF

Description

This option allows you to control the behavior of debugging messages in stored procedures and triggers that contain a MESSAGE statement with the DEBUG ONLY clause specified. By default, this option is set to OFF and debugging messages do not appear when the MESSAGE statement is executed. By setting DEBUG_MESSAGES to ON, you can enable the debugging messages in all stored procedures and triggers.

Note
DEBUG ONLY messages are inexpensive when the DEBUG_MESSAGES option is set to OFF, so these statements can usually be left in stored procedures on a production system. However, they should be used sparingly in locations where they would be executed frequently; otherwise, they may result in a small performance penalty.
See also
  • MESSAGE statement


DEDICATED_TASK option [database]

Function

Dedicates a request handling task to handling requests from a single connection.

Allowed values

ON, OFF

Scope

Can be set as a temporary option only, for the duration of the current connection. DBA permissions are required to set this option.

Default

OFF

Description

When the DEDICATED_TASK connection option is set to ON, a request handling task is dedicated exclusively to handling requests for the connection. By pre-establishing a connection with this option enabled, you will be able to gather information about the state of the database server if it becomes otherwise unresponsive.


DEFAULT_ISQL_ENCODING option [Interactive SQL]

Function

Specifies the code page that should be used by READ, INPUT, and OUTPUT statements.

Allowed values

identifier or string

Scope

Can be set as a temporary option only, for the duration of the current connection.

Default

Use system code page (empty string)

Description

This option is used to specify the code page to use when reading or writing files. It cannot be set permanently. The default code page is the default code page for the platform you are running on. On English Windows machines, the default code page is 1252.

Interactive SQL determines the code page that is used for a particular INPUT, OUTPUT, or READ statement as follows, where code page values occurring earlier in the list take precedence over those occurring later in the list:

  • the code page specified in the ENCODING clause of the INPUT, OUTPUT, or READ statement

  • the code page specified with the DEFAULT_ISQL_ENCODING option (if this option is set)

  • the code page specified with the -codepage command-line option when Interactive SQL was started

  • the default code page for the computer Interactive SQL is running on

For a complete list of supported code pages, see Supported code pages.

See also
  • READ statement [Interactive SQL]
  • INPUT statement [Interactive SQL]
  • OUTPUT statement [Interactive SQL]
  • Pieces in the character set puzzle
Example

  • Set the encoding to UTF-16 (for reading Unicode files):

    SET TEMPORARY OPTION DEFAULT_ISQL_ENCODING = 'UTF-16'


DEFAULT_TIMESTAMP_INCREMENT option [database]

Function

Specifies the number of microseconds to add to a column of type TIMESTAMP in order to keep values in the column unique.

Allowed values

Integer, between 1 and 60 000 000 inclusive.

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

1

Description

Since a TIMESTAMP value is precise to six decimal places in Adaptive Server Anywhere, by default 1 microsecond (0.000001 of a second) is added to differentiate between two identical TIMESTAMP values.

Some software, such as Microsoft Access, truncates TIMESTAMP values to three decimal places, making valid comparisons a problem. You can set the TRUNCATE_TIMESTAMP_VALUES option to ON to specify the number of decimal place values Adaptive Server Anywhere stores to maintain compatibility.

For MobiLink synchronization, this option must be set prior to performing the first synchronization.

See also

TRUNCATE_TIMESTAMP_VALUES option [database]


DELAYED_COMMIT_TIMEOUT option [database]

Function

Determines when the server returns control to an application following a COMMIT.

Allowed values

Integer, in milliseconds.

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

500

Description

This option has meaning only when DELAYED_COMMITS is set to ON. it governs when a COMMIT entry in the transaction log is written to disk. With DELAYED_COMMITS set to ON, the database server waits for the number of milliseconds set in the DELAYED_COMMIT_TIMEOUT option for other connections to fill a page of the log before writing the current page contents to disk.

For more information, see DELAYED_COMMITS option [database].


DELAYED_COMMITS option [database]

Function

Determines when the server returns control to an application following a COMMIT.

Allowed values

ON, OFF

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

OFF. This corresponds to ISO COMMIT behavior.

Description

When set to ON, the database server replies to a COMMIT statement immediately instead of waiting until the transaction log entry for the COMMIT has been written to disk. When set to OFF, the application must wait until the COMMIT is written to disk.

When this option is ON, the log is written to disk when the log page is full or according to the DELAYED_COMMIT_TIMEOUT option setting, whichever is first. There is a slight chance that a transaction may be lost even though committed if a system failure occurs after the server replies to a COMMIT, but before the page is written to disk. Setting DELAYED_COMMITS to ON, and the DELAYED_COMMIT_TIMEOUT option to a high value, promotes a quick response time at the cost of security.

If both COOPERATIVE_COMMITS and DELAYED_COMMITS are set to ON, and if the COOPERATIVE_COMMIT_TIMEOUT interval passes without the pages getting written, the application is resumed (as if the commit had worked), and the remaining interval (DELAYED_COMMIT_TIMEOUT - COOPERATIVE_COMMIT_TIMEOUT) is used as a DELAYED_COMMIT interval after which the pages will be written, even if they are not full.


DELETE_OLD_LOGS option [replication]

Function

Controls whether transaction logs are deleted when their messages have been replicated or synchronized.

Allowed values

ON, OFF, DELAY

Default

OFF

Description

This option is used at MobiLink clients, by SQL Remote, and by the Adaptive Server Anywhere Replication Agent. The default setting is OFF. When it is set to ON, each old transaction log is deleted when all the changes it contains have been sent and confirmed as received. When it is set to DELAY, each old transaction log with a file name indicating that it was created on the current day is not deleted.

For more information about how to use the DELETE_OLD_LOGS option in conjunction with the Backup statement to delete old copies of transaction logs, see the BACKUP statement.


DESCRIBE_JAVA_FORMAT option [Interactive SQL]

Function

Controls whether Java objects are interpreted as strings (for display) or as binary (for loading and unloading).

This option is of use only if you are connecting to a version 8 or earlier database server, as Java objects are not supported in later versions of the software.

Allowed values

varchar, binary

Default

varchar

Description

When set to varchar, Interactive SQL converts all data fetched from the database to strings. The database server calls the toString() method on Java columns to provide formatted output for the Results tab in the Results pane.

When set to binary, Interactive SQL does no data conversion.


DIVIDE_BY_ZERO_ERROR option [compatibility]

Function

Controls the reporting of division by zero.

Allowed values

ON, OFF

Default

ON

Description

This option indicates whether division by zero is reported as an error. If the option is set ON, then division by zero results in an error with SQLSTATE 22012.

If the option is set OFF, division by zero is not an error. Instead, a NULL is returned.


ECHO option [Interactive SQL]

Function

Controls whether statements are echoed to the log file before they are executed.

Allowed values

ON, OFF

Default

ON

Description

This option is most useful when you use the READ statement to execute a Interactive SQL command file. Logging must be turned on in order for this option to take effect.

For information about turning on logging, see START LOGGING statement [Interactive SQL].


Web Links Browse Collapse Expand PDF Previous Next

ASA Database Administration Guide

Database Options

Alphabetical list of options

ESCAPE_CHARACTER option [compatibility]

This option is reserved for system use. Do not change the setting of this option.


Web Links Browse Collapse Expand PDF Previous Next

ASA Database Administration Guide

Database Options

Alphabetical list of options

EXCLUDE_OPERATORS option [database]

This option is reserved for system use. Do not change the setting of this option.


EXTENDED_JOIN_SYNTAX option [database]

Function

Controls whether queries with duplicate correlation names syntax for multi-table joins are allowed, or reported as an error.

Allowed values

ON, OFF

Default

ON

Description

If this option is set to ON then Adaptive Server Anywhere allows duplicate correlation names to be used in the null-supplying side of the outer joins. The tables or views specified with the same correlation name are interpreted as the same instance of the table or view.

The following FROM clause illustrates the Adaptive Server Anywhere interpretation of a join using duplicate correlation names:

( R left outer join T on (C1), T  join S on ( C2 ) )

where C1 and C2 are search conditions.

If the option is set to ON, this join is interpreted as follows:

( R left outer join T on ( C1 ) ) join S on ( C2 )

If the option is set to OFF, the following error is generated:

ASA Error -137: Table 'T' requires a unique correlation name.

Note
To see the result of eliminating duplicate correlation names, you can view the rewritten statement using the REWRITE function with the second argument set to ANSI.
See also

REWRITE function [Miscellaneous]


FIRE_TRIGGERS option [compatibility]

Function

Controls whether triggers are fired in the database.

Allowed values

ON, OFF

Default

ON

Description

When set to ON, triggers are fired. When set to OFF, no triggers are fired, including referential integrity triggers (such as cascading updates and deletes). Only a user with DBA authority can set this option. The option is overridden by the -gf command-line option, which turns off all trigger firing regardless of the FIRE_TRIGGERS setting.

This option is relevant when replicating data from Adaptive Server Enterprise to Adaptive Server Anywhere because all actions from Adaptive Server Enterprise transaction logs are replicated to Adaptive Server Anywhere, including actions carried out by triggers.


FIRST_DAY_OF_WEEK option [database]

Function

Sets the numbering of the days of the week.

Allowed values

1 | 2 | 3 | 4 | 5 | 6 | 7

Default

7 (Sunday is the first day of the week)

Description

The values have the following meaning:

Value | Meaning
1 | Monday
2 | Tuesday
3 | Wednesday
4 | Thursday
5 | Friday
6 | Saturday
7 | Sunday


FLOAT_AS_DOUBLE option [compatibility]

Function

Controls the interpretation of the FLOAT keyword.

Allowed values

ON, OFF

Default

OFF

ON for Open Client and JDBC connections

Description

The FLOAT_AS_DOUBLE option makes the FLOAT keyword behave like Adaptive Server Enterprise's FLOAT keyword when a precision is not specified.

When enabled (set to ON), all occurrences of the keyword FLOAT are interpreted as equivalent to the keyword DOUBLE within SQL statements.

By default, Adaptive Server Anywhere FLOAT values are interpreted by Adaptive Server Enterprise as REAL values. Since Adaptive Server Enterprise treats its own FLOAT values as DOUBLE, enabling this option makes Adaptive Server Anywhere treat FLOAT values in the same way Enterprise treats FLOAT values.

REAL values are four bytes; DOUBLE values are eight bytes. According to the ANSI SQL/92 specification, FLOAT can be interpreted based on the platform. It is up to the database to decide what size the value is, so long as it can handle the necessary precision. Adaptive Server Enterprise and Adaptive Server Anywhere exhibit different default behavior.

The FLOAT_AS_DOUBLE option takes effect only when no precision is specified. For example, the following statement is not affected by the option setting:

CREATE TABLE t1(
   c1 float(5)
)

The following statement is affected by the option setting:

CREATE TABLE t2(
   c1 float)
// affected by option setting


FOR_XML_NULL_TREATMENT option [database]

Function

Controls the treatment of NULL values in queries that use the FOR XML clause.

Allowed values

EMPTY, OMIT

Default

OMIT

Description

If you execute a query that includes the FOR XML clause, the FOR_XML_NULL_TREATMENT option determines how NULL values are treated. By default, elements and attributes that contain NULL values are omitted from the result. Setting this option to EMPTY generates empty elements or attributes if the value is NULL.

See also

Using the FOR XML clause to retrieve query results as XML

SELECT statement


FORCE_VIEW_CREATION option [database]

This option is reserved for system use. Do not change the setting of this option.

Caution The FORCE_VIEW_CREATION option should only be used within a reload.sql script. This option is used by the Unload utility (dbunload) and should not be set explicitly.


GLOBAL_DATABASE_ID option [database]

Function

For use in generating unique primary keys in a replication environment. Controls the beginning of the range of values for columns created with DEFAULT GLOBAL AUTOINCREMENT.

Allowed values

Integer

Default

2147483647

Scope

Can be set for the PUBLIC group only. DBA authority required.

Description

If you create a column with DEFAULT GLOBAL AUTOINCREMENT, its value is incremented. The initial value is determined by the GLOBAL_DATABASE_ID value and the partition size.

For more information on the partition size, see CREATE TABLE statement.

Setting GLOBAL_DATABASE_ID to the default value indicates that GLOBAL DEFAULT AUTOINCREMENT is disabled. In this case NULL is generated as a default.

You can find the value of the option in the current database using the following statement:

SELECT db_property( 'GlobalDBId' )

This feature is of particular use in replication environments to ensure unique primary keys.

For more information, see Ensuring unique primary keys and Maintaining unique primary keys using global autoincrement.

See also

CREATE TABLE statement

Database-level properties

Ensuring unique primary keys


INPUT_FORMAT option [Interactive SQL]

Function

Sets the default data format expected by the INPUT statement.

Allowed values

String. See below.

Default

ASCII

Description

Certain file formats contain information about column names and types. Using this information, the INPUT statement will create the database table if it does not already exist. This is a very easy way to load data into the database. The formats that have enough information to create the table are: DBASEII, DBASEIII, FOXPRO, and LOTUS.

Allowable input formats are:

  • ASCII Input lines are assumed to be ASCII characters, one row per line, with values separated by commas. Alphabetic strings may be enclosed in apostrophes (single quotes) or quotation marks (double quotes). Strings containing commas must be enclosed in either single or double quotes. If single or double quotes are used, double the quote character to use it within the string. Optionally, you can use the DELIMITED BY clause to specify a different delimiter string than the default, which is a comma (,).

    Three other special sequences are also recognized. The two characters \n represent a newline character, \\ represents a single backslash character, and the sequence \xDD represents the character with hexadecimal code DD.

  • DBASE The file is in dBASE II or dBASE III format. Interactive SQL will attempt to determine which format, based on information in the file. If the table doesn't exist, it will be created.

  • DBASEII The file is in dBASE II format. If the table doesn't exist, it will be created.

  • DBASEIII The file is in dBASE III format. If the table doesn't exist, it will be created.

  • EXCEL Input file is in the format of Microsoft Excel 2.1. If the table doesn't exist, it will be created.

  • FIXED Input lines are in fixed format. The width of the columns can be specified using the COLUMN WIDTHS clause. If they are not specified, column widths in the file must be the same as the maximum number of characters required by any value of the corresponding database column's type.

  • FOXPRO The file is in FoxPro format. The FoxPro memo field is different than the dBASE memo field. If the table doesn't exist, it will be created.

  • LOTUS The file is a Lotus WKS format worksheet. INPUT assumes that the first row in the Lotus WKS format worksheet consists of column names. If the table doesn't exist, it will be created. In this case, the types and sizes of the columns created may not be correct because the information in the file pertains to a cell, not to a column.

See also

INPUT statement [Interactive SQL]


INTEGRATED_SERVER_NAME option [database]

Function

Specifies the name of the Domain Controller server used for looking up Windows user group membership for integrated logins.

Allowed values

String

Scope

Can be set for the PUBLIC group only. DBA authority is required to set this option.

Default

NULL

Description

This option allows the DBA to specify the name of the Domain Controller server that is used to look up group membership when using Windows user groups for integrated logins. By default, the machine that Adaptive Server Anywhere is running on is used for verifying group membership.

See also

Creating integrated logins for Windows user groups

GRANT statement

Example

The following example specifies that group membership is verified on the machine server-1.

SET OPTION PUBLIC.INTEGRATED_SERVER_NAME = '\\server-1'


ISOLATION_LEVEL option [compatibility]

Function

Controls the locking isolation level.

Allowed values

0, 1, 2, 3

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

0

1 for Open Client and JDBC connections

Description

This option controls the locking isolation level as follows.

  • 0 Allow dirty reads, non-repeatable reads, and phantom rows.

  • 1 Prevent dirty reads. Allow non-repeatable reads and phantom rows.

  • 2 Prevent dirty reads and guarantee repeatable reads. Allow phantom rows.

  • 3 Serializable. Do not allow dirty reads, guarantee repeatable reads, and do not allow phantom rows.

For more information, see Isolation levels and consistency.


ISQL_COMMAND_TIMING option [Interactive SQL]

Function

Controls whether SQL statements are timed or not.

Allowed values

ON, OFF

Default

ON

Description

This boolean option controls whether SQL statements are timed or not. If you set the option to ON, the time of execution appears in the Messages pane after you execute a statement. If you set the option to OFF, the time does not appear.

You can also set this option on the Messages tab of the Options dialog.


ISQL_ESCAPE_CHARACTER option [Interactive SQL]

Function

Controls the escape character used in place of unprintable characters in data exported to ASCII files.

Allowed values

Any single character

Default

A backslash ( \ )

Description

When Interactive SQL exports strings that contain unprintable characters (such as a carriage return), it converts each unprintable character into a hexadecimal format and precedes it with an escape character. The character you specify for this setting is used in the output if your OUTPUT statement does not contain an ESCAPE CHARACTER clause. This setting is used only if you are exporting to an ASCII file.

Example

  • Create a table that contains one string value with an embedded carriage return (denoted by the "\n" in the INSERT statement). Then export the data to c:\escape.txt with a # sign as the escape character.

    CREATE TABLE escape_test( TEXT varchar(10 ) );
INSERT INTO escape_test VALUES( 'one\ntwo' );
SET TEMPORARY OPTION ISQL_ESCAPE_CHARACTER='#';
SELECT * FROM escape_test;
OUTPUT TO c:\escape.txt FORMAT ASCII

    This code places the following data in escape.txt:

    'one#x0Atwo'

    where # is the escape character and x0A is the hexadecimal equivalent of the "\n" character.

    The start and end characters (in this case, single quotation marks) depend on the ISQL_QUOTE setting.


ISQL_FIELD_SEPARATOR option [Interactive SQL]

Function

Controls the default string used for separating values in data exported to ASCII files.

Allowed values

String

Default

A comma ( , )

Description

Controls the default string used for separating (or delimiting) values in data exported to ASCII files. If an OUTPUT statement does not contain a DELIMITED BY clause, the value of this setting is used.

Example

  • Set the field separator to a colon in the data exported to c:\employee.txt.

    SET TEMPORARY OPTION ISQL_FIELD_SEPARATOR=':';
SELECT emp_lname, emp_fname FROM employee WHERE emp_id < 150;
OUTPUT TO c:\employee.txt FORMAT ASCII

    This code places the following data in employee.txt:

    'Whitney': 'Fran'

    'Cobb':'Matthew'

    'Chin':'Philip'

    'Jordan':'Julie'

    The start and end characters (in this case, single quotation marks) depend on the ISQL_QUOTE setting.


ISQL_LOG option [Interactive SQL]

Function

Controls logging behavior.

Allowed values

String, containing a file name

Default

Empty string

Description

If ISQL_LOG is set to a non-empty string, all Interactive SQL statements are added to the end of the named file. Otherwise, if ISQL_LOG is set to the empty string, Interactive SQL statements are not logged.

Individual session only
This option logs an individual Interactive SQL session only.

For a description of the transaction log that logs all changes to the database by all users, see Backup and Data Recovery.


ISQL_PLAN option [Interactive SQL]

Function

Controls the type of access plan that appears on the Plan tab and the UltraLite Plan tab in the Interactive SQL Results pane after you execute statements.

Allowed values

SHORT, LONG, GRAPHICAL, GRAPHICALWITHSTATISTICS, NONE

Default

SHORT

Description

This option allows you to specify the type of access plan that appears for SELECT, INSERT, UPDATE, and DELETE statements. To set the level of detail for the plan the optimizer provides, you can choose one of the following values:

SHORT provides basic information about the access plan.

LONG provides detailed information about the access plan.

GRAPHICAL provides a tree diagram of the query. You can click a node in the plan diagram to see details about that part of the query.

GRAPHICALWITHSTATISTICS provides a tree diagram of the query, as well as statistics which indicate the resources used by the part of the query that is selected. The UltraLite plan treats this value the same as the GRAPHICAL value.

NONE means no optimizer information can be accessed. This parameter is deprecated.

The plan is computed only when you click the Plan tab.

You can also specify the plan type on the Plan tab of the Interactive SQL Options dialog.

Note that the access plan that appears may not be the same plan that was used when the statement was executed. The plan is fetched after the SQL statement is executed, at which point the optimizer may have new information available. This means that the optimizer may return a different plan than the one it used to execute the statement.


ISQL_PRINT_RESULT_SET option [Interactive SQL]

Function

This option specifies which result set(s) are printed when a .SQL file is run.

The ISQL_PRINT_RESULT_SET option takes effect only when you run the Interactive SQL [dbisql] utility within a command window (for example, when running a .SQL file).

Allowed values

LAST, ALL, NONE

Default

LAST

Description

This option allows you to specify which result set(s) are printed when a .SQL file is run. It is remembered on a per-machine basis (not per-user), and is case-insensitive.

You can choose one of the following print options:

LAST prints the result set from the last statement in the file.

ALL prints result sets from each statement in the file which returns a result set.

NONE does not print any result sets.

Although this option has no affect when Interactive SQL is running in windowed mode, you can still view and set the option in windowed mode. Choose Tools > Options, then select the appropriate action in the Console Mode box on the Results page. Remember to click Make Permanent if you want to set this option for all Interactive SQL sessions. Otherwise, the change will be discarded when you exit Interactive SQL.


ISQL_QUOTE option [Interactive SQL]

Function

Controls the default string that begins and ends all strings in data exported to ASCII files.

Allowed values

String

Default

A single apostrophe ( ' )

Description

Controls the default string that begins and ends all strings in data exported to ASCII files. If an OUTPUT statement does not contain a QUOTE clause, this value is used by default.

Example

  • To change the default string that begins and ends all strings to a double quote character.

    SET TEMPORARY OPTION ISQL_QUOTE='"';
SELECT emp_lname, emp_fname FROM employee WHERE emp_id < 150;
OUTPUT TO c:\employee.txt FORMAT ASCII

    This code places the following data in employee.txt:

    "Whitney", "Fran"

    "Cobb","Matthew"

    "Chin","Philip"

    "Jordan","Julie"

    The separator characters (in this case, commas) depend on the ISQL_FIELD_SEPARATOR setting.


JAVA_HEAP_SIZE option [database]

Function

To limit the memory used by Java applications for a connection.

Allowed values

Integer

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately. DBA permissions are required to set this option for any connection.

Default

1 000 000

Description

This option sets the maximum size (in bytes) of the memory that is allocated to Java applications on a per-connection basis. Per-connection memory allocations typically consist of the user's working set of allocated Java variables and Java application stack space.

While a Java application is executing on a connection, the per-connection allocations come out of the fixed cache of the database server, so it is important that a run-away Java application is prevented from using up too much memory.


JAVA_INPUT_OUTPUT option [database]

Function

Enables file access from Java in the database

Allowed values

ON, OFF

Supported on Windows NT only.

Scope

DBA authority required.

Default

OFF

Description

By default, the java.io package is only partially supported. In particular, classes that handle file access are disabled. If JAVA_INPUT_OUTPUT is set to ON, Java file access classes in java.io are enabled.

See also

Security management for Java


JAVA_NAMESPACE_SIZE option [database]

Function

Limits the memory used by Java applications for a connection.

Allowed values

Integer

Scope

Can be set for the PUBLIC group only. DBA authority required. Takes effect immediately.

Default

4 000 000

Description

This option sets the maximum size (in bytes) of the memory that is allocated to Java applications on a per-database basis.

Per-database memory allocations include Java class definitions. Because class definitions are effectively read-only, they are shared between connections. Consequently, their allocations come right out of the fixed cache, and this option sets a limit on the size of these allocations.


LOG_DEADLOCKS option [database]

Function

Controls whether deadlock reporting is turned on or off.

Allowed values

ON, OFF

Scope

Can be set for the PUBLIC group only. DBA authority required. Takes effect immediately.

Default

ON

Description

When this option is set to ON, the database server logs information about deadlocks in an internal buffer. The size of the buffer is fixed at 10,000 bytes. You can view the deadlock information using the sa_report_deadlocks stored procedure. The contents of the buffer are cleared when this option is set to OFF.

When deadlock occurs, information is reported for only those connections involved in the deadlock. The order in which connections are reported is based on which connection is waiting for which row. For thread deadlocks, information is reported about all connections.

See also

sa_report_deadlocks system procedure

Determining who is blocked


LOGIN_MODE option [database]

Function

Controls the use of integrated logins for the database.

Allowed values

Standard, Mixed, Integrated

Scope

Can be set for the PUBLIC group only. DBA authority required. Takes effect immediately.

Default

Standard

Description

This option specifies whether integrated logins are permitted. The following values are accepted (the values are case insensitive):

  • Standard This is the default setting, which does not permit integrated logins. An error occurs if an integrated login connection is attempted.

  • Mixed With this setting, both integrated logins and standard logins are allowed.

  • Integrated With this setting, all logins to the database must be made using integrated logins.

    Caution Setting the LOGIN_MODE database option to Integrated restricts connections to only those Windows users or groups who have been granted an integrated login mapping. Attempting to connect with a user ID and password generates an error. The only exceptions to this are users with DBA authority (full administrative rights).

For more information on integrated logins see Using integrated logins.


LOGIN_PROCEDURE option [database]

Function

A login procedure that sets connection compatibility options at startup. By default the procedure calls the sp_login_environment procedure to determine which options to set.

Allowed values

String

Scope

DBA authority required.

Default

sp_login_environment

Description

This login procedure calls the sp_login_environment procedure at run time to determine the database connection settings.

You can customize the default database option settings by creating a new procedure and setting LOGIN_PROCEDURE to call the new procedure. You should not edit either sp_login_environment or sp_tsql_environment.

Examples

  • The following example shows how you can disallow a connection by signaling the INVALID_LOGON error.

create procedure DBA.login_check()
   begin
      declare INVALID_LOGON exception for sqlstate '28000';
      // Allow a maximum of 3 concurrent connections
      if( db_property('ConnCount') > 3 ) then
      signal INVALID_LOGON;
      else
     call sp_login_environment;
      end if;
   end
   go
   grant execute on DBA.login_check to PUBLIC
   go
   set option PUBLIC.Login_procedure='DBA.login_check'
   go

For an alternate way to disallow connections, see RAISERROR statement [T-SQL].

  • The following example shows how you can block connection attempts if the number of failed connections for a user exceeds 3 within a 30 minute period. All blocked attempts during the block out period receive an invalid password error and are logged as failures. The log is kept long enough for a DBA to analyze it.

create table DBA.ConnectionFailure(
    pk int primary key default autoincrement,
    user_name char(128) not null,
    tm timestamp not null default current timestamp
)
go
create index ConnFailTime on DBA.ConnectionFailure(
    user_name, tm )
go
create event ConnFail type ConnectFailed
handler
begin
    declare usr char(128);
    set usr = event_parameter( 'User' );
    // Put a limit on the number of failures logged.
    if (select count(*) from DBA.ConnectionFailure
        where user_name = usr
        and tm >= dateadd( minute, -30,
            current timestamp )) < 20 then
        insert into DBA.ConnectionFailure( user_name )
            values( usr );
        commit;
        // Delete failures older than 7 days
        delete DBA.ConnectionFailure
        where user_name = usr
        and tm < dateadd( day, -7, current timestamp );
        commit;
    end if;
end
go

create procedure DBA.login_check()
begin
    declare usr char(128);
    declare INVALID_LOGON exception for sqlstate '28000';
    set usr = connection_property( 'Userid' );
    // Block connection attempts from this user
    // if 3 or more failed connection attempts have occurred
    // within the past 30 minutes.
    if (select count(*) from DBA.ConnectionFailure
        where user_name = usr
        and tm >= dateadd( minute, -30,
            current timestamp ) ) >= 3 then
        signal INVALID_LOGON;
    else
        call sp_login_environment;
    end if;
end
go
grant execute on DBA.login_check to PUBLIC
go

set option PUBLIC.Login_procedure='DBA.login_check'
go


MAX_CURSOR_COUNT option [database]

Function

A resource governor to limit the maximum number of cursors that a connection can use at once.

Allowed values

Integer

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately. DBA permissions are required to set this option for any connection.

Default

50

Description

This resource governor allows a DBA to limit the number of cursors per connection that a user can use. If an operation would exceed the limit for a connection, an error is generated, indicating that the governor for the resource has been exceeded.

If a connection executes a stored procedure, that procedure is executed under the permissions of the procedure owner. However, the resources used by the procedure are assigned to the current connection.

You can remove resource limits by setting the option to 0 (zero).


MAX_HASH_SIZE option [database] (deprecated)

Function

Specify the default maximum hash size for new indexes.

Allowed values

Integer, from 2 to 64 inclusive.

Scope

Can be set for the PUBLIC group only. Takes effect immediately. DBA permissions are required to set this option.

Default

10

Description

This option controls the default hash size for indexes. This option is deprecated.

See also

CREATE INDEX statement

CREATE TABLE statement


MAX_PLANS_CACHED option [database]

Function

Specify the maximum number of execution plans to be stored in a cache.

Allowed values

Integer

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately. DBA permissions are required to set this option for the PUBLIC group.

Default

20

Description

This option specifies the maximum number of plans cached for each connection. The optimizer caches the execution plan for queries, INSERT, UPDATE, and DELETE statements that are performed inside stored procedures, functions, and triggers. After a statement in a stored procedure, stored function, or trigger is executed several times by a connection, the optimizer builds a reusable plan for the statement.

Reusable plans do not use the values of host variables for selectivity estimation or rewrite optimizations. As a result of this, the reusable plan can have a higher cost than if the statement was re-optimized. When the cost of the reusable plan is close to the best observed cost for a statement, the optimizer adds the plan to the plan cache.

The cache is cleared when you execute statements, such as CREATE TABLE and DROP TABLE, that modify the table schema. Statements that reference declared temporary tables are not cached.

Setting this option to 0 disables plan caching.

See also

Access plan caching

Connection-level properties


MAX_RECURSIVE_ITERATIONS option [database]

Function

Limits the maximum number of iterations a recursive common table expression can make.

Allowed values

Integer

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately. DBA permissions are required to set this option for the PUBLIC group.

Default

100

Description

Computation of a recursive common table expression aborts and an error is generated if they fail to terminate within the specified number of iterations. Recursive subqueries often increase geometrically in the amount of resources required for each additional iteration. Set this option so as to limit the amount of time and resources that will be consumed before infinite recursion is detected, yet permit your recursive common table expressions to work as intended.

Setting this option to 0 disables recursive common table expressions.

See also

Common Table Expressions


MAX_STATEMENT_COUNT option [database]

Function

A resource governor to limit the maximum number of prepared statements that a connection can use at once.

Allowed values

Integer >=0

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately. DBA permissions are required to set this option for any connection.

Default

50

Description

This resource governor allows a DBA to limit the number of prepared statements per connection a user can use. If an operation would exceed the limit for a connection, an error is generated, indicating that the governor for the resource has been exceeded.

If a connection executes a stored procedure, that procedure is executed under the permissions of the procedure owner. However, the resources used by the procedure are assigned to the current connection.

You can remove resource limits by setting the option to 0 (zero).


MAX_WORK_TABLE_HASH_SIZE option [database] (deprecated)

Function

Specify the maximum hash size used during query optimization for internal temporary tables.

Allowed values

Integer, from 2 to 64 inclusive

Scope

Can be set for the PUBLIC group only. Takes effect immediately. DBA permissions are required to set this option.

Default

20

Description

In general, you should not need to use this option as the query optimizer allocates hash sizes for the internal temporary tables based on the data distribution within the table. The option allows you to override the optimizer behavior to either increase the maximum hash size it can use beyond 20, or to restrict it further. This option is deprecated.

See also

Use of work tables in query processing.


MIN_PASSWORD_LENGTH option [database]

Function

Sets the minimum length for new passwords in the database.

Allowed values

Integer, greater than or equal to zero.

The value is in bytes. For single-byte character sets, this is the same as the number of characters.

Scope

Can be set for the PUBLIC group. Takes effect immediately. DBA permissions are required to set this option.

Default

0 characters

Description

This option allows the database administrator to impose a minimum length on all new passwords for greater security. Existing passwords are not affected. Passwords have a maximum length of 255 bytes.

Example

  • Set the minimum length for new passwords to 6 bytes.

    SET OPTION PUBLIC.MIN_PASSWORD_LENGTH = 6


NEAREST_CENTURY option [compatibility]

Function

Controls the interpretation of two-digit years in string-to-date conversions.

Allowed values

Integer, between 0 and 100 inclusive.

Default

50 for databases created with Version 6 or later.

0 for databases created with Version 5.5 or earlier.

Description

This option controls the handling of two-digit years when converting from strings to dates or timestamps.

The NEAREST_CENTURY setting is a numeric value that acts as a rollover point. Two digit years less than the value are converted to 20yy, while years greater than or equal to the value are converted to 19yy.

The historical Adaptive Server Anywhere behavior is to add 1900 to the year. Adaptive Server Enterprise behavior is to use the nearest century, so any year where value yy is less than 50, the year is set to 20yy.


NON_KEYWORDS option [compatibility]

Function

Turns off individual keywords, allowing their use as identifiers.

Allowed values

String

Default

Empty string

Description

This option turns off individual keywords or all keywords introduced since a specific release of the product. This provides a way of ensuring that applications created with older versions of the product are not broken by new keywords. If you have an identifier in your database that is now a keyword, you can either add double quotes around the identifier in all applications or scripts, or turn off the keyword using the NON_KEYWORDS option.

In addition to specifying individual keywords, you can turn off all keywords since a specified release using one of the following special values in the list of keywords:

keywords_4_0_d, keywords_4_0_c, keywords_4_0_b, keywords_4_0_a, keywords_4_0, keywords_5_0_01, keywords_5_0

The following statement prevents TRUNCATE and SYNCHRONIZE from being recognized as keywords:

SET OPTION NON_KEYWORDS = 'TRUNCATE, SYNCHRONIZE'

The following statement prevents all keywords introduced since release 4.0d from being recognized as keywords:

SET OPTION NON_KEYWORDS = 'keywords_4_0_d'

Each new setting of this option replaces the previous setting. The following statement clears all previous settings.

SET OPTION NON_KEYWORDS =

A side-effect of this options is that SQL statements that use a turned off keyword cannot be used: they produce a syntax error.

See also

Keywords


NULLS option [Interactive SQL]

Function

Specifies how NULL values in the database appear.

Allowed values

String

Default

(NULL)

Description

Set this according to your preference.


ODBC_DESCRIBE_BINARY_AS_VARBINARY [database]

Function

Controls how the Adaptive Server Anywhere ODBC driver describes BINARY columns.

Allowed values

ON, OFF

Default

OFF

Description

This option allows you to choose whether you want all BINARY and VARBINARY columns to be described to your application as BINARY or VARBINARY. By default, the Adaptive Server Anywhere ODBC driver describes both BINARY and VARBINARY columns as SQL_BINARY. When this option is set to ON, the ODBC driver describes BINARY and VARBINARY columns as SQL_VARBINARY. Regardless of the setting of this option, it is not possible to distinguish between BINARY and VARBINARY columns.

It may be useful to turn this option ON if you are using Delphi applications where BINARY columns are always zero-padded, but VARBINARY columns are not. You can improve performance in Delphi by setting this option to ON so that all columns are treated as variable length data types.

See also
  • BINARY data type [Binary]
  • VARBINARY data type [BINARY]


ODBC_DISTINGUISH_CHAR_AND_VARCHAR option [database]

Function

Controls how the Adaptive Server Anywhere ODBC driver describes CHAR columns.

Allowed values

ON, OFF

Default

OFF

Description

When a connection is opened, the Adaptive Server Anywhere ODBC driver uses the setting of this option to determine how CHAR columns are described. If this option is set to OFF (the default), then CHAR columns are described as SQL_VARCHAR. If this option is set to ON, then CHAR columns are described as SQL_CHAR. VARCHAR columns are always described as SQL_VARCHAR.

See also
  • CHAR data type [Character]
  • CHARACTER VARYING (VARCHAR) data type [Character]


ON_CHARSET_CONVERSION_FAILURE option [database]

Function

Controls what happens if an error is encountered during character conversion.

Allowed values

String. See below for allowed values.

Default

IGNORE

Description

Controls what happens if an error is encountered during character conversion, as follows:

  • IGNORE Errors and warnings do not appear.

  • WARNING Reports substitutions and illegal characters as warnings. Illegal characters are not translated.

  • ERROR Reports substitutions and illegal characters as errors.

Single-byte to single-byte converters are not able to report substitutions and illegal characters, and must be set to IGNORE.


ON_ERROR option [Interactive SQL]

Function

Controls what happens if an error is encountered while executing statements in Interactive SQL.

Allowed values

String. See below for allowed values.

Default

PROMPT

Description

Controls what happens if an error is encountered while executing statements, as follows:

  • STOP Interactive SQL stops executing statements.

  • PROMPT Interactive SQL prompts the user to see if the user wishes to continue.

  • CONTINUE The error is ignored and Interactive SQL continues executing statements.

  • EXIT Interactive SQL terminates.

  • NOTIFY_CONTINUE The error is reporting, and the user is prompted to press Enter or click OK to continue.

  • NOTIFY_STOP The error is reported, and the user is prompted to press Enter or click OK to stop executing statements.

  • NOTIFY_EXIT The error is reported and the user is prompted to press Enter or click OK to terminate Interactive SQL.

When you are executing a .SQL file, the values STOP and EXIT are equivalent.


ON_TSQL_ERROR option [compatibility]

Function

Controls error-handling in stored procedures.

Allowed values

String. See below for allowed values.

Default

CONDITIONAL

Description

This option controls error handling in stored procedures.

  • STOP Stop execution immediately upon finding an error.

  • CONDITIONAL If the procedure uses ON EXCEPTION RESUME, and the statement following the error handles the error, continue, otherwise exit.

  • CONTINUE Continue execution, regardless of the following statement. If there are multiple errors, the first error encountered in the stored procedure is returned.

Both CONDITIONAL and CONTINUE settings for ON_TSQL_ERROR are used for Adaptive Server Enterprise compatibility, with CONTINUE most closely simulating Adaptive Server Enterprise behavior. The CONDITIONAL setting is recommended, particularly when developing new Transact-SQL stored procedures, as it allows errors to be reported earlier.

When this option is set to STOP or CONTINUE, it supercedes the setting of the CONTINUE_AFTER_RAISERROR option. However, when this option is set to CONDITIONAL (the default), behavior following a RAISERROR statement is determined by the setting of the CONTINUE_AFTER_RAISERROR option.

See also

CREATE PROCEDURE statement

CREATE PROCEDURE statement [T-SQL]

Transact-SQL procedure language overview

CONTINUE_AFTER_RAISERROR option [compatibility]


OPTIMISTIC_WAIT_FOR_COMMIT option [compatibility]

Function

Controls locking behavior for WAIT_FOR_COMMIT option.

Allowed values

ON, OFF

Default

OFF

Description

By default, OPTIMISTIC_WAIT_FOR_COMMIT is OFF.

Locking behavior is changed as follows when both OPTIMISTIC_WAIT_FOR_COMMIT and WAIT_FOR_COMMIT are ON:

  • No locks are placed on primary key rows when adding a foreign key row without a matching primary key row.

  • If a transaction adds a primary row, it will be allowed to commit only if the transaction has exclusive locks on all foreign rows that reference the primary row at the time the primary row is added.

This feature is for use in migrating 5.x applications to version 8.x or later by mimicking 5.x locking behavior when transactions add foreign rows before primary rows (as long as no two transactions concurrently add foreign rows with the same key value).

Note that this option is not recommended for general use as there are a number of situations in which transactions will not be allowed to commit, including:

  • If transactions concurrently add foreign rows with the same key value when the primary row does not exist, at most 1 of the transactions will be allowed to commit (the one that adds the corresponding primary row).

  • If a transaction deletes a primary row and then adds it back, it likely will not be allowed to commit (unless it has somehow obtained exclusive locks on all of the matching foreign rows).


OPTIMIZATION_GOAL option [database]

Function

Determines whether query processing is optimized towards returning the first row quickly, or minimizing the cost of returning the complete result set.

Allowed values

first-row, all-rows

Default

all-rows

Description

The OPTIMIZATION_GOAL option controls whether Adaptive Server Anywhere optimizes SQL data manipulation language (DML) statements for response time or total resource consumption.

If the option is set to all-rows (the default), then Adaptive Server Anywhere optimizes a query so as to choose an access plan with the minimal estimated total retrieval time. Setting OPTIMIZATION_GOAL to all-rows may be appropriate for applications that intend to process the entire result set, such as PowerBuilder DataWindow applications. A setting of all-rows is also appropriate for insensitive (ODBC static) cursors since the entire result is materialized when the cursor is opened. It may also be appropriate for scroll (ODBC keyset-driven) cursors, since the intent of such a cursor is to permit scrolling through the result set.

If the option is set to first-row, Adaptive Server Anywhere chooses an access plan that is intended to reduce the time to fetch the first row of the query's result, possibly at the expense of total retrieval time. In particular, the Adaptive Server Anywhere optimizer will typically avoid, if possible, access plans that require the materialization of results in order to reduce the time to return the first row. With this setting, the optimizer favors access plans that utilize an index to satisfy a query's ORDER BY clause, rather than plans that require an explicit sorting operation.

You can use the FASTFIRSTROW table hint in a query's FROM clause to set the optimization goal for a specific query to first-row, without having to change the OPTIMIZATION_GOAL setting.

For more information about using the FASTFIRSTROW table hint, see FROM clause.


OPTIMIZATION_LEVEL option [database]

Function

Controls the amount of effort made by the Adaptive Server Anywhere query optimizer to find an access plan for an SQL statement.

Allowed values

0–15

Default

9

Description

The OPTIMIZATION_LEVEL option controls the amount of effort that the Adaptive Server Anywhere optimizer spends on optimizing SQL data manipulation language (DML) statements. This option controls the maximum number of alternative join strategies that the optimizer will consider for any SELECT block. The higher the setting of OPTIMIZATION_LEVEL, the greater the maximum number of join strategies that the optimizer will consider.

If the option is set to 0, then Adaptive Server Anywhere optimizer chooses the first access plan it considers for execution, in effect avoiding any cost-based comparison of alternative plans. In addition, with level 0 some semantic optimizations of nested queries are disabled. If this option is set to a value higher than 0, the optimizer evaluates alternative strategies and chooses the one with the lowest expected cost. If this option is set to a value greater than the default (9), the optimizer is more aggressive in its search for alternative strategies, possibly resulting in much higher elapsed time spent in the optimization phase.

In typical scenarios, this option is temporarily set to lower levels (0, 1, or 2) when the application desires faster OPEN times for a DML statement, and it is known that though the statement may be complex the query's execution time is very small, and hence the specific access plan chosen by the optimizer is less consequential. It is not recommended that the PUBLIC setting of OPTIMIZATION_LEVEL be changed from its default.

The effect of setting the OPTIMIZATION_LEVEL option is independent of the settings of the OPTIMIZATION_GOAL and OPTIMIZATION_WORKLOAD options.

Simple DML statements (single-block, single-table queries that contain equality conditions in the WHERE clause that uniquely identify a specific row) are optimized heuristically and bypass the cost-based optimizer altogether. The optimization of simple DML statements is not affected by the setting of the OPTIMIZATION_LEVEL option. The count of the number of requests optimized through the optimizer bypass mechanism is available as the QueryBypassed connection property.

For more information about the QueryBypassed connection property, see Connection-level properties.


OPTIMIZATION_WORKLOAD option [database]

Function

Determines whether query processing is optimized towards a workload that is a mix of updates and reads or a workload that is predominantly read-based.

Allowed values

Mixed, OLAP

Scope

Can be set for the PUBLIC group only. DBA authority required.

Default

Mixed

Description

The OPTIMIZATION_WORKLOAD option controls whether Adaptive Server Anywhere optimizes queries for a workload that is a mix of updates and reads or predominantly read only.

If the option is set to Mixed (the default), Adaptive Server Anywhere chooses query optimization algorithms appropriate for a workload that is a mixture of short inserts, updates, and deletes and longer running read-only queries.

If the option is set to OLAP, Adaptive Server Anywhere chooses algorithms appropriate for a workload that consists for the most part of long-running queries, combined with batch updates. In particular, the optimizer may choose to use the Clustered Hash Group By query execution algorithm.

When the option is set to OLAP, the Clustered Hash Group By algorithm is enabled. If the option is set to Mixed (the default), it is disabled.

See also

Clustered Hash Group By algorithm


OUTPUT_FORMAT option [Interactive SQL]

Function

Sets the default output format for data retrieved by a SELECT statement that is redirected to a file or output using the OUTPUT statement.

Allowed values

String. See below for allowed values.

Default

ASCII

Description

The valid output formats are:

  • ASCII The output is an ASCII format file with one row per line in the file. All values are separated by commas, and strings are enclosed in apostrophes (single quotes). The delimiter and quote strings can be changed using the DELIMITED BY and QUOTE clauses. If ALL is specified in the QUOTE clause, then all values (not just strings) will be quoted.

    Three other special sequences are also used. The two characters \n represent a newline character; \\ represents a single backslash character, and the sequence \xDD represents the character with hexadecimal code DD.

  • DBASEII The output is a dBASE II format file with the column definitions at the top of the file. Note that a maximum of 32 columns can be output. Column names are truncated to 11 characters, and each row of data in each column is truncated to 255 characters.

  • DBASEIII The output is a dBASE III format file with the column definitions at the top of the file. Note that a maximum of 128 columns can be output. Column names are truncated to 11 characters, and each row of data in each column is truncated to 255 characters.

  • EXCEL The output is an Excel 2.1 worksheet. The first row of the worksheet contains column labels (or names if there are no labels defined). Subsequent worksheet rows contain the actual table data.

  • FIXED The output is fixed format, with each column having a fixed width. The width for each column can be specified using the COLUMN WIDTH clause. If this clause is omitted, the width for each column is computed from the data type for the column, and is large enough to hold any value of that data type. No column headings are output in this format.

  • FOXPRO The output is a FoxPro format file (the FoxPro memo field is different than the dBASE memo field) with the column definitions at the top of the file. Note that a maximum of 128 columns can be output. Column names are truncated to 11 characters, and each row of data in each column is truncated to 255 characters.

  • HTML The output is in the Hyper Text Markup Language (HTML) format.

  • LOTUS The output is a Lotus WKS format worksheet. Column names will be put as the first row in the worksheet. Note that there are certain restrictions on the maximum size of Lotus WKS format worksheets that other software (such as Lotus 1-2-3) can load. There is no limit to the size of file Interactive SQL can produce.

  • SQL The output is an Interactive SQL INPUT statement required to recreate the information in the table.

  • XML The output is an XML file encoded in UTF-8 and containing an embedded DTD. Binary values are encoded in CDATA blocks with the binary data rendered as 2-hex-digit strings.


OUTPUT_LENGTH option [Interactive SQL]

Function

Controls the length of column values when Interactive SQL exports information to an external file.

Allowed values

Integer

Default

0 (no truncation)

Description

This option controls the maximum length of column values when Interactive SQL exports data to an external file (using output redirection with the OUTPUT statement). This option affects only ASCII, HTML, and SQL output formats.


OUTPUT_NULLS option [Interactive SQL]

Function

Controls the way NULL values are exported.

Allowed values

String

Default

(empty string)

Description

This option controls the way NULL values are written by the OUTPUT statement. Every time a NULL value is found in the result set, the string from this option is returned instead. This option affects only ASCII, HTML, FIXED, EXCEL, and SQL output formats.


PERCENT_AS_COMMENT option [compatibility]

Function

Controls the interpretation of the percent character.

Allowed values

ON, OFF

Default

ON

Description

It is recommended that you do not use % as a comment marker.

Versions of this product before Version 6 treated the percent character (%) in SQL statements exclusively as a comment delimiter. Since Version 5, alternative comment markers such as //, /* */, and – (double dash) have been available. The double-dash style is the SQL/92 comment delimiter.

Adaptive Server Enterprise treats % as a modulo operator and does not support the Adaptive Server Anywhere mod function. Writing a statement that works in both environments and performs a modulo operation was previously impossible.

The PERCENT_AS_COMMENT option controls the meaning of %. The default setting is ON for backwards compatibility. You can set the option to OFF for compatibility with Adaptive Server Enterprise.

Procedures, triggers and views that were created with %-style comments are converted to double-dash comments when they are stored in the catalog.

Existing procedures must be recreated before changing option
Any existing procedures that contain %-style comments must be recreated before you change the option setting; otherwise, the procedures will fail to load.

Previous Next


PINNED_CURSOR_PERCENT_OF_CACHE option [database]

Function

Specifies how much of the cache can be used for pinning cursors.

Allowed values

Integer, between 0–100

Scope

Can be set for the PUBLIC group only. DBA authority required.

Default

10

Description

The server uses pages of virtual memory for the data structures needed to implement cursors. These pages are kept locked in memory between fetch requests so they are readily available when the next fetch request arrives.

To prevent these pages from occupying too much of the cache in low memory environments, a limit is placed on the percentage of the cache allowed to be used for pinning cursors. You can use the PINNED_CURSOR_PERCENT_OF_CACHE option to adjust this limit.

The option value is specified as a percentage from 0 to 100, with a default of 10. Setting the option to 0 means that cursor pages will not be pinned between fetch requests.


PRECISION option [database]

Function

Specifies the maximum number of digits in the result of any decimal arithmetic.

Allowed values

Integer, between 0 and 127 inclusive.

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

30

Description

Precision is the total number of digits to the left and right of the decimal point. The SCALE option specifies the minimum number of digits after the decimal point when an arithmetic result is truncated to the maximum PRECISION.

Multiplication, division, addition, subtraction, and aggregate functions can all have results that exceed the maximum precision.

For example, when a DECIMAL(8,2) is multiplied with a DECIMAL(9,2), the result could require a DECIMAL(17,4). If PRECISION is 15, only 15 digits will be kept in the result. If SCALE is 4, the result will be a DECIMAL(15,4). If SCALE is 2, the result will be a DECIMAL(15,2). In both cases, there is a possibility of overflow.


PREFETCH option [database]

Function

The PREFETCH option controls whether or not rows are fetched to the client side before being made available to the client application.

Allowed values

OFF, CONDITIONAL, ALWAYS

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

CONDITIONAL

Description

This option controls whether rows are fetched to the client side in advance of being made available to the client application. Fetching a number of rows at a time, even when the client application requests rows one at a time (for example, when looping over the rows of a cursor) can cut down on response time and improve overall throughput by cutting down the number of requests to the database.

  • OFF means no prefetching is done.

  • CONDITIONAL (the default) causes prefetching to occur unless the cursor type is SENSITIVE or the query includes a proxy table.

  • ALWAYS means prefetching is done even for SENSITIVE cursor types and cursors that involve a proxy table.

The ALWAYS value must be used with caution, as it affects some cursor semantics. For example, it causes the sensitive cursor to become asensitive. Old values may be fetched if the value was updated between the prefetch and the application's fetch request. In addition, using prefetch on a cursor that involves a proxy table can cause the error –668, Cursor is restricted to FETCH NEXT operations, if the client attempts to re-fetch prefetch rows. A client may attempt to re-fetch prefetch rows after a rollback or on a fetch relative 0, if a fetch column is re-bound or bound for the first time after the first fetch, or in some cases when GET DATA is used.

The setting of PREFETCH is ignored by Open Client and jConnect connections.

If the DisableMultiRowFetch connection parameter is set to YES, the PREFETCH database option is ignored and no prefetching is done.

This option previously accepted the value ON. This value is now an alias for CONDITIONAL.

See also
  • Prefetching rows
  • DisableMultiRowFetch connection parameter [DMRF]


PRESERVE_SOURCE_FORMAT option [database]

Function

Controls whether the original source definition of procedures, triggers, views, and event handlers is saved in system files. If saved, it is saved in the column source in SYSTABLE, SYSPROCEDURE, SYSTRIGGER, and SYSEVENT.

Allowed values

ON, OFF

Scope

Can be set for the PUBLIC group only. DBA authority required.

Default

ON

Description

When PRESERVE_SOURCE_FORMAT is ON, the server saves the formatted source from CREATE and ALTER statements on procedures, views, triggers, and events, and puts it in the appropriate system table's source column.

Unformatted source text is stored in the same system tables, in the columns proc_defn, trigger_defn, and view_defn. However, these definitions are not easy to read in Sybase Central. The formatted source column allows you to view the definitions with the spacing, comments, and case that you want.

This option can be turned off to reduce space used to save object definitions in the database. The option can be set only for the user PUBLIC.


PREVENT_ARTICLE_PKEY_UPDATE option [database]

Function

Controls updates to the primary key columns of tables involved in publications.

Allowed values

ON, OFF

Default

ON

Description

Setting this option to ON disallows updates to the primary key columns of tables that are part of a publication. This option helps ensure data integrity, especially in a replication and synchronization environment


QUALIFY_OWNERS option [replication]

Function

Controls whether SQL statements being replicated by SQL Remote should use qualified object names.

Allowed values

ON, OFF

Default

The default in Adaptive Server Anywhere is ON.

The default in Adaptive Server Enterprise is OFF.

Description

Qualifying owners in Adaptive Server Enterprise setups is rarely needed because it is common for objects to be owned by dbo. When qualification is not needed in Adaptive Server Anywhere setups, messages will be slightly smaller with the option OFF.


QUERY_PLAN_ON_OPEN option [compatibility]

Function

Controls whether a plan is returned when a cursor is opened.

Allowed values

ON, OFF

Default

OFF

Description

In early versions of the software, each time an OPEN was done on a cursor, the server would return in the SQLCA sqlerrmc field a string representing the query plan (limited to 70 bytes). A more complete description can be obtained using the EXPLAIN statement or the PLAN function. For this reason, computing and returning the query plan on an OPEN is needed only for compatibility with old applications. The QUERY_PLAN_ON_OPEN option controls whether the plan is returned on an OPEN. By default, the setting is OFF.


QUOTE_ALL_IDENTIFIERS option [replication]

Function

Controls whether SQL statements being replicated by SQL Remote should use quoted identifiers.

Allowed values

ON, OFF

Default

OFF

Description

When this option is OFF, dbremote quotes identifiers that require quotes by Adaptive Server Anywhere (as it has always done) and ssremote does not quote any identifiers.

When the option is ON, all identifiers are quoted.


QUOTED_IDENTIFIER option [compatibility]

Function

Controls the interpretation of strings that are enclosed in double quotes.

Allowed values

ON, OFF

Default

ON

OFF for Open Client and JDBC connections

Description

This option controls whether strings that are enclosed in double quotes are interpreted as identifiers (ON) or as literal strings (OFF). The QUOTED_IDENTIFIER option is included for Transact-SQL compatibility.

Note that Interactive SQL automatically executes the equivalent of

SET TEMPORARY OPTION QUOTED_IDENTIFIER = ON

when it connects to a database. TEMPORARY options apply only to the current connection, and last only until the connection is closed.

For more information, see Setting options for Transact-SQL compatibility.


READ_PAST_DELETED option [database]

Function

Controls server behavior on uncommitted deletes at isolation levels 1 and 2.

Allowed values

ON, OFF

Default

ON

Description

If READ_PAST_DELETED is ON (the default), sequential scans at isolation levels 1 and 2 will skip uncommitted deleted rows. If OFF, sequential scans will block on uncommitted deleted rows at isolation levels 1 and 2 (until the deleting transaction commits or rolls back). This option changes server behavior at isolation levels 1 and 2.

For most purposes, this option should be left ON. If set to OFF, the blocking behavior depends on the plan chosen by the optimizer (if there is an index that could possibly be used).


RECOVERY_TIME option [database]

Function

Sets the maximum length of time, in minutes, that the database server will take to recover from system failure.

Allowed values

Integer, in minutes

Scope

Can be set for the PUBLIC group only. DBA authority required. Takes effect when server is restarted.

Default

2

Description

This option is used with the CHECKPOINT_TIME option to decide when checkpoints should be done.

Adaptive Server Anywhere uses a heuristic to estimate the recovery time based on the operations that have been performed since the last checkpoint. Thus, the recovery time is not exact.

For more information, see The automatic recovery process.


REMOTE_IDLE_TIMEOUT option [database]

Function

Controls how many seconds of inactivity web service client procedures and functions will tolerate.

Allowed values

Integer, in seconds

Default

15

Description

This option affects web service client procedures and functions. If more time than the specified number of seconds passes without activity, the procedure or function times out.


Web Links Browse Collapse Expand PDF Previous Next

ASA Database Administration Guide

Database Options

Alphabetical list of options

REPLICATE_ALL option [replication]

Previous Next


REPLICATION_ERROR option [replication]

Function

For SQL Remote, allows you to specify a stored procedure to be called by the Message Agent when a SQL error occurs.

Allowed values

Stored procedure name

Default

No procedure

Description

For SQL Remote, the REPLICATION_ERROR option allows you to specify a stored procedure to be called by the Message Agent when a SQL error occurs. By default no procedure is called.

The procedure must have a single argument of type CHAR, VARCHAR, or LONG VARCHAR. The procedure is called once with the SQL error message and once with the SQL statement that causes the error.

Although the option allows you to track and monitor SQL errors in replication, you must still design them out of your setup; this option is not intended to resolve such errors.


REPLICATION_ERROR_PIECE option [replication]

Function

For SQL Remote, the REPLICATION_ERROR_PIECE option works in conjunction with the REPLICATION_ERROR option to allow you to specify a long varchar stored procedure to be called by the Message Agent when a SQL error occurs.

This is a compatibility feature most useful for databases created with older versions of Adaptive Server Enterprise that do not support LONG VARCHAR.

Allowed values

Stored procedure name

Default

No procedure

Description

If an error occurs and REPLICATION_ERROR is defined then the REPLICATION_ERROR procedure is called with the full error string.

If REPLICATION_ERROR and REPLICATION_ERROR _PIECE are both defined then the error is broken up into VARCHAR pieces. REPLICATION_ERROR is called with the first piece and REPLICATION_ERROR_PIECE is called repeatedly with the remaining pieces.


RETURN_DATE_TIME_AS_STRING option [database]

Function

To control how a date, time, or timestamp value is passed to the client application when queried.

Allowed values

ON, OFF

Scope

Can be set as a temporary option only, for the duration of the current connection.

Default

OFF

Description

This option indicates whether date, time, and timestamp values are returned to applications as a date or time datatype or as a string.

When this option is set to ON, the server converts the date, time, or timestamp value to a string before it is sent to the client in order to preserve the TIMESTAMP_FORMAT, DATE_FORMAT, or TIME_FORMAT option setting.

Sybase Central and Interactive SQL automatically turn the RETURN_DATE_TIME_AS_STRING option ON.

See also

DATE_FORMAT option [compatibility]

TIME_FORMAT option [compatibility]

TIMESTAMP_FORMAT option [compatibility]


RETURN_JAVA_AS_STRING option [database]

Function

To control how a Java object is passed to the client application when queried.

Allowed values

ON, OFF

Scope

Can be set as a temporary option only, for the duration of the current connection.

Default

OFF

Description

The option indicates how a Java object is returned to applications connecting over Open Client or jConnect.

By default, a Java object is returned over TDS as a Sun serialization of the object. The client, or receiver of the object serialization, is responsible for deserializing the object into an instance.

If RETURN_JAVA_AS_STRING is set to ON, the object is first converted to an instance of java.lang.String using the toString() method, and the String object is returned to the client.


RI_TRIGGER_TIME option [compatibility]

Function

Controls the relative timing of referential integrity checks and trigger actions.

Allowed values

BEFORE, AFTER

Scope

Can be set for the PUBLIC group only. DBA authority required.

Default

AFTER

Description

The option can be set to either BEFORE or AFTER. When it's set to AFTER, referential integrity actions are executed after the UPDATE or DELETE.

Only the PUBLIC setting can be used; any other setting is ignored.


ROLLBACK_ON_DEADLOCK [database]

Function

Controls how transactions are treated when a deadlock occurs.

Allowed values

ON, OFF

Scope

Can be set by any user and can be set for the PUBLIC group, as well as individual connections. Takes effect immediately.

Default

ON

Description

When this option is set to ON, a transaction is automatically rolled back if it encounters a deadlock. The rollback happens after the current request completes. If this option is set to OFF, Adaptive Server Anywhere automatically rolls back the statement that encountered the deadlock, and returns an error to that transaction indicating which form of deadlock occurred. Note that rolling back the statement likely will not release any of the locks acquired by the statement.

For more information about deadlocks, see Deadlock.


ROW_COUNTS option [database]

Function

Specifies whether the database will always count the number of rows in a query when it is opened.

Allowed values

ON, OFF

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

OFF

Description

If this option is set to OFF, the row count is usually only an estimate. If this option is set to ON, the row count is always accurate.

Warning
When ROW_COUNTS is set to ON, it may take significantly longer to execute queries. In fact, it will usually cause Adaptive Server Anywhere to execute the query twice, doubling the execution time.

Previous Next


SCALE option [database]

Function

Specifies the minimum number of digits after the decimal point when an arithmetic result is truncated to the maximum PRECISION.

Allowed values

Integer, between 0 and 127 inclusive.

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

6

Description

Multiplication, division, addition, subtraction, and aggregate functions can all have results that exceed the maximum precision.

For an example, see PRECISION option [database].


SORT_COLLATION option [database]

Function

Allows implicit use of the SORTKEY function on ORDER BY expressions.

Allowed values

INTERNAL, collation_name, or collation_id

Default

INTERNAL

Description

When the value of this option is INTERNAL, the ORDER BY clause remains unchanged.

When the value of this option is set to a valid collation name or collation ID, any string expression in the ORDER BY clause is treated as if the SORTKEY function had been invoked.

See also

SORTKEY function [String]

Example

Set the sort collation to binary:

set temporary option sort_collation='binary'

Having the sort collation set to binary transforms

SELECT name, id
FROM product
ORDER BY name, id

and

SELECT name, id
FROM product
ORDER BY 1, 2

into

SELECT name, id
FROM product
ORDER BY SORTKEY(name, 'binary'), id


SQL_FLAGGER_ERROR_LEVEL option [compatibility]

Function

Controls the response to any SQL that is not part of a specified set of SQL/92.

Allowed values

E, I, F, W

Default

W

Description

This option flags any SQL that is not part of a specified set of SQL/92 as an error.

The allowed values are as follows:

  • E Flag syntax that is not entry-level SQL/92 syntax

  • I Flag syntax that is not intermediate-level SQL/92 syntax

  • F Flag syntax that is not full-SQL/92 syntax

  • W Allow all supported syntax


SQL_FLAGGER_WARNING_LEVEL option [compatibility]

Function

Controls the response to any SQL that is not part of a specified set of SQL/92.

Allowed values

E, I, F, W

Default

W

Description

This option flags any SQL that is not part of a specified set of SQL/92 as a warning.

The allowed values are as follows:

  • E Flag syntax that is not entry-level SQL/92 syntax

  • I Flag syntax that is not intermediate-level SQL/92 syntax

  • F Flag syntax that is not full-SQL/92 syntax

  • W Allow all supported syntax


STATISTICS option [Interactive SQL]

Function

Controls whether the execution time is enabled.

Allowed values

Any non-negative integer

Default

7

Description

This option is an older version of the ISQL_PLAN option, and is used only by dbisqlc.

When you set the STATISTICS option to 0, no information appears in the Messages pane after you execute a SQL statement. When you set the option to any other number, the execution time appears in the Messages pane after you execute a statement. The number you specify also becomes the default height (in lines) of the Messages pane.

See also

ISQL_COMMAND_TIMING option [Interactive SQL]

ISQL_PLAN option [Interactive SQL]


STRING_RTRUNCATION option [compatibility]

Function

Determines whether an error is raised when an INSERT or UPDATE truncates a CHAR or VARCHAR string.

Allowed values

ON, OFF

Default

OFF

Description

If the truncated characters consist only of spaces, no exception is raised. The setting of ON corresponds to ANSI/ISO SQL/92 behavior. When it is set to OFF, the exception is not raised and the character string is silently truncated.


SUBSCRIBE_BY_REMOTE option [replication]

Function

Controls interpretation of NULL or empty-string SUBSCRIBE BY values.

Allowed values

ON, OFF

Default

ON

Description

When the option is set to ON, operations from remote databases on rows with a SUBSCRIBE BY value that is NULL or an empty string assume that the remote user is subscribed to the row. When it is set to OFF, the remote user is assumed not to be subscribed to the row.


SUBSUME_ROW_LOCKS option [database]

Function

Controls when the server acquires individual row locks for a table.

Allowed values

ON, OFF

Default

ON

Description

If the SUBSUME_ROW_LOCKS option is ON (the default) then whenever a table t is locked exclusively with LOCK TABLE t IN EXCLUSIVE MODE, the server will no longer acquire individual row locks for t.

This can result in a significant performance improvement if extensive updates are made to t in a single transaction, especially if t is large relative to cache size. It also allows for atomic update operations that are larger than the lock table can currently handle (> ~2-4m rows).

When this option is ON, keyset cursors over a table locked in this fashion will return row changed warnings for every row in the cursor, if any row in the database has been modified. Note that the server could turn an updateable cursor with an ORDER BY into a keyset cursor as a result.


SUPPRESS_TDS_DEBUGGING option [database]

Function

Determines whether TDS debugging information appears in the server window.

Allowed values

ON, OFF

Default

OFF

Description

When the server is started with the -z option, debugging information appears in the server window, including debugging information about the TDS protocol.

The SUPPRESS_TDS_DEBUGGING option restricts the debugging information about TDS that appears in the server window. When this option is set to OFF (the default) TDS debugging information appears in the server window.


TDS_EMPTY_STRING_IS_NULL option [database]

Function

Controls whether empty strings are returned as NULL or a string containing one blank character for TDS connections.

Allowed values

ON, OFF

Default

OFF

Description

By default, this option is set to OFF and empty strings are returned as a string containing one blank character for TDS connections. When this option is set to ON, empty strings are returned as NULL strings for TDS connections. Non-TDS connections distinguish empty strings from NULL strings.


TEMP_SPACE_LIMIT_CHECK option [database]

Function

Checks the amount of temporary file space used by a connection and fails the request if the amount of space requested is greater than the connection's allowable quota.

Allowed values

ON, OFF

Scope

Can be set for the PUBLIC group only. DBA authority required.

Default

OFF

Description

When TEMP_SPACE_LIMIT_CHECK is set to OFF (the default), the database server does not check the amount of temporary file space used by a connection. If a connection requests more than its quota of temporary space when this option is set to off, a fatal error can occur. When this option is set to ON, if a connection requests more than its quota of temporary file space, then the request fails and the error SQLSTATE_TEMP_SPACE_LIMIT is returned.

Two factors are used to determine the temporary file quota for a connection: the maximum size of the temporary file and the number of active database connections. The maximum size of the temporary file is the sum of the file's current size and the amount of disk space available on the partition containing the file. When limit checking is turned on, a connection is checked for exceeding its quota when the temporary file has grown to 80% or more of its maximum size and the connection requests more temporary file space. Once this happens, any connection fails that uses more than the maximum temporary file space divided by the number of active connections.

You can obtain information about the space available for the temporary file using the sa_disk_free_space system procedure.

See also

sa_disk_free_space system procedure


TIME_FORMAT option [compatibility]

Function

Sets the format for times retrieved from the database.

Allowed values

String, composed of the symbols listed below.

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

HH:NN:SS.SSS

Description

The format is a string using the following symbols:

  • hh Two digit hours (24 hour clock)

  • nn Two digit minutes

  • mm Two digit minutes if following a colon (as in hh:mm)

  • ss[.s...] Two digit seconds plus optional fraction

Each symbol is substituted with the appropriate data for the time that is being formatted. Any format symbol that represents character rather than digit output can be put in upper case, which causes the substituted characters to also be in upper case. For numbers, using mixed case in the format string suppresses leading zeros.


TIME_ZONE_ADJUSTMENT option [database]

Function

Allows a connection's time zone adjustment to be modified.

Allowed values

Integer, (for example, 300), Negative integer, enclosed in quotation marks (for example, '-300'), String, representing a time in hours and minutes, preceded by + or -, enclosed in quotation marks (for example, '+5:00', or '-5:00').

Default

If the client is connecting via embedded SQL, ODBC, OLE DB, or ADO, the default value is set according to the client's time zone. If the client is connecting via jConnect or Open Client, the default is based on the server's time zone.

Description

The TIME_ZONE_ADJUSTMENT option value is the same value as that returned by connection_property('TimeZoneAdjustment'). The value represents the number of minutes that must be added to the Coordinated Universal Time (UTC) to display time local to the connection.

See also

Connection-level properties


TIMESTAMP_FORMAT option [compatibility]

Function

Sets the format for timestamps that are retrieved from the database.

Allowed values

String, composed of the symbols listed below.

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

YYYY-MM-DD HH:NN:ss.SSS

For Open Client and JDBC connections the default is set to YYYY-MM-DD HH:NN:SS.SSS.

Description

The format is a string using the following symbols:

Symbol | Description
yy | Two digit year
yyyy | Four digit year
mm | Two digit month, or two digit minutes if following a colon (as in 'hh:mm')
mmm[m...] | Character short form for months—as many characters as there are "m"s
dd | Two digit day of month
ddd[d...] | Character short form for day of the week
hh | Two digit hours
nn | Two digit minutes
ss.ssssss | Seconds and fractions of a second, up to six decimal places. Not all platforms support timestamps to a precision of six places.
aa | am or pm (12 hour clock)
pp | pm if needed (12 hour clock)
f | Use French days and months (deprecated)

Each symbol is substituted with the appropriate data for the date that is being formatted.

For symbols that represent character data (such as mmm), you can control the case of the output as follows:

  • Type the symbol in all upper case to have the format appear in all upper case. For example, MMM produces JAN.

  • Type the symbol in all lower case to have the format appear in all lower case. For example, mmm produces jan.

  • Type the symbol in mixed case to have Adaptive Server Anywhere choose the appropriate case for the language that is being used. For example, in English, typing Mmm produces May, while in French it produces mai.

For symbols that represent numeric data, you can control zero-padding with the case of the symbols:

  • Type the symbol in same-case (such as MM or mm) to allow zero padding. For example, yyyy/mm/dd could produce 2002/01/01.

  • Type the symbol in mixed case (such as Mm) to suppress zero padding. For example, yyyy/Mm/Dd could produce 2002/1/1.


TRUNCATE_DATE_VALUES option [database] (deprecated)

Function

To change the storage of time values within DATE data type values.

Allowed values

ON, OFF

Scope

Can be set for the PUBLIC group only. DBA authority required.

Default

ON for databases created with Version 7 or later software, or upgraded to Version 7 or later.

OFF for older databases

Description
Note
This option is deprecated.

When the option is set to ON, columns or variables declared as DATE data types have no hours or minutes stored.

When the option is set to OFF, DATE columns or variables also have hours and minutes stored. These time components are typically not displayed because of the DATE_FORMAT setting. However, exact comparisons between DATE values may unexpectedly fail because of non-matching time components.

See also

DATE_FORMAT option [compatibility]

DATE data type [Date and Time]


TRUNCATE_TIMESTAMP_VALUES option [database]

Function

Limits the resolution of timestamp values.

Allowed values

ON, OFF

Scope

Can be set for the PUBLIC group only. DBA authority required. This option should not be enabled for databases already containing timestamp data.

Default

OFF

Description

A TIMESTAMP value is precise to six decimal places in Adaptive Server Anywhere. However, to maintain compatibility with other software, which may truncate the TIMESTAMP value to three decimal places, you can set the TRUNCATE_TIMESTAMP_VALUES option to ON to limit the number of decimal places Adaptive Server Anywhere stores. The DEFAULT_TIMESTAMP_INCREMENT option determines the number of decimal places to which the TIMESTAMP value is truncated.

For MobiLink synchronization, this option must be set prior to performing the first synchronization.

If the database server finds TIMESTAMP values with a higher resolution than that specified by the combination of TRUNCATE_TIMESTAMP_VALUES and DEFAULT_TIMESTAMP_INCREMENT, an error is reported.

In most cases, unloading the database and then reloading it into a new database in which the TRUNCATE_TIMESTAMP_VALUES and DEFAULT_TIMESTAMP_INCREMENT values have been set is the easiest solution to ensure the proper TIMESTAMP values are used. However, depending on the type of TIMESTAMP columns in your table, you can also do the following:

  • If the TIMESTAMP columns are defined with DEFAULT TIMESTAMP or DEFAULT UTC TIMESTAMP (so that the value is automatically updated by the server when the row is modified), you must delete all the rows in the table before the TRUNCATE_TIMESTAMP_VALUES option is changed. You can delete the rows using the DELETE or TRUNCATE TABLE statement.

  • If the TIMESTAMP column is defined with a value other than DEFAULT TIMESTAMP or DEFAULT UTC TIMESTAMP, you can execute an UPDATE statement that casts the values to a string and then back to a TIMESTAMP. For example,

    UPDATE T
   SET ts = CAST( DATEFORMAT( ts, 'yyyy/mm/dd hh:nn:ss.ss')
 AS TIMESTAMP)

    Note that this process may lose more precision than is necessary. The format string to use depends on the number of digits of precision to be kept.

Example

Setting the DEFAULT_TIMESTAMP_INCREMENT option to 100 000 causes truncation after the first decimal place in the seconds component, allowing a value such as '2000/12/05 10:50:53:700' to be stored.


TRUNCATE_WITH_AUTO_COMMIT option [database]

Function

To speed up TRUNCATE TABLE statements.

Allowed values

ON, OFF

Scope

Can be set for the PUBLIC group only. DBA authority required.

Default

ON

Description

If TRUNCATE_WITH_AUTO_COMMIT is set to ON, then a COMMIT is executed both before and after the TRUNCATE TABLE statement is executed. The primary purpose of the option is to enable faster table truncation (delete of all rows).

There are some cases where a fast TRUNCATE cannot be done:

  • If there are foreign keys either to or from the table

  • If the TRUNCATE TABLE statement is executed within a trigger

  • If the TRUNCATE TABLE statement is executed within an atomic statement

See also

TRUNCATE TABLE statement


TRUNCATION_LENGTH option [Interactive SQL]

Function

Controls the truncation of wide columns for displays to fit on a screen.

Allowed values

Integer

Default

256

Description

The TRUNCATION_LENGTH option limits the length of displayed column values. The unit is in characters. A value of 0 means that column values are not truncated. The default truncation length is 256.


TSQL_HEX_CONSTANT option [compatibility]

Function

Controls whether hexadecimal constants are treated as binary typed constants.

Allowed values

ON, OFF

Default

ON

Description

When this option is set to ON, hexadecimal constants are treated as binary typed constants. To get the historical behavior, set the option to OFF.


TSQL_VARIABLES option [compatibility]

Function

Controls whether the @ sign can be used as a prefix for embedded SQL host variable names.

Allowed values

ON, OFF

Default

OFF

ON for Open Client and JDBC connections

Description

When this option is set to ON, you can use the @ sign instead of the colon as a prefix for host variable names in embedded SQL. This is implemented primarily for Transact-SQL compatibility.


UPDATE_STATISTICS option [database]

Function

Controls the gathering of statistics during query execution

Allowed values

ON, OFF

Default

ON

Description

The server collects statistics during normal query execution and uses the gathered statistics to self-tune the column histograms. You can set the UPDATE_STATISTICS option OFF to disable the gathering of statistics during query execution.

The UPDATE_STATISTICS option does not affect changes to statistics as a result of updates to data (LOAD/INSERT/UPDATE/DELETE).

Under normal circumstances, it should not be necessary to turn this option off.


USER_ESTIMATES option [database]

Function

Controls whether or not user selectivity estimates in query predicates are respected or ignored by the query optimizer.

Allowed values

ENABLED, DISABLED, OVERRIDE-MAGIC

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

OVERRIDE-MAGIC

Description

Adaptive Server Anywhere allows you to specify user selectivity estimates can improve the optimizer's performance when the server is unable to accurately predict the selectivity of a predicate. However, user selectivity estimates should be used only in appropriate circumstances. For example, it may be useful to supply a selectivity estimate for a predicate that involves one or more functions if the OVERRIDE-MAGIC selectivity estimate used by the optimizer is significantly different from the actual selectivity.

If you have used selectivity estimates that are inaccurate as a workaround to performance problems where the software-selected access plan was poor, it is recommended that you set this option to DISABLED. The server may not select an optimal plan if you use inaccurate estimates.

For more information about user selectivity estimates, see Explicit selectivity estimates.

When a user selectivity estimate is supplied with a predicate, the estimate is respected or ignored based on the setting of this option. The following values are accepted:

  • ENABLED All user-supplied selectivity estimates are respected. You can also use ON to turn on this option.

  • OVERRIDE-MAGIC A user selectivity estimate is respected and used only if the optimizer would otherwise choose to use its last-resort, heuristic value (also called the magic value).

  • DISABLED All user estimates are ignored and magic values are used when no other estimate data is available. You can also use OFF to turn off this option.


VERIFY_ALL_COLUMNS option [replication]

Function

Controls whether messages that contain updates published by the local database are sent with all column values included.

Allowed values

ON, OFF

Default

OFF

Description

This option is used by SQL Remote only. When it is set to ON, messages that contain updates published by the local database are sent with all column values included, and a conflict in any column triggers a RESOLVE UPDATE trigger at the subscriber database.


VERIFY_THRESHOLD option [replication]

Function

Controls which columns are verified when updates are replicated.

Allowed values

Integer, in bytes

Default

1 000

Description

This option is used by SQL Remote only. If the data type of a column is longer than the threshold, old values for the column are not verified when an UPDATE is replicated. This keeps the size of SQL Remote messages down, but has the disadvantage that conflicting updates of long values are not detected.


WAIT_FOR_COMMIT option [database]

Function

Determines when foreign key integrity is checked, as data is manipulated.

Allowed values

ON,+ OFF

Scope

Can be set for an individual connection or for the PUBLIC group. Takes effect immediately.

Default

OFF

Description

If this option is set to ON, the database does not check foreign key integrity until the next COMMIT statement. Otherwise, all foreign keys that are not created with the CHECK_ON_COMMIT option are checked as they are inserted, updated or deleted.


WEBSERVICE_NAMESPACE_HOST option [database]

Function

Specifies the hostname to be used as the XML namespace within generated WSDL documents. Requires DBA authority.

Allowed values

hostname-string or NULL

Scope

Can be set for the PUBLIC group only. Takes effect immediately. DBA authority is required to set this option.

Default

NULL

Description

Webservices Description Language Documents (WSDLs) are exported by DISH services. These are XML documents that contain descriptions of the available SOAP services. The URL of the targetNameSpace and the soapAction operations within this XML document contain a hostname. When this option is set to NULL, the default value, the hostname is that of the computer on which the database server is running. If this option is set to a string value, the string is used as the hostname instead. This option is intended for use when developing Web Service client applications that will, when deployed, target a host other than the one used for development.


Database Performance and Connection Properties

About this chapter

This chapter contains information and tables relating to database performance monitoring and database connection parameters.


Database performance statistics

Adaptive Server Anywhere provides a set of statistics that can be used to monitor database performance. These are accessible from Sybase Central, and client applications can access the statistics as functions. In addition, these statistics are made available by the server to the Windows Performance Monitor.

Note
The Windows Performance Monitor is available in Windows NT/2000/XP.

This section describes how to access performance and related statistics from client applications, how to monitor database performance using Sybase Central, and how to monitor database performance using the Windows Performance Monitor.

Performance Monitor statistics


Performance Monitor statistics

The Windows Performance Monitor is an application for viewing the behavior of objects such as processors, memory, and applications. Adaptive Server Anywhere provides many statistics for the Performance Monitor to display.

For information on how to use the Performance Monitor, see Monitoring database statistics from Windows Performance Monitor.

Adaptive Server Anywhere makes statistics available for the Performance Monitor. Rates are reported per second. The statistics are grouped into the following areas:

  • Cache statistics

  • Checkpoint and recovery statistics

  • Communications statistics

  • Disk I/O statistics

  • Disk read statistics

  • Disk write statistics

  • Index statistics

  • Java VM statistics

  • Memory pages statistics

  • Request statistics

  • Miscellaneous statistics

Cache statistics

These statistics describe the use of the cache.

Statistic | Scope | Description
Cache Hits/sec | Connection and Database | The rate at which database page lookups are satisfied by finding the page in the cache.
Cache Reads: Index Interior/sec | Connection and Database | The rate at which index internal-node pages are read from the cache.
Cache Reads: Index Leaf/sec | Connection and Database | The rate at which index leaf pages are read from the cache.
Cache Reads: Table/sec | Connection and Database | The rate at which table pages are read from the cache.
Cache Reads: Total Pages/sec | Connection and Database | The rate at which database pages are looked up in the cache.
Cache Size: Current | Server | The current size of the database server cache, in kilobytes.
Cache Size: Maximum | Server | The maximum allowed size of the database server cache, in kilobytes.
Cache Size: Minimum | Server | The minimum allowed size of the database server cache, in kilobytes.
Cache Size: Peak | Server | The peak size of the database server cache, in kilobytes.
Checkpoint and recovery statistics

These statistics isolate the checkpoint and recovery actions performed when the database is in an idle state.

Statistic | Scope | Description
Checkpoint Flushes/sec | Database | The rate at which ranges of adjacent pages are written out during a checkpoint.
Checkpoint Log | Database | The rate at which the transaction log is checkpointed.
Checkpoint Urgency | Database | Checkpoint Urgency, expressed as a percentage.
Checkpoints/sec | Database | The rate at which checkpoints are performed.
Idle Actives/sec | Database | The rate at which the server's idle thread becomes active to do idle writes, idle checkpoints, etc.
Idle Checkpoint Time | Database | The total time spent doing idle checkpoints, in seconds.
Idle Checkpoints/sec | Database | The rate at which checkpoints are completed by the server's idle thread. An idle checkpoint occurs whenever the idle thread writes out the last dirty page in the cache.
Idle Writes/sec | Database | The rate at which disk writes are issued by the server's idle thread.
Recovery I/O Estimate | Database | The estimated number of I/O operations required to recover the database.
Recovery Urgency | Database | Recovery Urgency expressed as a percentage.
Communications statistics

These statistics describe client/server communications activity.

Statistic | Scope | Description
Comm: Buffer Misses | Server | The total number of network buffer allocations exceeding the connection buffer pool.
Comm: Bytes Received/sec | Connection and Server | The rate at which network data (in bytes) are received.
Comm: Bytes Received Uncompressed/sec | Connection and Server | The rate at which bytes would have been received if compression was disabled.
Comm: Bytes Sent/sec | Connection and Server | The rate at which bytes are transmitted over the network.
Comm: Bytes Sent Uncompressed/sec | Connection and Server | The rate at which bytes would have been sent if compression was disabled.
Comm: Free Buffers | Server | Number of free network buffers.
Comm: Licenses in Use | Server | The number of unique client network addresses connected.
Comm: Multi-packets Received/sec | Server | The rate at which multi-packet deliveries are received.
Comm: Multi-packets Sent/sec | Server | The rate at which multi-packet deliveries are transmitted.
Comm: Packets Received/sec | Connection and Server | The rate at which network packets are received.
Comm: Packets Received Uncompressed/sec | Connection and Server | The rate at which network packets would have been received if compression was disabled.
Comm: Packets Sent/sec | Connection and Server | The rate at which network packets are transmitted.
Comm: Packets Sent Uncompressed/sec | Connection and Server | The rate at which network packets would have been transmitted if compression was disabled.
Comm: Send Fails/sec | Server | The rate at which the underlying protocol(s) failed to send a packet.
Comm: TotalBuffers | Server | The total number of network buffers.
Disk I/O statistics

These statistics combine disk reads and disk writes to give overall information about the amount of activity devoted to disk I/O.

Statistic | Scope | Description
Disk: Active I/O | Database | The current number of file I/Os issued by the server which have not yet completed.
Disk: Maximum I/O | Database | The maximum value "Disk Reads: Active I/O" has reached.
Disk read statistics

These statistics describe the amount and type of activity devoted to reading information from disk.

Statistic | Scope | Description
Disk Reads: Total Pages/sec | Connection and Database | The rate at which pages are read from a file.
Disk Reads: Active | Database | The current number of file reads issued by the server which have not yet completed.
Disk Reads: Index interior/sec | Connection and Database | The rate at which index internal-node pages are being read from disk.
Disk Reads: Index leaf/sec | Connection and Database | The rate at which index leaf pages are being read from disk.
Disk Reads: Table/sec | Connection and Database | The rate at which table pages are being read from disk.
Disk Reads: Maximum Active | Database | The maximum value "Disk Reads: Active" has reached.
Disk write statistics

These statistics describe the amount and type of activity devoted to writing information to disk.

Statistic | Scope | Description
Disk Writes: Active | Database | The current number of file writes issued by the server which are not yet completed.
Disk Writes: Maximum Active | Database | The maximum value "Disk Writes: Active" has reached.
Disk Writes: Commit Files/sec | Database | The rate at which the server forces a flush of the disk cache. Windows NT/2000/XP and NetWare platforms use unbuffered (direct) I/O, so the disk cache does not need to be flushed.
Disk Writes: Database Extends/sec | Database | The rate at which the database file is extended, in pages/sec.
Disk Writes: Temp Extends/sec | Database | The rate at which temporary files are extended, in pages/sec.
Disk Writes: Pages/sec | Connection and Database | The rate at which modified pages are being written to disk.
Disk Writes: Transaction Log/sec | Connection and Database | The rate at which pages are written to the transaction log.
Disk Writes: Transaction Log Group Commits | Connection and Database | Occurs when a commit of the transaction log is requested but the log has already been written (so the commit was done for "free").
Index statistics

These statistics describe the use of the index.

Statistic | Scope | Description
Index: Adds/sec | Connection and Database | The rate at which entries are added to indexes.
Index: Lookups/sec | Connection and Database | The rate at which entries are looked up in indexes.
Index: Full Compares/sec | Connection and Database | The rate at which comparisons beyond the hash value in an index must be performed.
Java VM statistics

These statistics describe the memory used by the Java VM.

Statistic | Scope | Description
JVM: Global Fixed Size | Server | The total bytes allocated to the Java VM fixed heap.
JVM: Heap Size | Connection and Database | The total bytes allocated to connection Java VMs.
JVM: Namespace Size | Database | The total number of bytes allocated to the Java VM namespace.
Memory pages statistics

These statistics describe the amount and purpose of memory used by the database server.

Statistic | Scope | Description
Mem Pages: Locked Heap | Server | The number of heap pages locked in the cache.
Mem Pages: Lock Table | Database | The number of pages used to store lock information.
Mem Pages: Rollback Log | Connection and Database | The number of pages in the rollback log.
Mem Pages: Main Heap | Server | The number of pages used for global server data structures.
Mem Pages: Map Pages | Database | The number of map pages used for accessing the lock table, frequency table, and table layout.
Mem Pages: Procedure Definitions | Database | The number of relocatable heap pages used for procedures.
Mem Pages: Relocatable | Database | The number of pages used for relocatable heaps (cursors, statements, procedures, triggers, views, etc.).
Mem Pages: Relocations/sec | Database | The rate at which relocatable heap pages are read from the temporary file.
Mem Pages: Trigger Definitions | Database | The number of relocatable heap pages used for triggers.
Mem Pages: View Definitions | Database | The number of relocatable heap pages used for views.
Request statistics

These statistics describe the database server activity devoted to responding to requests from client applications.

Statistic | Scope | Description
Requests | Server | The rate at which the server is entered to allow it to handle a new request or continue processing an existing request.
Requests: Active | Server | The number of server threads currently handling a request.
Requests: Unscheduled | Server | The number of requests that are currently queued up waiting for an available server thread.
Cursors | Connection | The number of declared cursors currently maintained by the server.
Cursors Open | Connection | The number of open cursors currently maintained by the server.
Statements | Connection | The number of prepared statements currently maintained by the server.
Statement Prepares | Connection | The rate at which statement prepares are being handled by the server.
Transaction Commits | Connection | The rate at which Commit requests are handled.
Transaction Rollbacks | Connection | The rate at which Rollback requests are handled.
Miscellaneous statistics
Statistic | Scope | Description
Avail IO | Server | Expressed as a count.
Connection Count | Database | The number of connections to this database.
Main Heap Bytes | Server | The number of bytes used for global server data structures.
Query Low Memory Strategy | Connection and Database | The number of times the server changed its execution plan during execution because of low memory conditions.
Temporary Table Pages | Connection and Database | The number of pages in the temporary file used for temporary tables.


Database properties

Adaptive Server Anywhere provides a set of properties that are made available to client applications. These properties describe aspects of connection, database, and database server behavior.

Accessing properties

Each type of property can be accessed by supplying its name as an argument to a system function.

toggle To access connection properties

  • Use the connection_property system function: the following statement returns the number of pages that have been read from file by the current connection.

    SELECT connection_property ( 'DiskRead' )
toggle To access database properties

  • Use the db_property system function. For example, the following statement returns the page size of the current database:

    SELECT db_property ( 'PageSize' )
toggle To access database server properties

  • Use the property system function: the following statement returns the number of pages that have been read from file by the current connection.

    SELECT property ( 'MainHeapPages' )


Connection-level properties

The following table lists properties available for each connection.

Examples
toggle To retrieve the value of a connection property

  • Use the connection_property system function. The following statement returns the number of pages that have been read from file by the current connection.

    SELECT connection_property ( 'DiskRead' )
toggle To retrieve the values of all connection properties

  • Use the sa_conn_properties system procedure:

    CALL sa_conn_properties

    A separate row appears for each connection.

Descriptions
Property | Description
Allow_nulls_by_default | ALLOW_NULLS_BY_DEFAULT option [compatibility]
Ansi_blanks | ANSI_BLANKS option [compatibility]
Ansi_close_cursors_on_rollback | ANSI_CLOSE_CURSORS_ON_ROLLBACK option [compatibility]
Ansi_integer_overflow | ANSI_INTEGER_OVERFLOW option [compatibility]
Ansi_permissions | ANSI_PERMISSIONS option [compatibility]
Ansi_update_constraints | ANSI_UPDATE_CONSTRAINTS option [compatibility]
Ansinull | ANSINULL option [compatibility]
AppInfo | Returns information about the client that made the connection. For HTTP connections, this includes information about the browser. For connections using older versions of jConnect or Open Client, the information may be incomplete. The API value can be DBLIB, ODBC, OLEDB, or ADO.NET. For more information about the values returned for other types of connections, see AppInfo connection parameter [APP].
Auditing | AUDITING option [database]
AuditingTypes | The types of auditing currently enabled. AUDITING option [database]
Automatic_timestamp | AUTOMATIC_TIMESTAMP option [compatibility]
Background_priority | BACKGROUND_PRIORITY option [database]
BlockedOn | If the current connection is not blocked, this is zero. If it is blocked, the connection number on which the connection is blocked due to a locking conflict.
Blocking | BLOCKING option [database]
Blocking_timeout | BLOCKING_TIMEOUT option [database]
BytesReceived | The number of bytes received during client/server communications.
BytesReceivedUncomp | The number of bytes that would have been received during client/server communications if compression was disabled. (This value is the same as the value for BytesReceived if compression is disabled.)
BytesSent | The number of bytes sent during client/server communications.
BytesSentUncomp | The number of bytes that would have been sent during client/server communications if compression was disabled. (This value is the same as the value for BytesSent if compression is disabled.)
CacheHits | The number of successful reads of the cache.
CacheRead | The number of database pages that have been looked up in the cache.
CacheReadIndInt | The number of index internal-node pages that have been read from the cache.
CacheReadIndLeaf | The number of index leaf pages that have been read from the cache.
CacheReadTable | The number of table pages that have been read from the cache.
Chained | CHAINED option [compatibility]
CharSet | The character set used by the connection.
Checkpoint_time | CHECKPOINT_TIME option [database]
Cis_option | CIS_OPTION option [database]
Cis_rowset_size | Reserved
ClientLibrary | ReturnsjConnect for jConnect connections; CT_Library for Open Client connections; None for HTTP connections, and CmdSeq for ODBC, embedded SQL, OLE DB, ADO.NET, and iAnywhere JDBC driver connections.
ClientPort | Returns the client's TCP/IP port number or 0 if the connection is not a TCP/IP connection.
Close_on_EndTrans | CLOSE_ON_ENDTRANS option [compatibility]
Commit | The number of Commit requests that have been handled.
CommLink | The communication link for the connection. This is one of the network protocols supported by Adaptive Server Anywhere, or local for a same-machine connection.
CommNetworkLink | The communication link for the connection. This is one of the network protocols supported by Adaptive Server Anywhere. Values can include SharedMemory, TCPIP, SPX, or NamedPipes. The CommLinkNetwork property always returns the name of the link, regardless of whether it is same-machine or not.
CommProtocol | Returns TDS for Open Client and jConnect connections, HTTP for HTTP connections, and CmdSeq for OLE DB, ADO.NET and iAnywhere JDBC driver connections.
Compression | Returns ON or OFF to indicate whether communication compression is enabled on the connection.
Connection_authentication | A string used to authenticate the client. Authentication is required before the database can be modified.
Conversion_error | CONVERSION_ERROR option [compatibility]
Cooperative_commit_timeout | COOPERATIVE_COMMIT_TIMEOUT option [database]
Cooperative_commits | COOPERATIVE_COMMITS option [database]
Cursor | The number of declared cursors that are currently being maintained by the server.
CursorOpen | The number of open cursors that are currently being maintained by the server.
Database_authentication | A string used to authenticate the database. Authentication is required before the database can be modified.
Date_format | DATE_FORMAT option [compatibility]
Date_order | DATE_ORDER option [compatibility]
DBNumber | The ID number of the database.
Debug_messages | DEBUG_MESSAGES option [database]
Dedicated_task | DEDICATED_TASK option [database]
Default_timestamp_increment | DEFAULT_TIMESTAMP_INCREMENT option [database]
Delayed_commit_timeout | DELAYED_COMMIT_TIMEOUT option [database]
Delayed_commits | DELAYED_COMMITS option [database]
DiskRead | The number of pages that have been read from disk.
DiskReadIndInt | The number of index internal-node pages that have been read from disk.
DiskReadIndLeaf | The number of index leaf pages that have been read from disk.
DiskReadTable | The number of table pages that have been read from disk.
DiskWrite | The number of modified pages that have been written to disk.
Divide_by_zero_error | DIVIDE_BY_ZERO_ERROR option [compatibility]
Encryption | Encryption connection parameter [ENC]
Escape_character | ESCAPE_CHARACTER option [compatibility]
EventName | The name of the associated event if the connection is running an event handler. Otherwise, the result is NULL.
Exclude_operators | EXCLUDE_OPERATORS option [database]
Extended_join_syntax | EXTENDED_JOIN_SYNTAX option [database]
Fire_triggers | FIRE_TRIGGERS option [compatibility]
First_day_of_week | FIRST_DAY_OF_WEEK option [database]
Float_as_double | FLOAT_AS_DOUBLE option [compatibility]
For_xml_null_treatment | FOR_XML_NULL_TREATMENT option [database]
Force_view_creation | FORCE_VIEW_CREATION option [database]
FullCompare | The number of comparisons that have been performed beyond the hash value in an index.
Global_database_id | GLOBAL_DATABASE_ID option [database]
IdleTimeout | The idle timeout value of the connection. For more information, see Idle connection parameter [IDLE].
IndAdd | The number of entries that have been added to indexes.
IndLookup | The number of entries that have been looked up in indexes.
Integrated_server_name | INTEGRATED_SERVER_NAME option [database]
Isolation_level | ISOLATION_LEVEL option [compatibility]
Java_heap_size | JAVA_HEAP_SIZE option [database]
Java_input_output | JAVA_INPUT_OUTPUT option [database]
Java_namespace_size | JAVA_NAMESPACE_SIZE option [database]
Java_page_buffer_size | The page buffer size used by the Java VM.
JavaHeapSize | The heap size per Java VM.
Language | The locale language.
LastIdle | The number of ticks between requests.
LastReqTime | The time at which the last request for the specified connection started.
LastStatement | The most recently prepared SQL statement for the current connection. For more information, see -zl server option.
LivenessTimeout | The liveness timeout period for the current connection. For more information, see LivenessTimeout connection parameter [LTO].
Lock_rejected_rows | Reserved
LockName | A 64-bit unsigned integer value representing the lock for which a connection is waiting.
Log_deadlocks | LOG_DEADLOCKS option [database]
LogFreeCommit | The number of Redo Free Commits. A Redo Free Commit occurs when a commit of the transaction log is requested but the log has already been written (so the commit was done for free.)
Login_mode | LOGIN_MODE option [database]
Login_procedure | LOGIN_PROCEDURE option [database]
LoginTime | The date and time the connection was established.
LogWrite | The number of pages that have been written to the transaction log.
Max_cursor_count | MAX_CURSOR_COUNT option [database]
Max_plans_cached | MAX_PLANS_CACHED option [database]
Max_recursive_iterations | MAX_RECURSIVE_ITERATIONS option [database]
Max_statement_count | MAX_STATEMENT_COUNT option [database]
MessageReceived | The string that was generated by the MESSAGE statement that caused the WAITFOR statement to be interrupted. Otherwise, an empty string is returned.
Min_password_length | MIN_PASSWORD_LENGTH option [database]
Name | The name of the current connection.
Nearest_century | NEAREST_CENTURY option [compatibility]
NodeAddress | The node for the client in a client/server connection. When the client and server are both on the same machine, an empty string is returned.
Non_keywords | NON_KEYWORDS option [compatibility]
Number | The ID number of the connection.
ODBC_describe_binary_as_varbinary | ODBC_DESCRIBE_BINARY_AS_VARBINARY [database]
ODBC_distinguish_char_and_varchar | ODBC_DISTINGUISH_CHAR_AND_VARCHAR option [database]
On_charset_conversion_failure | ON_CHARSET_CONVERSION_FAILURE option [database]
On_tsql_error | ON_TSQL_ERROR option [compatibility]
Optimistic_wait_for_commit | OPTIMISTIC_WAIT_FOR_COMMIT option [compatibility]
Optimization_goal | OPTIMIZATION_GOAL option [database]
Optimization_level | Reserved
Optimization_workload | OPTIMIZATION_WORKLOAD option [database]
PacketSize | The packet size used by the connection, in bytes.
PacketsReceived | The number of client/server communication packets received.
PacketsReceivedUncomp | The number of packets that would have been received during client/server communications if compression was disabled. (This value is the same as the value for PacketsReceived if compression is disabled.)
PacketsSent | The number of client/server communication packets sent.
PacketsSentUncomp | The number of packets that would have been sent during client/server communications if compression was disabled. (This value is the same as the value for PacketsSent if compression is disabled.)
Percent_as_comment | PERCENT_AS_COMMENT option [compatibility]
Pinned_cursor_percent_of_cache | PINNED_CURSOR_PERCENT_OF_CACHE option [database]
Precision | PRECISION option [database]
Prefetch | PREFETCH option [database]
Prepares | The number of statement preparations carried out.
PrepStmt | The number of prepared statements currently being maintained by the server.
Preserve_source_format | PRESERVE_SOURCE_FORMAT option [database]
Prevent_article_pkey_update | PREVENT_ARTICLE_PKEY_UPDATE option [database]
Query_plan_on_open | QUERY_PLAN_ON_OPEN option [compatibility]
QueryBypassed | The number of requests optimized by the optimizer bypass.
QueryCachedPlans | The number of query execution plans currently cached for the connection.
QueryCachePages | The number of pages used to cache execution plans.
QueryLowMemoryStrategy | The number of times the server changed its execution plan during execution as a result of low memory conditions. The strategy can change because less memory is available than the optimizer estimated, or because the execution plan required more memory than the optimizer estimated.
QueryOptimized | The number of requests that have been fully optimized.
QueryReused | The number of requests that have been reused from the plan cache.
Quoted_identifier | QUOTED_IDENTIFIER option [compatibility]
Read_past_deleted | READ_PAST_DELETED option [database]
Recovery_time | RECOVERY_TIME option [database]
Remote_idle_timeout | REMOTE_IDLE_TIMEOUT option [database]
Replicate_all | REPLICATE_ALL option [replication]
ReqType | A string for the type of the last request.
Return_date_time_as_string | RETURN_DATE_TIME_AS_STRING option [database]
RI_trigger_time | RI_TRIGGER_TIME option [compatibility]
Rlbk | The number of Rollback requests that have been handled.
Rollback_on_deadlock | ROLLBACK_ON_DEADLOCK [database]
RollbackLogPages | The number of pages in the rollback log.
Row_counts | ROW_COUNTS option [database]
Scale | SCALE option [database]
ServerPort | Returns the server's TCP/IP port number or 0.
Sort_collation | SORT_COLLATION option [database]
SQL_flagger_error_level | SQL_FLAGGER_ERROR_LEVEL option [compatibility]
SQL_flagger_warning_level | SQL_FLAGGER_WARNING_LEVEL option [compatibility]
String_rtruncation | STRING_RTRUNCATION option [compatibility]
Subsume_row_locks | SUBSUME_ROW_LOCKS option [database]
Suppress_TDS_debugging | SUPPRESS_TDS_DEBUGGING option [database]
TDS_empty_string_is_null | TDS_EMPTY_STRING_IS_NULL option [database]
Temp_space_limit_check | TEMP_SPACE_LIMIT_CHECK option [database]
TempTablePages | The number of pages in the temporary file used for temporary tables.
Time_format | TIME_FORMAT option [compatibility]
Timestamp_format | TIMESTAMP_FORMAT option [compatibility]
TimeZoneAdjustment | The number of minutes that must be added to the Coordinated Universal Time (UTC) to display time local to the connection. By default, the value is set according to the client's time zone.
TransactionStartTime | A string containing the time the database was first modified after a COMMIT or ROLLBACK, or an empty string if no modifications have been made to the database since the last COMMIT or ROLLBACK.
Truncate_date_values | TRUNCATE_DATE_VALUES option [database] (deprecated)
Truncate_timestamp_values | TRUNCATE_TIMESTAMP_VALUES option [database]
Truncate_with_autocommit | TRUNCATE_WITH_AUTO_COMMIT option [database]
Tsql_hex_constant | TSQL_HEX_CONSTANT option [compatibility]
Tsql_variables | TSQL_VARIABLES option [compatibility]
UncommitOp | The number of uncommitted operations.
User_estimates | USER_ESTIMATES option [database]
UserAppInfo | The string specified by the AppInfo connection parameter in a connection string. For more information, see AppInfo connection parameter [APP].
Userid | The user ID for the connection.
UtilCmdsPermitted | Returns ON or OFF to indicate whether utility commands such as CREATE DATABASE, DROP DATABASE, and RESTORE DATABASE are permitted for the connection. For more information, see -gu server option.
Wait_for_commit | WAIT_FOR_COMMIT option [database]


Server-level properties

The following table lists properties that apply across the server as a whole.

Examples
toggle To retrieve the value of a server property

  • Use the property system function. For example, the following statement returns the number of cache pages being used to hold the main heap:

    SELECT property ( 'MainHeapPages' )
toggle To retrieve the values of all server properties

  • Use the sa_eng_properties system procedure:

    CALL sa_eng_properties
Descriptions
Property | Description
ActiveReq | The number of server threads that are currently handling a request.
AvailIO | Reserved
BuildChange | Reserved
BuildClient | Reserved
BuildReproducible | Reserved
BytesReceived | The number of bytes received during client/server communications.
BytesReceivedUncomp | The number of bytes that would have been received during client/server communications if compression was disabled. (This value is the same as the value for BytesReceived if compression is disabled.)
BytesSent | The number of bytes sent during client/server communications.
BytesSentUncomp | The number of bytes that would have been sent during client/server communications if compression was disabled. (This value is the same as the value for BytesSent if compression is disabled.)
C2 Returns YES if the -sc option was used when the server was started. Otherwise, returns NO.

For more information, see -sc server option.
CacheHitsEng | The number of database page lookups.
CacheReplacements | The number of pages in the cache that have been replaced.
CharSet | The character set in use by the database server.
CommandLine The command line that was used to start the server.

If the encryption key for a database was specified using the -ek option, the key is replaced with a constant string of asterisks in the value returned by this property.

If you need to specify the encryption key, you can start the database server with the -ep option to be prompted for the key, or use the START DATABASE statement. As well, if the database can be autostarted, the key can be provided in the DBKEY connection parameter.
CompactPlatformVer | A condensed version of the PlatformVer property.
CompanyName | The name of the company owning this software.
ConnsDisabled Returns ON or OFF to indicate the current setting of the server option to disable new connections.

For information, see sa_server_option system procedure.
ConsoleLogFile | Returns the name of the file where messages from the database server window are logged if the -o option was specified, otherwise returns an empty string.
CurrentCacheSize | The current cache size, in kilobytes.
DefaultCollation | The collation that would be used for new databases, if none is explicitly specified.
FipsMode | Returns YES if the -fips option was specified when the database server was started, and NO otherwise.
FreeBuffers | The number of available network buffers.
IdleTimeout The default idle timeout.

For more information, see -ti server option.
IsFipsAvailable | Returns YES if the FIPS DLL is installed, and NO otherwise.
IsIQ | Returns YES if the server is an IQ server, and NO otherwise.
IsJavaAvailable | Returns YES if the JavaVM is installed, and NO if the JavaVM is not installed. This property only indicates if the Java VM is available, not whether it is currently being used.
IsNetworkServer | Returns YES if connected to a network database server, and NO if connected to a personal database server.
IsRuntimeServer | Returns YES if connected to the limited desktop runtime database server, and NO otherwise.
JavaGlobFix | Java VM global fixed size.
Language | The locale language for the server.
LegalCopyright | The copyright string for the software.
LegalTrademarks | Trademark information for the software.
LicenseCount | The number of licensed seats or processors.
LicensedCompany | The name of the licensed company.
LicensedUser | The name of the licensed user.
LicensesInUse | The number of concurrent users currently connected to the network server, as determined by the number of unique client network addresses connected to the server.
LicenseType | The license type. Can be networked seat (per-seat) or cpu-based.
LivenessTimeout | The client liveness timeout default.
LockedHeapPages | The number of heap pages locked in the cache.
MachineName | The name or IP address of the computer running a database server.
MainHeapBytes | The number of bytes used for global server data structures.
MainHeapPages | The number of pages used for global server data structures.
MaxCacheSize | The maximum allowed cache size, in kilobytes.
MaxMessage | The current maximum line number that can be retrieved from the server's message window. This represents the most recent message displayed in the server's message window.
Message, linenumber A line from the server's message window, prefixed by the date and time the message appeared. The second parameter specifies the line number.

The value returned by PROPERTY( "message" ) is the first line of output that was written to the Server Messages window. Calling PROPERTY( "message", i ) returns the i-th line of server output (with zero being the first line). The buffer is finite, so as messages are generated, the first lines are dropped and may no longer be available in memory. In this case, NULL is returned.
MessageText, linenumber | The text associated with the specified line number in the server's message window, without a date and time prefix. The second parameter specifies the line number.
MessageTime, linenumber | The date and time associated with the specified line number in the server's message window. The second parameter specifies the line number.
MessageWindowSize | The maximum number of lines that can be retrieved from the server's message window.
MinCacheSize | The minimum allowed cache size, in kilobytes.
MultiPacketsReceived | The number of multi-packet deliveries received during client/server communications.
MultiPacketsSent | The number of multi-packet deliveries sent during client/server communications.
Name | The name of the server.
NativeProcessorArchitecture On platforms where a processor can be emulated (such as X86 on Win64), returns a string that identifies the native processor type. In all other cases, it returns the same value as property( 'ProcessorArchitecture' ).

Values can include:

32-bit Windows (not CE) - X86

NetWare - X86

Intel Solaris - X86

CE - SH3, SH4, MIPS or ARM

64-bit Windows - IA64 or AMD64 64-bit

UNIX - IA64 or AMD64

Solaris - SPARC

AIX - PPC

MAC OS - PPC

HP - PA_RISC

DEC UNIX - ALPHA

Linux - X86, SPARC, IA64
NumProcessorsAvail | The number of processors on the server.
NumProcessorsMax | The maximum number of processors used. Normally this should be 2 for dbeng.exe and 0 for dbsrv.exe.
PacketsReceived | The number of client/server communication packets received.
PacketsReceivedUncomp | The number of packets that would have been received during client/server communications if compression was disabled. (This value is the same as the value for PacketsReceived if compression is disabled.)
PacketsSent | The number of client/server communication packets sent.
PacketsSentUncomp | The number of packets that would have been sent during client/server communications if compression was disabled. (This value is the same as the value for PacketsSent if compression is disabled.)
PageSize | The size of the database server cache pages. This can be set using the -gp option, otherwise, it is the maximum database page size of the databases specified on the command line.
PeakCacheSize | The largest value the cache has reached in the current session, in kilobytes.
Platform | The operating system on which the software is running. For example, if you are running on Windows 2000, this property returns Windows2000.
PlatformVer | The operating system on which the software is running, including build numbers, service packs, etc. For example, it could return Windows 2000 Build 2195 Service Pack 3 .
ProcessCPU | CPU usage statistics for the server process. Values are in seconds. This property is supported on Windows NT/2000/XP, Windows 95/98/Me, and UNIX. This property is not supported on Windows CE or NetWare.
ProcessCPUSystem | Process CPU system usage. Values are in seconds. This property is supported on Windows NT/2000/XP, Windows 95/98/Me, and UNIX. This property is not supported on Windows CE or NetWare.
ProcessCPUUser | Process CPU user usage. Values are in seconds. This property is supported on Windows NT/2000/XP, Windows 95/98/Me, and UNIX. This property is not supported on Windows CE or NetWare.
ProcessorArchitecture A string that identifies the processor type. Values can include:

32-bit Windows (not CE) - X86

NetWare - X86

Intel Solaris - X86

CE - SH3, SH4, or ARM

64-bit Windows - IA64 or AMD64 64-bit

UNIX - IA64 or AMD64

Solaris - SPARC

AIX - PPC

MAC OS - PPC

HP - PA_RISC

DEC UNIX - ALPHA
ProductName | The name of the software.
ProfileFilterConn Returns the ID of the connection being monitored if procedure profiling for a specific connection is turned on. Otherwise, returns an empty string. You control procedure profiling by user with the sa_server_option procedure.

For more information, see sa_server_option system procedure.
ProfileFilterUser Returns the name of the user being monitored if procedure profiling for a specific user is turned on. Otherwise, returns an empty string. You control procedure profiling by user with the sa_server_option procedure.

ProductVersion | The version of the software being run.
QuittingTime | Shutdown time for the server. If none is specified, the value is none.
RememberLastStatement | Returns ON if the server is recording the last statement prepared by each connection, and OFF otherwise.
Req | The number of times the server has been entered to allow it to handle a new request or continue processing an existing request.
RequestLogFile The name of the request logging file. An empty string is returned if there is no level logging.

For information, see sa_server_option system procedure.
RequestLogging ALL, SQL, or NONE.

For information, see sa_server_option system procedure.
RequestLogNumFiles The number of request log files being kept.

For more information, see sa_server_option system procedure.
SendFail | The number of times that the underlying communications protocols have failed to send a packet.
StartTime | The date/time that the server started
Tempdir | The directory in which temporary files are stored by the server.
TimeZoneAdjustment | The number of minutes that must be added to the Coordinated Universal Time (UTC) to display time local to the server.
TotalBuffers | The total number of network buffers.
UnschReq | The number of requests that are currently queued up waiting for an available server thread.


Database-level properties

The following table lists properties available for each database on the server.

Examples
toggle To retrieve the value of a database property

  • Use the db_property system function. For example, the following statement returns the page size of the current database:

    SELECT db_property ( 'PageSize' )
toggle To retrieve the values of all database properties

  • Use the sa_db_properties system procedure:

    CALL sa_db_properties
Descriptions
Property | Description
Alias | The database name.
BlankPadding | The status of the blank padding feature. Returns ON if the database has blank padding enabled. Otherwise, it returns OFF.
BlobArenas | The status of the BlobArenas feature. Returns ON if the database stores extension (BLOB) pages separately from table pages for the database. Otherwise, returns OFF.
CacheHits | The number of database page lookups satisfied by finding the page in the cache.
CacheRead | The number of database pages that have been looked up in the cache.
CacheReadIndInt | The number of index internal-node pages that have been read from the cache.
CacheReadIndLeaf | The number of index leaf pages that have been read from the cache.
CacheReadTable | The number of table pages that have been read from the cache.
Capabilities | The capability bits enabled for the database. This property is primarily for use by technical support.
CaseSensitive | The status of the case sensitivity feature. Returns ON if the database is case sensitive. Otherwise, it returns OFF.
CaseSensitivePasswords | The status of password case sensitivity. In versions 9.0.0 and later, password case sensitivity is independent of database case sensitivity. Returns ON if database passwords are case sensitive. Otherwise, it returns OFF.
CharSet | The character set of the database.
CheckpointUrgency | The time that has elapsed since the last checkpoint as a percentage of the checkpoint time setting of the database.
Checksum | Returns ON if database page checksums are enabled for the database. Otherwise, returns OFF.
Chkpt | The number of checkpoints that have been performed.
ChkptFlush | The number of ranges of adjacent pages written out during a checkpoint.
ChkptPage | The number of transaction log checkpoints.
CommitFile | The number of times the server has forced a flush of the disk cache. On Windows NT/2000/XP and NetWare platforms, the disk cache does not need to be flushed if unbuffered (direct) I/O is used.
CompressedBTrees | Returns ON if Compressed B-tree indexes are supported. Otherwise, returns OFF.
Compression | The compression status of the database. Returns either ON (meaning the database is compressed) or OFF. If a write file is created on a compressed database, the write file is NOT compressed. Starting a write file created on a compressed database and selecting db_property('compression'), returns OFF.
ConnCount | The number of connections to the database.
CurrentRedoPos | The current offset in the transaction log file where the next database operation is to be logged.
CurrIO | The current number of file I/Os that were issued by the server but have not yet completed.
CurrRead | The current number of file reads that were issued by the server but have not yet completed.
CurrWrite | The current number of file writes that were issued by the server but have not yet completed.
DBFileFragments | The number of database file fragments. This property is supported on Windows NT/2000/XP.
DiskRead | The number of pages that have been read from disk.
DiskReadIndInt | The number of index internal-node pages that have been read from disk.
DiskReadIndLeaf | The number of index leaf pages that have been read from disk.
DiskReadTable | The number of table pages that have been read from disk.
DiskWrite | The number of modified pages that have been written to disk.
DriveType dbspace The drive on which the database file is located. Returns CD, FIXED, RAMDISK, REMOTE, REMOVABLE, and UNKNOWN.

On UNIX, depending on the version of UNIX and the type of drive, it may not be possible to determining the drive type. In these cases "UNKNOWN" is returned.

When used with db_extended_property, you can specify which dbspace you want the size for.

Dbspace can be either the name of the dbspace or the file_id of the dbspace.

Leaving dbspace unspecified or using system both refer to the system dbspace.

If the specified dbspace does not exist, the property function returns NULL. If the name of a dbspace is specified and the ID of a database that is not the database of the current connection is also specified, the function also returns NULL.
Encryption | The type of encryption applied to the database. Returns None, Simple, or AES.
ExtendDB | The number of pages by which the database file has been extended.
ExtendTempWrite | The number of pages by which temporary files have been extended.
File | The file name of the database root file, including path.
FileSize dbspace When used with db_property, this property returns the file size of the system dbspace, in pages.

When used with db_extended_property, you can specify which dbspace you want the size for.

Dbspace can be either the name of the dbspace, the file_id of the dbspace, or temporary to refer to the temporary dbspace.

You can also specify translog to return the size of the log file.

Finally, you can specify writefile to refer to the write file. When using a write file, FileSize on a dbspace returns the amount of space in the virtual dbspace, represented by the underlying dbspace plus the modifications to that dbspace that have been stored in the write file.

Leaving the dbspace unspecified, or using system, both refer to the system dbspace.

If the specified dbspace does not exist, the property function returns NULL. If the name of a dbspace is specified and an id or name of a database which is not the database of the current connection is also specified, the function also returns NULL.
FileVersion | The version of the database file. This does not correspond to a software release version.
FreePageBitMaps | Returns ON if free database pages are managed via bitmaps. Otherwise, returns OFF.
FreePages dbspace FreePages is only supported on databases created with version 8.0.0 or later.

When used with db_property, this property returns the number of free pages in the system dbspace.

When used with db_extended_property, you can specify which dbspace you want the number of free pages for. Dbspace can be either the name of the dbspace, the file_id of the dbspace, or temporary to refer to the temporary dbspace.

You can also specify translog to return the number of free pages in the log file.

Finally, you can specify writefile to refer to the write file. When using a write file, FreePages on a dbspace returns the number of free pages in the virtual dbspace, represented by the underlying dbspace plus the modifications to that dbspace that have been stored in the write file.

Leaving the dbspace unspecified, or using system both refer to the system dbspace.

If the specified dbspace does not exist, the property function returns null. If the name of a dbspace is specified and an id or name of a database which is not the database of the current connection is also specified, the function also returns null.
FullCompare | The number of comparisons that have been performed beyond the hash value in an index.
GlobalDBId | The value of the GLOBAL_DATABASE_ID option used to generate unique primary key values in a replication environment.
Histograms | Returns ON if optimizer statistics are maintained as histograms. Otherwise, returns OFF.
IdleCheck | The number of times that the server's idle thread has become active to do idle writes, idle checkpoints, and so on.
IdleChkpt | The number of checkpoints completed by the server's idle thread. An idle checkpoint occurs whenever the idle thread writes out the last dirty page in the cache.
IdleChkTime | The number of 100ths of a second spent checkpointing during idle I/O.
IdleWrite | The number of disk writes that have been issued by the server's idle thread.
IndAdd | The number of entries that have been added to indexes.
IndLookup | The number of entries that have been looked up in indexes.
IOToRecover | The estimated number of I/O operations required to recover the database.
IQStore | Reserved.
JavaHeapSize | Heap size per Java VM.
JavaNSSize | Java VM Namespace size.
JDKVersion | The Java runtime library version used by this database.
Language Returns a comma-separated list of languages known to be supported by the database collation. The languages are in two-letter ISO format. If the language is not known (usually a custom collation), the return value is NULL.

For a list of the two-letter ISO format language names and the language they correspond to, see Understanding the locale language.
LargeProcedureIDs | Returns ON if 32-bit stored procedure IDs are supported for the database. Otherwise, returns OFF.
LockTablePages | The number of pages used to store lock information.
LogFileFragments | The number of log file fragments. This property is supported on Windows NT/2000/XP.
LogFreeCommit | The number of Redo Free Commits. A Redo Free Commit occurs when a commit of the transaction log is requested but the log has already been written (so the commit was done for free).
LogName | The file name of the transaction log, including path.
LogWrite | The number of pages that have been written to the transaction log.
LTMGeneration | The generation number of the LTM or Replication Agent. This property is primarily for use by technical support.
LTMTrunc | The minimal confirmed log offset for the Replication Agent.
MapPages | The number of map pages used for accessing the lock table, frequency table, and table layout.
MaxIO | The maximum value that CurrIO has reached.
MaxRead | The maximum value that CurrRead has reached.
MaxWrite | The maximum value that CurrWrite has reached.
MultiByteCharSet | Returns ON if the database uses a multi-byte character set. Otherwise, returns OFF.
Name | The database name (identical to alias).
PageRelocations | The number of relocatable heap pages that have been read from the temporary file.
PageSize | The page size of the database, in bytes.
PreserveSource | Returns ON if the database preserves the source for procedures and views. Otherwise, returns OFF.
ProcedurePages | The number of relocatable heap pages that have been used for procedures.
ProcedureProfiling | Returns ON if procedure profiling is turned on for the database. Otherwise, returns OFF.
QueryBypassed | The number of requests optimized by the optimizer bypass.
QueryCachedPlans | The number of cached execution plans across all connections.
QueryCachePages | The number of pages used to cache execution plans.
QueryLowMemoryStrategy | The number of times the server changed its execution plan during execution as a result of low memory conditions. The strategy can change because less memory is available than the optimizer estimated, or because the execution plan required more memory than the optimizer estimated.
QueryOptimized | The number of requests fully optimized.
QueryBypassed | The number of requests reused from the plan cache.
ReadOnly | Returns ON if the database is being run in read-only mode. Otherwise, returns OFF.
RecoveryUrgency | An estimate of the amount of time required to recover the database.
RelocatableHeapPages | The number of pages used for relocatable heaps (cursors, statements, procedures, triggers, views, etc.).
RemoteTrunc | The minimal confirmed log offset for the SQL Remote Message Agent.
RollbackLogPages | The number of pages in the rollback log.
SeparateCheckpointLog | Returns ON if the checkpoint log for the database is maintained at the end of the SYSTEM dbspace. Otherwise, returns OFF.
SeparateForeignKeys | Returns ON if primary and foreign keys are stored separately. Otherwise, returns OFF.
SyncTrunc | The minimal confirmed log offset for the MobiLink client dbmlsync executable.
TableBitMaps | Returns ON if the database supports table bitmaps. Otherwise, returns OFF.
TempFileName | The file name of the database temporary file, including path.
TempTablePages | The number of pages in the temporary file used for temporary tables.
TransactionsSpanLogs | Returns ON if transactions can span multiple log files. Otherwise, returns OFF.
TriggerPages | The number of relocatable heap pages used for triggers.
VariableHashSize | Returns ON if the hash size can be specified for B-tree indexes. Otherwise, returns OFF.
ViewPages | The number of relocatable heap pages used for views.


Physical Limitations

About this chapter

This chapter describes the limitations on size and number of objects in Adaptive Server Anywhere databases.

Size and number limitations


Size and number limitations

The following table lists the physical limitations on size and number of objects in an Adaptive Server Anywhere database. The memory, CPU, and disk drive of the computer are more limiting factors in most cases.

Item | Limitation
Database size | 13 files per database. For each file, the largest file allowed by operating system and file system
Field size | 2 GB
File size (FAT 12) | 16 MB
File size (FAT 16) | 2 GB
File size (FAT 32) | 4 GB
File size for NTFS, NetWare (NSS volumes), HP-UX 11.0 and later, Solaris 2.6 and later, Linux 2.4 and later)

  • 256 GB for 1 KB pages

  • 512 GB for 2KB pages

  • 1 TB for 4 KB pages

  • 2 TB for 8 KB pages
NetWare (traditional volumes) | 4 GB
File size (all other platforms and file systems) | 2 GB
Maximum cache size (non-AWE cache) (Windows 95/98, Windows NT, Windows 2000 Professional, Windows 2000 Server, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 Web Edition, Windows Server 2003 Standard Edition) | 1.8 GB
Maximum cache size (non-AWE cache) (Windows NT Advanced Server, Windows 2000 Advanced Server, Windows 2000 Enterprise Server, Windows 2000 Datacenter Server, Windows Server 2003 Enterprise Edition, Windows Server 2003 Datacenter Edition) | 2.7 GB
Maximum cache size (AWE cache) (Windows 2000 Professional, Windows 2000 Server, Windows 2000 Advanced Server, Windows 2000 Datacenter Server, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 Web Edition, Windows Server 2003 Standard Edition, Windows Server 2003 Enterprise Edition, Windows Server 2003 Datacenter Edition ) | 100% of all available memory - 128 MB
Maximum cache size (Windows CE) | Limited by available memory on the device
Maximum cache size (UNIX—Solaris, x86 Linux, AIX, HP) | 2 GB for 32-bit servers
Maximum cache size (Win 64) | Limited by physical memory on 64-bit servers
Maximum cache size (UNIX—Tru64 UNIX, Itanium Linux, Itanium HP-UX) | Limited by physical memory on 64-bit servers
Maximum cache size (NetWare) | 2 GB
Maximum index entry size | No limit
Number of databases per server | 255
Number of columns per table

  • ((page size)/4)^2 for 32-bit servers

  • ((page size)/8)^2 for 64-bit servers

Note: An excessive number of columns, although allowed, will affect performance.
Number of indexes per table | 2^32
Number of rows per database | Limited by file size
Number of rows per table | Limited by file size
Number of tables per database | 2^32 – 2^20 - 1 = 4 293 918 719
Number of temporary tables per connection | 2^20 = 1 048 576
Number of tables referenced per transaction | No limit
Number of stored procedures per database | 2^32 – 1 = 4 294 967 295
Number of events per database | 2^31 – 1 = 2 147 483 647
Number of triggers per database | 2^32 – 1 = 4 294 967 295
Row size | Limited by file size
Table size | Maximum file size. User-created indexes for the table can be stored separately from the table


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL User's Guide

Version 9.0.2

DC38124-01-0902-01

October 2004

Copyright
About This Manual
Designing Your Database
Working with Database Objects
Ensuring Data Integrity
Using Transactions and Isolation Levels
Monitoring and Improving Performance
Queries: Selecting Data from a Table
Summarizing, Grouping, and Sorting Query Results
Joins: Retrieving Data from Several Tables
Common Table Expressions
Using OLAP
Using Subqueries
Adding, Changing, and Deleting Data
Query Optimization and Execution
Transact-SQL Compatibility
Differences from Other SQL Dialects
Using XML in the Database
Importing and Exporting Data
Accessing Remote Data
Server Classes for Remote Data Access
Using Procedures, Triggers, and Batches
Debugging Logic in the Database


About This Manual

Subject

This book describes how to design and create databases; how to import, export, and modify data; how to retrieve data; and how to build stored procedures and triggers.

Audience

This manual is for all users of Adaptive Server Anywhere.

Before you begin

This manual assumes that you have an elementary familiarity with database-management systems and Adaptive Server Anywhere in particular. If you do not have such a familiarity, you should consider reading Introducing SQL Anywhere Studio before reading this manual.


Designing Your Database

About this chapter

This chapter introduces the basic concepts of relational database design and gives you step-by-step suggestions for designing your own databases. It uses the expedient technique known as conceptual data modeling, which focuses on entities and the relationships between them.


Introduction

While designing a database is not a difficult task for small and medium sized databases, it is an important one. Bad database design can lead to an inefficient and possibly unreliable database system. Because client applications are built to work on specific parts of a database, and rely on the database design, a bad design can be difficult to revise at a later date.

For more information, you may also wish to consult an introductory book such as A Database Primer by C. J. Date. If you are interested in pursuing database theory, C. J. Date's An Introduction to Database Systems is an excellent textbook on the subject.


Database design concepts

In designing a database, you plan what things you want to store information about, and what information you will keep about each one. You also determine how these things are related. In the common language of database design, what you are creating during this step is a conceptual database model.

Entities and relationships

The distinguishable objects or things that you want to store information about are called entities. The associations between them are called relationships. In the language of database description, you can think of entities as nouns and relationships as verbs.

Conceptual models are useful because they make a clean distinction between the entities and relationships. These models hide the details involved in implementing a design in any particular database-management system. They allow you to focus on fundamental database structure. Hence, they also form a common language for the discussion of database design.

Entity-relationship diagrams

The main component of a conceptual database model is a diagram that shows the entities and relationships. This diagram is commonly called an entity-relationship diagram. In consequence, many people use the name entity-relationship modeling to refer to the task of creating a conceptual database model.

Conceptual database design is a top-down design method. There are now sophisticated tools such as Sybase PowerDesigner that help you pursue this method, or other approaches. This chapter is an introductory chapter only, but it does contain enough information for the design of straightforward databases.


Entities

An entity is the database equivalent of a noun. Distinguishable objects such as employees, order items, departments and products are all examples of entities. In a database, a table represents each entity. The entities that you build into your database arise from the activities for which you will be using the database, such as tracking sales calls and maintaining employee information.

Attributes

Each entity contains a number of attributes. Attributes are particular characteristics of the things that you would like to store. For example, in an employee entity, you might want to store an employee ID number, first and last names, an address, and other particular information that pertains to a particular employee. Attributes are also known as properties.

You depict an entity using a rectangular box. Inside, you list the attributes associated with that entity.

The Employee table with its columns: employee number, first name, last name, and address. Employee number is underlined.

An identifier is one or more attributes on which all the other attributes depend. It uniquely identifies an item in the entity. Underline the names of attributes that you wish to form part of an identifier.

In the Employee entity, above, the Employee Number uniquely identifies an employee. All the other attributes store information that pertains only to that one employee. For example, an employee number uniquely determines an employee's name and address. Two employees might have the same name or the same address, but you can make sure that they don't have the same employee number. Employee Number is underlined to show that it is an identifier.

It is good practice to create an identifier for each entity. As will be explained later, these identifiers become primary keys within your tables. Primary key values must be unique and cannot be null or undefined. They identify each row in a table uniquely and improve the performance of the database server.


Relationships

A relationship between entities is the database equivalent of a verb. An employee is a member of a department, or an office is located in a city. Relationships in a database may appear as foreign key relationships between tables, or may appear as separate tables themselves. You will see examples of each in this chapter.

The relationships in the database are an encoding of rules or practices that govern the data in the entities. If each department has one department head, you can create a one-to-one relationship between departments and employees to identify the department head.

Once a relationship is built into the structure of the database, there is no provision for exceptions. There is nowhere to put a second department head. Duplicating the department entry would involve duplicating the department ID, which is the identifier. Duplicate identifiers are not allowed.

Tip
Strict database structure can benefit you, because it can eliminate inconsistencies, such as a department with two managers. On the other hand, you as the designer should make your design flexible enough to allow some expansion for unforeseen uses. Extending a well-designed database is usually not too difficult, but modifying the existing table structure can render an entire database and its client applications obsolete.
Cardinality of relationships

There are three kinds of relationships between tables. These correspond to the cardinality (number) of the entities involved in the relationship.

  • One-to-one relationships You depict a relationship by drawing a line between two entities. The line may have other markings on it such as the two little circles shown. Later sections explain the purpose of these marks. In the following diagram, one employee manages one department. The management relationship between Department and Employee.

  • One-to-many relationships The fact that one item contained in Entity 1 can be associated with multiple entities in Entity 2 is denoted by the multiple lines forming the attachment to Entity 2. In the following diagram, one office can have many phones. The phone location relationship between office and telephones.

  • Many-to-many relationships In this case, draw multiple lines for the connections to both entities. This means that one warehouse can hold many different parts, and one type of part can be stored at many warehouses. The storage relationship between parts and warehouses.

Roles

You can describe each relationship with two roles. Roles are verbs or phrases that describe the relationship from each point of view. For example, a relationship between employees and departments might be described by the following two roles.

  1. An employee is a member of a department.

  2. A department contains an employee.

Employees are members of departments, and departments contain employees.

Roles are very important because they afford you a convenient and effective means of verifying your work.

Tip
Whether reading from left-to-right or from right-to-left, the following rule makes it easy to read these diagrams: Read the 1 name of the first entity, 2 role next to the first entity, 3 cardinality from the connection to the second entity, and 4 name of the second entity.
Mandatory elements

The little circles just before the end of the line that denotes the relation serve an important purpose. A circle means that an element can exist in the one entity without a corresponding element in the other entity.

If a cross bar appears in place of the circle, that entity must contain at least one element for each element in the other entity. An example will clarify these statements.

The Publisher table, Books table and Authors table.

This diagram corresponds to the following four statements.

  1. A publisher publishes zero or more books.

  2. A book is published by exactly one publisher.

  3. A book is written by one or more authors.

  4. An author writes zero or more books.

Tip
Think of the little circle as the digit 0 and the cross bar as the number one. The circle means at least zero. The cross bar means at least one.
Reflexive relationships

Sometimes, a relationship will exist between entries in a single entity. In this case, the relationship is said to be reflexive. Both ends of the relationship attach to a single entity.

The Employee table.

This diagram corresponds to the following two statements.

  1. An employee reports to at most one other employee.

  2. An employee manages zero or more employees.

Notice that in the case of this relation, it is essential that the relation be optional in both directions. Some employees are not managers. Similarly, at least one employee should head the organization and hence report to no one.

Naturally, you would also like to specify that an employee cannot be his or her own manager. This restriction is a type of business rule. Business rules are discussed later as part of The design process.


Changing many-to-many relationships into entities

When you have attributes associated with a relationship, rather than an entity, you can change the relationship into an entity. This situation sometimes arises with many-to-many relationships, when you have attributes that are particular to the relationship and so you cannot reasonably add them to either entity.

Suppose that your parts inventory is located at a number of different warehouses. You have drawn the following diagram.

Parts are stored at warehouses and warehouses contain parts.

But you wish to record the quantity of each part stored at each location. This attribute can only be associated with the relationship. Each quantity depends on both the parts and the warehouse involved. To represent this situation, you can redraw the diagram as follows:

Between the Parts entity and Warehouse entity is the Inventory entity, which contains the Quantity column.

Notice the following details of the transformation:

  1. Two new relations join the relation entity with each of the two original entities. They inherit their names from the two roles of the original relationship: stored at and contains, respectively.

  2. Each entry in the Inventory entity demands one mandatory entry in the Parts entity and one mandatory entry in the Warehouse entity. These relationships are mandatory because a storage relationship only makes sense if it is associated with one particular part and one particular warehouse.

  3. The new entity is dependent on both the Parts entity and on the Warehouse entity, meaning that the new entity is identified by the identifiers of both of these entities. In this new diagram, one identifier from the Parts entity and one identifier from the Warehouse entity uniquely identify an entry in the Inventory entity. The triangles that appear between the circles and the multiple lines that join the two new relationships to the new Inventory entity denote the dependencies.

Do not add either a Part Number or Warehouse ID attribute to the Inventory entity. Each entry in the Inventory entity does depend on both a particular part and a particular warehouse, but the triangles denote this dependence more clearly.


The design process

There are five major steps in the design process.

  • Step 1: Identify entities and relationships.

  • Step 2: Identify the required data.

  • Step 3: Normalize the data.

  • Step 4: Resolve the relationships.

  • Step 5: Verify the design.

For more information about implementing the database design, see Working with Database Objects.

Step 1: Identify entities and relationships
Entity and relationship example
Step 2: Identify the required data
Step 3: Normalize the data
Step 4: Resolve the relationships
Step 5: Verify the design


Step 1: Identify entities and relationships

toggle To identify the entities in your design and their relationship to each other

  1. Define high-level activities Identify the general activities for which you will use this database. For example, you may want to keep track of information about employees.

  2. Identify entities For the list of activities, identify the subject areas you need to maintain information about. These subjects will become entities. For example, hire employees, assign to a department, and determine a skill level.

  3. Identify relationships Look at the activities and determine what the relationships will be between the entities. For example, there is a relationship between parts and warehouses. Define two roles to describe each relationship.

  4. Break down the activities You started out with high-level activities. Now, examine these activities more carefully to see if some of them can be broken down into lower-level activities. For example, a high-level activity such as maintain employee information can be broken down into:

    • Add new employees.

    • Change existing employee information.

    • Delete terminated employees.

  5. Identify business rules Look at your business description and see what rules you follow. For example, one business rule might be that a department has one and only one department head. These rules will be built into the structure of the database.


Entity and relationship example

Example

ACME Corporation is a small company with offices in five locations. Currently, 75 employees work for ACME. The company is preparing for rapid growth and has identified nine departments, each with its own department head.

To help in its search for new employees, the personnel department has identified 68 skills that it believes the company will need in its future employee base. When an employee is hired, the employee's level of expertise for each skill is identified.

Define high-level activities

Some of the high-level activities for ACME Corporation are:

  • Hire employees.

  • Terminate employees.

  • Maintain personal employee information.

  • Maintain information on skills required for the company.

  • Maintain information on which employees have which skills.

  • Maintain information on departments.

  • Maintain information on offices.

Identify the entities and relationships

Identify the entities (subjects) and the relationships (roles) that connect them. Create a diagram based on the description and high-level activities.

Use boxes to show entities and lines to show relationships. Use the two roles to label each relationship. You should also identify those relationships that are one-to-many, one-to-one, and many-to-many using the appropriate annotation.

Following is a rough entity-relationship diagram. It will be refined throughout the chapter.

Break down the high-level activities

The following lower-level activities below are based on the high-level activities listed above:

  • Add or delete an employee.

  • Add or delete an office.

  • List employees for a department.

  • Add a skill to the skill list.

  • Identify the skills of an employee.

  • Identify an employee's skill level for each skill.

  • Identify all employees that have the same skill level for a particular skill.

  • Change an employee's skill level.

These lower-level activities can be used to identify if any new tables or relationships are needed.

Identify business rules

Business rules often identify one-to-many, one-to-one, and many-to-many relationships.

The kind of business rules that may be relevant include the following:

  • There are now five offices; expansion plans allow for a maximum of ten.

  • Employees can change department or office.

  • Each department has one department head.

  • Each office has a maximum of three telephone numbers.

  • Each telephone number has one or more extensions.

  • When an employee is hired, the level of expertise in each of several skills is identified.

  • Each employee can have from three to twenty skills.

  • An employee may or may not be assigned to an office.


Step 2: Identify the required data

toggle To identify the required data

  1. Identify supporting data.

  2. List all the data you need to track.

  3. Set up data for each entity.

  4. List the available data for each entity. The data that describes an entity (subject) answers the questions who, what, where, when, and why.

  5. List any data required for each relationship (verb).

  6. List the data, if any, that applies to each relationship.

Identify supporting data

The supporting data you identify will become the names of the attributes of the entity. For example, the data below might apply to the Employee entity, the Skill entity, and the Expert In relationship.

Employee | Skill | Expert In
Employee ID | Skill ID | Skill level
Employee first name | Skill name | Date skill was acquired
Employee last name | Description of skill |
Employee department |  |
Employee office |  |
Employee address |  |

If you make a diagram of this data, it will look something like this picture:

Employees are capable of skills, and skills are acquired by employees.

Observe that not all of the attributes you listed appear in this diagram. The missing items fall into two categories:

  1. Some are contained implicitly in other relationships; for example, Employee department and Employee office are denoted by the relations to the Department and Office entities, respectively.

  2. Others are not present because they are associated not with either of these entities, but rather the relationship between them. The above diagram is inadequate.

The first category of items will fall naturally into place when you draw the entire entity-relationship diagram.

You can add the second category by converting this many-to-many relationship into an entity.

The new entity Expert In is added between Employee and Skill.

The new entity depends on both the Employee and the Skill entities. It borrows its identifiers from these entities because it depends on both of them.

Notes

  • When you are identifying the supporting data, be sure to refer to the activities you identified earlier to see how you will access the data.

    For example, you may need to list employees by first name in some situations and by last name in others. To accommodate this requirement, create a First Name attribute and a Last Name attribute, rather than a single attribute that contains both names. With the names separate, you can later create two indexes, one suited to each task.

  • Choose consistent names. Consistency makes it easier to maintain your database and easier to read reports and output windows.

    For example, if you choose to use an abbreviated name such as Emp_status for one attribute, you should not use a full name, such as Employee_ID, for another attribute. Instead, the names should be Emp_status and Emp_ID.

  • At this stage, it is not crucial that the data be associated with the correct entity. You can use your intuition. In the next section, you'll apply tests to check your judgment.


Step 3: Normalize the data

Normalization is a series of tests that eliminate redundancy in the data and make sure the data is associated with the correct entity or relationship. There are five tests. This section presents the first three of them. These three tests are the most important and so the most frequently used.

Why normalize?
The goals of normalization are to remove redundancy and to improve consistency. For example, if you store a customer's address in multiple locations, it is difficult to update all copies correctly when they move.

For more information about the normalization tests, see a book on database design.

Normal forms

There are several tests for data normalization. When your data passes the first test, it is considered to be in first normal form. When it passes the second test, it is in second normal form, and when it passes the third test, it is in third normal form.

toggle To normalize data in a database

  1. List the data.

    • Identify at least one key for each entity. Each entity must have an identifier.

    • Identify keys for relationships. The keys for a relationship are the keys from the two entities that it joins.

    • Check for calculated data in your supporting data list. Calculated data is not normally stored in a relational database.

  2. Put data in first normal form.

    • If an attribute can have several different values for the same entry, remove these repeated values.

    • Create one or more entities or relationships with the data that you remove.

  3. Put data in second normal form.

    • Identify entities and relationships with more than one key.

    • Remove data that depends on only one part of the key.

    • Create one or more entities and relationships with the data that you remove.

  4. Put data in third normal form.

    • Remove data that depends on other data in the entity or relationship, not on the key.

    • Create one or more entities and relationships with the data that you remove.

Data and identifiers

Before you begin to normalize (test your design), simply list the data and identify a unique identifier each table. The identifier can be made up of one piece of data (attribute) or several (a compound identifier).

The identifier is the set of attributes that uniquely identifies each row in an entity. For example, the identifier for the Employee entity is the Employee ID attribute. The identifier for the Works In relationship consists of the Office Code and Employee ID attributes.

You can make an identifier for each relationship in your database by taking the identifiers from each of the entities that it connects. In the following table, the attributes identified with an asterisk are the identifiers for the entity or relationship.

Entity or Relationship | Attributes
Office | *Office code Office address Phone number
Works in | *Office code *Employee ID
Department | *Department ID Department name
Heads | *Department ID *Employee ID
Member of | *Department ID *Employee ID
Skill | *Skill ID Skill name Skill description
Expert in | *Skill ID *Employee ID Skill level Date acquired
Employee | *Employee ID last name first name Social security number Address phone number date of birth
Putting data in first normal form

  • To test for first normal form, look for attributes that can have repeating values.

  • Remove attributes when multiple values can apply to a single item. Move these repeating attributes to a new entity.

In the entity below, Phone number can repeat—an office can have more than one telephone number.

The office and phone entity contains office code, office address, and phone number.

Remove the repeating attribute and make a new entity called Telephone. Set up a relationship between Office and Telephone.

The Office entity contains an office code and office address. The Telephone entity contains telephone numbers. The relationships are: an office has telephones, and telephones are located in an office.
Putting data in second normal form

  • Remove data that does not depend on the whole key.

  • Look only at entities and relationships whose identifier is composed of more than one attribute. To test for second normal form, remove any data that does not depend on the whole identifier. Each attribute should depend on all of the attributes that comprise the identifier.

In this example, the identifier of the Employee and Department entity is composed of two attributes. Some of the data does not depend on both identifier attributes; for example, the department name depends on only one of those attributes, Department ID, and Employee first name depends only on Employee ID.

The Employee and Department entity contains employee id, department id, employee first name, employee last name, and department name.

Move the identifier Department ID, which the other employee data does not depend on, to a entity of its own called Department. Also move any attributes that depend on it. Create a relationship between Employee and Department.

Employees work in a department, and a department contains employees.
Putting data in third normal form

  • Remove data that doesn't depend directly on the key.

  • To test for third normal form, remove any attributes that depend on other attributes, rather than directly on the identifier.

In this example, the Employee and Office entity contains some attributes that depend on its identifier, Employee ID. However, attributes such as Office location and Office phone depend on another attribute, Office code. They do not depend directly on the identifier, Employee ID.

The Employee and Office entity contains employee id, employee first name, employee last name, office code, office location, and office phone.

Remove Office code and those attributes that depend on it. Make another entity called Office. Then, create a relationship that connects Employee with Office.

The Employee entity contains employee id, employee first name, and employee last name. The Office entity contains office code, office location, and office phone. The relationship is: employees work out of an office, and offices house employees.


Step 4: Resolve the relationships

When you finish the normalization process, your design is almost complete. All you need to do is to generate the physical data model that corresponds to your conceptual data model. This process is also known as resolving the relationships, because a large portion of the task involves converting the relationships in the conceptual model into the corresponding tables and foreign-key relationships.

Whereas the conceptual model is largely independent of implementation details, the physical data model is tightly bound to the table structure and options available in a particular database application. In this case, that application is Adaptive Server Anywhere.

Resolving relationships that do not carry data

In order to implement relationships that do not carry data, you define foreign keys. A foreign key is a column or set of columns that contains primary key values from another table. The foreign key allows you to access data from more than one table at one time.

A database design tool such as the DataArchitect component of Sybase PowerDesigner can generate the physical data model for you. However, if you're doing it yourself there are some basic rules that help you decide where to put the keys.

  • One to many An one-to-many relationship always becomes an entity and a foreign key relationship. Employees are members of departments, and departments contain employees.

    Notice that entities become tables. Identifiers in entities become (at least part of) the primary key in a table. Attributes become columns. In a one-to-many relationship, the identifier in the one entity will appear as a new foreign key column in the many table.

    The foreign key relationship between the Employee table and Department table is Department ID = Department ID.

    In this example, the Employee entity becomes an Employee table. Similarly, the Department entity becomes a Department table. A foreign key called Department ID appears in the Employee table.

  • One to one In a one-to-one relationship, the foreign key can go into either table. If the relationship is mandatory on one side, but optional on the other, it should go on the optional side. In this example, put the foreign key (Vehicle ID) in the Truck table because a vehicle does not have to be a truck. A vehicle may be a truck, but a truck must be a type of vehicle.

    The above entity-relationship model thus resolves the database base structure, below.

    The foreign key relationship between the Vehicle table and Truck table is Vehicle ID = Vehicle ID.

  • Many to many In a many-to-many relationship, a new table is created with two foreign keys. This arrangement is necessary to make the database efficient. Parts are stored at warehouses and warehouses contain parts.

    The new Storage Location table relates the Parts and Warehouse tables.

    The foreign key relationship between the Parts table and Storage Location table is Part Number = Part Number. The foreign key relationship between the Storage Location table and Warehouse table is Warehouse ID = Warehouse ID.
Resolving relationships that carry data

Some of your relationships may carry data. This situation often occurs in many-to-many relationships.

Between the Parts entity and Warehouse entity is the Inventory entity, which contains the Quantity column.

If this is the case, each entity resolves to a table. Each role becomes a foreign key that points to another table.

The foreign key relationship between the Parts table and Inventory table is Part Number = Part Number. The foreign key relationship between the Inventory table and Warehouse table is Warehouse ID = Warehouse ID.

The Inventory entity borrows its identifiers from the Parts and Warehouse tables, because it depends on both of them. Once resolved, these borrowed identifiers form the primary key of the Inventory table.

Tip
A conceptual data model simplifies the design process because it hides a lot of details. For example, a many-to-many relationship always generates an extra table and two foreign key references. In a conceptual data model, you can usually denote all of this structure with a single connection.

Previous Next


Step 5: Verify the design

Before you implement your design, you need to make sure that it supports your needs. Examine the activities you identified at the start of the design process and make sure you can access all of the data that the activities require.

  • Can you find a path to get the information you need?

  • Does the design meet your needs?

  • Is all of the required data available?

If you can answer yes to all the questions above, you are ready to implement your design.

Final design

Applying steps 1 through 3 to the database for the little company produces the following entity-relationship diagram. This database is now in third normal form.

The relationships between the following entities: Skill, Expert In, Employee, Office, and Department.

The corresponding physical data model appears below.


Designing the database table properties

The database design specifies which tables you have and what columns each table contains. This section describes how to specify each column's properties.

For each column, you must decide the column name, the data type and size, whether or not NULL values are allowed, and whether you want the database to restrict the values allowed in the column.


Choosing column names

A column name can be any set of letters, numbers, or symbols. However, you must enclose a column name in double quotes if it contains characters other than letters, numbers, or underscores, if it does not begin with a letter, or if it is the same as a keyword.


Choosing data types for columns

Available data types in Adaptive Server Anywhere include the following:

  • Integer data types

  • Decimal data types

  • Floating-point data types

  • Character data types

  • Binary data types

  • Date/time data types

  • Domains (user-defined data types)

For more information about data types, see SQL Data Types.

The long binary data type can be used to store information such as images (for instance, stored as bitmaps) or word-processing documents in a database. These types of information are commonly called binary large objects, or BLOBS.

For more information about each data type, see SQL Data Types.

NULL and NOT NULL

If the column value is mandatory for a record, you define the column as being NOT NULL. Otherwise, the column is allowed to contain the NULL value, which represents no value. The default in SQL is to allow NULL values, but you should explicitly declare columns NOT NULL unless there is a good reason to allow NULL values.

For more information about the NULL value, see NULL value. For information on its use in comparisons, see Search conditions.


Choosing constraints

Although the data type of a column restricts the values that are allowed in that column (for example, only numbers or only dates), you may want to further restrict the allowed values.

You can restrict the values of any column by specifying a CHECK constraint. You can use any valid condition that could appear in a WHERE clause to restrict the allowed values. Most CHECK constraints use either the BETWEEN or IN condition.

For more information about valid conditions, see Search conditions. For more information about assigning constraints to tables and columns, see Ensuring Data Integrity.

Example

The sample database has a table called Department, which has columns named dept_id, dept_name, and dept_head_id. Its definition is as follows:

Column | Data Type | Size | Null/Not Null | Constraint
dept_id | integer | — | not null | None
dept_name | char | 40 | not null | None
dept_head_id | integer | — | null | None

If you specify NOT NULL, a column value must be supplied for every row in the table.


Working with Database Objects

About this chapter

This chapter describes the mechanics of creating, altering, and deleting database objects such as tables, views, and indexes.

Introduction
Working with databases
Working with tables
Working with views
Working with indexes
Working with temporary tables
Copying database objects in Sybase Central


Introduction

With the Adaptive Server Anywhere tools, you can create a database file to hold your data. Once this file is created, you can begin managing the database. For example, you can add database objects, such as tables or users, and you can set overall database properties.

This chapter describes how to create a database and the objects within it. It includes procedures for Sybase Central, Interactive SQL, and command-line utilities. If you want more conceptual information before you begin, see the following chapters:

  • Designing Your Database

  • Ensuring Data Integrity

  • About Sybase Central

  • Using Interactive SQL

The SQL statements for carrying out the tasks in this chapter are called the data definition language (DDL). The definitions of the database objects form the database schema: you can think of the schema as an empty database.

Procedures and triggers are also database objects, but they are discussed in Using Procedures, Triggers, and Batches.

Chapter contents

This chapter contains the following material:

  • An introduction to working with database objects (this section)

  • A description of how to create and work with the database itself

  • A description of how to create and alter tables, views, and indexes


Working with databases

This section describes how to create and work with a database. As you read this section, keep in mind the following simple concepts:

  • The databases that you can create (called relational databases) are a collection of tables, related by primary and foreign keys. These tables hold the information in a database, and the tables and keys together define the structure of the database. A database may be stored in one or more database files, on one or more devices.

  • A database file also contains the system tables, which hold the schema definition as you build your database.

Creating a database
Erasing databases
Disconnecting from a database
Setting properties for database objects
Setting database options
Specifying a consolidated database
Displaying system objects in a database
Logging SQL statements as you work with a database
Starting a database without connecting
Installing the jConnect metadata support to an existing database


Creating a database

Adaptive Server Anywhere provides a number of ways to create a database: in Sybase Central, in Interactive SQL, and at the command line. Creating a database is also called initializing it. Once the database is created, you can connect to it and build the tables and other objects that you need in the database.

Transaction log

When you create a database, you must decide where to place the transaction log. This log stores all changes made to a database, in the order in which they are made. In the event of a media failure on a database file, the transaction log is essential for database recovery. It also makes your work more efficient. By default, it is placed in the same directory as the database file, but this is not recommended for production use.

For more information on placing the transaction log, see Configuring your database for data protection.

Database file compatibility

An Adaptive Server Anywhere database is an operating system file. It can be copied to other locations just as any other file is copied.

Database files are compatible among all operating systems, except where file system file size limitations or Adaptive Server Anywhere support for large files apply. A database created from any operating system can be used from another operating system by copying the database file(s). Similarly, a database created with a personal server can be used with a network server. Adaptive Server Anywhere servers can manage databases created with earlier versions of the software, but old servers cannot manage newer databases.

For more information about limitations, see Size and number limitations.

Using other applications to create databases

Some application design systems, such as Sybase PowerBuilder, contain tools for creating database objects. These tools construct SQL statements that are submitted to the server, typically through its ODBC interface. If you are using one of these tools, you do not need to construct SQL statements to create tables, assign permissions, and so on.

This chapter describes the SQL statements for defining database objects. You can use these statements directly if you are building your database from an interactive SQL tool, such as Interactive SQL. Even if you are using an application design tool, you may want to use SQL statements to add features to the database if they are not supported by the design tool.

For more advanced use, database design tools such as Sybase PowerDesigner provide a more thorough and reliable approach to developing well-designed databases.

For more information about database design, see Designing Your Database.


Creating databases (Sybase Central)

You can create a database in Sybase Central using the Create Database utility. After you have created a database, it appears under its server in the left pane of Sybase Central.

For more information, see Creating databases (SQL), and Creating databases (command line).

toggle To create a new database (Sybase Central)

  1. Choose Tools > Adaptive Server Anywhere 9 > Create Database.

  2. Follow the instructions in the wizard.

toggle To create a new database based on a current connection

  1. Connect to a database.

  2. In the left pane, select the Adaptive Server Anywhere plug-in.

  3. In the right pane, click the Utilities tab.

  4. In the right pane, double-click Create Database.

  5. Follow the instructions in the wizard.

Creating databases for Windows CE

You can create databases for Windows CE by copying an Adaptive Server Anywhere database file to the device.

Sybase Central has features to make database creation easy for Windows CE databases. If you have Windows CE services installed on your Windows desktop, you have the option to create a Windows CE database when you create a database from Sybase Central. Sybase Central omits some features for Windows CE databases, and optionally copies the resulting database file to your Windows CE machine.


Creating databases (SQL)

In Interactive SQL, you can use the CREATE DATABASE statement to create databases. You need to connect to an existing database before you can use this statement.

toggle To create a new database (SQL)

  1. Connect to an existing database.

  2. Execute a CREATE DATABASE statement.

For more information, see CREATE DATABASE statement.

Example

Create a database file in the c:\temp directory with the database name temp.db.

CREATE DATABASE 'c:\\temp\\temp.db'

The directory path is relative to the database server. You set the permissions required to execute this statement on the server command line, using the -gu command-line option. The default setting requires DBA authority.

The backslash is an escape character in SQL, and must be doubled. For more information, see Strings.


Creating databases (command line)

You can create a database from a command line with the dbinit utility. With this utility, you can include command-line parameters to specify different options for the database.

toggle To create a new database (command line)

  1. Open a command prompt.

  2. Run the dbinit utility. Include any necessary parameters.

    For example, to create a database called company.db with a 4 Kb page size, type:

    dbinit –p 4096 company.db

For more information, see The Initialization utility.


Erasing databases

Erasing a database deletes all tables and data from disk, including the transaction log that records alterations to the database. All database files are read-only to prevent accidental modification or deletion of the database files.

In Sybase Central, you can erase a database using the Erase Database utility. You need to connect to a database to access this utility, but the Erase Database wizard lets you specify any database for erasing. In order to erase a non-running database, the database server must be running.

In Interactive SQL, you can erase a database using the DROP DATABASE statement. Required permissions can be set using the database server -gu command-line option. The default setting is to require DBA authority.

You can also erase a database from a command line with the dberase utility. The database to be erased must not be running when this utility is used.

toggle To erase a database (Sybase Central)

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Erase Database.

  4. Follow the instructions in the wizard.

toggle To erase a database (SQL)

  • Execute a DROP DATABASE statement.

    For example,

    DROP DATABASE 'c:\\temp\\temp.db'
toggle To erase a database (command line)

  • From a command line, run the dberase utility.

    For example,

    dberase company.db

For more information, see DROP DATABASE statement, and The Erase utility.


Disconnecting from a database

When you are finished working with a database, you can disconnect from it. Adaptive Server Anywhere also gives you the ability to disconnect other users from a given database; for more information about doing this in Sybase Central, see Managing connected users.

When a database server is started, it assigns a unique connection ID to each new connection to the server. You can obtain a user's connection-id using the connection_property function to request the connection number. The following statement returns the connection ID of the current connection:

SELECT connection_property( 'number' )
toggle To disconnect from a database (Sybase Central)

  1. Select a database.

  2. Choose Tools > Disconnect.

toggle To disconnect from a database (SQL)

  • Execute a DISCONNECT statement.

Example 1

The following statement shows how to use DISCONNECT from Interactive SQL to disconnect all connections:

DISCONNECT ALL
Example 2

The following statement shows how to use DISCONNECT in Embedded SQL:

EXEC SQL DISCONNECT :conn_name
toggle To disconnect other users from a database (SQL)

  1. Connect to an existing database with DBA authority.

  2. Execute a DROP CONNECTION statement.

Example

The following statement drops the connection with ID number 4.

DROP CONNECTION 4

For more information, see DISCONNECT statement [ESQL] [Interactive SQL], and DROP CONNECTION statement.


Setting properties for database objects

Most database objects (including the database itself) have properties that you can either view or set. Some properties are non-configurable and reflect the settings chosen when you created the database or object. Other properties are configurable.

The best way to view and set properties is to use the property sheets in Sybase Central.

If you are not using Sybase Central, properties can be specified when you create the object with a CREATE statement. If the object already exists, you can modify options with a SET OPTION statement.

toggle To view and edit the properties of a database object (Sybase Central)

  1. In the left pane of Sybase Central, open the folder in which the object resides.

  2. Select the object. The object's properties appear in the right pane of Sybase Central.

  3. In the right pane, click the appropriate tabs to edit the desired properties.

    You can also view and edit properties on the object's property sheet. To view the property sheet, right-click the object and choose Properties from the popup menu.


Setting database options

Database options are configurable settings that change the way the database behaves or performs. In Sybase Central, all of these options are grouped together in the Database Options dialog. In Interactive SQL, you can specify an option in a SET OPTION statement.

toggle To set options for a database (Sybase Central)

  1. Open the desired server.

  2. Right-click the desired database and choose Options from the popup menu.

  3. Edit the desired values.

toggle To set the options for a database (SQL)

  • Specify the desired properties within a SET OPTION statement.

Tips
With the Database Options dialog, you can also set database options for specific users and groups (when you open this dialog for a user or group, it is called the User Options dialog or Group Options dialog respectively).

When you set options for the database itself, you are actually setting options for the PUBLIC group in that database because all users and groups inherit option settings from PUBLIC.


Specifying a consolidated database

In Sybase Central, you can specify the consolidated database for SQL Remote replication. The consolidated database is the one that serves as the "master" database in the replication setup. The consolidated database contains all of the data to be replicated, while its remote databases may only contain their own subsets of the data. In case of conflict or discrepancy, the consolidated database is considered to have the primary copy of all data.

For more information, see Consolidated and remote databases.

toggle To set a consolidated database (Sybase Central)

  1. Right-click the desired database and choose Properties from the popup menu.

  2. Click the SQL Remote tab.

  3. Select the This Remote Database Has a Corresponding Consolidated Database option.

  4. Configure the desired settings.


Displaying system objects in a database

In a database, a table, view, stored procedure, or domain is a system object. System tables store information about the database itself, while system views, procedures, and domains largely support Sybase Transact-SQL compatibility.

In Interactive SQL, you cannot display a list of all system objects, but you can browse the contents of a system table; for more information, see Displaying system tables.

toggle To display system objects in a database (Sybase Central)

  1. Open the desired server.

  2. Right-click the desired connected database and choose Filter Objects by Owner.

  3. Select SYS and dbo, and then click OK.

    The system tables, system views, system procedures, and system domains appear in their respective folders. For example, system tables appear alongside normal tables in the Tables folder.

For more information, see System Tables.


Logging SQL statements as you work with a database

As you work with a database in Sybase Central, the application automatically generates SQL statements depending on your actions. You can keep track of these statements in a separate pane, called Design Details or save the information to a file. The Design Details pane has a tab for each database and database server. The tab for database servers contains the same information as the Server Messages window.

When you work with Interactive SQL, you can also log statements that you execute.

For information about logging statements in Interactive SQL, see Logging commands.

toggle To log SQL statements generated by Sybase Central

  1. From the View menu, choose Design Details.

    The Design Details pane appears at the bottom of the Sybase Central window.

  2. Right-click in the Design Details pane and choose Options from the popup menu.

    The Options dialog appears.

  3. In the resulting dialog, specify the desired settings. If you wish to save the logging information to a file, click the Save button.


Starting a database without connecting

With both Sybase Central and Interactive SQL, you can start a database without connecting to it.

toggle To start a database on a server without connecting (Sybase Central)

  1. Right-click the desired server and choose Start Database from the popup menu.

  2. In the Start Database dialog, type the desired values.

    The database appears under the server as a disconnected database.

toggle To start a database on a server without connecting (SQL)

  1. Start Interactive SQL.

  2. Execute a START DATABASE statement.

Example

Start the database file c:\asa9\sample_2.db as sam2 on the server named sample.

START DATABASE 'c:\asa9\sample_2.db'
AS sam2
ON sample

For more information, see START DATABASE statement [Interactive SQL].


Installing the jConnect metadata support to an existing database

If a database was created without the jConnect metadata support, you can use Sybase Central to install it at a later date.

toggle To add jConnect metadata support to an existing database (Sybase Central)

  1. Connect to the database you want to upgrade.

  2. In the left pane, select the Adaptive Server Anywhere plug-in.

  3. In the right pane, click the Utilities tab.

  4. In the right pane, double-click Upgrade Database.

  5. Click Next on the introductory page of the wizard.

  6. Select the database you want to upgrade from the list. Click Next.

  7. You can choose to create a backup of the database if you wish. Click Next.

  8. Select the Install jConnect Meta-Information Support option.

  9. Follow the remaining instructions in the wizard.


Working with tables

When a database is first created, the only tables in the database are the system tables. System tables hold the database schema.

This section describes how to create, alter, and delete tables. You can execute the examples in Interactive SQL, but the SQL statements are independent of the administration tool you use.

For more information, see Editing table values in Interactive SQL.

To make it easier for you to re-create the database schema when necessary, create command files to define the tables in your database. The command files should contain the CREATE TABLE and ALTER TABLE statements.

For more information about groups, tables, and connecting as another user, see Referring to tables owned by groups and Database object names and prefixes.

Creating tables
Altering tables
Deleting tables
Browsing the information in tables
Managing primary keys
Managing foreign keys
Working with computed columns
Copying tables or columns within/between databases
Displaying system tables


Creating tables

When a database is first created, the only tables in the database are the system tables, which hold the database schema. You can then create new tables to hold your actual data, either with SQL statements in Interactive SQL or with Sybase Central.

There are two types of tables that you can create:

  • Base table A table that holds persistent data. The table and its data continue to exist until you explicitly delete the data or drop the table. It is called a base table to distinguish it from temporary tables and from views.

  • Temporary table Data in a temporary table is held for a single connection only. Global temporary table definitions (but not data) are kept in the database until dropped. Local temporary table definitions and data exist for the duration of a single connection only.

    For more information about temporary tables, see Working with temporary tables.

Tables consist of rows and columns. Each column carries a particular kind of information, such as a phone number or a name, while each row specifies a particular entry.

toggle To create a table (Sybase Central)

  1. Connect to the database.

  2. Open the Tables folder.

  3. From the File menu, choose New > Table.

    The Table Creation wizard appears.

  4. In the Table Creation wizard:

    • Type a name for the new table.

    • Select an owner for the table.

    • Create a primary key for the table.

    • Configure the other desired options.

  5. Click Finish.

  6. On the Columns tab in the right pane, you can add columns to the table.

  7. Choose File > Save when finished.

toggle To create a table (SQL)

  1. Connect to the database with DBA authority.

  2. Execute a CREATE TABLE statement.

Example

The following statement creates a new table to describe qualifications of employees within a company. The table has columns to hold an identifying number, a name, and a type (technical or administrative) for each skill.

CREATE TABLE skill (
   skill_id INTEGER NOT NULL,
   skill_name CHAR( 20 ) NOT NULL,
   skill_type CHAR( 20 ) NOT NULL
)

For more information, see CREATE TABLE statement.


Altering tables

This section describes how to change the structure or column definitions of a table. For example, you can add columns, change various column attributes, or delete columns entirely.

In Sybase Central, you can perform these tasks on the SQL tab in the right pane of Sybase Central. In Interactive SQL, you can perform these tasks with the ALTER TABLE statement.

If you are working with Sybase Central, you can also manage columns (add or remove them from the primary key, change their properties, or delete them) by working with menu commands when you have a column selected in the Columns folder.

For information on altering database object properties, see Setting properties for database objects.

For information on granting and revoking table permissions, see Granting permissions on tables and Revoking user permissions.


Altering tables (Sybase Central)

You can alter tables in Sybase Central on the Columns tab in the right pane. For example, you can add or delete columns, change column definitions, or change table or column properties.

toggle To alter an existing table (Sybase Central)

  1. Connect to the database.

  2. Open the Tables folder.

  3. In the left pane, select the table you want to alter.

  4. Click the Columns tab in the right pane and make the necessary changes.

Tips
You can add columns by selecting a table's Columns tab and choosing File > New Column.

You can delete columns by selecting the column on the Columns tab and choosing Edit > Delete.

You can copy a column to a table by selecting the column on the Columns tab in the right pane and then clicking the Copy button. Select the desired table, click the Columns tab in the right pane, and then click the Paste button.

It is also necessary to click the Save Table button or choose File > Save Table. Changes are not made to the table until then.

For more information, see ALTER TABLE statement.


Altering tables (SQL)

You can alter tables in Interactive SQL using the ALTER TABLE statement.

toggle To alter an existing table (SQL)

  1. Connect to the database with DBA authority.

  2. Execute an ALTER TABLE statement.

Examples

The following command adds a column to the skill table to allow space for an optional description of the skill:

ALTER TABLE skill
ADD skill_description CHAR( 254 )

This statement adds a column called skill_description that holds up to a few sentences describing the skill.

You can also modify column attributes with the ALTER TABLE statement. The following statement shortens the skill_description column of the sample database from a maximum of 254 characters to a maximum of 80:

ALTER TABLE skill
MODIFY skill_description CHAR( 80 )

Any current entries that are longer than 80 characters are trimmed to conform to the 80-character limit, and a warning appears.

The following statement changes the name of the skill_type column to classification:

ALTER TABLE skill
RENAME skill_type TO classification

The following statement deletes the classification column.

ALTER TABLE skill
DROP classification

The following statement changes the name of the entire table:

ALTER TABLE skill
RENAME qualification

These examples show how to change the structure of the database. The ALTER TABLE statement can change just about anything pertaining to a table—you can use it to add or delete foreign keys, change columns from one type to another, and so on. In all these cases, once you make the change, stored procedures, views and any other item referring to this table will no longer work.

For more information, see ALTER TABLE statement, and Ensuring Data Integrity.


Deleting tables

This section describes how to delete tables from a database. You can use either Sybase Central or Interactive SQL to perform this task. In Interactive SQL deleting a table is also called dropping it.

You cannot delete a table that is being used as an article in a SQL Remote publication. If you try to do this in Sybase Central, an error appears.

toggle To delete a table (Sybase Central)

  1. Connect to the database.

  2. Open the Tables folder for that database.

  3. Right-click the table and choose Delete from the popup menu.

toggle To delete a table (SQL)

  1. Connect to the database with DBA authority.

  2. Execute a DROP TABLE statement.

Example

The following DROP TABLE command deletes all the records in the skill table and then removes the definition of the skill table from the database

DROP TABLE skill

Like the CREATE statement, the DROP statement automatically executes a COMMIT statement before and after dropping the table. This makes permanent all changes to the database since the last COMMIT or ROLLBACK. The drop statement also drops all indexes on the table.

For more information, see DROP statement.


Browsing the information in tables

You can use Sybase Central or Interactive SQL to browse the data held within the tables of a database.

If you are working in Sybase Central, view the data in a table by clicking the Data tab in the right pane.

If you are working in Interactive SQL, execute the following statement:

SELECT * FROM table-name

You can edit the data in the table from the Interactive SQL Results tab or from Sybase Central.


Managing primary keys

The primary key is a unique identifier that is comprised of a column or combination of columns with values that do not change over the life of the data in the row. Because uniqueness is essential to good database design, it is best to specify a primary key when you define the table.

This section describes how to create and edit primary keys in your database. You can use either Sybase Central or Interactive SQL to perform these tasks.

Column order in multi-column primary keys
Primary key column order is determined by the order of the columns during table creation. It is not based on the order of the columns as specified in the primary key declaration.

Managing primary keys (Sybase Central)
Managing primary keys (SQL)

Previous Next


Managing primary keys (Sybase Central)

In Sybase Central, the primary key of a table appears in several places:

  • On the Columns tab of the table's property sheet.

  • On the Columns tab in the right pane when a table is selected in the left pane.

The lists in both the table property sheet and on the Columns tab display the primary key columns (along with the non-key columns). The order of the primary key columns is determined by the order of the columns during table creation. This may differ from the actual ordering of columns in the primary key.

toggle To create and edit the primary key (Sybase Central)

  1. Open the Tables folder.

  2. In the left pane, select the desired table.

  3. In the right pane, click the Columns tab.

  4. Change the primary key as desired.

    To make a column a primary key column, place a checkmark in the checkbox beside the column name. Clear the checkbox to remove the column from the primary key.


Managing primary keys (SQL)

You can create and modify the primary key in Interactive SQL using the CREATE TABLE and ALTER TABLE statements. These statements let you set many table attributes, including column constraints and checks.

Columns in the primary key cannot contain NULL values. You must specify NOT NULL on the column in the primary key.

toggle To modify the primary key of an existing table (SQL)

  1. Connect to the database with DBA authority.

  2. Execute a ALTER TABLE statement.

Example 1

The following statement creates the same skill table as before, except that it adds a primary key:

CREATE TABLE skill (
  skill_id INTEGER NOT NULL,
  skill_name CHAR( 20 ) NOT NULL,
  skill_type CHAR( 20 ) NOT NULL,
  primary key( skill_id )
)

The primary key values must be unique for each row in the table which, in this case, means that you cannot have more than one row with a given skill_id. Each row in a table is uniquely identified by its primary key.

Example 2

The following statement adds the columns skill_id and skill_type to the primary key for the skill table:

ALTER TABLE skill
  ADD PRIMARY KEY ( "skill_id", "skill_type" )

If a PRIMARY KEY clause is specified in an ALTER TABLE statement, the table must not already have a primary key that was created by the CREATE TABLE statement or another ALTER TABLE statement.

Example 3

The following statement removes all columns from the primary key for the skill table. Before you delete a primary key, make sure you are aware of the consequences in your database.

ALTER TABLE skill
  DELETE PRIMARY KEY

For more information, see ALTER TABLE statement, and Managing primary keys (Sybase Central).


Managing foreign keys

This section describes how to create and edit foreign keys in your database. You can use either Sybase Central or Interactive SQL to perform these tasks.

Foreign keys are used to relate values in a child table (or foreign table) to those in a parent table (or primary table). A table may have multiple foreign keys that refer to multiple parent tables linking various types of information.


Managing foreign keys (Sybase Central)

In Sybase Central, the foreign key of a table appears on the Foreign Keys tab (located on the right pane when a table is selected).

You cannot create a foreign key in a table if the table contains values for the foreign columns that can't be matched to values in the primary table's primary key.

After you have created a foreign key, you can keep track of it on each table's Referencing Tables tab in the right pane; this folder displays any foreign tables that reference the currently selected table.

toggle To create a new foreign key in a given table (Sybase Central)

  1. Select the table for which you wish to create a foreign key.

  2. Click the Foreign Keys tab in the right pane.

  3. From the File menu, choose New > Foreign Key.

    The Foreign Key Creation wizard appears.

  4. Follow the instructions in the wizard.

toggle To delete a foreign key (Sybase Central)

  1. Select the table for which you wish to delete a foreign key.

  2. Click the Foreign Keys tab in the right pane.

  3. Right-click the foreign key you want to delete and choose Delete from the popup menu.

toggle To display which tables have foreign keys that reference a given table (Sybase Central)

  1. In the left pane, select the desired table.

  2. In the right pane, click the Referencing Tables tab.

Tips
When you create a foreign key using the wizard, you can set properties for the foreign key. To view properties after the foreign key is created, right-click the foreign key on the Foreign Keys tab and choose Properties from the popup menu.

You can view the properties of a referencing table by right-clicking the table on the Referencing Tables tab and choosing Properties from the popup menu.


Managing foreign keys (SQL)

You can create and modify the foreign key in Interactive SQL using the CREATE TABLE and ALTER TABLE statements. These statements let you set many table attributes, including column constraints and checks.

A table can only have one primary key defined, but it may have as many foreign keys as necessary.

toggle To modify the foreign key of an existing table (SQL)

  1. Connect to the database with DBA authority.

  2. Execute an ALTER TABLE statement.

Example 1

You can create a table named emp_skill, which holds a description of each employee's skill level for each skill in which they are qualified, as follows:

CREATE TABLE emp_skill(
   emp_id INTEGER NOT NULL,
   skill_id INTEGER NOT NULL,
   "skill level" INTEGER NOT NULL,
   PRIMARY KEY( emp_id, skill_id ),
   FOREIGN KEY REFERENCES employee,
   FOREIGN KEY REFERENCES skill
)

The emp_skill table definition has a primary key that consists of two columns: the emp_id column and the skill_id column. An employee may have more than one skill, and so appear in several rows, and several employees may possess a given skill, so that the skill_id column may appear several times. However, there may be no more than one entry for a given employee and skill combination.

The emp_skill table also has two foreign keys. The foreign key entries indicate that the emp_id column must contain a valid employee number from the employee table, and that the skill_id column must contain a valid entry from the skill table.

Example 2

You can add a foreign key called foreignkey to the existing table skill and reference this foreign key to the primary key in the table contact, as follows:

ALTER TABLE skill
ADD FOREIGN KEY "foreignkey" ("skill_id")
REFERENCES "DBA"."contact" ("id")

This example creates a relationship between the skill_id column of the table skill (the foreign table) and the id column of the table contact (the primary table). The "DBA" signifies the owner of the table contact.

Example 3

You can specify properties for the foreign key as you create it. For example, the following statement creates the same foreign key as in Example 2, but it defines the foreign key as NOT NULL along with restrictions for when you update or delete.

ALTER TABLE skill
ADD NOT NULL FOREIGN KEY "foreignkey" ("skill_id")
REFERENCES "DBA"."contact" ("id")
ON UPDATE RESTRICT
ON DELETE RESTRICT

In Sybase Central, you can also specify properties in the Foreign Key Creation wizard or on the foreign key's property sheet.

For more information, see ALTER TABLE statement, and Managing foreign keys (Sybase Central).


Working with computed columns

A computed column is a column whose value is an expression that can refer to the values of other columns, termed dependent columns, in the same row. Computed columns are especially useful in situations where you want to index a complex expression that may include the values of one or more dependent columns. During query optimization, the Adaptive Server Anywhere optimizer automatically attempts to transform a predicate involving a complex expression into one that simply refers to the computed column's definition. For example, suppose that you want to query a table containing summary information about product shipments:

CREATE TABLE SHIPMENTS(
   SHIPMENT_ID   INTEGER NOT NULL PRIMARY KEY,
   SHIPMENT_DATE TIMESTAMP,
   PRODUCT_CODE  CHAR(20) NOT NULL,
   QUANTITY      INTEGER NOT NULL,
   TOTAL_PRICE   DECIMAL(10,2) NOT NULL )

In particular, the query is to return those shipments whose average cost is between two and four dollars. The query could be written as

SELECT *
FROM SHIPMENTS
WHERE ( TOTAL_PRICE / QUANTITY ) BETWEEN 2.00 AND 4.00

but the predicate in the WHERE clause is not sargable since it does not refer to a single base column. If the size of the SHIPMENTS table is relatively large, an indexed retrieval might be appropriate rather than a sequential scan. You can do this by creating a computed column AVERAGE_COST for the SHIPMENTS table, as follows:

ALTER TABLE shipments
ADD average_cost DECIMAL(30,22)
COMPUTE (total_price / quantity)

CREATE INDEX idx_avg_cost ON shipments( average_cost ASC )

Choosing the type of the computed column is important; the Adaptive Server Anywhere optimizer replaces only complex expressions by a computed column if the data type of the expression in the query precisely matches the data type of the computed column. To determine what the type of any expression is, you can use the EXPRTYPE() built-in function that returns the expression's type in ready-to-use SQL terms:

SELECT EXPRTYPE( 'SELECT (TOTAL_PRICE / QUANTITY ) AS X FROM
SHIPMENTS', 1 )
FROM DUMMY

For the SHIPMENTS table, the above query returns NUMERIC(30,22). During optimization, the Adaptive Server Anywhere optimizer rewrites the query above as

SELECT *
FROM SHIPMENTS
WHERE AVERAGE_COST BETWEEN 2.00 AND 4.00

and the predicate in the WHERE clause is now a sargable one, making it possible for the optimizer to choose an indexed scan, using the new idx_avg_cost index, for the query's access plan. Values of computed columns are automatically maintained by the database server as rows are inserted and updated. Most applications should never need to update or insert computed column values directly; however, since computed columns are base columns like any other, they can be directly referenced in predicates and in expressions when it makes sense to do so.

Although you can use INSERT, UPDATE, or LOAD TABLE statements to insert values in computed columns, this is neither the recommended nor intended application of this feature. The LOAD TABLE statement permits the optional computation of computed columns, which can aid the DBA during complex unload/reload sequences, or when it is vital that the value of a computed column stay constant when the COMPUTE expression refers to non-deterministic values, such as CURRENT TIMESTAMP.

Modifying computed column expressions

You can change the expression used in a computed column with the ALTER TABLE statement. The following statement changes the expression that a computed column is based on.

ALTER TABLE table_name
ALTER column-name SET COMPUTE ( new-expression )

The column is recalculated when this statement is executed. If the new expression is invalid, the ALTER TABLE statement fails.

The following statement stops a column from being a computed column.

ALTER TABLE table_name
ALTER column-name DROP COMPUTE

Existing values in the column are not changed when this statement is executed, but they are no longer updated automatically.


Inserting and updating computed columns

Computed columns restrict the allowed INSERT and UPDATE statements.

  • No direct inserts or updates You cannot insert a value directly into a computed column. If the column called Computed is a computed column, the following statement fails with a Duplicate Insert Column error:

    -- Incorrect statement
INSERT INTO T1 (id, computed)
VALUES( 3006, 'bad insert statement' )

    Similarly, you cannot use UPDATE statements to directly change the value of a computed column.

  • Listing column names You must always explicitly specify column names in INSERT statements on tables with computed columns.

  • Triggers If you define triggers on a computed column, any INSERT or UPDATE statement that affects the column fires the triggers.


When computed columns are recalculated

Computed columns are recalculated under the following circumstances:

  • Any column is deleted, added, or renamed.

  • The table is renamed.

  • Any column's data type or COMPUTE clause is modified.

  • A row is inserted.

  • A row is updated.

Computed columns are not recalculated when queried. If you use a time-dependent expression, or one that depends on the state of the database in some other way, then the computed column may not give a proper result.


Copying tables or columns within/between databases

With Sybase Central, you can copy existing tables or columns and insert them into another location in the same database or into a completely different database.

If you are not using Sybase Central, see one of the following locations:

  • To insert SELECT statement results into a given location, see SELECT statement.

  • To insert a row or selection of rows from elsewhere in the database into a table, see INSERT statement.


Displaying system tables

In a database, a table, view, stored procedure, or domain is a system object. System tables store the database's schema, or information about the database itself. System views, procedures, and domains largely support Sybase Transact-SQL compatibility.

All the information about tables in a database appears in the system tables. The information is distributed among several tables.

For more information, see System Tables.

toggle To display system tables (Sybase Central)

  1. Right-click the desired connected database and choose Filter Objects by Owner from the popup menu.

  2. Select the checkbox beside SYS and click OK.

    The system tables, system views, system procedures, and system domains appear in their respective folders. For example, system tables appear alongside normal tables in the Tables folder.

toggle To browse system tables (SQL)

  1. Connect to a database.

  2. Execute a SELECT statement, specifying the system table you want to browse. The system tables are owned by the SYS user ID.

Example

Display the contents of the table sys.systable on the Results tab in the Results pane.

SELECT *
FROM SYS.SYSTABLE


Working with views

Views are computed tables. You can use views to show database users exactly the information you want to present, in a format you can control.

Similarities between views and base tables

Views are similar to the permanent tables of the database (a permanent table is also called a base table) in many ways:

  • You can assign access permissions to views just as to base tables.

  • You can perform SELECT queries on views.

  • You can perform UPDATE, INSERT, and DELETE operations on some views.

  • You can create views based on other views.

Differences between views and permanent tables

There are some differences between views and permanent tables:

  • You cannot create indexes on views.

  • You cannot perform UPDATE, INSERT, and DELETE operations on all views.

  • You cannot assign integrity constraints and keys to views.

  • Views refer to the information in base tables, but do not hold copies of that information. Views are recomputed each time you invoke them.

Benefits of tailoring access

Views let you tailor access to data in the database. Tailoring access serves several purposes:

  • Improved security By allowing access to only the information that is relevant.

  • Improved usability By presenting users and application developers with data in a more easily understood form than in the base tables.

  • Improved consistency By centralizing in the database the definition of common queries.

Creating views
Using views
Using the WITH CHECK OPTION clause
Modifying views
Deleting views
Browsing the information in views
Views in the system tables


Creating views

When you browse data, a SELECT statement operates on one or more tables and produces a result set that is also a table. Just like a base table, a result set from a SELECT query has columns and rows. A view gives a name to a particular query, and holds the definition in the database system tables.

Suppose you frequently need to list the number of employees in each department. You can get this list with the following statement:

SELECT dept_ID, count(*)
FROM employee
GROUP BY dept_ID

You can create a view containing the results of this statement using either Sybase Central or Interactive SQL.

toggle To create a new view (Sybase Central)

  1. Connect to a database.

  2. Open the Views folder for that database.

  3. From the File menu, choose New > View.

    The View Creation wizard appears.

  4. Follow the instructions in the wizard. When the wizard exits, you can edit the code on the SQL tab in the right pane.

  5. Complete the code by entering the table and the columns you want to use. For the example above, type employee and dept_ID.

  6. From the File menu, choose Save View.

    New views appear in the Views folder.

toggle To create a new view (SQL)

  1. Connect to a database.

  2. Execute a CREATE VIEW statement.

Example

Create a view called DepartmentSize that contains the results of the SELECT statement given at the beginning of this section:

CREATE VIEW DepartmentSize AS
SELECT dept_ID, count(*)
FROM employee
GROUP BY dept_ID

Since the information in a view is not stored separately in the database, referring to the view executes the associated SELECT statement to retrieve the appropriate data.

On one hand, this is good because it means that if someone modifies the employee table, the information in the DepartmentSize view is automatically brought up to date. On the other hand, complicated SELECT statements may increase the amount of time SQL requires to find the correct information every time you use the view.

For more information, see CREATE VIEW statement.


Using views

Restrictions on SELECT statements

There are some restrictions on the SELECT statements you can use as views. In particular, you cannot use an ORDER BY clause in the SELECT query. A characteristic of relational tables is that there is no significance to the ordering of the rows or columns, and using an ORDER BY clause would impose an order on the rows of the view. You can use the GROUP BY clause, subqueries, and joins in view definitions.

To develop a view, tune the SELECT query by itself until it provides exactly the results you need in the format you want. Once you have the SELECT query just right, you can add a phrase in front of the query to create the view:

CREATE VIEW view-name AS
Updating views

UPDATE, INSERT, and DELETE statements are allowed on some views, but not on others, depending on its associated SELECT statement.

You cannot update views containing aggregate functions, such as COUNT(*). Nor can you update views containing a GROUP BY clause in the SELECT statement, or views containing a UNION operation. In all these cases, there is no way to translate the UPDATE into an action on the underlying tables.

Copying views

In Sybase Central, you can copy views between databases. To do so, select the view in the right pane of Sybase Central and drag it to the Views folder of another connected database. A new view is then created, and the original view's code is copied to it.

Note that only the view code is copied to the new view. The other view properties, such as permissions, are not copied.


Using the WITH CHECK OPTION clause

Even when INSERT and UPDATE statements are allowed against a view, it is possible that the inserted or updated rows in the underlying tables may not meet the requirements for the view itself. For example, the view has no new rows even though the INSERT or UPDATE modified the underlying tables.

Examples using the WITH CHECK OPTION clause

The following example illustrates the usefulness of the WITH CHECK OPTION clause. This optional clause is the final clause in the CREATE VIEW statement.

toggle To create a view displaying the employees in the sales department (SQL)

  1. Type the following statements:

    CREATE VIEW sales_employee
AS SELECT emp_id,
      emp_fname,
      emp_lname,
      dept_id
FROM employee
WHERE dept_id = 200

    The contents of this view are as follows:

    SELECT *
FROM sales_employee

    They appear in Interactive SQL as follows:

    emp_id | emp_fname | emp_lname | dept_id
    129 | Philip | Chin | 200
    195 | Marc | Dill | 200
    299 | Rollin | Overbey | 200
    467 | James | Klobucher | 200
    ... ... ... ...

  2. Transfer Philip Chin to the marketing department This view update causes the entry to vanish from the view, as it no longer meets the view selection criterion.

    UPDATE sales_employee
SET dept_id = 400
WHERE emp_id = 129

  3. List all employees in the sales department Inspect the view.

    SELECT *
FROM sales_employee
    Emp_id | Emp_fname | Emp_lname | Dept_id
    129 | Philip | Chin | 200
    195 | Marc | Dill | 200
    299 | Rollin | Overbey | 200
    467 | James | Klobucher | 200
    ... ... ... ...

  4. List all employees in the sales department Inspect the view.

    SELECT *
FROM sales_employee
    Emp_id | emp_fname | emp_lname | dept_id
    195 | Marc | Dill | 200
    299 | Rollin | Overbey | 200
    467 | James | Klobucher | 200
    641 | Thomas | Powell | 200
    ... ... ... ...

When you create a view using the WITH CHECK OPTION, any UPDATE or INSERT statement on the view is checked to ensure that the new row matches the view condition. If it does not, the operation causes an error and is rejected.

The following modified sales_employee view rejects the update statement, generating the following error message:

Invalid value for column 'dept_id' in table 'employee'

  • Create a view displaying the employees in the sales department (second attempt) Use WITH CHECK OPTION this time.

    CREATE VIEW sales_employee
AS SELECT emp_id, emp_fname, emp_lname, dept_id
    FROM employee
    WHERE dept_id = 200
WITH CHECK OPTION
The check option is inherited

If a view (say V2) is defined on the sales_employee view, any updates or inserts on V2 that cause the WITH CHECK OPTION criterion on sales_employee to fail are rejected, even if V2 is defined without a check option.


Modifying views

You can modify a view using both Sybase Central and Interactive SQL. When doing so, you cannot rename an existing view directly. Instead, you must create a new view with the new name, copy the previous code to it, and then delete the old view.

In Sybase Central, you can edit the code of views, procedures, and functions on the object's SQL tab in the right pane. You edit a view in a separate window by right-clicking the view and choosing Edit In New Window from the popup menu. In Interactive SQL, you can use the ALTER VIEW statement to modify a view. The ALTER VIEW statement replaces a view definition with a new definition, but it maintains the permissions on the view.

For more information on altering database object properties, see Setting properties for database objects.

For more information on setting permissions, see Granting permissions on tables and Granting permissions on views. For information about revoking permissions, see Revoking user permissions.

toggle To edit a view definition (Sybase Central)

  1. Open the Views folder.

  2. Select the desired view.

  3. In the right pane, click the SQL tab and edit the view's code.

    Tip
    If you wish to edit multiple views, you may wish to open separate windows for each view rather than editing each view on the SQL tab in the right pane. You can open a separate window by right-clicking a view and choosing Edit In New Window from the popup menu.
toggle To edit a view definition (SQL)

  1. Connect to a database with DBA authority or as the owner of the view.

  2. Execute an ALTER VIEW statement.

Example

Rename the column names of the DepartmentSize view (described in the Creating views section) so that they have more informative names.

ALTER VIEW DepartmentSize
  (Dept_ID, NumEmployees)
AS
  SELECT dept_ID, count(*)
  FROM Employee
  GROUP BY dept_ID

For more information, see ALTER VIEW statement.


Deleting views

You can delete a view in both Sybase Central and Interactive SQL.

toggle To delete a view (Sybase Central)

  1. Open the Views folder.

  2. Right-click the desired view and choose Delete from the popup menu.

toggle To delete a view (SQL)

  1. Connect to a database with DBA authority or as the owner of the view.

  2. Execute a DROP VIEW statement.

Examples

Remove a view called DepartmentSize.

DROP VIEW DepartmentSize

For more information, see DROP statement.


Browsing the information in views

To browse the data held within the views, you can use the Interactive SQL utility. This utility lets you execute queries to identity the data you want to view. For more information about using these queries, see Queries: Selecting Data from a Table.

If you are working in Sybase Central, you can right-click a view on which you have permission and choose View Data in Interactive SQL from the popup menu. This command opens Interactive SQL with the view contents displayed on the Results tab in the Results pane. To browse the view, Interactive SQL executes a select * from owner.view statement.


Views in the system tables

All the information about views in a database is held in the system table SYS.SYSTABLE. The information is presented in a more readable format in the system view SYS.SYSVIEWS. For more information about these, see SYSTABLE system table, and SYSVIEWS system view.

You can use Interactive SQL to browse the information in these tables. Type the following statement in the SQL Statements pane to see all the columns in the SYS.SYSVIEWS view:

SELECT *
FROM SYS.SYSVIEWS

To extract a text file containing the definition of a specific view, use a statement such as the following:

SELECT viewtext FROM SYS.SYSVIEWS
   WHERE viewname = 'DepartmentSize';
OUTPUT TO viewtext.sql
FORMAT ASCII


Working with indexes

Performance is an important consideration when designing and creating your database. Indexes can dramatically improve the performance of statements that search for a specific row or a specific subset of the rows. On the other hand, indexes take up additional disk space and may slow inserts, updates, and deletes.

Choosing a set of indexes
When to use indexes
Use indexes for frequently-searched columns
Using clustered indexes
Creating indexes
Validating indexes
Dropping indexes
Index Consultant overview
Starting the Index Consultant
Stopping the Index Consultant
Understanding the Index Consultant
Indexes in the system tables


Choosing a set of indexes

Choosing an appropriate set of indexes for a database is an important part of optimizing performance. Identifying an appropriate set can also be a demanding problem. The performance benefits from some indexes may be significant, but there are also costs associated with indexes, in both storage space and in overhead when modifying data.

The Index Consultant is a tool to assist you in proper selection of indexes. It analyzes either a single query or a set of operations, and recommends which indexes to add to your database. It also notifies you of indexes that are unused.

For more information about the Index Consultant, see Starting the Index Consultant.


When to use indexes

An index provides an ordering on the rows in a column or columns of a table. An index is like a telephone book that initially sorts people by surname, and then sorts identical surnames by first names. This ordering speeds up searches for phone numbers for a particular surname, but it does not provide help in finding the phone number at a particular address. In the same way, a database index is useful only for searches on a specific column or columns.

Indexes get more useful as the size of the table increases. The average time to find a phone number at a given address increases with the size of the phone book, while it does not take much longer to find the phone number of, say, K. Kaminski, in a large phone book than in a small phone book.

The database server query optimizer automatically uses an index when a suitable index exists and when using one will improve performance.

There are some downsides to creating indexes. In particular, any indexes must be maintained along with the table itself when the data in a column is modified, so that the performance of inserts, updates, and deletes can be affected by indexes. For this reason, unnecessary indexes should be dropped. Use the Index Consultant to identify unnecessary indexes.

For more information about the Index Consultant, see Starting the Index Consultant.


Use indexes for frequently-searched columns

Indexes require extra space and may slightly reduce the performance of statements that modify the data in the table, such as INSERT, UPDATE, and DELETE statements. However, they can improve search performance dramatically and are highly recommended whenever you search data frequently.

For more information about performance, see Using indexes.

Adaptive Server Anywhere automatically indexes primary key and foreign key columns. Thus, manually creating an index on a key column is not necessary and generally not recommended. If a column is only part of a key, an index may help.

Adaptive Server Anywhere automatically uses indexes to improve the performance of any database statement whenever it can. There is no need to explicitly refer to indexes once they are created. Also, the index is updated automatically when rows are deleted, updated or inserted.

Index hints

Adaptive Server Anywhere lets you supply index hints, which override the optimizer's choice of query access plan by forcing the use of a particular index. This feature should be used only by advanced users and database administrators. It may lead to poor performance.

To supply an index hint, add a FORCE INDEX or WITH ( INDEX () ) clause to your query. For more information, see FROM clause.

For information on altering database object properties, see Setting properties for database objects.


Using clustered indexes

Although standard indexes can dramatically improve the performance of statements that search for a specific row or a specific subset of the rows, two rows appearing sequentially in the index do not necessarily appear on the same page in the database.

However, you can further improve the performance of indexes by creating clustered indexes. Clustered indexes in Adaptive Server Anywhere store the table rows in approximately the same order as they appear in the corresponding index.

Using the clustered index feature increases the chance that the two rows will appear on the same page in the database. This can lead to performance benefits by further reducing the number of times each page needs to be read into memory.

For example, in a case where you select two rows that appear sequentially in a clustered index, it is possible that you are retrieving two rows that appear sequentially on the same page, thus reducing the number of pages to read into memory by half.

The clustering of indexes in Adaptive Server Anywhere is approximate. While the server attempts to preserve the key order, total clustering is not guaranteed. As well, the clustering degrades over time, as more and more rows are inserted into your database.

You can implement one clustered index per table, using the following statements:

  • The CREATE TABLE statement

  • The ALTER TABLE statement

  • The CREATE INDEX statement

  • The DECLARE LOCAL TEMPORARY TABLE statement

Several statements work in conjunction with each other to allow you to maintain and restore the clustering effect:

  • The UNLOAD TABLE statement allows you to unload a table in the order of the index key.

  • The LOAD TABLE statement inserts rows into the table in the order of the index key.

  • The INSERT statement attempts to put new rows on the same table page as the one containing adjacent rows as per the primary key order.

  • The REORGANIZE table statement can restore the clustering by rearranging the rows according to the clustering index. On tables where clustering is not specified, tables are ordered using the primary key.

The Optimizer assumes that the table rows are stored in key order and costs index scans accordingly.


Creating indexes

Indexes are created on one or more columns of a specified table. You can create indexes on base tables or temporary tables, but you cannot create an index on a view. To create an individual index, you can use either Sybase Central or Interactive SQL. You can use the Index Consultant to guide you in a proper selection of indexes for your database.

toggle To create a new index for a given table (Sybase Central)

  1. Open the Indexes folder.

  2. From the File menu, choose New > Index.

    The Index Creation wizard appears.

  3. Name the index and select the table from the list. Click Next.

  4. Follow the instructions in the wizard.

    New indexes appear in the Indexes folder.

toggle To create a new index for a given table (SQL)

  1. Connect to a database with DBA authority or as the owner of the table on which the index is created.

  2. Execute a CREATE INDEX statement.

In addition to creating indexes on one or more columns in a table, you can create indexes on a built-in function using a computed column. For more information, see CREATE INDEX statement.

Example

To speed up a search on employee surnames in the sample database, you could create an index called EmpNames with the following statement:

CREATE INDEX EmpNames
ON employee (emp_lname, emp_fname)

For more information, see CREATE INDEX statement, and Monitoring and Improving Performance.


Validating indexes

You can validate an index to ensure that every row referenced in the index actually exists in the table. For foreign key indexes, a validation check also ensures that the corresponding row exists in the primary table, and that their hash values match. This check complements the validity checking carried out by the VALIDATE TABLE statement.

Validate tables or entire databases only when no connections are making changes to the database; otherwise, spurious errors may be reported indicating some form of database corruption even though no corruption actually exists.

toggle To validate an index (Sybase Central)

  1. Connect to a database with DBA authority or as the owner of the table on which the index is created.

  2. In the left pane, open the Indexes folder.

  3. Right-click the desired index and choose Validate from the popup menu.

toggle To validate an index (SQL)

  1. Connect to a database with DBA authority or as the owner of the table on which the index is created.

  2. Execute a VALIDATE INDEX statement.

toggle To validate an index (command line)

  1. Open a command prompt.

  2. Run the dbvalid utility.

Examples

Validate an index called EmployeeIndex. If you supply a table name instead of an index name, the primary key index is validated.

VALIDATE INDEX EmployeeIndex

Validate an index called EmployeeIndex. The -i switch specifies that each object name given is an index.

dbvalid –i EmployeeIndex

For more information, see VALIDATE INDEX statement, and The Validation utility.


Dropping indexes

If an index is no longer required, you can remove it from the database in Sybase Central or in Interactive SQL.

toggle To drop an index (Sybase Central)

  1. Connect to a database with DBA authority or as the owner of the table on which the index is created.

  2. In the left pane, open the Indexes folder.

  3. Right-click the desired index and choose Delete from the popup menu.

toggle To drop an index (SQL)

  1. Connect to a database with DBA authority or as the owner of the table associated with the index.

  2. Execute a DROP INDEX statement.

Example

The following statement removes the index from the database:

DROP INDEX EmpNames

For more information, see DROP statement.


Index Consultant overview

The selection of a proper set of indexes can make a big difference to the performance of your database. To help you in the task of selecting such a set of indexes, Adaptive Server Anywhere includes an Index Consultant. The Index Consultant guides you through the process of selecting indexes for a single query or for a set of database requests (called a workload). It creates many different sets of virtual indexes. For each set, the Index Consultant optimizes queries and other requests as if those virtual indexes were present. The Index Consultant then gathers the results of these explorations into a set of recommendations.

There are several stages in the Index Consultant's work. Understanding these stages helps you make the most of the tool.

  1. Starting the Index Consultant.

    You can run the Index Consultant from either Interactive SQL or from Sybase Central. Access the Index Consultant from Interactive SQL to analyze indexes for a single query, and from Sybase Central to analyze indexes for a workload.

    For information on how to start the Index Consultant, see Starting the Index Consultant.

  2. Capturing a workload.

    A workload is a set of queries or other data manipulation statements over which the Index Consultant tries to optimize performance. Depending on your goals, you may wish to make your workload a representative set of operations, or you may wish to identify a set of key bottleneck operations. The Index Consultant can capture one or more workloads, and can store them for later analysis.

    For more information, see Understanding workloads.

  3. Analyzing the workload.

    The Index Consultant analyzes a workload or single query by generating candidate indexes and exploring their effect on performance. To explore the effect of different candidate indexes, the Index Consultant repeatedly re-optimizes the queries in the workload under different sets of indexes. It does not execute the queries.

    The Index Consultant can also store the results of multiple analyses on any workload, using different settings.

    When analyzing a workload, the Index Consultant presents you with a set of options:

    • Recommend clustered indexes If this option is selected, the Index Consultant analyzes the effect of clustered indexes as well as unclustered indexes.

      Properly selected clustered indexes can provide significant performance improvements over unclustered indexes for some workloads, but you must reorganize the table (using the REORGANIZE TABLE statement) for them to be effective. In addition, the analysis takes longer if the effects of clustered indexes are considered.

      For more information about clustered indexes, see Using clustered indexes.

    • Keep existing secondary indexes The Index Consultant can carry out its analysis by either maintaining the existing set of secondary indexes in the database, or by ignoring the existing secondary indexes. A secondary index is an index that is not a unique constraint or a primary or foreign key. Indexes that are present to enforce referential integrity constraints are always considered when selecting access plans.

    The analysis includes the following steps:

    • Generate candidate indexes For each workload, the Index Consultant generates a set of candidate indexes. Creating a real index on a large table can be a time consuming operation, so the Index Consultant creates its candidates as virtual indexes. A virtual index cannot be used to actually execute queries, but the query optimizer can use virtual indexes to estimate the cost of execution plans as if such an index were available. Virtual indexes allow the Index Consultant to carry out "what-if" analysis without the expense of creating and managing real indexes. Virtual indexes have a limit of four columns.

    • Testing the benefits and costs of candidate indexes The Index Consultant asks the Adaptive Server Anywhere query optimizer to estimate the cost of executing the queries in the workload, with and without different combinations of candidate indexes.

    • Generating recommendations The Index Consultant assembles the results of the query costs and sorts the indexes by the total benefit they provide. It provides a SQL script, which you can run to carry out the recommendations or which you can save for your own review and analysis.

    For more information, see Understanding the analysis.

  4. Implementing the recommendations.

    The Index Consultant provides a SQL script that you can run to implement its recommendations. Before doing so, you may wish to assess the recommendations in the light of your own knowledge of your database.

    Using the Index Consultant with Interactive SQL
    The Index Consultant can only analyze one statement at a time from Interactive SQL.

    For more information, see Assessing the recommendations, and Implementing the recommendations.


Starting the Index Consultant

The Index Consultant guides you in the proper selection of indexes. You can use the Index Consultant in the following ways:

  • Interactive SQL You can use the Index Consultant from Interactive SQL to analyze the benefits of indexes for an individual query.

  • Sybase Central You can use the Index Consultant from Sybase Central to analyze the benefits of indexes for a workload, or set of database requests.

toggle To start the Index Consultant (Sybase Central)

  1. In the left pane of Sybase Central, right-click the Indexes folder.

  2. From the popup menu, choose Index Consultant.

toggle To start the Index Consultant (Interactive SQL)

  1. Enter a query that you wish to analyze into the SQL Statements pane of Interactive SQL.

  2. Choose Tools > Index Consultant.


Stopping the Index Consultant

The Index Consultant does have an impact on database performance while it is capturing a workload for analysis. For this reason, the database server window displays an informational message while the Index Consultant is capturing a workload.

Usually, the Index Consultant is stopped from the Sybase Central user interface. There may be occasions when it is necessary to stop the Index Consultant from another machine: for example, if the Index Consultant is inadvertently left running.

To pause or stop the capturing of a workload, call the sa_pause_workload_capture procedure or the sa_stop_workload_capture, respectively:

call sa_pause_workload_capture;
call sa_stop_workload_capture;

To stop the Index Consultant, call the sa_stop_index_consultant system stored procedure:

call sa_stop_index_consultant


Understanding the Index Consultant

Selecting the best set of indexes for a database is not a problem that has a single well-defined answer. The recommendations of the Index Consultant are based on an extensive search of the outcomes of alternative indexing schemes, and careful analysis of the costs and benefits associated with indexes. Nevertheless, the nature of the problem is such that the Index Consultant recommendations cannot be guaranteed to always lead to an optimal set of indexes.

This section describes some aspects of how the Index Consultant works. The goal of the section is to provide information that enables you to better judge the recommendations it provides.


Understanding workloads

The first step of Index Consultant operation is to capture a workload of data manipulation and query operations. It does this by capturing information as an application or set of applications carries out operations on the database.

The workload consists of all SELECT, INSERT, UPDATE, and DELETE statements executed during the capture step. The context of these operations is not captured as part of the workload. For example, although queries executed as part of a stored procedure, trigger, or event handler are captured as part of a workload, the surrounding code is not captured. This leads to the following consequences:

  • Parameters are not captured.

    Parameterized SQL statements are stored by substituting an appropriate literal value with the statement definition. For example, if a query with a parameter in the WHERE clause is executed 15 times with different values for the parameter, the Index Consultant captures 15 distinct queries, each with a separate constant instead of the parameter.

  • Queries against temporary tables cannot be analyzed.

    Although queries against temporary tables are collected as part of the workload, the data present in the temporary table is not captured. Consequently, the query cannot be analyzed during the analysis step. The Index Consultant cannot provide recommendations for suitable indexes on temporary tables.

  • Connection state is not entirely captured.

    The connection state includes the set of database options in effect when a query is executed. The OPTIMIZATION_GOAL option often has a major effect on the execution plan chosen by the optimizer, and is stored along with the query. Other options are not stored, however.

  • Server state is not captured.

    The server state includes whether data is available in cache or whether it must be fetched from disk. It also includes the effect of concurrent operations.

Caution Do not change the database schema during the workload capture step. Do not change the database schema between the capture step and the analysis step. Such changes invalidate the Index Consultant recommendations.


Understanding the analysis

The analysis step is carried out by repeatedly carrying out the following set of operations:

  1. Create a candidate set of virtual indexes.

    A virtual index contains no actual data and cannot be used for actual query execution. It can be used by the optimizer when selecting an appropriate execution plan for a query. The Index Consultant generates many alternative sets of virtual indexes.

  2. Optimize the workload operations for this candidate set of virtual indexes.

    The Index Consultant retrieves the plan for each statement in the workload, as chosen by the Adaptive Server Anywhere query optimizer. The optimizer considers applicable virtual indexes from the candidate set for each statement. However, the statements are not executed. The Index Consultant does not modify user data.

    For each query, the query optimizer compares the execution cost of many alternative execution plans. It estimates the execution cost based on an internal cost model. One important choice that influences the cost of each execution plan is which tables to access using an index, and which to access without using an index. Each set of virtual indexes opens up new execution plan alternatives and closes others.

    The cost model depends on the state of the database server. Specifically, although the Index Consultant itself does not read data from disk or execute operations against the database, the cost model depends on which data is in cache and which must be accessed from disk. Therefore, running the Index Consultant may not generate the same recommendations each time you run an analysis on a particular workload. For example, running the Index Consultant on a database server that has just started up (and so has no data in cache) may provide different recommendations to running it on a database server that has been in operation for some time.

    For more information about the cost model, see Optimizer estimates and histograms.


Understanding the recommendations

The Index Consultant provides a set of tabs with the results of a given analysis. The results of an analysis can be saved for later review.

Summary tab

The Summary tab provides an overview of the workload and the analysis, including such information as the number of queries in the workload, the number of recommended indexes, the number of pages required for the recommended indexes, and the benefit that the recommended indexes are expected to yield. The benefit number is measured in internal units of cost.

Recommended Indexes tab

The Recommended Indexes tab contains data about each of the recommended indexes. Among the information provided is the following:

  • Clustered Each table can have at most one clustered index. In some cases, a clustered index can provide significantly more benefit than an unclustered index.

    For more information about clustered indexes, see Using clustered indexes.

  • Pages The estimated number of database pages required to hold the index if you choose to create it.

    For more information about database page sizes, see The Initialization utility.

  • Relative Benefit A number from one to ten, indicating the estimated overall benefit of creating the specified index. A higher number indicates a greater estimated benefit.

    The relative benefit is computed using an internal algorithm, separately from the Total Cost Benefit column. There are several factors included in estimating the relative benefit that do not appear in the total cost benefit. For example, it can happen that the presence of one index dramatically affects the benefits associated with a second index. In this case, the relative benefit attempts to estimate the separate impact of each index.

    For more information, see Assessing the recommendations.

  • Total Benefit The cost decrease associated with the index, summed over all operations in the workload, measured in internal units of cost.

    For more information on the cost model, see Optimizer estimates and histograms.

  • Update Cost Adding an index introduces cost, both in additional storage space and in extra work required when data is modified. The Update Cost column is an estimate of the additional maintenance cost associated with an index. It is measured in internal units of cost.

  • Total Cost Benefit The total benefit minus the update cost associated with the index.

Requests tab

The Requests tab provides a breakdown of the impact of the recommendations for individual requests within the workload. The information includes the estimated cost before and after applying the recommended indexes, as well as the virtual indexes used by the query. A button enables you to view the best execution plan found for the request.

Updates tab

The Updates tab provides a breakdown of the impact of the recommendations.

Unused Indexes tab

The Unused Indexes tab lists indexes that already exist in the database that were not used in the execution of any requests in the workload. Only secondary indexes are listed: that is, neither indexes on primary keys and foreign keys nor unique constraints are listed.

Log tab

The Log tab lists activities that have been completed for this analysis.


Assessing the recommendations

Although the Index Consultant recommendations are based on an extensive search of available options, it is good practice to evaluate the recommendations before implementing them in a production database. For example, you may wish to carry out checks such as the following:

  • Do the proposed indexes match your own expectations? If you know the data in your database well, and you know the queries being run against the database, you may wish to check the usefulness of the proposed indexes against your own knowledge. Perhaps a proposed index only affects a single query that is run rarely, or perhaps it is on a small table and makes relatively little overall impact. Perhaps an index that the Index Consultant suggests should be dropped is used for some other task that was not included in your workload.

  • Are there strong correlations between the effects of proposed indexes? The index recommendations attempt to evaluate the relative benefit of each index separately. It may be the case, however, that two indexes are of use only if both exist (a query may use both if they exist, and none if either is missing). You may want to study the Requests tab and inspect the query plans to see how the proposed indexes are being used.

  • Are you able to re-organize a table when creating a clustered index? To take full advantage of a clustered index, you should reorganize the table on which it is created using the REORGANIZE TABLE statement. If the Index Consultant recommends many clustered indexes, you may have to unload and reload your database to get the full benefit. Unloading and reloading tables can be a time-consuming operation and can require large disk space resources. You may want to confirm that you have the time and resources you need to implement the recommendations.

  • Do the server and connection state during the analysis reflect a realistic state during product operation? The results of the analysis depend on the state of the server, including which data is in the cache. They also depend on the state of the connection, including some database option settings. As the analysis creates only virtual indexes, and does not execute requests, the state of the server is essentially static during the analysis (except for changes introduced by other connections). If the state does not represent the typical operation of your database, you may wish to rerun the analysis under different conditions.


Implementing the recommendations

The Index Consultant provides its recommendations as a SQL script. You can implement the recommendations from the Index Consultant, or you can save the script for later use.

The names of the proposed indexes are generated from the name of the analysis. You may wish to rename them before creating the indexes in the database.

For information on running command files from Interactive SQL, see Using SQL command files.


Indexes in the system tables

All the information about indexes in a database is held in the system tables SYS.SYSINDEX and SYS.SYSIXCOL. The information is presented in a more readable format in the system view SYS.SYSINDEXES. You can use Sybase Central or Interactive SQL to browse the information in these tables.


Working with temporary tables

Temporary tables, whether local or global, serve the same purpose: temporary storage of data. The difference between the two, and the advantages of each, however, lies in the duration each table exists.

A local temporary table exists only for the duration of a connection or, if defined inside a compound statement, for the duration of the compound statement.

For more information, see DECLARE LOCAL TEMPORARY TABLE statement.

The definition of the global temporary table remains in the database permanently, but the rows exist only within a given connection. When you close the database connection, the data in the global temporary table disappears. However, the table definition remains with the database for you to access when you open your database next time.

Temporary tables are stored in the temporary file. Like any other dbspace, pages from the temporary file can be cached. Operations on temporary tables are never written to the transaction log.

For more information, see CREATE TABLE statement.


Copying database objects in Sybase Central

In Sybase Central, you can copy existing database objects and insert them into another location in the same database or in a completely different database.

To copy an object, select the object in the left pane of Sybase Central and drag it to the appropriate folder or container, or copy the object and then paste it in the appropriate folder or container. A new object is created, and the original object's code is copied to the new object. When copying objects within the same database, you must rename the new object.

You can also paste objects onto other objects in the database. For example, if you paste a table onto a user, this gives the user permissions on the table.

Copying a database object's code for use in other applications

In Sybase Central, when you copy any of the objects from the following list, the SQL for the object is copied to the clipboard so it can be pasted into other applications, such as Interactive SQL or a text editor. For example, if you copy an index in Sybase Central and paste it into a text editor, the CREATE INDEX statement for that index appears.

  • Articles

  • Check constraints

  • Columns (Copy button only)

  • Domains

  • Events

  • External logins

  • Foreign keys

  • Indexes

  • Message types

  • Procedures and functions

  • Publications

  • Remote servers

  • System triggers

  • Tables

  • Triggers

  • UltraLite projects

  • UltraLite statements

  • Unique constraints

  • Users

  • Views

  • Web services


Ensuring Data Integrity

About this chapter

Building integrity constraints right into the database is the surest way to make sure your data stays in good shape. This chapter describes the facilities in Adaptive Server Anywhere for ensuring that the data in your database is valid and reliable.

You can enforce several types of integrity constraints. For example, you can ensure individual entries are correct by imposing constraints and CHECK constraints on tables and columns. Setting column properties by choosing an appropriate data type or setting special default values assists this task.

The SQL statements in this chapter use the CREATE TABLE and ALTER TABLE statements, basic forms of which were introduced in Working with Database Objects.

Data integrity overview
Using column defaults
Using table and column constraints
Using domains
Enforcing entity and referential integrity
Integrity rules in the system tables


Data integrity overview

If data has integrity, the data is valid—correct and accurate—and the relational structure of the database is intact. Referential integrity constraints enforce the relational structure of the database. These rules maintain the consistency of data between tables.

Adaptive Server Anywhere supports stored procedures, which give you detailed control over how data enters the database. You can also create triggers, or customized stored procedures invoked automatically when a certain action, such as an update of a particular column, occurs.

For more information on procedures and triggers see Using Procedures, Triggers, and Batches.

How data can become invalid
Integrity constraints belong in the database
How database contents change
Data integrity tools
SQL statements for implementing integrity constraints


How data can become invalid

Here are a few examples of how the data in a database may become invalid if proper checks are not made. You can prevent each of these examples from occurring using facilities described in this chapter.

Incorrect information

  • An operator types the date of a sales transaction incorrectly.

  • An employee's salary becomes ten times too small because the operator missed a digit.

Duplicated data

  • Two different people add the same new department (with dept_id 200) to the department table of the organization's database.

Foreign key relations invalidated

  • The department identified by dept_id 300 closes down and one employee record inadvertently remains unassigned to a new department.


Integrity constraints belong in the database

To ensure the validity of data in a database, you need to formulate checks to define valid and invalid data, and design rules to which data must adhere (also known as business rules). Together, checks and rules become constraints.

Build integrity constraints into database

Constraints that are built into the database itself are more reliable than constraints that are built into client applications or that are spelled out as instructions to database users. Constraints built into the database become part of the definition of the database itself, and the database enforces them consistently across all applications. Setting a constraint once in the database imposes it for all subsequent interactions with the database.

In contrast, constraints built into client applications are vulnerable every time the software changes, and may need to be imposed in several applications, or in several places in a single client application.


How database contents change

Changes occur to information in database tables when you submit SQL statements from client applications. Only a few SQL statements actually modify the information in a database. You can:

  • Update information in a row of a table using the UPDATE statement.

  • Delete an existing row of a table using the DELETE statement.

  • Insert a new row into a table using the INSERT statement.


Data integrity tools

To maintain data integrity, you can use defaults, data constraints, and constraints that maintain the referential structure of the database.

Defaults

You can assign default values to columns to make certain kinds of data entry more reliable. For example:

  • A column can have a current date default value for recording the date of transactions with any user or client application action.

  • Other types of default values allow column values to increment automatically without any specific user action other than entering a new row. With this feature, you can guarantee that items (such as purchase orders for example) are unique, sequential numbers.

For more information on these and other column defaults, see Using column defaults.

Constraints

You can apply several types of constraints to the data in individual columns or tables. For example:

  • A NOT NULL constraint prevents a column from containing a null entry.

  • A CHECK constraint assigned to a column can ensure that every item in the column meets a particular condition. For example, you can ensure that salary column entries fit within a specified range and thus protect against user error when typing in new values.

  • CHECK constraints can be made on the relative values in different columns. For example, you can ensure that a date_returned entry is later than a date_borrowed entry in a library database.

  • Triggers can enforce more sophisticated CHECK conditions. For more information on triggers, see Using Procedures, Triggers, and Batches.

As well, column constraints can be inherited from domains. For more information on these and other table and column constraints, see Using table and column constraints.

Entity and referential integrity

Relationships, defined by the primary keys and foreign keys, tie together the information in relational database tables. You must build these relations directly into the database design. The following integrity rules maintain the structure of the database:

  • Entity integrity Keeps track of the primary keys. It guarantees that every row of a given table can be uniquely identified by a primary key that guarantees IS NOT NULL.

  • Referential integrity Keeps track of the foreign keys that define the relationships between tables. It guarantees that all foreign key values either match a value in the corresponding primary key or contain the NULL value if they are defined to allow NULL.

For more information about enforcing referential integrity, see Enforcing entity and referential integrity. For more information about designing appropriate primary and foreign key relations, see Designing Your Database.

Triggers for advanced integrity rules

You can also use triggers to maintain data integrity. A trigger is a procedure stored in the database and executed automatically whenever the information in a specified table changes. Triggers are a powerful mechanism for database administrators and developers to ensure that data remains reliable.

For more information about triggers, see Using Procedures, Triggers, and Batches.


SQL statements for implementing integrity constraints

The following SQL statements implement integrity constraints:

  • CREATE TABLE statement This statement implements integrity constraints during creation of the database.

  • ALTER TABLE statement This statement adds integrity constraints to an existing database, or modifies constraints for an existing database.

  • CREATE TRIGGER statement This statement creates triggers that enforce more complex business rules.

  • CREATE DOMAIN statement This statement creates a user-defined data type. The definition of the data type can include constraints.

For more information about the syntax of these statements, see SQL Statements.


Using column defaults

Column defaults automatically assign a specified value to particular columns whenever someone enters a new row into a database table. The default value assigned requires no action on the part of the client application, however if the client application does specify a value for the column, the new value overrides the column default value.

Column defaults can quickly and automatically fill columns with information, such as the date or time a row is inserted, or the user ID of the person typing the information. Using column defaults encourages data integrity, but does not enforce it. Client applications can always override defaults.

Supported default values

SQL supports the following default values:

  • A string specified in the CREATE TABLE statement or ALTER TABLE statement

  • A number specified in the CREATE TABLE statement or ALTER TABLE statement

  • An automatically incremented number: one more than the previous highest value in the column

  • Universally Unique Identifiers (UUIDs) generated using the NEWID function.

  • The current date, time, or timestamp

  • The current user ID of the database user

  • A NULL value

  • A constant expression, as long as it does not reference database objects

Creating column defaults
Modifying and deleting column defaults
Working with column defaults in Sybase Central
Current date and time defaults
The user ID default
The AUTOINCREMENT default
The NEWID default
The NULL default
String and number defaults
Constant expression defaults


Creating column defaults

You can use the CREATE TABLE statement to create column defaults at the time a table is created, or the ALTER TABLE statement to add column defaults at a later time.

Example

The following statement adds a condition to an existing column named id in the sales_order table, so that it automatically increments (unless a client application specifies a value):

ALTER TABLE sales_order
MODIFY id DEFAULT AUTOINCREMENT

Each of the other default values is specified in a similar manner. For more information, see ALTER TABLE statement and CREATE TABLE statement.


Modifying and deleting column defaults

You can change or remove column defaults using the same form of the ALTER TABLE statement you used to create defaults. The following statement changes the default value of a column named order_date from its current setting to CURRENT DATE:

ALTER TABLE sales_order
MODIFY order_date DEFAULT CURRENT DATE

You can remove column defaults by modifying them to be NULL. The following statement removes the default from the order_date column:

ALTER TABLE sales_order
MODIFY order_date DEFAULT NULL


Working with column defaults in Sybase Central

You can add, alter, and delete column defaults in Sybase Central using the Value tab of the column properties sheet.

toggle To display the property sheet for a column

  1. Connect to the database.

  2. Open the Tables folder for that database.

  3. Double-click the table holding the column you want to change.

  4. In the right pane, click the Columns tab.

  5. Select the desired column.

  6. Choose File > Properties.

    The column's property sheet appears.


Current date and time defaults

For columns with the DATE, TIME, or TIMESTAMP data type, you can use the current date, current time, or current timestamp as a default. The default you choose must be compatible with the column's data type.

Useful examples of current date default

A current date default might be useful to record:

  • dates of phone calls in a contact database

  • dates of orders in a sales entry database

  • the date a patron borrows a book in a library database

Current timestamp

The current timestamp is similar to the current date default, but offers greater accuracy. For example, a user of a contact management application may have several contacts with a single customer in one day: the current timestamp default would be useful to distinguish these contacts.

Since it records a date and the time down to a precision of millionths of a second, you may also find the current timestamp useful when the sequence of events is important in a database.

For more information about timestamps, times, and dates, see SQL Data Types.


The user ID default

Assigning a DEFAULT USER to a column is an easy and reliable way of identifying the person making an entry in a database. This information may be required; for example, when salespeople are working on commission.

Building a user ID default into the primary key of a table is a useful technique for occasionally connected users, and helps to prevent conflicts during information updates. These users can make a copy of tables relevant to their work on a portable computer, make changes while not connected to a multi-user database, and then apply the transaction log to the server when they return.


The AUTOINCREMENT default

The AUTOINCREMENT default is useful for numeric data fields where the value of the number itself may have no meaning. The feature assigns each new row a value of one greater than the previous highest value in the column. You can use AUTOINCREMENT columns to record purchase order numbers, to identify customer service calls or other entries where an identifying number is required.

Autoincrement columns are typically primary key columns or columns constrained to hold unique values (see Enforcing entity integrity). For example, autoincrement default is effective when the column is the first column of an index, because the server uses an index or key definition to find the highest value.

While using the autoincrement default in other cases is possible, doing so can adversely affect database performance. For example, in cases where the next value for each column is stored as an integer (4 bytes), using values greater than 231 – 1 or large double or numeric values may cause wraparound to negative values.

You can retrieve the most recent value inserted into an autoincrement column using the @@identity global variable. For more information, see @@identity global variable.

Autoincrement and negative numbers

Autoincrement is intended to work with positive integers.

The initial autoincrement value is set to 0 when the table is created. This value remains as the highest value assigned when inserts are done that explicitly insert negative values into the column. An insert where no value is supplied causes the AUTOINCREMENT to generate a value of 1, forcing any other generated values to be positive.

In UltraLite applications, the autoincrement value is not set to 0 when the table is created, and AUTOINCREMENT generates negative numbers when a signed data type is used for the column.

You should define AUTOINCREMENT columns as unsigned to prevent negative values from being used.

Autoincrement and the IDENTITY column

A column with the AUTOINCREMENT default is referred to in Transact-SQL applications as an IDENTITY column. For information on IDENTITY columns, see The special IDENTITY column.


The NEWID default

UUIDs (Universally Unique IDentifiers), also known as GUIDs (Globally Unique IDentifiers), can be used to uniquely identify rows in a table. The values are generated such that a value produced on one computer will not match that produced on another. They can therefore be used as keys in replication and synchronization environments.

Using UUID values as primary keys has some tradeoffs when you compare them with using GLOBAL AUTOINCREMENT values. For example,

  • UUIDs can be easier to set up than GLOBAL AUTOINCREMENT, since there is no need to assign each remote database a unique database ID. There is also no need to consider the number of databases in the system or the number of rows in individual tables. The Extraction utility [dbxtract] can be used to deal with the assignment of database IDs. This isn't usually a concern for GLOBAL AUTOINCREMENT if the BIGINT data type is used, but it needs to be considered for smaller data types.

  • UUID values are considerably larger than those required for GLOBAL AUTOINCREMENT, and will require more table space in both primary and foreign tables. Indexes on these columns will also be less efficient when UUIDs are used. In short, GLOBAL AUTOINCREMENT is likely to perform better.

  • UUIDs have no implicit ordering. For example, if A and B are UUID values, A > B does not imply that A was generated after B, even when A and B were generated on the same computer. If you require this behavior, an additional column and index may be necessary.

For more information, see the NEWID function [Miscellaneous], or the UNIQUEIDENTIFIER data type [Binary].


The NULL default

For columns that allow NULL values, specifying a NULL default is exactly the same as not specifying a default at all. If the client inserting the row does not explicitly assign a value, the row automatically receives A NULL value.

You can use NULL defaults when information for some columns is optional or not always available, and when it is not required for the data in the database be correct.

For more information about the NULL value, see NULL value.


String and number defaults

You can specify a specific string or number as a default value, as long as the column holds a string or number data type. You must ensure that the default specified can be converted to the column's data type.

Default strings and numbers are useful when there is a typical entry for a given column. For example, if an organization has two offices, the headquarters in city_1 and a small office in city_2, you may want to set a default entry for a location column to city_1, to make data entry easier.


Constant expression defaults

You can use a constant expression as a default value, as long as it does not reference database objects. Constant expressions allow column defaults to contain entries such as the date fifteen days from today, which would be entered as

... DEFAULT ( dateadd( day, 15, getdate() ) )


Using table and column constraints

Along with the basic table structure (number, name and data type of columns, name and location of the table), the CREATE TABLE statement and ALTER TABLE statement can specify many different table attributes that allow control over data integrity. Constraints allow you to place restrictions on the values that can appear in a column, or on the relationship between values in different columns. Constraints can be either table-wide constraints, or can apply to individual columns.

Caution Altering tables can interfere with other users of the database. Although you can execute the ALTER TABLE statement while other connections are active, you cannot execute the ALTER TABLE statement if any other connection is using the table you want to alter. For large tables, ALTER TABLE is a time-consuming operation, and all other requests referencing the table being altered are prohibited while the statement is processing.

This section describes how to use constraints to help ensure the accuracy of data in the table.

Using CHECK constraints on columns
Using CHECK constraints on tables
Inheriting column CHECK constraints from domains
Working with table and column constraints in Sybase Central
Modifying and deleting CHECK constraints


Using CHECK constraints on columns

You use a CHECK condition to ensure that the values in a column satisfy some definite criterion or rule. For example, these rules or criteria may simply be required for data to be reasonable, or they may be more rigid rules that reflect organization policies and procedures.

CHECK conditions on individual column values are useful when only a restricted range of values are valid for that column.

Example 1

  • You can enforce a particular formatting requirement. For example, if a table has a column for phone numbers you may wish to ensure that users type them all in the same manner. For North American phone numbers, you could use a constraint such as:

    ALTER TABLE customer
MODIFY phone
CHECK ( phone LIKE '(___) ___-____' )
Example 2

  • You can ensure that the entry matches one of a limited number of values. For example, to ensure that a city column only contains one of a certain number of allowed cities (say, those cities where the organization has offices), you could use a constraint such as:

    ALTER TABLE office
MODIFY city
CHECK ( city IN ( 'city_1', 'city_2', 'city_3' ) )

  • By default, string comparisons are case insensitive unless the database is explicitly created as a case-sensitive database.

Example 3

  • You can ensure that a date or number falls in a particular range. For example, you may require that the start_date column of an employee table must be between the date the organization was formed and the current date using the following constraint:

    ALTER TABLE employee
MODIFY start_date
CHECK ( start_date BETWEEN '1983/06/27'
                   AND CURRENT DATE )

  • You can use several date formats. The YYYY/MM/DD format in this example has the virtue of always being recognized regardless of the current option settings.

Column CHECK tests only fail if the condition returns a value of FALSE. If the condition returns a value of UNKNOWN, the change is allowed.


Using CHECK constraints on tables

A CHECK condition applied as a constraint on the table typically ensures that two values in a row being added or modified have a proper relation to each other.

When you give a name to the constraint, the constraint is held individually in the system tables, and you can replace or delete them individually. Since this is more flexible behavior, it is recommended that you either name a CHECK constraint or use an individual column constraint wherever possible.

For example, in a library database, the date_borrowed must come before the date_returned.

ALTER TABLE loan
ADD CONSTRAINT valid_date CHECK(date_returned >= date_borrowed)

For more information, see ALTER TABLE statement.


Inheriting column CHECK constraints from domains

You can attach CHECK constraints to domains. Columns defined on those data types inherit the CHECK constraints. A CHECK constraint explicitly specified for the column overrides that from the domain.

Any column defined using the posint data type accepts only positive integers unless the column itself has a CHECK constraint explicitly specified. In the following example, the domain accepts only positive integers. Since any variable prefixed with the @ sign is replaced by the name of the column when the CHECK constraint is evaluated, any variable name prefixed with @ could be used instead of @col.

CREATE DATATYPE posint INT
CHECK ( @col > 0 )

An ALTER TABLE statement with the DELETE CHECK clause deletes all CHECK constraints from the table definition, including those inherited from domains.

Any changes made to constraint in a domain definition after a column is defined on that domain are not applied to the column. The column gets the constraints from the domain when it is created, but there is no further between the two.

For more information about domains, see Domains.


Working with table and column constraints in Sybase Central

In Sybase Central, you add, alter, and delete column constraints on the Constraints tab of the table or column property sheet.

toggle To manage constraints

  1. Open the Tables folder.

  2. In the right pane, double-click the table you want to alter.

  3. The right pane has separate tabs for unique constraints and check constraints.

  4. Make the appropriate changes to the constraint you wish to modify. For example, to add a table or column constraint, click the Check Constraints tab and choose File > New > Table Check Constraint or File > New > Column Check Constraint.


Modifying and deleting CHECK constraints

There are several ways to alter the existing set of CHECK constraints on a table.

  • You can add a new CHECK constraint to the table or to an individual column.

  • You can delete a CHECK constraint on a column by setting it to NULL. For example, the following statement removes the CHECK constraint on the phone column in the customer table:

    ALTER TABLE customer
MODIFY phone CHECK NULL

  • You can replace a CHECK constraint on a column in the same way as you would add a CHECK constraint. For example, the following statement adds or replaces a CHECK constraint on the phone column of the customer table:

    ALTER TABLE customer
MODIFY phone
CHECK ( phone LIKE '___-___-____' )

  • You can modify a CHECK constraint defined on the table:

    • You can add a new CHECK constraint using ALTER TABLE with an ADD table-constraint clause.

    • If you have defined constraint names, you can modify individual constraints.

    • If you have not defined constraint names, you can delete all existing CHECK constraints (including column CHECK constraints and CHECK constraints inherited from domains) using ALTER TABLE DELETE CHECK, and then add in new CHECK constraints.

      To use the ALTER TABLE statement with the DELETE CHECK clause:

      ALTER TABLE table_name
DELETE CHECK

Sybase Central lets you add, modify and delete both table and column CHECK constraints. For more information, see Working with table and column constraints in Sybase Central.

Deleting a column from a table does not delete CHECK constraints associated with the column held in the table constraint. Not removing the constraints produces a column not found error message upon any attempt to insert, or even just query, data in the table.

Table CHECK constraints fail only if a value of FALSE is returned. A value of UNKNOWN allows the change.


Using domains

A domain is a user-defined data type that, together with other attributes, can restrict the range of acceptable values or provide defaults. A domain extends one of the built-in data types. The range of permissible values is usually restricted by a check constraint. In addition, a domain can specify a default value and may or may not allow nulls.

You can define your own domains for a number of reasons.

  • A number of common errors can be prevented if inappropriate values cannot be entered. A constraint placed on a domain ensures that all columns and variables intended to hold values in a desired range or format can hold only the intended values. For example, a data type can ensure that all credit card numbers typed into the database contain the correct number of digits.

  • Domains can make it much easier to understand applications and the structure of a database.

  • Domains can prove convenient. For example, you may intend that all table identifiers are positive integers that, by default, auto-increment. You could enforce this restriction by entering the appropriate constraints and defaults each time you define a new table, but it is less work to define a new domain, then simply state that the identifier can take only values from the specified domain.

For more information about domains, see SQL Data Types.


Creating domains (Sybase Central)

You can use Sybase Central to create a domain or assign it to a column.

toggle To create a new domain (Sybase Central)

  1. In the left pane, select the Domains folder.

  2. Choose File > New > Domain.

    The Domain Creation wizard appears.

  3. Follow the instructions in the wizard.

All domains appear in the Domains folder in Sybase Central.

toggle To assign domains to columns (Sybase Central)

  1. For the desired table, click the Columns tab in the right pane.

  2. In the data type column for the desired column, either:

    • Select the domain from the dropdown list, or

    • Click the button next to the dropdown list and choose the domain on the property sheet.


Creating domains (SQL)

You can use the CREATE DOMAIN statement to create and define domains.

toggle To create a new domain (SQL)

  1. Connect to a database.

  2. Execute a CREATE DOMAIN statement.

Example 1: Simple domains

Some columns in the database are to be used for people's names and others are to store addresses. You might then define type following domains.

CREATE DOMAIN persons_name CHAR(30)
CREATE DOMAIN street_address CHAR(35)

Having defined these domains, you can use them much as you would the built-in data types. For example, you can use these definitions to define a tables as follows.

CREATE TABLE customer (
   id INT  DEFAULT AUTOINCREMENT  PRIMARY KEY
   name persons_name
   address street_address
)
Example 2: Default values, check constraints, and identifiers

In the above example, the table's primary key is specified to be of type integer. Indeed, many of your tables may require similar identifiers. Instead of specifying that these are integers, it is much more convenient to create an identifier domain for use in these applications.

When you create a domain, you can specify a default value and provide check constraint to ensure that no inappropriate values are typed into any column of this type.

Integer values are commonly used as table identifiers. A good choice for unique identifiers is to use positive integers. Since such identifiers are likely to be used in many tables, you could define the following domain.

CREATE DOMAIN identifier INT
DEFAULT AUTOINCREMENT
CHECK ( @col > 0 )

This check constraint uses the variable @col. Using this definition, you can rewrite the definition of the customer table, shown above.

CREATE TABLE customer (
   id identifier PRIMARY KEY
   name persons_name
   address street_address
)
Example 3: Built-in domains

Adaptive Server Anywhere comes with some domains pre-defined. You can use these pre-defined domains as you would a domain that you created yourself. For example, the following monetary domain has already been created for you.

CREATE DOMAIN MONEY NUMERIC(19,4)
NULL

For more information, see CREATE DOMAIN statement.


Deleting domains

You can use either Sybase Central or a DROP DOMAIN statement to delete a domain.

Only the user DBA or the user who created a domain can drop it. In addition, since a domain cannot be dropped if any variable or column in the database is an instance of the domain, you need to first drop any columns or variables of that type before you can drop the domain.

toggle To delete a domain (Sybase Central)

  1. Open the Domains folder.

  2. Right-click the desired domain and choose Delete from the popup menu.

toggle To delete a domain (SQL)

  1. Connect to a database.

  2. Execute a DROP DOMAIN statement.

Example

The following statement drops the customer_name domain.

DROP DOMAIN customer_name

For more information, see DROP statement.


Enforcing entity and referential integrity

The relational structure of the database enables the personal server to identify information within the database, and ensures that all the rows in each table uphold the relationships between tables (described in the database structure).

Enforcing entity integrity
If a client application breaches entity integrity
Primary keys enforce entity integrity
Enforcing referential integrity
Foreign keys enforce referential integrity
Losing referential integrity
If a client application breaches referential integrity
Referential integrity actions
Referential integrity checking


Enforcing entity integrity

When a user inserts or updates a row, the database server ensures that the primary key for the table is still valid: that each row in the table is uniquely identified by the primary key.

Example 1

The employee table in the sample database uses an employee ID as the primary key. When you add a new employee to the table, the database server checks that the new employee ID value is unique and is not NULL.

Example 2

The sales_order_items table in the sample database uses two columns to define a primary key.

This table holds information about items ordered. One column contains an id specifying an order, but there may be several items on each order, so this column by itself cannot be a primary key. An additional line_id column identifies which line corresponds to the item. The columns id and line_id, taken together, specify an item uniquely, and form the primary key.


If a client application breaches entity integrity

Entity integrity requires that each value of a primary key be unique within the table, and that no NULL values exist. If a client application attempts to insert or update a primary key value, providing values that are not unique would breach entity integrity. A breach in entity integrity prevents the new information from being added to the database, and instead sends the client application an error.

The application programmer should decide how to present this information to the user and enable the user to take appropriate action. The appropriate action is usually as simple as asking the user to provide a different, unique value for the primary key.


Primary keys enforce entity integrity

Once you specify the primary key for each table, maintaining entity integrity requires no further action by either client application developers or by the database administrator.

The table owner defines the primary key for a table when they create it. If they modify the structure of a table at a later date, they can also redefine the primary key.

Some application development systems and database design tools allow you to create and alter database tables. If you are using such a system, you may not have to enter the CREATE TABLE or ALTER TABLE statement explicitly: the application may generate the statement itself from the information you provide.

For more information about creating primary keys, see Managing primary keys. For the detailed syntax of the CREATE TABLE statement, see CREATE TABLE statement. For information about changing table structure, see the ALTER TABLE statement.


Enforcing referential integrity

A foreign key (made up of a particular column or combination of columns) relates the information in one table (the foreign table) to information in another (referenced or primary) table. For the foreign key relationship to be valid, the entries in the foreign key must correspond to the primary key values of a row in the referenced table. Occasionally, some other unique column combination may be referenced instead of a primary key.

Example 1

The sample database contains an employee table and a department table. The primary key for the employee table is the employee ID, and the primary key for the department table is the department ID. In the employee table, the department ID is called a foreign key for the department table because each department ID in the employee table corresponds exactly to a department ID in the department table.

The foreign key relationship is a many-to-one relationship. Several entries in the employee table have the same department ID entry, but the department ID is the primary key for the department table, and so is unique. If a foreign key could reference a column in the department table containing duplicate entries, or entries with a NULL value, there would be no way of knowing which row in the department table is the appropriate reference. This is a mandatory foreign key.

Example 2

Suppose the database also contained an office table listing office locations. The employee table might have a foreign key for the office table that indicates which city the employee's office is in. The database designer can choose to leave an office location unassigned at the time the employee is hired, for example, either because they haven't been assigned to an office yet, or because they don't work out of an office. In this case, the foreign key can allow NULL values, and is optional.


Foreign keys enforce referential integrity

Like primary keys, you use the CREATE TABLE or ALTER TABLE statements to create foreign keys. Once you create a foreign key, the column or columns in the key can contain only values that are present as primary key values in the table associated with the foreign key.

For more information about creating foreign keys, see Managing primary keys.


Losing referential integrity

Your database can lose referential integrity if someone:

  • Updates or deletes a primary key value. All the foreign keys referencing that primary key would become invalid.

  • Adds a new row to the foreign table, and enters a value for the foreign key that has no corresponding primary key value. The database would become invalid.

Adaptive Server Anywhere provides protection against both types of integrity loss.


If a client application breaches referential integrity

If a client application updates or deletes a primary key value in a table, and if a foreign key references that primary key value elsewhere in the database, there is a danger of a breach of referential integrity.

Example

If the server allowed the primary key to be updated or deleted, and made no alteration to the foreign keys that referenced it, the foreign key reference would be invalid. Any attempt to use the foreign key reference, for example in a SELECT statement using a KEY JOIN clause, would fail, as no corresponding value in the referenced table exists.

While Adaptive Server Anywhere handles breaches of entity integrity in a generally straightforward fashion by simply refusing to enter the data and returning an error message, potential breaches of referential integrity become more complicated. You have several options (known as referential integrity actions) available to help you maintain referential integrity.


Referential integrity actions

Maintaining referential integrity when updating or deleting a referenced primary key can be as simple as disallowing the update or delete. Often, however, it is also possible to take a specific action on each foreign key to maintain referential integrity. The CREATE TABLE and ALTER TABLE statements allow database administrators and table owners to specify what action to take on foreign keys that reference a modified primary key when a breach occurs.

You can specify each of the available referential integrity actions separately for updates and deletes of the primary key:

  • RESTRICT Generates an error and prevents the modification if an attempt to modify a referenced primary key value occurs. This is the default referential integrity action.

  • SET NULL Sets all foreign keys that reference the modified primary key to NULL.

  • SET DEFAULT Sets all foreign keys that reference the modified primary key to the default value for that column (as specified in the table definition).

  • CASCADE When used with ON UPDATE, this action updates all foreign keys that reference the updated primary key to the new value. When used with ON DELETE, this action deletes all rows containing foreign keys that reference the deleted primary key.

System triggers implement referential integrity actions. The trigger, defined on the primary table, is executed using the permissions of the owner of the secondary table. This behavior means that cascaded operations can take place between tables with different owners, without additional permissions having to be granted.


Referential integrity checking

For foreign keys defined to RESTRICT operations that would violate referential integrity, default checks occur at the time a statement executes. If you specify a CHECK ON COMMIT clause, then the checks occur only when the transaction is committed.

Using a database option to control check time

Setting the WAIT_FOR_COMMIT database option controls the behavior when a foreign key is defined to restrict operations that would violate referential integrity. The CHECK ON COMMIT clause can override this option.

With the default WAIT_FOR_COMMIT set to OFF, operations that would leave the database inconsistent cannot execute. For example, an attempt to DELETE a department that still has employees in it is not allowed. The following statement gives the error primary key for row in table 'department' is referenced in another table:

DELETE FROM department
WHERE dept_id = 200

Setting WAIT_FOR_COMMIT to ON causes referential integrity to remain unchecked until a commit executes. If the database is in an inconsistent state, the database disallows the commit and reports an error. In this mode, a database user could delete a department with employees in it, however, the user cannot commit the change to the database until they:

  • Delete or reassign the employees belonging to that department.

  • Redo the search condition on a SELECT statement to select the rows that violate referential integrity.

  • Insert the dept_id row back into the department table.

  • Roll back the transaction to undo the DELETE operation.


Integrity rules in the system tables

All the information about database integrity checks and rules is held in the following system tables:

System table | Description
SYS.SYSTABLE | The view_def column of SYS.SYSTABLE holds CHECK constraints. For views, the view_def holds the CREATE VIEW command that created the view. You can check whether a particular table is a base table or a view by looking at the table_type column, which is BASE or VIEW.
SYS.SYSTRIGGER SYS.SYSTRIGGER holds referential integrity actions.

The referential_action column holds a single character indicating whether the action is cascade (C), delete (D), set null (N), or restrict (R).

The event column holds a single character specifying the event that causes the action to occur: insert, delete (A), insert, update (B), update (C), a delete (D), delete, update (E),insert (I), update (U), insert, delete, update (M).

The trigger_time column shows whether the action occurs after (A) or before (B) the triggering event.
SYS.SYSFOREIGNKEYS | This view presents the foreign key information from the two tables SYS.SYSFOREIGNKEY and SYS.SYSFKCOL in a more readable format.
SYS.SYSCOLUMNS | This view presents the information from the SYS.SYSCOLUMN table in a more readable format. It includes default settings and primary key information for columns.

For more information about the contents of each system table, see System Tables. You can use Sybase Central or Interactive SQL to browse these tables and views.


Using Transactions and Isolation Levels

About this chapter

You can group SQL statements into transactions, which have the property that either all statements are executed or none is executed. You should design each transaction to perform a task that changes your database from one consistent state to another.

This chapter describes transactions and how to use them in applications. It also describes how Adaptive Server Anywhere you can set isolation levels to limit the interference among concurrent transaction.

Introduction to transactions
Isolation levels and consistency
Transaction blocking and deadlock
Choosing isolation levels
Isolation level tutorials
How locking works
Particular concurrency issues
Replication and concurrency
Summary


Introduction to transactions

To ensure data integrity, it is essential that you can identify states in which the information in your database is consistent. The concept of consistency is best illustrated through an example:

Consistency example

Suppose you use your database to handle financial accounts, and you wish to transfer money from one client's account to another. The database is in a consistent state both before and after the money is transferred; but it is not in a consistent state after you have debited money from one account and before you have credited it to the second. During a transferal of money, the database is in a consistent state when the total amount of money in the clients' accounts is as it was before any money was transferred. When the money has been half transferred, the database is in an inconsistent state. Either both or neither of the debit and the credit must be processed.

Transactions are logical units of work

A transaction is a logical unit of work. Each transaction is a sequence of logically related commands that accomplish one task and transform the database from one consistent state into another. The nature of a consistent state depends on your database.

The statements within a transaction are treated as an indivisible unit: either all are executed or none is executed. At the end of each transaction, you commit your changes to make them permanent. If for any reason some of the commands in the transaction do not process properly, then any intermediate changes are undone, or rolled back. Another way of saying this is that transactions are atomic.

Grouping statements into transactions is key both to protecting the consistency of your data (even in the event of media or system failure), and to managing concurrent database operations. Transactions may be safely interleaved and the completion of each transaction marks a point at which the information in the database is consistent.

In the event of a system failure or database crash during normal operation, Adaptive Server Anywhere performs automatic recovery of your data when the database is next started. The automatic recovery process recovers all completed transactions, and rolls back any transactions that were uncommitted when the failure occurred. The atomic character of transactions ensures that databases are recovered to a consistent state.

For more information about database backups and data recovery, see Backup and Data Recovery.

For more information about concurrent database usage, see Introduction to concurrency.


Using transactions

Adaptive Server Anywhere expects you to group your commands into transactions. Knowing which commands or actions signify the start or end of a transaction lets you take full advantage of this feature.

Starting transactions

Transactions start with one of the following events:

  • The first statement following a connection to a database

  • The first statement following the end of a transaction

Completing transactions

Transactions complete with one of the following events:

  • A COMMIT statement makes the changes to the database permanent.

  • A ROLLBACK statement undoes all the changes made by the transaction.

  • A statement with a side effect of an automatic commit is executed: data definition commands, such as ALTER, CREATE, COMMENT, and DROP all have the side effect of an automatic commit.

  • A disconnection from a database performs an implicit rollback.

  • ODBC and JDBC have an autocommit setting that enforces a COMMIT after each statement. By default, ODBC and JDBC require autocommit to be on, and each statement is a single transaction. If you want to take advantage of transaction design possibilities, then you should turn autocommit off.

    For more information on autocommit, see Setting autocommit or manual commit mode.

  • Setting the database option CHAINED to OFF is similar to enforcing an autocommit after each statement. By default, connections that use jConnect or Open Client applications have CHAINED set to OFF.

    For more information, see Setting autocommit or manual commit mode, and CHAINED option [compatibility].

Options in Interactive SQL

Interactive SQL lets you control when and how transactions from your application terminate:

  • If you set the option AUTO_COMMIT to ON, Interactive SQL automatically commits your results following every successful statement and automatically performs a ROLLBACK after each failed statement.

  • The setting of the option COMMIT_ON_EXIT controls what happens to uncommitted changes when you exit Interactive SQL. If this option is set to ON (the default), Interactive SQL does a COMMIT; otherwise it undoes your uncommitted changes with a ROLLBACK statement.

Adaptive Server Anywhere also supports Transact-SQL commands such as BEGIN TRANSACTION, for compatibility with Sybase Adaptive Server Enterprise. For further information, see Transact-SQL Compatibility.


Introduction to concurrency

Concurrency is the ability of the database server to process multiple transactions at the same time. Were it not for special mechanisms within the database server, concurrent transactions could interfere with each other to produce inconsistent and incorrect information.

Example

A database system in a department store must allow many clerks to update customer accounts concurrently. Each clerk must be able to update the status of the accounts as they assist each customer: they cannot afford to wait until no one else is using the database.

Who needs to know about concurrency

Concurrency is a concern to all database administrators and developers. Even if you are working with a single-user database, you must be concerned with concurrency if you want to process requests from multiple applications or even from multiple connections from a single application. These applications and connections can interfere with each other in exactly the same way as multiple users in a network setting.

Transaction size affects concurrency

The way you group SQL statements into transactions can have significant effects on data integrity and on system performance. If you make a transaction too short and it does not contain an entire logical unit of work, then inconsistencies can be introduced into the database. If you write a transaction that is too long and contains several unrelated actions, then there is greater chance that a ROLLBACK will unnecessarily undo work that could have been committed quite safely into the database.

If your transactions are long, they can lower concurrency by preventing other transactions from being processed concurrently.

There are many factors that determine the appropriate length of a transaction, depending on the type of application and the environment.


Savepoints within transactions

You may identify important states within a transaction and return to them selectively using savepoints to separate groups of related statements.

A SAVEPOINT statement defines an intermediate point during a transaction. You can undo all changes after that point using a ROLLBACK TO SAVEPOINT statement. Once a RELEASE SAVEPOINT statement has been executed or the transaction has ended, you can no longer use the savepoint. Note that savepoints to do not have an effect on COMMITs. When a COMMIT is executed, all changes within the transaction are made permanent in the database.

No locks are released by the RELEASE SAVEPOINT or ROLLBACK TO SAVEPOINT commands: locks are released only at the end of a transaction.

Naming and nesting savepoints

Using named, nested savepoints, you can have many active savepoints within a transaction. Changes between a SAVEPOINT and a RELEASE SAVEPOINT can be canceled by rolling back to a previous savepoint or rolling back the transaction itself. Changes within a transaction are not a permanent part of the database until the transaction is committed. All savepoints are released when a transaction ends.

Savepoints cannot be used in bulk operations mode. There is very little additional overhead in using savepoints.


Isolation levels and consistency

There are four isolation levels

Adaptive Server Anywhere allows you to control the degree to which the operations in one transaction are visible to the operations in other concurrent transactions. You do so by setting a database option called the isolation level.

Adaptive Server Anywhere provides the following four different isolation levels:

This isolation level... Has these characteristics...
0—read uncommitted
  • Read permitted on row with or without write lock
  • No read locks are applied
  • No guarantee that concurrent transaction will not modify row or roll back changes to row
1—read committed
  • Read only permitted on row with no write lock
  • Read lock acquired and held for read on current row only, but released when cursor moves off the row
  • No guarantee that data will not change during transaction
2—repeatable read
  • Read only permitted on row with no write lock
  • Read lock acquired as each row in the result set is read and held until transaction ends
3—serializable
  • Read only permitted on rows in result without write lock
  • Read locks acquired when cursor is opened and held until transaction ends

These isolation levels prevent some or all interference. Level 3 provides the highest level of isolation. Lower levels allow more inconsistencies, but typically have better performance. Level 0 (read uncommitted) is the default setting.

Notes
All isolation levels guarantee that each transaction will execute completely or not at all, and that no updates will be lost.

The isolation is between transactions only: multiple cursors within the same transaction can interfere with each other.


Typical types of inconsistency

There are three typical types of inconsistency that can occur during the execution of concurrent transactions. This list is not exhaustive as other types of inconsistencies can also occur. These three types are mentioned in the ISO SQL/92 standard and are important because behavior at lower isolation levels is defined in terms of them.

  • Dirty read Transaction A modifies a row, but does not commit or roll back the change. Transaction B reads the modified row. Transaction A then either further changes the row before performing a COMMIT, or rolls back its modification. In either case, transaction B has seen the row in a state which was never committed.

    • For more information about dirty reads, see Dirty read tutorial.

  • Non-repeatable read Transaction A reads a row. Transaction B then modifies or deletes the row and performs a COMMIT. If transaction A then attempts to read the same row again, the row will have been changed or deleted.

    • For more information about non-repeatable reads, see Non-repeatable read tutorial.

  • Phantom row Transaction A reads a set of rows that satisfy some condition. Transaction B then executes an INSERT or an UPDATE on a row which did not previously meet A's condition. Transaction B commits these changes. These newly committed rows now satisfy the condition. Transaction A then repeats the initial read and obtains a different set of rows.

    • For more information about phantom rows, see Phantom row tutorial.

Other types of inconsistencies can also exist. These three were chosen for the ISO SQL/92 standard because they are typical problems and because it was convenient to describe amounts of locking between transactions in terms of them.

Isolation levels and dirty reads, non-repeatable reads, and phantom rows

The isolation levels are different with respect to the type of inconsistent behavior that Adaptive Server Anywhere allows. An x means that the behavior is prevented, and a Y means that the behavior may occur.

Isolation level | Dirty reads | Non-repeatable reads | Phantom rows
0–read uncommitted | Y | Y | Y
1–read committed | x | Y | Y
2–repeatable read | x | x | Y
3–serializable | x | x | x

This table demonstrates two points:

  • Each isolation level eliminates one of the three typical types of inconsistencies.

  • Each level eliminates the types of inconsistencies eliminated at all lower levels.

The four isolation levels have different names under ODBC. These names are based on the names of the inconsistencies that they prevent, and are described in The ValuePtr parameter.

Cursor instability


Cursor instability

Another significant inconsistency is cursor instability. When this inconsistency is present, a transaction can modify a row that is being referenced by another transaction's cursor. Cursor stability ensures that applications using cursors do not introduce inconsistencies into the data in the database.

Example

Transaction A reads a row using a cursor. Transaction B modifies that row and commits. Not realizing that the row has been modified, Transaction A modifies it.

Eliminating cursor instability

Adaptive Server Anywhere provides cursor stability at isolation levels 1, 2, and 3. Cursor stability ensures that no other transactions can modify information that is contained in the present row of your cursor. The information in a row of a cursor may be the copy of information contained in a particular table or may be a combination of data from different rows of multiple tables. More than one table will likely be involved whenever you use a join or sub-selection within a SELECT statement.

For information on programming SQL procedures and cursors, see Using Procedures, Triggers, and Batches.

Cursors are used only when you are using Adaptive Server Anywhere through another application. For more information, see Using SQL in Applications.

A related but distinct concern for applications using cursors is whether changes to underlying data are visible to the application. You can control the changes that are visible to applications by specifying the sensitivity of the cursor.

For more information about cursor sensitivity, see Adaptive Server Anywhere cursors.


Setting the isolation level

Each connection to the database has its own isolation level. In addition, the database can store a default isolation level for each user or group. The PUBLIC setting enables you to set a single default isolation level for the entire database's group.

You can also set the isolation level using table hints, but this is an advanced feature that should be used only when needed. For more information, see the WITH table-hint section in the FROM clause.

The isolation level is a database option. You change database options using the SET OPTION statement. For example, the following command sets the isolation level for the current user to 3, the highest level.

SET OPTION ISOLATION_LEVEL = 3

You can change the isolation of your connection and the default level associated with your user ID using the SET OPTION command. If you have permission, you can also change the isolation level for other users or groups.

toggle To set the isolation level for the current user ID

  • Execute the SET OPTION statement. For example, the following statement sets the isolation level to 3 for the current user:

    SET OPTION ISOLATION_LEVEL = 3
toggle To set the isolation level for a user or group

  1. Connect to the database as a user with DBA authority.

  2. Execute the SET OPTION statement, adding the name of the group and a period before ISOLATION_LEVEL. For example, the following command sets the default isolation for the special group PUBLIC to 3.

    SET OPTION PUBLIC.ISOLATION_LEVEL = 3
toggle To set the isolation level just for your present session

  • Execute the SET OPTION statement using the TEMPORARY keyword. For example, the following statement sets the isolation level to 3 for the duration of your connection:

    SET TEMPORARY OPTION ISOLATION_LEVEL = 3

    Once you disconnect, your isolation level reverts to its previous value.

Default isolation level

When you connect to a database, the database server determines your initial isolation level as follows:

  1. A default isolation level may be set for each user and group. If a level is stored in the database for your user ID, then the database server uses it.

  2. If not, the database server checks the groups to which you belong until it finds a level. All users are members of the special group PUBLIC. If it finds no other setting first, then Adaptive Server Anywhere will use the level assigned to that group.

For more information about users and groups, see Managing User IDs and Permissions.

For more information about the SET OPTION statement syntax, see SET OPTION statement.

You may wish to change the isolation level in mid-transaction if, for example, just one table or group of tables requires serialized access. For information about changing the isolation level within a transaction, see Changing isolation levels within a transaction.


Setting the isolation level from an ODBC-enabled application

ODBC applications call SQLSetConnectAttr with Attribute set to SQL_ATTR_TXN_ISOLATION and ValuePtr set according to the corresponding isolation level:

The ValuePtr parameter
ValuePtr | Isolation Level
SQL_TXN_READ_UNCOMMITTED | 0
SQL_TXN_READ_COMMITTED | 1
SQL_TXN_REPEATABLE_READ | 2
SQL_TXT_SERIALIZABLE | 3
Changing an isolation level via ODBC

You can change the isolation level of your connection via ODBC using the function SQLSetConnectOption in the library ODBC32.dll.

The SQLSetConnectOption function takes three parameters: the value of the ODBC connection handle, the fact that you wish to set the isolation level, and the value corresponding to the isolation level. These values appear in the table below.

String | Value
SQL_TXN_ISOLATION | 108
SQL_TXN_READ_UNCOMMITTED | 1
SQL_TXN_READ_COMMITTED | 2
SQL_TXN_REPEATABLE_READ | 4
SQL_TXT_SERIALIZABLE | 8

Do not use the SET OPTION statement to change an isolation level from within an ODBC application. Since the ODBC driver does not parse the statements, execution of any statement in ODBC will not be recognized by the ODBC driver. This could lead to unexpected locking behavior.

Example

The following function call sets the isolation level of the connection MyConnection to isolation level 2:

SQLSetConnectOption( MyConnection.hDbc,
                     SQL_TXN_ISOLATION,
                     SQL_TXN_REPEATABLE_READ )

ODBC uses the isolation feature to support assorted database lock options. For example, in PowerBuilder you can use the Lock attribute of the transaction object to set the isolation level when you connect to the database. The Lock attribute is a string, and is set as follows:

SQLCA.lock = "RU"

The Lock option is honored only at the moment the CONNECT occurs. Changes to the Lock attribute after the CONNECT have no effect on the connection.


Changing isolation levels within a transaction

Sometimes you will find that different isolation levels are suitable for different parts of a single transaction. Adaptive Server Anywhere allows you to change the isolation level of your database in the middle of a transaction.

Note
You can also set the isolation level using table hints, but this is an advanced feature that you should use only when needed. For more information, see the WITH table-hint section in the FROM clause.

When you change the ISOLATION_LEVEL option in the middle of a transaction, the new setting affects only the following:

  • Any cursors opened after the change

  • Any statements executed after the change

You may wish to change the isolation level during a transaction, as doing so affords you control over the number of locks your transaction places. You may find a transaction needs to read a large table, but perform detailed work with only a few of the rows. If an inconsistency would not seriously affect your transaction, set the isolation to a low level while you scan the large table to avoid delaying the work of others.

You may also wish to change the isolation level in mid transaction if, for example, just one table or group of tables requires serialized access.

For an example in which the isolation level is changed in the middle of a transaction, see Phantom row tutorial.


Viewing the isolation level

You can inspect the isolation level of the current connection using the CONNECTION_PROPERTY function.

toggle To view the isolation level for the current connection

  • Execute the following statement:

    SELECT CONNECTION_PROPERTY('ISOLATION_LEVEL')


Transaction blocking and deadlock

When a transaction is being executed, the database server places locks on rows to prevent other transactions from interfering with the affected rows. Locks control the amount and types of interference permitted.

Adaptive Server Anywhere uses transaction blocking to allow transactions to execute concurrently without interference, or with limited interference. Any transaction can acquire a lock to prevent other concurrent transactions from modifying or even accessing a particular row. This transaction blocking scheme always stops some types of interference. For example, a transaction that is updating a particular row of a table always acquires a lock on that row to ensure that no other transaction can update or delete the same row at the same time.

Transaction blocking


Transaction blocking

When a transaction attempts to carry out an operation, but is forbidden by a lock held by another transaction, a conflict arises and the progress of the transaction attempting to carry out the operation is impeded.

Two-phase locking describes deadlock, which occurs when two or more transactions are blocked by each other in such a way that none can proceed.

Sometimes a set of transactions arrive at a state where none of them can proceed. For more information, see Deadlock.


The BLOCKING option

If two transactions have each acquired a read lock on a single row, the behavior when one of them attempts to modify that row depends on the database setting BLOCKING. To modify the row, that transaction must block the other, yet it cannot do so while the other transaction has it blocked.

  • If BLOCKING is ON (the default), then the transaction that attempts to write waits until the other transaction releases its read lock. At that time, the write goes through.

  • If BLOCKING has been set to OFF, then the statement that attempts to write receives an error.

When BLOCKING is OFF, the statement terminates instead of waiting and any partial changes it has made are rolled back. In this event, try executing the transaction again, later.

Blocking is more likely to occur at higher isolation levels because more locking and more checking is done. Higher isolation levels usually provide less concurrency. How much less depends on the individual natures of the concurrent transactions.

For more information about the BLOCKING option, see BLOCKING option [database].


Deadlock

Transaction blocking can lead to deadlock, a situation in which a set of transactions arrive at a state where none of them can proceed.

Reasons for deadlocks

A deadlock can arise for two reasons:

  • A cyclical blocking conflict Transaction A is blocked on transaction B, and transaction B is blocked on transaction A. Clearly, more time will not solve the problem, and one of the transactions must be canceled, allowing the other to proceed. The same situation can arise with more than two transactions blocked in a cycle.

  • All active database threads are blocked When a transaction becomes blocked, its database thread is not relinquished. If the database is configured with three threads and transactions A, B, and C are blocked on transaction D which is not currently executing a request, then a deadlock situation has arisen since there are no available threads.

Adaptive Server Anywhere automatically rolls back the last statement that became blocked (eliminating the deadlock situation), and returns an error to that transaction indicating which form of deadlock occurred.

The number of database threads that the server uses depends on the individual database's setting.

For information about setting the number of database threads, see Controlling threading behavior.

Determining who is blocked

You can use the sa_conn_info system procedure to determine which connections are blocked on which other connections. This procedure returns a result set consisting of a row for each connection. One column of the result set lists whether the connection is blocked, and if so which other connection it is blocked on.

For more information, see sa_conn_info system procedure.

The database server provides more detailed deadlock reporting using the LOG_DEADLOCKS option and sa_report_deadlocks system procedure. When you turn on the LOG_DEADLOCKS option, the database server records information about the blocked connections in an internal buffer.

toggle To use deadlock reporting

  1. Turn on the LOG_DEADLOCKS option.

    SET OPTION PUBLIC.LOG_DEADLOCKS='ON'

    The database server records information about deadlocks in an internal buffer.

    For more information, see LOG_DEADLOCKS option [database].

  2. Retrieve the deadlock information using sa_report_deadlocks.

    CALL sa_report_deadlocks()

    For more information, see sa_report_deadlocks system procedure.


Choosing isolation levels

The choice of isolation level depends on the kind of task an application is carrying out. This section gives some guidelines for choosing isolation levels.

When you choose an appropriate isolation level you must balance the need for consistency and accuracy with the need for concurrent transactions to proceed unimpeded. If a transaction involves only one or two specific values in one table, it is unlikely to interfere as much with other processes as one which searches many large tables and may need to lock many rows or entire tables and may take a very long time to complete.

For example, if your transactions involve transferring money between bank accounts or even checking account balances, you will likely want to do your utmost to ensure that the information you return is correct. On the other hand, if you just want a rough estimate of the proportion of inactive accounts, then you may not care whether your transaction waits for others or not and indeed may be willing to sacrifice some accuracy to avoid interfering with other users of the database.

Furthermore, a transfer may affect only the two rows which contain the two account balances, whereas all the accounts must be read in order to calculate the estimate. For this reason, the transfer is less likely to delay other transactions.

Adaptive Server Anywhere provides four levels of isolation: levels 0, 1, 2, and 3. Level 3 provides complete isolation and ensures that transactions are interleaved in such a manner that the schedule is serializable.

Serializable schedules
Typical transactions at various isolation levels
Improving concurrency at isolation levels 2 and 3
Reducing the impact of locking


Serializable schedules

To process transactions concurrently, the database server must execute some component statements of one transaction, then some from other transactions, before continuing to process further operations from the first. The order in which the component operations of the various transactions are interleaved is called the schedule.

Applying transactions concurrently in this manner can result in many possible outcomes, including the three particular inconsistencies described in the previous section. Sometimes, the final state of the database also could have been achieved had the transactions been executed sequentially, meaning that one transaction was always completed in its entirety before the next was started. A schedule is called serializable whenever executing the transactions sequentially, in some order, could have left the database in the same state as the actual schedule.

For more information about how Adaptive Server Anywhere handles serialization, see Two-phase locking.

Serializability is the commonly accepted criterion for correctness. A serializable schedule is accepted as correct because the database is not influenced by the concurrent execution of the transactions.

The isolation level affects a transaction's serializability. At isolation level 3, all schedules are serializable. The default setting is 0.

Serializable means that concurrency has added no effect

Even when transactions are executed sequentially, the final state of the database can depend upon the order in which these transactions are executed. For example, if one transaction sets a particular cell to the value 5 and another sets it to the number 6, then the final value of the cell is determined by which transaction executes last.

Knowing a schedule is serializable does not settle which order transactions would best be executed, but rather states that concurrency has added no effect. Outcomes which may be achieved by executing the set of transactions sequentially in some order are all assumed correct.

Unserializable schedules introduce inconsistencies

The inconsistencies introduced in Typical types of inconsistency are typical of the types of problems that appear when the schedule is not serializable. In each case, the inconsistency appeared because the statements were interleaved in such a way as to produce a result that would not be possible if all transactions were executed sequentially. For example, a dirty read can only occur if one transaction can select rows while another transaction is in the middle of inserting or updating data in the same row.


Typical transactions at various isolation levels

Various isolation levels lend themselves to particular types of tasks. Use the information below to help you decide which level is best suited to each particular operation.

Typical level 0 transactions

Transactions that involve browsing or performing data entry may last several minutes, and read a large number of rows. If isolation level 2 or 3 is used, concurrency can suffer. Isolation level of 0 or 1 is typically used for this kind of transaction.

For example, a decision support application that reads large amounts of information from the database to produce statistical summaries may not be significantly affected if it reads a few rows that are later modified. If high isolation is required for such an application, it may acquire read locks on large amounts of data, not allowing other applications write access to it.

Typical level 1 transactions

Isolation level 1 is particularly useful in conjunction with cursors, because this combination ensures cursor stability without greatly increasing locking requirements. Adaptive Server Anywhere achieves this benefit through the early release of read locks acquired for the present row of a cursor. These locks must persist until the end of the transaction at either levels two or three in order to guarantee repeatable reads.

For example, a transaction that updates inventory levels through a cursor is particularly suited to this level, because each of the adjustments to inventory levels as items are received and sold would not be lost, yet these frequent adjustments would have minimal impact on other transactions.

Typical level 2 transactions

At isolation level 2, rows that match your criterion cannot be changed by other transactions. You can thus employ this level when you must read rows more than once and rely that rows contained in your first result set won't change.

Because of the relatively large number of read locks required, you should use this isolation level with care. As with level 3 transactions, careful design of your database and indexes reduce the number of locks acquired and hence can improve the performance of your database significantly.

Typical level 3 transactions

Isolation level 3 is appropriate for transactions that demand the most in security. The elimination of phantom rows lets you perform multi-step operations on a set of rows without fear that new rows will appear partway through your operations and corrupt the result.

However much integrity it provides, isolation level 3 should be used sparingly on large systems that are required to support a large number of concurrent transactions. Adaptive Server Anywhere places more locks at this level than at any other, raising the likelihood that one transaction will impede the process of many others.


Improving concurrency at isolation levels 2 and 3

Isolation levels 2 and 3 use a lot of locks and so good design is of particular importance for databases that make regular use of these isolation levels. When you must make use of serializable transactions, it is important that you design your database, in particular the indices, with the business rules of your project in mind. You may also improve performance by breaking large transactions into several smaller ones, thus shortening the length of time that rows are locked.

Although serializable transactions have the most potential to block other transactions, they are not necessarily less efficient. When processing these transactions, Adaptive Server Anywhere can perform certain optimizations that may improve performance, in spite of the increased number of locks. For example, since all rows read must be locked whether or not they match the a search criteria, the database server is free to combine the operation of reading rows and placing locks.


Reducing the impact of locking

You should avoid running transactions at isolation level 3 whenever practical. They tend to place large number of locks and hence impact the efficient execution of other concurrent transactions.

When the nature of an operation demands that it run at isolation level 3, you can lower its impact on concurrency by designing the query to read as few rows and index entries as possible. These steps will help the level 3 transaction run more quickly and, of possibly greater importance, will reduce the number of locks it places.

In particular, you may find that adding an index may greatly help speed up transactions, particularly when at least one of them must execute at isolation level 3. An index can have two benefits:

  • An index enables rows to be located in an efficient manner

  • Searches that make use of the index may need fewer locks.

For more information about the details of the locking methods employed by Adaptive Server Anywhere is located in How locking works.

For more information on performance and how Adaptive Server Anywhere plans its access of information to execute your commands, see Monitoring and Improving Performance.


Isolation level tutorials

The different isolation levels behave in very different ways, and which one you will want to use depends on your database and on the operations you are carrying out. The following set of tutorials will help you determine which isolation levels are suitable for different tasks.


Dirty read tutorial

The following tutorial demonstrates one type of inconsistency that can occur when multiple transactions are executed concurrently. Two employees at a small merchandising company access the corporate database at the same time. The first person is the company's Sales Manager. The second is the Accountant.

The Sales Manager wants to increase the price of tee shirts sold by their firm by $0.95, but is having a little trouble with the syntax of the SQL language. At the same time, unknown to the Sales Manager, the Accountant is trying to calculate the retail value of the current inventory to include in a report he volunteered to bring to the next management meeting.

Tip:
Before altering your database in the following way, it is prudent to test the change by using SELECT in place of UPDATE.

In this example, you will play the role of two people, both using the demonstration database concurrently.

  1. Start Interactive SQL.

  2. Connect to the sample database as the Sales Manager:

    • In the Connect dialog, choose the ODBC data source ASA 9.0 Sample.

    • On the Advanced tab, type the following string to make the window easier to identify:

         ConnectionName=Sales Manager

    Click OK to connect.

  3. Start a second instance of Interactive SQL.

  4. Connect to the sample database as the Accountant:

    • In the Connect dialog, choose the ODBC data source ASA 9.0 Sample.

    • On the Advanced tab, type the following string to make the window easier to identify:

         ConnectionName=Accountant

    • Click OK to connect.

  5. As the Sales Manager, raise the price of all the tee shirts by $0.95:

    • In the window labeled Sales Manager, execute the following commands:

         SELECT id, name, unit_price
   FROM product;
   UPDATE PRODUCT
   SET unit_price = unit_price + 95
   WHERE NAME = 'Tee Shirt'

    The result is:

    id | name | unit_price
    300 | Tee Shirt | 104.00
    301 | Tee Shirt | 109.00
    302 | Tee Shirt | 109.00
    400 | Baseball Cap | 9.00
    ... ... ...

    You observe immediately that you should have entered 0.95 instead of 95, but before you can fix your error, the Accountant accesses the database from another office.

  6. The company's Accountant is worried that too much money is tied up in inventory. As the Accountant, execute the following commands to calculate the total retail value of all the merchandise in stock:

    SELECT SUM( quantity * unit_price )
  AS inventory
FROM product

    The result is:

    inventory
    21453.00

    Unfortunately, this calculation is not accurate. The Sales Manager accidentally raised the price of the visor $95, and the result reflects this erroneous price. This mistake demonstrates one typical type of inconsistency known as a dirty read. You, as the Accountant, accessed data which the Sales Manager has entered, but has not yet committed.

    You can eliminate dirty reads and other inconsistencies explained in Isolation levels and consistency.

  7. As the Sales Manager, fix the error by rolling back your first changes and entering the correct UPDATE command. Check that your new values are correct.

    ROLLBACK;
UPDATE product
SET unit_price = unit_price + 0.95
WHERE NAME = 'Tee Shirt';
    id | name | unit_price
    300 | Tee Shirt | 9.95
    301 | Tee Shirt | 14.95
    302 | Tee Shirt | 14.95
    400 | Baseball Cap | 9.00
    ... ... ...

  8. The Accountant does not know that the amount he calculated was in error. You can see the correct value by executing his SELECT statement again in his window.

    SELECT SUM( quantity * unit_price )
  AS inventory
FROM product;
    inventory
    6687.15

  9. Finish the transaction in the Sales Manager's window. She would enter a COMMIT statement to make his changes permanent, but you may wish to enter a ROLLBACK, instead, to avoid changing the copy of the demonstration database on your machine.

    ROLLBACK;

The Accountant unknowingly receives erroneous information from the database because the database server is processing the work of both the Sales Manager and the Accountant concurrently.


Non-repeatable read tutorial

The example in Dirty read tutorial demonstrated the first type of inconsistency, namely the dirty read. In that example, an Accountant made a calculation while the Sales Manager was in the process of updating a price. The Accountant's calculation used erroneous information which the Sales Manager had entered and was in the process of fixing.

The following example demonstrates another type of inconsistency: non-repeatable reads. In this example, you will play the role of the same two people, both using the demonstration database concurrently. The Sales Manager wishes to offer a new sales price on plastic visors. The Accountant wishes to verify the prices of some items that appear on a recent order.

This example begins with both connections at isolation level 1, rather than at isolation level 0, which is the default for the demonstration database supplied with Adaptive Server Anywhere. By setting the isolation level to 1, you eliminate the type of inconsistency which the previous tutorial demonstrated, namely the dirty read.

  1. Start Interactive SQL.

  2. Connect to the sample database as the Sales Manager:

    • In the Connect dialog, choose the ODBC data source ASA 9.0 Sample.

    • On the Advanced tab, enter the following string to make the window easier to identify:

         ConnectionName=Sales Manager

    • Click OK to connect.

  3. Start a second instance of Interactive SQL.

  4. Connect to the sample database as the Accountant:

    • In the Connect dialog, choose the ODBC data source ASA 9.0 Sample.

    • On the Advanced tab, enter the following string to make the window easier to identify:

         ConnectionName=Accountant

    • Click OK to connect.

  5. Set the isolation level to 1 for the Accountant's connection by executing the following command.

    SET TEMPORARY OPTION ISOLATION_LEVEL = 1

  6. Set the isolation level to 1 in the Sales Manager's window by executing the following command:

    SET TEMPORARY OPTION ISOLATION_LEVEL = 1

  7. The Accountant decides to list the prices of the visors. As the Accountant, execute the following command:

    SELECT id, name, unit_price FROM product
    id | name | unit_price
    300 | Tee Shirt | 9.00
    301 | Tee Shirt | 14.00
    302 | Tee Shirt | 14.00
    400 | Baseball Cap | 9.00
    ... ... ...

  8. The Sales Manager decides to introduce a new sale price for the plastic visor. As the Sales Manager, execute the following command:

    SELECT id, name, unit_price FROM product
WHERE name = 'Visor';
UPDATE product
SET unit_price = 5.95 WHERE id = 501;
COMMIT;
    id | name | unit_price
    500 | Visor | 7.00
    501 | Visor | 5.95

  9. Compare the price of the visor in the Sales Manager window with the price for the same visor in the Accountant window. The Accountant window still displays the old price, even though the Sales Manager has entered the new price and committed the change.

    This inconsistency is called a non-repeatable read, because if the Accountant did the same SELECT a second time in the same transaction, he wouldn't get the same results. Try it for yourself. As the Accountant, execute the select command again. Observe that the Sales Manager's sale price now displays.

    SELECT id, name, price
FROM product
    id | name | unit_price
    300 | Tee Shirt | 9.00
    301 | Tee Shirt | 14.00
    302 | Tee Shirt | 14.00
    400 | Baseball Cap | 9.00
    ... ... ...

    Of course if the Accountant had finished his transaction, for example by issuing a COMMIT or ROLLBACK command before using SELECT again, it would be a different matter. The database is available for simultaneous use by multiple users and it is completely permissible for someone to change values either before or after the Accountant's transaction. The change in results is only inconsistent because it happens in the middle of his transaction. Such an event makes the schedule unserializable.

  10. The Accountant notices this behavior and decides that from now on he doesn't want the prices changing while he looks at them. Repeatable reads are eliminated at isolation level 2. Play the role of the Accountant:

    SET TEMPORARY OPTION ISOLATION_LEVEL = 2;
SELECT id, name, unit_price
FROM product

  11. The Sales Manager decides that it would be better to delay the sale on the plastic visor until next week so that she won't have to give the lower price on a big order that she's expecting will arrive tomorrow. In her window, try to execute the following statements. The command will start to execute, and then his window will appear to freeze.

    UPDATE product
SET unit_price = 7.00
WHERE id = 501

    The database server must guarantee repeatable reads at isolation level 2. To do so, it places a read lock on each row of the product table that the Accountant reads. When the Sales Manager tries to change the price back, her transaction must acquire a write lock on the plastic visor row of the product table. Since write locks are exclusive, her transaction must wait until the Accountant's transaction releases its read lock.

  12. The Accountant is finished looking at the prices. He doesn't want to risk accidentally changing the database, so he completes his transaction with a ROLLBACK statement.

    ROLLBACK

    Observe that as soon as the database server executes this statement, the Sales Manager's transaction completes.

    id | name | unit_price
    500 | Visor | 7.00
    501 | Visor | 7.00

  13. The Sales Manager can finish now. She wishes to commit her change to restore the original price.

    COMMIT
Types of Locks and different isolation levels

When you upgraded the Accountant's isolation from level 1 to level 2, the database server used read locks where none had previously been acquired. In general, each isolation level is characterized by the types of locks needed and by how locks held by other transactions are treated.

At isolation level 0, the database server needs only write locks. It makes use of these locks to ensure that no two transactions make modifications that conflict. For example, a level 0 transaction acquires a write lock on a row before it updates or deletes it, and inserts any new rows with a write lock already in place.

Level 0 transactions perform no checks on the rows they are reading. For example, when a level 0 transaction reads a row, it doesn't bother to check what locks may or may not have been acquired on that row by other transactions. Since no checks are needed, level 0 transactions are particularly fast. This speed comes at the expense of consistency. Whenever they read a row which is write locked by another transaction, they risk returning dirty data.

At level 1, transactions check for write locks before they read a row. Although one more operation is required, these transactions are assured that all the data they read is committed. Try repeating the first tutorial with the isolation level set to 1 instead of 0. You will find that the Accountant's computation cannot proceed while the Sales Manager's transaction, which updates the price of the tee shirts, remains incomplete.

When the Accountant raised his isolation to level 2, the database server began using read locks. From then on, it acquired a read lock for his transaction on each row that matched his selection.

Transaction blocking

In the above tutorial, the Sales Manager window froze during the execution of her UPDATE command. The database server began to execute her command, then found that the Accountant's transaction had acquired a read lock on the row that the Sales Manager needed to change. At this point, the database server simply paused the execution of the UPDATE. Once the Accountant finished his transaction with the ROLLBACK, the database server automatically released his locks. Finding no further obstructions, it then proceeded to complete execution of the Sales Manager's UPDATE.

In general, a locking conflict occurs when one transaction attempts to acquire an exclusive lock on a row on which another transaction holds a lock, or attempts to acquire a shared lock on a row on which another transaction holds an exclusive lock. One transaction must wait for another transaction to complete. The transaction that must wait is said to be blocked by another transaction.

When the database server identifies a locking conflict which prohibits a transaction from proceeding immediately, it can either pause execution of the transaction, or it can terminate the transaction, roll back any changes, and return an error. You control the route by setting the BLOCKING option. When BLOCKING is ON the second transaction waits, as in the above tutorial.

For more information about the blocking option, see The BLOCKING option.


Phantom row tutorial

The following tutorial continues the same scenario. In this case, the Accountant views the department table while the Sales Manager creates a new department. You will observe the appearance of a phantom row.

If you have not done so, do steps 1 through 4 of the previous tutorial, Non-repeatable read tutorial, so that you have two instances of Interactive SQL.

  1. Set the isolation level to 2 in the Sales Manager window by executing the following command.

    SET TEMPORARY OPTION ISOLATION_LEVEL = 2;

  2. Set the isolation level to 2 for the Accountant window by executing the following command.

    SET TEMPORARY OPTION ISOLATION_LEVEL = 2;

  3. In the Accountant window, enter the following command to list all the departments.

    SELECT * FROM department
ORDER BY dept_id;
    dept_id | dept_name | dept_head_id
    100 | R & D | 501
    200 | Sales | 902
    300 | Finance | 1293
    400 | Marketing | 1576
    ... ... ...

  4. The Sales Manager decides to set up a new department to focus on the foreign market. Philip Chin, who has emp_id 129, will head the new department.

    INSERT INTO department
   (dept_id, dept_name, dept_head_id)
   VALUES(600, 'Foreign Sales', 129);
COMMIT;

    The final command creates the new entry for the new department. It appears as a new row at the bottom of the table in the Sales Manager's window.

  5. The Accountant, however, is not aware of the new department. At isolation level 2, the database server places locks to ensure that no row changes, but places no locks that stop other transactions from inserting new rows.

    The Accountant will only discover the new row if he executes his SELECT command again. In the Accountant's window, execute the SELECT statement again. You will see the new row appended to the table.

    SELECT *
FROM department
ORDER BY dept_id;
    dept_id | dept_name | dept_head_id
    100 | R & D | 501
    200 | Sales | 902
    300 | Finance | 1293
    500 | Shipping | 703
    ... ... ...

    The new row that appears is called a phantom row because, from the Accountant's point of view, it appears like an apparition, seemingly from nowhere. The Accountant is connected at isolation level 2. At that level, the database server acquires locks only on the rows that he is using. Other rows are left untouched and hence there is nothing to prevent the Sales Manager from inserting a new row.

  6. The Accountant would prefer to avoid such surprises in future, so he raises the isolation level of his current transaction to level 3. Enter the following commands for the Accountant.

    SET TEMPORARY OPTION ISOLATION_LEVEL = 3
SELECT *
FROM department
ORDER BY dept_id

  7. The Sales Manager would like to add a second department to handle sales initiative aimed at large corporate partners. Execute the following command in the Sales Manager's window.

    INSERT INTO department
   (dept_id, dept_name, dept_head_id)
VALUES(700, 'Major Account Sales', 902)

    The Sales Manager's window will pause during execution because the Accountant's locks block the command. Click the Interrupt the SQL Statement button on the toolbar (or choose Stop from the SQL menu) to interrupt this entry.

  8. To avoid changing the demonstration database that comes with Adaptive Server Anywhere, you should roll back the insertion of the new departments. Execute the following command in the Sales Manager's window:

    ROLLBACK

When the Accountant raised his isolation to level 3 and again selected all rows in the department table, the database server placed anti-insert locks on each row in the table, and one extra phantom lock to avoid insertion at the end of the table. When the Sales Manager attempted to insert a new row at the end of the table, it was this final lock that blocked her command.

Notice that the Sales Manager's command was blocked even though the Sales Manager is still connected at isolation level 2. The database server places anti-insert locks, like read locks, as demanded by the isolation level and statements of each transactions. Once placed, these locks must be respected by all other concurrent transactions.

For more information on locking, see How locking works.


Practical locking implications tutorial

The following continues the same scenario. In this tutorial, the Accountant and the Sales Manager both have tasks that involve the sales order and sales order items tables. The Accountant needs to verify the amounts of the commission checks paid to the sales employees for the sales they made during the month of April 2001. The Sales Manager notices that a few orders have not been added to the database and wants to add them.

Their work demonstrates phantom locking. A phantom lock is a shared lock placed on an indexed scan position to prevent phantom rows. When a transaction at isolation level 3 selects rows which match a given criterion, the database server places anti-insert locks to stop other transactions from inserting rows which would also match. The number of locks placed on your behalf depends both on the search criterion and on the design of your database.

If you have not done so, do steps 1 through 3 of the previous tutorial which describe how to start two instances of Interactive SQL.

  1. Set the isolation level to 2 in both the Sales Manager window and the Accountant window by executing the following command.

    SET TEMPORARY OPTION ISOLATION_LEVEL = 2

  2. Each month, the sales representatives are paid a commission, which is calculated as a percentage of their sales for that month. The Accountant is preparing the commission checks for the month of April 2001. His first task is to calculate the total sales of each representative during this month.

    Enter the following command in the Accountant's window. Prices, sales order information, and employee data are stored in separate tables. Join these tables using the foreign key relationships to combine the necessary pieces of information.

    SELECT emp_id, emp_fname, emp_lname,
   SUM(sales_order_items.quantity * unit_price)
      AS "April sales"
FROM employee
   KEY JOIN sales_order
   KEY JOIN sales_order_items
   KEY JOIN product
WHERE '2001-04-01' <= order_date
   AND order_date < '2001-05-01'
GROUP BY  emp_id, emp_fname, emp_lname
    emp_id | emp_fname | emp_lname | April sales
    129 | Philip | Chin | 2160.00
    195 | Marc | Dill | 2568.00
    299 | Rollin | Overbey | 5760.00
    467 | James | Klobucher | 3228.00
    ... ... ... ...

  3. The Sales Manager notices that a big order sold by Philip Chin was not entered into the database. Philip likes to be paid his commission promptly, so the Sales manager enters the missing order, which was placed on April 25.

    In the Sales Manager's window, enter the following commands. The Sales order and the items are entered in separate tables because one order can contain many items. You should create the entry for the sales order before you add items to it. To maintain referential integrity, the database server allows a transaction to add items to an order only if that order already exists.

    INSERT into sales_order
VALUES ( 2653, 174, '2001-04-22', 'r1',
      'Central', 129);
INSERT into sales_order_items
VALUES ( 2653, 1, 601, 100, '2001-04-25' );
COMMIT;

  4. The Accountant has no way of knowing that the Sales Manager has just added a new order. Had the new order been entered earlier, it would have been included in the calculation of Philip Chin's April sales.

    In the Accountant's window, calculate the April sales totals again. Use the same command, and observe that Philip Chin's April sales changes to $4560.00.

    emp_id | emp_fname | emp_lname | April sales
    129 | Philip | Chin | 4560.00
    195 | Marc | Dill | 2568.00
    299 | Rollin | Overbey | 5760.00
    467 | James | Klobucher | 3228.00
    ... ... ... ...

    Imagine that the Accountant now marks all orders placed in April to indicate that commission has been paid. The order that the Sales Manager just entered might be found in the second search and marked as paid, even though it was not included in Philip's total April sales!

  5. At isolation level 3, the database server places anti-insert locks to ensure that no other transactions can add a row which matches the criterion of a search or select.

    First, roll back the insertion of Philip's missing order: Execute the following statement in the Sales Manager's window.

    ROLLBACK

  6. In the Accountant's window, execute the following two statements.

    ROLLBACK;
SET TEMPORARY OPTION ISOLATION_LEVEL = 3;

  7. In the Sales Manager's window, execute the following statements to remove the new order.

    DELETE
FROM sales_order_items
WHERE id = 2653;
DELETE
FROM sales_order
WHERE id = 2653;
COMMIT;

  8. In the Accountant's window, execute same query as before.

    SELECT emp_id, emp_fname, emp_lname,
   SUM(sales_order_items.quantity * unit_price)
      AS "April sales"
FROM employee
   KEY JOIN sales_order
   KEY JOIN sales_order_items
   KEY JOIN product
WHERE '2001-04-01' <= order_date
   AND order_date < '2001-05-01'
GROUP BY  emp_id, emp_fname, emp_lname

    Because you set the isolation to level 3, the database server will automatically place anti-insert locks to ensure that the Sales Manager can't insert April order items until the Accountant finishes his transaction.

  9. Return to the Sales Manager's window. Again attempt to enter Philip Chin's missing order.

    INSERT INTO sales_order
VALUES ( 2653, 174, '2001-04-22',
         'r1','Central', 129)

    The Sales Manager's window will hang; the operation will not complete. Click the Interrupt the SQL Statement button on the toolbar (or choose Stop from the SQL menu) to interrupt this entry.

  10. The Sales Manager can't enter the order in April, but you might think that she could still enter it in May.

    Change the date of the command to May 05 and try again.

    INSERT INTO sales_order
VALUES ( 2653, 174, '2001-05-05', 'r1',
      'Central', 129)

    The Sales Manager's window will hang again. Click the Interrupt the SQL Statement button on the toolbar (or choose Stop from the SQL menu) to interrupt this entry. Although the database server places no more locks than necessary to prevent insertions, these locks have the potential to interfere with a large number of other transactions.

    The database server places locks in table indices. For example, it places a phantom lock in an index so a new row cannot be inserted immediately before it. However, when no suitable index is present, it must lock every row in the table.

    In some situations, anti-insert locks may block some insertions into a table, yet allow others.

  11. The Sales Manager wishes to add a second item to order 2651. Use the following command.

    INSERT INTO sales_order_items
VALUES ( 2651, 2, 302, 4, '2001-05-22' )

    All goes well, so the Sales Manager decides to add the following item to order 2652 as well.

    INSERT INTO sales_order_items
VALUES ( 2652, 2, 600, 12, '2001-05-25' )

    The Sales Manager's window will hang. Click the Interrupt the SQL Statement button on the toolbar (or choose Stop from the SQL menu) to interrupt this entry.

  12. Conclude this tutorial by undoing any changes to avoid changing the demonstration database. Enter the following command in the Sales Manager's window.

    ROLLBACK

    Enter the same command in the Accountant's window.

    ROLLBACK

You may now close both windows.


How locking works

When the database server processes a transaction, it can lock one or more rows of a table. The locks maintain the reliability of information stored in the database by preventing concurrent access by other transactions. They also improve the accuracy of result queries by identifying information which is in the process of being updated.

The database server places these locks automatically and needs no explicit instruction. It holds all the locks acquired by a transaction until the transaction is completed, for example by either a COMMIT or ROLLBACK statement, with a single exception noted in Early release of read locks.

The transaction that has access to the row is said to hold the lock. Depending on the type of lock, other transactions may have limited access to the locked row, or none at all.

Obtaining information about locks on a table

You can use the sa_locks system procedure to list information about locks that are held in the database. For more information, see sa_locks system procedure.

You can also view locks in Sybase Central. Select the database in the left pane, and a tab called Table Locks appears in the right pane. For each lock, this tab shows you the connection ID, user ID, table name, lock type, and lock name.

Objects that can be locked
Types of locks
Locking during queries
Locking during inserts
Locking during updates
Locking during deletes
Two-phase locking
Early release of read locks
Special optimizations


Objects that can be locked

Adaptive Server Anywhere places locks on the following objects.

  • Rows in tables A transaction can lock a particular row to prevent another transaction from changing it. A transaction must place a write lock on a row if it intends to modify the row.

  • Insertion points between rows Transactions typically scan rows using the ordering imposed by an index, or scan rows sequentially. In either case, a lock can be placed on the scan position. For example, placing a lock in an index can prevent another transaction from inserting a row with a specific value or range of values.

  • Table schemas A transaction can lock the schema of a table, preventing other transactions from modifying the table's structure.

Of these objects, rows are likely the most intuitive. It is understandable that a transaction reading, updating, deleting, or inserting a row should limit the simultaneous access to other transactions. Similarly, a transaction changing the structure of a table, perhaps inserting a new column, could greatly impact other transactions. In such a case, it is essential to limit the access of other transactions to prevent errors.

Row orderings

You can use an index to order rows based on a particular criterion established when the index was constructed.

When there is no index, Adaptive Server Anywhere orders rows by their physical placement on disk. In the case of a sequential scan, the specific ordering is defined by the internal workings of the database server. You should not rely on the order of rows in a sequential scan. From the point of view of scanning the rows, however, Adaptive Server Anywhere treats the request similarly to an indexed scan, albeit using an ordering of its own choosing. It can place locks on positions in the scan as it would were it using an index.

Through locking a scan position, a transaction prevents some actions by other transactions relating to a particular range of values in that ordering of the rows. Insert and anti-insert locks are always placed on scan positions.

For example, a transaction might delete a row, hence deleting a particular primary key value. Until this transaction either commits the change or rolls it back, it must protect its right to do either. In the case of a deleted row, it must ensure that no other transaction can insert a row using the same primary key value, hence making a rollback operation impossible. A lock on the scan position this row occupied reserves this right while having the least impact on other transactions.


Types of locks

Adaptive Server Anywhere uses four distinct types of locks to implement its locking scheme and ensure appropriate levels of isolation between transactions:

  • read lock (shared)

  • phantom lock or anti-insert lock (shared)

  • write lock (exclusive)

  • anti-phantom lock or insert lock (shared)

Remember that the database server places these locks automatically and needs no explicit instruction.

Each of these locks has a separate purpose, and they all work together. Each prevents a particular set of inconsistencies that could occur in their absence. Depending on the isolation level you select, the database server will use some or all of them to maintain the degree of consistency you require.

The above types of locks have the following uses:

  • A transaction acquires a write lock whenever it inserts, updates, or deletes a row. No other transaction can obtain either a read or a write lock on the same row when a write lock is set. A write lock is an exclusive lock.

  • A transaction can acquire a read lock when it reads a row. Several transactions can acquire read locks on the same row (a read lock is a shared or nonexclusive lock). Once a row has been read locked, no other transaction can obtain a write lock on it. Thus, a transaction can ensure that no other transaction modifies or deletes a row by acquiring a read lock.

  • An anti-insert lock, or phantom lock, is placed on a scan position to prevent phantom rows. It prevents other transactions from inserting a row into a table immediately before the row which is anti-insert locked. Anti-insert locks for lookups using indexes require a read lock on each row that is read, and one extra read lock to prevent insertions into the index at the end of the result set. Phantom rows for lookups that do not use indexes require a read lock on all rows in a table to prevent insertions from altering the result set, and so can have a bad effect on concurrency.

  • An insert lock, or anti-phantom lock, is placed on a scan position to reserve the right to insert a row. Once one transaction acquires an insert lock on a row, no other transaction can acquire an anti-insert lock on the same row. A read lock on the corresponding row is always acquired at the same time as an insert lock to ensure that no other process can update or destroy the row, thereby bypassing the insert lock.

Adaptive Server Anywhere uses these four types of locks as necessary to ensure the level of consistency that you require. You do not need to explicitly request the use of a particular lock. Instead, you control the level of consistency, as is explained in the next section. Knowledge of the types of locks will guide you in choosing isolation levels and understanding the impact of each level on performance.

Exclusive versus shared locks

These four types of locks each fall into one of two categories:

  • Exclusive locks Only one transaction can hold an exclusive lock on a row of a table at one time. No transaction can obtain an exclusive lock while any other transaction holds a lock of any type on the same row. Once a transaction acquires an exclusive lock, requests to lock the row by other transactions will be denied.

    Write locks are exclusive.

  • Shared locks Any number of transactions may acquire shared locks on any one row at the same time. Shared locks are sometimes referred to as non-exclusive locks.

    Read locks, insert locks, and anti-insert locks are shared.

Only one transaction should change any one row at one time. Otherwise, two simultaneous transactions might try to change one value to two different new ones. Hence, it is important that a write lock be exclusive.

By contrast, no difficulty arises if more than one transaction wants to read a row. Since neither is changing it, there is no conflict of interest. Hence, read locks may be shared.

You may apply similar reasoning to anti-insert and insert locks. Many transactions can prevent the insertion of a row in a particular scan position by each acquiring an anti-insert lock. Similar logic applies for insert locks. When a particular transaction requires exclusive access, it can easily achieve exclusive access by obtaining both an anti-insert and an insert lock on the same row. These locks do not conflict when they are held by the same transaction.

Which specific locks conflict?

The following table identifies the combination of locks that conflict.

 | read | write | anti-insert | insert
read |  | conflict |  |
write | conflict | conflict |  |
anti-insert |  |  |  | conflict
insert |  |  | conflict |

These conflicts arise only when the locks are held by different transactions. For example, one transaction can obtain both anti-insert and insert locks on a single scan position to obtain exclusive access to a location.


Locking during queries

The locks that Adaptive Server Anywhere uses when a user enters a SELECT statement depend on the transaction's isolation level.

SELECT statements at isolation level 0

No locking operations are required when executing a SELECT statement at isolation level 0. Each transaction is not protected from changes introduced by other transactions. It is the responsibility of the programmer or database user to interpret the result of these queries with this limitation in mind.

SELECT statements at isolation level 1

You may be surprised to learn that Adaptive Server Anywhere uses almost no more locks when running a transaction at isolation level 1 than it does at isolation level 0. Indeed, the database server modifies its operation in only two ways.

The first difference in operation has nothing to do with acquiring locks, but rather with respecting them. At isolation level 0, a transaction is free to read any row, whether or not another transaction has acquired a write lock on it. By contrast, before reading each row an isolation level 1 transaction must check whether a write lock is in place. It cannot read past any write-locked rows because doing so might entail reading dirty data.

The second difference in operation creates cursor stability. Cursor stability is achieved by acquiring a read lock on the current row of a cursor. This read lock is released when the cursor is moved. More than one row may be affected if the contents of the cursor is the result of a join. In this case, the database server acquires read locks on all rows which have contributed information to the cursor's current row and removes all these locks as soon as another row of the cursor is selected as current.

SELECT statements at isolation level 2

At isolation level 2, Adaptive Server Anywhere modifies its procedures to ensure that your reads are repeatable. If your SELECT command returns values from every row in a table, then the database server acquires a read lock on each row of the table as it reads it. If, instead, your SELECT contains a WHERE clause, or another condition which restricts the rows to selected, then the database server instead reads each row, tests the values in the row against your criterion, and then acquires a read lock on the row if it meets your criterion.

As at all isolation levels, the locks acquired at level 2 include all those set at levels 1 and 0. Thus, cursor stability is again ensured and dirty reads are not permitted.

SELECT statements at isolation level 3

When operating at isolation level 3, Adaptive Server Anywhere is obligated to ensure that all schedules are serializable. In particular, in addition to the requirements imposed at each of the lower levels, it must eliminate phantom rows.

To accommodate this requirement, the database server uses read locks and anti-insert locks. When you make a selection, the database server acquires a read lock on each row that contributes information to your result set. Doing so ensures that no other transactions can modify that material before you have finished using it.

This requirement is similar to the procedures that the database server uses at isolation level 2, but differs in that a lock must be acquired for each row read, whether or not it meets any attached criteria. For example, if you select the names of all employees in the sales department, then the server must lock all the rows which contain information about a sales person, whether the transaction is executing at isolation level 2 or 3. At isolation level 3, however, it must also acquire read locks on each of the rows of employees which are not in the sales department. Otherwise, someone else accessing the database could potentially transfer another employee to the sales department while you were still using your results.

The fact that a read lock must be acquired on each row whether or not it meets your criteria has two important implications.

  • The database server may need to place many more locks than would be necessary at isolation level 2.

  • The database server can operate a little more efficiently: It can immediately acquire a read lock on each row at as it reads it, since the locks must be placed whether or not the information in the row is accepted.

The number of anti-insert locks the server places can very greatly and depends upon your criteria and on the indexes available in the table. Suppose you select information about the employee with Employee ID 123. If the employee ID is the primary key of the employee table, then the database server can economize its operations. It can use the index, which is automatically built for a primary key, to locate the row efficiently. In addition, there is no danger that another transaction could change another Employee's ID to 123 because primary key values must be unique. The server can guarantee that no second employee is assigned that ID number simply by acquiring a read lock on only the one row containing information about the employee with that number.

By contrast, the database server would acquire more locks were you instead to select all the employees in the sales department. Since any number of employees could be added to the department, the server will likely have to read every row in the employee table and test whether each person is in sales. If this is the case, both read and anti-insert locks must be acquired for each row.


Locking during inserts

INSERT operations create new rows. Adaptive Server Anywhere employs the following procedure to ensure data integrity.

For more information about how locks are used during inserts, see Anti-insert locks.

  1. Make a location in memory to store the new row. The location is initially hidden from the rest of the database, so there is as yet no concern that another transaction could access it.

  2. Fill the new row with any supplied values.

  3. Write lock the new row.

  4. Place an insert lock in the table to which the row is being added. Recall that insert locks are exclusive, so once the insert lock is acquired, no other transaction can block the insertion by acquiring an anti-insert lock.

  5. Insert the row into the table. Other transactions can now, for the first time, see that the new row exists. They can't modify or delete it, though, because of the write lock acquired earlier.

  6. Update all affected indexes and verify both referential integrity and uniqueness, where appropriate. Verifying referential integrity means ensuring that no foreign key points to a primary key that does not exist. Primary key values must be unique. Other columns may also be defined to contain only unique values, and if any such columns exist, uniqueness is verified.

  7. The transaction can be committed provided referential integrity will not be violated by doing so: record the operation in the transaction log file and release all locks.

  8. Insert other rows as required, if you have selected the cascade option, and fire triggers.

Uniqueness

You can ensure that all values in a particular column, or combination of columns, are unique. The database server always performs this task by building an index for the unique column, even if you do not explicitly create one.

In particular, all primary key values must be unique. The database server automatically builds an index for the primary key of every table. Thus, you should not ask the database server to create an index on a primary key, as that index would be a redundant index.

Orphans and referential integrity

A foreign key is a reference to a primary key, usually in another table. When that primary key doesn't exist, the offending foreign key is called an orphan. Adaptive Server Anywhere automatically ensures that your database contains no orphans. This process is referred to as verifying referential integrity. The database server verifies referential integrity by counting orphans.

WAIT FOR COMMIT

You can ask the database server to delay verifying referential integrity to the end of your transaction. In this mode, you can insert one row which contains a foreign key, then insert a second row which contains the missing primary key. You must perform both operations in the same transaction. Otherwise, the database server will not allow your operations.

To request that the database server delay referential integrity checks until commit time, set the value of the option WAIT_FOR_COMMIT to ON. By default, this option is OFF. To turn it on, issue the following command:

SET OPTION WAIT_FOR_COMMIT = ON;

Before committing a transaction, the database server verifies that referential integrity is maintained by checking the number of orphans your transaction has created. At the end of every transaction, that number must be zero.

Even if the necessary primary key exists at the time you insert the row, the database server must ensure that it still exists when you commit your results. It does so by placing a read lock on the target row. With the read lock in place, any other transaction is still free to read that row, but none can delete or alter it.


Locking during updates

The database server modifies the information contained in a particular record using the following procedure.

  1. Write lock the affected row.

  2. If any entries changed are included in an index, delete each index entry corresponding to the old values. Make a record of any orphans created by doing so.

  3. Update each of the affected values.

  4. If indexed values were changed, add new index entries. Verify uniqueness where appropriate and verify referential integrity if a primary or foreign key was changed.

  5. The transaction can be committed provided referential integrity will not be violated by doing so: record the operation in the transaction log file, including the previous values of all entries in the row, and release all locks.

  6. Cascade the insert or delete operations, if you have selected this option and primary or secondary keys are affected.

You may be surprised to see that the deceptively simple operation of changing a value in a table can necessitate a rather large number of operations. The amount of work that the database server needs to do is much less if the value you are changing is not part of a primary or foreign key. It is lower still if it is not contained in an index, either explicitly or implicitly because you have declared that attribute unique.

The operation of verifying referential integrity during an UPDATE operation is no less simple than when the verification is performed during an INSERT. In fact, when you change the value of a primary key, you may create orphans. When you insert the replacement value, the database server must check for orphans once more.


Locking during deletes

The DELETE operation follows almost the same steps as the INSERT operation, except in the opposite order.

  1. Write lock the affected row.

  2. Delete each index entry present for the any values in the row. Immediately prior to deleting each index entry, acquire one or more anti-insert locks as necessary to prevent another transaction inserting a similar entry before the delete is committed. In order to verify referential integrity, the database server also keeps track of any orphans created as a side effect of the deletion.

  3. Remove the row from the table so that it is no longer visible to other transactions. The row cannot be destroyed until the transaction is committed because doing so would remove the option of rolling back the transaction.

  4. The transaction can be committed provided referential integrity will not be violated by doing so: record the operation in the transaction log file including the values of all entries in the row, release all locks, and destroy the row.

  5. Cascade the delete operation, if you have selected this option and have modified a primary or foreign key.

Anti-insert locks

The database server must ensure that the DELETE operation can be rolled back. It does so in part by acquiring anti-insert locks. These locks are not exclusive; however, they deny other transactions the right to insert rows that make it impossible to roll back the DELETE operation. For example, the row deleted may have contained a primary key value, or another unique value. Were another transaction allowed to insert a row with the same value, the DELETE could not be undone without violating the uniqueness property.

Adaptive Server Anywhere enforces uniqueness constraints through indexes. In the case of a simple table with only a one-attribute primary key, a single phantom lock may suffice. Other arrangements can quickly escalate the number of locks required. For example, the table may have no primary key or other index associated with any of the attributes. Since the rows in a table have no fundamental ordering, the only way of preventing inserts may be to anti-insert lock the entire table.

Deleting a row can mean acquiring a great many locks. You can minimize the effect on concurrency in your database in a number of ways. As described earlier, indexes and primary keys reduce the number of locks required because they impose an ordering on the rows in the table. The database server automatically takes advantage of these orderings. Instead of acquiring locks on every row in the table, it can simply lock the next row. Without the index, the rows have no order and thus the concept of a next row is meaningless.

The database server acquires anti-insert locks on the row following the row deleted. Should you delete the last row of a table, the database server simply places the anti-insert lock on an invisible end row. In fact, if the table contains no index, the number of anti-insert locks required is one more than the number of rows in the table.

Anti-insert locks and read locks

While one or more anti-insert locks exclude an insert lock and one or more read locks exclude a write lock, no interaction exists between anti-insert/insert locks and read/write locks. For example, although a write lock cannot be acquired on a row that contains a read lock, it can be acquired on a row that has only an anti-insert lock. More options are open to the database server because of this flexible arrangement, but it means that the server must generally take the extra precaution of acquiring a read lock when acquiring an anti-insert lock. Otherwise, another transaction could delete the row.


Two-phase locking

Often, the general information about locking provided in the earlier sections will suffice to meet your needs. There are times, however, when you may benefit from more knowledge of what goes on inside the database server when you perform basic types of operations. This knowledge will provide you with a better basis from which to understand and predict potential problems that users of your database may encounter.

Two-phase locking is important in the context of ensuring that schedules are serializable. The two-phase locking protocol specifies a procedure each transaction follows.

This protocol is important because, if observed by all transactions, it will guarantee a serializable, and thus correct, schedule. It may also help you understand why some methods of locking permit some types of inconsistencies.

The two-phase locking protocol

  1. Before operating on any row, a transaction must acquire a lock on that row.

  2. After releasing a lock, a transaction must never acquire any more locks.

In practice, a transaction normally holds locks until it terminates with either a COMMIT or ROLLBACK statement. Releasing locks before the end of the transaction disallows the operation of rolling back the changes whenever doing so would necessitate operating on rows to return them to an earlier state.

The two-phase locking protocol allows the statement of the following important theorem:

The two-phase locking theorem
If all transactions obey the two-phase locking protocol, then all possible interleaved schedules are serializable.

In other words, if all transactions follow the two-phase locking protocol, then none of the inconsistencies mentioned above are possible.

This protocol defines the operations necessary to ensure complete consistency of your data, but you may decide that some types of inconsistencies are permissible during some operations on your database. Eliminating all inconsistency often means reducing the efficiency of your database.

Write locks are placed on modified, inserted, and deleted rows regardless of isolation level. They are always held until commit and rollback.

Read locks at different isolation levels
Isolation level | Read locks
0 | None
1 | On rows that appear in the result set; they are held only when a cursor is positioned on a row.
2 | On rows that appear in the result set; they are held until the user executes a COMMIT or a ROLLBACK.
3 | On all rows read and all insertion points crossed in the computation of a result set

For more information, see Serializable schedules

The details of locking are best broken into two sections: what happens during an INSERT, UPDATE, DELETE or SELECT and how the various isolation levels affect the placement of read, anti-insert, and insert locks.

Although you can control the amount of locking that takes place within the database server by setting the isolation level, there is a good deal of locking that occurs at all levels, even at level 0. These locking operations are fundamental. For example, once one transaction updates a row, no other transaction can modify the same row before the first transaction completes. Without this precaution, you could not rollback the first transaction.

The locking operations that the database server performs at isolation level 0 are the best to learn first exactly because they represent the foundation. The other levels add locking features, but do not remove any present in the lower levels. Thus, moving to higher isolation level adds operations not present at lower levels.


Early release of read locks

At isolation level 3, a transaction acquires a read lock on every row it reads. Ordinarily, a transaction never releases a lock before the end of the transaction. Indeed, it is essential that a transaction does not release locks early if the schedule is to be serializable.

Adaptive Server Anywhere always retains write locks until a transaction completes. If it were to release a lock sooner, another transaction could modify that row making it impossible to roll back the first transaction.

Read locks are released only in one, special circumstance. Under isolation level 1, transactions acquire a read lock on a row only when it becomes the current row of a cursor. Under isolation level 1, however, when that row is no longer current, the lock is released. This behavior is acceptable because the database server does not need to guarantee repeatable reads at isolation level 1.

For more information about isolation levels, see Choosing isolation levels.


Special optimizations

The previous sections describe the locks acquired when all transactions are operating at a given isolation level. For example, when all transactions are running at isolation level 2, locking is performed as described in the appropriate section, above.

In practice, your database is likely to need to process multiple transactions that are at different levels. A few transactions, such as the transfer of money between accounts, must be serializable and so run at isolation level 3. For other operations, such as updating an address or calculating average daily sales, a lower isolation level will often suffice.

While the database server is not processing any transactions at level 3, it optimizes some operations so as to improve performance. In particular, many extra anti-insert and insert locks are often necessary to support a level 3 transaction. Under some circumstances, the database server can avoid either placing or checking for some types of locks when no level 3 transactions are present.

For example, the database server uses anti-insert locks to guard against two distinct types of circumstances:

  1. Ensure that deletes in tables with unique attributes can be rolled back.

  2. Eliminate phantom rows in level 3 transactions.

If no level 3 transactions are using a particular table, then the database server need not place anti-insert locks in the index of a table that contains no unique attributes. If, however, even one level 3 transaction is present, all transactions, even those at level 0, must place anti-insert locks so that the level 3 transactions can identify their operations.

Naturally, the database server always attaches notes to a table when it attempts the types of optimizations described above. Should a level 3 transaction suddenly start, you can be confident that the necessary locks will be put in place for it.

You may have little control over the mix of isolation levels in use at one time as so much will depend on the particular operations that the various users of your database wish to perform. Where possible, however, you may wish to select the time that level 3 operations execute because they have the potential to cause significant slowing of database operations. The impact is magnified because the database server is forced to perform extra operations for lower-level operations.


Particular concurrency issues

This section discusses the following particular concurrency issues:

  • Primary key generation

  • Data definition statements and concurrency


Primary key generation

You will encounter situations where the database should automatically generate a unique number. For example, if you are building a table to store sales invoices you might prefer that the database assign unique invoice numbers automatically, rather than require sales staff to pick them.

There are many methods for generating such numbers.

Example

For example, invoice numbers could be obtained by adding 1 to the previous invoice number. This method will not work when there is more than one person adding invoices to the database. Two people may decide to use the same invoice number.

There is more than one solution to the problem:

  • Assign a range of invoice numbers to each person who adds new invoices.

    You could implement this scheme by creating a table with the columns user name and invoice number. The table would have one row for each user that adds invoices. Each time a user adds an invoice, the number in the table would be incremented and used for the new invoice. In order to handle all tables in the database, the table should have three columns: table name, user name, and last key value. You should periodically check that each person still has a sufficient supply of numbers.

  • Create a table with the columns table name and last key value.

    One row in this table would contain the last invoice number used. Each time someone adds an invoice, establish a new connection, increment the number in the table, and commit the change immediately. The incremented number can be used for the new invoice. Other users will be able to grab invoice numbers because you updated the row with a separate transaction that only lasted an instant.

  • Use a column with a default value of NEWID in conjunction with the UNIQUEIDENTIFIER binary data type to generate a universally unique identifier.

    UUID and GUID values can be used to uniquely identify rows in a table. The values are generated such that a value produced on one computer will not match that produced on another. They can therefore be used as keys in replication and synchronization environments.

    For more information about generating unique identifiers, see The NEWID default.

  • Use a column with a default value of AUTOINCREMENT.

    For example,

    CREATE TABLE orders (
   order_id INTEGER NOT NULL DEFAULT AUTOINCREMENT,
   order_date DATE,
   primary key( order_id )
)

    On inserts into the table, if a value is not specified for the autoincrement column, a unique value is generated. If a value is specified, it will be used. If the value is larger than the current maximum value for the column, that value will be used as a starting point for subsequent inserts. The value of the most recently inserted row in an autoincrement column is available as the global variable @@identity.

Unique values in replicated databases
Different techniques are required if you replicate your database and more than one person can add entries which must later be merged. For more information, see Replication and concurrency.

Previous Next


Data definition statements and concurrency

Data definition statements that change an entire table, such as CREATE INDEX, ALTER TABLE, and TRUNCATE TABLE, are prevented whenever the table on which the statement is acting is currently being used by another connection. These data definition statements can be time consuming and the database server will not process requests referencing the same table while the command is being processed.

The CREATE TABLE statement does not cause any concurrency conflicts.

The GRANT statement, REVOKE statement, and SET OPTION statement also do not cause concurrency conflicts. These commands affect any new SQL statements sent to the database server, but do not affect existing outstanding statements.

GRANT and REVOKE for a user are not allowed if that user is connected to the database.

Data definition statements and synchronized databases
Using data definition statements in databases using synchronization requires special care. For more information see the separate manuals MobiLink Administration Guide and SQL Remote User's Guide.

Previous Next


Replication and concurrency

Some computers on your network might be portable computers that people take away from the office or which are occasionally connected to the network. There may be several database applications that they would like to use while not connected to the network.

Database replication is the ideal solution to this problem. Using SQL Remote or MobiLink synchronization, you can publish information in a consolidated, or master, database to any number of other computers. You can control precisely the information replicated on any particular computer. Any person can receive particular tables, or even portions of the rows or columns of a table. By customizing the information each receives, you can ensure that their copy of the database is no larger than necessary to contain the information they require.

Extensive information on SQL Remote replication and MobiLink synchronization is provided in the separate manuals entitled SQL Remote User's Guide and MobiLink Synchronization User's Guide. The information in this section is, thus, not intended to be complete. Rather, it introduces concepts related directly to locking and concurrency considerations.

SQL Remote and MobiLink allow replicated databases to be updated from a central, consolidated database, as well as updating this same central data as the results of transactions processed on the remote machine. Since updates can occur in either direction, this ability is referred to as bi-directional replication.

Since the results of transactions can affect the consolidated database, whether they are processed on the central machine or on a remote one, the effect is that of allowing concurrent transactions.

Transactions may happen at the same time on different machines. They may even involve the same data. In this case, though, the machines may not be physically connected. No means may exist by which the remote machine can contact the consolidated database to set any form of lock or identify which rows have changed. Thus, locks can not prevent inconsistencies as they do when all transactions are processed by a single server.

An added complication is introduced by the fact that any given remote machine may not hold a full copy of the database. Consider a transaction executed directly on the main, consolidated database. It may affect rows in two or more tables. The same transaction might not execute on a remote database, as there is no guarantee that one or both of the affected tables is replicated on that machine. Even if the same tables exist, they may not contain exactly the same information, depending upon how recently the information in the two databases has been synchronized.

To accommodate the above constraints, replication is not based on transactions, but rather on operations. An operation is a change to one row in a table. This change could be the result of an UPDATE, INSERT, or DELETE statement. An operation resulting from an UPDATE or DELETE identifies the initial values of each column and a transaction resulting from an INSERT or UPDATE records the final values.

A transaction may result in none, one, or more than one operation. One operation will never result from two or more transactions. If two transactions modify a table, then two or more corresponding operations will result.

If an operation results from a transaction processed on a remote computer, then it must be passed to the consolidated database so that the information can be merged. If, on the other hand, an operation results from a transaction on the consolidated computer, then the operation may need to be sent to some remote sites, but not others. Since each remote site may contain a replica of a portion of the complete database, SQL Remote knows to pass the operation to a remote site only when it affects that portion of the database.

Transaction log based replication

SQL Remote uses a transaction log based replication mechanism. When you activate SQL Remote on a machine, it scans the transaction log to identify the operations it must transfer and prepares one or more messages.

SQL Remote can pass these messages between computers using a number of methods. It can create files containing the messages and store them in a designated directory. Alternatively, SQL Remote can pass messages using any of the most common messaging protocols. You likely can use your present e-mail system.

Conflicts may arise when merging operations from remote sites into the consolidated database. For example, two people, each at a different remote site, may have changed the same value in the same table. Whereas the locking facility built into Adaptive Server Anywhere can eliminate conflict between concurrent transactions handled by the same server, it is impossible to automatically eliminate all conflicts between two remote users who both have permission to change the same value.

As the database administrator, you can avoid this potential problem through suitable database design or by writing conflict resolution algorithms. For example, you can decide that only one person will be responsible for updating a particular range of values in a particular table. If such a restriction is impractical, then you can instead use the conflict resolution facilities of SQL Remote to implement triggers and procedures which resolve conflicts in a manner appropriate to the data involved.

SQL Remote provides the tools and programming facilities you need to take full advantage of database replication. For further information, see the SQL Remote User's Guide and the MobiLink Synchronization User's Guide.


Summary

Transactions and locking are perhaps second only in importance to relations between tables. The integrity and performance of any database can benefit from the judicious use of locking and careful construction of transactions. Both are essential to creating databases that must execute a large number of commands concurrently.

Transactions group SQL statements into logical units of work. You may end each by either rolling back any changes you have made or by committing these changes and so making them permanent.

Transactions are essential to data recovery in the event of system failure. They also play a pivotal role in interweaving statements from concurrent transactions.

To improve performance, multiple transactions must be executed concurrently. Each transaction is composed of component SQL statements. When two or more transactions are to be executed concurrently, the database server must schedule the execution of the individual statements. Concurrent transactions have the potential to introduce new, inconsistent results that could not arise were these same transactions executed sequentially.

Many types of inconsistencies are possible, but four typical types are particularly important because they are mentioned in the ISO SQL/92 standard and the isolation levels are defined in terms of them.

  • Dirty read One transaction reads data modified, but not yet committed, by another.

  • Non-repeatable read A transaction reads the same row twice and gets different values.

  • Phantom row A transaction selects rows, using a certain criterion, twice and finds new rows in the second result set.

  • Lost Update One transaction's changes to a row are completely lost because another transaction is allowed to save an update based on earlier data.

A schedule is called serializable whenever the effect of executing the statements according to the schedule is the same as could be achieved by executing each of the transactions sequentially. Schedules are said to be correct if they are serializable. A serializable schedule will cause none of the above inconsistencies.

Locking controls the amount and types of interference permitted. Adaptive Server Anywhere provides you with four levels of locking: isolation levels 0, 1, 2, and 3. At the highest isolation, level 3, Adaptive Server Anywhere guarantees that the schedule is serializable, meaning that the effect of executing all the transactions is equivalent to running them sequentially.

Unfortunately, locks acquired by one transaction may impede the progress of other transactions. Because of this problem, lower isolation levels are desirable whenever the inconsistencies they may allow are tolerable. Increased isolation to improve data consistency frequently means lowering the concurrency, the efficiency of the database at processing concurrent transactions. You must frequently balance the requirements for consistency against the need for performance to determine the best isolation level for each operation.

Conflicting locking requirements between different transactions may lead to blocking or deadlock. Adaptive Server Anywhere contains mechanisms for dealing with both these situations, and provides you with options to control them.

Transactions at higher isolation levels do not, however, always impact concurrency. Other transactions will be impeded only if they require access to locked rows. You can improve concurrency through careful design of your database and transactions. For example, you can shorten the time that locks are held by dividing one transaction into two shorter ones, or you might find that adding an index allows your transaction to operate at higher isolation levels with fewer locks.

The increased popularity of portable computers will frequently mean that your database may need to be replicated. Replication is an extremely convenient feature of Adaptive Server Anywhere, but it introduces new considerations related to concurrency. These topics are covered in a separate manual.


Monitoring and Improving Performance

About this chapter

This chapter describes how to monitor and improve the performance of your database.

Performance analysis tools
Top performance tips
Using the cache to improve performance
Using indexes to improve performance
Using keys to improve query performance
Sorting query results
Use of work tables in query processing
Monitoring database performance
Fragmentation
Profiling database procedures


Performance analysis tools

While improving database performance doesn't have to be labor-intensive, it's always best to start with a plan. Evaluate the current performance of your database, and consider all your options before changing anything. By re-evaluating your database schema using Adaptive Server Anywhere's performance features and performance analysis tools, you can diagnose and correct performance problems and keep your database performing at its optimum.

Ultimately, how well your database performs depends heavily on the design of its bones. And so, one of the most basic of ways of improving performance is with good schema design. The database schema is the skeleton of your database, and includes definitions of such things as tables, views, triggers, and the relationships between them. Re-evaluate your database schema and make note of the following areas where small changes can offer impressive gains.

A variety of tools are available to help you analyze and monitor the current performance of your Adaptive Server Anywhere database. Tools include request logging, procedure profiling, graphical plans, the Performance Monitor and timing utilities.


Request logging

Request logging is a good starting point for performance analysis of a specific application when it is not obvious whether the server or the client is at fault. It is also useful in determining the specific request to the server that might be responsible for problems.

Request logging logs individual requests received from and responses sent to an application. It's most useful for determining what the server is being asked to do by the application.

Logged information includes timestamps, connection ids, and request type, for example. You can use the -zr server option. You can redirect the output to a request log file for further analysis using the -zo server option.

For more information, see -zr server option and -zo server option.

The sa_get_request_times ( [ request_log_filename [, connection_id ] ] ) stored procedure reads a request log and populates a global temporary table satmp_request_time with statements from the log and their execution times. The time recorded is straightforward for INSERT/UPDATE/DELETE statements. For queries, the time recorded is the total elapsed time from PREPARE to DROP (describe/open/fetch/close). That means you need to be aware of any open cursors.

Analyze satmp_request_time for candidates. Statements that are cheap but frequently executed may represent performance problems

You can use sa_get_request_profile( [ request_log_filename [, connection_id ] ] ) to call sa_get_request_times() and summarize the resulting satmp_request_time into another global temporary table satmp_request_profile. This procedure also groups statements together and provides the number of calls, execution times, and so on.

Filtering request logs

Output to the request log can be filtered to include only requests from a specific connection or from a specific database. This can help reduce the size of the log when monitoring a server with many active connections or multiple databases.

toggle To filter according to a connection

  • Use the following syntax:

    call sa_server_option('requests_for_connection',connection-id)

    where connection-id can be obtained from sa_conn_info().

toggle To filter according to a database

  • Use the following syntax:

    call sa_server_option('requests_for_database',database-id)

    The database-id can be obtained from connection_property('DBNumber') when connected to that database. Filtering remains in effect until explicitly reset, or until the server is shut down.

toggle To reset filtering

  • Use either of the following two statements, to reset either by connection or by database:

    call sa_server_option('requests_for_connection',-1)
    call sa_server_option('requests_for_database',-1)
Outputting host variables to request logs

Host variable values can be output to a request log.

toggle To include host variable values

  • To include host variable values in the request log:

    • use the -zr server command line option with a value of sql+hostvars

    • execute the following:

      call sa_server_option('RequestLogging','sql+host')

The request log analysis procedure, sa_get_request_times recognizes host variables in the log and adds them to the global temporary table satmp_request_hostvar. For database versions before 9.0.0 where this temporary table does not exist, host variable values are ignored.


Index Consultant

The Index Consultant recommends indexes that can help improve performance for large workloads or complex queries. It takes as input either a single query or a workload of queries, and recommends indexes to add to the database as well as unused indexes to drop.

The Index Consultant creates a set of virtual indexes in the database. It estimates query execution costs using those indexes to see which indexes lead to improved execution plans. The Index Consultant evaluates multiple column indexes as well as single-column indexes, and also investigates the impact of clustered or unclustered indexes.

For more information about the Index Consultant, see Index Consultant overview.


Procedure profiling

Procedure profiling shows you how long it takes your stored procedures, functions, events, and triggers to execute. You can also view the execution time for each line of a procedure. Using the database profiling information, you can determine which procedures can be fine-tuned to improve performance within your database.

Procedure profiling can help you analyze specific database procedures (including stored procedures, functions, events and triggers) found to be expensive via request logging. It can also help you discover expensive, hidden, procedures, for example triggers, events, and nested stored procedure calls. As well, it can help pin-point potential problem areas within the body of a procedure

You can use stored procedures to view procedure profiling information that has been gathered by the server. The sa_procedure_profile_summary stored procedure provides information about all of the procedures within the database. You can use this procedure to view the profiling data for stored procedures, functions, events, and triggers within the same result set. However, a better way to examine this information is to use Sybase Central.

Profiling can be enabled/disabled dynamically and the data it generates is transient, stored in memory by the server. You can view it using the Profile tab in Sybase Central. Once profiling is enabled, the database gathers profiling information until you disable profiling or until the server is shut down. Profiling information is cumulative, and accurate to 1 ms.


Graphical plan

The graphical plan feature in Interactive SQL displays the execution plan for a query. It is useful for diagnosing performance issues with specific queries. For example, the information in the plan may help you decide where to add an index to your database.

The graphical plan provides a great deal more information than the short or long plans. You can choose to see the graphical plan either with or without statistics. Both allow you to quickly view which parts of the plan have been estimated as the most expensive. The graphical plan with statistics, though more expensive to view, also provides the actual query execution statistics as monitored by the server when the query is executed, and permits direct comparison between the estimates used by the query optimizer in constructing the access plan with the actual statistics monitored during execution. Note, however, that the optimizer is often unable to precisely estimate a query's cost, so expect there to be differences. The graphical plan is the default format for access plans.

You can obtain detailed information about the nodes in the plan by clicking the node in the graphical diagram. The graphical plan with statistics shows you all the estimates that are provided with the graphical plan, but also shows actual runtime costs of executing the statement. To do this, the statement must actually be executed. This means that there may be a delay in accessing the plan for expensive queries. It also means that any parts of your query such as deletes or updates are actually executed, although you can perform a rollback to undo these changes.

Use the graphical plan with statistics when you are having performance problems, and the estimated row count or run time differs from your expectations. The graphical plan with statistics provides estimates and actual statistics for you to compare. A large difference between actual and estimate is a warning sign that the optimizer might not have sufficient information to prepare correct estimates.

Following are some of the key statistics you can check in the graphical plan with statistics, and some possible remedies:

  • Row count measures the rows in the result set. If the estimated row count is significantly different from the actual row count, the selectivity of underlying predicates is probably incorrect.

  • Accurate selectivity estimates are critical for the proper operation of the query optimizer. For example, if the optimizer mistakenly estimates a predicate to be highly selective (with, say, a selectivity of 5%), but in reality, the predicate is much less selective (for example, 50%), then performance may suffer. In general, estimates may not be precise. However, a significantly large error does indicate a possible problem. If the predicate is over a base column for which there does not exist a histogram, executing a CREATE STATISTICS statement to create a histogram may correct the problem. If selectivity error remains a problem then, as a last resort, you may wish to consider specifying a user estimate of selectivity along with the predicate in the query text.

  • Runtime measures the time to execute the query. If the runtime is incorrect for a table scan or index scan, you may improve performance by executing the REORGANIZE TABLE statement. You can use the sa_table_fragmentation and the sa_index_density function to determine whether the table or index are fragmented.

  • When the source of the estimate is Guess, the optimizer has no information to use, which may indicate a problem. If the estimate source is Index and the selectivity estimate is incorrect, your problem may be that the index is skewed: you may benefit from defragmenting the index with the REORGANIZE INDEX statement.

  • If the number of cache reads and cache hits are exactly the same, then your entire database is in cache—an excellent thing. When reads are greater than hits, it means that the server is attempting to go to cache but failing, and that it must read from disk. In some cases, such as hash joins, this is expected. In other cases, such as nested loops joins, a poor cache-hit ratio may indicate a performance problem, and you may benefit from increasing your cache size.


Performance Monitor

The Performance Monitor is useful for tracking detailed information about database server actions, including disk and memory access.

With the Sybase Central Performance Monitor, you can graph a variety of statistics of any Adaptive Server Anywhere database server that you can connect to in Sybase Central. All statistics in Sybase Central are shown in the Statistics folder.

Features of the Performance Monitor include:

  • Real-time updates (at adjustable intervals)

  • A color-coded and resizable legend

  • Configurable appearance properties

When you're using the Sybase Central Performance Monitor, note that it uses actual queries against the server to gather its statistics, so the monitor itself affects some statistics (such as Cache Reads/sec). As a more precise alternative, you can graph server statistics using the Windows Performance Monitor.

The Windows monitor has two advantages:

  • It offers more performance statistics (mainly those concerned with network communications).

  • Unlike the Sybase Central monitor, the Windows monitor is non-intrusive. It uses a shared-memory scheme instead of performing queries against the server, so it does not affect the statistics themselves.

If you run multiple versions of Adaptive Server Anywhere simultaneously, it is also possible to run multiple versions of the Performance Monitor simultaneously


Timing utilities

Some performance testing utilities, including fetchtst, instest, and trantest, are available in the <installation-dir>\samples\asa\ directory. Complete documentation can be found in the Readme.txt file in the same folder as the utility. These tools will give you more accurate timings than the graphical plan with statistics. These utilities can provide an indication of the best achievable performance (for example, throughput) for a given server and database configuration.

Fetchtst measures fetch rates for an arbitrary query. Instest determines the time required for rows to be inserted into a table. Trantest measures the load that can be handled by a given server configuration given a database design and a set of transactions.


Concurrency

When the database server processes a transaction, it can lock one or more rows of a table. The locks maintain the reliability of information stored in the database by preventing concurrent access by other transactions. They also improve the accuracy of result queries by identifying information which is in the process of being updated.

The database server places these locks automatically and needs no explicit instruction. It holds all the locks acquired by a transaction until the transaction is completed. The transaction that has access to the row is said to hold the lock. Depending on the type of lock, other transactions may have limited access to the locked row, or none at all.

Performance can be compromised if a row or rows are frequently accessed by a number of users simultaneously. If you suspect locking problems, consider using the sa_locks procedure to obtain information on locks in the database. If lock issues are identified, information on the connection processes involved can be found using the AppInfo connection property.


Top performance tips

Adaptive Server Anywhere provides excellent performance automatically. However, the following tips will help you achieve the most from the product.

Always use a transaction log
Increase the cache size
Normalize your table structure
Use indexes effectively
Place different files on different devices
Turn off autocommit mode
Use bulk operations methods
Use the WITH EXPRESS CHECK option when validating tables
Try using Adaptive Server Anywhere's compression features
Reduce the number of requests between client and server
Reduce table widths
Reduce primary key width
Declare constraints
Use appropriate data types
Use AUTOINCREMENT to create primary keys
Replace expensive triggers
Minimize cascading referential actions
Pay attention to the order of columns
Upgrade to take advantage of new features
Rebuild your database
Examine your database and server configurations
Use an appropriate page size
Examine file, table, and index fragmentation
Acquire adequate hardware
Choose the Optimizer's priority
Specify the correct cursor type
Consider collecting statistics on small tables
Supply explicit selectivity estimates sparingly
Reduce expensive user-defined functions


Always use a transaction log

You might think that Adaptive Server Anywhere would run faster without a transaction log because it would have to maintain less information on disk. Yet, the opposite is actually true. Not only does a transaction log provide a large amount of protection, it can dramatically improve performance.

Operating without a transaction log, Adaptive Server Anywhere must perform a checkpoint at the end of every transaction. Writing these changes consumes considerable resources.

With a transaction log, however, Adaptive Server Anywhere need only write notes detailing the changes as they occur. It can choose to write the new database pages all at once, at the most efficient time. Checkpoints make sure information enters the database file, and that it is consistent and up to date.

Tip
Always use a transaction log. It helps protect your data and it greatly improves performance.

If you can store the transaction log on a different physical device than the one containing the main database file, you can further improve performance. The extra drive head does not generally have to seek to get to the end of the transaction log.


Increase the cache size

Adaptive Server Anywhere stores recently used pages in a cache. Should a request need to access the page more than once, or should another connection require the same page, it may find it already in memory and hence avoid having to read information from disk. This is especially an issue for encrypted databases, which require a larger cache than unencrypted.

If your cache is too small, Adaptive Server Anywhere cannot keep pages in memory long enough to reap these benefits.

On UNIX, Windows NT/2000/XP, and Windows 95/98/Me, the database server dynamically changes cache size as needed. However, the cache is still limited by the amount of memory that is physically available, and by the amount used by other applications.

On Windows CE and Novell NetWare, the size of the cache is set when you launch the database server. Be sure to allocate as much memory to the database cache as possible, given the requirements of the other applications and processes that run concurrently. In particular, databases using Java objects benefit greatly from larger cache sizes. If you use Java in your database, consider a cache of at least 8 Mb.

Tip
Increasing the cache size can often improve performance dramatically, since retrieving information from memory is many times faster than reading it from disk. You may find it worthwhile to purchase more RAM to allow a larger cache.

For more information, see Using the cache to improve performance.


Normalize your table structure

In general, the information in each column of a table should depend solely on the value of the primary key. If this is not the case, then one table may contain multiple copies of the same information, and your table may need to be normalized.

Normalization reduces duplication in a relational database. For example, suppose the people in your company work at a number of offices. To normalize the database, consider placing information about the offices (such as its address and main telephone numbers) in a separate table, rather than duplicating all this information for every employee.

You can, however, take the generally good notion of normalization too far. If the amount of duplicate information is small, you may find it better to duplicate the information and maintain its integrity using triggers or other constraints.


Use indexes effectively

When executing a query, Adaptive Server Anywhere chooses how to access each table. Indexes greatly speed up the access. When the database server cannot find a suitable index, it instead resorts to scanning the table sequentially—a process that can take a long time.

For example, suppose you need to search a large database for people, but you only know either their first or their last name, but not both. If no index exists, Adaptive Sever Anywhere scans the entire table. If however, you created two indexes (one that contains the last names first, and a second that contains the first names first), Adaptive Sever Anywhere scans the indexes first, and can generally return the information to you faster.

Using indexes

Although indexes let Adaptive Server Anywhere locate information very efficiently, exercise some caution when adding them. Each index creates extra work every time you insert, delete, or update a row because Adaptive Server Anywhere must also update all affected indexes.

Consider adding an index when it will allow Adaptive Server Anywhere to access data more efficiently. In particular, add an index when it eliminates unnecessarily accessing a large table sequentially. If, however, you need better performance when you add rows to a table, and finding information quickly is not an issue, use as few indexes as possible.

You may wish to use the Index Consultant to guide you through the selection of an effective set of indexes for your database. For more information, see Index Consultant overview.

Clustered indexes

Using clustered indexes stores rows in a table in approximately the same order as they appear in the index.

For more information, see Indexes and Using clustered indexes.


Place different files on different devices

Disk drives operate much more slowly than modern processors or RAM. Often, simply waiting for the disk to read or write pages is the reason that a database server is slow.

You almost always improve database performance when you put different physical database files on different physical devices. For example, while one disk drive is busy swapping database pages to and from the cache, another device can be writing to the log file.

Notice that to gain these benefits, the devices must be independent. A single disk, partitioned into smaller logical drives, is unlikely to yield benefits.

Adaptive Server Anywhere uses four types of files:

  1. database (.db)

  2. transaction log (.log)

  3. transaction log mirror (.mlg)

  4. temporary file (.tmp)

The database file holds the entire contents of your database. A single file can contain a single database, or you can add up to 12 dbspaces, which are additional files holding the same database. You choose a location for it, appropriate to your needs.

The transaction log file is required for recovery of the information in your database in the event of a failure. For extra protection, you can maintain a duplicate in a third type of file called a transaction log mirror file. Adaptive Server Anywhere writes the same information at the same time to each of these files.

Tip
By placing the transaction log mirror file (if you use one) on a physically separate drive, you gain better protection against disk failure, and Adaptive Server Anywhere runs faster because it can efficiently write to the log and log mirror files. To specify the location of the transaction log and transaction log mirror files, use the dblog command line utility, or the Change Log File Settings wizard in Sybase Central.

Adaptive Server Anywhere may need more space than is available to it in the cache for such operations as sorting and forming unions. When it needs this space, it generally uses it intensively. The overall performance of your database becomes heavily dependent on the speed of the device containing the fourth type of file, the temporary file.

Tip
If the temporary file is on a fast device, physically separate from the one holding the database file, Adaptive Server Anywhere will run faster. This is because many of the operations that necessitate using the temporary file also require retrieving a lot of information from the database. Placing the information on two separate disks allows the operations to take place simultaneously.

Choose the location of your temporary file carefully. Adaptive Server Anywhere examines the following environment variables, in the order shown, to determine the directory in which to place the temporary file.

  1. ASTMP

  2. TMP

  3. TMPDIR

  4. TEMP

If none of these is defined, Adaptive Server Anywhere places its temporary file in the current directory—not a good location for the best performance.

If an environment variable is not defined, Adaptive Server Anywhere places its temporary file in the /tmp directory for UNIX, and in the current directory for Windows.

If your machine has a sufficient number of fast devices, you can gain even more performance by placing each of these files on a separate device. You can even divide your database into multiple dbspaces, located on separate devices. In such a case, group tables in the separate dbspaces so that common join operations read information from different files.

A similar strategy involves placing the temporary and database files on a RAID device or a Windows NT stripe set. Although such devices act as a logical drive, they dramatically improve performance by distributing files over many physical drives and accessing the information using multiple heads.

You can specify the -fc option when starting the database server to implement a callback function when the database server encounters a file system full condition.

For more information, see -fc server option.

For more information about work tables, see Use of work tables in query processing.

For information about data recovery, see Backup and Data Recovery.

For information about transaction logs and the dbcc utility, see Transaction log utility options.


Turn off autocommit mode

If your application runs in autocommit mode, then Adaptive Server Anywhere treats each of your statements as a separate transaction. In effect, it is equivalent to appending a COMMIT statement to the end of each of your commands.

Instead of running in autocommit mode, consider grouping your commands so each group performs one logical task. If you do disable autocommit, you must execute an explicit commit after each logical group of commands. Also, be aware that if logical transactions are large, blocking and deadlock can happen.

The cost of using autocommit mode is particularly high if you are not using a transaction log file. Every statement forces a checkpoint—an operation that can involve writing numerous pages of information to disk.

Each application interface has its own way of setting autocommit behavior. For the Open Client, ODBC, and JDBC interfaces, Autocommit is the default behavior.

For more information about autocommit, see Setting autocommit or manual commit mode.


Use bulk operations methods

If you find yourself loading huge amounts of information into your database, you can benefit from the special tools provided for these tasks.

If you are loading large files, it is more efficient to create indexes on the table after the data is loaded.

For information on improving bulk operation performance, see Performance aspects of bulk operations.


Use the WITH EXPRESS CHECK option when validating tables

If you find that validating large databases with a small cache takes a long time, you can use one of two options to reduce the amount of time it takes. Using the WITH EXPRESS CHECK option with the VALIDATE TABLE statement, or the -fx option with the Validation utility can significantly increase the speed at which your tables validate.

For information on improving performance when validating databases, see Improving performance when validating databases.


Try using Adaptive Server Anywhere's compression features

Enabling compression for one connection or for all connections, and adjusting the minimum size limit at which packets are compressed can offer significant improvements to Adaptive Server Anywhere performance under some circumstances.

To determine if enabling compression will help in your particular situation, we recommend that you conduct a performance analysis on your particular network and using your particular application before using communication compression in a production environment.

Enabling compression increases the quantity of information stored in data packets, thereby reducing the number of packets required to transmit a particular set of data. By reducing the number of packets, the data can be transmitted more quickly.

Specifying the compression threshold allows you to choose the minimum size of data packets that you want compressed. The optimal value for the compression threshold may be affected by a variety of factors, including the type and speed of network you are using.

For information about using compression to improve performance, see Adjusting communication compression settings to improve performance.

For more information about compression settings, see the Compress connection parameter [COMP] and the CompressionThreshold connection parameter [COMPTH].


Reduce the number of requests between client and server

If you find yourself in a situation where your:

  • network exhibits poor latency

  • application sends many cursor open and close requests

you can use the LazyClose and PrefetchOnOpen network connection parameters to reduce the number of requests between the client and server and thereby improve performance.

For information about these parameters, see the LazyClose connection parameter [LCLOSE] and the PreFetchOnOpen connection parameter.


Reduce table widths

Tables with a large number of columns are known as wide tables. When the number of columns in a table causes the size of individual rows to exceed the database page size, each row is split across two or more database pages. The more pages a row takes up, the longer it takes to read each row. If you find performance lacking, and you know you have tables with many columns, consider normalizing your tables to reduce the number of columns. If that is not possible, a larger database page size may be helpful, especially if most tables are wide.


Reduce primary key width

Wide primary keys are composed of two or more columns. The more columns contained in your primary key, the more demand there is on the server. Reducing the number of columns in your primary keys can improve performance.


Declare constraints

Undeclared primary key-foreign key relationships exist between tables when there is an implied relationship between the values of columns in different tables. It is true that not declaring the relationship can save time on index maintenance, however, declaring the relationship can improve performance of queries when joins take place because the cost model is able to do a better job of estimation.


Use appropriate data types

Data types store information about specific sets of data, including ranges of values, the operations that can be performed on those values, and how the values are stored in memory. You can improve performance by using the appropriate data type for your data. For instance, avoid assigning a data type of char or string to values that only contain numeric data. And whenever possible, choose economical data types over the more expensive numeric and string types.


Use AUTOINCREMENT to create primary keys

Primary key values must be unique. Although there are a variety of ways to create unique values for primary keys, the most efficient method is setting the default column value to be AUTOINCREMENT ON. You can use this default for any column in which you want to maintain unique values. Using the AUTOINCREMENT feature to generate primary key values is faster than other methods because the value is generated by the server.


Replace expensive triggers

Evaluate the use of triggers to see if some of the triggers could be replaced by features available in the server. For instance, triggers to update columns with the latest update time and user information can be replaced with the corresponding special values in the server. As well, using the default settings on existing triggers can also improve performance.


Minimize cascading referential actions

Cascading referential actions are costly in terms of performance, because they cause updates to multiple tables for every transaction. For example, if the foreign key from employee to department were defined with ON UPDATE CASCADE, then updating the department ID would automatically update the employee table. While cascading referential actions are convenient, sometimes it might be more efficient to implement them in application logic.


Pay attention to the order of columns

Columns in a row are accessed in a sequential manner in the order of their creation. For example, in order to access columns at the end of a row, Adaptive Server Anywhere has to skip over any columns that appear earlier in the row. Primary key columns are always stored at the beginning of rows. For this reason, it is important to create tables such that small and/or frequently accessed columns are placed before seldom accessed columns in the table.


Upgrade to take advantage of new features

Adaptive Server Anywhere is constantly being evaluated and enhanced in terms of performance features and usability. With each subsequent release, you can take advantage of new features and behavior changes that will help you optimize performance.

While you can simply run a database created with an older version of Adaptive Server Anywhere on a newer release, many of the new features are only available if the database is upgraded. Running the Upgrade utility adds and modifies system tables, system procedures and database options to upgrade a database from an older version of Adaptive Server Anywhere to a newer version.


Rebuild your database

Rebuilding your database is the process of unloading and reloading your entire database. It is sometimes called upgrading your database file format.

Rebuilding removes all the information, including data and schema, and puts it all back in a uniform fashion, thus filling space and improving performance much like defragmenting your disk drive. It also gives you the opportunity to change certain settings. In comparison, using the upgrade utility is quicker than rebuilding, and it does not affect the storage of your files.

When you upgrade your database, rebuilding also gives you access to all new features and performance enhancements in the latest version of the software.


Examine your database and server configurations

Go over your database/server configuration, and make sure that your hardware and file space are appropriate for your usage.


Use an appropriate page size

The page size you choose can affect the performance of your database. Adaptive Server Anywhere supports page sizes of (in bytes) 1024, 2048, 4096, 8192, 16384, or 32768, with 2048 being the default. There are advantages and disadvantages to whichever page size you choose.

While smaller pages hold less information and may force less efficient use of space, particularly if you insert rows that are slightly more than half a page in size. However, small page sizes allow Adaptive Server Anywhere to run with fewer resources because it can store more pages in a cache of the same size. Small pages are particularly useful if your database must run on small machines with limited memory. They can also help in situations when you use your database primarily to retrieve small pieces of information from random locations.

By contrast, a larger page sizes help Adaptive Server Anywhere read databases more efficiently. Large page sizes also tend to benefit large databases, and queries that perform sequential table scans. Often, the physical design of disks permits them to retrieve fewer large blocks more efficiently than many small ones. Other benefits of large page sizes include improving the fan-out of your indexes, thereby reducing the number of index levels, and allowing tables to include more columns.

Keep in mind that larger page sizes have additional memory requirements. And since the maximum number of rows stored on a page is 255, tables with small rows will not fill each page and therefore use space inefficiently. As well, extremely large page sizes (16 kb or 32 kb) are not recommended for most applications unless you can be sure that a large database server cache is always available. Investigate the effects of increased memory and disk space on performance characteristics before using 16 kb or 32 kb page sizes.

The server's memory usage is proportional to the number of databases loaded, and the page size of the databases. It is strongly recommended that you do performance testing (and testing in general) when choosing a page size. Then choose the smallest page size (>= 4K) that gives satisfactory results. It is particularly important to pick the correct (and reasonable) page size if a large number of databases are going to be started on the same server.

You cannot change the page size of an existing database. Instead you must create a new database and use the -p option of dbinit to specify the page size. For example, the following command creates a database with 4K pages.

dbinit –p 4096 new.db

For more information about larger page sizes, see Setting a maximum page size.

Scattered reads

If you are working with a Windows NT Service Patch 2 or higher system, or with a Windows 2000/XP system, a page size of at least 4K allows the database server to read a large contiguous region of database pages on disk directly into the appropriate place in cache, bypassing the 64K buffer entirely. This feature can significantly improve performance.


Examine file, table, and index fragmentation

Fragmentation occurs naturally as you make changes to your database. Performance can suffer if your files, tables, or indexes are excessively fragmented. This becomes more important as your database increases in size. Adaptive Server Anywhere contains stored procedures that generate information about the fragmentation of files, tables, and indexes.

If the decrease in performance is significant, consider

  • rebuilding your database to reduce table and/or index fragmentation

  • putting the database on a disk partition by itself to reduce file fragmentation

  • running one of the available Windows utilities periodically to reduce file fragmentation

  • reorganizing your tables to reduce database fragmentation

  • rebuilding your database if you have performed extensive delete/update/insert activity on a number of tables

  • using the REORGANIZE TABLE statement to defragment rows in a table, or to compress indexes which may have become sparse due to DELETEs. Reorganizing tables can reduce the total number of pages used to store a table and its indexes, and it may reduce the number of levels in an index tree as well.

For more information about detecting and fixing file, table, and index fragmentation, see Fragmentation.

Eliminate operating system file fragmentation

To eliminate operating system file fragmentation problems, periodically run one of the available disk defragmentation utilities. File fragmentation can have a detrimental impact on performance.

The database server determines the number of file fragments in the database file when you start a database on Windows NT/2000/XP, and displays the following information in the server message window when the number of fragments is greater than one:

Database file "mydatabase.db" consists of nnn fragments

You can also obtain the number of database file fragments using the DBFileFragments database property.

Minimize index fragmentation

Indexes are designed to speed up searches on particular columns, but they can become fragmented if many DELETEs are performed on the indexed table. This may result in reduced performance if the index is accessed frequently and the cache is not large enough to hold all of the index.

The sa_index_density stored procedure provides information about the degree of fragmentation in a database's indexes. You must have DBA authority to run this procedure. The following statement calls the sa_index_density stored procedure:

CALL sa_index_density (['table_name'[,'owner_name']])

If your index is highly fragmented, you can run REORGANIZE TABLE. You can also drop the index and recreate it. However, if the index is a primary key, you will also have to drop and recreate the foreign key indexes.

As well, you can improve performance by creating a clustered index on a table. Clustered indexes cause table rows to be stored in approximately the same order as they appear in the index.

Minimize table fragmentation

Table fragmentation occurs when rows are not stored contiguously, or when rows are split between multiple pages. Performance decreases because these rows require additional page accesses.

Adaptive Server Anywhere reserves extra room on each page to allow rows to grow slightly. When an update to a row causes it to grow beyond the space available on the current page reserve, the row is split and the initial row location contains a pointer to another page where the continuous row is stored. For example, filling empty rows with UPDATE statements or inserting new columns into a table can lead to severe row splitting. As more rows are stored on separate pages, more time is required to access the additional pages.

You can use the sa_table_fragmentation stored procedure to obtain information about the degree of fragmentation of your database tables. The following statement calls the sa_table_fragmentation stored procedure:

CALL sa_table_fragmentation (['table_name' [,'owner_name']])

There are three ways to minimize table fragmentation:

  • You can specify the percentage of space in a table page that should be reserved for future updates. This PCTFREE specification can be set with CREATE TABLE, ALTER TABLE, DECLARE LOCAL TEMPORARY TABLE, or LOAD TABLE.

  • You can reorganize specific tables. To defragment particular tables or parts of tables, you can run REORGANIZE TABLE. Reorganizing tables does not disrupt database access.

  • You can rebuild the entire the database. Rebuilding is more comprehensive in that it defragments all tables, including system tables. Additionally, it rearranges the table rows so they appear in the order specified by the clustered index and primary keys


Acquire adequate hardware

When running on a PC, make sure your server meets Adaptive Server Anywhere's minimum CPU, memory and disk requirements:

  • Adaptive Server Anywhere can run with as little as 4 Mb of memory. If you use Java in the database, Adaptive Server Anywhere requires 8 Mb of memory. If you are using the administration tools, Adaptive Server Anywhere requires at least 32 Mb of RAM. Your computer must have this much memory in addition to the requirements for the operating system.

  • Enough disk space to hold your database and log files.

  • Keep in mind that these are the minimums. If you are meeting only the minimum hardware requirements, and find that performance is suffering, consider upgrading some or all of your hardware. In general, evaluate the hardware configuration to see if it is adequate for the kind of work load being placed on the server.

You can specify the -fc option when starting the database server to implement a callback function when the database server encounters a file system full condition.

For more information, see -fc server option.


Choose the Optimizer's priority

The OPTIMIZATION_GOAL option controls whether Adaptive Server Anywhere optimizes SQL statements for response time (first-row) or for total resource consumption (all-rows). In simpler terms, you can pick whether to optimize query processing towards returning the first row quickly, or towards minimizing the cost of returning the complete result set.

If the option is set to first-row, Adaptive Server Anywhere chooses an access plan that is intended to reduce the time to fetch the first row of the query's result, possibly at the expense of total retrieval time. In particular, the Adaptive Server Anywhere optimizer will typically avoid, if possible, access plans that require the materialization of results in order to reduce the time to return the first row. With this setting, for example, the optimizer favors access plans that utilize an index to satisfy a query's ORDER BY clause, rather than plans that require an explicit sorting operation.

You can use the FASTFIRSTROW table hint in a query's FROM clause to set the optimization goal for a specific query to first-row, without having to change the OPTIMIZATION_GOAL setting.

If the option is set to all-rows (the default), then Adaptive Server Anywhere optimizes a query so as to choose an access plan with the minimal estimated total retrieval time. Setting OPTIMIZATION_GOAL to all-rows may be appropriate for applications that intend to process the entire result set, such as PowerBuilder DataWindow applications.


Specify the correct cursor type

Specifying the correct cursor type can improve performance. For example, if a cursor is read-only, then declaring it as read-only allows for faster optimization and execution, since there is less material to build (no check constraints, and so on). If the cursor is updatable, some rewrites can be skipped. Also, if a query is updatable, then depending on the execution plan chosen by the optimizer, the execution engine must use a keyset driven approach. Keep in mind that key-set cursors are more expensive.


Consider collecting statistics on small tables

Adaptive Server Anywhere uses statistical information to determine the most efficient strategy for executing each statement. Adaptive Server Anywhere automatically gathers and updates these statistics, and stores them permanently in the database. Statistics gathered while processing one statement are available when searching for efficient ways to execute subsequent statements.

By default Adaptive Server Anywhere creates statistics for all tables with five or more rows. If you need to create statistics for a table with less than five rows, you can do so using the CREATE STATISTICS statement. This statement creates statistics for all tables, regardless of how many rows are in a table. Once created, the statistics are automatically maintained by Adaptive Server Anywhere.


Supply explicit selectivity estimates sparingly

Occasionally, statistics may become inaccurate. This condition is most likely to arise when only a few queries have been executed since a large amount of data was added, updated, or deleted. Inaccurate or unavailable statistics can impede performance. If Adaptive Server Anywhere is taking too long to update the statistics, try executing CREATE STATISTICS or DROP STATISTICS to refresh them. As well, in newer versions of the server (version 9.0 or later), Adaptive Server Anywhere will try to update statistics not only on LOAD TABLE and during query execution, but also on update DML statement.

In unusual circumstances, however, these measures may prove ineffective. If you know that a condition has a success rate that differs from the optimizer's estimate, you can explicitly supply a user estimate in the search condition.

Although user defined estimates can sometimes improve performance, avoid supplying explicit user-defined estimates in statements that are to be used on an ongoing basis. Should the data change, the explicit estimate may become inaccurate and may force the optimizer to select poor plans.

If you have used selectivity estimates that are inaccurate as a workaround to performance problems where the software-selected access plan was poor, you can set USER_ESTIMATES to OFF to ignore the values.

For more information, see Explicit selectivity estimates.


Reduce expensive user-defined functions

Reducing expensive user-defined functions in queries where they have to be executed many times can improve performance.


Using the cache to improve performance

The database cache is an area of memory used by the database server to store database pages for repeated fast access. The more pages that are accessible in the cache, the fewer times the database server needs to read data from disk. As reading data from disk is a slow operation, the amount of cache available is often a key factor in determining performance.

You can control the size of the database cache on the database server command line when the database is started.

Dynamic cache sizing

Adaptive Server Anywhere provides automatic resizing of the database cache. The capabilities are different on different operating systems. On Windows NT/2000/XP, Windows 95/98/Me, and UNIX operating systems, the cache grows and shrinks. Details are provided in the following sections.

Full dynamic cache sizing helps to ensure that the performance of your database server is not impacted by allocating inadequate memory. The cache grows when the database server can usefully use more, as long as memory is available, and shrinks when cache memory is required by other applications, so that the database server does not unduly impact other applications on the system. The effectiveness of dynamic cache sizing is limited, of course, by the physical memory available on your system.

Generally, dynamic cache sizing assesses cache requirements at the rate of approximately once per minute. However, after a new database is started or when a file grows significantly, statistics are sampled and the cache may be resized every five seconds for thirty seconds. After the initial thirty second period, the sampling rate drops back down to once per minute. Significant growth of a file is defined as a 1/8 growth since the database started or since the last growth that triggered an increase in the sampling rate. This change improves performance further, by adapting the cache size more quickly when databases are started dynamically and when a lot of data is inserted.

Dynamic cache sizing removes the need for explicit configuration of database cache in many situations, making Adaptive Server Anywhere even easier to use.

There is no dynamic cache resizing on Windows CE or Novell NetWare. When an Address Windowing Extensions (AWE) cache is used, dynamic cache sizing is disabled.

For more information about AWE caches, see -cw server option.

Limiting the memory used by the cache
Dynamic cache sizing (Windows NT/2000/XP, Windows 95/98/Me)
Dynamic cache sizing (UNIX)
Monitoring cache size
Using cache warming


Limiting the memory used by the cache

The initial, minimum, and maximum cache sizes are all controllable from the database server command line.

  • Initial cache size You can change the initial cache size by specifying the database server –c command-line option. The default value is as follows:

    • Windows CE The formula is as follows:

      max( 600K, min( dbsize , physical-memory ) )

      where dbsize is the total size of the database file or files started, and physical-memory is 25% of the physical memory on the machine.

    • Windows NT/2000/XP, Windows 95/98/Me, NetWare The formula is as follows:

      max( 2M, min( dbsize , physical-memory ) )

      where dbsize is the total size of the database file or files started, and physical-memory is 25% of the physical memory on the machine.

      If an AWE cache is used on Windows 2000, Windows XP, or Windows Server 2003 the formula is as follows:

      min( 100% of available memory-128MB, dbsize )

      An AWE cache is not used if this value is smaller than 2 Mb.

      For information about AWE caches, see -cw server option.

    • UNIX At least 8 Mb.

      For information about UNIX initial cache size, see Dynamic cache sizing (UNIX).

  • Maximum cache size You can control the maximum cache size by specifying the database server –ch command-line option. The default is based on an heuristic that depends on the physical memory in your machine. On non-UNIX machines, this is usually approximately 90% of total physical memory, but not more than 256 Mb. On UNIX machines, this is the greater of the following:

    (25% total physical-memory,
   25%(available-physical-memory + available-swap-space),
   sum-of-file-sizes-on-the-command-line)

    but is no more than 256 Mb and is no less than 24 Mb.

  • Minimum cache size You can control the minimum cache size by specifying the database server -cl command-line option. By default, the minimum cache size is the same as the initial cache size.

You can also disable dynamic cache sizing by using the –ca command-line option.

For more information on command-line options, see The database server.


Dynamic cache sizing (Windows NT/2000/XP, Windows 95/98/Me)

On Windows NT/2000/XP and Windows 95/98/Me, the database server evaluates cache and operating statistics once per minute and computes an optimum cache size. The server computes a target cache size that uses all physical memory currently not in use, except for approximately 5 Mb that is to be left free for system use. The target cache size is never smaller than the specified or implicit minimum cache size. The target cache size never exceeds the specified or implicit maximum cache size, or the sum of the sizes of all open database and temporary files plus the size of the main heap.

To avoid cache size oscillations, the database server increases the cache size incrementally. Rather than immediately adjusting the cache size to the target value, each adjustment modifies the cache size by 75% of the difference between the current and target cache size.

Windows 2000, Windows XP, and Windows Server 2003 can use Address Windowing Extensions (AWE) to support large cache sizes by specifying the -cw command-line option when starting the database server. AWE caches do not support dynamic cache sizing.

For more information, see -cw server option.


Dynamic cache sizing (UNIX)

On UNIX, the database server uses swap space and memory to manage the cache size. The swap space is a system-wide resource on most UNIX operating systems, but not on all. In this section, the sum of memory and swap space is called the system resources. See your operating system documentation for details.

On startup, the database allocates the specified maximum cache size from the system resources. It loads some of this into memory (the initial cache size) and keeps the remainder as swap space.

The total amount of system resources used by the database server is constant until the database server shuts down, but the proportion loaded into memory changes. Each minute, the database server evaluates cache and operating statistics. If the database server is busy and demanding of memory, it may move cache pages from swap space into memory. If the other processes in the system require memory, the database server may move cache pages out from memory to swap space.

Initial cache size

By default, the initial cache size is assigned using an heuristic based on the available system resources. The initial cache size is always less than 1.1 times the total database size.

If the initial cache size is greater than 3/4 of the available system resources, the database server exits with a Not Enough Memory error.

You can change the initial cache size using the -c option.

Maximum cache size

The maximum cache must be less than the available system resources on the machine. By default, the maximum cache size is assigned using an heuristic based on the available system resources and the total physical memory on the machine. The cache size never exceeds the specified or implicit maximum cache size, or the sum of the sizes of all open database and temporary files plus the size of the main heap.

If you specify a maximum cache size greater than the available system resources, the server exits with a Not Enough Memory error. If you specify a maximum cache size greater than the available memory, the server warns of performance degradation, but does not exit.

The database server allocates all the maximum cache size from the system resources, and does not relinquish it until the server exits. You should be sure that you choose a maximum cache size that gives good Adaptive Server Anywhere performance while leaving space for other applications. The formula for the default maximum cache size is an heuristic that attempts to achieve this balance. You only need to tune the value if the default value is not appropriate on your system.

If you specify a maximum cache size less than 8 Mb, you will not be able to run Java applications. Low maximum cache sizes will impact performance.

You can use the -ch server option to set the maximum cache size, and limit automatic cache growth. For more information, see -ch server option.

Minimum cache size

If the -c option is specified, the minimum cache size is the same as the initial cache size. If no -c option is specified, the minimum cache size on UNIX is 8 Mb.

You can use the -cl server option to adjust the minimum cache size.

For more information, see -cl server option.


Monitoring cache size

The following statistics have been added to the Windows Performance Monitor and to the database's property functions.

  • CurrentCacheSize The current cache size in kilobytes

  • MinCacheSize The minimum allowed cache size in kilobytes

  • MaxCacheSize The maximum allowed cache size in kilobytes

  • PeakCacheSize The peak cache size in kilobytes

Note: Windows Performance Monitor is available in Windows NT, Windows 2000, and Windows XP.

For more information on these properties, see Server-level properties.

For information on monitoring performance, see Monitoring database performance.


Using cache warming

Cache warming is designed to help reduce the execution times of the initial queries executed against a database. This is done by preloading the database server's cache with database pages that were referenced the last time the database was started. Warming the cache can improve performance when the same query or similar queries are executed against a database each time it is started.

You control the cache warming settings on the database server command line. There are two activities that can take place when a database is started and cache warming is turned on: collection of database pages and cache reloading (warming).

Collection of referenced database pages is controlled by the -cc database server option, and is turned on by default. When database page collection is turned on, the database server keeps track of every database page that is requested from database startup until one of the following occurs: the maximum number of pages has been collected (the value is based on cache size and database size), the collection rate falls below the minimum threshold value, or the database is shut down. Note that the server controls the maximum number of pages and the collection threshold. Once collection completes, the referenced pages are recorded in the database so they can be used to warm the cache the next time the database is started.

Cache warming (reloading) is turned on by default, and is controlled by the -cr database server option. To warm the cache, the server checks whether the database contains a previously recorded collection of pages. If it does, the server loads the corresponding pages into the cache. The database can still process requests while the cache is loading pages, but warming may stop if a significant amount of I/O activity is detected in the database. Cache warming stops in this case in order to avoid performance degradation of queries that access pages that are not contained in the set of pages being reloaded into the cache. You can specify the -cv option if you want messages about cache warming to appear in the database server window.

For more information about the database server options used for cache warming, see -cc server option, -cr server option, and -cv server option.


Using indexes to improve performance

Proper selection of indexes can make a large performance difference. Creating and managing indexes is described in Working with indexes.


Using keys to improve query performance

Primary keys and foreign keys, while used primarily for validation purposes, can also improve database performance.

Example

The following example illustrates how primary keys can make queries execute more quickly.

SELECT *
FROM employee
WHERE emp_id = 390

The simplest way for the server to execute this query would be to look at all 75 rows in the employee table and check the employee ID number in each row to see if it is 390. This does not take very long since there are only 75 employees, but for tables with many thousands of entries a sequential search can take a long time.

The referential integrity constraints embodied by each primary or foreign key are enforced by Adaptive Server Anywhere through the help of an index, implicitly created with each primary or foreign key declaration. The emp_id column is the primary key for the employee table. The corresponding primary key index permits the retrieval of employee number 390 quickly. This quick search takes almost the same amount of time whether there are 100 rows or 1,000,000 rows in the employee table.


Using primary keys to improve query performance

A primary key improves performance on the following statement:

SELECT *
FROM employee
WHERE emp_id = 390
Information on the Plan tab

The Plan tab in the Results pane contains the following information:

employee <employee>

Whenever the name inside the parentheses on the Plan tab PLAN description is the same as the name of the table, it means that the primary key for the table is used to improve performance.


Using foreign keys to improve query performance

The following query lists the orders from the customer with customer ID 113:

SELECT *
FROM sales_order
WHERE cust_id = 113
Information on the Plan tab

The Plan tab in the Results pane contains the following information:

sales_order <ky_so_customer>

Here ky_so_customer refers to the foreign key that the sales_order table has for the customer table.


Separate primary and foreign key indexes

Separate indexes are created automatically for primary and foreign keys. This arrangement allows Adaptive Server Anywhere to perform many operations more efficiently. This feature was introduced in version 7.0.


Sorting query results

Many queries have an ORDER BY clause that ensures that the rows appear in a predictable order. Indexes order the information quickly. For example, the following query can use the index on the lname column of the customer table to access the rows of the customer table in alphabetical order by last name:

SELECT *
FROM customer
ORDER BY customer.lname
Queries with WHERE and ORDER BY clauses

A potential problem arises when a query has both a WHERE clause and an ORDER BY clause.

SELECT *
FROM customer
WHERE id > 300
ORDER BY company_name

Adaptive Server Anywhere must decide between two strategies:

  1. Go through the entire customer table in order by company name, checking each row to see if the customer id is greater than 300.

  2. Use the key on the id column to read only the companies with id greater than 300. The results would then need to be sorted by company name.

If there are very few id values greater than 300, the second strategy is better because only a few rows need to be scanned and quickly sorted. If most of the id values are greater than 300, the first strategy is much better because it requires no sorting.

For more information about sorting, see The ORDER BY clause: sorting query results, or The GROUP BY clause: organizing query results into groups.


Use of work tables in query processing

Work tables are materialized temporary result sets that are created during the execution of a query. Work tables are used when Adaptive Server Anywhere determines that the cost of using one is less than alternative strategies. Generally, the time to fetch the first few rows is higher when a work table is used, but the cost of retrieving all rows may be substantially lower in some cases if a work table can be used. Because of this difference, Adaptive Server Anywhere chooses different strategies based on the OPTIMIZATION_GOAL setting. The default is first-row. When it is set to first-row, Adaptive Server Anywhere tries to avoid work tables. When it is set to all-rows, Adaptive Server Anywhere uses work tables when they reduce the total execution cost of a query.

Work tables are used in the following cases:

When work tables occur

  • When a query has an ORDER BY, GROUP BY, OR DISTINCT clause and Adaptive Server Anywhere does not use an index for sorting the rows. If a suitable index exists and the OPTIMIZATION_GOAL setting is first-row, Adaptive Server Anywhere avoids using a work table. However, when OPTIMIZATION_GOAL is set to all-rows, it may be more expensive to fetch all the rows of a query using an index than it is to build a work table and sort the rows. Adaptive Server Anywhere chooses the cheaper strategy if the optimization goal is set to all-rows. For GROUP BY and DISTINCT, the hash-based algorithms use work tables, but are generally more efficient when fetching all the rows out of a query.

  • When a hash join algorithm is chosen, work tables are used to store interim results (if the input doesn't fit into memory) and a work table is used to store the results of the join.

  • When a cursor is opened with sensitive values, a work table is created to hold the row identifiers and primary keys of the base tables. This work table is filled in as rows are fetched from the query in the forward direction. However, if you fetch the last row from the cursor, the entire table is filled in.

  • When a cursor is opened with insensitive semantics, a work table is populated with the results of the query when the query is opened.

  • When a multiple-row UPDATE is being performed and the column being updated appears in the WHERE clause of the update or in an index being used for the update.

  • When a multiple-row UPDATE or DELETE has a subquery in the WHERE clause that references the table being modified.

  • When performing an INSERT from a SELECT statement and the SELECT statement references the insert table.

  • When performing a multiple row INSERT, UPDATE, or DELETE, and a corresponding trigger is defined on the table that may fire during the operation.

In these cases, the records affected by the operation go into the work table. In certain circumstances, such as keyset-driven cursors, a temporary index is built on the work table. The operation of extracting the required records into a work table can take a significant amount of time before the query results appear. Creating indexes that can be used to do the sorting in the first case, above, improves the time to retrieve the first few rows. However, the total time to fetch all rows may be lower if work tables are used, since these permit query algorithms based on hashing and merge sort. These algorithms use sequential I/O, which is faster than the random I/O used with an index scan.

The query optimizer in the database server analyzes each query to determine whether a work table will give the best performance. Enhancements to the optimizer in new releases of Adaptive Server Anywhere may improve the access plan for queries. No user action is required to take advantage of these optimizations.

Notes

The INSERT, UPDATE and DELETE cases above are usually not a performance problem since they are usually one-time operations. However, if problems occur, you may be able to rephrase the command to avoid the conflict and avoid building a work table. This is not always possible.


Monitoring database performance

Adaptive Server Anywhere provides a set of statistics you can use to monitor database performance. Accessible from Sybase Central, client applications can access the statistics as functions. In addition, the server makes these statistics available to the Windows Performance Monitor.

This section describes how to access performance and related statistics from client applications, how to monitor database performance using Sybase Central, how to monitor database performance using the Windows Performance Monitor, and how to detect file, table, and index fragmentation.

Obtaining database statistics from a client application
Monitoring database statistics from Sybase Central
Monitoring database statistics from Windows Performance Monitor


Obtaining database statistics from a client application

Adaptive Server Anywhere provides a set of system functions that can access information on a per-connection, per-database, or server-wide basis. The kind of information available ranges from static information (such as the server name) to detailed performance-related statistics (such as disk and memory usage).

Functions that retrieve system information

The following functions retrieve system information:

  • property function Provides the value of a given property on an engine-wide basis.

  • connection_property function Provides the value of a given property for a given connection, or by default, for the current connection.

  • db_property function Provides the value of a given property for a given database, or by default, for the current database.

Supply as an argument only the name of the property you wish to retrieve. The functions return the value for the current server, connection, or database.

For more information, see PROPERTY function [System], CONNECTION_PROPERTY function [System], and DB_PROPERTY function [System].

For a complete list of the properties available from the system functions, see System functions.

Examples

The following statement sets a variable named server_name to the name of the current server:

SET server_name = property( 'name' )

The following query returns the user ID for the current connection:

SELECT connection_property( 'userid' )

The following query returns the filename for the root file of the current database:

SELECT db_property( 'file' )
Improving query efficiency

For better performance, a client application monitoring database activity should use the property_number function to identify a named property, and then use the number to repeatedly retrieve the statistic. The following set of statements illustrates the process from Interactive SQL:

CREATE VARIABLE propnum INT ;
CREATE VARIABLE propval INT ;
SET propnum = property_number( 'cacheread' );
SET propval = property( propnum )

Property names obtained in this way are available for many different database statistics, from the number of transaction log page write operations and the number of checkpoints carried out, to the number of reads of index leaf pages from the memory cache.

You can view many of these statistics in graph form from the Sybase Central database management tool.


Monitoring database statistics from Sybase Central

With the Sybase Central Performance Monitor, you can graph the statistics of any Adaptive Server Anywhere database server that you can connect to in Sybase Central. All statistics in Sybase Central are shown in the Statistics folder.

Features of the Performance Monitor include:

  • Real-time updates (at adjustable intervals)

  • A color-coded and resizable legend

  • Configurable appearance properties

When you're using the Sybase Central Performance Monitor, note that it uses actual queries against the server to gather its statistics, so the monitor itself affects some statistics (such as Cache Reads/sec). As a more precise alternative, you can graph server statistics using the Windows Performance Monitor.

For information on setting properties, see Setting properties for database objects.


Opening the Sybase Central Performance Monitor

You can display the Performance Monitor in the right pane of Sybase Central when you have the Statistics folder open.

toggle To open the Performance Monitor

  1. In the left pane, select the desired server.

  2. In the right pane, click the Performance Monitor tab.

Note
The Performance Monitor only graphs statistics that you have added to it ahead of time.

See also

  • Adding and removing statistics

  • Configuring the Sybase Central Performance Monitor

  • Monitoring database statistics from Windows Performance Monitor


Adding and removing statistics
toggle To add statistics to the Sybase Central Performance Monitor

  1. In the left pane, select the desired server.

  2. In the right pane, click the Statistics tab.

  3. Right-click a statistic that is not currently being graphed and choose Add to Performance Monitor from the popup menu.

toggle To remove statistics from the Sybase Central Performance Monitor

  1. Do one of the following:

    • If you are working on the Statistic tab in the right pane, right-click a statistic that is currently being graphed.

    • If you are working in the Performance Monitor tab in the right pane, right-click the desired statistic in the legend.

  2. From the popup menu, choose Remove from Performance Monitor.

Tip
You can also add a statistic to or remove one from the Performance Monitor on the statistic's property sheet.

See also

  • Opening the Sybase Central Performance Monitor

  • Configuring the Sybase Central Performance Monitor

  • Monitoring database statistics from Windows Performance Monitor


Configuring the Sybase Central Performance Monitor

The Sybase Central Performance Monitor is configurable; you can choose the type of graph it uses and the amount of time between updates to the graph.

toggle To choose a graph type

  1. Choose Tools > Options.

  2. On the Options dialog, click the Chart tab.

  3. Choose a type of graph.

toggle To set the update interval

  1. Choose Tools > Options.

  2. On the Options dialog, click the Chart tab.

  3. Move the slider to reflect a new time value (or type the value directly in the text box provided).

See also

  • Opening the Sybase Central Performance Monitor

  • Adding and removing statistics

  • Monitoring database statistics from Windows Performance Monitor


Monitoring database statistics from Windows Performance Monitor

As an alternative to using the Sybase Central Performance Monitor, you can use the Windows Performance Monitor.

The Windows monitor has two advantages:

  • It offers more performance statistics (mainly those concerned with network communications).

  • Unlike the Sybase Central monitor, the Windows monitor is non-intrusive. It uses a shared-memory scheme instead of performing queries against the server, so it does not affect the statistics themselves.

For a complete list of performance statistics you can monitor, see Performance Monitor statistics.

Note: Windows Performance Monitor is available in Windows NT, Windows 2000, and Windows XP. If you run multiple versions of Adaptive Server Anywhere simultaneously, it is also possible to run multiple versions of the Performance Monitor simultaneously.

toggle To use the Windows Performance Monitor in Windows NT

  1. With an Adaptive Server Anywhere engine or database running, start the Performance Monitor:

    • Choose Start > Programs > Administrative Tools (Common) > Performance Monitor.

  2. Choose Edit > Add To Chart, or click the Plus sign button on the toolbar. The Add To Chart dialog appears.

  3. From the Object list, select one of the following:

    • Adaptive Server Anywhere Connection To monitor performance for a single connection. Choose a connection to monitor from the displayed list.

    • Adaptive Server Anywhere Database To monitor performance for a single database. Choose a database to monitor from the displayed list.

    • Adaptive Server Anywhere Engine To monitor performance on a server-wide basis.

    The Counter box displays a list of the statistics you can view.

  4. From the Counter list, click a statistic to view. To select multiple statistics, hold the Ctrl or Shift keys while clicking.

  5. If you selected Adaptive Server Anywhere Connection or Adaptive Server Anywhere Database, choose an instance from the Instance box.

  6. For a description of the selected counter, click Explain.

  7. To display the counter, click Add.

  8. When you have selected all the counters you wish to display, click Done.

For more information about the Windows Performance Monitor, see the online help for the program.


Fragmentation

As you make changes to your database, the database file, tables, and indexes can become fragmented. Fragmentation can decrease performance. Adaptive Server Anywhere provides information that you can use to assess the level of fragmentation in files, tables, and indexes.

This section describes how to detect fragmentation in files, tables, and indexes, and how to defragment them.


File fragmentation

Performance can suffer if your database file is excessively fragmented. This is disk fragmentation and it becomes more important as your database increases in size.

The database server determines the number of file fragments in each dbspace when you start a database on Windows NT/2000/XP. The server displays the following information in the server message window when the number of fragments is greater than one:

Database file "mydatabase.db" consists of nnn fragments

You can also obtain the number of database file fragments using the DBFileFragments database property.

For more information, see Database-level properties.

toggle To eliminate file fragmentation problems

  1. Put the database on a disk partition by itself.

  2. Periodically run one of the available Windows disk defragmentation utilities.


Table fragmentation

When rows are not stored contiguously, or if rows are split onto more than one page, performance decreases because these rows require additional page accesses. Table fragmentation is distinct from file fragmentation.

Adaptive Server Anywhere reserves extra room on each page to allow rows to grow slightly. When an update to a row causes it to grow beyond the original space allocated for it, the row is split and the initial row location contains a pointer to another page where the entire row is stored. For example, filling empty rows with UPDATE statements or inserting new columns into a table can lead to severe row splitting. As more rows are stored on separate pages, more time is required to access the additional pages.

You can reduce the amount of fragmentation in your tables by specifying the percentage of space in a table page that should be reserved for future updates. This PCTFREE specification can be set with CREATE TABLE, ALTER TABLE, DECLARE LOCAL TEMPORARY TABLE, or LOAD TABLE.

For more information, see CREATE TABLE statement, ALTER TABLE statement, DECLARE LOCAL TEMPORARY TABLE statement, and LOAD TABLE statement.

You can use the sa_table_fragmentation stored procedure to obtain information about the degree of fragmentation of your database tables. You must have DBA authority to run this procedure. The following statement calls the sa_table_fragmentation stored procedure:

CALL sa_table_fragmentation (['table_name' [,'owner_name']])

For more information, see sa_table_fragmentation system procedure.

Defragmenting tables

The following procedures are useful when you detect that performance is poor because a table is highly fragmented. Unloading and reloading the database is more comprehensive in that it defragments all tables, including system tables. To defragment particular tables or parts of tables, run REORGANIZE TABLE. Reorganizing tables does not disrupt database access.

toggle To defragment all the tables in a database

  1. Unload the database.

  2. Reload the database to reclaim disk space and improve performance.

For more information about unloading a database, see Unloading a database using the dbunload command-line utility.

For more information about rebuilding a database, see The Rebuild utility.

toggle To defragment individual tables

  • Execute a REORGANIZE TABLE statement.

For more information, see REORGANIZE TABLE statement.


Index fragmentation

Indexes are designed to speed up searches on particular columns, but they can become fragmented if many DELETEs are performed on the indexed table. This may result in reduced performance if the index is accessed frequently and the cache is not large enough to hold all of the index.

The sa_index_density stored procedure provides information about the degree of fragmentation in a database's indexes. You must have DBA authority to run this procedure. The following statement calls the sa_index_density stored procedure:

CALL sa_index_density (['table_name'[,'owner_name']])

If your index is highly fragmented, you can run REORGANIZE TABLE. You can also drop the index and recreate it. However, if the index is a primary key, you will also have to drop and recreate the foreign key indexes.

For more information, see REORGANIZE TABLE statement.

For more information about dropping an index, see Dropping indexes.


Monitoring query performance

Adaptive Server Anywhere includes a number of tools for testing the performance of queries. Complete documentation about each tool can be found in a Readme.txt file that is located in the same folder as the tool.

fetchtst

Function: Determines the time required for a result set to be retrieved.

Location: SQL Anywhere 9\Samples\Asa\PerformanceFetch

odbcfet

Function: Determines the time required for a result set to be retrieved. This function is similar to fetchtst, but with less functionality.

Location: SQL Anywhere 9\Samples\Asa\PerformanceFetch

instest

Function: Determines the time required for rows to be inserted into a table.

Location: SQL Anywhere 9\Samples\Asa\PerformanceInsert

trantest

Function: Measures the load that can be handled by a given server configuration given a database design and a set of transactions.

Location: SQL Anywhere 9\Samples\Asa\PerformanceTransaction

For information about system procedures that measure query execution times, see sa_get_request_profile system procedure and sa_get_request_times system procedure.


Profiling database procedures

Procedure profiling shows you how long it takes your stored procedures, functions, events, system triggers, and triggers to execute. You can also view the execution time for each line of a procedure. Using the database profiling information, you can determine which procedures can be fine-tuned to increase performance within your database.

When profiling is enabled, Adaptive Server Anywhere monitors which stored procedures, functions, events, system triggers, and triggers are used, keeping track of how long it takes to execute them, and how many times each one is called.

Profiling information is stored in memory by the server and can be viewed in Sybase Central via the Profile tab or in Interactive SQL. Once profiling is enabled, the database gathers profiling information until you disable profiling or until the server is shut down.

For more information about obtaining profiling information in Interactive SQL, see Viewing procedure profiling information in Interactive SQL.

Enabling procedure profiling
Resetting procedure profiling
Disabling procedure profiling
Viewing procedure profiling information in Sybase Central
Viewing procedure profiling information in Interactive SQL


Enabling procedure profiling

Procedure profiling tracks the usage of procedures and triggers by all connections. You can enable profiling in either Sybase Central or Interactive SQL. You must have DBA authority to enable and use procedure profiling.

toggle To enable profiling (Sybase Central)

  1. Connect to your database as a user with DBA authority.

  2. Select the database in the left pane.

  3. From the File menu, choose Properties.

    The Database property sheet appears.

  4. On the Profiling tab, select Enable Profiling on This Database.

  5. Click OK to close the property sheet.

Note

You can also right click your database in Sybase Central to enable profiling. From the popup menu, choose Profiling > Start Profiling.

toggle To enable profiling (SQL)

  1. Connect to your database as a user with DBA authority.

  2. Call the sa_server_option stored procedure with the ON setting.

    For example, enter:

    CALL sa_server_option ( 'procedure_profiling', 'ON')

If necessary, you can see what procedures a specific user is using, without preventing other connections from using the database. This is useful if the connection already exists, or if multiple users connect with the same userid.

toggle To filter procedure profiling by user

  1. Connect to the database as a user with DBA authority.

  2. Call the following procedure:

    CALL sa_server_option ('ProfileFilterUser','userid')

    The value of userid is the name of the user being monitored.


Resetting procedure profiling

When you reset profiling, the database clears the old information and immediately starts collecting new information about procedures, functions, events, and triggers.

The following sections assume that you are already connected to your database as a user with DBA authority and that procedure profiling is enabled.

toggle To reset profiling (Sybase Central)

  1. Select the database in the left pane.

  2. From the File menu, choose Properties.

    The Database property sheet appears.

  3. On the Profiling tab, click Reset Now.

  4. Click OK to close the property sheet.

Note

You can also right click your database in Sybase Central to reset profiling. From the popup menu, click Profiling > Reset Profiling Information.

toggle To reset profiling (SQL)

  • Call the sa_server_option stored procedure with the RESET setting.

    For example, enter:

    CALL sa_server_option ('procedure_profiling', 'RESET')


Disabling procedure profiling

Once you are finished with the profiling information, you can either disable profiling or you can clear profiling. If you disable profiling, the database stops collecting profiling information and the information that it has collected to that point remains on the Profile tab in Sybase Central. If you clear profiling, the database turns profiling off and removes all the profiling data from the Profile tab in Sybase Central.

toggle To disable profiling (Sybase Central)

  1. Select the database in the left pane.

  2. From the File menu, choose Properties.

    The Database property sheet appears.

  3. On the Profiling tab, clear the Enable Profiling on This Database option.

  4. Click OK to close the property sheet.

Note

You can also right click your database in Sybase Central to disable profiling. From the popup menu, choose Profiling > Stop Profiling.

toggle To disable profiling (SQL)

  • Call the sa_server_option stored procedure with the OFF setting.

    For example, enter:

    CALL sa_server_option ('procedure_profiling', 'OFF')
toggle To clear profiling (Sybase Central)

  1. Select the database in the left pane.

  2. From the File menu, choose Properties.

    The Database property sheet appears.

  3. On the Profiling tab, click Clear Now.

    You can only clear profiling if profiling is enabled.

  4. Click OK to close the property sheet.

Note

You can also right click your database in Sybase Central to clear profiling. From the popup menu, select Profiling > Clear Profiling Information.

toggle To clear profiling (SQL)

  • Call the sa_server_option stored procedure with the CLEAR setting.

    For example, enter:

    CALL sa_server_option ('procedure_profiling', 'CLEAR')


Viewing procedure profiling information in Sybase Central

Procedure profiling provides you with different information depending whether you choose to look at information for your entire database, a specific type of object, or a particular procedure. The information can be displayed in the following ways:

  • details for all profiled objects within the database

  • details for all stored procedures and functions

  • details for all events

  • details for all triggers

  • details for all system triggers

  • details for individual profiled objects

You must be connected to your database and have profiling enabled to view profiling information.

When you view profiling information for your entire database, the following columns appear:

  • Name lists the name of the object.

  • Owner lists the owner of the object.

  • Table lists which table a trigger belongs to (this column only appears on the database Profile tab).

  • Event shows the type of trigger for system triggers. This can be Update or Delete.

  • Type lists the type of object, for example, a procedure.

  • # Exes. lists the number times each object has been called.

  • #msecs. lists the total execution time for each object.

These columns provide a summary of the profiling information for all of the procedures that have been executed within the database. One procedure can call other procedures, so there may be more items listed than those users call specifically.

toggle To view summary profiling information for stored procedures and functions

  1. Select the Procedures & Functions folder in the left pane.

  2. Click the Profile tab in the right pane.

    Profiling information about all the stored procedures and functions within your database appears on the Profile tab.

toggle To view summary profiling information for events

  1. Open the Events folder in the left pane.

    A list of all the events in your database appears on the Events tab in the right pane.

  2. Click the Profile tab in the right pane.

    Profiling information about all of the events within your database appears on the Profile tab.

toggle To view summary profiling information for triggers

  1. Open the Triggers folder in the left pane.

    A list of all the triggers in your database appears on the Triggers tab.

  2. Click the Profile tab in the right pane.

    Profiling information about all of the triggers in your database appears on the Profile tab.

toggle To view summary profiling information for system triggers

  1. Open the System Triggers folder in the left pane.

    A list of all the triggers in your database appears on the System Triggers tab.

  2. Click the Profile tab in the right pane.

    Profiling information about all of the system triggers in your database appears on the Profile tab.

Viewing profiling information for a specific procedure


Viewing profiling information for a specific procedure

Adaptive Server Anywhere provides procedure profiling information about individual stored procedures, functions, events, and triggers. Sybase Central displays different information about individual procedures than it does about all of the stored procedures, functions, events, or triggers within a database.

When you look at the profiling information for a specific procedure, the following columns appear:

  • Calls lists the number of times the object has been called.

  • Milliseconds lists the total execution time for each object.

  • Line lists the line number beside each line of the procedure.

  • Source displays the SQL procedure, line by line.

The procedure is broken down line by line and you can examine it to see which lines have longer execution times and therefore might benefit from changes to improve the procedure's performance. You must be connected to the database, have profiling enabled, and have DBA authority to access procedure profiling information.

toggle To view the profiling information for a stored procedure or function

  1. Expand the database in the left pane.

  2. Select the Procedures and Functions folder in the left pane.

    A list of all the stored procedures and functions within your database appears on the Procedures & Functions tab in the right pane.

  3. Click the stored procedure or function you want to profile in the left pane.

  4. Click the Profile tab in the right pane.

    Profiling information about the specific stored procedure or function appears on the Profile tab in the right pane.

toggle To view profiling information for an event

  1. Expand the database in the left pane.

  2. Select the Events folder in the left pane.

    A list of all the events within your database appears on the Events tab in the right pane.

  3. Click the event you want to profile in the left pane.

  4. Click the Profile tab in the right pane.

    Profiling information about the specific event appears on the Profile tab in the right pane.

toggle To view profiling information for triggers

  1. Expand the database in the left pane.

  2. Open the Triggers folder in the left pane.

    A list of all the triggers appears on the Triggers tab in the right pane.

  3. Select the trigger you want to profile in the right pane.

  4. Click the Profile tab in the right pane.

    Profiling information about the specific trigger appears on the Profile tab in the right pane.

toggle To view profiling information for system triggers

  1. Expand the database in the left pane.

  2. Open the System Triggers folder in the left pane.

    A list of all the system triggers appears on the System Triggers tab in the right pane.

  3. Select the system trigger you want to profile in the right pane.

  4. Click the Profile tab in the right pane.

    Profiling information about the specific system trigger appears on the Profile tab in the right pane.


Viewing procedure profiling information in Interactive SQL

You can use stored procedures to view procedure profiling information. The profiling information is the same whether you view it in Sybase Central or in Interactive SQL.

The sa_procedure_profile_summary stored procedure provides information about all of the procedures within the database. You can use this procedure to view the profiling data for stored procedures, functions, events, system triggers, and triggers within the same result set. The following parameters restrict the rows the procedure returns.

  • p_object_name specify the name of an object to profile.

  • p_owner_name specify the owner whose objects you want to profile.

  • p_table_name specify which table you want to profile triggers for.

  • p_object_type specify the type of object to profile. You can choose from the following five options. Choosing one of these values restricts the result set to only objects of the specified type.

    • P stored procedure

    • F function

    • T trigger

    • E event

    • S system trigger

  • p_ordering specify the sort order of the result set.

Keep in mind that there may be more items listed than those called specifically by users because one procedure can call another procedure.

The following sections assume that you are already connected to your database as a user with DBA authority and that you have procedure profiling enabled.

toggle To view summary profiling information for all procedures

  1. Execute the sa_procedure_profile_summary stored procedure.

    For example, enter:

    CALL sa_procedure_profile_summary

  2. From the SQL menu, choose Execute.

    A result set with information about all of the procedures in your database appears on the Results pane.

For more information about the sa_procedure_profile_summary stored procedure, see sa_procedure_profile_summary system procedure.

Viewing profiling information for a specific procedure in Interactive SQL


Viewing profiling information for a specific procedure in Interactive SQL

The sa_procedure_profile stored procedure provides information about individual lines within specific procedures. The result set includes the line number, execution time, and percentage of total execution time for lines within procedures. You can use the following parameters to restrict the rows the procedure returns:

  • p_object_name specify the name of an object to profile.

  • p_owner_name specify the owner whose objects you want to profile.

  • p_table_name specify which table you want to profile triggers for.

If you do not include any parameters in your query, the procedure returns profiling information for all the procedures that have been called.

toggle To view profiling information for specific lines within procedures

  1. Execute the sa_procedure_profile stored procedure.

    For example, enter:

    CALL sa_procedure_profile

  2. From the SQL menu, choose Execute.

    A result set with profiling information for individual procedure lines appears in the Results pane.

For more information about the sa_procedure_profile stored procedure, see sa_procedure_profile system procedure.


Queries: Selecting Data from a Table

About this chapter

The SELECT statement retrieves data from the database. You can use it to retrieve a subset of the rows in one or more tables and to retrieve a subset of the columns in one or more tables.

This chapter focuses on the basics of single-table SELECT statements. Advanced uses of SELECT are described later in this manual.


Query overview

A query requests data from the database and receives the results. This process is also known as data retrieval. All SQL queries are expressed using the SELECT statement.


Queries are made up of clauses

You construct SELECT statements from clauses. In the following SELECT syntax, each new line is a separate clause. Only the more common clauses are listed here.

SELECT select-list
[ FROM table-expression ]
[ WHERE search-condition ]
[ GROUP BY column-name ]
[ HAVING search-condition ]
[ ORDER BY { expression | integer } ]

The clauses in the SELECT statement are as follows:

  • The SELECT clause specifies the columns you want to retrieve. It is the only required clause in the SELECT statement.

  • The FROM clause specifies the tables from which columns are pulled. It is required in all queries that retrieve data from tables. SELECT statements without FROM clauses have a different meaning, and this chapter does not discuss them.

    Although most queries operate on tables, queries may also retrieve data from other objects that have columns and rows, including views, other queries (derived tables) and stored procedure result sets. For more information, see FROM clause.

  • The ON clause specifies how tables in the FROM clause are to be joined. It is used only for multi-table queries and is not discussed in this chapter.

    For information on multi-table queries, see Joins: Retrieving Data from Several Tables.

  • The WHERE clause specifies the rows in the tables you want to see.

  • The GROUP BY clause allows you to aggregate data.

  • The HAVING clause specifies rows on which aggregate data is to be collected.

  • The ORDER BY clause sorts the rows in the result set. (By default, rows are returned from relational databases in an order that has no meaning.)

    For information on GROUP BY, HAVING, and ORDER BY clauses, see Summarizing, Grouping, and Sorting Query Results.

Most of the clauses are optional, but if they are included then they must appear in the correct order.

For more information about the SELECT statement syntax, see SELECT statement.


SQL queries

In this manual, SELECT statements and other SQL statements appear with each clause on a separate row, and with the SQL keywords in upper case. This is not a requirement. You can type SQL keywords in any case, and you can break lines at any point.

Keywords and line breaks

For example, the following SELECT statement finds the first and last names of contacts living in California from the Contact table.

SELECT first_name, last_name
FROM Contact
WHERE state = 'CA'

It is equally valid, though not as readable, to enter this statement as follows:

SELECT first_name,
last_name from contact
wHere state
 = 'CA'
Case sensitivity of strings and identifiers

Identifiers (that is, table names, column names, and so on) are case insensitive in Adaptive Server Anywhere databases.

Strings are case insensitive by default, so that 'CA', 'ca', 'cA', and 'Ca' are equivalent, but if you create a database as case-sensitive then the case of strings is significant. The sample database is case insensitive.

Qualifying identifiers

You can qualify the names of database identifiers if there is ambiguity about which object is being referred to. For example, the sample database contains several tables with a column called city, so you may have to qualify references to city with the name of the table. In a larger database you may also have to use the name of the owner of the table to identify the table.

SELECT DBA.contact.city
FROM contact
WHERE state = 'CA'

Since the examples in this chapter involve single-table queries, column names in syntax models and examples are usually not qualified with the names of the tables or owners to which they belong.

These elements are left out for readability; it is never wrong to include qualifiers.

The remaining sections in this chapter analyze the syntax of the SELECT statement in more detail.


The SELECT list: specifying columns

The select list

The select list commonly consists of a series of column names separated by commas, or an asterisk as shorthand to represent all columns.

More generally, the select list can include one or more expressions, separated by commas. The general syntax for the select list looks like this:

SELECT expression [, expression ]...

If any table or column name in the list does not conform to the rules for valid identifiers, you must enclose the identifier in double quotes.

The select list expressions can include * (all columns), a list of column names, character strings, column headings, and expressions including arithmetic operators. You can also include aggregate functions, which are discussed in Summarizing, Grouping, and Sorting Query Results.

For more information about what expressions can consist of, see Expressions.

The following sections provide examples of the kinds of expressions you can use in a select list.

Selecting all columns from a table
Selecting specific columns from a table
Renaming columns in query results
Character strings in query results
Computing values in the SELECT list
Eliminating duplicate query results


Selecting all columns from a table

The asterisk (*) has a special meaning in SELECT statements. It stands for all the column names in all the tables specified in the FROM clause. You can use it to save typing time and errors when you want to see all the columns in a table.

When you use SELECT *, the columns are returned in the order in which they were defined when the table was created.

The syntax for selecting all the columns in a table is:

SELECT *
FROM table-expression

SELECT * finds all the columns currently in a table, so that changes in the structure of a table such as adding, removing, or renaming columns automatically modify the results of SELECT *. Listing the columns individually gives you more precise control over the results.

Example

The following statement retrieves all columns in the department table. No WHERE clause is included; and so this statement retrieves every row in the table:

SELECT *
FROM department

The results look like this:

dept_id | dept_name | dept_head_id
100 | R & D | 501
200 | Sales | 902
300 | Finance | 1293
400 | Marketing | 1576
... | ... | ...

You get exactly the same results by listing all the column names in the table in order after the SELECT keyword:

SELECT dept_id, dept_name, dept_head_id
FROM department

Like a column name, "*" can be qualified with a table name, as in the following query:

SELECT department.*
FROM department


Selecting specific columns from a table

To SELECT only specific columns in a table, use this syntax:

SELECT column_name [, column_name ]...
FROM table-name

You must separate each column name from the column name that follows it with a comma. For example:

SELECT emp_lname, emp_fname
FROM employee
Rearranging the order of columns

The order in which you list the column names determines the order in which the columns are displayed. The two following examples show how to specify column order in a display. Both of them find and display the department names and identification numbers from all five of the rows in the department table, but in a different order.

SELECT dept_id, dept_name
FROM department
dept_id | dept_name
100 | R & D
200 | Sales
300 | Finance
400 | Marketing
... | ...
SELECT dept_name, dept_id
FROM department
dept_name | dept_id
R & D | 100
Sales | 200
Finance | 300
Marketing | 400
... | ...


Renaming columns in query results

Query results consist of a set of columns. By default, the heading for each column is the expression supplied in the select list.

When query results are displayed, each column's default heading is the name given to it when it was created. You can specify a different column heading, or alias, in one of the following ways:

SELECT column-name AS alias

SELECT column-name alias

SELECT alias = column-name

Providing an alias can produce more readable results. For example, you can change dept_name to Department in a listing of departments as follows:

SELECT dept_name AS Department,
   dept_id AS "Identifying Number"
FROM department
Department | Identifying Number
R & D | 100
Sales | 200
Finance | 300
Marketing | 400
... | ...
Using spaces and keywords in alias

The Identifying Number alias for dept_id is enclosed in double quotes because it is an identifier. You also use double quotes if you wish to use keywords in aliases. For example, the following query is invalid without the quotation marks:

SELECT dept_name AS Department,
   dept_id AS "integer"
FROM department

If you wish to ensure compatibility with Adaptive Server Enterprise, you should use quoted aliases of 30 bytes or less.


Character strings in query results

The SELECT statements you have seen so far produce results that consist solely of data from the tables in the FROM clause. Strings of characters can also be displayed in query results by enclosing them in single quotation marks and separating them from other elements in the select list with commas.

To enclose a quotation mark in a string, you precede it with another quotation mark.

For example:

SELECT 'The department''s name is' AS "Prefix",
   Department = dept_name
FROM department
Prefix | Department
The department's name is | R & D
The department's name is | Sales
The department's name is | Finance
The department's name is | Marketing
The department's name is | Shipping


Computing values in the SELECT list

The expressions in the select list can be more complicated than just column names or strings. For example, you can perform computations with data from numeric columns in a select list.

Arithmetic operations

To illustrate the numeric operations you can carry out in the select list, we start with a listing of the names, quantity in stock, and unit price of products in the sample database.

SELECT name, quantity, unit_price
FROM product
name | quantity | unit_price
Tee Shirt | 28 | 9
Tee Shirt | 54 | 14
Tee Shirt | 75 | 14
Baseball Cap | 112 | 9
... | ... | ...

Suppose the practice is to replenish the stock of a product when there are ten items left in stock. The following query lists the number of each product that must be sold before re-ordering:

SELECT name, quantity - 10
   AS "Sell before reorder"
FROM product
name | Sell before reorder
Tee Shirt | 18
Tee Shirt | 44
Tee Shirt | 65
Baseball Cap | 102
... | ...

You can also combine the values in columns. The following query lists the total value of each product in stock:

SELECT name,
   quantity * unit_price AS "Inventory value"
FROM product
name | Inventory value
Tee Shirt | 252
Tee Shirt | 756
Tee Shirt | 1050
Baseball Cap | 1008
... | ...
Arithmetic operator precedence

When there is more than one arithmetic operator in an expression, multiplication, division, and modulo are calculated first, followed by subtraction and addition. When all arithmetic operators in an expression have the same level of precedence, the order of execution is left to right. Expressions within parentheses take precedence over all other operations.

For example, the following SELECT statement calculates the total value of each product in inventory, and then subtracts five dollars from that value.

SELECT name, quantity * unit_price - 5
FROM product

To avoid misunderstandings, it is recommended that you use parentheses. The following query has the same meaning and gives the same results as the previous one, but some may find it easier to understand:

SELECT name, ( quantity * unit_price ) - 5
FROM product

For more information on operator precedence, see Operator precedence.

String operations

You can concatenate strings using a string concatenation operator. You can use either || (SQL/92 compliant) or + (supported by Adaptive Server Enterprise) as the concatenation operator.

The following example illustrates the use of the string concatenation operator in the select list:

SELECT emp_id, emp_fname || ' ' || emp_lname AS Name
FROM employee
emp_id | Name
102 | Fran Whitney
105 | Matthew Cobb
129 | Philip Chin
148 | Julie Jordan
... | ...
Date and time operations

Although you can use operators on date and time columns, this typically involves the use of functions. For information on SQL functions, see SQL Functions.


Eliminating duplicate query results

The optional DISTINCT keyword eliminates duplicate rows from the results of a SELECT statement.

If you do not specify DISTINCT, you get all rows, including duplicates. Optionally, you can specify ALL before the select list to get all rows. For compatibility with other implementations of SQL, Adaptive Server syntax allows the use of ALL to explicitly ask for all rows. ALL is the default.

For example, if you search for all the cities in the contact table without DISTINCT, you get 60 rows:

SELECT city
FROM contact

You can eliminate the duplicate entries using DISTINCT. The following query returns only 16 rows.:

SELECT DISTINCT city
FROM contact
NULL values are not distinct

The DISTINCT keyword treats NULL values as duplicates of each other. In other words, when DISTINCT is included in a SELECT statement, only one NULL is returned in the results, no matter how many NULL values are encountered.


The FROM clause: specifying tables

The FROM clause is required in every SELECT statement involving data from tables, views, or stored procedures.

The FROM clause can include JOIN conditions linking two or more tables, and can include joins to other queries (derived tables). For information on these features, see Joins: Retrieving Data from Several Tables.

Qualifying table names

In the FROM clause, the full naming syntax for tables and views is always permitted, such as:

SELECT select-list
FROM owner.table_name

Qualifying table, view, and procedure names is necessary only when the object is owned by a user ID that is not the same as the user ID of the current connection, or is not the name of a group to which the user ID of the current connection belongs.

Using correlation names

You can give a table name a correlation name to save typing. You assign the correlation name in the FROM clause by typing it after the table name, like this:

SELECT d.dept_id, d.dept_name
FROM Department d

All other references to the Department table, for example in a WHERE clause, must use the correlation name. Correlation names must conform to the rules for valid identifiers.

For more information about the FROM clause, see FROM clause.

Querying from objects other than tables

The most common elements in a FROM clause are table names. It is also possible to query rows from other database objects that have a table-like structure—that is, a well-defined set of rows and columns. In addition to querying from tables and views, you can use derived tables (which are SELECT statements) or stored procedures that return result sets.

For example, the following query operates on the result set of a stored procedure.

SELECT *
FROM sp_customer_products( 149 )

For more information, see FROM clause.


The WHERE clause: specifying rows

The WHERE clause in a SELECT statement specifies the search conditions for exactly which rows are retrieved. The general format is:

SELECT select_list
FROM table_list
WHERE search-condition

Search conditions, also called qualifications or predicates, in the WHERE clause include the following:

  • Comparison operators (=, <, >, and so on) For example, you can list all employees earning more than $50,000:

    SELECT emp_lname
FROM employee
WHERE salary > 50000

  • Ranges (BETWEEN and NOT BETWEEN) For example, you can list all employees earning between $40,000 and $60,000:

    SELECT emp_lname
FROM employee
WHERE salary BETWEEN 40000 AND 60000

  • Lists (IN, NOT IN) For example, you can list all customers in Ontario, Quebec, or Manitoba:

    SELECT company_name , state
FROM customer
WHERE state IN( 'ON', 'PQ', 'MB')

  • Character matches (LIKE and NOT LIKE) For example, you can list all customers whose phone numbers start with 415. (The phone number is stored as a string in the database):

    SELECT company_name , phone
FROM customer
WHERE phone LIKE '415%'

  • Unknown values (IS NULL and IS NOT NULL) For example, you can list all departments with managers:

    SELECT dept_name
FROM Department
WHERE dept_head_id IS NOT NULL

  • Combinations (AND, OR) For example, you can list all employees earning over $50,000 whose first name begins with the letter A.

    SELECT emp_fname, emp_lname
FROM employee
WHERE salary > 50000
AND emp_fname like 'A%'

In addition, the WHERE keyword can introduce the following:

  • Transact-SQL join conditions Joins are discussed in Joins: Retrieving Data from Several Tables.

For more information about search conditions, see Search conditions.

The following sections describe how to use WHERE clauses.

Using comparison operators in the WHERE clause
Using ranges (between and not between) in the WHERE clause
Using lists in the WHERE clause
Matching character strings in the WHERE clause
Character strings and quotation marks
Unknown Values: NULL
Connecting conditions with logical operators


Using comparison operators in the WHERE clause

You can use comparison operators in the WHERE clause. The operators follow the syntax:

WHERE expression comparison-operator expression

For more information about comparison operators, see Comparison operators. For a description of what an expression can consist of, see Expressions.

Notes on comparisons

  • Sort orders In comparing character data, < means earlier in the sort order and > means later in the sort order. The sort order is determined by the collation chosen when the database is created. You can find out the collation by running the dbinfo command-line utility against the database:

    dbinfo -c "uid=DBA;pwd=SQL"

    You can also find the collation from Sybase Central. It is on the Extended Information tab of the database property sheet.

  • Trailing blanks When you create a database, you indicate whether trailing blanks are to be ignored or not for the purposes of comparison.

    By default, databases are created with trailing blanks not ignored. For example, 'Dirk' is not the same as 'Dirk '. You can create databases with blank padding, so that trailing blanks are ignored. Trailing blanks are ignored by default in Adaptive Server Enterprise databases.

  • Comparing dates In comparing dates, < means earlier and > means later.

  • Case sensitivity When you create a database, you indicate whether string comparisons are case sensitive or not.

    By default, databases are created case insensitive. For example, 'Dirk' is the same as 'DIRK'. You can create databases to be case sensitive, which is the default behavior for Adaptive Server Enterprise databases.

Here are some SELECT statements using comparison operators:

SELECT *
FROM product
WHERE quantity < 20
SELECT E.emp_lname, E.emp_fname
FROM employee E
WHERE emp_lname > 'McBadden'
SELECT id, phone
FROM contact
WHERE state  != 'CA'
The NOT operator

The NOT operator negates an expression. Either of the following two queries will find all Tee shirts and baseball caps that cost $10 or less. However, note the difference in position between the negative logical operator (NOT) and the negative comparison operator (!>).

SELECT id, name, quantity
FROM product
WHERE (name = 'Tee Shirt' OR name = 'BaseBall Cap')
AND NOT unit_price > 10
SELECT id, name, quantity
FROM product
WHERE (name = 'Tee Shirt' OR name = 'BaseBall Cap')
AND unit_price !> 10


Using ranges (between and not between) in the WHERE clause

The BETWEEN keyword specifies an inclusive range, in which the lower value and the upper value are searched for as well as the values they bracket.

toggle To list all the products with prices between $10 and $15, inclusive

  • Type the following query:

    SELECT name, unit_price
FROM product
WHERE unit_price BETWEEN 10 AND 15
name | unit_price
Tee Shirt | 14
Tee Shirt | 14
Baseball Cap | 10
Shorts | 15

You can use NOT BETWEEN to find all the rows that are not inside the range.

toggle To list all the products cheaper than $10 or more expensive than $15

  • Execute the following query:

    SELECT name, unit_price
FROM product
WHERE unit_price NOT BETWEEN 10 AND 15
name | unit_price
Tee Shirt | 9
Baseball Cap | 9
Visor | 7
Visor | 7
... | ...


Using lists in the WHERE clause

The IN keyword allows you to select values that match any one of a list of values. The expression can be a constant or a column name, and the list can be a set of constants or, more commonly, a subquery.

For example, without in, if you want a list of the names and states of all the contacts who live in Ontario, Manitoba, or Quebec, you can type this query:

SELECT company_name , state
FROM customer
WHERE state = 'ON' OR state = 'MB' OR state = 'PQ'

However, you get the same results if you use IN. The items following the IN keyword must be separated by commas and enclosed in parentheses. Put single quotes around character, date, or time values. For example:

SELECT company_name , state
FROM customer
WHERE state IN( 'ON', 'MB', 'PQ')

Perhaps the most important use for the IN keyword is in nested queries, also called subqueries.


Matching character strings in the WHERE clause

The LIKE keyword indicates that the following character string is a matching pattern. LIKE is used with character, binary, or date and time data.

The syntax for LIKE is:

{ WHERE | HAVING } expression [ NOT ] LIKE match-expression

The expression to be matched is compared to a match-expression that can include these special symbols:

Symbols | Meaning
% Matches any string of 0 or more characters
_ Matches any one character
[specifier] The specifier in the brackets may take the following forms:

  • Range A range is of the form rangespec1-rangespec2, where rangespec1 indicates the start of a range of characters, the hyphen indicates a range, and rangespec2 indicates the end of a range of characters

  • Set A set can be comprised of any discrete set of values, in any order. For example, [a2bR].

Note that the range [a-f], and the sets [abcdef] and [fcbdae] return the same set of values.
[^specifier] | The caret symbol (^) preceding a specifier indicates non-inclusion. [^a-f] means not in the range a-f; [^a2bR] means not a, 2, b, or R.

You can match the column data to constants, variables, or other columns that contain the wildcard characters displayed in the table. When using constants, you should enclose the match strings and character strings in single quotes.

Examples

All the following examples use LIKE with the last_name column in the Contact table. Queries are of the form:

SELECT last_name
FROM contact
WHERE last_name LIKE match-expression

The first example would be entered as

SELECT last_name
FROM contact
WHERE last_name LIKE 'Mc%'
Match expression | Description | Returns
'Mc%' | Search for every name that begins with the letters Mc | McEvoy
'%er' | Search for every name that ends with er | Brier, Miller, Weaver, Rayner
'%en%' | Search for every name containing the letters en. | Pettengill, Lencki, Cohen
'_ish' | Search for every four-letter name ending in ish. | Fish
'Br[iy][ae]r' | Search for Brier, Bryer, Briar, or Bryar. | Brier
'[M-Z]owell' | Search for all names ending with owell that begin with a single letter in the range M to Z. | Powell
'M[^c]%' | Search for all names beginning with M' that do not have c as the second letter | Moore, Mulley, Miller, Masalsky
Wildcards require LIKE

Wildcard characters used without LIKE are interpreted as literals rather than as a pattern: they represent exactly their own values. The following query attempts to find any phone numbers that consist of the four characters 415% only. It does not find phone numbers that start with 415.

SELECT phone
FROM Contact
WHERE phone = '415%'
Using LIKE with date and time values

You can use LIKE on date and time fields as well as on character data. When you use LIKE with date and time values, the dates are converted to the standard DATETIME format, and then to VARCHAR.

One feature of using LIKE when searching for DATETIME values is that, since date and time entries may contain a variety of date parts, an equality test has to be written carefully in order to succeed.

For example, if you insert the value 9:20 and the current date into a column named arrival_time, the clause:

WHERE arrival_time = '9:20'

fails to find the value, because the entry holds the date as well as the time. However, the clause below would find the 9:20 value:

WHERE arrival_time LIKE '%09:20%'
Using NOT LIKE

With NOT LIKE, you can use the same wildcard characters that you can use with LIKE. To find all the phone numbers in the Contact table that do not have 415 as the area code, you can use either of these queries:

SELECT phone
FROM Contact
WHERE phone NOT LIKE '415%'
SELECT phone
FROM Contact
WHERE NOT phone LIKE '415%'


Character strings and quotation marks

When you enter or search for character and date data, you must enclose it in single quotes, as in the following example.

SELECT first_name, last_name
FROM contact
WHERE first_name = 'John'

If the quoted_identifier database option is set to OFF (it is ON by default), you can also use double quotes around character or date data.

Interactive SQL automatically sets quoted_identifier to ON for the duration of the Interactive SQL session.

toggle To set the quoted_identifier option off for the current user ID

  • Type the following command:

    SET OPTION quoted_identifier = 'OFF'

The quoted_identifier option is provided for compatibility with Adaptive Server Enterprise. By default, the Adaptive Server Enterprise option is quoted_identifier OFF and the Adaptive Server Anywhere option is quoted_identifier ON.

Quotation marks in strings

There are two ways to specify literal quotations within a character entry. The first method is to use two consecutive quotation marks. For example, if you have begun a character entry with a single quotation mark and want to include a single quotation mark as part of the entry, use two single quotation marks:

'I don''t understand.'

With double quotation marks (quoted_identifier OFF):

"He said, ""It is not really confusing."""

The second method, applicable only with quoted_identifier OFF, is to enclose a quotation in the other kind of quotation mark. In other words, surround an entry containing double quotation marks with single quotation marks, or vice versa. Here are some examples:

'George said, "There must be a better way."'
"Isn't there a better way?"
'George asked, "Isn''t there a better way?"'


Unknown Values: NULL

A NULL in a column means that the user or application has made no entry in that column. A data value for the column is unknown or not available.

NULL does not mean the same as zero (numerical values) or blank (character values). Rather, NULL values allow you to distinguish between a deliberate entry of zero for numeric columns or blank for character columns and a non-entry, which is NULL for both numeric and character columns.

Entering NULL

NULL can be entered in a column where NULL values are permitted, as specified in the create table statement, in two ways:

  • Default If no data is entered, and the column has no other default setting, NULL is entered.

  • Explicit entry You can explicitly enter the value NULL by typing the word NULL (without quotation marks).

    If the word NULL is typed in a character column with quotation marks, it is treated as data, not as a null value.

For example, the dept_head_id column of the department table allows nulls. You can enter two rows for departments with no manager as follows:

INSERT INTO department (dept_id, dept_name)
VALUES (201, 'Eastern Sales')
INSERT INTO department
VALUES (202, 'Western Sales', null)
When NULLs are retrieved

When NULLS are retrieved, displays of query results in Interactive SQL show (NULL) in the appropriate position:

SELECT *
FROM department
dept_id | dept_name | dept_head_id
100 | R & D | 501
200 | Sales | 904
300 | Finance | 1293
400 | Marketing | 1576
500 | Shipping | 703
201 | Eastern Sales | (NULL)
202 | Western Sales | (NULL)


Testing a column for NULL

You can use IS NULL in search conditions to compare column values to NULL and to select them or perform a particular action based on the results of the comparison. Only columns that return a value of TRUE are selected or result in the specified action; those that return FALSE or UNKNOWN do not.

The following example selects only rows for which unit_price is less than $15 or is NULL:

SELECT quantity , unit_price
FROM product
WHERE unit_price < 15
OR unit_price IS NULL

The result of comparing any value to NULL is UNKNOWN, since it is not possible to determine whether NULL is equal (or not equal) to a given value or to another NULL.

There are some conditions that never return true, so that queries using these conditions do not return result sets. For example, the following comparison can never be determined to be true, since NULL means having an unknown value:

WHERE column1 > NULL

This logic also applies when you use two column names in a WHERE clause, that is, when you join two tables. A clause containing the condition

WHERE column1 = column2

does not return rows where the columns contain NULL.

You can also find NULL or non-NULL with this pattern:

WHERE column_name IS [NOT] NULL

For example:

WHERE advance < $5000
OR advance IS NULL

For more information, see NULL value.


Properties of NULL

The following list expands on the properties of NULL.

  • The difference between FALSE and UNKNOWN Although neither FALSE nor UNKNOWN returns values, there is an important logical difference between FALSE and UNKNOWN, because the opposite of false ("not false") is true. For example,

    1 = 2

    evaluates to false and its opposite,

    1 != 2

    evaluates to true. But "not unknown" is still unknown. If null values are included in a comparison, you cannot negate the expression to get the opposite set of rows or the opposite truth value.

  • Substituting a value for NULLs Use the ISNULL built-in function to substitute a particular value for nulls. The substitution is made only for display purposes; actual column values are not affected. The syntax is:

    ISNULL( expression, value )

    For example, use the following statement to select all the rows from test, and display all the null values in column t1 with the value unknown.

    SELECT ISNULL(t1, 'unknown')
FROM test

  • Expressions that evaluate to NULL An expression with an arithmetic or bitwise operator evaluates to NULL if any of the operands are null. For example:

    1 + column1

    evaluates to NULL if column1 is NULL.

  • Concatenating strings and NULL If you concatenate a string and NULL, the expression evaluates to the string. For example:

    SELECT 'abc' || NULL || 'def'

    returns the string abcdef.


Connecting conditions with logical operators

The logical operators AND, OR, and NOT are used to connect search conditions in WHERE clauses.

Using AND

The AND operator joins two or more conditions and returns results only when all of the conditions are true. For example, the following query finds only the rows in which the contact's last name is Purcell and the contact's first name is Beth. It does not find the row for Beth Glassmann.

SELECT *
FROM contact
WHERE first_name = 'Beth'
   AND last_name = 'Purcell'
Using OR

The OR operator also connects two or more conditions, but it returns results when any of the conditions is true. The following query searches for rows containing variants of Elizabeth in the first_name column.

SELECT *
FROM contact
WHERE first_name = 'Beth'
   OR first_name = 'Liz'
Using NOT

The NOT operator negates the expression that follows it. The following query lists all the contacts who do not live in California:

SELECT *
FROM contact
WHERE NOT state = 'CA'

When more than one logical operator is used in a statement, AND operators are normally evaluated before OR operators. You can change the order of execution with parentheses. For example:

SELECT *
FROM contact
WHERE ( city = 'Lexington'
        OR city = 'Burlington' )
   AND state = 'MA'


Summarizing, Grouping, and Sorting Query Results

About this chapter

Aggregate functions display summaries of the values in specified columns. You can also use the GROUP BY clause, HAVING clause, and ORDER BY clause to group and sort the results of queries using aggregate functions, and the UNION operator to combine the results of queries.

This chapter describes how to group and sort query results.

Summarizing query results using aggregate functions
The GROUP BY clause: organizing query results into groups
Understanding GROUP BY
The HAVING clause: selecting groups of data
The ORDER BY clause: sorting query results
Performing set operations on query results with UNION, INTERSECT, and EXCEPT
Standards and compatibility


Summarizing query results using aggregate functions

You can apply aggregate functions to all the rows in a table, to a subset of the table specified by a WHERE clause, or to one or more groups of rows in the table. From each set of rows to which an aggregate function is applied, Adaptive Server Anywhere generates a single value.

The following are among the available aggregate functions:

  • avg( expression ) The mean of the supplied expression over the returned rows.

  • count( expression ) The number of rows in the supplied group where the expression is not NULL.

  • count(*) The number of rows in each group.

  • list( string-expr) A string containing a comma-separated list composed of all the values for string-expr in each group of rows.

  • max( expression ) The maximum value of the expression, over the returned rows.

  • min( expression ) The minimum value of the expression, over the returned rows.

  • stddev( expression ) The standard deviation of the expression, over the returned rows.

  • sum( expression ) The sum of the expression, over the returned rows.

  • variance( expression ) The variance of the expression, over the returned rows.

For a complete list of aggregate functions, see Aggregate functions.

You can use the optional keyword DISTINCT with AVG, SUM, LIST, and COUNT to eliminate duplicate values before the aggregate function is applied.

The expression to which the syntax statement refers is usually a column name. It can also be a more general expression.

For example, with this statement you can find what the average price of all products would be if one dollar were added to each price:

SELECT AVG (unit_price + 1)
FROM product
Example

The following query calculates the total payroll from the annual salaries in the employee table:

SELECT SUM(salary)
FROM employee

To use aggregate functions, you must give the function name followed by an expression on whose values it will operate. The expression, which is the salary column in this example, is the function's argument and must be specified inside parentheses.

Where you can use aggregate functions
Aggregate functions and data types
Using COUNT(*)
Using aggregate functions with DISTINCT
Aggregate functions and NULL


Where you can use aggregate functions

The aggregate functions can be used in a select list, as in the previous examples, or in the HAVING clause of a select statement that includes a GROUP BY clause.

For more information about the HAVING clause, see The HAVING clause: selecting groups of data.

You cannot use aggregate functions in a WHERE clause or in a JOIN condition. However, a SELECT statement with aggregate functions in its select list often includes a WHERE clause that restricts the rows to which the aggregate is applied.

If a SELECT statement includes a WHERE clause, but not a GROUP BY clause, an aggregate function produces a single value for the subset of rows that the WHERE clause specifies.

Whenever an aggregate function is used in a SELECT statement that does not include a GROUP BY clause, it produces a single value. This is true whether it is operating on all the rows in a table or on a subset of rows defined by a where clause.

You can use more than one aggregate function in the same select list, and produce more than one scalar aggregate in a single SELECT statement.

Aggregate functions and outer references

Adaptive Server Anywhere version 8 and later follows SQL/99 standards for clarifying the use of aggregate functions when they appear in a subquery. These changes affect the behavior of statements written for previous versions of the software: previously correct queries may now produce error messages, and result sets may change.

When an aggregate function appears in a subquery, and the column referenced by the aggregate function is an outer reference, the entire aggregate function itself is now treated as an outer reference. This means that the aggregate function is now computed in the outer block, not in the subquery, and becomes a constant within the subquery.

The following restrictions now apply to the use of outer reference aggregate functions in subqueries:

  • The outer reference aggregate function can only appear in subqueries that are in the SELECT list or HAVING clause, and these clauses must be in the immediate outer block.

  • Outer reference aggregate functions can only contain one outer column reference.

  • Local column references and outer column references cannot be mixed in the same aggregate function.

Some problems related to the new standards can be circumvented by rewriting the aggregate function so that it only includes local references. For example, the subquery (SELECT MAX(S.y + R.y) FROM S) contains both a local column reference (S.y) and an outer column reference (R.y), which is now illegal. It can be rewritten as (SELECT MAX(S.y) + R.y FROM S). In the rewrite, the aggregate function has only a local column reference. The same sort of rewrite can be used when an outer reference aggregate function appears in clauses other than SELECT or HAVING.

Example

The following query produced the following results in Adaptive Server Anywhere version 7.

SELECT name, (SELECT SUM(p.quantity)
              FROM sales_order_items)
FROM product p
name | sum(p.quantity)
Tee shirt | 30,716
Tee shirt | 59,238

In later versions, the same query produces the error message ASA Error -149: Function or column reference to 'name' must also appear in a GROUP BY. The reason that the statement is no longer valid is that the outer reference aggregate function sum(p.quantity) is now computed in the outer block. In later versions, the query is semantically equivalent to the following (except that Z does not appear as part of the result set):

SELECT name,
       SUM(p.quantity) as Z,
       (SELECT Z FROM sales_order_items)
FROM product p

Since the outer block now computes an aggregate function, the outer block is treated as a grouped query and column name must appear in a GROUP BY clause in order to appear in the SELECT list.


Aggregate functions and data types

Some aggregate functions have meaning only for certain kinds of data. For example, you can use SUM and AVG with numeric columns only.

However, you can use MIN to find the lowest value—the one closest to the beginning of the alphabet—in a character type column:

SELECT MIN(last_lname)
FROM  contact


Using COUNT(*)

The COUNT(*) function does not require an expression as an argument because, by definition, it does not use information about any particular column. The COUNT(*) function finds the total number of rows in a table. This statement finds the total number of employees:

SELECT COUNT(*)
FROM employee

COUNT(*) returns the number of rows in the specified table without eliminating duplicates. It counts each row separately, including rows that contain NULL.

Like other aggregate functions, you can combine count(*) with other aggregates in the select list, with where clauses, and so on:

SELECT count(*), AVG(unit_price)
FROM product
WHERE  unit_price > 10
count(*) | AVG(product.unit_price)
5 | 18.2


Using aggregate functions with DISTINCT

The DISTINCT keyword is optional with SUM, AVG, and COUNT. When you use DISTINCT, duplicate values are eliminated before calculating the sum, average, or count.

For example, to find the number of different cities in which there are contacts, type:

SELECT count(DISTINCT city)
FROM contact
count(distinct contact.city)
16

You can use more than one aggregate function with DISTINCT in a query. Each DISTINCT is evaluated independently. For example:

SELECT count( DISTINCT first_name ) "first names",
       count( DISTINCT last_name ) "last names"
FROM contact
first names | last names
48 | 60


Aggregate functions and NULL

Any NULLS in the column on which the aggregate function is operating are ignored for the purposes of the function except COUNT(*), which includes them. If all the values in a column are NULL, COUNT(column_name) returns 0.

If no rows meet the conditions specified in the WHERE clause, COUNT returns a value of 0. The other functions all return NULL. Here are examples:

SELECT COUNT (DISTINCT name)
FROM product
WHERE unit_price > 50
count(DISTINCT name)
0
SELECT AVG(unit_price)
FROM product
WHERE unit_price > 50
AVG(product.unit_price)
( NULL )


The GROUP BY clause: organizing query results into groups

The GROUP BY clause divides the output of a table into groups. You can GROUP BY one or more column names, or by the results of computed columns using numeric data types in an expression.

Using GROUP BY with aggregate functions


Using GROUP BY with aggregate functions

A GROUP BY clause almost always appears in statements that include aggregate functions, in which case the aggregate produces a value for each group. These values are called vector aggregates. (Remember that a scalar aggregate is a single value produced by an aggregate function without a GROUP BY clause.)

Example

The following query lists the average price of each kind of product:

SELECT name, AVG(unit_price) AS Price
FROM product
GROUP BY name
name | Price
Tee Shirt | 12.333333333
Baseball Cap | 9.5
Visor | 7
Sweatshirt | 24
... | ...

The summary values (vector aggregates) produced by SELECT statements with aggregates and a GROUP BY appear as columns in each row of the results. By contrast, the summary values (scalar aggregates) produced by queries with aggregates and no GROUP BY also appear as columns, but with only one row. For example:

SELECT AVG(unit_price)
FROM product
AVG(product.unit_price)
13.3


Understanding GROUP BY

Understanding which queries are valid and which are not can be difficult when the query involves a GROUP BY clause. This section describes a way to think about queries with GROUP BY so that you may understand the results and the validity of queries better.


How queries with GROUP BY are executed

Consider a single-table query of the following form:

SELECT select-list
FROM table
WHERE where-search-condition
GROUP BY [ group-by-expression | ROLLUP (group-by-expression) ]
HAVING having-search-condition

This query can be thought of as being executed in the following manner:

  1. Apply the WHERE clause This generates an intermediate result that contains only some of the rows of the table. The intermediate result contains a subset of rows from the table.

  2. Partition the result into groups This action generates an intermediate result with one row for each group as dictated by the GROUP BY clause. Each generated row contains the group-by-expression for each group, and the computed aggregate functions in the select-list and having-search-condition. A second intermediate result is made smaller by the application of the GROUP BY clause.

  3. Apply any ROLLUP operation Subtotal rows computed as part of a ROLLUP operation are added to the result set.

    For more information, see Using ROLLUP.

  4. Apply the HAVING clause Any rows from this second intermediate result that do not meet the criteria of the HAVING clause are removed at this point.

  5. Project out the results to display This action takes from step 3 only those columns that need to be displayed in the result set of the query–that is, it takes only those columns corresponding to the expressions from the select-list. The final result set is a projection of the second intermediate result set.

This process makes requirements on queries with a GROUP BY clause:

  • The WHERE clause is evaluated first. Therefore, any aggregate functions are evaluated only over those rows that satisfy the WHERE clause.

  • The final result set is built from the second intermediate result, which holds the partitioned rows. The second intermediate result holds rows corresponding to the group-by-expression. Therefore, if an expression that is not an aggregate function appears in the select-list, then it must also appear in the group-by-expression. No function evaluation can be carried out during the projection step.

  • An expression can be included in the group-by-expression but not in the select-list. It is projected out in the result.


GROUP BY with multiple columns

You can list more than one expression in the GROUP BY clause in order to nest groups—that is, you can group a table by any combination of expressions.

The following query lists the average price of products, grouped first by name and then by size:

SELECT name, size, AVG(unit_price)
FROM product
GROUP BY name, size
name | size | AVG(product.unit_price)
Tee Shirt | Small | 9
Tee Shirt | Medium | 14
Tee Shirt | One size fits all | 14
Baseball Cap | One size fits all | 9.5
... | ... | ...
Columns in GROUP BY that are not in the select list

A Sybase extension to the SQL/92 standard that is supported by both Adaptive Server Enterprise and Adaptive Server Anywhere is to allow expressions to the GROUP BY clause that are not in the select list. For example, the following query lists the number of contacts in each city:

SELECT state, count(id)
FROM contact
GROUP BY state, city


WHERE clause and GROUP BY

You can use a WHERE clause in a statement with GROUP BY. The WHERE clause is evaluated before the GROUP BY clause. Rows that do not satisfy the conditions in the WHERE clause are eliminated before any grouping is done. Here is an example:

SELECT  name, AVG(unit_price)
FROM product
WHERE id > 400
GROUP BY name

Only the rows with id values of more than 400 are included in the groups that are used to produce the query results.

Example

The following query illustrates the use of WHERE, GROUP BY, and HAVING clauses in one query:

SELECT name, SUM(quantity)
FROM product
WHERE name LIKE '%shirt%'
GROUP BY name
HAVING SUM(quantity) > 100
name | SUM(product.quantity)
Tee Shirt | 157

In this example:

  • The WHERE clause includes only rows that have a name including the word shirt (Tee Shirt, Sweatshirt).

  • The GROUP BY clause collects the rows with a common name.

  • The SUM aggregate calculates the total quantity of products available for each group.

  • The HAVING clause excludes from the final results the groups whose inventory totals do not exceed 100.


The HAVING clause: selecting groups of data

The HAVING clause restricts the rows returned by a query. It sets conditions for the GROUP BY clause similar to the way in which WHERE sets conditions for the SELECT clause.

The HAVING clause search conditions are identical to WHERE search conditions except that WHERE search conditions cannot include aggregates, while HAVING search conditions often do. The example below is legal:

HAVING AVG(unit_price) > 20

But this example is not legal:

WHERE AVG(unit_price) > 20
Using HAVING with aggregate functions

The following statement is an example of simple use of the HAVING clause with an aggregate function.

To list those products available in more than one size or color, you need a query to group the rows in the product table by name, but eliminate the groups that include only one distinct product:

SELECT name
FROM product
GROUP BY name
HAVING COUNT(*) > 1
name
Tee Shirt
Baseball Cap
Visor
Sweatshirt

For information about when you can use aggregate functions in HAVING clauses, see Where you can use aggregate functions.

Using HAVING without aggregate functions

The HAVING clause can also be used without aggregates.

The following query groups the products, and then restricts the result set to only those groups for which the name starts with B.

SELECT name
FROM product
GROUP BY name
HAVING name LIKE 'B%'
name
Baseball Cap
More than one condition in HAVING

More than one condition can be included in the HAVING clause. They are combined with the AND, OR, or NOT operators, as in the following example.

To list those products available in more than one size or color, for which one version costs more than $10, you need a query to group the rows in the product table by name, but eliminate the groups that include only one distinct product, and eliminate those groups for which the maximum unit price is under $10.

SELECT name
FROM product
GROUP BY name
HAVING COUNT(*) > 1
AND MAX(unit_price) > 10
name
Tee Shirt
Sweatshirt


The ORDER BY clause: sorting query results

The ORDER BY clause allows sorting of query results by one or more columns. Each sort can be ascending (ASC) or descending (DESC). If neither is specified, ASC is assumed.

A simple example

The following query returns results ordered by name:

SELECT id, name
FROM product
ORDER BY name
id | name
400 | Baseball Cap
401 | Baseball Cap
700 | Shorts
600 | Sweatshirt
... | ...
Sorting by more than one column

If you name more than one column in the ORDER BY clause, the sorts are nested.

The following statement sorts the shirts in the product table first by name in ascending order, then by quantity (descending) within each name:

SELECT id, name, quantity
FROM product
WHERE name like '%shirt%'
ORDER BY name, quantity DESC
id | name | quantity
600 | Sweatshirt | 39
601 | Sweatshirt | 32
302 | Tee Shirt | 75
301 | Tee Shirt | 54
... | ... | ...
Using the column position

You can use the position number of a column in a select list instead of the column name. Column names and select list numbers can be mixed. Both of the following statements produce the same results as the preceding one.

SELECT id, name, quantity
FROM product
WHERE name like '%shirt%'
ORDER BY 2, 3 DESC
SELECT id, name, quantity
FROM product
WHERE name like '%shirt%'
ORDER BY 2, quantity DESC

Most versions of SQL require that ORDER BY items appear in the select list, but Adaptive Server Anywhere has no such restriction. The following query orders the results by quantity, although that column does not appear in the select list:

SELECT id, name
FROM product
WHERE name like '%shirt%'
ORDER BY 2, quantity DESC
ORDER BY and NULL

With ORDER BY, NULL sorts before all other values in ascending sort order.

ORDER BY and case sensitivity

The effects of an ORDER BY clause on mixed-case data depend on the database collation and case sensitivity specified when the database is created.


Explicitly limiting the number of rows returned by a query

You can use the FIRST or TOP keywords to limit the number of rows included in the result set of a query. These keywords are for use with queries that include an ORDER BY clause.

Examples

The following query returns information about the employee that appears first when employees are sorted by last name:

SELECT FIRST *
FROM employee
ORDER BY emp_lname

The following query returns the first five employees as sorted by last name:

SELECT TOP 5 *
FROM employee
ORDER BY emp_lname

When you use TOP, you can also use START AT to provide an offset. The following statement lists the fifth and sixth employees sorted in descending order by last name:

SELECT TOP 2 START AT 5 *
FROM employee
ORDER BY emp_lname DESC

FIRST and TOP should be used only in conjunction with an ORDER BY clause to ensure consistent results. Use of FIRST or TOP without an ORDER BY triggers a syntax warning, and will likely yield unpredictable results.

Note
The 'start at' value must be greater than 0. The 'top' value must be greater than 0 when a constant and greater or equal to 0 when a variable.

Previous Next


ORDER BY and GROUP BY

You can use an ORDER BY clause to order the results of a GROUP BY in a particular way.

Example

The following query finds the average price of each product and orders the results by average price:

SELECT name, AVG(unit_price)
FROM product
GROUP BY name
ORDER BY AVG(unit_price)
name | AVG(product.unit_price)
Visor | 7
Baseball Cap | 9.5
Tee Shirt | 12.333333333
Shorts | 15
... | ...


Performing set operations on query results with UNION, INTERSECT, and EXCEPT

The operators described in this section carry out set operations on the results of two or more queries. While many of the operations can also be carried out using operations in the WHERE clause or HAVING clause, there are some operations that are very difficult to carry out in any way other than using these set-based operators. For example:

  • When data is held in an unnormalized manner, you may wish to assemble seemingly disparate information into a single result set, even though the tables are unrelated.

  • NULL is treated differently by set operators than in the WHERE clause or HAVING clause. In the WHERE clause or HAVING clause, two null-containing rows with identical non-null entries are not seen as identical, as the two NULL values are not defined to be identical. The set operators see two such rows as the same.

    For more information on NULL and set operations, see Set operators and NULL.

For more information, see EXCEPT operation, INTERSECT operation, and UNION operation.


Combining sets with the UNION operation

The UNION operator combines the results of two or more queries into a single result set.

By default, the UNION operator removes duplicate rows from the result set. If you use the ALL option, duplicates are not removed. The columns in the result set have the same names as the columns in the first table referenced. Any number of union operators may be used. For example:

x UNION y UNION z

By default, a statement containing multiple UNION operators is evaluated from left to right. Parentheses may be used to specify the order of evaluation.

For example, the following two expressions are not equivalent, due to the way that duplicate rows are removed from result sets:

x UNION ALL (y UNION z)
(x UNION ALL y) UNION z

In the first expression, duplicates are eliminated in the UNION between y and z. In the UNION between that set and x, duplicates are not eliminated. In the second expression, duplicates are included in the union between x and y, but are then eliminated in the subsequent union with z.


Using EXCEPT and INTERSECT

The EXCEPT operation lists the differences between two result sets. The following general construction lists all those rows that appear in the result set of query-1, but not in the result set of query-2.

query-1
EXCEPT
query-2

The INTERSECT operation lists the rows that appear in each of two result sets. The following general construction lists all those rows that appear in the result set of both query-1 and query-2.

query-1
INTERSECT
query-2

Like the UNION operation, both EXCEPT and INTERSECT take the ALL modifier, which prevents the elimination of duplicate rows from the result set.

For more information, see EXCEPT operation, and INTERSECT operation.


Rules for set operations

The following rules apply to UNION, EXCEPT, and INTERSECT operations:

  • Same number of items in the select lists All select lists in the queries must have the same number of expressions (such as column names, arithmetic expressions, and aggregate functions). The following statement is invalid because the first select list is longer than the second:

    -- This is an example of an invalid statement
SELECT store_id, city, state
FROM stores
UNION
SELECT store_id, city
FROM stores_east

  • Data types must match Corresponding expressions in the SELECT lists must be of the same data type, or an implicit data conversion must be possible between the two data types, or an explicit conversion should be supplied.

    For example, a UNION, INTERSECT, or EXCEPT is not possible between a column of the CHAR data type and one of the INT data type, unless an explicit conversion is supplied. However, a set operation is possible between a column of the MONEY data type and one of the INT data type.

  • Column ordering You must place corresponding expressions in the individual queries of a set operation in the same order, because the set operators compare the expressions one to one in the order given in the individual queries in the SELECT clauses.

  • Multiple set operations You can string several set operations together, as in the following example:

    SELECT city AS Cities
FROM contact
UNION
SELECT city
FROM customer
UNION
SELECT city
FROM employee

    For UNION operations, the order of queries is not important. For INTERSECT, the order is important when there are two or more queries. For EXCEPT, the order is always important.

  • Column headings The column names in the table resulting from a UNION are taken from the first individual query in the statement. If you want to define a new column heading for the result set, you can do so in the select list of the first query, as in the following example:

    SELECT city AS Cities
FROM contact
UNION
SELECT city
FROM customer

    In the following query, the column heading remains as city, as it is defined in the first query of the UNION statement.

    SELECT city
FROM contact
UNION
SELECT city AS Cities
FROM customer

    Alternatively, you can use the WITH clause to define the column names. For example:

    WITH V( Cities )
AS ( SELECT city
     FROM contact
     UNION
     SELECT city
     FROM customer )
SELECT * FROM V

  • Ordering the results You can use the WITH clause of the SELECT statement to order the column names in the select list . For example:

    WITH V( cityname )
AS ( SELECT Cities = city
     FROM contact
     UNION
     SELECT city
     FROM customer )
SELECT * FROM V
ORDER BY cityname

    Alternatively, you can use a single ORDER BY clause at the end of the list of queries, but you must use integers rather than column names, as in the following example:

    SELECT Cities = city
FROM contact
UNION
SELECT city
FROM customer
ORDER BY 1


Set operators and NULL

NULL is treated differently by the set operators UNION, EXCEPT, and INTERSECT than it is in search conditions. This difference is one of the main reasons to use set operators.

When comparing rows, set operators treat NULL values as equal to each other. In contrast, when NULL is compared to NULL in a search condition the result is unknown (not true).

One particularly useful consequence of this difference is that the number of rows in the result set for query-1 EXCEPT ALL query-2 is always the difference in the number of rows in the result sets of the individual queries.

For example, consider two tables T1 and T2, each with the following columns:

col1 INT,
col2 CHAR(1)

The data in the tables is as follows:

  • Table T1.

    col1 | col2
    1 | a
    2 | b
    3 | (NULL)
    3 | (NULL)
    4 | (NULL)
    4 | (NULL)

  • Table T2

    col1 | col2
    1 | a
    2 | x
    3 | (NULL)

One query that asks for rows in T1 that also appear in T2 is as follows:

SELECT T1.col1, T1.col2
FROM T1 JOIN T2
ON T1.col1 = T2.col2
AND T1.col2 = T2.col2
T1.col1 | T1.col2
1 | a

The row ( 3, NULL ) does not appear in the result set, as the comparison between NULL and NULL is not true. In contrast, approaching the problem using the INTERSECT operator includes a row with NULL:

SELECT col1, col2
FROM T1
INTERSECT
SELECT col1, col2
FROM T2
col1 | col2
1 | a
3 | (NULL)

The following query uses search conditions to list rows in T1 that do not appear in T2:

SELECT col1, col2
FROM T1
WHERE col1 NOT IN (
    SELECT col1
    FROM t2
    WHERE t1.col2 = t2.col2 )
OR col2 NOT IN (
    SELECT col2
    FROM t2
    WHERE t1.col1 = t2.col1 )
col1 | col2
2 | b
3 | (NULL)
4 | (NULL)
3 | (NULL)
4 | (NULL)

The NULL-containing rows from T1 are not excluded by the comparison. In contrast, approaching the problem using EXCEPT ALL excludes NULL-containing rows that appear in both tables. In this case, the (3, NULL) row in T2 is identified as the same as the (3, NULL) row in T1.

SELECT col1, col2
FROM T1
EXCEPT ALL
SELECT col1, col2
FROM T2
col1 | col2
2 | b
3 | (NULL)
4 | (NULL)
4 | (NULL)

The EXCEPT operator is more restrictive still. It eliminates both (3, NULL) rows from T1 and excludes one of the (4, NULL) rows as a duplicate.

SELECT col1, col2
FROM T1
EXCEPT
SELECT col1, col2
FROM T2
col1 | col2
2 | b
4 | (NULL)


Standards and compatibility

This section describes standards and compatibility aspects of the Adaptive Server Anywhere GROUP BY clause.


GROUP BY and the SQL/92 standard

The SQL/92 standard for GROUP BY requires the following:

  • A column used in an expression of the SELECT clause must be in the GROUP BY clause. Otherwise, the expression using that column is an aggregate function.

  • A GROUP BY expression can only contain column names from the select list, but not those used only as arguments for vector aggregates.

The results of a standard GROUP BY with vector aggregate functions produce one row with one value per group.

Adaptive Server Anywhere and Adaptive Server Enterprise support extensions to HAVING that allow aggregate functions not in the select list and not in the GROUP BY clause.


Compatibility with Adaptive Server Enterprise

Adaptive Server Enterprise supports several extensions to the GROUP BY clause that are not supported in Adaptive Server Anywhere. These include the following:

  • Non-grouped columns in the select list Adaptive Server Enterprise permits column names in the select list that do not appear in the group by clause. For example, the following is valid in Adaptive Server Enterprise:

    SELECT name, unit_price
FROM product
GROUP BY name

    This syntax is not supported in Adaptive Server Anywhere.

  • Nested aggregate functions The following query, which nests a vector aggregate inside a scalar aggregate, is valid in Adaptive Server Enterprise but not in Adaptive Server Anywhere:

    SELECT MAX(AVG(unit_price))
FROM product
GROUP BY name

  • GROUP BY and ALL Adaptive Server Anywhere does not support the use of ALL in the GROUP BY clause.

  • HAVING with no GROUP BY Adaptive Server Anywhere does not support the use of HAVING with no GROUP BY clause unless all the expressions in the select and having clauses are aggregate functions. For example, the following query is valid in Adaptive Server Enterprise, but is not supported in Adaptive Server Anywhere:

    --unsupported syntax
SELECT unit_price
   FROM product
   HAVING COUNT(*) > 8

    However, the following statement is valid in Adaptive Server Anywhere, because the functions MAX and COUNT are aggregate functions:

    SELECT MAX(unit_price)
FROM product
HAVING COUNT(*) > 8

  • HAVING conditions Adaptive Server Enterprise supports extensions to HAVING that allow non-aggregate functions not in the select list and not in the GROUP BY clause. Only aggregate functions of this type are allowed in Adaptive Server Anywhere.

  • DISTINCT with ORDER BY or GROUP BY Adaptive Server Enterprise permits the use of columns in the ORDER BY or GROUP BY clause that do not appear in the select list, even in SELECT DISTINCT queries. This can lead to repeated values in the SELECT DISTINCT result set. Adaptive Server Anywhere does not support this behavior.

  • Column names in UNIONS Adaptive Server Enterprise permits the use of columns in the ORDER BY clause in unions of queries. In Adaptive Server Anywhere, the ORDER BY clause must use an integer to mark the column by which the results are being ordered.


Joins: Retrieving Data from Several Tables

About this chapter

When you create a database, you normalize the data by placing information specific to different objects in different tables, rather than in one large table with many redundant entries.

A join operation recreates a larger table using the information from two or more tables (or views). Using different joins, you can construct a variety of these virtual tables, each suited to a particular task.

Before you start

This chapter assumes some knowledge of queries and the syntax of the select statement. Information about queries appears in Queries: Selecting Data from a Table.

Sample database schema
How joins work
Joins overview
Explicit join conditions (the ON phrase)
Cross joins
Inner and outer joins
Specialized joins
Natural joins
Key joins


Sample database schema

This chapter makes frequent reference to the sample database. In the following diagram, the sample database is shown with the names of the foreign keys that relate the tables. The sample database is held in a file called asademo.db, and is located in your installation directory.

The Adaptive Server Anywhere sample database, including tables, column names, primary keys, and foreign key relationships.


How joins work

A relational database stores information about different types of objects in different tables. For example, information particular to employees appears in one table, and information that pertains to departments in another. The employee table contains information such as employee names and addresses. The department table contains information about one department, such as the name of the department and who the department head is.

Most questions can only be answered using a combination of information from the various tables. For example, you may want to answer the question "Who manages the Sales department?" To find the name of this person, you must identify the correct person using information from the department table, then look up that person's name in the employee table.

Joins are a means of answering such questions by forming a new virtual table that includes information from multiple tables. For example, you could create a list of the department heads by combining the information contained in the employee table and the department table. You specify which tables contain the information you need using the FROM clause.

To make the join useful, you must combine the correct columns of each table. To list department heads, each row of the combined table should contain the name of a department and the name of the employee who manages it. You control how columns are matched in the composite table by either specifying a particular type of join operation or using the ON phrase.


Joins overview

A join is an operation that combines the rows in tables by comparing the values in specified columns. This section is an overview of Adaptive Server Anywhere join syntax. All of the concepts are explored in greater detail in later sections.

The FROM clause
Join conditions
Joined tables
Joining two tables
Joining more than two tables
Join compatible data types
Using joins in delete, update, and insert statements
Non-ANSI joins


The FROM clause

Use the FROM clause to specify which base tables, temporary tables, views or derived tables to join. The FROM clause can be used in SELECT or UPDATE statements. An abbreviated syntax for the FROM clause is as follows:

FROM table_expression, ...

where:

table_expression:
table | view | derived table | joined table | ( table_expression, ... )

table or view:
[userid.] table-or-view-name [ [ AS ] correlation-name ]

derived table:
( select-statement ) [ AS ] correlation-name [ ( column-name, ... ) ]

joined table:
table_expression join_operator table_expression [ ON join_condition ]

join_operator:
[ KEY | NATURAL ] [ join_type ] JOIN | CROSS JOIN

join_type:
INNER | FULL [ OUTER ] | LEFT [ OUTER ] | RIGHT [ OUTER ]

Notes

You cannot use an ON phrase with CROSS JOIN.

For the complete syntax, see FROM clause.

For the syntax of the ON phrase, see Search conditions.


Join conditions

Tables can be joined using join conditions. A join condition is simply a search condition. It chooses a subset of rows from the joined tables based on the relationship between values in the columns. For example, the following query retrieves data from the product and sales_order_items tables.

SELECT *
FROM product JOIN sales_order_items
   ON product.id = sales_order_items.prod_id

The join condition in this query is

product.id = sales_order_items.prod_id

This join condition means that rows can be combined in the result set only if they have the same product ID in both tables.

Join conditions can be explicit or generated. An explicit join condition is a join condition that is put in an ON phrase or a WHERE clause. The following query uses an ON phrase. It produces a cross product of the two tables (all combinations of rows), but with rows excluded if the id numbers do not match. The result is a list of customers with details of their orders.

SELECT *
FROM customer JOIN sales_order
  ON sales_order.cust_id = customer.id

A generated join condition is a join condition that is automatically created when you specify KEY JOIN or NATURAL JOIN. In the case of a key join, the generated join condition is based on the foreign key relationships between the tables. In the case of a natural join, the generated join condition is based on columns that have the same name.

Tip: Both key join syntax and natural join syntax are shortcuts: you get identical results from using the keyword JOIN without KEY or NATURAL, and then explicitly stating the same join condition in an ON phrase.

When you use an ON phrase with a key join or natural join, the join condition that is used is the conjunction of the explicitly specified join condition with the generated join condition. This means that the join conditions are combined with the keyword AND.


Joined tables

Adaptive Server Anywhere supports the following classes of joined tables.

  • CROSS JOIN A cross join of two tables produces all possible combinations of rows from the two tables. The size of the result set is the number of rows in the first table multiplied by the number of rows in the second table. A cross join is also called a cross product or Cartesian product. You cannot use an ON phrase with a cross join.

  • KEY JOIN (default) A join condition is automatically generated based on the foreign key relationships that have been built into the database. Key join is the default when the JOIN keyword is used without specifying a join type and there is no ON phrase.

  • NATURAL JOIN A join condition is automatically generated based on columns having the same name.

  • Join using an ON phrase You specify an explicit join condition. When used with a key join or natural join, the join condition contains both the generated join condition and the explicit join condition. When used with the keyword JOIN without the keywords KEY or NATURAL, there is no generated join condition. You cannot use an ON clause with a cross join.

Inner and outer joins

Key joins, natural joins and joins with an ON clause may be qualified by specifying INNER, LEFT OUTER, RIGHT OUTER, or FULL OUTER. The default is INNER. When using the keywords LEFT, RIGHT or FULL, the keyword OUTER is optional.

In an inner join, each row in the result satisfies the join condition.

In a left or right outer join, all rows are preserved for one of the tables, and for the other table nulls are returned for rows that do not satisfy the join condition. For example, in a right outer join the right side is preserved and the left side is null-supplying.

In a full outer join, all rows are preserved for both of the tables, and nulls are supplied for rows that do not satisfy the join condition.


Joining two tables

To understand how a simple inner join is computed, consider the following query. It answers the question: which product sizes have been ordered in the same quantity as the quantity in stock?

SELECT DISTINCT name, size,
    sales_order_items.quantity
FROM product JOIN sales_order_items
ON product.id = sales_order_items.prod_id
  AND product.quantity = sales_order_items.quantity
name | size | quantity
Baseball Cap | One size fits all | 12
Visor | One size fits all | 36

You can interpret the query as follows. Note that this is a conceptual explanation of the processing of this query, used to illustrate the semantics of a query involving a join. It does not represent how Adaptive Server Anywhere actually computes the result set.

  • Create a cross product of the product table and sales_order_items table. A cross product contains every combination of rows from the two tables.

  • Exclude all rows where the product IDs are not identical (because of the join condition product.id   =   sales_order_items.prod_id).

  • Exclude all rows where the quantity is not identical (because of the join condition product.quantity   =   sales_order_items.quantity).

  • Create a result table with three columns: product.name, product.size, and sales_order_items.quantity.

  • Exclude all duplicate rows (because of the DISTINCT keyword).

For a description of how outer joins are computed, see Outer joins.


Joining more than two tables

With Adaptive Server Anywhere, there is no fixed limit on the number of tables you can join.

When joining more than two tables, parentheses are optional. If you do not use parentheses, Adaptive Server Anywhere evaluates the statement from left to right. Therefore, A JOIN B JOIN C is equivalent to (A JOIN B) JOIN C. Another example:

SELECT *
FROM A JOIN B JOIN C JOIN D

is equivalent to

SELECT *
FROM ((A JOIN B) JOIN C) JOIN D

Whenever more than two tables are joined, the join involves table expressions. In the example A JOIN B JOIN C, the table expression A JOIN B is joined to C. This means, conceptually, that A and B are joined, and then the result is joined to C.

The order of joins is important if the table expression contains outer joins. For example, A JOIN B LEFT OUTER JOIN C is interpreted as (A JOIN B) LEFT OUTER JOIN C. This means that the table expression A JOIN B is joined to C. The table expression A JOIN B is preserved and table C is null-supplying.

For more information about outer joins, see Outer joins.

For more information about how Adaptive Server Anywhere performs a key join of table expressions, see Key joins of table expressions.

For more information about how Adaptive Server Anywhere performs a natural join of table expressions, see Natural joins of table expressions.


Join compatible data types

When you join two tables, the columns you compare must have the same or compatible data types.

For more information about data type conversion in joins, see Conversion when using comparison operators.


Using joins in delete, update, and insert statements

You can use joins in DELETE, UPDATE and INSERT statements, as well as in SELECT statements. You can update some cursors that contain joins if the ANSI_UPDATE_CONSTRAINTS option is set to OFF. This is the default for databases created before Adaptive Server Anywhere version 7. For databases created in version 7 or later, the default is ON.

For more information, see ANSI_UPDATE_CONSTRAINTS option [compatibility].


Non-ANSI joins

Adaptive Server Anywhere supports ISO/ANSI standards for joins. It also supports the following non-standard joins:

  • Transact-SQL outer joins (*= or =*)

  • Duplicate correlation names in joins (star joins)

  • Key joins

  • Natural joins

You can use the REWRITE function to see the ANSI equivalent of a non-ANSI join.

For more information, see REWRITE function [Miscellaneous].


Explicit join conditions (the ON phrase)

Instead of, or along with, a key or natural join, you can specify a join using an explicit join condition. You specify a join condition by inserting an ON phrase immediately after the join. The join condition always refers to the join immediately preceding it.

Example

In the following query, the first ON phrase is used to join sales_order to customer. The second ON phrase is used to join the table expression (sales_order JOIN customer) to the base table sales_order_item.

SELECT *
FROM sales_order JOIN customer
    ON sales_order.cust_id = customer.id
  JOIN sales_order_items
    ON sales_order_items.id = sales_order.id
Tables that can be referenced

The tables that are referenced in an ON phrase must be part of the join that the ON phrase modifies. For example, the following is invalid:

FROM (A KEY JOIN B) JOIN (C JOIN D ON A.x = C.x)

The problem is that the join condition A.x = C.x references table A, which is not part of the join it modifies (in this case, C JOIN D).

However, as of the ANSI/ISO standard SQL99 and Adaptive Server Anywhere 7.0, there is an exception to this rule: if you use commas between table expressions, an ON condition of a join can reference a table that precedes it syntactically in the FROM clause. Therefore, the following is valid:

FROM (A KEY JOIN B) , (C JOIN D ON A.x = C.x)

For more information about commas, see Commas.


Generated joins and the ON phrase

Key joins are the default if the keyword JOIN is used and no join type is specified—unless you use an ON phrase. If you use an ON phrase with an unspecified JOIN, key join is not the default and no generated join condition is applied.

For example, the following is a key join, because key join is the default when the keyword JOIN is used and there is no ON phrase:

SELECT *
FROM A JOIN B

The following is a join between table A and table B with the join condition A.x   =   B.y. It is not a key join.

SELECT *
FROM A JOIN B ON A.x = B.y

If you specify a KEY JOIN or NATURAL JOIN and use an ON phrase, the final join condition is the conjunction of the generated join condition and the explicit join condition(s). For example, the following statement has two join conditions: one generated because of the key join, and one explicitly stated in the ON phrase.

SELECT *
FROM A KEY JOIN B ON A.x = B.y

If the join condition generated by the key join is A.w   =   B.z, then the following statement is equivalent:

SELECT *
FROM A JOIN B
  ON A.x = B.y
  AND A.w = B.z

For more information about key joins, see Key joins.


Types of explicit join conditions

Most join conditions are based on equality, and so are called equijoins. For example,

SELECT *
FROM department JOIN employee
   ON department.dept_id = employee.dept_id

However, you do not have to use equality (=) in a join condition. You can use any search condition, such as conditions containing LIKE, SOUNDEX, BETWEEN, > (greater than), and != (not equal to).

Example

The following example answers the question: For which products has someone ordered more than the quantity in stock?

SELECT DISTINCT product.name
FROM product JOIN sales_order_items
ON product.id = sales_order_items.prod_id
   AND product.quantity > sales_order_items.quantity

For more information about search conditions, see Search conditions.


Using the WHERE clause for join conditions

Except when using outer joins, you can specify join conditions in the WHERE clause instead of the ON phrase. However, you should be aware that there may be semantic differences between the two if the query contains outer joins.

The ON phrase is part of the FROM clause, and so is processed before the WHERE clause. This does not make a difference to results except in the case of outer joins, where using the WHERE clause can convert the join to an inner join.

When deciding whether to put join conditions in an ON phrase or WHERE clause, keep the following rules in mind:

  • When you specify an outer join, putting a join condition in the WHERE clause may convert the outer join to an inner join.

    For more information about the WHERE clause and outer joins, see Outer joins and join conditions.

  • Conditions in an ON phrase can only refer to tables that are in the table expressions joined by the associated JOIN. However, conditions in a WHERE clause can refer to any tables, even if they are not part of the join.

  • You cannot use an ON phrase with the keywords CROSS JOIN, but you can always use a WHERE clause.

  • When join conditions are in an ON phrase, key join is not the default. However, key join can be the default if join conditions are put in a WHERE clause.

    For more information about the conditions under which key join is the default, see When key join is the default.

In the examples in this documentation, join conditions are put in an ON phrase. In examples using outer joins, this is necessary. In other cases it is done to make it obvious that they are join conditions and not general search conditions.


Cross joins

A cross join of two tables produces all possible combinations of rows from the two tables. A cross join is also called a cross product or Cartesian product.

Each row of the first table appears once with each row of the second table. Hence, the number of rows in the result set is the product of the number of rows in the first table and the number of rows in the second table, minus any rows that are omitted because of restrictions in a WHERE clause.

You cannot use an ON phrase with cross joins. However, you can put restrictions in a WHERE clause.

Inner and outer modifiers do not apply to cross joins

Except in the presence of additional restrictions in the WHERE clause, all rows of both tables always appear in the result set of cross joins. Thus, the keywords INNER, LEFT OUTER and RIGHT OUTER are not applicable to cross joins.

For example, the following statement joins two tables.

SELECT *
FROM A CROSS JOIN B

The result set from this query includes all columns in A and all columns in B. There is one row in the result set for each combination of a row in A and a row in B. If A has n rows and B has m rows, the query returns n x m rows.

Commas


Commas

A comma works like a join operator, but is not one. A comma creates a cross product exactly as the keyword CROSS JOIN does. However, join keywords create table expressions, and commas create lists of table expressions.

In the following simple inner join of two tables, a comma and the keywords CROSS JOIN are equivalent:

Select *
FROM A CROSS JOIN B CROSS JOIN C
WHERE A.x = B.y

and

Select *
FROM A, B, C
WHERE A.x = B.y

Generally, you can use a comma instead of the keywords CROSS JOIN. The comma syntax is equivalent to cross join syntax, except in the case of generated join conditions in table expressions using commas.

For information about how commas work with generated join conditions, see Key joins of table expressions.

In the syntax of star joins, commas have a special use. For more information, see Duplicate correlation names in joins (star joins).


Inner and outer joins

The keywords INNER, LEFT OUTER, RIGHT OUTER, and FULL OUTER may be used to modify key joins, natural joins, and joins with an ON phrase. The default is INNER. The keyword OUTER is optional. These modifiers do not apply to cross joins.


Inner joins

By default, joins are inner joins. This means that rows are included in the result set only if they satisfy the join condition.

Example

For example, each row of the result set of the following query contains the information from one customer row and one sales_order row, satisfying the key join condition. If a particular customer has placed no orders, the condition is not satisfied and the result set does not contain the row corresponding to that customer.

SELECT fname, lname, order_date
FROM customer KEY INNER JOIN sales_order
ORDER BY order_date
fname | lname | order_date
Hardy | Mums | 1/2/00
Aram | Najarian | 1/3/00
Tommie | Wooten | 1/3/00
Alfredo | Margolis | 1/6/00
... | ... | ...

Because inner joins and key joins are the defaults, you obtain the same result using the following FROM clause.

FROM customer JOIN sales_order


Outer joins

A left or right outer join of two tables preserves all the rows in one table, and supplies nulls for the other table when it does not meet the join condition. A left outer join preserves every row in the left-hand table, and a right outer join preserves every row in the right-hand table. In a full outer join, all rows from both tables are preserved.

The table expressions on either side of a left or right outer join are referred to as preserved and null-supplying. In a left outer join, the left-hand table expression is preserved and the right-hand table expression is null-supplying.

For information about creating outer joins with Transact-SQL syntax, see Transact-SQL outer joins (*= or =*).

Example

For example, the following statement includes all customers, whether or not they have placed an order. If a particular customer has placed no orders, each column in the result that corresponds to order information contains the NULL value.

SELECT lname, order_date, city
FROM customer LEFT OUTER JOIN sales_order
    ON customer.id = sales_order.cust_id
WHERE customer.state = 'NY'
ORDER BY order_date
lname | order_date | city
Thompson | (NULL) | Bancroft
Reiser | 2000-01-22 | Rockwood
Clarke | 2000-01-27 | Rockwood
Mentary | 2000-01-30 | Rockland
... | ... | ...

You can interpret the outer join in this statement as follows. Note that this is a conceptual explanation, and does not represent how Adaptive Server Anywhere actually computes the result set.

  • Return one row for every sales order placed by a customer. More than one row is returned when the customer placed two or more sales orders, because a row is returned for each sales order. This is the same result as an inner join. The ON condition is used to match customer and sales order rows. The WHERE clause is not used for this step.

  • Include one row for every customer who has not placed any sales orders. This ensures that every row in the customer table is included. For all of these rows, the columns from sales_order are filled with nulls. These rows are added because the keyword OUTER is used, and would not have appeared in an inner join. Neither the ON condition nor the WHERE clause is used for this step.

  • Exclude every row where the customer does not live in New York, using the WHERE clause.


Outer joins and join conditions

A common mistake with outer joins is the placement of the join condition. In most cases, if you place restrictions on the null-supplying table in a WHERE clause, the join is equivalent to an inner join.

The reason for this is that most search conditions cannot evaluate to TRUE when any of their inputs are NULL. The WHERE clause restriction on the null-supplying table compares values to null, resulting in the elimination of the row from the result set. The rows in the preserved table are not preserved and so the join is an inner join.

The exception to this is comparisons that can evaluate to true when any of their inputs are NULL. These include IS NULL, IS UNKNOWN, IS FALSE, IS NOT TRUE, and expressions involving ISNULL or COALESCE.

Example

For example, the following statement computes a left outer join.

SELECT *
FROM customer KEY LEFT OUTER JOIN sales_order
   ON sales_order.order_date < '2000-01-03'

In contrast, the following statement creates an inner join.

SELECT lname, order_date
FROM customer KEY LEFT OUTER JOIN sales_order
   WHERE sales_order.order_date < '2000-01-03'

The first of these two statements can be thought of as follows: First, left-outer join the customer table to the sales_order table. The result set includes every row in the customer table. For those customers who have no orders prior to January 3 2000, fill the sales order fields with nulls.

In the second statement, first left-outer join customer and sales_order. The result set includes every row in the customer table. For those customers who have no orders, fill the sales order fields with nulls. Next, apply the WHERE condition by selecting only those rows in which the customer has placed an order since January 3 2000. For those customers who have not placed orders, these values are NULL. Comparing any value to NULL evaluates to UNKNOWN. Hence, these rows are eliminated and the statement reduces to an inner join.

For more information about search conditions, see Search conditions.


Understanding complex outer joins

The order of joins is important when a query includes table expressions using outer joins. For example, A JOIN B LEFT OUTER JOIN C is interpreted as (A JOIN B) LEFT OUTER JOIN C. This means that the table expression (A JOIN B) is joined to C. The table expression (A JOIN B) is preserved and table C is null-supplying.

Consider the following statement, in which A, B and C are tables:

SELECT *
FROM A LEFT OUTER JOIN B RIGHT OUTER JOIN C

To understand this statement, first remember that Adaptive Server Anywhere evaluates statements from left to right, adding parentheses. This results in

SELECT *
FROM (A LEFT OUTER JOIN B) RIGHT OUTER JOIN C

Next, you may want to convert the right outer join to a left outer join so that both joins are the same type. To do this, simply reverse the position of the tables in the right outer join, resulting in:

SELECT *
FROM C LEFT OUTER JOIN (A LEFT OUTER JOIN B)

A is the preserved table and B is the null-supplying table for the nested outer join. C is the preserved table for the first outer join.

You can interpret this join as follows:

  • Join A to B, preserving all rows in A.

  • Next, join C to the results of the join of A and B, preserving all rows in C.

The join does not have an ON phrase, and so is by default a key join. The way Adaptive Server Anywhere generates join conditions for this type of join is explained in Key joins of table expressions that do not contain commas .

In addition, the join condition for an outer join must only include tables that have previously been referenced in the FROM clause. This restriction is according to the ANSI/ISO standard, and is enforced to avoid ambiguity. For example, the following two statements are syntactically incorrect, because C is referenced in the join condition before the table itself is referenced.

SELECT *
FROM (A LEFT OUTER JOIN B ON B.x = C.x) JOIN C

and

SELECT *
FROM A LEFT OUTER JOIN B ON A.x = C.x, C


Outer joins of views and derived tables

Outer joins can also be specified for views and derived tables.

The statement

SELECT *
FROM V LEFT OUTER JOIN A ON (V.x = A.x)

can be interpreted as follows:

  • Compute the view V.

  • Join all the rows from the computed view V with A by preserving all the rows from V, using the join condition V.x   =   A.x.

Example

The following example defines a view called V that returns the employee IDs and department names of women who make over $60 000.

CREATE VIEW V AS
SELECT employee.emp_id, dept_name
  FROM employee JOIN department
    ON employee.dept_id = department.dept_id
  WHERE sex = 'F' and salary > 60000

Next, use this view to add a list of the departments where the women work and the regions where they have sold. The view V is preserved and sales_order is null-supplying.

SELECT DISTINCT V.emp_id, region, V.dept_name
  FROM V LEFT OUTER JOIN sales_order
    ON V.emp_id = sales_order.sales_rep
emp_id | region | dept_name
243 | (NULL) | R & D
316 | (NULL) | R & D
529 | (NULL) | R & D
902 | Eastern | Sales
... | ... | ...


Transact-SQL outer joins (*= or =*)

In accordance with ANSI/ISO SQL standards, Adaptive Server Anywhere supports the LEFT OUTER, RIGHT OUTER, and FULL OUTER keywords. For compatibility with Adaptive Server Enterprise prior to version 12, Adaptive Server Anywhere also supports the Transact-SQL counterparts of these keywords, *= and =*. However, there are some limitations and potential problems with the Transact-SQL semantics.

For a detailed discussion of Transact-SQL outer joins, see the whitepaper Semantics and Compatibility of Transact-SQL Outer Joins, which is available at [external link] http://www.ianywhere.com/whitepapers/tsql.html.

Warning: When you are creating outer joins, do not mix *= syntax with ON phrase syntax. This also applies to views that are referenced in the query.

In the Transact-SQL dialect, you create outer joins by supplying a comma-separated list of tables in the FROM clause, and using the special operators *= or =* in the WHERE clause. In Adaptive Server Enterprise prior to version 12, the join condition must appear in the WHERE clause (ON was not supported).

Example

For example, the following left outer join lists all customers and finds their order dates (if any):

SELECT fname, lname, order_date
FROM customer, sales_order
WHERE customer.id *= sales_order.cust_id
ORDER BY order_date

This statement is equivalent to the following statement, in which ANSI/ISO syntax is used:

SELECT fname, lname, order_date
FROM customer LEFT OUTER JOIN sales_order
ON customer.id = sales_order.cust_id
ORDER BY order_date


Transact-SQL outer join limitations

There are several restrictions for Transact-SQL outer joins:

  • If you specify an outer join and a qualification on a column from the null-supplying table of the outer join, the results may not be what you expect. The qualification in the query does not exclude rows from the result set, but rather affects the values that appear in the rows of the result set. For rows that do not meet the qualification, a null value appears in the null-supplying table.

  • You cannot mix ANSI/ISO SQL syntax and Transact-SQL outer join syntax in a single query. If a view is defined using one dialect for an outer join, you must use the same dialect for any outer-join queries on that view.

  • A null-supplying table cannot participate in both a Transact-SQL outer join and a regular join or two outer joins. For example, the following WHERE clause is not allowed, because table S violates this limitation.

    WHERE R.x *= S.x
AND S.y = T.y

    When you cannot rewrite your query to avoid using a table in both an outer join and a regular join clause, you must divide your statement into two separate queries, or use only ANSI/ISO SQL syntax.

  • You cannot use a subquery that contains a join condition involving the null-supplying table of an outer join. For example, the following WHERE clause is not allowed:

    WHERE R.x *= S.y
AND EXISTS ( SELECT *
             FROM T
             WHERE T.x = S.x )


Using views with Transact-SQL outer joins

If you define a view with an outer join, and then query the view with a qualification on a column from the null-supplying table of the outer join, the results may not be what you expect. The query returns all rows from the null-supplying table. Rows that do not meet the qualification show a NULL value in the appropriate columns of those rows.

The following rules determine what types of updates you can make to columns through views that contain outer joins:

  • INSERT and DELETE statements are not allowed on outer join views.

  • UPDATE statements are allowed on outer join views. If the view is defined WITH CHECK option, the update fails if any of the affected columns appears in the WHERE clause in an expression that includes columns from more than one table.


How NULL affects Transact-SQL joins

NULL values in tables or views being joined never match each other in a Transact-SQL outer join. The result of comparing a NULL value with any other NULL value is FALSE.


Specialized joins

This section describes how to create some specialized joins such as self-joins, star joins, and joins using derived tables.


Self-joins

In a self-join, a table is joined to itself by referring to the same table using a different correlation name.

Example 1

The following self-join produces a list of pairs of employees. Each employee name appears in combination with every employee name.

SELECT a.emp_fname, a.emp_lname,
      b.emp_fname, b.emp_lname
FROM employee AS a CROSS JOIN employee AS b
emp_fname | emp_lname | emp_fname | emp_lname
Fran | Whitney | Fran | Whitney
Fran | Whitney | Matthew | Cobb
Fran | Whitney | Philip | Chin
Fran | Whitney | Julie | Jordan
... | ... | ... | ...

Since the employee table has 75 rows, this join contains 75 x 75 = 5 625 rows. It includes, as well, rows that list each employee with themselves. For example, it contains the row

emp_fname | emp_lname | emp_fname | emp_lname
Fran | Whitney | Fran | Whitney

If you want to exclude rows that contain the same name twice, add the join condition that the employee IDs should not be equal to each other.

SELECT a.emp_fname, a.emp_lname,
      b.emp_fname, b.emp_lname
FROM employee AS a CROSS JOIN employee AS b
WHERE a.emp_id != b.emp_id

Without these duplicate rows, the join contains 75 x 74 = 5 550 rows.

This new join contains rows that pair each employee with every other employee, but because each pair of names can appear in two possible orders, each pair appears twice. For example, the result of the above join contains the following two rows.

emp_fname | emp_lname | emp_fname | emp_lname
Matthew | Cobb | Fran | Whitney
Fran | Whitney | Matthew | Cobb

If the order of the names is not important, you can produce a list of the (75 x 74)/2 = 2 775 unique pairs.

SELECT a.emp_fname, a.emp_lname,
      b.emp_fname, b.emp_lname
FROM employee AS a CROSS JOIN employee AS b
WHERE a.emp_id < b.emp_id

This statement eliminates duplicate lines by selecting only those rows in which the emp_id of employee a is less than that of employee b.

Example 2

The following self-join uses the correlation names report and manager to distinguish two instances of the employee table, and creates a list of employees and their managers.

SELECT report.emp_fname, report.emp_lname,
   manager.emp_fname, manager.emp_lname
FROM employee AS report JOIN employee AS manager
   ON (report.manager_id = manager.emp_id)
ORDER BY report.emp_lname, report.emp_fname

This statement produces the result shown partially below. The employee names appear in the two left-hand columns, and the names of their managers are on the right.

emp_fname | emp_lname | emp_fname | emp_lname
Alex | Ahmed | Scott | Evans
Joseph | Barker | Jose | Martinez
Irene | Barletta | Scott | Evans
Jeannette | Bertrand | Jose | Martinez
... | ... | ... | ...


Duplicate correlation names in joins (star joins)

The reason for using duplicate table names is to create a star join. In a star join, one table or view is joined to several others.

To create a star join, you use the same table name, view name, or correlation name more than once in the FROM clause. This is an extension to the ANSI/ISO SQL standard. The ability to use duplicate names does not add any additional functionality, but it makes it much easier to formulate certain queries.

The duplicate names must be in different joins for the syntax to make sense. When a table name or view name is used twice in the same join, the second instance is ignored. For example, FROM A,A and FROM A CROSS JOIN A are both interpreted as FROM A.

The following example, in which A, B and C are tables, is valid in Adaptive Server Anywhere. In this example, the same instance of table A is joined both to B and C. Note that a comma is required to separate the joins in a star join. The use of a comma in star joins is specific to the syntax of star joins.

SELECT *
FROM A LEFT OUTER JOIN B ON A.x = B.x,
     A LEFT OUTER JOIN C ON A.y = C.y

The next example is equivalent.

SELECT *
FROM A LEFT OUTER JOIN B ON A.x = B.x,
     C RIGHT OUTER JOIN A ON A.y = C.y

Both of these are equivalent to the following standard ANSI/ISO syntax. (The parentheses are optional.)

SELECT *
FROM (A LEFT OUTER JOIN B ON A.x = B.x)
LEFT OUTER JOIN C ON A.y = C.y

In the next example, table A is joined to three tables: B, C and D.

SELECT *
FROM A JOIN B ON A.x = B.x,
     A JOIN C ON A.y = C.y,
     A JOIN D ON A.w = D.w

This is equivalent to the following standard ANSI/ISO syntax. (The parentheses are optional.)

SELECT *
FROM ((A JOIN B ON A.x = B.x)
JOIN C ON A.y = C.y)
JOIN D ON A.w = D.w

With complex joins, it can help to draw a diagram. The previous example can be described by the following diagram, which illustrates that tables B, C and D are joined via table A.

Table A is in the center, with B, C, and D each connecting to it.

Note You can use duplicate table names only if the EXTENDED_JOIN_SYNTAX option is ON (the default).

For more information, see the EXTENDED_JOIN_SYNTAX option [database].

Example 1

Create a list of the names of the customers who have placed orders with Rollin Overbey. Notice that one of the tables in the FROM clause, employee, does not contribute any columns to the results. Nor do any of the columns that are joined—such as customer.id or employee.id—appear in the results. Nonetheless, this join is possible only using the employee table in the FROM clause.

SELECT customer.fname, customer.lname,
    sales_order.order_date
FROM    sales_order KEY JOIN customer,
      sales_order KEY JOIN employee
WHERE employee.emp_fname = 'Rollin'
  AND employee.emp_lname = 'Overbey'
ORDER BY sales_order.order_date
fname | lname | order_date
Tommie | Wooten | 1/3/00
Michael | Agliori | 1/8/00
Salton | Pepper | 1/17/00
Tommie | Wooten | 1/23/00
... | ... | ...

Following is the equivalent statement in standard ANSI/ISO syntax:

SELECT customer.fname, customer.lname,
  sales_order.order_date
FROM sales_order JOIN customer
  ON sales_order.cust_id = customer.id
JOIN employee
  ON sales_order.sales_rep = employee.emp_id
WHERE employee.emp_fname = 'Rollin'
  AND employee.emp_lname = 'Overbey'
ORDER BY sales_order.order_date
Example 2

This example answers the question: How much of each product has each customer ordered, and who is the manager of the salesperson who took the order?

To answer the question, start by listing the information you need to retrieve. In this case, it is product, quantity, customer name, and manager name. Next, list the tables that hold this information. They are product, sales_order_items, customer, and employee. When you look at the structure of the sample database (see Sample database schema), you will notice that these tables are all related through the sales_order table. You can create a star join on the sales_order table to retrieve the information from the other tables.

In addition, you need to create a self-join in order to get the name of the manager, because the employee table contains ID numbers for managers and the names of all employees, but not a column listing only manager names. For more information, see Self-joins.

The following statement creates a star join around the sales_order table. The joins are all outer joins so that the result set will include all customers. Some customers have not placed orders, so the other values for these customers are NULL. The columns in the result set are customer, product, quantity ordered, and the name of the manager of the salesperson.

SELECT customer.fname, product.name,
  SUM(sales_order_items.quantity), m.emp_fname
FROM   sales_order
         KEY RIGHT OUTER JOIN customer,
       sales_order
         KEY LEFT OUTER JOIN sales_order_items
         KEY LEFT OUTER JOIN product,
      sales_order
         KEY LEFT OUTER JOIN employee AS e
         LEFT OUTER JOIN employee AS m
         ON (e.manager_id = m.emp_id)
WHERE customer.state = 'CA'
GROUP BY customer.fname, product.name, m.emp_fname
ORDER BY SUM(sales_order_items.quantity) DESC, customer.fname
fname | name | SUM(sales_order_items.quantity) | emp_fname
Sheng | Baseball Cap | 240 | Moira
Laura | Tee Shirt | 192 | Moira
Moe | Tee Shirt | 192 | Moira
Leilani | Sweatshirt | 132 | Moira
... | ... | ... | ...

Following is a diagram of the tables in this star join. The arrows indicate the directionality (left or right) of the outer joins. As you can see, the complete list of customers is maintained throughout all the joins.

The following standard ANSI/ISO syntax is equivalent to the star join in Example 2.

SELECT customer.fname, product.name,
  SUM(sales_order_items.quantity), m.emp_fname
FROM sales_order LEFT OUTER JOIN sales_order_items
    ON sales_order.id = sales_order_items.id
  LEFT OUTER JOIN product
    ON sales_order_items.prod_id = product.id
  LEFT OUTER JOIN employee as e
    ON sales_order.sales_rep = e.emp_id
  LEFT OUTER JOIN employee as m
    ON e.manager_id = m.emp_id
  RIGHT OUTER JOIN customer
    ON sales_order.cust_id = customer.id
WHERE customer.state = 'CA'
GROUP BY customer.fname, product.name, m.emp_fname
ORDER BY SUM(sales_order_items.quantity) DESC, customer.fname


Joins involving derived tables

Derived tables allow you to nest queries within a FROM clause. With derived tables, you can perform grouping of groups, or you can construct a join with a group, without having to create a view.

In the following example, the inner SELECT statement (enclosed in parentheses) creates a derived table, grouped by customer id values. The outer SELECT statement assigns this table the correlation name sales_order_counts and joins it to the customer table using a join condition.

SELECT lname, fname, number_of_orders
FROM customer JOIN
   (   SELECT cust_id, count(*)
      FROM sales_order
      GROUP BY cust_id   )
   AS sales_order_counts (cust_id, number_of_orders)
   ON (customer.id = sales_order_counts.cust_id)
WHERE number_of_orders > 3

The result is a table of the names of those customers who have placed more than three orders, including the number of orders each has placed.

For an explanation of key joins of derived tables, see Key joins of views and derived tables.

For an explanation of natural joins of derived tables, see Natural joins of views and derived tables.

For an explanation of outer joins of derived tables, see Outer joins of views and derived tables.


Natural joins

When you specify a natural join, Adaptive Server Anywhere generates a join condition based on columns with the same name. For this to work in a natural join of base tables, there must be at least one pair of columns with the same name, with one column from each table. If there is no common column name, an error is issued.

If table A and table B have one column name in common, and that column is called x, then

SELECT *
FROM A NATURAL JOIN B

is equivalent to the following:

SELECT *
FROM A JOIN B
 ON A.x = B.x

If table A and table B have two column names in common, and they are called a and b, then A NATURAL JOIN B is equivalent to the following:

A JOIN B
 ON A.a = B.a
 AND A.b = B.b
Example

For example, you can join the employee and department tables using a natural join because they have a column name in common, the dept_id column.

SELECT emp_fname, emp_lname, dept_name
FROM employee NATURAL JOIN department
ORDER BY dept_name, emp_lname, emp_fname
emp_fname | emp_lname | dept_name
Janet | Bigelow | Finance
Kristen | Coe | Finance
James | Coleman | Finance
Jo Ann | Davidson | Finance
... | ... | ...

The following statement is equivalent. It explicitly specifies the join condition that was generated in the previous example.

SELECT emp_fname, emp_lname, dept_name
FROM employee JOIN department
  ON (employee.dept_id = department.dept_id)
ORDER BY dept_name, emp_lname, emp_fname


Natural joins with an ON phrase

When you specify a NATURAL JOIN and put a join condition in an ON phrase, the result is the conjunction of the two join conditions.

For example, the following two queries are equivalent. In the first query, Adaptive Server Anywhere generates the join condition employee.dept_id   =   department.dept_id. The query also contains an explicit join condition.

SELECT emp_fname, emp_lname, dept_name
FROM employee NATURAL JOIN department
  ON employee.manager_id = department.dept_head_id

The next query is equivalent. In it, the natural join condition that was generated in the previous query is specified in the ON phrase.

SELECT emp_fname, emp_lname, dept_name
FROM employee JOIN department
  ON employee.manager_id = department.dept_head_id
   AND employee.dept_id = department.dept_id


Natural joins of table expressions

When there is a multiple-table expression on at least one side of a natural join, Adaptive Server Anywhere generates a join condition by comparing the set of columns for each side of the join operator, and looking for columns that have the same name.

For example, in the statement

SELECT *
FROM (A JOIN B) NATURAL JOIN (C JOIN D)

there are two table expressions. The column names in the table expression A JOIN B are compared to the column names in the table expression C JOIN D, and a join condition is generated for each unambiguous pair of matching column names. An unambiguous pair of matching columns means that the column name occurs in both table expressions, but does not occur twice in the same table expression.

If there is a pair of ambiguous column names, an error is issued. However, a column name may occur twice in the same table expression, as long as it doesn't also match the name of a column in the other table expression.

Natural joins of lists

When a list of table expressions is on at least one side of a natural join, a separate join condition is generated for each table expression in the list.

Consider the following tables:

  • table A consists of columns called a, b and c

  • table B consists of columns called a and d

  • table C consists of columns called d and c

In this case, the join (A,B) NATURAL JOIN C causes Adaptive Server Anywhere to generate two join conditions:

ON A.c = C.c
 AND B.d = C.d

If there is no common column name for A-C or B-C, an error is issued.

If table C consists of columns a, d, and c, then the join (A,B) NATURAL JOIN C is invalid. The reason is that column a appears in all three tables, and so the join is ambiguous.

Example

The following example answers the question: for each sale, provide information about what was sold and who sold it.

SELECT *
FROM (employee KEY JOIN sales_order)
  NATURAL JOIN (sales_order_items KEY JOIN product)

This is equivalent to

SELECT *
FROM (employee KEY JOIN sales_order)
  JOIN (sales_order_items KEY JOIN product)
    ON sales_order.id = sales_order_items.id


Natural joins of views and derived tables

An extension to the ANSI/ISO SQL standard is that you can specify views or derived tables on either side of a natural join. In the following statement,

SELECT *
FROM View1 NATURAL JOIN View2

the columns in View1 are compared to the columns in View2. If, for example, a column called emp_id is found to occur in both views, and there are no other columns that have identical names, then the generated join condition is (View1.emp_id   =   View2.emp_id).

Example

The following example illustrates that a view used in a natural join can include expressions, and not just columns, and they are treated the same way in the natural join. First, create the view V with a column called x, as follows:

CREATE VIEW V(x) AS
SELECT R.y + 1
FROM R

Next, create a natural join of the view to a derived table. The derived table has a correlation name T with a column called x.

SELECT *
FROM V NATURAL JOIN (SELECT P.y FROM P) as T(x)

This join is equivalent to the following:

SELECT *
FROM V JOIN (SELECT P.y FROM P) as T(x) ON (V.x = T.x)


Key joins

When you specify a key join, Adaptive Server Anywhere generates a join condition based on the foreign key relationships in the database. To use a key join, there must be a foreign key relationship between the tables, or an error is issued.

The key join is a Sybase extension to the ANSI/ISO SQL standard. It does not provide any greater functionality, but it makes it easier to formulate certain queries.

When key join is the default

Key join is the default in Adaptive Server Anywhere when all of the following apply:

  • the keyword JOIN is used.

  • the keywords CROSS, NATURAL or KEY are not specified.

  • there is no ON phrase.

Example

For example, the following query is a simple key join that joins the tables product and sales_order_items based on the foreign key relationship in the database.

SELECT *
FROM product KEY JOIN sales_order_items

The next query is equivalent. It leaves out the word KEY, but by default a JOIN without an ON phrase is a KEY JOIN.

SELECT *
FROM product JOIN sales_order_items

The next query is also equivalent, because the join condition specified in the ON phrase happens to be the same as the join condition that Adaptive Server Anywhere generates for these tables based on their foreign key relationship in the sample database.

SELECT *
FROM product JOIN sales_order_items
ON sales_order_items.prod_id = product.id

Key joins with an ON phrase
Key joins when there are multiple foreign key relationships
Key joins of table expressions
Key joins of views and derived tables
Rules describing the operation of key joins


Key joins with an ON phrase

When you specify a KEY JOIN and put a join condition in an ON phrase, the result is the conjunction of the two join conditions. For example,

SELECT *
FROM A KEY JOIN B
ON A.x = B.y

If the join condition generated by the key join of A and B is A.w   =   B.z, then this query is equivalent to

SELECT *
FROM A JOIN B
ON A.x = B.y AND A.w = B.z


Key joins when there are multiple foreign key relationships

When Adaptive Server Anywhere attempts to generate a join condition based on a foreign key relationship, it sometimes finds more than one relationship. In these cases, Adaptive Server Anywhere determines which foreign key relationship to use by matching the role name of the foreign key to the correlation name of the primary key table that the foreign key references.

The following sections describe how Adaptive Server Anywhere generates join conditions for key joins. This information is summarized in Rules describing the operation of key joins.

Correlation name and role name

A correlation name is the name of a table or view that is used in the FROM clause of the query—either its original name, or an alias that is defined in the FROM clause.

A role name is the name of the foreign key. It must be unique for a given foreign (child) table.

If you do not specify a role name for a foreign key, the name is assigned as follows:

  • If there is no foreign key with the same name as the primary table name, the primary table name is assigned as the role name.

  • If the primary table name is already being used by another foreign key, the role name is the primary table name concatenated with a zero-padded three-digit number unique to the foreign table.

If you don't know the role name of a foreign key, you can find it in Sybase Central by expanding the database container in the left pane. Select the table in left pane, and then click the Foreign Keys tab in the right pane. A list of foreign keys for that table appears in the right pane.

See Sample database schema for a diagram that includes the role names of all foreign keys in the sample database.

Generating join conditions

Adaptive Server Anywhere looks for a foreign key that has the same role name as the correlation name of the primary key table:

  • If there is exactly one foreign key with the same name as a table in the join, Adaptive Server Anywhere uses it to generate the join condition.

  • If there is more than one foreign key with the same name as a table, the join is ambiguous and an error is issued.

  • If there is no foreign key with the same name as the table, Adaptive Server Anywhere looks for any foreign key relationship, even if the names don't match. If there is more than one foreign key relationship, the join is ambiguous and an error is issued.

Example 1

In the sample database, two foreign key relationships are defined between the tables employee and department: the foreign key ky_dept_id in the employee table references the department table; and the foreign key ky_dept_head in the department table references the employee table.

The employee table and department table, showing their foreign key relationships.

The following query is ambiguous because there are two foreign key relationships and neither has the same role name as the primary key table name. Therefore, attempting this query results in the syntax error SQLE_AMBIGUOUS_JOIN (-147).

SELECT employee.emp_lname, department.dept_name
FROM employee KEY JOIN department
Example 2

This query modifies the query in Example 1 by specifying the correlation name ky_dept_id for the department table. Now, the foreign key ky_dept_id has the same name as the table it references, and so it is used to define the join condition. The result includes all the employee last names and the departments where they work.

SELECT employee.emp_lname, ky_dept_id.dept_name
FROM employee KEY JOIN department AS ky_dept_id

The following query is equivalent. It is not necessary to create an alias for the department table in this example. The same join condition that was generated above is specified in the ON phrase in this query:

SELECT employee.emp_lname, department.dept_name
FROM employee JOIN department
   ON department.dept_id = employee.dept_id
Example 3

If the intent was to list all the employees that are the head of a department, then the foreign key ky_dept_head should be used and Example 1 should be rewritten as follows. This query imposes the use of the foreign key ky_dept_head by specifying the correlation name ky_dept_head for the primary key table employee.

SELECT ky_dept_head.emp_lname, department.dept_name
FROM employee AS ky_dept_head KEY JOIN department

The following query is equivalent. The join condition that was generated above is specified in the ON phrase in this query:

SELECT employee.emp_lname, department.dept_name
FROM employee JOIN department
   ON department.dept_head_id = employee.emp_id
Example 4

A correlation name is not needed if the foreign key role name is identical to the primary key table name. For example, we can define the foreign key department for the employee table:

ALTER TABLE employee ADD FOREIGN KEY department (dept_id) REFERENCES department (dept_id)

Now, this foreign key relationship is the default join condition when a KEY JOIN is specified between the two tables. If the foreign key department is defined, then the following query is equivalent to Example 3.

SELECT employee.emp_lname, department.dept_name
FROM employee KEY JOIN department
Note

If you try this example in Interactive SQL, you should reverse the change to the sample database with the following statement:

ALTER TABLE employee DROP FOREIGN KEY department


Key joins of table expressions

Adaptive Server Anywhere generates join conditions for the key join of table expressions by examining the foreign key relationship of each pair of tables in the statement.

The following example joins four pairs of tables.

SELECT *
FROM (A NATURAL JOIN B) KEY JOIN (C NATURAL JOIN D)

The table-pairs are A-C, A-D, B-C and B-D. Adaptive Server Anywhere considers the relationship within each pair and then creates a generated join condition for the table expression as a whole. How Adaptive Server Anywhere does this depends on whether the table expressions use commas or not. Therefore, the generated join conditions in the following two examples are different. A JOIN B is a table expression that does not contain commas, and (A,B) is a table expression list.

SELECT *
FROM (A JOIN B) KEY JOIN C

is semantically different from

SELECT *
FROM (A,B) KEY JOIN C

The two types of join behavior are explained in the following sections:

  • Key joins of table expressions that do not contain commas

  • Key joins of table expression lists

Key joins of table expressions that do not contain commas
Key joins of table expression lists
Key joins of lists and table expressions that do not contain commas


Key joins of table expressions that do not contain commas

When both of the two table expressions being joined do not contain commas, Adaptive Server Anywhere examines the foreign key relationships in the pairs of tables in the statement, and generates a single join condition.

For example, the following join has two table-pairs, A-C and B-C.

(A NATURAL JOIN B) KEY JOIN C

Adaptive Server Anywhere generates a single join condition for joining C with (A NATURAL JOIN B) by looking at the foreign key relationships within the table-pairs A-C and B-C. It generates one join condition for the two pairs according to the rules for determining key joins when there are multiple foreign key relationships:

  • First, it looks at both A-C and B-C for a single foreign key that has the same role name as the correlation name of one of the primary key tables it references. If there is exactly one foreign key meeting this criterion, it uses it. If there is more than one foreign key with the same role name as the correlation name of a table, the join is considered to be ambiguous and an error is issued.

  • If there is no foreign key with the same name as the correlation name of a table, Adaptive Server Anywhere looks for any foreign key relationship between the tables. If there is one, it uses it. If there is more than one, the join is considered to be ambiguous and an error is issued.

  • If there is no foreign key relationship, an error is issued.

For more information, see Key joins when there are multiple foreign key relationships.

Example

The following query finds all the employees who are sales representatives, and their departments.

SELECT employee.emp_lname, ky_dept_id.dept_name
FROM (employee KEY JOIN department as ky_dept_id)
  KEY JOIN sales_order

You can interpret this query as follows.

  • Adaptive Server Anywhere considers the table expression (employee KEY JOIN department as ky_dept_id) and generates the join condition employee.dept_id   =   ky_dept_id.dept_id based on the foreign key ky_dept_id.

  • Adaptive Server Anywhere then considers the table-pairs employee-sales_order and ky_dept_id-sales_order. Note that only one foreign key can exist between the tables sales_order and employee and between sales_order and ky_dept_id, or the join is ambiguous. As it happens, there is exactly one foreign key relationship between the tables sales_order and employee (ky_so_employee_id), and no foreign key relationship between sales_order and ky_dept_id. Hence, the generated join condition is sales_order.emp_id   =   employee.sales_rep.

The following query is therefore equivalent to the previous query:

SELECT employee.emp_lname, department.dept_name
FROM (employee JOIN department
   ON ( employee.dept_id = department.dept_id ) )
JOIN sales_order
   ON (employee.emp_id = sales_order.sales_rep)


Key joins of table expression lists

To generate a join condition for the key join of two table expression lists, Adaptive Server Anywhere examines the pairs of tables in the statement, and generates a join condition for each pair. The final join condition is the conjunction of the join conditions for each pair. There must be a foreign key relationship between each pair.

The following example joins two table-pairs, A-C and B-C.

SELECT *
FROM (A,B) KEY JOIN C

Adaptive Server Anywhere generates a join condition for joining C with (A,B) by generating a join condition for each of the two pairs A-C and B-C. It does so according to the rules for key joins when there are multiple foreign key relationships:

  • For each pair, Adaptive Server Anywhere looks for a foreign key that has the same role name as the correlation name of the primary key table. If there is exactly one foreign key meeting this criterion, it uses it. If there is more than one, the join is considered to be ambiguous and an error is issued.

  • For each pair, if there is no foreign key with the same name as the correlation name of the table, Adaptive Server Anywhere looks for any foreign key relationship between the tables. If there is one, it uses it. If there is more than one, the join is considered to be ambiguous and an error is issued.

  • For each pair, if there is no foreign key relationship, an error is issued.

  • If Adaptive Server Anywhere is able to determine exactly one join condition for each pair, it combines the join conditions using AND.

For more information, see Key joins when there are multiple foreign key relationships.

Example

The following query returns the names of all salespeople who have sold at least one order to a specific region.

SELECT DISTINCT employee.emp_lname,
  ky_dept_id.dept_name, sales_order.region
FROM (sales_order, department AS ky_dept_id)
   KEY JOIN employee
emp_lname | dept_name | region
Chin | Sales | Eastern
Chin | Sales | Western
Chin | Sales | Central
... | ... | ...

This query deals with two pairs of tables: sales_order and employee; and department AS ky_dept_id and employee.

For the pair sales_order and employee, there is no foreign key with the same role name as one of the tables. However, there is a foreign key (ky_so_employee_id) relating the two tables. It is the only foreign key relating the two tables, and so it is used, resulting in the generated join condition (employee.emp_id   =   sales_order.sales_rep).

For the pair department AS ky_dept_id and employee, there is one foreign key that has the same role name as the primary key table. It is ky_dept_id, and it matches the correlation name given to the department table in the query. There are no other foreign keys with the same name as the correlation name of the primary key table, so ky_dept_id is used to form the join condition for the table-pair. The join condition that is generated is (employee.dept_id   =   ky_dept_id.dept_id). Note that there is another foreign key relating the two tables, but as it has a different name from either of the tables, it is not a factor.

The final join condition adds together the join condition generated for each table-pair. Therefore, the following query is equivalent:

SELECT DISTINCT employee.emp_lname, department.dept_name, sales_order.region
FROM ( sales_order, department )
   JOIN employee
   ON employee.emp_id = sales_order.sales_rep
   AND employee.dept_id = department.dept_id


Key joins of lists and table expressions that do not contain commas

When table expression lists are joined via key join with table expressions that do not contain commas, Adaptive Server Anywhere generates a join condition for each table in the table expression list.

For example, the following statement is the key join of a table expression list with a table expression that does not contain commas. This example generates a join condition for table A with table expression C NATURAL JOIN D, and for table B with table expression C NATURAL JOIN D.

SELECT *
FROM (A,B) KEY JOIN (C NATURAL JOIN D)

(A,B) is a list of table expressions and C NATURAL JOIN D is a table expression. Adaptive Server Anywhere must therefore generate two join conditions: it generates one join condition for the pairs A-C and A-D, and a second join condition for the pairs B-C and B-D. It does so according to the rules for key joins when there are multiple foreign key relationships:

  • For each set of table-pairs, Adaptive Server Anywhere looks for a foreign key that has the same role name as the correlation name of one of the primary key tables. If there is exactly one foreign key meeting this criterion, it uses it. If there is more than one, the join is ambiguous and an error is issued.

  • For each set of table-pairs, if there is no foreign key with the same name as the correlation name of a table, Adaptive Server Anywhere looks for any foreign key relationship between the tables. If there is exactly one relationship, it uses it. If there is more than one, the join is ambiguous and an error is issued.

  • For each set of pairs, if there is no foreign key relationship, an error is issued.

  • If Adaptive Server Anywhere is able to determine exactly one join condition for each set of pairs, it combines the join conditions with the keyword AND.

Example 1

Consider the following join of five tables:

((A,B) JOIN (C NATURAL JOIN D) ON A.x = D.y) KEY JOIN E

In this case, Adaptive Server Anywhere generates a join condition for the key join to E by generating a condition either between (A,B) and E or between C NATURAL JOIN D and E. This is as described in Key joins of table expressions that do not contain commas .

If Adaptive Server Anywhere generates a join condition between (A,B) and E, it needs to create two join conditions, one for A-E and one for B-E. It must find a valid foreign key relationship within each table-pair. This is as described in Key joins of table expression lists.

If Adaptive Server Anywhere creates a join condition between C NATURAL JOIN D and E, it creates only one join condition, and so must find only one foreign key relationship in the pairs C-E and D-E. This is as described in Key joins of table expressions that do not contain commas .

Example 2

The following is an example of a key join of a table expression and a list of table expressions. The example provides the name and department of employees who are sales representatives and also managers.

SELECT DISTINCT employee.emp_lname, ky_dept_id.dept_name
FROM (sales_order, department AS ky_dept_id)
  KEY JOIN (employee JOIN department AS d
    ON employee.emp_id = d.dept_head_id)

Adaptive Server Anywhere generates two join conditions:

  • There must be exactly one foreign key relationship between the table-pairs sales_order-employee and sales_order-d. There is; it is sales_order.sales_rep = employee.emp_id.

  • There must be exactly one foreign key relationship between the table-pairs ky_dept_id-employee and ky_dept_id-d. There is; it is ky_dept_id.dept_id = employee.dept_id.

This example is equivalent to the following. In the following version, it is not necessary to create the correlation name department AS ky_dept_id, because that was only needed to clarify which of two foreign keys should be used to join employee and department.

SELECT DISTINCT employee.emp_lname, department.dept_name
FROM (sales_order, department)
  JOIN (employee JOIN department AS d
      ON employee.emp_id = d.dept_head_id)
    ON sales_order.sales_rep = employee.emp_id
      AND department.dept_id = employee.dept_id


Key joins of views and derived tables

When you include a view or derived table in a key join, Adaptive Server Anywhere follows the same basic procedure as with tables, but with these differences:

  • For each key join, Adaptive Server Anywhere considers the pairs of tables in the FROM clause of the query and the view, and generates one join condition for the set of all pairs, regardless of whether the FROM clause in the view contains commas or join keywords.

  • Adaptive Server Anywhere joins the tables based on the foreign key that has the same role name as the correlation name of the view or derived table.

  • When you include a view or derived table in a key join, the view cannot contain UNION, ORDER BY, DISTINCT, GROUP BY, or an aggregate function. If it contains any of those items, an error is issued.

A derived table works identically to a view. The only difference is that instead of referencing a predefined view, the definition for the table is included in the statement.

Example 1

For example, in the following statement, View1 is a view.

SELECT *
FROM View1 KEY JOIN B

The definition of View1 can be any of the following and result in the same join condition to B. (The result set will differ, but the join conditions will be identical.)

SELECT *
FROM C CROSS JOIN D

or

SELECT *
FROM C,D

or

SELECT *
FROM C JOIN D ON (C.x = D.y)

In each case, to generate a join condition for the key join of View1 and B, Adaptive Server Anywhere considers the table-pairs C-B and D-B, and generates a single join condition. It generates the join condition based on the rules for multiple foreign key relationships described in Key joins of table expressions, except that it looks for a foreign key with the same name as the correlation name of the view (rather than a table referenced in the view).

Using any of the view definitions above, you can interpret the processing of View1 KEY JOIN B as follows:

Adaptive Server Anywhere generates a single join condition by considering the table-pairs C-B and D-B. It generates the join condition according to the rules for determining key joins when there are multiple foreign key relationships:

  • First, it looks at both C-B and D-B for a single foreign key that has the same role name as the correlation name of the view. If there is exactly one foreign key meeting this criterion, it uses it. If there is more than one foreign key with the same role name as the correlation name of the view, the join is considered to be ambiguous and an error is issued.

  • If there is no foreign key with the same name as the correlation name of the view, Adaptive Server Anywhere looks for any foreign key relationship between the tables. If there is one, it uses it. If there is more than one, the join is considered to be ambiguous and an error is issued.

  • If there is no foreign key relationship, an error is issued.

Assume this generated join condition is B.y   =   D.z. We can now expand the original join.

SELECT *
FROM View1 KEY JOIN B

is equivalent to

SELECT *
FROM View1 JOIN B ON B.y = View1.z

For more information, see Key joins when there are multiple foreign key relationships.

Example 2

The following view contains all the employee information about the manager of each department.

CREATE VIEW V AS
SELECT department.dept_name, employee.*
FROM employee JOIN department
  ON employee.emp_id = department.dept_head_id

The following query joins the view to a table expression.

SELECT *
FROM V KEY JOIN (sales_order, department ky_dept_id)

This is equivalent to

SELECT *
FROM V JOIN (sales_order, department ky_dept_id)
ON (V.emp_id = sales_order.sales_rep
AND V.dept_id = ky_dept_id.dept_id)


Rules describing the operation of key joins

The following rules summarize the information provided above.

Rule 1: key join of two tables

This rule applies to A KEY JOIN B, where A and B are base or temporary tables.

  1. Find all foreign keys from A referencing B.

    If there exists a foreign key whose role name is the correlation name of table B, then mark it as a preferred foreign key.

  2. Find all foreign keys from B referencing A.

    If there exists a foreign key whose role name is the correlation name of table A, then mark it as a preferred foreign key.

  3. If there is more than one preferred key, the join is ambiguous. The syntax error SQLE_AMBIGUOUS_JOIN (-147) is issued.

  4. If there is a single preferred key, then this foreign key is chosen to define the generated join condition for this KEY JOIN expression.

  5. If there is no preferred key, then other foreign keys between A and B are used:

    • If there is more than one foreign key between A and B, then the join is ambiguous. The syntax error SQLE_AMBIGUOUS_JOIN (-147) is issued.

    • If there is a single foreign key, then this foreign key is chosen to define the generated join condition for this KEY JOIN expression.

    • If there is no foreign key, then the join is invalid and an error is generated.

Rule 2: key join of table expressions that do not contain commas

This rule applies to A KEY JOIN B, where A and B are table expressions that do not contain commas.

  1. For each pair of tables; one from expression A and one from expression B, list all foreign keys, and mark all preferred foreign keys between the tables. The rule for determining a preferred foreign key is given in Rule 1, above.

  2. If there is more than one preferred key, then the join is ambiguous. The syntax error SQLE_AMBIGUOUS_JOIN (-147) is issued.

  3. If there is a single preferred key, then this foreign key is chosen to define the generated join condition for this KEY JOIN expression.

  4. If there is no preferred key, then other foreign keys between pairs of tables are used:

    • If there is more than one foreign key, then the join is ambiguous. The syntax error SQLE_AMBIGUOUS_JOIN (-147) is issued.

    • If there is a single foreign key, then this foreign key is chosen to define the generated join condition for this KEY JOIN expression.

    • If there is no foreign key, then the join is invalid and an error is generated.

Rule 3: key join of table expression lists

This rule applies to (A1, A2, ...) KEY JOIN ( B1, B2, ...) where A1, B1, and so on are table expressions that do not contain commas.

  1. For each pair of table expressions Ai and Bj, find a unique generated join condition for the table expression (Ai KEY JOIN Bj) by applying Rule 1 or 2. If any KEY JOIN for a pair of table expressions is ambiguous by Rule 1 or 2, a syntax error is generated.

  2. The generated join condition for this KEY JOIN expression is the conjunction of the join conditions found in step 1.

Rule 4: key join of lists and table expressions that do not contain commas

This rule applies to (A1, A2, ...) KEY JOIN ( B1, B2, ...) where A1, B1, and so on are table expressions that may contain commas.

  1. For each pair of table expressions Ai and Bj, find a unique generated join condition for the table expression (Ai KEY JOIN Bj) by applying Rule 1, 2, or 3. If any KEY JOIN for a pair of table expressions is ambiguous by Rule 1, 2, or 3, then a syntax error is generated.

  2. The generated join condition for this KEY JOIN expression is the conjunction of the join conditions found in step 1.


Common Table Expressions

About this chapter

The WITH prefix to the SELECT statements affords you the opportunity to define common table expressions. These can be used like temporary views within your query. This chapter describes how to use them.

About common table expressions
Typical applications of common table expressions
Recursive common table expressions
Parts explosion problems
Data type declarations in recursive common table expressions
Least distance problem
Using multiple recursive common table expressions


About common table expressions

Common table expressions are temporary views that are known only within the scope of a single SELECT statement. They permit you to write queries more easily, and to write queries that could not otherwise be expressed.

Common table expressions are useful or may be necessary if a query involves multiple aggregate functions or defines a view within a stored procedure that references program variables. Common table expressions also provide a convenient means to temporarily store sets of values.

Recursive common table expressions permit you to query tables that represent hierarchical information, such as reporting relationships within a company. They can also be used to solve parts explosion problems and least distance problems.

For information about recursive queries, see Recursive common table expressions.

For example, consider the problem of determining which department has the most number of employees. The employee table in the sample database lists all the employees in a fictional company and specifies in which department each works. The following query lists the department ID codes and the total number of employees in each department.

SELECT dept_id, count(*) AS n
FROM employee
GROUP BY dept_id

This query can be used to extract the department with the most employees as follows:

SELECT dept_id, n
FROM ( SELECT dept_id, count(*) AS n
       FROM employee GROUP BY dept_id ) AS a
WHERE a.n =
  ( SELECT max(n)
    FROM ( SELECT dept_id, count(*) AS n
           FROM employee GROUP BY dept_id ) AS b )

While this statement provides the correct result, it has some disadvantages. The first disadvantage is that the repeated subquery makes this statement clumsy. The second is that this statement provides no clear link between the subqueries.

One way around these problems is to create a view, then use it to re-express the query. This approach avoids the problems mentioned above.

CREATE VIEW CountEmployees(dept_id, n) AS
    SELECT dept_id, count(*) AS n
    FROM employee GROUP BY dept_id;
SELECT dept_id, n
FROM CountEmployees
WHERE n = ( SELECT max(n)
            FROM CountEmployees );

The disadvantage of this approach is that some overhead is required, as the engine must update the system tables when creating the view. If the view will be used frequently, this approach is reasonable. However, in cases where the view is used only once within a particular SELECT statement, the preferred method is to instead use a common table expression.

Using common table expressions

Common table expressions are defined using the WITH clause, which precedes the SELECT keyword in a SELECT statement. The content of the clause defines one or more temporary views that may then be referenced elsewhere in the statement. The syntax of this clause mimics that of the CREATE VIEW statement. Using common table expressions, you can express the previous query as follows.

WITH CountEmployees(dept_id, n) AS
  ( SELECT dept_id, count(*) AS n
    FROM employee GROUP BY dept_id )
SELECT dept_id, n
FROM CountEmployees
WHERE n = ( SELECT max(n)
            FROM CountEmployees )

Instead searching for the department with the fewest employees demonstrates that such queries may return multiple rows.

WITH CountEmployees(dept_id, n) AS
  ( SELECT dept_id, count(*) AS n
    FROM employee GROUP BY dept_id )
SELECT dept_id, n
FROM CountEmployees
WHERE n = ( SELECT min(n)
            FROM CountEmployees )

In the sample database, two departments share the minimum number of employees, which is 9.

Multiple correlation names

Just as when using tables, you can give different correlation names to multiple instances of a common table expression. Doing so permits you to join a common table expression to itself. For example, the query below produces pairs of departments that have the same number of employees, although there are only two departments with the same number of employees in the sample database.

WITH CountEmployees(dept_id, n) AS
    ( SELECT dept_id, count(*) AS n
      FROM employee GROUP BY dept_id )
SELECT a.dept_id, a.n, b.dept_id, b.n
FROM CountEmployees AS a JOIN CountEmployees AS b
ON a.n = b.n AND a.dept_id < b.dept_id
Multiple table expressions

A single WITH clause may define more than one common table expression. These definitions must be separated by commas. The following example lists the department that has the smallest payroll and the department that has the largest number of employees.

WITH
  CountEmployees(dept_id, n) AS
    ( SELECT dept_id, count(*) AS n
      FROM employee GROUP BY dept_id ),
  DeptPayroll( dept_id, amt ) AS
     ( SELECT dept_id, sum(salary) AS amt
       FROM employee GROUP BY dept_id )
SELECT count.dept_id, count.n, pay.amt
FROM CountEmployees AS count JOIN DeptPayroll AS pay
ON count.dept_id = pay.dept_id
WHERE count.n = ( SELECT max(n) FROM CountEmployees )
   OR pay.amt = ( SELECT min(amt) FROM DeptPayroll )

Where common table expressions are permitted


Where common table expressions are permitted

Common table expression definitions are permitted in only three places, although they may be referenced throughout the body of the query or in any subqueries.

  • Top-level SELECT statement Common table expressions are permitted within top-level SELECT statements, but not within subqueries.

    WITH DeptPayroll( dept_id, amt ) AS
  ( SELECT dept_id, sum(salary) AS amt
    FROM employee GROUP BY dept_id )
SELECT dept_id, amt
FROM DeptPayroll
WHERE amt = ( SELECT max(amt)
              FROM DeptPayroll )

  • The top-level SELECT statement in a view definition Common table expressions are permitted within the top-level SELECT statement that defines a view, but not within subqueries within the definition.

    CREATE VIEW LargestDept (dept_id, size, pay) AS
   WITH
     CountEmployees(dept_id, n) AS
       ( SELECT dept_id, count(*) AS n
         FROM employee GROUP BY dept_id ),
     DeptPayroll( dept_id, amt ) AS
       ( SELECT dept_id, sum(salary) AS amt
         FROM employee GROUP BY dept_id )
  SELECT count.dept_id, count.n, pay.amt
  FROM CountEmployees count JOIN DeptPayroll pay
  ON count.dept_id = pay.dept_id
  WHERE count.n = ( SELECT max(n) FROM CountEmployees )
     OR pay.amt = ( SELECT max(amt) FROM DeptPayroll )

  • A top-level SELECT statement in an INSERT statement Common table expressions are permitted within a top-level SELECT statement in an INSERT statement, but not within subqueries within the INSERT statement.

    INSERT INTO LargestPayrolls (dept_id, payroll, date)
  WITH DeptPayroll( dept_id, amt ) AS
    ( SELECT dept_id, sum(salary) AS amt
      FROM employee
      GROUP BY dept_id )
  SELECT dept_id, amt, CURRENT TIMESTAMP
  FROM DeptPayroll
  WHERE amt = ( SELECT max(amt)
                FROM DeptPayroll )


Typical applications of common table expressions

In general, common table expressions are useful whenever a table expression must appear multiple times within a single query. The following typical situations are suited to common table expressions.

  • Queries that involve multiple aggregate functions.

  • Views within a procedure that must contain a reference to a program variable.

  • Queries that use temporary views to store a set of values.

This list is not exhaustive. You may encounter many other situations in which common table expressions are useful.

Multiple aggregate functions

Common table expressions are useful whenever multiple levels of aggregation must appear within a single query. This is the case in the example used in the previous section. The task was to retrieve the department ID of the department that has the most employees. To do so, the count aggregate function is used to calculate the number of employees in each department and the max function is used to select the largest department.

A similar situation arises when writing a query to determine which department has the largest payroll. The sum aggregate function is used to calculate each department's payroll and the max function to determine which is largest. The presence of both functions in the query is a clue that a common table expression may be helpful.

WITH DeptPayroll( dept_id, amt ) AS
    ( SELECT dept_id, sum(salary) AS amt
      FROM employee GROUP BY dept_id )
SELECT dept_id, amt
FROM DeptPayroll
WHERE amt = ( SELECT max(amt)
              FROM DeptPayroll )
Views that reference program variables

Sometimes, it can be convenient to create a view that contains a reference to a program variable. For example, you may define a variable within a procedure that identifies a particular customer. You want to query the customer's purchase history, and as you will be accessing similar information multiple times or perhaps using multiple aggregate functions, you want to create a view that contains information about that specific customer.

You cannot create a view that references a program variable because there is no way to limit the scope of a view to that of your procedure. Once created, a view can be used by in other contexts. You can, however, use a common table expressions within the queries in your procedure. As the scope of a common table expression is limited to the statement, the variable reference creates no ambiguity and is thus permitted.

The following statement selects the gross sales of the various sales representatives in the sample database.

SELECT emp_fname || ' ' || emp_lname AS sales_rep_name,
       sales_rep AS sales_rep_id,
       sum( p.unit_price * i.quantity ) AS total_sales
FROM employee LEFT OUTER JOIN sales_order AS o
              INNER JOIN sales_order_items AS i
              INNER JOIN product AS p
WHERE '2000-01-01' <= order_date
                  AND order_date < '2001-01-01'
GROUP BY sales_rep, emp_fname, emp_lname

The above query is the basis of the common table expression that appears in the following procedure. The ID number of the sales representative and the year in question are incoming parameters. As this procedure demonstrates, the procedure parameters and any declared local variables can be referenced within the WITH clause.

CREATE PROCEDURE sales_rep_total (
  IN rep  INTEGER,
  IN yyyy INTEGER )
BEGIN
  DECLARE start_date DATE;
  DECLARE end_date   DATE;
  SET start_date = YMD( yyyy,  1,  1 );
  SET   end_date = YMD( yyyy, 12, 31 );
  WITH total_sales_by_rep ( sales_rep_name,
                            sales_rep_id,
                            month,
                            order_year,
                            total_sales ) AS
  ( SELECT emp_fname || ' ' || emp_lname AS sales_rep_name,
           sales_rep AS sales_rep_id, month( order_date),
           year(order_date),
           sum( p.unit_price * i.quantity ) AS total_sales
    FROM employee LEFT OUTER JOIN sales_order o
                       INNER JOIN sales_order_items i
                       INNER JOIN product p
    WHERE start_date <= order_date AND
                        order_date <= end_date AND
          sales_rep = rep
    GROUP BY year(order_date), month(order_date),
             emp_fname, emp_lname, sales_rep )
  SELECT sales_rep_name,
            monthname( YMD(yyyy, month, 1) ) AS month_name,
            order_year,
            total_sales
  FROM total_sales_by_rep
  WHERE total_sales =
    ( SELECT max( total_sales) FROM total_sales_by_rep )
  ORDER BY order_year ASC, month ASC;
END;

The following statement demonstrates how to call the above procedure.

CALL sales_rep_total(129, 2000);
Views that store values

Sometimes, it can be useful to store a particular set of values within a SELECT statement or within a procedure. For example, suppose a company prefers to analyze the results of its sales staff by thirds of a year, instead of by quarter. Since there is no built-in date part for thirds, as there is for quarters, it is necessary to store the dates within the procedure.

WITH thirds (q_name, q_start, q_end) AS
( SELECT 'T1', '2000-01-01', '2000-04-30' UNION
  SELECT 'T2', '2000-05-01', '2000-08-31' UNION
  SELECT 'T3', '2000-09-01', '2000-12-31' )
SELECT q_name,
       sales_rep,
       count(*) AS num_orders,
       sum( p.unit_price * i.quantity ) AS total_sales
FROM thirds LEFT OUTER JOIN sales_order AS o
    ON q_start <= order_date AND order_date <= q_end
                   INNER JOIN sales_order_items AS i
                   INNER JOIN product AS p
 GROUP BY q_name, sales_rep
 ORDER BY q_name, sales_rep

This method should be used with care, as the values may need periodic maintenance. For example, the above statement must be modified if it is to be used for any other year.

You can also apply this technique within procedures. The following example declares a procedure that takes the year in question as an argument.

CREATE PROCEDURE sales_by_third ( IN y INTEGER )
BEGIN
  WITH thirds (q_name, q_start, q_end) AS
  ( SELECT 'T1', YMD( y, 01, 01), YMD( y, 04, 30) UNION
    SELECT 'T2', YMD( y, 05, 01), YMD( y, 08, 31) UNION
    SELECT 'T3', YMD( y, 09, 01), YMD( y, 12, 31) )
  SELECT q_name,
         sales_rep,
         count(*) AS num_orders,
         sum(p.unit_price * i.quantity) AS total_sales
  FROM thirds JOIN sales_order AS o
    ON q_start <= order_date AND order_date <= q_end
            KEY JOIN sales_order_items AS i
            KEY JOIN product AS p
  GROUP BY q_name, sales_rep
  ORDER BY q_name, sales_rep;
END;
CALL sales_by_third (2000);


Recursive common table expressions

Common table expressions may be recursive. Common table expressions are recursive when the RECURSIVE keyword appears immediately after WITH. A single WITH clause may contain multiple recursive expressions, and may contain both recursive and non-recursive common table expressions.

Recursive common table expressions provide a convenient way to write queries that return relationships to an arbitrary depth. For example, given a table that represents the reporting relationships within a company, you can readily write a query that returns all the employees that report to one particular person.

Depending on how you write the query, you can either limit the number of levels of recursion or you can provide no limit. Limiting the number of levels permits you to return only the top levels of management, for example, but may exclude some employees if the chains of command are longer than you anticipated. Providing no restriction on the number of levels ensures no employees will be excluded, but can introduce infinite recursion should the graph contain any cycles; for example, if an employee directly or indirectly reports to himself. This situation could arise within a company's management hierarchy if, for example, an employee within the company also sits on the board of directors.

Recursion provides a much easier means of traversing tables that represent tree or tree-like data structures. The only way to traverse such a structure in a single statement without using recursive expressions is to join the table to itself once for each possible level. For example, if a reporting hierarchy contains at most seven levels, you must join the employee table to itself seven times. If the company reorganizes and a new management level is introduced, you must rewrite the query.

Recursive common table expressions contain an initial subquery, or seed, and a recursive subquery that during each iteration appends additional rows to the result set. The two parts can be connected only with the operator UNION ALL. The initial subquery is an ordinary non-recursive query and is processed first. The recursive portion contains a reference to the rows added during the previous iteration. Recursion stops automatically whenever an iteration generates no new rows. There is no way to reference rows selected prior to the previous iteration.

The select list of the recursive subquery must match that of the initial subquery in number and data type. If automatic translation of data types cannot be performed, explicitly cast the results of one subquery so that they match those in the other subquery.

For more information about common table expressions, see About common table expressions.


Selecting hierarchical data

The following query demonstrates how to list the employees by management level. Level 0 represents employees with no managers. Level 1 represents employees who report directly to one of the level 0 managers, level 2 represents employees who report directly to a level 1 manager, and so on.

WITH RECURSIVE
  manager ( emp_id, manager_id,
            emp_fname, emp_lname, mgmt_level ) AS
( ( SELECT emp_id, manager_id,       -- initial subquery
           emp_fname, emp_lname, 0
    FROM employee AS e
    WHERE manager_id = emp_id )
  UNION ALL
  ( SELECT e.emp_id, e.manager_id,   -- recursive subquery
           e.emp_fname, e.emp_lname, m.mgmt_level + 1
    FROM employee AS e JOIN manager AS m
     ON   e.manager_id =  m.emp_id
      AND e.manager_id <> e.emp_id
      AND m.mgmt_level < 20 ) )
SELECT * FROM manager
ORDER BY mgmt_level, emp_lname, emp_fname

The condition within the recursive query that restricts the management level to less than 20 is an important precaution. It prevents infinite recursion in the event that the table data contains a cycle.

The MAX_RECURSIVE_ITERATIONS option

The option MAX_RECURSIVE_ITERATIONS is designed to catch runaway recursive queries. The default value of this option is 100. Recursive queries that exceed this number of levels of recursion terminate, but cause an error.

Although this option may seem to diminish the importance of a stop condition, this is not usually the case. The number of rows selected during each iteration may grow exponentially, seriously impacting database performance before the maximum is reached. Stop conditions within recursive queries provide a means of setting appropriate limits in each situation.


Restrictions on recursive common table expressions

The following restrictions apply to recursive common table expressions.

  • References to other recursive common table expressions cannot appear within the definition of recursive common table expressions. Thus, recursive common table expressions cannot be mutually recursive. However, non-recursive common table expressions can contain references to recursive ones, and recursive common table expressions can contain references to non-recursive ones.

  • The only set operator permitted between the initial subquery and the recursive subquery is UNION ALL. No other set operators are permitted.

  • Within the definition of a recursive subquery, a self-reference to the recursive table expression can appear only within the FROM clause of the recursive subquery.

  • When a self-reference appears within the FROM clause of the recursive subquery, the reference to the recursive table cannot appear on the null-supplying side of an outer join.

  • The recursive subquery cannot contain DISTINCT, or a GROUP BY or an ORDER BY clause.

  • The recursive subquery can not make use of any aggregate function.

  • To prevent runaway recursive queries, an error is generated if the number of levels of recursion exceeds the current setting of the MAX_RECURSIVE_ITERATIONS option. The default value of this option is 100.


Parts explosion problems

The parts explosion problem is a classic application of recursion. In this problem, the components necessary to assemble a particular object are represented by a graph. The goal is to represent this graph using a database table, then to calculate the total number of the necessary elemental parts.

For example, the following graph represents the components of a simple bookshelf. The bookshelf is made up of three shelves, a back, and four feet that are held on by four screws. Each shelf is a board held on with four screws. The back is another board held on by eight screws.

Graph representing hierarchical relationship of bookshelf subcomponents

The information in the table below represents the edges of the bookshelf graph. The first column names a component, the second column names one of the subcomponents of that component, and the third column specifies how many of the subcomponents are required.

component | subcomponent | quantity
bookcase | back | 1
bookcase | side | 2
bookcase | shelf | 3
bookcase | foot | 4
bookcase | screw | 4
back | backboard | 1
back | screw | 8
side | plank | 1
shelf | plank | 1
shelf | screw | 4

The following statements create the bookcase table and insert the data shown in the above table.

CREATE TABLE bookcase (
      component      VARCHAR(9),
      subcomponent   VARCHAR(9),
    quantity       integer,
    PRIMARY KEY (component, subcomponent)
);
INSERT INTO bookcase
  SELECT 'bookcase', 'back',      1 UNION
  SELECT 'bookcase', 'side',      2 UNION
  SELECT 'bookcase', 'shelf',     3 UNION
  SELECT 'bookcase', 'foot',      4 UNION
  SELECT 'bookcase', 'screw',     4 UNION
  SELECT 'back',     'backboard', 1 UNION
  SELECT 'back',     'screw',     8 UNION
  SELECT 'side',     'plank',     1 UNION
  SELECT 'shelf',    'plank',     1 UNION
  SELECT 'shelf',    'screw',     4;

After you have created the bookcase table, you can recreate the table of its parts, shown above, with the following query..

SELECT * FROM bookcase
ORDER BY component, subcomponent;

With this table constructed, you can generate a list of the primitive parts and the quantity of each required to construct the bookcase.

WITH RECURSIVE parts (component, subcomponent, quantity) AS
( SELECT component, subcomponent, quantity
  FROM bookcase WHERE component = 'bookcase'
    UNION ALL
  SELECT b.component, b.subcomponent, p.quantity * b.quantity
  FROM parts p JOIN bookcase b ON p.subcomponent = b.component )
SELECT subcomponent, sum(quantity) AS quantity
FROM parts
WHERE subcomponent NOT IN ( SELECT component FROM bookcase )
GROUP BY subcomponent
ORDER BY subcomponent;

The results of this query are shown below.

subcomponent | quantity
backboard | 1
foot | 4
plank | 5
screw | 24

Alternatively, you can rewrite this query to perform an additional level of recursion, thus avoiding the need for the subquery in the main SELECT statement:

WITH RECURSIVE parts (component, subcomponent, quantity) AS
( SELECT component, subcomponent, quantity
  FROM bookcase WHERE component = 'bookcase'
    UNION ALL
  SELECT p.subcomponent, b.subcomponent,
    IF b.quantity IS NULL
    THEN p.quantity
    ELSE p.quantity * b.quantity
    ENDIF
  FROM parts p LEFT OUTER JOIN bookcase b
  WHERE p.subcomponent = b.component AND
        p.subcomponent IS NOT NULL
 )
SELECT component, sum(quantity) FROM parts
WHERE subcomponent IS NULL
GROUP BY component
ORDER BY component;

The results of this query are identical to those of the previous query.


Data type declarations in recursive common table expressions

The data types of the columns in the temporary view are defined by those of the initial subquery. The data types of the columns from the recursive subquery must match. The database server automatically attempts to convert the values returned by the recursive subquery to match those of the initial query. If this is not possible, or if information may be lost in the conversion, an error is generated.

In general, explicit casts are often required when the initial subquery returns a literal value or NULL. Explicit casts may also be required when the initial subquery selects values from different columns than the recursive subquery.

Casts may be required if the columns of the initial subquery do not have the same domains as those of the recursive subquery. Casts must always be applied to NULL values in the initial subquery.

For example, the bookshelf parts explosion sample works correctly because the initial subquery returns rows from the bookcase table, and thus inherits the data types of the selected columns.

For more information, see Parts explosion problems.

If this query is rewritten as follows, explicit casts are required.

WITH RECURSIVE parts (component, subcomponent, quantity) AS
( SELECT NULL, 'bookcase', 1         -- ERROR! Wrong domains!
    UNION ALL
  SELECT b.component, b.subcomponent,
         p.quantity * b.quantity
  FROM parts p JOIN bookcase b
    ON p.subcomponent = b.component )
SELECT * FROM parts
ORDER BY component, subcomponent

Without casts, errors result for the following reasons:

  • The correct data type for component names is VARCHAR, but the first column is NULL.

  • The digit 1 is assumed to be a short integer, but the data type of the quantity column is INT.

No cast is required for the second column because this column of the initial query is already a string.

Casting the data types in the initial subquery allows the query to behave as intended:

WITH RECURSIVE parts (component, subcomponent, quantity) AS
( SELECT CAST(NULL AS VARCHAR),  -- CASTs must be used
         'bookcase',             -- to declare the
         CAST( 1   AS INT)       -- correct datatypes
      UNION ALL
  SELECT b.component, b.subcomponent,
         p.quantity * b.quantity
  FROM parts p JOIN bookcase b
    ON p.subcomponent = b.component )
SELECT * FROM parts
ORDER BY component, subcomponent


Least distance problem

You can use recursive common table expressions to find desirable paths on a directed graph. Each row in a database table represents a directed edge. Each row specifies an origin, a destination, and a cost of traveling from the origin to the destination. Depending on the problem, the cost may represent distance, travel time, or some other measure. Recursion permits you to explore possible routes through this graph. From the set of possible routes, you can then select the ones that interest you.

For example, consider the problem of finding a desirable way to drive between the cities of Kitchener and Pembroke. There are quite a few possible routes, each of which takes you through a different set of intermediate cities. The goal is to find the shortest routes, and to compare them to reasonable alternatives.

Directed graph showing distance between cities

First, define a table to represent the edges of this graph and insert one row for each edge. Since all the edges of this graph happen to be bi-directional, the edges that represent the reverse directions must be inserted also. This is done by selecting the initial set of rows, but interchanging the origin and destination. For example, one row must represent the trip from Kitchener to Toronto, and another row the trip from Toronto back to Kitchener.

CREATE TABLE travel (
    origin      AS VARCHAR(10),
    destination AS VARCHAR(10),
    distance    AS INT,
  PRIMARY KEY (origin, destination)
);
INSERT INTO travel
  SELECT 'Kitchener',  'Toronto',    105 UNION
  SELECT 'Kitchener',  'Barrie',     155 UNION
  SELECT 'North Bay',  'Pembroke',   220 UNION
  SELECT 'Pembroke',   'Ottawa',     150 UNION
  SELECT 'Barrie',     'Toronto',     90 UNION
  SELECT 'Toronto',    'Belleville', 190 UNION
  SELECT 'Belleville', 'Ottawa',     230 UNION
  SELECT 'Belleville', 'Pembroke',   230 UNION
  SELECT 'Barrie',     'Huntsville', 125 UNION
  SELECT 'Huntsville', 'North Bay',  130 UNION
  SELECT 'Huntsville', 'Pembroke',   245;
INSERT INTO travel   -- Insert the return trips
  SELECT destination, origin, distance
  FROM travel;

The next task is to write the recursive common table expression. Since the trip will start in Kitchener, the initial subquery begins by selecting all the possible paths out of Kitchener, along with the distance of each.

The recursive subquery extends the paths. For each path, it adds segments that continue along from the destinations of the previous segments, adding the length of the new segments so as to maintain a running total cost of each route. For efficiency, routes are terminated if they meet either of the following conditions:

  • The path returns to the starting location.

  • The path returns to the previous location.

  • The path reaches the desired destination.

In the current example, no path should return to Kitchener and all paths should be terminated if they reach Pembroke.

It is particularly important to guarantee that recursive queries will terminate properly when using them to explore cyclic graphs. In this case, the above conditions are insufficient, as a route may include an arbitrarily large number of trips back and forth between two intermediate cities. The recursive query below guarantees termination by limiting the maximum number of segments in any given route to seven.

Since the point of the example query is to select a practical route, the main query selects only those routes that are less than 50 percent longer than the shortest route.

WITH RECURSIVE
    trip (route, destination, previous, distance, segments) AS
( SELECT CAST(origin || ', ' || destination AS VARCHAR(256)),
         destination, origin, distance, 1
  FROM travel
  WHERE origin = 'Kitchener'
    UNION ALL
  SELECT route || ', ' || v.destination,
         v.destination,            -- current endpoint
         v.origin,                 -- previous endpoint
         t.distance + v.distance,  -- total distance
         segments + 1              -- total number of segments
  FROM trip t JOIN travel v ON t.destination = v.origin
  WHERE v.destination <> 'Kitchener'  -- Don't return to start
    AND v.destination <> t.previous   -- Prevent backtracking
    AND v.origin      <> 'Pembroke'   -- Stop at the end
    AND segments                      -- TERMINATE RECURSION!
          < ( SELECT count(*)/2 FROM travel ) )
SELECT route, distance, segments FROM trip
WHERE destination = 'Pembroke' AND
      distance < 1.5 * ( SELECT min(distance)
                         FROM trip
                         WHERE destination = 'Pembroke' )
ORDER BY distance, segments, route;

When run with against the above data set, this statement yields the following results.

route | distance | segments
Kitchener, Barrie, Huntsville, Pembroke | 525 | 3
Kitchener, Toronto, Belleville, Pembroke | 525 | 3
Kitchener, Toronto, Barrie, Huntsville, Pembroke | 565 | 4
Kitchener, Barrie, Huntsville, North Bay, Pembroke | 630 | 4
Kitchener, Barrie, Toronto, Belleville, Pembroke | 665 | 4
Kitchener, Toronto, Barrie, Huntsville, North Bay, Pembroke | 670 | 5
Kitchener, Toronto, Belleville, Ottawa, Pembroke | 675 | 4


Using multiple recursive common table expressions

A recursive query may include multiple recursive queries, as long as they are disjoint. It may also include a mix of recursive and non-recursive common table expressions. The RECURSIVE keyword must be present if at least one of the common table expressions is recursive.

For example, the following query—which returns the same result as the previous query—uses a second, non-recursive common table expression to select the length of the shortest route. The definition of the second common table expression is separated from the definition of the first by a comma.

WITH RECURSIVE
  trip (route, destination, previous, distance, segments) AS
    ( SELECT CAST(origin || ', ' || destination AS VARCHAR(256)),
             destination, origin, distance, 1
      FROM travel
      WHERE origin = 'Kitchener'
      UNION ALL
      SELECT route || ', ' || v.destination,
             v.destination,
             v.origin,
             t.distance + v.distance,
             segments + 1
      FROM trip t JOIN travel v ON t.destination = v.origin
      WHERE v.destination <> 'Kitchener'
        AND v.destination <> t.previous
        AND v.origin      <> 'Pembroke'
        AND segments
              < ( SELECT count(*)/2 FROM travel ) ),
  shortest ( distance ) AS                 -- Additional,
    ( SELECT min(distance)                 -- non-recursive
      FROM trip                            -- common table
      WHERE destination = 'Pembroke' )     -- expression
SELECT route, distance, segments FROM trip
WHERE destination = 'Pembroke' AND
      distance < 1.5 * ( SELECT distance FROM shortest )
ORDER BY distance, segments, route;

Like non-recursive common table expressions, recursive expressions, when used within stored procedures, may contain references to local variables or procedure parameters. For example, the best_routes procedure, defined below, identifies the shortest routes between the two named cities.

CREATE PROCEDURE best_routes (
   IN initial VARCHAR(10),
   IN final   VARCHAR(10)
)
BEGIN
  WITH RECURSIVE
      trip (route, destination, previous, distance, segments) AS
  ( SELECT CAST(origin || ', ' || destination AS VARCHAR(256)),
           destination, origin, distance, 1
    FROM travel
    WHERE origin = initial
      UNION ALL
    SELECT route || ', ' || v.destination,
           v.destination,            -- current endpoint
           v.origin,                 -- previous endpoint
           t.distance + v.distance,  -- total distance
           segments + 1              -- total number of segments
    FROM trip t JOIN travel v ON t.destination = v.origin
    WHERE v.destination <> initial     -- Don't return to start
      AND v.destination <> t.previous  -- Prevent backtracking
      AND v.origin      <> final       -- Stop at the end
      AND segments                     -- TERMINATE RECURSION!
            < ( SELECT count(*)/2 FROM travel ) )
  SELECT route, distance, segments FROM trip
  WHERE destination = final AND
        distance < 1.4 * ( SELECT min(distance)
                           FROM trip
                           WHERE destination = final )
  ORDER BY distance, segments, route;
END;
CALL best_routes ( 'Pembroke', 'Kitchener' );


Using OLAP

About this chapter

This chapter describes online analytical processing (OLAP) functionality. OLAP is a method of data analysis for information stored in relational databases. Using OLAP you can acquire result sets with subtotalled rows and organize data into multidimensional cubes. It lets you use filters so that you can drill down into the data and is designed to return result sets quickly.


Understanding OLAP

Online analytical processing (OLAP) lets you analyze the data stored in relational databases. The result sets you obtain using OLAP can have subtotaled rows and can be organized into multidimensional cubes.

OLAP gives you the ability to do time series analyses, cost allocations, goal seeking, ad hoc multidimensional structural changes, non-procedural modeling, exception alerting, and data mining. Adaptive Server Anywhere provides a multidimensional conceptual view of the data, including full support for hierarchies and multiple hierarchies.

OLAP functionality lets you complete the following tasks:

  • calculations applied across dimensions

  • calculations applied through hierarchies

  • trend analysis over sequences of time

  • reach-through to underlying data

Some database products provide a separate OLAP module which requires that data be moved from the database into the OLAP module before it is analyzed. Adaptive Server Anywhere builds OLAP features into the database itself. This makes deployment and integration with other database features (such as stored procedures) easier and more seamless.


Understanding subtotals

Subtotal rows can help you analyze data, especially if there are large amounts of data, different dimensions to the data, data contained in different tables, or even different databases altogether. For example, a sales manager might find reports on sales figures broken down by sales representative, region, and quarter to be useful in understanding patterns in sales. Subtotals for the data give the sales manager a picture of overall sales from different perspectives. Analyzing this data is easier when summary information is provided based on the criteria that the sales manager wants to compare.

With OLAP, the procedure for analyzing and computing row and column subtotals is invisible to the end-user. The following diagram shows conceptually how Adaptive Server Anywhere creates subtotals:

The process by which Adaptive Server Anywhere calculates subtotals and adds them to the result set. This three-step process is invisible to the end-user.

  1. This step yields an intermediate result set. The query is tabulated according to the conditions set out in it.

  2. OLAP creates the subtotals and attaches them to the result set.

  3. The rows are arranged according to the ORDER BY clause in the query.

Note
This sequence is seamless to the end-user.

About OLAP operations


About OLAP operations

Think of OLAP operations (ROLLUP, CUBE, and GROUPING SETS) as follows:

  • A list of prefixes is constructed for the query. A prefix is a subset of the items in the group-by-list.

    A prefix is constructed by excluding one or more of the rightmost items from those in the query's group-by-list. The remaining columns are called the prefix columns.

    Take the following ROLLUP query as an example:

    SELECT year (order_date) Year, quarter (order_date) Quarter, count (*) Orders
FROM sales_order
GROUP BY ROLLUP (Year, Quarter)
ORDER BY Year, Quarter

    In the example above the group-by-list includes two variables (Year and Quarter).

    GROUP BY ROLLUP (Year, Quarter)

    There are two prefixes for this query:

    • Exclude Quarter The set of prefix columns contains the single column Year.

    • Exclude both Quarter and Year There are no prefix columns.

    A result set from a basic ROLLUP query with two variables (Year and Quarter) that identifies the rows showing the Exclude Quarter and Year prefix and the Exclude Quarter prefix.
    Note
    There are the same number of prefixes as there are items in the group-by-list.

  • For each prefix, a subtotal row is constructed corresponding to all those rows in which the prefix columns have the same value.

    For example, let's examine the following query again:

    SELECT year (order_date) AS Year, quarter (order_date) AS Quarter, COUNT (*) Orders
FROM sales_order
GROUP BY ROLLUP (Year, Quarter)
ORDER BY Year, Quarter

    In this query, the prefix containing the Year column leads to a summary row for Year=2000 and a summary row for Year=2001. There is a single summary row for the prefix that has no columns, which is a subtotal over all rows in the intermediate result set.

    The value of each column in a subtotal row is as follows:

    • Column included in the prefix The value of the column. For example, in the preceding query, the value of the Year column for the subtotal over rows with Year=2000 is 2000.

    • Column excluded from the prefix NULL. For example, the Quarter column has a value of NULL for the subtotal rows generated by the prefix consisting of the Year column.

    • Aggregate function An aggregate over the values of the excluded columns.

      Subtotal values are computed over the rows in the underlying data, not over the aggregated rows. In many cases, such as SUM or COUNT, the result is the same, but the distinction is important in the case of statistical functions such as AVG, STDDEV, and VARIANCE, for which the result differs.


NULL values and subtotal rows

When rows in the input to a GROUP BY operation contain NULL, there is the possibility of confusion between subtotal rows added by the ROLLUP, CUBE, or GROUPING SETS operations and rows that contain NULL values that are part of the original input data.

The GROUPING function distinguishes subtotal rows from others by taking a column in the group by list as its argument, and returning 1 if the column is NULL because the row is a subtotal row, and 0 otherwise.

Example

The following example includes GROUPING columns in the result set. Rows are highlighted that contain NULL as a result of the input data, not because they are subtotal rows. The GROUPING columns are highlighted. The query is an outer join between the employee table and the sales_order table. The query selects female employees who live in either Texas, New York, or California. NULL appears in the columns corresponding to those female employees who are not sales representatives (and therefore have no sales).

SELECT employee.emp_id AS Employee,
       year(order_date) AS Year,
       COUNT(*) AS Orders,
       GROUPING ( Employee ) AS GE,
       GROUPING ( Year ) AS GY
FROM employee LEFT OUTER JOIN sales_order
ON employee.emp_id = sales_order.sales_rep
WHERE employee.sex IN ('F')
AND employee.state IN ('TX', 'CA', 'NY')
GROUP BY ROLLUP (Year, Employee)
ORDER BY Year, Employee

The table that follows represents the result set from the query.

A result set from a ROLLUP query where the NULL values that are a product of the result set, not subtotalled rows, are highlighted.


Using ROLLUP

The ROLLUP operation provides subtotals of aggregate rows. It adds subtotal rows into the result sets of queries with GROUP BY clauses. ROLLUP generates a result set showing aggregates for a hierarchy of values in the selected columns. Use the ROLLUP operation when you want a result set showing totals and subtotals.

This SQL syntax... Defines the following sets...
GROUP BY ROLLUP (A, B, C);
 (A, B, C)

(A, B)

(A)

( )

For more information about rows returned by ROLLUP queries, see About OLAP operations. For more information about using GROUP BY clauses in queries, see GROUP BY clause.

Example 1

In the example that follows, the query returns data that summarizes the number of sales orders by year and quarter.

SELECT year (order_date) AS Year, quarter (order_date) AS Quarter, COUNT (*) AS Orders
FROM sales_order
GROUP BY ROLLUP (Year, Quarter)
ORDER BY Year, Quarter

The table that follows represents the result set from the query. The subtotal rows are highlighted in the result set. Each subtotal row has a NULL in the column or columns over which the subtotal is computed.

A result set from a ROLLUP query identifying the subtotalled rows.

The row marked [1] represents the total number of orders across both years (2000, 2001) and all quarters. This row has NULL in both the Year and Quarter columns and is the row where all columns were excluded from the prefix.

Note
Every ROLLUP operation returns a result set with one row where NULL appears in each column except for the aggregate column. This row represents the summary of each column to the aggregate function. For example, if SUM were the aggregate function in question, this row would represent the grand total of all values.

The rows highlighted row [2] represent the total number of orders in the years 2000 and 2001, respectively. Both rows have NULL in the Quarter column because the values in that column are rolled up to give a subtotal for Year.

Note
The number of rows like this in your result set depends on the number of variables that appear in your ROLLUP query.

The remaining rows marked [3] provide summary information by giving the total number of orders for each quarter in both years.

Example 2

Here is another example of the ROLLUP operation that returns a slightly more complicated result set than the first example. The result set summarizes the number of sales orders by year, quarter, and region. In this example, only the first and second quarters and two selected regions (Canada and the Eastern region) are examined.

SELECT year (order_date) AS Year, quarter (order_date) AS Quarter, region, COUNT (*) AS Orders
FROM sales_order
WHERE region IN ('Canada', 'Eastern') AND quarter IN ('1', '2')
GROUP BY ROLLUP (Year, Quarter, Region)
ORDER BY Year, Quarter, Region

The table that follows represents the result set from the query. Each subtotal row has a NULL in the column or columns over which the subtotal is computed.

A result from a ROLLUP query showing the total number of sales orders over all years, quarters, and regions, and the subtotals of sales orders by year.

The first row [1] is an aggregate over all rows, and has NULL in the Year, Quarter, and Region columns. The value in the Orders column of this row represents the total number of orders in Canada and the Eastern region in Quarters 1 and 2 in the years 2000 and 2001.

The rows marked [2] represent the total number of sales orders in each year (2000) and (2001) in Quarters 1 and 2 in Canada and the Eastern region. The values of these rows [2] are equal to the grand total represented in row [1].

The rows marked [3] provide data about the total number of orders for the given year and quarter by region.

A result set from a ROLLUP query showing the total number of orders for each year by quarter and region.

The rows marked [4] provide data about the total number of orders for each year, each quarter, and each region in the result set.

A result set from a ROLLUP query showing the number of orders for each year, each quarter, and each region.
Understanding ROLLUP and subtotal rows

ROLLUP is equivalent to a UNION of a set of GROUP BY queries. The result sets of the following queries are identical. The result set of GROUP BY A, B consists of subtotals over all those rows in which A and B are held constant. To make a union possible, column C is assigned NULL.

This ROLLUP query... Is equivalent to this query without ROLLUP...
SELECT A, B, C,
     SUM( D )
FROM T1
GROUP BY ROLLUP
     (A, B, C);

SELECT * FROM (
 ( SELECT A, B, C, SUM( D )
   GROUP BY A, B, C )
  UNION ALL
 ( SELECT A, B, NULL, SUM( D )
   GROUP BY A, B )
  UNION ALL
 ( SELECT A, NULL, NULL, SUM( D )
   GROUP BY A )
  UNION ALL
 ( SELECT NULL, NULL, NULL, SUM( D ) )
)


Using CUBE

The CUBE operation is an OLAP feature. OLAP is a way of organizing data to fit the way you analyze and manage it so that it takes less time and effort to generate the result sets that you need. You precalculate the summary values for the reports, which speeds up report calculation. CUBES are useful when you want to work with a large amount of data in your reports.

Like ROLLUP, the CUBE operator provides subtotals of aggregate values in the result set. When the CUBE operation is performed on variables, the result set includes many subtotal rows based on combinations of the values of the variables. Unlike ROLLUP, CUBE returns all possible combinations of the variables that you specify in the query.

The CUBE operator returns a result set with added information of dimensions to the data. You can further analyze columns of your data, which are referred to as dimensions. CUBE provides a cross tabulation report of all possible combinations of the dimensions and generates a result set that shows aggregates for all combinations of values in selected columns.

Note
CUBE is particularly useful when your dimensions are not a part of the same hierarchy.
This SQL syntax... Defines the following sets...
GROUP BY CUBE (A, B, C);
 (A, B, C)

(A, B)

(A, C)

(A)

(B, C)

(B)

(C)

( )

For more information about rows returned by CUBE queries, see About OLAP operations. For more information about using GROUP BY clauses in queries, see GROUP BY clause.

Example

In the example that follows, the query returns a result set that summarizes the total number of orders and then calculates subtotals for the number of orders by year and quarter.

Note
As the number of variables that you want to compare increases, so too does the complexity of the cube that the query returns.
SELECT year (order_date) AS Year, quarter (order_date) AS Quarter, COUNT (*) AS Orders
FROM sales_order
GROUP BY CUBE (Year, Quarter)
ORDER BY Year, Quarter

The table that follows represents the result set from the query. The subtotal rows are highlighted in the result set. Each subtotal row has a NULL in the column or columns over which the subtotal is computed.

A result set from a CUBE query showing the grand total and subtotalled number of sales orders.

The first highlighted row [1] represents the total number of orders across both years and all quarters. The value in the Orders column is the sum of the values in each of the rows marked [3]. It is also the sum of the four values in the rows marked [2].

Note
All CUBE operations return result sets with at least one row where NULL appears in each column except for the aggregate column. This row represents the summary of each column to the aggregate function.

The next set of highlighted rows [2] represents the total number of orders by quarter across both years. The following two rows marked by [3] represent the total number of orders across all quarters first in the year 2000 and then in the year 2001.

Understanding CUBE

The CUBE operation is equivalent to a GROUPING SETS query that includes all possible combinations of variables.

This CUBE query... Is equivalent to this query without CUBE...
SELECT A, B, C, SUM( D )
FROM t
GROUP BY CUBE( A, B, C)

SELECT A, B, C,
     SUM( D )
FROM t
GROUP BY GROUPING SETS(
     ( A, B, C ),
     ( A, B ), ( A ), ( B, C ),
     ( B ), ( A, C ), ( C ),
     () )

For information about the GROUPING SETS syntax used in the preceding SQL query, see Using GROUPING SETS.


Using GROUPING SETS

GROUPING SETS let you compute groups on several different sets of grouping columns in the same query. Whereas CUBE and ROLLUP add a predefined set of subtotals into the result set, GROUPING SETS lets you explicitly specify which subtotals to add. It is more complicated to use than ROLLUP or CUBE, but permits finer control over the result set. This operation is useful if you would like to return only part of the multidimensional result set of a cube. GROUPING SETS let you select which variables to compare instead of returning a comparison of all the variables like CUBE, or a hierarchical subset, like ROLLUP.

This SQL syntax... Defines the following sets...
GROUP BY GROUPING SETS
     ((A, B), (A, C), (C));
 (A, B)

(A, C)

(C)

For more information about rows returned by GROUPING SETS queries, see About OLAP operations. For more information about using GROUP BY clauses in queries, see GROUP BY clause.

Example

The following example shows how you can tailor the results that are returned from a query using GROUPING SETS. The query specifies that the result set returns subtotal rows for each year, but not for the individual quarters.

SELECT year (order_date) AS Year, quarter (order_date) AS Quarter, COUNT (*) AS Orders
FROM sales_order
GROUP BY GROUPING SETS ((Year, Quarter), (Year))
ORDER BY Year, Quarter

The table that follows represents the result set from the query. The subtotal rows are highlighted.

A result set from a GROUPING SETS query showing the subtotal rows for number of sales orders for each year.

The result set includes only the subtotal rows for each year (2000 and 2001). Notice that it does not provide a grand total for the number of orders in both years and all quarters.

If you ran a query using the CUBE operator, you would get additional subtotal rows for overall orders, for each quarter (1, 2, 3, and 4), and for each year (2000 and 2001).

Understanding GROUPING SETS

Similar to ROLLUP, the GROUPING SETS operation is equivalent to a UNION ALL of GROUP BY queries.

This GROUPING SETS query... Is equivalent to this query without GROUPING SETS...
SELECT A, B, C,
     SUM( D )
FROM t
GROUP BY GROUPING SETS
     ( A, B, C )

SELECT * FROM (
 ( SELECT A, NULL, NULL, SUM( D )
FROM t GROUP BY A )
  UNION ALL
 ( SELECT NULL, B, NULL, SUM( D )
FROM t GROUP BY B )
  UNION ALL
 ( SELECT NULL, NULL, C, SUM( D )
FROM t GROUP BY C )
)

Using concatenated GROUPING SETS


Using concatenated GROUPING SETS

Another method of specifying GROUPING SETS is to use concatenated GROUPING SETS. These offer a concise way to generate large combinations of groupings. Using concatenated GROUPING SETS yields the cross-product of groupings from each GROUPING SET list. You can perform concatenations on groupings specified with CUBE and ROLLUP. The cross-product operation enables even a small number of concatenated groupings to generate a large number of final groups.

This SQL syntax... Defines the following sets...
GROUP BY GROUPING SETS (A, B)
     (Y, Z)
 (A, Y)

(A, Z)

(B, Y)

(B, Z)


Working with OLAP functions

OLAP functions provide the capability to perform analytic tasks on data, such as computing moving averages, ranks, and cumulative values. You can include an OLAP function in a select-list or on the ORDER BY clause of a SELECT statement. An OLAP function cannot be used as an argument of an aggregate function. Therefore, you cannot have functions like SUM( RANK() ).

When using an OLAP function, a window is specified that defines the rows over which the function is applied, and in what order. The set of rows is defined, relative to the current row, as either a range or a number of rows preceding and following. For example, you can calculate an average over the previous three month period.

The following OLAP functions are available:

  • Rank functions Let you compile a list of values from your data set in ranked order. For example, listing the sales representatives in decreasing order of total sales for each quarter.

  • Reporting functions Let you compare a non-aggregate value to an aggregate value. For example, listing all quarters in which expenses are less than the average.

  • Window functions Let you analyze your data by defining a moving window for it. For example, calculating a moving average, such as the NASDAQ figure, over a 30-day period.


Rank functions

Rank functions let you compute a rank value for each row in a result set based on an ordering specified in the query. For example, a sales manager might need to identify the top or bottom sales people in the company, the highest- or lowest-performing sales region, or the best- or worst-selling products. Rank functions can provide this information.

The following statistical functions are classified as rank functions:

  • CUME_DIST function Computes the position of one row returned from a query with respect to the other rows returned by the query, as defined by the ORDER BY clause. For information, see CUME_DIST function [Aggregate].

  • RANK function Computes the rank of each row returned from a query with respect to the other rows returned by the query, as defined by the ORDER BY clause. For information, see RANK function [Aggregate].

  • DENSE_RANK function Calculates the rank of a value in a group. The difference between RANK and DENSE_RANK is that RANK leaves a gap in the ranking sequence when there are ties between values. For information, see DENSE_RANK function [Aggregate].

  • PERCENT_RANK function Calculates a percentage for the rank rather than a fractional amount. This function returns a decimal value between 0 and 1. For information, see PERCENT_RANK function [Aggregate].

  • ROW_NUMBER function Assigns a unique number to each row, which is determined by the ORDER BY clause. For information, see ROW_NUMBER function [Aggregate].

Example 1

The SQL query that follows finds the male and female employees from Utah and ranks them in descending order according to salary.

SELECT emp_lname, salary, sex,
     RANK () OVER (ORDER BY salary DESC) "Rank"
     FROM employee
WHERE state IN ('UT')

The table that follows represents the result set from the query.

A result set showing a list of employees from Utah and ranking them in descending order according to salary.
Example 2

You can partition your data to provide different results. Using the query from example 1, you can change the data by partitioning it by gender. The following example ranks employees in descending order by salary and partitions by gender.

SELECT emp_lname, salary, sex,
     RANK () OVER (PARTITION BY sex
     ORDER BY salary DESC) "Rank"
     FROM employee
WHERE state IN ('UT')

The table that follows represents the result set from the query.

A result set showing a list of employees in Utah ranked in descending order by salary and partitioned by gender.
Example 3

The following example finds a list of female employees in Utah and Arizona and ranks them in descending order according to salary. The PERCENT_RANK function is used to provide a cumulative total in descending order.

SELECT emp_lname, salary,
     PERCENT_RANK () OVER (ORDER BY salary DESC) "Rank"
     FROM employee
WHERE state IN ('UT','AZ') AND sex IN ('F')

The table that follows represents the result set from the query.

A result set showing a list of female employees in Utah and Arizona ranked in descending order using a percentage cumulative total according to salary.
Example 4

You can use rank functions to find the top or bottom percentiles in the data set. In the following example, the query returns male employees whose salary is in the top five percent of the data set.

SELECT *
FROM ( SELECT emp_lname, salary,
       PERCENT_RANK () OVER (ORDER BY salary DESC) "Rank"
       FROM employee
       WHERE sex IN ('M')  )
       AS DT ( last_name, salary, percent )
WHERE percent < 0.05

The table that follows represents the result set from the query.

A result set showing a list of male employees whose salary is in the top five percent of the data set.


Reporting functions

Reporting functions let you compare non-aggregate values to aggregate values. For example, a salesperson might need to compile a list of all customers who ordered more than the average number of a product in a specified year, or a manager might want to compare an employee's salary against the average salary of the department.

You can use any aggregate function in conjunction with reporting functions. For a list of the available aggregate functions, see Aggregate functions.

Note
You can use the same statistical functions, with the exception of LIST, with window functions.
Example 1

The following query returns a result set that shows a list of the products that sold higher than the average number of sales. The result set is partitioned by year.

SELECT *
FROM (SELECT year(order_date) AS Year, prod_id,
        SUM( quantity ) AS Q,
        AVG (SUM(quantity))
        OVER (PARTITION BY Year) AS Average
        FROM sales_order JOIN sales_order_items
        GROUP BY year(order_date), prod_id
        ORDER BY Year)
    AS derived_table
WHERE Q > Average

The table that follows represents the result set from the query.

A result set

For the year 2000, the average number of orders was 1,787. Four products (700, 601, 600, and 400) sold higher than that amount. In 2001, the average number of orders was 1,048 and three products exceeded that amount.

Example 2

The following query returns a result set that shows the employees whose salary is one standard deviation greater than the average salary of their department. Standard deviation is a measure of how much the data varies from the mean.

SELECT *
FROM (SELECT
        emp_lname   AS Employee,
        dept_id     AS Dept,
        CAST( salary as DECIMAL( 10, 2) ) AS Salary,
        CAST( AVG( salary )
            OVER (PARTITION BY dept_id) AS DECIMAL (10,2) ) AS Average,
        CAST (STDDEV_POP (salary)
            OVER (PARTITION BY dept_id) AS DECIMAL (10, 2 ) ) AS Std_Dev
        FROM employee
        GROUP BY Dept, Employee, Salary)
    AS derived_table
WHERE Salary > Average + Std_Dev
ORDER BY Dept, Salary, Employee

The table that follows represents the result set from the query. Every department has at least one employee whose salary significantly deviates from the mean.

A result set showing a list of employees, partitioned by department, whose salary is significantly different from the average salary of their department.

Employee Scott earns $96,300.00 while the departmental average is $58,736.28. The standard deviation for that department is 16,829.00, which means that salaries less than $75,565.88 (58736.28 + 16829.60 = 75565.88) fall within one standard deviation of the mean. At $96,300.00, employee Scott is well above that figure.


Window functions

Window functions let you analyze your data by computing aggregate values over windows surrounding each row. The result set returns a summary value representing a set of rows. You can use window functions to calculate a moving average of the sales figures for a company over a specified time period.

You can use any aggregate function (except LIST) in conjunction with window functions.

For a list of the available aggregate functions, see Aggregate functions.

Note
You can use the same statistical functions with reporting functions.

The illustration that follows shows a partition and the window view that it contains. The window is defined by a certain number of rows and descends through the partition.

A graphical depiction of a partition and a window view within the partition.
Example

The following example shows a window function. The query returns a result set that partitions the data by department and then provides a cumulative summary of employees' salaries starting with the employee who has been at the company the longest. The result set includes only those employees who reside in California, Utah, New York, or Arizona. The column Sum Salary provides the cumulative total of employees' salaries.

SELECT dept_id, emp_lname, start_date, salary,
SUM(salary) OVER (PARTITION BY dept_id
ORDER BY start_date
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS "Sum_Salary"
FROM employee
WHERE state IN ('CA', 'UT', 'NY', 'AZ') AND dept_id IN ('100', '200')
ORDER BY dept_id, start_date;

The table that follows represents the result set from the query. The result set is partitioned by department.

A result set, partitioned by department, showing a list of employees in California, Arizona, Utah, and New York and ranked in descending order according to salary and providing a cumulative total by department.

For department 100, the cumulative total of salaries from employees in California, Utah, New York, and Arizona is $434,091.69 and the cumulative total for employees in department 200 is $250,200.00.


Using Subqueries

About this chapter

When you create a query, you use WHERE and HAVING clauses to restrict the rows that the query returns.

Sometimes, the rows you select depend on information stored in more than one table. A subquery in the WHERE or HAVING clause allows you to select rows from one table according to specifications obtained from another table. Additional ways to do this can be found in Joins: Retrieving Data from Several Tables.

Before your start

This subquery chapter assumes some knowledge of queries and the syntax of the select statement. Information about queries appears in Queries: Selecting Data from a Table.

Introduction to subqueries
Using subqueries in the WHERE clause
Subqueries in the HAVING clause
Subquery comparison test
Quantified comparison tests with ANY and ALL
Testing set membership with IN conditions
Existence test
Outer references
Subqueries and joins
Nested subqueries
How subqueries work


Introduction to subqueries

A relational database stores information about different types of objects in different tables. For example, you should store information particular to products in one table, and information that pertains to sales orders in another. The product table contains the information about the various products. The sales order items table contains information about customers' orders.

In general, only the simplest questions can be answered using only one table. For example, if the company reorders products when there are fewer than 50 of them in stock, then it is possible to answer the question "Which products are nearly out of stock?" with this query:

SELECT id, name, description, quantity
FROM product
WHERE quantity < 50

However, if "nearly out of stock" depends on how many items of each type the typical customer orders, the number "50" will have to be replaced by a value obtained from the sales_order_items table.

Structure of the subquery

A subquery is structured like a regular query, and appears in the main query's SELECT, FROM, WHERE, or HAVING clause. Continuing with the previous example, you can use a subquery to select the average number of items that a customer orders, and then use that figure in the main query to find products that are nearly out of stock. The following query finds the names and descriptions of subquery the products which number less than twice the average number of items of each type that a customer orders.

SELECT name, description
FROM product WHERE quantity <  2 * (
   SELECT avg(quantity)
   FROM sales_order_items
   )

In the WHERE clause, subqueries help select the rows from the tables listed in the FROM clause that appear in the query results. In the HAVING clause, they help select the row groups, as specified by the main query's GROUP BY clause, that appear in the query results.


Using subqueries in the WHERE clause

Subqueries in the WHERE clause work as part of the row selection process. You use a subquery in the WHERE clause when the criteria you use to select rows depend on the results of another table.

Example

Find the products whose in-stock quantities are less than double the average ordered quantity.

SELECT name, description
FROM product WHERE quantity <  2 * (
   SELECT avg(quantity)
   FROM sales_order_items)

This is a two-step query: first, find the average number of items requested per order; and then find which products in stock number less than double that quantity.

The query in two steps

The quantity column of the sales_order_items table stores the number of items requested per item type, customer, and order. The subquery is

SELECT avg(quantity)
FROM sales_order_items

It returns the average quantity of items in the sales_order_items table, which is 25.851413.

The next query returns the names and descriptions of the items whose in-stock quantities are less than twice the previously-extracted value.

SELECT name, description
FROM product
WHERE quantity < 2*25.851413

Using a subquery combines the two steps into a single operation.

Purpose of a subquery in the WHERE clause

A subquery in the WHERE clause is part of a search condition. The chapter Queries: Selecting Data from a Table describes simple search conditions you can use in the WHERE clause.


Subqueries in the HAVING clause

Although you usually use subqueries as search conditions in the WHERE clause, sometimes you can also use them in the HAVING clause of a query. When a subquery appears in the HAVING clause, like any expression in the HAVING clause, it is used as part of the row group selection.

Here is a request that lends itself naturally to a query with a subquery in the HAVING clause: "Which products' average in-stock quantity is more than double the average number of each item ordered per customer?"

Example
SELECT name, avg(quantity)
FROM product
GROUP BY name
HAVING avg(quantity) > 2* (
   SELECT avg(quantity)
   FROM sales_order_items
   )
name | avg(product.quantity)
Tee Shirt | 52.333333
Baseball Cap | 62
Shorts | 80

The query executes as follows:

  • The subquery calculates the average quantity of items in the sales_order_items table.

  • The main query then goes through the product table, calculating the average quantity product, grouping by product name.

  • The HAVING clause then checks if each average quantity is more than double the quantity found by the subquery. If so, the main query returns that row group; otherwise, it doesn't.

  • The SELECT clause produces one summary row for each group, displaying the name of each product and its in-stock average quantity.

You can also use outer references in a HAVING clause, as shown in the following example, a slight variation on the one above.

Example

"Find the product ID numbers and line ID numbers of those products whose average ordered quantities is more than half the in-stock quantities of those products."

SELECT prod_id, line_id
FROM sales_order_items
GROUP BY prod_id, line_id
HAVING 2* avg(quantity) > (
   SELECT quantity
   FROM product
   WHERE product.id = sales_order_items.prod_id)
prod_id | line_id
401 | 2
401 | 1
401 | 4
501 | 3
... | ...

In this example, the subquery must produce the in-stock quantity of the product corresponding to the row group being tested by the HAVING clause. The subquery selects records for that particular product, using the outer reference sales_order_items.prod_id.

A subquery with a comparison returns a single value

This query uses the comparison ">", suggesting that the subquery must return exactly one value. In this case, it does. Since the id field of the product table is a primary key, there is only one record in the product table corresponding to any particular product id.

Subquery tests


Subquery tests

The chapter Queries: Selecting Data from a Table describes simple search conditions you can use in the HAVING clause. Since a subquery is just an expression that appears in the WHERE or HAVING clauses, the search conditions on subqueries may look familiar.

They include:

  • Subquery comparison test Compares the value of an expression to a single value produced by the subquery for each record in the table(s) in the main query.

  • Quantified comparison test Compares the value of an expression to each of the set of values produced by a subquery.

  • Subquery set membership test Checks if the value of an expression matches one of the set of values produced by a subquery.

  • Existence test Checks if the subquery produces any rows.


Subquery comparison test

The subquery comparison test (=, <>, <. <=, >, >=) is a modified version of the simple comparison test. The only difference between the two is that in the former, the expression following the operator is a subquery. This test is used to compare a value from a row in the main query to a single value produced by the subquery.

Example

This query contains an example of a subquery comparison test:

SELECT name, description, quantity
FROM product
WHERE quantity <  2 * (
   SELECT avg(quantity)
   FROM sales_order_items)
name | description | quantity
Tee Shirt | Tank Top | 28
Baseball Cap | Wool cap | 12
Visor | Cloth Visor | 36
Visor | Plastic Visor | 28
... | ... | ...

The following subquery retrieves a single value—the average quantity of items of each type per customer's order—from the sales_order_items table.

SELECT avg(quantity)
FROM sales_order_items

Then the main query compares the quantity of each in-stock item to that value.

A subquery in a comparison test returns one value

A subquery in a comparison test must return exactly one value. Consider this query, whose subquery extracts two columns from the sales_order_items table:

SELECT name, description, quantity
FROM product
WHERE quantity <  2 * (
   SELECT avg(quantity), max (quantity)
   FROM sales_order_items)

It returns the error Subquery allowed only one select list item.


Quantified comparison tests with ANY and ALL

The quantified comparison test has two categories, the ALL test and the ANY test:


The ANY test

The ANY test, used in conjunction with one of the SQL comparison operators (=, <>, <, <=, >, >=), compares a single value to the column of data values produced by the subquery. To perform the test, SQL uses the specified comparison operator to compare the test value to each data value in the column. If any of the comparisons yields a TRUE result, the ANY test returns TRUE.

A subquery used with ANY must return a single column.

Example

Find the order and customer IDs of those orders placed after the first product of the order #2005 was shipped.

SELECT id, cust_id
FROM sales_order
WHERE order_date > ANY (
   SELECT ship_date
   FROM sales_order_items
   WHERE id=2005)
id | cust_id
2006 | 105
2007 | 106
2008 | 107
2009 | 108
... | ...

In executing this query, the main query tests the order dates for each order against the shipping dates of every product of the order #2005. If an order date is greater than the shipping date for one shipment of order #2005, then that id and customer id from the sales_order table are part of the result set. The ANY test is thus analogous to the OR operator: the above query can be read, "Was this sales order placed after the first product of the order #2005 was shipped, or after the second product of order #2005 was shipped, or..."

Understanding the ANY operator

The ANY operator can be a bit confusing. It is tempting to read the query as "Return those orders placed after any products of order #2005 were shipped." But this means the query will return the order IDs and customer IDs for the orders placed after all products of order #2005 were shipped—which is not what the query does.

Instead, try reading the query like this: "Return the order and customer IDs for those orders placed after at least one product of order #2005 was shipped." Using the keyword SOME may provide a more intuitive way to phrase the query. The following query is equivalent to the previous query.

SELECT id, cust_id
FROM sales_order
WHERE order_date > SOME (
   SELECT ship_date
   FROM sales_order_items
   WHERE id=2005)

The keyword SOME is equivalent to the keyword ANY.

Notes about the ANY operator

There are two additional important characteristics of the ANY test:

  • Empty subquery result set If the subquery produces an empty result set, the ANY test returns FALSE. This makes sense, since if there are no results, then it is not true that at least one result satisfies the comparison test.

  • NULL values in subquery result set Assume that there is at least one NULL value in the subquery result set. If the comparison test is false for all non-NULL data values in the result set, the ANY search returns NULL. This is because in this situation, you cannot conclusively state whether there is a value for the subquery for which the comparison test holds. There may or may not be a value, depending on the "correct" values for the NULL data in the result set.


The ALL test

Like the ANY test, the ALL test is used in conjunction with one of the six SQL comparison operators (=, <>, <, <=, >, >=) to compare a single value to the data values produced by the subquery. To perform the test, SQL uses the specified comparison operator to compare the test value to each data value in the result set. If all of the comparisons yield TRUE results, the ALL test returns TRUE.

Example

Here is a request naturally handled with the ALL test: "Find the order and customer IDs of those orders placed after all products of order #2001 were shipped."

SELECT id, cust_id
FROM sales_order
WHERE order_date > ALL (
   SELECT ship_date
   FROM sales_order_items
   WHERE id=2001)
id | cust_id
2002 | 102
2003 | 103
2004 | 104
2005 | 101
... | ...

In executing this query, the main query tests the order dates for each order against the shipping dates of every product of order #2001. If an order date is greater than the shipping date for every shipment of order #2001, then the id and customer id from the sales_order table are part of the result set. The ALL test is thus analogous to the AND operator: the above query can be read, "Was this sales order placed before the first product of order #2001 was shipped, and before the second product of order #2001 was shipped, and..."

Notes about the ALL operator

There are three additional important characteristics of the ALL test:

  • Empty subquery result set If the subquery produces an empty result set, the ALL test returns TRUE. This makes sense, since if there are no results, then it is true that the comparison test holds for every value in the result set.

  • NULL values in subquery result set If the comparison test is false for any values in the result set, the ALL search returns FALSE. It returns TRUE if all values are true. Otherwise, it returns UNKNOWN—for example, this can occur if there is a NULL value in the subquery result set but the search condition is TRUE for all non-NULL values.

  • Negating the ALL test The following expressions are not equivalent.

    NOT a = ALL (subquery)
a <> ALL (subquery)

    For more information about this test, see Quantified comparison test.


Testing set membership with IN conditions

You can use the subquery set membership test to compare a value from the main query to more than one value in the subquery.

The subquery set membership test compares a single data value for each row in the main query to the single column of data values produced by the subquery. If the data value from the main query matches one of the data values in the column, the subquery returns TRUE.

Example

Select the names of the employees who head the Shipping or Finance departments:

SELECT emp_fname, emp_lname
FROM employee
WHERE emp_id IN (
   SELECT dept_head_id
   FROM department
   WHERE (dept_name='Finance' or dept_name = 'Shipping'))
emp_fname | emp_lname
Jose | Martinez
Mary Anne | Shea

The subquery in this example

SELECT dept_head_id
FROM department
WHERE (dept_name='Finance' OR dept_name = 'Shipping')

extracts from the department table the id numbers that correspond to the heads of the Shipping and Finance departments. The main query then returns the names of the employees whose id numbers match one of the two found by the subquery.

Set membership test is equivalent to =ANY test

The subquery set membership test is equivalent to the =ANY test. The following query is equivalent to the query from the above example.

SELECT emp_fname, emp_lname
FROM employee
WHERE emp_id =ANY (
   SELECT dept_head_id
   FROM department
   WHERE (dept_name='Finance' or dept_name = 'Shipping'))
Negation of the set membership test

You can also use the subquery set membership test to extract those rows whose column values are not equal to any of those produced by a subquery. To negate a set membership test, insert the word NOT in front of the keyword IN.

Example

The subquery in this query returns the first and last names of the employees that are not heads of the Finance or Shipping departments.

SELECT emp_fname, emp_lname
FROM employee
WHERE emp_id NOT IN (
   SELECT dept_head_id
   FROM department
   WHERE (dept_name='Finance' OR dept_name = 'Shipping'))


Existence test

Subqueries used in the subquery comparison test and set membership test both return data values from the subquery table. Sometimes, however, you may be more concerned with whether the subquery returns any results, rather than which results. The existence test (EXISTS) checks whether a subquery produces any rows of query results. If the subquery produces one or more rows of results, the EXISTS test returns TRUE. Otherwise, it returns FALSE.

Example

Here is an example of a request expressed using a subquery: "Which customers placed orders after July 13, 2001?"

SELECT fname, lname
FROM customer
WHERE EXISTS (
   SELECT *
   FROM sales_order
   WHERE (order_date > '2001-07-13') AND
    (customer.id = sales_order.cust_id))
fname | lname
Almen | de Joie
Grover | Pendelton
Ling Ling | Andrews
Bubba | Murphy
Explanation of the existence test

Here, for each row in the customer table, the subquery checks if that customer ID corresponds to one that has placed an order after July 13, 2001. If it does, the query extracts the first and last names of that customer from the main table.

The EXISTS test does not use the results of the subquery; it just checks if the subquery produces any rows. So the existence test applied to the following two subqueries return the same results. These are subqueries and cannot be processed on their own, because they refer to the customer table which is part of the main query, but not part of the subquery.

For more information, see Correlated subqueries.

SELECT *
FROM sales_order
WHERE (order_date > '2001-07-13') AND (customer.id = sales_order.cust_id)
SELECT ship_date
FROM sales_order
WHERE (order_date > '2001-07-13') AND (customer.id = sales_order.cust_id)

It does not matter which columns from the sales_order table appear in the SELECT statement, though by convention, the "SELECT *" notation is used.

Negating the existence test

You can reverse the logic of the EXISTS test using the NOT EXISTS form. In this case, the test returns TRUE if the subquery produces no rows, and FALSE otherwise.

Correlated subqueries

You may have noticed that the subquery contains a reference to the id column from the customer table. A reference to columns or expressions in the main table(s) is called an outer reference and the subquery is said to be correlated. Conceptually, SQL processes the above query by going through the customer table, and performing the subquery for each customer. If the order date in the sales_order table is after July 13, 2001, and the customer ID in the customer and sales_order tables match, then the first and last names from the customer table appear. Since the subquery references the main query, the subquery in this section, unlike those from previous sections, returns an error if you attempt to run it by itself.


Outer references

Within the body of a subquery, it is often necessary to refer to the value of a column in the active row of the main query. Consider the following query:

SELECT name, description
FROM product
WHERE quantity < 2 * (
   SELECT avg(quantity)
   FROM sales_order_items
   WHERE product.id = sales_order_items.prod_id)

This query extracts the names and descriptions of the products whose in-stock quantities are less than double the average ordered quantity of that product—specifically, the product being tested by the WHERE clause in the main query. The subquery does this by scanning the sales_order_items table. But the product.id column in the WHERE clause of the subquery refers to a column in the table named in the FROM clause of the main query—not the subquery. As SQL moves through each row of the product table, it uses the id value of the current row when it evaluates the WHERE clause of the subquery.

Description of an outer reference

The product.id column in this subquery is an example of an outer reference. A subquery that uses an outer reference is a correlated subquery. An outer reference is a column name that does not refer to any of the columns in any of the tables in the FROM clause of the subquery. Instead, the column name refers to a column of a table specified in the FROM clause of the main query. As the above example shows, the value of a column in an outer reference comes from the row currently being tested by the main query.


Subqueries and joins

The subquery optimizer automatically rewrites as joins many of the queries that make use of subqueries.

Example

Consider the request, "When did Mrs. Clarke and Suresh place their orders, and by which sales representatives?" It can be answered with the following query:

SELECT order_date, sales_rep
FROM sales_order
WHERE cust_id IN (
   SELECT id
   FROM customer
   WHERE lname = 'Clarke' OR fname = 'Suresh')
Order_date | sales_rep
2001-01-05 | 1596
2000-01-27 | 667
2000-11-11 | 467
2001-02-04 | 195
... | ...

The subquery yields a list of customer IDs that correspond to the two customers whose names are listed in the WHERE clause, and the main query finds the order dates and sales representatives corresponding to those two people's orders.

Replacing a subquery with a join

The same question can be answered using joins. Here is an alternative form of the query, using a two-table join:

SELECT order_date, sales_rep
FROM sales_order, customer
WHERE cust_id=customer.id AND
  (lname = 'Clarke' OR fname = 'Suresh')

This form of the query joins the sales_order table to the customer table to find the orders for each customer, and then returns only those records for Suresh and Clarke.

Some joins cannot be written as subqueries

Both of these queries find the correct order dates and sales representatives, and neither is more right than the other. Many people will find the subquery form more natural, because the request doesn't ask for any information about customer IDs, and because it might seem odd to join the sales_order and customer tables together to answer the question.

If, however, the request changes to include some information from the customer table, the subquery form no longer works. For example, the request "When did Mrs. Clarke and Suresh place their orders, and by which representatives, and what are their full names?", it is necessary to include the customer table in the main WHERE clause:

SELECT fname, lname, order_date, sales_rep
FROM sales_order, customer
WHERE cust_id=customer.id AND (lname = 'Clarke' OR fname = 'Suresh')
fname | lname | order_date | sales_rep
Belinda | Clarke | 1/5/01 | 1596
Belinda | Clarke | 1/27/00 | 667
Belinda | Clarke | 11/11/00 | 467
Belinda | Clarke | 2/4/01 | 195
... | ... | ... | ...
Some subqueries cannot be written as joins

Similarly, there are cases where a subquery will work but a join will not. For example:

SELECT name, description, quantity
FROM product
WHERE quantity <  2 * (
   SELECT avg(quantity)
   FROM sales_order_items)
name | description | quantity
Tee Shirt | Tank Top | 28
Baseball Cap | Wool cap | 12
Visor | Cloth Visor | 36
... | ... | ...

In this case, the inner query is a summary query and the outer query is not, so there is no way to combine the two queries by a simple join.

For more information on joins, see Joins: Retrieving Data from Several Tables.


Nested subqueries

As we have seen, subqueries always appear in the HAVING clause or the WHERE clause of a query. A subquery may itself contain a WHERE clause and/or a HAVING clause, and, consequently, a subquery may appear in another subquery. Subqueries inside other subqueries are called nested subqueries.

Examples

List the order IDs and line IDs of those orders shipped on the same day when any item in the fees department was ordered.

SELECT id, line_id
FROM sales_order_items
WHERE ship_date = ANY (
   SELECT order_date
   FROM sales_order
   WHERE fin_code_id IN (
      SELECT code
      FROM fin_code
      WHERE (description = 'Fees')))
id | line_id
2001 | 1
2001 | 2
2001 | 3
2002 | 1
... | ...
Explanation of the nested subqueries

  • In this example, the innermost subquery produces a column of financial codes whose descriptions are "Fees":

SELECT code
FROM fin_code
WHERE (description = 'Fees')

  • The next subquery finds the order dates of the items whose codes match one of the codes selected in the innermost subquery:

SELECT order_date
FROM sales_order
WHERE fin_code_id IN (subquery)

  • Finally, the outermost query finds the order IDs and line IDs of the orders shipped on one of the dates found in the subquery.

SELECT id, line_id
FROM sales_order_items
WHERE ship_date = ANY (subquery)

Nested subqueries can also have more than three levels. Though there is no maximum number of levels, queries with three or more levels take considerably longer to run than do smaller queries.


How subqueries work

Understanding which queries are valid and which ones aren't can be complicated when a query contains a subquery. Similarly, figuring out what a multi-level query does can also be very involved, and it helps to understand how Adaptive Server Anywhere processes subqueries. For general information about processing queries, see Summarizing, Grouping, and Sorting Query Results.

Correlated subqueries
Converting subqueries in the WHERE clause to joins
Comparison operators
Quantified comparison test
Set membership test
Existence test


Correlated subqueries

In a simple query, the database server evaluates and processes the query's WHERE clause once for each row of the query. Sometimes, though, the subquery returns only one result, making it unnecessary for the database server to evaluate it more than once for the entire result set.

Uncorrelated subqueries

Consider this query:

SELECT name, description
FROM product
WHERE quantity <  2 * (
   SELECT avg(quantity)
   FROM sales_order_items)

In this example, the subquery calculates exactly one value: the average quantity from the sales_order_items table. In evaluating the query, the database server computes this value once, and compares each value in the quantity field of the product table to it to determine whether to select the corresponding row.

Correlated subqueries

When a subquery contains an outer reference, you cannot use this shortcut. For instance, the subquery in the query

SELECT name, description
FROM product
WHERE quantity < 2 * (
   SELECT avg(quantity)
   FROM sales_order_items
   WHERE product.id=sales_order_items.prod_id)

returns a value dependent upon the active row in the product table. Such a subquery is called a correlated subquery. In these cases, the subquery might return a different value for each row of the outer query, making it necessary for the database server to perform more than one evaluation.


Converting subqueries in the WHERE clause to joins

The Adaptive Server Anywhere query optimizer converts some multi-level queries to use joins. The conversion is carried out without any user action. This section describes which subqueries can be converted to joins so you can understand the performance of queries in your database.

Example

The question "When did Mrs. Clarke and Suresh place their orders, and by which sales representatives?" can be written as a two-level query:

SELECT order_date, sales_rep
FROM sales_order
WHERE cust_id IN (
   SELECT id
   FROM customer
   WHERE lname = 'Clarke' OR fname = 'Suresh')

An alternate, and equally correct way to write the query uses joins:

SELECT fname, lname, order_date, sales_rep
FROM sales_order, customer
WHERE cust_id=customer.id AND
  (lname = 'Clarke' OR fname = 'Suresh')

The criteria that must be satisfied in order for a multi-level query to be able to be rewritten with joins differ for the various types of operators. Recall that when a subquery appears in the query's WHERE clause, it is of the form

SELECT select-list
FROM table
WHERE
[NOT] expression comparison-operator ( subquery )
| [NOT] expression comparison-operator { ANY | SOME } ( subquery )
| [NOT] expression comparison-operator ALL ( subquery )
| [NOT] expression IN ( subquery )
| [NOT] EXISTS ( subquery )
GROUP BY group-by-expression
HAVING search-condition

Whether a subquery can be converted to a join depends on a number of factors, such as the type of operator and the structures of the query and of the subquery.


Comparison operators

A subquery that follows a comparison operator (=, <>, <, <=, >, >=) must satisfy certain conditions if it is to be converted into a join. Subqueries that follow comparison operators are valid only if they return exactly one value for each row of the main query. In addition to this criterion, a subquery is converted to a join only if the subquery

  • does not contain a GROUP BY clause

  • does not contain the keyword DISTINCT

  • is not a UNION query

  • is not an aggregate query

Example

Suppose the request "When were Suresh's products ordered, and by which sales representative?" were phrased as the subquery

SELECT order_date, sales_rep
FROM sales_order
WHERE cust_id = (
   SELECT id
   FROM customer
   WHERE fname = 'Suresh')

This query satisfies the criteria, and therefore, it would be converted to a query using a join:

SELECT order_date, sales_rep
FROM sales_order, customer
WHERE cust_id=customer.id AND (lname = 'Clarke' OR fname = 'Suresh')

However, the request, "Find the products whose in-stock quantities are less than double the average ordered quantity" cannot be converted to a join, as the subquery contains the aggregate function avg:

SELECT name, description
FROM product
WHERE quantity <  2 * (
   SELECT avg(quantity)
   FROM sales_order_items)


Quantified comparison test

A subquery that follows one of the keywords ALL, ANY and SOME is converted into a join only if it satisfies certain criteria.

  • The main query does not contain a GROUP BY clause, and is not an aggregate query, or the subquery returns exactly one value.

  • The subquery does not contain a GROUP BY clause.

  • The subquery does not contain the keyword DISTINCT.

  • The subquery is not a UNION query.

  • The subquery is not an aggregate query.

  • The conjunct 'expression comparison-operator ANY/SOME (subquery)' must be negated.

  • The conjunct 'expression comparison-operator ALL (subquery)' must not be negated.

The first four of these conditions are relatively straightforward.

Example

The request "When did Ms. Clarke and Suresh place their orders, and by which sales representatives?" can be handled in subquery form:

SELECT order_date, sales_rep
FROM sales_order
WHERE cust_id = ANY (
   SELECT id
   FROM customer
   WHERE lname = 'Clarke' OR fname = 'Suresh')

Alternately, it can be phrased in join form

SELECT fname, lname, order_date, sales_rep
FROM sales_order, customer
WHERE cust_id=customer.id AND (lname = 'Clarke' OR fname = 'Suresh')

However, the request, "When did Ms. Clarke, Suresh, and any employee who is also a customer, place their orders?" would be phrased as a union query, and thus cannot be converted to a join:

SELECT order_date, sales_rep
FROM sales_order
WHERE cust_id = ANY (
   SELECT id
   FROM customer
   WHERE lname = 'Clarke' OR fname = 'Suresh'
   UNION
   SELECT emp_id
   FROM employee)

Similarly, the request "Find the order IDs and customer IDs of those orders that were not placed after all products of order #2001 were shipped," is naturally expressed with a subquery:

SELECT id, cust_id
FROM sales_order
WHERE NOT order_date > ALL (
   SELECT ship_date
   FROM sales_order_items
   WHERE id=2001)

It would be converted to the join:

SELECT sales_order.id, cust_id
FROM sales_order, sales_order_items
WHERE (sales_order_items.id=2001) and (order_date <= ship_date)

However, the request "Find the order IDs and customer IDs of those orders not shipped after the first shipping dates of all the products" would be phrased as the aggregate query:

SELECT id, cust_id
FROM sales_order
WHERE NOT order_date > ALL (
   SELECT first (ship_date)
   FROM sales_order_items )

Therefore, it would not be converted to a join.

Negating subqueries with the ANY and ALL operators

The fifth criterion is a little more puzzling: queries of the form

SELECT select-list
FROM table
WHERE NOT expression comparison-operator ALL( subquery )
are converted to joins, as are queries of the form

SELECT select-list
FROM table
WHERE expression comparison-operator ANY( subquery )

but the queries

SELECT select-list
FROM table
WHERE expression comparison-operator ALL( subquery )

and

SELECT select-list
FROM table
WHERE NOT expression comparison-operator ANY( subquery )

are not.

Logical equivalence of ANY and ALL expressions

This is because the first two queries are in fact equivalent, as are the last two. Recall that the any operator is analogous to the OR operator, but with a variable number of arguments; and that the ALL operator is similarly analogous to the AND operator. Just as the expression

NOT ((X > A) AND (X > B))

is equivalent to the expression

(X <= A) OR (X <= B)

the expression

NOT order_date > ALL (
   SELECT first (ship_date)
   FROM sales_order_items )

is equivalent to the expression

order_date <= ANY (
   SELECT first (ship_date)
   FROM sales_order_items )
Negating the ANY and ALL expressions

In general, the expression

NOT column-name operator ANY( subquery )

is equivalent to the expression

column-name inverse-operator ALL( subquery )

and the expression

NOT column-name operator ALL( subquery )

is equivalent to the expression

column-name inverse-operator ANY( subquery )

where inverse-operator is obtained by negating operator, as shown in the table:

Table of operators and their inverses

The following table lists the inverse of each operator.

Operator | inverse-operator
= | <>
< | =>
> | =<
=< | >
=> | <
<> | =


Set membership test

A query containing a subquery that follows the keyword IN is converted into a join only if:

  • The main query does not contain a GROUP BY clause, and is not an aggregate query, or the subquery returns exactly one value.

  • The subquery does not contain a GROUP BY clause.

  • The subquery does not contain the keyword DISTINCT.

  • The subquery is not a UNION query.

  • The subquery is not an aggregate query.

  • The conjunct 'expression IN (subquery)' must not be negated.

Example

So, the request "Find the names of the employees who are also department heads", expressed by the query:

SELECT emp_fname, emp_lname
FROM employee
WHERE emp_id IN (
   SELECT dept_head_id
   FROM department
   WHERE (dept_name='Finance' or dept_name = 'Shipping'))

would be converted to a joined query, as it satisfies the conditions. However, the request, "Find the names of the employees who are either department heads or customers" would not be converted to a join if it were expressed by the UNION query.

A UNION query following the IN operator can't be converted
SELECT emp_fname, emp_lname
FROM employee
WHERE emp_id IN (
   SELECT dept_head_id
   FROM department
   WHERE (dept_name='Finance' or dept_name = 'Shipping')
   UNION
   SELECT cust_id
   FROM sales_order)

Similarly, the request "Find the names of employees who are not department heads" is formulated as the negated subquery

SELECT emp_fname, emp_lname
FROM employee
  WHERE NOT emp_id IN (
   SELECT dept_head_id
   FROM department
   WHERE (dept_name='Finance' OR dept_name = 'Shipping'))

and would not be converted.

The conditions that must be fulfilled for a subquery that follows the IN keyword and the ANY keyword to be converted to a join are identical. This is not a coincidence, and the reason for this is that the expression

A query with an IN operator can be converted to one with an ANY operator

WHERE column-name IN( subquery )

is logically equivalent to the expression

WHERE column-name = ANY( subquery )

So the query

SELECT emp_fname, emp_lname
FROM employee
WHERE emp_id IN (
   SELECT dept_head_id
   FROM department
   WHERE (dept_name='Finance' or dept_name = 'Shipping'))

is equivalent to the query

SELECT emp_fname, emp_lname
FROM employee
WHERE emp_id = ANY (
   SELECT dept_head_id
   FROM department
   WHERE (dept_name='Finance' or dept_name = 'Shipping'))

Conceptually, Adaptive Server Anywhere converts a query with the IN operator to one with an ANY operator, and decides accordingly whether to convert the subquery to a join.


Existence test

A subquery that follows the keyword EXISTS is converted to a join only if it satisfies the following two conditions:

  • The main query does not contain a GROUP BY clause, and is not an aggregate query, or the subquery returns exactly one value.

  • The conjunct 'EXISTS (subquery)' is not negated.

  • The subquery is correlated; that is, it contains an outer reference.

Example

Therefore, the request, "Which customers placed orders after July 13, 2001?", which can be formulated by this query whose non-negated subquery contains the outer reference customer.id = sales_order.cust_id, could be converted to a join.

SELECT fname, lname
FROM customer
WHERE EXISTS (
   SELECT *
   FROM sales_order
   WHERE (order_date > '2001-07-13')
 AND (customer.id = sales_order.cust_id))

The EXISTS keyword essentially tells the database server to check for empty result sets. When using inner joins, the database server automatically displays only the rows where there is data from all of the tables in the FROM clause. So, this query returns the same rows as does the one with the subquery:

SELECT fname, lname
FROM customer, sales_order
WHERE (sales_order.order_date > '2001-07-13')
AND (customer.id = sales_order.cust_id)


Adding, Changing, and Deleting Data

About this chapter

This chapter describes how to modify the data in a database.

Most of the chapter is devoted to the INSERT, UPDATE, and DELETE statements, as well as statements for bulk loading and unloading.


Data modification statements

The statements you use to add, change, or delete data are called data modification statements. The most common such statements include:

  • Insert adds new rows to a table

  • Update changes existing rows in a table

  • Delete removes specific rows from a table

Any single INSERT, UPDATE, or DELETE statement changes the data in only one table or view.

In addition to the common statements, the LOAD TABLE and TRUNCATE TABLE statements are especially useful for bulk loading and deleting of data.

Sometimes, the data modification statements are collectively known as the data modification language (DML) part of SQL.


Permissions for data modification

You can only execute data modification statements if you have the proper permissions on the database tables you want to modify. The database administrator and the owners of database objects use the GRANT and REVOKE statements to decide who has access to which data modification functions.

Permissions can be granted to individual users, groups, or the public group. For more information on permissions, see Managing User IDs and Permissions.


Transactions and data modification

When you modify data, the transaction log stores a copy of the old and new state of each row affected by each data modification statement. This means that if you begin a transaction, realize you have made a mistake, and roll the transaction back, you also restore the database to its previous condition.

For more information about transactions, see Using Transactions and Isolation Levels.


Adding data using INSERT

You add rows to the database using the INSERT statement. The INSERT statement has two forms: you can use the VALUES keyword or a SELECT statement:

INSERT using values

The VALUES keyword specifies values for some or all of the columns in a new row. A simplified version of the syntax for the INSERT statement using the VALUES keyword is:

INSERT [ INTO ] table-name [ ( column-name, ... ) ]
VALUES ( expression , ... )

You can omit the list of column names if you provide a value for each column in the table, in the order in which they appear when you execute a query using SELECT *.

INSERT from SELECT

You can use SELECT within an INSERT statement to pull values from one or more tables. If the table you are inserting data into has a large number of columns, you can also use WITH AUTO NAME to simplify the syntax. Using WITH AUTO NAME, you only need to specify the column names in the SELECT statement, rather than in both the INSERT and the SELECT statements. The names in the SELECT statement must be column references or aliased expressions.

A simplified version of the syntax for the INSERT statement using a select statement is:

INSERT [ INTO ] table-name
WITH AUTO NAME select-statement

For more information about the INSERT statement, see the INSERT statement.


Inserting values into all columns of a row

The following INSERT statement adds a new row to the department table, giving a value for every column in the row:

INSERT INTO department
VALUES ( 702, 'Eastern Sales', 902 )
Notes

  • Type the values in the same order as the column names in the original CREATE TABLE statement, that is, first the ID number, then the name, then the department head ID.

  • Surround the values by parentheses.

  • Enclose all character data in single quotes.

  • Use a separate insert statement for each row you add.


Inserting values into specific columns

You can add data to some columns in a row by specifying only those columns and their values. Define all other columns not included in the column list must to allow NULL or have defaults. If you skip a column that has a default value, the default appears in that column.

Adding data in only two columns, for example, dept_id and dept_name, requires a statement like this:

INSERT INTO department (dept_id, dept_name)
VALUES ( 703, 'Western Sales' )

The dept_head_id column has no default, but can allow NULL. A NULL is assigned to that column.

The order in which you list the column names must match the order in which you list the values. The following example produces the same results as the previous one:

INSERT INTO department (dept_name, dept_id )
VALUES ('Western Sales', 703)
Values for unspecified columns

When you specify values for only some of the columns in a row, one of four things can happen to the columns with no values specified:

  • NULL entered NULL appears if the column allows NULL and no default value exists for the column.

  • A default value entered The default value appears if a default exists for the column.

  • A unique, sequential value entered A unique, sequential value appears if the column has the AUTOINCREMENT default or the IDENTITY property.

  • INSERT rejected, and an error message appears An error message appears if the column does not allow NULL and no default exists.

By default, columns allow NULL unless you explicitly state NOT NULL in the column definition when creating tables. You can alter the default using the ALLOW_NULLS_BY_DEFAULT option.

Restricting column data using constraints

You can create constraints for a column or domain. Constraints govern the kind of data you can or cannot add.

For more information on constraints, see Using table and column constraints.

Explicitly inserting NULL

You can explicitly insert NULL into a column by typing NULL. Do not enclose this in quotes, or it will be taken as a string.

For example, the following statement explicitly inserts NULL into the dept_head_id column:

INSERT INTO department
VALUES (703, 'Western Sales', NULL )
Using defaults to supply values

You can define a column so that, even though the column receives no value, a default value automatically appears whenever a row is inserted. You do this by supplying a default for the column.

For more information about defaults, see Using column defaults.


Adding new rows with SELECT

To pull values into a table from one or more other tables, you can use a SELECT clause in the INSERT statement. The select clause can insert values into some or all of the columns in a row.

Inserting values for only some columns can come in handy when you want to take some values from an existing table. Then, you can use update to add the values for the other columns.

Before inserting values for some, but not all, columns in a table, make sure that either a default exists, or you specify NULL for the columns for which you are not inserting values. Otherwise, an error appears.

When you insert rows from one table into another, the two tables must have compatible structures—that is, the matching columns must be either the same data types or data types between which Adaptive Server automatically converts.

Example

If the columns are in the same order in their create table statements, you do not need to specify column names in either table. Suppose you have a table named newproduct that contains some rows of product information in the same format as in the product table. To add to product all the rows in newproduct:

INSERT product
SELECT *
FROM newproduct

You can use expressions in a SELECT statement inside an INSERT statement.

Inserting data into some columns

You can use the SELECT statement to add data to some, but not all, columns in a row just as you do with the VALUES clause. Simply specify the columns to which you want to add data in the INSERT clause.

Inserting Data from the Same Table

You can insert data into a table based on other data in the same table. Essentially, this means copying all or part of a row.

For example, you can insert new products, based on existing products, into the product table. The following statement adds new Extra Large Tee Shirts (of Tank Top, V-neck, and Crew Neck varieties) into the product table. The identification number is ten greater than the existing sized shirt:

INSERT INTO product
SELECT id+ 10, name, description,
    'Extra large', color, 50, unit_price
FROM product
WHERE name = 'Tee Shirt'


Inserting documents and images

If you want to store documents or images in LONG BINARY columns in your database, you can write an application that reads the contents of the file into a variable, and supplies that variable as a value for an INSERT statement.

For more information about adding INSERT statements to applications, see How to use prepared statements, and SET statement.

You can also use the xp_read_file system function to insert file contents into a table. This function is useful if you want to insert file contents from Interactive SQL, or some other environment that does not provide a full programming language.

DBA authority is required to use this external function.

Example

In this example, you create a table, and insert an image into a column of the table. You can carry out these steps from Interactive SQL.

  1. Create a table to hold some images.

    CREATE TABLE pictures
( c1 INT DEFAULT AUTOINCREMENT PRIMARY KEY,
   filename VARCHAR(254),
   picture LONG BINARY )

  2. Insert the contents of portrait.gif , in the current working directory of the database server, into the table.

    INSERT INTO pictures (filename, picture)
VALUES (    'portrait.gif',
   xp_read_file( 'portrait.gif' ) )

For more information, see xp_read_file system procedure.


Changing data using UPDATE

You can use the UPDATE statement, followed by the name of the table or view, to change single rows, groups of rows, or all rows in a table. As in all data modification statements, you can change the data in only one table or view at a time.

The UPDATE statement specifies the row or rows you want changed and the new data. The new data can be a constant or an expression that you specify or data pulled from other tables.

If an UPDATE statement violates an integrity constraint, the update does not take place and an error message appears. For example, if one of the values being added is the wrong data type, or if it violates a constraint defined for one of the columns or data types involved, the update does not take place.

UPDATE syntax

A simplified version of the UPDATE syntax is:

UPDATE table-name
SET column_name = expression
WHERE search-condition

If the company Newton Ent. (in the customer table of the sample database) is taken over by Einstein, Inc., you can update the name of the company using a statement such as the following:

UPDATE customer
SET company_name = 'Einstein, Inc.'
WHERE company_name = 'Newton Ent.'

You can use any expression in the WHERE clause. If you are not sure how the company name was spelled, you could try updating any company called Newton, with a statement such as the following:

UPDATE customer
SET company_name = 'Einstein, Inc.'
WHERE company_name LIKE 'Newton%'

The search condition need not refer to the column being updated. The company ID for Newton Entertainments is 109. As the ID value is the primary key for the table, you could be sure of updating the correct row using the following statement:

UPDATE customer
SET company_name = 'Einstein, Inc.'
WHERE id = 109
The SET clause

The SET clause specifies the columns to be updated, and their new values. The WHERE clause determines the row or rows to be updated. If you do not have a WHERE clause, the specified columns of all rows are updated with the values given in the SET clause.

You can provide any expression of the correct data type in the SET clause.

The WHERE clause

The WHERE clause specifies the rows to be updated. For example, the following statement replaces the One Size Fits All Tee Shirt with an Extra Large Tee Shirt

UPDATE product
SET size  = 'Extra Large'
WHERE name = 'Tee Shirt'
   AND size = 'One Size Fits All'
The FROM clause

You can use a FROM clause to pull data from one or more tables into the table you are updating.


Changing data using INSERT

You can use the ON EXISTING clause of the INSERT statement to update existing rows in a table (based on primary key lookup) with new values. This clause can only be used on tables that have a primary key. Attempting to use this clause on tables without primary keys or on proxy tables generates a syntax error.

Specifying the ON EXISTING clause causes the server to do a primary key lookup for each input row. If the corresponding row does not exist, it inserts the new row. For rows already existing in the table, you can choose to:

  • generate an error for duplicate key values. This is the default behavior if the ON EXISTING clause is not specified.

  • silently ignore the input row, without generating any errors.

  • update the existing row with the values in the input row

For more information, see the INSERT statement.


Deleting data using DELETE

Simple DELETE statements have the following form:

DELETE [ FROM ] table-name
WHERE column-name = expression

You can also use a more complex form, as follows

DELETE [ FROM ] table-name
FROM table-list
WHERE search-condition

The WHERE clause

Use the WHERE clause to specify which rows to remove. If no WHERE clause appears, the DELETE statement remove all rows in the table.

The FROM clause

The FROM clause in the second position of a DELETE statement is a special feature allowing you to select data from a table or tables and delete corresponding data from the first-named table. The rows you select in the FROM clause specify the conditions for the delete.

Example

This example uses the sample database. To execute the statements in the example, you should set the option WAIT_FOR_COMMIT to OFF. The following statement does this for the current connection only:

SET TEMPORARY OPTION WAIT_FOR_COMMIT = 'OFF'

This allows you to delete rows even if they contain primary keys referenced by a foreign key, but does not permit a COMMIT unless the corresponding foreign key is deleted also.

The following view displays products and the value of that product that has been sold:

CREATE VIEW ProductPopularity as
SELECT  product.id,
   SUM(product.unit_price * sales_order_items.quantity) as "Value Sold"
FROM  product JOIN sales_order_items
ON product.id = sales_order_items.prod_id
GROUP BY product.id

Using this view, you can delete those products which have sold less than $20,000 from the product table.

DELETE
FROM product
FROM product NATURAL JOIN ProductPopularity
WHERE "Value Sold" < 20000

You should roll back your changes when you have completed the example:

ROLLBACK

Deleting all rows from a table


Deleting all rows from a table

You can use the TRUNCATE TABLE statement as a fast method of deleting all the rows in a table. It is faster than a DELETE statement with no conditions, because the delete logs each change, while the transaction log does not record truncate table operations individually.

The table definition for a table emptied with the TRUNCATE TABLE statement remains in the database, along with its indexes and other associated objects, unless you execute a DROP TABLE statement.

You cannot use TRUNCATE TABLE if another table has rows that reference it through a referential integrity constraint. Delete the rows from the foreign table, or truncate the foreign table and then truncate the primary table.

TRUNCATE TABLE syntax

The syntax of truncate table is:

TRUNCATE TABLE table-name

For example, to remove all the data in the sales_order table, type the following:

TRUNCATE TABLE sales_order

A TRUNCATE TABLE statement does not fire triggers defined on the table.


Query Optimization and Execution

About this chapter

Once each query is parsed, the optimizer analyzes it and decides on an access plan that will compute the result using as few resources as possible. This chapter describes the steps the optimizer goes through to optimize a query. It documents the assumptions that underlie the design of the optimizer, and discusses selectivity estimation, cost estimation, and the other steps of optimization.

Although update, insert, and delete statements must also be optimized, the focus of this chapter is on select queries. The optimization of these other commands follows similar principles.

The role of the optimizer
How the optimizer works
Query execution algorithms
Physical data organization and access
Indexes
Semantic query transformations
Subquery and function caching
Reading access plans


The role of the optimizer

The role of the optimizer is to devise an efficient way to execute SQL statements. The optimizer expresses its chosen method in the form of an access plan. The access plan describes which tables to scan, which index, if any, to use for each table, which join strategy to use, and what order to read the tables in. Often, a great number of plans exist that all accomplish the same goal. Other variables may further enlarge the number of possible access plans.

Cost based

The optimizer begins selecting for the choices available using efficient, and in some cases proprietary, algorithms. It bases its decisions on predictions of the resources each query requires. The optimizer takes into account both the cost of disk access operations and the estimated CPU cost of each operation.

Syntax independent

Most commands may be expressed in many different ways using the SQL language. These expressions are semantically equivalent in that they accomplish the same task, but may differ substantially in syntax. With few exceptions, the Adaptive Server Anywhere optimizer devises a suitable access plan based only on the semantics of each statement.

Syntactic differences, although they may appear to be substantial, usually have no effect. For example, differences in the order of predicates, tables, and attributes in the query syntax have no affect on the choice of access plan. Neither is the optimizer affected by whether or not a query contains a view.

A good plan, not necessarily the best plan

The goal of the optimizer is to find a good access plan. Ideally, the optimizer would identify the most efficient access plan possible, but this goal is often impractical. Given a complicated query, a great number of possibilities may exist.

However efficient the optimizer, analyzing each option takes time and resources. The optimizer compares the cost of further optimization with the cost of executing the best plan it has found so far. If a plan has been devised that has a relatively low cost, the optimizer stops and allows execution of that plan to proceed. Further optimization might consume more resources than would execution of an access plan already found.

In the case of expensive and complicated queries, the optimizer works longer. In the case of very expensive queries, it may run long enough to cause a discernible delay.


How the optimizer works

The Adaptive Server Anywhere optimizer must decide the order in which to access tables in a query, and whether or not to use an index for each table. The optimizer attempts to pick the best strategy.

The best strategy for executing each query is the one that gets the results in the shortest period of time, with the least cost. The optimizer determines the cost of each strategy by estimating the number of disk reads and writes required, and chooses the strategy with the lowest cost.

The optimizer uses a generic disk access cost model to differentiate the relative performance differences between random and sequential retrieval on the database file. It is possible to calibrate a database for a particular hardware configuration using an ALTER DATABASE statement. The particulars of a specific cost model can be determined with the sa_get_dtt() stored procedure.

By default, query processing is optimized towards returning the complete result set. You can change this, using the OPTIMIZATION_GOAL option, to minimize the cost of returning the first row quickly.

You can view the access plan for any query in Interactive SQL by opening the Plan tab in the Results pane. To change the degree of detail that is displayed, change the setting in the Plan tab of the Options dialog (available from the Tools menu).

For more information about optimization goals, see OPTIMIZATION_GOAL option [database].

For more information about reading access plans, see Reading access plans.


Optimizer estimates and histograms

The optimizer chooses a strategy for processing a statement based on histograms stored in the database and on heuristics (educated guesses).

Histograms

Histograms, also called column statistics, store information about the distribution of values in a column. In Adaptive Server Anywhere, a histogram represents the data distribution for a column by dividing the domain of the column into a set of consecutive value ranges (also called buckets) and by remembering, for each value range (or bucket), the number of rows in the table for which the column value falls in the bucket.

Adaptive Server Anywhere pays particular attention to single column values that are present in a large number of rows in the table. Significant single value selectivities are maintained in singleton histogram buckets (for example, buckets that encompass a single value in the column domain). Adaptive Server Anywhere tries to maintain a minimum number of singleton buckets in each histogram, usually between 10 and 100 depending upon the size of the table. Additionally, all single values with selectivities greater than 1% are kept as singleton buckets. As a result, a histogram for a given column remembers the top N single value selectivities for the column where the value of N is dependent upon the size of the table and the number of single value selectivities that are greater than 1%.

Once the minimum number of value ranges have been met, low-selectivity frequencies are replaced by large-selectivity frequencies as they come along. The histogram will only have more than the minimum number of singleton value ranges after it has seen enough values with a selectivity of greater than 1%.

Adaptive Server Anywhere updates histograms as a by-product of query execution. As queries are executed, Adaptive Server Anywhere compares the number of rows estimated by the histograms for a given predicate with the number of rows actually found to satisfy the predicate, and then adjusts the values in the histogram to reduce the margin of error for subsequent optimizations.

Adaptive Server Anywhere also creates or updates histograms during LOAD TABLE and UPDATE statements as well as on CREATE INDEX statements.

Heuristics

For each table in a potential execution plan, the optimizer estimates the number of rows that will form part of the results. The number of rows depends on the size of the table and the restrictions in the WHERE clause or the ON clause of the query.

Given the histogram on a column, Adaptive Server Anywhere estimates the number of rows satisfying a given query predicate on the column by adding up the number of rows in all value ranges that overlap the values satisfying the specified predicate. For value ranges in the histograms that are partially contained in the query result set, Adaptive Server Anywhere uses interpolation within the value range.

In many cases, the optimizer uses more sophisticated heuristics. For example, the optimizer uses default estimates only in cases where better statistics are unavailable. As well, the optimizer makes use of indexes and keys to improve its guess of the number of rows. The following are a few single-column examples:

  • Equating a column to a value: estimate one row when the column has a unique index or is the primary key.

  • A comparison of an indexed column to a constant: probe the index to estimate the percentage of rows that satisfy the comparison.

  • Equating a foreign key to a primary key (key join): use relative table sizes in determining an estimate. For example, if a 5000 row table has a foreign key to a 1000 row table, the optimizer guesses that there are five foreign key rows for each primary key row.

See also

For more information about histograms, see SYSCOLSTAT system table.

For information about obtaining the selectivities of predicates and the distribution of column values, see the following:

  • sa_get_histogram system procedure
  • The Histogram utility
  • ESTIMATE function [Miscellaneous]
  • ESTIMATE_SOURCE function [Miscellaneous]

Updating column statistics


Updating column statistics

Column statistics are stored permanently in the database in the system table SYSCOLSTAT. Statistics are automatically updated if a significant amount of data is changed using the INSERT, UPDATE, or DELETE statements.

If you suspect that performance is suffering because your statistics inaccurately reflect the current column values, you may want to execute the statements DROP STATISTICS or CREATE STATISTICS. CREATE STATISTICS deletes old statistics and creates new ones, while DROP STATISTICS just deletes the existing statistics.

With more accurate statistics available to it, the optimizer can compute better estimates, thus improving the performance of subsequent queries. However, incorrect estimates are only a problem if they lead to poorly optimized queries.

When you execute LOAD TABLE, statistics are created for the table. Adaptive Server Anywhere automatically creates histograms for tables with five or more rows. However, when a CREATE STATISTICS statement is executed, a histogram is created for the specified table, regardless of the number of rows.

For more information about column statistics, see:

  • SYSCOLSTAT system table

  • DROP STATISTICS statement

  • CREATE STATISTICS statement


Automatic performance tuning

One of the most common constraints in a query is equality with a column value. The following example tests for equality of the sex column.

SELECT *
FROM employee
WHERE sex = 'f'

Queries often optimize differently at the second execution. For the above type of constraint, Adaptive Server Anywhere learns from experience, automatically allowing for columns that have an unusual distribution of values. The database stores this information permanently unless you explicitly delete it using the DROP STATISTICS command. Note that subsequent queries with predicates over that column may cause the server to recreate a histogram on the column.


Underlying assumptions

A number of assumptions underlie the design direction and philosophy of the Adaptive Server Anywhere query optimizer. You can improve the quality or performance of your own applications through an understanding of the optimizer's decisions. These assumptions provide a context in which you may understand the information contained in the remaining sections.

Minimal administration work
Optimize for first rows or for entire result set
Optimize for mixed or OLAP workload
Statistics are present and correct
An index can usually be found to satisfy a predicate
Virtual memory is a scarce resource
Rewriting subqueries as EXISTS predicates


Minimal administration work

Traditionally, high performance database servers have relied heavily on the presence of a knowledgeable, dedicated, database administrator. This person spent a great deal of time adjusting data storage and performance controls of all kinds to achieve good database performance. These controls often required continuing adjustment as the data in the database changed.

Adaptive Server Anywhere learns and adjusts as the database grows and changes. Each query betters its knowledge of the data distribution in the database. Adaptive Server Anywhere automatically stores and uses this information to optimize future queries.

Every query both contributes to this internal knowledge and benefits from it. Every user can benefit from knowledge that Adaptive Server Anywhere has gained through executing another user's query.

Statistics-gathering mechanisms are thus an integral part of the database server, and require no external mechanism. Should you find an occasion where it would help, you can provide the database server with estimates of data distributions to use during optimization. If you encode these into a trigger or procedure, for example, you then assume responsibility for maintaining these estimates and updating them whenever appropriate.


Optimize for first rows or for entire result set

The OPTIMIZATION_GOAL option allows you to specify whether query processing should be optimized towards returning the first row quickly, or minimizing the cost of returning the complete result set. The default is first row.

For more information, see OPTIMIZATION_GOAL option [database].


Optimize for mixed or OLAP workload

The OPTIMIZATION_WORKLOAD option allows you to specify whether query processing should be optimized towards databases where updates, deletes, or inserts are commonly executed concurrently with queries (Mixed workload) or whether the main form of update activity in the database is batch-style updates that are rarely executed concurrently with query execution.

For more information, see OPTIMIZATION_WORKLOAD option [database].


Statistics are present and correct

The optimizer is self-tuning, storing all the needed information internally. The system table SYSCOLSTAT is a persistent repository of data distributions and predicate selectivity estimates. At the completion of each query, Adaptive Server Anywhere uses statistics gathered during query execution to update SYSCOLSTAT. In consequence, all subsequent queries gain access to more accurate estimates.

The optimizer relies heavily on these statistics and, therefore, the quality of the access plans it generates depends heavily on them. If you recently inserted a lot of new rows, these statistics may no longer accurately describe the data. You may find that your subsequent queries execute unusually slowly.

If you have significantly altered your data, and you find that query execution is slow, you may want to execute DROP STATISTICS and/or CREATE STATISTICS.


An index can usually be found to satisfy a predicate

Often, Adaptive Server Anywhere can evaluate predicates with the aid of an index. Using an index, the optimizer speeds access to data and reduces the amount of information read. For example, when OPTIMIZATION_GOAL is set to first-row, the Adaptive Server Anywhere optimizer will try to use indexes to satisfy ORDER BY and GROUP BY clauses.

When the optimizer cannot find a suitable index, it resorts to a sequential table scan, which can be expensive. An index can improve performance dramatically when joining tables. Add indexes to tables or rewrite queries wherever doing so facilitates the efficient processing of common requests.


Virtual memory is a scarce resource

The operating system and a number of applications frequently share the memory of a typical computer. Adaptive Server Anywhere treats memory as a scarce resource. Because it uses memory economically, Adaptive Server Anywhere can run on relatively small computers. This economy is important if you wish your database to operate on portable computers or on older machines.

Reserving extra memory, for example to hold the contents of a cursor, may be expensive. If the buffer cache is full, one or more pages may have to be written to disk to make room for new pages. Some pages may need to be re-read to complete a subsequent operation.

In recognition of this situation, Adaptive Server Anywhere associates a higher cost with execution plans that require additional buffer cache overhead. This cost discourages the optimizer from choosing plans that use work tables.

On the other hand, it is careful to use memory where it improves performance. For example, it caches the results of subqueries when they will be needed repeatedly during the processing of the query.


Rewriting subqueries as EXISTS predicates

The assumptions which underlie the design of Adaptive Server Anywhere require that it conserves memory and that by default it returns the first few results of a cursor as quickly as possible. In keeping with these objectives, Adaptive Server Anywhere rewrites all set-operation subqueries, such as IN, ANY, or SOME predicates, as EXISTS predicates. By doing so, Adaptive Server Anywhere avoids creating unnecessary work tables and may more easily identify a suitable index through which to access a table.

Non-correlated subqueries are subqueries that contain no explicit reference to the table or tables contained in the rest higher-level portions of the query.

The following is an ordinary query that contains a non-correlated subquery. It selects information about all the customers who did not place an order on January 1, 2001.

Non-correlated subquery
SELECT *
FROM customer c
WHERE c.id NOT IN
   (   SELECT o.cust_id
      FROM sales_order o
      WHERE o.order_date = '2001-01-01' )

One possible way to evaluate this query is to first read the sales_order table and create a work table of all the customers who placed orders on January 1, 2001, then read the customer table and extract one row for each customer listed in the work table.

However, Adaptive Server Anywhere avoids materializing results as work tables. It also gives preference to plans that return the first few rows of a result most quickly. Thus, the optimizer rewrites such queries using EXISTS predicates. In this form, the subquery becomes correlated: the subquery now contains an explicit reference to the id column of the customer table.

Correlated subquery
SELECT *
FROM customer c
WHERE NOT EXISTS
   (   SELECT *
      FROM sales_order o
      WHERE o.order_date = '2000-01-01'
         AND o.cust_id = c.id )

c<seq> : o<key_so_customer>

This query is semantically equivalent to the one above, but when expressed in this new syntax, two advantages become apparent.

  1. The optimizer can choose to use either the index on the cust_id attribute or the order_date attribute of the sales_order table. (However, in the sample database, only the id and cust_id columns are indexed.)

  2. The optimizer has the option of choosing to evaluate the subquery without materializing intermediate results as work tables.

Adaptive Server Anywhere can cache the results of this correlated subquery during processing. This strategy lets Adaptive Server Anywhere reuse previously computed results. In the case of query above, caching does not help because customer identification numbers are unique in the customer table.

Further information on subquery caching is located in Subquery and function caching.


Access plan caching

Normally, the optimizer selects an access plan for a query every time the query is executed. Optimizing at execution time allows the optimizer to choose a plan based on current system state, as well as the values of current selectivity estimates and estimates based on the values of host variables. For queries that are executed very frequently, the cost of query optimization can outweigh the benefits of optimizing at execution time. For queries and INSERT, UPDATE and DELETE statements performed inside stored procedures, stored functions, and triggers, the optimizer caches execution plans between executions of the query.

After a statement in a stored procedure, stored function, or trigger has been executed several times by one connection, the optimizer builds a reusable plan for the statement. A reusable plan does not use the values of host variables for selectivity estimation or rewrite optimizations. The reusable plan may have a higher cost because of this. If the cost of the reusable plan is close to the best observed cost for the statement, the optimizer will choose to add the reusable plan to a plan cache. Otherwise, the benefit of optimizing on each execution outweighs the savings from avoiding optimization, and the execution plan is not cached.

The plan cache is a per-connection cache of the data structures used to execute an access plan. Reusing the cached plan involves looking up the plan in the cache and resetting it to an initial state. This is typically substantially faster than optimizing the statement. Cached plans may be stored to disk if they are used infrequently, and they do not increase the cache usage. The optimizer periodically re-optimizes queries to verify that the cached plan is still relatively efficient.

You can use the database or connection property QueryCachePages to determine the number of pages used to cache execution plans. These pages occupy space in the temporary file, but are not necessarily resident in memory.

You can use QueryCachedPlans statistic to show how many query execution plans are currently cached. This property can be retrieved using CONNECTION_PROPERTY to show how many query execution plans are cached for a given connection, or DB_PROPERTY can be used to count the number of cached execution plans across all connections. This property can be used in combination with QueryCachePages, QueryOptimized, QueryBypassed, and QueryReused to help determine the best setting for the MAX_PLANS_CACHED option

The maximum number of plans to cache is specified with the option setting MAX_PLANS_CACHED. The default is 20. To disable plan caching, set this option to 0.

For more information, see MAX_PLANS_CACHED option [database].


Steps in optimization

The steps the Adaptive Server Anywhere optimizer follows in generating a suitable access plan include the following.

  1. The parser converts the SQL query into an internal representation. It may rewrite the query, converting it to a syntactically different, but semantically equivalent, form. For example, a subquery may be rewritten as a join. These conversions make the statement easier to analyze.

  2. Optimization proper commences just before execution. If you are using cursors in your application, optimization commences when the cursor is opened. Unlike many other commercial database systems, Adaptive Server Anywhere optimizes each statement just before executing it.

  3. The optimizer performs semantic optimization on the statement. It rewrites each SQL statement whenever doing so leads to better, more efficient access plans.

  4. The optimizer performs join enumeration for each subquery.

  5. The optimizer optimizes access order.

Because Adaptive Server Anywhere performs just-in-time optimization of each statement, the optimizer has access to the values of host variables and stored procedure variables. Hence, it makes better choices because it performs better selectivity analysis.

Adaptive Server Anywhere optimizes each query you execute, regardless of how many times you executed it before, with the exception of queries that are contained in stored procedures or user-defined functions. For queries contained in stored procedures or user-defined functions, the optimizer may cache the access plans so that they can be reused.

For more information, see Access plan caching.

Because Adaptive Server Anywhere saves statistics each time it executes a query, the optimizer can learn from the experience of executing previous plans and can adjust its choices when appropriate.

Simple queries

If a query is recognized as a simple query, a heuristic rather than cost-based optimization is used—the optimizer decides whether to use and index scan or sequential table scan, and builds and executes the access plan immediately. Steps 4 and 5 are bypassed.

A simple query is a DYNAMIC SCROLL or NO SCROLL cursor that does not contain any kind of subquery, more than one table, a proxy table, user defined functions, NUMBER(*), UNION, aggregation, DISTINCT, GROUP BY, or more than one predicate on a single column. Simple queries can contain ORDER BY only as long as the WHERE clause contains conditions on each primary key column.


Query execution algorithms

The following is an explanation of the algorithms Adaptive Server Anywhere uses to compute queries.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL User's Guide

Query Optimization and Execution

Query execution algorithms

Table access algorithms

The basic ways to access single tables are the index scan and the sequential table scan.


Index scans

An index scan uses an index to determine which rows satisfy a search condition. It reads only those pages that satisfy the condition. Indexes can return rows in sorted order.

Index scans are displayed in the short and long plan as correlation_name<index_name>, where correlation_name is the correlation name specified in the FROM clause, or the table name if none was specified; and index_name is the name of the index.

Indexes provide an efficient mechanism for reading a few rows from a large table. However, index scans cause pages to be read from the database in random order, which is more expensive than sequential reads. Index scans may also reference the same table page multiple times if there are several rows on the page that satisfy the search condition. If only a few pages are matched by the index scan, it is likely that the pages will remain in cache, and multiple access does not lead to extra I/O. However, if many pages are matched by the search condition, they may not all fit in cache. This can lead to the index scan reading the same page from disk multiple times.

The optimizer will tend to prefer index scans over sequential table scans if the OPTIMIZATION_GOAL setting is first-row. This is because indexes tend to return the first few rows of a query faster than table scans.

Indexes can also be used to satisfy an ordering requirement, either explicitly defined in an ORDER BY clause, or implicitly needed for a GROUP BY or DISTINCT clause. Ordered group-by and ordered distinct methods can return initial rows faster than hash-based grouping and distinct, but they may be slower at returning the entire result set.

The optimizer uses an index scan to satisfy a search condition if the search condition is sargable, and if the optimizer's estimate of the selectivity of the search condition is sufficiently low for the index scan to be cheaper than a sequential table scan.

An index scan can also evaluate non-sargable search conditions after rows are fetched from the index. Evaluating conditions in the index scan is slightly more efficient than evaluating them in a filter after the index scan.

For more information about when Adaptive Server Anywhere can make use of indexes, see Predicate analysis.

For more information about optimization goals, see OPTIMIZATION_GOAL option [database].


Sequential table scans

A sequential table scan reads all the rows in all the pages of a table in the order in which they are stored in the database.

Sequential table scans are displayed in the short and long plan as correlation_name<seq>, where correlation_name is the correlation name specified in the FROM clause, or the table name if none was specified.

This type of scan is used when it is likely that a majority of table pages have a row that match the query's search condition or a suitable index is not defined.

Although sequential table scans may read more pages than index scans, the disk I/O can be substantially cheaper because the pages are read in contiguous blocks from the disk (this performance improvement is best if the database file is not fragmented on the disk). Sequential I/O minimizes overhead due to disk head movement and rotational latency. For large tables, sequential table scans also read groups of several pages at a time. This further reduces the cost of sequential table scans relative to index scans.

Although sequential table scans may take less time than index scans that match many rows, they also cannot exploit the cache as effectively as index scans if the scan is executed many times. Since index scans are likely to access fewer table pages, it is more likely that the pages will be available in the cache, resulting in faster access. Because of this, it is much better to have an index scan for table accesses that are repeated, such as the right hand side of a nested loops join.

For isolation level 3, Adaptive Server Anywhere acquires a lock on each row that is accessed—even if it does not satisfy the search condition. For this level, sequential table scans acquire locks on all of the rows in the table, while index scans only acquire locks on the rows that match the search condition. This means that sequential table scans may substantially reduce the throughput in multi-user environments. For this reason, the optimizer prefers indexed access over sequential access at isolation level 3. Sequential scans can efficiently evaluate simple comparison predicates between table columns and constants during the scan. Other search conditions that refer only to the table being scanned are evaluated after these simple comparisons, and this approach is slightly more efficient that evaluating the conditions in a filter after the sequential scan.


Hash table scans

The hash table scan is an operator that lets Adaptive Server Anywhere scan the build side of a hash join as if it were an in-memory table. This lets you convert a plan with this structure:

table1<seq>*JH ( arbitrary dfos... ( table2<seq> ) )

to this structure:

table1<seq>*JF ( arbitrary dfos... ( HTS JNB table2<idx> ) )

where idx is an index that you can use to probe the join key values stored in the hash table.

When there are intervening operators between the hash join and the scan, it reduces the number of rows needed that need to be processed by other operators.

This strategy is most useful when the index probes are highly selective, for example, when the number of rows in the build side is small compared to the cardinality of the index.

Note
If the build side of the hash join is large, it is more effective to do a regular sequential scan.

The optimizer computers a threshold build size, similar to how it computes the threshold for the has join alternate execution, beyond which the (HTS JNB table<idx>) will be treated as a sequential scan (table<seq>) during execution.

Note
The sequential strategy is used if the build side of the hash table has to spill to disk.

Previous Next


Parallel index scans

On volumes with multiple disk spindles, Adaptive Server Anywhere can scan tables using an index in parallel. Parallel index scans let the server take advantage of tables and index pages across multiple disks to schedule multiple input/output operations at the same time. Each scan carried out in parallel searches for rows matching a different key and ensures that these pages are in memory when needed.

Note
Parallel index scans are not supported over compressed indexes and not at isolation level 3.

Previous Next


IN list

The IN list algorithm is used in cases where an IN predicate can be satisfied using an index. For example, in the following query, the optimizer recognizes that it can access the employee table using its primary key index.

SELECT *
FROM employee
WHERE emp_id in (102, 105, 129)

In order to accomplish this, a join is built with a special IN list table on the left hand side. Rows are fetched from the IN list and used to probe the employee table. Multiple IN lists can be satisfied using the same index. If the optimizer chooses not to use an index to satisfy the IN predicate (perhaps because another index gives better performance), then the IN list appears as a predicate in a filter.


Derived table

A derived table is a SELECT statement included in the FROM clause of a query. The result set of the SELECT statement is logically treated as if it were a table. The query optimizer may also generate derived tables during query rewrites, for example in queries including the set based operations UNION, INTERSECT, or EXCEPT. The graphical plan displays the name of the derived table and the list of columns that were computed.

For more information on derived tables, see The FROM clause: specifying tables and FROM clause.

Example

The following query of the sample database has derived tables in its graphical plan:

SELECT emp_id FROM employee
UNION ALL
SELECT dept_id FROM (
    SELECT TOP 5 dept_id
    FROM department
    ORDER BY dept_name DESC ) MyDerivedTable


Recursive table

A recursive table is a common table expression constructed as a result of a WITH clause in a query. The WITH clause is used for recursive union queries. Common table expressions are temporary views that are known only within the scope of a single SELECT statement.

For more information, see Common Table Expressions.


Join algorithms

Join algorithms are required when more than one table appears in the FROM clause. You cannot specify which join algorithm is used—the choice is made by the optimizer.

Nested Loops Join algorithm
Nested Loops Semijoin algorithm
Nested Block Join and Sorted Block algorithms
Hash Join algorithm
Hash Semijoin algorithm
Hash Antisemijoin algorithm
Merge Join algorithm
Recursive Hash Join algorithm
Recursive Left Outer Hash Join algorithm


Nested Loops Join algorithm

The nested loops join computes the join of its left and right sides by completely reading the right hand side for each row of the left hand side. (The syntactic order of tables in the query does not matter, because the optimizer chooses the appropriate join order for each block in the request.)

The optimizer may choose nested loops join if the join condition does not contain an equality condition, or if it is optimizing for first-row time.

Since a nested loops join reads the right hand side many times, it is very sensitive to the cost of the right hand side. If the right hand side is an index scan or a small table, then the right hand side can likely be computed using cached pages from previous iterations. On the other hand, if the right hand side is a sequential table scan or an index scan that matches many rows, then the right hand side needs to be read from disk many times. Typically, a nested loops join is less efficient than other join methods. However, nested loops join can provide the first matching row quickly compared to join methods that must compute their entire result before returning.

Nested loops join is the only join algorithm that can provide sensitive semantics for queries containing joins. This means that sensitive cursors on joins can only be executed with a nested loops join.

A semijoin fetches only the first matching row from the right hand side. It is a more efficient version of the nested loops join, but can only be used when an EXISTS, or sometimes a DISTINCT, keyword is used.


Nested Loops Semijoin algorithm

Similar to the nested loop join described above, the nested loops semijoin algorithm joins each row of the left-hand side with the right-hand side using a nested loops algorithm. As with nested loops join, the right-hand side may be read many times, so for larger inputs an index scan is preferable. However, nested loops semijoin differs from nested loop join in two respects. First, semijoin only outputs values from the left-hand side; the right hand side is used only for restricting which rows of the left-hand side appear in the result. Second, the nested loops semijoin algorithm stops each search of the right-hand side as soon as the first match is encountered. Nested loops semijoin can be used as the join algorithm when join's inputs include table expressions from an existentially-quantified (IN, SOME, ANY, EXISTS) nested query that has been rewritten as a join.


Nested Block Join and Sorted Block algorithms

The nested block join (also called the block nested loops join) reads a block of rows from the left hand side, and sorts the rows by the join attributes (the columns used in the join conditions). The left hand child of a nested block join is called a sorted block node. For each block of rows with equal join attributes, the right hand side is scanned once. This algorithm improves on the nested loops join if there are several rows on the left hand side that join with each row of the right hand side.

A nested block join will be chosen by the optimizer if the left hand side has many rows with the same values for join attributes and the right hand side has an index that satisfies the search condition.

Every nested block join has a left child that is a sorted block node. The cost shown for this node is the cost of reading and sorting the rows from the left input.

The left hand input is read into memory in blocks. Changes to tables in the left hand input may not be visible in the results. Because of this, a nested block join cannot provide sensitive semantics.

Nested block joins locks rows on the left input before they are copied to memory.

The nested block join algorithm is disabled in low memory conditions.


Hash Join algorithm

The hash join algorithm builds an in-memory hash table of the smaller of its two inputs, and then reads the larger input and probes the in-memory hash table to find matches, which are written to a work table. If the smaller input does not fit into memory, the hash join operator partitions both inputs into smaller work tables. These smaller work tables are processed recursively until the smaller input fits into memory.

The hash join algorithm has the best performance if the smaller input fits into memory, regardless of the size of the larger input. In general, the optimizer will choose hash join if one of the inputs is expected to be substantially smaller than the other.

If the hash join algorithm executes in an environment where there is not enough cache memory to hold all the rows that have a particular value of the join attributes, then it is not able to complete. In this case, the hash join method discards the interim results and an indexed-based nested loops join is used instead. All of the rows of the smaller table are read and used to probe the work table to find matches. This indexed-based strategy is significantly slower than other join methods, and the optimizer will avoid generating access plans using a hash join if it detects that a low memory situation may occur during query execution. When the nested loops strategy is needed due to low memory, a performance counter is incremented. You can read this monitor with the QueryLowMemoryStrategy database or connection property, or in the "Query: Low Memory Strategies" counter in Windows Performance Monitor.

The hash join algorithm is disabled on Windows CE in low memory conditions.

Note: Windows Performance Monitor may not be available on Windows CE, 95, 98, or Me.

For more information, see QueryLowMemoryStrategy in Connection-level properties.

The hash join algorithm computes all of the rows of its result before returning the first row.

The hash join algorithm uses a work table, which provides insensitive semantics unless a value-sensitive cursor has been requested.

Hash join locks rows in its inputs before they are copied to memory.


Hash Semijoin algorithm

The hash semijoin variant of the hash join algorithm performs a semijoin between the left-hand side and the right-hand side. As with nested loop semijoin described above, the right-hand side is only used to determine which rows from the left-hand side appear in the result. With hash semijoin the right-hand side is read to form an in-memory hash table which is subsequently probed by each row from the left-hand side. As soon as any match is found, the left-hand row is output to the result and the match process starts again for the next left-hand row. At least one equality join condition must be present in order for hash semijoin to be considered by the query optimizer. As with nested loop semijoin, hash semijoin will be utilized in cases where the join's inputs include table expressions from an existentially-quantified (IN, SOME, ANY, EXISTS) nested query that has been rewritten as a join. Hash semijoin will tend to outperform nested loop semijoin when the join condition includes inequalities, or if a suitable index does not exist to make indexed retrieval of the right-hand side sufficiently inexpensive.

As with hash join, the hash semijoin algorithm may revert to a nested loops semijoin strategy if there is insufficient cache memory to enable the operation to complete. Should this occur, a performance counter is incremented. You can read this monitor with the QueryLowMemoryStrategy database or connection property, or in the Query: Low Memory Strategies counter in Windows Performance Monitor.

Note: Windows Performance Monitor may not be available on Windows CE, 95, 98, or Me.

For more information, see QueryLowMemoryStrategy in Connection-level properties.


Hash Antisemijoin algorithm

The hash antisemijoin variant of the hash join algorithm performs an antisemijoin between the left-hand side and the right-hand side. As with nested loop antisemijoin described above, the right-hand side is only used to determine which rows from the left-hand side appear in the result. With hash antisemijoin the right-hand side is read to form an in-memory hash table which is subsequently probed by each row from the left-hand side. Each left-hand row is output only if it fails to match any row from the right-hand side. As with nested loop antisemijoin, hash antisemijoin will be utilized in cases where the join's inputs include table expressions from a universally-quantified (NOT IN, ALL, NOT EXISTS) nested query that has been rewritten as an anti-join. Hash antisemijoin will tend to outperform nested loop antisemijoin when the join condition includes inequalities, or if a suitable index does not exist to make indexed retrieval of the right-hand side sufficiently inexpensive.

As with hash join, the hash antisemijoin algorithm may revert to a nested loops antisemijoin strategy if there is insufficient cache memory to enable the operation to complete. Should this occur, a performance counter is incremented. You can read this monitor with the QueryLowMemoryStrategy database or connection property, or in the Query: Low Memory Strategies counter in Windows Performance Monitor.

Note: Windows Performance Monitor may not be available on Windows CE, 95, 98, or Me.

For more information, see QueryLowMemoryStrategy in Connection-level properties.


Merge Join algorithm

The merge join algorithm reads two inputs which are both ordered by the join attributes. For each row of the left input, the algorithm reads all of the matching rows of the right input by accessing the rows in sorted order.

If the inputs are not already ordered by the join attributes (perhaps because of an earlier merge join or because an index was used to satisfy a search condition), then the optimizer adds a sort to produce the correct row order. This sort adds cost to the merge join.

One advantage of a merge join compared to a hash join is that the cost of sorting can be amortized over several joins, provided that the merge joins are over the same attributes. The optimizer will choose merge join over a hash join if the sizes of the inputs are likely to be similar, or if it can amortize the cost of the sort over several operations.


Recursive Hash Join algorithm

The recursive hash join is a variant of the hash join algorithm that is used in recursive union queries.

For more information, see Hash Join algorithm, and Recursive common table expressions.


Recursive Left Outer Hash Join algorithm

The recursive left outer hash join is a variant of the hash join algorithm used in certain recursive union queries.

For more information, see Hash Join algorithm, and Recursive common table expressions.


Duplicate elimination algorithms

A duplicate elimination operator produces an output that has no duplicate rows. Duplicate elimination nodes may be introduced by the optimizer, for example, when converting a nested query into a join.

For more information, see Hash Distinct algorithm, Ordered Distinct algorithm, and Indexed Distinct algorithm.


Hash Distinct algorithm

The hash distinct algorithm reads its input, and builds an in-memory hash table. If an input row is found in the hash table, it is ignored; otherwise it is written to a work table. If the input does not completely fit into the in-memory hash table, it is partitioned into smaller work tables, and processed recursively.

The hash distinct algorithm works very well if the distinct rows fit into an in-memory table, irrespective of the total number of rows in the input.

The hash distinct uses a work table, and as such can provide insensitive or value sensitive semantics.

If the hash distinct algorithm executes in an environment where there is very little cache memory available, then it will not be able to complete. In this case, the hash distinct method discards its interim results, and the indexed distinct algorithm is used instead. The optimizer avoids generating access plans using the hash distinct algorithm if it detects that a low memory situation may occur during query execution.

The hash distinct returns a row as soon as it finds one that has not previously been returned. However, the results of a hash distinct must be fully materialized before returning from the query. If necessary, the optimizer adds a work table to the execution plan to ensure this.

Hash distinct locks the rows of its input.


Ordered Distinct algorithm

If the input is ordered by all the columns, then an ordered distinct can be used. This algorithm reads each row and compares it to the previous row. If it is the same, it is ignored; otherwise, it is output. The ordered distinct is effective if rows are already ordered (perhaps because of an index or a merge join); if the input is not ordered, the optimizer inserts a sort. No work table is used by the ordered distinct itself, but one is used by any inserted sort.


Indexed Distinct algorithm

The indexed distinct algorithm maintains a work table of the unique rows from the input. As rows are read from the input, an index on the work table is searched to find a previously seen duplicate of the input row. If one is found, the input row is ignored. Otherwise, the input row is inserted into the work table. The work table index is created on all the columns of the SELECT list; in order to improve index performance, a hash expression is included as the first expression. This hash expression is a computed value embodying the values of all the columns in the SELECT list.

The indexed distinct method returns distinct rows as they are encountered. This allows it to return the first few rows quickly compared to other duplicate elimination methods. The indexed distinct algorithm only stores two rows in memory at a time, and can work well in extremely low memory situations. However, if the number of distinct rows is large, the execution cost of the indexed distinct algorithm is typically worse than hash distinct. The work table used to store distinct rows may not fit in cache, leading to rereading work table pages many times in a random access pattern.

Since the indexed distinct method uses a work table, it cannot provide fully sensitive semantics; however, it also does not provide fully insensitive semantics, and another work table is required for insensitive cursors.

The indexed distinct method locks the rows of its input.


Grouping algorithms

Grouping algorithms compute a summary of their input. They are applicable only if the query contains a GROUP BY clause, or if the query contains aggregate functions (such as SELECT COUNT(*) FROM T).

For more information, see Hash Group By algorithm, Ordered Group By algorithm, Indexed Group By algorithm, and Single Group By algorithm.

Hash Group By algorithm
Hash Group By Sets algorithm
Clustered Hash Group By algorithm
Ordered Group By algorithm
Ordered Group By Sets algorithm
Indexed Group By algorithm
Single Group By algorithm
Single XML Group By algorithm
Sorted Group By Sets algorithm


Hash Group By algorithm

The hash group by algorithm creates an in-memory hash table of group rows. As rows are read from the input, the group rows are updated. If the hash table doesn't fit into memory, the input is partitioned into smaller work tables which are recursively partitioned until they fit into memory. If there is not enough memory for the partitions, the optimizer discards the interim results from the hash group by, and uses an indexed group by algorithm. The optimizer avoids generating access plans using the hash group by algorithm if it detects that a low memory situation may occur during query execution.

The hash group by algorithm works very well if the groups fit into memory, irrespective of the size of the input.

The hash group by algorithm computes all of the rows of its result before returning the first row, and can be used to satisfy a fully sensitive or values sensitive cursor. The results of the hash group by must be fully materialized before returning from the query. If necessary, the optimizer adds a work table to the execution plan to ensure this.


Hash Group By Sets algorithm

A variant of the Hash Group By algorithm used when carrying out GROUPING SETS queries.

For more information, see Hash Group By algorithm.


Clustered Hash Group By algorithm

In some cases, values in the grouping columns of the input table are clustered, so that similar values appear close together. For example, if a table contains a column that is always set to the current date, all rows with a single date are relatively close within the table. The Clustered Hash Group By algorithm exploits this clustering.

The optimizer may use Clustered Hash Group By when grouping tables that are significantly larger than the available memory. In particular, it is effective when the HAVING predicate returns only a small proportion of rows.

The Clustered Hash Group By algorithm can lead to significant wasted work on the part of the optimizer if it is chosen in an environment where data is updated concurrently with query execution. Clustered Hash Group By is therefore most appropriate for OLAP workloads characterized by occasional batch-style updates and read-based queries. Set the OPTIMIZATION_WORKLOAD option to OLAP to indicate to the optimizer that it should include the Clustered Hash Group By algorithm in the possibilities it investigates.

For more information, see OPTIMIZATION_WORKLOAD option [database].


Ordered Group By algorithm

The ordered group by reads an input that is ordered by the grouping columns. As each row is read, it is compared to the previous row. If the grouping columns match, then the current group is updated; otherwise, the current group is output and a new group is started.


Ordered Group By Sets algorithm

A variant of the Ordered Group By algorithm used when carrying out GROUPING SETS queries. This algorithm requires that indexes be available.

For more information, see Ordered Group By algorithm.


Indexed Group By algorithm

The indexed group by algorithm is similar to the indexed distinct algorithm. It builds a work table containing one row per group. As input rows are read, the associated group is looked up in the work table using an index. The aggregate functions are updated, and the group row is rewritten to the work table. If no group record is found, a new group record is initialized and inserted into the work table.

Indexed group by is chosen when the optimizer is reasonably certain that the size of the input is very small.

The indexed group by computes all the rows of its result before returning the first row, and fully materializes its input. It can be used to satisfy a FULLY INSENSITIVE requirement.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL User's Guide

Query Optimization and Execution

Query execution algorithms

Grouping algorithms

Single Group By algorithm

When no GROUP BY is specified, a single row aggregate is produced.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL User's Guide

Query Optimization and Execution

Query execution algorithms

Grouping algorithms

Single XML Group By algorithm

An algorithm used when processing XML-based queries.


Sorted Group By Sets algorithm

An algorithm used when processing OLAP queries that contain GROUPING SETS.

This algorithm may be used when it is not possible to use the Ordered Group By Sets algorithm, because of lack of an index.


Sorting and union algorithms

Sorting algorithms are applicable when the query includes an order by clause, and union algorithms are applicable for union queries.

For more information, see Merge sort and Union all.


Merge sort

The sort operator reads its input into memory, sorts it in memory, and then outputs the sorted results. If the input does not completely fit into memory, then several sorted runs are created and then merged together. Sort does not return any rows until it has read all of the input rows. Sort locks its input rows.

If the merge sort algorithm executes in an environment where there is very little cache memory available, it may not be able to complete. In this case, the merge sort orders the remainder of the input using an indexed-based sort method. Input rows are read and inserted into a work table, and an index is built on the ordering columns of the work table. In this case, rows are read from the work table using a complex index scan. This indexed-based strategy is significantly slower than other join methods. The optimizer avoids generating access plans using a merge sort algorithm if it detects that a low memory situation may occur during query execution. When the index-based strategy is needed due to low memory, a performance counter is incremented; you can read this monitor with the QueryLowMemoryStrategy property, or in the "Query: Low Memory Strategies" counter in Windows Performance Monitor.

Sort performance is affected by the size of the sort key, the row size, and the total size of the input. For large rows, it may be cheaper to use a VALUES SENSITIVE cursor. In that case, columns in the SELECT list are not copied into the work tables used by the sort. While the sort does not write output rows to a work table, the results of the wort must be materialized before rows are returned to the application. If necessary, the optimizer adds a work table to ensure this.


Union all

The union all algorithm reads rows from each of its inputs and outputs them, regardless of duplicates. This algorithm is used to implement UNION and UNION ALL clauses. In the UNION case, a duplicate elimination algorithm is needed to remove any duplicates generated by the union all.


Recursive union

The recursive union algorithm is employed during the execution of recursive union queries.

For more information, see Recursive common table expressions.


Sort Top N

The Sort Top N algorithm is used for queries that contain a TOP N clause and an ORDER BY clause. It is an efficient algorithm for sorting only those rows required in the result set.

For more information, see SELECT statement.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL User's Guide

Query Optimization and Execution

Query execution algorithms

Miscellaneous algorithms

The following are additional methods that may be used in an access plan.


Filter, pre-filter, and hash-filter algorithms

Filters apply search conditions. The search conditions appear in the statement in the WHERE and HAVING clauses and in the ON conditions of JOINS in the FROM clause.

Pre-filter is the same as filter, except that it doesn't depend on input. For example, in the case of WHERE 1 = 2 a pre-filter applies.

A hash-filter can be used when an execution plan fetches all of the rows of one table before fetching any rows from another table that joins to it. The hash filter builds an array of bits, and turns one bit on for each row of the first table that matches search conditions on that table. When accessing the second table, rows that could not possibly join with the first table are rejected.

For example, consider the plan:

R<idx> *JH S<seq> JH* T<idx>

Here we are joining R to S and T. We will have read all of the rows of R before reading any row from T, and we can immediately reject rows of T that can not possibly join with R. This reduces the number of rows that must be stored in the second hash join.

For more information, see The WHERE clause: specifying rows.


Lock algorithm

Lock indicates that there is a lock at a certain isolation level. For example, at isolation level 1, a lock is maintained for only one row at a time. If you are at isolation level 0, no lock is acquired, but the node will still be called Lock. In this case, the lock node verifies that the row still exists.

For more information, see How locking works.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL User's Guide

Query Optimization and Execution

Query execution algorithms

Miscellaneous algorithms

Row limit algorithm

Row limits are set by the TOP n or FIRST clause of the SELECT statement.

For more information, see SELECT statement.


Bloom filter algorithm

The Bloom filter or hash map is a data structure that represents the distribution of values in a column or set of columns. It may be used in queries that satisfy the following conditions:

  • An operation in the query reads its entire input before returning a row to later operations. For example, a join of two tables on a single column requires that all the relevant rows be read to establish whether they meet the criterion for the join.

  • A later operation in the query refers to the rows in the result of the operation. For example, a second join on the same column would use only those rows that satisfy the first join.


Explode algorithm

The Explode algorithm is used during the execution of set operations such as EXCEPT and INTERSECT. It is a feature of such operations that the number of rows in the result set is explicitly related to the number of rows in the two sets being operated on. The Explode algorithm ensures that the number of rows in the result set is correct.

For more information, see Performing set operations on query results with UNION, INTERSECT, and EXCEPT.


Window functions algorithm

This algorithm is used in evaluating OLAP queries that use window functions.

For more information, see Working with OLAP functions, and Window functions.


Physical data organization and access

Storage allocations for each table or entry have a large impact on the efficiency of queries. The following points are of particular importance because each influence how fast your queries execute.


Disk allocation for inserted rows

Adaptive Server Anywhere stores rows contiguously, if possible

Every new row that is smaller than the page size of the database file will always be stored on a single page. If no present page has enough free space for the new row, Adaptive Server Anywhere writes the row to a new page. For example, if the new row requires 600 bytes of space but only 500 bytes are available on a partially filled page, then Adaptive Server Anywhere places the row on a new page.

To make table pages more contiguous on the disk, Adaptive Server Anywhere allocates table pages in blocks of eight pages. For example, when it needs to allocate a page it allocates eight pages, inserts the page in the block, and then fills up with the block with the next seven pages. In addition, it uses a free page bitmap to find contiguous blocks of pages within the dbspace, and performs sequential scans by reading groups of 64K, using the bitmap to find relevant pages. This leads to more efficient sequential scans.

Adaptive Server Anywhere may store rows in any order

Adaptive Server Anywhere locates space on pages and inserts rows in the order it receives them in. It assigns each to a page, but the locations it chooses in the table may not correspond to the order they were inserted in. For example, the engine may have to start a new page to store a long row contiguously. Should the next row be shorter, it may fit in an empty location on a previous page.

The rows of all tables are unordered. If the order that you receive or process the rows is important, use an ORDER BY clause in your SELECT statement to apply an ordering to the result. Applications that rely on the order of rows in a table can fail without warning.

If you frequently require the rows of a table to be in a particular order, consider creating an index on those columns specified in the query's ORDER BY clause.

Space is not reserved for NULL columns

By default, whenever Adaptive Server Anywhere inserts a row, it reserves only the space necessary to store the row with the values it contains at the time of creation. It reserves no space to store values that are NULL or to accommodate fields, such as text strings, which may enlarge.

You can force Adaptive Server Anywhere to reserve space by using the PCTFREE option when creating the table. For more information, see CREATE TABLE statement.

Once inserted, rows identifiers are immutable

Once assigned a home position on a page, a row never moves from that page. If an update changes any of the values in the row so it no longer fits in its assigned page, then the row splits and the extra information is inserted on another page.

This characteristic deserves special attention, especially since Adaptive Server Anywhere allows no extra space when you insert the row. For example, suppose you insert a large number of empty rows into a table, then fill in the values, one column at a time, using update statements. The result would be that almost every value in a single row will be stored on a separate page. To retrieve all the values from one row, the engine may need to read several disk pages. This simple operation would become extremely and unnecessarily slow.

You should consider filling new rows with data at the time of insertion. Once inserted, they then have sufficient room for the data you expect them to hold.

A database file never shrinks

As you insert and delete rows from the database, Adaptive Server Anywhere automatically reuses the space they occupy. Thus, Adaptive Server Anywhere may insert a row into space formerly occupied by another row.

Adaptive Server Anywhere keeps a record of the amount of empty space on each page. When you ask it to insert a new row, it first searches its record of space on existing pages. If it finds enough space on an existing page, it places the new row on that page, reorganizing the contents of the page if necessary. If not, it starts a new page.

Over time, however, if you delete a number of rows and don't insert new rows small enough to use the empty space, the information in the database may become sparse. You can reload the table, or use the REORGANIZE TABLE statement to defragment the table.

For more information, see REORGANIZE TABLE statement.


Table and page sizes

The page size you choose for your database can affect the performance of your database. In general, smaller page sizes are likely to benefit operations that retrieve a relatively small number of rows from random locations. By contrast, larger pages tend to benefit queries that perform sequential table scans, particularly when the rows are stored on pages in the order the rows are retrieved via an index. In this situation, reading one page into memory to obtain the values of one row may have the side effect of loading the contents of the next few rows into memory. Often, the physical design of disks permits them to retrieve fewer large blocks more efficiently than many small ones.

Adaptive Server Anywhere creates a bitmap for sufficiently large tables within databases that have at least a 2K page size. Each table's bitmap reflects the position of each table page in the entire dbspace file. For databases of 2K, 4K, or 8K pages, the server utilizes the bitmap to read large blocks (64K) of table pages instead of single pages at a time, reducing the total number of I/O operations to disk and hence improving performance. Users cannot control the server's criteria for bitmap creation or usage.

Note that bitmaps, also called page maps, are only available for databases created in version 8.0 and higher. If a database is upgraded from an older version, the server will not create a bitmap for database tables, even if they meet its criteria. Bitmaps are not created for work tables or system tables.

Should you choose a larger page size, such as 4 kb, you may wish to increase the size of the cache. Fewer large pages can fit into the same space. For example, 1 Mb of memory can hold 1000 pages that are each 1 kb in size, but only 250 pages that are 4 kb in size. How many pages is enough depends entirely on your database and the nature of the queries your application performs. You can conduct performance tests with various cache sizes. If your cache cannot hold enough pages, performance suffers as Adaptive Server Anywhere begins swapping frequently-used pages to disk.

Page sizes also affect indexes. By default, index pages have a hash size of 10 bytes: they store approximately the first 10 bytes of data for each index entry. This allows for a fan-out of roughly 200 using 4K pages, meaning that each index page holds 200 rows, or 40 000 rows with a two-level index. Each new level of an index allows for a table 200 times larger. Page size can significantly affect fan-out, in turn affecting the depth of index required for a table. Large databases should have 4K pages.

Adaptive Server Anywhere attempts to fill pages as much as possible. Empty space accumulates only when new objects are too large to fit empty space on existing pages. Consequently, adjusting the page size may not significantly affect the overall size of your database.


Indexes

Indexes can greatly improve the performance of searches on the indexed column(s). However, indexes take up space within the database and slow down insert, update, and delete operations. This section will help you to determine when you should create an index and tell you how to achieve maximum performance from your index.

There are many situations in which creating an index improves the performance of a database. An index provides an ordering of the rows of a table on the basis of the values in some or all of the columns. An index allows Adaptive Server Anywhere to find rows quickly. It permits greater concurrency by limiting the number of database pages accessed. An index also affords Adaptive Server Anywhere a convenient means of enforcing a uniqueness constraint on the rows in a table.

The Index Consultant is a tool that assists you in the selection of an appropriate set of indexes for your database. For more information, see Index Consultant overview.


When to create an index

There is no simple formula to determine whether or not an index should be created for a particular column. You must consider the trade-off of the benefits of indexed retrieval versus the maintenance overhead of that index. The following factors may help to determine whether you should create an index.

  • Keys and unique columns Adaptive Server Anywhere automatically creates indexes on primary keys, foreign keys, and unique columns. You should not create additional indexes on these columns. The exception is composite keys, which can sometimes be enhanced with additional indexes.

    For more information, see Composite indexes.

  • Frequency of search If a particular column is searched frequently, you can achieve performance benefits by creating an index on that column. Creating an index on a column that is rarely searched may not be worthwhile.

  • Size of table Indexes on relatively large tables with many rows provide greater benefits than indexes on relatively small tables. For example, a table with only 20 rows is unlikely to benefit from an index, since a sequential scan would not take any longer than an index lookup.

  • Number of updates An index is updated every time a row is inserted or deleted from the table and every time an indexed column is updated. An index on a column slows the performance of inserts, updates and deletes. A database that is frequently updated should have fewer indexes than one that is read-only.

  • Space considerations Indexes take up space within the database. If database size is a primary concern, you should create indexes sparingly.

  • Data distribution If an index lookup returns too many values, it is more costly than a sequential scan. Adaptive Server Anywhere does not make use of the index when it recognizes this condition. For example, Adaptive Server Anywhere would not make use of an index on a column with only two values, such as employee.sex in the sample database. For this reason, you should not create an index on a column that has only a few distinct values.

The Index Consultant is a tool that assists you in the selection of an appropriate set of indexes for your database. For more information, see Index Consultant overview.

Temporary tables

You can create indexes on both local and global temporary tables. You may want to consider indexing a temporary table if you expect it will be large and accessed several times in sorted order or in a join. Otherwise, any improvement in performance for queries is likely to be outweighed by the cost of creating and dropping the index.

For more information, see Working with indexes.


Improving index performance

If your index is not performing as well as expected, you may want to consider the following actions.

  • Reorganize composite indexes.

  • Increase the page size.

These measures are aimed at increasing index selectivity and index fan-out, as explained below.

Index selectivity

Index selectivity refers to the ability of an index to locate a desired index entry without having to read additional data.

If selectivity is low, additional information must be retrieved from the table page that the index references. These retrievals are called full compares, and they have a negative effect on index performance.

The FullCompare property function keeps track of the number of full compares that have occurred. You can also monitor this statistic using the Sybase Central Performance monitor or the Windows Performance Monitor.

Note: Windows Performance Monitor may not be available on Windows CE, 95, 98, or Me.

In addition, the number of full compares is provided in the graphical plan with statistics. For more information, see Common statistics used in the plan.

For more information on the FullCompare function, see Database-level properties.

Index structure and index fan-out

Indexes are organized in a number of levels, like a tree. The first page of an index, called the root page, branches into one or more pages at the next level, and each of those pages branch again, until the lowest level of the index is reached. These lowest level index pages are called leaf pages. To locate a specific row, an index with n levels requires n reads for index pages and one read for the data page containing the actual row. In general, fewer than n reads from disk are needed, since index pages that are used frequently tend to be stored in cache.

The index fan-out is the number of index entries stored on a page. An index with a higher fan-out may have fewer levels than an index with a lower fan-out. Therefore, higher index fan-out generally means better index performance.

You can see the number of levels in an index by using the sa_index_levels system procedure.

For more information, see sa_index_levels system procedure.

Composite indexes


Composite indexes

An index can contain one, two, or more columns. An index on two or more columns is called a composite index. For example, the following statement creates a two-column composite index:

CREATE INDEX name
ON employee (emp_lname, emp_fname)

A composite index is useful if the first column alone does not provide high selectivity. For example, a composite index on emp_lname and emp_fname is useful when many employees have the same last name. A composite index on emp_id and emp_lname would not be useful because each employee has a unique ID, so the column emp_lname does not provide any additional selectivity.

Additional columns in an index can allow you to narrow down your search, but having a two-column index is not the same as having two separate indexes. A composite index is structured like a telephone book, which first sorts people by their last names, and then all the people with the same last name by their first names. A telephone book is useful if you know the last name, even more useful if you know both the first name and the last name, but worthless if you only know the first name and not the last name.

The compressed B-tree index method substantially improves performance for composite indexes.

Column order

When you create composite indexes, you should think carefully about the order of the columns. Composite indexes are useful for doing searches on all of the columns in the index or on the first columns only; they are not useful for doing searches on any of the later columns alone.

If you are likely to do many searches on one column only, that column should be the first column in the composite index. If you are likely to do individual searches on both columns of a two-column index, you may want to consider creating a second index that contains the second column only.

Primary keys that have more than one column are always automatically indexed as composite indexes with their columns in the order that they appear in the table definition, not in the order that they are specified in the primary key definition. You should consider the searches that you will execute involving the primary key to determine which column should come first. Consider adding an extra index on any later column of the primary key that is frequently searched.

For example, suppose you create a composite index on two columns. One column contains employee's first names, the other their last names. You could create an index that contains their first name, then their last name. Alternatively, you could index the last name, then the first name. Although these two indexes organize the information in both columns, they have different functions.

CREATE INDEX fname_lname
   ON employee emp_fname, emp_lname;
CREATE INDEX lname_fname
   ON employee emp_lname, emp_fname;

Suppose you then want to search for the first name John. The only useful index is the one containing the first name in the first column of the index. The index organized by last name then first name is of no use because someone with the first name John could appear anywhere in the index.

If you think it likely that you will need to look up people by first name only or second name only, then you should consider creating both of these indexes.

Alternatively, you could make two indexes, each containing only one of the columns. Remember, however, that Adaptive Server Anywhere only uses one index to access any one table while processing a single query. Even if you know both names, it is likely that Adaptive Server Anywhere will need to read extra rows, looking for those with the correct second name.

When you create an index using the CREATE INDEX command, as in the example above, the columns appear in the order shown in your command.

Primary key indexes and column order

The order of the columns in a primary key index is enforced to be the same as the order in which the columns appear in the table's definition, regardless as to the ordering of the columns specified in the PRIMARY KEY constraint. Moreover, Adaptive Server Anywhere enforces an additional constraint that a table's primary key columns must be at the beginning of each row. Hence if a primary key is added to an existing table the server may rewrite the entire table to ensure that the key columns are at the beginning of each row.

In situations where more than one column appears in a primary key, you should consider the types of searches needed. If appropriate, switch the order of the columns in the table definition so the most frequently searched-for column appears first, or create separate indexes, as required, for the other columns.

Composite indexes and ORDER BY

By default, the columns of an index are sorted in ascending order, but they can optionally be sorted in descending order by specifying DESC in the CREATE INDEX statement.

Adaptive Server Anywhere can choose to use an index to optimize an ORDER BY query as long as the ORDER BY clause contains only columns included in that index. In addition, the columns in the index must be ordered in exactly the same way, or in exactly the opposite way, as the ORDER BY clause. For single-column indexes, the ordering is always such that it can be optimized, but composite indexes require slightly more thought. The table below shows the possibilities for a two-column index.

Index columns | Optimizable ORDER BY queries | Not optimizable ORDER BY queries
ASC, ASC | ASC, ASC or DESC, DESC | ASC, DESC or DESC, ASC
ASC, DESC | ASC, DESC or DESC, ASC | ASC, ASC or DESC, DESC
DESC, ASC | DESC, ASC or ASC, DESC | ASC, ASC or DESC, DESC
DESC, DESC | DESC, DESC or ASC, ASC | ASC, DESC or DESC, ASC

An index with more than two columns follows the same general rule as above. For example, suppose you have the following index:

CREATE INDEX idx_example
ON table1 (col1 ASC, col2 DESC, col3 ASC)

In this case, the following queries can be optimized:

SELECT col1, col2, col3 from table1
ORDER BY col1 ASC, col2 DESC, col3 ASC

and

SELECT col1, col2, col3 from example
ORDER BY col1 DESC, col2 ASC, col3 DESC

The index is not used to optimize a query with any other pattern of ASC and DESC in the ORDER BY clause. For example:

SELECT col1, col2, col3 from table1
ORDER BY col1 ASC, col2 ASC, col3 ASC

is not optimized.


Other uses for indexes

Adaptive Server Anywhere uses indexes to achieve other performance benefits. Having an index allows Adaptive Server Anywhere to enforce column uniqueness, to reduce the number of rows and pages that must be locked, and to better estimate the selectivity of a predicate.

  • Enforce column uniqueness Without an index, Adaptive Server Anywhere has to scan the entire table every time that a value is inserted to ensure that it is unique. For this reason, Adaptive Server Anywhere automatically builds an index on every column with a uniqueness constraint.

  • Reduce locks Indexes reduce the number of rows and pages that must be locked during inserts, updates, and deletes. This reduction is a result of the ordering that indexes impose on a table.

    For more information on indexes and locking, see How locking works.

  • Estimate selectivity Because an index is ordered, the optimizer can estimate the percentage of values that satisfy a given query by scanning the upper levels of the index. This action is called a partial index scan.


Types of index

Adaptive Server Anywhere supports two types of index, and automatically chooses between them depending on the declared width of the indexed columns. For a total column width that is less than 10 bytes, Adaptive Server Anywhere uses a B-tree index that contains an order-preserving encoding, or hash value, that represents the indexed data. Hash B-tree indexes are also used when the index key length is longer than one-eighth of the page size for the database or 256 bytes (whichever is lower). For data values whose combined declared length is between these two bounds, Adaptive Server Anywhere uses a compressed B-tree index that stores each key in a compressed form.

Indexes can be stored as either clustered or unclustered. Clustered indexes may assist performance, but only one index on a table can be clustered.


Hash B-tree indexes

A hash B-tree index does not store the actual row value(s) from the table. Instead, a hash B-tree index stores an order-preserving encoding of the original data. The number of bytes in each index entry used to store this hash value is termed the hash size, and is automatically chosen by the server based on the declared width of all of the indexed columns. The server compares these hashed values as it searches through an index to find a particular row.

Hash values

Adaptive Server Anywhere must represent values in an index to decide how to order them. For example, if you index a column of names, then it must know that Amos comes before Smith.

For each value in your index, Adaptive Server Anywhere creates a corresponding hash value. It stores the hash value in the index, rather than the actual value. Adaptive Server Anywhere can perform operations with the hash value. For example, it can tell when two values are equal or which of two values is greater.

When you index a small storage type, such as an integer, the hash value that Adaptive Server Anywhere creates takes the same amount of space as the original value. For example, the hash value for an integer is 4 bytes in size, the same amount of space as required to store an integer. Because the hash value is the same size, Adaptive Server Anywhere can use hash values with a one-to-one correspondence to the actual value. Adaptive Server Anywhere can always tell whether two values are equal, or which is greater by comparing their hash values. However, it can retrieve the actual value only by reading the entry from the corresponding table.

When you index a column containing larger data types, the hash value will often be shorter than the size of the type. For example, if you index a column of string values, the hash value used is at most 9 bytes in length. Consequently, Adaptive Server Anywhere cannot always compare two strings using only the hash values. If the hash values are equal, Adaptive Server Anywhere must retrieve and compare the actual two values from the table.

For example, suppose you index the titles of books, many of which are similar. If you wish to search for a particular title, the index may identify only a set of possible rows. In this case, Adaptive Server Anywhere must retrieve each of the candidate rows and examine the full title.

Composite indexes

An ordered sequence of columns is also called a composite index. However, each index key in these indexes is at most a 9 byte hash value. Hence, the hash value cannot necessarily identify the correct row uniquely. When two hash values are equal, Adaptive Server Anywhere must retrieve and compare the actual values.


Compressed B-tree indexes

Compressed B-tree indexes store a compressed form of each indexed value in the index's internal nodes. To do this, compressed B-tree indexes store the values using Patricia tries, an optimized form of a trie data structure that is augmented with a skip-count to compress its representation. As a result, compressed B-tree indexes offer substantial improvements over hash indexes when the overall data length is reasonably large. More significantly, the compaction algorithm efficiently handles index values that are identical (or nearly so), so common substrings within the indexed values have negligible impact on storage requirements and performance. Compressed B-tree indexes are chosen automatically if the sum of the declared width of the indexed columns is between 10 bytes and one-eighth of the database page size to a maximum of 256 bytes.


Recommended page sizes

The page size of the database can have a significant effect on the index fan-out. The index fan-out approximately doubles as the page size doubles.

Each index lookup requires one page read for each of the levels of the index plus one page read for the table page, and a single query can require several thousand index lookups. A large fan-out often means that fewer index levels are required, which can improve searches considerably. For this reason, consider using a large page size, such as 4K, to improve index performance. You may also want to consider using a larger page size when you wish to index long string columns using compressed B-tree indexes, but the size limit on smaller page sizes is preventing their creation.


Semantic query transformations

To operate efficiently, Adaptive Server Anywhere usually rewrites your query, possibly in several steps, into a new form. It ensures that the new version computes the same result, even though it expresses the query in a new way. In other words, Adaptive Server Anywhere rewrites your queries into semantically equivalent, but syntactically different, forms.

Adaptive Server Anywhere can perform a number of different rewrite operations. If you read the access plans, you will frequently find that they do not correspond to a literal interpretation of your original statement. For example, the optimizer tries as much as possible to rewrite subqueries with joins. The fact that the optimizer has the freedom to rewrite your SQL statements and some of the ways in which it does so, are of importance to you.

Example

Unlike the SQL language definition, some languages mandate strict behavior for AND and OR operations. Some guarantee that the left-hand condition will be evaluated first. If the truth of the entire condition can then be determined, the compiler guarantees that the right-hand condition will not be evaluated.

This arrangement lets you combine conditions that would otherwise require two nested IF statements into one. For example, in C you can test whether a pointer is NULL before you use it as follows. You can replace the nested conditions

if ( X != NULL ) {
   if ( X->var != 0 ) {
      ... statements ...
   }
}

with the more compact expression

if ( X != NULL && X->var != 0 ) {
      ... statements ...
}

Unlike C, SQL has no such rules concerning execution order. Adaptive Server Anywhere is free to rearrange the order of such conditions as it sees fit. The reordered form is semantically equivalent because the SQL language specification makes no distinction. In particular, query optimizers are completely free to reorder predicates in a WHERE, HAVING, and ON clause.


Predicate analysis

A predicate is a conditional expression that, combined with the logical operators AND and OR, makes up the set of conditions in a WHERE, HAVING, or ON clause. In SQL, a predicate that evaluates to UNKNOWN is interpreted as FALSE.

A predicate that can exploit an index to retrieve rows from a table is called sargable. This name comes from the phrase search argument-able. Predicates that involve comparisons of a column with constants, other columns, or expressions may be sargable.

The predicate in the following statement is sargable. Adaptive Server Anywhere can evaluate it efficiently using the primary index of the employee table.

SELECT *
FROM employee
WHERE employee.emp_id = 123

employee<employee>

In contrast, the following predicate is not sargable. Although the emp_id column is indexed in the primary index, using this index does not expedite the computation because the result contains all, or all except one, row.

SELECT *
FROM employee
where employee.emp_id <> 123

employee<seq>

Similarly, no index can assist in a search for all employees whose first name ends in the letter "k". Again, the only means of computing this result is to examine each of the rows individually.

Functions

In general, a predicate that has a function on the column name is not sargable. For example, an index would not be used on the following query:

SELECT * from sales_order
WHERE year(order_date)='2000'

You can sometimes rewrite a query to avoid using a function, thus making it sargable. For example, you can rephrase the above query:

SELECT * from sales_order
WHERE order_date > '1999-12-31'
AND order_date < '2001-01-01'

A query that uses a function becomes sargable if you store the function values in a computed column and build an index on this column. A computed column is a column whose values are obtained from other columns in the table. For example, if you have a column called order_date that holds the date of an order, you can create a computed column called order_year that holds the values for the year extracted from the order_date column.

ALTER TABLE sales_order
ADD order_year INTEGER
COMPUTE year(order_date)

You can then add an index on the column order_year in the ordinary way:

CREATE INDEX idx_year
ON sales_order (order_year)

If you then execute the following statement

SELECT * from sales_order
WHERE year(order_date) = '2000'

the server recognizes that there is an indexed column that holds that information and uses that index to answer the query.

The domain of the computed column must be equivalent to the domain of the COMPUTE expression in order for the column substitution to be made. In the above example, if year(order_date) had returned a string instead of an integer, the optimizer would not have substituted the computed column for the expression, and consequently the index idx_year could not have been used to retrieve the required rows.

For more information about computed columns, see Working with computed columns.

Examples

In each of these examples, attributes x and y are each columns of a single table. Attribute z is contained in a separate table. Assume that an index exists for each of these attributes.

Sargable | Non-sargable
x = 10 | x <> 10
x IS NULL | x IS NOT NULL
x > 25 | x = 4 OR y = 5
x = z | x = y
x IN (4, 5, 6) | x NOT IN (4, 5, 6)
x LIKE 'pat%' | x LIKE '%tern'
x = 20 - 2 | x + 2 = 20

Sometimes it may not be obvious whether a predicate is sargable. In these cases, you may be able to rewrite the predicate so it is sargable. For each example, you could rewrite the predicate x LIKE 'pat%' using the fact that "u" is the next letter in the alphabet after "t": x >= 'pat' and x < 'pau'. In this form, an index on attribute x is helpful in locating values in the restricted range. Fortunately, Adaptive Server Anywhere makes this particular transformation for you automatically.

A sargable predicate used for indexed retrieval on a table is a matching predicate. A WHERE clause can have a number of matching predicates. Which is most suitable can depend on the join strategy. The optimizer re-evaluates its choice of matching predicates when considering alternate join strategies.


Types of semantic transformations

The optimizer can perform a number of transformations in search of more efficient and convenient representations of your query. Because the optimizer performs these transformations, the plan may look quite different from a literal interpretation of your original query. Common manipulations include:

  • unnecessary DISTINCT elimination

  • subquery unnesting

  • predicate pushdown in UNION or GROUPed views

  • join elimination

  • optimization for minimum or maximum functions

  • OR, in-list optimization

  • LIKE optimizations

  • conversion of outer joins to inner joins

  • discovery of exploitable conditions through predicate inference

  • elimination of unnecessary case translation

The following subsections discuss each of these operations.

Unnecessary DISTINCT elimination
Subquery unnesting
Predicate pushdown into GROUPed or UNION views
Join elimination
Optimization for minimum or maximum functions
IN-list optimization
LIKE optimizations
Conversion of outer joins to inner joins
Discovery of exploitable conditions
Elimination of unnecessary case translation


Unnecessary DISTINCT elimination

Sometimes a DISTINCT condition is unnecessary. For example, the properties of one or more column in your result may contain a UNIQUE condition, either explicitly, or implicitly because it is in fact a primary key.

Examples

The distinct keyword in the following command is unnecessary because the product table contains the primary key p.id, which is part of the result set.

SELECT DISTINCT p.id, p.quantity
FROM product p

p<seq>

The database server actually executes the semantically equivalent query:

SELECT p.id, p.quantity
FROM product p

Similarly, the result of the following query contains the primary keys of both tables so each row in the result must be distinct.

SELECT DISTINCT *
FROM sales_order o JOIN customer c
   ON o.cust_id = c.id
WHERE c.state = 'NY'

c<seq> JNL o<ix_sales_cust>


Subquery unnesting

You may express statements as nested queries, given the convenient syntax provided in the SQL language. However, rewriting nested queries as joins often leads to more efficient execution and more effective optimization, since Adaptive Server Anywhere can take better advantage of highly selective conditions in a subquery's WHERE clause.

Examples

The subquery in the following example can match at most one row for each row in the outer block. Because it can match at most one row, Adaptive Server Anywhere recognizes that it can convert it to an inner join.

SELECT s.*
FROM sales_order_items s
WHERE EXISTS
    (   SELECT *
      FROM product p
      WHERE s.prod_id = p.id
         AND p.id = 300 AND p.quantity > 300)

Following conversion, this same statement is expressed internally using join syntax:

SELECT s.*
FROM product p JOIN sales_order_items s
   ON p.id = s.prod_id
WHERE p.id = 300 AND p.quantity > 20

p<seq> JNL s<ky_prod_id>

Similarly, the following query contains a conjunctive EXISTS predicate in the subquery. This subquery can match more than one row.

SELECT p.*
FROM product p
WHERE EXISTS
    (   SELECT *
      FROM sales_order_items s
      WHERE s.prod_id = p.id
         AND s.id = 2001)

Adaptive Server Anywhere converts this query to an inner join, with a DISTINCT in the SELECT list.

SELECT DISTINCT p.*
FROM product p JOIN sales_order_items s
   ON p.id = s.prod_id
WHERE s.id = 2001

DistI[ s<id_fk> JNL p<product> ]

Adaptive Server Anywhere can also eliminate subqueries in comparisons, when the subquery can match at most one row for each row in the outer block. Such is the case in the following query.

SELECT *
FROM product p
WHERE p.id =
    (   SELECT s.prod_id
      FROM sales_order_items s
      WHERE s.id = 2001
         AND s.line_id = 1 )

Adaptive Server Anywhere rewrites this query as follows.

SELECT p.*
FROM product p, sales_order_items s
WHERE p.id = s.prod_id
   AND s.id = 2001
   AND s.line_id = 1

p<seq> JNL s<sales_order_items>

The DUMMY table is treated as a special table when subquery unnesting rewrite optimizations are performed. Subquery flattening is always done on subqueries of the form SELECT expression FROM DUMMY, even if the subquery is not correlated.


Predicate pushdown into GROUPed or UNION views

It is quite common for queries to restrict the result of a view so that only a few of the records are returned. In cases where the view contains GROUP BY or UNION, it would be preferable for the server to only compute the result for the desired rows.

Example

Suppose we have the view product_summary defined as

CREATE VIEW product_summary( product_id, num_orders, total_qty) as
SELECT prod_id, count(*), sum( quantity )
FROM sales_order_items
GROUP BY prod_id

which returns, for each product ordered, a count of the number of orders that include it, and the sum of the quantities ordered over all of the orders. Now consider the following query over this view:

SELECT *
FROM product_summary
WHERE product_id = 300

which restricts the output to that for product id 300. The query and the query from the view could be combined into one semantically equivalent SELECT statement, namely:

SELECT prod_id, count(*), sum( quantity )
FROM sales_order_items
GROUP BY prod_id
HAVING prod_id = 300.

A naive execution plan for this query would involve computing the aggregates for each product, and then restricting the result to only the single row for product ID 300. However, the HAVING predicate on the product_id column can be pushed into the query's WHERE clause since it is a grouping column, yielding

SELECT prod_id, count(*), sum( quantity )
FROM sales_order_items
WHERE prod_id = 300
GROUP BY prod_id

which significantly reduces the computation required. If this predicate is sufficiently selective, the optimizer could now use an index on prod_id to quickly retrieve only those rows for product 300, rather than sequentially scanning the sales_order_items table.

The same optimization is also used for views involving UNION or UNION ALL.


Join elimination

The join elimination rewrite optimization reduces the join degree of the query by eliminating tables from the query when it is safe to do so. Typically, this optimization is used when the query contains a primary key-foreign key join, and only primary key columns from the primary table are referenced in the query.

Example

For example, the query

SELECT s.id, s.line_id, p.id
FROM sales_order_items s KEY JOIN product p

would be rewritten as

SELECT s.id, s.line_id, s.prod_id
FROM sales_order_items s
WHERE s.prod_id IS NOT NULL.

The second query is semantically equivalent to the first because any row from the sales_order_items table that has a NULL foreign key to product will not appear in the result.

The join elimination optimization can also apply to tables involved in outer joins, although the conditions for which the optimization is valid are much more complex. Under certain other conditions, tables involved in primary key-primary key joins may also be candidates for elimination.

Users should be aware that when this optimization is used, the result of a DESCRIBE can differ from the expected result due to the substitution of columns. In addition, an UPDATE or DELETE WHERE CURRENT request may fail if the update statement refers to one or more of the eliminated base tables. To circumvent this problem, either ensure that additional columns from the eliminated table are present in the query's SELECT list (to avoid the optimization in the first place), or update the necessary row(s) using a separate statement.


Optimization for minimum or maximum functions

The min/max rewrite optimization is designed to exploit an existing index to efficiently compute the result of a simple aggregation query involving the MAX() or MIN() aggregate functions. The goal of this optimization is to be able to compute the result with a single-row lookup using the index. To be a candidate for this optimization, the query:

  • must not contain a GROUP BY clause

  • must be over a single table

  • cannot contain anything other than conjunctive equality conditions in the WHERE clause

  • must contain only a single aggregate function (MAX or MIN) in the query's SELECT list

Example

To illustrate this optimization, assume that an index prod_qty on (prod_id ASC, quantity ASC) exists on the sales_order_items table. Then the query

SELECT MIN( quantity )
FROM sales_order_items
Where prod_id = 300

is rewritten internally as

SELECT MIN( quantity )
FROM ( SELECT FIRST quantity
       FROM sales_order_items
       WHERE prod_id = 300 and quantity IS NOT NULL
       ORDER BY prod_id ASC, quantity ASC ) as s(quantity)

The NULL_VALUE_ELIMINATED warning may not be generated for aggregate queries when this optimization is applied.

The access plan (short form) for the rewritten query is:

GrByS[ RL[ sales_order_items<prod_qty> ] ]


IN-list optimization

The Adaptive Server Anywhere optimizer supports a special optimization for exploiting IN predicates on indexed columns. This optimization also applies equally to multiple predicates on the same indexed column that are ORed together, since the two are semantically equivalent. To enable the optimization, the IN-list must contain only constants.

When the optimizer encounters a qualifying IN-list predicate, and the IN-list predicate is sufficiently selective to consider indexed retrieval, the optimizer converts the IN-list predicate into a nested-loop join. The following example illustrates how the optimization works.

Suppose we have the query

SELECT *
FROM sales_order
WHERE sales_rep = 142 or sales_rep = 1596

that lists all of the orders for these two sales reps. This query is semantically equivalent to

SELECT *
FROM sales_order
WHERE sales_rep IN (142, 1596)

The optimizer estimates the combined selectivity of the IN-list predicate to be high enough to warrant indexed retrieval. Consequently the optimizer treats the IN-list as a virtual table, and joins this virtual table to the sales_order table on the sales_rep attribute. While the net effect of the optimization is to include an additional "join" in the access plan, the join degree of the query is not increased, so optimization time should not be affected.

There are two main advantages of this optimization. First, the IN-list predicate can be treated as a sargable predicate and exploited for indexed retrieval. Second, the optimizer can sort the IN-list to match the sort sequence of the index, leading to more efficient retrieval.

The short form of the access plan for the above query is

IN JNL sales_order<ky_so_employee_id>


LIKE optimizations

LIKE predicates involving patterns that are either literal constants or host variables are very common. Depending on the pattern, the optimizer may rewrite the LIKE predicate entirely, or augment it with additional conditions that could be exploited to perform indexed retrieval on the corresponding table.

Examples

In each of the following examples, assume that the pattern in the LIKE predicate is a literal constant or host variable, and X is a column in a base table.

  • X LIKE '%' is rewritten as X IS NOT NULL

  • X LIKE 'abc' is rewritten as X = 'abc'

  • X LIKE 'abc%' is augmented with the predicates X < 'abcZ' and X > = 'abc_'

where Z and _ represent the corresponding high values and low values for the collating sequence of this database. If the database is configured to store blank-padded strings, the second comparison operator is >, not >=, to ensure correct semantics.


Conversion of outer joins to inner joins

For the most part, the optimizer generates a left-deep processing tree for its access plans. The only exception to this rule is the existence of a right-deep nested outer join expression. The query execution engine's algorithms for computing LEFT or RIGHT OUTER JOINs require that preserved tables must precede null-supplying tables in any join strategy. Consequently the optimizer looks for opportunities to convert LEFT or RIGHT outer joins to inner joins whenever possible, since inner joins are commutable and give the optimizer greater degrees of freedom when performing join enumeration.

A LEFT or RIGHT OUTER JOIN can be converted to an inner join when a null-intolerant predicate on the null-supplying table is present in the query's WHERE clause. Since this predicate is null-intolerant, any all-NULL row that would be produced by the outer join will be eliminated from the result, hence making the query semantically equivalent to an inner join.

Example

For example, consider the query

SELECT *
FROM product p KEY LEFT OUTER JOIN sales_order_items s
WHERE s.quantity > 15

which is intended to list all products and their orders for larger quantities; the LEFT OUTER JOIN is intended to ensure that all products are listed, even if they have no orders. The problem with this query is that the predicate in the WHERE clause will eliminate from the result any product with no orders, because the predicate s.quantity > 15 will be interpreted as FALSE if s.quantity is NULL. Hence the query is semantically equivalent to

SELECT *
FROM product p KEY JOIN sales_order_items s
WHERE s.quantity > 15

and it is this rewritten form of the query that the server will optimize.

In this example, the query is almost certainly written incorrectly; it should probably read

SELECT *
FROM product p
    KEY LEFT OUTER JOIN sales_order_items s
          ON s.quantity > 15

so that the test of quantity is part of the outer join condition.

While it is rare for this optimization to apply to straightforward outer join queries, it can often apply when a query refers to one or more views that are written using outer joins. The query's WHERE clause may include conditions that restrict the output of the view such that all null-supplying rows from one or more table expressions would be eliminated, hence making this optimization applicable.


Discovery of exploitable conditions

An efficient access strategy for virtually any query relies on the presence of sargable conditions in the WHERE/ON/HAVING clauses. Indexed retrieval is possible only by exploiting sargable conditions as matching predicates. In addition, hash, merge, and block-nested loop joins can only be used when an equijoin condition is present. For these reasons, Adaptive Server Anywhere does detailed analysis of the search conditions in the original query text in order to discover simplified or implied conditions that can be exploited by the optimizer.

As a preprocessing step, several simplifications are made to predicates in the original statement once view expansion and merging have taken place. For example:

  • X = X is rewritten as X IS NOT NULL if X is nullable; otherwise the predicate is eliminated.

  • ISNULL(X,X) is rewritten as simply X.

  • X+0 is rewritten as X if X is a numeric column.

  • AND 1=1 is eliminated.

  • OR 1=0 is eliminated.

  • IN-list predicates that consist of a single element are converted to simple equality conditions.

After this preprocessing step, Adaptive Server Anywhere attempts to normalize the original search condition into conjunctive normal form (CNF). For an expression to be in CNF, each term in the expression must be ANDed together. Each term is either made up of a single atomic condition, or a set of conditions ORed together.

Converting an arbitrary condition into CNF may yield an expression of similar complexity but with a much larger set of conditions. Adaptive Server Anywhere recognizes this situation, and refrains from naively converting the condition into CNF. Instead, Adaptive Server Anywhere analyzes the original expression for exploitable predicates that are implied by the original search condition, and ANDs these inferred conditions to the query. Complete normalization is also avoided if this would require duplication of an expensive predicate (for example, a quantified subquery predicate). However, the algorithm will merge IN-list predicates together whenever feasible.

Once the search condition has either been completely normalized or the exploitable conditions have been found, the optimizer performs transitivity analysis to discover transitive equality conditions, primarily transitive join conditions and conditions with a constant. In doing so the optimizer will increase its degrees of freedom when performing join enumeration during its cost-based optimization phase, since these transitive conditions may permit additional alternative join orders.

Example

Suppose the original query is

SELECT e.emp_lname, s.id, s.order_date
FROM sales_order s, employee e
WHERE (e.emp_id = s.sales_rep and
          (s.sales_rep = 142 or s.sales_rep = 1596)
      )
         OR
      ( e.emp_id = s.sales_rep and s.cust_id = 667)

This query has no conjunctive equijoin condition; hence without detailed predicate analysis the optimizer would fail to discover an efficient access plan. Fortunately, Adaptive Server Anywhere is able to convert the entire expression to CNF, yielding the equivalent query

SELECT e.emp_lname, s.id, s.order_date
FROM sales_order as s, employee as e
WHERE e.emp_id = s.sales_rep AND
   (s.sales_rep = 142 or s.sales_rep = 1596 or s.cust_id = 667)'

which can now be efficiently optimized as an inner join query.


Elimination of unnecessary case translation

By default, Adaptive Server Anywhere databases support case-insensitive string comparisons. Occasionally the optimizer may encounter queries where the user is explicitly forcing text conversion through the use of the UPPER() or LOWER() built-in functions when such conversion is unnecessary. Adaptive Server Anywhere will automatically eliminate this unnecessary conversion when the database's collating sequence permits it. Eliminating the case translation may then permit the comparison predicate to be used for indexed retrieval of the corresponding table.

Example

On a case insensitive database, the query

SELECT *
FROM customer
WHERE UPPER(lname) = 'SMITH'

is rewritten internally as

SELECT *
FROM customer
WHERE lname = 'SMITH'

and the optimizer can now consider using an index on customer.lname.


Subquery and function caching

When Adaptive Server Anywhere processes a subquery, it caches the result. This caching is done on a request-by-request basis; cached results are never shared by concurrent requests or connections. Should Adaptive Server Anywhere need to re-evaluate the subquery for the same set of correlation values, it can simply retrieve the result from the cache. In this way, Adaptive Server Anywhere avoids many repetitious and redundant computations. When the request is completed (the query's cursor is closed), Adaptive Server Anywhere releases the cached values.

As the processing of a query progresses, Adaptive Server Anywhere monitors the frequency with which cached subquery values are reused. If the values of the correlated variable rarely repeat, then Adaptive Server Anywhere needs to compute most values only once. In this situation, Adaptive Server Anywhere recognizes that it is more efficient to recompute occasional duplicate values, than to cache numerous entries that occur only once. Hence the server suspends the caching of this subquery for the remainder of the statement and proceeds to re-evaluate the subquery for each and every row in the outer query block.

Adaptive Server Anywhere also does not cache if the size of the dependent column is more than 255 bytes. In such cases, you may wish to rewrite your query or add another column to your table to make such operations more efficient.

Function caching

Some built-in and user-defined functions are cached in the same way that subquery results are cached. This can result in a substantial improvement for expensive functions that are called during query processing with the same parameters. However, it may mean that a function is called less times than would otherwise be expected.

For a functions to be cached, it must satisfy two conditions:

  • It must always return the same result for a given set of parameters.

  • It must have no side effects on the underlying data.

Functions that satisfy these conditions are called deterministic or idempotent functions.

Built-in functions are treated as deterministic with a few exceptions. The RAND, NEW_ID, and GET_IDENTITY functions are treated as non-deterministic, and their results are not cached.

User-defined functions are treated as deterministic unless they are specified as NOT DETERMINISTIC when created.

For more information about user-defined functions, see CREATE FUNCTION statement.


Reading access plans

The optimizer can tell you the query optimization strategy (plan) it has chosen in response to any statement.

The optimizer's job is to understand the semantics of your query and to construct a plan that computes its result. This plan may not correspond exactly to the syntax you used. The optimizer is free to rewrite your query in any semantically equivalent form.

For more information about the rules Adaptive Server Anywhere obeys when rewriting your query, see Rewriting subqueries as EXISTS predicates and Semantic query transformations.

For information about the methods that the optimizer uses to implement your query, see Query execution algorithms.

You can view the plan in Interactive SQL or using SQL functions. You can choose to retrieve the access plan in several different formats:

  • Short text

  • Long text

  • Graphical

  • Graphical with statistics

  • UltraLite (short, long, or graphical)

As well, you can obtain plans for SQL queries with a particular cursor type.

For more information about how to access the plan, see Accessing the plan. For information about how to read plans, see Text plans and Graphical plans.

Following is an explanation of the statistics and other items that are displayed in access plans.

Abbreviations used in the plan

Following are the abbreviations that are used in short plan, and in the short name form of the graphical plans:

Name | Short Plan / Short name
Hash except all | EAH
Hash except | EH
Hash group by | GrByH
Hash table scan | HTS
Clustered Hash group by | GrByHClust
Hash rollup group by | GrByHR
Ordered group by | GrByO
Ordered rollup group by | GrByOR
Single row group by | GrByS
Indexed group by | GrByI
Hash distinct | DistH
Indexed distinct | DistI
Ordered distinct | DistO
Sort Top N | StrN
Hash filter | HF
Hash intersect all | IAH
Hash intersect | IH
Exists join | JE
Nested loops semijoin | JNLS
Hash exists | JHE
Hash not exists | JHNE
Hash join | JH
Sorted block | SrtBl
Left outer hash join | JHO
Full outer hash join | JHFO
Recursive hash join | JHR
Left outer recursive hash join | JHRO
Nested block join | JNB
Left outer nested block join | JNBO
Not exists join | JNE
Nested loops join | JNL
Left outer nested loops join | JNLO
Full outer nested loops join | JNLFO
Merge join | JM
Left outer merge join | JMO
Full outer merge join | JMFO
Merge except | EM
Merge except all | EAM
Merge intersect | IM
Merge intersect all | IAM
Row limit | RL
Row replicate | RR
Derived table | DT
Recursive table | RT. In short plan is rt<seq>
Recursive union | RU
Union all | UA
Table scan | In short plan is tablename<seq>. In graphical plans is just the table name.
Index scan | In short plan is tablename<indexname>. In graphical plans is just the table name.
In list | IN

For an explanation of the algorithms, see Query execution algorithms.

Common statistics used in the plan

The following statistics are actual, measured amounts.

Statistic | Explanation
Invocations | Number of times a row was requested from the sub tree.
RowsReturned | Number of rows returned for the current node.
RunTime | Time required for execution of the sub-tree, including time for children.
CacheHits | Number of successful reads of the cache.
CacheRead | Number of database pages that have been looked up in the cache.
CacheReadTable | Number of table pages that have been read from the cache.
CacheReadIndLeaf | Number of index leaf pages that have been read from the cache.
CacheReadIndInt | Number of index internal node pages that have been read from the cache.
DiskRead | Number of pages that have been read from disk.
DiskReadTable | Number of table pages that have been read from disk.
DiskReadIndLeaf | Number of index leaf pages that have been read from disk.
DiskReadIndInt | Number of index internal node pages that have been read from disk.
DiskWrite | Number of pages that have been written to disk (work table pages or modified table pages).
IndAdd | Number of entries that have been added to indexes.
IndLookup | Number of entries that have been looked up in indexes.
FullCompare | Number of comparisons that have been performed beyond the hash value in an index.
Common estimates used in the plan
Statistic | Explanation
EstRowCount | Estimated number of rows that the node will return each time it is invoked.
AvgRowCount | Average number of rows returned on each invocation. This is not an estimate, but is calculated as RowsReturned / Invocations. If this value is significantly different from EstRowCount, the selectivity estimates may be poor.
EstRunTime | Estimated time required for execution (sum of EstDiskReadTime, EstDiskWriteTime, and EstCpuTime).
AvgRunTime | Average time required for execution (measured).
EstDiskReads | Estimated number of read operations from the disk.
AvgDiskReads | Average number of read operations from the disk (measured).
EstDiskWrites | Estimated number of write operations to the disk.
AvgDiskWrites | Average number of write operations to the disk (measured).
EstDiskReadTime | Estimated time required for reading rows from the disk.
EstDiskWriteTime | Estimated time required for writing rows to the disk.
EstCpuTime | Estimated processor time required for execution.
Items in the plan related to SELECT, INSERT, UPDATE, and DELETE
Item | Explanation
Optimization Goal | Determines whether query processing is optimized towards returning the first row quickly, or minimizing the cost of returning the complete result set. See OPTIMIZATION_GOAL option [database].
Optimization workload | Determines whether query processing is optimized towards a workload that is a mix of updates and reads or a workload that is predominantly read-based. See OPTIMIZATION_WORKLOAD option [database].
ANSI update constraints | Controls the range of updates that are permitted (options are OFF, CURSORS, and STRICT). See ANSI_UPDATE_CONSTRAINTS option [compatibility]
Optimization level | Reserved for future use.
Select list | List of expressions selected by the query.
Items in the plan related to locks
Item | Explanation
Locked tables | List of all locked tables and their isolation levels.
Items in the plan related to scans
Item | Explanation
Table name | Actual name of the table.
Correlation name | Alias for the table.
Estimated rows | Estimated number of rows in the table.
Estimated pages | Estimated number of pages in the table.
Estimated row size | Estimated row size for the table.
Page maps | YES when a page map is used to read multiple pages.
Items in the plan related to index scans
Item | Explanation
Index name | Name of the index.
Key type | Can be one of PRIMARY KEY, FOREIGN KEY, CONSTRAINT (unique constraint), or UNIQUE (unique index). The key type is not displayed if the index is a non-unique secondary index.
Depth | Height of the index. For more information, see Table and page sizes.
Estimated leaf pages | Estimated number of leaf pages.
Cardinality | The cardinality of the index if it is different from the estimated number of rows. This applies only to Adaptive Server Anywhere databases version 6.0 and earlier.
Selectivity | The estimated number of rows that match the range bounds.
Direction | FORWARD or BACKWARD.
Range bounds | Range bounds are shown as a list (col_name=value) or col_name IN [low, high].
Items in the plan related to joins, filter, and pre-filter
Item | Explanation
Predicate | The search condition that is evaluated in this node, along with selectivity estimates and measurement. For more information, see Selectivity in the plan
Items in the plan related to hash filter
Item | Explanation
Build values | Estimated number of distinct values in the input.
Probe values | Estimated number of distinct values in the input when checking the predicate.
Bits | Number of bits selected to build the hash map.
Pages | Number of pages required to store the hash map.
Items in the plan related to Union
Item | Explanation
Union List | The columns involved in a UNION operation.
Items in the plan related to GROUP BY
Item | Explanation
Aggregates | All the aggregate functions.
Group-by list | All the columns in the group by clause.
Items in the plan related to DISTINCT
Item | Explanation
Distinct list | All the columns in the distinct clause.
Items in the plan related to IN LIST
Item | Explanation
In List | All the expressions in the specified set.
Expression SQL | Expressions to compare to the list.
Items in the plan related to SORT
Item | Explanation
Order-by | List of all expressions to sort by.
Items in the plan related to row limits
Item | Explanation
Row limit count | Maximum number of rows returned as specified by FIRST or TOP n.


Text plans

There are two types of text plan: short and long. To choose a plan type in Interactive SQL, open the Options dialog from the Tools menu, and click the Plan tab. To use SQL functions to access the plan, see Accessing the plan with SQL functions.

Colons separate join strategies

The following command contains two query blocks: the outer select statement from the sales_order and sales_order_items tables, and the subquery that selects from the product table.

SELECT *
FROM sales_order AS o
   KEY JOIN sales_order_items AS i
WHERE EXISTS
   (   SELECT *
      FROM product p
      WHERE p.id = 300 )

i<seq> JNL o<sales_order> : p<seq>

Colons separate join strategies. Plans always list the join strategy for the main block first. Join strategies for other query blocks follow. The order of join strategies for these other query blocks may not correspond to the order in your statement nor to the order in which they execute.

Short text plan

The short plan is useful when you want to compare plans quickly. It provides the least amount of information of all the access plan formats, but it provides it on a single line.

In the following example, the plan starts with the word SORT because the ORDER BY clause causes the entire result set to be sorted. The customer table is accessed by its primary key index, also called customer. An index scan is used to satisfy the search condition because the column customer.id is a primary key. The abbreviation JNL indicates that the optimizer is using a nested loops join to process the query. Finally, the sales_order table is accessed using the foreign key index ky_so_customer to find matching rows in the customer table.

The Plan tab in Interactive SQL, showing the short plan for a query.

For more information about code words used in the plan, see Abbreviations used in the plan.

Long text plan

The long plan provides a little more information than the short plan, and provides information in a way that is easy to print and view without scrolling down.

In the long plan output for the same query, the first line is Plan [ I/O Estimate: 1 ]. The words Plan or Sub-plan indicate the start of a query block (in this case, there is only one). The I/O estimates how many I/O are required for the query (in this case, one). Again, the plan indicates that the results are sorted, and that a nested loops join is the join algorithm to be used. On the same line as the algorithm, there is either the word TRUE or the search condition and selectivity estimate for the algorithm (in this case, there is none). The WHERE condition is represented on the line starting with FILTER, followed by the search condition, selectivity estimate for the search condition, and source of the selectivity estimate.

The Plan tab in Interactive SQL, showing the long plan for a query.

For more information about code words used in the plan, see Abbreviations used in the plan.


Graphical plans

There are two types of graphical plan: the graphical plan, and the graphical plan with statistics. To choose a plan type in Interactive SQL, open the Options dialog from the Tools menu, and click the Plan tab. To access the plan with SQL functions, see Accessing the plan with SQL functions.

Once the graphical plan is displayed, you can configure the way it is displayed by right-clicking the left pane and choosing Customize.

You can print the graphical plan for later reference. To print the plan, right-click a node and choose Print.

To obtain context-sensitive help for each node in the graphical plan, select the node, right-click it and choose Help. For example, right-click Nested Loops Join and choose Help for information about the resources used by that part of the execution. There is also pop-up information that is available by hovering your cursor over each element in the graphical plan.

Graphical plan

The graphical plan provides a great deal more information than the short or long plans. You can choose to see either the graphical plan, or the graphical plan with statistics. Both allow you to quickly view which parts of the plan have been estimated as the most expensive. The graphical plan with statistics, though more expensive to view, also provides the actual query execution statistics as monitored by the server when the query is executed, and permits direct comparison between the estimates used by the query optimizer in constructing the access plan with the actual statistics monitored during execution. Note, however, that the optimizer is often unable to precisely estimate a query's cost, so expect there to be differences. The graphical plan is the default format for access plans.

The graphical plan is designed to provide some key information visually:

  • Each operation displayed in the graphical plan is displayed in a container. The container indicates whether the operation materializes data, whether it is an index scan, whether it is a table scan, or whether it is some other operation.

  • The number of rows that an operation passes to the next operation in the plan is indicated by the thickness of the line joining the operations. This provides a visual indicator of the operations carried out on most data in the query.

  • The container for an operation that is particularly slow is given a red border.

In general, execution of nodes on the thick lines and in subtrees with red boxes are most likely to determine query performance.

Each of these display features is customizable.

If a query is recognized as a simple query, some optimization steps are bypassed and neither the Query Optimizer section nor the Predicate section are displayed in the graphical plan. For more information on simple queries, see How the optimizer works.

Following is the same query that was used to describe the short and long text plans, presented with the graphical plan. The diagram is in the form of a tree, indicating that each node requests rows from the nodes beneath it. The Lock node indicates that the result set is materialized, or that a row is returned to an application. In this case, the sort requires that results are materialized. At level 0, rows aren't really locked: Adaptive Server Anywhere just ensures that the row has not been deleted since it was read from the base tables. At level 1, a row is locked only until the next row is accessed. At levels 2 and 3, read locks are applied and held until COMMIT.

You can obtain detailed information about the nodes in the plan by clicking the node in the graphical diagram. In this example, the nested loops join node is selected. The information in the right pane pertains only to that node. For example, the Predicate description is simply TRUE, indicating that at this stage in the query execution no predicate is being applied (the only predicate in the query (customer.id < 100) is applied in the customer table query node).

The Plan tab in Interactive SQL, showing the graphical plan for a query.

For more information about abbreviations used in the plan, see Abbreviations used in the plan.

Graphical plan with statistics

The graphical plan with statistics shows you all the estimates that are provided with the graphical plan, but also shows actual runtime costs of executing the statement. To do this, the statement must actually be executed. This means that there may be a delay in accessing the plan for expensive queries. It also means that any parts of your query such as deletes or updates are actually executed, although you can perform a rollback to undo these changes.

Use the graphical plan with statistics when you are having performance problems and if the estimated row count or run time differs from your expectations. The graphical plan with statistics provides estimates and actual statistics for you to compare. A large difference between actual and estimate is a warning sign that the optimizer might not have sufficient information to choose a good access plan.

The database options and other global settings that affect query execution are displayed for the root operator only.

Following are some of the key statistics you can check in the graphical plan with statistics, and some possible remedies:

  • Selectivity statistics The selectivity of a predicate (conditional expression) is the percentage of rows that satisfy the condition. The estimated selectivity of predicates provides the information on which the optimizer bases its cost estimates. If the selectivity estimates are poor, the query optimizer may generate a poor access plan. For example, if the optimizer mistakenly estimates a predicate to be highly selective (with, say, a selectivity of 5%), but the actual selectivity is much lower (for example, 50%), then it may choose an inappropriate plan. Selectivity estimates are not precise, but a significantly large error does indicate a possible problem.

    If you determine that the selectivity information for a key part of your query is inaccurate, you may be able to use CREATE STATISTICS to generate a new set of statistics for the column in question. In rare cases, you may wish to supply explicit selectivity estimates, although these present potential maintenance problems.

    For more information about selectivity, see Selectivity in the plan.

    For more information about creating statistics, see CREATE STATISTICS statement.

    For more information about user estimates, see Explicit selectivity estimates.

    Selectivity statistics are not displayed if the query is determined to be a simple query, so that the optimizer is bypassed. For more information on simple queries, see How the optimizer works.

    Indicators of poor selectivity occur in the following places:

    • RowsReturned actuals and estimates RowsReturned is the number of rows in the result set. The RowsReturned statistic appears in the table for the root node at the top of the tree. A significant difference between the estimated rows returned and the actual number returned is a warning sign that the optimizer is working on poor selectivity information.

    • Predicate selectivity actuals and estimates Look for a subheading of Predicate to see predicate selectivities. For information about reading the predicate information, see Selectivity in the plan.

      If the predicate is over a base column for which there does not exist a histogram, executing a CREATE STATISTICS statement to create a histogram may correct the problem. If selectivity error remains a problem then, as a last resort, you may wish to consider specifying a user estimate of selectivity along with the predicate in the query text.

    • Estimate source The source of selectivity estimates is also listed under the Predicate subheadings in the statistics pane. For information about reading the predicate information, see Selectivity in the plan.

      An estimate source of Guess indicates that the optimizer has no selectivity information to use. If the estimate source is Index and the selectivity estimate is incorrect, your problem may be that the index is skewed: you may benefit from defragmenting the index with the REORGANIZE TABLE statement.

      For a complete list of the possible sources of selectivity estimates, see ESTIMATE_SOURCE function [Miscellaneous].

  • Cache reads and hits If the number of cache reads and cache hits are exactly the same, then all the information needed to execute the query is in cache—an excellent thing. When reads are greater than hits, it means that the server is attempting to go to cache but failing, and that it must read from disk. In some cases, such as hash joins, this is expected. In other cases, such as nested loops joins, a poor cache-hit ratio may indicate a performance problem, and you may benefit from increasing your cache size.

    For more information about cache management, see Increase the cache size.

  • Lack of appropriate indexes It is often not obvious from query execution plans whether an index would help provide better performance or not. Some of the scan-based algorithms used in Adaptive Server Anywhere provide excellent performance for many queries without using indexes.

    If you suspect that additional indexes may help provide better performance for a query, use the Index Consultant. For more information, see Index Consultant overview.

    For more information about indexes and performance, see Top performance tips and Using indexes.

  • Data fragmentation problems The Runtime actual and estimated values are provided in the root node statistics. Runtime measures the time to execute the query. If the runtime is incorrect for a table scan or index scan, you may improve performance by executing the REORGANIZE TABLE statement.

    For more information, see REORGANIZE TABLE statement and Examine file, table, and index fragmentation..

Following is an example of the graphical plan with statistics. Again, the nested loops join node is selected. The statistics in the right pane indicate the resources used by that part of the query.

The Plan tab in Interactive SQL, showing the graphical plan with statistics for a query.

For more information about code words used in the plan, see Abbreviations used in the plan.

Selectivity in the plan

Following is an example of the Predicate showing selectivity of a search condition. In this example, the selected node represents a scan of the department table, and the statistics pane shows the Predicate as the search condition and selectivity statistics.

Selectivity information may not be displayed for simple queries for which some optimization steps are bypassed. For more information on simple queries, see How the optimizer works.

The access plan depends on the statistics available in the database, which depends in turn on what queries have previously been executed. You may see different statistics and plans from those shown here.

Graphical plan with statistics showing the predicate.

This predicate description is

department.dept_name = 'Sales' : 5% Guess; true 1/5 20%

This can be read as follows:

  • department.dept_name = 'Sales' is the predicate.

  • 5% is the optimizer's estimate of the selectivity. That is, the optimizer is basing its query access selection on the estimate that 5% of the rows satisfy the predicate.

    This is the same output as is provided by the ESTIMATE function. For more information, see ESTIMATE function [Miscellaneous].

  • Guess is the source of the estimate. This is the same output as is provided by the ESTIMATE_SOURCE function. For a complete list of the possible sources of selectivity estimates, see ESTIMATE_SOURCE function [Miscellaneous].

  • true 1/5 20% is the actual selectivity of the predicate during execution. The predicate was evaluated five times, and was true once, for a selectivity of 20%.

    If the actual selectivity is very different from the estimate, and if the predicate was evaluated a large number of times, it is possible that the incorrect estimates are causing a significant problem in query performance. Collecting statistics on the predicate may improve performance by giving the optimizer better information on which to base its choices.

Note: If you select the graphical plan, but not the graphical plan with statistics, the final two statistics are not displayed.


Accessing the plan

You can see the access plan in Interactive SQL, or using SQL functions. The plan is also displayed from the Index Consultant


Accessing the plan in Interactive SQL

The following types of plan are available in Interactive SQL:

  • Short plan

  • Long plan

  • Graphical plan

  • Graphical plan with statistics

To choose the type of plan you want to see, click Tools > Options and select the Plan tab.

To see the plan, execute a query and then open the Plan tab. The Plan tab is located at the bottom of the Interactive SQL window.

UltraLite plan

You can also view the UltraLite plan for your query. The UltraLite plan does not include statistics.

To view the UltraLite plan in Interactive SQL, open the Options dialog from the Tools menu and select Show UltraLite Plan. This option is selected by default. You control the UltraLite plan type by selecting one of the types above (graphical, short plan, or long plan). If you choose graphical plan with statistics, you get the graphical plan.

The UltraLite Plan tab appears at the bottom of the Interactive SQL window. For some queries, the UltraLite execution plan may differ from the plan selected for Adaptive Server Anywhere.

For more information, see GRAPHICAL_ULPLAN function [Miscellaneous].


Accessing the plan with SQL functions

You can access the plan using SQL functions, and retrieve the output in XML format.

  • To access the short plan, see the EXPLANATION function [Miscellaneous].

  • To access the long plan, see the PLAN function [Miscellaneous].

  • To access the graphical plan, see the GRAPHICAL_PLAN function [Miscellaneous].

  • To access the UltraLite plan, see the GRAPHICAL_ULPLAN function [Miscellaneous], SHORT_ULPLAN function [Miscellaneous], or LONG_ULPLAN function [Miscellaneous].


Transact-SQL Compatibility

About this chapter

Transact-SQL is the dialect of SQL supported by Sybase Adaptive Server Enterprise.

This chapter is a guide for creating applications that are compatible with both Adaptive Server Anywhere and Adaptive Server Enterprise. It describes Adaptive Server Anywhere support for Transact-SQL language elements and statements, and for Adaptive Server Enterprise system tables, views, and procedures.

An overview of Transact-SQL support
Adaptive Server architectures
Configuring databases for Transact-SQL compatibility
Writing compatible SQL statements
Transact-SQL procedure language overview
Automatic translation of stored procedures
Returning result sets from Transact-SQL procedures
Variables in Transact-SQL procedures
Error handling in Transact-SQL procedures


An overview of Transact-SQL support

Adaptive Server Anywhere supports a large subset of Transact-SQL, which is the dialect of SQL supported by Sybase Adaptive Server Enterprise. This chapter describes compatibility of SQL between Adaptive Server Anywhere and Adaptive Server Enterprise.

Goals

The goals of Transact-SQL support in Adaptive Server Anywhere are as follows:

  • Application portability Many applications, stored procedures, and batch files can be written for use with both Adaptive Server Enterprise and Adaptive Server Anywhere databases.

  • Data portability Adaptive Server Anywhere and Adaptive Server Enterprise databases can exchange and replicate data between each other with minimum effort.

The aim is to write applications to work with both Adaptive Server Enterprise and Adaptive Server Anywhere. Existing Adaptive Server Enterprise applications generally require some changes to run on an Adaptive Server Anywhere database.

How Transact-SQL is supported

Transact-SQL support in Adaptive Server Anywhere takes the following form:

  • Many SQL statements are compatible between Adaptive Server Anywhere and Adaptive Server Enterprise.

  • For some statements, particularly in the procedure language used in procedures, triggers, and batches, a separate Transact-SQL statement is supported together with the syntax supported in previous versions of Adaptive Server Anywhere. For these statements, Adaptive Server Anywhere supports two dialects of SQL. In this chapter, we name those dialects Transact-SQL and Watcom-SQL.

  • A procedure, trigger, or batch is executed in either the Transact-SQL or Watcom-SQL dialect. You must use control statements from one dialect only throughout the batch or procedure. For example, each dialect has different flow control statements.

The following diagram illustrates how the two dialects overlap.

Similarities and differences

Adaptive Server Anywhere supports a very high percentage of Transact-SQL language elements, functions, and statements for working with existing data. For example, Adaptive Server Anywhere supports all of the numeric functions, all but one of the string functions, all aggregate functions, and all date and time functions. As another example, Adaptive Server Anywhere supports Transact-SQL outer joins (using =* and *= operators) and extended DELETE and UPDATE statements using joins.

Further, Adaptive Server Anywhere supports a very high percentage of the Transact-SQL stored procedure language (CREATE PROCEDURE and CREATE TRIGGER syntax, control statements, and so on) and many, but not all, aspects of Transact-SQL data definition language statements.

There are design differences in the architectural and configuration facilities supported by each product. Device management, user management, and maintenance tasks such as backups tend to be system-specific. Even here, Adaptive Server Anywhere provides Transact-SQL system tables as views, where the tables that are not meaningful in Adaptive Server Anywhere have no rows. Also, Adaptive Server Anywhere provides a set of system procedures for some of the more common administrative tasks.

This chapter looks first at some system-level issues where differences are most noticeable, before discussing data manipulation and data definition language aspects of the dialects where compatibility is high.

Transact-SQL only

Some SQL statements supported by Adaptive Server Anywhere are part of one dialect, but not the other. You cannot mix the two dialects within a procedure, trigger, or batch. For example, Adaptive Server Anywhere supports the following statements, but as part of the Transact-SQL dialect only:

  • Transact-SQL control statements IF and WHILE

  • Transact-SQL EXECUTE statement

  • Transact-SQL CREATE PROCEDURE and CREATE TRIGGER statements

  • Transact-SQL BEGIN TRANSACTION statement

  • SQL statements not separated by semicolons are part of a Transact-SQL procedure or batch

Adaptive Server Anywhere only

Adaptive Server Enterprise does not support the following statements:

  • control statements CASE, LOOP, and FOR

  • Adaptive Server Anywhere versions of IF and WHILE

  • CALL statement

  • Adaptive Server Anywhere versions of the CREATE PROCEDURE, CREATE FUNCTION, and CREATE TRIGGER statements

  • SQL statements separated by semicolons

Notes

The two dialects cannot be mixed within a procedure, trigger, or batch. This means that:

  • You can include Transact-SQL-only statements together with statements that are part of both dialects in a batch, procedure, or trigger.

  • You can include statements not supported by Adaptive Server Enterprise together with statements that are supported by both servers in a batch, procedure, or trigger.

  • You cannot include Transact-SQL-only statements together with Adaptive Server Anywhere-only statements in a batch, procedure, or trigger.


Adaptive Server architectures

Adaptive Server Enterprise and Adaptive Server Anywhere are complementary products, with architectures designed to suit their distinct purposes. Adaptive Server Anywhere works well as a workgroup or departmental server requiring little administration, and as a personal database. Adaptive Server Enterprise works well as an enterprise-level server for the largest databases.

This section describes architectural differences between Adaptive Server Enterprise and Adaptive Server Anywhere. It also describes the Adaptive Server Enterprise-like tools that Adaptive Server Anywhere includes for compatible database management.


Servers and databases

The relationship between servers and databases is different in Adaptive Server Enterprise and Adaptive Server Anywhere.

In Adaptive Server Enterprise, each database exists inside a server, and each server can contain several databases. Users can have login rights to the server, and can connect to the server. They can then use each database on that server for which they have permissions. System-wide system tables, held in a master database, contain information common to all databases on the server.

No master database in Adaptive Server Anywhere

In Adaptive Server Anywhere, there is no level corresponding to the Adaptive Server Enterprise master database. Instead, each database is an independent entity, containing all of its system tables. Users can have connection rights to a database, not to the server. When a user connects, they connect to an individual database. There is no system-wide set of system tables maintained at a master database level. Each Adaptive Server Anywhere database server can dynamically load and unload multiple databases, and users can maintain independent connections on each.

Adaptive Server Anywhere provides tools in its Transact-SQL support and in its Open Server support to allow some tasks to be carried out in a manner similar to Adaptive Server Enterprise. For example, Adaptive Server Anywhere provides an implementation of the Adaptive Server Enterprise sp_addlogin system procedure that carries out the nearest equivalent action: adding a user to a database.

For information about Open Server support, see Adaptive Server Anywhere as an Open Server.

File manipulation statements

Adaptive Server Anywhere does not support the Transact-SQL statements DUMP DATABASE and LOAD DATABASE. Adaptive Server Anywhere has its own CREATE DATABASE and DROP DATABASE statements with different syntax.


Device management

Adaptive Server Anywhere and Adaptive Server Enterprise use different models for managing devices and disk space, reflecting the different uses for the two products. While Adaptive Server Enterprise sets out a comprehensive resource management scheme using a variety of Transact-SQL statements, Adaptive Server Anywhere manages its own resources automatically, and its databases are regular operating system files.

Adaptive Server Anywhere does not support Transact-SQL DISK statements, such as DISK INIT, DISK MIRROR, DISK REFIT, DISK REINIT, DISK REMIRROR, and DISK UNMIRROR.

For information on disk management, see Working with Database Files.


Defaults and rules

Adaptive Server Anywhere does not support the Transact-SQL CREATE DEFAULT statement or CREATE RULE statement. The CREATE DOMAIN statement allows you to incorporate a default and a rule (called a CHECK condition) into the definition of a domain, and so provides similar functionality to the Transact-SQL CREATE DEFAULT and CREATE RULE statements.

In Adaptive Server Enterprise, the CREATE DEFAULT statement creates a named default. This default can be used as a default value for columns by binding the default to a particular column or as a default value for all columns of a domain by binding the default to the data type using the sp_bindefault system procedure.

The CREATE RULE statement creates a named rule which can be used to define the domain for columns by binding the rule to a particular column or as a rule for all columns of a domain by binding the rule to the data type. A rule is bound to a data type or column using the sp_bindrule system procedure.

In Adaptive Server Anywhere, a domain can have a default value and a CHECK condition associated with it, which are applied to all columns defined on that data type. You create the domain using the CREATE DOMAIN statement.

You can define default values and rules, or CHECK conditions, for individual columns using the CREATE TABLE statement or the ALTER TABLE statement.

For a description of the Adaptive Server Anywhere syntax for these statements, see SQL Statements.


System tables

In addition to its own system tables, Adaptive Server Anywhere provides a set of system views that mimic relevant parts of the Adaptive Server Enterprise system tables. You'll find a list and individual descriptions in Views for Transact-SQL compatibility, which describes the system catalogs of the two products. This section provides a brief overview of the differences.

The Adaptive Server Anywhere system tables rest entirely within each database, while the Adaptive Server Enterprise system tables rest partly inside each database and partly in the master database. The Adaptive Server Anywhere architecture does not include a master database.

In Adaptive Server Enterprise, the database owner (user ID dbo) owns the system tables. In Adaptive Server Anywhere, the system owner (user ID SYS) owns the system tables. A dbo user ID owns the Adaptive Server Enterprise-compatible system views provided by Adaptive Server Anywhere.


Administrative roles

Adaptive Server Enterprise has a more elaborate set of administrative roles than Adaptive Server Anywhere. In Adaptive Server Enterprise there is a set of distinct roles, although more than one login account on an Adaptive Server Enterprise can be granted any role, and one account can possess more than one role.

Adaptive Server Enterprise roles

In Adaptive Server Enterprise distinct roles include:

  • System Administrator Responsible for general administrative tasks unrelated to specific applications; can access any database object.

  • System Security Officer Responsible for security-sensitive tasks in Adaptive Server Enterprise, but has no special permissions on database objects.

  • Database Owner Has full permissions on objects inside the database he or she owns, can add users to a database and grant other users the permission to create objects and execute commands within the database.

  • Data definition statements Permissions can be granted to users for specific data definition statements, such as CREATE TABLE or CREATE VIEW, enabling the user to create database objects.

  • Object owner Each database object has an owner who may grant permissions to other users to access the object. The owner of an object automatically has all permissions on the object.

In Adaptive Server Anywhere, the following database-wide permissions have administrative roles:

  • The Database Administrator (DBA authority) has, like the Adaptive Server Enterprise database owner, full permissions on all objects inside the database (other than objects owned by SYS) and can grant other users the permission to create objects and execute commands within the database. The default database administrator is user ID DBA.

  • The RESOURCE permission allows a user to create any kind of object within a database. This is instead of the Adaptive Server Enterprise scheme of granting permissions on individual CREATE statements.

  • Adaptive Server Anywhere has object owners in the same way that Adaptive Server Enterprise does. The owner of an object automatically has all permissions on the object, including the right to grant permissions.

For seamless access to data held in both Adaptive Server Enterprise and Adaptive Server Anywhere, you should create user IDs with appropriate permissions in the database (RESOURCE in Adaptive Server Anywhere, or permission on individual CREATE statements in Adaptive Server Enterprise) and create objects from that user ID. If you use the same user ID in each environment, object names and qualifiers can be identical in the two databases, ensuring compatible access.


Users and groups

There are some differences between the Adaptive Server Enterprise and Adaptive Server Anywhere models of users and groups.

In Adaptive Server Enterprise, users connect to a server, and each user requires a login ID and password to the server as well as a user ID for each database they want to access on that server. Each user of a database can only be a member of one group.

In Adaptive Server Anywhere, users connect directly to a database and do not require a separate login ID to the database server. Instead, each user receives a user ID and password on a database so they can use that database. Users can be members of many groups, and group hierarchies are allowed.

Both servers support user groups, so you can grant permissions to many users at one time. However, there are differences in the specifics of groups in the two servers. For example, Adaptive Server Enterprise allows each user to be a member of only one group, while Adaptive Server Anywhere has no such restriction. You should compare the documentation on users and groups in the two products for specific information.

Both Adaptive Server Enterprise and Adaptive Server Anywhere have a public group, for defining default permissions. Every user automatically becomes a member of the public group.

Adaptive Server Anywhere supports the following Adaptive Server Enterprise system procedures for managing users and groups.

For the arguments to each procedure, see Adaptive Server Enterprise system and catalog procedures.

System procedure | Description
sp_addlogin | In Adaptive Server Enterprise, this adds a user to the server. In Adaptive Server Anywhere, this adds a user to a database.
sp_adduser | In Adaptive Server Enterprise and Adaptive Server Anywhere, this adds a user to a database. While this is a distinct task from sp_addlogin in Adaptive Server Enterprise, in Adaptive Server Anywhere, they are the same.
sp_addgroup | Adds a group to a database.
sp_changegroup | Adds a user to a group, or moves a user from one group to another.
sp_droplogin | In Adaptive Server Enterprise, removes a user from the server. In Adaptive Server Anywhere, removes a user from the database.
sp_dropuser | Removes a user from the database.
sp_dropgroup | Removes a group from the database.

In Adaptive Server Enterprise, login IDs are server-wide. In Adaptive Server Anywhere, users belong to individual databases.

Database object permissions

The Adaptive Server Enterprise and Adaptive Server Anywhere GRANT and REVOKE statements for granting permissions on individual database objects are very similar. Both allow SELECT, INSERT, DELETE, UPDATE, and REFERENCES permissions on database tables and views, and UPDATE permissions on selected columns of database tables. Both allow EXECUTE permissions to be granted on stored procedures.

For example, the following statement is valid in both Adaptive Server Enterprise and Adaptive Server Anywhere:

GRANT INSERT, DELETE
ON TITLES
TO MARY, SALES

This statement grants permission to use the INSERT and DELETE statements on the TITLES table to user MARY and to the SALES group.

Both Adaptive Server Anywhere and Adaptive Server Enterprise support the WITH GRANT OPTION clause, allowing the recipient of permissions to grant them in turn, although Adaptive Server Anywhere does not permit WITH GRANT OPTION to be used on a GRANT EXECUTE statement.

Database-wide permissions

Adaptive Server Enterprise and Adaptive Server Anywhere use different models for database-wide user permissions. These are discussed in Users and groups. Adaptive Server Anywhere employs DBA permissions to allow a user full authority within a database. The System Administrator in Adaptive Server Enterprise enjoys this permission for all databases on a server. However, DBA authority on an Adaptive Server Anywhere database is different from the permissions of an Adaptive Server Enterprise Database Owner, who must use the Adaptive Server Enterprise SETUSER statement to gain permissions on objects owned by other users.

Adaptive Server Anywhere employs RESOURCE permissions to allow a user the right to create objects in a database. A closely corresponding Adaptive Server Enterprise permission is GRANT ALL, used by a Database Owner.


Configuring databases for Transact-SQL compatibility

You can eliminate some differences in behavior between Adaptive Server Anywhere and Adaptive Server Enterprise by selecting appropriate options when creating a database or, if you are working on an existing database, when rebuilding the database. You can control other differences by connection level options using the SET TEMPORARY OPTION statement in Adaptive Server Anywhere or the SET statement in Adaptive Server Enterprise.

Creating a Transact-SQL-compatible database
Setting options for Transact-SQL compatibility
Case sensitivity
Ensuring compatible object names
The special Transact-SQL timestamp column and data type
The special IDENTITY column


Creating a Transact-SQL-compatible database

This section describes choices you must make when creating or rebuilding a database.

Quick start

Here are the steps you need to take to create a Transact-SQL-compatible database. The remainder of the section describes which options you need to set.

toggle To create a Transact-SQL compatible database (Sybase Central)

  1. Start Sybase Central.

  2. Choose Tools > Adaptive Server Anywhere 9 > Create Database.

  3. Follow the instructions in the wizard.

  4. When you see a button called Emulate Adaptive Server Enterprise, click it, and then click Next.

  5. Follow the remaining instructions in the wizard.

toggle To create a Transact-SQL compatible database (Command line)

  • Enter the following command at a command prompt:

    dbinit -b -c -k db-name.db

    For more information about these options, see Initialization utility options.

toggle To create a Transact-SQL compatible database (SQL)

  1. Connect to any Adaptive Server Anywhere database.

  2. Enter the following statement, for example, in Interactive SQL:

    CREATE DATABASE 'db-name.db'
ASE COMPATIBLE

    In this statement, ASE COMPATIBLE means compatible with Adaptive Server Enterprise.

Make the database case sensitive

By default, string comparisons in Adaptive Server Enterprise databases are case sensitive, while those in Adaptive Server Anywhere are case insensitive.

When building an Adaptive Server Enterprise-compatible database using Adaptive Server Anywhere, choose the case sensitive option.

  • If you are using Sybase Central, this option is in the Create Database wizard.

  • If you are using the dbinit command-line utility, specify the -c command-line switch.

Ignore trailing blanks in comparisons

When building an Adaptive Server Enterprise-compatible database using Adaptive Server Anywhere, choose the option to ignore trailing blanks in comparisons.

  • If you are using Sybase Central, this option is in the Create Database wizard.

  • If you are using the dbinit command line utility, specify the -b command-line switch.

When you choose this option, Adaptive Server Enterprise and Adaptive Server Anywhere considers the following two strings equal:

'ignore the trailing blanks   '
'ignore the trailing blanks'

If you do not choose this option, Adaptive Server Anywhere considers the two strings above different.

A side effect of this choosing this option is that strings are padded with blanks when fetched by a client application.

Remove historical system views

Older versions of Adaptive Server Anywhere employed two system views whose names conflict with the Adaptive Server Enterprise system views provided for compatibility. These views include SYSCOLUMNS and SYSINDEXES. If you are using Open Client or JDBC interfaces, create your database excluding these views. You can do this with the dbinit -k command-line switch.

If you do not use this option when creating your database, the following two statements return different results:

SELECT * FROM SYSCOLUMNS ;

SELECT * FROM dbo.syscolumns ;
toggle To drop the Adaptive Server Anywhere system views from an existing database

  1. Connect to the database as a user with DBA authority.

  2. Execute the following statements:

    DROP VIEW SYS.SYSCOLUMNS ;
DROP VIEW SYS.SYSINDEXES
    Caution Ensure that you do not drop the dbo.syscolumns or dbo.sysindexes system view.


Setting options for Transact-SQL compatibility

You set Adaptive Server Anywhere database options using the SET OPTION statement. Several database option settings are relevant to Transact-SQL behavior.

Set the allow_nulls_by_default option

By default, Adaptive Server Enterprise disallows NULLs on new columns unless you explicitly tell the column to allow NULLs. Adaptive Server Anywhere permits NULL in new columns by default, which is compatible with the SQL/92 ISO standard.

To make Adaptive Server Enterprise behave in a SQL/92-compatible manner, use the sp_dboption system procedure to set the allow_nulls_by_default option to true.

To make Adaptive Server Anywhere behave in a Transact-SQL-compatible manner, set the allow_nulls_by_default option to OFF. You can do this using the SET OPTION statement as follows:

SET OPTION PUBLIC.allow_nulls_by_default = 'OFF'
Set the quoted_identifier option

By default, Adaptive Server Enterprise treats identifiers and strings differently than Adaptive Server Anywhere, which matches the SQL/92 ISO standard.

The quoted_identifier option is available in both Adaptive Server Enterprise and Adaptive Server Anywhere. Ensure the option is set to the same value in both databases, for identifiers and strings to be treated in a compatible manner.

For SQL/92 behavior, set the quoted_identifier option to ON in both Adaptive Server Enterprise and Adaptive Server Anywhere.

For Transact-SQL behavior, set the quoted_identifier option to OFF in both Adaptive Server Enterprise and Adaptive Server Anywhere. If you choose this, you can no longer use identifiers that are the same as keywords, enclosed in double quotes.

For more information on the quoted_identifier option, see QUOTED_IDENTIFIER option [compatibility].

Set the automatic_ timestamp option to ON

Transact-SQL defines a timestamp column with special properties. With the automatic_timestamp option set to ON, the Adaptive Server Anywhere treatment of timestamp columns is similar to Adaptive Server Enterprise behavior.

With the automatic_timestamp option set to ON in Adaptive Server Anywhere (the default setting is OFF), any new columns with the TIMESTAMP data type that do not have an explicit default value defined receive a default value of timestamp.

For information on timestamp columns, see The special Transact-SQL timestamp column and data type.

Set the string_rtruncation option

Both Adaptive Server Enterprise and Adaptive Server Anywhere support the string_rtruncation option, which affects error message reporting when an INSERT or UPDATE string is truncated. Ensure that each database has the option set to the same value.

For more information on the STRING_RTRUNCATION option, see STRING_RTRUNCATION option [compatibility].

For more information on database options for Transact-SQL compatibility, see Compatibility options.


Case sensitivity

Case sensitivity in databases refers to:

  • Data The case sensitivity of the data is reflected in indexes and so on.

  • Identifiers Identifiers include table names, column names, and so on.

  • Passwords Case sensitivity of passwords is treated differently from other identifiers.

Case sensitivity of data

You decide the case-sensitivity of Adaptive Server Anywhere data in comparisons when you create the database. By default, Adaptive Server Anywhere databases are case-insensitive in comparisons, although data is always held in the case in which you enter it.

Adaptive Server Enterprise's sensitivity to case depends on the sort order installed on the Adaptive Server Enterprise system. Case sensitivity can be changed for single-byte character sets by reconfiguring the Adaptive Server Enterprise sort order.

Case sensitivity of identifiers

Adaptive Server Anywhere does not support case sensitive identifiers. In Adaptive Server Enterprise, the case sensitivity of identifiers follows the case sensitivity of the data. User IDs are treated like any other identifier, and are always case insensitive. The default user ID for databases is upper case DBA.

In Adaptive Server Enterprise, domain names are case sensitive. In Adaptive Server Anywhere, they are case insensitive, with the exception of Java data types.

Case sensitivity of passwords

In Adaptive Server Anywhere, password case sensitivity is specified separately from the case sensitivity of the data. By default, if you do not specify that passwords are case sensitive, then passwords follow the case sensitivity of the database. However, you can specify that passwords are case sensitive in case insensitive databases, and you can have case insensitive passwords in case sensitive databases. Extended characters used in passwords are case sensitive, regardless of the password case sensitivity setting. The default password for databases is upper case SQL.

For more information about setting password case sensitivity, see the PASSWORD CASE clause in CREATE DATABASE statement.

In Adaptive Server Enterprise, the case sensitivity of user IDs and passwords follows the case sensitivity of the server.


Ensuring compatible object names

Each database object must have a unique name within a certain name space. Outside this name space, duplicate names are allowed. Some database objects occupy different name spaces in Adaptive Server Enterprise and Adaptive Server Anywhere.

In Adaptive Server Anywhere, indexes and triggers are owned by the owner of the table on which they are created. Index and trigger names must be unique for a given owner. For example, while the tables t1 owned by user user1 and t2 owned by user user2 may have indexes of the same name, no two tables owned by a single user may have an index of the same name.

Adaptive Server Enterprise has a less restrictive name space for index names than Adaptive Server Anywhere. Index names must be unique on a given table, but any two tables may have an index of the same name. For compatible SQL, stay within the Adaptive Server Anywhere restriction of unique index names for a given table owner.

Adaptive Server Enterprise has a more restrictive name space on trigger names than Adaptive Server Anywhere. Trigger names must be unique in the database. For compatible SQL, you should stay within the Adaptive Server Enterprise restriction and make your trigger names unique in the database.


The special Transact-SQL timestamp column and data type

Adaptive Server Anywhere supports the Transact-SQL special timestamp column. The timestamp column, together with the tsequal system function, checks whether a row has been updated.

Two meanings of timestamp
Adaptive Server Anywhere has a TIMESTAMP data type, which holds accurate date and time information. It is distinct from the special Transact-SQL TIMESTAMP column and data type.
Creating a Transact-SQL timestamp column in Adaptive Server Anywhere

To create a Transact-SQL timestamp column, create a column that has the (Adaptive Server Anywhere) data type TIMESTAMP and a default setting of timestamp. The column can have any name, although the name timestamp is common.

For example, the following CREATE TABLE statement includes a Transact-SQL timestamp column:

CREATE TABLE table_name (
   column_1 INTEGER ,
   column_2 TIMESTAMP DEFAULT TIMESTAMP
)

The following ALTER TABLE statement adds a Transact-SQL timestamp column to the sales_order table:

ALTER TABLE sales_order
ADD timestamp TIMESTAMP DEFAULT TIMESTAMP

In Adaptive Server Enterprise a column with the name timestamp and no data type specified automatically receives a TIMESTAMP data type. In Adaptive Server Anywhere you must explicitly assign the data type yourself.

If you have the AUTOMATIC_TIMESTAMP database option set to ON, you do not need to set the default value: any new column created with TIMESTAMP data type and with no explicit default receives a default value of timestamp. The following statement sets AUTOMATIC_TIMESTAMP to ON:

SET OPTION PUBLIC.AUTOMATIC_TIMESTAMP='ON'
The data type of a timestamp column

Adaptive Server Enterprise treats a timestamp column as a domain that is VARBINARY(8), allowing NULL, while Adaptive Server Anywhere treats a timestamp column as the TIMESTAMP data type, which consists of the date and time, with fractions of a second held to six decimal places.

When fetching from the table for later updates, the variable into which the timestamp value is fetched should correspond to the column description.

Timestamping an existing table

If you add a special timestamp column to an existing table, all existing rows have a NULL value in the timestamp column. To enter a timestamp value (the current timestamp) for existing rows, update all rows in the table such that the data does not change. For example, the following statement updates all rows in the sales_order table, without changing the values in any of the rows:

UPDATE sales_order
SET region = region

In Interactive SQL, you may need to set the TIMESTAMP_FORMAT option to see the differences in values for the rows. The following statement sets the TIMESTAMP_FORMAT option to display all six digits in the fractions of a second:

SET OPTION TIMESTAMP_FORMAT='YYYY-MM-DD HH:NN:ss.SSSSSS'

If all six digits are not shown, some timestamp column values may appear to be equal: they are not.

Using tsequal for updates

With the tsequal system function you can tell whether a timestamp column has been updated or not.

For example, an application may SELECT a timestamp column into a variable. When an UPDATE of one of the selected rows is submitted, it can use the tsequal function to check whether the row has been modified. The tsequal function compares the timestamp value in the table with the timestamp value obtained in the SELECT. Identical timestamps means there are no changes. If the timestamps differ, the row has been changed since the SELECT was carried out.

A typical UPDATE statement using the tsequal function looks like this:

UPDATE publishers
SET city = 'Springfield'
WHERE pub_id = '0736'
AND TSEQUAL(timestamp, '1995/10/25 11:08:34.173226')

The first argument to the tsequal function is the name of the special timestamp column; the second argument is the timestamp retrieved in the SELECT statement. In Embedded SQL, the second argument is likely to be a host variable containing a TIMESTAMP value from a recent FETCH on the column.


The special IDENTITY column

To create an IDENTITY column, use the following CREATE TABLE syntax:

CREATE TABLE table-name (
   ...
   column-name numeric(n,0) IDENTITY NOT NULL,
   ...
)

where n is large enough to hold the value of the maximum number of rows that may be inserted into the table.

The IDENTITY column stores sequential numbers, such as invoice numbers or employee numbers, which are automatically generated. The value of the IDENTITY column uniquely identifies each row in a table.

In Adaptive Server Enterprise, each table in a database can have one IDENTITY column. The data type must be numeric with scale zero, and the IDENTITY column should not allow nulls.

In Adaptive Server Anywhere, the IDENTITY column is a column default setting. You can explicitly insert values that are not part of the sequence into the column with an INSERT statement. Adaptive Server Enterprise does not allow INSERTs into identity columns unless the identity_insert option is on. In Adaptive Server Anywhere, you need to set the NOT NULL property yourself and ensure that only one column is an IDENTITY column. Adaptive Server Anywhere allows any numeric data type to be an IDENTITY column.

In Adaptive Server Anywhere the identity column and the AUTOINCREMENT default setting for a column are identical.

Retrieving IDENTITY column values with @@identity


Retrieving IDENTITY column values with @@identity

The first time you insert a row into the table, an IDENTITY column has a value of 1 assigned to it. On each subsequent insert, the value of the column increases by one. The value most recently inserted into an identity column is available in the @@identity global variable.

The value of @@identity changes each time a statement attempts to insert a row into a table.

  • If the statement affects a table without an IDENTITY column, @@identity is set to 0.

  • If the statement inserts multiple rows, @@identity reflects the last value inserted into the IDENTITY column.

This change is permanent. @@identity does not revert to its previous value if the statement fails or if the transaction that contains it is rolled back.

For more information on the behavior of @@identity, see @@identity global variable.


Writing compatible SQL statements

This section describes general guidelines for writing SQL for use on more than one database-management system, and discusses compatibility issues between Adaptive Server Enterprise and Adaptive Server Anywhere at the SQL statement level.


General guidelines for writing portable SQL

When writing SQL for use on more than one database-management system, make your SQL statements as explicit as possible. Even if more than one server supports a given SQL statement, it may be a mistake to assume that default behavior is the same on each system. General guidelines applicable to writing compatible SQL include:

  • Spell out all of the available options, rather than using default behavior.

  • Use parentheses to make the order of execution within statements explicit, rather than assuming identical default order of precedence for operators.

  • Use the Transact-SQL convention of an @ sign preceding variable names for Adaptive Server Enterprise portability.

  • Declare variables and cursors in procedures, triggers, and batches immediately following a BEGIN statement. Adaptive Server Anywhere requires this, although Adaptive Server Enterprise allows declarations to be made anywhere in a procedure, trigger, or batch.

  • Avoid using reserved words from either Adaptive Server Enterprise or Adaptive Server Anywhere as identifiers in your databases.

  • Assume large namespaces. For example, ensure that each index has a unique name.


Creating compatible tables

Adaptive Server Anywhere supports domains which allow constraint and default definitions to be encapsulated in the data type definition. It also supports explicit defaults and CHECK conditions in the CREATE TABLE statement. It does not, however, support named constraints or named defaults.

NULL

Adaptive Server Anywhere and Adaptive Server Enterprise differ in some respects in their treatment of NULL. In Adaptive Server Enterprise, NULL is sometimes treated as if it were a value.

For example, a unique index in Adaptive Server Enterprise cannot contain rows that hold null and are otherwise identical. In Adaptive Server Anywhere, a unique index can contain such rows.

By default, columns in Adaptive Server Enterprise default to NOT NULL, whereas in Adaptive Server Anywhere the default setting is NULL. You can control this setting using the allow_nulls_by_default option. Specify explicitly NULL or NOT NULL to make your data definition statements transferable.

For information on this option, see Setting options for Transact-SQL compatibility.

Temporary tables

You can create a temporary table by placing a pound sign (#) in front of a CREATE TABLE statement. These temporary tables are Adaptive Server Anywhere declared temporary tables, and are available only in the current connection. For information about declared temporary tables in Adaptive Server Anywhere, see DECLARE LOCAL TEMPORARY TABLE statement.

Physical placement of a table is carried out differently in Adaptive Server Enterprise and in Adaptive Server Anywhere. Adaptive Server Anywhere supports the ON segment-name clause, but segment-name refers to an Adaptive Server Anywhere dbspace.

For information about the CREATE TABLE statement, see CREATE TABLE statement.


Writing compatible queries

There are two criteria for writing a query that runs on both Adaptive Server Anywhere and Adaptive Server Enterprise databases:

  • The data types, expressions, and search conditions in the query must be compatible.

  • The syntax of the SELECT statement itself must be compatible.

This section explains compatible SELECT statement syntax, and assumes compatible data types, expressions, and search conditions. The examples assume the QUOTED_IDENTIFIER setting is OFF: the default Adaptive Server Enterprise setting, but not the default Adaptive Server Anywhere setting.

Adaptive Server Anywhere supports the following subset of the Transact-SQL SELECT statement.

Syntax

SELECT [ ALL | DISTINCT ] select-list
...[ INTO #temporary-table-name ]
...[ FROM table-spec [ HOLDLOCK | NOHOLDLOCK ],
... table-spec [ HOLDLOCK | NOHOLDLOCK ], ... ]
...[ WHERE search-condition ]
...[ GROUP BY column-name, ... ]
...[ HAVING search-condition ]
[ ORDER BY { expression | integer }
[ ASC | DESC ], ... ]

Parameters

select-list:
table-name.*
| *
| expression
| alias-name = expression
| expression as identifier
| expression as T_string

table-spec:
[ owner . ]table-name
...[ [ AS ] correlation-name ]
...[ ( INDEX index_name [ PREFETCH size ][ LRU | MRU ] ) ]

alias-name:identifier :
| 'string' | "string"

For a full description of the SELECT statement, see SELECT statement.

Adaptive Server Anywhere does not support the following keywords and clauses of the Transact-SQL SELECT statement syntax:

  • SHARED keyword

  • COMPUTE clause

  • FOR BROWSE clause

  • GROUP BY ALL clause

Notes

  • The INTO table_name clause, which creates a new table based on the SELECT statement result set, is supported only for declared temporary tables where the table name starts with a #. Declared temporary tables exist for a single connection only.

  • Adaptive Server Anywhere does not support the Transact-SQL extension to the GROUP BY clause allowing references to columns and expressions that are not used for creating groups. In Adaptive Server Enterprise, this extension produces summary reports.

  • The FOR READ ONLY clause and the FOR UPDATE clause are parsed, but have no effect.

  • The performance parameters part of the table specification is parsed, but has no effect.

  • The HOLDLOCK keyword is supported by Adaptive Server Anywhere. It makes a shared lock on a specified table or view more restrictive by holding it until the completion of a transaction (instead of releasing the shared lock as soon as the required data page is no longer needed, whether or not the transaction has been completed). For the purposes of the table for which the HOLDLOCK is specified, the query is carried out at isolation level 3.

  • The HOLDLOCK option applies only to the table or view for which it is specified, and only for the duration of the transaction defined by the statement in which it is used. Setting the isolation level to 3 applies a holdlock for each select within a transaction. You cannot specify both a HOLDLOCK and NOHOLDLOCK option in a query.

  • The NOHOLDLOCK keyword is recognized by Adaptive Server Anywhere, but has no effect.

  • Transact-SQL uses the SELECT statement to assign values to local variables:

    SELECT @localvar = 42

    The corresponding statement in Adaptive Server Anywhere is the SET statement:

    SET localvar = 42

    The variable name can optionally be set using the SET statement and the Transact-SQL convention of an @ sign preceding the name:

    SET @localvar = 42

  • Adaptive Server Enterprise does not support the following clauses of the SELECT statement syntax:

    • INTO host-variable-list

    • INTO variable-list.

    • Parenthesized queries.

  • Adaptive Server Enterprise uses join operators in the WHERE clause , rather than the FROM clause and the ON condition for joins.


Compatibility of joins

In Transact-SQL, joins appear in the WHERE clause, using the following syntax:

start of select, update, insert, delete, or subquery
FROM { table-list | view-list } WHERE [ NOT ]
[ table-name.| view name.]column-name
join-operator
[ table-name.| view-name.]column_name
[ { AND | OR } [ NOT ]
[ table-name.| view-name.]column_name
join-operator
[ table-name.| view-name.]column-name ]...
end of select, update, insert, delete, or subquery

The join-operator in the WHERE clause may be any of the comparison operators, or may be either of the following outer-join operators:

  • *= Left outer join operator

  • =* Right outer join operator.

Adaptive Server Anywhere supports the Transact-SQL outer-join operators as an alternative to the native SQL/92 syntax. You cannot mix dialects within a query. This rule applies also to views used by a query—an outer-join query on a view must follow the dialect used by the view-defining query.

Adaptive Server Anywhere also provides a SQL/92 syntax for joins other than outer joins, in which the joins are placed in the FROM clause rather than the WHERE clause.

For information about joins in Adaptive Server Anywhere and in the ANSI/ISO SQL standards, see Joins: Retrieving Data from Several Tables, and FROM clause.

For more information on Transact-SQL compatibility of joins, see Transact-SQL outer joins (*= or =*).


Transact-SQL procedure language overview

The stored procedure language is the part of SQL used in stored procedures, triggers, and batches.

Adaptive Server Anywhere supports a large part of the Transact-SQL stored procedure language in addition to the Watcom-SQL dialect based on SQL/92.


Transact-SQL stored procedure overview

Based on the ISO/ANSI draft standard , the Adaptive Server Anywhere stored procedure language differs from the Transact-SQL dialect in many ways. Many of the concepts and features are similar, but the syntax is different. Adaptive Server Anywhere support for Transact-SQL takes advantage of the similar concepts by providing automatic translation between dialects. However, a procedure must be written exclusively in one of the two dialects, not in a mixture of the two.

Adaptive Server Anywhere support for Transact-SQL stored procedures

There are a variety of aspects to Adaptive Server Anywhere support for Transact-SQL stored procedures, including:

  • Passing parameters

  • Returning result sets

  • Returning status information

  • Providing default values for parameters

  • Control statements

  • Error handling

  • User-defined functions


Transact-SQL trigger overview

Trigger compatibility requires compatibility of trigger features and syntax. This section provides an overview of the feature compatibility of Transact-SQL and Adaptive Server Anywhere triggers.

Adaptive Server Enterprise executes triggers after the triggering statement has completed: they are statement level, after triggers. Adaptive Server Anywhere supports both row level triggers (which execute before or after each row has been modified) and statement level triggers (which execute after the entire statement).

Row-level triggers are not part of the Transact-SQL compatibility features, and are discussed in Using Procedures, Triggers, and Batches.

Description of unsupported or different Transact-SQL triggers

Features of Transact-SQL triggers that are either unsupported or different in Adaptive Server Anywhere include:

  • Triggers firing other triggers Suppose a trigger carries out an action that would, if carried out directly by a user, fire another trigger. Adaptive Server Anywhere and Adaptive Server Enterprise respond slightly differently to this situation. By default in Adaptive Server Enterprise, triggers fire other triggers up to a configurable nesting level, which has the default value of 16. You can control the nesting level with the Adaptive Server Enterprise nested triggers option. In Adaptive Server Anywhere, triggers fire other triggers without limit unless there is insufficient memory.

  • Triggers firing themselves Suppose a trigger carries out an action that would, if carried out directly by a user, fire the same trigger. Adaptive Server Anywhere and Adaptive Server Enterprise respond slightly differently to this situation. In Adaptive Server Anywhere, non-Transact-SQL triggers fire themselves recursively, while Transact-SQL dialect triggers do not fire themselves recursively.

    By default in Adaptive Server Enterprise, a trigger does not call itself recursively, but you can turn on the self_recursion option to allow triggers to call themselves recursively.

  • ROLLBACK statement in triggers Adaptive Server Enterprise permits the ROLLBACK TRANSACTION statement within triggers, to roll back the entire transaction of which the trigger is a part. Adaptive Server Anywhere does not permit ROLLBACK (or ROLLBACK TRANSACTION) statements in triggers because a triggering action and its trigger together form an atomic statement.

    Adaptive Server Anywhere does provide the Adaptive Server Enterprise-compatible ROLLBACK TRIGGER statement to undo actions within triggers. See ROLLBACK TRIGGER statement.


Transact-SQL batch overview

In Transact-SQL, a batch is a set of SQL statements submitted together and executed as a group, one after the other. Batches can be stored in command files. The Interactive SQL utility in Adaptive Server Anywhere and the isql utility in Adaptive Server Enterprise provide similar capabilities for executing batches interactively.

The control statements used in procedures can also be used in batches. Adaptive Server Anywhere supports the use of control statements in batches and the Transact-SQL-like use of non-delimited groups of statements terminated with a GO statement to signify the end of a batch.

For batches stored in command files, Adaptive Server Anywhere supports the use of parameters in command files. Adaptive Server Enterprise does not support parameters.

For information on parameters, see PARAMETERS statement [Interactive SQL].


Automatic translation of stored procedures

In addition to supporting Transact-SQL alternative syntax, Adaptive Server Anywhere provides aids for translating statements between the Watcom-SQL and Transact-SQL dialects. Functions returning information about SQL statements and enabling automatic translation of SQL statements include:

  • SQLDialect(statement) Returns Watcom-SQL or Transact-SQL.

  • WatcomSQL(statement) Returns the Watcom-SQL syntax for the statement.

  • TransactSQL(statement) Returns the Transact-SQL syntax for the statement.

These are functions, and so can be accessed using a select statement from Interactive SQL. For example:

select SqlDialect('select * from employee')

returns the value Watcom-SQL.

Using Sybase Central to translate stored procedures


Using Sybase Central to translate stored procedures

Sybase Central has facilities for creating, viewing, and altering procedures and triggers.

toggle To translate a stored procedure using Sybase Central

  1. Connect to a database using Sybase Central, either as owner of the procedure you wish to change, or as a DBA user.

  2. Open the Procedures & Functions folder.

  3. Right-click the procedure you want to translate and from the popup menu choose one of the Translate to commands, depending on the dialect you want to use.

    The procedure appears in the right pane in the selected dialect. If the selected dialect is not the one in which the procedure is stored, the server translates it to that dialect. Any untranslated lines appear as comments.

  4. Rewrite any untranslated lines as needed.

  5. When finished, choose File > Save Procedure to save the translated version to the database. You can also export the text to a file for editing outside of Sybase Central.


Returning result sets from Transact-SQL procedures

Adaptive Server Anywhere uses a RESULT clause to specify returned result sets. In Transact-SQL procedures, the column names or alias names of the first query are returned to the calling environment.

Example of Transact-SQL procedure

The following Transact-SQL procedure illustrates how Transact-SQL stored procedures returns result sets:

CREATE PROCEDURE showdept (@deptname varchar(30))
AS
   SELECT employee.emp_lname, employee.emp_fname
   FROM department, employee
   WHERE department.dept_name = @deptname
   AND department.dept_id = employee.dept_id
Example of Watcom-SQL procedure

The following is the corresponding Adaptive Server Anywhere procedure:

CREATE PROCEDURE showdept(in deptname varchar(30))
RESULT ( lastname char(20), firstname char(20))
BEGIN
   SELECT employee.emp_lname, employee.emp_fname
   FROM department, employee
   WHERE department.dept_name = deptname
   AND department.dept_id = employee.dept_id
END

For more information about procedures and results, see Returning results from procedures


Variables in Transact-SQL procedures

Adaptive Server Anywhere uses the SET statement to assign values to variables in a procedure. In Transact-SQL, values are assigned using either the SELECT statement with an empty table-list, or the SET statement. The following simple procedure illustrates how the Transact-SQL syntax works:

CREATE PROCEDURE multiply
               @mult1 int,
               @mult2 int,
               @result int output
AS
SELECT @result = @mult1 * @mult2

This procedure can be called as follows:

CREATE VARIABLE @product int
go
EXECUTE multiply 5, 6, @product OUTPUT
go

The variable @product has a value of 30 after the procedure executes.

For more information on using the SELECT statement to assign variables, see Writing compatible queries. For more information on using the SET statement to assign variables, see SET statement.


Error handling in Transact-SQL procedures

Default procedure error handling is different in the Watcom-SQL and Transact-SQL dialects. By default, Watcom-SQL dialect procedures exit when they encounter an error, returning SQLSTATE and SQLCODE values to the calling environment.

Explicit error handling can be built into Watcom-SQL stored procedures using the EXCEPTION statement, or you can instruct the procedure to continue execution at the next statement when it encounters an error, using the ON EXCEPTION RESUME statement.

When a Transact-SQL dialect procedure encounters an error, execution continues at the following statement. The global variable @@error holds the error status of the most recently executed statement. You can check this variable following a statement to force return from a procedure. For example, the following statement causes an exit if an error occurs.

IF @@error != 0 RETURN

When the procedure completes execution, a return value indicates the success or failure of the procedure. This return status is an integer, and can be accessed as follows:

DECLARE @status INT
EXECUTE @status = proc_sample
IF @status = 0
   PRINT 'procedure succeeded'
ELSE
   PRINT 'procedure failed'

The following table describes the built-in procedure return values and their meanings:

Value | Meaning
0 | Procedure executed without error
–1 | Missing object
–2 | Data type error
–3 | Process was chosen as deadlock victim
–4 | Permission error
–5 | Syntax error
–6 | Miscellaneous user error
–7 | Resource error, such as out of space
–8 | Non-fatal internal problem
–9 | System limit was reached
–10 | Fatal internal inconsistency
–11 | Fatal internal inconsistency
–12 | Table or index is corrupt
–13 | Database is corrupt
–14 | Hardware error

The RETURN statement can be used to return other integers, with their own user-defined meanings.


Using the RAISERROR statement in procedures

The RAISERROR statement is a Transact-SQL statement for generating user-defined errors. It has a similar function to the SIGNAL statement.

For a description of the RAISERROR statement, see RAISERROR statement [T-SQL].

By itself, the RAISERROR statement does not cause an exit from the procedure, but it can be combined with a RETURN statement or a test of the @@error global variable to control execution following a user-defined error.

If you set the ON_TSQL_ERROR database option to CONTINUE, the RAISERROR statement no longer signals an execution-ending error. Instead, the procedure completes and stores the RAISERROR status code and message, and returns the most recent RAISERROR. If the procedure causing the RAISERROR was called from another procedure, the RAISERROR returns after the outermost calling procedure terminates.

You lose intermediate RAISERROR statuses and codes after the procedure terminates. If, at return time, an error occurs along with the RAISERROR, then the error information is returned and you lose the RAISERROR information. The application can query intermediate RAISERROR statuses by examining @@error global variable at different execution points.


Transact-SQL-like error handling in the Watcom-SQL dialect

You can make a Watcom-SQL dialect procedure handle errors in a Transact-SQL-like manner by supplying the ON EXCEPTION RESUME clause to the CREATE PROCEDURE statement:

CREATE PROCEDURE sample_proc()
ON EXCEPTION RESUME
BEGIN
   ...
END

The presence of an ON EXCEPTION RESUME clause prevents explicit exception handling code from being executed, so avoid using these two clauses together.


Differences from Other SQL Dialects

About this chapter

Adaptive Server Anywhere complies completely with the SQL-92-based United States Federal Information Processing Standard Publication (FIPS PUB) 127.

Adaptive Server Anywhere is entry-level compliant with the ISO/ANSI SQL-92 standard, and with minor exceptions is compliant with SQL-99 core specifications.

Complete, detailed information about compliance is provided in the reference documentation for each feature of Adaptive Server Anywhere.

This chapter describes those features of Adaptive Server Anywhere that are not commonly found in other SQL implementations.

Adaptive Server Anywhere SQL features


Adaptive Server Anywhere SQL features

The following features of the SQL supported by Adaptive Server Anywhere are not found in many other SQL implementations.

Type conversions

Full type conversion is implemented. Any data type can be compared with or used in any expression with any other data type.

Dates

Adaptive Server Anywhere has date, time and timestamp types that includes a year, month and day, hour, minutes, seconds and fraction of a second. For insertions or updates to date fields, or comparisons with date fields, a free format date is supported.

In addition, the following operations are allowed on dates:

  • date + integer Add the specified number of days to a date.

  • date - integer Subtract the specified number of days from a date.

  • date - date Compute the number of days between two dates.

  • date + time Make a timestamp out of a date and time.

Also, many functions are provided for manipulating dates and times. See SQL Functions for a description of these.

Integrity

Adaptive Server Anywhere supports both entity and referential integrity. This has been implemented via the following two extensions to the CREATE TABLE and ALTER TABLE commands.

PRIMARY KEY ( column-name, ... )
[NOT NULL] FOREIGN KEY [role-name]
            [(column-name, ...)]
         REFERENCES table-name [(column-name, ...)]
            [ CHECK ON COMMIT ]

The PRIMARY KEY clause declares the primary key for the relation. Adaptive Server Anywhere will then enforce the uniqueness of the primary key, and ensure that no column in the primary key contains the NULL value.

The FOREIGN KEY clause defines a relationship between this table and another table. This relationship is represented by a column (or columns) in this table which must contain values in the primary key of another table. The system will then ensure referential integrity for these columns - whenever these columns are modified or a row is inserted into this table, these columns will be checked to ensure that either one or more is NULL or the values match the corresponding columns for some row in the primary key of the other table. For more information, see CREATE TABLE statement.

Joins

Adaptive Server Anywhere allows automatic joins between tables. In addition to the NATURAL and OUTER join operators supported in other implementations, Adaptive Server Anywhere allows KEY joins between tables based on foreign key relationships. This reduces the complexity of the WHERE clause when performing joins.

Updates

Adaptive Server Anywhere allows more than one table to be referenced by the UPDATE command. Views defined on more than one table can also be updated. Many SQL implementations will not allow updates on joined tables.

Altering tables

The ALTER TABLE command has been extended. In addition to changes for entity and referential integrity, the following types of alterations are allowed:

ADD column data-type
MODIFY column data-type
DELETE column
RENAME new-table-name
RENAME old-column TO new-column

The MODIFY can be used to change the maximum length of a character column as well as converting from one data type to another. For more information, see ALTER TABLE statement.

Subqueries where expressions are allowed

Adaptive Server Anywhere allows subqueries to appear wherever expressions are allowed. Many SQL implementations only allow subqueries on the right side of a comparison operator. For example, the following command is valid in Adaptive Server Anywhere but not valid in most other SQL implementations.

SELECT   emp_lname,
         birth_date,
         (   SELECT dept_name
            FROM department
            WHERE emp_id = employee.emp_ID
            AND dept_id = 200 )
FROM employee
Additional functions

Adaptive Server Anywhere supports several functions not in the ANSI SQL definition. See SQL Functions for a full list of available functions.

Cursors

When using Embedded SQL, cursor positions can be moved arbitrarily on the FETCH statement. Cursors can be moved forward or backward relative to the current position or a given number of records from the beginning or end of the cursor.


Using XML in the Database

About this chapter

This chapter provides a summary of the XML support in Adaptive Server Anywhere, including importing, exporting, storing, and querying XML data.

What is XML?
Storing XML documents in relational databases
Exporting relational data as XML
Importing XML documents as relational data
Obtaining query results as XML
Using SQL/XML to obtain query results as XML


What is XML?

Extensible Markup Language (XML) represents structured data in text format. XML was designed specifically to meet the challenges of large-scale electronic publishing.

XML is a simple markup language, like HTML, but is also flexible, like SGML. XML is hierarchical, and its main purpose is to describe the structure of data for both humans and computer software to author and read.

Rather than providing a static set of elements which describe various forms of data, XML lets you define elements. As a result, many types of structured data can be described with XML. XML documents can optionally use a document type definition (DTD) or XML schema to define the structure, elements, and attributes that are used in an XML file.

For more detailed information about XML, see [external link] http://www.w3.org/XML/.

XML and Adaptive Server Anywhere


XML and Adaptive Server Anywhere

There are several ways you can use XML with Adaptive Server Anywhere:

  • Storing XML documents in the database

  • Exporting relational data as XML

  • Importing XML into the database

  • Querying relational data as XML


Storing XML documents in relational databases

Adaptive Server Anywhere supports two data types that can be used to store XML documents in your database: the XML data type and the LONG VARCHAR data type. Both of these data types store the XML document as a string in the database.

Benefits of using the XML data type

You can cast between the XML data type and any other data type that can be cast to or from a string. Note that there is no checking that the string is well-formed when it is cast to XML.

When you generate elements from relational data, any characters that are invalid in XML are escaped unless the data is of type XML. For example, suppose you wish to generate a <product> element with the following content:

<hat>bowler</hat>

so that the element content contains less than and greater than signs. If you write a query that specifies that the element content is of type XML, as follows:

SELECT XMLFOREST( CAST( '<hat>bowler</hat>' AS XML ) AS product )

then the greater than and less than signs are not quoted and you get the following result:

<product><hat>bowler</hat></product>

However, if the query does not specify that the element content is of type XML, for example:

SELECT XMLFOREST( '<hat>bowler</hat>' AS product )

then the less than and greater than signs are replaced with entity references as follows:

<product>&lt;hat&gt;bowler&lt;/hat&gt;</product>

Note that attributes are always quoted, regardless of the data type.

For more information about how element content is escaped, see Invalid column names.

For more information about the XML data type, see XML data type [Character].


Exporting relational data as XML

Adaptive Server Anywhere provides two ways to export your relational data as XML: the Interactive SQL OUTPUT statement and the ADO.NET DataSet object.

The FOR XML clause and SQL/XML functions allow you to generate a result set as XML from the relational data in your database. You can then export the generated XML to a file using the UNLOAD statement or the xp_write_file system procedure.


Exporting relational data as XML from Interactive SQL

The Interactive SQL OUTPUT statement supports an XML format that outputs query results to a generated XML file.

This generated XML file is encoded in UTF-8 and contains an embedded DTD. In the XML file, binary values are encoded in character data (CDATA) blocks with the binary data rendered as 2-hex-digit strings.

For more information about exporting XML with the OUTPUT statement, see OUTPUT statement [Interactive SQL].

The INPUT statement does not accept XML as a file format. However, you can import XML using the OPENXML function or the ADO.NET DataSet object.

For more information about importing XML, see Importing XML documents as relational data.


Exporting relational data as XML using the DataSet object

The ADO.NET DataSet object allows you to save the contents of the DataSet in an XML document. Once you have filled the DataSet (for example, with the results of a query on your database) you can save either the schema or both the schema and data from the DataSet in an XML file. The WriteXml method saves both the schema and data in an XML file, while the WriteXmlSchema method saves only the schema in an XML file. You can fill a DataSet object using the Adaptive Server Anywhere ADO.NET data provider.

For information about exporting relational data as XML using a DataSet, see Inserting, updating, and deleting rows using the AsaCommand object.


Importing XML documents as relational data

Adaptive Server Anywhere supports two different ways to import XML into your database:

  • using the OPENXML function to generate a result set from an XML document

  • using the ADO.NET DataSet object to read the data and/or schema from an XML document into a DataSet


Importing XML using OPENXML

OPENXML is used in the FROM clause of a query to generate a result set from an XML document. OPENXML uses a subset of the XPath query language to select nodes from an XML document.

Using XPath expressions

When you use OPENXML, the XML document is parsed and the result is modeled as a tree. The tree is made up of nodes. XPath expressions are used to select nodes in the tree. The following list describes some commonly-used XPath expressions:

  • / indicates the root node of the XML document

  • . (single period) indicates the current node of the XML document

  • // indicates all descendants of the current node, including the current node

  • .. indicates the parent node of the current node

  • ./@attributename indicates the attribute of the current node having the name attributename

  • ./childname indicates the children of the current node that are elements having the name childname

Consider the following XML document:

<inventory>
 <product id="301" size="Medium">Tee Shirt
  <quantity>54</quantity>
 </product>
 <product id="302" size="One size fits all">Tee Shirt
  <quantity>75</quantity>
 </product>
 <product id="400" size="One size fits all">Baseball Cap
  <quantity>112</quantity>
 </product>
</inventory>

The <inventory> element is the root node. You can refer to it using the following XPath expression:

/inventory

Suppose that the current node is a <quantity> element. You can refer to this node using the following XPath expression:

.

To find all the <product> elements that are children of the <inventory> element, use the following XPath expression:

/inventory/product

If the current node is a <product> element and you want to refer to the size attribute, use the following XPath expression:

./@size

For a complete list of XPath syntax supported by OPENXML, see OPENXML function [String].

For information about the XPath query language, see [external link] http://www.w3.org/TR/xpath.

Generating a result set using OPENXML

Each match for the first xpath-query argument to OPENXML generates one row in the result set. The WITH clause specifies the schema of the result set and how the value is found for each column in the result set. For example, consider the following query:

SELECT * FROM OPENXML( '<inventory>
                         <product>Tee Shirt
                          <quantity>54</quantity>
                          <color>Orange</color>
                         </product>
                         <product>Baseball Cap
                          <quantity>112</quantity>
                          <color>Black</color>
                         </product>
                        </inventory>',
                       '/inventory/product' )
WITH ( name CHAR (25) './text()',
       quantity CHAR(3) 'quantity',
       color CHAR(20) 'color')

The first xpath-query argument is /inventory/product, and there are two <product> elements in the XML, so two rows are generated by this query.

The WITH clause specifies that there are three columns: name, quantity, and color. The values for these columns are taken from the <product>, <quantity> and <color> elements. The query above generates the following result:

name | quantity | color
Tee Shirt | 54 | Orange
Baseball Cap | 112 | Black

For more information, see OPENXML function [String].

Using OPENXML to generate an edge table

OPENXML can be used to generate an edge table, a table that contains a row for every element in the XML document. You may wish to generate an edge table so that you can query the data in the result set using SQL.

The following SQL statement creates a variable, x, that contains an XML document. The XML generated by the query has a root element called <root>, which is generated using the XMLELEMENT function, and elements are generated for each column in the employee, sales_order, and customer tables using FOR XML AUTO with the ELEMENTS modifier specified.

For information about the XMLELEMENT function, see XMLELEMENT function [String].

For information about FOR XML AUTO, see Using FOR XML AUTO.

CREATE VARIABLE x XML;
SET x=(SELECT XMLELEMENT( NAME root,
         (SELECT * FROM employee
         KEY JOIN sales_order
         KEY JOIN customer
         FOR XML AUTO, ELEMENTS)));

The generated XML looks as follows (the result has been formatted to make it easier to read—the result returned by the query is one continuous string):

<root>
 <employee>
  <emp_id>299</emp_id>
  <manager_id>902</manager_id>
  <emp_fname>Rollin</emp_fname>
  <emp_lname>Overbey</emp_lname>
  <dept_id>200</dept_id>
  <street>191 Companion Ct.</street>
  <city>Kanata</city>
  <state>CA</state>
  <zip_code>94608</zip_code>
  <phone>5105557255</phone>
  <status>A</status>
  <ss_number>025487133</ss_number>
  <salary>39300.000</salary>
  <start_date>1987-02-19</start_date>
  <birth_date>1964-03-15</birth_date>
  <bene_health_ins>Y</bene_health_ins>
  <bene_life_ins>Y</bene_life_ins>
  <bene_day_care>N</bene_day_care>
  <sex>M</sex>
  <sales_order>
   <id>2001</id>
   <cust_id>101</cust_id>
   <order_date>2000-03-16</order_date>
   <fin_code_id>r1</fin_code_id>
   <region>Eastern</region>
   <sales_rep>299</sales_rep>
   <customer>
    <id>101</id>
    <fname>Michael</fname>
    <lname>Devlin</lname>
    <address>114 Pioneer Avenue</address>
    <city>Kingston</city>
    <state>NJ</state>
    <zip>07070</zip>
    <phone>2015558966</phone>
    <company_name>The Power Group</company_name>
   </customer>
  </sales_order>
</employee>
...

The following query uses the descendant-or-self (//*) XPath expression to match every element in the above XML document, and for each element the id metaproperty is used to obtain an id for the node, and the parent (../) XPath expression is used with the id metaproperty to get the parent node. The localname metaproperty is used to obtain the name of each element.

SELECT * FROM OPENXML( x, '//*' )
 WITH (id INT '@mp:id',
       parent INT '../@mp:id',
       name CHAR(20) '@mp:localname',
       text LONG VARCHAR 'text()' )
ORDER BY id

The result set generated by this query shows the id of each node, the id of the parent node, and the name and content for each element in the XML document.

id | parent | name | text
5 | (NULL) | root | (NULL)
23 | 15 | emp_id | 299
47 | 15 | manager_id | 902
74 | 15 | emp_fname | Rollin
... | ... | ... | ...
Querying XML in a column

If you have a table with a column that contains XML, you can use OPENXML to query all the XML values in the column at once. This can be done using a lateral derived table.

The following statements create a table with two columns, manager_id and reports. The reports column contains XML data generated from the employee table.

CREATE TABLE t (manager_id INT, reports XML);
INSERT INTO t
SELECT manager_id, XMLELEMENT( NAME reports,
                    XMLAGG(
                     XMLELEMENT( NAME e, emp_id)))
FROM employee
GROUP BY manager_id;

Execute the following query to view the data in the t table:

SELECT * FROM t;

This query produces the following result:

manager_id reports
1293
<reports>
 <e>148</e>
 <e>390</e>
 <e>586</e>
 <e>757</e>
 ...
</reports>
1576
<reports>
 <e>184</e>
 <e>207</e>
 <e>318</e>
 <e>409</e>
 ...
</reports>
902
<reports>
 <e>129</e>
 <e>195</e>
 <e>299</e>
 <e>467</e>
 ...
</reports>
703
<reports>
 <e>191</e>
 <e>750</e>
 <e>868</e>
 <e>921</e>
 ...
</reports>
... ...

The following query uses a lateral derived table to generate a result set with two columns: one that lists the id for each manager, and one that lists the id for each employee that reports to that manager:

SELECT manager_id, eid
FROM t, LATERAL( OPENXML( t.reports, '//e' )
WITH (eid INT '.') ) dt

This query generates the following result:

manager_id | eid
1293 | 148
1293 | 390
1293 | 586
1293 | 757
... | ...

For more information about lateral derived tables, see FROM clause.


Importing XML using the DataSet object

The ADO.NET DataSet object allows you to read the data and/or schema from an XML document into a DataSet.

  • The ReadXml method populates a DataSet from an XML document that contains both a schema and data.

  • The ReadXmlSchema method reads only the schema from an XML document. Once the DataSet is filled with data from the XML document, you can update the tables in your database with the changes from the DataSet.

DataSet objects can also be manipulated using the Adaptive Server Anywhere ADO.NET data provider.

For information about using a DataSet to read the data and/or schema from an XML document using the Adaptive Server Anywhere .NET data provider, see Getting data using the AsaDataAdapter object.


Obtaining query results as XML

Adaptive Server Anywhere supports two different ways to obtain query results from your relational data as XML:

  • FOR XML clause The FOR XML clause can be used in a SELECT statement to generate an XML document.

    For information about using the FOR XML clause, see Using the FOR XML clause to retrieve query results as XML and SELECT statement.

  • SQL/XML Adaptive Server Anywhere supports functions based on the draft SQL/XML standard that generate XML documents from relational data.

    For information about using one or more of these functions in a query, see Using SQL/XML to obtain query results as XML.

The FOR XML clause and the SQL/XML functions supported by Adaptive Server Anywhere give you two alternatives for generating XML from your relational data. In most cases, you can use either one to generate the same XML.

For example, this query uses FOR XML AUTO to generate XML,

SELECT id, name
FROM product
WHERE color='black'
FOR XML AUTO

and this query uses the XMLELEMENT function to generate XML:

SELECT XMLELEMENT(NAME product,
          XMLATTRIBUTES(id, name))
FROM product
WHERE color='black'

Both queries generate the following XML (the result set has been formatted to make it easier to read):

<product id="302" name="Tee Shirt"/>
<product id="400" name="Baseball Cap"/>
<product id="501" name="Visor"/>
<product id="700" name="Shorts"/>
Tip

If you are generating deeply-nested documents, a FOR XML EXPLICIT query will likely be more efficient than a SQL/XML query because EXPLICIT mode queries normally use a UNION to generate nesting, while SQL/XML uses subqueries to generate the required nesting.


Using the FOR XML clause to retrieve query results as XML

Adaptive Server Anywhere allows you to execute a SQL query against your database and return the results as an XML document by using the FOR XML clause in your SELECT statement. The XML document is of type XML.

For information about the XML data type, see XML data type [Character].

The FOR XML clause can be used in any SELECT statement, including subqueries, queries with a GROUP BY clause or aggregate functions, and view definitions.

For examples of how the FOR XML clause can be used, see FOR XML examples.

Adaptive Server Anywhere does not generate a schema for XML documents generated by the FOR XML clause.

Within the FOR XML clause, you specify one of three XML modes that control the format of the XML that is generated:

  • RAW represents each row that matches the query as an XML <row> element, and each column as an attribute.

    For more information, see Using FOR XML RAW.

  • AUTO returns query results as nested XML elements. Each table referenced in the select-list is represented as an element in the XML. The order of nesting for the elements is based on the order of the tables in the select-list.

    For more information, see Using FOR XML AUTO.

  • EXPLICIT allows you to write queries that contain information about the expected nesting so you can control the form of the resulting XML.

    For more information, see Using FOR XML EXPLICIT.

The following sections describe the behavior of all three modes of the FOR XML clause regarding binary data, NULL values, and invalid XML names, as well as providing examples of how the FOR XML clause can be used.


FOR XML and binary data

When you use the FOR XML clause in a SELECT statement, regardless of the mode used, any BINARY, LONG BINARY, IMAGE, or VARBINARY columns are output as attributes or elements that are automatically represented in base64-encoded format.

If you are using OPENXML to generate a result set from XML, OPENXML assumes that the types BINARY, LONG BINARY, IMAGE, and VARBINARY, are base64-encoded and decodes them automatically.

For more information about OPENXML, see OPENXML function [String].


FOR XML and NULL values

By default, elements and attributes that contain NULL values are omitted from the result. This behavior is controlled by the FOR_XML_NULL_TREATMENT option.

Consider a table that contains the following data:

id | fname | lname | company_name
100 | Robert | Michaels | NULL
101 | Michael | Devlin | The Power Group

If you execute the following query with the FOR_XML_NULL_TREATMENT option set to OMIT (the default)

SELECT id, fname, lname, company_name
FROM customer
FOR XML RAW

the company_name attribute is omitted from the result for Robert Michaels:

<row id="100" fname="Robert" lname="Michaels"/>
<row id="101" fname="Michael" lname="Devlin"
 company_name="The Power Group"/>'

If the FOR_XML_NULL_TREATMENT option is set to EMPTY, then an empty attribute is included in the result:

<row id="100" fname="Robert" lname="Michaels"
 company_name=""/>
<row id="101" fname="Michael" lname="Devlin"
 company_name="The Power Group"/>'

In this case, an empty company_name attribute is generated for Robert Michaels.

For information about the FOR_XML_NULL_TREATMENT option, see FOR_XML_NULL_TREATMENT option [database].


Invalid column names

Adaptive Server Anywhere uses the following rules for encoding names that are not legal XML names (for example, column names that include spaces):

  • Unicode characters that are not valid XML name characters are encoded as _xHHHH_, where HHHH is the four digit hexadecimal codepoint for the character. Characters whose Unicode codepoint value cannot be specified in 16 bits are encoded.

    For example, the following query contains a column name with a space:

    SELECT emp_id AS "employee id"
FROM employee
FOR XML RAW

    and returns the following result:

    <row employee_x0020_id="102"/>
<row employee_x0020_id="105"/>
<row employee_x0020_id="129"/>
<row employee_x0020_id="148"/>
...

  • Non-Unicode characters are encoded as _xHHHHHHHH_, where HHHHHHHH is the eight digit hexadecimal codepoint for the character.

  • Underscores (_) are escaped if they are followed by the character x.

  • Colons (:) are not escaped so that namespace declarations and qualified element and attribute names can be generated using a FOR XML query.

For information about the syntax of the FOR XML clause, see SELECT statement.

Tip
When executing queries that contain a FOR XML clause in Interactive SQL, you may wish to increase the column length by setting the TRUNCATION_LENGTH option.

For information about setting the truncation length, see TRUNCATION_LENGTH option [Interactive SQL] and Options dialog: Results tab.


FOR XML examples

The following examples show how the FOR XML clause can be used in a SELECT statement.

  • The following example shows how the FOR XML clause can be used in a subquery:

    SELECT XMLELEMENT(
   NAME root,
      (SELECT * FROM employee
       FOR XML RAW))

  • The following example shows how the FOR XML clause can be used in a query with a GROUP BY clause and aggregate function:

    SELECT name, AVG(unit_price) AS Price
FROM product
GROUP BY name
FOR XML RAW

  • The following example shows how the FOR XML clause can be used in a view definition:

    CREATE VIEW emp_dept
AS SELECT emp_lname, emp_fname, dept_name
FROM employee JOIN department
ON employee.dept_id = department.dept_id
FOR XML AUTO


Using FOR XML RAW

When you specify FOR XML RAW in a query, each row is represented as a <row> element, and each column is an attribute of the <row> element.

Syntax

FOR XML RAW[, ELEMENTS ]

Parameters

ELEMENTS tells FOR XML RAW to generate an XML element, instead of an attribute, for each column in the result. If there are NULL values, the element is omitted from the generated XML document. The following query generates <emp_id> and <dept_name> elements:

SELECT employee.emp_id, department.dept_name
FROM employee JOIN department
   ON employee.dept_id=department.dept_id
FOR XML RAW, ELEMENTS

and gives the following result:

<row>
   <emp_id>102</emp_id>
   <dept_name>R &amp; D</dept_name>
</row>
<row>
   <emp_id>105</emp_id>
   <dept_name>R &amp; D</dept_name>
</row>
<row>
   <emp_id>160</emp_id>
   <dept_name>R &amp; D</dept_name>
</row>
<row>
   <emp_id>243</emp_id>
   <dept_name>R &amp; D</dept_name>
</row>
...
Usage

Data in BINARY, LONG BINARY, IMAGE, and VARBINARY columns is automatically returned in base64-encoded format when you execute a query that contains FOR XML RAW.

By default, NULL values are omitted from the result. This behavior is controlled by the FOR_XML_NULL_TREATMENT option.

For information about how NULL values are returned in queries that contain a FOR XML clause, see FOR XML and NULL values.

FOR XML RAW does not return a well-formed XML document because the document does not have a single root node. If a <root> element is required, one way to insert one is to use the XMLELEMENT function. For example,

SELECT XMLELEMENT( NAME root,
                   (SELECT emp_id AS id, emp_fname AS name
                   FROM employee FOR XML RAW))

For more information about the XMLELEMENT function, see XMLELEMENT function [String].

The attribute or element names used in the XML document can be changed by specifying aliases. The following query renames the id attribute to product_id:

SELECT id AS product_id
FROM product
WHERE color='black'
FOR XML RAW

and gives the following result:

<row product_id="302"/>
<row product_id="400"/>
<row product_id="501"/>
<row product_id="700"/>

The order of the results depend on the plan chosen by the optimizer, unless you request otherwise. If you wish the results to appear in a particular order, you must include an ORDER BY clause in the query, for example,

SELECT employee.emp_id, department.dept_name
FROM employee JOIN department
   ON employee.dept_id=department.dept_id
ORDER BY emp_id
FOR XML RAW
Example

Suppose you want to retrieve information about which department an employee belongs to, as follows:

SELECT employee.emp_id, department.dept_name
FROM employee JOIN department
   ON employee.dept_id=department.dept_id
FOR XML RAW

The following XML document is returned:

<row emp_id="102" dept_name="R &amp; D"/>
<row emp_id="105" dept_name="R &amp; D"/>
<row emp_id="160" dept_name="R &amp; D"/>
<row emp_id="243" dept_name="R &amp; D"/>
...


Using FOR XML AUTO

AUTO mode generates nested elements within the XML document. Each table referenced in the select list is represented as an element in the generated XML. The order of nesting is based on the order in which tables are referenced in the select list. When you specify AUTO mode, an element is created for each table in the select list, and each column in that table is a separate attribute.

Syntax

FOR XML AUTO[, ELEMENTS ]

Parameters

ELEMENTS tells FOR XML AUTO to generate an XML element, instead of an attribute, for each column in the result. For example,

SELECT employee.emp_id, department.dept_name
FROM employee JOIN department
   ON employee.dept_id=department.dept_id
ORDER BY emp_id
FOR XML AUTO, ELEMENTS

In this case, each column in the result set is returned as a separate element, rather than as an attribute of the <employee> element. If there are NULL values, the element is omitted from the generated XML document.

<employee>
   <emp_id>102</emp_id>
   <department>
      <dept_name>R &amp; D</dept_name>
   </department>
</employee>
<employee>
   <emp_id>105</emp_id>
   <department>
      <dept_name>R &amp; D</dept_name>
   </department>
</employee>
<employee>
   <emp_id>160</emp_id>
   <department>
   <dept_name>R &amp; D</dept_name>
   </department>
</employee>
...
Usage

When you execute a query using FOR XML AUTO, data in BINARY, LONG BINARY, IMAGE, and VARBINARY columns is automatically returned in base64-encoded format. By default, NULL values are omitted from the result. You can return NULL values as empty attributes by setting the FOR_XML_NULL_TREATMENT option to EMPTY.

For information about setting the FOR_XML_NULL_TREATMENT option, see FOR_XML_NULL_TREATMENT option [database].

Unless otherwise requested, the database server returns the rows of a table in an order that has no meaning. If you wish the results to appear in a particular order, or for a parent element to have multiple children, you must include an ORDER BY clause in the query so that all children are adjacent. If you do not specify an ORDER BY clause, the nesting of the results depends on the plan chosen by the optimizer and you may not get the nesting you desire.

FOR XML AUTO does not return a well-formed XML document because the document does not have a single root node. If a <root> element is required, one way to insert one is to use the XMLELEMENT function. For example,

SELECT XMLELEMENT( NAME root,
                   (SELECT emp_id AS id, emp_fname AS name
                   FROM employee FOR XML AUTO ) )

For more information about the XMLELEMENT function, see XMLELEMENT function [String].

You can change the attribute or element names used in the XML document by specifying aliases. The following query renames the id attribute to product_id:

SELECT id AS product_id
FROM product
WHERE color='black'
FOR XML AUTO

The following XML is generated:

<product product_id="302"/>
<product product_id="400"/>
<product product_id="501"/>
<product product_id="700"/>

You can also rename the table with an alias. The following query renames the table to product_info:

SELECT id AS product_id
FROM product AS product_info
WHERE color='black'
FOR XML AUTO

The following XML is generated:

<product_info product_id="302"/>
<product_info product_id="400"/>
<product_info product_id="501"/>
<product_info product_id="700"/>
Example

The following query generates XML that contains both <employee> and <department> elements, and the <employee> element (the table listed first in the select list) is the parent of the <department> element.

SELECT employee.emp_id, department.dept_name
FROM employee JOIN department
   ON employee.dept_id=department.dept_id
ORDER BY emp_id
FOR XML AUTO

The following XML is generated by the above query:

<employee emp_id="102">
   <department dept_name="R &amp; D"/>
</employee>
<employee emp_id="105">
   <department dept_name="R &amp; D"/>
</employee>
<employee emp_id="160">
   <department dept_name="R &amp; D"/>
</employee>
<employee emp_id="243">
   <department dept_name="R &amp; D"/>
</employee>
...

If you change the order of the columns in the select list as follows:

SELECT department.dept_name, employee.emp_id
FROM employee JOIN department
   ON employee.dept_id=department.dept_id
ORDER BY 1, 2
FOR XML AUTO

the result is nested as follows:

<department dept_name="R &amp; D">
   <employee emp_id="102"/>
   <employee emp_id="105"/>
   <employee emp_id="160"/>
   ...
</department>
<department dept_name="Sales">
   <employee emp_id="129"/>
   <employee emp_id="195"/>
   <employee emp_id="299"/>
   ...
</department>
...

Again, the XML generated for the query contains both <employee> and <department> elements, but in this case the <department> element is the parent of the <employee> element.


Using FOR XML EXPLICIT

FOR XML EXPLICIT allows you to control the structure of the XML document returned by the query. The query must be written in a particular way so that information about the nesting you desire is specified within the query result. The optional directives supported by FOR XML EXPLICIT allow you to configure the treatment of individual columns. For example, you can control whether a column appears as element or attribute content, or whether a column is used only to order the result, rather than appearing in the generated XML.

For an example of how to write a query using FOR XML EXPLICIT, see Writing an EXPLICIT mode query.

Parameters

In EXPLICIT mode, the first two columns in the SELECT statement must be named Tag and Parent, respectively. Tag and Parent are metadata columns, and their values are used to determine the parent-child relationship, or nesting, of the elements in the XML document that is returned by the query.

  • Tag column This is the first column specified in the select list. The Tag column stores the tag number of the current element. Permitted values for tag numbers are 1 to 255.

  • Parent column This column stores the tag number for the parent of the current element. If the value in this column is NULL, the row is placed at the top level of the XML hierarchy.

For example, consider a query that returns the following result set when FOR XML EXPLICIT is not specified. (The purpose of the first_name!1 and id!2 data columns is discussed in the following section, Adding data columns to the query).

Tag | Parent | first_name!1 | id!2
1 | NULL | 'Beth' | NULL
2 | NULL | NULL | '102'

In this example, the values in the Tag column are the tag numbers for each element in the result set. The Parent column for both rows contains the value NULL. This means that both elements are generated at the top level of the hierarchy, giving the following result when the query includes the FOR XML EXPLICIT clause:

<first_name>Beth</first_name>
<id>102</id>

However, if the second row had the value 1 in the Parent column, the result would look as follows:

<first_name>Beth
   <id>102</id>
</first_name>

For an example of how to write a query using FOR XML EXPLICIT, see Writing an EXPLICIT mode query.

Adding data columns to the query

In addition to the Tag and Parent columns, the query must also contain one or more data columns. The names of these data columns control how the columns are interpreted during tagging. Each column name is split into fields separated by an exclamation mark (!). The following fields can be specified for data columns:

ElementName!TagNumber!AttributeName!Directive

ElementName the name of the element. For a given row, the name of the element generated for the row is taken from the ElementName field of the first column with a matching tag number. If there are multiple columns with the same TagNumber, the ElementName is ignored for subsequent columns with the same TagNumber. In the example above, the first row generates an element called <first_name>.

TagNumber the tag number of the element. For a row with a given tag value, all columns with the same value in their TagNumber field will contribute content to the element that corresponds to that row.

AttributeName specifies that the column value is an attribute of the ElementName element. For example, if a data column had the name prod_id!1!color, then color would appear as an attribute of the <prod_id> element.

Directive this optional field allows you to control the format of the XML document further. You can specify any one of the following values for Directive:

  • hide indicates that this column is ignored for the purpose of generating the result. This directive can be used to include columns that are only used to order the table. The attribute name is ignored and does not appear in the result.

    For an example using the hide directive, see Using the hide directive.

  • element indicates that the column value is inserted as a nested element with the name AttributeName, rather than as an attribute.

    For an example using the element directive, see Using the element directive.

  • xml indicates that the column value is inserted with no quoting. If the AttributeName is specified, the value is inserted as an element with that name. Otherwise, it is inserted with no wrapping element. If this directive is not used, then markup characters are escaped unless the column is of type XML. For example, the value <a/> would be inserted as &lt;a/&gt;.

    For an example using the xml directive, see Using the xml directive.

  • cdata indicates that the column value is to be inserted as a CDATA section. The AttributeName is ignored.

    For an example using the cdata directive, see Using the cdata directive.

Usage

Data in BINARY, LONG BINARY, IMAGE, and VARBINARY columns is automatically returned in base64-encoded format when you execute a query that contains FOR XML EXPLICIT. By default, any NULL values in the result set are omitted. You can change this behavior by changing the setting of the FOR_XML_NULL_TREATMENT option.

For more information about the FOR_XML_NULL_TREATMENT option, see FOR_XML_NULL_TREATMENT option [database] and FOR XML and NULL values.

Writing an EXPLICIT mode query

Suppose you want to write a query using FOR XML EXPLICIT that generates the following XML document:

<employee emp_id='129'>
   <customer cust_id='107' region='Eastern'/>
   <customer cust_id='119' region='Western'/>
   <customer cust_id='131' region='Eastern'/>
</employee>
<employee emp_id='195'>
   <customer cust_id='109' region='Eastern'/>
   <customer cust_id='121' region='Central'/>
</employee>

You do this by writing a SELECT statement that returns the following result set in the exact order specified, and then appending FOR XML EXPLICIT to the query.

Tag | Parent | employee!1!emp_id | customer!2!cust_id | customer!2!region
1 | NULL | 129 | NULL | NULL
2 | 1 | 129 | 107 | Eastern
2 | 1 | 129 | 119 | Western
2 | 1 | 129 | 131 | Central
1 | NULL | 195 | NULL | NULL
2 | 1 | 195 | 109 | Eastern
2 | 1 | 195 | 121 | Central

When you write your query, only some of the columns for a given row become part of the generated XML document. A column is included in the XML document only if the value in the TagNumber field (the second field in the column name) matches the value in the Tag column.

In the example, the third column is used for the two rows that have the value 1 in their Tag column. In the fourth and fifth columns, the values are used for the rows that have the value 2 in their Tag column. The element names are taken from the first field in the column name. In this case, <employee> and <customer> elements are created.

The attribute names come from the third field in the column name, so an emp_id attribute is created for <employee> elements, while cust_id and region attributes are generated for <customer> elements.

The following steps explain how to construct the FOR XML EXPLICIT query that generates an XML document similar to the one found at the beginning of this section using the sample database.

toggle To write a FOR XML EXPLICIT query

  1. Write a SELECT statement to generate the top-level elements.

    In this example, the first SELECT statement in the query generates the <employee> elements. The first two values in the query must be the Tag and Parent column values. The <employee> element is at the top of the hierarchy, so it is assigned a Tag value of 1, and a Parent value of NULL.

    Note
    If you are writing an EXPLICIT mode query that uses a UNION, then only the column names specified in the first SELECT statement are used. Column names that are to be used as element or attribute names must be specified in the first SELECT statement because column names specified in subsequent SELECT statements are ignored.

    To generate the <employee> elements for the table above, your first SELECT statement is as follows:

    SELECT
      1       AS tag,
      NULL    AS parent,
      emp_id  AS [employee!1!emp_id],
      NULL    AS [customer!2!cust_id],
      NULL    AS [customer!2!region]
FROM employee

  2. Write a SELECT statement to generate the child elements.

    The second query generates the <customer> elements. Because this is an EXPLICIT mode query, the first two values specified in all the SELECT statements must be the Tag and Parent values. The <customer> element is given the tag number 2, and because it is a child of the <employee> element, it has a Parent value of 1. The first SELECT statement has already specified that emp_id, cust_id, and region are attributes.

    SELECT
      2,
      1,
      emp_id,
      cust_id,
      region
FROM employee KEY JOIN sales_order

  3. Add a UNION ALL to the query to combine the two SELECT statements together:

    SELECT
      1       AS tag,
      NULL    AS parent,
      emp_id  AS [employee!1!emp_id],
      NULL    AS [customer!2!cust_id],
      NULL    AS [customer!2!region]
FROM employee
UNION ALL
    SELECT
      2,
      1,
      emp_id,
      cust_id,
      region
FROM employee KEY JOIN sales_order

  4. Add an ORDER BY clause to specify the order of the rows in the result. The order of the rows is the order that is used in the resulting document.

    SELECT
      1       AS tag,
      NULL    AS parent,
      emp_id  AS [employee!1!emp_id],
      NULL    AS [customer!2!cust_id],
      NULL    AS [customer!2!region]
FROM employee
UNION ALL
    SELECT
      2,
      1,
      emp_id,
      cust_id,
      region
FROM employee KEY JOIN sales_order
ORDER BY 3, 1
FOR XML EXPLICIT

For information about the syntax of EXPLICIT mode, see Parameters.

FOR XML EXPLICIT examples

The following example query retrieves information about the orders placed by employees. In this example, there are three types of elements: <emp>, <order>, and <dept>. The <emp> element has id and name attributes, the <order> element has a date attribute, and the <dept> element has a name attribute.

SELECT
        1           tag,
        NULL        parent,
        emp_id      [emp!1!id],
        emp_fname   [emp!1!name],
        NULL        [order!2!date],
        NULL        [dept!3!name]
FROM employee
UNION ALL
SELECT
        2,
        1,
        emp_id,
        NULL,
        order_date,
        NULL
FROM employee KEY JOIN sales_order
UNION ALL
SELECT
        3,
        1,
        emp_id,
        NULL,
        NULL,
        dept_name
FROM employee e JOIN department d
   ON e.dept_id=d.dept_id
ORDER BY 3, 1
FOR XML EXPLICIT

You get the following result from this query:

<emp id="102" name="Fran">
   <dept name="R &amp; D"/>
</emp>
<emp id="105" name="Matthew">
   <dept name="R &amp; D"/>
</emp>
<emp id="129" name="Philip">
   <order date="2000-07-24"/>
   <order date="2000-07-13"/>
   <order date="2000-06-24"/>
   <order date="2000-06-08"/>
   ...
   <dept name="Sales"/>
</emp>
<emp id="148" name="Julie">
   <dept name="Finance"/>
</emp>
...
Using the element directive

If you wish to generate sub-elements rather than attributes, you can add the element directive to the query, as follows:

SELECT
        1          tag,
        NULL       parent,
        emp_id     [emp!1!id!element],
        emp_fname  [emp!1!name!element],
        NULL       [order!2!date!element],
        NULL       [dept!3!name!element]
FROM employee
UNION ALL
SELECT
        2,
        1,
        emp_id,
        NULL,
        order_date,
        NULL
FROM employee KEY JOIN sales_order
UNION ALL
SELECT
        3,
        1,
        emp_id,
        NULL,
        NULL,
        dept_name
FROM employee e JOIN department d
   ON e.dept_id=d.dept_id
ORDER BY 3, 1
FOR XML EXPLICIT

You get the following result from this query:

<emp>
   <id>102</id>
   <name>Fran</name>
   <dept>
      <name>R &amp; D</name>
   </dept>
</emp>
<emp>
   <id>105</id>
   <name>Matthew</name>
   <dept>
      <name>R &amp; D</name>
   </dept>
</emp>
<emp>
   <id>129</id>
   <name>Philip</name>
   <order>
      <date>2000-07-24</date>
   </order>
   <order>
      <date>2000-07-13</date>
   </order>
   <order>
      <date>2000-06-24</date>
   </order>
   ...
   <dept>
      <name>Sales</name>
   </dept>
</emp>
...
Using the hide directive

In the following query, the employee ID is used to order the result, but the employee ID does not appear in the result because the hide directive is specified:

SELECT
        1           tag,
        NULL        parent,
        emp_id      [emp!1!id!hide],
        emp_fname   [emp!1!name],
        NULL        [order!2!date],
        NULL        [dept!3!name]
FROM employee
UNION ALL
SELECT
        2,
        1,
        emp_id,
        NULL,
        order_date,
        NULL
FROM employee KEY JOIN sales_order
UNION ALL
SELECT
        3,
        1,
        emp_id,
        NULL,
        NULL,
        dept_name
FROM employee e JOIN department d
   ON e.dept_id=d.dept_id
ORDER BY 3, 1
FOR XML EXPLICIT

This query returns the following result:

<emp name="Fran">
   <dept name="R &amp; D"/>
</emp>
<emp name="Matthew">
   <dept name="R &amp; D"/>
</emp>
<emp name="Philip">
   <order date="2000-07-24"/>
   <order date="2000-07-13"/>
   <order date="2000-06-24"/>
   <order date="2000-06-08"/>
   ...
   <dept name="Sales"/>
</emp>
<emp name="Julie">
   <dept name="Finance"/>
</emp>
...
Using the xml directive

By default, when the result of a FOR XML EXPLICIT query contains characters that are not valid XML characters, the invalid characters are escaped (for information see Invalid column names) unless the column is of type XML. For example, the following query generates XML that contains an ampersand (&):

SELECT
        1               AS tag,
        NULL            AS parent,
        id              AS [customer!1!id!element],
        company_name    AS [customer!1!company_name]
FROM customer
WHERE id = '115'
FOR XML EXPLICIT

In the result generated by this query, the ampersand is escaped because the column is not of type XML:

<customer company_name="Sterling &amp; Co.">
   <id>115</id>
</customer>

The xml directive indicates that the column value is inserted into the generated XML with no quoting. If you execute the same query as above with the xml directive:

SELECT
        1               AS tag,
        NULL            AS parent,
        id              AS [customer!1!id!element],
        company_name    AS [customer!1!company_name!xml]
FROM customer
WHERE id = '115'
FOR XML EXPLICIT

the ampersand is not quoted in the result:

<customer>
 <id>115</id>
 <company_name>Sterling & Co.</company_name>
</customer>

Note that this XML is not well-formed because it contains an ampersand, which is a special character in XML. When XML is generated by a query, it is your responsibility to ensure that the XML is well-formed and valid: Adaptive Server Anywhere does not check whether the XML being generated is well-formed or valid.

When you specify the xml directive, the AttributeName field is ignored, and elements are generated rather than attributes.

Using the cdata directive

The following query uses the cdata directive to return the customer name in a CDATA section:

SELECT
        1               AS tag,
        NULL            AS parent,
        id              AS [product!1!id],
        description     AS [product!1!cdata]
FROM product
FOR XML EXPLICIT

The result produced by this query lists the description for each product in a CDATA section. Data contained in the CDATA section is not quoted:

<product id="300">
   <![CDATA[Tank Top]]>
</product>
<product id="301">
   <![CDATA[V-neck]]>
</product>
<product id="302">
   <![CDATA[Crew Neck]]>
</product>
<product id="400">
   <![CDATA[Cotton Cap]]>
</product>
...


Using SQL/XML to obtain query results as XML

SQL/XML is a draft standard that describes a functional integration of XML into the SQL language: it describes the ways that SQL can be used in conjunction with XML. The supported functions allow you to write queries that construct XML documents from relational data.

Invalid names and SQL/XML

In SQL/XML, expressions that are not legal XML names, for example expressions that include spaces, are escaped in the same manner as the FOR XML clause. Element content of type XML is not quoted.

For more information about quoting invalid expressions, see Invalid column names.

For information about using the XML data type, see Storing XML documents in relational databases.


Using the XMLAGG function

The XMLAGG function is used to produce a forest of XML elements from a collection of XML elements. XMLAGG is an aggregate function, and produces a single aggregated XML result for all the rows in the query.

In the following query, XMLAGG is used to generate a <name> element for each row, and the <name> elements are ordered by employee name. The ORDER BY clause is specified to order the XML elements:

SELECT XMLELEMENT( NAME department,
                   XMLATTRIBUTES (dept_id ),
                   XMLAGG( XMLELEMENT( NAME name,
                             emp_lname )
                             ORDER BY emp_lname )
                  ) AS dept_list
FROM employee
GROUP BY dept_id

This query produces the following result:

dept_list
<department dept_id="100">
 <name>Breault</name>
 <name>Cobb</name>
 <name>Diaz</name>
 <name>Driscoll</name>
 ...
</department>

<department dept_id="200">
 <name>Chao</name>
 <name>Chin</name>
 <name>Clark</name>
 <name>Dill</name>
 ...
</department>

<department dept_id="300">
 <name>Bigelow</name>
 <name>Coe</name>
 <name>Coleman</name>
 <name>Davidson</name>
 ...
</department>

...

For more information about the XMLAGG function, see XMLAGG function [String].


Using the XMLCONCAT function

The XMLCONCAT function creates a forest of XML elements by concatenating all the XML values passed in. For example, the following query concatenates the <first_name> and <last_name> elements for each employee in the employee table:

SELECT XMLCONCAT( XMLELEMENT( NAME first_name, emp_fname ),
                  XMLELEMENT( NAME last_name, emp_lname )
                 ) AS "Employee_Name"
FROM employee

This query returns the following result:

Employee_Name
<first_name>Fran</first_name>
<last_name>Whitney</last_name>

<first_name>Matthew</first_name>
<last_name>Cobb</last_name>

<first_name>Philip</first_name>
<last_name>Chin</last_name>

<first_name>Julie</first_name>
<last_name>Jordan</last_name>

...

For more information, see XMLCONCAT function [String].


Using the XMLELEMENT function

The XMLELEMENT function constructs an XML element from relational data. You can specify the content of the generated element and if you wish, you can also specify attributes and attribute content for the element.

Generating nested elements

The following query generates nested XML, producing a <product_info> element for each product, with elements that provide the name, quantity, and description of each product:

SELECT id,
       XMLELEMENT( NAME product_info,
       XMLELEMENT( NAME item_name, product.name ),
       XMLELEMENT( NAME quantity_left, product.quantity ),
       XMLELEMENT( NAME description, product.size || ' ' ||
                            product.color || ' ' ||
                         product.name )
       ) AS results
FROM product
WHERE quantity > 30

This query produces the following result:

id results
301
<product_info>
 <item_name>Tee Shirt
  </item_name>
 <quantity_left>54
  </quantity_left>
 <description>Medium Orange
  Tee Shirt</description>
</product_info>
302
<product_info>
 <item_name>Tee Shirt
  </item_name>
 <quantity_left>75
  </quantity_left>
 <description>One size fits
  all Black Tee Shirt
  </description>
</product_info>
400
<product_info>
 <item_name>Baseball Cap
  </item_name>
 <quantity_left>112
  </quantity_left>
 <description>One size fits
  all Black Baseball Cap
  </description>
</product_info>
... ...
Specifying element content

The XMLELEMENT function allows you to specify the content of an element. The following statement produces an XML element with the content hat.

SELECT id, XMLELEMENT( NAME product_type, 'hat' )
FROM product
WHERE name IN ( 'Baseball Cap', 'Visor' )
Generating elements with attributes

You can add attributes to the elements by including the XMLATTRIBUTES argument in your query. This argument specifies the attribute name and content. The following statement produces an attribute for the name, color, and unit_price of each item.

SELECT id, XMLELEMENT( NAME item_description,
                       XMLATTRIBUTES( name,
                                      color,
                                      unit_price )
                      ) AS item_description_element
FROM product
WHERE id > 400

Attributes can be named by specifying the AS clause:

SELECT id, XMLELEMENT( NAME item_description,
                       XMLATTRIBUTES ( unit_price AS
                        price ),
                       product.name
                     ) AS products
FROM product
WHERE id > 400

For more information, see XMLELEMENT function [String].


Using the XMLFOREST function

XMLFOREST constructs a forest of XML elements. An element is produced for each XMLFOREST argument.

The following query produces an <item_description> element, with <name>, <color>, and <price> elements:

SELECT id, XMLELEMENT( NAME item_description,
                       XMLFOREST( name,
                                  color,
                                  unit_price AS price )
                      ) AS product_info
FROM product
WHERE id > 400

The following result is generated by this query:

id product_info
401
<item_description>
 <name>Baseball Cap</name>
 <color>White</color>
 <price>10.00</price>
</item_description>
500
<item_description>
 <name>Visor</name>
 <color>White</color>
 <price>7.00</price>
</item_description>
501
<item_description>
 <name>Visor</name>
 <color>Black</color>
 <price>7.00</price>
</item_description>
... ...

For more information, see XMLFOREST function [String].


Using the XMLGEN function

The XMLGEN function is used to generate an XML value based on an XQuery constructor.

The XML generated by the following query provides information about customer orders in the sample database. It uses the following variable references:

  • {$id} Generates content for the <id> element using values from the id column in the sales_order table.

  • {$order_date} Generates content for the <date> element using values from the order_date column in the sales_order table.

  • {$customer} Generates content for the <customer> element from the company_name column in the customer table.

SELECT XMLGEN ( '<order>
                 <id>{$id}</id>
                 <date>{$order_date}</date>
                 <customer>{$customer}</customer>
                 </order>',
                sales_order.id,
                sales_order.order_date,
                customer.company_name AS customer)
 FROM sales_order JOIN customer
 ON customer.id = sales_order.cust_id

This query generates the following result:

order_info
<order>
 <id>2131</id>
 <date>2000-01-02</date>
 <customer>BoSox Club</customer>
</order>

<order>
 <id>2126</id>
 <date>2000-01-03</date>
 <customer>Leisure Time</customer>
</order>

<order>
 <id>2065</id>
 <date>2000-01-03</date>
 <customer>Bloomfield&apos;s</customer>
</order>

<order>
 <id>2127</id>
 <date>2000-01-06</date>
 <customer>Creative Customs Inc.</customer>
</order>

...
Generating attributes

If you want the order ID number to appear as an attribute of the <order> element, you would write query as follows (note that the variable reference is contained in double quotes because it specifies an attribute value):

SELECT XMLGEN ( '<order id="{$id}">
                 <date>{$order_date}</date>
                 <customer>{$customer}</customer>
                 </order>',
                sales_order.id,
                sales_order.order_date,
                customer.company_name AS customer
              ) AS order_info
FROM sales_order JOIN customer
 ON customer.id = sales_order.cust_id
 ORDER BY sales_order.order_date

This query generates the following result:

order_info
<order id="2131">
 <date>2000-01-02</date>
 <customer>BoSox Club</customer>
</order>

<order id="2126">
 <date>2000-01-03</date>
 <customer>Leisure Time</customer>
</order>

<order id="2065">
 <date>2000-01-03</date>
 <customer>Bloomfield&apos;s</customer>
</order>

<order id="2127">
 <date>2000-01-06</date>
 <customer>Creative Customs Inc.</customer>
</order>

...

In both result sets, the customer name Bloomfield's is quoted as Bloomfield&apos;s because the apostrophe is a special character in XML and the column the <customer> element was generated from was not of type XML.

For more information about quoting of illegal characters in XMLGEN, see Invalid names and SQL/XML.

Specifying header information for XML documents

The FOR XML clause and the SQL/XML functions supported by Adaptive Server Anywhere do not include version declaration information in the XML documents they generate. You can use the XMLGEN function to generate header information.

SELECT XMLGEN( '<?xml version="1.0"
                encoding="ISO-8859-1" ?>
                <r>{$x}</r>',
                (SELECT fname, lname FROM customer FOR XML RAW) AS x )

This produces the following result:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<r>
 <row fname="Michael" lname="Devlin"/>
 <row fname="Beth" lname="Reiser"/>
 <row fname="Erin" lname="Niedringhaus"/>
 <row fname="Meghan" lname="Mason"/>
 ...
</r>

For more information about the XMLGEN function, see XMLGEN function [String].


Importing and Exporting Data

About this chapter

This chapter describes the process of transferring bulk data into and out of your Adaptive Server Anywhere database.

Transferring data into and out of databases
Performance aspects of bulk operations
Data recovery issues for bulk operations
Importing data into databases
Exporting data from databases
Rebuilding databases
Extracting databases
Migrating databases to Adaptive Server Anywhere
Using SQL command files
Adaptive Server Enterprise compatibility


Transferring data into and out of databases

Transferring data into and out of your database may be necessary in several situations. For example:

  • Importing an initial set of data into a new database.

  • Building new copies of a database, perhaps with a modified structure.

  • Exporting data from your database for use with other applications, such as spreadsheets.

  • Creating extractions of a database for replication or synchronization.

  • Repairing a corrupt database.

  • Rebuilding a database to improve its performance.

  • Obtaining a newer version of database software and completing software upgrades.

These tasks are often grouped together as bulk operations. They are carried by a user with DBA authority and are not part of typical end-user applications. Bulk operations may put particular demands on concurrency and transaction logs and are often best carried out when no other users are connected to the database.


Performance aspects of bulk operations

The performance of bulk operations depends on whether the operation is internal or external to the database server.

External to the database server: Client-side

The INPUT and OUTPUT commands are executed through the Interactive SQL client. If Interactive SQL is being run on a different machine than the database server, paths to files being read or written are relative to the client, not to the server. An INPUT is recorded in the transaction log as a separate INSERT statement for each row read. As a result, INPUT is considerably slower than LOAD TABLE. This also means that ON INSERT triggers will fire during an INPUT. Missing values will be inserted as NULL on NULLABLE rows, as 0 (zero) on non-nullable numeric columns, and as an empty string on non-nullable non-numeric columns. The OUTPUT statement is useful when compatibility is an issue since it can write out the result set of a SELECT statement to any one of a number of file formats.

Internal to the database sever: Server-side

The LOAD TABLE, UNLOAD TABLE, and UNLOAD statements are internal to the database server. Paths to files being written or read are relative to the database server. A LOAD TABLE statement is recorded in the transaction log as a single command. The data file must contain the same number of columns as the table to be loaded. Missing values on columns with a default value will be inserted as NULL, zero, or an empty string if the DEFAULTS option is set to OFF (default), or as the default value if the DEFAULTS option is set to ON. Internal importing and exporting only provides access to text and BCP formats, but it is a faster method.

For more information, see Performance tips for importing data.


Data recovery issues for bulk operations

You should back up the database before and after using bulk operations mode because, in this mode, your database is not protected against media failure. If you are running the database server in bulk operations mode (the -b option) for importing large amounts of data, the database server does not do certain important functions. Specifically:

When the database server is in bulk operations mode, the database server does not... | Which has the following implications...
Keep a rollback log | Savepoints cannot be used and aborting a command always causes transactions to roll back.
Maintain a transaction log | There is no record of the changes.
Lock any records | There are no serious implications.
Perform an automatic COMMIT before data definition commands | Without automatic COMMIT, a ROLLBACK undoes everything since the last explicit COMMIT.

The preceding conditions have serious implications for the database if there is a media failure. Therefore,

If you have data that requires many COMMITs, running with the -b option may slow the database operation. At each COMMIT, the server carries out a checkpoint, which slows down the database server.

For information, see -b server option and Backup and Data Recovery.


Importing data into databases

Importing is an administrative task that involves reading data into your database as a bulk operation. Adaptive Server Anywhere lets you:

  • import entire tables or portions of tables from ASCII files

  • import entire tables or portions of tables from other database formats, such as DBASEII

  • import a number of tables consecutively by automating the import procedure with a script

  • insert or append data into tables

  • replace data in tables

  • create a table before the import or during the import

  • import files between Adaptive Server Anywhere and Adaptive Server Enterprise using the BCP format clause

If you are trying to create an entirely new database, consider loading the data instead of importing it, for performance reasons.

For more information about unloading and reloading complete databases, see Rebuilding databases.

In the following sections, learn about import tools, followed by instructions for importing databases, data, and tables.


Import considerations

Before you begin importing data into your database, spend some time and consider in detail what resources you have and exactly what you want to accomplish by importing data into your database.

Consider this factor... | For information, see...
The import tools that are available. | Import tools
Impact on database performance that importing might have. | Performance aspects of bulk operations Performance tips for importing data
Compatibility issues between your data and the destination table. | Table structures for import


Performance tips for importing data

Although importing large volumes of data into a database can be time consuming, there are a few things you can do to save time:

  • Place data files on a separate physical disk drive from the database. This could avoid excessive disk head movement during the load.

  • Extend the size of the database, as described in ALTER DBSPACE statement. This command allows a database to be extended in large amounts before the space is required, rather than the normal 256 kb at a time when the space is needed. As well as improving performance for loading large amounts of data, it also serves to keep the database more contiguous within the file system.

  • Use temporary tables to load data. Local or global temporary tables are useful when you need to load a set of data repeatedly, or when you need to merge tables with different structures.

  • If using the LOAD TABLE statement, do not start the database server with the -b option (bulk operations mode) because it is not necessary.

  • If using the INPUT or OUTPUT command, run Interactive SQL or the client application on the same machine as the database server. Loading data over the network adds extra communication overhead. This might mean loading new data during off hours.


Import tools

There are a variety of tools available to help you import data into an Adaptive Server Anywhere database. A discussion of each import tool follows.

Using the Interactive SQL Import wizard
Using the INPUT statement to import data
Using the LOAD TABLE statement to import data
Using the INSERT statement to import data
Using proxy tables to import data


Using the Interactive SQL Import wizard

The Interactive SQL Import wizard lets you choose a file to import, a file format, and a destination table in which to place the data. You can import data in text, DBASEII, DBASEIII, Excel 2.1, FOXPRO, and Lotus formats. You can choose to import this data into an existing table, or you can use the wizard to create and configure a completely new table.

Consider using the Interactive SQL Import wizard when:

  • You prefer using a graphical interface to import data in a format other than text.

  • You want to create a table at the same time you import the data.

Example 1

This example shows you how to import data using the Interactive SQL Data menu.

toggle To import data (Interactive SQL Data menu)

  1. From the Interactive SQL window, choose Data > Import.

    The Open dialog appears.

  2. Locate the file you want to import and click Open.

    The Import wizard appears.

  3. Specify how the database values are stored in the file you are importing.

  4. Select the Use An Existing Table option and then enter the name and location of the existing table. Click Next.

    You can also click the Browse button and locate the table you want to import the data into.

  5. For ASCII files, you can specify the field delimiter for the file, as well as the escape character, whether trailing blanks should be included, and the encoding for the file. The encoding option allows you to specify the code page that is used to read the file to ensure that characters are treated correctly. If you select (Default), the default encoding for the machine Interactive SQL is running on is used.

    For information about supported code pages, see Supported code pages.

  6. Follow the remaining instructions in the wizard.

    Importing appends the new data to the existing table. If the import is successful, the Messages pane displays the amount of time it to took to import the data. If the import is unsuccessful, a message appears indicating the import was unsuccessful.

Example 2

The following example shows you how to add data to the employee table of the ASA 9.0 Sample database. This example adds information about an employee named Julia Chan.

toggle To import data into the sample database

  1. Create and save a text file named import.txt with the following values (on a single line):

    100,500,'Julia','Chan',
100, '300 Royal Drive','Springfield','OR','97015','6175553985',
'A','017239033', 55700,'1984-09-29',,'1968-05-05','Y','Y','N','F'

  2. In Interactive SQL, choose Data > Import.

  3. Locate the import.txtfile and click Open.

    The Import wizard appears.

  4. Specify how the database values are stored in the file you are importing.

  5. Select the Use An Existing Table option and then enter employee as the name of the table into which you want to import data. Click Next.

  6. Follow the remaining steps in the Import wizard.


Using the INPUT statement to import data

The INPUT statement lets you import data in a variety of file formats into one or more tables. You can choose a default input format, or you can specify the file format on each INPUT statement. Interactive SQL can execute a command file containing multiple INPUT statements.

Consider using the INPUT statement to import data when:

  • You want to import data into one or more tables.

  • You want to automate the import process using a command file.

  • You want to import data in a format other than text.

For information, see INPUT statement [Interactive SQL].

Impact on the database

Changes are recorded in the transaction log. In the event of a media failure, there is a record of the changes. However, there are performance impacts associated with importing large amounts of data with the INPUT statement, since the INPUT statement writes everything to the transaction log.

The INPUT statement is slower than LOAD TABLE statement. If a data file is in DBASE, DBASEII, DBASEIII, FOXPRO, or LOTUS format and the table does not exist, it will be created.

Example

This example shows you how to import data using the Interactive SQL INPUT statement.

toggle To import data (Interactive SQL INPUT statement)

  1. Ensure that the table you want to place the data in exists.

  2. Enter an INPUT statement in the SQL Statements pane of the Interactive SQL window. For example,

    INPUT INTO t1
FROM file1
FORMAT ASCII;

    Where t1 is the name of the table you want to place the data in, and file1 is the name of the file that holds the data you want to import.

  3. Execute the statement.

    If the import is successful, the Messages pane displays the amount of time it to took to import the data. If the import is unsuccessful, a message appears indicating the import was unsuccessful.

For information about using the INPUT statement to import data, see INPUT statement [Interactive SQL].

The following is an example of an INPUT statement from an ASCII text file.

INPUT INTO employee
FROM new_emp.inp
FORMAT ASCII;


Using the LOAD TABLE statement to import data

The LOAD TABLE statement lets you import data only, into a table, in an efficient manner in text/ASCII/FIXED formats. The table must exist and have the same number of columns as the input file has fields, defined using compatible data types. The LOAD TABLE statement imports with one row per line, with values separated by a delimiter.

Consider using the LOAD TABLE statement when:

  • You want to import data in text format.

  • You want to improve performance and can use the LOAD TABLE statement instead of an INPUT statement.

For more information, see LOAD TABLE statement.

Impact on the database

Changes are not recorded in the transaction log. If you need to recover data, this information will not be available. Data is lost in the event of a crash, making this statement unusable with SQL Remote or MobiLink remote databases.

The LOAD TABLE statement is considerably faster than the INPUT statement.

The LOAD TABLE statement appends the contents of the file to the existing rows of the table; it does not replace the existing rows in the table.


Using the INSERT statement to import data

The INSERT statement lets you add rows to the database. Because you include the data you want to place in your table directly in the INSERT statement, it is considered interactive input. You can also use the INSERT statement with remote data access to import data from another database rather than a file.

Consider using the INSERT statement to import data when:

  • You want to import small amounts of data into a single table.

  • File formats are not an issue.

  • You want to import remote data from an external database rather than from a file.

For information, see INSERT statement.

Impact on the database

Changes are recorded in the transaction log. This means that if there is a media failure, you can recover information about the changes you made from the transaction log. For more information, see The transaction log.

Example

This example shows you how to import data using the INSERT statement. With this INSERT statement, you add data to the department table of the sample database.

toggle To import data (INSERT statement)

  1. Ensure that the table you want to place the data in exists.

  2. Execute an INSERT statement. For example,

    INSERT INTO t1
VALUES ( ... )

    Inserting values appends the new data to the existing table.

The following example inserts a new row into the department table in the sample database.

INSERT
INTO department ( dept_id, dept_name, dept_head_id )
VALUES ( 700, 'Training', 501)


Using proxy tables to import data

A proxy table is a local table containing metadata used to access a table on a remote database server as if it were a local table. These let you import data directly.

Consider using proxy tables to import data when:

  • You have access to remote data.

  • You want to import data directly from another database.

How to use proxy tables

Create a proxy table, then use an INSERT statement with a SELECT clause to insert data from the remote database into a permanent table in your database.

For information about remote data access, see Accessing Remote Data.

For information about INSERT statements, see INSERT statement.


Load tools

You can use either of the following tools to help you load data into your database:

  • Using the INSERT statement to import data

  • Using the LOAD TABLE statement to import data


Handling conversion errors during import

When you load data from external sources, there may be errors in the data. For example, there may be dates that are not valid dates and numbers that are not valid numbers. The CONVERSION_ERROR database option allows you to ignore conversion errors by converting them to NULL values.

For more information about setting Interactive SQL database options, see SET OPTION statement, or CONVERSION_ERROR option [compatibility].


Importing tables

You can import tables into an existing database using either the Interactive SQL Data menu or the Statements pane. The table data can be in text, DBASEII, Excel 2.1, FOXPRO, and Lotus formats.

toggle To import a table (Interactive SQL Data menu)

  1. Ensure that the table you want to place the data in exists.

  2. From the Interactive SQL window, choose Data > Import.

    The Open dialog appears.

  3. Locate the file you want to import and click Open.

    The Import wizard appears.

  4. Select the Create A New Table With The Following Name option and enter a name for the new table in the field.

  5. Follow the remaining instructions in the wizard.

    If the import is successful, the Messages pane displays the amount of time it to took to import the data. If the import is unsuccessful, a message appears indicating the import was unsuccessful. The Results tab in the Results pane displays what execution plan was used.

toggle To import a table (Interactive SQL)

  1. In the SQL Statements pane of the Interactive SQL window, create the table you want to load data into.

    You can use the CREATE TABLE statement to create the table.

  2. Execute a LOAD TABLE statement. For example,

    LOAD TABLE department
FROM 'dept.txt'

  3. To keep trailing blanks in your values, use the STRIP OFF clause in your LOAD TABLE statement. The default setting (STRIP ON) strips trailing blanks from values before inserting them.

    The LOAD TABLE statement appends the contents of the file to the existing rows of the table; it does not replace the existing rows in the table. You can use the TRUNCATE TABLE statement to remove all the rows from a table.

    Neither the TRUNCATE TABLE statement nor the LOAD TABLE statement fires triggers, including referential integrity actions, such as cascaded deletes.

For more information about the LOAD TABLE statement syntax, see LOAD TABLE statement.


Table structures for import

The structure of the data you want to load into a table does not need to match the structure of the destination table itself. For example, the column data types may be different or in a different order, or there may be extra values in the import data that do not match columns in the destination table.

Rearranging the table or data

If you know that the structure of the data you want to import does not match the structure of the destination table, you have several options:

  • You can rearrange the columns in your table using the LOAD TABLE statement.

  • You can rearrange the import data to fit the table using a variation of the INSERT statement and a global temporary table.

  • You can use the INPUT statement to specify a specific set or order of columns.

Allowing columns to contain NULL values

If the file you are importing contains data for a subset of the columns in a table, or if the columns are in a different order, you can also use the LOAD TABLE statement DEFAULTS option to fill in the blanks and merge non-matching table structures.

If DEFAULTS is OFF, any column not present in the column list is assigned NULL. If DEFAULTS is OFF and a non-nullable column is omitted from the column list, the database server attempts to convert the empty string to the column's type. If DEFAULTS is ON and the column has a default value, that value is used.

For example, to load two columns into the employee table, and set the remaining column values to the default values if there are any, the LOAD TABLE statement should look like this:

LOAD TABLE employee (emp_lname, emp_fname)
FROM 'new_employees.txt'
DEFAULTS ON


Merging different table structures

You can rearrange the import data to fit the table using a variation of the INSERT statement and a global temporary table.

toggle To load data with a different structure using a global temporary table

  1. In the SQL Statements pane of the Interactive SQL window, create a global temporary table with a structure matching that of the input file.

    You can use the CREATE TABLE statement to create the global temporary table.

  2. Use the LOAD TABLE statement to load your data into the global temporary table.

    When you close the database connection, the data in the global temporary table disappears. However, the table definition remains. You can use it the next time you connect to the database.

  3. Use the INSERT statement with a FROM SELECT clause to extract and summarize data from the temporary table and put it into one or more permanent database tables.


Exporting data from databases

Exporting is an administrative task that involves writing data out of your database. Exporting is a useful tool if you need to share large portions of your database, or extract portions of your database according to particular criteria. Adaptive Server Anywhere lets you:

  • export individual tables, query results, or table schema

  • create scripts that automate exporting so that you can export a number of tables consecutively

  • export to many different file formats

  • export files between Adaptive Server Anywhere and Adaptive Server Enterprise using the BCP FORMAT clause

If you want to export an entire database, consider unloading the database instead of exporting data, for performance reasons.

For more information about unloading and reloading complete databases, see Rebuilding databases.

Following is a summary of export tools, followed by instructions for exporting query results, databases, and tables.


Export considerations

Before you begin exporting data, spend some time and consider in detail what resources you have and exactly what type of information you want to export from your database.

Consider this factor... | For information, see...
The export tools that are available. | Export tools
Impact of exporting on the database performance. | Performance aspects of bulk operations
How to handle NULL values. | Outputting NULLs


Export tools

There are a variety of tools available to help you export your data.

Using Interactive SQL to export data
Using the OUTPUT statement to export data
Using the UNLOAD TABLE statement
Using the UNLOAD statement
Using the dbunload utility to export data


Using Interactive SQL to export data

You can use the Interactive SQL Export wizard to export data from result sets of queries you have obtained from your database.

Use this export tool when you want to save result sets to a file. In Interactive SQL, choose Data > Export. This allows you to choose the file format of the exported query results.

Example

The following example shows you how to export a result set from a SQL query to a file.

toggle To export result sets data using Interactive SQL

  1. Execute the following query using the ASA 9.0 Sample database.

    SELECT * FROM employee
WHERE state = 'GA'

    The result set includes a list of all employees who live in Georgia.

  2. In Interactive SQL, choose Data > Export.

  3. In the Export dialog, type a file name, choose a file type, and a destination.

  4. Click OK.

    The result set is exported to a file in the location that you specified.


Using the OUTPUT statement to export data

Use the OUTPUT statement to export query results, tables, or views from your database.

The OUTPUT statement is useful when compatibility is an issue because it can write out the result set of a SELECT statement in several different file formats. You can either specify the default output format, or you can specify the file format on each OUTPUT statement. Interactive SQL can execute a command file containing multiple OUTPUT statements.

Consider using the Interactive SQL OUTPUT statement when:

  • You want to export all or part of a table or view in a format other than text.

  • You want to automate the export process using a command file.

Impact on the database

If you have a choice between using the OUTPUT statement, UNLOAD statement, or UNLOAD TABLE statement, choose the UNLOAD TABLE statement for performance reasons.

There are performance impacts associated with exporting large amounts of data with the OUTPUT statement. Use the OUTPUT statement on the same machine as the server if possible to avoid sending large amounts of data across the network.

For more information, see OUTPUT statement [Interactive SQL].

Example

The following example exports the data from the employee table in the sample database to a .TXT file named employee.txt.

SELECT *
FROM employee;
OUTPUT TO employee.txt
FORMAT ASCII


Using the UNLOAD TABLE statement

The UNLOAD TABLE statements lets you export data only, in an efficient manner in text/ASCII/FIXED formats. The UNLOAD TABLE statement exports with one row per line, and values separated by a comma delimiter. The data exports in order by primary key values to make reloading quicker.

You execute the UNLOAD TABLE statement from the SQL Statements pane of the Interactive SQL window.

Consider using the UNLOAD TABLE statement when:

  • You want to export entire tables in text format.

  • You are concerned about database performance.

Impact on the database

The UNLOAD TABLE statement places an exclusive lock on the whole table while you are unloading it.

If you have a choice between using the OUTPUT statement, UNLOAD statement, or UNLOAD TABLE statement, choose the UNLOAD TABLE statement for performance reasons.

For more information, see UNLOAD TABLE statement.

Example

Using the ASA 9.0 sample database, you can unload the employee table to a text file named emp_test.txt by executing the following command:

UNLOAD TABLE employee TO 'c:\emp_test.txt'


Using the UNLOAD statement

The UNLOAD statement is similar to the OUTPUT statement in that they both export query results to a file. The UNLOAD statement, however, allows you to export data in a more efficient manner and in text/ASCII/FIXED formats only. The UNLOAD statement exports with one row per line, with values separated by a comma delimiter.

Consider using the UNLOAD statement to unload data when:

  • You want to export query results if performance is an issue.

  • You want output in text format.

  • You want to embed an export command in an application.

Impact on the database

If you have a choice between using the OUTPUT statement, UNLOAD statement, or UNLOAD TABLE statement, choose the UNLOAD TABLE statement for performance reasons.

To use the UNLOAD statement, the user must have ALTER or SELECT permission on the table. For more information about controlling who can use the UNLOAD statement, see -gl server option.

The UNLOAD statement is executed at the current isolation level.

When unloading and reloading a database that has proxy tables, you must create an external login to map the local user to the remote user, even if the user has the same password on both the local and remote databases. If you do not have an external login, the reload may fail because you cannot connect to the remote server.

For more information, see UNLOAD statement.


Using the dbunload utility to export data

The dbunload utility lets you export one, many, or all of the tables in the database. You can export table data as well as table schema. If you want to rearrange your tables in the database, you can also use the dbunload utility to create the necessary command files and modify them as needed. You can unload tables with structure only, data only, or with both structure and data.

You can also extract one or many tables with or without command files. These files can be used to create identical tables in different databases.

Note
The dbunload utility is functionally equivalent to Sybase Central, despite being graphically different. You can use either one interchangeably to produce the same results.

Consider using the dbunload utility when:

  • You want to export data in text format.

  • You need to process large amounts of data quickly.

  • Your file format requirements are flexible.

  • Your database needs to be rebuilt or extracted.

Impact on the database

Establish a connection before you attempt to unload fewer than all of the tables in a database.

For more information about the dbunload utility, see Unloading a database using the dbunload command-line utility.


Unload tools

You can use the following tools to help you unload data from your database:

  • Using the dbunload utility to export data

  • Using the Unload Database wizard

  • Using the Unload Data dialog


Using the Unload Database wizard

You can use the Unload Database wizard to unload an existing database into a new database.

You can use the Sybase Central Unload Database wizard to unload an entire database in ASCII comma-delimited format and to create the necessary Interactive SQL command files to completely recreate your database. This may be useful for creating SQL Remote extractions or building new copies of your database with the same or a slightly modified structure. The Unload Database wizard is useful for exporting Adaptive Server Anywhere files intended for reuse within Adaptive Server Anywhere.

Note
The Sybase Central Unload Database wizard and the dbunload utility are graphically different, and functionally equivalent. You can use them interchangeably to produce the same results.

Previous Next


Using the Unload Data dialog

You can use the Unload Data dialog to unload one or more tables in a database. This functionality is also available using the Unload Database wizard or the Unload utility (dbunload), but this dialog allows you to unload tables in one step instead of completing the entire Unload Database wizard.

toggle To unload tables using the Unload Data dialog

  1. Connect to your database in Sybase Central.

  2. In the left pane of Sybase Central, expand your database and then expand the Tables folder.

  3. In the right pane of Sybase Central, select the table you wish to export data from.

    You can select multiple tables by pressing Shift while you click the tables.

  4. Choose File > Unload Data.

    The Unload Data dialog appears.

  5. Select the desired options and then click OK to unload the data.


Exporting query results

You can export queries (including queries on views) to a file from Interactive SQL using the Data menu or the OUTPUT statement.

You can import and export files between Adaptive Server Anywhere and Adaptive Server Enterprise using the BCP FORMAT clause.

For more information, see Adaptive Server Enterprise compatibility.

toggle To export query results (Interactive SQL Data menu)

  1. Enter your query in the SQL Statements pane of the Interactive SQL window.

  2. Click Execute SQL statement(s) to display the result set.

  3. Choose Data > Export.

    The Save As dialog appears.

  4. Specify a name and location for the exported data.

  5. Specify the file format and click Save.

    If the export is successful, the Messages pane displays the amount of time it to took to export the query result set, the filename and path of the exported data, and the number of rows written.

    If the export is unsuccessful, a message appears indicating the export was unsuccessful.

toggle To export query results (Interactive SQL OUTPUT statement)

  1. Enter your query in the SQL Statements pane of the Interactive SQL window.

  2. At the end of the query, type OUTPUT TO 'c:\filename'.

    For example, to export the entire employee table to the file employee.dbf, enter the following query:

    SELECT *
FROM employee;
OUTPUT TO 'c:\employee.dbf'

  3. Do any of the following:

    To do this... Use this statement... Example...
    Export query results and append the results to another file... APPEND
    SELECT * FROM employee;
OUTPUT TO 'c:\employee.dbf'
APPEND
    Export query results and include messages... VERBOSE
    SELECT * FROM employee;
OUTPUT TO 'c:\employee.dbf'
VERBOSE
    Specify a file format other than ASCII (the default file format)... FORMAT
    SELECT * FROM employee;
OUTPUT TO 'c:\employee.dbf'
FORMAT dbaseiii;
    where c:\employee.dbf is the path, name, and extension of the new file and dbaseiii is the file format for this file. You can enclose the string in single or double quotation marks, but they are only required if the path contains embedded spaces.

    If you leave the FORMAT option out, the file type defaults to ASCII.

  4. Execute the statement.

    If the export is successful, the Messages pane displays the amount of time it to took to export the query result set, the filename and path of the exported data, and the number of rows written. If the export is unsuccessful, a message appears indicating the export was unsuccessful.

    For more information about exporting query results using the OUTPUT statement, see OUTPUT statement [Interactive SQL].

Tips
You can combine the APPEND and VERBOSE statements to append both results and messages to an existing file. For example, type OUTPUT TO 'filename.sql' APPEND VERBOSE. For more information about APPEND and VERBOSE, see the OUTPUT statement [Interactive SQL].

The OUTPUT TO, APPEND, and VERBOSE statements are equivalent to the >#, >>#, >&, and >>& operators of earlier versions of Interactive SQL. You can still use these operators to redirect data, but the new Interactive SQL statements allow for more precise output and easier to read code.

toggle To export query results (UNLOAD statement)

  1. In the SQL Statements pane of the Interactive SQL window, enter the UNLOAD statement. For example,

    UNLOAD
SELECT *
FROM employee;
TO 'c:\employee.dbf'

  2. Execute the UNLOAD statement.

    If the export is successful, the Messages pane displays the amount of time it to took to export the query result set, the filename and path of the exported data, and the number of rows written.

    If the export is unsuccessful, a message appears indicating the export was unsuccessful.


Exporting databases

toggle To unload all or part of a database (Sybase Central)

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

    All of the operations you can perform on a database appear in the right pane.

  3. Double-click Unload Database in the right pane.

    The Unload Database wizard appears.

    You can also open the Unload Database wizard by right-clicking the database in the left pane, and choosing Unload Database from the popup menu, or by choosing the Tools > Adaptive Server Anywhere 9 > Unload Database command.

  4. Follow the instructions in the wizard.

toggle To unload all or part of a database (Command line)

  1. At a command prompt, enter the dbunload command and specify connection parameters using the –c option.

    For example, the following command unloads the entire database to c:\temp:

    dbunload -c "dbn=asademo;uid=DBA;pwd=SQL" c:\temp

  2. Do either of the following:

    • To export data only, use -d. For example:

      dbunload -c "dbn=asademo;uid=DBA;pwd=SQL" –d c:\temp

    • To export a schema only, use -n. For example:

      dbunload -c "dbn=asademo;uid=DBA;pwd=SQL" –n c:\temp

For more information, see Unloading a database using the dbunload command-line utility.


Outputting NULLs

If you want to extract data for use in other software products. Because the other software package may not understand NULL values, there are two ways of specifying how NULL values are output:

  • the Interactive SQL NULLS option—lets you set the default behavior or change the output value for a particular session

  • the IFNULL function—lets you apply the output value to a particular instance or query

Both options allow you to output a specific value in place of a NULL value. Specifying how NULL values are output provides for greater compatibility with other software packages.

toggle To specify NULL value output (Interactive SQL)

  1. From the Interactive SQL window, choose Tools > Options to display the Options dialog.

  2. Click the Results tab.

  3. In the Display Null Values As field, type the value you want to replace NULL values with.

  4. Do one of the following:

    • Click Make Permanent—makes the changes become the default

    • Click OK—puts the changes in effect only for the current session

For more information on setting Interactive SQL options, see SET OPTION statement.


Exporting tables

In addition to the methods described in the sections that follow, you can also export a table by selecting all the data in a table and exporting the query results.

For more information, see Exporting query results.

Tip
You can export views just as you would export tables.
toggle To export a table (Command line)

  • At a command prompt, enter the following dbunload command and press Enter:

    dbunload -c "dbn=asademo;uid=DBA;pwd=SQL" –t employee c:\temp

    where –c specifies the database connection parameters and –t specifies the name of the table(s) you want to export. This dbunload command unloads the data from the sample database (assumed to be running on the default database server with the default database name) into a set of files in the c:\temp directory. A command file to rebuild the database from the data files is created with the default name reload.sql in the current directory.

    You can unload more than one table by separating the table names with a comma (,) delimiter.

toggle To export a table (SQL)

  • Execute an UNLOAD TABLE statement. For example,

    UNLOAD TABLE department
TO 'dept.txt'

    This statement unloads the department table from the sample database into the file dept.txt in the server's current working directory. If you are running against a network server, the command unloads the data into a file on the server machine, not the client machine. Also, the file name passes to the server as a string. Using escape backslash characters in the file name prevents misinterpretation if a directory of file name begins with an n (\n is a newline character) or any other special characters.

    Each row of the table is output on a single line of the output file, and no column names are exported. The columns are separated, or delimited, by a comma. The delimiter character can be changed using the DELIMITED BY clause. The fields are not fixed-width fields. Only the characters in each entry are exported, not the full width of the column.

For more information about the UNLOAD TABLE statement syntax, see UNLOAD TABLE statement.


Rebuilding databases

Rebuilding a database is a specific type of import and export involving unloading and reloading your entire database. The rebuild (load/unload) and extract procedures are used to rebuild databases and to create new databases from part of an old one. Rebuilding your database takes all the information out of your database and puts it back in, in a uniform fashion, thus filling space and improving performance much like defragmenting your disk drive.

Consider rebuilding your database when you want to improve database performance, reclaim fragmented disk space, or upgrade your database to a newer version of Adaptive Server Anywhere.

You can carry out rebuilding your database from Sybase Central or by using the dbunload command line utility.

Note
It is good practice to make backups of your database before rebuilding. For information, see Introduction to backup and recovery.
From one Adaptive Server Anywhere database to another

Rebuilding generally takes data out of an Adaptive Server Anywhere database and then places that data back into an Adaptive Server Anywhere database. The unloading and reloading are closely tied together since you usually perform both tasks, rather than just one or the other.

Rebuilding versus exporting

Rebuilding is different from exporting in that rebuilding exports and imports table definitions and schema in addition to the data. The unload portion of the rebuild process produces ASCII format data files and a reload.sql file which contains table and other definitions. Running the reload.sql script recreates the tables and loads the data into them.

Consider extracting a database (creating a new database from an old database) if you are using SQL Remote or MobiLink. For more information about extracting a database, see Extracting databases.

Rebuilding replicating databases

The procedure for rebuilding a database depends on whether the database is involved in replication or not. If the database is involved in replication, you must preserve the transaction log offsets across the operation, as the Message Agent and Replication Agent require this information. If the database is not involved in replication, the process is simpler.

Reasons to rebuild databases
Rebuild considerations
Rebuild and reload tools
Exporting table data or table schema
Reloading a database
Minimizing downtime during rebuilding


Reasons to rebuild databases

There are several reasons to consider rebuilding your database. You might rebuild your database if you want to:

  • Upgrade your database file format Some new features are made available by applying the Upgrade utility, but others require a database file format upgrade, which is carried out by unloading and reloading the database. The New Features documentation will state if an unload and reload is required to obtain a particular feature.

    New versions of the Adaptive Server Anywhere database server can be used without upgrading your database. If you want to use features of the new version that require access to new system tables or database options, you must use the upgrade utility to upgrade your database. The upgrade utility does not unload or reload any data.

    If you want to use features of the new version that rely on changes in the database file format, you must unload and reload your database. You should back up your database after rebuilding the database. For more information about upgrading your database, see Upgrading Adaptive Server Anywhere.

  • Reclaim disk space Databases do not shrink if you delete data. Instead, any empty pages are simply marked as free so they can be used again. They are not removed from the database unless you rebuild it. Rebuilding a database can reclaim disk space if you have deleted a large amount of data from your database and do not anticipate adding more.

  • Improve database performance Rebuilding databases can improve performance for the following reasons:

    • If data on pages within the database is fragmented, unloading and reloading can eliminate the fragmentation.

      Note
      If you need to defragment your database, and a full rebuild is not possible due to requirements for continuous access to the database, consider reorganizing the table instead of rebuilding.

      For more information about reorganizing tables, see the REORGANIZE TABLE statement.

    • Since the data can be unloaded and reloaded in order by primary keys, access to related information can be faster, as related rows may appear on the same or adjacent pages.


Rebuild considerations

The rebuild (load and unload) and extract procedures are used to rebuild databases and to create new databases from part of an old one. Before rebuilding a database, you should consider how to go about the process.

Consider this factor... | For information, see...
What is involved in rebuilding a database | Rebuilding databases Reasons to rebuild databases
The available tools for rebuilding | Rebuild and reload tools
The impact that rebuilding has on the database's performance |
The impact that rebuilding has on the database users | Minimizing downtime during rebuilding
Whether or not the database is involved in replication | Rebuilding databases involved in replication Rebuilding databases not involved in replication
Whether or not the database contains proxy tables | Rebuilding databases with proxy tables


Rebuilding databases not involved in replication

The following procedures should be used only if your database is not involved in replication.

For instructions about rebuilding a database not involved in replication from Sybase Central, see Upgrading the database file format.

toggle To rebuild a database not involved in replication (Command line)

  1. At a command prompt, execute the dbunload command line utility using one of the following options:

    To do this... Use this option... Example
    Rebuild to a new database... -an
    dbunload -c
"dbf=asademo.db;uid=DBA;pwd=SQL"
   -an  asacopy.db
    Reload to an existing database... -ac
    dbunload -c
"dbf=asademo.db;uid=DBA;pwd=SQL"
   -ac "uid=DBA;pwd=SQL;dbf=newdemo.db"
    Replace an existing database... -ar
    dbunload -c
"dbf=asademo.db;uid=DBA;pwd=SQL"
   -ar "uid=DBA;pwd=SQL;dbf=newdemo.db"

    If you use one these options, no interim copy of the data is created on disk, so you do not specify an unload directory on the command line. This provides greater security for your data. The -ar and -an options should also execute more quickly than Sybase Central, but -ac is slower.

  2. Shut down the database and archive the transaction log before using the reloaded database.

Notes

The -an and -ar options only apply to connections to a personal server, or connections to a network server over shared memory.

There are additional options available for the dbunload utility that allow you to tune the unload, as well as connection parameter options that allow you to specify a running or non-running database and database parameters.


Rebuilding databases involved in replication

If a database is participating in replication, particular care needs to be taken if you want to rebuild the database. Replication is based on the offsets in the transaction log. When you rebuild a database, the offsets in the old transaction log are different than the offsets in the new log, making the old log unavailable. For this reason, good backup practices are especially important when participating in replication.

There are two ways of rebuilding a database involved in replication. The first method uses the dbunload utility -ar option to make the unload and reload occur in a way that does not interfere with replication. The second method is a manual method of accomplishing the same task.

With importing and exporting, the destination of the data is either into your database or out of your database. Importing reads data into your database. Exporting writes data out of your database. Often the information is either coming from or going to another non-Adaptive Server Anywhere database.

Rebuilding, however, combines two functions: loading and unloading. Loading and unloading takes data and schema out of an Adaptive Anywhere database and then places the data and schema back into an Adaptive Server Anywhere database. The unloading procedure produces fixed format data files and a reload.sql file which contains table definitions required to recreate the table exactly. Running the reload.sql script recreates the tables and loads the data back into them.

Rebuilding a database can be a time consuming operation, and can require a large amount of disk space. As well, the database is unavailable for use while being unloaded and reloaded. For these reasons, rebuilding a database is not advised in a production environment unless you have a definite goal in mind.

toggle To rebuild a database involved in replication (dbunload utility)

  1. Shut down the database.

  2. Perform a full off-line backup by copying the database and transaction log files to a secure location.

  3. At a command prompt, run dbunload to rebuild the database:

    dbunload -c connection_string -ar directory

    where connection_string is a connection with DBA authority, directory is the directory used in your replication environment for old transaction logs, and there are no other connections to the database.

    The -ar option only applies to connections to a personal server, or connections to a network server over shared memory.

    For more information, see Unload utility options.

  4. Shut down the new database. Perform validity checks that you would usually perform after restoring a database.

  5. Start the database using any production options you need. You can now allow user access to the reloaded database.

Notes

There are additional options available for the dbunload utility that allow you to tune the unload, as well as connection parameter options that allow you to specify a running or non-running database and database parameters.

If the above procedure does not meet your needs, you can manually adjust the transaction log offsets. The following procedure describes how to carry out that operation.

toggle To rebuild a database involved in replication, with manual intervention

  1. Shut down the database.

  2. Perform a full off-line backup by copying the database and transaction log files to a secure location.

  3. Run the dbtran utility to display the starting offset and ending offset of the database's current transaction log file. Note the ending offset for later use.

  4. Rename the current transaction log file so that it is not modified during the unload process, and place this file in the dbremote off-line logs directory.

  5. Rebuild the database.

    For information on this step, see Rebuilding databases.

  6. Shut down the new database.

  7. Erase the current transaction log file for the new database.

  8. Use dblog on the new database with the ending offset noted in step 3 as the -z parameter, and also set the relative offset to zero.

    dblog -x 0 -z 137829 database-name.db

  9. When you run the Message Agent, provide it with the location of the original off-line directory on its command line.

  10. Start the database. You can now allow user access to the reloaded database.


Rebuilding databases with proxy tables

When unloading and reloading a database that has proxy tables, you must create an external login to map the local user to the remote user, even if the user has the same password on both the local and remote databases. If you do not have an external login, the reload may fail because you cannot connect to the remote server.

For more information about external logins, see Working with external logins.


Rebuild and reload tools

There are a variety of tools to help you rebuild a database. There are also some tools to help you reload data into an existing database.


Using the dbunload and dbisql utilities to rebuild databases

The dbunload and dbisqlutilities let you unload an entire database in ASCII comma-delimited format and to create the necessary Interactive SQL command files to completely recreate your database. This may be useful for creating SQL Remote extractions or building new copies of your database with the same or a slightly modified structure. These utilities are useful for exporting Adaptive Server Anywhere files intended for reuse within Adaptive Server Anywhere.

Note
The dbunload/dbisql utilities and the Sybase Central Unload Database wizard are graphically different, but functionally equivalent. You can use them interchangeably to produce the same results.

Consider using the dbunload or dbisql utility when:

  • You want to rebuild your database or extract data from your database.

  • You want to export in text format.

  • You need to process large amounts of data quickly.

  • Your file format requirements are flexible.

For more information, see Rebuilding databases not involved in replication, Rebuilding databases involved in replication, and Unloading a database using the Unload Database wizard.


Using the UNLOAD TABLE statement to rebuild databases

The UNLOAD TABLE statement lets you export data only, in an efficient manner in text/ASCII/FIXED formats. The UNLOAD TABLE statement exports with one row per line, with values separated by a comma delimiter. To make reloading quicker, the data exports in order by primary key values.

Consider using the UNLOAD TABLE statement to rebuild databases when:

  • Performance is an issue.

  • You want to export data in text format.

Impact on the database

The UNLOAD TABLE statement places an exclusive lock on the entire table.

To use the UNLOAD TABLE statement, the user must have ALTER or SELECT permission on the table.

For more information, see UNLOAD TABLE statement.


Exporting table data or table schema

toggle To export table data or table schema (Command line)

  1. At a command prompt, enter the dbunload command and specify connection parameters using the –c option.

  2. Specify the table(s) you want to export data or schema for, using the –t option.

    For example, to export part of the employee table, enter

    dbunload -c "dbn=asademo;uid=DBA;pwd=SQL" –t employee c:\temp

    You can unload more than one table by separating the table names with a comma delimiter.

  3. Do either of the following:

    To do this... Add this option... Example...
    Export data only... -d
    dbunload -c
"dbn=asademo;uid=DBA;pwd=SQL"
 –d –t employee c:\temp
    Export schemas only... -n
    dbunload -c
"dbn=asademo;uid=DBA;pwd=SQL"
 –n –t employee c:\temp

  4. Press Enter to execute the command.

    The dbunload commands in these examples unload the data or schema from the sample database table (assumed to be running on the default database server with the default database name) into a file in the c:\temp directory. A command file to rebuild the database from the data files is created with the default name reload.sql in the current directory.


Reloading a database

Reloading involves creating an empty database file and using the reload.sql file to create the schema and then inserting all the data unloaded from another Adaptive Server Anywhere database into the newly created tables. You reload databases from the command line.

toggle To reload a database (Command line)

  1. Open a command prompt.

  2. Execute the reload.sql script.

    For example, the following command loads the reload.sql script in the current directory.

    dbisql -c "dbn=asademo;uid=DBA;pwd=SQL" reload.sql


Minimizing downtime during rebuilding

The following steps help you rebuild a database while minimizing downtime. This can be especially useful if your database is in operation 24 hours a day.

It is wise to do a practice run of steps 1-4, and determine the times required for each step, prior to beginning the actual backup. You may also want to save copies of your files at various points during the rebuild.

Make sure that no other scheduled backups rename the production database's log. If this happens in error, you will need to apply the transactions from these renamed logs to the rebuilt database in the correct order.

toggle To minimize the downtime during a rebuild

  1. Using DBBACKUP -r, create a backup of the database and log, and rename the log.

  2. Rebuild the backed up database on another machine.

  3. Do another DBBACKUP -r on the production server to rename the log.

  4. Run DBTRAN on the log from step 3 and apply the transactions to the rebuilt server.

    You now have a rebuilt database that contains all transactions up to the end of the backup in step 3.

  5. Shut down the production server and make copies of the database and log.

  6. Copy the rebuilt database onto the production server.

  7. Run DBTRAN on the log from step 5.

    This should be a relatively small file.

  8. Start the server on the rebuilt database, but don't allow users to connect.

  9. Apply the transactions from step 8.

  10. Allow users to connect.


Extracting databases

Extracting removes a remote Adaptive Server Anywhere database from a consolidated Adaptive Server Enterprise or Adaptive Server Anywhere database.

You can use the Sybase Central Extract Database wizard or the Extraction utility to extract databases. The Extraction utility is the recommended way of creating and synchronizing remote databases from a consolidated database.

For more information about how to perform database extractions, see:

  • The Database Extraction utility

  • Using the extraction utility

  • Extraction utility options

  • Extracting groups

  • Deploying remote databases

  • Extracting a remote database in Sybase Central


Migrating databases to Adaptive Server Anywhere

You can import tables from remote Oracle, DB2, Microsoft SQL Server, Sybase Adaptive Server Enterprise, Adaptive Server Anywhere, and Microsoft Access databases into Adaptive Server Anywhere using the sa_migrate set of stored procedures or the Data Migration wizard.


Using the Data Migration wizard

Before you can migrate data using the Data Migration wizard, or the sa_migrate set of stored procedures, you must first create a target database. The target database is the database into which data is migrated.

For information about creating a database, see Creating a database.

You can create a remote server to connect to the remote database, as well as an external login (if required) to connect the current user to the remote database using the Data Migration wizard.

toggle To import remote tables (Sybase Central)

  1. From Sybase Central, connect to the target database.

  2. In the left pane, select the Adaptive Server Anywhere plug-in.

  3. In the right pane, click the Utilities tab.

    All the operations you can perform on a database appear in the right pane.

  4. Double-click Migrate Database.

    The Database Migration wizard appears.

    You can also open the Database Migration wizard by right-clicking the target database in the left pane and choosing Migrate Database from the popup menu, or by choosing Tools > Adaptive Server Anywhere 9 > Migrate Database.

  5. Select the target database from the list, and then click Next.

  6. Select the remote server you want to use to connect to the remote database from which you want to migrate data, and then click Next.

    If you have not already created a remote server, click Create Remote Server Now to open the Remote Server Creation wizard.

    For more information about creating a remote server, see Creating remote servers.

    You can also create an external login for the remote server. By default, Adaptive Server Anywhere uses the user ID and password of the current user when it connects to a remote server on behalf of that user. However, if the remote server does not have a user defined with the same user ID and password as the current user, you must create an external login. The external login assigns an alternate login name and password for the current user so that user can connect to the remote server.

  7. Select the tables that you want to migrate, and then click Next.

    You cannot migrate system tables, so no system tables appear in this list.

  8. Select the user that will own the tables on the target database, and then click Next.

    If you have not already created a user, click Create User Now to open the User Creation wizard.

  9. Select whether you want to migrate the data and/or the foreign keys from the remote tables and whether you want to keep the proxy tables that are created for the migration process, and then click Next.

    If the target database is version 8.0.0 or earlier, the Migrate the foreign keys option is not enabled. You must upgrade the database to version 8.0.1 or later to use this option.

    For more information about upgrading, see Upgrading a database.

  10. Click Finish.


Using the sa_migrate stored procedures

The sa_migrate stored procedures can allow you to migrate remote data. If you do not want to modify the tables in any way, you can use the single step method. Alternatively, if you would like to remove tables or foreign key mappings, you can use the extended method.

When using the sa_migrate set of stored procedures, you must complete the following steps before you can import a remote database:

  • Create a target database.

    For information about creating a database, see Creating a database.

  • Create a remote server to connect to the remote database.

    For information about creating a remote server, see Creating remote servers.

  • Create an external login to connect to the remote database. This is only required when the user has different passwords on the target and remote databases, or when you want to login using a different user ID on the remote database than the one you are using on the target database.

    For information about creating an external login, see Creating external logins.

  • Create a local user who will own the migrated tables in the target database.

    For information about creating a user, see Creating new users.

The following example uses the sa_migrate stored procedure to import all the tables that belong to one owner on the remote database in one step.

Migrating a database in one step using sa_migrate

Supplying NULL for both the table_name and owner_name parameters migrates all the tables in the database, including system tables. As well, tables that have the same name, but different owners, in the remote database all belong to one owner in the target database. For these reasons, it is recommended that you migrate tables associated with one owner at a time.

toggle To import remote tables (single step)

  1. From Interactive SQL, connect to the target database.

  2. In the Interactive SQL Statements pane, run the sa_migrate stored procedure. For example,

    CALL sa_migrate( 'local_a', 'ase', NULL, l_smith, NULL, 1, 1, 1 )

    This procedure calls several procedures in turn and migrates all the remote tables belonging to the user l_smith using the specified criteria.

If you do not want all the migrated tables to be owned by the same user on the target database, you must run the sa_migrate procedure for each owner on the target database, specifying the local_table_owner and owner_name arguments. It is recommended that you migrate tables associated with one owner at a time.

For more information, see sa_migrate system procedure.

For target databases that are version 8.0.0 or earlier, foreign keys are migrated automatically. If you do not want to migrate the foreign keys, you must upgrade the database file format to version 8.0.1 or later.

For more information about upgrading, see Upgrading a database.

Migrating individual tables using the sa_migrate stored procedures
toggle To import remote tables (with modifications)

  1. From Interactive SQL, connect to the target database.

  2. Run the sa_migrate_create_remote_table_list stored procedure. For example,

    CALL sa_migrate_create_remote_table_list( 'ase',
     NULL, 'remote_a', 'mydb' )

    You must specify a database name for Adaptive Server Enterprise and Microsoft SQL Server databases.

    This populates the dbo.migrate_remote_table_list table with a list of remote tables to migrate. You can delete rows from this table for remote tables you do not wish to migrate.

    Do not supply NULL for both the table_name and owner_name parameters. Doing so migrates all the tables in the database, including system tables. As well, tables that have the same name but different owners in the remote database all belong to one owner in the target database. It is recommended that you migrate tables associated with one owner at a time.

    For more information about the sa_migrate_create_remote_table_list stored procedure, see sa_migrate_create_remote_table_list system procedure.

  3. Run the sa_migrate_create_tables stored procedure. For example,

    CALL sa_migrate_create_tables( 'local_a', )

    This procedure takes the list of remote tables from dbo.migrate_remote_table_list and creates a proxy table and a base table for each remote table listed. This procedure also creates all primary key indexes for the migrated tables.

    For more information about the sa_migrate_create_tables stored procedure, see sa_migrate_create_tables system procedure.

  4. If you want to migrate the data from the remote tables into the base tables on the target database, run the sa_migrate_data stored procedure. For example,

    Enter the following stored procedure:

    CALL sa_migrate_data( 'local_a' )

    This procedure migrates the data from each remote table into the base table created by the sa_migrate_create_tables procedure.

    For more information about the sa_migrate_data stored procedure, see sa_migrate_data system procedure.

    If you do not want to migrate the foreign keys from the remote database, you can skip to step 7.

  5. Run the sa_migrate_create_remote_fks_list stored procedure. For example,

    CALL sa_migrate_create_remote_fks_list( 'ase' )

    This procedure populates the table dbo.migrate_remote_fks_list with the list of foreign keys associated with each of the remote tables listed in dbo.migrate_remote_table_list.

    You can remove any foreign key mappings you do not want to recreate on the local base tables.

    For more information about the sa_migrate_create_remote_fks_list stored procedure, see sa_migrate_create_remote_fks_list system procedure.

  6. Run the sa_migrate_create_fks stored procedure. For example,

    CALL sa_migrate_create_fks( 'local_a' )

    This procedure creates the foreign key mappings defined in dbo.migrate_remote_fks_list on the base tables.

    For more information about the sa_migrate_create_fks stored procedure, see sa_migrate_create_fks system procedure.

  7. If you want to drop the proxy tables that were created for migration purposes, run the sa_drop_proxy_tables stored procedure. For example,

    CALL sa_migrate_drop_proxy_tables( 'local_a' )

    This procedure drops all proxy tables created for migration purposes and completes the migration process.

    For more information about the sa_migrate_drop_proxy_tables stored procedure, see sa_migrate_drop_proxy_tables system procedure.


Using SQL command files

This section describes how to process files consisting of a set of commands. Command files are text files that contain SQL statements and are useful if you want to run the same SQL statements repeatedly.

Creating command files

You can use any text editor that you like to create command files. You can include comment lines along with the SQL statements to be executed. Command files are also commonly called scripts.

Opening SQL command files in Interactive SQL

On Windows platforms you can make Interactive SQL the default editor for .sql files so that you can double-click the file and it appears in the SQL Statements pane of Interactive SQL.

For more information about making Interactive SQL the default editor for .sql files, see Options dialog: General tab.

Executing SQL command files

You can execute command files in any of the following ways:

  • You can use the Interactive SQL READ command to execute command files. For example, the following statement executes the file temp.sql:

    READ temp.sql

    For more information, see READ statement [Interactive SQL].

  • You can load a command file into the SQL Statements pane and execute it directly from there.

    You load command files back into the SQL Statements pane by choosing File > Open. Enter temp.sql when prompted for the file name.

  • You can supply a command file as a command-line argument for Interactive SQL.


Running SQL command files

Running SQL command files

You can run command files interactively or in batch mode.

toggle To run a command file immediately

  1. In Interactive SQL, choose File > Run Script.

  2. In the Open dialog, find and select the file. Click Open when finished.

    The Run Script menu item is the equivalent of a READ statement. For example, in the SQL Statements pane, you can also run a command file by typing:

    READ 'c:\filename.sql'

    where c:\filename.sql is the path, name, and extension of the file. Single quotation marks (as shown) are required only if the path contains spaces.

toggle To run a command file using the SQL Statements pane

  • Type the following command:

    READ 'c:\filename.sql'

    where c:\filename.sql is the path, name, and extension of the file. Single quotation marks (as shown) are required only if the path contains spaces.

toggle To run a command file in batch mode

  1. Open a command prompt.

  2. Supply a command file as a command-line argument for Interactive SQL.

    For example, the following command runs the command file myscript.sql against the sample database.

    dbisql -c "dsn= ASA 9.0 Sample" myscript.sql
Loading SQL command files

When you begin a new Interactive SQL session, you can load the contents of a command file into the SQL Statements pane, or you can run the contents immediately.

toggle To load commands from a file into the SQL Statements pane

  1. Choose File > Open.

  2. In the Open dialog, find and select the file.

  3. Click Open when finished.


Writing database output to a file

In Interactive SQL, the result set data for each command remains on the Results tab in the Results pane only until the next command is executed. To keep a record of your data, you can save the output of each statement to a separate file. If statement1 and statement2 are two SELECT statements, then you can output them to file1 and file2, respectively, as follows:

statement1; OUTPUT TO file1;
statement2; OUTPUT TO file2;

For example, the following command saves the result of a query to a file named Employees.txt:

SELECT * FROM EMPLOYEE;
OUTPUT TO 'C:\\My Documents\\Employees.txt'

For more information, see OUTPUT statement [Interactive SQL].


Adaptive Server Enterprise compatibility

You can import and export files between Adaptive Server Anywhere and Adaptive Server Enterprise using the BCP FORMAT clause. Simply make sure the BCP output is in delimited ASCII format. If you are exporting BLOB data from Adaptive Server Anywhere for use in Adaptive Server Enterprise, use the BCP format clause with the UNLOAD TABLE statement.

For more information about BCP and the FORMAT clause, see LOAD TABLE statement or UNLOAD TABLE statement.


Accessing Remote Data

About this chapter

Adaptive Server Anywhere can access data located on different servers, both Sybase and non-Sybase, as if the data were stored on the local server.

This chapter describes how to configure Adaptive Server Anywhere to access remote data.

Introduction
Basic concepts to access remote data
Working with remote servers
Working with external logins
Working with proxy tables
Joining remote tables
Joining tables from multiple local databases
Sending native statements to remote servers
Using remote procedure calls (RPCs)
Transaction management and remote data
Internal operations
Troubleshooting remote data access


Introduction

Adaptive Server Anywhere remote data access give you access to data in other data sources. You can use this feature to migrate data into an Adaptive Server Anywhere database. You can also use the feature to query data across databases, although performance for such multi-database queries is much slower than when all the data is in a single Adaptive Server Anywhere database.

With remote data access you can:

  • Use Adaptive Server Anywhere to move data from one location to another using insert-select.

  • Access data in relational databases such as Sybase, Oracle, and DB2.

  • Access desktop data such as Excel spreadsheets, MS-Access databases, FoxPro, and text files.

  • Access any other data source that supports an ODBC interface.

  • Perform joins between local and remote data, although performance is much slower than if all the data is in a single Adaptive Server Anywhere database.

  • Perform joins between tables in separate Adaptive Server Anywhere databases. Performance limitations here are the same as with other remote data sources.

  • Use Adaptive Server Anywhere features on data sources that would normally not have that ability. For instance, you could use a Java function against data stored in Oracle, or perform a subquery on spreadsheets. Adaptive Server Anywhere compensates for features not supported by a remote data source by operating on the data after it is retrieved.

  • Access remote servers directly using passthrough mode.

  • Execute remote procedure calls to other servers.

Adaptive Server Anywhere allows access to the following external data sources:

  • Adaptive Server Anywhere

  • Adaptive Server Enterprise

  • Oracle

  • IBM DB2

  • Microsoft SQL Server

  • Other ODBC data sources

For platform availability, see Windows and NetWare operating systems.

Accessing remote data from PowerBuilder DataWindows


Accessing remote data from PowerBuilder DataWindows

You can access remote data from a PowerBuilder DataWindow by setting the DBParm Block parameter to 1 on connect.

  • In the design environment, you can set the Block parameter by accessing the Transaction tab in the Database Profile Setup dialog and setting the Retrieve Blocking Factor to 1.

  • In a connection string, use the following phrase:

    DBParm="Block=1"


Basic concepts to access remote data

This section describes the basic concepts required to access remote data.


Remote table mappings

Adaptive Server Anywhere presents tables to a client application as if all the data in the tables were stored in the database to which the application is connected. Internally, when a query involving remote tables is executed, the storage location is determined, and the remote location is accessed so that data can be retrieved.

To have remote tables appear as local tables to the client, you create local proxy tables that map to the remote data.

toggle To create a proxy table

  1. Define the server where the remote data is located. This specifies the type of server and location of the remote server.

    For more information, see Working with remote servers.

  2. Map the local user login information to the remote server user login information if the logins on the two servers are different.

    For more information, see Working with external logins.

  3. Create the proxy table definition. This specifies the mapping of a local proxy table to the remote table. This includes the server where the remote table is located, the database name, owner name, table name, and column names of the remote table.

For more information, see Working with proxy tables.

Administering remote table mappings

To manage remote table mappings and remote server definitions, you can use Sybase Central or you can use a tool such as Interactive SQL and execute the SQL statements directly.


Server classes

A server class is assigned to each remote server. The server class specifies the access method used to interact with the server. Different types of remote servers require different access methods. The server classes provide Adaptive Server Anywhere detailed server capability information. Adaptive Server Anywhere adjusts its interaction with the remote server based on those capabilities.

There are currently two groups of server classes. The first is JDBC-based; the second is ODBC-based.

The JDBC-based server classes are:

  • asajdbc for Adaptive Server Anywhere (version 6 and later)

  • asejdbc for Adaptive Server Enterprise and SQL Server (version 10 and later)

The ODBC-based server classes are:

  • asaodbc for Adaptive Server Anywhere (version 5.5 and later)

  • aseodbc for Adaptive Server Enterprise and SQL Server (version 10 and later)

  • db2odbc for IBM DB2

  • mssodbc for Microsoft SQL Server

  • oraodbc for Oracle servers (version 8.0 and later)

  • odbc for all other ODBC data sources

For a full description of remote server classes, see Server Classes for Remote Data Access.


Working with remote servers

Before you can map remote objects to a local proxy table, you must define the remote server where the remote object is located. When you define a remote server, an entry is added to the SYSSERVERS table for the remote server. This section describes how to create, alter, and delete a remote server definition.


Creating remote servers

Use the CREATE SERVER statement to set up remote server definitions. You can execute the statements directly, or use Sybase Central.

For ODBC connections, each remote server corresponds to an ODBC data source. For some systems, including Adaptive Server Anywhere, each data source describes a database, so a separate remote server definition is needed for each database.

You must have RESOURCE authority to create a server.

On UNIX platforms, you need to reference the ODBC driver manager as well.

For a full description of the CREATE SERVER statement, see CREATE SERVER statement.

Example 1

The following statement creates an entry in the SYSSERVERS table for the Adaptive Server Enterprise server called ASEserver:

CREATE SERVER ASEserver
CLASS 'ASEJDBC'
USING 'rimu:6666'

where:

  • ASEserver is the name of the remote server

  • ASEJDBC is a keyword indicating that the server is Adaptive Server Enterprise and the connection to it is JDBC-based

  • rimu:6666 is the machine name and the TCP/IP port number where the remote server is located

Example 2

The following statement creates an entry in the SYSSERVERS table for the ODBC-based Adaptive Server Anywhere server named testasa:

CREATE SERVER testasa
CLASS 'ASAODBC'
USING 'test4'

where:

  • testasa is the name by which the remote server is known within this database.

  • ASAODBC is a keyword indicating that the server is Adaptive Server Anywhere and the connection to it uses ODBC.

  • test4 is the ODBC data source name.

Example 3

On Unix platforms, the following statement creates an entry in the SYSSERVERS table for the ODBC-based Adaptive Server Anywhere server named remasa:

CREATE SERVER remasa
CLASS 'asaodbc'
USING 'driver=/opt/sybase/SYBSsa9/lib/dbodbc9_r.so;dsn=my_asa_dsn'

where:

  • remasa is the name by which the remote server is known within this database.

  • ASAODBC is a keyword indicating that the server is Adaptive Server Anywhere and the connection to it uses ODBC.

  • USING is the reference to the ODBC driver manager.

Example 4

On Unix platforms the following statement creates an entry in the sysservers table for the ODBC-based Adaptive Server Enterprise server named remase:

CREATE SERVER remase
CLASS 'aseodbc'
USING 'driver=/opt/sybase/SYBSsa9/drivers/lib/libodbc.so;dsn=my_ase_dsn'

where:

  • remase is the name by which the remote server is known within this database

  • ASEODBC is a keyword indicating that the server is Adaptive Server Enterprise and the connection to it uses ODBC

  • USING is thereference to the ODBC driver manager.

Creating remote servers using Sybase Central


Creating remote servers using Sybase Central

You can create a remote server using a wizard in Sybase Central. For more information, see Creating remote servers.

toggle To create a remote server (Sybase Central)

  1. Connect to the host database from Sybase Central.

  2. Open the Remote Servers folder for that database.

  3. From the File menu, choose New > Remote Server.

    The Remote Server Creation wizard appears.

  4. On the first page of the wizard, enter a name to use for the remote server. This name simply refers to the remote server from within the local database; it does not need to correspond with the name the server supplies. Click Next.

  5. Select an appropriate type of server and then click Next.

  6. Select a data access method (ODBC or JDBC), and supply connection information. Click Next.

    • For ODBC, supply a data source name.

    • For JDBC, supply a URL in the form machine-name:port-number

    The data access method (JDBC or ODBC) is the method used by Adaptive Server Anywhere to access the remote database. This is not related to the method used by Sybase Central to connect to your database.

  7. Specify whether you want the remote server to be read-only. Click Next.

  8. Create an external login for the remote server.

    By default, Adaptive Server Anywhere uses the user ID and password of the current user when it connects to a remote server on behalf of that user. However, if the remote server does not have a user defined with the same user ID and password as the current user, you must create an external login. The external login assigns an alternate login name and password for the current user so that user can connect to the remote server.

  9. Optionally, you can click Test Connection to test whether you can connect to the remote server before the remote server definition is created.

    Click Finish to create the remote server definition.


Deleting remote servers

You can use Sybase Central or a DROP SERVER statement to delete a remote server from the Adaptive Server Anywhere system tables. All remote tables defined on that server must already be dropped for this action to succeed.

You must have DBA authority to delete a remote server.

toggle To delete a remote server (Sybase Central)

  1. Connect to the host database from Sybase Central.

  2. Open the Remote Servers folder.

  3. Right-click the remote server you want to delete and choose Delete from the popup menu.

toggle To delete a remote server (SQL)

  1. Connect to the host database from Interactive SQL.

  2. Execute a DROP SERVER statement.

For more information, see DROP SERVER statement.

Example

The following statement drops the server named testasa:

DROP SERVER testasa


Altering remote servers

You can use Sybase Central or an ALTER SERVER statement to modify the attributes of a server. These changes do not take effect until the next connection to the remote server.

You must have RESOURCE authority to alter a server.

toggle To alter the properties of a remote server (Sybase Central)

  1. Connect to the host database from Sybase Central.

  2. Open the Remote Servers folder for that database.

  3. Right-click the remote server and choose Properties from the popup menu.

  4. Configure the various remote server properties.

toggle To alter the properties of a remote server (SQL)

  1. Connect to the host database from Interactive SQL.

  2. Execute an ALTER SERVER statement.

Example

The following statement changes the server class of the server named ASEserver to aseodbc. In this example, the Data Source Name for the server is ASEserver.

ALTER SERVER ASEserver
CLASS 'aseodbc'

The ALTER SERVER statement can also be used to enable or disable a server's known capabilities.

For more information, see ALTER SERVER statement.


Listing the remote tables on a server

It may be helpful when you are configuring Adaptive Server Anywhere to get a list of the remote tables available on a particular server. The sp_remote_tables procedure returns a list of the tables on a server.

sp_remote_tables servername
                 [,tablename]
                 [, owner ]
                 [, database]

If tablename, owner, or database is given, the list of tables is limited to only those that match.

For example, to get a list of all of the Microsoft Excel worksheets available from a remote server named excel:

sp_remote_tables  excel

Or to get a list of all of the tables in the production database in an ASE named asetest, owned by 'fred':

sp_remote_tables  asetest, null, fred, production

For more information, see sp_remote_tables system procedure.


Listing remote server capabilities

The sp_servercaps procedure displays information about a remote server's capabilities. Adaptive Server Anywhere uses this capability information to determine how much of a SQL statement can be passed off to a remote server.

The system tables which contain server capabilities are not populated until after Adaptive Server Anywhere first connects to the remote server. This information comes from the SYSCAPABILITY and SYSCAPABILITYNAME system tables. The servername specified must be the same servername used in the CREATE SERVER statement.

Issue the stored procedure sp_servercaps as follows:

sp_servercaps  servername

For more information, see sp_servercaps system procedure.


Working with external logins

By default, Adaptive Server Anywhere uses the names and passwords of its clients whenever it connects to a remote server on behalf of those clients. However, this default can be overridden by creating external logins. External logins are alternate login names and passwords to be used when communicating with a remote server.

For more information, see Using integrated logins.


Creating external logins

You can create an external login using either Sybase Central or the CREATE EXTERNLOGIN statement.

Only the login-name and the DBA account can add or modify an external login.

toggle To create an external login (Sybase Central)

  1. Connect to the host database from Sybase Central.

  2. Open the Remote Servers folder for that database and select the remote server.

  3. From the File menu, choose New > External Login.

    The External Login Creation wizard appears.

  4. Follow the instructions in the wizard.

toggle To create an external login (SQL)

  1. Connect to the host database from Interactive SQL.

  2. Execute a CREATE EXTERNLOGIN statement.

Example

The following statement allows the local user fred to gain access to the server ASEserver, using the remote login frederick with password banana.

CREATE EXTERNLOGIN fred
TO ASEserver
REMOTE LOGIN frederick
IDENTIFIED BY banana

For more information, see CREATE EXTERNLOGIN statement.


Dropping external logins

You can use either Sybase Central or a DROP EXTERNLOGIN statement to delete an external login from the Adaptive Server Anywhere system tables.

Only the login-name and the DBA account can delete an external login.

toggle To delete an external login (Sybase Central)

  1. Connect to the host database from Sybase Central.

  2. Open the Remote Servers folder.

  3. In the left pane, select the remote server and then click the External Logins tab in the right pane.

  4. Right-click the external login and choose Delete from the popup menu.

toggle To delete an external login (SQL)

  1. Connect to the host database from Interactive SQL.

  2. Execute a DROP EXTERNLOGIN statement.

Example

The following statement drops the external login for the local user fred created in the example above:

DROP EXTERNLOGIN fred TO ASEserver

See also

  • DROP EXTERNLOGIN statement


Working with proxy tables

Location transparency of remote data is enabled by creating a local proxy table that maps to the remote object. Use one of the following statements to create a proxy table:

  • If the table already exists at the remote storage location, use the CREATE EXISTING TABLE statement. This statement defines the proxy table for an existing table on the remote server.

  • If the table does not exist at the remote storage location, use the CREATE TABLE statement. This statement creates a new table on the remote server, and also defines the proxy table for that table.

Specifying proxy table locations
Creating proxy tables (Sybase Central)
Creating proxy tables with the CREATE EXISTING TABLE statement
Creating a proxy table with the CREATE TABLE statement
Listing the columns on a remote table


Specifying proxy table locations

The AT keyword is used with both CREATE TABLE and CREATE EXISTING TABLE to define the location of an existing object. This location string has four components, each separated by either a period or a semicolon. The semicolon delimiter allows filenames and extensions to be used in the database and owner fields.

The syntax of the AT clause is

... AT 'server.database.owner.table-name'

  • Server This is the name by which the server is known in the current database, as specified in the CREATE SERVER statement. This field is mandatory for all remote data sources.

  • Database The meaning of the database field depends on the data source. In some cases this field does not apply and should be left empty. The periods are still required, however.

    In Adaptive Server Enterprise, database specifies the database where the table exists. For example master or pubs2.

    In Adaptive Server Anywhere, this field does not apply; leave it empty.

    In Excel, Lotus Notes, and Access, you must include the name of the file containing the table. If the file name includes a period, use the semicolon delimiter.

  • Owner If the database supports the concept of ownership, this field represents the owner name. This field is only required when several owners have tables with the same name.

  • Table-name This specifies the name of the table. In the case of an Excel spreadsheet, this is the name of the "sheet" in the workbook. If the table name is left empty, the remote table name is assumed to be the same as the local proxy table name.

Examples:

The following examples illustrate the use of location strings:

  • Adaptive Server Anywhere:

'testasa..DBA.employee'

  • Adaptive Server Enterprise:

'ASEServer.pubs2.dbo.publishers'

  • Excel:

'excel;d:\pcdb\quarter3.xls;;sheet1$'

  • Access:

'access;\\server1\production\inventory.mdb;;parts'


Creating proxy tables (Sybase Central)

You can create a proxy table using either Sybase Central or a CREATE EXISTING TABLE statement. You cannot create proxy tables for system tables.

The CREATE EXISTING TABLE statement creates a proxy table that maps to an existing table on the remote server. Adaptive Server Anywhere derives the column attributes and index information from the object at the remote location.

For information about the CREATE EXISTING TABLE statement, see CREATE EXISTING TABLE statement.

toggle To create a proxy table (Sybase Central)

  1. Connect to the host database from Sybase Central.

  2. In the left pane, open the Remote Servers folder.

  3. In the right pane, click the Proxy Tables tab.

  4. From the File menu choose New > Proxy Table.

  5. Follow the instructions in the wizard.

Tip
Proxy tables are displayed in the right pane on the Proxy Tables tab when their remote server is selected in the left pane. They also appear in the Tables folder. They are distinguished from other tables by a letter P on their icon.

Previous Next


Creating proxy tables with the CREATE EXISTING TABLE statement

The CREATE EXISTING TABLE statement creates a proxy table that maps to an existing table on the remote server. Adaptive Server Anywhere derives the column attributes and index information from the object at the remote location.

toggle To create a proxy table with the CREATE EXISTING TABLE statement (SQL)

  1. Connect to the host database.

  2. Execute a CREATE EXISTING TABLE statement.

For more information, see the CREATE EXISTING TABLE statement.

Example 1

To create a proxy table called p_employee on the current server to a remote table named employee on the server named asademo1, use the following syntax:

CREATE EXISTING TABLE p_employee
AT 'asademo1..DBA.employee'
A proxy table called p_employee is on the local server, and is mapped to the employee table on the asademo1 server.
Example 2

The following statement maps the proxy table a1 to the Microsoft Access file mydbfile.mdb. In this example, the AT keyword uses the semicolon (;) as a delimiter. The server defined for Microsoft Access is named access.

CREATE EXISTING TABLE a1
AT'access;d:\mydbfile.mdb;;a1'


Creating a proxy table with the CREATE TABLE statement

The CREATE TABLE statement creates a new table on the remote server, and defines the proxy table for that table when you use the AT option. You enter the CREATE TABLE statement using Adaptive Server Anywhere data types. Adaptive Server Anywhere automatically converts the data into the remote server's native types.

If you use the CREATE TABLE statement to create both a local and remote table, and then subsequently use the DROP TABLE statement to drop the proxy table, then the remote table also gets dropped. You can, however, use the DROP TABLE statement to drop a proxy table created using the CREATE EXISTING TABLE statement if you do not want to drop the remote table.

For more information, see the CREATE TABLE statement.

toggle To create a proxy table with the CREATE EXISTING TABLE statement (SQL)

  1. Connect to the host database.

  2. Execute a CREATE TABLE statement.

For more information, see the CREATE TABLE statement.

Example

The following statement creates a table named employee on the remote server asademo1, and creates a proxy table named members that maps to the remote location:

CREATE TABLE members
( membership_id INTEGER NOT NULL,
member_name CHAR(30) NOT NULL,
office_held CHAR( 20 ) NULL)
AT 'asademo1..DBA.employee'


Listing the columns on a remote table

If you are entering a CREATE EXISTING statement and you are specifying a column list, it may be helpful to get a list of the columns that are available on a remote table. The sp_remote_columns system procedure produces a list of the columns on a remote table and a description of those data types.

sp_remote_columns servername, tablename [, owner ]
[, database]

If a table name, owner, or database name is given, the list of columns is limited to only those that match.

For example, the following returns a list of the columns in the sysobjects table in the production database on an Adaptive Server Enterprise server named asetest:

sp_remote_columns  asetest, sysobjects, null, production

For more information, see sp_remote_columns system procedure.


Joining remote tables

The following figure illustrates the remote Adaptive Server Anywhere tables employee and department in the sample database mapped to the local server named testasa.

The remote tables and proxy tables are mapped.

In real-world cases, you may use joins between tables on different Adaptive Server Anywhere databases. Here we describe a simple case using just one database to illustrate the principles.

toggle To perform a join between two remote tables (SQL)

  1. Create a new database named empty.db.

    This database holds no data. We will use it only to define the remote objects, and access the sample database from it.

  2. Start a database server running both empty.db and the sample database. You can do this using the following command line, executed from the installation directory:

    dbeng9 asademo empty

  3. Connect to empty.db from Interactive SQL using the user ID DBA and the password SQL.

  4. In the new database, create a remote server named testasa. Its server class is asaodbc, and the connection information is 'ASA 9.0 Sample':

    CREATE SERVER testasa
CLASS 'asaodbc'
USING 'ASA 9.0 Sample'

  5. In this example, we use the same user ID and password on the remote database as on the local database, so no external logins are needed.

  6. Define the employee proxy table:

    CREATE EXISTING TABLE employee
AT 'testasa..DBA.employee'

  7. Define the department proxy table:

    CREATE EXISTING TABLE department
AT 'testasa..DBA.department'

  8. Use the proxy tables in the SELECT statement to perform the join.

    SELECT emp_fname, emp_lname, dept_name
FROM employee JOIN department
ON employee.dept_id = department.dept_id
ORDER BY emp_lname


Joining tables from multiple local databases

An Adaptive Server Anywhere server may have several local databases running at one time. By defining tables in other local Adaptive Server Anywhere databases as remote tables, you can perform cross database joins.

For more information about specifying multiple databases, see USING parameter value in the CREATE SERVER statement.

Example

For example, if you are using database db1 and you want to access data in tables in database db2, you need to set up proxy table definitions that point to the tables in database db2. For instance, on an Adaptive Server Anywhere named testasa, you might have three databases available, db1, db2, and db3.

  • If using ODBC, create an ODBC data source name for each database you will be accessing.

  • Connect to one of the databases that you will be performing joins from. For example, connect to db1.

  • Perform a CREATE SERVER for each other local database you will be accessing. This sets up a loopback connection to your Adaptive Server Anywhere server.

    CREATE SERVER local_db2
CLASS 'asaodbc'
USING 'testasa_db2'
CREATE SERVER local_db3
CLASS 'asaodbc'
USING    'testasa_db3'

    Alternatively, using JDBC:

    CREATE SERVER local_db2
CLASS 'asajdbc'
USING 'mypc1:2638/db2'
CREATE SERVER local_db3
CLASS 'asajdbc'
USING 'mypc1:2638/db3'

  • Create proxy table definitions using CREATE EXISTING to the tables in the other databases you want to access.

    CREATE EXISTING TABLE employee
AT 'local_db2...employee'


Sending native statements to remote servers

Use the FORWARD TO statement to send one or more statements to the remote server in its native syntax. This statement can be used in two ways:

  • To send a statement to a remote server.

  • To place Adaptive Server Anywhere into passthrough mode for sending a series of statements to a remote server.

If a connection cannot be made to the specified server, a message is sent to the user explaining why. If a connection is made, any results are converted into a form that can be recognized by the client program.

The FORWARD TO statement can be used to verify that a server is configured correctly. If you send a statement to the remote server and Adaptive Server Anywhere does not return an error message, the remote server is configured correctly.

The FORWARD TO statement cannot be used within procedures or batches.

For more information, see FORWARD TO statement.

Example 1

The following statement verifies connectivity to the server named ASEserver by selecting the version string:

FORWARD TO ASEserver {SELECT @@version}
Example 2

The following statements show a passthrough session with the server named ASEserver:

FORWARD TO ASEserver
select * from titles
select * from authors
FORWARD TO


Using remote procedure calls (RPCs)

Adaptive Server Anywhere users can issue procedure calls to remote servers that support the feature.

This feature is supported by Sybase Adaptive Server Anywhere, Sybase Adaptive Server Enterprise, Oracle, and DB2. Issuing a remote procedure call is similar to using a local procedure call.


Creating remote procedures

You can issue a remote procedure call using either Sybase Central or the CREATE PROCEDURE statement.

You must have DBA authority to create a remote procedure.

toggle To issue a remote procedure call (Sybase Central)

  1. Connect to the host database from Sybase Central.

  2. Open the Remote Servers folder.

  3. In the left pane, select the remote server for which you want to create a remote procedure.

  4. In the right pane, click the Remote Procedures tab.

  5. From the File menu, choose New > Remote Procedure.

    The Remote Procedure Creation wizard appears.

  6. Follow the instructions in the wizard.

toggle To issue a remote procedure call (SQL)

  1. First define the procedure to Adaptive Server Anywhere.

    The syntax is the same as a local procedure definition except instead of using SQL statements to make up the body of the call, a location string is given defining the location where the procedure resides.

    CREATE PROCEDURE remotewho ()
AT 'bostonase.master.dbo.sp_who'

  2. Execute the procedure as follows:

    call remotewho()

For more information, see CREATE PROCEDURE statement.

Example

Here is an example with a parameter:

CREATE PROCEDURE remoteuser (IN uname char(30))
AT 'bostonase.master.dbo.sp_helpuser'
call remoteuser('joe')
Data types for remote procedures

The following data types are allowed for RPC parameters. Other data types are disallowed:

  • [ UNSIGNED ] SMALLINT

  • [ UNSIGNED ] INT

  • [ UNSIGNED ] BIGINT

  • TINYINT

  • REAL

  • DOUBLE

  • CHAR

  • BIT

NUMERIC and DECIMAL data types are allowed for IN parameters, but not for OUT or INOUT parameters.


Dropping remote procedures

You can delete a remote procedure using either Sybase Central or the DROP PROCEDURE statement.

You must have DBA authority to delete a remote procedure.

toggle To delete a remote procedure (Sybase Central)

  1. Open the Remote Servers folder.

  2. In the left pane, select the remote server.

  3. In the right pane, click the Remote Procedures tab.

  4. On the Remote Procedures tab, right-click the remote procedure and choose Delete from the popup menu.

toggle To delete a remote procedure (SQL)

  1. Connect to a database.

  2. Execute a DROP PROCEDURE statement.

For more information, see DROP statement.

Example

Delete a remote procedure called remoteproc.

DROP PROCEDURE remoteproc


Transaction management and remote data

Transactions provide a way to group SQL statements so that they are treated as a unit—either all work performed by the statements is committed to the database, or none of it is.

For the most part, transaction management with remote tables is the same as transaction management for local tables in Adaptive Server Anywhere, but there are some differences. They are discussed in the following section.

For a general discussion of transactions, see Using Transactions and Isolation Levels.


Remote transaction management overview

The method for managing transactions involving remote servers uses a two-phase commit protocol. Adaptive Server Anywhere implements a strategy that ensures transaction integrity for most scenarios. However, when more than one remote server is invoked in a transaction, there is still a chance that a distributed unit of work will be left in an undetermined state. Even though two-phase commit protocol is used, no recovery process is included.

The general logic for managing a user transaction is as follows:

  1. Adaptive Server Anywhere prefaces work to a remote server with a BEGIN TRANSACTION notification.

  2. When the transaction is ready to be committed, Adaptive Server Anywhere sends a PREPARE TRANSACTION notification to each remote server that has been part of the transaction. This ensures the that remote server is ready to commit the transaction.

  3. If a PREPARE TRANSACTION request fails, all remote servers are told to roll back the current transaction.

    If all PREPARE TRANSACTION requests are successful, the server sends a COMMIT TRANSACTION request to each remote server involved with the transaction.

Any statement preceded by BEGIN TRANSACTION can begin a transaction. Other statements are sent to a remote server to be executed as a single, remote unit of work.


Restrictions on transaction management

Restrictions on transaction management are as follows:

  • Savepoints are not propagated to remote servers.

  • If nested BEGIN TRANSACTION and COMMIT TRANSACTION statements are included in a transaction that involves remote servers, only the outermost set of statements is processed. The innermost set, containing the BEGIN TRANSACTION and COMMIT TRANSACTION statements, is not transmitted to remote servers.


Internal operations

This section describes the underlying operations on remote servers performed by Adaptive Server Anywhere on behalf of client applications.


Query parsing

When a statement is received from a client, it is parsed. An error is raised if the statement is not a valid Adaptive Server Anywhere SQL statement.


Query normalization

The next step is called query normalization. During this step, referenced objects are verified and some data type compatibility is checked.

For example, consider the following query:

SELECT *
FROM t1
WHERE c1 = 10

The query normalization stage verifies that table t1 with a column c1 exists in the system tables. It also verifies that the data type of column c1 is compatible with the value 10. If the column's data type is datetime, for example, this statement is rejected.


Query preprocessing

Query preprocessing prepares the query for optimization. It may change the representation of a statement so that the SQL statement Adaptive Server Anywhere generates for passing to a remote server will be syntactically different from the original statement.

Preprocessing performs view expansion so that a query can operate on tables referenced by the view. Expressions may be reordered and subqueries may be transformed to improve processing efficiency. For example, some subqueries may be converted into joins.


Server capabilities

The previous steps are performed on all queries, both local and remote.

The following steps depend on the type of SQL statement and the capabilities of the remote servers involved.

Each remote server defined to Adaptive Server Anywhere has a set of capabilities associated with it. These capabilities are stored in the syscapabilities system table. These capabilities are initialized during the first connection to a remote server. The generic server class odbc relies strictly on information returned from the ODBC driver to determine these capabilities. Other server classes such as db2odbc have more detailed knowledge of the capabilities of a remote server type and use that knowledge to supplement what is returned from the driver.

Once syscapabilities is initialized for a server, the capability information is retrieved only from the system table. This allows a user to alter the known capabilities of a server.

Since a remote server may not support all of the features of a given SQL statement, Adaptive Server Anywhere must break the statement into simpler components to the point that the query can be given to the remote server. SQL features not passed off to a remote server must be evaluated by Adaptive Server Anywhere itself.

For example, a query may contain an ORDER BY statement. If a remote server cannot perform ORDER BY, the statement is sent to the remote server without it and Adaptive Server Anywhere performs the ORDER BY on the result returned, before returning the result to the user. The result is that the user can employ the full range of Adaptive Server Anywhere supported SQL without concern for the features of a particular back end.


Complete passthrough of the statement

The most efficient way to handle a statement is usually to hand as much of the original statement as possible off to the remote server involved. Adaptive Server Anywhere will attempt to pass off as much of the statement as is possible. In many cases this will be the complete statement as originally given to Adaptive Server Anywhere.

Adaptive Server Anywhere will hand off the complete statement when:

  • Every table in the statement resides in the same remote server.

  • The remote server is capable of processing all of the syntax in the statement.

In rare conditions, it may actually be more efficient to let Adaptive Server Anywhere do some of the work instead of passing it off. For example, Adaptive Server Anywhere may have a better sorting algorithm. In this case you may consider altering the capabilities of a remote server using the ALTER SERVER statement.

For more information, see ALTER SERVER statement.


Partial passthrough of the statement

If a statement contains references to multiple servers, or uses SQL features not supported by a remote server, the query is decomposed into simpler parts.

Select

SELECT statements are broken down by removing portions that cannot be passed on and letting Adaptive Server Anywhere perform the feature. For example, let's say a remote server can not process the atan2() function in the following statement:

select a,b,c where atan2(b,10) > 3 and c = 10

The statement sent to the remote server would be converted to:

select a,b,c where c = 10

Locally, Adaptive Server Anywhere would apply "where atan2(b,10) > 3" to the intermediate result set.

Joins

When two tables are joined, one table is selected to be the outer table. The outer table is scanned based on the WHERE conditions that apply to it. For every qualifying row found, the other table, known as the inner table is scanned to find a row that matches the join condition.

This same algorithm is used when remote tables are referenced. Since the cost of searching a remote table is usually much higher than a local table (due to network I/O), every effort is made to make the remote table the outermost table in the join.

Update and delete

If Adaptive Server Anywhere cannot pass off an UPDATE or DELETE statement entirely to a remote server, it must change the statement into a table scan containing as much of the original WHERE clause as possible, followed by positioned UPDATE or DELETE "where current of cursor" when a qualifying row is found.

For example, when the function atan2 is not supported by a remote server:

UPDATE t1
SET a = atan2(b, 10)
WHERE b > 5

Would be converted to the following:

SELECT a,b
FROM t1
WHERE  b > 5

Each time a row is found, Adaptive Server Anywhere would calculate the new value of a and issue:

UPDATE t1
SET a = 'new value'
WHERE CURRENT OF CURSOR

If a already has a value that equals the "new value", a positioned UPDATE would not be necessary and would not be sent remotely.

In order to process an UPDATE or DELETE that requires a table scan, the remote data source must support the ability to perform a positioned UPDATE or DELETE ("where current of cursor"). Some data sources do not support this capability.

Temporary tables cannot be updated
In this release of Adaptive Server Anywhere, an UPDATE or DELETE cannot be performed if an intermediate temporary table is required in Adaptive Server Anywhere. This occurs in queries with ORDER BY and some queries with subqueries.

Previous Next


Troubleshooting remote data access

This section provides some hints for troubleshooting remote servers.

Features not supported for remote data
Case sensitivity
Connectivity problems
General problems with queries
Queries blocked on themselves
Managing remote data access connections


Features not supported for remote data

The following Adaptive Server Anywhere features are not supported on remote data. Attempts to use these features will therefore run into problems:

  • ALTER TABLE statement against remote tables

  • Triggers defined on proxy tables will not fire

  • SQL Remote

  • Foreign keys that refer to remote tables are ignored

  • The READTEXT, WRITETEXT, and TEXTPTR functions.

  • Positioned UPDATE and DELETE

  • UPDATE and DELETE requiring an intermediate temporary table.

  • Backwards scrolling on cursors opened against remote data. Fetch statements must be NEXT or RELATIVE 1.

  • If a column on a remote table has a name that is a keyword on the remote server, you cannot access data in that column. Adaptive Server Anywhere cannot know all of the remote server reserved words. You can execute a CREATE EXISTING TABLE statement, and import the definition but you cannot select that column.


Case sensitivity

The case sensitivity setting of your Adaptive Server Anywhere database should match the settings used by any remote servers accessed.

Adaptive Server Anywhere databases are created case insensitive by default. With this configuration, unpredictable results may occur when selecting from a case sensitive database. Different results will occur depending on whether ORDER BY or string comparisons are pushed off to a remote server or evaluated by the local Adaptive Server Anywhere.


Connectivity problems

Take the following steps to be sure you can connect to a remote server:

  • Determine that you can connect to a remote server using a client tool such as Interactive SQL before configuring Adaptive Server Anywhere.

  • Perform a simple passthrough statement to a remote server to check your connectivity and remote login configuration. For example:

    FORWARD TO testasa {SELECT @@version}

  • Turn on remote tracing for a trace of the interactions with remote servers.

    SET OPTION CIS_OPTION = 7

    Once you have turned on remote tracing, the tracing information appears in the database server window. You can log this output to a file by specifying the - o filename server option when you start the database server.

    For more information about the CIS_OPTION option, see CIS_OPTION option [database].

    For more information about the -o server option, see -o server option.


General problems with queries

If you are faced with some type of problem with the way Adaptive Server Anywhere is handling a query against a remote table, it is usually helpful to understand how Adaptive Server Anywhere is executing that query. You can display remote tracing, as well as a description of the query execution plan:

SET OPTION CIS_OPTION = 7

For more information about using the CIS_OPTION option for debugging queries when using remote data access, see CIS_OPTION option [database].

Once you have turned on remote tracing, the tracing information appears in the database server window. You can log this output to a file by specifying the - o filename server option when you start the database server.

For more information about the -o server option, see -o server option.


Queries blocked on themselves

If you access multiple databases on a single Adaptive Server Anywhere server, you may need to increase the number of threads used by the database server on Windows using the -gx command-line switch.

You must have enough threads available to support the individual tasks that are being run by a query. Failure to provide the number of required tasks can lead to a query becoming blocked on itself.


Managing remote data access connections

If you access remote databases via ODBC, the connection to the remote server is given a name. The name can be used to drop the connection as one way to cancel a remote request.

The connections are named ASACIS_conn-name, where conn-name is the connection ID of the local connection. The connection ID can be obtained from the sa_conn_info stored procedure.


Server Classes for Remote Data Access

About this chapter

This chapter describes how Adaptive Server Anywhere interfaces with different classes of servers. It describes

  • Types of servers that each server class supports

  • The USING clause value for the CREATE SERVER statement for each server class

  • Special configuration requirements


Overview

The server class you specify in the CREATE SERVER statement determines the behavior of a remote connection. The server classes give Adaptive Server Anywhere detailed server capability information. Adaptive Server Anywhere formats SQL statements specific to a server's capabilities.

There are two categories of server classes:

  • JDBC-based server classes

  • ODBC-based server classes

Each server class has a set of unique characteristics that database administrators and programmers need to know to configure the server for remote data access.

When using this chapter, refer both to the section generic to the server class category (JDBC-based or ODBC-based), and to the section specific to the individual server class.


JDBC-based server classes

JDBC-based server classes are used when Adaptive Server Anywhere internally uses a Java virtual machine and jConnect 4.0 to connect to the remote server. The JDBC-based server classes are:

  • asajdbc Adaptive Server Anywhere (version 6 and later).

  • asejdbc Adaptive Server Enterprise and SQL Server (version 10 and later).

If you are using NetWare, only the asajdbc class is supported.


Configuration notes for JDBC classes

When you access remote servers defined with JDBC-based classes, consider that:

  • Your local database must be enabled for Java.

    For more information, see Java-enabling a database.

  • The Java virtual machine needs more than the default amount of memory to load and run jConnect. Set these memory options to at least the following values:

    SET OPTION PUBLIC.JAVA_NAMESPACE_SIZE = 3000000
SET OPTION PUBLIC.JAVA_HEAP_SIZE = 1000000

  • Since jConnect 4.0 is automatically installed with Adaptive Server Anywhere, no additional drivers need to be installed.

  • For optimum performance, Sybase recommends an ODBC-based class (asaodbc or aseodbc).

  • Any remote server that you access using the asejdbc or asajdbc server class must be set up to handle a jConnect 4.x based client. The jConnect setup scripts are SQL_anywhere.sql for Adaptive Server Anywhere or sql_server.sql for Adaptive Server Enterprise. Run these against any remote server you will be using.


Server class asajdbc

A server with server class asajdbc is Adaptive Server Anywhere (version 6 and later). No special requirements exist for the configuration of an Adaptive Server Anywhere data source.

USING parameter value in the CREATE SERVER statement


USING parameter value in the CREATE SERVER statement

You must perform a separate CREATE SERVER for each Adaptive Server Anywhere database you intend to access. For example, if an Adaptive Server Anywhere server named testasa is running on the machine 'banana' and owns three databases (db1, db2, db3), you would configure the local Adaptive Server Anywhere similar to this:

CREATE SERVER testasadb1
CLASS 'asajdbc'
USING 'banana:2638/db1'
CREATE SERVER testasadb2
CLASS 'asajdbc'
USING 'banana:2638/db2'
CREATE SERVER testasadb2
CLASS 'asajdbc'
USING 'banana:2638/db3'

If you do not specify a /databasename value, the remote connection uses the remote Adaptive Server Anywhere default database.

For more information about the CREATE SERVER statement, see CREATE SERVER statement.


Server class asejdbc

A server with server class asejdbc is Adaptive Server Enterprise, SQL Server (version 10 and later). No special requirements exist for the configuration of an Adaptive Server Enterprise data source.

Data type conversions: JDBC and Adaptive Server Enterprise


Data type conversions: JDBC and Adaptive Server Enterprise

When you issue a CREATE TABLE statement, Adaptive Server Anywhere automatically converts the data types to the corresponding Adaptive Server Enterprise data types. The following table describes the Adaptive Server Anywhere to Adaptive Server Enterprise data type conversions.

Adaptive Server Anywhere data type | ASE default data type
bit | bit
tinyint | tinyint
smallint | smallint
int | int
integer | integer
decimal [defaults p=30, s=6] | numeric(30,6)
decimal(128,128) | not supported
numeric [defaults p=30 s=6] | numeric(30,6)
numeric(128,128) | not supported
float | real
real | real
double | float
smallmoney | numeric(10,4)
money | numeric(19,4)
date | datetime
time | datetime
timestamp | datetime
smalldatetime | datetime
datetime | datetime
char(n) | varchar(n)
character(n) | varchar(n)
varchar(n) | varchar(n)
character varying(n) | varchar(n)
long varchar | text
text | text
binary(n) | binary(n)
long binary | image
image | image
bigint | numeric(20,0)


ODBC-based server classes

The ODBC-based server classes include:

  • asaodbc

  • aseodbc

  • db2odbc

  • mssodbc

  • oraodbc

  • odbc

Defining ODBC external servers
Server class asaodbc
Server class aseodbc
Server class db2odbc
Server class oraodbc
Server class mssodbc
Server class odbc


Defining ODBC external servers

The most common way of defining an ODBC-based server bases it on an ODBC data source. To do this, you must create a data source in the ODBC Administrator.

Once you have the data source defined, the USING clause in the CREATE SERVER statement should match the ODBC data source name.

For example, to configure a DB2 server named mydb2 whose Data Source Name is also mydb2, use:

CREATE SERVER mydb2
CLASS 'db2odbc'
USING 'mydb2'

For more information on creating data sources, see Creating an ODBC data source.

Using connection strings instead of data sources

An alternative, which avoids using data sources, is to supply a connection string in the USING clause of the CREATE SERVER statement. To do this, you must know the connection parameters for the ODBC driver you are using. For example, a connection to an ASA may be as follows:

CREATE SERVER testasa
CLASS 'asaodbc'
USING 'driver=adaptive server anywhere 9.0;eng=testasa;dbn=sample;links=tcpip{}'

This defines a connection to an Adaptive Server Anywhere database server named testasa, database sample, and using the TCP-IP protocol.

See also

For information specific to particular ODBC server classes, see:

  • Server class asaodbc

  • Server class aseodbc

  • Server class db2odbc

  • Server class oraodbc

  • Server class mssodbc

  • Server class odbc


Server class asaodbc

A server with server class asaodbc is Adaptive Server Anywhere version 5.5 or later. No special requirements exist for the configuration of an Adaptive Server Anywhere data source.

To access Adaptive Server Anywhere servers that support multiple databases, create an ODBC data source name defining a connection to each database. Issue a CREATE SERVER statement for each of these ODBC data source names.


Server class aseodbc

A server with server class aseodbc is Adaptive Server Enterprise, SQL Server (version 10 and later). Adaptive Server Anywhere requires the installation of the Adaptive Server Enterprise ODBC driver and Open Client connectivity libraries to connect to a remote Adaptive Server with class aseodbc. However, the performance is better than with the asejdbc class.

Notes

  • Open Client should be version 11.1.1, EBF 7886 or above. Install Open Client and verify connectivity to the Adaptive Server before you install ODBC and configure Adaptive Server Anywhere. The Sybase ODBC driver should be version 11.1.1, EBF 7911 or above.

  • Configure a User Data Source in the Configuration Manager with the following attributes:

    • Under the General tab:

      Enter any value for Data Source Name. This value is used in the USING clause of the CREATE SERVER statement.

      The server name should match the name of the server in the Sybase interfaces file.

    • Under the Advanced tab, check the Application Using Threads box and check the Enable Quoted Identifiers box.

    • Under the Connection tab:

      Set the charset field to match your Adaptive Server Anywhere character set.

      Set the language field to your preferred language for error messages.

    • Under the Performance tab:

      Set Prepare Method to "2-Full."

      Set Fetch Array Size as large as possible for best performance. This increases memory requirements since this is the number of rows that must be cached in memory. Sybase recommends using a value of 100.

      Set Select Method to "0-Cursor."

      Set Packet Size to as large as possible. Sybase recommends using a value of -1.

      Set Connection Cache to 1.

Data type conversions: ODBC and Adaptive Server Enterprise


Data type conversions: ODBC and Adaptive Server Enterprise

When you issue a CREATE TABLE statement, Adaptive Server Anywhere automatically converts the data types to the corresponding Adaptive Server Enterprise data types. The following table describes the Adaptive Server Anywhere to Adaptive Server Enterprise data type conversions.

Adaptive Server Anywhere data type | Adaptive Server Enterprise default data type
Bit | bit
Tinyint | tinyint
Smallint | smallint
Int | int
Integer | integer
decimal [defaults p=30, s=6] | numeric(30,6)
decimal(128,128) | not supported
numeric [defaults p=30 s=6] | numeric(30,6)
numeric(128,128) | not supported
Float | real
Real | real
Double | float
Smallmoney | numeric(10,4)
Money | numeric(19,4)
Date | datetime
Time | datetime
Timestamp | datetime
Smalldatetime | datetime
Datetime | datetime
char(n) | varchar(n)
Character(n) | varchar(n)
varchar(n) | varchar(n)
Character varying(n) | varchar(n)
long varchar | text
Text | text
binary(n) | binary(n)
long binary | image
Image | image
Bigint | numeric(20,0)


Server class db2odbc

A server with server class db2odbc is IBM DB2

Notes

  • Sybase certifies the use of IBM's DB2 Connect version 5, with fix pack WR09044. Configure and test your ODBC configuration using the instructions for that product. Adaptive Server Anywhere has no specific requirements on configuration of DB2 data sources.

  • The following is an example of a CREATE EXISTING TABLE statement for a DB2 server with an ODBC data source named mydb2:

    CREATE EXISTING TABLE ibmcol
AT 'mydb2..sysibm.syscolumns'

Data type conversions: DB2


Data type conversions: DB2

When you issue a CREATE TABLE statement, Adaptive Server Anywhere automatically converts the data types to the corresponding DB2 data types. The following table describes the Adaptive Server Anywhere to DB2 data type conversions.

Adaptive Server Anywhere data type | DB2 default data type
Bit | smallint
Tinyint | smallint
Smallint | smallint
Int | int
Integer | int
Bigint | decimal(20,0)
char(1–254) | varchar(n)
char(255–4000) | varchar(n)
char(4001–32767) | long varchar
Character(1–254) | varchar(n)
Character(255–4000) | varchar(n)
Character(4001–32767) | long varchar
varchar(1–4000) | varchar(n)
varchar(4001–32767) | long varchar
Character varying(1–4000) | varchar(n)
Character varying(4001–32767) | long varchar
long varchar | long varchar
text | long varchar
binary(1–4000) | varchar for bit data
binary(4001–32767) | long varchar for bit data
long binary | long varchar for bit data
image | long varchar for bit data
decimal [defaults p=30, s=6] | decimal(30,6)
numeric [defaults p=30 s=6] | decimal(30,6)
decimal(128, 128) | NOT SUPPORTED
numeric(128, 128) | NOT SUPPORTED
real | real
float | float
double | float
smallmoney | decimal(10,4)
money | decimal(19,4)
date | date
time | time
smalldatetime | timestamp
datetime | timestamp
timestamp | timestamp


Server class oraodbc

A server with server class oraodbc is Oracle version 8.0 or later.

Notes

  • Sybase certifies the use of version 8.0.03 of Oracle's ODBC driver. Configure and test your ODBC configuration using the instructions for that product.

  • The following is an example of a CREATE EXISTING TABLE statement for an Oracle server named myora:

    CREATE EXISTING TABLE employees
AT 'myora.database.owner.employees'

  • Due to Oracle ODBC driver restrictions, you cannot issue a CREATE EXISTING TABLE for system tables. A message returns stating that the table or columns cannot be found.

Data type conversions: Oracle


Data type conversions: Oracle

When you issue a CREATE TABLE statement, Adaptive Server Anywhere automatically converts the data types to the corresponding Oracle data types. The following table describes the Adaptive Server Anywhere to Oracle data type conversions.

Adaptive Server Anywhere data type | Oracle data type
bit | number(1,0)
tinyint | number(3,0)
smallint | number(5,0)
int | number(11,0)
bigint | number(20,0)
decimal(prec, scale) | number(prec, scale)
numeric(prec, scale) | number(prec, scale)
float | float
real | real
smallmoney | numeric(13,4)
money | number(19,4)
date | date
time | date
timestamp | date
smalldatetime | date
datetime | date
char(n) | if (n > 255) long else varchar(n)
varchar(n) | if (n > 2000) long else varchar(n)
long varchar | long or clob
binary(n) | if (n > 255) long raw else raw(n)
varbinary(n) | if (n > 255) long raw else raw(n)
long binary | long raw


Server class mssodbc

A server with server class mssodbc is Microsoft SQL Server version 6.5, Service Pack 4.

Notes

  • Sybase certifies the use of version 3.60.0319 of Microsoft SQL Server's ODBC driver (included in MDAC 2.0 release). Configure and test your ODBC configuration using the instructions for that product.

  • The following is an example of a CREATE EXISTING TABLE statement for a Microsoft SQL Server named mymssql:

    CREATE EXISTING TABLE accounts,
AT 'mymssql.database.owner.accounts'

Data type conversions: Microsoft SQL Server


Data type conversions: Microsoft SQL Server

When you issue a CREATE TABLE statement, Adaptive Server Anywhere automatically converts the data types to the corresponding Microsoft SQL Server data types. The following table describes the Adaptive Server Anywhere to Microsoft SQL Server data type conversions.

Adaptive Server Anywhere data type | Microsoft SQL Server default data type
bit | bit
tinyint | tinyint
smallint | smallint
int | int
bigint | numeric(20,0)
decimal [defaults p=30, s=6] | decimal(prec, scale)
numeric [defaults p=30 s=6] | numeric(prec, scale)
float | if (prec) float(prec) else float
real | real
smallmoney | smallmoney
money | money
date | datetime
time | datetime
timestamp | datetime
smalldatetime | datetime
datetime | datetime
char(n) | if (length > 255) text else varchar(length)
character(n) | char(n)
varchar(n) | if (length > 255) text else varchar(length)
long varchar | text
binary(n) | if (length > 255) image else binary(length)
long binary | image
double | float
uniqueidentifierstr | uniqueidentifier

The SQL Server uniqueidentifier columns is mapped to an Adaptive Server Anywhere uniqueidentifierstr column. The resulting string can be converted to a binary UUID value using the STRTOUUID function. See STRTOUUID function [String].


Server class odbc

ODBC data sources that do not have their own server class use server class odbc. You can use any ODBC driver that complies with ODBC version 2.0 compliance level 1 or higher. Sybase certifies the following ODBC data sources:

  • Microsoft Excel (Microsoft 3.51.171300)

  • Microsoft Access (Microsoft 3.51.171300)

  • Microsoft FoxPro (Microsoft 3.51.171300)

  • Lotus Notes SQL 2.0

The latest versions of Microsoft ODBC drivers can be obtained through the Microsoft Data Access Components (MDAC) distribution found at [external link] http://msdn.microsoft.com/data/downloads/default.aspx. The Microsoft driver versions listed below are part of MDAC 2.0.

The following sections provide notes on accessing these data sources.


Microsoft Excel (Microsoft 3.51.171300)

With Excel, each Excel workbook is logically considered to be a database holding several tables. Tables are mapped to sheets in a workbook. When you configure an ODBC data source name in the ODBC driver manager, you specify a default workbook name associated with that data source. However, when you issue a CREATE TABLE statement, you can override the default and specify a workbook name in the location string. This allows you to use a single ODBC DSN to access all of your excel workbooks.

In this example, an ODBC data source named excel was created. To create a workbook named work1.xls with a sheet (table) called mywork:

CREATE TABLE mywork (a int, b char(20))
AT 'excel;d:\work1.xls;;mywork'

To create a second sheet (or table) execute a statement such as:

CREATE TABLE mywork2 (x float, y int)
AT 'excel;d:\work1.xls;;mywork2'

You can import existing worksheets into Adaptive Server Anywhere using CREATE EXISTING, under the assumption that the first row of your spreadsheet contains column names.

CREATE EXISTING TABLE mywork
AT'excel;d:\work1;;mywork'

If Adaptive Server Anywhere reports that the table is not found, you may need to explicitly state the column and row range you wish to map to. For example:

CREATE EXISTING TABLE mywork
AT 'excel;d:\work1;;mywork$'

Adding the $ to the sheet name indicates that the entire worksheet should be selected.

Note in the location string specified by AT that a semicolon is used instead of a period for field separators. This is because periods occur in the file names. Excel does not support the owner name field so leave this blank.

Deletes are not supported. Also some updates may not be possible since the Excel driver does not support positioned updates.


Microsoft Access (Microsoft 3.51.171300)

Access databases are stored in a .mdb file. Using the ODBC manager, create an ODBC data source and map it to one of these files. A new .mdb file can be created through the ODBC manager. This database file becomes the default if you don't specify a different default when you create a table through Adaptive Server Anywhere.

Assuming an ODBC data source named access.

CREATE TABLE tab1 (a int, b char(10))
AT 'access...tab1'

or

CREATE TABLE tab1 (a int, b char(10))
AT 'access;d:\pcdb\data.mdb;;tab1'

or

CREATE EXISTING TABLE tab1
AT 'access;d:\pcdb\data.mdb;;tab1'

Access does not support the owner name qualification; leave it empty.


Microsoft FoxPro (Microsoft 3.51.171300)

You can store FoxPro tables together inside a single FoxPro database file (.dbc), or, you can store each table in its own separate .dbf file. When using .dbf files, be sure the file name is filled into the location string; otherwise the directory that Adaptive Server Anywhere was started in is used.

CREATE TABLE fox1 (a int, b char(20))
AT 'foxpro;d:\pcdb;;fox1'

This statement creates a file named d:\pcdb\fox1.dbf when you choose the "free table directory" option in the ODBC Driver Manager.


Lotus Notes SQL 2.0

You can obtain this driver (version 2.04.0203) from the [external link] Lotus Web site. Read the documentation that comes with it for an explanation of how Notes data maps to relational tables. You can easily map Adaptive Server Anywhere tables to Notes forms.

Here is how to set up Adaptive Server Anywhere to access the Address sample file.

  • Create an ODBC data source using the NotesSQL driver. The database will be the sample names file: c:\notes\data\names.nsf. The Map Special Characters option should be turned on. For this example, the Data Source Name is my_notes_dsn.

  • Create a server in Adaptive Server Anywhere:

    CREATE SERVER names
CLASS 'odbc'
USING 'my_notes_dsn'

  • Map the Person form into an Adaptive Server Anywhere table:

    CREATE EXISTING TABLE Person
AT 'names...Person'

  • Query the table

    SELECT * FROM Person
Avoiding password prompts

Lotus Notes does not support sending a user name and password through the ODBC API. If you try to access Lotus notes using a password protected ID, a window appears on the machine where Adaptive Server Anywhere is running, and prompts you for a password. Avoid this behavior in multi-user server environments.

To access Lotus Notes unattended, without ever receiving a password prompt, you must use a non-password-protected ID. You can remove password protection from your ID by clearing it (File > Tools > User ID > Clear Password), unless your Domino administrator required a password when your ID was created. In this case, you will not be able to clear it.


Using Procedures, Triggers, and Batches

About this chapter

Procedures and triggers store procedural SQL statements in the database for use by all applications. They enhance the security, efficiency, and standardization of databases. User-defined functions are one kind of procedures that return a value to the calling environment for use in queries and other SQL statements. Batches are sets of SQL statements submitted to the database server as a group. Many features available in procedures and triggers, such as control statements, are also available in batches.

For many purposes, server-side JDBC provides a more flexible way to build logic into the database than SQL stored procedures. For information about JDBC, see JDBC Programming.

Procedure and trigger overview
Benefits of procedures and triggers
Introduction to procedures
Introduction to user-defined functions
Introduction to triggers
Introduction to batches
Control statements
The structure of procedures and triggers
Returning results from procedures
Using cursors in procedures and triggers
Errors and warnings in procedures and triggers
Using the EXECUTE IMMEDIATE statement in procedures
Transactions and savepoints in procedures and triggers
Tips for writing procedures
Statements allowed in batches
Calling external libraries from procedures


Procedure and trigger overview

Procedures and triggers store procedural SQL statements in a database for use by all applications. They can include control statements that allow repetition (LOOP statement) and conditional execution (IF statement and CASE statement) of SQL statements.

Procedures are invoked with a CALL statement, and use parameters to accept values and return values to the calling environment. SELECT statements can also operate on procedure result sets by including the procedure name in the FROM clause.

Procedures can return result sets to the caller, call other procedures, or fire triggers. For example, a user-defined function is a type of stored procedure that returns a single value to the calling environment. User-defined functions do not modify parameters passed to them, but rather, they broaden the scope of functions available to queries and other SQL statements.

Triggers are associated with specific database tables. They fire automatically whenever someone inserts, updates or deletes rows of the associated table. Triggers can call procedures and fire other triggers, but they have no parameters and cannot be invoked by a CALL statement.

Procedure debugger

You can debug stored procedures and triggers using the database object debugger. For more information, see Debugging Logic in the Database.

You can profile stored procedures to analyze performance characteristics in Sybase Central. For more information, see Profiling database procedures.


Benefits of procedures and triggers

Definitions for procedures and triggers appear in the database, separately from any one database application. This separation provides a number of advantages.

Standardization

Procedures and triggers standardize actions performed by more than one application program. By coding the action once and storing it in the database for future use, applications need only call the procedure or fire the trigger to achieve the desired result repeatedly. And since changes occur in only one place, all applications using the action automatically acquire the new functionality if the implementation of the action changes.

Efficiency

Procedures and triggers used in a network database server environment can access data in the database without requiring network communication. This means they execute faster and with less impact on network performance than if they had been implemented in an application on one of the client machines.

When you create a procedure or trigger, it is automatically checked for correct syntax, and then stored in the system tables. The first time any application calls or fires a procedure or trigger, it is compiled from the system tables into the server's virtual memory and executed from there. Since one copy of the procedure or trigger remains in memory after the first execution, repeated executions of the same procedure or trigger happen instantly. As well, several applications can use a procedure or trigger concurrently, or one application can use it recursively.

Procedures are less efficient if they contain simple queries and have many arguments. For complex queries, procedures are more efficient.

Security

Procedures and triggers provide security by allowing users limited access to data in tables that they cannot directly examine or modify.

Triggers, for example, execute under the table permissions of the owner of the associated table, but any user with permissions to insert, update or delete rows in the table can fire them. Similarly, procedures (including user-defined functions) execute with permissions of the procedure owner, but any user granted permissions can call them. This means that procedures and triggers can (and usually do) have different permissions than the user ID that invoked them.


Introduction to procedures

To use procedures, you need to understand how to:

  • Create procedures

  • Call procedures from a database application

  • Drop or remove procedures

  • Control who has permissions to use procedures

This section discusses the above aspects of using procedures, as well as some different applications of procedures.

Creating procedures
Altering procedures
Calling procedures
Copying procedures in Sybase Central
Deleting procedures
Returning procedure results in parameters
Returning procedure results in result sets


Creating procedures

Adaptive Server Anywhere provides a number of tools that let you create a new procedure.

In Sybase Central, you can use a wizard to provide necessary information. The Procedure Creation wizard also provides the option of using procedure templates.

Alternatively, you use the CREATE PROCEDURE statement to create procedures. However, you must have RESOURCE authority. Where you enter the statement depends on which tool you use.

toggle To create a new procedure (Sybase Central)

  1. Connect to a database as a user with DBA or Resource authority.

  2. Open the Procedures & Functions folder of the database.

  3. From the File menu, choose New > Procedure.

    The Procedure Creation wizard appears.

  4. Follow the instructions in the wizard.

  5. When the wizard finishes, you can complete the code of the procedure on the SQL tab in the right pane.

    The new procedure appears in the Procedures & Functions folder.

toggle To create a new remote procedure (Sybase Central)

  1. Connect to a database as a user with DBA authority.

  2. Open the Procedures & Functions folder of the database.

  3. From the File menu, choose New > Remote Procedure.

    The Remote Procedure Creation wizard appears.

  4. Follow the instructions in the wizard.

  5. When the wizard finishes, you can complete the code on the SQL tab in the right pane.

    The new remote procedure appears in the Procedures and Functions folder.

toggle To create a procedure using a different tool

  • Follow the instructions for your tool. You may need to change the command delimiter away from the semicolon before entering the CREATE PROCEDURE statement.

For more information about connecting, see Connecting to a Database.

Example

The following simple example creates the procedure new_dept, which carries out an INSERT into the department table of the sample database, creating a new department.

CREATE PROCEDURE new_dept (
   IN id INT,
   IN name CHAR(35),
   IN head_id INT )
BEGIN
   INSERT
   INTO DBA.department ( dept_id,
       dept_name, dept_head_id )
   VALUES ( id, name, head_id );
END

The body of a procedure is a compound statement. The compound statement starts with a BEGIN statement and concludes with an END statement. In the case of new_dept, the compound statement is a single INSERT bracketed by BEGIN and END statements.

Parameters to procedures can be marked as one of IN, OUT, or INOUT. By default, parameters are INOUT parameters. All parameters to the new_dept procedure are IN parameters, as they are not changed by the procedure.

For more information, see CREATE PROCEDURE statement, ALTER PROCEDURE statement, and Using compound statements.


Altering procedures

You can modify an existing procedure using either Sybase Central or Interactive SQL. You must have DBA authority or be the owner of the procedure.

In Sybase Central, you cannot rename an existing procedure directly. Instead, you must create a new procedure with the new name, copy the previous code to it, and then delete the old procedure.

Alternatively, you can use an ALTER PROCEDURE statement to modify an existing procedure. You must include the entire new procedure in this statement (in the same syntax as in the CREATE PROCEDURE statement that created the procedure). You must also reassign user permissions on the procedure.

For more information on altering database object properties, see Setting properties for database objects.

For more information on granting or revoking permissions for procedures, see Granting permissions on procedures and Revoking user permissions.

toggle To alter the code of a procedure (Sybase Central)

  1. Open the Procedures & Functions folder.

  2. Select the desired procedure. You can then do one of the following:

    • Edit the code directly on the SQL tab in the right pane.

    • Translate the code to Watcom-SQL or Transact-SQL prior to editing it:

      • Right-click the desired procedure and choose Open as Watcom-SQL or Open as Transact-SQL from the popup menu.

      • Edit the code on the SQL tab in the right pane.

    • Edit the code in a separate window by right-clicking the procedure in the right pane and choose Edit In New Window from the popup menu.

      Tip
      If you wish to copy code between procedures, you can open a separate window for each procedure.
toggle To alter the code of a procedure (SQL)

  1. Connect to the database.

  2. Execute an ALTER PROCEDURE statement. Include the entire new procedure in this statement.

For more information, see ALTER PROCEDURE statement, CREATE PROCEDURE statement, and Creating procedures.


Calling procedures

CALL statements invoke procedures. Procedures can be called by an application program, or by other procedures and triggers.

For more information, see CALL statement.

The following statement calls the new_dept procedure to insert an Eastern Sales department:

CALL new_dept( 210, 'Eastern Sales', 902 );

After this call, you may wish to check the department table to see that the new department has been added.

All users who have been granted EXECUTE permissions for the procedure can call the new_dept procedure, even if they have no permissions on the department table.

For more information about EXECUTE permissions, see EXECUTE statement [ESQL].

Another way of calling a procedure that returns a result set is to call it in a query. You can execute queries on result sets of procedures and apply WHERE clauses and other SELECT features to limit the result set.

SELECT t.id, t.quantity_ordered AS q
FROM sp_customer_products( 149 ) t

For more information, see FROM clause.


Copying procedures in Sybase Central

In Sybase Central, you can copy procedures between databases. To do so, select the procedure in the left pane of Sybase Central and drag it to the Procedures & Functions folder of another connected database. A new procedure is then created, and the original procedure's code is copied to it.

Note that only the procedure code is copied to the new procedure. The other procedure properties (permissions, etc.) are not copied. A procedure can be copied to the same database, provided it is given a new name.


Deleting procedures

Once you create a procedure, it remains in the database until someone explicitly removes it. Only the owner of the procedure or a user with DBA authority can drop the procedure from the database.

toggle To delete a procedure (Sybase Central)

  1. Connect to a database as a user with DBA authority or as the owner of the procedure.

  2. Open the Procedures & Functions folder.

  3. Right-click the desired procedure and choose Delete from the popup menu.

toggle To delete a procedure (SQL)

  1. Connect to a database as a user with DBA authority or as the owner of the procedure.

  2. Execute a DROP PROCEDURE statement.

Example

The following statement removes the procedure new_dept from the database:

DROP PROCEDURE new_dept

For more information, see DROP statement.


Returning procedure results in parameters

Procedures return results to the calling environment in one of the following ways:

  • Individual values are returned as OUT or INOUT parameters.

  • Result sets can be returned.

  • A single result can be returned using a RETURN statement.

This section describes how to return results from procedures as parameters.

The following procedure on the sample database returns the average salary of employees as an OUT parameter.

CREATE PROCEDURE AverageSalary( OUT avgsal
   NUMERIC (20,3) )
BEGIN
   SELECT AVG( salary )
   INTO avgsal
   FROM employee;
END
toggle To run this procedure and display its output (SQL)

  1. Connect to the sample database from Interactive SQL with a user ID of DBA and a password of SQL. For more information about connecting, see Connecting to a Database.

  2. In the SQL Statements pane, type the above procedure code.

  3. Create a variable to hold the procedure output. In this case, the output variable is numeric, with three decimal places, so create a variable as follows:

    CREATE VARIABLE Average NUMERIC(20,3)

  4. Call the procedure using the created variable to hold the result:

    CALL AverageSalary(Average)

    If the procedure was created and run properly, the Interactive SQL Messages pane does not display any errors.

  5. Execute the SELECT Average statement to inspect the value of the variable.

    Look at the value of the output variable Average. The Results tab in the Results pane displays the value 49988.623 for this variable, the average employee salary.


Returning procedure results in result sets

In addition to returning results to the calling environment in individual parameters, procedures can return information in result sets. A result set is typically the result of a query. The following procedure returns a result set containing the salary for each employee in a given department:

CREATE PROCEDURE SalaryList ( IN department_id INT)
RESULT ( "Employee ID" INT, Salary NUMERIC(20,3) )
BEGIN
    SELECT emp_id, salary
    FROM employee
    WHERE employee.dept_id = department_id;
END

If Interactive SQL calls this procedure, the names in the RESULT clause are matched to the results of the query and used as column headings in the displayed results.

To test this procedure from Interactive SQL, you can CALL it, specifying one of the departments of the company. In Interactive SQL, the results appear on the Results tab in the Results pane.

Example

To list the salaries of employees in the R & D department (department ID 100), type the following:

CALL SalaryList (100)
Employee ID | Salary
102 | 45700
105 | 62000
160 | 57490
243 | 72995
... | ...

Interactive SQL can only return multiple result sets if you have this option enabled on the Results tab of the Options dialog. Each result set appears on a separate tab in the Results pane.

For more information, see Returning multiple result sets from procedures.


Introduction to user-defined functions

User-defined functions are a class of procedures that return a single value to the calling environment. Adaptive Server Anywhere treats all user-defined functions as idempotent unless they are declared NOT DETERMINISTIC.

Idempotent functions return a consistent result for the same parameters and are free of side effects. Two successive calls to an idempotent function with the same parameters return the same result, and have no unwanted side-effects on the query's semantics.

For more information about non-deterministic and deterministic functions, see Function caching.

This section introduces creating, using, and dropping user-defined functions.


Creating user-defined functions

You use the CREATE FUNCTION statement to create user-defined functions. However, you must have RESOURCE authority.

The following simple example creates a function that concatenates two strings, together with a space, to form a full name from a first name and a last name.

CREATE FUNCTION fullname (firstname CHAR(30),
   lastname CHAR(30))
RETURNS CHAR(61)
BEGIN
     DECLARE name CHAR(61);
     SET name = firstname || ' ' || lastname;
     RETURN ( name );
END
toggle To create this example using Interactive SQL

  1. Connect to the sample database from Interactive SQL with a user ID of DBA and a password of SQL. For more information about connecting, see Connecting to a Database.

  2. In the SQL Statements pane, type the above function code.

Note
If you are using a tool other than Interactive SQL or Sybase Central, you may need to change the command delimiter to something other than the semicolon.

For more information, see CREATE FUNCTION statement.

The CREATE FUNCTION syntax differs slightly from that of the CREATE PROCEDURE statement. The following are distinctive differences:

  • No IN, OUT, or INOUT keywords are required, as all parameters are IN parameters.

  • The RETURNS clause is required to specify the data type being returned.

  • The RETURN statement is required to specify the value being returned.


Calling user-defined functions

A user-defined function can be used, subject to permissions, in any place you would use a built-in non-aggregate function.

The following statement in Interactive SQL returns a full name from two columns containing a first and last name:

SELECT fullname (emp_fname, emp_lname)
FROM employee;
fullname (emp_fname, emp_lname)
Fran Whitney
Matthew Cobb
Philip Chin
...

The following statement in Interactive SQL returns a full name from a supplied first and last name:

SELECT fullname ('Jane', 'Smith');
fullname ('Jane','Smith')
Jane Smith

Any user who has been granted EXECUTE permissions for the function can use the fullname function.

Example

The following user-defined function illustrates local declarations of variables.

The customer table includes some Canadian customers sprinkled among those from the USA, but there is no country column. The user-defined function nationality uses the fact that the US zip code is numeric while the Canadian postal code begins with a letter to distinguish Canadian and US customers.

CREATE FUNCTION nationality( cust_id INT )
RETURNS CHAR( 20 )
BEGIN
   DECLARE natl CHAR(20);
   IF cust_id IN ( SELECT id FROM customer
    WHERE LEFT(zip,1) > '9') THEN
          SET natl = 'CDN';
   ELSE
        SET natl = 'USA';
   END IF;
   RETURN ( natl );
END

This example declares a variable natl to hold the nationality string, uses a SET statement to set a value for the variable, and returns the value of the natl string to the calling environment.

The following query lists all Canadian customers in the customer table:

SELECT *
FROM customer
WHERE nationality(id) = 'CDN'

Declarations of cursors and exceptions are discussed in later sections.

The same query restated without the function would perform better, especially if an index on zip existed. For example,

Select *
FROM customer
WHERE zip > '99999'
Notes

While this function is useful for illustration, it may perform very poorly if used in a SELECT involving many rows. For example, if you used the SELECT query on a table containing 100 000 rows, of which 10 000 are returned, the function will be called 10 000 times. If you use it in the WHERE clause of the same query, it would be called 100 000 times.


Dropping user-defined functions

Once you create a user-defined function, it remains in the database until someone explicitly removes it. Only the owner of the function or a user with DBA authority can drop a function from the database.

The following statement removes the function fullname from the database:

DROP FUNCTION fullname


Permissions to execute user-defined functions

Ownership of a user-defined function belongs to the user who created it, and that user can execute it without permission. The owner of a user-defined function can grant permissions to other users with the GRANT EXECUTE command.

For example, the creator of the function fullname could allow another_user to use fullname with the statement:

GRANT EXECUTE ON fullname TO another_user

The following statement revokes permissions to use the function:

REVOKE EXECUTE ON fullname FROM another_user

For more information on managing user permissions on functions, see Granting permissions on procedures.


Introduction to triggers

A trigger is a special form of stored procedure that is executed automatically when a query that modifies data is executed. You use triggers whenever referential integrity and other declarative constraints are insufficient.

For more information on referential integrity, see Ensuring Data Integrity and CREATE TABLE statement.

You may want to enforce a more complex form of referential integrity involving more detailed checking, or you may want to enforce checking on new data but allow legacy data to violate constraints. Another use for triggers is in logging the activity on database tables, independent of the applications using the database.

Trigger execution permissions
Triggers execute with the permissions of the owner of the associated table, not the user ID whose actions cause the trigger to fire. A trigger can modify rows in a table that a user could not modify directly.
Trigger events

Triggers can be defined on one or more of the following triggering events:

Action | Description
INSERT | Invokes the trigger whenever a new row is inserted into the table associated with the trigger
DELETE | Invokes the trigger whenever a row of the associated table is deleted.
UPDATE | Invokes the trigger whenever a row of the associated table is updated.
UPDATE OF column-list | Invokes the trigger whenever a row of the associated table is updated such that a column in the column-list has been modified

You may write separate triggers for each event that you need to handle or, if you have some shared actions and some actions that depend on the event, you can create a trigger for all events and use an IF statement to distinguish the action taking place.

For more information, see Trigger operation conditions.

Trigger times

Triggers can be either row-level or statement-level:

  • A row-level trigger executes once for each row that is changed. Row-level triggers execute BEFORE or AFTER the row is changed.

  • A statement-level trigger executes after the entire triggering statement is completed.

Flexibility in trigger execution time is particularly useful for triggers that rely on referential integrity actions such as cascaded updates or deletes being carried out (or not) as they execute.

If an error occurs while a trigger is executing, the operation that fired the trigger fails. INSERT, UPDATE, and DELETE are atomic operations (see Atomic compound statements). When they fail, all effects of the statement (including the effects of triggers and any procedures called by triggers) revert back to their pre-operation state.

For a full description of trigger syntax, see CREATE TRIGGER statement.


Creating triggers

You create triggers using either Sybase Central or Interactive SQL. In Sybase Central, you can use a wizard to provide necessary information. In Interactive SQL, you can use a CREATE TRIGGER statement. For both tools, you must have DBA or RESOURCE authority to create a trigger and you must have ALTER permissions on the table associated with the trigger.

The body of a trigger consists of a compound statement: a set of semicolon-delimited SQL statements bracketed by a BEGIN and an END statement.

You cannot use COMMIT and ROLLBACK and some ROLLBACK TO SAVEPOINT statements within a trigger.

For more information, see the list of cross-references at the end of this section.

toggle To create a trigger for a given table (Sybase Central)

  1. Open the Triggers folder of the desired table.

  2. From the File menu, choose New > Trigger.

    The Trigger Creation wizard appears.

  3. Follow the instructions in the wizard.

  4. When the wizard finishes, you can complete the code of the trigger on the SQL tab in the right pane.

toggle To create a trigger for a given table (SQL)

  1. Connect to a database.

  2. Execute a CREATE TRIGGER statement.

Example 1: A row-level INSERT trigger

The following trigger is an example of a row-level INSERT trigger. It checks that the birth date entered for a new employee is reasonable:

CREATE TRIGGER check_birth_date
    AFTER INSERT ON Employee
REFERENCING NEW AS new_employee
FOR EACH ROW
BEGIN
     DECLARE err_user_error EXCEPTION
     FOR SQLSTATE '99999';
     IF new_employee.birth_date > 'June 6, 2001' THEN
          SIGNAL err_user_error;
     END IF;
END

This trigger fires after any row is inserted into the employee table. It detects and disallows any new rows that correspond to birth dates later than June 6, 2001.

The phrase REFERENCING NEW AS new_employee allows statements in the trigger code to refer to the data in the new row using the alias new_employee.

Signaling an error causes the triggering statement, as well as any previous effects of the trigger, to be undone.

For an INSERT statement that adds many rows to the employee table, the check_birth_date trigger fires once for each new row. If the trigger fails for any of the rows, all effects of the INSERT statement roll back.

You can specify that the trigger fires before the row is inserted rather than after by changing the first line of the example to:

CREATE TRIGGER mytrigger BEFORE INSERT ON Employee

The REFERENCING NEW clause refers to the inserted values of the row; it is independent of the timing (BEFORE or AFTER) of the trigger.

You may find it easier in some cases to enforce constraints using declaration referential integrity or CHECK constraints, rather than triggers. For example, implementing the above example with a column check constraint proves more efficient and concise:

CHECK (@col <= 'June 6, 2001')
Example 2: A row-level DELETE trigger example

The following CREATE TRIGGER statement defines a row-level DELETE trigger:

CREATE TRIGGER mytrigger BEFORE DELETE ON employee
REFERENCING OLD AS oldtable
FOR EACH ROW
BEGIN
     ...
END

The REFERENCING OLD clause enables the delete trigger code to refer to the values in the row being deleted using the alias oldtable.

You can specify that the trigger fires after the row is deleted rather than before, by changing the first line of the example to:

CREATE TRIGGER check_birth_date AFTER DELETE ON employee

The REFERENCING OLD clause is independent of the timing (BEFORE or AFTER) of the trigger.

Example 3: A statement-level UPDATE trigger example

The following CREATE TRIGGER statement is appropriate for statement-level UPDATE triggers:

CREATE TRIGGER mytrigger AFTER UPDATE ON employee
REFERENCING NEW AS table_after_update
            OLD AS table_before_update
FOR EACH STATEMENT
BEGIN
     ...
END

The REFERENCING NEW and REFERENCING OLD clause allows the UPDATE trigger code to refer to both the old and new values of the rows being updated. The table alias table_after_update refers to columns in the new row and the table alias table_before_update refers to columns in the old row.

The REFERENCING NEW and REFERENCING OLD clause has a slightly different meaning for statement-level and row-level triggers. For statement-level triggers the REFERENCING OLD or NEW aliases are table aliases, while in row-level triggers they refer to the row being altered.

For more information, see CREATE TRIGGER statement, and Using compound statements.


Executing triggers

Triggers execute automatically whenever an INSERT, UPDATE, or DELETE operation is performed on the table named in the trigger. A row-level trigger fires once for each row affected, while a statement-level trigger fires once for the entire statement.

When an INSERT, UPDATE, or DELETE fires a trigger, the order of operation is as follows:

  1. BEFORE triggers fire.

  2. Referential actions are performed.

  3. The operation itself is performed.

  4. AFTER triggers fire.

If any of the steps encounter an error not handled within a procedure or trigger, the preceding steps are undone, the subsequent steps are not performed, and the operation that fired the trigger fails.


Altering triggers

You can modify an existing trigger using either Sybase Central or Interactive SQL. You must be the owner of the table on which the trigger is defined, or be DBA, or have ALTER permissions on the table and have RESOURCE authority.

In Sybase Central, you cannot rename an existing trigger directly. Instead, you must create a new trigger with the new name, copy the previous code to it, and then delete the old trigger.

Alternatively, you can use an ALTER TRIGGER statement to modify an existing trigger. You must include the entire new trigger in this statement (in the same syntax as in the CREATE TRIGGER statement that created the trigger).

For more information on altering database object properties, see Setting properties for database objects.

toggle To alter the code of a trigger (Sybase Central)

  1. Open the Triggers folder.

  2. Select the desired trigger. You can then do one of the following:

    • Edit the code directly on the SQL tab in the right pane.

    • Translate the code to Watcom-SQL or Transact-SQL prior to editing it:

      • Right-click the desired trigger and choose Open as Watcom-SQL or Open as Transact-SQL from the popup menu.

      • Edit the code on the SQL tab in the right pane.

    • Edit the code in a separate window by right-clicking the trigger in the right pane and choose Edit In New Window from the popup menu.

      Tip
      If you wish to copy code between triggers, you can open a separate window for each trigger.
toggle To alter the code of a trigger (SQL)

  1. Connect to the database.

  2. Execute an ALTER TRIGGER statement. Include the entire new trigger in this statement.

For more information, see ALTER TRIGGER statement.


Dropping triggers

Once you create a trigger, it remains in the database until someone explicitly removes it. You must have ALTER permissions on the table associated with the trigger to drop the trigger.

toggle To delete a trigger (Sybase Central)

  1. Open the Triggers folder.

  2. Right-click the desired trigger and choose Delete from the popup menu.

toggle To delete a trigger (SQL)

  1. Connect to a database.

  2. Execute a DROP TRIGGER statement.

Example

The following statement removes the trigger mytrigger from the database:

DROP TRIGGER mytrigger

For more information, see DROP statement.


Trigger execution permissions

You cannot grant permissions to execute a trigger, since users cannot execute triggers: Adaptive Server Anywhere fires them in response to actions on the database. Nevertheless, a trigger does have permissions associated with it as it executes, defining its right to carry out certain actions.

Triggers execute using the permissions of the owner of the table on which they are defined, not the permissions of the user who caused the trigger to fire, and not the permissions of the user who created the trigger.

When a trigger refers to a table, it uses the group memberships of the table creator to locate tables with no explicit owner name specified. For example, if a trigger on user_1.Table_A references Table_B and does not specify the owner of Table_B, then either Table_B must have been created by user_1 or user_1 must be a member of a group (directly or indirectly) that is the owner of Table_B. If neither condition is met, a table not found message results when the trigger fires.

Also, user_1 must have permissions to carry out the operations specified in the trigger.


Introduction to batches

A simple batch consists of a set of SQL statements, separated by semicolons or separated by a separate line with just the word go on it. The use of go is recommended. For example, the following set of statements form a batch, which creates an Eastern Sales department and transfers all sales reps from Massachusetts to that department.

INSERT
INTO department ( dept_id, dept_name )
VALUES ( 220, 'Eastern Sales' )
go
UPDATE employee
SET dept_id = 220
WHERE dept_id = 200
AND state = 'MA'
go
COMMIT
go

You can include this set of statements in an application and execute them together.

Interactive SQL and batches
Interactive SQL parses a list of semicolon-separated statements, such as the above, before sending them to the server. In this case, Interactive SQL sends each statement to the server individually, not as a batch. Unless you have such parsing code in your application, the statements would be sent and treated as a batch. Putting a BEGIN and END around a set of statements causes Interactive SQL to treat them as a batch.

Many statements used in procedures and triggers can also be used in batches. You can use control statements (CASE, IF, LOOP, and so on), including compound statements (BEGIN and END), in batches. Compound statements can include declarations of variables, exceptions, temporary tables, or cursors inside the compound statement.

The following batch creates a table only if a table of that name does not already exist:

IF NOT EXISTS (
   SELECT * FROM SYSTABLE
   WHERE table_name = 't1' ) THEN
      CREATE TABLE t1 (
      firstcol INT PRIMARY KEY,
      secondcol CHAR( 30 )
      )
      go
ELSE
   MESSAGE 'Table t1 already exists' TO CLIENT;
END IF

If you run this batch twice from Interactive SQL, it creates the table the first time you run it and displays the message in the Interactive SQL Messages pane the next time you run it.


Control statements

There are a number of control statements for logical flow and decision making in the body of the procedure or trigger, or in a batch. Available control statements include:

Control statement Syntax
Compound statements

For more information, see BEGIN statement.

BEGIN [ ATOMIC ]
   Statement-list
END
Conditional execution: IF

For more information, see IF statement.

IF condition THEN
   Statement-list
ELSEIF condition THEN
   Statement-list
ELSE
   Statement-list
END IF
Conditional execution: CASE

For more information, see CASE statement.

CASE expression
WHEN value THEN
   Statement-list
WHEN value THEN
   Statement-list
ELSE
   Statement-list
END CASE
Repetition: WHILE, LOOP

For more information, see LOOP statement.

WHILE condition LOOP
   Statement-list
END LOOP
Repetition: FOR cursor loop

For more information, see FOR statement.

FOR loop-name
   AS cursor-name
   CURSOR FOR select statement
DO
   Statement-list
END FOR
Break: LEAVE

For more information, see LEAVE statement.

LEAVE label
CALL

For more information, see CALL statement.

CALL procname( arg, ... )

For more information about each statement, see the entries in SQL Statements


Using compound statements

A compound statement starts with the keyword BEGIN and concludes with the keyword END. The body of a procedure or trigger is a compound statement. Compound statements can also be used in batches. Compound statements can be nested, and combined with other control statements to define execution flow in procedures and triggers or in batches.

A compound statement allows a set of SQL statements to be grouped together and treated as a unit. Delimit SQL statements within a compound statement with semicolons.

For more information about compound statements, see the BEGIN statement.


Declarations in compound statements

Local declarations in a compound statement immediately follow the BEGIN keyword. These local declarations exist only within the compound statement. Within a compound statement you can declare:

  • Variables

  • Cursors

  • Temporary tables

  • Exceptions (error identifiers)

Local declarations can be referenced by any statement in that compound statement, or in any compound statement nested within it. Local declarations are not visible to other procedures called from the compound statement.


Atomic compound statements

An atomic statement is a statement executed completely or not at all. For example, an UPDATE statement that updates thousands of rows might encounter an error after updating many rows. If the statement does not complete, all changes revert back to their original state. The UPDATE statement is atomic.

All non-compound SQL statements are atomic. You can make a compound statement atomic by adding the keyword ATOMIC after the BEGIN keyword.

BEGIN ATOMIC
    UPDATE employee
    SET manager_ID = 501
    WHERE emp_ID = 467;
    UPDATE employee
    SET birth_date = 'bad_data';
END

In this example, the two update statements are part of an atomic compound statement. They must either succeed or fail as one. The first update statement would succeed. The second one causes a data conversion error since the value being assigned to the birth_date column cannot be converted to a date.

The atomic compound statement fails and the effect of both UPDATE statements is undone. Even if the currently executing transaction is eventually committed, neither statement in the atomic compound statement takes effect.

If an atomic compound statement succeeds, the changes made within the compound statement take effect only if the currently executing transaction is committed. In the case when an atomic compound statement succeeds but the transaction in which it occurs gets rolled back, the atomic compound statement also gets rolled back. A savepoint is established at the start of the atomic compound statement. Any errors within the statement result in a rollback to that savepoint.

You cannot use COMMIT and ROLLBACK and some ROLLBACK TO SAVEPOINT statements within an atomic compound statement (see Transactions and savepoints in procedures and triggers).

There is a case where some, but not all, of the statements within an atomic compound statement are executed. This happens when an exception handler within the compound statement deals with an error.

For more information, see Using exception handlers in procedures and triggers.


The structure of procedures and triggers

The body of a procedure or trigger consists of a compound statement as discussed in Using compound statements. A compound statement consists of a BEGIN and an END, enclosing a set of SQL statements. Semicolons delimit each statement.


SQL statements allowed in procedures and triggers

You can use almost all SQL statements within procedures and triggers, including the following:

  • SELECT, UPDATE, DELETE, INSERT and SET VARIABLE.

  • The CALL statement to execute other procedures.

  • Control statements (see Control statements).

  • Cursor statements (see Using cursors in procedures and triggers).

  • Exception handling statements (see Using exception handlers in procedures and triggers).

  • The EXECUTE IMMEDIATE statement.

Some SQL statements you cannot use within procedures and triggers include:

  • CONNECT statement

  • DISCONNECT statement.

You can use COMMIT, ROLLBACK and SAVEPOINT statements within procedures and triggers with certain restrictions (see Transactions and savepoints in procedures and triggers).

For more information, see the Usage for each SQL statement in the chapter SQL Statements.


Declaring parameters for procedures

Procedure parameters appear as a list in the CREATE PROCEDURE statement. Parameter names must conform to the rules for other database identifiers such as column names. They must have valid data types (see SQL Data Types), and can be prefixed with one of the keywords IN, OUT or INOUT. By default, parameters are INOUT parameters. These keywords have the following meanings:

  • IN The argument is an expression that provides a value to the procedure.

  • OUT The argument is a variable that could be given a value by the procedure.

  • INOUT The argument is a variable that provides a value to the procedure, and could be given a new value by the procedure.

You can assign default values to procedure parameters in the CREATE PROCEDURE statement. The default value must be a constant, which may be NULL. For example, the following procedure uses the NULL default for an IN parameter to avoid executing a query that would have no meaning:

CREATE PROCEDURE
CustomerProducts( IN customer_id
                  INTEGER DEFAULT NULL )
RESULT ( product_id INTEGER,
         quantity_ordered INTEGER )
BEGIN
    IF customer_id IS NULL THEN
        RETURN;
    ELSE
        SELECT    product.id,
                 sum( sales_order_items.quantity )
        FROM   product,
                 sales_order_items,
                 sales_order
        WHERE sales_order.cust_id = customer_id
        AND sales_order.id = sales_order_items.id
        AND sales_order_items.prod_id = product.id
        GROUP BY product.id;
    END IF;
END

The following statement assigns the DEFAULT NULL, and the procedure RETURNs instead of executing the query.

CALL customerproducts();


Passing parameters to procedures

You can take advantage of default values of stored procedure parameters with either of two forms of the CALL statement.

If the optional parameters are at the end of the argument list in the CREATE PROCEDURE statement, they may be omitted from the CALL statement. As an example, consider a procedure with three INOUT parameters:

CREATE PROCEDURE SampleProc( INOUT var1 INT
                              DEFAULT 1,
                     INOUT var2 int DEFAULT 2,
                     INOUT var3 int DEFAULT 3 )
...

We assume that the calling environment has set up three variables to hold the values passed to the procedure:

CREATE VARIABLE V1 INT;
CREATE VARIABLE V2 INT;
CREATE VARIABLE V3 INT;

The procedure SampleProc may be called supplying only the first parameter as follows:

CALL SampleProc( V1 )

in which case the default values are used for var2 and var3.

A more flexible method of calling procedures with optional arguments is to pass the parameters by name. The SampleProc procedure may be called as follows:

CALL SampleProc( var1 = V1, var3 = V3 )

or as follows:

CALL SampleProc( var3 = V3, var1 = V1 )


Passing parameters to functions

User-defined functions are not invoked with the CALL statement, but are used in the same manner that built-in functions are. For example, the following statement uses the fullname function defined in Creating user-defined functions to retrieve the names of employees:

toggle To list the names of all employees

  • Type the following:

    SELECT fullname(emp_fname, emp_lname) AS Name
FROM employee
Name
Fran Whitney
Matthew Cobb
Philip Chin
Julie Jordan
...
Notes

  • Default parameters can be used in calling functions. However, parameters cannot be passed to functions by name.

  • Parameters are passed by value, not by reference. Even if the function changes the value of the parameter, this change is not returned to the calling environment.

  • Output parameters cannot be used in user-defined functions.

  • User-defined functions cannot return result sets.


Returning results from procedures

Procedures can return results in the form of a single row of data, or multiple rows. Results consisting of a single row of data can be passed back as arguments to the procedure. Results consisting of multiple rows of data are passed back as result sets. Procedures can also return a single value given in the RETURN statement.

For simple examples of how to return results from procedures, see Introduction to procedures. For more detailed information, see the following sections.

Returning a value using the RETURN statement
Returning results as procedure parameters
Returning result sets from procedures
Returning multiple result sets from procedures
Returning variable result sets from procedures


Returning a value using the RETURN statement

The RETURN statement returns a single integer value to the calling environment, causing an immediate exit from the procedure. The RETURN statement takes the form:

RETURN expression

The value of the supplied expression is returned to the calling environment. To save the return value in a variable, use an extension of the CALL statement:

CREATE VARIABLE returnval INTEGER ;
returnval = CALL myproc() ;


Returning results as procedure parameters

Procedures can return results to the calling environment in the parameters to the procedure.

Within a procedure, parameters and variables can be assigned values using:

  • the SET statement.

  • a SELECT statement with an INTO clause.

Using the SET statement

The following somewhat artificial procedure returns a value in an OUT parameter assigned using a SET statement:

CREATE PROCEDURE greater (   IN a INT,
                           IN b INT,
                           OUT c INT)
BEGIN
   IF a > b THEN
      SET c = a;
   ELSE
      SET c = b;
   END IF ;
END
Using single-row SELECT statements

Single-row queries retrieve at most one row from the database. This type of query uses a SELECT statement with an INTO clause. The INTO clause follows the select list and precedes the FROM clause. It contains a list of variables to receive the value for each select list item. There must be the same number of variables as there are select list items.

When a SELECT statement executes, the server retrieves the results of the SELECT statement and places the results in the variables. If the query results contain more than one row, the server returns an error. For queries returning more than one row, you must use cursors. For information about returning more than one row from a procedure, see Returning result sets from procedures.

If the query results in no rows being selected, a row not found warning appears.

The following procedure returns the results of a single-row SELECT statement in the procedure parameters.

toggle To return the number of orders placed by a given customer

  • Type the following:

    CREATE PROCEDURE OrderCount (IN customer_ID INT,
                              OUT Orders INT)
BEGIN
   SELECT COUNT(DBA.sales_order.id)
      INTO Orders
   FROM DBA.customer
      KEY LEFT OUTER JOIN "DBA".sales_order
   WHERE DBA.customer.id = customer_ID;
END

You can test this procedure in Interactive SQL using the following statements, which show the number of orders placed by the customer with ID 102:

CREATE VARIABLE orders INT;
CALL OrderCount ( 102, orders );
SELECT orders;
Notes

  • The customer_ID parameter is declared as an IN parameter. This parameter holds the customer ID passed in to the procedure.

  • The Orders parameter is declared as an OUT parameter. It holds the value of the orders variable that returned to the calling environment.

  • No DECLARE statement is necessary for the Orders variable, as it is declared in the procedure argument list.

  • The SELECT statement returns a single row and places it into the variable Orders.


Returning result sets from procedures

Result sets allow a procedure to return more than one row of results to the calling environment.

The following procedure returns a list of customers who have placed orders, together with the total value of the orders placed. The procedure does not list customers who have not placed orders.

CREATE PROCEDURE ListCustomerValue ()
RESULT ("Company" CHAR(36), "Value" INT)
BEGIN
   SELECT company_name,
      CAST( sum(   sales_order_items.quantity *
                  product.unit_price)
                  AS INTEGER ) AS value
   FROM customer
      INNER JOIN sales_order
      INNER JOIN sales_order_items
      INNER JOIN product
   GROUP BY company_name
   ORDER BY value DESC;
END

  • Type the following:

    CALL ListCustomerValue ()
Company | Value
Chadwicks | 8076
Overland Army Navy | 8064
Martins Landing | 6888
Sterling & Co. | 6804
Carmel Industries | 6780
... | ...
Notes

  • The number of variables in the RESULT list must match the number of the SELECT list items. Automatic data type conversion is carried out where possible if data types do not match.

  • The RESULT clause is part of the CREATE PROCEDURE statement, and does not have a command delimiter.

  • The names of the SELECT list items do not need to match those of the RESULT list.

  • When testing this procedure, Interactive SQL displays only the first result set by default. You can configure Interactive SQL to display more than one result set by setting the Show multiple result sets option on the Results tab of the Options dialog.

  • You can modify procedure result sets, unless they are generated from a view. The user calling the procedure requires the appropriate permissions on the underlying table to modify procedure results. This is different than the usual permissions for procedure execution, where the procedure owner must have permissions on the table.

    For information about modifying result sets in Interactive SQL, see Editing table values in Interactive SQL.

  • If a stored procedure or user-defined function returns a result set, it cannot also set output parameters or return a return value.


Returning multiple result sets from procedures

Before Interactive SQL can return multiple result sets, you need to enable this option on the Results tab of the Options dialog. By default, this option is disabled. If you change the setting, it takes effect in newly created connections (such as new windows).

toggle To enable multiple result set functionality

  1. Choose Tools > Options.

  2. In the resulting Options dialog, click the Results tab.

  3. Select the Show Multiple Result Sets checkbox.

After you enable this option, a procedure can return more than one result set to the calling environment. If a RESULT clause is employed, the result sets must be compatible: they must have the same number of items in the SELECT lists, and the data types must all be of types that can be automatically converted to the data types listed in the RESULT list.

The following procedure lists the names of all employees, customers, and contacts listed in the database:

CREATE PROCEDURE ListPeople()
RESULT ( lname CHAR(36), fname CHAR(36) )
BEGIN
   SELECT emp_lname, emp_fname
   FROM employee;
   SELECT lname, fname
   FROM customer;
   SELECT last_name, first_name
   FROM contact;
END
Notes

  • To test this procedure in Interactive SQL, enter the following statement in the SQL Statements pane:

    CALL ListPeople ()


Returning variable result sets from procedures

The RESULT clause is optional in procedures. Omitting the result clause allows you to write procedures that return different result sets, with different numbers or types of columns, depending on how they are executed.

If you do not use the variable result sets feature, you should use a RESULT clause for performance reasons.

For example, the following procedure returns two columns if the input variable is Y, but only one column otherwise:

CREATE PROCEDURE names( IN formal char(1))
BEGIN
   IF formal = 'y' THEN
      SELECT emp_lname, emp_fname
      FROM employee
   ELSE
      SELECT emp_fname
      FROM employee
   END IF
END

The use of variable result sets in procedures is subject to some limitations, depending on the interface used by the client application.

  • Embedded SQL You must DESCRIBE the procedure call after the cursor for the result set is opened, but before any rows are returned, in order to get the proper shape of result set.

    For more information about the DESCRIBE statement, see DESCRIBE statement [ESQL].

  • ODBC Variable result set procedures can be used by ODBC applications. The Adaptive Server Anywhere ODBC driver carries out the proper description of the variable result sets.

  • Open Client applications Open Client applications can use variable result set procedures. Adaptive Server Anywhere carries out the proper description of the variable result sets.


Using cursors in procedures and triggers

Cursors retrieve rows one at a time from a query or stored procedure with multiple rows in its result set. A cursor is a handle or an identifier for the query or procedure, and for a current position within the result set.


Cursor management overview

Managing a cursor is similar to managing a file in a programming language. The following steps manage cursors:

  1. Declare a cursor for a particular SELECT statement or procedure using the DECLARE statement.

  2. Open the cursor using the OPEN statement.

  3. Use the FETCH statement to retrieve results one row at a time from the cursor.

  4. The warning Row Not Found signals the end of the result set.

  5. Close the cursor using the CLOSE statement.

By default, cursors are automatically closed at the end of a transaction (on COMMIT or ROLLBACK statements). Cursors are opened using the WITH HOLD clause will stay open for subsequent transactions until someone explicitly closes them.

For more information on positioning cursors, see Cursor positioning.


Using cursors on SELECT statements in procedures

The following procedure uses a cursor on a SELECT statement. Based on the same query used in the ListCustomerValue procedure described in Returning result sets from procedures, it illustrates several features of the stored procedure language.

CREATE PROCEDURE TopCustomerValue
   (   OUT TopCompany CHAR(36),
      OUT TopValue INT )
BEGIN
   -- 1. Declare the "error not found" exception
   DECLARE err_notfound
      EXCEPTION FOR SQLSTATE '02000';
 -- 2.   Declare variables to hold
   --      each company name and its value
   DECLARE ThisName CHAR(36);
   DECLARE ThisValue INT;
 -- 3.   Declare the cursor ThisCompany
   --      for the query
   DECLARE ThisCompany CURSOR FOR
   SELECT company_name,
         CAST( sum( sales_order_items.quantity *
               product.unit_price ) AS INTEGER )
         AS value
   FROM customer
      INNER JOIN sales_order
      INNER JOIN sales_order_items
      INNER JOIN product
   GROUP BY company_name;
 -- 4. Initialize the values of TopValue
   SET TopValue = 0;
   -- 5. Open the cursor
   OPEN ThisCompany;
 -- 6. Loop over the rows of the query
   CompanyLoop:
   LOOP
      FETCH NEXT ThisCompany
         INTO ThisName, ThisValue;
      IF SQLSTATE = err_notfound THEN
         LEAVE CompanyLoop;
      END IF;
      IF ThisValue > TopValue THEN
         SET TopCompany = ThisName;
         SET TopValue = ThisValue;
      END IF;
   END LOOP CompanyLoop;
 -- 7. Close the cursor
   CLOSE ThisCompany;
END
Notes

The TopCustomerValue procedure has the following notable features:

  • The "error not found" exception is declared. This exception signals, later in the procedure, when a loop over the results of a query completes.

    For more information about exceptions, see Errors and warnings in procedures and triggers.

  • Two local variables ThisName and ThisValue are declared to hold the results from each row of the query.

  • The cursor ThisCompany is declared. The SELECT statement produces a list of company names and the total value of the orders placed by that company.

  • The value of TopValue is set to an initial value of 0, for later use in the loop.

  • The ThisCompany cursor opens.

  • The LOOP statement loops over each row of the query, placing each company name in turn into the variables ThisName and ThisValue. If ThisValue is greater than the current top value, TopCompany and TopValue are reset to ThisName and ThisValue.

  • The cursor closes at the end of the procedure.

  • You can also write this procedure without a loop by adding an ORDER BY value DESC clause to the SELECT statement. Then, only the first row of the cursor needs to be fetched.

The LOOP construct in the TopCompanyValue procedure is a standard form, exiting after the last row processes. You can rewrite this procedure in a more compact form using a FOR loop. The FOR statement combines several aspects of the above procedure into a single statement.

CREATE PROCEDURE TopCustomerValue2(
      OUT TopCompany CHAR(36),
      OUT TopValue INT )
BEGIN
   -- Initialize the TopValue variable
   SET TopValue = 0;
   -- Do the For Loop
   FOR CompanyFor AS ThisCompany
      CURSOR FOR
      SELECT company_name AS ThisName ,
         CAST( sum( sales_order_items.quantity *
               product.unit_price ) AS INTEGER )
         AS ThisValue
      FROM customer
         INNER JOIN sales_order
         INNER JOIN sales_order_items
         INNER JOIN product
      GROUP BY ThisName
   DO
      IF ThisValue > TopValue THEN
         SET TopCompany = ThisName;
         SET TopValue = ThisValue;
         END IF;
   END FOR;
END


Errors and warnings in procedures and triggers

After an application program executes a SQL statement, it can examine a status code. This status code (or return code) indicates whether the statement executed successfully or failed and gives the reason for the failure. You can use the same mechanism to indicate the success or failure of a CALL statement to a procedure.

Error reporting uses either the SQLCODE or SQLSTATE status descriptions. For full descriptions of SQLCODE and SQLSTATE error and warning values and their meanings, see ASA Error Messages. Whenever a SQL statement executes, a value appears in special procedure variables called SQLSTATE and SQLCODE. That value indicates whether or not there were any unusual conditions encountered while the statement was being performed. You can check the value of SQLSTATE or SQLCODE in an IF statement following a SQL statement, and take actions depending on whether the statement succeeded or failed.

For example, the SQLSTATE variable can be used to indicate if a row is successfully fetched. The TopCustomerValue procedure presented in section Using cursors on SELECT statements in procedures used the SQLSTATE test to detect that all rows of a SELECT statement had been processed.

Default error handling in procedures and triggers
Error handling with ON EXCEPTION RESUME
Default handling of warnings in procedures and triggers
Using exception handlers in procedures and triggers
Nested compound statements and exception handlers


Default error handling in procedures and triggers

This section describes how Adaptive Server Anywhere handles errors that occur during a procedure execution, if you have no error handling built in to the procedure.

For different behavior, you can use exception handlers, described in Using exception handlers in procedures and triggers. Warnings are handled in a slightly different manner from errors: for a description, see Default handling of warnings in procedures and triggers.

There are two ways of handling errors without using explicit error handling:

  • Default error handling The procedure or trigger fails and returns an error code to the calling environment.

  • ON EXCEPTION RESUME If the ON EXCEPTION RESUME clause appears in the CREATE PROCEDURE statement, the procedure carries on executing after an error, resuming at the statement following the one causing the error.

    The precise behavior for procedures that use ON EXCEPTION RESUME is dictated by the ON_TSQL_ERROR option setting. For more information, see ON_TSQL_ERROR option [compatibility].

Default error handling

Generally, if a SQL statement in a procedure or trigger fails, the procedure or trigger terminates execution and control returns to the application program with an appropriate setting for the SQLSTATE and SQLCODE values. This is true even if the error occurred in a procedure or trigger invoked directly or indirectly from the first one. In the case of a trigger, the operation causing the trigger is also undone and the error is returned to the application.

The following demonstration procedures show what happens when an application calls the procedure OuterProc, and OuterProc in turn calls the procedure InnerProc, which then encounters an error.

CREATE PROCEDURE OuterProc()
BEGIN
   MESSAGE 'Hello from OuterProc.' TO CLIENT;
   CALL InnerProc();
   MESSAGE 'SQLSTATE set to ',
      SQLSTATE,' in OuterProc.' TO CLIENT
END
CREATE PROCEDURE InnerProc()
   BEGIN
      DECLARE column_not_found
         EXCEPTION FOR SQLSTATE '52003';
      MESSAGE 'Hello from InnerProc.' TO CLIENT;
      SIGNAL column_not_found;
   MESSAGE 'SQLSTATE set to ',
      SQLSTATE, ' in InnerProc.' TO CLIENT;
END
Notes

  • The DECLARE statement in InnerProc declares a symbolic name for one of the predefined SQLSTATE values associated with error conditions already known to the server.

  • The MESSAGE statement sends a message to the Interactive SQL Messages pane.

  • The SIGNAL statement generates an error condition from within the InnerProc procedure.

The following statement executes the OuterProc procedure:

CALL OuterProc();

The Interactive SQL Messages pane displays the following:

Hello from OuterProc.

Hello from InnerProc.

None of the statements following the SIGNAL statement in InnerProc execute: InnerProc immediately passes control back to the calling environment, which in this case is the procedure OuterProc. None of the statements following the CALL statement in OuterProc execute. The error condition returns to the calling environment to be handled there. For example, Interactive SQL handles the error by displaying a message window describing the error.

The TRACEBACK function provides a list of the statements that were executing when the error occurred. You can use the TRACEBACK function from Interactive SQL by typing the following statement:

SELECT TRACEBACK(*)


Error handling with ON EXCEPTION RESUME

If the ON EXCEPTION RESUME clause appears in the CREATE PROCEDURE statement, the procedure checks the following statement when an error occurs. If the statement handles the error, then the procedure continues executing, resuming at the statement after the one causing the error. It does not return control to the calling environment when an error occurred.

The behavior for procedures that use ON EXCEPTION RESUME can be modified by the ON_TSQL_ERROR option setting. For more information, see ON_TSQL_ERROR option [compatibility].

Error-handling statements include the following:

  • IF

  • SELECT @variable =

  • CASE

  • LOOP

  • LEAVE

  • CONTINUE

  • CALL

  • EXECUTE

  • SIGNAL

  • RESIGNAL

  • DECLARE

  • SET VARIABLE

The following example illustrates how this works.

Drop the procedures

Remember to drop both the InnerProc and OuterProc procedures by entering the following commands in the SQL Statements pane before continuing with the tutorial:

DROP PROCEDURE OuterProc;
DROP PROCEDURE InnerProc

The following demonstration procedures show what happens when an application calls the procedure OuterProc; and OuterProc in turn calls the procedure InnerProc, which then encounters an error. These demonstration procedures are based on those used earlier in this section:

CREATE PROCEDURE OuterProc()
ON EXCEPTION RESUME
BEGIN
   DECLARE res CHAR(5);
   MESSAGE 'Hello from OuterProc.' TO CLIENT;
   CALL InnerProc();
   SELECT @res=SQLSTATE;
   IF res='52003' THEN
      MESSAGE 'SQLSTATE set to ',
         res, ' in OuterProc.' TO CLIENT;
   END IF
END;

CREATE PROCEDURE InnerProc()
ON EXCEPTION RESUME
BEGIN
   DECLARE column_not_found
      EXCEPTION FOR SQLSTATE '52003';
   MESSAGE 'Hello from InnerProc.' TO CLIENT;
   SIGNAL column_not_found;
   MESSAGE 'SQLSTATE set to ',
   SQLSTATE, ' in InnerProc.' TO CLIENT;
END

The following statement executes the OuterProc procedure:

CALL OuterProc();

The Interactive SQL Messages pane then displays the following:

Hello from OuterProc.

Hello from InnerProc.

SQLSTATE set to 52003 in OuterProc.

The execution path is as follows:

  1. OuterProc executes and calls InnerProc.

  2. In InnerProc, the SIGNAL statement signals an error.

  3. The MESSAGE statement is not an error-handling statement, so control is passed back to OuterProc and the message is not displayed.

  4. In OuterProc, the statement following the error assigns the SQLSTATE value to the variable named res. This is an error-handling statement, and so execution continues and the OuterProc message appears.


Default handling of warnings in procedures and triggers

Errors and warnings are handled differently. While the default action for errors is to set a value for the SQLSTATE and SQLCODE variables, and return control to the calling environment in the event of an error, the default action for warnings is to set the SQLSTATE and SQLCODE values and continue execution of the procedure.

Drop the procedures

Remember to drop both the InnerProc and OuterProc procedures by entering the following commands in the SQL Statements pane before continuing with the tutorial:

DROP PROCEDURE OuterProc;
DROP PROCEDURE InnerProc

The following demonstration procedures illustrate default handling of warnings. These demonstration procedures are based on those used in Default error handling in procedures and triggers. In this case, the SIGNAL statement generates a row not found condition, which is a warning rather than an error.

CREATE PROCEDURE OuterProc()
BEGIN
   MESSAGE 'Hello from OuterProc.' TO CLIENT;
   CALL InnerProc();
   MESSAGE 'SQLSTATE set to ',
      SQLSTATE,' in OuterProc.' TO CLIENT;
END
CREATE PROCEDURE InnerProc()
BEGIN
   DECLARE row_not_found
      EXCEPTION FOR SQLSTATE '02000';
   MESSAGE 'Hello from InnerProc.' TO CLIENT;
   SIGNAL row_not_found;
   MESSAGE 'SQLSTATE set to ',
   SQLSTATE, ' in InnerProc.' TO CLIENT;
END

The following statement executes the OuterProc procedure:

CALL OuterProc();

The Interactive SQL Messages pane then displays the following:

Hello from OuterProc. Hello from InnerProc. SQLSTATE set to 02000 in InnerProc. SQLSTATE set to 00000 in OuterProc.

The procedures both continued executing after the warning was generated, with SQLSTATE set by the warning (02000).

Execution of the second MESSAGE statement in InnerProc resets the warning. Successful execution of any SQL statement resets SQLSTATE to 00000 and SQLCODE to 0. If a procedure needs to save the error status, it must do an assignment of the value immediately after execution of the statement which caused the error warning.


Using exception handlers in procedures and triggers

It is often desirable to intercept certain types of errors and handle them within a procedure or trigger, rather than pass the error back to the calling environment. This is done through the use of an exception handler.

You define an exception handler with the EXCEPTION part of a compound statement (see Using compound statements). Whenever an error occurs in the compound statement, the exception handler executes. Unlike errors, warnings do not cause exception handling code to be executed. Exception handling code also executes if an error appears in a nested compound statement or in a procedure or trigger invoked anywhere within the compound statement.

Drop the procedures

Remember to drop both the InnerProc and OuterProc procedures by entering the following commands in the SQL Statements pane before continuing with the tutorial:

DROP PROCEDURE OuterProc;
DROP PROCEDURE InnerProc

The demonstration procedures used to illustrate exception handling are based on those used in Default error handling in procedures and triggers. In this case, additional code handles the column not found error in the InnerProc procedure.

CREATE PROCEDURE OuterProc()
BEGIN
   MESSAGE 'Hello from OuterProc.' TO CLIENT;
   CALL InnerProc();
   MESSAGE 'SQLSTATE set to ',
      SQLSTATE,' in OuterProc.' TO CLIENT
END
CREATE PROCEDURE InnerProc()
BEGIN
    DECLARE column_not_found
    EXCEPTION FOR SQLSTATE '52003';
    MESSAGE 'Hello from InnerProc.' TO CLIENT;
  SIGNAL column_not_found;
  MESSAGE 'Line following SIGNAL.' TO CLIENT;
    EXCEPTION
        WHEN column_not_found THEN
        MESSAGE 'Column not found handling.' TO CLIENT;
        WHEN OTHERS THEN
      RESIGNAL ;
END

The EXCEPTION statement declares the exception handler itself. The lines following the EXCEPTION statement do not execute unless an error occurs. Each WHEN clause specifies an exception name (declared with a DECLARE statement) and the statement or statements to be executed in the event of that exception. The WHEN OTHERS THEN clause specifies the statement(s) to be executed when the exception that occurred does not appear in the preceding WHEN clauses.

In this example, the statement RESIGNAL passes the exception on to a higher-level exception handler. RESIGNAL is the default action if WHEN OTHERS THEN is not specified in an exception handler.

The following statement executes the OuterProc procedure:

CALL OuterProc();

The Interactive SQL Messages pane then displays the following:

Hello from OuterProc. Hello from InnerProc. Column not found handling. SQLSTATE set to 00000 in OuterProc.

Notes

  • The EXCEPTION statements execute, rather than the lines following the SIGNAL statement in InnerProc.

  • As the error encountered was a column not found error, the MESSAGE statement included to handle the error executes, and SQLSTATE resets to zero (indicating no errors).

  • After the exception handling code executes, control passes back to OuterProc, which proceeds as if no error was encountered.

  • You should not use ON EXCEPTION RESUME together with explicit exception handling. The exception handling code is not executed if ON EXCEPTION RESUME is included.

  • If the error handling code for the column not found exception is simply a RESIGNAL statement, control passes back to the OuterProc procedure with SQLSTATE still set at the value 52003. This is just as if there were no error handling code in InnerProc. Since there is no error handling code in OuterProc, the procedure fails.

Exception handling and atomic compound statements

When an exception is handled inside a compound statement, the compound statement completes without an active exception and the changes before the exception are not reversed. This is true even for atomic compound statements. If an error occurs within an atomic compound statement and is explicitly handled, some but not all of the statements in the atomic compound statement are executed.


Nested compound statements and exception handlers

The code following a statement that causes an error executes only if an ON EXCEPTION RESUME clause appears in a procedure definition.

You can use nested compound statements to give you more control over which statements execute following an error and which do not.

Drop the procedures

Remember to drop both the InnerProc and OuterProc procedures by entering the following commands in the SQL Statements pane before continuing with the tutorial:

DROP PROCEDURE OuterProc;
DROP PROCEDURE InnerProc

The following demonstration procedure illustrates how nested compound statements can be used to control flow. The procedure is based on that used as an example in Default error handling in procedures and triggers.

CREATE PROCEDURE InnerProc()
BEGIN
   BEGIN
      DECLARE column_not_found
         EXCEPTION FOR SQLSTATE VALUE '52003';
         MESSAGE 'Hello from InnerProc' TO CLIENT;
         SIGNAL column_not_found;
            MESSAGE 'Line following SIGNAL' TO CLIENT
            EXCEPTION
         WHEN column_not_found THEN
            MESSAGE 'Column not found handling' TO
            CLIENT;
         WHEN OTHERS THEN
            RESIGNAL;
   END;
      MESSAGE 'Outer compound statement' TO CLIENT;
END

The following statement executes the InnerProc procedure:

CALL InnerProc();

The Interactive SQL Messages pane then displays the following:

Hello from InnerProc Column not found handling Outer compound statement

When the SIGNAL statement that causes the error is encountered, control passes to the exception handler for the compound statement, and the Column not found handling message prints. Control then passes back to the outer compound statement and the Outer compound statement message prints.

If an error other than column not found is encountered in the inner compound statement, the exception handler executes the RESIGNAL statement. The RESIGNAL statement passes control directly back to the calling environment, and the remainder of the outer compound statement is not executed.


Using the EXECUTE IMMEDIATE statement in procedures

The EXECUTE IMMEDIATE statement allows statements to be constructed inside procedures using a combination of literal strings (in quotes) and variables.

For example, the following procedure includes an EXECUTE IMMEDIATE statement that creates a table.

CREATE PROCEDURE CreateTableProc(
      IN tablename char(30) )
BEGIN
   EXECUTE IMMEDIATE 'CREATE TABLE '
   || tablename
   || '(column1 INT PRIMARY KEY)'
END

The EXECUTE IMMEDIATE statement can be used with queries that return result sets. For example:

CREATE PROCEDURE DynamicResult(
   IN Columns LONG VARCHAR,
   IN TableName CHAR(128),
   IN Restriction LONG VARCHAR DEFAULT NULL)
BEGIN
    DECLARE Command LONG VARCHAR;
    SET Command = 'SELECT ' || Columns || ' FROM ' || TableName;
    IF ISNULL( Restriction,'') <> '' THEN
         SET Command = Command || ' WHERE ' || Restriction;
    END IF;
    EXECUTE IMMEDIATE WITH RESULT SET ON Command;
END

The following statement calls this procedure:

CALL DynamicResult(
   'table_id,table_name',
   'SYSTABLE',
   'table_id <= 10')
table_id | table_name
1 | SYSTABLE
2 | SYSCOLUMN
3 | SYSINDEX
... | ...

In ATOMIC compound statements, you cannot use an EXECUTE IMMEDIATE statement that causes a COMMIT, as COMMITs are not allowed in that context.

For more information about the EXECUTE IMMEDIATE statement, see EXECUTE IMMEDIATE statement [SP].


Transactions and savepoints in procedures and triggers

SQL statements in a procedure or trigger are part of the current transaction (see Using Transactions and Isolation Levels). You can call several procedures within one transaction or have several transactions in one procedure.

COMMIT and ROLLBACK are not allowed within any atomic statement (see Atomic compound statements). Note that triggers are fired due to an INSERT, UPDATE, or DELETE which are atomic statements. COMMIT and ROLLBACK are not allowed in a trigger or in any procedures called by a trigger.

Savepoints (see Savepoints within transactions) can be used within a procedure or trigger, but a ROLLBACK TO SAVEPOINT statement can never refer to a savepoint before the atomic operation started. Also, all savepoints within an atomic operation are released when the atomic operation completes.


Tips for writing procedures

This section provides some pointers for developing procedures.

Check if you need to change the command delimiter
Remember to delimit statements within your procedure
Use fully-qualified names for tables in procedures
Specifying dates and times in procedures
Verifying that procedure input arguments are passed correctly


Check if you need to change the command delimiter

You do not need to change the command delimiter in Interactive SQL or Sybase Central when you write procedures. However, if you create and test procedures and triggers from some other browsing tool, you may need to change the command delimiter from the semicolon to another character.

Each statement within the procedure ends with a semicolon. For some browsing applications to parse the CREATE PROCEDURE statement itself, you need the command delimiter to be something other than a semicolon.

If you are using an application that requires changing the command delimiter, a good choice is to use two semicolons as the command delimiter (;;) or a question mark (?) if the system does not permit a multicharacter delimiter.


Remember to delimit statements within your procedure

You should terminate each statement within the procedure with a semicolon. Although you can leave off semicolons for the last statement in a statement list, it is good practice to use semicolons after each statement.

The CREATE PROCEDURE statement itself contains both the RESULT specification and the compound statement that forms its body. No semicolon is needed after the BEGIN or END keywords, or after the RESULT clause.


Use fully-qualified names for tables in procedures

If a procedure has references to tables in it, you should always preface the table name with the name of the owner (creator) of the table.

When a procedure refers to a table, it uses the group memberships of the procedure creator to locate tables with no explicit owner name specified. For example, if a procedure created by user_1 references Table_B and does not specify the owner of Table_B, then either Table_B must have been created by user_1 or user_1 must be a member of a group (directly or indirectly) that is the owner of Table_B. If neither condition is met, a table not found message results when the procedure is called.

You can minimize the inconvenience of long fully qualified names by using a correlation name to provide a convenient name to use for the table within a statement. Correlation names are described in FROM clause.


Specifying dates and times in procedures

When dates and times are sent to the database from procedures, they are sent as strings. The date part of the string is interpreted according to the current setting of the DATE_ORDER database option. As different connections may set this option to different values, some strings may be converted incorrectly to dates, or the database may not be able to convert the string to a date.

You should use the unambiguous date format yyyy-mm-dd or yyyy/mm/dd when using data strings within procedures. The server interprets these strings unambiguously as dates, regardless of the DATE_ORDER database option setting.

For more information on dates and times, see Date and time data types.


Verifying that procedure input arguments are passed correctly

One way to verify input arguments is to display the value of the parameter in the Interactive SQL Messages pane using the MESSAGE statement. For example, the following procedure simply displays the value of the input parameter var:

CREATE PROCEDURE message_test (IN var char(40))
BEGIN
   MESSAGE var TO CLIENT;
END

You can also use the stored procedure debugger.


Statements allowed in batches

All SQL statements are acceptable in batches (including data definition statements such as CREATE TABLE, ALTER TABLE, and so on), with the exception of the following:

  • CONNECT or DISCONNECT statement.

  • ALTER PROCEDURE or ALTER FUNCTION statement.

  • CREATE TRIGGER statement.

  • Interactive SQL commands such as INPUT or OUTPUT.

  • You cannot use host variables in batches.

The CREATE PROCEDURE statement is allowed, but must be the final statement of the batch. Therefore a batch can contain only a single CREATE PROCEDURE statement.

Using SELECT statements in batches


Using SELECT statements in batches

You can include one or more SELECT statements in a batch.

The following is a valid batch:

IF EXISTS(   SELECT *
            FROM SYSTABLE
            WHERE table_name='employee' )
THEN
   SELECT   emp_lname AS LastName,
            emp_fname AS FirstName
   FROM employee;
   SELECT lname, fname
   FROM customer;
   SELECT last_name, first_name
   FROM contact;
END IF

The alias for the result set is necessary only in the first SELECT statement, as the server uses the first SELECT statement in the batch to describe the result set.

A RESUME statement is necessary following each query to retrieve the next result set.


Calling external libraries from procedures

You can call a function in an external library from a stored procedure or user-defined function. You can call functions in a DLL under Windows operating systems, in an NLM under NetWare, and in a shared object on UNIX. You cannot call external functions on Windows CE.

This section describes how to use the external library calls in procedures. Sample external stored procedures, plus the files required to build a DLL containing them, are located in the following folder: %ASANY9%\Samples\Asa\ExternalProcedures.

Caution External libraries called from procedures share the memory of the server. If you call an external library from a procedure and the external library contains memory-handling errors, you can crash the server or corrupt your database. Ensure that you thoroughly test your libraries before deploying them on production databases.

The API described in this section replaces an older API. Libraries written to the older API, used in versions before version 7.0, are still supported, but in new development you should use the new API.

Adaptive Server Anywhere includes a set of system procedures that make use of this capability, for example to send MAPI e-mail messages.

For more information on system procedures, see System Procedures and Functions.

Creating procedures and functions with external calls
External function prototypes
Passing parameters to external functions
Hiding the contents of procedures, functions, triggers and views


Creating procedures and functions with external calls

This section presents some examples of procedures and functions with external calls.

DBA authority required
You must have DBA authority to create procedures or functions that reference external libraries. This requirement is more strict than the RESOURCE authority required for creating other procedures or functions.
Syntax

You can create a procedure that calls a function function_name in DLL library.dll as follows:

CREATE PROCEDURE dll_proc ( parameter-list )
EXTERNAL NAME 'function_name@library.dll'

If you call an external DLL from a procedure, the procedure cannot carry out any other tasks; it just forms a wrapper around the DLL.

An analogous CREATE FUNCTION statement is as follows:

CREATE FUNCTION dll_func ( parameter-list )
RETURNS data-type
EXTERNAL NAME 'function_name@library.dll'

In these statements, function_name is the exported name of a function in the dynamic link library, and library.dll is the name of the library. The arguments in parameter-list must correspond in type and order to the argument expected by the library function. The library function accesses the procedure argument using an API described in External function prototypes.

Any value returned by the external function is in turn returned by the procedure to the calling environment.

No other statements permitted

A procedure that references an external function can include no other statements: its sole purpose is to take arguments for a function, call the function, and return any value and returned arguments from the function to the calling environment. You can use IN, INOUT, or OUT parameters in the procedure call in the same way as for other procedures: the input values get passed to the external function, and any parameters modified by the function are returned to the calling environment in OUT or INOUT parameters.

System-dependent calls

You can specify operating-system dependent calls, so that a procedure calls one function when run on one operating system, and another function (presumably analogous) on another operating system. The syntax for such calls involves prefixing the function name with the operating system name. For example:

CREATE PROCEDURE dll_proc ( parameter-list )
EXTERNAL NAME
'Windows95:95_fn@95_lib.dll;WindowsNT:nt_fn@nt_lib.dll'

The operating system identifier must be one of WindowsNT, Windows95, UNIX, or NetWare.

If the list of functions does not contain an entry for the operating system on which the server is running, but the list does contain an entry without an operating system specified, the database server calls the function in that entry.

NetWare calls have a slightly different format than the other operating systems. All symbols are globally known under NetWare, so any symbol (such as a function name) exported must be unique to all NLMs on the system. Consequently, the NLM name is not necessary in the call as long as the NLM is already loaded.

It is recommended that you always use the library name, regardless of whether the NLM is already loaded. If the NLM is not already loaded, you must provide a library name. The file extension .nlm is optional.

For more information about the CREATE PROCEDURE statement syntax, see CREATE PROCEDURE statement.

For more information about the CREATE FUNCTION statement syntax, see CREATE FUNCTION statement.


External function prototypes

This section describes the API for functions in external libraries.

The API is defined by a header file named extfnapi.h, in the h subdirectory of your SQL Anywhere Studio installation directory. This header file handles the platform-dependent features of external function prototypes. The API supercedes a previous API for functions in external libraries.

Declaring the API version

To notify the database server that the external library is not written using the old API, provide a function as follows:

uint32 extfn_use_new_api( )

The function returns an unsigned 32-bit integer. If the return value is non-zero, the database server assumes that you are not using the old API.

If the function is not exported by the DLL, the database server assumes that the old API is in use. When using the new API, the returned value must be the API version number defined in extfnapi.h.

On NetWare, to notify the database server that the external procedure is written using the new API, your NLM must export either a function called extfn_use_new_api, or a function called name_use_new_api, where name is the name of the NLM. For example, an NLM named external.nlm would export a function external_use_new_api.

Exporting name_use_new_api avoids export name conflicts when more than one external NLM is in use at one time. If the NLM exports a function called name_use_new_api then the CREATE PROCEDURE or CREATE FUNCTION statement must contain the NLM name.

Function prototypes

The name of the function must match that referenced in the CREATE PROCEDURE or CREATE FUNCTION statement. The function declaration must be as follows:

void function-name( an_extfn_api *api, void *argument-handle )

The function must return void, and must take as arguments a structure used to pass the arguments, and a handle to the arguments provided by the SQL procedure.

The an_extfn_api structure has the following form:

typedef struct an_extfn_api {
    short (SQL_CALLBACK *get_value)(
                void *          arg_handle,
                a_SQL_uint32    arg_num,
                an_extfn_value *value
                );
    short (SQL_CALLBACK *get_piece)(
                void *          arg_handle,
                a_SQL_uint32    arg_num,
                an_extfn_value *value,
                a_SQL_uint32    offset
                );
    short (SQL_CALLBACK *set_value)(
                void *          arg_handle,
                a_SQL_uint32    arg_num,
                an_extfn_value *value
                short          append
                );
void (SQL_CALLBACK *set_cancel)(
                void *   arg_handle,
                void *   cancel_handle
                );
} an_extfn_api;

The an_extfn_value structure has the following form:

typedef struct an_extfn_value {
    void *            data;
    a_SQL_uint32       piece_len;
    union {
        a_SQL_uint32   total_len;
        a_SQL_uint32   remain_len;
    } len;
    a_SQL_data_type      type;
} an_extfn_value;
Notes

Calling get_value on an OUT parameter returns the data type of the argument, and returns data as NULL.

The get_piece function for any given argument can only be called immediately after the get_value function for the same argument,

To return NULL, set data to NULL in an_extfn_value.

The append field of set_value determines whether the supplied data replaces (false) or appends to (true) the existing data. You must call set_value with append=FALSE before calling it with append=TRUE for the same argument. The append field is ignored for fixed length data types.

The header file itself contains some additional notes.

The following table shows the conditions under which the functions defined in an_extfn_api return false:

Function | Returns 0 when the following is true; else returns 1
get_value() | - arg_num is invalid; for example, arg_num is greater than the number of arguments in ext_fn - It is called before the external function call has been properly initialized
get_piece() | - arg_num is invalid; for example, arg_num does not correspond to the last get_value. |- The offset is greater than the total length of the value for the arg_num argument. - It is called before the external function call has been properly initialized.
set_value() | - arg_num is invalid; for example, arg_num is greater than the number of arguments in ext_fn. - arg_num argument is input only. - The type of value supplied does not match that of the arg_num argument. - It is called before the external function call has been properly initialized.

For more information about the values you can enter in the a_sql_data_type field, see Embedded SQL data types.

For more information about passing parameters to external functions, see Passing parameters to external functions.

Implementing cancel processing

An external function that expects to be canceled must inform the database server by calling the set_cancel API function. You must export a special function to enable external operations to be canceled. This function must have the following form:

void an_extfn_cancel( void * cancel_handle )

If the DLL does not export this function, the database server ignores any user interrupts for functions in the DLL. In this function, cancel_handle is a pointer provided by the function being cancelled to the database server upon each call to the external function by the set_cancel API function listed in the an_extfn_api structure, above.


Passing parameters to external functions

Data types

The following SQL data types can be passed to an external library:

SQL data type | C type
CHAR | Character data, with a specified length
VARCHAR | Character data, with a specified length
LONG VARCHAR | Character data, with a specified length
BINARY | Binary data, with a specified length
LONG BINARY | Character data, with a specified length
TINYINT | 1-byte integer
[ UNSIGNED ] SMALLINT | [ Unsigned ] 2-byte integer
[ UNSIGNED ] INT | [ Unsigned ] 4-byte integer
[ UNSIGNED ] BIGINT | [ Unsigned ] 8-byte integer
VARBINARY | Binary data, with a specified length
REAL | Single precision floating point number
DOUBLE | Double precision floating point number

You cannot use date or time data types, and you cannot use exact numeric data types.

To provide values for INOUT or OUT parameters, use the set_value API function. To read IN and INOUT parameters, use the get_value API function.

Passing NULL

You can pass NULL as a valid value for all arguments. Functions in external libraries can supply NULL as a return type for any data type.

External function return types

The following table lists the supported return types, and how they map to the return type of the SQL function or procedure.

C data type | SQL data type
void | Used for external procedures.
char * | function returning CHAR().
long | function returning INTEGER
float | function returning FLOAT
double | function returning DOUBLE.

If a function in the external library returns NULL, and the SQL external function was declared to return CHAR(), then the return value of the SQL extended function is NULL.


Hiding the contents of procedures, functions, triggers and views

In some cases, you may want to distribute an application and a database without disclosing the logic contained within procedures, functions, triggers and views. As an added security measure, you can obscure the contents of these objects using the SET HIDDEN clause of the ALTER PROCEDURE, ALTER FUNCTION, ALTER TRIGGER, and ALTER VIEW statements.

The SET HIDDEN clause scrambles the contents of the associated objects and makes them unreadable, while still allowing the objects to be used. You can also unload and reload the objects into another database.

The modification is irreversible, and for databases created using version 8.0 or higher, deletes the original text of the object. Preserving the original source for the object outside the database is required.

Debugging using the stored procedure debugger will not show the procedure definition, nor will procedure profiling display the source.

Running one of the above statements on an object that is already hidden has no effect.

To hide the text for all objects of a particular type, you can use a loop similar to the following:

begin
    for hide_lp as hide_cr cursor for
        select proc_name,user_name
        from SYS.SYSPROCEDURE p, SYS.SYSUSERPERM u
        where p.creator = u.user_id
        and p.creator not in (0,1,3)
    do
        message 'altering ' || proc_name;
        execute immediate 'alter procedure "' ||
            user_name || '"."' || proc_name
            || '" set hidden'
    end for
end

For more information, see the ALTER FUNCTION statement, the ALTER PROCEDURE statement, the ALTER TRIGGER statement, and the ALTER VIEW statement.


Debugging Logic in the Database

About this chapter

This chapter describes how to use the Sybase debugger to assist in developing SQL stored procedures, triggers, and event handlers as well as Java stored procedures.

Introduction to debugging in the database
Tutorial: Getting started with the debugger
Working with breakpoints
Working with variables
Working with connections


Introduction to debugging in the database

You can use the debugger during the development of the following objects:

  • SQL stored procedures, triggers, event handlers, and user-defined functions.

  • Java stored procedures in the database.

This chapter describes how to set up and use the debugger.

Separately-licensable component

Java in the database is a separately licensable component and must be ordered before you can install it. To order this component, see the card in your SQL Anywhere Studio package or see [external link] http://www.sybase.com/detail?id=1015780.


Debugger features

You can carry out many tasks with the debugger, including the following:

  • Debug procedures and triggers You can debug SQL stored procedures and triggers.

  • Debug event handlers Event handlers are an extension of SQL stored procedures. The material in this chapter about debugging stored procedures applies equally to debugging event handlers.

  • Browse stored procedures and classes You can browse through the source code of SQL procedures. You can also browser the source code of installed Java classes as long as the code for those classes is available on your disk.

  • Debug Java classes You can debug Java classes that are stored in the database.

  • Trace execution Step line by line through the code of a stored procedure or Java class running in the database. You can also look up and down the stack of functions that have been called.

  • Set breakpoints Run the code until you hit a breakpoint, and stop at that point in the code.

  • Set break conditions Breakpoints include lines of code, but you can also specify conditions when the code is to break. For example, you can stop at a line the tenth time it is executed, or only if a variable has a particular value. You can also stop whenever a particular exception is thrown in a Java application.

  • Inspect and modify local variables When execution is stopped at a breakpoint, you can inspect the values of local variables and alter their value.

  • Inspect and break on expressions When execution is stopped at a breakpoint, you can inspect the value of a wide variety of expressions.

  • Inspect and modify row variables Row variables are the OLD and NEW values of row-level triggers. You can inspect and modify these values.

  • Execute queries When execution is stopped at a breakpoint in a SQL procedure, you can execute queries. This permits you to look at intermediate results held in temporary tables, as well as to check values in base tables and to view the query execution plan.


Requirements for using the debugger

You need the following in order to use the debugger:

  • Permissions In order to use the debugger, you must either have DBA authority or be granted permissions in the SA_DEBUG group. This group is added to all databases when they are created.

  • Source code for Java classes The source code for your application must be available to the debugger. For Java classes, the source code is held on a directory on your hard disk. For stored procedures, the source code is held in the database.

  • Compilation options To debug Java classes, they must be compiled so that they contain debugging information. For example, if you are using the Sun Microsystems JDK compiler javac.exe, they must be compiled using the -g command-line option.


Tutorial: Getting started with the debugger

This tutorial describes how to start the debugger, how to connect to a database, how to debug a simple stored procedure, and how to debug a Java class.


Lesson 1: Connect to a database and start the debugger

This tutorial shows you how to start the debugger, connect to a database, and attach to a connection for debugging. It uses the Adaptive Server Anywhere sample database.

Start the debugger


Start the debugger
toggle To start the debugger

  1. Start Sybase Central:

    Choose Start > Programs > SQL Anywhere 9 > Sybase Central.

  2. Connect to the database.

    In this tutorial, you connect to the Adaptive Server Anywhere sample database.

    1. In the left pane, right click Adaptive Server Anywhere and choose Connect from the popup menu.

      The connection dialog appears.

  3. Choose Debug mode.

    Sybase Central can be used in Design mode or Debug mode. When running in Debug mode, debugger breakpoints are active. Also, Sybase Central shows debugging menus and a Debugger Details pane.

    To choose Debug mode, click Task > Debug. The Debugger Details pane appears at the bottom of Sybase Central and the Adaptive Server Anywhere toolbar displays a set of debugger tools.

    The Debugger Details pane


Lesson 2: Debug a stored procedure

This tutorial describes a sample session for debugging a stored procedure. It is a continuation of Lesson 1: Connect to a database and start the debugger.

This tutorial illustrates how to use the debugger to identify errors in stored procedures. To set the stage, you introduce a deliberate error into the stored procedure debugger_tutorial, which is part of the sample database.

The debugger_tutorial procedure should return a result set that contains the name of the company that has placed the highest value of orders, and the value of their orders. It computes these values by looping over the result set of a query that lists companies and orders. (This result could be achieved without adding the logic into the procedure, by using a SELECT FIRST query. The procedure is used to create a convenient example.) The procedure has an intentional bug in it. In this tutorial you diagnose and fix the bug.


Run the debugger_tutorial procedure

The debugger_tutorial procedure should return a result set consisting of the top company and the value of products they have ordered. As a result of a bug, it does not return this result set. In this lesson, you run the stored procedure.

toggle To run the debugger_tutorial stored procedure

  1. In the Sybase Central left pane, open the Procedures and Functions folder.

  2. Execute the procedure.

    Right click the debugger_tutorial procedure and choose Execute from Interactive SQL from the popup menu.

    An Interactive SQL window opens and the following result set is displayed:

    top_company | top_value
    (NULL) | (NULL)

    This is clearly an incorrect result. The remainder of the tutorial diagnoses the error that produced this result.

  3. Close the Interactive SQL window to clear your workspace.


Diagnose the bug

To diagnose the bug in the procedure, set breakpoints in the procedure and step through the code, watching the value of variables as the procedure is executed.

Here, you set a breakpoint at the first executable statement in the procedure.

toggle To diagnose the bug

  1. Change Sybase Central to Debug mode.

    From the Task menu, choose Debug. Sybase Central displays a Debugger Details pane at the bottom of the main window.

  2. Set a breakpoint at the first executable statement in the procedure.

    The statement contains the following text:

    open cur_this_cust;

    Click to the left of this line in the vertical gray bar to set a breakpoint. The breakpoint appears as a red circle. An alternative way to set a breakpoint is to press F9.

  3. Execute the procedure again.

    1. In the left pane, right click the sp_customer_products procedure and choose Execute from Interactive SQL from the popup menu.

    2. A message box appears, asking if you want to debug the connection from Interactive SQL. Click Yes.

      Execution of the procedure stops at the breakpoint. A yellow arrow in the source code window indicates the current position, which is at the breakpoint.

  4. Inspect variables.

    The Local variables window in the Debugger Details pane displays a list of variables in the procedure together with their current value and data type. The top_company, top_value, this_value, and this_company variables are all uninitialized and are therefore NULL.

  5. Step through the code.

    Press F11 several times to step through the code, until you reach the following line:

      if this_value > top_value then

    As you step through the lines of the stored procedure, the value of the variables changes.

    When you are at the if statement, this_value is set to 3000 and top_value is still NULL.

  6. Step into one more statement.

    Press F11 once more to see which branch the execution takes. The yellow arrow moves directly back to the label statement at the beginning of the loop, which contains the following text:

    customer loop: loop

    The if test did not return true. The test failed because a comparison of any value to NULL returns NULL. A value of NULL fails the test and the code inside the if...end if statement is not executed.

    At this point, you may realize that the problem is the fact that top_value is not initialized.


Confirm the diagnosis and fix the bug

You can test the hypothesis that the problem is the lack of initialization for top_value right in the debugger, without changing the procedure code.

toggle To test the hypothesis

  1. Set a value for top_value.

    In the Local window, click the Value field of the top_value variable, and enter a value of 3000.

  2. Step through the loop again.

    Press F11 to step through the instructions to the if statement and check the values of this_value and top_value. You may have to step through several loops until you get a value of top_value greater than 3000.

  3. Disable the breakpoint and execute the procedure.

    1. Click the breakpoint so that it turns gray (disabled).

    2. Press F5 to complete execution of the procedure.

      The Interactive SQL window appears again. It shows the correct results.

      top_company | top_value
      Chadwicks | 8076

    The hypothesis is confirmed. The problem is that the top_value is not initialized.

toggle To fix the bug

  1. From the Task menu, choose Design to leave Debug mode.

  2. Immediately after the line containing the following text

    open cur_this_cust;

    Create a new line that initializes the top_value variable:

    set top_value = 0;

  3. Press Ctrl+S to save the modified procedure.

  4. Execute the procedure again, and confirm that Interactive SQL displays the correct results.

You have now completed the lesson. Close down Sybase Central and any open Interactive SQL windows.


Lesson 3: Debug a Java class

This lesson describes a sample session for debugging a Java class.

This lesson requires that you have the Java in the database component.

Separately licensable option required
Java in the database is a separately licensable component and must be ordered before you can install it.

To order this component, see Separately-licensable components.

In this lesson, you call JDBCExamples.Query() from Interactive SQL, interrupt the execution in the debugger, and trace through the source code for this method.

The JDBCExamples.Query() method executes the following query against the sample database:

SELECT id, unit_price
FROM product

It then loops through all the rows of the result set, and returns the one with the highest unit price.

Compiling Java classes for debugging

You must compile classes with the javac -g option in order to debug them. The sample classes are already compiled for debugging.


Prepare the database

To work through this tutorial, you must enable the sample database to use Java, and install JDBCExamples.class into the sample database.

For instructions, see Setting up the Java sample.

For information about the JDBCExamples class and its methods, see JDBC Programming.


Display Java source code in the debugger

The debugger looks in a set of locations for source code files (with .java extension). You need to add the Samples\ASA\Java subdirectory of your installation directory to the list of locations, so that the code for the class currently being executed in the database is available to the debugger.

toggle To display Java source code in the debugger

  1. Start Sybase Central and connect to the sample database (ASA 9.0 Sample ODBC data source).

  2. Choose the Sybase Central Debug task.

    Choose Task > Debug.

  3. Set the locations in which to look for Java source code.

    1. From the Debug menu, choose Set Java Source Path. The Java Source Path window appears.

    2. Click Browse Folder. Navigate to the folder where your Java source code (.java files) is stored. To view the source code for the JDBCExamples class, browse to the Samples\ASA\Java subdirectory of your SQL Anywhere installation. If you installed SQL Anywhere in the default installation directory, you would navigate to the following directory:

      C:\Program Files\Sybase\SQL Anywhere 9\Samples\ASA\Java

  4. Display the source code for the JDBCExamples class:

    1. In the Sybase Central left pane, open the Java Objects folder.

    2. In the right pane, open the All Java Classes folder and locate the JAR file or class you wish to debug. Depending on your Sybase Central settings, you may wish to click the Creator column. This sorts the listing by creator so that classes owned by DBA appear before those owned by SYS.

    3. Double-click the JDBCExamples class.

    4. In the right pane, click the Source tab. The source code for the class is displayed.


Set a breakpoint
toggle Set a breakpoint in a Java class

  1. In the source code window, page down until you see the beginning of the Query method. This method is near the end of the class, and starts with the following line:

    public static int Query() {

  2. Click the gray column on the left of the line until it shows a red circle.

    int max_price = 0;

    Repeatedly clicking the indicator toggles its status.


Run the method
toggle Invoke the method from Interactive SQL

  1. Start Interactive SQL. Connect to the sample database as used ID DBA and password SQL.

  2. Enter the following command in Interactive SQL to invoke the method:

    SELECT JDBCExamples.Query()

    The query does not complete. Instead, execution is stopped in the debugger at the breakpoint. In Interactive SQL, the Interrupt the SQL Statement button is enabled. In the debugger Source window, the yellow arrow indicates the current line.

You can now step through source code and carry out debugging activities in the debugger.


Step through source code

This section illustrates some of the ways you can step through code in the debugger.

Following the previous section, the debugger should have stopped execution of JDBCExamples.Query at the first statement in the method:

Examples

Here are some example steps you can try:

  1. Step to the next line Choose Debug > Step Over, or press F10 to step to the next line in the current method. Try this two or three times.

  2. Run to the cursor Select the following line using the mouse, and choose Debug > Run To Cursor, or press Ctrl+F10 to run to that line and break:

    max_price = price;

    The yellow arrow moves to the line.

  3. Set a breakpoint and execute to it Put the cursor at the following line (line 292) and press F9 to set a breakpoint on that line:

    return max_price;

    A red stop sign appears in the left-hand column to mark the breakpoint. Press F5 to execute to that breakpoint.

  4. Experiment Try different methods of stepping through the code. End with F5 to complete the execution.

    The complete set of options for stepping through source code is available from the Debug menu.

    When you have completed the execution, the Interactive SQL Results pane in the Results tab displays the value 24.


Inspect and modify variables

In this lesson you inspect the values of both local variables (declared in a method) and class static variables in the debugger.

Inspecting local variables

You can inspect the values of local variables in a method as you step through the code, to better understand what is happening. You must have compiled the class with the javac -g option to do this.

toggle To inspect and modify the value of a variable

  1. Set a breakpoint at the first line of the JDBCExamples.Query method. This line is as follows:

    int max_price = 0

  2. In Interactive SQL, enter the following statement again to execute the method:

    SELECT JDBCExamples.Query()

    The query executes only as far as the breakpoint.

  3. Press F10 to step to the next line. The max_price variable has now been declared and initialized to zero.

  4. In the Local tab list, double-click the Value column entry for max_price, and type in 45 to change the value of max_price to 45.

    The value 45 is larger than any other price. Instead of returning 24, the query will now return 45 as the maximum price.

  5. Press F10 repeatedly to step through the code. As you do so, the values of the variables appear in the Local tab list. Step through until the stmt and result variables have values.

  6. Expand the result object by clicking the icon next to it, or setting the cursor on the line and pressing Enter. This displays the values of the fields in the object.

  7. When you have experimented with inspecting and modifying variables, press F5 to complete the execution of the query and finish the tutorial.

Inspecting static variables

In addition to local variables, you can display class-level variables (static variables) in the debugger Statics tab, and watch their values in the Watch tab. For more information, see the debugger online Help.


Working with breakpoints

This section describes how to use breakpoints to control when the debugger interrupts execution of your source code.


Setting breakpoints

A breakpoint instructs the debugger to interrupt execution at a specified line.

toggle To set a breakpoint

  1. With Sybase Central running the Debug task, display the code where you wish to set a breakpoint.

  2. Click in the gray column on the left of the window, or click a line and press F9 to set the breakpoint. A red circle indicates each line with a breakpoint.

toggle To set a breakpoint (Debug menu)

  1. Display the Breakpoints window.

    With Sybase Central running the Debug task, choose Debug > Breakpoints.

  2. In the Breakpoints window, click New Breakpoint. The New Breakpoint window is displayed.

  3. Choose a Procedure name from the drop down list, and optionally enter condition and count values.

    The Condition is a SQL or Java expression that must evaluate to true for the breakpoint to interrupt execution. For example, you can set a breakpoint to apply to a connection made by a specified user, you can enter the following condition:

    CURRENT USER = 'user-name'

    The Count is a number of times the breakpoint is hit before it stops execution. A value of 0 means that the breakpoint always stops execution.

  4. Click OK to set the breakpoint. The breakpoint is set on the first executable statement in the procedure.

When you set a breakpoint, it applies to all connections. To make a breakpoint apply to a specific connection only, set a condition on the breakpoint.

toggle To set a condition on a breakpoint

  1. Right click the breakpoint marker and choose Edit Breakpoint from the popup menu. The Edit Breakpoint dialog appears.

  2. Enter a condition in the Condition field. For example, to set the breakpoint so that it applies only to connections from a specific user ID, enter the following condition:

    CURRENT USER='user-name'

    where user-name is the user ID for which the breakpoint is to be active.


Disabling and enabling breakpoints

You can change the status of a breakpoint from the Sybase Central right pane or from the Breakpoints window.

toggle To change the status of a breakpoint

  1. Display the source code for the procedure that contains the breakpoint whose status you wish to change.

  2. Click the breakpoint indicator on the left of the line you wish to edit. The status of the line switches from being an active breakpoint being a disabled breakpoint.

toggle To change the status of a breakpoint (Breakpoints window)

  1. Open the Breakpoints window.

  2. Edit the breakpoint.

  3. Alternatively, you can delete a breakpoint by selecting the breakpoint and pressing Delete.


Editing breakpoint conditions

You can add conditions to breakpoints, to instruct the debugger to interrupt execution at that breakpoint only when a certain condition or count is satisfied.

toggle To add a condition or count to a breakpoint

  • Open the Breakpoints window.

    For a Java class, the condition must be a Java boolean expression. For procedures and triggers, it must be a SQL search condition.

Examples

In the procedure sp_contacts, you might use the breakpoint

contact.id = contact.old_id

on the line

DELETE FROM contact WHERE contact.id = contact.old_id

In the Java method JDBCExamples.Query(), you might use the breakpoint condition

(price < 10)

on the line

if (max.price == price) or (price == 10)


Working with variables

The debugger lets you view and edit the behavior of your variables while stepping through your code. The debugger provides a Debugger Details window to display the different kinds of variables used in stored procedures and Java classes. The Debugger Details windows appear at the bottom of the Sybase Central window when Sybase Central is running the Debug task.

Local variables
toggle To watch the values of your variables

  1. Set a breakpoint in the procedure whose variables you wish to examine.

    For information on setting breakpoints, see Setting breakpoints.

  2. Click the Local tab on the Variables pane of the Debugger Details.

  3. Run the procedure. The variables, along with their values, appear in the Local tab.

Other variables

Global variables are defined by Adaptive Server Anywhere and hold information about the current connection, database, and other settings. They are displayed on the Globals tab of the Variables window.

For a list of global variables, see Global variables.

Row variables are used to hold the values used in triggers. They are displayed on the Row tab of the Variables window.

For more information on triggers, see Introduction to triggers.

Static variables are used in Java classes. They are displayed in the Statics tab.

The call stack

It is useful to examine the sequence of calls that has been made when you are debugging nested procedures or Java classes. You can view a listing of the procedures in the Call Stack tab.

toggle To display the call stack

  1. Set a breakpoint in the procedure whose variables you wish to examine.

  2. Run the code to the breakpoint.

    The names of the procedures appear in the Calls Stack tab. The current procedure is shown at the top of the list. The procedure that called it is immediately below, and so on.


Working with connections

The Connection window displays the connections to the database. At any time, multiple connections may be running. Some may be stopped at a breakpoint, and others may not.

The source code window displays the state for a single connection. To switch connections, double-click a connection in the Connections window.

A useful technique is to set a breakpoint so that it interrupts execution for a single user ID. You can do this by setting a breakpoint condition of the following form:

CURRENT USER = 'user-name'

The SQL special value CURRENT USER holds the user ID of the connection.

For more information, see Editing breakpoint conditions, and CURRENT USER special value.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

Version 9.0.2

DC38129-01-0902-01

October 2004

Copyright
About This Manual
SQL Language Elements
SQL Data Types
SQL Functions
SQL Statements
System Tables
System Views
System Procedures and Functions


About This Manual

Subject

This book provides a complete reference for the SQL language used by Adaptive Server Anywhere. It also describes the Adaptive Server Anywhere system tables and procedures.

While other manuals provide more motivation and context for how to carry out particular tasks, this manual is the place to look for complete listings of available SQL syntax and system objects.

Audience

This manual is for all users of Adaptive Server Anywhere. It includes material of particular interest to users of MobiLink and SQL Remote. It is to be used in conjunction with other manuals in the documentation set.


Documentation conventions

This section lists the typographic and graphical conventions used in this documentation.

toggle Syntax conventions

The following conventions are used in the SQL syntax descriptions:

  • Keywords All SQL keywords appear in upper case, like the words ALTER TABLE in the following example:

    ALTER TABLE [ owner.]table-name

  • Placeholders Items that must be replaced with appropriate identifiers or expressions are shown like the words owner and table-name in the following example:

    ALTER TABLE [ owner.]table-name

  • Repeating items Lists of repeating items are shown with an element of the list followed by an ellipsis (three dots), like column-constraint in the following example:

    ADD column-definition [ column-constraint, ... ]

    One or more list elements are allowed. In this example, if more than one is specified, they must be separated by commas.

  • Optional portions Optional portions of a statement are enclosed by square brackets.

    RELEASE SAVEPOINT [ savepoint-name ]

    These square brackets indicate that the savepoint-name is optional. The square brackets should not be typed.

  • Options When none or only one of a list of items can be chosen, vertical bars separate the items and the list is enclosed in square brackets.

    [ ASC | DESC ]

    For example, you can choose one of ASC, DESC, or neither. The square brackets should not be typed.

  • Alternatives When precisely one of the options must be chosen, the alternatives are enclosed in curly braces and a bar is used to separate the options.

    [ QUOTES { ON | OFF } ]

    If the QUOTES option is used, one of ON or OFF must be provided. The brackets and braces should not be typed.

Graphic icons

The following icons are used in this documentation.

  • A client application.

    The icon for a client application: a box containing three triangles in a circle.

  • A database server, such as Sybase Adaptive Server Anywhere.

    The icon for a database server: a box containing a schematic table in a circle.

  • A database. In some high-level diagrams, the icon may be used to represent both the database and the database server that manages it.

    The icon for a database: a cylinder.

  • Replication or synchronization middleware. These assist in sharing data among databases. Examples are the MobiLink Synchronization Server and the SQL Remote Message Agent.

    The icon for replication or synchronization middleware: a box containing an arrow in a circle.

  • A programming interface.

    The icon for a client application: a shaded box with rounded ends.


SQL Language Elements

About this chapter

This chapter describes the elements and conventions of the SQL language.


Keywords

Each SQL statement contains one or more keywords. SQL is case insensitive to keywords, but throughout these manuals, keywords are indicated in upper case.

For example, in the following statement, SELECT and FROM are keywords:

SELECT *
FROM employee

The following statements are equivalent to the one above:

Select *
From employee
select * from employee
sELECT * FRoM employee

Some keywords cannot be used as identifiers without surrounding them in double quotes. These are called reserved words. Other keywords, such as DBA, do not require double quotes, and are not reserved words.

Reserved words


Reserved words

Some keywords in SQL are also reserved words. To use a reserved word in a SQL statement as an identifier, you must enclose it in double quotes. Many, but not all, of the keywords that appear in SQL statements are reserved words. For example, you must use the following syntax to retrieve the contents of a table named SELECT.

SELECT *
FROM "SELECT"

Because SQL is not case sensitive with respect to keywords, each of the following words may appear in upper case, lower case, or any combination of the two. All strings that differ only in capitalization from one of the following words are reserved words.

If you are using Embedded SQL, you can use the database library function SQL_needs_quotes to determine whether a string requires quotation marks. A string requires quotes if it is a reserved word or if it contains a character not ordinarily allowed in an identifier.

The SQL keywords in Adaptive Server Anywhere are as follows:

Reserved word | Reserved word | Reserved word | Reserved word
add | all | alter | and
any | as | asc | backup
begin | between | bigint | binary
bit | bottom | break | by
call | capability | cascade | case
cast | char | char_convert | character
check | checkpoint | close | comment
commit | conflict | connect | constraint
contains | continue | convert | create
cross | cube | current | current_timestamp
current_user | cursor | date | dbspace
deallocate | dec | decimal | declare
default | delete | deleting | desc
distinct | do | double | drop
dynamic | else | elseif | encrypted
end | endif | escape | except
exception | exec | execute | existing
exists | externlogin | fetch | first
float | for | force | foreign
forward | from | full | goto
grant | group | having | holdlock
identified | if | in | index
index_lparen | inner | inout | insensitive
insert | inserting | install | instead
int | integer | integrated | intersect
into | iq | is | isolation
join | key | lateral | left
like | lock | login | long
match | membership | message | mode
modify | natural | new | no
noholdlock | not | notify | null
numeric | of | off | on
open | option | options | or
order | others | out | outer
over | passthrough | precision | prepare
primary | print | privileges | proc
procedure | publication | raiserror | readtext
real | reference | references | release
remote | remove | rename | reorganize
resource | restore | restrict | return
revoke | right | rollback | rollup
save | savepoint | scroll | select
sensitive | session | set | setuser
share | smallint | some | sqlcode
sqlstate | start | stop | subtrans
subtransaction | synchronize | syntax_error | table
temporary | then | time | timestamp
tinyint | to | top | tran
trigger | truncate | tsequal | unbounded
union | unique | uniqueidentifier | unknown
unsigned | update | updating | user
using | validate | values | varbinary
varchar | variable | varying | view
wait | waitfor | when | where
while | window | with | with_cube
with_lparen | with_rollup | within | work
writetext |  |  |


Identifiers

toggle Function

Identifiers are names of objects in the database, such as user IDs, tables, and columns.

toggle Description

Identifiers have a maximum length of 128 bytes. They must be enclosed in double quotes or square brackets if any of the following conditions are true:

  • The identifier contains spaces.

  • The first character of the identifier is not an alphabetic character (as defined below).

  • The identifier contains a reserved word.

  • The identifier contains characters other than alphabetic characters and digits.

Alphabetic characters include the alphabet, as well as the underscore character (_), at sign (@), number sign (#), and dollar sign ($). The database collation sequence dictates which characters are considered alphabetic or digit characters.

The following characters are not permitted in identifiers:

  • Double quotes

  • Control characters (any character less than 0x20)

  • Double backslashes

You can use a single backslash in an identifier only if it is used as an escape character.

If the QUOTED_IDENTIFIER database option is set to OFF, double quotes are used to delimit SQL strings and cannot be used for identifiers. However, you can always use square brackets to delimit identifiers, regardless of the setting of QUOTED_IDENTIFIER. The default setting for the QUOTED_IDENTIFIER option is to OFF for Open Client and jConnect connections; otherwise the default is ON.

You can represent an apostrophe (single quote) inside an identifier by following it with another apostrophe.

toggle See also
  • For a complete list of the reserved words, see Reserved words.
  • For information about the QUOTED_IDENTIFIER option, see QUOTED_IDENTIFIER option [compatibility].
toggle Examples

The following are all valid identifiers.

Surname
"Surname"
[Surname]
SomeBigName
"Client Number"


Strings

Strings are of the following types:

  • literal strings

  • expressions with CHAR or VARCHAR data types.

An expression with a CHAR data type may be a built-in or user-defined function, or one of the many other kinds of expressions available.

For more information on expressions, see Expressions.

A literal string is any sequence of characters enclosed in apostrophes ('single quotes'). A SQL variable of character data type can hold a string. The following is a simple example of a literal string:

'This is a string.'
Special characters in strings

You represent special character in strings by escape sequences, as follows:

  • To represent an apostrophe inside a string, use two apostrophes in a row. For example,

    'John''s database'

  • To represent a new line character, use a backslash followed by n (\n). For example,

    'First line:\nSecond line:'

  • To represent a backslash character, use two backslashes in a row (\\). For example,

    'c:\\temp'

  • Hexadecimal escape sequences can be used for any character, printable or not. A hexadecimal escape sequence is a backslash followed by an x followed by two hexadecimal digits (for example, \x6d represents the letter m). For example,

    '\x00\x01\x02\x03'
toggle See also
  • For information about the handling of strings in dynamically constructed SQL statements, see EXECUTE IMMEDIATE statement [SP].
toggle Standards and compatibility

For compatibility with Adaptive Server Enterprise, you can set the QUOTED_IDENTIFIER database option to OFF. With this setting, you can also use double quotes to mark the beginning and end of strings. The option is set to ON by default.

For information about the QUOTED_IDENTIFIER option, see QUOTED_IDENTIFIER option [compatibility].


Operators

This section describes arithmetic, string, and bit-wise operators. For information on comparison operators, see the section Search conditions.

The normal precedence of operations applies. Expressions in parentheses are evaluated first, then multiplication and division before addition and subtraction. String concatenation happens after addition and subtraction.

For more information, see Operator precedence.


Comparison operators

The syntax for comparison conditions is as follows:

expression compare expression

where compare is a comparison operator. The following comparison operators are available:

operator | description
= | Equal to
> | Greater than
< | Less than
>= | Greater than or equal to
<= | Less than or equal to
!= | Not equal to
<> | Not equal to
!> | Not greater than
!< | Not less than
Case sensitivity
All string comparisons are case insensitive unless the database was created as case sensitive.
toggle Standards and compatibility

  • Trailing blanks Any trailing blanks in character data are ignored for comparison purposes by Adaptive Server Enterprise. The behavior of Adaptive Server Anywhere when comparing strings is controlled the –b command-line switch that is set when creating the database.

    For more information about blank padding, see Initialization utility options.

  • Case sensitivity By default, Adaptive Server Anywhere databases are created as case insensitive, while Adaptive Server Enterprise databases are created as case sensitive. Comparisons are carried out with the same attention to case as the database they are operating on. You can control the case sensitivity of Adaptive Server Anywhere databases with the -c command line switch when you create the database.

    For more information about case sensitivity for string comparisons, see Initialization utility options.


Logical operators

Search conditions can be combined using AND, OR, and NOT.

Conditions are combined using AND as follows:

condition1 AND condition2

The combined condition is TRUE if both conditions are TRUE, FALSE if either condition is FALSE, and UNKNOWN otherwise.

Conditions are combined using OR as follows:

condition1 OR condition2

The combined condition is TRUE if either condition is TRUE, FALSE if both conditions are FALSE, and UNKNOWN otherwise.

The syntax for the NOT operator is as follows:

NOT condition

The NOT condition is TRUE if condition is FALSE, FALSE if condition is TRUE, and UNKNOWN if condition is UNKNOWN.

The IS operator provides a means to test a logical value. The syntax for the IS operator is as follows:

expression IS [ NOT ] truth-value

The condition is TRUE if the expression evaluates to the supplied truth-value, which must be one of TRUE, FALSE, UNKNOWN, or NULL. Otherwise, the value is FALSE.

For more information, see Three-valued logic.

toggle Standards and compatibility

  • The logical operators are compatible between Adaptive Server Anywhere and Adaptive Server Enterprise.


Arithmetic operators

expression + expression Addition. If either expression is the NULL value, the result is NULL.

expression - expression Subtraction. If either expression is the NULL value, the result is NULL.

-expression Negation. If the expression is the NULL value, the result is NULL.

expression * expression Multiplication. If either expression is NULL, the result is NULL.

expression / expression Division. If either expression is NULL or if the second expression is 0, the result is NULL.

expression % expression Modulo finds the integer remainder after a division involving two whole numbers. For example, 21 % 11 = 10 because 21 divided by 11 equals 1 with a remainder of 10.

toggle Standards and compatibility

  • Modulo The % operator can be used in Adaptive Server Anywhere only if the PERCENT_AS_COMMENT option is set to OFF. The default value is ON.


String operators

expression || expression String concatenation (two vertical bars). If either string is NULL, it is treated as the empty string for concatenation.

expression + expression Alternative string concatenation. When using the + concatenation operator, you must ensure the operands are explicitly set to character data types rather than relying on implicit data conversion.

For example, the following query returns the integer value 579:

SELECT 123 + 456

whereas the following query returns the character string 123456:

SELECT '123' + '456'

You can use the CAST or CONVERT function to explicitly convert data types.

toggle Standards and compatibility

  • SQL/92 The || operator is the SQL/92 string concatenation operator.

  • Sybase The + operator is supported by Adaptive Server Enterprise.

    The || concatenation operator is not supported by Adaptive Server Enterprise.


Bitwise operators

The following operators can be used on integer data types, in both Adaptive Server Anywhere and Adaptive Server Enterprise.

Operator | Description
& | bitwise AND
| | bitwise OR
^ | bitwise exclusive OR
~ | bitwise NOT

The bitwise operators &, | and ~ are not interchangeable with the logical operators AND, OR, and NOT.

toggle Example

For example, the following statement selects rows in which the correct bits are set.

SELECT *
FROM tableA
WHERE (options & 0x0101) <> 0


Join operators

The Transact-SQL outer join operators *= and =* are supported in Adaptive Server Anywhere, in addition to the SQL/92 join syntax that uses a table expression in the FROM clause.


Operator precedence

The precedence of operators in expressions is as follows. The operators at the top of the list are evaluated before those at the bottom of the list.

  1. unary operators (operators that require a single operand)

  2. &, | , ^, ~

  3. *, /, %

  4. +, -

  5. ||

  6. not

  7. and

  8. or

When you use more than one operator in an expression, it is recommended that you make the order of operation explicit using parentheses rather than relying on an identical operator precedence between Adaptive Server Enterprise and Adaptive Server Anywhere.


Expressions

toggle Syntax

expression:
case-expression
| constant
| [correlation-name.]column-name
| - expression
| expression operator expression
| ( expression )
| function-name ( expression, ... )
| if-expression
| special value
| ( subquery )
| variable-name

toggle Parameters

case-expression:
CASE expression
WHEN expression
THEN expression,...
[ ELSE expression ]
END

alternative form of case-expression:
CASE
WHEN search-condition
THEN expression,...
[ ELSE expression ]
END

constant:
integer | number | string | host-variable

special-value:
CURRENT { DATE | TIME | TIMESTAMP }
| NULL
| SQLCODE
| SQLSTATE
| USER

if-expression:
IF condition
THEN expression
[ ELSE expression ]
ENDIF

operator:
{ + | - | * | / | || | % }

toggle Usage

Anywhere.

Authorization

Must be connected to the database.

toggle Side effects

None.

toggle Description

Expressions are formed from several different kinds of elements. These are discussed in the following sections.

For information on functions, see SQL Functions. For information on variables, see Variables.

toggle See also
  • Constants in expressions
  • Special values
  • Column names in expressions
  • SQL Functions
  • Subqueries in expressions
  • Search conditions
  • SQL Data Types
  • Variables
  • CASE expressions
toggle Standards and compatibility

  • The IF condition is not supported in Adaptive Server Enterprise.

  • For other differences, see the separate descriptions of each class of expression, in the following sections.


Constants in expressions

Constants are numbers or string literals. String constants are enclosed in apostrophes ('single quotes'). An apostrophe is represented inside a string by two apostrophes in a row.


Column names in expressions

A column name is an identifier preceded by an optional correlation name. (A correlation name is usually a table name. For more information on correlation names, see FROM clause.) If a column name has characters other than letters, digits and underscore, it must be surrounded by quotation marks (""). For example, the following are valid column names:

employee.name
address
"date hired"
"salary"."date paid"

For more information on identifiers, see Identifiers.


Subqueries in expressions

A subquery is a SELECT statement that is nested inside another SELECT, INSERT, UPDATE, or DELETE statement, or another subquery.

The SELECT statement must be enclosed in parentheses, and must contain one and only one select list item. When used as an expression, a subquery is generally allowed to return only one value.

A subquery can be used anywhere that a column name can be used. For example, a subquery can be used in the select list of another SELECT statement.

For other uses of subqueries, see Subqueries in search conditions.


IF expressions

The syntax of the IF expression is as follows:

IF condition
THEN expression1
[ ELSE expression2 ]
ENDIF

This expression returns the following:

  • If condition is TRUE, the IF expression returns expression1.

  • If condition is FALSE, the IF expression returns expression2.

  • If condition is FALSE, and there is no expression2, the IF expression returns NULL.

  • If condition is UNKNOWN, the IF expression returns NULL.

For more information about TRUE, FALSE and UNKNOWN conditions, see NULL value, and Search conditions.

IF statement is different from IF expression
Do not confuse the syntax of the IF expression with that of the IF statement.

For information on the IF statement, see IF statement.


CASE expressions

The CASE expression provides conditional SQL expressions. Case expressions can be used anywhere an expression can be used.

The syntax of the CASE expression is as follows:

CASE expression
WHEN expression
THEN expression, ...
[ ELSE expression ]
END

If the expression following the CASE statement is equal to the expression following the WHEN statement, then the expression following the THEN statement is returned. Otherwise the expression following the ELSE statement is returned, if it exists.

For example, the following code uses a case expression as the second clause in a SELECT statement.

SELECT id,
   ( CASE name
      WHEN 'Tee Shirt' then 'Shirt'
      WHEN 'Sweatshirt' then 'Shirt'
      WHEN 'Baseball Cap' then 'Hat'
      ELSE 'Unknown'
   END ) as Type
FROM "DBA".Product

An alternative syntax is as follows:

CASE
WHEN search-condition
THEN expression, ...
[ ELSE expression ]
END

If the search-condition following the WHEN statement is satisfied, the expression following the THEN statement is returned. Otherwise the expression following the ELSE statement is returned, if it exists.

For example, the following statement uses a case expression as the third clause of a SELECT statement to associate a string with a search-condition.

SELECT id, name,
   ( CASE
      WHEN name='Tee Shirt' then 'Sale'
      WHEN quantity >= 50  then 'Big Sale'
      ELSE 'Regular price'
   END ) as Type
FROM "DBA".Product
NULLIF function for abbreviated CASE expressions

The NULLIF function provides a way to write some CASE statements in short form. The syntax for NULLIF is as follows:

NULLIF ( expression-1, expression-2 )

NULLIF compares the values of the two expressions. If the first expression equals the second expression, NULLIF returns NULL. If the first expression does not equal the second expression, NULLIF returns the first expression.

CASE statement is different from CASE expression
Do not confuse the syntax of the CASE expression with that of the CASE statement.

For information on the CASE statement, see CASE statement.


Compatibility of expressions

The following tables describe the compatibility of expressions and constants between Adaptive Server Enterprise and Adaptive Server Anywhere. These tables are a guide only, and a marking of Both may not mean that the expression performs in an identical manner for all purposes under all circumstances. For detailed descriptions, you should refer to the Adaptive Server Enterprise documentation and the Adaptive Server Anywhere documentation on the individual expression.

In the following table, expr represents an expression, and op represents an operator.

Expression | Supported by
constant | Both
column name | Both
variable name | Both
function (expr) | Both
- expr | Both
expr op expr | Both
( expr ) | Both
( subquery ) | Both
if-expression | Adaptive Server Anywhere only
Constant | Supported by
integer | Both
number | Both
'string' | Both
special-constant | Both
host-variable | Adaptive Server Anywhere
Default interpretation of delimited strings

By default, Adaptive Server Enterprise and Adaptive Server Anywhere give different meanings to delimited strings: that is, strings enclosed in apostrophes (single quotes) and in quotation marks (double quotes).

Adaptive Server Anywhere employs the SQL/92 convention, that strings enclosed in apostrophes are constant expressions, and strings enclosed in quotation marks (double quotes) are delimited identifiers (names for database objects). Adaptive Server Enterprise employs the convention that strings enclosed in quotation marks are constants, while delimited identifiers are not allowed by default and are treated as strings.

The quoted_identifier option


The quoted_identifier option

Both Adaptive Server Enterprise and Adaptive Server Anywhere provide a quoted_identifier option that allows the interpretation of delimited strings to be changed. By default, the quoted_identifier option is set to OFF in Adaptive Server Enterprise, and to ON in Adaptive Server Anywhere.

You cannot use SQL reserved words as identifiers if the quoted_identifier option is off.

For a complete list of reserved words, see Reserved words.

Setting the option

While the Transact-SQL SET statement is not supported for most Adaptive Server Enterprise connection options, it is supported for the quoted_identifier option.

The following statement in either Adaptive Server Anywhere or Adaptive Server Enterprise changes the setting of the quoted_identifier option to ON:

SET quoted_identifier ON

With the quoted_identifier option set to ON, Adaptive Server Enterprise allows table, view, and column names to be delimited by quotes. Other object names cannot be delimited in Adaptive Server Enterprise.

The following statement in Adaptive Server Anywhere or Adaptive Server Enterprise changes the setting of the quoted_identifier option to OFF:

SET quoted_identifier OFF
Compatible interpretation of delimited strings

You can choose to use either the SQL/92 or the default Transact-SQL convention in both Adaptive Server Enterprise and Adaptive Server Anywhere as long as the quoted_identifier option is set to the same value in each DBMS.

toggle Examples

If you choose to operate with the quoted_identifier option ON (the default Adaptive Server Anywhere setting), then the following statements involving the SQL keyword user are valid for both DBMSs.

CREATE TABLE "user" (
   col1 char(5)
) ;
INSERT "user" ( col1 )
VALUES ( 'abcde' ) ;

If you choose to operate with the quoted_identifier option off (the default Adaptive Server Enterprise setting), then the following statements are valid for both DBMSs.

SELECT *
FROM employee
WHERE emp_lname = "Chin"


Search conditions

toggle Function

To specify a search condition for a WHERE clause, a HAVING clause, a CHECK clause, an ON phrase in a join, or an IF expression.

toggle Syntax

search-condition:
expression compare expression
| expression compare { [ ANY | SOME ] | ALL } ( subquery )
| expression IS [ NOT ] NULL
| expression [ NOT ] BETWEEN expression AND expression
| expression [ NOT ] LIKE expression [ ESCAPE expression ]
| expression [ NOT ] IN ( { expression
| subquery
| value-expr1 , value-expr2 [ ,value-expr3 ] ... } )
| EXISTS ( subquery )
| NOT condition
| search-condition AND search-condition
| search-condition OR search-condition
| ( search-condition )
| ( search-condition , estimate )
| search-condition IS [ NOT ] { TRUE | FALSE | UNKNOWN }
| trigger-operation

toggle Parameters

compare:
= | > | < | >= | <= | <> | != | !< | !>

trigger-operation:
INSERTING | DELETING
| UPDATING( column-name-string ) | UPDATE( column-name )

toggle Usage

Anywhere.

toggle Permissions

Must be connected to the database.

toggle Side effects

None.

toggle Description

Search conditions are used to choose a subset of the rows from a table, or in a control statement such as an IF statement to determine control of flow.

In SQL, every condition evaluates as one of TRUE, FALSE, or UNKNOWN. This is called three-valued logic. The result of a comparison is UNKNOWN if either value being compared is the NULL value. For tables displaying how logical operators combine in three-valued logic, see the section Three-valued logic.

Rows satisfy a search condition if and only if the result of the condition is TRUE. Rows for which the condition is UNKNOWN or FALSE do not satisfy the search condition. For more information about NULL, see NULL value.

Subqueries form an important class of expression that is used in many search conditions. For information about using subqueries in search conditions, see Subqueries in search conditions.

The different types of search condition are discussed in the following sections.

toggle See also
  • Expressions

Subqueries in search conditions
ALL or ANY conditions
BETWEEN conditions
LIKE conditions
IN conditions
EXISTS conditions
IS NULL conditions
Truth value conditions
Trigger operation conditions
Three-valued logic
Explicit selectivity estimates


Subqueries in search conditions

Subqueries that return exactly one column and either zero or one row can be used in any SQL statement wherever a column name could be used, including in the middle of an expression.

For example, expressions can be compared to subqueries in comparison conditions (see Comparison operators) as long as the subquery does not return more than one row. If the subquery (which must have one column) returns one row, then the value of that row is compared to the expression. If a subquery returns no rows, its value is NULL.

Subqueries that return exactly one column and any number of rows can be used in IN conditions, ANY conditions, and ALL conditions. Subqueries that return any number of columns and rows can be used in EXISTS conditions. These conditions are discussed in the following sections.


ALL or ANY conditions

The syntax for ANY conditions is

expression compare ANY ( subquery )

where compare is a comparison operator.

For example, an ANY condition with an equality operator,

expression = ANY ( subquery )

is TRUE if expression is equal to any of the values in the result of the subquery, and FALSE if the expression is not NULL and does not equal any of the columns of the subquery. The ANY condition is UNKNOWN if expression is the NULL value, unless the result of the subquery has no rows, in which case the condition is always FALSE.

The keyword SOME can be used instead of ANY.

The syntax for ALL conditions is

expression compare ALL ( subquery )

where compare is a comparison operator.

toggle Standards and compatibility

  • ANY and ALL subqueries are compatible between Adaptive Server Enterprise and Adaptive Server Anywhere. Only Adaptive Server Anywhere supports SOME as a synonym for ANY.


BETWEEN conditions

The syntax for BETWEEN conditions is as follows:

expr [ NOT ] BETWEEN start-expr AND end-expr

The BETWEEN condition can evaluate as TRUE, FALSE, or UNKNOWN. Without the NOT keyword, the condition evaluates as TRUE if expr is between start-expr and end-expr. The NOT keyword reverses the meaning of the condition but leaves UNKNOWN unchanged.

The BETWEEN conditions is equivalent to a combination of two inequalities:

[ NOT ] ( expr >= start-expr AND expr <= end-expr )

toggle Standards and compatibility

  • The BETWEEN condition is compatible between Adaptive Server Anywhere and Adaptive Server Enterprise.


LIKE conditions

The syntax for LIKE conditions is as follows:

expr [NOT] LIKE pattern [ESCAPE escape-expr]

The LIKE condition can evaluate as TRUE, FALSE, or UNKNOWN.

Without the NOT keyword, the condition evaluates as TRUE if expression matches the pattern. If either expression or pattern is the NULL value, this condition is UNKNOWN. The NOT keyword reverses the meaning of the condition, but leaves UNKNOWN unchanged.

The pattern may contain any number of wildcards. The wildcards are:

Wildcard | Matches
_ (underscore) | Any one character
% (percent) | Any string of zero or more characters
[] | Any single character in the specified range or set
[^] | Any single character not in the specified range or set

All other characters must match exactly.

For example, the search condition

... name LIKE 'a%b_'

is TRUE for any row where name starts with the letter a and has the letter b as its second last character.

If an escape-expr is specified, it must evaluate to a single character. The character can precede a percent, an underscore, a left square bracket, or another escape character in the pattern to prevent the special character from having its special meaning. When escaped in this manner, a percent will match a percent, and an underscore will match an underscore.

All patterns of length 126 characters or less are supported. Patterns of length greater than 254 characters are not supported. Some patterns of length between 127 and 254 characters are supported, depending on the contents of the pattern.

Searching for one of a set of characters

A set of characters to look for is specified by listing the characters inside square brackets. For example, the following condition finds the strings smith and smyth:

LIKE 'sm[iy]th'
Searching for one of a range of characters

A range of characters to look for is specified by giving the ends of the range inside square brackets, separated by a hyphen. For example, the following condition finds the strings bough and rough, but not tough:

LIKE '[a-r]ough'

The range of characters [a-z] is interpreted as "greater than or equal to a, and less than or equal to z", where the greater than and less than operations are carried out within the collation of the database. For information on ordering of characters within a collation, see International Languages and Character Sets.

The lower end of the range must precede the higher end of the range. For example, a LIKE condition containing the expression [z-a] returns no rows because no character matches the [z-a] range.

Unless the database is created as case sensitive, the range of characters is case insensitive. For example, the following condition finds the strings Bough, rough, and TOUGH:

LIKE '[a-z]ough'

If the database is created as a case-sensitive database, the search condition is case sensitive also. To perform a case insensitive search in a case sensitive database, you must include upper and lower characters. For example, the following condition finds the strings Bough, rough, and TOUGH:

LIKE '[a-zA-Z][oO][uU][gG][hH]'
Combining searches for ranges and sets

You can combine ranges and sets within a square bracket. For example, the following condition finds the strings bough, rough, and tough:

... LIKE '[a-rt]ough'

The bracket [a-mpqs-z] is interpreted as "exactly one character that is either in the range a to m inclusive, or is p, or is q, or is in the range s to z inclusive".

Searching for one character not in a range

The caret character (^) is used to specify a range of characters that is excluded from a search. For example, the following condition finds the string tough, but not the strings rough, or bough:

... LIKE '[^a-r]ough'

The caret negates the entire rest of the contents of the brackets. For example, the bracket [^a-mpqs-z] is interpreted as "exactly one character that is not in the range a to m inclusive, is not p, is not q, and is not in the range s to z inclusive".

Special cases of ranges and sets

Any single character in square brackets means that character. For example, [a] matches just the character a . [^] matches just the caret character, [%] matches just the percent character (the percent character does not act as a wildcard in this context), and [_] matches just the underscore character. Also, [[] matches just the character [.

Other special cases are as follows:

  • The expression [a-] matches either of the characters a or -.

  • The expression [] is never matched and always returns no rows.

  • The expressions [ or [abp-q are ill-formed expressions, and give syntax errors.

  • You cannot use wildcards inside square brackets. The expression [a%b] finds one of a, %, or b.

  • You cannot use the caret character to negate ranges except as the first character in the bracket. The expression [a^b] finds one of a, ^, or b.

Search patterns with trailing blanks

When your search pattern includes trailing blanks, Adaptive Server Anywhere matches the pattern only to values that contain blanks—it does not blank-pad strings. For example, the search patterns '90 ', '90[ ]' and '90_' match the value '90 ', but do not match the value '90', even if the value being tested is in a char or varchar column that is three or more characters in width.

toggle Standards and compatibility

  • The ESCAPE clause is supported by Adaptive Server Anywhere only.


IN conditions

The syntax for IN conditions is as follows:

expression [ NOT ] IN { ( subquery ) | ( expression2 ) | ( value-expr, ... ) }

An IN condition, without the NOT keyword, evaluates according to the following rules:

  • TRUE if expression is not NULL and equals at least one of the values.

  • UNKNOWN if expression is NULL and the values list is not empty, or if at least one of the values is NULL and expression does not equal any of the other values.

  • FALSE if expression is NULL and subquery returns no values; or if expression is not NULL, none of the values are NULL, and expression does not equal any of the values.

The NOT keyword interchanges TRUE and FALSE.

The search condition expression IN ( values ) is identical to the search condition expression = ANY ( values ). The search condition expression NOT IN ( values ) is identical to the search condition expression <> ALL ( values ).

The value-expr arguments are expressions that take on a single value, which may be a string, a number, a date, or any other SQL datatype.

toggle Standards and compatibility

  • IN conditions are compatible between Adaptive Server Enterprise and Adaptive Server Anywhere.


EXISTS conditions

The syntax for EXISTS conditions is as follows:

EXISTS( subquery )

The EXISTS condition is TRUE if the subquery result contains at least one row, and FALSE if the subquery result does not contain any rows. The EXISTS condition cannot be UNKNOWN.

toggle Standards and compatibility

  • The EXISTS condition is compatible between Adaptive Server Enterprise and Adaptive Server Anywhere.


IS NULL conditions

The syntax for IS NULL conditions is as follows:

expression IS [ NOT ] NULL

Without the NOT keyword, the IS NULL condition is TRUE if the expression is the NULL value, and FALSE otherwise. The NOT keyword reverses the meaning of the condition.

toggle Standards and compatibility

  • The IS NULL condition is compatible between Adaptive Server Enterprise and Adaptive Server Anywhere.


Truth value conditions

The syntax for truth-value conditions is as follows:

IS [ NOT ] truth-value

Without the NOT keyword, the condition is TRUE if the condition evaluates to the supplied truth-value, which must be one of TRUE, FALSE, or UNKNOWN. Otherwise, the value is FALSE. The NOT keyword reverses the meaning of the condition, but leaves UNKNOWN unchanged.

toggle Standards and compatibility

  • Vendor extension. Adaptive Server Enterprise does not support truth-valued conditions.


Trigger operation conditions

The syntax for trigger operation conditions is as follows:

trigger-operation:
INSERTING | DELETING
| UPDATING( column-name-string ) | UPDATE( column-name )

Trigger-operation conditions can be used only in triggers, to carry out actions depending on the kind of action that caused the trigger to fire.

The argument for UPDATING is a quoted string (for example, UPDATING( 'mycolumn' )). The argument for UPDATE is an identifier (for example, UPDATE( mycolumn )). The two versions are interoperable, and are included for compatibility with SQL dialects of other vendors' DBMS.

If you supply an UPDATING or UPDATE function, you must also supply a REFERENCING clause in the CREATE TRIGGER statement to avoid syntax errors.

toggle Example

The following trigger displays a message showing which action caused the trigger to fire.

CREATE TRIGGER tr BEFORE INSERT, UPDATE, DELETE
ON sample_table
REFERENCING OLD AS t1old
FOR EACH ROW
BEGIN
    DECLARE msg varchar(255);
    SET msg = 'This trigger was fired by an ';
    IF INSERTING THEN
        SET msg = msg || 'insert'
    ELSEIF DELETING THEN
        set msg = msg || 'delete'
    ELSEIF UPDATING THEN
        set msg = msg || 'update'
    END IF;
    MESSAGE msg TO CLIENT
END


Three-valued logic

The following tables display how the AND, OR, NOT, and IS logical operators of SQL work in three-valued logic.

AND operator
AND | TRUE | FALSE | UNKNOWN
TRUE | TRUE | FALSE | UNKNOWN
FALSE | FALSE | FALSE | FALSE
UNKNOWN | UNKNOWN | FALSE | UNKNOWN
OR operator
OR | TRUE | FALSE | UNKNOWN
TRUE | TRUE | TRUE | TRUE
FALSE | TRUE | FALSE | UNKNOWN
UNKNOWN | TRUE | UNKNOWN | UNKNOWN
NOT operator
TRUE | FALSE | UNKNOWN
FALSE | TRUE | UNKNOWN
IS operator
IS | TRUE | FALSE | UNKNOWN
TRUE | TRUE | FALSE | FALSE
FALSE | FALSE | TRUE | FALSE
UNKNOWN | FALSE | FALSE | TRUE


Explicit selectivity estimates

Adaptive Server Anywhere uses statistical information to determine the most efficient strategy for executing each statement. Adaptive Server Anywhere automatically gathers and updates these statistics. These statistics are stored permanently in the database in the system table SYSCOLSTAT. Statistics gathered while processing one statement are available when searching for efficient ways to execute subsequent statements.

Occasionally, the statistics may become inaccurate or relevant statistics may be unavailable. This condition is most likely to arise when few queries have been executed since a large amount of data was added, updated, or deleted. In this situation, you may want to execute CREATE STATISTICS.

If there are problems with a particular execution plan, you can use optimizer hints to require that a particular index be used. For more information, see FROM clause.

In unusual circumstances, however, these measures may prove ineffective. In such cases, you can sometimes improve performance by supplying explicit selectivity estimates.

For each table in a potential execution plan, the optimizer must estimate the number of rows that will be part of the result set. If you know that a condition has a success rate that differs from the optimizer's estimate, you can explicitly supply a user estimate in the search condition.

The estimate is a percentage. It can be a positive integer or can contain fractional values.

Caution Whenever possible, avoid supplying explicit estimates in statements that are to be used on an ongoing basis. Should the data change, the explicit estimate may become inaccurate and may force the optimizer to select poor plans. If you do use explicit selectivity estimates, ensure that the number is accurate. Do not, for example, supply values of 0% or 100% to force the use of an index.

You can disable user estimates by setting the database option USER_ESTIMATES to OFF. The default value for USER_ESTIMATES is OVERRIDE-MAGIC, which means that user-supplied selectivity estimates are used only when the optimizer would use a MAGIC (default) selectivity value for the condition. The optimizer uses MAGIC values as a last resort when it is unable to accurately predict the selectivity of a predicate.

For more information about disabling user-defined selectivity estimates, see USER_ESTIMATES option [database].

For more information about statistics, see Optimizer estimates and histograms.

toggle Examples

  • The following query provides an estimate that one percent of the ship_date values will be later than 2001/06/30:

    SELECT  ship_date
    FROM  sales_order_items
WHERE ( ship_date > '2001/06/30', 1 )
ORDER BY ship_date DESC

  • The following query estimates that half a percent of the rows will satisfy the condition:

    SELECT *
    FROM customer c, sales_order o
WHERE (c.id = o.cust_id, 0.5)

Fractional values enable more accurate user estimates for joins, particularly for large tables.

toggle Standards and compatibility

  • Adaptive Server Enterprise does not support explicit estimates.


Special values

Special values can be used in expressions, and as column defaults when creating tables.

While some special values can be queried, some can only be used as default values for columns. For example, user, last user, timestamp and UTC timestamp can only be used as default values.

CURRENT DATABASE special value
CURRENT DATE special value
CURRENT PUBLISHER special value
CURRENT TIME special value
CURRENT TIMESTAMP special value
CURRENT USER special value
CURRENT UTC TIMESTAMP special value
LAST USER special value
SQLCODE special value
SQLSTATE special value
TIMESTAMP special value
USER special value
UTC TIMESTAMP special value


CURRENT DATABASE special value

toggle Function

CURRENT DATABASE returns the name of the current database.

toggle Data type

STRING

toggle See also
  • Expressions


CURRENT DATE special value

toggle Function

CURRENT DATE returns the current year, month, and day.

toggle Data type

DATE

toggle See also
  • Expressions
  • TIME data type [Date and Time]


CURRENT PUBLISHER special value

toggle Function

CURRENT PUBLISHER returns a string that contains the publisher user ID of the database for SQL Remote replications.

toggle Data type

STRING

CURRENT PUBLISHER can be used as a default value in columns with character data types.

toggle See also
  • Expressions
  • SQL Remote Design for Adaptive Server Anywhere


CURRENT TIME special value

toggle Function

The current hour, minute, second and fraction of a second.

toggle Data type

TIME

toggle Description

The fraction of a second is stored to 6 decimal places. The accuracy of the current time is limited by the accuracy of the system clock.

toggle See also
  • Expressions
  • TIME data type [Date and Time]


CURRENT TIMESTAMP special value

toggle Function

Combines CURRENT DATE and CURRENT TIME to form a TIMESTAMP value containing the year, month, day, hour, minute, second and fraction of a second. The fraction of a second is stored to 3 decimal places. The accuracy is limited by the accuracy of the system clock.

The information CURRENT TIMESTAMP returns is equivalent to the information returned by the GETDATE and NOW functions.

CURRENT_TIMESTAMP is equivalent to CURRENT TIMESTAMP.

toggle Data type

TIMESTAMP

toggle See also
  • CURRENT TIME special value
  • Expressions
  • TIMESTAMP data type [Date and Time]
  • GETDATE function [Date and time]
  • NOW function [Date and time]


CURRENT USER special value

toggle Function

CURRENT USER returns a string that contains the user ID of the current connection.

toggle Data type

STRING

CURRENT USER can be used as a default value in columns with character data types.

toggle Description

On UPDATE, columns with a default value of CURRENT USER are not changed. CURRENT_USER is equivalent to CURRENT USER.

toggle See also
  • Expressions


CURRENT UTC TIMESTAMP special value

toggle Function

Combines CURRENT DATE and CURRENT TIME, adjusted by the server's time zone adjustment value, to form a Coordinated Universal Time (UTC) TIMESTAMP value containing the year, month, day, hour, minute, second and fraction of a second. This feature allows data to be entered with a consistent time reference, regardless of the time zone in which the data was entered.

toggle Data type

TIMESTAMP

toggle See also
  • TIMESTAMP data type [Date and Time]
  • UTC TIMESTAMP special value
  • CURRENT TIMESTAMP special value
  • TRUNCATE_TIMESTAMP_VALUES option [database]


LAST USER special value

toggle Function

The name of the user who last modified the row.

toggle Data type

String.

LAST USER can be used as a default value in columns with character data types.

toggle Description

On INSERT, this constant has the same effect as CURRENT USER. On UPDATE, if a column with a default value of LAST USER is not explicitly modified, it is changed to the name of the current user.

When combined with the DEFAULT TIMESTAMP, a default value of LAST USER can be used to record (in separate columns) both the user and the date and time a row was last changed.

toggle See also
  • CURRENT USER special value
  • CURRENT TIMESTAMP special value
  • CREATE TABLE statement


SQLCODE special value

toggle Function

Current SQLCODE value.

toggle Data type

String.

toggle Description

The SQLCODE value is set after each statement. You can check the SQLCODE to see whether or not the statement succeeded.

toggle See also
  • Expressions
  • ASA Error Messages.


SQLSTATE special value

toggle Function

Current SQLSTATE value

toggle Data type

STRING

toggle Description

The SQLSTATE value is set after each statement. You can check the SQLSTATE to see whether or not the statement succeeded.

toggle See also
  • Expressions
  • ASA Error Messages


TIMESTAMP special value

toggle Function

TIMESTAMP indicates when each row in the table was last modified. When a column is declared with DEFAULT TIMESTAMP, a default value is provided for inserts, and the value is updated with the current date and time whenever the row is updated.

toggle Data type

TIMESTAMP

toggle Description

Columns declared with DEFAULT TIMESTAMP contain unique values so that applications can detect near-simultaneous updates to the same row. If the current timestamp value is the same as the last value, it is incremented by the value of the DEFAULT_TIMESTAMP_INCREMENT option.

You can automatically truncate timestamp values in Adaptive Server Anywhere based on the DEFAULT_TIMESTAMP_INCREMENT option. This is useful for maintaining compatibility with other database software which records less precise timestamp values.

The global variable @@dbts returns a TIMESTAMP value representing the last value generated for a column using DEFAULT TIMESTAMP.

toggle See also
  • TIMESTAMP data type [Date and Time]
  • CURRENT UTC TIMESTAMP special value
  • DEFAULT_TIMESTAMP_INCREMENT option [database]
  • TRUNCATE_TIMESTAMP_VALUES option [database]


USER special value

toggle Function

USER returns a string that contains the user ID of the current connection.

toggle Data type

STRING

USER can be used as a default value in columns with character data types.

toggle Description

On UPDATE, columns with a default value of USER are not changed.

toggle See also
  • Expressions
  • CURRENT USER special value
  • LAST USER special value


UTC TIMESTAMP special value

toggle Function

UTC TIMESTAMP indicates the Coordinated Universal (UTC) time when each row in the table was last modified.

toggle Data type

TIMESTAMP

toggle See also
  • TIMESTAMP data type [Date and Time]
  • CURRENT UTC TIMESTAMP special value
  • TIMESTAMP special value
  • DEFAULT_TIMESTAMP_INCREMENT option [database]
  • TRUNCATE_TIMESTAMP_VALUES option [database]


Variables

Adaptive Server Anywhere supports three levels of variables:

  • Local variables These are defined inside a compound statement in a procedure or batch using the DECLARE statement. They exist only inside the compound statement.

  • Connection-level variables These are defined with a CREATE VARIABLE statement. They belong to the current connection, and disappear when you disconnect from the database or when you use the DROP VARIABLE statement.

  • Global variables These are system-supplied variables that have system-supplied values. All global variables have names beginning with two @ signs. For example, the global variable @@version has a value that is the current version number of the database server. Users cannot define global variables.

Local and connection-level variables are declared by the user, and can be used in procedures or in batches of SQL statements to hold information. Global variables are system-supplied variables that provide system-supplied values.

toggle See also
  • TIMESTAMP data type [Date and Time]
  • CREATE VARIABLE statement


Local variables

Local variables are declared using the DECLARE statement, which can be used only within a compound statement (that is, bracketed by the BEGIN and END keywords). The variable is initially set as NULL. The value of the variable can be set using the SET statement, or can be assigned using a SELECT statement with an INTO clause.

The syntax of the DECLARE statement is as follows:

DECLARE variable-name data-type

Local variables can be passed as arguments to procedures, as long as the procedure is called from within the compound statement.

toggle Examples

  • The following batch illustrates the use of local variables.

    BEGIN
   DECLARE local_var INT;
   SET local_var = 10;
   MESSAGE 'local_var = ', local_var TO CLIENT;
END

    Running this batch from Interactive SQL gives the message local_var = 10 in the Interactive SQL Messages pane.

  • The variable local_var does not exist outside the compound statement in which it is declared. The following batch is invalid, and gives a column not found error.

    -- This batch is invalid.
BEGIN
   DECLARE local_var INT;
   SET local_var = 10;
END;
MESSAGE 'local_var = ', local_var TO CLIENT;

  • The following example illustrates the use of SELECT with an INTO clause to set the value of a local variable:

    BEGIN
   DECLARE local_var INT;
   SELECT 10 INTO local_var;
   MESSAGE 'local_var = ', local_var TO CLIENT;
END

    Running this batch from Interactive SQL gives the message local_var = 10 on the server window.

toggle Standards and compatibility

  • Names Adaptive Server Enterprise and Adaptive Server Anywhere both support local variables. In Adaptive Server Enterprise, all variables must be prefixed with an @ sign. In Adaptive Server Anywhere, the @ prefix is optional. To write compatible SQL, prefix all of your variables with @.

  • Scope The scope of local variables is different in Adaptive Server Anywhere and Adaptive Server Enterprise. Adaptive Server Anywhere supports the use of the DECLARE statement to declare local variables within a batch. However, if the DECLARE is executed within a compound statement, the scope is limited to the compound statement.

  • Declaration Only one variable can be declared for each DECLARE statement in Adaptive Server Anywhere. In Adaptive Server Enterprise, more than one variable can be declared in a single statement.

For more information on batches and local variable scope, see Variables in Transact-SQL procedures.


Connection-level variables

Connection-level variables are declared with the CREATE VARIABLE statement. Connection-level variables can be passed as parameters to procedures.

The syntax for the CREATE VARIABLE statement is as follows:

CREATE VARIABLE variable-name data-type

When a variable is created, it is initially set to NULL. The value of connection-level variables can be set in the same way as local variables, using the SET statement or using a SELECT statement with an INTO clause.

Connection-level variables exist until the connection is terminated, or until the variable is explicitly dropped using the DROP VARIABLE statement. The following statement drops the variable con_var:

DROP VARIABLE con_var
toggle Standards and compatibility

  • Adaptive Server Enterprise does not support connection-level variables.

toggle Example

  • The following batch of SQL statements illustrates the use of connection-level variables.

    CREATE VARIABLE con_var INT;
SET con_var = 10;
MESSAGE 'con_var = ', con_var TO CLIENT;

    Running this batch from Interactive SQL gives the message con_var = 10 on the server window.


Global variables

Global variables have values set by the database server. For example, the global variable @@version has a value that is the current version number of the database server.

Global variables are distinguished from local and connection-level variables by having two @ signs preceding their names. For example, @@error and @@rowcount are global variables. Users cannot create global variables, and cannot update the values of global variables directly.

Some global variables, such as @@identity, hold connection-specific information, and so have connection-specific values. Other variables, such as @@connections, have values that are common to all connections.

Global variable and special constants

The special constants (for example, CURRENT DATE, CURRENT TIME, USER, and SQLSTATE) are similar to global variables.

The following statement retrieves a value of the version global variable.

SELECT @@version

In procedures and triggers, global variables can be selected into a variable list. The following procedure returns the server version number in the ver parameter.

CREATE PROCEDURE VersionProc (OUT ver
            VARCHAR(100))
BEGIN
   SELECT @@version
   INTO ver;
END

In Embedded SQL, global variables can be selected into a host variable list.

List of global variables

The following table lists the global variables available in Adaptive Server Anywhere

Variable name Meaning
@@dbts
 A value of type TIMESTAMP representing the last generated value used for all columns defined with DEFAULT TIMESTAMP.
@@error
 Commonly used to check the error status (succeeded or failed) of the most recently executed statement. It contains 0 if the previous transaction succeeded; otherwise, it contains the last error number generated by the system. A statement such as if @@error != 0 return causes an exit if an error occurs. Every SQL statement resets @@error, so the status check must immediately follow the statement whose success is in question.
@@fetch_status
 Contains status information resulting from the last fetch statement. @@fetch_status may contain the following values

  • 0 The fetch statement completed successfully.

  • -1 The fetch statement resulted in an error.

  • -2 There is no more data in the result set.

This feature is the same as @@sqlstatus, except that it returns different values. It is for Microsoft SQL Server compatibility.
@@identity
 Last value inserted into any IDENTITY or DEFAULT AUTOINCREMENT column by an INSERT or SELECT INTO statement.

For a description, see @@identity global variable.

@@isolation
 Current isolation level. @@isolation takes the value of the active level.
@@procid
 Stored procedure ID of the currently executing procedure.
@@rowcount
 Number of rows affected by the last statement. The value of @@rowcount should be checked immediately after the statement.

Inserts, updates, and deletes set @@rowcount to the number of rows affected.

With cursors, @@rowcount represents the cumulative number of rows returned from the cursor result set to the client, up to the last fetch request.

Unlike in Adaptive Server Enterprise, @@rowcount is not reset to zero by any statement which does not affect rows, such as an IF statement.

@@servername
 Name of the current database server.
@@sqlstatus
 Contains status information resulting from the last fetch statement. @@sqlstatus may contain the following values

  • 0 The fetch statement completed successfully.

  • 1 The fetch statement resulted in an error.

  • 2 There is no more data in the result set.

@@version
 Version number of the current version of Adaptive Server Anywhere.
toggle Standards and compatibility

The following list includes all Adaptive Server Enterprise global variables supported in Adaptive Server Anywhere. Adaptive Server Enterprise global variables not supported by Adaptive Server Anywhere are not included in the list. In contrast to the above table, this list includes all global variables that return a value, including those for which the value is fixed at NULL, 1, -1, or 0, and may not be meaningful.

Global variable | Returns
@@char_convert | Returns 0.
@@client_csname | In Adaptive Server Enterprise, the client's character set name. Set to NULL if client character set has never been initialized; otherwise, it contains the name of the most recently used character set. Returns NULL in Adaptive Server Anywhere.
@@client_csid | In Adaptive Server Enterprise, the client's character set ID. Set to –1 if client character set has never been initialized; otherwise, it contains the most recently used client character set ID from syscharsets. Returns –1 in Adaptive Server Anywhere.
@@connections | The number of logins since the server was last started
@@cpu_busy | In Adaptive Server Enterprise, the amount of time, in ticks, that the CPU has spent doing Adaptive Server Enterprise work since the last time Adaptive Server Enterprise was started. In Adaptive Server Anywhere, returns 0.
@@error Commonly used to check the error status (succeeded or failed) of the most recently executed statement. It contains 0 if the previous transaction succeeded; otherwise, it contains the last error number generated by the system. A statement such as
if @@error != 0 return
causes an exit if an error occurs. Every statement resets @@error, including PRINT statements or IF tests, so the status check must immediately follow the statement whose success is in question.
@@identity Last value inserted into an IDENTITY column by an INSERT or SELECT INTO statement.

For a description, see @@identity global variable.
@@idle | In Adaptive Server Enterprise, the amount of time, in ticks, that Adaptive Server Enterprise has been idle since it was last started. In Adaptive Server Anywhere, returns 0.
@@io_busy | In Adaptive Server Enterprise, the amount of time, in ticks, that Adaptive Server Enterprise has spent doing input and output operations since it was last started. In Adaptive Server Anywhere, returns 0.
@@isolation | Current isolation level of the connection. In Adaptive Server Enterprise, @@isolation takes the value of the active level
@@langid | Returns a unique language ID for the language in use by the current connection.
@@language | Returns the name of the language in use by the connection.
@@maxcharlen | In Adaptive Server Enterprise, maximum length, in bytes, of a character in Adaptive Server Enterprise's default character set. In Adaptive Server Anywhere, returns 1.
@@max_ connections For the personal server, the maximum number of simultaneous connections that can be made to the server, which is 10.

For the network server, the maximum number of active clients (not database connections, as each client can support multiple connections).

For Adaptive Server Enterprise, the maximum number of connections to the server.
@@ncharsize | In Adaptive Server Enterprise, average length, in bytes, of a national character. In Adaptive Server Anywhere, returns 1.
@@nestlevel | In Adaptive Server Enterprise, nesting level of current execution (initially 0). Each time a stored procedure or trigger calls another stored procedure or trigger, the nesting level is incremented. In Adaptive Server Anywhere, returns –1.
@@pack_received | In Adaptive Server Enterprise, number of input packets read by Adaptive Server Enterprise since it was last started. In Adaptive Server Anywhere, returns 0.
@@pack_sent | In Adaptive Server Enterprise, number of output packets written by Adaptive Server Enterprise since it was last started. In Adaptive Server Anywhere, returns 0.
@@packet_errors | In Adaptive Server Enterprise, number of errors that have occurred while Adaptive Server Enterprise was sending and receiving packets. In Adaptive Server Anywhere, returns 0.
@@procid | Stored procedure ID of the currently executing procedure.
@@rowcount | Number of rows affected by the last command. In Adaptive Server Enterprise @@rowcount is set to zero by any command which does not return rows, such as an IF statement; in Adaptive Server Anywhere, such statements to not reset @@rowcount. With cursors, @@rowcount represents the cumulative number of rows returned from the cursor result set to the client, up to the last fetch request.
@@servername | Name of the local Adaptive Server Enterprise or Adaptive Server Anywhere server.
@@spid | In Adaptive Server Enterprise, server process ID number of the current process. In Adaptive Server Anywhere, the connection handle for the current connection. This is the same value as that displayed by the sa_conn_info procedure.
@@sqlstatus Contains status information resulting from the last fetch statement. @@sqlstatus may contain the following values

  • 0 The fetch statement completed successfully.

  • 1 The fetch statement resulted in an error.

  • 2 There is no more data in the result set.
@@textsize | Current value of the SET TEXTSIZE option, which specifies the maximum length, in bytes, of text or image data to be returned with a select statement. The default setting is 32765, which is the largest bytestring that can be returned using READTEXT. The value can be set using the SET statement.
@@thresh_hysteresis | In Adaptive Server Enterprise, change in free space required to activate a threshold. In Adaptive Server Anywhere, returns 0.
@@timeticks | In Adaptive Server Enterprise, number of microseconds per tick. The amount of time per tick is machine-dependent. In Adaptive Server Anywhere, returns 0.
@@total_errors | In Adaptive Server Enterprise, number of errors that have occurred while Adaptive Server Enterprise was reading or writing. In Adaptive Server Anywhere, returns 0.
@@total_read | In Adaptive Server Enterprise, number of disk reads by Adaptive Server Enterprise since it was last started. In Adaptive Server Anywhere, returns 0.
@@total_write | In Adaptive Server Enterprise, number of disk writes by Adaptive Server Enterprise since it was last started. In Adaptive Server Anywhere, returns 0.
@@tranchained | Current transaction mode of the Transact-SQL program. @@tranchained returns 0 for unchained or 1 for chained.
@@trancount | Nesting level of transactions. Each BEGIN TRANSACTION in a batch increments the transaction count.
@@transtate | In Adaptive Server Enterprise, current state of a transaction after a statement executes. In Adaptive Server Anywhere, returns –1.
@@version | Information on the current version of Adaptive Server Enterprise or Adaptive Server Anywhere.

@@identity global variable


@@identity global variable

The @@identity variable holds the most recent value inserted into an IDENTITY column or a DEFAULT AUTOINCREMENT column, or zero if the most recent insert was into a table that had no such column.

The value of @@identity is connection specific. It is reset each time a row is inserted into a table. If a statement inserts multiple rows, @@identity reflects the IDENTITY value for the last row inserted. If the affected table does not contain an IDENTITY column, @@ identity is set to 0.

The value of @@identity is not affected by the failure of an INSERT or SELECT INTO statement, or the rollback of the transaction that contained it. @@identity retains the last value inserted into an IDENTITY column, even if the statement that inserted it fails to commit.

@@identity and triggers

When an insert causes referential integrity actions or fires a trigger, @@identity behaves like a stack. For example, if an insert into a table T1 (with an identity or autoincrement column) fires a trigger that inserts a row into table T2 (also with an identity or autoincrement column), then the value returned to the application or procedure which carried out the insert is the value inserted into T1. Within the trigger, @@identity has the T1 value before the insert into T2 and the T2 value after. The trigger can copy the values to local variables if it needs to access both.


Comments

Comments are used to attach explanatory text to SQL statements or statement blocks. The database server does not execute comments.

Several comment indicators are available in Adaptive Server Anywhere.

  • -- (Double hyphen) The database server ignores any remaining characters on the line. This is the SQL/92 comment indicator.

  • // (Double slash) The double slash has the same meaning as the double hyphen.

  • /* ... */ (Slash-asterisk) Any characters between the two comment markers are ignored. The two comment markers may be on the same or different lines. Comments indicated in this style can be nested. This style of commenting is also called C-style comments.

  • % (Percent sign) The percent sign has the same meaning as the double hyphen, if the PERCENT_AS_COMMENT option is set to ON. It is recommended that % not be used as a comment indicator.

toggle Standards and compatibility

  • The double-hyphen and the slash-asterisk comment styles are compatible with Adaptive Server Enterprise.

toggle Examples

  • The following example illustrates the use of double-dash comments:

    CREATE FUNCTION fullname (firstname CHAR(30),
         lastname CHAR(30))
RETURNS CHAR(61)
-- fullname concatenates the firstname and lastname
-- arguments with a single space between.
BEGIN
   DECLARE name CHAR(61);
   SET name = firstname || ' ' || lastname;
   RETURN ( name );
END

  • The following example illustrates the use of C-style comments:

    /*
   Lists the names and employee IDs of employees
   who work in the sales department.
*/
CREATE VIEW SalesEmployee AS
SELECT emp_id, emp_lname, emp_fname
FROM "DBA".employee
WHERE dept_id = 200


NULL value

toggle Function

To specify a value that is unknown or not applicable.

toggle Syntax

NULL

toggle Usage

Anywhere.

toggle Permissions

Must be connected to the database.

toggle Side effects

None.

toggle See also
  • Expressions
  • Search conditions
toggle Description

The NULL value is a special value which is different from any valid value for any data type. However, the NULL value is a legal value in any data type. The NULL value is used to represent missing or inapplicable information. There are two separate and distinct cases where NULL is used:

Situation | Description
missing | The field does have a value, but that value is unknown.
inapplicable | The field does not apply for this particular row.

SQL allows columns to be created with the NOT NULL restriction. This means that those particular columns cannot contain NULL.

The NULL value introduces the concept of three valued logic to SQL. The NULL value compared using any comparison operator with any value (including the NULL value) is "UNKNOWN." The only search condition that returns TRUE is the IS NULL predicate. In SQL, rows are selected only if the search condition in the WHERE clause evaluates to TRUE; rows that evaluate to UNKNOWN or FALSE are not selected.

The IS [ NOT ] truth-value clause, where truth-value is one of TRUE, FALSE or UNKNOWN can be used to select rows where the NULL value is involved. See Search conditions for a description of this clause.

In the following examples, the column Salary contains NULL.

Condition | Truth value | Selected?
Salary = NULL | UNKNOWN | NO
Salary <> NULL | UNKNOWN | NO
NOT (Salary = NULL) | UNKNOWN | NO
NOT (Salary <> NULL) | UNKNOWN | NO
Salary = 1000 | UNKNOWN | NO
Salary IS NULL | TRUE | YES
Salary IS NOT NULL | FALSE | NO
Salary = expression IS UNKNOWN | TRUE | YES

The same rules apply when comparing columns from two different tables. Therefore, joining two tables together will not select rows where any of the columns compared contain the NULL value.

NULL also has an interesting property when used in numeric expressions. The result of any numeric expression involving the NULL value is NULL. This means that if NULL is added to a number, the result is NULL—not a number. If you want NULL to be treated as 0, you must use the ISNULL( expression, 0 ) function (see SQL Functions).

Many common errors in formulating SQL queries are caused by the behavior of NULL. You will have to be careful to avoid these problem areas. See Search conditions for a description of the effect of three-valued logic when combining search conditions.

Set operators and DISTINCT clause

In set operations (UNION, INTERSECT, EXCEPT), and in the DISTINCT operation, NULL is treated differently from in search conditions. Rows that contain NULL and are otherwise identical are treated as identical for the purposes of these operations.

For example, if a column called redundant contained NULL for every row in a table T1, then the following statement would return a single row:

SELECT DISTINCT redundant
FROM T1
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • Sybase In some contexts, Adaptive Server Enterprise treats NULL as a value, whereas Adaptive Server Anywhere does not. For example, rows of a column c1 that are NULL are not included in the results of a query with the following WHERE clause in Adaptive Server Anywhere, as the condition has a value of UNKNOWN:

    WHERE NOT( C1 = NULL )

    In Adaptive Server Enterprise, the condition is evaluated as TRUE, and these rows are returned. You should use IS NULL rather than a comparison operator for compatibility.

    Unique indexes in Adaptive Server Anywhere can hold rows that hold NULL and are otherwise identical. Adaptive Server Enterprise does not permit such entries in unique indexes.

    If you use jConnect, the TDS_EMPTY_STRING_IS_NULL option controls whether empty strings are returned as NULL strings or as a string containing one blank character.

    For more information, see TDS_EMPTY_STRING_IS_NULL option [database].

toggle Example

  • The following INSERT statement inserts a NULL into the date_returned column of the Borrowed_book table.

    INSERT
INTO Borrowed_book
( date_borrowed, date_returned, book )
VALUES ( CURRENT DATE, NULL, '1234' )


SQL Data Types

About this chapter

This chapter describes the data types supported by Adaptive Server Anywhere.

Character data types
Numeric data types
Money data types
BIT data type
Date and time data types
Binary data types
Domains
Data type conversions
Java and SQL data type conversion
Year 2000 compliance


Character data types

toggle Function

For storing strings of letters, numbers and symbols.

toggle Description

Adaptive Server Anywhere treats CHAR, VARCHAR, and LONG VARCHAR columns all as the same type. Values up to 254 characters are stored as short strings, with a preceding length byte. Any values that are longer than 255 bytes are considered long strings. Characters after the 255th byte are stored separately from the row containing the long string value.

There are several functions (see SQL Functions) that will ignore the part of any string past the 255th character. They are SOUNDEX, SIMILAR, and all of the date functions. Also, any arithmetic involving the conversion of a long string to a number will work on only the first 255 characters. It would be extremely unusual to run in to one of these limitations.

All other functions and all other operators work with the full length of long strings.

Character sets and code pages

Character data is placed in the database using the exact binary representation that is passed from the application. This usually means that character data is stored in the database with the binary representation of the current code page. The code page is the character set representation used by IBM-compatible personal computers. You can find documentation about code pages in the documentation for your operating system.

Most code pages are the same for the first 128 characters. If you use special characters from the top half of the code page (accented international language characters), you must be careful with your databases. In particular, if you copy the database to a machine that uses a different code page, those special characters will be retrieved from the database using the original code page representation. With the new code page, they will appear on the screen to be the wrong characters.

This problem also appears if you have two clients using the same multi-user server, but run with different code pages. Data inserted or updated by one client may appear incorrect to the other.

This problem also shows up if a database is used across platforms. PowerBuilder and many other Windows applications insert data into the database in the standard ANSI character set. If non-Windows applications attempt to use this data, they will not properly display or update the extended characters.

This problem is quite complex. If any of your applications use the extended characters in the upper half of the code page, make sure that all clients and all machines using the database use the same or a compatible code page.

Notes

Data type lengths of less than one are not allowed.

Compatibility

  • The CHARACTER (n) alternative for CHAR is not supported in Adaptive Server Enterprise.

  • Adaptive Server Anywhere does not support the NCHAR and NVARCHAR data types provided by Adaptive Server Enterprise.

CHAR data type [Character]
CHARACTER VARYING (VARCHAR) data type [Character]
LONG VARCHAR data type [Character]
TEXT data type [Character]
UNIQUEIDENTIFIERSTR data type [Character]
XML data type [Character]


CHAR data type [Character]

toggle Function

Character data of maximum length max-length bytes.

toggle Syntax

{ CHAR | CHARACTER } [ ( max-length ) ]

toggle Usage

The default value of max-length is 1.

For strings up to 254 bytes in length, the storage requirement is the number of bytes in the string plus one additional byte. For longer strings, there is more overhead.

Strings of multi-byte characters can be held as the CHAR data type, but max-length is in bytes, not characters.

toggle Parameters

max-length The maximum length in bytes of the string. The maximum size allowed is 32767.

toggle Standards and compatibility

  • SQL/92 Compatible with SQL/92.

  • Sybase Compatible with Adaptive Server Enterprise. In Adaptive Server Enterprise, the storage requirements for CHAR data types is always max-length. The maximum max-length for Adaptive Server Enterprise is 255.

  • Other database systems In many other database-management systems, unlike Adaptive Server Anywhere, CHAR data types result in blank padding to the full length of the string. This means that they require max-length bytes of storage, regardless of the length of the actual string.

toggle See also
  • CHARACTER VARYING (VARCHAR) data type [Character]
  • LONG VARCHAR data type [Character]


CHARACTER VARYING (VARCHAR) data type [Character]

toggle Function

Same as CHAR.

toggle Syntax

{ VARCHAR | CHARACTER VARYING } [ ( max-length ) ]

toggle Usage

The default value of max-length is 1.

For strings up to 254 bytes in length, the storage requirements are the number of bytes in the string plus one additional byte. For longer strings, there is more overhead.

Strings of multi-byte characters can be held as the CHAR data type, but it is important to note that max-length is in bytes, not characters.

toggle Parameters

max-length The maximum length of the string, in bytes. The maximum size allowed is 32767.

toggle Standards and compatibility

  • SQL/92 Compatible with SQL/92.

  • Sybase Compatible with Adaptive Server Enterprise. The maximum max-length for Adaptive Server Enterprise is 255.

toggle See also
  • CHAR data type [Character]
  • LONG VARCHAR data type [Character]


LONG VARCHAR data type [Character]

toggle Function

Arbitrary length character data.

toggle Syntax

LONG VARCHAR

toggle Usage

Arbitrary length strings. The maximum size is limited by the maximum size of the database file (currently 2 GB).

In addition to the length of the string itself, there is some additional overhead for storage.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Not supported in Adaptive Server Enterprise.

toggle See also
  • CHAR data type [Character]
  • CHARACTER VARYING (VARCHAR) data type [Character]


TEXT data type [Character]

toggle Function

This is a domain. It is implemented as a LONG VARCHAR allowing NULL.

toggle Syntax

TEXT

toggle Usage

Arbitrary length strings. The usage is as for LONG VARCHAR.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • LONG VARCHAR data type [Character]


UNIQUEIDENTIFIERSTR data type [Character]

toggle Function

This is a domain. It is implemented as a CHAR( 36 ).

toggle Syntax

UNIQUEIDENTIFIERSTR

toggle Usage

This data type is used for remote data access, when mapping SQL Server uniqueidentifier columns.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • Data type conversions: Microsoft SQL Server
  • STRTOUUID function [String]


XML data type [Character]

toggle Function

A domain, implemented as LONG VARCHAR.

toggle Syntax

XML

toggle Usage

XML is provided for storing XML documents in an Adaptive Server Anywhere database. Data of type XML is not quoted when generating element content from relational data.

You can cast between the XML data type and any other data type that can be cast to or from a string. Note that there is no checking that the string is well-formed when it is cast to XML.

For information about using the XML data type when generating XML elements, see Storing XML documents in relational databases.

toggle Standards and compatibility

  • Part of the SQL/XML draft standard.

  • Sybase Not supported in Adaptive Server Enterprise.

toggle See also
  • LONG VARCHAR data type [Character]


Numeric data types

toggle Function

For storing numerical data.

Notes

  • The NUMERIC and DECIMAL data types, and the various kinds of INTEGER data types, are sometimes called exact numeric data types, in contrast to the approximate numeric data types FLOAT, DOUBLE, and REAL.

    The exact numeric data types are those for which precision and scale values can be specified, while approximate numeric data types are stored in a predefined manner. Only exact numeric data is guaranteed accurate to the least significant digit specified after an arithmetic operation.

  • Before release 5.5, hexadecimal constants longer than four bytes were treated as string constants, and others were treated as integers. The new default behavior is to treat them as binary type constants. To use the historical behavior, set the TSQL_HEX_CONSTANTS database option to OFF.

  • Data type lengths and precision of less than one are not allowed.

Compatibility

  • Only the NUMERIC data type with scale = 0 can be used for the Transact-SQL identity column.

  • You should avoid default precision and scale settings for NUMERIC and DECIMAL data types, because these are different between Adaptive Server Anywhere and Adaptive Server Enterprise. In Adaptive Server Anywhere, the default precision is 30 and the default scale is 6. In Adaptive Server Enterprise, the default precision is 18 and the default scale is 0.

  • The FLOAT ( p ) data type is a synonym for REAL or DOUBLE, depending on the value of p. For Adaptive Server Enterprise, REAL is used for p less than or equal to 15, and DOUBLE for p greater than 15. For Adaptive Server Anywhere, the cutoff is platform-dependent, but on all platforms the cutoff value is greater than 15.

For information about changing the defaults by setting database options, see PRECISION option [database] and SCALE option [database].

BIGINT data type [Numeric]
DECIMAL data type [Numeric]
DOUBLE data type [Numeric]
FLOAT data type [Numeric]
INT or INTEGER data type [Numeric]
NUMERIC data type [Numeric]
REAL data type [Numeric]
SMALLINT data type [Numeric]
TINYINT data type [Numeric]


BIGINT data type [Numeric]

toggle Function

Integer requiring 8 bytes of storage.

toggle Syntax

[ UNSIGNED ] BIGINT

toggle Usage

The BIGINT data type is an exact numeric data type: its accuracy is preserved after arithmetic operations.

A BIGINT value requires 8 bytes of storage.

The range for signed BIGINT values is –263 to 263 – 1, or –9223372036854775808 to 9223372036854775807.

The range for unsigned BIGINT values is 0 to 264 – 1, or 0 to 18446744073709551615.

By default, the data type is signed.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Not supported in Adaptive Server Enterprise.

toggle See also
  • INT or INTEGER data type [Numeric]
  • TINYINT data type [Numeric]
  • SMALLINT data type [Numeric]


DECIMAL data type [Numeric]

toggle Function

A decimal number with precision total digits and with scale of the digits after the decimal point.

toggle Syntax

{ DECIMAL | DEC } [ ( precision [ , scale ] ) ]

toggle Usage

The DECIMAL data type is an exact numeric data type; its accuracy is preserved to the least significant digit after arithmetic operations.

The storage required for a decimal number can be estimated as

2 + int( (before + 1)/2 ) + int( (after + 1)/2 )

The function int takes the integer portion of its argument, and before and after are the number of significant digits before and after the decimal point. The storage is based on the value being stored, not on the maximum precision and scale allowed in the column.

toggle Parameters

precision An integer expression that specifies the number of digits in the expression. The default setting is 30.

scale An integer expression that specifies the number of digits after the decimal point. The default setting is 6.

The defaults can be changed by setting database options. For information, see PRECISION option [database] and SCALE option [database].

toggle Standards and compatibility

  • SQL/92 Compatible with SQL/92.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • FLOAT data type [Numeric]
  • REAL data type [Numeric]
  • DOUBLE data type [Numeric]


DOUBLE data type [Numeric]

toggle Function

A double-precision floating-point number.

toggle Syntax

DOUBLE [ PRECISION ]

toggle Usage

The DOUBLE data type holds a double-precision floating point number. An approximate numeric data type, it is subject to rounding errors after arithmetic operations. The approximate nature of DOUBLE values means that queries using equalities should generally be avoided when comparing DOUBLE values.

DOUBLE values require 8 bytes of storage.

The value range is 2.22507385850721e–308 to 1.79769313486231e+308. Values held as DOUBLE are accurate to 15 significant digits, but may be subject to round-off error beyond the fifteenth digit.

toggle Standards and compatibility

  • SQL/92 Compatible with SQL/92.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • FLOAT data type [Numeric]
  • REAL data type [Numeric]
  • DECIMAL data type [Numeric]


FLOAT data type [Numeric]

toggle Function

A floating point number, which may be single or double precision.

toggle Syntax

FLOAT [ ( precision ) ]

toggle Usage

When a column is created using the FLOAT ( precision ) data type, columns on all platforms are guaranteed to hold the values to at least the specified minimum precision. In contrast, REAL and DOUBLE do not guarantee a platform-independent minimum precision.

If precision is not supplied, the FLOAT data type is a single precision floating point number, equivalent to the REAL data type, and requires 4 bytes of storage.

If precision is supplied, the FLOAT data type is either single or double precision, depending on the value of precision specified. The cutoff between REAL and DOUBLE is platform-dependent. Single precision FLOATs require 4 bytes of storage, and double precision FLOATs require 8 bytes.

The FLOAT data type is an approximate numeric data type. It is subject to round-off errors after arithmetic operations. The approximate nature of FLOAT values means that queries using equalities should generally be avoided when comparing FLOAT values.

toggle Parameters

precision An integer expression that specifies the number of bits in the mantissa. A mantissa is the decimal part of a logarithm. For example, in the logarithm 5.63428, the mantissa is 0.63428. The IEEE standard 754 floating-point precision is as follows:

Supplied precision value | Decimal precision | Equivalent SQL data type | Storage size
1-24 | 7 decimal digits | REAL | 4 bytes
25-53 | 15 decimal digits | DOUBLE | 8 bytes
toggle Standards and compatibility

  • SQL/92 Compatible with SQL/92.

  • Sybase You can tune the behavior of the FLOAT data type for compatibility with Adaptive Server Enterprise, using the FLOAT_AS_DOUBLE option [compatibility].

toggle See also
  • DECIMAL data type [Numeric]
  • REAL data type [Numeric]
  • DOUBLE data type [Numeric]


INT or INTEGER data type [Numeric]

toggle Function

Integer requiring 4 bytes of storage.

toggle Syntax

[ UNSIGNED ] { INT | INTEGER }

toggle Usage

The INTEGER data type is an exact numeric data type; its accuracy is preserved after arithmetic operations.

If you specify UNSIGNED, the integer can never be assigned a negative number. By default, the data type is signed.

The range for signed integers is –231 to 231 – 1, or –2147483648 to 2147483647.

The range for unsigned integers is 0 to 232 – 1, or 0 to 4294967295.

toggle Standards and compatibility

  • SQL/92 Compatible with SQL/92. The UNSIGNED keyword is a vendor extension.

  • Sybase The signed data type is compatible with Adaptive Server Enterprise. Adaptive Server Enterprise does not support the UNSIGNED data type.

toggle See also
  • BIGINT data type [Numeric]
  • TINYINT data type [Numeric]
  • SMALLINT data type [Numeric]


NUMERIC data type [Numeric]

toggle Function

Same as DECIMAL.

toggle Syntax

NUMERIC [ ( precision [ , scale ] ) ]

toggle Usage

The NUMERIC data type is an exact numeric data type; its accuracy is preserved to the least significant digit after arithmetic operations.

The number of bytes required to store a decimal number can be estimated as

2 + int( (before+1)/2 ) + int( (after+1)/2 )

The function int takes the integer portion of its argument, and before and after are the number of significant digits before and after the decimal point. The storage is based on the value being stored, not on the maximum precision and scale allowed in the column.

toggle Parameters

precision An integer expression that specifies the number of digits in the expression. The default value is 30.

scale An integer expression that specifies the number of digits after the decimal point. The default value is 6.

The defaults can be changed by setting database options. For information, see PRECISION option [database] and SCALE option [database].

toggle Standards and compatibility

  • SQL/92 Compatible with SQL/92, if the SCALE option is set to zero.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • FLOAT data type [Numeric]
  • REAL data type [Numeric]
  • DOUBLE data type [Numeric]


REAL data type [Numeric]

toggle Function

A single-precision floating-point number stored in 4 bytes.

toggle Syntax

REAL

toggle Usage

The REAL data type is an approximate numeric data type; it is subject to roundoff errors after arithmetic operations.

The range of values is -3.402823e+38 to 3.402823e+38, with numbers close to zero as small as 1.175495e-38. Values held as REAL are accurate to 10 significant digits, but may be subject to round-off error beyond the sixth digit.

The approximate nature of REAL values means that queries using equalities should generally be avoided when comparing REAL values

toggle Standards and compatibility

  • SQL/92 Compatible with SQL/92.

  • Sybase Compatible with Adaptive Server Enterprise.


SMALLINT data type [Numeric]

toggle Function

Integer requiring 2 bytes of storage.

toggle Syntax

[ UNSIGNED ] SMALLINT

toggle Usage

The SMALLINT data type is an exact numeric data type; its accuracy is preserved after arithmetic operations. It requires 2 bytes of storage.

The range for signed SMALLINT values is –215 to 215 – 1, or –32768 to 32767.

The range for unsigned SMALLINT values is 0 to 216 – 1, or 0 to 65535.

toggle Standards and compatibility

  • SQL/92 Compatible with SQL/92. The UNSIGNED keyword is a vendor extension.

  • Sybase The signed data type is compatible with Adaptive Server Enterprise. Adaptive Server Enterprise does not support the UNSIGNED data type.

toggle See also
  • INT or INTEGER data type [Numeric]
  • TINYINT data type [Numeric]
  • BIGINT data type [Numeric]


TINYINT data type [Numeric]

toggle Function

Unsigned integer requiring 1 byte of storage.

toggle Syntax

[ UNSIGNED ] TINYINT

toggle Usage

The TINYINT data type is an exact numeric data type; its accuracy is preserved after arithmetic operations.

You can explicitly specify TINYINT as UNSIGNED, but the UNSIGNED modifier has no effect as the type is always unsigned.

The range for TINYINT values is 0 to 28 – 1, or 0 to 255.

In Embedded SQL, TINYINT columns should not be fetched into variables defined as char or unsigned char, since the result is an attempt to convert the value of the column to a string and then assign the first byte to the variable in the program. Instead, TINYINT columns should be fetched into 2-byte or 4-byte integer columns. Also, to send a TINYINT value to a database from an application written in C, the type of the C variable should be integer.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • BIGINT data type [Numeric]
  • TINYINT data type [Numeric]
  • SMALLINT data type [Numeric]


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

SQL Data Types

Money data types

toggle Function

For storing monetary data.


MONEY data type [Money]

toggle Function

This data type is convenient for storing monetary data, and provides compatibility with the Adaptive Server Enterprise MONEY data type.

toggle Syntax

MONEY

toggle Usage

The MONEY data type is implemented as a domain, as NUMERIC(19,4), allowing NULL.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Monetary data types in Adaptive Server Anywhere are implemented as domains, and are primarily intended for compatibility with Adaptive Server Enterprise.

toggle See also
  • SMALLMONEY data type [Money]


SMALLMONEY data type [Money]

toggle Function

This data type is convenient for storing monetary data that is not too large, and provides compatibility with the Adaptive Server Enterprise SMALLMONEY data type.

toggle Syntax

SMALLMONEY

toggle Usage

The SMALLMONEY data type is implemented in Adaptive Server Anywhere as a domain, as NUMERIC(10,4), allowing NULL.

The range for SMALLMONEY values is -214 748.3648 to 214 748.3647.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Monetary data types in Adaptive Server Anywhere are implemented as domains, and are primarily intended for compatibility with Adaptive Server Enterprise.

toggle See also
  • MONEY data type [Money]


BIT data type

toggle Function

For storing Boolean values (0 or 1).

toggle Syntax

BIT

toggle Usage

By default, columns of BIT data type do not allow NULL. This behavior is different from other data types. You can explicitly allow NULL if desired.

Allowed values are 0 and 1.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.


Date and time data types

toggle Function

For storing dates and times.

Sending dates and times to the database
Retrieving dates and times from the database
Comparing dates and times in the database
Using unambiguous dates and times
DATE data type [Date and Time]
DATETIME data type [Date and Time]
SMALLDATETIME data type [Date and Time]
TIME data type [Date and Time]
TIMESTAMP data type [Date and Time]


Sending dates and times to the database

Dates and times may be sent to the database in one of the following ways:

  • Using any interface, as a string

  • Using ODBC, as a TIMESTAMP structure

  • Using Embedded SQL, as a SQLDATETIME structure

When a time is sent to the database as a string (for the TIME data type) or as part of a string (for TIMESTAMP or DATE data types), the hours, minutes, and seconds must be separated by colons in the format hh:mm:ss.sss, but can appear anywhere in the string. The following are valid and unambiguous strings for specifying times:

21:35 -- 24 hour clock if no am or pm specified
10:00pm -- pm specified, so interpreted as 12 hour clock
10:00 -- 10:00am in the absence of pm
10:23:32.234 -- seconds and fractions of a second included

When a date is sent to the database as a string, conversion to a date is automatic. The string can be supplied in one of two ways:

  • As a string of format yyyy/mm/dd or yyyy-mm-dd, which is interpreted unambiguously by the database

  • As a string interpreted according to the DATE_ORDER database option

Transact-SQL compatibility of string-to-date/time conversions


Transact-SQL compatibility of string-to-date/time conversions

There are some differences in behavior between Adaptive Server Anywhere and Adaptive Server Enterprise, when converting strings to date and time data types.

If a string containing only a time value (no date) is converted to a date/time data type, Adaptive Server Enterprise uses a default date of January 1, 1900, but Adaptive Server Anywhere uses the current date.

If the fraction portion of a time is less than 3 digits Adaptive Server Enterprise interprets the value differently depending on whether it was preceded by a period or a colon. If preceded by a colon, the value means thousandths of a second. If preceded by a period, one digit means tenths, two digits mean hundredths, and three digits mean thousandths. Adaptive Server Anywhere interprets the value the same way, regardless of the separator.

toggle Examples

Adaptive Server Enterprise converts the values below as shown. The second line in each pair differs in the use of a colon rather than a period.

12:34:56.7 to 12:34:56.700
12:34:56:7 to 12:34:56.007
12.34.56.78 to 12:34:56.780
12.34.56:78 to 12:34:56.078
12:34:56.789 to 12:34:56.789
12:34:56:789 to 12:34:56.789

Adaptive Server Anywhere converts the milliseconds value in the manner that Adaptive Server Enterprise does for values preceded by a period, in both cases:

12:34:56.7 to 12:34:56.700
12:34:56:7 to 12:34:56.700
12.34.56.78 to 12:34:56.780
12.34.56:78 to 12:34:56.780
12:34:56.789 to 12:34:56.789
12:34:56:789 to 12:34:56.789


Retrieving dates and times from the database

Dates and times may be retrieved from the database in one of the following ways:

  • Using any interface, as a string

  • Using ODBC, as a TIMESTAMP structure

  • Using embedded SQL, as a SQLDATETIME structure

When a date or time is retrieved as a string, it is retrieved in the format specified by the database options DATE_FORMAT, TIME_FORMAT and TIMESTAMP_FORMAT. For descriptions of these options, see SET OPTION statement.

For information on functions that deal with dates and times, see Date and time functions. The following arithmetic operators are allowed on dates:

  • timestamp + integer Add the specified number of days to a date or timestamp.

  • timestamp - integer Subtract the specified number of days from a date or timestamp.

  • date - date Compute the number of days between two dates or timestamps.

  • date + time Create a timestamp combining the given date and time.


Comparing dates and times in the database

By default, values stored as DATE do not have any hour or minute values, and so comparison of dates is straightforward.

If you set the TRUNCATE_DATE_VALUES option to OFF, then the DATE data type also contains a time, which introduces complications when comparing dates. If the time is not specified when a date is entered into the database, the time defaults to 0:00 or 12:00am (midnight). Any date comparisons with this option setting compare the times as well as the date itself. A database date value of '1999-05-23 10:00' is not equal to the constant '1999-05-23'. The DATEFORMAT function or one of the other date functions can be used to compare parts of a date and time field. For example,

DATEFORMAT(invoice_date,'yyyy/mm/dd') = '1999/05/23'

If a database column requires only a date, client applications should ensure that times are not specified when data is entered into the database. This way, comparisons with date-only strings will work as expected.

If you wish to compare a date to a string as a string, you must use the DATEFORMAT function or CAST function to convert the date to a string before comparing.


Using unambiguous dates and times

Dates in the format yyyy/mm/dd or yyyy-mm-dd are always recognized unambiguously as dates, regardless of the DATE_ORDER setting. Other characters can be used as separators instead of "/" or "-"; for example, "?", a space character, or ",". You should use this format in any context where different users may be employing different DATE_ORDER settings. For example, in stored procedures, use of the unambiguous date format prevents misinterpretation of dates according to the user's DATE_ORDER setting.

Also, a string of the form hh:mm:ss.sss is interpreted unambiguously as a time.

For combinations of dates and times, any unambiguous date and any unambiguous time yield an unambiguous date-time value. Also, the form

YYYY-MM-DD HH.MM.SS.SSS

is an unambiguous date-time value. Periods can be used in the time only in combination with a date.

In other contexts, a more flexible date format can be used. Adaptive Server Anywhere can interpret a wide range of strings as dates. The interpretation depends on the setting of the database option DATE_ORDER. The DATE_ORDER database option can have the value MDY, YMD, or DMY (see SET OPTION statement). For example, the following statement sets the DATE_ORDER option to DMY:

SET OPTION DATE_ORDER = 'DMY' ;

The default DATE_ORDER setting is 'YMD'. The ODBC driver sets the DATE_ORDER option to 'YMD' whenever a connection is made. The value can still be changed using the SET TEMPORARY OPTION statement.

The database option DATE_ORDER determines whether the string 10/11/12 is interpreted by the database as November 12, 2010; October 11, 2012; or November 10, 2012. The year, month, and day of a date string should be separated by some character (/, -, or space) and appear in the order specified by the DATE_ORDER option.

The year can be supplied as either 2 or 4 digits. The value of the option NEAREST_CENTURY affects the interpretation of 2-digit years: 2000 is added to values less than NEAREST_CENTURY and 1900 is added to all other values. The default value of this option is 50. Thus, by default, 50 is interpreted as 1950 and 49 is interpreted 2049.

The month can be the name or number of the month. The hours and minutes are separated by a colon, but can appear anywhere in the string.

Notes

  • We recommend that you always specify the year using the four-digit format.

    For more information about Y2K compliance issues, see Year 2000 compliance.

  • With an appropriate setting of DATE_ORDER, the following strings are all valid dates:

    99-05-23 21:35
99/5/23
1999/05/23
May 23 1999
23-May-1999
Tuesday May 23, 1999 10:00pm

  • If a string contains only a partial date specification, default values are used to fill out the date. The following defaults are used:

    • year This year

    • month No default

    • day 1 (useful for month fields; for example, May 1999 will be the date 1999-05-01 00:00)

    • hour, minute, second, fraction 0


DATE data type [Date and Time]

toggle Function

A calendar date, such as a year, month and day.

toggle Syntax

DATE

toggle Usage

The year can be from the year 0001 to 9999. The minimum date in Adaptive Server Anywhere is 0001-01-01 00:00:00.

For historical reasons, a DATE column can also contain an hour and minute if the TRUNCATE_DATE_VALUES option is set to OFF. The TIMESTAMP data type is recommended for anything with hours and minutes.

The format in which DATE values are retrieved by applications is controlled by the DATE_FORMAT setting. For example, a date value representing the 19th of July, 2003 may be returned to an application as 2003/07/19, as Jul 19, 2003, or as one of a number of other possibilities.

The way in which a string is interpreted by the database server as a date is controlled by the DATE_ORDER option. For example, depending on the DATE_ORDER setting, a value of 02/05/2002 supplied by an application for a DATE value may be interpreted in the database as the 2nd of May or the 5th of February.

A DATE value requires 4 bytes of storage.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Supported by Adaptive Server Enterprise 12.5.1 and later.

toggle See also
  • DATE_FORMAT option [compatibility]
  • DATE_ORDER option [compatibility]
  • DATETIME data type [Date and Time]
  • SMALLDATETIME data type [Date and Time]
  • TIMESTAMP data type [Date and Time]
  • TRUNCATE_DATE_VALUES option [database] (deprecated)


DATETIME data type [Date and Time]

toggle Function

A domain, implemented as TIMESTAMP.

toggle Syntax

DATETIME

toggle Usage

DATETIME is provided primarily for compatibility with Adaptive Server Enterprise.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise. For an exception, see Transact-SQL compatibility of string-to-date/time conversions.

toggle See also
  • DATE data type [Date and Time]
  • SMALLDATETIME data type [Date and Time]
  • TIMESTAMP data type [Date and Time]


SMALLDATETIME data type [Date and Time]

toggle Function

A domain, implemented as TIMESTAMP.

toggle Syntax

SMALLDATETIME

toggle Usage

SMALLDATETIME is provided primarily for compatibility with Adaptive Server Enterprise.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise. For an exception, see Transact-SQL compatibility of string-to-date/time conversions.

toggle See also
  • DATE data type [Date and Time]
  • DATETIME data type [Date and Time]
  • TIMESTAMP data type [Date and Time]


TIME data type [Date and Time]

toggle Function

The time of day, containing hour, minute, second and fraction of a second.

toggle Syntax

TIME

toggle Usage

The fraction is stored to 6 decimal places. A TIME value requires 8 bytes of storage. (ODBC standards restrict TIME data type to an accuracy of seconds. For this reason you should not use TIME data types in WHERE clause comparisons that rely on a higher accuracy than seconds.)

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Supported by Adaptive Server Enterprise 12.5.1 and later.

toggle See also
  • TIMESTAMP data type [Date and Time]


TIMESTAMP data type [Date and Time]

toggle Function

The point in time, containing year, month, day, hour, minute, second and fraction of a second.

toggle Syntax

TIMESTAMP

toggle Usage

The fraction is stored to 6 decimal places. A TIMESTAMP value requires 8 bytes of storage.

Although the range of possible dates for the TIMESTAMP data type is the same as the DATE type (covering years 0001 to 9999), the useful range of TIMESTAMP date types is from 1600-02-28 23:59:59 to 7911-01-01 00:00:00. Prior to, and after this range the time portion of the TIMESTAMP may be incomplete.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Not supported in Adaptive Server Enterprise.

toggle See also
  • TIME data type [Date and Time]


Binary data types

toggle Function

For storing binary data, including images and other information that is not interpreted by the database.


BINARY data type [Binary]

toggle Function

Binary data of a specified maximum length (in bytes).

toggle Syntax

BINARY [ ( max-length ) ]

toggle Usage

The default max-length is 1.

The maximum size allowed is 32767. The BINARY data type is identical to the CHAR data type except when used in comparisons. BINARY values are compared exactly while CHAR values are compared using the collation sequence of the database.

toggle Parameters

max-length An integer expression that specifies the maximum length of the expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Adaptive Server Enterprise supports max-length up to 255.

toggle See also
  • LONG BINARY data type [BINARY]
  • VARBINARY data type [BINARY]


LONG BINARY data type [BINARY]

toggle Function

Arbitrary length binary data.

toggle Syntax

LONG BINARY

toggle Usage

The maximum size is 2 GB.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • BINARY data type [Binary]
  • VARBINARY data type [BINARY]


IMAGE data type [BINARY]

toggle Function

LONG BINARY data allowing NULL.

toggle Syntax

IMAGE

toggle Usage

IMAGE is implemented in Adaptive Server Anywhere as a domain, as LONG BINARY allowing NULL. It is provided primarily for compatibility with Adaptive Server Enterprise.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.


UNIQUEIDENTIFIER data type [Binary]

toggle Function

Storage of UUID (also known as GUID) values.

toggle Syntax

UNIQUEIDENTIFIER

toggle Usage

The UNIQUEIDENTIFIER data type is typically used for a primary key or other unique column to hold UUID (Universally Unique Identifier) values that uniquely identify rows. The NEWID function generates UUID values in such a way that a value produced on one computer will not match a UUID produced on another computer. UNIQUEIDENTIFIER values generated using NEWID can therefore be used as keys in a synchronization environment.

For example:

CREATE TABLE T1 (
    pk UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(),
    c1 INT )

UUID values are also referred to as GUIDs (Globally Unique Identifier).

Adaptive Server Anywhere automatically converts UNIQUEIDENTIFIER values between string and binary values as needed.

UNIQUEIDENTIFIER values are stored as BINARY(16), but are described to client applications as BINARY(36). This description ensures that if the client fetches the value as a string, it has allocated sufficient space for the result. For ODBC client applications, uniqueidentifier values appear as a SQL_GUID type.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

  • Backwards compatibility In databases created before version 9.0.2, UNIQUEIDENTIFIER was implemented as a user-defined data type using BINARY(16). The STRTOUUID and UUIDTOSTR functions were needed to convert the values between BINARY(16) and string representations. The STRTOUUID and UUIDTOSTR functions are not needed in databases created with version 9.0.2 or later, which support native UNIQUEIDENTIFIER data types.

    To confirm that your database supports the native UNIQUEIDENTIFER data type, check that the UniqueIdentifier property in the Extended Information tab of the Sybase Central Database Properties sheet is ON, or that the following query returns ON:

    select db_property('UniqueIdentifier')
toggle See also
  • The NEWID default
  • NEWID function [Miscellaneous]
  • UUIDTOSTR function [String]
  • STRTOUUID function [String]


VARBINARY data type [BINARY]

toggle Function

Identical to BINARY.

toggle Syntax

VARBINARY [ ( max-length ) ]

toggle Usage

Variable length binary strings. The default value for max-length is 1.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • BINARY data type [Binary]
  • LONG BINARY data type [BINARY]


Domains

toggle Function

Domains are aliases for built-in data types, including precision and scale values where applicable, and optionally including DEFAULT values and CHECK conditions. Some domains, such as the monetary data types, are pre-defined in Adaptive Server Anywhere, but you can add more of your own.

Domains, also called user-defined data types, allow columns throughout a database to be automatically defined on the same data type, with the same NULL or NOT NULL condition, with the same DEFAULT setting, and with the same CHECK condition. Domains encourage consistency throughout the database and can eliminate some types of errors.

Simple domains

Domains are created using the CREATE DOMAIN statement For full description of the syntax, see CREATE DOMAIN statement.

The following statement creates a data type named street_address, which is a 35-character string.

CREATE DOMAIN street_address CHAR( 35 )

CREATE DATATYPE can be used as an alternative to CREATE DOMAIN, but is not recommended because CREATE DOMAIN is the syntax used in the draft SQL/3 standard.

Resource authority is required to create data types. Once a data type is created, the user ID that executed the CREATE DOMAIN statement is the owner of that data type. Any user can use the data type. Unlike with other database objects, the owner name is never used to prefix the data type name.

The street_address data type may be used in exactly the same way as any other data type when defining columns. For example, the following table with two columns has the second column as a street_address column:

CREATE TABLE twocol (
    id INT,
    street street_address
)

Domains can be dropped by their owner or by the DBA, using the DROP DOMAIN statement:

DROP DOMAIN street_address

This statement can be carried out only if the data type is not used in any table in the database. If you attempt to drop a domain that is in use, the message "Primary key for row in table 'SYSUSERTYPE' is referenced in another table" appears.

Constraints and defaults with domains

Many of the attributes associated with columns, such as allowing NULL values, having a DEFAULT value, and so on, can be built into a domain. Any column that is defined on the data type automatically inherits the NULL setting, CHECK condition, and DEFAULT values. This allows uniformity to be built into columns with a similar meaning throughout a database.

For example, many primary key columns in the sample database are integer columns holding ID numbers. The following statement creates a data type that may be useful for such columns:

CREATE DOMAIN id INT
NOT NULL
DEFAULT AUTOINCREMENT
CHECK( @col > 0 )

Any column created using the data type id is not allowed to hold NULLs, defaults to an auto-incremented value, and must hold a positive number. Any identifier could be used instead of col in the @col variable.

The attributes of the data type can be overridden if needed by explicitly providing attributes for the column. A column created on data type id with NULL values explicitly allowed does allow NULLs, regardless of the setting in the id data type.

Compatibility

  • Named constraints and defaults In Adaptive Server Anywhere, domains are created with a base data type, and optionally a NULL or NOT NULL condition, a default value, and a CHECK condition. Named constraints and named defaults are not supported.

  • Creating data types In Adaptive Server Anywhere, you can use the sp_addtype system procedure to add a domain, or you can use the CREATE DOMAIN statement. In Adaptive Server Enterprise, you must use sp_addtype.


Data type conversions

Type conversions can happen automatically, or they can be explicitly requested using the CAST or CONVERT function.

If a string is used in a numeric expression or as an argument to a function that expects a numeric argument, the string is converted to a number.

If a number is used in a string expression or as a string function argument, it is converted to a string before being used.

All date constants are specified as strings. The string is automatically converted to a date before use.

There are certain cases where the automatic database conversions are not appropriate.

'12/31/90' + 5
'a' > 0

The automatic data type conversion fails here. You can use the CAST or CONVERT function to force type conversions. For information about the CAST and CONVERT functions, see Data type conversion functions.

The following functions can also be used to force type conversions (see SQL Functions).

  • DATE( value ) Converts the expression into a date, and removes any hours, minutes or seconds. Conversion errors may be reported.

  • STRING( value ) Equivalent to CAST( value AS LONG VARCHAR ).

    For more information about the STRING function, see STRING function [String].

  • VALUE+0.0 Equivalent to CAST( value AS DECIMAL ).

For more information about the CAST function, see CAST function [Data type conversion].

Conversion when using comparison operators


Conversion when using comparison operators

When a comparison (such as =) is performed between arguments with different data types, one or both arguments must be converted so that the comparison is done using one data type. Sometimes it is preferable for you to explicitly convert one of the arguments using CAST or CONVERT.

Adaptive Server Anywhere uses the following rules to perform a comparison (the rules are examined in the order listed, and the first rule that applies is used):

  1. If the data type of either argument is TIME, convert both to TIME and compare.

  2. If one argument is TINYINT and the other is INTEGER, convert both to INTEGER and compare.

  3. If one argument is TINYINT and the other is SMALLINT, convert both to SMALLINT and compare.

  4. If one argument is UNSIGNED SMALLINT and the other is INTEGER, convert both to INTEGER and compare.

  5. If the data types of the arguments have a common super type, convert to the common super type and compare. The super types are the final data type in each of the following lists:

    • BIT > TINYINT > UNSIGNED SMALLINT > UNSIGNED INTEGER > UNSIGNED BIGINT > NUMERIC

    • SMALLINT > INTEGER > BIGINT > NUMERIC

    • REAL > DOUBLE

    • CHAR > LONG VARCHAR

    • BINARY > LONG BINARY

    • DATE > TIMESTAMP

    For example, if the two arguments are of types BIT and TINYINT, they are converted to NUMERIC.

  6. If either data type has the type DATE or TIMESTAMP, convert to both to TIMESTAMP and compare.

    For example, if the two arguments are of type REAL and DATE, they are both converted to TIMESTAMP.

  7. If the data type of either argument is UNIQUEIDENTIFIER, convert both to UNIQUEIDENTIFIER and compare.

  8. If one argument has CHARACTER data type and the other has BINARY data type, convert both to BINARY and compare.

  9. If one argument has NUMERIC data type and the other has FLOAT, convert both to DOUBLE and compare.

  10. Convert to NUMERIC and compare.

    For example, if the two arguments have REAL and CHAR data types, they are both converted to NUMERIC.

Notes

  • You can override these rules by explicitly casting arguments to another type. For example, if you want to compare a DATE and a CHAR as a CHAR, then you need to explicitly cast the DATE to a CHAR.

    For more information, see CAST function [Data type conversion].

  • Rules 1, 6, and 10 may lead to conversions that fail.


Java and SQL data type conversion

Data type conversion between Java types and SQL types is required for both Java stored procedures and JDBC applications. Java to SQL and SQL to Java data type conversions are carried out according to the JDBC standard. The conversions are described in the following tables.


Java to SQL data type conversion

Java type | SQL type
String | CHAR
String | VARCHAR
String | TEXT
java.math.BigDecimal | NUMERIC
java.math.BigDecimal | MONEY
java.math.BigDecimal | SMALLMONEY
boolean | BIT
byte | TINYINT
Short | SMALLINT
Int | INTEGER
long | INTEGER
float | REAL
double | DOUBLE
byte[ ] | VARBINARY
byte[ ] | IMAGE
java.SQL.Date | DATE
java.SQL.Time | TIME
java.SQL.Timestamp | TIMESTAMP
java.lang.Double | DOUBLE
java.lang.Float | REAL
java.lang.Integer | INTEGER
java.lang.Long | INTEGER
void | this1

1 The method returns the object itself


SQL to Java data type conversion

SQL type | Java type
CHAR | String
VARCHAR | String
TEXT | String
NUMERIC | java.math.BigDecimal
DECIMAL | java.math.BigDecimal
MONEY | java.math.BigDecimal
SMALLMONEY | java.math.BigDecimal
BIT | boolean
TINYINT | byte
SMALLINT | short
INTEGER | int
BIGINT | long
REAL | float
FLOAT | double
DOUBLE | double
BINARY | byte[ ]
VARBINARY | byte[ ]
LONG VARBINARY | byte[ ]
IMAGE | byte[ ]
DATE | java.SQL.Date
TIME | java.SQL.Time
TIMESTAMP | java.SQL.Timestamp


Year 2000 compliance

The problem of handling dates, in particular year values in and beyond the year 2000, was a significant issue for the computer industry.

This section examines the year 2000 compliance of Adaptive Server Anywhere. It illustrates how date values are handled internally by Adaptive Server Anywhere, and how Adaptive Server Anywhere handles ambiguous date information, such as the conversion of a two digit year string value.

Users of Sybase Adaptive Server Anywhere and its predecessors can be assured that dates are handled and stored internally in a manner not adversely effected by the transition from the 20th century to the 21st century.

Consider the following measurements of Adaptive Server Anywhere year 2000 compliance:

  • Adaptive Server Anywhere always returns correct values for any legal arithmetic and logical operations on dates, regardless of whether the calculated values span different centuries.

  • At all times, the Adaptive Server Anywhere internal storage of dates explicitly includes the century portion of a year value.

  • The operation of Adaptive Server Anywhere is unaffected by any return value, including the current date.

  • Date values can always be output in full century format.

Many of the date–related topics summarized in this section are explained in greater detail in other parts of the documentation.


How dates are stored

Dates containing year values are used internally and stored in Adaptive Server Anywhere databases using either of the following data types:

Data type | Contains | Stored in | Range of possible values
DATE | Calendar date (year, month, day) | 4-bytes | 0001-01-01 to 9999-12-31
TIMESTAMP | Time stamp (year, month, day, hour minute, second, and fraction of second accurate to 6 decimal places) | 8-bytes | 0001-01-01 to 9999-12-31 (precision of the time portion of TIMESTAMP is dropped prior to 1600-02-28 23:59:59 and after 7911-01-01 00:00:00)

For more information on Adaptive Server Anywhere date and time data types see Date and time data types.


Sending and retrieving date values

Date values are stored within Adaptive Server Anywhere as either a DATE or TIMESTAMP data type, but they are passed to and retrieved from Adaptive Server Anywhere using one of the following methods:

  • As a string, using any Adaptive Server Anywhere programming interface.

  • As a TIMESTAMP structure, using ODBC.

  • As a SQLDATETIME structure, using Embedded SQL.

A string containing a date value is considered unambiguous and is automatically converted to a DATE or TIMESTAMP data type without potential for misinterpretation if it is passed using the following format: yyyy-mm-dd (the "-" dash separator is one of several characters that are permitted).

For more information

Date formats other than yyyy-mm-dd can be used by setting the DATE_FORMAT database option. For more information, see DATE_FORMAT option [compatibility].

For more information on unambiguous date formats, see Using unambiguous dates and times.

For more information on the ODBC TIMESTAMP structure, see the Microsoft Open Database Connectivity SDK, or Sending dates and times to the database.

Used in the development of C programs, an embedded SQL SQLDATETIME structure's year value is a 16-bit signed integer.

For more information on the SQLDATETIME data type, see Embedded SQL data types.


Leap years

The year 2000 is a leap year, with an additional day in the month of February. Adaptive Server Anywhere uses a globally accepted algorithm for determining which years are leap years. Using this algorithm, a year is considered a leap year if it is divisible by four, unless the year is a century date (such as the year 1900), in which case it is a leap year only if it is divisible by 400.

Adaptive Server Anywhere handles all leap years correctly. For example, the following SQL statement results in a return value of "Tuesday":

SELECT DAYNAME('2000-02-29')

Adaptive Server Anywhere accepts February 29, 2000—a leap year—as a date, and using this date determines the day of the week.

However, the following statement is rejected by Adaptive Server Anywhere:

SELECT DAYNAME('2001-02-29')

This statement results in an error (cannot convert '2001-02-29' to a date) because February 29th does not exist in the year 2001.


Ambiguous string to date conversions

Adaptive Server Anywhere automatically converts a string into a date when a date value is expected, even if the year is represented in the string by only two digits.

If the century portion of a year value is omitted, the method of conversion is determined by the NEAREST_CENTURY database option.

The NEAREST_CENTURY database option is a numeric value that acts as a break point between 19YY date values and 20YY date values.

Two-digit years less than the NEAREST_CENTURY value are converted to 20yy, while years greater than or equal to the value are converted to 19yy.

If this option is not set, the default setting of 50 is assumed. Thus, two-digit year strings are understood to refer to years between 1950 and 2049.

This NEAREST_CENTURY option was introduced in SQL Anywhere Version 5.5. In version 5.5, the default setting was 0.

Ambiguous date conversion example

The following statement creates a table that can be used to illustrate the conversion of ambiguous date information in Adaptive Server Anywhere.

CREATE TABLE T1 (C1 DATE);

The table T1 contains one column, C1, of the type DATE.

The following statement inserts a date value into the column C1. Adaptive Server Anywhere automatically converts a string that contains an ambiguous year value, one with two digits representing the year but nothing to indicate the century.

INSERT INTO T1 VALUES('00-01-01');

By default, the NEAREST_CENTURY option is set to 50, thus Adaptive Server Anywhere converts the above string into the date 2000-01-01. The following statement verifies the result of this insert.

SELECT * FROM T1;

Changing the NEAREST_CENTURY option using the following statement alters the conversion process.

SET OPTION NEAREST_CENTURY = 0;

When NEAREST_CENTURY option is set to 0, executing the previous insert using the same statement will create a different date value:

INSERT INTO T1 VALUES('00-01-01');

The above statement now results in the insertion of the date 1900-01-01. Use the following statement to verify the results.

SELECT * FROM T1;


Date to string conversions

Adaptive Server Anywhere provides several functions for converting Adaptive Server Anywhere date and time values into a wide variety of strings and other expressions. It is possible in converting a date value into a string to reduce the year portion into a two-digit number representing the year, thereby losing the century portion of the date.

Wrong century values

Consider the following statement, which incorrectly converts a string representing the date January 1, 2000 into a string representing the date January 1, 1900 even though no database error occurs.

SELECT DATEFORMAT (
            DATEFORMAT('2000-01-01', 'Mmm dd/yy' ),
            'yyyy-Mmm-dd' )
    AS Wrong_year;

Adaptive Server Anywhere automatically and correctly converts the unambiguous date string 2000-01-01 into a date value. However, the 'Mmm dd/yy' formatting of the inner, or nested, DATEFORMAT function drops the century portion of the date when it is converted back to a string and passed to the outer DATEFORMAT function.

Because the database option NEAREST_CENTURY in this case is set to 0, the outer DATEFORMAT function converts the string representing a date with a two-digit year value into a year between 1900 and 1999.

For more information on date and time functions, see Date and time functions.


SQL Functions

About this chapter

Functions are used to return information from the database. They are allowed anywhere an expression is allowed.

NULL parameters
Unless otherwise stated, any function that receives NULL as a parameter returns NULL.

The chapter includes a grouping of functions by type, followed by an alphabetical list of functions.


Function types

This section groups the available function by type.

Aggregate functions
Rank functions
Data type conversion functions
Date and time functions
Java and SQL user-defined functions
Miscellaneous functions
Numeric functions
HTTP functions
String functions
System functions
Text and image functions


Aggregate functions

Aggregate functions summarize data over a group of rows from the database. The groups are formed using the GROUP BY clause of the SELECT statement. Aggregate functions are allowed only in the select list and in the HAVING and ORDER BY clauses of a SELECT statement.

List of functions

The following aggregate functions are available:

  • AVG function [Aggregate]

  • COS function [Numeric]

  • COVAR_POP function [Aggregate]

  • COVAR_SAMP function [Aggregate]

  • COUNT function [Aggregate]

  • GROUPING function [Aggregate]

  • LIST function [Aggregate]

  • MAX function [Aggregate]

  • MIN function [Aggregate]

  • REGR_AVGX [Aggregate]

  • REGR_AVGY [Aggregate]

  • REGR_COUNT [Aggregate]

  • REGR_INTERCEPT [Aggregate]

  • REGR_R2 [Aggregate]

  • REGR_SLOPE [Aggregate]

  • REGR_SXX [Aggregate]

  • REGR_SXY [Aggregate]

  • REGR_SYY [Aggregate]

  • STDDEV function [Aggregate]

  • STDDEV_POP function [Aggregate]

  • STDDEV_SAMP function [Aggregate]

  • SUM function [Aggregate]

  • VAR_POP function [Aggregate]

  • VAR_SAMP function [Aggregate]

  • VARIANCE function [Aggregate]


Rank functions

Rank functions let you compute a rank value for each row in a result set based on an ordering specified in the query.

  • CUME_DIST function [Aggregate]

  • DENSE_RANK function [Aggregate]

  • PERCENT_RANK function [Aggregate]

  • RANK function [Aggregate]

  • ROW_NUMBER function [Aggregate]


Data type conversion functions

These functions are used to convert arguments from one data type to another, or to test whether they can be converted.

Compatibility

  • The Adaptive Server Anywhere cast function is not currently supported by Adaptive Server Enterprise.

List of functions

The following data type conversion functions are available:

  • CAST function [Data type conversion]

  • CONVERT function [Data type conversion]

  • HEXTOINT function [Data type conversion]

  • INTTOHEX function [Data type conversion]

  • ISDATE function [Data type conversion]

  • ISNUMERIC function [Miscellaneous]


Date and time functions

Date and time functions perform operations on date and time data types or return date or time information.

In this chapter, the term datetime is used to mean date or time or timestamp. The specific data type DATETIME is indicated as DATETIME.

For more information on datetime data types, see Date and time data types.

List of functions

The following date and time functions are available:

  • DATE function [Date and time]

  • DATEADD function [Date and time]

  • DATEDIFF function [Date and time]

  • DATEFORMAT function [Date and time]

  • DATENAME function [Date and time]

  • DATEPART function [Date and time]

  • DATETIME function [Date and time]

  • DAY function [Date and time]

  • DAYNAME function [Date and time]

  • DAYS function [Date and time]

  • DOW function [Date and time]

  • GETDATE function [Date and time]

  • HOUR function [Date and time]

  • HOURS function [Date and time]

  • MINUTE function [Date and time]

  • MINUTES function [Date and time]

  • MONTH function [Date and time]

  • MONTHNAME function [Date and time]

  • MONTHS function [Date and time]

  • NOW function [Date and time]

  • QUARTER function [Date and time]

  • SECOND function [Date and time]

  • SECONDS function [Date and time]

  • TODAY function [Date and time]

  • WEEKS function [Date and time]

  • YEAR function [Date and time]

  • YEARS function [Date and time]

  • YMD function [Date and time]

Date parts


Date parts

Many of the date functions use dates built from date parts. The following table displays allowed values of date-parts.

Date Part | Abbreviation | Values
Year | yy | 1–9999
Quarter | qq | 1–4
Month | mm | 1–12
Week | wk | 1–54. Weeks begin on Sunday.
Day | dd | 1–31
Dayofyear | dy | 1–366
Weekday | dw | 1–7 (Sunday = 1, ..., Saturday = 7)
Hour | hh | 0–23
Minute | mi | 0–59
Second | ss | 0–59
Millisecond | ms | 0–999
Calyearofweek | cyr | Integer. The year in which the week begins. The week containing the first few days of the year may have started in the previous year, depending on the weekday on which the year started. Years starting on Monday through Thursday have no days that are part of the previous year, but years starting on Friday through Sunday start their first week on the first Monday of the year.
Calweekofyear | cwk | 1–54. The week number within the year that contains the specified date.
Caldayofweek | cdw | 1–7. (Sunday = 1, ..., Saturday = 7)


Java and SQL user-defined functions

There are two mechanisms for creating user-defined functions in Adaptive Server Anywhere. You can use the SQL language to write the function, or you can use Java.

User-defined functions in SQL

You can implement your own functions in SQL using the CREATE FUNCTION statement. The RETURN statement inside the CREATE FUNCTION statement determines the data type of the function.

Once a SQL user-defined function is created, it can be used anywhere a built-in function of the same data type is used.

For more information on creating SQL functions, see Using Procedures, Triggers, and Batches.

User-defined functions in Java

Java classes provide a more powerful and flexible way of implementing user-defined functions, with the additional advantage that they can be moved from the database server to a client application if desired.

Any class method of an installed Java class can be used as a user-defined function anywhere a built-in function of the same data type is used.

Instance methods are tied to particular instances of a class, and so have different behavior from standard user-defined functions.

For more information on creating Java classes, and on class methods, see A Java seminar.


Miscellaneous functions

Miscellaneous functions perform operations on arithmetic, string or date/time expressions, including the return values of other functions.

List of functions

The following miscellaneous functions are available:

  • ARGN function [Miscellaneous]

  • COALESCE function [Miscellaneous]

  • COMPRESS function [String]

  • CONFLICT function [Miscellaneous]

  • DECOMPRESS function [String]

  • DECRYPT function [String]

  • ENCRYPT function [String]

  • ERRORMSG function [Miscellaneous]

  • ESTIMATE function [Miscellaneous]

  • ESTIMATE_SOURCE function [Miscellaneous]

  • EXPERIENCE_ESTIMATE function [Miscellaneous]

  • EXPLANATION function [Miscellaneous]

  • EXPRTYPE function [Miscellaneous]

  • GET_IDENTITY function [Miscellaneous]

  • GRAPHICAL_PLAN function [Miscellaneous]

  • GRAPHICAL_ULPLAN function [Miscellaneous]

  • GREATER function [Miscellaneous]

  • HASH function [String]

  • IDENTITY function [Miscellaneous]

  • IFNULL function [Miscellaneous]

  • INDEX_ESTIMATE function [Miscellaneous]

  • ISNULL function [Data type conversion]

  • LESSER function [Miscellaneous]

  • LONG_ULPLAN function [Miscellaneous]

  • NEWID function [Miscellaneous]

  • NULLIF function [Miscellaneous]

  • NUMBER function [Miscellaneous]

  • PLAN function [Miscellaneous]

  • REWRITE function [Miscellaneous]

  • SHORT_ULPLAN function [Miscellaneous]

  • SQLDIALECT function [Miscellaneous]

  • TRACEBACK function [Miscellaneous]

  • TRANSACTSQL function [Miscellaneous]

  • VAREXISTS function [Miscellaneous]

  • WATCOMSQL function [Miscellaneous]


Numeric functions

Numeric functions perform mathematical operations on numerical data types or return numeric information.

List of functions

The following numeric functions are available:

  • ABS function [Numeric]

  • ACOS function [Numeric]

  • ASIN function [Numeric]

  • ATAN function [Numeric]

  • ATN2 function [Numeric]

  • CEILING function [Numeric]

  • COS function [Numeric]

  • COT function [Numeric]

  • DEGREES function [Numeric]

  • EXP function [Numeric]

  • FLOOR function [Numeric]

  • LOG function [Numeric]

  • LOG10 function [Numeric]

  • MOD function [Numeric]

  • PI function [Numeric]

  • POWER function [Numeric]

  • RADIANS function [Numeric]

  • RAND function [Numeric]

  • REMAINDER function [Numeric]

  • ROUND function [Numeric]

  • SIGN function [Numeric]

  • SIN function [Numeric]

  • SQRT function [Numeric]

  • TAN function [Numeric]

  • TRUNCATE function [Numeric]

  • TRUNCNUM function [Numeric]


HTTP functions

HTTP functions facilitate the handling of HTTP requests within web services.

List of functions

The following functions are available:

  • HTML_DECODE function

  • HTML_ENCODE function

  • HTTP_DECODE function [HTTP]

  • HTTP_ENCODE function [HTTP]

  • HTTP_VARIABLE function [HTTP]

  • NEXT_HTTP_HEADER function [HTTP]

  • NEXT_HTTP_VARIABLE function [HTTP]


String functions

String functions perform conversion, extraction, or manipulation operations on strings, or return information about strings.

When working in a multi-byte character set, check carefully whether the function being used returns information concerning characters or bytes.

List of functions

The following string functions are available:

  • ASCII function [String]

  • BASE64_DECODE function [String]

  • BASE64_ENCODE function [String]

  • BYTE_LENGTH function [String]

  • BYTE_SUBSTR function [String]

  • CHAR function [String]

  • CHARINDEX function [String]

  • CHAR_LENGTH function [String]

  • COMPARE function [String]

  • COMPRESS function [String]

  • CSCONVERT function [String]

  • DECOMPRESS function [String]

  • DECRYPT function [String]

  • DIFFERENCE function [String]

  • ENCRYPT function [String]

  • HASH function [String]

  • INSERTSTR function [String]

  • LCASE function [String]

  • LEFT function [String]

  • LENGTH function [String]

  • LOCATE function [String]

  • LOWER function [String]

  • LTRIM function [String]

  • OPENXML function [String]

  • PATINDEX function [String]

  • REPEAT function [String]

  • REPLACE function [String]

  • REPLICATE function [String]

  • RIGHT function [String]

  • RTRIM function [String]

  • SIMILAR function [String]

  • SORTKEY function [String]

  • SOUNDEX function [String]

  • SPACE function [String]

  • STR function [String]

  • STRING function [String]

  • STRTOUUID function [String]

  • STUFF function [String]

  • SUBSTRING function [String]

  • TRIM function [String]

  • UCASE function [String]

  • UPPER function [String]

  • UUIDTOSTR function [String]

  • XMLAGG function [String]

  • XMLCONCAT function [String]

  • XMLELEMENT function [String]

  • XMLFOREST function [String]

  • XMLGEN function [String]


System functions

System functions return system information.

List of functions

The following system functions are available:

  • CONNECTION_PROPERTY function [System]

  • DATALENGTH function [System]

  • DB_ID function [System]

  • DB_NAME function [System]

  • DB_EXTENDED_PROPERTY function [System]

  • DB_PROPERTY function [System]

  • EVENT_CONDITION function [System]

  • EVENT_CONDITION_NAME function [System]

  • EVENT_PARAMETER function [System]

  • NEXT_CONNECTION function [System]

  • NEXT_DATABASE function [System]

  • PROPERTY function [System]

  • PROPERTY_DESCRIPTION function [System]

  • PROPERTY_NAME function [System]

  • PROPERTY_NUMBER function [System]

Compatibility

The following table displays the Adaptive Server Enterprise system functions and their status in Adaptive Server Anywhere:

Function Status
Col_length
 Implemented
Col_name
 Implemented
Curunreservedpgs
 Not implemented
Data_pgs
 Not implemented
Datalength
 Implemented
Db_id
 Implemented
Db_name
 Implemented
Host_id
 Not implemented
Host_name
 Not implemented
Index_col
 Implemented
Lct_admin
 Not implemented
Object_id
 Implemented
Object_name
 Implemented
Proc_role
 Always returns 0
Reserved_pgs
 Not implemented
Rowcnt
 Not implemented
Show_role
 Always returns NULL
Suser_id
 Implemented
Suser_name
 Implemented
Tsequal
 Implemented
Used_pgs
 Not implemented
User_id
 Implemented
User_name
 Implemented
Valid_name
 Not implemented
Valid_user
 Not implemented
Notes

  • Some of the system functions are implemented in Adaptive Server Anywhere as stored procedures.

  • The db_id, db_name, and datalength functions are implemented as built-in functions.

The implemented system functions are described in the following table.

System function Description
Col_length( table-name, column-name )
 Returns the defined length of column
Col_name( table-id, column-id [, database-id] )
 Returns the column name
Datalength( expression )
 Returns the length of the expression, in bytes
Db_id( [ database-name ] )
 Returns the database ID number
Db_name( [ database-id ] )
 Returns the database name
Index_col (table-name, index-id, key_# [, userid] )
 Returns the name of the indexed column
Object_id (object-name )
 Returns the object ID
Object_name ( object-id [, database-id ] )
 Returns the object name
Suser_id( [user-name] )
 Returns an integer user identification number
Suser_name( [user-id] )
 Returns the user ID (server user name in Adaptive Server Enterprise)
Tsequal (timestamp, timestamp2 )
 Compares timestamp values to prevent update on a row that has been modified since it was selected
User_id( [ user-name] )
 Returns an integer user identification number. This does not return the Adaptive Server Anywhere user ID
User_name( [user-id] )
 Returns the user ID (user name in Adaptive Server Enterprise)


Text and image functions

Text and image functions operate on text and image data types. Adaptive Server Anywhere supports only the textptr text and image function.

Compatibility

  • Adaptive Server Anywhere does not currently support the Adaptive Server Enterprise textvalid function.

List of functions

The following text and image function is available:

  • TEXTPTR function [Text and image]


Alphabetical list of functions

Each function is listed, and the function type (numeric, character, and so on) is indicated next to it.

For links to all functions of a given type, see Function types.

ABS function [Numeric]
ACOS function [Numeric]
ARGN function [Miscellaneous]
ASCII function [String]
ASIN function [Numeric]
ATAN function [Numeric]
ATN2 function [Numeric]
AVG function [Aggregate]
BASE64_DECODE function [String]
BASE64_ENCODE function [String]
BYTE_LENGTH function [String]
BYTE_SUBSTR function [String]
CAST function [Data type conversion]
CEILING function [Numeric]
CHAR function [String]
CHARINDEX function [String]
CHAR_LENGTH function [String]
COALESCE function [Miscellaneous]
COMPARE function [String]
COMPRESS function [String]
CONNECTION_PROPERTY function [System]
CONFLICT function [Miscellaneous]
CONVERT function [Data type conversion]
CORR function [Aggregate]
COS function [Numeric]
COT function [Numeric]
COUNT function [Aggregate]
COVAR_POP function [Aggregate]
COVAR_SAMP function [Aggregate]
CSCONVERT function [String]
CUME_DIST function [Aggregate]
DATALENGTH function [System]
DATE function [Date and time]
DATEADD function [Date and time]
DATEDIFF function [Date and time]
DATEFORMAT function [Date and time]
DATENAME function [Date and time]
DATEPART function [Date and time]
DATETIME function [Date and time]
DAY function [Date and time]
DAYNAME function [Date and time]
DAYS function [Date and time]
DB_ID function [System]
DB_NAME function [System]
DB_EXTENDED_PROPERTY function [System]
DB_PROPERTY function [System]
DECOMPRESS function [String]
DECRYPT function [String]
DEGREES function [Numeric]
DENSE_RANK function [Aggregate]
DIFFERENCE function [String]
DOW function [Date and time]
ENCRYPT function [String]
ERRORMSG function [Miscellaneous]
ESTIMATE function [Miscellaneous]
ESTIMATE_SOURCE function [Miscellaneous]
EVENT_CONDITION function [System]
EVENT_CONDITION_NAME function [System]
EVENT_PARAMETER function [System]
EXP function [Numeric]
EXPERIENCE_ESTIMATE function [Miscellaneous]
EXPLANATION function [Miscellaneous]
EXPRTYPE function [Miscellaneous]
FLOOR function [Numeric]
GET_IDENTITY function [Miscellaneous]
GETDATE function [Date and time]
GRAPHICAL_PLAN function [Miscellaneous]
GRAPHICAL_ULPLAN function [Miscellaneous]
GREATER function [Miscellaneous]
GROUPING function [Aggregate]
HASH function [String]
HEXTOINT function [Data type conversion]
HOUR function [Date and time]
HOURS function [Date and time]
HTML_DECODE function
HTML_ENCODE function
HTTP_DECODE function [HTTP]
HTTP_ENCODE function [HTTP]
HTTP_HEADER function [HTTP]
HTTP_VARIABLE function [HTTP]
IDENTITY function [Miscellaneous]
IFNULL function [Miscellaneous]
INDEX_ESTIMATE function [Miscellaneous]
INSERTSTR function [String]
INTTOHEX function [Data type conversion]
ISDATE function [Data type conversion]
ISNULL function [Data type conversion]
ISNUMERIC function [Miscellaneous]
LCASE function [String]
LEFT function [String]
LENGTH function [String]
LESSER function [Miscellaneous]
LIST function [Aggregate]
LOCATE function [String]
LOG function [Numeric]
LOG10 function [Numeric]
LONG_ULPLAN function [Miscellaneous]
LOWER function [String]
LTRIM function [String]
MAX function [Aggregate]
MIN function [Aggregate]
MINUTE function [Date and time]
MINUTES function [Date and time]
MOD function [Numeric]
MONTH function [Date and time]
MONTHNAME function [Date and time]
MONTHS function [Date and time]
NEWID function [Miscellaneous]
NEXT_CONNECTION function [System]
NEXT_DATABASE function [System]
NEXT_HTTP_HEADER function [HTTP]
NEXT_HTTP_VARIABLE function [HTTP]
NOW function [Date and time]
NULLIF function [Miscellaneous]
NUMBER function [Miscellaneous]
OPENXML function [String]
PATINDEX function [String]
PERCENT_RANK function [Aggregate]
PI function [Numeric]
PLAN function [Miscellaneous]
POWER function [Numeric]
PROPERTY_DESCRIPTION function [System]
PROPERTY function [System]
PROPERTY_NAME function [System]
PROPERTY_NUMBER function [System]
QUARTER function [Date and time]
RADIANS function [Numeric]
RAND function [Numeric]
RANK function [Aggregate]
REGR_AVGX [Aggregate]
REGR_AVGY [Aggregate]
REGR_COUNT [Aggregate]
REGR_INTERCEPT [Aggregate]
REGR_R2 [Aggregate]
REGR_SLOPE [Aggregate]
REGR_SXX [Aggregate]
REGR_SXY [Aggregate]
REGR_SYY [Aggregate]
REMAINDER function [Numeric]
REPEAT function [String]
REPLACE function [String]
REPLICATE function [String]
REWRITE function [Miscellaneous]
RIGHT function [String]
ROUND function [Numeric]
ROW_NUMBER function [Aggregate]
RTRIM function [String]
SECOND function [Date and time]
SECONDS function [Date and time]
SHORT_ULPLAN function [Miscellaneous]
SIGN function [Numeric]
SIMILAR function [String]
SIN function [Numeric]
SORTKEY function [String]
SOUNDEX function [String]
SPACE function [String]
SQLDIALECT function [Miscellaneous]
SQRT function [Numeric]
STDDEV function [Aggregate]
STDDEV_POP function [Aggregate]
STDDEV_SAMP function [Aggregate]
STR function [String]
STRING function [String]
STRTOUUID function [String]
STUFF function [String]
SUBSTRING function [String]
SUM function [Aggregate]
TAN function [Numeric]
TEXTPTR function [Text and image]
TODAY function [Date and time]
TRACEBACK function [Miscellaneous]
TRANSACTSQL function [Miscellaneous]
TRIM function [String]
TRUNCATE function [Numeric]
TRUNCNUM function [Numeric]
UCASE function [String]
UPPER function [String]
UUIDTOSTR function [String]
VAR_POP function [Aggregate]
VAR_SAMP function [Aggregate]
VARIANCE function [Aggregate]
VAREXISTS function [Miscellaneous]
WATCOMSQL function [Miscellaneous]
WEEKS function [Date and time]
XMLAGG function [String]
XMLCONCAT function [String]
XMLELEMENT function [String]
XMLFOREST function [String]
XMLGEN function [String]
YEAR function [Date and time]
YEARS function [Date and time]
YMD function [Date and time]


ABS function [Numeric]

toggle Function

Returns the absolute value of a numeric expression.

toggle Syntax

ABS ( numeric-expression )

toggle Parameters

numeric expression The number whose absolute value is to be returned.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value 66.

SELECT ABS( -66 )


ACOS function [Numeric]

toggle Function

Returns the arc-cosine, in radians, of a numeric expression.

toggle Syntax

ACOS ( numeric-expression )

toggle Parameters

numeric-expression The cosine of the angle.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • ASIN function [Numeric]
  • ATAN function [Numeric]
  • ATN2 function [Numeric]
  • COS function [Numeric]
toggle Example

The following statement returns the value 1998-06-12.

SELECT YMD( 1998, 06, 12 )

If the values are outside their normal range, the date will adjust accordingly. For example, the following statement returns the value 2000-03-01.

SELECT YMD( 1999, 15, 1 )
toggle Example

The following statement returns the value 1.023945.

SELECT ACOS( 0.52 )


ARGN function [Miscellaneous]

toggle Function

Returns a selected argument from a list of arguments.

toggle Syntax

ARGN ( integer-expression, expression [ , ...] )

toggle Parameters

integer-expression The position of an argument within the list of expressions.

expression An expression of any data type passed into the function. All supplied expressions must be of the same data type.

toggle Usage

Using the value of the integer-expression as n, returns the nth argument (starting at 1) from the remaining list of arguments. While the expressions can be of any data type, they must all be of the same data type. The integer expression must be from one to the number of expressions in the list or NULL is returned. Multiple expressions are separated by a comma.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value 6.

SELECT ARGN( 6, 1,2,3,4,5,6 )


ASCII function [String]

toggle Function

Returns the integer ASCII value of the first byte in a string-expression.

toggle Syntax

ASCII ( string-expression )

toggle Parameters

string-expression The string.

toggle Usage

If the string is empty, then ASCII returns zero. Literal strings must be enclosed in quotes. If the database character set is multi-byte and the first character of the parameter string consists of more than one byte, the result is NULL.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value 90.

SELECT ASCII( 'Z' )


ASIN function [Numeric]

toggle Function

Returns the arc-sine, in radians, of a number.

toggle Syntax

ASIN ( numeric-expression )

toggle Parameters

numeric-expression The sine of the angle.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • ACOS function [Numeric]
  • ATAN function [Numeric]
  • ATN2 function [Numeric]
  • SIN function [Numeric]
toggle Example

The following statement returns the value 0.546850.

SELECT ASIN( 0.52 )


ATAN function [Numeric]

toggle Function

Returns the arc-tangent, in radians, of a number.

toggle Syntax

ATAN ( numeric-expression )

toggle Parameters

numeric-expression The tangent of the angle.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • ACOS function [Numeric]
  • ASIN function [Numeric]
  • ATN2 function [Numeric]
  • TAN function [Numeric]
toggle Example

The following statement returns the value 0.479519.

SELECT ATAN( 0.52 )


ATN2 function [Numeric]

toggle Function

Returns the arc-tangent, in radians, of the ratio of two numbers.

toggle Syntax

{ ATN2 | ATAN2 } ( numeric-expression-1, numeric-expression-2 )

toggle Parameters

numeric-expression-1 The numerator in the ratio whose arc-tangent is calculated.

numeric-expression-2 The denominator in the ratio whose arc-tangent is calculated.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase ATN2 is compatible with Adaptive Server Enterprise. ATAN2 is not supported by Adaptive Server Enterprise.

toggle See also
  • ACOS function [Numeric]
  • ASIN function [Numeric]
  • ATAN function [Numeric]
  • TAN function [Numeric]
toggle Example

The following statement returns the value 0.008666.

SELECT ATAN2( 0.52, 060 )


AVG function [Aggregate]

toggle Function

Computes the average, for a set of rows, of a numeric-expression or of a set unique values.

toggle Syntax

AVG ( numeric-expression | DISTINCT column-name )

toggle Parameters

numeric-expression The expression whose average is calculated over a set of rows.

DISTINCT column-name Computes the average of the unique values in column-name. This is of limited usefulness, but is included for completeness.

toggle Usage

This average does not include rows where the numeric expression is the NULL value. Returns the NULL value for a group containing no rows.

toggle Standards and compatibility

  • SQL/92 SQL/92 compatible.

  • SQL/99 Core feature.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • SUM function [Aggregate]
  • COUNT function [Aggregate]
toggle Example

The following statement returns the value 49988.6.

SELECT AVG( salary ) FROM employee


BASE64_DECODE function [String]

toggle Function

Decodes data using the MIME base64 format and returns the string as a LONG VARCHAR.

toggle Syntax

BASE64_DECODE ( string-expression )

toggle Parameters

string-expression The string that is to be decoded. Note that the string must be base64-encoded.

toggle Standards and compatibility

SQL/92 Vendor extension.

SQL/99 Vendor extension.

Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • BASE64_ENCODE function [String]
toggle Example

The following inserts an image into an image table from an embedded SQL program. The input data (host variable) must be base64 encoded.

EXEC SQL INSERT INTO images ( image_data ) VALUES ( BASE64_DECODE ( :img ) )


BASE64_ENCODE function [String]

toggle Function

Encodes data using the MIME base64 format and returns it as a 7-bit ASCII string.

toggle Syntax

BASE64_ENCODE ( string-expression )

toggle Parameters

string-expression The string that is to be encoded.

toggle Standards and compatibility

SQL/92 Vendor extension.

SQL/99 Vendor extension.

Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • BASE64_DECODE function [String]
toggle Example

The following retrieves data from a table containing images and returns it in ASCII format. The resulting string can be embedded into an email message, and then decoded by the recipient to retrieve the original image.

SELECT BASE64_ENCODE ( image_data ) FROM IMAGES


BYTE_LENGTH function [String]

toggle Function

Returns the number of bytes in a string.

toggle Syntax

BYTE_LENGTH ( string-expression )

toggle Parameters

string-expression The string whose length is to be calculated.

toggle Usage

Trailing white space characters are included in the length returned.

The return value of a NULL string is NULL.

If the string is in a multi-byte character set, the BYTE_LENGTH value differs from the number of characters returned by CHAR_LENGTH.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • CHAR_LENGTH function [String]
  • DATALENGTH function [System]
  • LENGTH function [String]
toggle Example

The following statement returns the value 12.

SELECT BYTE_LENGTH( 'Test Message' )


BYTE_SUBSTR function [String]

toggle Function

Returns a substring of a string. The substring is calculated using bytes, not characters.

toggle Syntax

BYTE_SUBSTR ( string-expression, start [, length ] )

toggle Parameters

string-expression The string from which the substring is taken.

start An integer expression indicating the start of the substring. A positive integer starts from the beginning of the string, with the first character being position 1. A negative integer specifies a substring starting from the end of the string, the final character being at position -1.

length An integer expression indicating the length of the substring. A positive length specifies the number of bytes to be taken starting at the start position. A negative length returns at most length bytes up to, and including, the starting position, from the left of the starting position.

toggle Usage

If length is specified, the substring is restricted to that number of bytes. Both start and length can be either positive or negative. Using appropriate combinations of negative and positive numbers, you can get a substring from either the beginning or end of the string.

If start is zero and length is non-negative, a start value of 1 is used. If start is zero and length is negative, a start value of -1 is used.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • SUBSTRING function [String]
toggle Example

The following statement returns the value Test.

SELECT BYTE_SUBSTR( 'Test Message',1,4 )


CAST function [Data type conversion]

toggle Function

Returns the value of an expression converted to a supplied data type.

toggle Syntax

CAST ( expression AS data type )

toggle Parameters

expression The expression to be converted.

data type The target data type.

toggle Usage

If you do not indicate a length for character string types, the database server chooses an appropriate length. If neither precision nor scale is specified for a DECIMAL conversion, the database server selects appropriate values.

toggle Standards and compatibility

  • SQL/92 This function is SQL/92 compatible.

  • SQL/99 Core feature.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • CONVERT function [Data type conversion]
toggle Example

The following function ensures a string is used as a date:

SELECT CAST( '2000-10-31' AS DATE )

The value of the expression 1 + 2 is calculated, and the result cast into a single-character string.

SELECT CAST( 1 + 2 AS CHAR )

You can use the CAST function to shorten strings:

SELECT CAST( 'Surname' AS CHAR(5) )


CEILING function [Numeric]

toggle Function

Returns the ceiling (smallest integer not less than) of a number.

toggle Syntax

CEILING ( numeric-expression )

toggle Parameters

numeric-expression The number whose ceiling is to be calculated.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • FLOOR function [Numeric]
toggle Example

The following statement returns the value 60.

SELECT CEILING( 59.84567 )


CHAR function [String]

toggle Function

Returns the character with the ASCII value of a number.

toggle Syntax

CHAR ( integer-expression )

toggle Parameters

integer-expression The number to be converted to an ASCII character. The number must be in the range 0 to 255, inclusive.

toggle Usage

The character returned corresponds to the supplied numeric expression in the current database character set, according to a binary sort order.

CHAR returns NULL for integer expressions with values greater than 255 or less than zero.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value Y.

SELECT CHAR( 89 )


CHARINDEX function [String]

toggle Function

Returns the position of one string in another.

toggle Syntax

CHARINDEX ( string-expression-1, string-expression-2 )

toggle Parameters

string-expression-1 The string for which you are searching.

string-expression-2 The string to be searched.

toggle Usage

The first character of string-expression-1 is identified as 1. If the string being searched contains more than one instance of the other string, then CHARINDEX returns the position of the first instance.

If the string being searched does not contain the other string, then CHARINDEX returns 0.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • SUBSTRING function [String]
toggle Example

The statement

SELECT emp_lname, emp_fname
FROM employee
WHERE CHARINDEX('K', emp_lname ) = 1

returns the following values:

emp_lname | emp_fname
Klobucher | James
Kuo | Felicia
Kelly | Moira


CHAR_LENGTH function [String]

toggle Function

Returns the number of characters in a string.

toggle Syntax

CHAR_LENGTH ( string-expression )

toggle Parameters

string-expression The string whose length is to be calculated.

toggle Usage

Trailing white space characters are included in the length returned.

The return value of a NULL string is NULL.

If the string is in a multi-byte character set, the CHAR_LENGTH value differs from the number of bytes returned by BYTE_LENGTH.

toggle Standards and compatibility

  • SQL/92 This function is SQL/92 compatible.

  • SQL/99 Core feature.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • BYTE_LENGTH function [String]
toggle Example

The following statement returns the value 8.

SELECT CHAR_LENGTH( 'Chemical' )


COALESCE function [Miscellaneous]

toggle Function

Returns the first non-NULL expression from a list.

toggle Syntax

COALESCE ( expression, expression [ , ...] )

toggle Parameters

expression Any expression.

toggle Standards and compatibility

  • SQL/92 SQL/92.

  • SQL/99 Core feature.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value 34.

SELECT COALESCE( NULL, 34, 13, 0 )


COMPARE function [String]

toggle Function

Allows you to directly compare two character strings based on alternate collation rules.

toggle Syntax

COMPARE (
string-expression-1,
string-expression-2
[ , collation-name | , collation-id ] )

toggle Parameters

string-expression-1 The first string expression.

string-expression-2 The second string expression.

The string expression may only contain characters that are encoded in the database's character set.

collation-name A string or a character variable that specifies the name of the sort order to use. For a list of valid collation names, see SORTKEY function [String].

collation-id A variable or integer constant that specifies the sort order to use. You can only use a collation-id for built-in collations. For more information, see SORTKEY function [String].

If you do not specify a collation name or id, the default is Default Unicode multilingual.

toggle Usage

The COMPARE function returns the following values, based on the collation rules that you choose:

Value | Meaning
1 | string-expression-1 is greater than string-expression-2
0 | string-expression-1 is equal to string-expression-2
-1 | string-expression-1 is less than string-expression-2

The COMPARE function does not equate empty strings and strings containing only spaces, even if the database has blank-padding enabled. COMPARE uses the SORTKEY function to generate collation keys for comparison. Therefore, an empty string, a string with one space, and a string with two spaces will not compare equally.

If either string-expression-1 or string-expression-2 is null, the result is null.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • SORTKEY function [String]


COMPRESS function [String]

toggle Function

Compresses the string and returns a LONG BINARY.

toggle Syntax

COMPRESS( string-expression [, algorithm ]

toggle Parameters

string-expression The string to be compressed. Binary values can be passed to this function. This parameter is case sensitive, even in case-insensitive databases.

algorithm Currently, the only supported algorithm is zip, and zip is used if the algorithm is not specified.

toggle Usage

The COMPRESS function returns a LONG BINARY value that is shorter than the binary string passed to the function. This value is not human-readable. If the value returned is longer than the original string, its maximum size will not be larger than a 0.1% increase over the original string + 12 bytes. You can decompress a compressed string-expression using the DECOMPRESS function.

If you are storing compressed values in a table, the column should be BINARY or LONG BINARY so that character set conversion is not performed on the data.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • DECOMPRESS function [String]
toggle Example

The following example uses the COMPRESS function to compress data from the product_xml_info table shown below.

prod_id prod_info
301
<product_info>
 <item_name>Tee Shirt
 </item_name>
 <quantity_left>54
 </quantity_left>
 <description>Medium Orange Tee Shirt
 </description>
</product_info>
302
<product_info>
 <item_name>Tee Shirt
 </item_name>
 <quantity_left>75
 </quantity_left>
 <description>One size fits all Black Tee Shirt
 </description>
</product_info>

Obtain the compressed value for the prod_info column for product 302:

SELECT COMPRESS('prod_info')
FROM product_xml_info
WHERE prod_id = '302'


CONNECTION_PROPERTY function [System]

toggle Function

Returns the value of a given connection property as a string.

toggle Syntax

CONNECTION_PROPERTY (
{ integer-expression-1 | string-expression }
[ , integer-expression-2 ] )

toggle Parameters

integer-expression-1 In most cases it is more convenient to supply a string expression as the first argument. If you do supply an integer-expression, it is the connection property ID. You can determine this using the PROPERTY_NUMBER function.

string-expression The connection property name. Either the property ID or the property name must be specified.

For a list of connection properties, see Connection-level properties.

integer-expression-2 The connection ID of the current database connection. The current connection is used if this argument is omitted.

toggle Usage

The current connection is used if the second argument is omitted.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • Connection-level properties
  • PROPERTY_NUMBER function [System]
toggle Example

The following statement returns the number of prepared statements being maintained.

SELECT connection_property( 'PrepStmt' )


CONFLICT function [Miscellaneous]

toggle Function

Indicates if a column is a source of conflict for an UPDATE being performed against a consolidated database in a SQL Remote environment.

toggle Syntax

CONFLICT ( column-name )

toggle Parameters

column-name The name of the column being tested for conflicts.

toggle Usage

Returns TRUE if the column appears in the VERIFY list of an UPDATE statement executed by the SQL Remote Message Agent and if the value provided in the VALUES list of that statement does not match the original value of the column in the row being updated. Otherwise, returns FALSE.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • CREATE TRIGGER statement
  • Managing conflicts
toggle Example

The CONFLICT function is intended for use in SQL Remote RESOLVE UPDATE triggers to avoid error messages. To illustrate the use of the CONFLICT function, consider the following table:

CREATE TABLE Admin (
  PKey bigint NOT NULL DEFAULT GLOBAL AUTOINCREMENT,
  TextCol CHAR(20) NULL,
  PRIMARY KEY (PKey)
);

Assume that consolidated and remote databases both have the following row in the Admin table:

1, 'Initial'

Now, at the consolidated database, update the row as follows:

UPDATE Admin
SET TextCol = 'Consolidated Update'
WHERE PKey = 1;

At the remote database, update the row to a different value as follows:

UPDATE Admin
SET TextCol = 'Remote Update'
WHERE PKey = 1;

Next, run dbremote on the remote database. It generates a message file with the following statements in it, to be executed at the consolidated database:

UPDATE cons.Admin
   SET TextCol='Remote Update',
VERIFY (TextCol)
VALUES ('Initial')
WHERE PKey=1

When the SQL Remote Message Agent runs at the consolidated database and applies this UPDATE statement, Adaptive Server Anywhere uses the VERIFY and VALUES clause to determine whether a RESOLVE UPDATE trigger will fire. A RESOLVE UPDATE trigger fires only when the update is executed from the SQL Remote Message Agent against a consolidated database. Here is a RESOLVE UPDATE trigger:

CREATE TRIGGER ResolveUpdateAdmin
RESOLVE UPDATE ON cons.Admin
REFERENCING OLD AS OldConsolidated
    NEW AS NewRemote
    REMOTE as OldRemote
FOR EACH ROW BEGIN
  MESSAGE 'OLD';
  MESSAGE OldConsolidated.PKey || ',' || OldConsolidated.TextCol;
  MESSAGE 'NEW';
  MESSAGE NewRemote.PKey || ',' || NewRemote.TextCol;
  MESSAGE 'REMOTE';
  MESSAGE OldRemote.PKey || ',' || OldRemote.TextCol;
END;

The RESOLVE UPDATE trigger fires because the current value of the TextCol column at the consolidated database ('Consolidated Update') does not match the value in the VALUES clause for the associated column ('Initial').

This trigger results in a failure because the PKey column was not modified in the UPDATE statement executed on the remote, so there is no OldRemote.PKey value accessible from this trigger.

The CONFLICT function helps to avoid this error by returning the following values:

  • If there is no OldRemote.PKey value, return FALSE.

  • If there is an OldRemote.PKey value, but it matches OldConsolidated.PKey, return FALSE.

  • If there is an OldRemote.PKey value, and it is different than OldConsolidated.PKey, return TRUE.

You can use the CONFLICT function to rewrite the trigger as follows and avoid the error:

CREATE TRIGGER ResolveUpdateAdmin
RESOLVE UPDATE ON cons.Admin
REFERENCING OLD AS OldConsolidated
    NEW AS NewRemote
    REMOTE as OldRemote
FOR EACH ROW BEGIN
  message 'OLD';
  message OldConsolidated.PKey || ',' || OldConsolidated.TextCol;
  message 'NEW';
  message NewRemote.PKey || ',' || NewRemote.TextCol;
  message 'REMOTE';
  if CONFLICT( PKey ) then
    message OldRemote.PKey;
  end if;
  if CONFLICT( TextCol ) then
    message OldRemote.TextCol;
  end if;
END;


CONVERT function [Data type conversion]

toggle Function

Returns an expression converted to a supplied data type.

toggle Syntax

CONVERT ( data type, expression [ , format-style ] )

toggle Parameters

data type The data type to which the expression will be converted.

expression The expression to be converted.

format-style For converting strings to date or time data types and vice versa, the format-style is a style code number that describes the date format string to be used. The values of the format-style argument have the following meanings:

Without century (yy) | With century (yyyy) | Output
- | 0 or 100 | Mmm dd yyyy hh:nn:ss:sss AM (or PM)
1 | 101 | mm/dd/yy[yy]
2 | 102 | [yy]yy.mm.dd
3 | 103 | dd/mm/yy[yy]
4 | 104 | dd.mm.yy[yy]
5 | 105 | dd-mm-yy[yy]
6 | 106 | dd Mmm yy[yy]
7 | 107 | Mmm dd, yy[yy]
8 | 108 | hh:nn:ss
- | 9 or 109 | Mmm dd yyyy hh:nn:ss:sssAM (or PM)
10 | 110 | mm-dd-yy[yy]
11 | 111 | [yy]yy/mm/dd
12 | 112 | [yy]yymmdd
13 | 113 | dd Mmm yyy hh:nn:ss:sss (24 hour clock, Europe default + milliseconds, 4-digit year )
14 | 114 | hh:nn:ss:sss (24 hour clock)
20 | 120 | yyyy-mm-dd hh:nn:ss:sss (24-hour clock, ODBC canonical, 4-digit year)
21 | 121 | yyyy-mm-dd hh:nn:ss.sss (24 hour clock, ODBC canonical with milliseconds, 4-digit year )

If no format-style argument is provided, Style Code 0 is used.

For a description of the styles produced by each output symbol (such as Mmm), see DATE_FORMAT option [compatibility].

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • CAST function [Data type conversion]
toggle Example

The following statements illustrate the use of format styles:

SELECT CONVERT( CHAR( 20 ), order_date, 104 )
FROM sales_order
order_date
16.03.2000
20.03.2000
23.03.2000
25.03.2000
...
SELECT CONVERT( CHAR( 20 ), order_date, 7 )
FROM sales_order
order_date
Mar 16, 00
Mar 20, 00
Mar 23, 00
Mar 25, 00
...

The following statement illustrates conversion to an integer, and returns the value 5:

SELECT CONVERT( integer, 5.2 )


CORR function [Aggregate]

toggle Function

Returns the correlation coefficient of a set of number pairs.

toggle Syntax

CORR ( dependent-expression, independent-expression )

toggle Parameters

dependent-expression The variable that is affected by the independent variable.

independent-expression The variable that influences the outcome.

toggle Usage

The function returns a numeric value. If the function is applied to an empty set, then it returns NULL.

Both dependent-expression and independent-expression are numeric. The function is applied to the set of (dependent-expression, independent-expression) after eliminating the pairs for which either dependent-expression or independent-expression is null. The following computation is made:

COVAR_POP ( x, y ) / STDDEV_POP ( x ) * STDDEV_POP ( y )

where x represents the dependent-expression and y represents the independent-expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Aggregate functions
  • COVAR_POP function [Aggregate]
  • STDDEV_POP function [Aggregate]
toggle Example

The following example performs a correlation to discover whether age is associated with income level. This function returns the value 0.44022675645995957.

SELECT CORR (salary, (year(now()) - year(birth_date))) FROM employee


COS function [Numeric]

toggle Function

Returns the cosine of a number.

toggle Syntax

COS ( numeric-expression )

toggle Parameters

numeric-expression The angle, in radians.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • ACOS function [Numeric]
  • COT function [Numeric]
  • SIN function [Numeric]
  • TAN function [Numeric]
toggle Example

The statement

SELECT COS( 0.52 )

returns the value 0.86781.


COT function [Numeric]

toggle Function

Returns the cotangent of a number.

toggle Syntax

COT ( numeric-expression )

toggle Parameters

numeric-expression The angle, in radians.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • COS function [Numeric]
  • SIN function [Numeric]
  • TAN function [Numeric]
toggle Example

The following statement returns the value 1.74653.

SELECT COT( 0.52 )


COUNT function [Aggregate]

toggle Function

Counts the number of rows in a group depending on the specified parameters.

toggle Syntax

COUNT (
*
| expression
| DISTINCT { expression | column-name } )

toggle Parameters

* Returns the number of rows in each group.

expression Returns the number of rows in each group where the expression is not the null value.

DISTINCT expression or column-name Returns the number of different values in the expression, or the column with name column-name. Rows where the value is the NULL value are not included in the count.

toggle Standards and compatibility

  • SQL/92 SQL/92 compatible.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • AVG function [Aggregate]
  • SUM function [Aggregate]
toggle Example

The following statement returns each unique city, and the number of rows with that city value:

SELECT city , Count(*)
FROM employee
GROUP BY city


COVAR_POP function [Aggregate]

toggle Function

Returns the population covariance of a set of number pairs.

toggle Syntax

COVAR_POP ( dependent-expression, independent-expression )

toggle Parameters

dependent-expression The variable that is affected by the independent variable.

independent-expression The variable that influences the outcome.

toggle Usage

The function returns a numeric value. If the function is applied to an empty set, then it returns NULL.

Both dependent-expression and independent-expression are numeric. The function is applied to the set of (dependent-expression, independent-expression) pairs after eliminating all pairs for which either dependent-expression or independent-expression is NULL. The following computation is then made:

(SUM ( x * y ) - SUM ( y ) * SUM ( x ) * SUM ( x ) / n) / n

where x represents the dependent-expression and y represents the independent-expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • COVAR_SAMP function [Aggregate]
  • SUM function [Aggregate]
toggle Example

The following example measures the strength of association between employees' age and salary. This function returns the value 73785.84005866687.

SELECT COVAR_POP (salary, (year(now()) - year(birth_date)))
FROM employee


COVAR_SAMP function [Aggregate]

toggle Function

Returns the sample covariance of a set of number pairs.

toggle Syntax

COVAR_SAMP ( dependent-expression, independent-expression )

toggle Parameters

dependent-expression The variable that is affected by the independent variable.

independent-expression The variable that influences the outcome.

toggle Usage

The function returns a numeric value. If the function is applied to an empty set, then it returns NULL.

Both dependent-expression and independent-expression are numeric. The function is applied to the set of (dependent-expression, independent-expression) pairs after eliminating all pairs for which either dependent-expression or independent-expression is null. The following computation is then made:

(SUM ( x * y ) - SUM ( x ) * SUM ( y ) / n) / ( n-1 )

where x represents the dependent-expression and y represents the independent-expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • COVAR_POP function [Aggregate]
  • SUM function [Aggregate]
toggle Example

The following example returns the value 74782.94600540561.

SELECT COVAR_SAMP (salary, (year(now()) - year(birth_date)))
FROM employee


CSCONVERT function [String]

toggle Function

Converts strings between character sets.

toggle Syntax

CSCONVERT (
string-expression,
'target-charset'
[ , 'source-charset' ] )

toggle Parameters

string-expression The string.

target-charset The destination character set. Target-charset can be one of the following:

  • os_charset The character set used by the operating system.

  • db_charset The character set used by the database.

  • any other supported character set label You can specify any of the Adaptive Server Anywhere supported character set labels. For more information, see Character set labels.

source-charset The character set used by the original string-expression. The default is db_charset. Source-charset-name can be one of the following:

  • os_charset The character set used by the operating system.

  • db_charset The character set used by the database.

  • any other supported character set label You can specify any of the Adaptive Server Anywhere supported character set labels. For more information, see Character set labels.

toggle Standards and compatibility

  • SQL/92 SQL/92 compatible.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • Starting a database server using character set translation
toggle Examples

This fragment converts the mytext column from the Traditional Chinese character set to the Simplified Chinese character set:

SELECT CSCONVERT (mytext, 'cp936', 'cp950')
FROM mytable

This fragment converts the mytext column from the database character set to the Simplified Chinese character set:

SELECT CSCONVERT (mytext, 'cp936')
FROM mytable

If a filename is stored in the database, it is stored in the database's character set. If the server is going to read from or write to a file whose name is stored in a database (for example, in an external stored procedure), the filename must be explicitly converted to the operating system's character set before the file can be accessed. Filenames stored in the database and retrieved by the client are converted automatically to the client's character set, so explicit conversion is not necessary.

This fragment converts the filename column from the database character set to the operating system character set:

SELECT CSCONVERT (filename, 'os_charset')
FROM mytable

A table contains a list of filenames. An external stored procedure takes a filename from this table as a parameter and reads information directly out of that file. The following statement works when character set conversion is not required:

SELECT MYFUNC( filename )
FROM mytable

where mytable is a table that contains a filename column. However, if you need to convert the filename to the character set of the operating system, you would use the following statement.

SELECT MYFUNC( csconvert( filename, 'os_charset' ) )
FROM mytable


CUME_DIST function [Aggregate]

toggle Function

Computes the relative position of one value among a group of rows. It returns a decimal value between 0 and 1.

toggle Syntax

CUME_DIST ( )

toggle Usage

Composite sort keys are not currently allowed in the CUME_DIST function. You can use composite sort keys with any of the other rank functions.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/OLAP feature T611

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • DENSE_RANK function [Aggregate]
  • PERCENT_RANK function [Aggregate]
  • RANK function [Aggregate]
  • ROW_NUMBER function [Aggregate]
toggle Example

The following example returns a result set that provides a cumulative distribution of the salaries of employees who live in California.

SELECT dept_id, emp_lname, salary,
CUME_DIST () OVER (PARTITION BY dept_id
ORDER BY salary DESC) "Rank"
FROM employee
WHERE state IN ('CA')

Here is the result set:

dept_id | emp_lname | salary | Rank
200 | Savarino | 72300.000 | 0.333333333333333
200 | Clark | 45000.000 | 0.666666666666667
200 | Overbey | 39300.000 | 1


DATALENGTH function [System]

toggle Function

Returns the length in bytes of the underlying storage for the result of an expression.

toggle Syntax

DATALENGTH ( expression )

toggle Parameters

expression The expression is usually a column name. If the expression is a string constant, it must be enclosed in quotes.

toggle Usage

The return values of DATALENGTH are as follows:

Data type | DATALENGTH
SMALLINT | 2
INTEGER | 4
DOUBLE | 8
CHAR | Length of the data
BINARY | Length of the data
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value 27, the longest string in the company_name column.

SELECT following MAX( DATALENGTH( company_name ) )
FROM customer


DATE function [Date and time]

toggle Function

Converts the expression into a date, and removes any hours, minutes or seconds.

toggle Syntax

DATE ( expression )

toggle Parameters

expression The value to be converted to date format. The expression is usually a string.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value 1999-01-02 as a date.

SELECT DATE( '1999-01-02 21:20:53' )


DATEADD function [Date and time]

toggle Function

Returns the date produced by adding a number of the date parts to a date.

toggle Syntax

DATEADD ( date-part, numeric-expression, date-expression )

date-part :
year | quarter | month | week | day | hour | minute | second | millisecond

toggle Parameters

date-part The date-part to be added to the date..

For more information about date-parts, see Date parts.

numeric-expression The number of date-parts to be added to the date. The numeric_expression can be any numeric type, but the value is truncated to an integer.

date-expression The date to be modified.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

  • The following statement returns the value: 1995-11-02 00:00:00.0.

SELECT dateadd( month, 102, '1987/05/02' )


DATEDIFF function [Date and time]

toggle Function

Returns the interval between two dates.

toggle Syntax

DATEDIFF ( date-part, date-expression-1, date-expression-2 )

date-part :
year | quarter | month | week | day | hour | minute | second | millisecond

toggle Parameters

date-part Specifies the date-part in which the interval is to be measured.

For more information about date-parts, see Date parts.

date-expression-1 The starting date for the interval. This value is subtracted from date-expression-2 to return the number of date-parts between the two arguments.

date-expression-2 The ending date for the interval. Date-expression-1 is subtracted from this value to return the number of date-parts between the two arguments.

toggle Usage

This function calculates the number of date parts between two specified dates. The result is a signed integer value equal to (date2 - date1), in date parts.

DATEDIFF results are truncated, not rounded, when the result is not an even multiple of the date part.

When you use day as the date part, DATEDIFF returns the number of midnights between the two times specified, including the second date but not the first.

When you use month as the date part, DATEDIFF returns the number of first-of-the-months between two dates, including the second date but not the first.

When you use week as the date part, DATEDIFF returns the number of Sundays between the two dates, including the second date but not the first.

For the smaller time units there are overflow values:

  • milliseconds 24 days

  • seconds 68 years

  • minutes 4083 years

  • others No overflow limit

The function returns an overflow error if you exceed these limits.

toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns 1:

SELECT datediff( hour, '4:00AM', '5:50AM' )

The following statement returns 102:

SELECT datediff( month, '1987/05/02', '1995/11/15' )

The following statement returns 0:

SELECT datediff( day, '00:00', '23:59' )

The following statement returns 4:

SELECT datediff( day,
   '1999/07/19 00:00',
   '1999/07/23 23:59' )

The following statement returns 0:

SELECT datediff( month, '1999/07/19', '1999/07/23' )

The following statement returns 1:

SELECT datediff( month, '1999/07/19', '1999/08/23' )


DATEFORMAT function [Date and time]

toggle Function

Returns a string representing a date-expression in the specified format.

toggle Syntax

DATEFORMAT ( datetime-expression, string-expression )

toggle Parameters

datetime-expression The datetime to be converted.

string-expression The format of the converted date.

For information on date format descriptions, see DATE_FORMAT option [compatibility].

toggle Usage

Any allowable date format can be used for the string-expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

Year 2000 compliance
It is possible to use the DATEFORMAT function to produce a string with the year value represented by only two digits. This can cause problems with year 2000 compliance even though no error has occurred.

For more information on year 2000 compliance, please see Year 2000 compliance.

toggle See also
  • DATE_FORMAT option [compatibility]
toggle Example

The following statement returns the value Jan 01, 1989.

SELECT DATEFORMAT( '1989-01-01', 'Mmm dd, yyyy' )


DATENAME function [Date and time]

toggle Function

Returns the name of the specified part (such as the month "June") of a datetime value, as a character string.

toggle Syntax

DATENAME ( date-part, date-expression )

toggle Parameters

date-part The date-part to be named.

For a complete listing of allowed date-parts, see Date parts.

date-expression The date for which the date-part name is to be returned. The date must contain the requested date-part.

toggle Usage

DATENAME returns a string, even if the result is numeric, such as 23 for the day.

toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value May.

SELECT datename( month , '1987/05/02' )


DATEPART function [Date and time]

toggle Function

Returns the value of part of a datetime value.

toggle Syntax

DATEPART ( date-part, date-expression )

toggle Parameters

date-part The date-part to be returned.

For a complete listing of allowed date-parts, see Date parts.

date-expression The date for which the part is to be returned. The date must contain the date-part field.

toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value 5.

SELECT datepart( month , '1987/05/02' )


DATETIME function [Date and time]

toggle Function

Converts an expression into a timestamp.

toggle Syntax

DATETIME ( expression )

toggle Parameters

expression The expression to be converted. It is generally a string. Attempts to convert numerical values return an error.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns a timestamp with value 1998-09-09 12:12:12.000.

SELECT DATETIME( '1998-09-09 12:12:12.000' )


DAY function [Date and time]

toggle Function

Returns an integer from 1 to 31 corresponding to the day of the month of a date.

toggle Syntax

DAY ( date-expression )

toggle Parameters

date-expression The date.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value 12.

SELECT DAY( '2001-09-12' )


DAYNAME function [Date and time]

toggle Function

Returns the name of the day of the week from the a date.

toggle Syntax

DAYNAME( date-expression )

toggle Parameters

date-expression The date.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value Saturday.

SELECT DAYNAME ( '1987/05/02' )


DAYS function [Date and time]

toggle Function

Given a single date, this function returns the number of days since 0000-02-29.

Given two dates, this function returns the integer number of days between them. It is recommended that you use the DATEDIFF function [Date and time] instead for this purpose.

Given one date and an integer, it adds the integer number of days to the specified date. It is recommended that you use the DATEADD function [Date and time] instead for this purpose.

Syntax 1 returns an integer. Syntax 2 returns a timestamp.

DAYS ignores hours, minutes, and seconds.

toggle Syntax 1

DAYS ( [ datetime-expression, ] datetime-expression )

toggle Syntax 2

DAYS ( datetime-expression, integer-expression )

toggle Parameters

datetime-expression A date and time.

integer-expression The number of days to be added to the datetime-expression. If the integer-expression is negative, the appropriate number of days is subtracted from the timestamp. If you supply an integer expression, the datetime-expression must be explicitly cast as a date or timestamp.

For information on casting data types, see CAST function [Data type conversion].

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the integer 729 889.

SELECT DAYS( '1998-07-13 06:07:12' )

The following statement returns the current Julian day.

SELECT DAYS( CURRENT DATE ) + 1721119

The following statements return the integer value –366, indicating that the second date is 366 days prior to the first. It is recommended that you use the second example (DATEDIFF).

SELECT DAYS( '1998-07-13 06:07:12',
             '1997-07-12 10:07:12' )
SELECT DATEDIFF( day,
   '1998-07-13 06:07:12',
   '1997-07-12 10:07:12' )

The following statements return the timestamp 1999-07-14 00:00:00.0. It is recommended that you use the second example (DATEADD).

SELECT DAYS( CAST('1998-07-13' AS DATE ), 366 )
SELECT DATEADD( day, 366, '1998-07-13' )


DB_ID function [System]

toggle Function

Returns the database ID number.

toggle Syntax

DB_ID ( [ database-name ] )

toggle Parameters

database-name A string containing the database name. If no database-name is supplied, the ID number of the current database is returned.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value 0 if asademo is the only running database:

SELECT DB_ID( 'asademo' )

The following statement returns the value 0 if executed against the only running database.

SELECT DB_ID()


DB_NAME function [System]

toggle Function

Returns the name of a database with a given ID number.

toggle Syntax

DB_NAME ( [ database-id ] )

toggle Parameters

database-id The ID of the database. The database-id must be a numeric expression.

toggle Usage

If no database ID is supplied, the name of the current database is returned.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The statement returns the database name asademo, when executed against the sample database as the sole database on the server.

SELECT DB_NAME( 0 )


DB_EXTENDED_PROPERTY function [System]

toggle Function

Returns the value of the given property. Allows an optional property-specific string parameter to be specified.

toggle Syntax

DB_EXTENDED_PROPERTY (
{ property_id | property_name },
[, property-specific_argument
[, { database_id | database_name } ] ])

toggle Parameters

property_id The database property ID.

property_name The database property name.

database_id The database ID number, as returned by DB_ID. Typically, the database name is used.

database_name The name of the database, as returned by DB_NAME.

property_specific_argument The optional property-specific string parameter associated with FileSize and FreePages properties. If you provide a property specific argument for a property that does not require one (for example, any property other than FileSize or FreePages), the item is ignored. For a list of properties, see Database-level properties.

toggle Usage

Returns a string. The current database is used if the second argument is omitted.

Db_extended_property() is similar to db_property() except that it allows an optional property-specific string parameter to be specified. The interpretation of the property-specific argument depends on the property id or name specified in the first argument. Calling db_extended_property( x ) is equivalent to calling db_property( x ).

toggle Standards and compatibility

  • SQL/92 Vendor extension.

    SQL/99 Vendor extension.

    Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • DB_ID function [System]
  • DB_NAME function [System]
  • Database-level properties
toggle Example

The following statement returns the file size of the system dbspace, in pages.

SELECT DB_EXTENDED_PROPERTY( 'FileSize' )

The following statement returns the file size of the transaction log, in pages.

SELECT DB_EXTENDED_PROPERTY( 'FileSize', 'translog')


DB_PROPERTY function [System]

toggle Function

Returns the value of the given property.

toggle Syntax

DB_PROPERTY (
{ property_id | property_name }
[, { database_id | database_name } ] )

toggle Parameters

property_id The database property ID.

property_name The database property name.

database_id The database ID number, as returned by DB_ID. Typically, the database name is used.

database_name The name of the database, as returned by DB_NAME.

toggle Usage

Returns a string. The current database is used if the second argument is omitted.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • DB_ID function [System]
  • DB_NAME function [System]
  • Database-level properties
toggle Example

The following statement returns the page size of the current database, in bytes.

SELECT DB_PROPERTY( 'PAGESIZE' )


DECOMPRESS function [String]

toggle Function

Decompresses the string and returns a LONG BINARY value.

toggle Syntax

DECOMPRESS( string-expression [, algorithm ] )

toggle Parameters

string-expression The string to decompress. Binary values can also be passed to this function. This parameter is case sensitive, even in case-insensitive databases.

algorithm The default value is zip. Currently, this is the only available algorithm.

toggle Usage

The DECOMPRESS function returns a LONG BINARY value. This function can be used to decompress a value that was compressed using the COMPRESS function.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • COMPRESS function [String]
toggle Example

The following example uses the DECOMPRESS function to decompress a value that was compressed by the COMPRESS function.

INSERT INTO product_xml_info
VALUES ('400', COMPRESS('<product_info>
 <item_name>Baseball Cap</item_name>
 <quantity_left>112</quantity_left>
 <description>One size fits all Black Baseball Cap</description>
</product_info>'))

Because the original value was of type XML, the CAST function is used to convert the LONG BINARY returned by the DECOMPRESS function to the XML data type.

SELECT CAST (DECOMPRESS( prod_info ) AS XML)
FROM product_xml_info
WHERE prod_id = '400'


DECRYPT function [String]

toggle Function

Decrypts the string using the supplied key and returns a LONG BINARY.

toggle Syntax

DECRYPT( string-expression, key [, algorithm ] )

toggle Parameters

string-expression The string to be decrypted. Binary values can also be passed to this function. This parameter is case sensitive, even in case-insensitive databases.

key The encryption key required to decrypt the string-expression. This must be the same encryption key that was used to encrypt the string-expression in order to obtain the original value that was encrypted. This parameter is case sensitive, even in case-insensitive databases.

Caution Protect your key. Be sure to store a copy of your key in a safe location. A lost key will result in the encrypted data becoming completely inaccessible, from which there is no recovery.

algorithm This optional parameter specifies the algorithm used to decrypt the string-expression. The string-expression must be decrypted using the same algorithm it was encrypted with. Currently, AES is the only supported algorithm and it is used by default. AES is a block encryption algorithm chosen as the new Advanced Encryption Standard (AES) for block ciphers by the National Institute of Standards and Technology (NIST).

toggle Usage

You can use the DECRYPT function to decrypt a string-expression that was encrypted with the ENCRYPT function. This function returns a LONG BINARY value with the same number of bytes as the input string.

In order to successfully decrypt a string-expression, you must use the same encryption key that was used to encrypt the data. If you specify an incorrect encryption key, an error is generated. A lost key will result in inaccessible data, from which there is no recovery.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • ENCRYPT function [String]
  • Encrypting portions of a database
toggle Example

The following example decrypts a user's password from the user_info table. The CAST function is used to convert the password back to a CHAR data type because the DECRYPT function converts values to the LONG BINARY data type.

SELECT CAST (DECRYPT(user_pwd, '8U3dkA') AS CHAR(100)) FROM user_info;


DEGREES function [Numeric]

toggle Function

Converts a number from radians to degrees.

toggle Syntax

DEGREES ( numeric-expression )

toggle Parameters

numeric-expression An angle in radians.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value 29.793805.

SELECT DEGREES( 0.52 )


DENSE_RANK function [Aggregate]

toggle Function

Calculates the rank of a value in a partition. In the case of tied values, DENSE_RANK does not leave gaps in the ranking sequence.

toggle Syntax

DENSE_RANK ( )

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/OLAP feature T611

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • CUME_DIST function [Aggregate]
  • PERCENT_RANK function [Aggregate]
  • RANK function [Aggregate]
  • ROW_NUMBER function [Aggregate]
toggle Example

The following example returns a result set that provides a ranking of the employees' salaries in Utah and New York. Although 19 records are returned in the result set, only 18 rankings are listed because of a 7th-place tie between the 7th and 8th employee in the list, who have identical salaries. Instead of ranking the 9th employee as '9', the employee is listed as '8' because DENSE_RANK does not leave gaps in the ranks.

SELECT dept_id, emp_lname, salary, state,
DENSE_RANK () OVER (ORDER BY salary DESC) "Rank"
FROM employee
WHERE state IN ('NY','UT')

Here is the result set:

emp_lname | salary | state | Rank
Shishov | 72995.000 | UT | 1
Wang | 68400.000 | UT | 2
Cobb | 62000.000 | UT | 3
Morris | 61300.000 | UT | 4
Davidson | 57090.000 | NY | 5
Martel | 55700.000 | NY | 6
Blaikie | 54900.000 | NY | 7
Diaz | 54900.000 | UT | 7
Driscoll | 48023.000 | UT | 8
Hildebrand | 45829.000 | UT | 9
Whitney | 45700.000 | NY | 10
Guevara | 42998.000 | NY | 11
Soo | 39075.000 | NY | 12
Goggin | 37900.000 | UT | 13
Wetherby | 35745.000 | NY | 14
Ahmed | 34992.000 | NY | 15
Rebeiro | 34576.000 | UT | 16
Bigelow | 31200.000 | UT | 17
Lynch | 24903.000 | UT | 18


DIFFERENCE function [String]

toggle Function

Returns the difference in the SOUNDEX values between the two string expressions.

toggle Syntax

DIFFERENCE ( string-expression-1, string-expression-2 )

toggle Parameters

string-expression-1 The first SOUNDEX argument.

string-expression-2 The second SOUNDEX argument.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • SOUNDEX function [String]
toggle Example

The following statement returns the value 3.

SELECT DIFFERENCE( 'test', 'chest' )


DOW function [Date and time]

toggle Function

Returns a number from 1 to 7 representing the day of the week of a date, with Sunday=1, Monday=2, and so on.

toggle Syntax

DOW ( date-expression )

toggle Parameters

date-expression The date.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value 5.

SELECT DOW( '1998-07-09' )


ENCRYPT function [String]

toggle Function

Encrypts the specified values using the supplied encryption key and returns a LONG BINARY.

toggle Syntax

ENCRYPT( string-expression, key [, algorithm ] )

toggle Parameters

string-expression The data to be encrypted. Binary values can also be passed to this function. This parameter is case sensitive, even in case-insensitive databases.

key The encryption key used to encrypt the string-expression. This same key must be used to decrypt the value in order to obtain the original value. This parameter is case sensitive, even in case-insensitive databases.

As with most passwords, it is best to choose a key value that cannot be easily guessed. We recommend that you choose a value for your key that is at least 16 characters long, contains a mix of upper and lower case, and includes numbers, letters and special characters. You will require this key each time you want to decrypt the data.

Caution Protect your key. Be sure to store a copy of your key in a safe location. A lost key will result in the encrypted data becoming completely inaccessible, from which there is no recovery.

algorithm The algorithm used to encrypt the data. This parameter is optional, but data must be encrypted and decrypted using the same algorithm. Currently, AES is the only supported algorithm and it is used by default. AES is a block encryption algorithm chosen as the new Advanced Encryption Standard (AES) for block ciphers by the National Institute of Standards and Technology (NIST).

toggle Usage

This function returns a LONG BINARY value, which is at most 31 bytes longer than the input string-expression. The value returned by this function is not human-readable. You can use the DECRYPT function to decrypt a string-expression that was encrypted with the ENCRYPT function. In order to successfully decrypt a string-expression, you must use the same encryption key and algorithm that were used to encrypt the data. If you specify an incorrect encryption key, an error is generated. A lost key will result in inaccessible data, from which there is no recovery.

If you are storing encrypted values in a table, the column should be BINARY or LONG BINARY so that character set conversion is not performed on the data.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • DECRYPT function [String]
  • Encrypting portions of a database
toggle Example

The following trigger encrypts the user_pwd column of the user_info table. This column contains users' passwords, and the trigger fires whenever the password value is changed.

CREATE TRIGGER encrypt_updated_pwd
BEFORE UPDATE OF user_pwd
ON user_info
REFERENCING NEW AS new_pwd
FOR EACH ROW
BEGIN
    SET new_pwd.user_pwd=ENCRYPT(new_pwd.user_pwd, '8U3dkA');
END


ERRORMSG function [Miscellaneous]

toggle Function

Provides the error message for the current error, or for a specified SQLSTATE or SQLCODE value.

toggle Syntax

ERRORMSG ( [ sqlstate | sqlcode ] )

sqlstate: string

sqlcode: integer

toggle Parameters

sqlstate The SQLSTATE value for which the error message is to be returned.

sqlcode The SQLCODE value for which the error message is to be returned.

toggle Return value

A string containing the error message. If no argument is supplied, the error message for the current state is supplied. Any substitutions (such as table names and column names) are made.

If an argument is supplied, the error message for the supplied SQLSTATE or SQLCODE is returned, with no substitutions. Table names and column names are supplied as placeholders (%1).

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Error messages indexed by SQLSTATE
  • Error messages indexed by Adaptive Server Anywhere SQLCODE
toggle Example

The following statement returns the error message for SQLCODE -813.

select errormsg( -813 )


ESTIMATE function [Miscellaneous]

toggle Function

Provides selectivity estimates for the query optimizer, based on specified parameters.

toggle Syntax

ESTIMATE ( column-name [, value [, relation-string ] ] )

toggle Parameters

column-name The column used in the estimate.

value The value to which the column is compared.

relation-string The comparison operator used for the comparison, enclosed in single quotes; the default is '='.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • INDEX_ESTIMATE function [Miscellaneous]
  • ESTIMATE_SOURCE function [Miscellaneous]
toggle Example

The following statement returns the percentage of emp_id values estimated to be greater than 200. The precise value depends on the actions you have carried out on the database.

SELECT FIRST ESTIMATE( emp_id, 200, '>' )
   FROM employee


ESTIMATE_SOURCE function [Miscellaneous]

toggle Function

Provides the source for selectivity estimates used by the query optimizer.

toggle Syntax

ESTIMATE_SOURCE (
column-name
[, value [ , relation-string ] ] )

toggle Parameters

column-name The name of the column that is being investigated.

value The value to which the column is compared. This is optional.

relation-string The comparison operator used for the comparison, enclosed in single quotes. The default is equality (=).

toggle Return value

The source of the selectivity estimate can be one of the following:

  • Statistics is used as the source when you have specified a value, and there is a stored statistic available that estimates the average selectivity of the value in the column. The statistic is available only when the selectivity of the value is a significant enough number that it is stored in the statistics. Currently, a value is deemed significant if it occurs in at least 1% of the rows.

  • Column is similar to Statistics, except that the selectivity of the value occurs in less than 1% of the rows. In this case, the selectivity that is used is the average of all values that have been stored in the statistics that occur in less than 1% of rows.

  • Guess is returned when there is no relevant index to use, and no statistics have been collected for the column. In this case, built-in guesses are used.

  • Column-column is returned when the estimate that is used is the selectivity of a join. In this case, the estimate is calculated as the number of rows in the joined result set divided by the number of rows in the Cartesian product of the two tables.

  • Index is used as the source when there are no statistics available to estimate the selectivity, but there is an index which can be probed to estimate selectivity.

  • User is returned when there is a user supplied estimate, and the USER_ESTIMATES database option is not set to DISABLED.

    For more information, see USER_ESTIMATES option [database].

  • Computed is returned when statistics are computed by the optimizer based on other information. For example, Adaptive Server Anywhere does not maintain statistics on multiple columns, so if you want an estimate on a multiple column equation, such as x=5 and y=10, and there are statistics on the columns x and y, then the optimizer creates an estimate by multiplying the estimated selectivity for each column.

  • Always is used when the test is by definition true. For example, if the value is 1=1.

  • Combined is used when the optimizer uses more than one of the above sources, and combines them.

  • Bounded can qualify one of the other sources. This indicates that Adaptive Server Anywhere has placed an upper and/or lower bound on the estimate. The optimizer does this to keep estimates within logical bounds. For example, it ensures that an estimate is not greater than 100%, or that the selectivity is not less than one row.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • ESTIMATE function [Miscellaneous]
  • INDEX_ESTIMATE function [Miscellaneous]
toggle Example

The following statement returns the value Index, which means that the query optimizer probed an index to estimate the selectivity.

SELECT FIRST ESTIMATE_SOURCE( emp_id, 200, '>' )
FROM employee


EVENT_CONDITION function [System]

toggle Function

Specifies when an event handler is triggered.

toggle Syntax

EVENT_CONDITION ( condition-name )

toggle Parameters

condition-name The condition triggering the event. The possible values are preset in the database, and are case insensitive. Each condition is valid only for certain event types. The conditions and the events for which they are valid are as follows:

Condition name | Units | Valid for... | Comments
DBFreePercent | n/a | DBDiskSpace |
DBFreeSpace | Mb | DBDiskSpace |
DBSize | Mb | GrowDB |
ErrorNumber | n/a | RAISERROR |
IdleTime | seconds | ServerIdle |
Interval | seconds | All | Time since handler last executed
LogFreePercent | n/a | LogDiskSpace |
LogFreeSpace | Mb | LogDiskSpace |
LogSize | Mb | GrowLog |
RemainingValues | integer | GlobalAutoincrement | The number of remaining values
TempFreePercent | n/a | TempDiskSpace |
TempFreeSpace | Mb | TempDiskSpace |
TempSize | Mb | GrowTemp |
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • CREATE EVENT statement
toggle Example

The following event definition uses the event_condition function:

create event LogNotifier
type LogDiskSpace
where event_condition( 'LogFreePercent' ) < 50
handler
begin
   message 'LogNotifier message'
end


EVENT_CONDITION_NAME function [System]

toggle Function

Can be used to list the possible parameters for EVENT_CONDITION.

toggle Syntax

EVENT_CONDITION_NAME ( integer )

toggle Parameters

integer Must be greater than or equal to zero.

toggle Usage

You can use EVENT_CONDITION_NAME to obtain a list of all EVENT_CONDITION arguments by looping over integers until the function returns NULL.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • CREATE EVENT statement


EVENT_PARAMETER function [System]

toggle Function

Provides context information for event handlers.

toggle Syntax

EVENT_PARAMETER ( context-name )

context-name:
'AppInfo'
| 'ConnectionID'
| DisconnectReason
| 'EventName'
| 'Executions'
| 'NumActive'
| 'ScheduleName'
| 'TableName'
| 'User'
| condition-name

toggle Parameters

context-name One of the preset strings. The strings are case insensitive, and carry the following information:

  • AppInfo The value of the AppInfo connection property for the connection that caused the event to be triggered. You can see the value of the property by using the following statement:

    SELECT connection_property('AppInfo')

    This parameter is valid for Connect, Disconnect, ConnectFailed, BackupEnd, and RAISERROR events. The AppInfo string contains the machine name and application name of the client connection for embedded SQL, ODBC, OLE DB, ADO.NET, and iAnywhere JDBC driver connections.

  • ConnectionId The connection ID of the connection that caused the event to be triggered.

  • DisconnectReason A string indicating the reason the connect was terminated. This parameter is valid only for Disconnect events. Possible results include:

    • from client The client application disconnected.

    • drop connection A DROP CONNECTION statement was executed.

    • liveness No liveness packets were received for the period specified by the -tl server option.

    • inactive No requests were received for the period specified by the -ti server option.

    • connect failed A connection attempt failed.

  • EventName The name of the event that has been triggered.

  • Executions The number of times the event handler has been executed.

  • NumActive The number of active instances of an event handler. This is useful if you want to limit an event handler so that only one instance executes at any given time.

  • ScheduleName The name of the schedule which caused an event to be fired. If the event was fired manually using TRIGGER EVENT or as a system event, the result will be an empty string. If the schedule was not assigned a name explicitly when it was created, its name will be the name of the event.

  • TableName The name of the table, for use with RemainingValues.

  • User The user ID for the user that caused the event to be triggered.

In addition, you can access any of the valid condition-name arguments to the EVENT_CONDITION function from the EVENT_PARAMETER function.

The following table indicates which context-name values are valid for which system event types.

Context-name value | Valid system event types
AppInfo | BackupEnd, "Connect", ConnectFailed, "Disconnect", "RAISERROR", user events
ConnectionID | BackupEnd, "Connect", "Disconnect", Global Autoincrement, "RAISERROR", user events
DisconnectReason | "Disconnect"
EventName | all
Executions | all
NumActive | all
TableName | GlobalAutoincrement
User | BackupEnd, "Connect", ConnectFailed, "Disconnect", GlobalAutoincrement, "RAISERROR", user events
toggle Example

The following example shows how to pass a string parameter to an event. The event displays the time it was triggered on the server console.

CREATE EVENT ev_PassedParameter
HANDLER
BEGIN
  MESSAGE 'ev_PassedParameter - was triggered at ' || event_parameter('time');
END;
TRIGGER EVENT ev_PassedParameter("Time"=string(current timestamp));
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • EVENT_CONDITION function [System]
  • CREATE EVENT statement
  • TRIGGER EVENT statement


EXP function [Numeric]

toggle Function

Returns the exponential function, e to the power of a number.

toggle Syntax

EXP ( numeric-expression )

toggle Parameters

numeric-expression The exponent.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The statement returns the value 3269017.372.

SELECT EXP( 15 )


EXPERIENCE_ESTIMATE function [Miscellaneous]

toggle Function

This function is the same as the ESTIMATE function, except that it always looks in the frequency table.

toggle Syntax

EXPERIENCE_ESTIMATE (
column-name
[ , value [, relation-string ] ] )

toggle Parameters

column-name The name of the column that is being investigated.

value The value to which the column is compared.

relation-string The comparison operator used for the comparison, enclosed in single quotes; the default is '='.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • ESTIMATE function [Miscellaneous]
toggle Example

The following statement returns NULL.

SELECT DISTINCT EXPERIENCE_ESTIMATE( emp_id, 200, '>' )
FROM employee


EXPLANATION function [Miscellaneous]

toggle Function

Returns the short plan optimization strategy of a SQL statement, as a string.

toggle Syntax

EXPLANATION (
string-expression [ cursor-type ],
update-status ] )

toggle Parameters

string-expression The SQL statement, which is commonly a SELECT statement but which may also be an UPDATE or DELETE.

cursor-type A string. Cursor-type can be asensitive (default), insensitive, sensitive, or keyset-driven.

update-status A string parameter accepting one of the following values indicating how the optimizer should treat the given cursor:

Value | Description
READ-ONLY | The cursor is read-only.
READ-WRITE (default) | The cursor can be read or written to.
FOR UPDATE | The cursor can be read or written to. This is exactly the same as READ-WRITE.
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • PLAN function [Miscellaneous]
  • GRAPHICAL_PLAN function [Miscellaneous]
  • GRAPHICAL_ULPLAN function [Miscellaneous]
  • LONG_ULPLAN function [Miscellaneous]
  • SHORT_ULPLAN function [Miscellaneous]
toggle Example

The following statement passes a SELECT statement as a string parameter and returns the plan for executing the query.

SELECT EXPLANATION(
   'SELECT * FROM department WHERE dept_id > 100' )

This information can help you decide which indexes to add or how to structure your database for better performance.

The following statement returns a string containing the short form of the textual plan for an INSENSITIVE cursor over the query 'select * from department where ....'.

SELECT EXPLANATION(
   'SELECT * FROM department WHERE dept_id > 100',
   'insensitive',
   'read-only' )

In Interactive SQL, you can view the plan for any SQL statement on the Plan tab in the Results pane.


EXPRTYPE function [Miscellaneous]

toggle Function

Returns a string that identifies the data type of an expression.

toggle Syntax

EXPRTYPE ( string-expression, integer-expression )

toggle Parameters

string-expression A SELECT statement. The expression whose data type is to be queried must appear in the select list. If the string is not a valid SELECT statement, NULL is returned.

integer-expression The position in the select list of the desired expression. The first item in the select list is numbered 1. If the integer-expression value does not correspond to a SELECT list item, NULL is returned.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • SQL Data Types
toggle Example

The following statement returns smallint when executed against the sample database.

SELECT EXPRTYPE(
   'SELECT line_id FROM sales_order_items', 1 )


FLOOR function [Numeric]

toggle Function

Returns the floor of (largest integer not greater than) a number.

toggle Syntax

FLOOR ( numeric-expression )

toggle Parameters

numeric- expression The number, usually a float.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • CEILING function [Numeric]
toggle Example
Value | FLOOR (Value)
123 | 123
123.45 | 123
–123.45 | –124


GET_IDENTITY function [Miscellaneous]

toggle Function

Allocates values to an autoincrement column. This is an alternative to using autoincrement to generate numbers.

toggle Syntax

GET_IDENTITY ( [ owner.] table-name [, num_to_alloc ],... )

toggle Parameters

num_to_allocate Default is 1.

toggle Usage

Using autoincrement or global autoincrement is still the most efficient way to generate IDs, but this function is provided as an alternative. The function assumes that the table has an autoincrement column defined. It returns the next available value that would be generated for the table's autoincrement column, and reserves that value so that no other connection will use it by default.

The function returns an error if the table is not found, and returns NULL if the table has no autoincrement column. If there is more than one autoincrement column, it uses the first one it finds.

If num_to_alloc is greater than 1, the function also reserves the remaining values. The next allocation uses the current number plus the value of num_to_alloc. This allows the application to execute get_identity less frequently.

No COMMIT is required after executing get_identity, and so it can be called using the same connection that is used to insert rows. If ID values are required for several tables, they can be obtained using a single SELECT that includes multiple calls to get_identity, as in the example.

GET_IDENTITY is a non-deterministic function. Successive calls to GET_IDENTITY may return different values. The query optimizer does not cache the results of the GET_IDENTITY function.

For more information about non-deterministic functions, see Function caching.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • CREATE TABLE statement
  • ALTER TABLE statement
  • NUMBER function [Miscellaneous]
toggle Example

The following statement makes three calls to the GET_IDENTITY function:

SELECT GET_IDENTITY('T1'),
   GET_IDENTITY('T2',10),
   GET_IDENTITY('T3',5)


GETDATE function [Date and time]

toggle Function

Returns the current year, month, day, hour, minute, second and fraction of a second. The accuracy is limited by the accuracy of the system clock.

The information the GETDATE function returns is equivalent to the information returned by the NOW function and the CURRENT TIMESTAMP special value.

toggle Syntax

GETDATE ()

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • NOW function [Date and time]
  • CURRENT TIMESTAMP special value
toggle Example

The following statement returns the system date and time.

SELECT GETDATE( )


GRAPHICAL_PLAN function [Miscellaneous]

toggle Function

Returns the plan optimization strategy of a SQL statement in XML format, as a string.

toggle Syntax

GRAPHICAL_PLAN (
string-expression
[ , statistics-level
[ , cursor-type
[, update-status ] ] ] )

toggle Parameters

string-expression The SQL statement, which is commonly a SELECT statement but which may also be an UPDATE or DELETE.

statistics-level An integer. Statistics-level can be one of the following values:

Value | Description
0 | Include optimizer estimates only. (default)
1 | Include actual summary statistics from execution.
2 | Include detailed actual statistics.

cursor-type A string. Cursor-type can be asensitive (default), insensitive, sensitive, or keyset-driven.

update-status A string parameter accepting one of the following values indicating how the optimizer should treat the given cursor:

Value | Description
READ-ONLY | The cursor is read-only.
READ-WRITE (default) | The cursor can be read or written to.
FOR UPDATE | The cursor can be read or written to. This is exactly the same as READ-WRITE.
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • PLAN function [Miscellaneous]
  • EXPLANATION function [Miscellaneous]
  • GRAPHICAL_ULPLAN function [Miscellaneous]
  • LONG_ULPLAN function [Miscellaneous]
  • SHORT_ULPLAN function [Miscellaneous]
toggle Examples

The following Interactive SQL example passes a SELECT statement as a string parameter and returns the plan for executing the query. It saves the plan in the file plan.xml.

SELECT GRAPHICAL_PLAN(
   'SELECT * FROM department WHERE dept_id > 100' );
OUTPUT TO plan.xml FORMAT FIXED

The following statement returns a string containing the graphical plan for a keyset-driven, updatable cursor over the query 'SELECT * FROM department WHERE ....'. It also causes the server to annotate the plan with actual execution statistics, in addition to the estimated statistics that were used by the optimizer.

SELECT GRAPHICAL_PLAN(
   'SELECT * FROM department WHERE dept_id > 100',
   2,
   'keyset-driven', 'for update' )

In Interactive SQL, you can view the plan for any SQL statement on the Plan tab in the Results pane.


GRAPHICAL_ULPLAN function [Miscellaneous]

toggle Function

Returns the UltraLite plan optimization strategy of a SQL statement in XML format, as a string. The UltraLite plan does not include statistics.

For some queries, the execution plan for UltraLite may differ from the plan selected for Adaptive Server Anywhere.

toggle Syntax

GRAPHICAL_ULPLAN ( string-expression )

toggle Parameters

string-expression The SQL statement, which is commonly a SELECT statement but which may also be an UPDATE or DELETE.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • PLAN function [Miscellaneous]
  • EXPLANATION function [Miscellaneous]
  • GRAPHICAL_PLAN function [Miscellaneous]
  • LONG_ULPLAN function [Miscellaneous]
  • SHORT_ULPLAN function [Miscellaneous]
toggle Example

The following Interactive SQL example passes a SELECT statement as a string parameter and returns the plan for executing the query. It saves the plan in the file plan.xml.

SELECT GRAPHICAL_ULPLAN(
   'select * from department where dept_id > 100' );
OUTPUT TO ulplan.xml
FORMAT FIXED

To display the plan, open the ulplan.xml file in Interactive SQL.

As an alternative, you can view the plan for any SQL statement on the UltraLite Plan tab in Interactive SQL, choose File > Save, and change the file type to xml. To change the type of plan that is displayed, choose Tools > Options and open the Plan tab.


GREATER function [Miscellaneous]

toggle Function

Returns the greater of two parameter values. If the parameters are equal, the first is returned.

toggle Syntax

GREATER ( expression-1, expression-2 )

toggle Parameters

expression-1 The first parameter value to be compared.

expression-2 The second parameter value to be compared.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • LESSER function [Miscellaneous]
toggle Example

The following statement returns the value 10.

SELECT GREATER( 10,5 ) FROM dummy


GROUPING function [Aggregate]

toggle Function

Identifies whether a column in a ROLLUP operation result set is NULL because it is part of a subtotal row, or NULL because of the underlying data.

toggle Syntax

GROUPING ( group-by-expression )

toggle Parameters

group-by-expression An expression appearing as a grouping column in the result set of a query that uses a GROUP BY clause with the ROLLUP keyword. The function identifies subtotal rows added to the result set by a ROLLUP operation.

toggle Return value

  • 1 Indicates that group-by-expression is NULL because it is part of a subtotal row. The column is not a prefix column for that row.

  • 0 Indicates that group-by-expression is a prefix column of a subtotal row.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Using ROLLUP
  • SELECT statement
toggle Example

See Using ROLLUP.


HASH function [String]

toggle Function

Returns the specified value in hashed form.

toggle Syntax

HASH ( string-expression [ , algorithm ] )

toggle Parameters

string-expression The value to be hashed. This parameter is case sensitive, even in case-insensitive databases.

algorithm The algorithm can be one of md5 or sha1. By default, the MD5 algorithm is used.

toggle Usage

When the MD5 algorithm is specified, this function returns a 32 character VARCHAR string. When SHA-1 is used, the function returns a 40 character VARCHAR string.

Using a hash converts the value to a byte sequence that is unique to each value passed to the function.

Caution Both MD5 and SHA-1 are one-way hashes. It is not possible to re-create the original string from the hash.
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following example creates a table called user_info that stores information about the users of an application, including their user ID and password.

CREATE TABLE user_info (
   emp_id    INTEGER NOT NULL PRIMARY KEY,
   user_name    CHAR(80),
   user_pwd    CHAR(80) );
INSERT INTO user_info VALUES ( '1', 's_phillips', '8uKj2s');

Generate the hashed form of the password using the SHA-1 algorithm:

SELECT HASH(user_pwd, 'sha1')
FROM user_info
WHERE emp_id = '1';


HEXTOINT function [Data type conversion]

toggle Function

Returns the decimal integer equivalent of a hexadecimal string.

toggle Syntax

HEXTOINT ( hexadecimal-string )

toggle Parameters

hexadecimal-string The string to be converted to an integer.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • INTTOHEX function [Data type conversion]
toggle Example

The following statement returns the value 420.

SELECT HEXTOINT ( '1A4' )


HOUR function [Date and time]

toggle Function

Returns a number from 0 to 23 corresponding to the hour component of a datetime.

toggle Syntax

HOUR ( datetime-expression )

toggle Parameters

datetime-expression The datetime.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value 21:

SELECT HOUR( '1998-07-09 21:12:13' )


HOURS function [Date and time]

toggle Function

Given two timestamps, this function returns the integer number of hours between them. It is recommended that you use the DATEDIFF function [Date and time] instead for this purpose.

Given a single date, this function returns the number of hours since 0000-02-29 00:00:00.

Given one date and an integer, it adds the integer number of hours to the specified timestamp. It is recommended that you use the DATEADD function [Date and time] instead for this purpose.

Syntax 1 returns an integer. Syntax 2 returns a timestamp.

toggle Syntax 1

HOURS ( [ datetime-expression, ] datetime-expression )

toggle Syntax 2

HOURS ( datetime-expression, integer-expression )

toggle Parameters

datetime-expression A date and time.

integer-expression The number of hours to be added to the datetime-expression. If integer-expression is negative, the appropriate number of hours is subtracted from the datetime. If you supply an integer expression, the datetime-expression must be explicitly cast as a datetime data type.

For information on casting data types, see CAST function [Data type conversion].

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statements return the value 4, signifying that the second timestamp is four hours after the first. It is recommended that you use the second example (DATEDIFF).

SELECT HOURS( '1999-07-13 06:07:12',
   '1999-07-13 10:07:12' )
SELECT DATEDIFF( hour,
   '1999-07-13 06:07:12',
   '1999-07-13 10:07:12' )

The following statement returns the value 17 517 342.

SELECT HOURS( '1998-07-13 06:07:12' )

The following statements return the datetime 1999-05-13 02:05:07.0. It is recommended that you use the second example (DATEADD).

SELECT HOURS(
   CAST( '1999-05-12 21:05:07' AS DATETIME ), 5)
SELECT DATEADD( hour, 5, '1999-05-12 21:05:07' )


HTML_DECODE function

toggle Function

Decodes special character entities that appear in HTML literal strings.

toggle Syntax

HTML_DECODE ( string )

toggle Parameters

string Arbitrary literal string used in an HTML document.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Usage

This function returns the string argument after making the following set of substitutions:

Characters | Substitution
&quot; | &quot;
&#39; | &#39;
&amp; | &
&lt; | <
&gt; | >
&#xnn; | character nn
toggle See also
  • HTML_ENCODE function
  • HTTP_DECODE function [HTTP]
toggle Example

Previous Next


HTML_ENCODE function

toggle Function

Encodes special characters within strings to be inserted into HTML documents.

toggle Syntax

HTML_ENCODE ( string )

toggle Parameters

string Arbitrary string to be used in an HTML document.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Usage

This function returns the string argument after making the following set of substitutions:

Characters | Substitution
" | &quot;
' | &#39;
& | &amp;
< | &lt;
> | &gt;
codes nn less than 0x20 | &#xnn;
toggle See also
  • HTML_DECODE function
  • HTTP_ENCODE function [HTTP]
toggle Example

Previous Next


HTTP_DECODE function [HTTP]

toggle Function

Decodes special characters within strings for use with HTTP.

toggle Syntax

HTTP_DECODE ( string )

toggle Parameters

string Arbitrary string to be used in an HTTP request.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Usage

This function returns the string argument after replacing all character sequences of the form %nn, where nn is a hexadecimal value, with the character with code nn. In addition, all plus signs (+) are replaced with spaces.

toggle See also
  • HTTP_ENCODE function [HTTP]
  • HTML_DECODE function
toggle Example

Previous Next


HTTP_ENCODE function [HTTP]

toggle Function

Encodes special characters in strings for use with HTTP.

toggle Syntax

HTTP_ENCODE ( string )

toggle Parameters

string Arbitrary string to be used in an HTTP request.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Usage

This function returns the string argument after making the following set of substitutions. In addition, all characters with hexadecimal codes less than 1F or greater than 7E are replaced with %nn, where nn is the character code.

Character | Substitution
space | %20
" | %22
# | %23
& | %26
, | %2C
; | %3B
< | %3C
> | %3E
[ | %5B
\ | %5C
] | %5D
` | %60
{ | %7B
| | %7C
} | %7D
toggle See also
  • HTTP_DECODE function [HTTP]
  • HTML_ENCODE function
toggle Example

Previous Next


HTTP_HEADER function [HTTP]

toggle Function

Gets the value of an HTTP header.

toggle Syntax

HTTP_HEADER ( field-name )

toggle Parameters

field-name The name of an HTTP header field.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Usage

This function returns the value of the named HTTP header field. It is used when processing an HTTP request via a web service.

toggle See also
  • HTTP_VARIABLE function [HTTP]
  • NEXT_HTTP_HEADER function [HTTP]
  • NEXT_HTTP_VARIABLE function [HTTP]


HTTP_VARIABLE function [HTTP]

toggle Function

Gets the value of an HTTP variable.

toggle Syntax

HTTP_VARIABLE ( var-name [ [ , instance ] , header-field ] )

toggle Parameters

var-name The name of the an HTTP variable.

instance If more than one variable has the same name, the instance number of the field instance, or NULL to get the first one. Useful for select lists that permit multiple selections.

header-field In a multi-part request, a header field field name associated with the named field.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Usage

This function returns the value of the named HTTP variable. It is used when processing an HTTP request within a web service.

toggle See also
  • HTTP_HEADER function [HTTP]
  • NEXT_HTTP_HEADER function [HTTP]
  • NEXT_HTTP_VARIABLE function [HTTP]


IDENTITY function [Miscellaneous]

toggle Function

Generates integer values, starting at 1, for each successive row in a query. Its implementation is identical to that of the NUMBER function.

toggle Syntax

IDENTITY ( expression )

toggle Parameters

expression An expression. The expression is parsed, but is ignored during the execution of the function.

toggle Usage

For a description of how to use the IDENTITY function, see the NUMBER function [Miscellaneous].

toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Offers similar behavior to that of Adaptive Server Enterprise.

toggle See also
  • NUMBER function [Miscellaneous]
toggle Example

The following statement returns a sequentially-numbered list of employees.

SELECT IDENTITY( 10 ), emp_lname FROM employee


IFNULL function [Miscellaneous]

toggle Function

If the first expression is the NULL value, then the value of the second expression is returned. If the first expression is not NULL, the value of the third expression is returned. If the first expression is not NULL and there is no third expression, NULL is returned.

toggle Syntax

IFNULL ( expression-1, expression-2 [ , expression-3 ] )

toggle Parameters

expression-1 The expression to be evaluated. Its value determines whether expression-2 or expression-3 is returned.

expression-2 The return value if expression-1 is NULL.

expression-3 The return value if expression-1 is not NULL.

toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value –66:

SELECT IFNULL( NULL, -66 )

The following statement: returns NULL, because the first expression is not NULL and there is no third expression:

SELECT IFNULL( -66, -66 )


INDEX_ESTIMATE function [Miscellaneous]

toggle Function

This function is the same as the ESTIMATE function, except that it always looks only in an index.

toggle Syntax

INDEX_ESTIMATE( column-name, number [ , relation-string ] )

toggle Parameters

column-name The name of the column that is used in the estimate.

number If number is specified, the function returns as a REAL the percentage estimate that the query optimizer uses.

relation-string The relation-string must be a comparison operator enclosed in single quotes; the default is '='.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • ESTIMATE function [Miscellaneous]
  • ESTIMATE_SOURCE function [Miscellaneous]
toggle Example

The following statement returns the value 81.304607.

SELECT FIRST ESTIMATE( emp_id, 200, '>' )
FROM employee


INSERTSTR function [String]

toggle Function

Inserts a string into another string at a specified position.

toggle Syntax

INSERTSTR (
integer-expression,
string-expression-1,
string-expression-2 )

toggle Parameters

integer-expression The position after which the string is to be inserted. Use zero to insert a string at the beginning.

string-expression-1 The string into which the other string is to be inserted.

string-expression-2 The string to be inserted.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • STUFF function [String]
toggle Example

The following statement returns the value backoffice.

SELECT INSERTSTR( 0, 'office ', 'back' )


INTTOHEX function [Data type conversion]

toggle Function

Returns a string containing the hexadecimal equivalent of an integer.

toggle Syntax

INTTOHEX ( integer-expression )

toggle Parameters

integer-expression The integer to be converted to hexadecimal.

toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • HEXTOINT function [Data type conversion]
toggle Example

The following statement returns the value 9c:

SELECT INTTOHEX( 156 )


ISDATE function [Data type conversion]

toggle Function

Tests if a string argument can be converted to a date. If a conversion is possible, the function returns 1; otherwise, 0 is returned. If the argument is null, 0 is returned.

toggle Syntax

ISDATE ( string )

toggle Parameters

string The string to be analyzed to determine if the string represents a valid date.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following example imports data from an external file, exports rows which contain invalid values, and copies the remaining rows to a permanent table.

create global temporary table MyData(
      person      varchar(100),
      birth_date  varchar(30),
      height_in_cms  varchar(10)
   ) on commit preserve rows;
   load table MyData from 'exported.dat';
   unload
      select *
      from MyData
      where isdate(birth_date)=0
  or isnumeric(height_in_cms)=0
   to 'badrows.dat';
   insert into PermData
      select person,birthdate,height_in_cms
      from MyData
      where isdate(birth_date)=1
  and isnumeric(height_in_cms)=1;
   commit;
   drop table MyData;


ISNULL function [Data type conversion]

toggle Function

Returns the first non-NULL expression in the parameter list.

toggle Syntax

ISNULL ( expression, expression [ , ... ] )

toggle Parameters

expression An expression to be tested against NULL.

At least two expressions must be passed into the function.

toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise, except that Adaptive Server Enterprise allows only two expressions.

toggle See also
  • COALESCE function [Miscellaneous]
toggle Example

The following statement returns the value –66.

SELECT ISNULL( NULL ,-66, 55, 45, NULL, 16 )


ISNUMERIC function [Miscellaneous]

toggle Function

Tests if a string argument can be converted to a numeric. If a conversion is possible, the function returns 1; otherwise, 0 is returned. If the argument is null, 0 is returned.

toggle Syntax

ISNUMERIC ( string )

toggle Parameters

string The string to be analyzed to determine if the string represents a valid numeric value.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following example imports data from an external file, exports rows which contain invalid values, and copies the remaining rows to a permanent table.

create global temporary table MyData(
      person      varchar(100),
      birth_date  varchar(30),
      height_in_cms  varchar(10)
   ) on commit preserve rows;
   load table MyData from 'exported.dat';
   unload
      select *
      from MyData
      where isdate(birth_date)=0
  or isnumeric(height_in_cms)=0
   to 'badrows.dat';
   insert into PermData
      select person,birthdate,height_in_cms
      from MyData
      where isdate(birth_date)=1
  and isnumeric(height_in_cms)=1;
   commit;
   drop table MyData;


LCASE function [String]

toggle Function

Converts all characters in a string to lower case.

toggle Syntax

LCASE ( string-expression )

toggle Parameters

string-expression The string to be converted to lower case.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase LCASE is not supported in Adaptive Server Enterprise; you can use LOWER to get the same functionality.

toggle See also
  • LOWER function [String]
  • UCASE function [String]
  • UPPER function [String]
toggle Example

The following statement returns the value lower case.

SELECT LCASE( 'LOWER CasE' )


LEFT function [String]

toggle Function

Returns a number of characters from the beginning of a string.

toggle Syntax

LEFT ( string-expression, integer-expression )

toggle Parameters

string-expression The string.

integer-expression The number of characters to return.

toggle Usage

If the string contains multi-byte characters, and the proper collation is being used, the number of bytes returned may be greater than the specified number of characters.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • RIGHT function [String]
  • International Languages and Character Sets
toggle Example

The following statement returns the value choco.

SELECT LEFT( 'chocolate', 5 )


LENGTH function [String]

toggle Function

Returns the number of characters in the specified string.

toggle Syntax

LENGTH ( string-expression )

toggle Parameters

string-expression The string.

toggle Usage

If the string contains multi-byte characters, and the proper collation is being used, LENGTH returns the number of characters, not the number of bytes. If string is of BINARY data type, the LENGTH function behaves as BYTE_LENGTH.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • BYTE_LENGTH function [String]
  • International Languages and Character Sets
toggle Example

The following statement returns the value 9.

SELECT LENGTH( 'chocolate' )


LESSER function [Miscellaneous]

toggle Function

Returns the lesser of two parameter values. If the parameters are equal, the first is returned.

toggle Syntax

LESSER ( expression-1, expression-2 )

toggle Parameters

expression-1 The first parameter value to be compared.

expression-2 The second parameter value to be compared.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • GREATER function [Miscellaneous]
toggle Example

The following statement returns the value 5.

SELECT LESSER( 10,5 ) FROM dummy


LIST function [Aggregate]

toggle Function

Returns a comma-separated list of values.

toggle Syntax

LIST (
{ string-expression | DISTINCT column-name }
[ , delimiter-string ]
[ ORDER BY order-by-expression ] )

toggle Parameters

string-expression A string, usually a column name. For each row, the expression's value is added to the comma-separated list.

DISTINCT column-name The name of a column that you are using in the query. For each unique value of that column, the value is added to the comma-separated list.

delimiter-string A delimiter string for the list items. The default setting is a comma. There is no delimiter if a value of NULL or an empty string is supplied. The delimiter-string must be a constant.

order-by-expression Order the items returned by the function. There is no comma preceding this argument, which makes it easy to use in the case where no delimiter-string is supplied.

Multiple LIST functions in the same query block are not allowed to use different order-by-expression arguments.

toggle Usage

NULL values are not added to the list. List(X) returns the concatenation (with delimiters) of all the non-NULL values of X for each row in the group. If there does not exist at least one row in the group with a definite X-value, then LIST(X) returns the empty string.

If both DISTINCT and ORDER BY are supplied, the DISTINCT expression must be the same as the ORDER BY expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Examples

The following statement returns the value 48 Kennedy Court, 54 School Street.

SELECT LIST( street ) FROM employee
WHERE emp_fname = 'Thomas'

The following statement lists employee IDs. Each row in the result set contains a comma-separated list of employee IDs for a single department.

SELECT LIST( emp_id )
FROM employee
GROUP BY dept_id
LIST( emp_id )
102,105,160,243,247,249,266,27,...
129,195,299,467,641,667,690,85,...
148,390,586,757,879,1293,1336,...
184,207,318,409,591,888,992,10,...
191,703,750,868,921,1013,1570,...

The following statement sorts the employee IDs by the last name of the employee:

SELECT LIST( emp_id ORDER BY emp_lname ) AS "Sorted IDs"
FROM EMPLOYEE
GROUP BY dept_id
Sorted IDs
160,105,1250,247,266,249,445,...
1039,129,1142,195,667,1162,902,...
1336,879,586,390,757,148,1483,...
1751,591,1062,1191,992,888,318,...
1013,191,750,921,868,1658,703,...

The following statement returns semicolon-separated lists. Note the position of the ORDER BY clause and the list separator:

SELECT LIST( emp_id, ';' ORDER BY emp_lname ) AS "Sorted IDs"
FROM EMPLOYEE
GROUP BY dept_id
Sorted IDs
160;105;1250;247;266;249;445;...
1039;129;1142;195;667;1162;902;...
1336;879;586;390;757;148;1483;...
1751;591;1062;1191;992;888;318;...
1013;191;750;921;868;1658;703;...

Be sure to distinguish the previous statement from the following statement, which returns comma-separated lists of employee IDs sorted by a compound sort-key of ( emp_lname, ';' ):

SELECT LIST( emp_id ORDER BY emp_lname, ';' ) AS "Sorted IDs"
FROM EMPLOYEE
GROUP BY dept_id


LOCATE function [String]

toggle Function

Returns the position of one string within another.

toggle Syntax

LOCATE ( string-expression-1, string-expression-2 [, integer-expression ] )

toggle Parameters

string-expression-1 The string to be searched.

string-expression-2 The string to be searched for. This string is limited to 255 bytes.

integer-expression The character position in the string to begin the search. The first character is position 1. If the starting offset is negative, the locate function returns the last matching string offset rather than the first. A negative offset indicates how much of the end of the string is to be excluded from the search. The number of bytes excluded is calculated as (-1 * offset) -1.

toggle Usage

If integer-expression is specified, the search starts at that offset into the string.

The first string can be a long string (longer than 255 bytes), but the second is limited to 255 bytes. If a long string is given as the second argument, the function returns a NULL value. If the string is not found, 0 is returned. Searching for a zero-length string will return 1. If any of the arguments are NULL, the result is NULL.

If multi-byte characters are used, with the appropriate collation, then the starting position and the return value may be different from the byte positions.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value 8.

SELECT LOCATE(
   'office party this week – rsvp as soon as possible',
   'party',
   2 )

The following statement:

BEGIN
   declare str long varchar;
   declare pos int;
   set str = 'c:\test\functions\locate.sql';
   set pos = locate( str, '\', -1 );
   select str, pos,
      substr( str, 1, pos -1 ) as path,
      substr( str, pos +1 ) as filename;
END

returns the following output:

str | pos | path | filename
c:\test\functions\locate.sql | 18 | c:\test\functions | locate.sql


LOG function [Numeric]

toggle Function

Returns the natural logarithm of a number.

toggle Syntax

LOG ( numeric-expression )

toggle Parameters

numeric-expression The number.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • LOG10 function [Numeric]
toggle Example

The following statement returns the value 3.912023.

SELECT LOG( 50 )


LOG10 function [Numeric]

toggle Function

Returns the base 10 logarithm of a number.

toggle Syntax

LOG10 ( numeric-expression )

toggle Parameters

numeric-expression The number.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • LOG function [Numeric]
toggle Example

The following statement returns the value 1.698970.

SELECT LOG10( 50 )


LONG_ULPLAN function [Miscellaneous]

toggle Function

Returns a long description of the UltraLite plan optimization strategy of a SQL statement, as a string. The description is the same as that returned by the PLAN function.

For some queries, the execution plan for UltraLite may differ from the plan selected for Adaptive Server Anywhere.

toggle Syntax

LONG_ULPLAN ( string-expression )

toggle Parameters

string-expression The SQL statement, which is commonly a SELECT statement but which may also be an UPDATE or DELETE.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • PLAN function [Miscellaneous]
  • EXPLANATION function [Miscellaneous]
  • GRAPHICAL_PLAN function [Miscellaneous]
  • GRAPHICAL_ULPLAN function [Miscellaneous]
  • SHORT_ULPLAN function [Miscellaneous]
toggle Example

The following statement passes a SELECT statement as a string parameter and returns the plan for executing the query.

SELECT LONG_ULPLAN(
   'select * from department where dept_id > 100' )

This information can help with decisions about indexes to add or how to structure your database for better performance.

In Interactive SQL, you can view the plan for any SQL statement on the UltraLite Plan tab in the Results pane.


LOWER function [String]

toggle Function

Converts all characters in a string to lower case.

toggle Syntax

LOWER ( string-expression )

toggle Parameters

string-expression The string to be converted.

toggle Standards and compatibility

  • SQL/92 SQL/92 compatible.

  • SQL/99 Core feature.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • LCASE function [String]
  • UCASE function [String]
  • UPPER function [String]
toggle Example

The following statement returns the value lower case.

SELECT LOWER( 'LOWER CasE' )


LTRIM function [String]

toggle Function

Trims leading blanks from a string.

toggle Syntax

LTRIM ( string-expression )

toggle Parameters

string-expression The string to be trimmed.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • RTRIM function [String]
  • TRIM function [String]
toggle Example

The following statement returns the value Test Message with all leading blanks removed.

SELECT LTRIM( '     Test Message' )


MAX function [Aggregate]

toggle Function

Returns the maximum expression value found in each group of rows.

toggle Syntax

MAX ( expression | DISTINCT column name )

toggle Parameters

expression The expression for which the maximum value is to be calculated. This is commonly a column name.

DISTINCT column-name Returns the same as MAX( expression ), and is included for completeness.

toggle Usage

Rows where expression is NULL are ignored. Returns NULL for a group containing no rows.

toggle Standards and compatibility

  • SQL/92 SQL/92 compatible.

  • SQL/99 Core feature.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • MIN function [Aggregate]
toggle Example

The following statement returns the value 138948.000, representing the maximum salary in the employee table.

SELECT MAX( salary )
FROM employee


MIN function [Aggregate]

toggle Function

Returns the minimum expression value found in each group of rows.

toggle Syntax

MIN ( expression
| DISTINCT column name )

toggle Parameters

expression The expression for which the minimum value is to be calculated. This is commonly a column name.

DISTINCT column-name Returns the same as MIN( expression ), and is included for completeness.

toggle Usage

Rows where expression is NULL are ignored. Returns NULL for a group containing no rows.

toggle Standards and compatibility

  • SQL/92 SQL/92 compatible.

  • SQL/99 Core feature.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • MAX function [Aggregate]
toggle Example

The following statement returns the value 24903.000, representing the minimum salary in the employee table.

SELECT MIN( salary )
FROM employee


MINUTE function [Date and time]

toggle Function

Returns a number from 0 to 59 corresponding to the minute component of a datetime value.

toggle Syntax

MINUTE ( datetime-expression )

toggle Parameters

datetime-expression The datetime value.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value 22.

SELECT MINUTE( '1998-07-13 12:22:34' )


MINUTES function [Date and time]

toggle Function

Given two timestamps, this function returns the integer number of minutes between them. It is recommended that you use the DATEDIFF function [Date and time] instead for this purpose.

Given a single date, this function returns the number of minutes since 0000-02-29 00:00:00.

Given one date and an integer, it adds the integer number of minutes to the specified timestamp. Instead, please use the DATEADD function [Date and time].

Syntax 1 returns an integer. Syntax 2 returns a timestamp.

toggle Syntax 1

MINUTES ( [ datetime-expression, ] datetime-expression )

toggle Syntax 2

MINUTES ( datetime-expression, integer-expression )

toggle Parameters

datetime-expression A date and time.

integer-expression The number of minutes to be added to the datetime-expression. If integer-expression is negative, the appropriate number of minutes is subtracted from the datetime value. If you supply an integer expression, the datetime-expression must be explicitly cast as a datetime data type.

For information on casting data types, see CAST function [Data type conversion].

toggle Usage

Since this function returns an integer, overflow may occur when syntax 1 is used with timestamps greater than or equal to 4083-03-23 02:08:00.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statements return the value 240, signifying that the second timestamp is 240 seconds after the first. It is recommended that you use the second example (DATEDIFF).

SELECT MINUTES( '1999-07-13 06:07:12',
    '1999-07-13 10:07:12' )
SELECT DATEDIFF( minute,
     '1999-07-13 06:07:12',
     '1999-07-13 10:07:12' )

The following statement returns the value 1 051 040 527.

SELECT MINUTES( '1998-07-13 06:07:12' )

The following statements return the timestamp 1999-05-12 21:10:07.0. It is recommended that you use the second example (DATEADD).

SELECT MINUTES( CAST( '1999-05-12 21:05:07'
AS DATETIME ), 5)
SELECT DATEADD( minute, 5, '1999-05-12 21:05:07' )


MOD function [Numeric]

toggle Function

Returns the remainder when one whole number is divided by another.

toggle Syntax

MOD ( dividend, divisor )

toggle Parameters

dividend The dividend, or numerator of the division.

divisor The divisor, or denominator of the division.

toggle Usage

Division involving a negative dividend will give a negative or zero result. The sign of the divisor has no effect.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise. The % operator is used as a modulo operator in Adaptive Server Enterprise.

toggle See also
  • REMAINDER function [Numeric]
toggle Example

The following statement returns the value 2.

SELECT MOD( 5, 3 )


MONTH function [Date and time]

toggle Function

Returns a number from 1 to 12 corresponding to the month of the given date.

toggle Syntax

MONTH ( date-expression )

toggle Parameters

date-expression A datetime value.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value 7.

SELECT MONTH( '1998-07-13' )


MONTHNAME function [Date and time]

toggle Function

Returns the name of the month from a date.

toggle Syntax

MONTHNAME ( date-expression )

toggle Parameters

date-expression The datetime value.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value September.

SELECT MONTHNAME( '1998-09-05' )


MONTHS function [Date and time]

toggle Function

Given two dates, this function returns the integer number of months between them. It is recommended that you use the DATEDIFF function [Date and time] instead for this purpose.

Given a single date, this function returns the number of months since 0000-02.

Given one date and an integer, it adds the integer number of months to the specified date. It is recommended that you use the DATEADD function [Date and time] instead for this purpose.

Syntax 1 returns an integer. Syntax 2 returns a timestamp.

toggle Syntax 1

MONTHS ( [ datetime-expression, ] datetime-expression )

toggle Syntax 2

MONTHS ( datetime-expression, integer-expression )

toggle Parameters

datetime-expression A date and time.

integer-expression The number of months to be added to the datetime-expression. If integer-expression is negative, the appropriate number of months is subtracted from the datetime value. If you supply an integer expression, the datetime-expression must be explicitly cast as a datetime data type.

For information on casting data types, see CAST function [Data type conversion].

toggle Usage

The value of MONTHS is calculated from the number of first days of the month between the two dates.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statements return the value 2, signifying that the second date is two months after the first. It is recommended that you use the second example (DATEDIFF).

SELECT MONTHS( '1999-07-13 06:07:12',
   '1999-09-13 10:07:12' )
SELECT DATEDIFF( month,
   '1999-07-13 06:07:12',
   '1999-09-13 10:07:12' )

The following statement returns the value 23 982.

SELECT MONTHS( '1998-07-13 06:07:12' )

The following statements return the timestamp 1999-10-12 21:05:07.0. It is recommended that you use the second example (DATEADD).

SELECT MONTHS( CAST( '1999-05-12 21:05:07'
AS DATETIME ), 5)
SELECT DATEADD( month, 5, '1999-05-12 21:05:07' )


NEWID function [Miscellaneous]

toggle Function

Generates a UUID (Universally Unique Identifier) value. A UUID is the same as a GUID (Globally Unique Identifier).

toggle Syntax

NEWID ( )

toggle Parameters

There are no parameters associated with NEWID().

toggle Usage

The NEWID() function generates a unique identifier value. It can be used in a DEFAULT clause for a column.

UUIDs can be used to uniquely identify rows in a table. The values are generated such that a value produced on one computer will not match that produced on another. Hence they can also be used as keys in replication and synchronization environments.

NEWID is a non-deterministic function. Successive calls to NEWID may return different values. The query optimizer does not cache the results of the NEWID function.

For more information about non-deterministic functions, see Function caching.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • The NEWID default
  • STRTOUUID function [String]
  • UUIDTOSTR function [String]
  • UNIQUEIDENTIFIER data type [Binary]
toggle Example

The following statement creates a table mytab with two columns. Column pk has a unique identifier data type, and assigns the newid() function as the default value. Column c1 has an integer data type.

CREATE TABLE T1(
   pk UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(),
   c1 INT )

The following statement returns the unique identifier as a string:

SELECT NEWID()

For example, the value might be 0xd3749fe09cf446e399913bc6434f1f08.


NEXT_CONNECTION function [System]

toggle Function

Returns an identifying number for a connection.

toggle Syntax

NEXT_CONNECTION ( [ connection-id ] [, database-id ] )

toggle Parameters

connection-id An integer, usually returned from a previous call to NEXT_CONNECTION. If connection-id is NULL, NEXT_CONNECTION returns the first connection ID.

database-id An integer representing one of the databases on the current server. If you supply no database-id, the current database is used. If you supply NULL, then NEXT_CONNECTION returns the next connection regardless of database.

toggle Usage

NEXT_CONNECTION can be used to enumerate the connections to a database. To get the first connection pass NULL; to get each subsequent connection, pass the previous return value. The function returns NULL when there are no more connections. The connection IDs are not returned in a particular order, but you can tell the order in which connections were made to the server using the connection ID. The first connection to a server is assigned the value 1, and for subsequent connections to the server, the connection IDs are incremented by a value of 1.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns an identifier for the first connection on the current database. The identifier is an integer value like 10.

SELECT NEXT_CONNECTION( NULL )

The following statement returns a value like 5.

SELECT NEXT_CONNECTION( 10 )

The following call returns the connection after connection-id on the current database.

NEXT_CONNECTION( connection-id )

The following call returns the connection after connection-id (regardless of database).

NEXT_CONNECTION( connection-id, NULL )

The following call returns the connection after connection-id on the specified database.

NEXT_CONNECTION( connection-id, database-id )

The following call returns the first connection (regardless of database).

NEXT_CONNECTION(NULL, NULL)

The following call returns the first connection on the specified database.

NEXT_CONNECTION( NULL, database-id )


NEXT_DATABASE function [System]

toggle Function

Returns an identifying number for a database.

toggle Syntax

NEXT_DATABASE ( { NULL | database-id } )

toggle Parameters

database-id An integer that specifies the ID number of the database.

toggle Usage

NEXT_DATABASE can be used to enumerate the databases running on a database server. To get the first database pass NULL; to get each subsequent database, pass the previous return value. The function returns NULL when there are no more databases. The database ID numbers are not returned in a particular order, but you can tell the order in which connections were made to the server using the database ID. The first database that connects to the server is assigned the value 0, and for subsequent connections to the server, the database IDs are incremented by a value of 1.

toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value 0, the first database value.

SELECT NEXT_DATABASE( NULL )

The following statement returns NULL, indicating that there are no more databases on the server.

SELECT NEXT_DATABASE( 0 )


NEXT_HTTP_HEADER function [HTTP]

toggle Function

Get the next HTTP header name.

toggle Syntax

NEXT_HTTP_HEADER (header-name)

toggle Parameters

header-name The name of the previous header. If header-name is null, this function returns the name of the first HTTP header.

toggle Usage

This function iterates over the HTTP headers included within a request. Calling it with NULL causes it to return the name of the first header. Subsequent headers are retrieved by passing the function the name of the previous header. This function returns NULL when called with the name of the last header.

Calling this function repeatedly returns all the header fields exactly once, but not necessarily in the order they appear in the HTTP request.

toggle See also
  • HTTP_HEADER function [HTTP]
  • HTTP_VARIABLE function [HTTP]
  • NEXT_HTTP_VARIABLE function [HTTP]


NEXT_HTTP_VARIABLE function [HTTP]

toggle Function

Get the next HTTP variable name.

toggle Syntax

NEXT_HTTP_VARIABLE (var-name)

toggle Parameters

var-name The name of the previous variable. If var-name is null, this function returns the name of the first HTTP variable.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Usage

This function iterates over the HTTP variables included within a request. Calling it with NULL causes it to return the name of the first variable. Subsequent variables are retrieved by passing the function the name of the previous variable. This function returns NULL when called with the name of the final variable.

Calling this function repeatedly returns all the variables exactly once, but not necessarily in the order they appear in the HTTP request. The variables url or url1, url2, ..., url10 are included if URL PATH is set to ON or ELEMENTS, respectively.

toggle See also
  • HTTP_HEADER function [HTTP]
  • HTTP_VARIABLE function [HTTP]
  • NEXT_HTTP_HEADER function [HTTP]


NOW function [Date and time]

toggle Function

Returns the current year, month, day, hour, minute, second and fraction of a second. The fraction of a second. The accuracy is limited by the accuracy of the system clock.

The information the NOW function returns is equivalent to the information returned by the GETDATE function and the CURRENT TIMESTAMP special value.

toggle Syntax

NOW ( * )

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • GETDATE function [Date and time]
  • CURRENT TIMESTAMP special value
toggle Example

The following statement returns the current date and time.

SELECT NOW(*)


NULLIF function [Miscellaneous]

toggle Function

Provides an abbreviated CASE expression by comparing expressions.

toggle Syntax

NULLIF ( expression-1, expression-2 )

toggle Parameters

expression-1 An expression to be compared.

expression-2 An expression to be compared.

toggle Usage

NULLIF compares the values of the two expressions.

If the first expression equals the second expression, NULLIF returns NULL.

If the first expression does not equal the second expression, or if the second expression is NULL, NULLIF returns the first expression.

The NULLIF function provides a short way to write some CASE expressions.

toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • CASE expressions
toggle Example

The following statement returns the value a:

SELECT NULLIF( 'a', 'b' )

The following statement returns NULL.

SELECT NULLIF( 'a', 'a' )


NUMBER function [Miscellaneous]

toggle Function

Generates numbers starting at 1 for each successive row in the results of the query. NUMBER is primarily intended for use in select lists.

toggle Syntax

NUMBER ( * )

toggle Usage

You can use NUMBER(*) in a select list to provide a sequential numbering of the rows in the result set. NUMBER(*) returns the value of the ANSI row number of each result row. This means that NUMBER can return positive or negative values, depending on how the application scrolls through the result set. For insensitive cursors, the value of NUMBER(*) will always be positive because the entire result set is materialized at OPEN.

In addition, the row number may be subject to change for some cursor types. The value is fixed for insensitive cursors and scroll cursors. If there are concurrent updates, it may change for dynamic and sensitive cursors.

A syntax error is generated if you use NUMBER in a DELETE statement, WHERE clause, HAVING clause, ORDER BY clause, subquery, query involving aggregation, any constraint, GROUP BY, DISTINCT, a query containing UNION ALL, or a derived table.

NUMBER(*) can be used in a view (subject to the above restrictions), but the view column corresponding to the expression involving NUMBER(*) can be referenced at most once in the query or outer view, and the view cannot participate as a null-supplying table in a left outer join or full outer join.

In Embedded SQL, care should be exercised when using a cursor that references a query containing a NUMBER(*) function. In particular, this function returns negative numbers when a database cursor is positioned using relative to the end of the cursor (an absolute position with a negative offset).

You can use NUMBER in the right hand side of an assignment in the SET clause of an UPDATE statement. For example, SET x = NUMBER(*).

NUMBER can also be used to generate primary keys when using the INSERT from SELECT statement (see INSERT statement), although using AUTOINCREMENT is a preferred mechanism for generating sequential primary keys.

For information on AUTOINCREMENT, see CREATE TABLE statement.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

    Behavior changes
    The behavior of the NUMBER function changed in version 8. For more information, see Adaptive Server Anywhere behavior changes.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns a sequentially-numbered list of departments.

SELECT NUMBER( * ), dept_name
FROM department
WHERE dept_id > 5
ORDER BY dept_name


OPENXML function [String]

toggle Function

Generates a result set from an XML document.

toggle Syntax

OPENXML ( xml-expression,
xpath-query [, flags [, namespace-declaration ] ] )
WITH ( column-name column-type [ xpath-query ],... )

toggle Parameters

xml-expression The XML on which the result set is based. This can be any string expression, such as a constant, variable, or column.

xpath-query A string containing an XPath query. XPath allows you to specify patterns that describe the structure of the XML document you are querying. The XPath pattern included in this argument selects the nodes from the XML document. Each node that matches the XPath query in the second xpath-query argument generates one row in the table.

Metaproperties can only be specified in WITH clause xpath-query arguments. A metaproperty is accessed within an XPath query as if it was an attribute. If a namespace-declaration is not specified, then by default the prefix mp is bound to the Uniform Resource Identifier (URI) urn:ianywhere-com:asa-xpath-metaprop. If a namespace-declaration is specified, this URI must be bound to mp or some other prefix in order to access metaproperties in the query. OPENXML supports the following metaproperties:

  • @mp:id returns an ID for a node that is unique within the XML document. The ID for a given node in a given document may change if the database server is restarted. The value of this metaproperty increases with document order.

  • @mp:localname returns the local part of the node's name, or NULL if the node does not have a name.

  • @mp:prefix returns the prefix part of the node's name, or NULL if the node does not have a name or if the name is not prefixed.

  • @mp:namespaceuri returns the URI of the namespace that the node belongs to, or NULL if the node is not in a namespace.

  • @mp:xmltext returns a subtree of the XML document in XML form. For example, when you match an internal node, you can use this metaproperty to return an XML string, rather than the concatenated values of the descendant text nodes.

flags Indicates the mapping that should be used between the XML data and the result set when an XPath query is not specified in the WITH clause. If the flags parameter is not specified, the default behavior is to map attributes to columns in the result set. The flags parameter can have one of the following values:

Value | Description
1 | XML attributes are mapped to columns in the result set (the default).
2 | XML elements are mapped to columns in the result set.

namespace-declaration An XML document. The in-scope namespaces for the query are taken from the root element of the document. If namespaces are specified, then you must include a flags argument, even if all the xpath-query arguments are specified.

WITH clause Specifies the schema of the result set and how the value is found for each column in the result set. WITH clause xpath-query arguments are matched relative to the matches for the xpath-query in the second argument. If a WITH clause expression matches more than one node, then only the first node in the document order is used. If the node is not a text node, then the result is found by appending all the text node descendants. If a WITH clause expression does not match any nodes, then the column for that row is NULL.

The OPENXML WITH clause syntax is similar to the syntax for selecting from a stored procedure.

For information about selecting from a stored procedure, see FROM clause.

column-name The name of the column in the result set.

column-type The data type of the column in the result set. The data type must be compatible with the values selected from the XML document.

For a list of data types, see SQL Data Types.

toggle Usage

OPENXML parses the xml-expression and models the result as a tree. The tree contains a separate node for each element, attribute, and text node, or other XML construct. The XPath queries supplied to OPENXML are used to select nodes from the tree, and the selected nodes are then mapped to the result set.

The XML parser used by OPENXML is non-validating, and does not read the external DTD subset or external parameter entities.

When there are multiple matches for a column expression, the first match in the document order (the order of the original XML document before it was parsed) is used. NULL is returned if there are no matching nodes. When an internal node is selected, the result is all the descendant text nodes of the internal node concatenated together.

Columns of type BINARY, LONG BINARY, IMAGE, and VARBINARY are assumed to be in base64-encoded format and are decoded automatically. If you generate XML using the FOR XML clause, these types are base64-encoded, and can be decoded using OPENXML.

For information about the FOR XML clause and encoding binary data, see FOR XML and binary data.

OPENXML supports a subset of the XPath syntax, as follows:

  • The child, self, attribute, descendant, descendant-or-self, and parent axes are fully supported.

    For descriptions, see Using XPath expressions.

  • Both abbreviated and unabbreviated syntax can be used for all supported features. For example, 'a' is equivalent to 'child::a' and '..' is equivalent to 'parent::node()'.

  • Name tests can use wildcards. For example, 'a/*/b'.

  • The following Kind tests are supported: node(), text(), processing-instruction(), and comment().

  • Qualifiers of the form expr1[expr2] and expr1[expr2="string"] can be used, where expr2 is any supported XPath expression. A qualifier evaluates TRUE if expr2 matches one or more nodes. For example, 'a[b]' finds a nodes that have at least one b child, and a[b="i"] finds a nodes that have at least one b child with a text value of i.

For information about the XPath query language, see [external link] http://www.w3.org/TR/xpath.

toggle Standards and compatibility

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Importing XML using OPENXML
toggle Example

The following query generates a result set from the XML document supplied as the first argument to OPENXML:

SELECT * FROM OPENXML( '<products>
                 <prod_type id="301">Tee Shirt</prod_type>
                 <prod_type id="401">Baseball Cap</prod_type>
                 </products>',
                 '/products/prod_type' )
WITH ( prod_name LONG VARCHAR 'text()', prod_id CHAR(3) '@id')

This query generates the following result:

prod_name | prod_id
Tee Shirt | 301
Baseball Cap | 401

The following query uses an equality predicate to generate a result set from the supplied XML document.

SELECT * FROM OPENXML ('<emp_directory>
   <employee>
      <column name="emp_id">105</column>
      <column name="emp_fname">Matthew</column>
      <column name="emp_lname">Cobb</column>
      <column name="street">7 Pleasant Street</column>
      <column name="city">Grimsby</column>
      <column name="state">UT</column>
      <column name="zip_code">02154</column>
      <column name="phone">6175553840</column>
   </employee>
   <employee>
      <column name="emp_id">148</column>
      <column name="emp_fname">Julie</column>
      <column name="emp_lname">Jordan</column>
      <column name="street">1244 Great Plain Avenue</column>
      <column name="city">Woodbridge</column>
      <column name="state">AZ</column>
      <column name="zip_code">01890</column>
      <column name="phone">6175557835</column>
   </employee>
   <employee>
      <column name="emp_id">160</column>
      <column name="emp_fname">Robert</column>
      <column name="emp_lname">Breault</column>
      <column name="street">358 Cherry Street</column>
      <column name="city">Milton</column>
      <column name="state">PA</column>
      <column name="zip_code">02186</column>
      <column name="phone">6175553099</column>
   </employee>
   <employee>
      <column name="emp_id">243</column>
      <column name="emp_fname">Natasha</column>
      <column name="emp_lname">Shishov</column>
      <column name="street">151 Milk Street</column>
      <column name="city">Grimsby</column>
      <column name="state">UT</column>
      <column name="zip_code">02154</column>
      <column name="phone">6175552755</column>
   </employee>
</emp_directory>', '/emp_directory/employee')
WITH ( emp_id INT 'column[@name="emp_id"]',
       first_name            CHAR(20) 'column[@name="emp_fname"]',
       last_name               CHAR(20) 'column[@name="emp_lname"]',
       phone_number      CHAR(10) 'column[@name="phone"]')

This query generates the following result set:

emp_id | first_name | last_name | phone_number
105 | Matthew | Cobb | 6175553840
148 | Julie | Jordan | 6175557835
160 | Robert | Breault | 6175553099
243 | Natasha | Shishov | 6175552755

For more examples of using OPENXML, see Importing XML using OPENXML.


PATINDEX function [String]

toggle Function

Returns an integer representing the starting position of the first occurrence of a pattern in a string.

toggle Syntax

PATINDEX ( '%pattern%', string_expression )

toggle Parameters

pattern The pattern to be searched for. If the leading percent wildcard is omitted, PATINDEX returns one (1) if the pattern occurs at the beginning of the string, and zero if not.

The pattern uses the same wildcards as the LIKE comparison. These are as follows:

Wildcard | Matches
_ (underscore) | Any one character
% (percent) | Any string of zero or more characters
[] | Any single character in the specified range or set
[^] | Any single character not in the specified range or set

string-expression The string to be searched for the pattern.

toggle Usage

PATINDEX returns the starting position of the first occurrence of the pattern. If the pattern is not found, it returns zero (0).

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise, except that the USING clause is not supported.

toggle See also
  • LIKE conditions
  • LOCATE function [String]
toggle Example

The following statement returns the value 2.

SELECT PATINDEX( '%hoco%', 'chocolate' )

The following statement returns the value 11.

SELECT PATINDEX ('%4_5_', '0a1A 2a3A 4a5A')


PERCENT_RANK function [Aggregate]

toggle Function

Computes the (fractional) position of one row returned from a query with respect to the other rows returned by the query, as defined by the ORDER BY clause. It returns a decimal value between 0 and 1.

toggle Syntax

PERCENT_RANK ( )

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/OLAP feature T611

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • CUME_DIST function [Aggregate]
  • DENSE_RANK function [Aggregate]
  • RANK function [Aggregate]
  • ROW_NUMBER function [Aggregate]
toggle Example

The following example returns a result set that shows the ranking of New York employees' salaries by gender. The results are ranked in descending order using a decimal percentage and are partitioned by gender.

SELECT dept_id, emp_lname, salary, sex,
PERCENT_RANK () OVER (PARTITION BY sex
ORDER BY salary DESC) "Rank"
FROM employee
WHERE state IN ('NY')
dept_id | emp_lname | salary | sex | Rank
200 | Martel | 55700.000 | M | 0
100 | Guevara | 42998.000 | M | 0.333333333
100 | Soo | 39075.000 | M | 0.666666667
400 | Ahmed | 34992.000 | M | 1
300 | Davidson | 57090.000 | F | 0
400 | Blaikie | 54900.000 | F | 0.333333333
100 | Whitney | 45700.000 | F | 0.666666667
400 | Wetherby | 35745.000 | F | 1


PI function [Numeric]

toggle Function

Returns the numeric value PI.

toggle Syntax

PI ( * )

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase The PI() function is supported in Adaptive Server Enterprise, but PI(*) is not.

toggle Example

The following statement returns the value 3.141592653...

SELECT PI( * )


PLAN function [Miscellaneous]

toggle Function

Returns the long plan optimization strategy of a SQL statement, as a string.

toggle Syntax

PLAN ( string-expression, [ cursor-type ], [ update-status ] )

toggle Parameters

string-expression The SQL statement, which is commonly a SELECT statement but which may also be an UPDATE or DELETE.

cursor-type A string. Cursor-type can be asensitive (default), insensitive, sensitive, or keyset-driven.

update-status A string parameter accepting one of the following values indicating how the optimizer should treat the given cursor:

Value | Description
READ-ONLY | The cursor is read-only.
READ-WRITE (default) | The cursor can be read or written to.
FOR UPDATE | The cursor can be read or written to. This is exactly the same as READ-WRITE.
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • EXPLANATION function [Miscellaneous]
  • GRAPHICAL_PLAN function [Miscellaneous]
  • GRAPHICAL_ULPLAN function [Miscellaneous]
  • LONG_ULPLAN function [Miscellaneous]
  • SHORT_ULPLAN function [Miscellaneous]
toggle Example

The following statement passes a SELECT statement as a string parameter and returns the plan for executing the query.

SELECT PLAN(
   'SELECT * FROM department WHERE dept_id > 100' )

This information can help with decisions about indexes to add or how to structure your database for better performance.

The following statement returns a string containing the textual plan for an INSENSITIVE cursor over the query 'select * from department where ...'.

SELECT PLAN(
   'SELECT * FROM department WHERE dept_id > 100',
   'insensitive',
   'read-only' )

In Interactive SQL, you can view the plan for any SQL statement on the Plan tab in the Results pane.


POWER function [Numeric]

toggle Function

Calculates one number raised to the power of another.

toggle Syntax

POWER ( numeric-expression-1, numeric-expression-2 )

toggle Parameters

numeric-expression-1 The base.

numeric-expression-2 The exponent.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value 64.

SELECT Power( 2, 6 )


PROPERTY_DESCRIPTION function [System]

toggle Function

Returns a description of a property.

toggle Syntax

PROPERTY_DESCRIPTION ( { property-id | property-name } )

toggle Parameters

property-id An integer that is the property-number of the database property. This number can be determined from the PROPERTY_NUMBER function. The property-id is commonly used when looping through a set of properties.

property-name A string giving the name of the database property.

toggle Usage

Each property has both a number and a name, but the number is subject to change between releases, and should not be used as a reliable identifier for a given property.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Database Performance and Connection Properties
toggle Example

The following statement returns the description Number of index insertions.

SELECT PROPERTY_DESCRIPTION( 'IndAdd' )


PROPERTY function [System]

toggle Function

Returns the value of the specified server-level property as a string.

toggle Syntax

PROPERTY ( { property-id | property-name } )

toggle Parameters

property-id An integer that is the property-number of the server-level property. This number can be determined from the PROPERTY_NUMBER function. The property-id is commonly used when looping through a set of properties.

property-name A string giving the name of the database property.

toggle Usage

Each property has both a number and a name, but the number is subject to change between releases, and should not be used as a reliable identifier for a given property.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Server-level properties
toggle Example

The following statement returns the name of the current database server:

SELECT PROPERTY( 'Name' )


PROPERTY_NAME function [System]

toggle Function

Returns the name of the property with the supplied property-number.

toggle Syntax

PROPERTY_NAME ( property-id )

toggle Parameters

property-id The property number of the database property.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Database properties
toggle Example

The following statement returns the property associated with property number 126. The actual property to which this refers changes from release to release.

SELECT PROPERTY_NAME( 126 )


PROPERTY_NUMBER function [System]

toggle Function

Returns the property number of the property with the supplied property-name.

toggle Syntax

PROPERTY_NUMBER ( property-name )

toggle Parameters

property-name A property name.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Database properties
toggle Example

The following statement returns an integer value. The actual value changes from release to release.

SELECT PROPERTY_NUMBER( 'PAGESIZE' )


QUARTER function [Date and time]

toggle Function

Returns a number indicating the quarter of the year from the supplied date expression.

toggle Syntax

QUARTER ( date-expression )

toggle Parameters

date- expression The date.

toggle Usage

The quarters are as follows:

Quarter | Period (inclusive)
1 | January 1 to March 31
2 | April 1 to June 30
3 | July 1 to September 30
4 | October 1 to December 31
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value 2.

SELECT QUARTER ( '1987/05/02' )


RADIANS function [Numeric]

toggle Function

Converts a number from degrees to radians.

toggle Syntax

RADIANS ( numeric-expression )

toggle Parameters

numeric-expression A number, in degrees. This angle is converted to radians.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns a value of approximately 0.5236.

SELECT RADIANS( 30 )


RAND function [Numeric]

toggle Function

Returns a random number in the interval 0 to 1, with an optional seed.

toggle Syntax

RAND ( [integer-expression] )

toggle Parameters

integer-expression The optional seed used to create a random number. This argument allows you to create repeatable random number sequences.

toggle Usage

RAND is a non-deterministic function. Successive calls to RAND may return different values. The query optimizer does not cache the results of the RAND function.

For more information about non-deterministic functions, see Function caching.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns a value of approximately 0.0554504.

SELECT RAND( 4 )


RANK function [Aggregate]

toggle Function

Calculates the value of a rank in a group of values. In the case of ties, RANK leaves a gap in the ranking sequence.

toggle Syntax

RANK ( )

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/OLAP feature T611

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • CUME_DIST function [Aggregate]
  • DENSE_RANK function [Aggregate]
  • PERCENT_RANK function [Aggregate]
  • ROW_NUMBER function [Aggregate]
toggle Example

The following example provides a rank in descending order of employees' salaries in Utah and New York. Notice that the 7th and 8th employees have an identical salary and therefore share the 7th place ranking. The employee that follows receives the 9th place ranking, which leaves a gap in the ranking sequence (no 8th place ranking).

SELECT emp_lname, salary, state,
RANK () OVER (ORDER BY salary DESC) "Rank"
FROM employee WHERE state IN ('NY','UT')
emp_lname | salary | state | Rank
Shishov | 72995.000 | UT | 1
Wang | 68400.000 | UT | 2
Cobb | 62000.000 | UT | 3
Morris | 61300.000 | UT | 4
Davidson | 57090.000 | NY | 5
Martel | 55700.000 | NY | 6
Blaikie | 54900.000 | NY | 7
Diaz | 54900.000 | NY | 7
Driscoll | 48023.690 | UT | 9
Hildebrand | 45829.000 | UT | 10
Whitney | 45700.000 | NY | 11
... | ... | ... | ...
Lynch | 24903.000 | UT | 19


REGR_AVGX [Aggregate]

toggle Function

Computes the average of the independent variable of the regression line.

toggle Syntax

REGR_AVGX ( dependent-expression , independent-expression )

toggle Parameters

dependent-expression The variable that is affected by the independent variable.

independent-expression The variable that influences the outcome.

toggle Usage

The function returns a numeric value. If the function is applied to an empty set, then it returns NULL.

The function is applied to the set of (dependent-expression and independent-expression) pairs after eliminating all pairs for which either dependent-expression or independent-expression is null. The function is computed simultaneously during a single pass through the data. After eliminating null values, the following computation is then made:

AVG ( y )

where y represents the independent-expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • AVG function [Aggregate]
  • REGR_COUNT [Aggregate]
  • REGR_INTERCEPT [Aggregate]
  • REGR_COUNT [Aggregate]
  • REGR_SLOPE [Aggregate]
  • REGR_SXX [Aggregate]
  • REGR_SXY [Aggregate]
  • REGR_SYY [Aggregate]
  • REGR_AVGY [Aggregate]
toggle Example

The following example calculates the average of the dependent variable, employee age. The function returns the value 45.44.

SELECT REGR_AVGX (salary, (year(now()) - year(birth_date)))
FROM employee


REGR_AVGY [Aggregate]

toggle Function

Computes the average of the dependent variable of the regression line.

toggle Syntax

REGR_AVGY ( dependent-expression , independent-expression )

toggle Parameters

dependent-expression The variable that is affected by the independent variable.

independent-expression The variable that influences the outcome.

toggle Usage

The function returns a numeric value. If the function is applied to an empty set, then it returns NULL.

The function is applied to the set of (dependent-expression and independent-expression) pairs after eliminating all pairs for which either dependent-expression or independent-expression is null. The function is computed simultaneously during a single pass through the data. After eliminating null values, the following computation is then made:

AVG ( x )

where x represents the dependent-expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • REGR_COUNT [Aggregate]
  • REGR_INTERCEPT [Aggregate]
  • REGR_COUNT [Aggregate]
  • REGR_SLOPE [Aggregate]
  • REGR_SXX [Aggregate]
  • REGR_SXY [Aggregate]
  • REGR_SYY [Aggregate]
  • REGR_AVGX [Aggregate]
  • AVG function [Aggregate]
toggle Example

The following example calculates the average of the independent variable, employee salary. This function returns the value 49988.6232.

SELECT REGR_AVGY (salary, (year(now()) - year(birth_date)))
FROM employee


REGR_COUNT [Aggregate]

toggle Function

Returns an integer that represents the number of non-null number pairs used to fit the regression line.

toggle Syntax

REGR_COUNT ( dependent-expression , independent-expression )

toggle Parameters

dependent-expression The variable that is affected by the independent variable.

independent-expression The variable that influences the outcome.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • REGR_INTERCEPT [Aggregate]
  • REGR_COUNT [Aggregate]
  • REGR_SLOPE [Aggregate]
  • REGR_SXX [Aggregate]
  • REGR_SXY [Aggregate]
  • REGR_SYY [Aggregate]
  • REGR_AVGY [Aggregate]
  • REGR_AVGX [Aggregate]
  • COUNT function [Aggregate]
  • AVG function [Aggregate]
  • SUM function [Aggregate]
toggle Example

The following example returns a value that indicates the number of non-null pairs that were used to fit the regression line. This function returns the value 75.

SELECT REGR_COUNT (salary, (year(now()) - year(birth_date)))
FROM employee


REGR_INTERCEPT [Aggregate]

toggle Function

Computes the y-intercept of the regression line.

toggle Syntax

REGR_INTERCEPT ( dependent-expression , independent-expression )

toggle Parameters

dependent-expression The variable that is affected by the independent variable.

independent-expression The variable that influences the outcome.

toggle Usage

The function returns a numeric value. If the function is applied to an empty set, then it returns NULL.

The function is applied to the set of (dependent-expression and independent-expression) pairs after eliminating all pairs for which either dependent-expression or independent-expression is null. The function is computed simultaneously during a single pass through the data. After eliminating null values, the following computation is then made:

AVG ( x ) - REGR_SLOPE ( x, y ) * AVG ( y )

where x represents the dependent-expression and y represents the independent-expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • REGR_COUNT [Aggregate]
  • REGR_COUNT [Aggregate]
  • REGR_SLOPE [Aggregate]
  • REGR_SXX [Aggregate]
  • REGR_SXY [Aggregate]
  • REGR_SYY [Aggregate]
  • REGR_AVGY [Aggregate]
  • REGR_AVGX [Aggregate]
  • REGR_SLOPE [Aggregate]
  • AVG function [Aggregate]
toggle Example

The following example returns the value 7,486.6384185191855.

SELECT REGR_INTERCEPT (salary, (year(now()) - year(birth_date)))
FROM employee


REGR_R2 [Aggregate]

toggle Function

Computes the coefficient of determination (also referred to as R-squared or thegoodness of fit) for the regression line.

toggle Syntax

REGR_R2 ( dependent-expression , independent-expression )

toggle Parameters

dependent-expression The variable that is affected by the independent variable.

independent-expression The variable that influences the outcome.

toggle Usage

The function returns a numeric value. If the function is applied to an empty set, then it returns NULL.

The function is applied to the set of (dependent-expression and independent-expression) pairs after eliminating all pairs for which either dependent-expression or independent-expression is null.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • REGR_COUNT [Aggregate]
  • REGR_INTERCEPT [Aggregate]
  • REGR_SLOPE [Aggregate]
  • REGR_SXX [Aggregate]
  • REGR_SXY [Aggregate]
  • REGR_SYY [Aggregate]
  • REGR_AVGX [Aggregate]
  • REGR_AVGY [Aggregate]
toggle Example

The following example returns the value 0.19379959710325653.

SELECT REGR_R2 (salary, (year(now()) - year(birth_date)))
FROM employee


REGR_SLOPE [Aggregate]

toggle Function

Computes the slope of the regression line fitted to non-null pairs.

toggle Syntax

REGR_SLOPE ( dependent-expression , independent-expression )

toggle Parameters

dependent-expression The variable that is affected by the independent variable.

independent-expression The variable that influences the outcome.

toggle Usage

The function returns a numeric value. If the function is applied to an empty set, then it returns NULL.

The function is applied to the set of (dependent-expression and independent-expression) pairs after eliminating all pairs for which either dependent-expression or independent-expression is null. The function is computed simultaneously during a single pass through the data. After eliminating null values, the following computation is then made:

COVAR_POP ( x , y ) / VAR_POP ( y )

where x represents the dependent-expression and y represents the independent-expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • REGR_COUNT [Aggregate]
  • REGR_INTERCEPT [Aggregate]
  • REGR_COUNT [Aggregate]
  • REGR_SXX [Aggregate]
  • REGR_SXY [Aggregate]
  • REGR_SYY [Aggregate]
  • REGR_AVGX [Aggregate]
  • REGR_AVGY [Aggregate]
  • COVAR_POP function [Aggregate]
  • VAR_POP function [Aggregate]
toggle Example

The following example returns the value 935.3429749445614.

SELECT REGR_SLOPE (salary, (year(now()) - year(birth_date)))
FROM employee


REGR_SXX [Aggregate]

toggle Function

Returns values that can evaluate the statistical validity of a regression model.

toggle Syntax

REGR_SXX ( dependent-expression , independent-expression )

toggle Parameters

dependent-expression The variable that is affected by the independent variable.

independent-expression The variable that influences the outcome.

toggle Usage

The function returns a numeric value. If the function is applied to an empty set, then it returns NULL.

The function is applied to the set of (dependent-expression and independent-expression) pairs after eliminating all pairs for which either dependent-expression or independent-expression is null. The function is computed simultaneously during a single pass through the data. After eliminating null values, the following computation is then made:

REGR_COUNT ( x , y ) * VAR_POP ( y )

where x represents the dependent-expression and y represents the independent-expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • REGR_COUNT [Aggregate]
  • REGR_INTERCEPT [Aggregate]
  • REGR_COUNT [Aggregate]
  • REGR_AVGX [Aggregate]
  • REGR_AVGY [Aggregate]
  • REGR_SXY [Aggregate]
  • REGR_SYY [Aggregate]
  • VAR_POP function [Aggregate]
toggle Example

The following example returns the value 5916.4800000000105.

SELECT REGR_SXX (salary, (year(now()) - year(birth_date)))
FROM employee


REGR_SXY [Aggregate]

toggle Function

Returns values that can evaluate the statistical validity of a regression model.

toggle Syntax

REGR_SXY ( dependent-expression , independent-expression )

toggle Parameters

dependent-expression The variable that is affected by the independent variable.

independent-expression The variable that influences the outcome.

toggle Usage

The function returns a numeric value. If the function is applied to an empty set, then it returns NULL.

The function is applied to the set of (dependent-expression and independent-expression) pairs after eliminating all pairs for which either dependent-expression or independent-expression is null. The function is computed simultaneously during a single pass through the data. After eliminating null values, the following computation is then made:

REGR_COUNT ( x , y ) * VAR_POP ( x )

where x represents the dependent-expression and y represents the independent-expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • REGR_COUNT [Aggregate]
  • REGR_INTERCEPT [Aggregate]
  • REGR_COUNT [Aggregate]
  • REGR_SLOPE [Aggregate]
  • REGR_AVGX [Aggregate]
  • REGR_AVGY [Aggregate]
  • REGR_SXX [Aggregate]
  • REGR_SYY [Aggregate]
toggle Example

The following example returns the value 5533938.004400015.

SELECT REGR_SXY (salary, (year(now()) - year(birth_date)))
FROM employee


REGR_SYY [Aggregate]

toggle Function

Returns values that can evaluate the statistical validity of a regression model.

toggle Syntax

REGR_SYY ( dependent-expression , independent-expression )

toggle Parameters

dependent-expression The variable that is affected by the independent variable.

independent-expression The variable that influences the outcome.

toggle Usage

The function returns a numeric value. If the function is applied to an empty set, then it returns NULL.

The function is applied to the set of (dependent-expression and independent-expression) pairs after eliminating all pairs for which either dependent-expression or independent-expression is null. The function is computed simultaneously during a single pass through the data. After eliminating null values, the following computation is then made:

REGR_COUNT ( x , y ) * COVAR_POP (x, y)

where x represents the dependent-expression and y represents the independent-expression.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • REGR_COUNT [Aggregate]
  • REGR_INTERCEPT [Aggregate]
  • REGR_COUNT [Aggregate]
  • REGR_AVGX [Aggregate]
  • REGR_AVGY [Aggregate]
  • REGR_SLOPE [Aggregate]
  • REGR_SXX [Aggregate]
  • REGR_SXY [Aggregate]
toggle Example

The following example returns the value 26, 708, 672,843.3002.

SELECT REGR_SYY (salary, (year(now()) - year(birth_date)))
FROM employee


REMAINDER function [Numeric]

toggle Function

Returns the remainder when one whole number is divided by another.

toggle Syntax

REMAINDER ( dividend, divisor )

toggle Parameters

dividend The dividend, or numerator of the division.

divisor The divisor, or denominator of the division.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise. The % (modulo) operator and the division operator can be used to produce a remainder.

toggle See also
  • MOD function [Numeric]
toggle Example

The following statement returns the value 2.

SELECT REMAINDER( 5, 3 )


REPEAT function [String]

toggle Function

Concatenates a string a specified number of times.

toggle Syntax

REPEAT ( string-expression, integer-expression )

toggle Parameters

string-expression The string to be repeated.

integer-expression The number of times the string is to be repeated. If integer-expression is negative, an empty string is returned.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise, but REPLICATE provides the same capabilities.

toggle See also
  • REPLICATE function [String]
toggle Example

The following statement returns the value repeatrepeatrepeat.

SELECT REPEAT( 'repeat', 3 )


REPLACE function [String]

toggle Function

Replaces all occurrences of a substring with another substring.

toggle Syntax

REPLACE ( original-string, search-string, replace-string )

toggle Parameters

If any argument is NULL, the function returns NULL.

original-string The string to be searched. This can be any length.

search-string The string to be searched for and replaced with replace-string. This string is limited to 255 bytes. If search-string is an empty string, the original string is returned unchanged.

replace-string The replacement string, which replaces search-string. This can be any length. If replacement-string is an empty string, all occurrences of search-string are deleted.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • SUBSTRING function [String]
toggle Example

The following statement returns the value xx.def.xx.ghi.

SELECT REPLACE( 'abc.def.abc.ghi', 'abc', 'xx' )

The following statement generates a result set containing ALTER PROCEDURE statements which, when executed, would repair stored procedures that reference a table that has been renamed. (To be useful, the table name would need to be unique.)

SELECT REPLACE(
   replace(proc_defn,'OldTableName','NewTableName'),
   'create procedure',
   'alter procedure')
FROM SYS.SYSPROCEDURE
WHERE proc_defn LIKE '%OldTableName%'

Use a separator other than the comma for the LIST function:

SELECT REPLACE( list( table_id ), ',', '--')
FROM  SYS.SYSTABLE
WHERE table_id <= 5


REPLICATE function [String]

toggle Function

Concatenates a string a specified number of times.

toggle Syntax

REPLICATE ( string-expression, integer-expression )

toggle Parameters

string-expression The string to be repeated.

integer-expression The number of times the string is to be repeated.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • REPEAT function [String]
toggle Example

The following statement returns the value repeatrepeatrepeat.

SELECT REPLICATE( 'repeat', 3 )


REWRITE function [Miscellaneous]

toggle Function

Returns a rewritten SELECT, UPDATE, or DELETE statement.

toggle Syntax

REWRITE ( select-statement [ , 'ANSI' ] )

toggle Parameters

select-statement The SQL statement to which the rewrite optimizations are applied to generate the function's results.

toggle Usage

You can use the REWRITE function without the ANSI argument to help understand how the optimizer generated the access plan for a given query. In particular, you can find how Adaptive Server Anywhere has rewritten the conditions in the statement's WHERE, ON, and HAVING clauses, and then determine whether or not applicable indexes exist that can be exploited to improve the request's execution time.

The statement that is returned by REWRITE may not match the semantics of the original statement. This is because several rewrite optimizations introduce internal mechanisms that cannot be translated directly into SQL. For example, the server's use of row identifiers to perform duplicate elimination cannot be translated into SQL.

The rewritten query from the REWRITE() function is not intended to be executable. It is a tool for analyzing performance issues by showing what gets passed to the optimizer after the rewrite phase.

There are some rewrite optimizations that are not reflected in the output of REWRITE. They include LIKE optimization, optimization for minimum or maximum functions, upper/lower elimination, and predicate subsumption.

If ANSI is specified, REWRITE returns the ANSI equivalent to the statement. In this case, only the following rewrite optimizations are applied:

  • Transact-SQL outer joins are rewritten as ANSI SQL outer joins.

  • Duplicate correlation names are eliminated.

  • KEY and NATURAL joins are rewritten as ANSI SQL joins.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Semantic query transformations
  • EXTENDED_JOIN_SYNTAX option [database]
  • Transact-SQL outer joins (*= or =*)
  • Key joins
  • Natural joins
  • Duplicate correlation names in joins (star joins)
toggle Example

In the following example, two rewrite optimizations are performed on a query. The first is the unnesting of the subquery into a join between the employee and sales_order tables. The second optimization simplifies the query by eliminating the primary key - foreign key join between employee and sales_order. Part of this rewrite optimization is to replace the join predicate e.emp_id=s.sales_rep with the predicate s.sales_rep IS NOT NULL.

SELECT REWRITE( 'SELECT s.id, s.order_date
    FROM sales_order s
    WHERE  EXISTS(SELECT *
       FROM employee e
          WHERE e.emp_id = s.sales_rep)' ) FROM dummy

The query returns a single column result set containing the rewritten query:

'SELECT s.id, s.order_date FROM sales_order s WHERE s.sales_rep IS NOT NULL'

The next example of REWRITE uses the ANSI argument.

SELECT REWRITE( 'SELECT DISTINCT s.id, s.order_date, e.emp_fname, e.emp_id
    FROM sales_order s, employee e
          WHERE e.emp_id *= s.sales_rep', 'ANSI' ) FROM dummy

The result is the ANSI equivalent of the statement. In this case, the Transact-SQL outer join is converted to an ANSI outer join. The query returns a single column result set (broken into separate lines for readability):

'SELECT DISTINCT s.id, s.order_date, e.emp_id, e.emp_fname
 FROM employee as e
 LEFT OUTER JOIN  sales_order as s
 ON e.emp_id = s.sales_rep'


RIGHT function [String]

toggle Function

Returns the rightmost characters of a string.

toggle Syntax

RIGHT ( string-expression, integer-expression )

toggle Parameters

string-expression The string to be left-truncated.

integer-expression The number of characters at the end of the string to return.

toggle Usage

If the string contains multi-byte characters, and the proper collation is being used, the number of bytes returned may be greater than the specified number of characters.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • LEFT function [String]
  • International Languages and Character Sets
toggle Example

The following statement returns the value olate.

SELECT RIGHT( 'chocolate', 5 )


ROUND function [Numeric]

toggle Function

Rounds the numeric-expression to the specified integer-expression amount of places after the decimal point.

toggle Syntax

ROUND ( numeric-expression, integer-expression )

toggle Parameters

numeric-expression The number, passed into the function, to be rounded..

integer-expression A positive integer specifies the number of significant digits to the right of the decimal point at which to round. A negative expression specifies the number of significant digits to the left of the decimal point at which to round.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • TRUNCNUM function [Numeric]
toggle Example

The following statement returns the value 123.200.

SELECT ROUND( 123.234, 1 )


ROW_NUMBER function [Aggregate]

toggle Function

Assigns a unique number to each row.

toggle Syntax

ROW_NUMBER ( )

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/OLAP feature T611

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • CUME_DIST function [Aggregate]
  • DENSE_RANK function [Aggregate]
  • PERCENT_RANK function [Aggregate]
  • RANK function [Aggregate]
toggle Example

The following example returns a result set that provides unique row numbers for each of employees in New York and Utah. Because the query is ordered by salary in descending order, the first row number is given to the employee with the highest salary in the data set. Although two employees have identical salaries, the tie is not resolved because the two employees are assigned unique row numbers.

SELECT emp_lname, salary, state,
ROW_NUMBER () OVER (ORDER BY salary DESC) "Rank"
FROM employee WHERE state IN ('NY','UT')
emp_lname | salary | state | Rank
Shishov | 72995.000 | UT | 1
Wang | 68400.000 | UT | 2
Cobb | 62000.000 | UT | 3
Morris | 61300.000 | UT | 4
Davidson | 57090.000 | NY | 5
Martel | 55700.000 | NY | 6
Blaikie | 54900.000 | NY | 7
Diaz | 54900.000 | NY | 8
Driscoll | 48023.690 | UT | 9
Hildebrand | 45829.000 | UT | 10
... | ... | ... | ...
Lynch | 24903.000 | UT | 19


RTRIM function [String]

toggle Function

Returns a string with trailing blanks removed.

toggle Syntax

RTRIM ( string-expression )

toggle Parameters

string-expression The string to be trimmed.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • LTRIM function [String]
toggle Example

The following statement returns the string Test Message, with all trailing blanks removed.

SELECT RTRIM( 'Test Message     ' )


SECOND function [Date and time]

toggle Function

Returns a number from 0 to 59 corresponding to the second component of the given datetime value.

toggle Syntax

SECOND ( datetime-expression )

toggle Parameters

datetime-expression The datetime value.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value 21.

SELECT SECOND( '1998-07-13:21:21:25' )


SECONDS function [Date and time]

toggle Function

Given two timestamps, this function returns the integer number of seconds between them. It is recommended that you use the DATEDIFF function [Date and time] instead for this purpose.

Given a single date, this function returns the number of seconds since 0000-02-29 00:00:00.

Given one date and an integer, it adds the integer number of seconds to the specified timestamp. It is recommended that you use the DATEADD function [Date and time] instead for this purpose.

Syntax 1 returns a bigint. Syntax 2 returns a timestamp.

toggle Syntax 1

SECONDS ( [ datetime-expression, ] datetime-expression )

toggle Syntax 2

SECONDS ( datetime-expression, integer-expression )

toggle Parameters

datetime-expression A date and time.

integer-expression The number of seconds to be added to the datetime-expression. If integer-expression is negative, the appropriate number of minutes is subtracted from the datetime value. If you supply an integer expression, the datetime-expression must be explicitly cast as a datetime data type.

For information on casting data types, see CAST function [Data type conversion].

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statements return the value 14 400, signifying that the second timestamp is 14 400 seconds after the first.

SELECT SECONDS( '1999-07-13 06:07:12',
   '1999-07-13 10:07:12' )
SELECT DATEDIFF( second,
   '1999-07-13 06:07:12',
   '1999-07-13 10:07:12' )

The following statement returns the value 63 062 431 632.

SELECT SECONDS( '1998-07-13 06:07:12' )

The following statements return the datetime 1999-05-12 21:05:12.0.

SELECT SECONDS( CAST( '1999-05-12 21:05:07'
AS TIMESTAMP ), 5)
SELECT DATEADD( second, '1999-05-12 21:05:07' )


SHORT_ULPLAN function [Miscellaneous]

toggle Function

Returns a short description of the UltraLite plan optimization strategy of a SQL statement, as a string. The description is the same as that returned by the EXPLANATION function.

For some queries, the execution plan for UltraLite may differ from the plan selected for Adaptive Server Anywhere.

toggle Syntax

SHORT_ULPLAN ( string-expression )

toggle Parameters

string-expression The SQL statement, which is commonly a SELECT statement but which may also be an UPDATE or DELETE.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • PLAN function [Miscellaneous]
  • EXPLANATION function [Miscellaneous]
  • GRAPHICAL_PLAN function [Miscellaneous]
  • GRAPHICAL_ULPLAN function [Miscellaneous]
  • LONG_ULPLAN function [Miscellaneous]
toggle Example

The following statement passes a SELECT statement as a string parameter and returns the plan for executing the query.

SELECT EXPLANATION(
   'select * from department where dept_id > 100' )

This information can help with decisions about indexes to add or how to structure your database for better performance.

In Interactive SQL, you can view the plan for any SQL statement on the UltraLite Plan tab in the Results pane.


SIGN function [Numeric]

toggle Function

Returns the sign of a number.

toggle Syntax

SIGN ( numeric-expression )

toggle Parameters

numeric-expression The number for which the sign is to be returned.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value -1

SELECT SIGN( -550 )
toggle Return value

For negative numbers, SIGN returns -1.

For zero, SIGN returns 0.

For positive numbers, SIGN returns 1.


SIMILAR function [String]

toggle Function

Returns a number indicating the similarity between two strings.

toggle Syntax

SIMILAR ( string-expression-1, string-expression-2 )

toggle Parameters

string-expression-1 The first string to be compared.

string-expression-2 The second string to be compared.

toggle Usage

The function returns an integer between 0 and 100 representing the similarity between the two strings. The result can be interpreted as the percentage of characters matched between the two strings. A value of 100 indicates that the two strings are identical.

This function can be used to correct a list of names (such as customers). Some customers may have been added to the list more than once with slightly different names. Join the table to itself and produce a report of all similarities greater than 90 percent but less than 100 percent.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value 75.

SELECT SIMILAR( 'toast', 'coast' )

This signifies that the two values are 75% similar.


SIN function [Numeric]

toggle Function

Returns the sine of a number.

toggle Syntax

SIN ( numeric-expression )

toggle Parameters

numeric-expression The angle, in radians.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • ASIN function [Numeric]
  • COS function [Numeric]
  • COT function [Numeric]
  • TAN function [Numeric]
toggle Example

The following statement returns the value 0.496880.

SELECT SIN( 0.52 )


SORTKEY function [String]

toggle Function

Generates values that can be used to sort character strings based on alternate collation rules.

toggle Syntax

SORTKEY ( string-expression
[, collation-name | , collation-id ] )

toggle Parameters

string-expression The string expression may only contain characters that are encoded in the database's character set.

If string-expression is an empty string, SORTKEY returns a zero-length binary value. If string-expression is null, SORTKEY returns a null value. An empty string has a different sort order value than a null string from a database column.

The maximum length of the string that SORTKEY can handle is 254 bytes. Any longer part is ignored.

collation-name A string or a character variable that specifies the name of the sort order to use.

collation-id A variable, integer constant, or string that specifies the ID number of the sort order to use.

If you do not specify a collation, the default is Default Unicode multilingual.

Following are the valid values for collation-name and collation-id:

Description | Collation name | Collation ID
Default Unicode multilingual | default | 0
CP 850 Alternative: no accent | altnoacc | 39
CP 850 Alternative: lower case first | altdict | 45
CP 850 Western European: no case, preference | altnocsp | 46
CP 850 Scandinavian dictionary | scandict | 47
CP 850 Scandinavian: no case, preference | scannocp | 48
GB Pinyin | gbpinyin | n/a
Binary sort | binary | 50
Latin-1 English, French, German dictionary | dict | 51
Latin-1 English, French, German no case | nocase | 52
Latin-1 English, French, German no case, preference | nocasep | 53
Latin-1 English, French, German no accent | noaccent | 54
Latin-1 Spanish dictionary | espdict | 55
Latin-1 Spanish no case | espnocs | 56
Latin-1 Spanish no accent | espnoac | 57
ISO 8859-5 Russian dictionary | rusdict | 58
ISO 8859-5 Russian no case | rusnocs | 59
ISO 8859-5 Cyrillic dictionary | cyrdict | 63
ISO 8859-5 Cyrillic no case | cyrnocs | 64
ISO 8859-7 Greek dictionary | elldict | 65
ISO 8859-2 Hungarian dictionary | hundict | 69
ISO 8859-2 Hungarian no accents | hunnoac | 70
ISO 8859-2 Hungarian no case | hunnocs | 71
ISO 8859-5 Turkish dictionary | turdict | 72
ISO 8859-5 Turkish no accents | turnoac | 73
ISO 8859-5 Turkish no case | turnocs | 74
CP 874 (TIS 620) Royal Thai dictionary | thaidict | 257
ISO 14651 ordering standard | 14651 | 258
Shift-JIS binary order | sjisbin | 259
Unicode UTF-8 binary sort | utf8bin | 260
EUC JIS binary order | eucjisbin | 261
GB2312 binary order | gb2312bn | 262
CP932 MS binary order | cp932bin | 263
Big5 binary order | big5bin | 264
EUC KSC binary order | euckscbin | 265
toggle Usage

The SORTKEY function generates values that can be used to order results based on predefined sort order behavior. This allows you to work with character sort order behaviors that are beyond the limitation of Adaptive Server Anywhere collations. The returned value is a binary value that contains coded sort order information for the input string is retained from the SORTKEY function.

For example, you can store the values returned by SORTKEY in a column with the source character string. When you want to retrieve the character data in the desired order, the SELECT statement only needs to include an ORDER BY clause on the columns that contain the results of running SORTKEY.

The SORTKEY function guarantees that the values it returns for a given set of sort order criteria work for the binary comparisons that are performed on VARBINARY data types.

The input of SORTKEY can generate up to six bytes of sort order information for each input character. The output of SORTKEY is of type VARBINARY and has a maximum length of (254 * 6) bytes.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise, except that Adaptive Server Enterprise does not allow the use of self-defined sort orders.

toggle See also
  • COMPARE function [String]
  • Introduction to international languages and character sets
toggle Example

The following statements return the sort key values in the sort order: Latin-1, English, French, German dictionary.

SELECT SORTKEY('coop', 'dict')
SORTKEY( 'coop', 'dict' )
0x08890997099709b30008000800080008
SELECT SORTKEY ( 'Cö-op', 51 )
SORTKEY( 'Cö-op', 51 )
0x08890997099709b30020004700020008000800080001fffd002d


SOUNDEX function [String]

toggle Function

Returns a number representing the sound of a string.

toggle Syntax

SOUNDEX ( string-expression )

toggle Parameters

string-expression The string.

toggle Usage

The SOUNDEX function value for a string is based on the first letter and the next three consonants other than H, Y, and W. Doubled letters are counted as one letter. For example,

SOUNDEX( 'apples' )

is based on the letters A, P, L, and S.

Multi-byte characters are ignored by the SOUNDEX function.

Although it is not perfect, SOUNDEX will normally return the same number for words that sound similar and that start with the same letter.

The SOUNDEX function works best with English words. It is less useful for other languages.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise, except that Adaptive Server Enterprise returns a CHAR(4) result and Adaptive Server Anywhere returns an integer.

toggle Example

The following statement returns two numbers, representing the sound of each name. The SOUNDEX value for each argument is 3827.

SELECT SOUNDEX( 'Smith' ), SOUNDEX( 'Smythe' )


SPACE function [String]

toggle Function

Returns a specified number of spaces.

toggle Syntax

SPACE ( integer-expression )

toggle Parameters

integer-expression The number of spaces to return.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns a string containing 10 spaces.

SELECT SPACE( 10 )


SQLDIALECT function [Miscellaneous]

toggle Function

Returns either 'Watcom-SQL' or 'Transact-SQL', indicating the SQL dialect of a statement.

toggle Syntax

SQLDIALECT ( sql-statement-string )

toggle Parameters

sql-statement-string The SQL statement that the function uses to determine its dialect.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • TRANSACTSQL function [Miscellaneous]
  • WATCOMSQL function [Miscellaneous]
toggle Example

The following statement returns the string Transact-SQL.

SELECT
   SQLDIALECT( 'SELECT employeeName = emp_lname FROM employee' )
FROM dummy


SQRT function [Numeric]

toggle Function

Returns the square root of a number.

toggle Syntax

SQRT ( numeric-expression )

toggle Parameters

numeric-expression The number for which the square root is to be calculated.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns the value 3.

SELECT SQRT( 9 )


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

SQL Functions

Alphabetical list of functions

STDDEV function [Aggregate]

toggle Function

An alias for STDDEV_SAMP. See STDDEV_SAMP function [Aggregate].


STDDEV_POP function [Aggregate]

toggle Function

Computes the standard deviation of a population consisting of a numeric-expression, as a DOUBLE.

toggle Syntax

STDDEV_POP ( numeric-expression )

toggle Parameters

numeric-expression The expression whose population-based standard deviation is calculated over a set of rows. The expression is commonly a column name.

toggle Usage

The population-based standard deviation (s) is computed according to the following formula:

s = [ (1/N) * SUM( xi - mean( x ) )2 ]1/2

This standard deviation does not include rows where numeric-expression is NULL. It returns NULL for a group containing no rows.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Aggregate functions
toggle Example

The following statement lists the average and variance in the number of items per order in different time periods:

SELECT year( ship_date ) AS Year,
    quarter( ship_date ) AS Quarter,
    avg( quantity ) AS Average,
    STDDEV_POP( quantity ) AS Variance
FROM sales_order_items
GROUP BY Year, Quarter
ORDER BY Year, Quarter
Year | Quarter | Average | Variance
2000 | 1 | 25.775148 | 14.2794...
2000 | 2 | 27.050847 | 15.0270...
... | ... | ... | ...


STDDEV_SAMP function [Aggregate]

toggle Function

Computes the standard deviation of a sample consisting of a numeric-expression, as a DOUBLE.

toggle Syntax

STDDEV_SAMP ( numeric-expression )

toggle Parameters

numeric-expression The expression whose sample-based standard deviation is calculated over a set of rows. The expression is commonly a column name.

toggle Usage

The standard deviation (s) is computed according to the following formula, which assumes a normal distribution:

s = [ (1/( N - 1 )) * SUM( xi - mean( x ) )2 ]1/2

This standard deviation does not include rows where numeric-expression is NULL. It returns NULL for a group containing no rows.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Aggregate functions
toggle Example

The following statement lists the average and variance in the number of items per order in different time periods:

SELECT year( ship_date ) AS Year,
    quarter( ship_date ) AS Quarter,
    avg( quantity ) AS Average,
    STDDEV_SAMP( quantity ) AS Variance
FROM sales_order_items
GROUP BY Year, Quarter
ORDER BY Year, Quarter
Year | Quarter | Average | Variance
2000 | 1 | 25.775148 | 14.3218...
2000 | 2 | 27.050847 | 15.0696...
... | ... | ... | ...


STR function [String]

toggle Function

Returns the string equivalent of a number.

toggle Syntax

STR ( numeric_expression [, length [, decimal ] ] )

toggle Parameters

numeric-expression Any approximate numeric (float, real, or double precision) expression between -1E126 and 1E127.

length The number of characters to be returned (including the decimal point, all digits to the right and left of the decimal point, and blanks). The default is 10.

decimal The number of decimal digits to be returned. The default is 0.

toggle Usage

If the integer portion of the number cannot fit in the length specified, then the result is a string of the specified length containing all asterisks. For example, the following statement returns ***

SELECT STR( 1234.56, 3 )
Note
The maximum length that is supported is 128. Any length that is not between 1 and 128 yields a result of NULL.
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

The following statement returns a string of six spaces followed by 1235, for a total of ten characters:

SELECT STR( 1234.56 )

The following statement returns the result 1234.6:

SELECT STR( 1234.56, 6, 1 )


STRING function [String]

toggle Function

Concatenates one or more strings into one large string.

toggle Syntax

STRING ( string-expression [, ...] )

toggle Parameters

string-expression A string.

If only one argument is supplied, it is converted into a single expression. If more than one argument is supplied, they are concatenated into a single string.

toggle Usage

Numeric or date parameters are converted to strings before concatenation. The STRING function can also be used to convert any single expression to a string by supplying that expression as the only parameter.

If all parameters are NULL, STRING returns NULL. If any parameters are non-NULL, then any NULL parameters are treated as empty strings.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement returns the value testing123.

SELECT STRING( 'testing', NULL, 123 )


STRTOUUID function [String]

toggle Function

Converts a string value to a unique identifier (UUID or GUID) value.

Not needed in newer databases
In databases created before version 9.0.2, the UNIQUEIDENTIFIER data type is defined as a user-defined data type and the STRTOUUID and UUIDTOSTR functions are needed to convert between binary and string representations of UUID values.

In databases created using version 9.0.2 or later, the UNIQUEIDENTIFIER data type is a native data type and Adaptive Server Anywhere carries out conversions as needed. The STRTOUUID and UUIDTOSTR functions are therefore not needed.

For more information, see UNIQUEIDENTIFIER data type [Binary].

toggle Syntax

STRTOUUID ( string-expression )

toggle Parameters

string-expression A string in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

toggle Usage

Converts a string in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx where x is a hexadecimal digit, to a unique identifier value. If the string is not a valid UUID string, a conversion error is returned unless the CONVERSION_ERROR option is set to OFF, in which case it returns NULL.

This function is useful for inserting UUID values into a database.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • UUIDTOSTR function [String]
  • NEWID function [Miscellaneous]
toggle Example
CREATE TABLE T1 (
   pk UNIQUEIDENTIFIER PRIMARY KEY,
   c1 INT );
INSERT INTO T1 (pk, c1)
VALUES (STRTOUUID
    ('12345678-1234-5678-9012-123456789012'), 1);


STUFF function [String]

toggle Function

Deletes a number of characters from one string and replaces them with another string.

toggle Syntax

STUFF ( string-expression-1, start, length, string-expression-2 )

toggle Parameters

string-expression-1 The string to be modified by the STUFF function.

start The character position at which to begin deleting characters. The first character in the string is position 1.

length The number of characters to delete.

string-expression-2 The string to be inserted. To delete a portion of a string using STUFF, use a replacement string of NULL.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • INSERTSTR function [String]
toggle Example

The following statement returns the value chocolate pie.

SELECT STUFF( 'chocolate cake', 11, 4, 'pie' )


SUBSTRING function [String]

toggle Function

Returns a substring of a string.

toggle Syntax

{ SUBSTRING | SUBSTR }( string-expression, start [, length ] )

toggle Parameters

string-expression The string from which a substring is to be returned.

start The start position of the substring to return, in characters. A negative starting position specifies a number of characters from the end of the string instead of the beginning. The first character in the string is at position 1.

length The length of the substring to return, in characters. A positive length specifies that the substring ends length characters to the right of the starting position, while a negative length returns at most length characters up to, and including, the starting position, from the left of the starting position.

toggle Usage

Both start and length can be either positive or negative. Using appropriate combinations of negative and positive numbers, you can get a substring from either the beginning or end of the string.

If length is specified, the substring is restricted to that length. If start is zero and length is non-negative, a start value of 1 is used. If start is zero and length is negative, a start value of -1 is used.

If string-expression is of binary data type, the SUBSTRING function behaves as BYTE_SUBSTR.

toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase SUBSTRING is compatible with Adaptive Server Enterprise. SUBSTR is not supported by Adaptive Server Enterprise.

toggle See also
  • BYTE_SUBSTR function [String]
toggle Example

The following statement returns back:

SELECT SUBSTRING( 'back yard', 1, 4 )

The following statement returns yard:

SELECT SUBSTRING( 'back yard', 6, 4 )

The following statement returns gh:

SELECT SUBSTR('abcdefgh',0,-2)

The following statement returns gh:

SELECT SUBSTR('abcdefgh',-2,2)

The following statements both return ab:

SELECT SUBSTR('abcdefgh',2,-2)
SELECT SUBSTR('abcdefgh',2,-4)

The following statement returns b:

SELECT SUBSTR('abcdefgh',2,-1)


SUM function [Aggregate]

toggle Function

Returns the total of the specified expression for each group of rows.

toggle Syntax

SUM ( expression | DISTINCT column-name )

toggle Parameters

expression The object to be summed. This is commonly a column name.

DISTINCT column-name This is of limited usefulness, but is included for completeness.

toggle Usage

Rows where the specified expression is NULL are not included.

Returns NULL for a group containing no rows.

toggle Standards and compatibility

  • SQL/92 SQL/92 compatible.

  • SQL/99 Core feature.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • COUNT function [Aggregate]
  • AVG function [Aggregate]
toggle Example

The following statement returns the value 3749146.

SELECT SUM( salary )
FROM Employee


TAN function [Numeric]

toggle Function

Returns the tangent of a number.

toggle Syntax

TAN ( numeric-expression )

toggle Parameters

numeric-expression An angle, in radians.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • COS function [Numeric]
  • SIN function [Numeric]
toggle Example

The following statement returns the value 0.572561.

SELECT TAN( 0.52 )


TEXTPTR function [Text and image]

toggle Function

Returns the 16-byte binary pointer to the first page of the specified text column.

toggle Syntax

TEXTPTR ( column-name )

toggle Parameters

column-name The name of a text column.

toggle Usage

This function is included for Transact-SQL compatibility.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example

Use TEXTPTR to locate the text column, copy, associated with au_id 486-29-1786 in the author's blurbs table.

The text pointer is put into a local variable @val and supplied as a parameter to the readtext command, which returns 5 bytes, starting at the second byte (offset of 1).

DECLARE @val VARBINARY(16)
SELECT @val = TEXTPTR(copy)
FROM blurbs
WHERE au_id = "486-29-1786"
READTEXT blurbs.copy @val 1 5


TODAY function [Date and time]

toggle Function

Returns the current date. This is the historical syntax for CURRENT DATE.

toggle Syntax

TODAY ( * )

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statements return the current day according to the system clock.

SELECT TODAY( * )
SELECT CURRENT DATE


TRACEBACK function [Miscellaneous]

toggle Function

Returns a string containing a traceback of the procedures and triggers that were executing when the most recent exception (error) occurred.

toggle Syntax

TRACEBACK ( * )

toggle Usage

This is useful for debugging procedures and triggers

toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

To use the traceback function, enter the following after an error occurs while executing a procedure:

SELECT TRACEBACK ( * )


TRANSACTSQL function [Miscellaneous]

toggle Function

Takes a Watcom-SQL statement and rewrites it in the Transact-SQL dialect.

toggle Syntax

TRANSACTSQL ( sql-statement-string )

toggle Parameters

sql-statement-string The SQL statement that the function uses to determine its dialect.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • SQLDIALECT function [Miscellaneous]
  • WATCOMSQL function [Miscellaneous]
toggle Example

The following statement returns the string 'select EmployeeName = empl_name from employee'.

SELECT TRANSACTSQL( 'SELECT empl_name as EmployeeName FROM employee' ) FROM dummy


TRIM function [String]

toggle Function

Removes leading and trailing blanks from a string.

toggle Syntax

TRIM ( string-expression )

toggle Parameters

string-expression The string to be trimmed.

toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • LTRIM function [String]
  • RTRIM function [String]
toggle Example

The following statement returns the value chocolate with no leading or trailing blanks.

SELECT TRIM( '   chocolate   ' )


TRUNCATE function [Numeric]

toggle Function

Truncates a number at a specified number of places after the decimal point. Deprecated in favor of TRUNCNUM.

toggle Syntax

"TRUNCATE" ( numeric-expression, integer-expression )

toggle Parameters

numeric-expression The number to be truncated.

integer-expression A positive integer specifies the number of significant digits to the right of the decimal point at which to round. A negative expression specifies the number of significant digits to the left of the decimal point at which to round.

toggle Usage

This function is the same as TRUNCNUM. Using TRUNCNUM is recommended as it does not cause keyword conflicts.

The quotation marks are required because of a keyword conflict with the TRUNCATE TABLE statement. You can only use TRUNCATE without the quotation marks if the QUOTED_IDENTIFIER option is set to OFF.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported in Adaptive Server Enterprise.

toggle See also
  • QUOTED_IDENTIFIER option [compatibility]
  • TRUNCNUM function [Numeric]
toggle Example

The following statement returns the value 600.

SELECT "TRUNCATE"( 655, -2 )

The following statement returns the value 655.340.

SELECT "TRUNCATE"( 655.348, 2 )


TRUNCNUM function [Numeric]

toggle Function

Truncates a number at a specified number of places after the decimal point.

toggle Syntax

TRUNCNUM ( numeric-expression, integer-expression )

toggle Parameters

numeric-expression The number to be truncated.

integer-expression A positive integer specifies the number of significant digits to the right of the decimal point at which to round. A negative expression specifies the number of significant digits to the left of the decimal point at which to round.

toggle Usage

This function is the same as TRUNCATE, but does not cause keyword conflicts.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported in Adaptive Server Enterprise.

toggle See also
  • ROUND function [Numeric]
  • TRUNCATE function [Numeric]
toggle Example

The following statement returns the value 600.

SELECT TRUNCNUM( 655, -2 )

The following statement: returns the value 655.340.

SELECT TRUNCNUM( 655.348, 2 )


UCASE function [String]

toggle Function

Converts all characters in a string to upper case.

toggle Syntax

UCASE ( string-expression )

toggle Parameters

string-expression The string to be converted to upper case.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase UCASE is not supported by Adaptive Server Enterprise, but UPPER provides the same feature in a compatible manner.

toggle See also
  • UPPER function [String]
  • LCASE function [String]
toggle Example

The following statement returns the value CHOCOLATE.

SELECT UCASE( 'ChocoLate' )


UPPER function [String]

toggle Function

Converts all characters in a string to upper case.

toggle Syntax

UPPER ( string-expression )

toggle Parameters

string-expression The string to be converted to upper case.

toggle Standards and compatibility

  • SQL/92 This function is SQL/92 compatible.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • UCASE function [String]
  • LCASE function [String]
  • LOWER function [String]
toggle Example

The following statement returns the value CHOCOLATE.

SELECT UPPER( 'ChocoLate' )


UUIDTOSTR function [String]

toggle Function

Converts a unique identifier value (UUID, also known as GUID) to a string value.

Not needed in newer databases
In databases created before version 9.0.2, the UNIQUEIDENTIFIER data type is defined as a user-defined data type and the STRTOUUID and UUIDTOSTR functions are needed to convert between binary and string representations of UUID values.

In databases created using version 9.0.2 or later, the UNIQUEIDENTIFIER data type is a native data type and Adaptive Server Anywhere carries out conversions as needed. The STRTOUUID and UUIDTOSTR functions are therefore not needed.

For more information, see UNIQUEIDENTIFIER data type [Binary].

toggle Syntax

UUIDTOSTR ( uuid-expression )

toggle Parameters

uuid-expression A unique identifier value.

toggle Usage

Converts a unique identifier to a string value in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, where x is a hexadecimal digit. If the binary value is not a valid uniqueidentifier, NULL is returned.

This function is useful if you want to view a UUID value.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • NEWID function [Miscellaneous]
  • STRTOUUID function [String]
toggle Example

The following statement creates a table mytab with two columns. Column pk has a unique identifier data type, and column c1 has an integer data type. It then inserts two rows with the values 1 and 2 respectively into column c1.

CREATE TABLE T1(
    pk UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(),
    c1 INT );
INSERT INTO T1( c1 ) values ( 1 );
INSERT INTO T1( c1 ) values ( 2 );

Executing the following SELECT statement returns all of the data in the newly created table.

SELECT *
FROM T1

You will see a two-column, two-row table. The value displayed for column pk will be binary values.

To convert the unique identifier values into a readable format, execute the following command:

SELECT UUIDTOSTR(pk),c1
FROM T1

The UUIDTOSTR function is not needed for database created with version 9.0.2 or later.


VAR_POP function [Aggregate]

toggle Function

Computes the statistical variance of a population consisting of a numeric-expression, as a DOUBLE.

toggle Syntax

VAR_POP ( numeric-expression )

toggle Parameters

numeric-expression The expression whose population-based variance is calculated over a set of rows. The expression is commonly a column name.

toggle Usage

The population-based variance (s2) is computed according to the following formula:

s2 = (1/N) * SUM( xi - mean( x ) )2

This variance does not include rows where numeric-expression is NULL. It returns NULL for a group containing no rows.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Aggregate functions
toggle Example

The following statement lists the average and variance in the number of items per order in different time periods:

SELECT year( ship_date ) AS Year,
    quarter( ship_date ) AS Quarter,
    avg( quantity ) AS Average,
    var_pop( quantity ) AS Variance
FROM sales_order_items
GROUP BY Year, Quarter
ORDER BY Year, Quarter
Year | Quarter | Average | Variance
2000 | 1 | 25.775148 | 203.9021...
2000 | 2 | 27.050847 | 225.8109...
... | ... | ... | ...


VAR_SAMP function [Aggregate]

toggle Function

Computes the statistical variance of a sample consisting of a numeric-expression, as a DOUBLE.

toggle Syntax

VAR_SAMP ( numeric-expression )

toggle Parameters

numeric-expression The expression whose sample-based variance is calculated over a set of rows. The expression is commonly a column name.

toggle Usage

The variance (s2) is computed according to the following formula, which assumes a normal distribution:

s2 = (1/( N - 1 )) * SUM( xi - mean( x ) )2

This variance does not include rows where numeric-expression is NULL. It returns NULL for a group containing no rows.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL. The VARIANCE syntax is a vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Aggregate functions
toggle Example

The following statement lists the average and variance in the number of items per order in different time periods:

SELECT year( ship_date ) AS Year,
    quarter( ship_date ) AS Quarter,
    avg( quantity ) AS Average,
    var_samp( quantity ) AS Variance
FROM sales_order_items
GROUP BY Year, Quarter
ORDER BY Year, Quarter
Year | Quarter | Average | Variance
2000 | 1 | 25.775148 | 205.1158...
2000 | 2 | 27.050847 | 227.0939...
... | ... | ... | ...


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

SQL Functions

Alphabetical list of functions

VARIANCE function [Aggregate]

toggle Function

An alias for VAR_SAMP. See VAR_SAMP function [Aggregate].


VAREXISTS function [Miscellaneous]

toggle Function

Returns 1 if a user-defined variable has been created or declared with a given name. Returns 0 if no such variable has been created.

toggle Syntax

VAREXISTS ( variable-name-string )

toggle Parameters

variable-name-string The name to be tested, as a string.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle See also
  • CREATE VARIABLE statement
  • DECLARE statement
  • IF statement
toggle Example

The following IF statement creates a variable with a name start_time if one is not already created or declared. The variable can then be used safely.

IF VAREXISTS('start_time') = 0 THEN
    CREATE VARIABLE start_time TIMESTAMP;
END IF;
SET start_time = current timestamp;


WATCOMSQL function [Miscellaneous]

toggle Function

Takes a Transact-SQL statement and rewrites it in the Watcom-SQL dialect. This can be useful when converting existing Adaptive Server Enterprise stored procedures into Watcom SQL syntax.

toggle Syntax

WATCOMSQL ( sql-statement-string )

toggle Parameters

sql-statement-string The SQL statement that the function uses to determine its dialect.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • SQLDIALECT function [Miscellaneous]
  • TRANSACTSQL function [Miscellaneous]
toggle Example

The following statement returns the string 'select empl_name as EmployeeName from employee'.

SELECT WATCOMSQL( 'SELECT EmployeeName=empl_name FROM employee' ) FROM dummy


WEEKS function [Date and time]

toggle Function

Given two dates, this function returns the integer number of weeks between them. It is recommended that you use the DATEDIFF function [Date and time] instead for this purpose.

Given a single date, this function returns the number of weeks since 0000-02-29.

Given one date and an integer, it adds the integer number of weeks to the specified date. It is recommended that you use the DATEADD function [Date and time] instead for this purpose.

Syntax 1 returns an integer. Syntax 2 returns a timestamp.

toggle Syntax 1

WEEKS ( [ datetime-expression, ] datetime-expression )

toggle Syntax 2

WEEKS ( datetime-expression, integer-expression )

toggle Parameters

datetime-expression A date and time.

integer-expression The number of weeks to be added to the datetime-expression. If integer-expression is negative, the appropriate number of weeks is subtracted from the datetime value. If you supply an integer expression, the datetime-expression must be explicitly cast as a datetime data type.

For information on casting data types, see CAST function [Data type conversion].

toggle Usage

The difference of two dates in weeks is the number of Sundays between the two dates.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statements return the value 8, signifying that the second date is eight weeks after the first. It is recommended that you use the second form (DATEDIFF).

SELECT WEEKS( '1999-07-13 06:07:12',
   '1999-09-13 10:07:12' )
SELECT DATEDIFF( week,
   '1999-07-13 06:07:12',
   '1999-09-13 10:07:12' )

The following statement returns the value 104 270.

SELECT WEEKS( '1998-07-13 06:07:12' )

The following statements return the timestamp 1999-06-16 21:05:07.0. It is recommended that you use the second form (DATEADD).

SELECT WEEKS( CAST( '1999-05-12 21:05:07'
AS TIMESTAMP ), 5)
SELECT DATEADD( week, '1999-05-12 21:05:07' )


XMLAGG function [String]

toggle Function

Generates a forest of XML elements from a collection of XML values.

toggle Syntax

XMLAGG ( value-expression [ ORDER BY order-by-expression ],... )

toggle Parameters

value-expression An XML value. The content is escaped unless the data type is XML. The order-by-expression orders the elements returned by the function.

order-by-expression An expression used to order the XML elements according to the value of this expression.

toggle Usage

Any values that are NULL are omitted from the result. If all inputs are NULL, or there are no rows, the result is NULL. If you require a well-formed XML document, you must ensure that your query is written so that the generated XML has a single root element.

Data in BINARY, LONG BINARY, IMAGE, and VARBINARY columns is automatically returned in base64-encoded format when you execute a query that contains XMLAGG.

For an example of a query that uses the XMLAGG function with an ORDER BY clause, see Using the XMLAGG function.

toggle Standards and compatibility

  • Part of the SQL/XML draft standard.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Using the XMLAGG function
toggle Example

The following statement generates an XML document that shows the orders placed by each customer.

SELECT XMLELEMENT( NAME "order",
                   XMLATTRIBUTES( id AS order_id ),
                     ( SELECT XMLAGG(
                         XMLELEMENT(
                           NAME "product",
                           XMLATTRIBUTES( prod_id,
                              quantity
                              AS "quantity_shipped" )
                                        )
                                    )
                      FROM sales_order_items soi
                      WHERE soi.id = so.id
                    )
                  ) AS products_ordered
FROM sales_order so
ORDER BY so.id


XMLCONCAT function [String]

toggle Function

Produces a forest of XML elements.

toggle Syntax

XMLCONCAT ( xml-value,... )

toggle Parameters

xml-value The XML values to be concatenated.

toggle Usage

Generates a forest of XML elements. In an unparsed XML document, a forest refers to the multiple root nodes within the document. NULL values are omitted from the result. If all the values are NULL, then NULL is returned. XMLCONCAT does not check whether the argument has a prolog. If you require a well-formed XML document, you must ensure that your query is written so that a single root element is generated.

Element content is always escaped unless the data type is XML. Data in BINARY, LONG BINARY, IMAGE, and VARBINARY columns is automatically returned in base64-encoded format when you execute a query that contains XMLCONCAT.

toggle Standards and Compatibility

  • Part of the SQL/XML draft standard.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Using the XMLCONCAT function
  • XMLFOREST function [String]
toggle Example

The following query generates <cust_id>, <cust_fname>, and <cust_lname> elements for each customer.

SELECT XMLCONCAT( XMLELEMENT ( NAME cust_id, id ),
                  XMLELEMENT( NAME cust_fname, fname ),
                  XMLELEMENT( NAME cust_lname, lname )
                 ) AS "Customer Information"
FROM customer
WHERE id < 120


XMLELEMENT function [String]

toggle Function

Produces an XML element within a query.

toggle Syntax

XMLELEMENT ( NAME element-name-expression
[, XMLATTRIBUTES ( attribute-value-expression
[ AS attribute-name ],... )
[, element-content-expression,... ] )

toggle Parameters

element-name-expression An identifier. For each row, an XML element with the same name as the identifier is generated.

attribute-value-expression An attribute of the element. This optional argument allows you to specify an attribute value for the generated element. This argument specifies the attribute name and content. If the attribute-value-expression is a column name, then the attribute name defaults to the column name. You can change the attribute name by specifying the attribute-name argument.

element-content-expression The content of the element. This can be any string expression. You can specify an unlimited number of element-content-expression arguments and they are concatenated together. For example,

SELECT XMLELEMENT( NAME x, 'abc', 'def' )

returns

<x>abcdef</x>
toggle Usage

NULL element values and NULL attribute values are omitted from the result. The letter case for both element and attribute names is taken from the query.

Element content is always escaped unless the data type is XML. Invalid element and attribute names are also quoted.

For more information about quoting and the XMLELEMENT function, see Invalid names and SQL/XML.

XMLELEMENT functions can be nested to create a hierarchy. If you wish to return different elements at the same level of the document hierarchy, use the XMLFOREST function.

For more information, see XMLFOREST function [String].

Data in BINARY, LONG BINARY, IMAGE, and VARBINARY columns is automatically returned in base64-encoded format when you execute a query that contains XMLELEMENT.

toggle Standards and compatibility

  • Part of the SQL/XML draft standard.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Using the XMLELEMENT function
  • XMLFOREST function [String]
toggle Example

The following statement produces an <item_name> element for each product in the result set, where the product name is the content of the element.

SELECT id, XMLELEMENT( NAME item_name, p.name )
FROM product p
WHERE id > 400


XMLFOREST function [String]

toggle Function

Generates a forest of XML elements.

toggle Syntax

XMLFOREST ( element-content-expression [ AS element-name ],... )

toggle Parameters

element-content-expression A string. An element is generated for each element-content-expression argument that is specified. The element-content-expression value becomes the content of the element. For example, if you specify the emp_id column from the employee table for this argument, then an <emp_id> element containing an emp_id value is generated for each value in the table.

Specify the element-name argument if you wish to assign a name other than the element-content-expression to the element, otherwise the element name defaults to the element-content-expression name.

toggle Usage

Produces a forest of XML elements. In the unparsed XML document, a forest refers to the multiple root nodes within the document. When all of the arguments to XMLFOREST are NULL, a NULL value is returned. If only some values are NULL, the NULL values are omitted from the result. Element content is always quoted unless the data type is XML. You cannot specify attributes using XMLFOREST. Use the XMLELEMENT function if you wish to specify attributes for generated elements.

For more information about the XMLELEMENT function, see XMLELEMENT function [String].

Element names are escaped unless the data type is XML.

If you require a well-formed XML document, you must ensure that your query is written so that a single root element is generated.

Data in BINARY, LONG BINARY, IMAGE, and VARBINARY columns is automatically returned in base64-encoded format when you execute a query that contains XMLFOREST.

toggle Standards and compatibility

  • Part of the SQL/XML draft standard.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Using the XMLFOREST function
  • XMLELEMENT function [String]
  • XMLCONCAT function [String]
toggle Example

The following statement produces an XML element for the first and last name of each employee.

SELECT emp_id,
       XMLFOREST( emp_fname, emp_lname
                ) AS "Employee Name"
FROM employee


XMLGEN function [String]

toggle Function

Generates an XML value based on an XQuery constructor.

toggle Syntax

XMLGEN ( xquery-constructor, content-expression [ AS variable-name ],... )

toggle Parameters

xquery-constructor An XQuery constructor. The XQuery constructor is an item defined in the XQuery language. It gives a syntax for constructing XML elements based on XQuery expressions. The xquery-constructor argument must be a well-formed XML document with one or more variable references. A variable reference is enclosed in curly braces and must be prefixed with a $ and have no surrounding white space. For example:

SELECT XMLGEN('<a>{$x}</a>', 1 AS x)

content-expression A variable. You can specify multiple content-expression arguments. The optional variable-name argument is used to name the variable. For example,

SELECT XMLGEN( '<emp emp_id="{$emp_id}"><start_date>{$x}
                </start_date></emp>',
               emp_id,
               start_date AS x
             )
FROM employee
toggle Usage

Computed constructors as defined in the XQuery specification are not supported by XMLGEN.

When you execute a query that contains XMLGEN, data in BINARY, LONG BINARY, IMAGE, and VARBINARY columns is automatically returned in base64-encoded format.

Element content is always escaped unless the data type is XML. Illegal XML element and attribute names are also escaped.

For information about escaping and the XMLGEN function, see Invalid names and SQL/XML.

toggle Standards and compatibility

  • Part of the SQL/XML draft standard.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle See also
  • Using the XMLGEN function
toggle Example

The following example generates an <emp> element, as well as <last_name>, <first_name>, and <start_date> elements for each employee.

SELECT XMLGEN ( '<emp emp_id="{$emp_id}">
                  <last_name>="{$emp_lname}"</last_name>
                  <first_name>="{$emp_fname}"</first_name>
                  <start_date>="{$start_date}"</start_date>
               </emp>',
               emp_id,
               emp_lname,
               emp_fname,
               start_date
              ) AS employee_list
FROM employee


YEAR function [Date and time]

toggle Function

Takes a timestamp value as a parameter and returns the year specified by that timestamp as a short value.

toggle Syntax

YEAR ( datetime-expression )

toggle Parameters

datetime-expression A date, time, or timestamp.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following example returns the value 2001.

SELECT YEAR ( '2001-09-12')


YEARS function [Date and time]

toggle Function

Given two dates, this function returns the integer number of years between them. It is recommended that you use the DATEDIFF function [Date and time] instead for this purpose.

Given one date, it returns the year. It is recommended that you use the DATEPART function [Date and time] instead for this purpose.

Given one date and an integer, it adds the integer number of years to the specified date. It is recommended that you use the DATEADD function [Date and time] instead for this purpose.

Syntax 1 returns an integer. Syntax 2 returns a timestamp.

toggle Syntax 1

YEARS ( [ datetime-expression, ] datetime-expression )

toggle Syntax 2

YEARS ( datetime-expression, integer-expression )

toggle Parameters

datetime-expression A date and time.

integer-expression The number of years to be added to the datetime-expression. If integer-expression is negative, the appropriate number of years is subtracted from the datetime value. If you supply an integer expression, the datetime-expression must be explicitly cast as a datetime data type.

For information on casting data types, see CAST function [Data type conversion].

toggle Usage

The value of YEARS is calculated from the number of first days of the year between the two dates.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statements both return –4

SELECT YEARS( '1998-07-13 06:07:12',
              '1994-03-13 08:07:13' )
SELECT DATEDIFF( year,
   '1998-07-13 06:07:12',
   '1994-03-13 08:07:13' )

The following statements return 1998.

SELECT YEARS( '1998-07-13 06:07:12' )
SELECT DATEPART( year, '1998-07-13 06:07:12' )

The following statements return the given date advanced 300 years.

SELECT YEARS(
   CAST( '1998-07-13 06:07:12' AS TIMESTAMP ),
   300 )
SELECT DATEADD( year, 300,
   '1998-07-13 06:07:12' )


YMD function [Date and time]

toggle Function

Returns a date value corresponding to the given year, month, and day of the month. Values are small integers from -32768 to 32767.

toggle Syntax

YMD (
integer-expression,
integer-expression,
integer-expression )

toggle Parameters

integer-expression The year.

integer-expression The number of the month. If the month is outside the range 1–12, the year is adjusted accordingly.

integer-expression The day number. The day is allowed to be any integer, the date is adjusted accordingly.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Compatible with Adaptive Server Enterprise

toggle Example

The following statement returns the value 1998-06-12.

SELECT YMD( 1998, 06, 12 )

If the values are outside their normal range, the date will adjust accordingly. For example, the following statement returns the value 2000-03-01.

SELECT YMD( 1999, 15, 1 )


SQL Statements

About this chapter

This chapter presents detailed descriptions of SQL statements in alphabetical order.

Using the SQL statement reference
ALLOCATE DESCRIPTOR statement [ESQL]
ALTER DATABASE statement
ALTER DBSPACE statement
ALTER DOMAIN statement
ALTER EVENT statement
ALTER FUNCTION statement
ALTER INDEX statement
ALTER PROCEDURE statement
ALTER PUBLICATION statement
ALTER REMOTE MESSAGE TYPE statement [SQL Remote]
ALTER SERVER statement
ALTER SERVICE statement
ALTER SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
ALTER SYNCHRONIZATION USER statement [MobiLink]
ALTER TABLE statement
ALTER TRIGGER statement
ALTER VIEW statement
ALTER WRITEFILE statement (deprecated)
BACKUP statement
BEGIN statement
BEGIN TRANSACTION statement
CALL statement
CASE statement
CHECKPOINT statement
CLEAR statement [Interactive SQL]
CLOSE statement [ESQL] [SP]
COMMENT statement
COMMIT statement
CONFIGURE statement [Interactive SQL]
CONNECT statement [ESQL] [Interactive SQL]
CREATE COMPRESSED DATABASE statement (deprecated)
CREATE DATABASE statement
CREATE DBSPACE statement
CREATE DECRYPTED FILE statement
CREATE DOMAIN statement
CREATE ENCRYPTED FILE statement
CREATE EVENT statement
CREATE EXISTING TABLE statement
CREATE EXTERNLOGIN statement
CREATE FUNCTION statement
CREATE INDEX statement
CREATE MESSAGE statement [T-SQL]
CREATE PROCEDURE statement
CREATE PROCEDURE statement [T-SQL]
CREATE PUBLICATION statement
CREATE REMOTE MESSAGE TYPE statement [SQL Remote]
CREATE SCHEMA statement
CREATE SERVER statement
CREATE SERVICE statement
CREATE STATISTICS statement
CREATE SUBSCRIPTION statement [SQL Remote]
CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
CREATE SYNCHRONIZATION USER statement [MobiLink]
CREATE TABLE statement
CREATE TRIGGER statement
CREATE TRIGGER statement [SQL Remote]
CREATE TRIGGER statement [T-SQL]
CREATE VARIABLE statement
CREATE VIEW statement
CREATE WRITEFILE statement (deprecated)
DEALLOCATE statement
DEALLOCATE DESCRIPTOR statement [ESQL]
Declaration section [ESQL]
DECLARE statement
DECLARE CURSOR statement [ESQL] [SP]
DECLARE CURSOR statement [T-SQL]
DECLARE LOCAL TEMPORARY TABLE statement
DELETE statement
DELETE (positioned) statement [ESQL] [SP]
DESCRIBE statement [ESQL]
DISCONNECT statement [ESQL] [Interactive SQL]
DROP statement
DROP DATABASE statement
DROP CONNECTION statement
DROP EXTERNLOGIN statement
DROP PUBLICATION statement
DROP REMOTE MESSAGE TYPE statement [SQL Remote]
DROP SERVER statement
DROP SERVICE statement
DROP STATEMENT statement [ESQL]
DROP STATISTICS statement
DROP SUBSCRIPTION statement [SQL Remote]
DROP SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
DROP SYNCHRONIZATION USER statement [MobiLink]
DROP VARIABLE statement
EXCEPT operation
EXECUTE statement [ESQL]
EXECUTE statement [T-SQL]
EXECUTE IMMEDIATE statement [SP]
EXIT statement [Interactive SQL]
EXPLAIN statement [ESQL]
FETCH statement [ESQL] [SP]
FOR statement
FORWARD TO statement
FROM clause
GET DATA statement [ESQL]
GET DESCRIPTOR statement [ESQL]
GET OPTION statement [ESQL]
GOTO statement [T-SQL]
GRANT statement
GRANT CONSOLIDATE statement [SQL Remote]
GRANT PUBLISH statement [SQL Remote]
GRANT REMOTE statement [SQL Remote]
GRANT REMOTE DBA statement [SQL Remote]
GROUP BY clause
HELP statement [Interactive SQL]
IF statement
IF statement [T-SQL]
INCLUDE statement [ESQL]
INPUT statement [Interactive SQL]
INSERT statement
INSTALL JAVA statement
INTERSECT operation
LEAVE statement
LOAD STATISTICS statement
LOAD TABLE statement
LOCK TABLE statement
LOOP statement
MESSAGE statement
OPEN statement [ESQL] [SP]
OUTPUT statement [Interactive SQL]
PARAMETERS statement [Interactive SQL]
PASSTHROUGH statement [SQL Remote]
PREPARE statement [ESQL]
PREPARE TO COMMIT statement
PRINT statement [T-SQL]
PUT statement [ESQL]
RAISERROR statement [T-SQL]
READ statement [Interactive SQL]
READTEXT statement [T-SQL]
RELEASE SAVEPOINT statement
REMOTE RESET statement [SQL Remote]
REMOVE JAVA statement
REORGANIZE TABLE statement
RESIGNAL statement
RESTORE DATABASE statement
RESUME statement
RETURN statement
REVOKE statement
REVOKE CONSOLIDATE statement [SQL Remote]
REVOKE PUBLISH statement [SQL Remote]
REVOKE REMOTE statement [SQL Remote]
REVOKE REMOTE DBA statement [SQL Remote]
ROLLBACK statement
ROLLBACK TO SAVEPOINT statement
ROLLBACK TRANSACTION statement
ROLLBACK TRIGGER statement
SAVE TRANSACTION statement
SAVEPOINT statement
SELECT statement
SET statement
SET statement [T-SQL]
SET CONNECTION statement [Interactive SQL] [ESQL]
SET DESCRIPTOR statement [ESQL]
SET OPTION statement
SET OPTION statement [Interactive SQL]
SET REMOTE OPTION statement [SQL Remote]
SET SQLCA statement [ESQL]
SETUSER statement
SIGNAL statement
START DATABASE statement [Interactive SQL]
START ENGINE statement [Interactive SQL]
START JAVA statement
START LOGGING statement [Interactive SQL]
START SUBSCRIPTION statement [SQL Remote]
START SYNCHRONIZATION DELETE statement [MobiLink]
STOP DATABASE statement
STOP ENGINE statement
STOP JAVA statement
STOP LOGGING statement [Interactive SQL]
STOP SUBSCRIPTION statement [SQL Remote]
STOP SYNCHRONIZATION DELETE statement [MobiLink]
SYNCHRONIZE SUBSCRIPTION statement [SQL Remote]
SYSTEM statement [Interactive SQL]
TRIGGER EVENT statement
TRUNCATE TABLE statement
UNION operation
UNLOAD statement
UNLOAD TABLE statement
UPDATE statement
UPDATE (positioned) statement [ESQL] [SP]
UPDATE statement [SQL Remote]
VALIDATE CHECKSUM statement
VALIDATE INDEX statement
VALIDATE TABLE statement
WAITFOR statement
WHENEVER statement [ESQL]
WHILE statement [T-SQL]
WRITETEXT statement [T-SQL]


Using the SQL statement reference

This section describes some conventions used in documenting the SQL statements.


Common elements in SQL syntax

This section lists language elements that are found in the syntax of many SQL statements.

For more information on the elements described here, see Identifiers, SQL Data Types, Search conditions, Expressions, or Strings.

  • column-name An identifier that represents the name of a column.

  • condition An expression that evaluates to TRUE, FALSE, or UNKNOWN.

  • connection-name A string representing the name of an active connection.

  • data-type A storage data type.

  • expression An expression.

  • filename A string containing a filename.

  • hostvar A C language variable, declared as a host variable preceded by a colon. See Using host variables for more information.

  • indicator-variable A second host variable of type short int immediately following a normal host variable. It must also be preceded by a colon. Indicator variables are used to pass NULL values to and from the database.

  • number Any sequence of digits followed by an optional decimal part and preceded by an optional negative sign. Optionally, the number can be followed by an E and then an exponent. For example,

    42
-4.038
.001
3.4e10
1e-10

  • owner An identifier representing the user ID who owns a database object.

  • role-name An identifier representing the role name of a foreign key.

  • savepoint-name An identifier that represents the name of a savepoint.

  • search-condition A condition that evaluates to TRUE, FALSE, or UNKNOWN.

  • special-value One of the special values described in Special values.

  • statement-label An identifier that represents the label of a loop or compound statement.

  • table-list A list of table names, which may include correlation names.

    For more information, see FROM clause.

  • table-name An identifier that represents the name of a table.

  • userid An identifier representing a user name.

  • variable-name An identifier that represents a variable name.


Syntax conventions

The following conventions are used in the SQL syntax descriptions:

  • Keywords All SQL keywords appear in upper case, like the SQL statement ALTER TABLE in the following example:

    ALTER TABLE [ owner.]table-name

  • Placeholders Items that must be replaced with appropriate identifiers or expressions appear in italics, like the words owner and table-name in the following example.

    ALTER TABLE [ owner.]table-name

  • Optional portions Optional portions of a statement are enclosed by square brackets.

    RELEASE SAVEPOINT [ savepoint-name ]

    These square brackets indicate that the savepoint-name is optional. The square brackets should not be typed.

  • Repeating items An item that can be repeated is follwed by the appropriate list separator and an ellipsis (three dots), like column-constraint in the following example:

    ADD column-definition [ column-constraint, ... ]

    In this case, you can specify no column constraint, one, or more. If more than one is specified, they must be separated by commas.

  • Options When none or only one of a list of items can be chosen, vertical bars separate the items and the list is enclosed in square brackets.

    [ ASC | DESC ]

    For example, you can choose one of ASC, DESC, or neither. The square brackets should not be typed.

  • Alternatives When precisely one of the options must be chosen, the alternatives are enclosed in curly braces.

    [ QUOTES { ON | OFF } ]

    In this case, if the QUOTES option is chosen, one of ON or OFF must be provided. The brackets and braces should not be typed.


Statement applicability indicators

Some statement titles are followed by an indicator in square brackets that indicate where the statement can be used. These indicators are as follows:

  • [ESQL] The statement is for use in Embedded SQL.

  • [Interactive SQL] The statement can be used only in Interactive SQL.

  • [SP] The statement is for use in stored procedures, triggers, or batches.

  • [T-SQL] The statement is implemented for compatibility with Adaptive Server Enterprise. In some cases, the statement cannot be used in stored procedures that are not in Transact-SQL format. In other cases, an alternative statement closer to the SQL/92 standard is recommended unless Transact-SQL compatibility is an issue.

  • [MobiLink] The statement is for use only in MobiLink clients.

  • [SQL Remote] The statement can be used only in SQL Remote.

If two sets of brackets are used, the statement can be used in both environments. For example, [ESQL][SP] means a statement can be used in both embedded SQL and stored procedures.


ALLOCATE DESCRIPTOR statement [ESQL]

toggle Description

Use this statement to allocate space for a SQL descriptor area (SQLDA).

toggle Syntax

ALLOCATE DESCRIPTOR descriptor-name
[ WITH MAX { integer | hostvar } ]

descriptor-name : string

toggle Parameters

WITH MAX clause Allows you to specify the number of variables within the descriptor area. The default size is one. You must still call fill_sqlda to allocate space for the actual data items before doing a fetch or any statement that accesses the data within a descriptor area.

toggle Usage

Allocates space for a descriptor area (SQLDA). You must declare the following in your C code prior to using this statement:

struct sqlda * descriptor_name
toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • DEALLOCATE DESCRIPTOR statement [ESQL]
  • The SQL descriptor area (SQLDA)
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Supported by Open Client/Open Server.

toggle Example

The following sample program includes an example of ALLOCATE DESCRIPTOR statement usage.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
EXEC SQL INCLUDE SQLCA;
#include <sqldef.h>
EXEC SQL BEGIN DECLARE SECTION;
int         x;
short       type;
int         numcols;
char        string[100];
a_SQL_statement_number  stmt = 0;
EXEC SQL END DECLARE SECTION;
int main(int argc, char * argv[]){
   struct sqlda *      sqlda1;
   if( !db_init( &sqlca ) ) {
      return 1;
   }
   db_string_connect( &sqlca,
   "UID=DBA;PWD=SQL;DBF=d:\\DB Files\\sample.db");
   EXEC SQL ALLOCATE DESCRIPTOR sqlda1 WITH MAX 25;
   EXEC SQL PREPARE :stmt FROM
      'SELECT * FROM employee';
   EXEC SQL DECLARE curs CURSOR FOR :stmt;
   EXEC SQL OPEN curs;
   EXEC SQL DESCRIBE :stmt into sqlda1;
   EXEC SQL GET DESCRIPTOR sqlda1 :numcols=COUNT;
   // how many columns?
   if( numcols > 25 ) {
      // reallocate if necessary
      EXEC SQL DEALLOCATE DESCRIPTOR sqlda1;
      EXEC SQL ALLOCATE DESCRIPTOR sqlda1
         WITH MAX :numcols;
      EXEC SQL DESCRIBE :stmt into sqlda1;
   }
   type = DT_STRING; // change the type to string
   EXEC SQL SET DESCRIPTOR sqlda1 VALUE 2 TYPE = :type;
   fill_sqlda( sqlda1 );
   // allocate space for the variables
   EXEC SQL FETCH ABSOLUTE 1 curs
      USING DESCRIPTOR sqlda1;
   EXEC SQL GET DESCRIPTOR sqlda1
      VALUE 2 :string = DATA;
   printf("name = %s", string );
   EXEC SQL DEALLOCATE DESCRIPTOR sqlda1;
   EXEC SQL CLOSE curs;
   EXEC SQL DROP STATEMENT :stmt;
   db_string_disconnect( &sqlca, "" );
   db_fini( &sqlca );
   return 0;
}


ALTER DATABASE statement

toggle Description

Use this statement to upgrade a database created with previous versions of the software; or to add Java or jConnect support to any database.

toggle Syntax 1

ALTER DATABASE
[ UPGRADE [ JAVA { ON | OFF | JDK { '1.1.8' | '1.3' } } ]
[ JCONNECT { ON | OFF } ]
| REMOVE JAVA ]

toggle Syntax 2

ALTER DATABASE
{ CALIBRATE [ SERVER ]
| CALIBRATE DBSPACE dbspace-name
| CALIBRATE DBSPACE TEMPORARY
| RESTORE DEFAULT CALIBRATION
}

toggle Syntax 3

ALTER DATABASE dbfile
MODIFY [ TRANSACTION ] LOG
{ { OFF | ON } { log-name | log-name MIRROR mirror-name | MIRROR mirror-name } }
[ KEY key ]

toggle Parameters

JAVA clause Controls support for Java in the upgraded database.

  • Specify JAVA ON to enable support for Java in the database by adding entries for the default Sybase runtime Java classes to the system tables. If Java in the database is already installed, but is at a lower version than the default classes, it is upgraded to the current default classes. The default classes are the JDK 1.3 classes.

  • Specify JAVA OFF to prevent the addition of Java in the database to databases that do not have already it installed. For databases that already have Java in the database installed, setting JAVA OFF does not remove Java support: the version of Java remains at the current version. If you wish to remove Java in the database, use the REMOVE JAVA clause.

  • Specify JAVA JDK '1.1.8' or JAVA JDK '1.3' to explicitly install support for the named version of the JDK. You can upgrade your database to a higher version of JDK, but you cannot downgrade.

    For JDK 1.1.8 the classes are held java\1.1\classes.zip under your SQL Anywhere directory. For JDK 1.3, they are held in java\1.3\rt.jar.

The default behavior is JAVA OFF.

If you add Java in the database, you must restart the database before it can be used.

For more information, see Introduction to Java in the Database.

Separately licensable option required
Java in the database is a separately licensable component and must be ordered before you can install it.

To order this component, see Separately-licensable components.

JCONNECT clause If you wish to use the Sybase jConnect JDBC driver to access system catalog information, you need to specify JCONNECT ON. If you wish to exclude the jConnect system objects, specify JCONNECT OFF. You can still use JDBC, as long as you do not access system catalog information. The default is to include jConnect support (JCONNECT ON).

Setting JCONNECT OFF does not remove jConnect support from a database.

REMOVE JAVA clause Removes Java in the database from a database. The operation leaves the database as if it were created with JAVA OFF. Java in the database must not be in use when the statement is issued. You must remove all Java classes from the database before executing this statement. The statement does not remove stored procedures and triggers that reference Java objects, and the presence of these objects does not trigger an error in the ALTER DATABASE statement.

toggle Usage

Syntax 1 You can use the ALTER DATABASE statement as an alternative to the Upgrade utility to upgrade a database. After using ALTER DATABASE UPGRADE, you should shut down the database. (The Upgrade utility does this for you automatically.)

Backup before upgrading
As with any software, it is recommended that you make a backup of your database before upgrading.

ALTER DATABASE can be used to upgrade databases created with earlier versions of the software. This applies to maintenance releases as well, so you can upgrade a database created with, for example, version 7.0.2 to 7.0.3 standards using the ALTER DATABASE statement in version 7.0.3 of the software.

In general, changes in databases between minor versions are limited to additional database options and minor system table changes.

When used to upgrade a database, ALTER DATABASE makes the following changes:

  • Upgrades the system tables to the current version.

  • Adds any new database options.

  • Drops and recreates all system stored procedures.

You can also use ALTER DATABASE to just add Java in the database or jConnect features if the database was created with the current version of the software.

For more information on adding Java support, see Java-enabling a database. For more information on adding jConnect support to a Version 6 database, see Installing jConnect system objects into a database.

Not all features made available
Features that require a physical reorganization of the database file are not made available by ALTER DATABASE. Such features include index enhancements and changes in data storage. To obtain the benefits of these enhancements, you must unload and reload your database.

For more information, see Rebuilding databases.

Syntax 2 You can also use ALTER DATABASE to perform recalibration of the I/O cost model used by the optimizer. This updates the Disk Transfer Time (DTT) model, which is a mathematical model of the disk I/O used by the cost model.

In normal operation, the cost model uses a built-in default DTT model. This default model was designed based on typical hardware and configuration. In rare cases when you are using specialized hardware such as non-standard disk drives, and when you are having performance problems, it may be useful to overwrite the default model with one based on your particular setup. However, it is generally recommended to leave the default in place.

When you recalibrate the I/O cost model, the server is unavailable for other use. In addition, it is essential that all other activities on the computer are idle. Recalibrating the server is an expensive operation and may take some time to complete.

When you use the CALIBRATE [SERVER] argument, all dbspaces are calibrated except for the temporary dbspace. Use CALIBRATE TEMPORARY DBSPACE to calibrate it. Use CALIBRATE DBSPACE dbspace-name to calibrate a single dbspace. Use RESTORE DEFAULT CALIBRATION to restore the default DTT model.

Syntax 3 You can use the ALTER DATABASE statement to change the transaction log and mirror names associated with a database file. These changes are the same as those made by the Transaction Log (dblog) utility. You can execute this statement while connected to the utility database or another database, depending on the setting of the -gu option. If you are changing the transaction or mirror log of an encrypted database, you must specify a key.

toggle Permissions

Must have DBA authority, and must be the only connection to the database.

For REMOVE JAVA, Java in the database must not be in use when the statement is issued.

ALTER DATABASE UPGRADE is not supported on Windows CE.

Separately licensable option required
Java in the database is a separately licensable component and must be ordered before you can install it.

To order this component, see Separately-licensable components.

toggle Side effects

Automatic commit

toggle See also
  • CREATE DATABASE statement
  • The Upgrade utility
  • CREATE STATISTICS statement
  • The Transaction Log utility
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following example upgrades a database to enable Java operations.

ALTER DATABASE UPGRADE
JAVA ON

The following example sets the transaction log filename associated with asademo.db to newdemo.log.

ALTER DATABASE 'asademo.db'
MODIFY LOG ON 'newdemo.log'


ALTER DBSPACE statement

toggle Description

Use this statement to pre-allocate space for a dbspace or for the transaction log, or when a database file is renamed or moved.

toggle Syntax

ALTER DBSPACE { dbspace-name | TRANSLOG | TEMPORARY }
{ ADD number [ PAGES | KB | MB | GB | TB ]
| RENAME filename-string }

toggle Parameters

TRANSLOG You supply the special dbspace name TRANSLOG to pre-allocate disk space for the transaction log. Pre-allocation improves performance if the transaction log is expected to grow quickly. You may want to use this feature if, for example, you are handling many binary large objects (BLOBs) such as bitmaps.

TEMPORARY You supply the special dbspace name TEMPORARY to add space to temporary dbspaces. When space is added to a temporary dbspace, the additional space materializes in the corresponding temporary file immediately. Pre-allocating space to the temporary dbspace of a database can improve performance during execution complex queries that use large work tables.

ADD clause An ALTER DBSPACE with the ADD clause pre-allocates disk space for a dbspace. It extends the corresponding database file by the specified size, in units of pages, kilobytes (KB), megabytes (MB), gigabytes (GB), or terabytes (TB). If you do not specify a unit, PAGES is the default. The page size of a database is fixed when the database is created.

If space is not pre-allocated, database files are extended by about 256K at a time for page sizes of 1K, 2K, 4K and 8K, and by about 32 pages for other page sizes, when the space is needed. Pre-allocating space can improve performance for loading large amounts of data and also serves to keep the database files more contiguous within the file system.

RENAME clause If you rename or move a database file other than the main file to a different directory or device, you can use ALTER DBSPACE with the RENAME clause to ensure that Adaptive Server Anywhere finds the new file when the database is started.

Using ALTER DBSPACE with RENAME on the main dbspace, SYSTEM, has no effect.

toggle Usage

Each database is held in one or more files. A dbspace is an additional file with a logical name associated with each database file, and used to hold more data than can be held in the main database file alone. ALTER DBSPACE modifies the main dbspace (also called the root file) or an additional dbspace. The dbspace names for a database are held in the SYSFILE system table. The main database file has a dbspace name of SYSTEM.

When a multi-file database is started, the start line or ODBC data source description tells Adaptive Server Anywhere where to find the main database file. The main database file holds the system tables. Adaptive Server Anywhere looks in these system tables to find the location of the other dbspaces, and then opens each of the other dbspaces.

toggle Permissions

Must have DBA authority. Must be the only connection to the database.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE DBSPACE statement
  • Working with databases
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following example increases the size of the SYSTEM dbspace by 200 pages:

ALTER DBSPACE system
ADD 200

The following example increases the size of the SYSTEM dbspace by 400 megabytes:

ALTER DBSPACE system
ADD 400 MB

The following example changes the filename associated with the system_2 dbspace:

ALTER DBSPACE system_2
RENAME 'e:\db\dbspace2.db'


ALTER DOMAIN statement

toggle Description

Use this statement to rename a user-defined domain or data type. You cannot rename Java types with this statement.

toggle Syntax

ALTER { DOMAIN | DATATYPE } user-type RENAME new-name

toggle Usage

When you execute this statement, the name of the user-defined domain or data type is updated in the SYSUSERTYPE system table. You cannot rename Java types with this statement.

Note
Any procedures, triggers, views, or events that refer to the user-defined domain or data type must be recreated, or else they will continue to refer to the old name.
toggle Permissions

Must have DBA authority or be the database user who created the domain.

toggle Side effects

Automatic commit.

toggle See also

CREATE DOMAIN statement

Domains

Using domains

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following example renames the Address domain to MailingAddress:

ALTER DOMAIN Address RENAME MailingAddress


ALTER EVENT statement

toggle Description

Use this statement to change the definition of an event or its associated handler for automating predefined actions. Also, to alter the definition of scheduled actions.

toggle Syntax

ALTER EVENT event-name
[ DELETE TYPE | TYPE event-type ]
{ WHERE { trigger-condition | NULL }
| { ADD | MODIFY | DELETE } SCHEDULE schedule-spec
}
[ ENABLE | DISABLE ]
[ [ MODIFY ] HANDLER compound-statement | DELETE HANDLER }

event-type :
BackupEnd | "Connect"
| ConnectFailed | DatabaseStart
| DBDiskSpace | "Disconnect"
| GlobalAutoincrement | GrowDB
| GrowLog | GrowTemp
| LogDiskSpace | "RAISERROR"
| ServerIdle | TempDiskSpace

trigger-condition :
event_condition( condition-name ) { = | < | > | != | <= | >= } value

schedule-spec :
[ schedule-name ]
{ START TIME start-time | BETWEEN start-time AND end-time }
[ EVERY period { HOURS | MINUTES | SECONDS } ]
[ ON { ( day-of-week, ... ) | ( day-of-month, ... ) } ]
[ START DATE start-date ]

event-name | schedule-name : identifier

day-of-week : string

value | period | day-of-month : integer

start-time | end-time : time

start-date : date

toggle Parameters

DELETE TYPE clause Removes an association of the event with an event type. For a description of event types, see Choosing a system event.

ADD | MODIFY | DELETE SCHEDULE clause Changes the definition of a schedule. Only one schedule can be altered in any one ALTER EVENT statement.

WHERE clause The WHERE NULL option deletes a condition.

For descriptions of most of the parameters, see CREATE EVENT statement.

toggle Usage

This statement allows you to alter an event definition created with CREATE EVENT. Possible uses include the following:

  • You can use ALTER EVENT to change an event handler during development.

  • You may want to define and test an event handler without a trigger condition or schedule during a development phase, and then add the conditions for execution using ALTER EVENT once the event handler is completed.

  • You may want to disable an event handler temporarily by disabling the event.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • BEGIN statement
  • CREATE EVENT statement


ALTER FUNCTION statement

toggle Description

Use this statement to modify a function. You must include the entire new function in the ALTER FUNCTION statement.

toggle Syntax 1

ALTER FUNCTION [ owner.]function-name
function-definition

function-definition:
CREATE FUNCTION syntax following the name

toggle Syntax 2

ALTER FUNCTION [ owner.]function-name SET HIDDEN

toggle Usage

Syntax 1 The ALTER FUNCTION statement is identical in syntax to the CREATE FUNCTION statement except for the first word. Either version of the CREATE FUNCTION statement can be altered.

Existing permissions on the function are maintained, and do not have to be reassigned. If a DROP FUNCTION and CREATE FUNCTION were carried out, execute permissions would have to be reassigned.

Syntax 2 You can use SET HIDDEN to scramble the definition of the associated function and cause it to become unreadable. The function can be unloaded and reloaded into other databases.

This setting is irreversible. If you will need the original source again, you must maintain it outside the database.

If SET HIDDEN is used, debugging using the stored procedure debugger will not show the function definition, nor will it be available through procedure profiling.

toggle Permissions

Must be the owner of the function or be DBA.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE FUNCTION statement
  • ALTER PROCEDURE statement
  • DROP statement
  • Hiding the contents of procedures, functions, triggers and views
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.


ALTER INDEX statement

toggle Description

Use this statement to rename an index or foreign key, or to change the clustered nature of the index.

toggle Syntax

ALTER { index-spec { rename-clause | cluster-clause }
| foreign-key-spec { rename-clause | cluster-clause }
| primary-key-spec cluster-clause }

index-spec :
INDEX index-name ON [ owner.]table-name

foreign-key-spec :
[ INDEX ] FOREIGN KEY role-name ON [ owner.]table-name

primary-key-spec :
[ INDEX ] PRIMARY KEY ON [ owner.]table-name

rename-clause :
RENAME [ AS | TO ] index-name

cluster-clause :
CLUSTERED | NONCLUSTERED

toggle Parameters

rename-clause Specify the new name for the index.

cluster-clause Specify whether the index should be changed to CLUSTERED or NONCLUSTERED. Only one index on a table can be clustered.

toggle Usage

The ALTER INDEX statement carries out two tasks:

  • It can be used to rename an index or foreign key.

  • It can also be used to change an index type from nonclustered to clustered, or vice versa.

    The ALTER INDEX statement can be used to change the clustering specification of the index, but does not reorganize the data. As well, only one index per table can be clustered. For more information on clustered indexes, see CREATE INDEX statement.

ALTER INDEX cannot be used to change an index on a local temporary table. An attempt to do so will result in an "Index not found" error.

toggle Permissions

Must own the table, or have REFERENCES permissions on the table, or have DBA authority.

toggle Side effects

Automatic commit. Clears the Results tab in the Results pane in Interactive SQL. Closes all cursors for the current connection.

toggle See also
  • CREATE INDEX statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement renames the index ix_prod_name on the product table to ixProductName:

ALTER INDEX ix_prod_name ON product
RENAME TO ixProductName

The following statement changes ix_prod_name to be a clustered index:

ALTER INDEX ix_prod_name ON product
CLUSTERED


ALTER PROCEDURE statement

toggle Description

Use this statement to modify a procedure, or to enable and disable a procedure for replication with Sybase Replication Server. You must include the entire new procedure in the ALTER PROCEDURE statement.

toggle Syntax 1

ALTER PROCEDURE [ owner.]procedure-name
procedure-definition

procedure-definition:
CREATE PROCEDURE syntax following the name

toggle Syntax 2

ALTER PROCEDURE [ owner.]procedure-name
REPLICATE { ON | OFF }

toggle Syntax 3

ALTER PROCEDURE [ owner.]procedure-name SET HIDDEN

toggle Usage

Syntax 1 The ALTER PROCEDURE statement is identical in syntax to the CREATE PROCEDURE statement except for the first word. Either version of the CREATE PROCEDURE statement can be altered.

Existing permissions on the procedure are maintained, and do not have to be reassigned. If a DROP PROCEDURE and CREATE PROCEDURE were carried out, execute permissions would have to be reassigned.

Syntax 2 If a procedure is to be replicated to other sites using Sybase Replication Server, you must set REPLICATE ON for the procedure.

Syntax 2 of the ALTER PROCEDURE statement has the same effect as the sp_setreplicate or sp_setrepproc 'table' Adaptive Server Enterprise system procedures.

Syntax 3 You can use SET HIDDEN to scramble the definition of the associated procedure and cause it to become unreadable. The procedure can be unloaded and reloaded into other databases.

This setting is irreversible. If you will need the original source again, you must maintain it outside the database.

If SET HIDDEN is used, debugging using the stored procedure debugger will not show the procedure definition, nor will it be available through procedure profiling.

You cannot combine Syntax 2 with Syntax 1. You cannot combine Syntax 3 with either Syntax 1 or 2.

toggle Permissions

Must be the owner of the procedure or be DBA.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE PROCEDURE statement
  • ALTER FUNCTION statement
  • DROP statement
  • Hiding the contents of procedures, functions, triggers and views
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.


ALTER PUBLICATION statement

toggle Description

Use this statement to alter a publication. In MobiLink, a publication identifies synchronized data in a Adaptive Server Anywhere remote database. In SQL Remote, publications identify replicated data in both consolidated and remote databases.

toggle Syntax

ALTER PUBLICATION [ owner.]publication-name alterpub-clause, ...

alterpub-clause:
ADD TABLE article-description
| MODIFY TABLE article-description
| { DELETE | DROP } TABLE [ owner.]table-name
| RENAME publication-name

owner, publication-name, table-name : identifier

article-description :
table-name [ ( column-name, ... ) ]
[ WHERE search-condition ]
[ SUBSCRIBE BY expression ]

toggle Usage

This statement is applicable only to MobiLink and SQL Remote.

The ALTER PUBLICATION statement alters a publication in the database. The contribution to a publication from one table is called an article. Changes can be made to a publication by adding, modifying, or deleting articles, or by renaming the publication. If an article is modified, the entire specification of the modified article must be entered.

You set options for a MobiLink publication with the ADD OPTION clause in the ALTER SYNCHRONIZATION SUBSCRIPTION statement or CREATE SYNCHRONIZATION SUBSCRIPTION statement.

toggle Permissions

Must have DBA authority, or be the owner of the publication. Requires exclusive access to all tables referred to in the statement.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE PUBLICATION statement
  • DROP PUBLICATION statement
  • ALTER SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • sp_add_article procedure
  • sp_add_article_col procedure
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Example

The following statement adds the customer table to the pub_contact publication.

ALTER PUBLICATION pub_contact
   ADD TABLE customer


ALTER REMOTE MESSAGE TYPE statement [SQL Remote]

toggle Description

Use this statement to change the publisher's message system, or the publisher's address for a given message system, for a message type that has been created.

toggle Syntax

ALTER REMOTE MESSAGE TYPE message-system
ADDRESS address

message-system: FILE | FTP | MAPI | SMTP | VIM

address: string

toggle Parameters

message-system One of the message systems supported by SQL Remote. It must be one of the following values:

address A string containing a valid address for the specified message system.

toggle Usage

The statement changes the publisher's address for a given message type.

The Message Agent sends outgoing messages from a database by one of the supported message links. The extraction utility uses this address when executing the GRANT CONSOLIDATE statement in the remote database.

The address is the publisher's address under the specified message system. If it is an e-mail system, the address string must be a valid e-mail address. If it is a file-sharing system, the address string is a subdirectory of the directory specified by the SQLREMOTE environment variable, or of the current directory if that is not set. You can override this setting on the GRANT CONSOLIDATE statement at the remote database.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE REMOTE MESSAGE TYPE statement [SQL Remote]
  • sp_remote_type procedure
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Example

The following statement changes the publisher's address for the FILE message link to new_addr.

CREATE REMOTE MESSAGE TYPE file
ADDRESS 'new_addr'


ALTER SERVER statement

toggle Description

Use this statement to modify the attributes of a remote server.

toggle Syntax

ALTER SERVER server-name
[ CLASS 'server-class' ]
[ USING 'connection-info' ]
[ CAPABILITY 'cap-name' { ON | OFF } ]
[ CONNECTION CLOSE [ CURRENT | ALL | connection-id

server-class :
ASAJDBC | ASEJDBC
| ASAODBC | ASEODBC
| DB2ODBC | MSSODBC
| ORAODBC | ODBC

connection-info :
machine-name:port-number[/dbname ] | data-source-name

toggle Parameters

CLASS clause The CLASS clause is specified to change the server class.

For more information on server classes and how to configure a server, see Server Classes for Remote Data Access.

USING clause The USING clause is specified to change the server connection information. For information about connection-info, see CREATE SERVER statement.

CAPABILITY clause The CAPABILITY clause turns a server capability ON or OFF. Server capabilities are stored in the system table syscapability. The names of these capabilities are stored in the system table syscapabilityname. The syscapability table contains no entries for a remote server until the first connection is made to that server. At the first connection, Adaptive Server Anywhere interrogates the server about its capabilities and then populates the syscapability table. For subsequent connections, the server's capabilities are obtained from this table.

In general, you do not need to alter a server's capabilities. It may be necessary to alter capabilities of a generic server of class ODBC.

CONNECTION CLOSE clause

When a user creates a connection to a remote server, the remote connection is not closed until the user disconnects from the local database. The CONNECTION CLOSE clause allows you to explicitly close connections to a remote server. You may find this useful when a remote connection becomes inactive or is no longer needed.

The following SQL statements are equivalent and close the current connection to the remote server:

ALTER SERVER server-name CONNECTION CLOSE
ALTER SERVER server-name CONNECTION CLOSE CURRENT

You can close both ODBC and JDBC connections to a remote server using this syntax. You do not need DBA authority to execute either of these statements.

You can also disconnect a specific remote ODBC connection by specifying a connection ID, or disconnect all remote ODBC connections by specifying the ALL keyword. If you attempt to close a JDBC connection by specifying the connection ID or the ALL keyword, an error occurs. When the connection identified by connection-id is not the current local connection, the user must have DBA authority to be able to close the connection.

toggle Usage

The ALTER SERVER statement modifies the attributes of a server. These changes do not take effect until the next connection to the remote server.

toggle Permissions

Must have RESOURCE authority.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE SERVER statement
  • DROP SERVER statement
  • Server Classes for Remote Data Access
  • Troubleshooting remote data access
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Open Client/Open Server.

toggle Example

The following example changes the server class of the Adaptive Server named ase_prod so its connection to Adaptive Server Anywhere is ODBC-based. Its Data Source Name is ase_prod.

ALTER SERVER ase_prod
CLASS 'ASEODBC'
USING 'ase_prod'

The following example changes a capability of server infodc.

ALTER SERVER infodc
CAPABILITY 'insert select' OFF

The following example closes all connections to the remote server named rem_test.

ALTER SERVER rem_test
CONNECTION CLOSE ALL

The following example closes the connection to the remote server named rem_test that has the connection ID 142536 .

ALTER SERVER rem_test
CONNECTION CLOSE 142536


ALTER SERVICE statement

toggle Description

Use this statement to alter a web service.

toggle Syntax 1

ALTER SERVICE service-name
[ TYPE 'DISH' ]
[ GROUP { group-name | NULL } ]
[ FORMAT { 'DNET' | 'CONCRETE' | 'XML' | NULL } ]
[ common-attributes ]

toggle Syntax 2

CREATE SERVICE service-name
[ TYPE 'SOAP' ]
[ FORMAT { 'DNET' | 'CONCRETE' | 'XML' | NULL } ]
[ common-attributes ]
[ AS statement ]

toggle Syntax 3

CREATE SERVICE service-name
[ TYPE { 'RAW' | 'HTML' | 'XML' } ]
[ URL [ PATH ] { ON | OFF | ELEMENTS } ]
[ common-attributes ]
[ AS { statement | NULL } ]

common-attributes:
[ AUTHORIZATION { ON | OFF } ]
[ SECURE { ON | OFF } ]
[ USER { user-name | NULL } ]

toggle Parameters

service-name Identifies the service being altered.

service-type-string Identifies the type of the service. The type must be one of the listed service types. There is no default value.

AUTHORIZATION clause Determines whether users must specify a user name and password through HTTP Basic Authorization when connecting to the service. If authorization is OFF, the AS clause is required and a single user must be identified by the USER clause. All requests are run using that user's account and permissions.

If authorization is ON, all users must provide a user name and password. Optionally, you may limit the users that are permitted to use the service by providing a user or group name using the USER clause. If the user name is NULL, all known users can access the service.

The default value is ON. It is recommended that production systems be run with authorization turned on and that you grant permission to use the service by adding users to a group.

SECURE clause Indicates whether unsecure connections are accepted. ON indicates that only HTTPS connections are to be accepted. Service requests received on the HTTP port are automatically redirected to the HTTPS port. If set to OFF, both HTTP and HTTPS connections are accepted. The default value is OFF.

USER clause If authorization is disabled, this parameter becomes mandatory and specifies the user id used to execute all service requests. If authorization is enabled (the default), this optional clause identifies the user or group permitted to access the service. The default value is NULL, which grants access to all users.

URL clause Determines whether URI paths are accepted and, if so, how they are processed. OFF indicates that nothing must follow the service name in a URI request. ON indicates that the remainder of the URI is interpreted as the value of a variable named URL. ELEMENTS indicates that the remainder of the URI path is to be split at the slash characters into a list of up to 10 elements. The values are assigned to variables named url plus a numeric suffix of between 1 and 10; for example, the first three variable names are url1, url2, and url3. If fewer than 10 values are supplied, the remaining variables are set to NULL. If the service name ends with the character /, then URL must be set to OFF. The default value is OFF.

GROUP clause Applies to DISH services only. Specifies a common prefix that controls which SOAP services the DISH service exposes. For example, specifying GROUP xyz exposes only SOAP services xyz/aaaa, xyz/bbbb, or xyz/cccc, but does not expose abc/aaaa or xyzaaaa. If no group name is specified, the DISH service exposes all the SOAP services in the database. SOAP services may be exposed by more than one DISH service. The same characters are permitted in group names as in service names.

FORMAT clause Applies to DISH and SOAP services only. Generates output formats compatible with various types of SOAP clients, such as .NET or Java JAX-RPC. If the format of a SOAP service is not specified, the format is inherited from the service's DISH service declaration. If the DISH service also does not declare a format, it defaults to DNET, which is compatible with .NET clients. A SOAP service that does not declare a format may be used with different types of SOAP clients by defining multiple DISH services, each having a different FORMAT type.

statement If the statement is NULL, the URI must specify the statement to be executed. Otherwise, the specified SQL statement is the only one that can be executed through the service. SOAP services must have statements; DISH services must have none. The default value is NULL.

It is strongly recommended that all services run in production systems define a statement. The statement can be NULL only if authorization is enabled.

Format types

  • DNET Microsoft DataSet format for use with .NET SOAP clients. DNET is the default FORMAT value and was the only format available before version 9.0.2.

  • CONCRETE A platform-neutral DataSet format for use with clients such as JAX-RPC, or with clients that automatically generate interfaces based on the format of the returned data structure. Specifying this format type exposes an ASADataset element within the WSDL. This element describes the result set as a containment hierarchy of a rowset composed of an array of rows, each of which contains an array of column elements.

  • XML A simple XML string format. The DataSet is returned as a string that can be passed to an XML parser. This format is the most portable between SOAP clients.

Service types

  • RAW The result set is sent to the client without any further formatting. You can produce formatted documents by generating the required tags explicitly within your procedure.

  • HTML The result set of a statement or procedure are automatically formatted into an HTML document that contains a table.

  • XML The result set is returned as XML. If the result set is already XML, no additional formatting is applied. If it is not already XML, it is automatically formatted as XML. The effect is similar to that of using the FOR XML RAW clause in a SELECT statement.

  • SOAP The result set is returned as a SOAP response. The format of the data is determined by the FORMAT clause. A request to a SOAP service must be a valid SOAP request, not just a simple HTTP request. For more information about the SOAP standards, see [external link] www.w3.org/TR/SOAP.

  • DISH A DISH service (Determine SOAP Handler) acts as a proxy for those SOAP services identified by the GROUP clause, and generates a WSDL (Web Services Description Language) file for each of these SOAP services.

toggle Usage

The alter service statement causes the database server to act as a web server.

toggle Permissions

Must have DBA authority.

toggle Side effects

None.

toggle See also
  • CREATE SERVICE statement, DROP SERVICE statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

To quickly set up a web server, start a database server with the -xs switch, then execute the following statements:

CREATE SERVICE tables TYPE 'XML'
ALTER SERVICE tables
   AUTHORIZATION OFF
   USER DBA
   AS SELECT *
      FROM SYS.SYSTABLE

After executing these statements, use any web browser to open the URL http://localhost/tables.


ALTER SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]

toggle Description

Use this statement in an Adaptive Server Anywhere remote database to alter the properties of a subscription of a MobiLink user to a publication.

toggle Syntax

ALTER SYNCHRONIZATION SUBSCRIPTION
TO publication-name
[ FOR ml_username, ... ]
[ TYPE protocol ]
[ ADDRESS protocol-options ]
[ ADD OPTION option=value, ... ]
[ MODIFY OPTION option=value, ... ]
[ DELETE { ALL OPTION | OPTION option, ... } ]

ml_username: identifier

protocol-type: http | https | https_fips |tcpip | ActiveSync

protocol-options: string

value: string | integer

toggle Parameters

TO clause Specify the name of a publication.

FOR clause Specify one or more MobiLink user names.

Omit the FOR clause to set the protocol type, protocol options, and extended options for a publication.

For information about how dbmlsync processes options that are specified in different locations, see Priority order for extended options and connection parameters.

TYPE clause This clause specifies the network protocol to use for synchronization. The default protocol is tcpip.

For more information about communication protocols, see CommunicationType (ctp) extended option.

ADDRESS clause This clause specifies network protocol options, including the location of the MobiLink synchronization server.

For a complete list of protocol options, see CommunicationAddress (adr) extended option.

ADD OPTION, MODIFY OPTION, DELETE OPTION, AND DELETE ALL OPTION clauses These clauses allow you to add, modify, delete, or delete all extended options. You may specify only one option in each clause.

The values for each option cannot contain the characters "=" or "," or ";".

For a complete list of options, see dbmlsync extended options.

toggle Usage

Use this statement to alter a synchronization subscription within a MobiLink remote or reference database.

toggle Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the publication.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE PUBLICATION statement
  • CREATE SYNCHRONIZATION USER statement [MobiLink]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Examples

Create a default subscription, which contains default subscription values, for the sales publication (by omitting the FOR clause). Indicate the address of the MobiLink synchronization server and specify that only the Certicom root certificate is to be trusted.

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   ADDRESS 'host=test.internal;port=2439;
      security=ecc_tls'
   OPTION memory='2m';

Subscribe MobiLink user ml_user1 to the sales publication. Set the memory option to 3 Mb, rather than the value specified in the default publication.

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR 'ml_user1'
   OPTION memory='3m';


ALTER SYNCHRONIZATION USER statement [MobiLink]

toggle Description

Use this statement in an Adaptive Server Anywhere remote database to alter the properties of a MobiLink user.

toggle Syntax

ALTER SYNCHRONIZATION USER ml_username
[ TYPE protocol-type ]
[ ADDRESS protocol-options ]
[ ADD OPTION option=value, ... ]
[ MODIFY OPTION option=value, ... ]
[ DELETE { ALL OPTION | OPTION option } ]

ml_username: identifier

protocol-type: http | https | https_fips | tcpip | ActiveSync

protocol-options: string

value: string | integer

toggle Parameters

TYPE clause This clause specifies the network protocol to use for synchronization.

For more information about communication protocols, see CommunicationType (ctp) extended option.

ADDRESS clause This clause specifies network protocol options, including the location of the MobiLink synchronization server.

For a complete list of protocol options, see CommunicationAddress (adr) extended option.

ADD OPTION, MODIFY OPTION, DELETE OPTION, AND DELETE ALL OPTION clauses These clauses allow you to add, modify, delete, or delete all extended options. You may specify only one option in each clause.

For a complete list of options, see dbmlsync extended options.

toggle Usage

Use this statement to alter the properties of a synchronization user within a MobiLink remote database.

toggle Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the publication.

toggle Side effects

Automatic commit.

toggle See also
  • ALTER SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • CREATE SYNCHRONIZATION USER statement [MobiLink]
  • CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.


ALTER TABLE statement

toggle Description

Use this statement to modify a table definition or to enable a table to take part in Replication Server replication.

toggle Syntax 1

ALTER TABLE [ owner.]table-name
{ add-clause | modify-clause | drop-clause | rename-clause }

add-clause :
ADD { column-definition | table-constraint }
| { ADD PCTFREE integer | PCTFREE DEFAULT }

modify-clause :
MODIFY column-definition
| MODIFY column-name { DEFAULT default-value
| [ NOT ] NULL
| [ CONSTRAINT constraint-name ]
CHECK { NULL | ( new-condition ) } }
| ALTER column-name column-modification
| ALTER constraint-name CHECK ( new-condition )

drop-clause :
{ DELETE | DROP }{
column-name
| CONSTRAINT constraint-name
| CHECK
| UNIQUE ( column-name, ... )
| PRIMARY KEY
| FOREIGN KEY role-name }

rename-clause :
RENAME new-table-name
| RENAME column-name TO new-column-name
| RENAME constraint-name TO new-constraint-name

column-definition :
column-name data-type [ [ NOT ] NULL ] [ DEFAULT default-value ] [ column-constraint ... ]

table-constraint :
[ CONSTRAINT constraint-name ] { UNIQUE ( column-name, ... )
| PRIMARY KEY [ CLUSTERED ] ( column-name, ... )
| foreign-key-constraint
| CHECK ( condition ) }

column-constraint :
[ CONSTRAINT constraint-name ] { UNIQUE
| PRIMARY KEY
| REFERENCES table-name
[ ( column-name ) ] [ actions ] [ CLUSTERED ]
| CHECK ( condition ) }
| COMPUTE ( expression )

column-modification :
SET DEFAULT default-value
| DROP DEFAULT
| ADD [ CONSTRAINT column-constraint-name ] CHECK ( condition )
| { DELETE | DROP } CONSTRAINT column-constraint-name
| { DELETE | DROP } CHECK
| SET COMPUTE ( expression )
| DROP COMPUTE

default-value :
special-value
| string
| global variable
| [ - ] number
| ( constant-expression )
| built-in-function( constant-expression )
| AUTOINCREMENT
| GLOBAL AUTOINCREMENT [ ( partition-size ) ]
| NULL
| TIMESTAMP
| UTC TIMESTAMP
| LAST USER
| USER

special-value:
CURRENT { DATABASE | DATE
| REMOTE USER | TIME
| TIMESTAMP | UTC TIMESTAMP
| USER | PUBLISHER }

foreign-key-constraint :
[ NOT NULL ] FOREIGN KEY [ role-name ] [ (column-name, ... ) ]
REFERENCES table-name [ (column-name, ... ) ] [ actions ]
[ CHECK ON COMMIT ] [ CLUSTERED ]

actions :
[ ON UPDATE action ] [ ON DELETE action ]

action :
CASCADE | SET NULL | SET DEFAULT | RESTRICT

toggle Syntax 2

ALTER TABLE [ owner.]table-name REPLICATE { ON | OFF }

toggle Parameters

add-clause Add a new column or table constraint to the table. For more information, see below.

modify-clause Change a single column definition. For more information, see below.

drop-clause Drop a column or a table constraint. For more information, see below.

rename-clause Change the name of the table, a column, or a constraint. For more information, see below.

ADD column-definition Add a new column to the table.

If the column has a default value, all rows of the new column are populated with that default value.

Adaptive Server Anywhere optimizes the creation of columns that are allowed to contain NULL. The first column allowed to contain NULL allocates room for eight such columns, and initializes all eight to be NULL. (This requires no extra storage.) Thus, the next seven columns added require no changes to the rows of the table. Adding a ninth column then allocates room for another eight such columns and modifies each row of the table to allocate the extra space.

ADD table-constraint Add a constraint to the table. See CREATE TABLE statement for a full explanation of table constraints.

If PRIMARY KEY is specified, the table must not already have a primary key that was created by the CREATE TABLE statement or another ALTER TABLE statement.

The optional constraint name allows you to modify or drop individual constraints at a later time, rather than having to modify the entire table constraint.

Table CHECK constraints fail only if a value of FALSE is returned. A value of UNKNOWN allows the change.

PCTFREE Specify the percentage of free space you want to reserve for each table page. The free space is used if rows increase in size when the data is updated. If there is no free space in a table page, every increase in the size of a row on that page requires the row to be split across multiple table pages, causing row fragmentation and possible performance degradation.

A free space percentage of 0 specifies that no free space is to be left on each page—each page is to be fully packed. A high free space percentage causes each row to be inserted into a page by itself. If PCTFREE is not set, or if DEFAULT is specified, 200 bytes are reserved in each page.

When PCTFREE is set, all subsequent inserts into table pages use the new value, but rows that were already inserted are not affected. The value persists until it is changed or the table is dropped.

The PCTFREE specification can be used for base, global temporary, or local temporary tables. Except for local temporary tables, the value for PCTFREE is stored in the SYSATTRIBUTE system table.

For more information, see SYSATTRIBUTE system table.

MODIFY column-definition Change the length or data type of an existing column in a table. If NOT NULL is specified, a NOT NULL constraint is added to the named column. Otherwise, the NOT NULL constraint for the column will not be changed. If necessary, the data in the modified column will be converted to the new data type. If a conversion error occurs, the operation will fail and the table will be left unchanged.

You cannot modify a column to make it a computed column using the MODIFY clause. Computed columns can only be added, dropped, or altered using the ADD, DELETE/DROP, or ALTER clause.

Deleting an index, constraint, or key
If the column is contained in a uniqueness constraint, a foreign key, or a primary key, then the constraint or key must be deleted before the column can be modified. If a primary key is deleted, all foreign keys referencing the table will also be deleted.

You cannot MODIFY a table or column constraint. To change a constraint, you must DELETE the old constraint and ADD the new constraint.

MODIFY column-name DEFAULT default-value Change the default value of an existing column in a table. To remove a default value for a column, specify DEFAULT NULL. Modifying a default value does not change any existing values in the table.

ALTER column-name column-modification Change the definition of a column. The permitted modifications are as follows:

  • SET DEFAULT default-value Change the default value of an existing column in a table. You can also use the MODIFY clause for this task, but ALTER is SQL/92 compliant, and MODIFY is not. Modifying a default value does not change any existing values in the table.

  • DROP DEFAULT Remove the default value of an existing column in a table. You can also use the MODIFY clause for this task, but ALTER is SQL/92 compliant, and MODIFY is not. Dropping a default does not change any existing values in the table.

  • ADD Add a named constraint or a CHECK condition to the column. The new constraint or condition applies only to operations on the table after its definition. The existing values in the table are not validated to confirm that they satisfy the new constraint or condition.

  • CONSTRAINT column-constraint-name The optional column constraint name allows you to modify or drop individual constraints at a later time, rather than having to modify the entire column constraint.

  • SET COMPUTE (expression) Change the expression associated with a computed column. The values in the column are recalculated when the statement is executed, and the statement fails if the new expression is invalid.

  • DROP COMPUTE Change a column from being a computed column to being a non-computed column. This statement does not change any existing values in the table.

MODIFY column-name [ NOT ] NULL Change the NOT NULL constraint on the column to allow or disallow NULL values in the column.

MODIFY column-name CHECK NULL Delete the check constraint for the column. This statement cannot be used on databases created before version 5.0.

MODIFY column-name CHECK (condition) Replace the existing CHECK condition for the column with the one specified. This statement cannot be used on databases created before version 5.0.

DELETE column-name Delete the column from the table. If the column is contained in any index, uniqueness constraint, foreign key, or primary key then the index, constraint, or key must be deleted before the column can be deleted. This does not delete CHECK constraints that refer to the column.

DELETE constraint-name Delete the named constraint from the table definition.

DELETE CHECK Delete all check constraints for the table. This includes both table check constraints and column check constraints.

DELETE UNIQUE (column-name, ...) Delete a uniqueness constraint for this table. Any foreign keys referencing this uniqueness constraint (rather than the primary key) will also be deleted.

DELETE PRIMARY KEY Delete the primary key constraint for this table. All foreign keys referencing the primary key for this table will also be deleted.

DELETE FOREIGN KEY role-name Delete the foreign key constraint for this table with the given role name.

RENAME new-table-name Change the name of the table to new-table-name. Note that any applications using the old table name must be modified. Foreign keys that were automatically assigned the old table name will not change names.

RENAME column-name TO new-column-name Change the name of the column to the new-column-name. Note that any applications using the old column name will need to be modified.

toggle Usage

Syntax 1 The ALTER TABLE statement changes table attributes (column definitions, constraints) in a table that was previously created. Note that the syntax allows a list of alter clauses; however, only one table-constraint or column-constraint can be added, modified or deleted in one ALTER TABLE statement. A table cannot be both added and modified in the same statement.

You cannot use ALTER TABLE on a local temporary table.

ALTER TABLE is prevented whenever the statement affects a table that is currently being used by another connection. ALTER TABLE can be time-consuming, and the server will not process requests referencing the table while the statement is being processed.

For more information on using the CLUSTERED option, see Using clustered indexes.

Before version 5.0, all table and column constraints were held in a single table constraint. Consequently, for these databases individual constraints on columns cannot be deleted using the MODIFY column-name CHECK NULL clause or replaced using the MODIFY column-name CHECK (condition ) clause. To use these statements, the entire table constraint should be deleted and the constraints added back using the MODIFY column-name CHECK (condition ) clause. At this point you can use MODIFY CHECK.

Syntax 2 When a table has REPLICATE ON, all changes to the table are sent to Replication Server for replication. The replication definitions in Replication Server are used to decide which table changes are sent to other sites. The remainder of this section describes syntax 1.

toggle Permissions

Must be one of the following:

  • The owner of the table.

  • A user with DBA authority.

  • A user granted ALTER permission on the table.

  • ALTER TABLE requires exclusive access to the table.

Global temporary tables cannot be altered unless all users that have referenced the temporary table have disconnected.

toggle Side effects

Automatic commit.

The MODIFY and DELETE (DROP) options close all cursors for the current connection.

A checkpoint is carried out at the beginning of the ALTER TABLE operation.

Once you alter a column or table, any stored procedures, views or other items that refer to the altered column no longer work.

If you change the declared length of a column, the statistics for that column are dropped.

toggle See also
  • CREATE TABLE statement
  • DROP statement
  • SQL Data Types
  • Altering tables
  • Special values
  • Using table and column constraints
  • ALLOW_NULLS_BY_DEFAULT option [compatibility]
toggle Standards and compatibility

  • SQL/92 Intermediate-level feature. MODIFY is not SQL/92 compliant.

  • SQL/99 ADD COLUMN is a core feature. Other clauses are vendor extensions or implementation of specific, named extensions to SQL/99.

  • Sybase Some clauses are supported by Adaptive Server Enterprise.

toggle Example

The following example adds a new column to the employee table showing which office they work in.

ALTER TABLE employee
ADD office CHAR(20) DEFAULT 'Boston'

The following example drops the office column from the employee table.

ALTER TABLE employee
DELETE office

The address column in the customer table can currently hold up to 35 characters. To allow it to hold up to 50 character, type the following.

ALTER TABLE customer
MODIFY address CHAR(50)

The following example adds a column to the customer table assigning each customer a sales contact.

ALTER TABLE customer
ADD sales_contact INTEGER
REFERENCES employee (emp_id)
ON UPDATE CASCADE
ON DELETE SET NULL

This foreign key is constructed with cascading updates and is set null on deletes. If an employee has their employee ID changed, the column is updated to reflect this change. If an employee leaves the company and has their employee ID deleted, the column is set to NULL.


ALTER TRIGGER statement

toggle Description

Use this statement to replace a trigger definition with a modified version.

You must include the entire new trigger definition in the ALTER TRIGGER statement.

toggle Syntax 1

ALTER TRIGGER trigger-name trigger-definition

trigger-definition :
CREATE TRIGGER syntax following the trigger name

toggle Syntax 2

ALTER TRIGGER trigger-name ON [owner.] table-name SET HIDDEN

toggle Usage

Syntax 1 The ALTER TRIGGER statement is identical in syntax to the CREATE TRIGGER statement except for the first word. For information on trigger-definition, see CREATE TRIGGER statement and CREATE TRIGGER statement [T-SQL].

Either the Transact-SQL or Watcom-SQL form of the CREATE TRIGGER syntax can be used.

Syntax 2 You can use SET HIDDEN to scramble the definition of the associated trigger and cause it to become unreadable. The trigger can be unloaded and reloaded into other databases.

This setting is irreversible. If you will need the original source again, you must maintain it outside the database.

If SET HIDDEN is used, debugging using the stored procedure debugger will not show the trigger definition, nor will it be available through procedure profiling.

toggle Permissions

Must be the owner of the table on which the trigger is defined, or be DBA, or have ALTER permissions on the table and have RESOURCE authority.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE TRIGGER statement
  • CREATE TRIGGER statement [T-SQL]
  • DROP statement
  • Hiding the contents of procedures, functions, triggers and views
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.


ALTER VIEW statement

toggle Description

Use this statement to replace a view definition with a modified version. If SET HIDDEN or RECOMPILE is used, the view definition is not specified.

toggle Syntax 1

ALTER VIEW
[ owner.]view-name [ ( column-name, ... ) ] AS select-statement
[ WITH CHECK OPTION ]

toggle Syntax 2

ALTER VIEW
[ owner.]view-name { SET HIDDEN | RECOMPILE }

toggle Usage

Syntax 1 The ALTER VIEW statement is identical in syntax to the CREATE VIEW statement except for the first word. The ALTER VIEW statement replaces the entire contents of the CREATE VIEW statement with the contents of the ALTER VIEW statement. Existing permissions on the view are maintained, and do not have to be reassigned. If a DROP VIEW followed by a CREATE VIEW is used, instead of ALTER VIEW, permissions on the view would have to be reassigned.

Syntax 2 You can use SET HIDDEN to scramble the definition of the associated view and cause it to become unreadable. The view can be unloaded and reloaded into other databases.

This setting is irreversible. If you will need the original source again, you must maintain it outside the database.

If SET HIDDEN is used, debugging using the stored procedure debugger will not show the view definition, nor will it be available through procedure profiling.

The RECOMPILE clause is used to re-create the column definitions for an existing view. If the tables a view is based on are updated, you can use RECOMPILE to update the view definition. RECOMPILE is also used by the sa_recompile_views system procedure to update view definitions when rebuilding a database.

For more information, see sa_recompile_views system procedure.

Caution If the SELECT statement defining the view contained an asterisk (*), the number of the columns in the view may change if columns have been added or deleted from the underlying tables. The names and data types of the view columns may also change.

For information on the keywords and options, see CREATE VIEW statement.

toggle Permissions

Must be owner of the view or have DBA authority.

toggle Side effects

Automatic commit.

All procedures and triggers are unloaded from memory, so that any procedure or trigger that references the view reflects the new view definition. The unloading and loading of procedures and triggers can have a performance impact if you are regularly altering views.

toggle See also
  • CREATE VIEW statement
  • DROP statement
  • Hiding the contents of procedures, functions, triggers and views
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.


ALTER WRITEFILE statement (deprecated)

toggle Description

Use this statement to change the name of the read-only database file to which a write file refers.

Deprecated statement
The use of write files is deprecated.
toggle Syntax

ALTER WRITEFILE write-file-name
REFERENCES db-file-name [ KEY key ]

write-file-name | db-file-name : string

toggle Usage

The ALTER WRITEFILE statement changes the name of the read-only database file to which the write file refers. If you move the database file from one directory to another, you can use this statement to point the write file to the new location.

The path name of the database file is relative to the database server's current directory at startup.

For information on escaping backslash characters in strings, see Strings.

toggle Permissions

The permissions required to execute this statement are set on the server command line, using the -gu option. The default setting is to require DBA authority.

You need to specify a KEY value if you want to change the writefile for a strongly encrypted database.

Not supported on Windows CE.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE WRITEFILE statement (deprecated)
  • The Write File utility (deprecated)
  • Working with write files (deprecated)
  • Using the utility database
  • DatabaseKey connection parameter [DBKEY]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement changes the existing write file c:\readwrite.wrt to point to the database file h:\readonly.db.

ALTER WRITEFILE 'c:\\readwrite.wrt'
REFERENCES 'h:\\readonly.db'


BACKUP statement

toggle Description

Use this statement to back up a database and transaction log.

toggle Syntax 1 (image backup)

BACKUP DATABASE
DIRECTORY backup-directory
[ WAIT BEFORE START ]
[ WAIT AFTER END ]
[ DBFILE ONLY ]
[ TRANSACTION LOG ONLY ]
[ TRANSACTION LOG RENAME [ MATCH ] ]
[ TRANSACTION LOG TRUNCATE ]
[ ON EXISTING ERROR ]
[ HISTORY { ON | OFF } ]

backup-directory : { string | variable }

toggle Syntax 2 (archive backup)

BACKUP DATABASE TO archive-root
[ WAIT BEFORE START ]
[ WAIT AFTER END ]
[ DBFILE ONLY ]
[ TRANSACTION LOG ONLY ]
[ TRANSACTION LOG RENAME [ MATCH ] ]
[ TRANSACTION LOG TRUNCATE ]
[ ATTENDED { ON | OFF } ]
[ WITH COMMENT comment string ]
[ HISTORY { ON | OFF } ]

archive-root : { string | variable }

comment-string : string

toggle Parameters

backup-directory The target location on disk for those files, relative to the server's current directory at startup. If the directory does not already exist, it is created. Specifying an empty string as a directory allows you to rename or truncate the log without making a copy of it first.

WAIT BEFORE START clause This clause ensures that the backup copy of the database does not contain any information required for recovery. In particular, it ensures that the rollback log for each connection is empty.

If a backup is carried out using this clause, you can start the backup copy of the database in read-only mode and validate it. By enabling validation of the backup database, you can avoid making an additional copy of the database.

WAIT AFTER END clause This clause may be used if the transaction log is being renamed or truncated. It ensures that all transactions are completed before the log is renamed or truncated. If this clause is used, the backup must wait for other connections to commit or rollback any open transactions before finishing.

DBFILE ONLY clause This clause may be used to cause backup copies of the main database file and any associated dbspaces to be made. The transaction log is not copied.

TRANSACTION LOG ONLY clause This clause may be used to cause a backup copy of the transaction log to be made. No other database files are copied.

TRANSACTION LOG RENAME [MATCH] clause This clause causes the server to rename the current transaction log at the completion of the backup. The name for the renamed copy will be of the form YYMMDDnn.log. If the MATCH keyword is omitted, the backup copy of the log will have the same name as the current transaction log for the database. If you supply the MATCH keyword, the backup copy of the transaction log is given a name of the form YYMMDDnn.log, to match the renamed copy of the current transaction log. Using the MATCH keyword enables the same statement to be executed several times without writing over old data.

TRANSACTION LOG TRUNCATE clause If this clause is used, the current transaction log is truncated and restarted at the completion of the backup.

archive-root The file name or tape drive device name for the archive file.

To back up to tape, you must specify the device name of the tape drive. For example, on Windows NT or NetWare, the first tape drive is \\.\tape0.

The backslash ( \ ) is an escape character in SQL strings, so each backslash must be doubled. For more information on escape characters and strings, see Strings.

ON EXISTING ERROR This clause applies only to image backups. By default, existing files are overwritten when you execute a BACKUP DATABASE statement. If this clause is used, an error occurs if any of the files to be created by the backup already exist.

ATTENDED The clause applies only when backing up to a tape device. ATTENDED ON (the default) indicates that someone is available to monitor the status of the tape drive and to place a new tape in the drive when needed. A message is sent to the application that issued the BACKUP statement if the tape drive requires intervention. The database server then waits for the drive to become ready. This may happen, for example, when a new tape is required.

If ATTENDED OFF is specified and a new tape is required or the drive is not ready, no message is sent, and an error is given.

Each BACKUP operation, whether image or archive, updates a history file called backup.syb.

For more information about the backup.syb file, see ASLOGDIR environment variable.

WITH COMMENT Record a comment in the archive file and in the backup history file.

HISTORY By default, each BACKUP operation appends a line to the backup.syb. You can prevent updates to the backup.syb file by specifying HISTORY OFF. You may want to prevent the file from being updated if all of the following conditions apply:

  • your backups occur frequently

  • there is no procedure to periodically archive or delete the backup.syb file

  • disk space is very limited

toggle Usage

The first syntax is an image backup and the second syntax is an archive backup.

Syntax 1 An image backup creates copies of each of the database files, in the same way as the Backup utility (dbbackup). By default, the Backup utility makes the backup on the client machine, but you can specify the -s option to create the backup on the server when using the Backup utility. In the case of the BACKUP statement, however, the backup can only be made on the server.

Optionally, only the database file(s) or transaction log can be saved. The log may also be renamed or truncated after the backup has completed.

Alternatively, you can specify an empty string as a directory to rename or truncate the log without copying it first. This is particularly useful in a replication environment where space is a concern. You can use this feature with an event handler on transaction log size to rename the log when it reaches a given size, and with the DELETE_OLD_LOGS option to delete the log when it is no longer needed.

To restore from an image backup, copy the saved files back to their original locations and reapply transaction logs as described in the chapter Backup and Data Recovery.

Syntax 2 An archive backup creates a single file holding all the required backup information. The destination can be either a file name or a tape drive device name. Archive backups to tape are not supported on versions of NetWare earlier than NetWare 5.

There can be only one backup on a given tape. The file backup.syb records the BACKUP and RESTORE operations that have been performed on a given server.

The tape is ejected at the end of the backup.

Only one archive per tape is allowed, but a single archive can span multiple tapes. To restore a database from an archive backup, use the RESTORE DATABASE statement.

If a RESTORE statement references an archive file containing only a transaction log, the statement must still specify a filename for the location of the restored database file, even if that file does not exist. For example, to restore from an archive containing only a log to the directory C:\MYNEWDB, the RESTORE statement looks like:

RESTORE DATABASE 'c:\mynewdb\my.db' FROM archive-location

toggle Permissions

Must have DBA authority.

toggle Side effects

Causes a checkpoint.

toggle See also
  • The Backup utility
  • RESTORE DATABASE statement
  • Backup and Data Recovery
  • EXECUTE IMMEDIATE statement [SP]

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not compatible with Adaptive Server Enterprise.

  • Windows CE Only the BACKUP DATABASE DIRECTORY syntax (syntax 1 above) is supported on the Windows CE platform.

toggle Example

Back up the current database and the transaction log to a file, renaming the existing transaction log. An image backup is created.

BACKUP DATABASE
DIRECTORY 'd:\\temp\\backup'
TRANSACTION LOG RENAME

The option to rename the transaction log is useful especially in replication environments, where the old transaction log is still required.

Back up the current database and transaction log to tape:

BACKUP DATABASE
TO '\\\\.\\tape0'

Rename the log without making a copy:

BACKUP DATABASE DIRECTORY''
TRANSACTION LOG ONLY
TRANSACTION LOG RENAME

Execute the BACKUP statement with a dynamically-constructed filename:

CREATE EVENT NightlyBackup
SCHEDULE
START TIME '23:00' EVERY 24 HOURS
HANDLER
BEGIN
    DECLARE dest LONG VARCHAR;
    DECLARE day_name CHAR(20);

    SET day_name = DATENAME(WEEKDAY, CURRENT DATE);
    SET dest = 'd:\\backups\\' || day_name;
            BACKUP DATABASE DIRECTORY dest
    TRANSACTION LOG RENAME;
END


BEGIN statement

toggle Description

Use this statement to group SQL statements together.

toggle Syntax

[ statement-label : ]
BEGIN [ [ NOT ] ATOMIC ]
[ local-declaration; ... ]
statement-list
[ EXCEPTION [ exception-case ... ] ]
END [ statement-label ]

local-declaration :
variable-declaration
| cursor-declaration
| exception-declaration
| temporary-table-declaration

variable-declaration :
DECLARE variable-name data-type

exception-declaration :
DECLARE exception-name EXCEPTION
FOR SQLSTATE [ VALUE ] string

exception-case :
WHEN exception-name [, ... ] THEN statement-list
| WHEN OTHERS THEN statement-list

toggle Parameters

local-declaration Immediately following the BEGIN, a compound statement can have local declarations for objects that only exist within the compound statement. A compound statement can have a local declaration for a variable, a cursor, a temporary table, or an exception. Local declarations can be referenced by any statement in that compound statement, or in any compound statement nested within it. Local declarations are not visible to other procedures that are called from within a compound statement.

statement-label If the ending statement-label is specified, it must match the beginning statement-label. The LEAVE statement can be used to resume execution at the first statement after the compound statement. The compound statement that is the body of a procedure or trigger has an implicit label that is the same as the name of the procedure or trigger.

For a complete description of compound statements and exception handling, see Using Procedures, Triggers, and Batches.

ATOMIC An atomic statement is a statement executed completely or not at all. For example, an UPDATE statement that updates thousands of rows might encounter an error after updating many rows. If the statement does not complete, all changes revert back to their original state. Similarly, if you specify that the BEGIN statement is atomic, the statement is executed either in its entirety or not at all.

toggle Usage

The body of a procedure or trigger is a compound statement. Compound statements can also be used in control statements within a procedure or trigger.

A compound statement allows one or more SQL statements to be grouped together and treated as a unit. A compound statement starts with the keyword BEGIN and ends with the keyword END.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • DECLARE CURSOR statement [ESQL] [SP]
  • DECLARE LOCAL TEMPORARY TABLE statement
  • LEAVE statement
  • SIGNAL statement
  • RESIGNAL statement
  • Using Procedures, Triggers, and Batches
  • Atomic compound statements
toggle Standards and compatibility

  • SQL/92 Persistent Stored Module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase Supported by Adaptive Server Enterprise. This does not mean that all statements inside a compound statement are supported.

    The BEGIN and END keywords are not required in Transact-SQL.

    BEGIN and END are used in Transact-SQL to group a set of statements into a single compound statement, so that control statements such as IF ... ELSE, which only affect the execution of a single SQL statement, can affect the execution of the whole group. The ATOMIC keyword is not supported by Adaptive Server Enterprise.

    In Transact-SQL. DECLARE statements need not immediately follow a BEGIN keyword, and the cursor or variable that is declared exists for the duration of the compound statement. You should declare variables at the beginning of the compound statement for compatibility.

toggle Example

The body of a procedure or trigger is a compound statement.

CREATE PROCEDURE TopCustomer (OUT TopCompany CHAR(35), OUT TopValue INT)
BEGIN
   DECLARE err_notfound EXCEPTION FOR
      SQLSTATE '02000';
   DECLARE curThisCust CURSOR FOR
      SELECT company_name, CAST(
            sum(sales_order_items.quantity *
            product.unit_price) AS INTEGER) VALUE
      FROM customer
            LEFT OUTER JOIN sales_order
            LEFT OUTER JOIN sales_order_items
            LEFT OUTER JOIN product
      GROUP BY company_name;
   DECLARE ThisValue INT;
   DECLARE ThisCompany CHAR(35);
   SET TopValue = 0;
   OPEN curThisCust;
   CustomerLoop:
   LOOP
      FETCH NEXT curThisCust
         INTO ThisCompany, ThisValue;
      IF SQLSTATE = err_notfound THEN
         LEAVE CustomerLoop;
      END IF;
      IF ThisValue > TopValue THEN
         SET TopValue = ThisValue;
         SET TopCompany = ThisCompany;
      END IF;
   END LOOP CustomerLoop;
   CLOSE curThisCust;
END


BEGIN TRANSACTION statement

toggle Description

Use this statement to begin a user-defined transaction.

toggle Syntax

BEGIN TRAN[SACTION] [ transaction-name ]

toggle Usage

The optional parameter transaction-name is the name assigned to this transaction. It must be a valid identifier. Use transaction names only on the outermost pair of nested BEGIN/COMMIT or BEGIN/ROLLBACK statements.

When executed inside a transaction, the BEGIN TRANSACTION statement increases the nesting level of transactions by one. The nesting level is decreased by a COMMIT statement. When transactions are nested, only the outermost COMMIT makes the changes to the database permanent.

Both Adaptive Server Enterprise and Adaptive Server Anywhere have two transaction modes.

The default Adaptive Server Enterprise transaction mode, called unchained mode, commits each statement individually, unless an explicit BEGIN TRANSACTION statement is executed to start a transaction. In contrast, the ISO SQL/92 compatible chained mode only commits a transaction when an explicit COMMIT is executed or when a statement that carries out an autocommit (such as data definition statements) is executed.

You can control the mode by setting the CHAINED database option. The default setting for ODBC and embedded SQL connections in Adaptive Server Anywhere is ON, in which case Adaptive Server Anywhere runs in chained mode. (ODBC users should also check the AutoCommit ODBC setting). The default for TDS connections is OFF.

In unchained mode, a transaction is implicitly started before any data retrieval or modification statement. These statements include: DELETE, INSERT, OPEN, FETCH, SELECT, and UPDATE. You must still explicitly end the transaction with a COMMIT or ROLLBACK statement.

You cannot alter the CHAINED option within a transaction.

Caution When calling a stored procedure, you should ensure that it operates correctly under the required transaction mode.

For more information, see CHAINED option [compatibility].

The current nesting level is held in the global variable @@trancount. The @@trancount variable has a value of zero before the first BEGIN TRANSACTION statement is executed, and only a COMMIT executed when @@trancount is equal to one makes changes to the database permanent.

A ROLLBACK statement without a transaction or savepoint name always rolls back statements to the outermost BEGIN TRANSACTION (explicit or implicit) statement, and cancels the entire transaction.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • COMMIT statement
  • ISOLATION_LEVEL option [compatibility]
  • ROLLBACK statement
  • SAVEPOINT statement
  • Savepoints within transactions
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Example

The following batch reports successive values of @@trancount as 0, 1, 2, 1, and 0. The values are printed on the server window.

PRINT @@trancount
BEGIN TRANSACTION
PRINT @@trancount
BEGIN TRANSACTION
PRINT @@trancount
COMMIT
PRINT @@trancount
COMMIT
PRINT @@trancount

You should not rely on the value of@@trancount for more than keeping track of the number of explicit BEGIN TRANSACTION statements that have been issued.

When Adaptive Server Enterprise starts a transaction implicitly, the @@trancount variable is set to 1. Adaptive Server Anywhere does not set the @@trancount value to 1 when a transaction is started implicitly. Consequently, the Adaptive Server Anywhere @@trancount variable has a value of zero before any BEGIN TRANSACTION statement (even though there is a current transaction), while in Adaptive Server Enterprise (in chained mode) it has a value of 1.

For transactions starting with a BEGIN TRANSACTION statement, @@trancount has a value of 1 in both Adaptive Server Anywhere and Adaptive Server Enterprise after the first BEGIN TRANSACTION statement. If a transaction is implicitly started with a different statement, and a BEGIN TRANSACTION statement is then executed, @@trancount has a value of 2 in both Adaptive Server Anywhere, and Adaptive Server Enterprise after the BEGIN TRANSACTION statement.


CALL statement

toggle Description

Use this statement to invoke a procedure.

toggle Syntax 1

[variable = ] CALL procedure-name ( [ expression, ... ] )

toggle Syntax 2

[variable = ] CALL procedure-name ( [ parameter-name = expression, ... ] )

toggle Usage

The CALL statement invokes a procedure that has been previously created with a CREATE PROCEDURE statement. When the procedure completes, any INOUT or OUT parameter values will be copied back.

The argument list can be specified by position or by using keyword format. By position, the arguments will match up with the corresponding parameter in the parameter list for the procedure. By keyword, the arguments are matched up with the named parameters.

Procedure arguments can be assigned default values in the CREATE PROCEDURE statement, and missing parameters are assigned the default value or. If no default is set, and an argument is not provided, an error is given.

Inside a procedure, a CALL statement can be used in a DECLARE statement when the procedure returns result sets (see Returning results from procedures).

Procedures can return an integer value (as a status indicator, say) using the RETURN statement. You can save this return value in a variable using the equality sign as an assignment operator:

CREATE VARIABLE returnval INT;
returnval = CALL proc_integer ( arg1 = val1, ... )

For information on returning non-integer values, see CREATE FUNCTION statement.

toggle Permissions

Must be the owner of the procedure, have EXECUTE permission for the procedure, or have DBA authority.

toggle Side effects

None.

toggle See also
  • CREATE PROCEDURE statement
  • GRANT statement
  • EXECUTE statement [T-SQL]
  • Using Procedures, Triggers, and Batches
toggle Standards and compatibility

  • SQL/92 Persistent Stored Module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase Not supported by Adaptive Server Enterprise. For an alternative that is supported, see EXECUTE statement [T-SQL].

toggle Example

Call the sp_customer_list procedure. This procedure has no parameters, and returns a result set.

CALL sp_customer_list()

The following Interactive SQL example creates a procedure to return the number of orders placed by the customer whose ID is supplied, creates a variable to hold the result, calls the procedure, and displays the result.

CREATE PROCEDURE OrderCount (IN customer_ID INT, OUT Orders INT)
BEGIN
   SELECT COUNT("DBA".sales_order.id)
   INTO Orders
   FROM "DBA".customer
   KEY LEFT OUTER JOIN "DBA".sales_order
   WHERE "DBA".customer.id = customer_ID;
END
go
 -- Create a variable to hold the result
CREATE VARIABLE Orders INT
go
-- Call the procedure, FOR customer 101
CALL OrderCount ( 101, Orders)
go
--  Display the result
SELECT Orders FROM DUMMY
go


CASE statement

toggle Description

Use this statement to select an execution path based on multiple cases.

toggle Syntax 1

CASE value-expression
WHEN [ constant | NULL ] THEN statement-list ...
[ WHEN [ constant | NULL ] THEN statement-list ] ...
[ ELSE statement-list ]
END CASE

toggle Syntax 2

CASE
WHEN [ search-condition | NULL] THEN statement-list ...
[ WHEN [ search-condition | NULL] THEN statement-list ] ...
[ ELSE statement-list ]
END CASE

toggle Usage

Syntax 1 The CASE statement is a control statement that allows you to choose a list of SQL statements to execute based on the value of an expression. The value-expression is an expression that takes on a single value, which may be a string, a number, a date, or other SQL data type. If a WHEN clause exists for the value of value-expression, the statement-list in the WHEN clause is executed. If no appropriate WHEN clause exists, and an ELSE clause exists, the statement-list in the ELSE clause is executed. Execution resumes at the first statement after the END CASE.

If the value-expression can be null, use the ISNULL function to replace the NULL value-expression with a different expression.

For more information about the ISNULL function, see ISNULL function [Data type conversion].

Syntax 2 With this form, the statements are executed for the first satisfied search-condition in the CASE statement. The ELSE clause is executed if none of the search-conditions are met.

If the expression can be NULL, use the following syntax for the first search-condition:

WHEN search-condition IS NULL THEN statement-list

For more information about NULL values, see Unknown Values: NULL.

CASE statement is different from CASE expression
Do not confuse the syntax of the CASE statement with that of the CASE expression.

For information on the CASE expression, see CASE expressions.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • BEGIN statement
  • Using Procedures, Triggers, and Batches
toggle Standards and compatibility

  • SQL/92 Persistent Stored Module feature. Adaptive Server Anywhere supports the CASE statement allowing WHEN NULL. This is a vendor extension to the SQL/92 standard.

  • SQL/99 Persistent Stored Module feature. Adaptive Server Anywhere supports the CASE statement allowing WHEN NULL. This is a vendor extension to the SQL/92 standard.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following procedure using a case statement classifies the products listed in the product table of the sample database into one of shirt, hat, shorts, or unknown.

CREATE PROCEDURE ProductType (IN product_id INT, OUT type CHAR(10))
BEGIN
   DECLARE prod_name CHAR(20);
   SELECT name INTO prod_name FROM "DBA"."product"
   WHERE id = product_id;
   CASE prod_name
   WHEN 'Tee Shirt' THEN
      SET type = 'Shirt'
   WHEN 'Sweatshirt' THEN
      SET type = 'Shirt'
   WHEN 'Baseball Cap' THEN
      SET type = 'Hat'
   WHEN 'Visor' THEN
      SET type = 'Hat'
   WHEN 'Shorts' THEN
      SET type = 'Shorts'
   ELSE
      SET type = 'UNKNOWN'
   END CASE;
END

The following example uses Syntax 2 to generate a message about product quantity within the sample database.

CREATE PROCEDURE StockLevel (IN product_id INT)
BEGIN
   DECLARE qty INT;
   SELECT quantity INTO qty FROM product
   WHERE id = product_id;
   CASE
   WHEN qty < 30 THEN
      MESSAGE 'Order Stock' TO CLIENT;
   WHEN qty > 100 THEN
      MESSAGE 'Overstocked' TO CLIENT;
   ELSE
      MESSAGE 'Sufficient stock on hand' TO CLIENT;
   END CASE;
END


CHECKPOINT statement

toggle Description

Use this statement to checkpoint the database.

toggle Syntax

CHECKPOINT

toggle Usage

The CHECKPOINT statement forces the database server to execute a checkpoint. Checkpoints are also performed automatically by the database server according to an internal algorithm. It is not normally required for applications issue the CHECKPOINT statement.

For a full description of checkpoints, see Backup and Data Recovery.

toggle Permissions

DBA authority is required to checkpoint the network database server.

No permissions are required to checkpoint the personal database server.

toggle Side effects

None.

toggle See also
  • CHECKPOINT_TIME option [database]
  • RECOVERY_TIME option [database]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Adaptive Server Enterprise.


CLEAR statement [Interactive SQL]

toggle Description

Use this statement to clear the Interactive SQL panes.

toggle Syntax

CLEAR

toggle Usage

The CLEAR statement is used to clear the SQL Statements pane, the Messages pane and the Results, Messages, Plan, and UltraLite Plan tabs in the Results pane.

toggle Permissions

None.

toggle Side effects

Closes the cursor associated with the data being cleared.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable


CLOSE statement [ESQL] [SP]

toggle Description

Use this statement to close a cursor.

toggle Syntax

CLOSE cursor-name

cursor-name : identifier | hostvar

toggle Usage

This statement closes the named cursor.

toggle Permissions

The cursor must have been previously opened.

toggle Side effects

None.

toggle See also
  • OPEN statement [ESQL] [SP]
  • DECLARE CURSOR statement [ESQL] [SP]
  • PREPARE statement [ESQL]
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Example

The following examples close cursors in embedded SQL.

EXEC SQL CLOSE employee_cursor;
EXEC SQL CLOSE :cursor_var;

The following procedure uses a cursor.

CREATE PROCEDURE TopCustomer (OUT TopCompany CHAR(35), OUT TopValue INT)
BEGIN
   DECLARE err_notfound EXCEPTION
      FOR SQLSTATE '02000';
   DECLARE curThisCust CURSOR FOR
   SELECT company_name, CAST(    sum(sales_order_items.quantity *
   product.unit_price) AS INTEGER) VALUE
   FROM customer
   LEFT OUTER JOIN sales_order
   LEFT OUTER JOIN sales_order_items
   LEFT OUTER JOIN product
   GROUP BY company_name;
   DECLARE ThisValue INT;
   DECLARE ThisCompany CHAR(35);
   SET TopValue = 0;
   OPEN curThisCust;
   CustomerLoop:
   LOOP
      FETCH NEXT curThisCust
      INTO ThisCompany, ThisValue;
         IF SQLSTATE = err_notfound THEN
            LEAVE CustomerLoop;
         END IF;
         IF ThisValue > TopValue THEN
            SET TopValue = ThisValue;
            SET TopCompany = ThisCompany;
         END IF;
      END LOOP CustomerLoop;
   CLOSE curThisCust;
END


COMMENT statement

toggle Description

Use this statement to store a comment in the system tables for a database object.

toggle Syntax

COMMENT ON
{
COLUMN [ owner.]table-name.column-name
| EVENT event-name
| FOREIGN KEY [ owner.]table-name.role-name
| INDEX [ [ owner.] table.]index-name
| JAVA CLASS java-class-name
| JAVA JAR java-jar-name
| LOGIN integrated_login_id
| PROCEDURE [ owner.]procedure-name
| SERVICE web-service-name
| TABLE [ owner.]table-name
| TRIGGER [ [ owner.]tablename.]trigger-name
| USER userid
| VIEW [ owner.]view-name
}
IS comment

comment : string | NULL

toggle Usage

Several system tables have a column named Remarks that allows you to associate a comment with a database item (SYSUSERPERM, SYSTABLE, SYSCOLUMN, SYSINDEX, SYSLOGIN, SYSFOREIGNKEY, SYSPROCEDURE, SYSTRIGGER). The COMMENT ON statement allows you to set the Remarks column in these system tables. A comment can be removed by setting it to NULL.

For a comment on an index or trigger, the owner of the comment is the owner of the table on which the index or trigger is defined.

toggle Permissions

Must either be the owner of the database object being commented, or have DBA authority.

toggle Side effects

Automatic commit.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following examples show how to add and remove a comment.

Add a comment to the employee table.

COMMENT
ON TABLE employee
IS 'Employee information'

Remove the comment from the employee table.

COMMENT
ON TABLE employee
IS NULL


COMMIT statement

toggle Description

Use this statement to make changes to the database permanent, or to terminate a user-defined transaction.

toggle Syntax 1

COMMIT [ WORK ]

toggle Syntax 2

COMMIT TRAN[SACTION] [ transaction-name ]

toggle Parameters

transaction-name An optional name assigned to this transaction. It must be a valid identifier. You should use transaction names only on the outermost pair of nested BEGIN/COMMIT or BEGIN/ROLLBACK statements.

For more information on transaction nesting in Adaptive Server Enterprise and Adaptive Server Anywhere, see BEGIN TRANSACTION statement. For more information on savepoints, see SAVEPOINT statement.

You can use a set of options to control the detailed behavior of the COMMIT statement. For information, see COOPERATIVE_COMMIT_TIMEOUT option [database], COOPERATIVE_COMMITS option [database], DELAYED_COMMITS option [database], and DELAYED_COMMIT_TIMEOUT option [database]. You can use the Commit connection property to return the number of Commits on the current connection.

toggle Usage

Syntax 1 The COMMIT statement ends a transaction and makes all changes made during this transaction permanent in the database.

Data definition statements all carry out a commit automatically. For information, see the Side effects listing for each SQL statement.

The COMMIT statement fails if the database server detects any invalid foreign keys. This makes it impossible to end a transaction with any invalid foreign keys. Usually, foreign key integrity is checked on each data manipulation operation. However, if the database option WAIT_FOR_COMMIT is set ON or a particular foreign key was defined with a CHECK ON COMMIT clause, the database server delays integrity checking until the COMMIT statement is executed.

Syntax 2 You can use BEGIN TRANSACTION and COMMIT TRANSACTION statements in pairs to construct nested transactions. Nested transactions are similar to savepoints. When executed as the outermost of a set of nested transactions, the statement makes changes to the database permanent. When executed inside a transaction, the COMMIT TRANSACTION statement decreases the nesting level of transactions by one. When transactions are nested, only the outermost COMMIT makes the changes to the database permanent.

toggle Permissions

None.

toggle Side effects

Closes all cursors except those opened WITH HOLD.

Deletes all rows of declared temporary tables on this connection, unless they were declared using ON COMMIT PRESERVE ROWS..

toggle See also
  • BEGIN TRANSACTION statement
  • PREPARE TO COMMIT statement
  • ROLLBACK statement
toggle Standards and compatibility

  • SQL/92 Syntax 1 is an entry-level feature. Syntax 2 is a Transact-SQL extension.

  • SQL/99 Syntax 1 is a core feature. Syntax 2 is a Transact-SQL extension.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Example

The following statement commits the current transaction:

COMMIT

The following Transact-SQL batch reports successive values of @@trancount as 0, 1, 2, 1, 0.

PRINT @@trancount
BEGIN TRANSACTION
PRINT @@trancount
BEGIN TRANSACTION
PRINT @@trancount
COMMIT TRANSACTION
PRINT @@trancount
COMMIT TRANSACTION
PRINT @@trancount
go


CONFIGURE statement [Interactive SQL]

toggle Description

Use this statement to open the Interactive SQL Options dialog.

toggle Syntax

CONFIGURE

toggle Usage

The CONFIGURE statement opens the Interactive SQL Options dialog. This window displays the current settings of all Interactive SQL options. It does not display or allow you to modify database options.

You can configure Interactive SQL settings in this dialog. If you select Make Permanent, the options are saved and will be used in subsequent Interactive SQL sessions. If you do not choose Make Permanent, and instead click OK, the options are set temporarily and remain in effect for the current database connection only.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • SET OPTION statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.


CONNECT statement [ESQL] [Interactive SQL]

toggle Description

Use this statement to establish a connection to a database.

toggle Syntax 1

CONNECT
[ TO engine-name ]
[ DATABASE database-name ]
[ AS connection-name ]
[ USER ] userid IDENTIFIED BY password

engine-name, database-name, connection-name, userid, password :
{ identifier | string | hostvar }

toggle Syntax 2

CONNECT USING connect-string

connect-string : { identifier | string | hostvar }

toggle Parameters

AS clause A connection can optionally be named by specifying the AS clause. This allows multiple connections to the same database, or multiple connections to the same or different database servers, all simultaneously. Each connection has its own associated transaction. You may even get locking conflicts between your transactions if, for example, you try to modify the same record in the same database from two different connections.

Syntax 2 A connect-string is a list of parameter settings of the form keyword=value, separated by semicolons, and must be enclosed in single quotes.

For more information on connection strings, see Connection parameters.

toggle Usage

The CONNECT statement establishes a connection to the database identified by database-name running on the server identified by engine-name.

Embedded SQL behavior In Embedded SQL, if no engine-name is specified, the default local database server will be assumed (the first database server started). If no database-name is specified, the first database on the given server will be assumed.

The WHENEVER statement, SET SQLCA and some DECLARE statements do not generate code and thus may appear before the CONNECT statement in the source file. Otherwise, no statements are allowed until a successful CONNECT statement has been executed.

The user ID and password are used for permission checks on all dynamic SQL statements.

You can connect without explicitly specifying a password by using a host variable for the password and setting the value of the host variable to be the null pointer.

If you are connected to a user ID with DBA authority, you can connect to another user ID without specifying a password. (The output of dbtran requires this capability.)

For a detailed description of the connection algorithm, see Troubleshooting connections.

Note
For Adaptive Server Anywhere, only Syntax 1 is valid with embedded SQL. For UltraLite, both Syntax 1 and Syntax 2 can be used with embedded SQL.

Interactive SQL behavior If no database or server is specified in the CONNECT statement, Interactive SQL remains connected to the current database, rather than to the default server and database. If a database name is specified without a server name, Interactive SQL attempts to connect to the specified database on the current server. If a server name is specified without a database name, Interactive SQL connects to the default database on the specified server.

For example, if the following batch is executed while connected to a database, the two tables are created in the same database.

CREATE TABLE t1( c1 int );
CONNECT DBA IDENTIFIED BY SQL;
CREATE TABLE t2 (c1 int );

No other database statements are allowed until a successful CONNECT statement has been executed.

In the user interface, if the password or the user ID and password are not specified, the user is prompted to type the missing information.

When Interactive SQL is running in command-prompt mode (-nogui is specified when you start Interactive SQL from a command prompt) or batch mode, or if you execute CONNECT without an AS clause, an unnamed connection is opened. If there is another unnamed connection already opened, the old one is automatically closed. Otherwise, existing connections are not closed when you run CONNECT.

Multiple connections are managed through the concept of a current connection. After a successful connect statement, the new connection becomes the current one. To switch to a different connection, use the SET CONNECTION statement. The DISCONNECT statement is used to drop connections.

In Interactive SQL, the connection information (including the database name, your user ID, and the database server) appears in the title bar above the SQL Statements pane. If you are not connected to a database, Not Connected appears in the title bar.

Note
Both Syntax 1 and Syntax 2 are valid with Interactive SQL.
toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • GRANT statement
  • DISCONNECT statement [ESQL] [Interactive SQL]
  • SET CONNECTION statement [Interactive SQL] [ESQL]
  • SETUSER statement
  • Connection parameters
toggle Standards and compatibility

  • SQL/92 Syntax 1 is a full SQL feature. Syntax 2 is a vendor extension.

  • SQL/99 Syntax 1 is a SQL/foundation feature outside of core SQL. Syntax 2 is a vendor extension.

  • Sybase Open Client Embedded SQL supports a different syntax for the CONNECT statement.

toggle Examples

The following are examples of CONNECT usage within Embedded SQL.

EXEC SQL CONNECT AS :conn_name
USER :userid IDENTIFIED BY :password;
EXEC SQL CONNECT USER "DBA" IDENTIFIED BY "SQL";

The following examples assume that the sample database (asademo.db) has already been started.

Connect to a database from Interactive SQL. Interactive SQL prompts for a user ID and a password.

CONNECT

Connect to the default database as DBA from Interactive SQL. Interactive SQL prompts for a password.

CONNECT USER "DBA"

Connect to the sample database as the DBA from Interactive SQL.

CONNECT
TO asademo
USER DBA
IDENTIFIED BY SQL

Connect to the sample database using a connect string, from Interactive SQL.

CONNECT
USING 'UID=DBA;PWD=SQL;DBN=asademo'

Once you connect to the sample database, the database name, your user ID, and the server name appear on the title bar: asademo (DBA) on asademo9.


CREATE COMPRESSED DATABASE statement (deprecated)

toggle Description

Use this statement to create a compressed database from an existing database file, or to expand a compressed database.

Deprecated statement
The use of compressed databases is deprecated.
toggle Syntax

CREATE [ COMPRESSED | EXPANDED ] DATABASE new-db-file-name
FROM old-db-file-name [ KEY key ]

toggle Usage

Creates a compressed database file from an uncompressed database file, or an uncompressed database file from a compressed one.

Any relative path is resolved relative to the current working directory of the server.

You cannot use this statement on files other than the main database file.

Caution Compressing an encrypted database removes encryption from the database.
toggle Permissions

  • The permissions required to execute this statement are set on the server command line, using the -gu option. The default setting is to require DBA authority.

  • The operating system account under which the server is running must have write permissions on the directories where files are created.

  • The old database file must not be currently running.

  • Not supported on Windows CE.

  • You must specify a key if you want to create a compressed database for a strongly encrypted database.

toggle Side effects

An operating system file is created.

toggle See also
  • The Compression utility (deprecated)
  • The Uncompression utility (deprecated)
  • DatabaseKey connection parameter [DBKEY]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement creates a compressed database file named compress.db in the C:\ directory from a database file named full.db in the current working directory of the server.

CREATE COMPRESSED DATABASE 'C:\\compress.db'
FROM 'full.db'

The following statement creates an uncompressed database file named full.db in the C:\ directory from a compressed database file named compress.db in the current working directory of the server.

CREATE EXPANDED DATABASE 'C:\\full.db'
FROM 'compress.db'


CREATE DATABASE statement

toggle Description

Use this statement to create a database. The database is stored as an operating system file.

toggle Syntax

CREATE DATABASE db-file-name
[ [ TRANSACTION ] { LOG OFF | LOG ON } [ log-file-name-string ]
[ MIRROR mirror-file-name-string ] ]
[ CASE { RESPECT | IGNORE } ]
[ PAGE SIZE page-size ]
[ COLLATION collation-label ]
[ ENCRYPTED { ON | OFF | key-spec } ]
[ BLANK PADDING { ON | OFF } ]
[ ASE [ COMPATIBLE ] ]
[ JAVA { ON | OFF | JDK { '1.1.8' | '1.3' } } ]
[ JCONNECT { ON | OFF } ]
[ PASSWORD CASE { RESPECT | IGNORE } ]
[ CHECKSUM { ON | OFF } ]
]

page-size :
1024 | 2048 | 4096 | 8192 | 16384 | 32768

collation-label : string

key-spec:
[ ON ] KEY key [ ALGORITHM { 'AES' | 'AES_FIPS' } ]

toggle Parameters

File name The file names ( db-file-name-string, log-file-name-string, mirror-file-name-string) are strings containing operating system file names. As literal strings, they must be enclosed in single quotes.

  • If you specify a path, any backslash characters (\) must be doubled if they are followed by an n or an x. Escaping them prevents them being interpreted as new line characters (\n) or as hexadecimal numbers (\x), according to the rules for strings in SQL.

    It is safer to always escape the backslash character. For example,

    CREATE DATABASE 'c:\\sybase\\my_db.db'
LOG ON 'e:\\logdrive\\my_db.log'

  • If you specify no path, or a relative path, the database file is created relative to the working directory of the server. If you specify no path for a log file, the file is created in the same directory as the database file.

  • If you provide no file extension, a file is created with extension .db for databases, .log for the transaction log, or .mlg for the mirror log.

TRANSACTION LOG clause The transaction log is a file where the database server logs all changes made to the database. The transaction log plays a key role in backup and recovery (see The transaction log), and in data replication.

MIRROR clause A transaction log mirror is an identical copy of a transaction log, usually maintained on a separate device, for greater protection of your data. By default, Adaptive Server Anywhere does not use a mirrored transaction log. If you do wish to use a transaction log mirror, this option allows you to provide a filename.

CASE clause For databases created with CASE RESPECT, all values are case sensitive in comparisons and string operations.

This option is provided for compatibility with the ISO/ANSI SQL standard. The default value for the option is CASE IGNORE; that is, all comparisons are case insensitive. User IDs and other identifiers in the database are case insensitive, even in case sensitive databases.

PAGE SIZE clause The page size for a database can be 1024, 2048, 4096, 8192, 16384, or 32768 bytes. The default page size is 2048 bytes. Large databases generally obtain performance benefits from a larger page size, but there can be additional overhead associated with large page sizes.

For more information, see Information utility options.

For example,

CREATE DATABASE 'c:\\sybase\\my_db.db'
PAGE SIZE 4096
Page size limit
The page size cannot be larger than the page size used by the current server. The server page size is taken from the first set of databases started or is set on the server command line using the -gp option.

COLLATION clause The collation sequence used for all string comparisons in the database.

If you want to create a custom collation, use the Collation utility to create a file containing the collation. Once you have modified the collation and inserted it into the appropriate scripts, you can create the database and specify the new collation. You must change the collation label in the custom collation file. Otherwise, the you will not be able to create a database using the new collation since it conflicts with an existing collation.

For more information on custom collation sequences, see International Languages and Character Sets.

For information on the Collation utility, see The Collation utility.

If you do not specify a collation, the default collation is used. Normal ASCII (binary) ordering is used for the lower 128 characters, subject to the case sensitivity setting (-c). For the upper 128 characters (also called the extended characters), any character that is an accented form of a letter in the lower 128 are sorted to the same position as the unaccented form. The determination of whether or not an extended character is an accented letter is based upon code page 850 (multilingual code page)

For a list of the available collating sequence labels, see Understanding collations.

ENCRYPTED clause Encryption makes the data stored in your physical database file unreadable. There are two levels of encryption:

Simple encryption is equivalent to obfuscation. The data is unreadable, but someone with cryptographic expertise could decipher the data. Simple encryption is achieved by specifying the ENCRYPTED clause with no KEY clause.

Strong encryption is achieved through the use of a 128-bit AES algorithm and a security key. The data is unreadable and virtually undecipherable without the key. To create a strongly encrypted database, specify the ENCRYPTED clause with the KEY option. As with most passwords, it is best to choose a KEY value that cannot be easily guessed. It is recommended that you choose a value for your KEY that is at least 16 characters long, contains a mix of upper and lower case, and includes numbers, letters, and special characters.

Caution Protect your key! Be sure to store a copy of your key in a safe location. A lost key will result in a completely inaccessible database, from which there is no recovery.

You will require this key each time you want to start the database.

The following are invalid for database encryption keys:

  • keys that begin with white space or single or double quotes

  • keys that end with white space

  • keys that contain semicolons

The ALGORITHM clause allows you to choose AES (the default) or AES_FIPS for the FIPS-approved algorithm. On Windows CE, only the AES algorithm is supported.

For more information about strong database encryption, see Strong encryption.

BLANK PADDING clause If you specify BLANK PADDING ON, trailing blanks are ignored in comparisons. For example, the two strings

'Smith'
'Smith   '

would be treated as equal in a database created with BLANK PADDING ON.

This option is provided for compatibility with the ISO/ANSI SQL standard, which is to ignore trailing blanks in comparisons. The default is that blanks are significant for comparisons (BLANK PADDING OFF).

ASE COMPATIBLE clause Do not create the SYS.SYSCOLUMNS and SYS.SYSINDEXES views. By default, these views are created for compatibility with system tables available in Watcom SQL (versions 4 and earlier of this software). These views conflict with the Sybase Adaptive Server Enterprise compatibility views dbo.syscolumns and dbo.sysindexes.

JCONNECT clause If you wish to use the Sybase jConnect JDBC driver to access system catalog information, you need to install jConnect support. Specify JCONNECT OFF if you wish to exclude the jConnect system objects. You can still use JDBC, as long as you do not access system information.

JAVA clause The default behavior is JAVA OFF.

To use Java in the database, you must install entries for the Sybase runtime Java classes into the system tables. Specifying JAVA JDK '1.1.8'or JAVA JDK '1.3' explicitly installs entries for the named version of the JDK. For JDK 1.1.8 the classes are held java\1.1\classes.zip under your SQL Anywhere directory. For JDK 1.3, they are held in java\1.3\rt.jar. The default classes are the JDK 1.3 classes.

Separately licensable option required
Java in the database is a separately licensable component and must be ordered before you can install it.

To order this component, see Separately-licensable components.

PASSWORD CASE clause You can specify whether passwords are case sensitive in the database. The case sensitivity of passwords does not have to be the same as the database's case sensitivity setting for string comparisons. If you do not specify the case sensitivity of passwords, passwords follow the case sensitivity of the database. Extended characters used in passwords are case sensitive, regardless of the password case sensitivity setting.

CHECKSUM clause Checksums are used to determine whether a database page has been modified on disk. When you create a database with checksums enabled, a checksum is calculated for each page just before it is written to disk. The next time the page is read from disk, the page's checksum is recalculated and compared to the checksum stored on the page. If the checksums are different, then the page has been modified on disk and an error occurs. Databases created created with checksums enabled can also be validated using checksums. You can check whether a database was created with checksums enabled by executing the following statement:

SELECT db_property ( 'Checksum' )

For more information, see Validating a database using the dbvalid command-line utility, sa_validate system procedure, or VALIDATE CHECKSUM statement.

toggle Usage

Creates a database file with the supplied name and attributes.

toggle Permissions

The permissions required to execute this statement are set on the server command line, using the -gu option. The default setting is to require DBA authority.

The account under which the server is running must have write permissions on the directories where files are created.

Not supported on Windows CE.

toggle Side effects

An operating system file is created.

toggle See also
  • ALTER DATABASE statement
  • DROP DATABASE statement
  • The Initialization utility
  • DatabaseKey connection parameter [DBKEY]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Adaptive Server Enterprise provides a CREATE DATABASE statement, but with different options.

toggle Example

The following statement creates a database file named mydb.db in the C:\ directory.

CREATE DATABASE 'C:\\mydb'
TRANSACTION LOG ON
CASE IGNORE
PAGE SIZE 1024
COLLATION '437'
ENCRYPTED OFF
BLANK PADDING OFF
JAVA JDK '1.3'
JCONNECT OFF

The following statement creates a database with no Sybase runtime Java classes. All database operations will execute normally, except for those involving Java classes or objects.

CREATE DATABASE 'C:\\nojava'
JAVA OFF


CREATE DBSPACE statement

toggle Description

Use this statement to define a new database space and create the associated database file.

toggle Syntax

CREATE DBSPACE dbspace-name AS filename

toggle Parameters

dbspace-name An internal name for the database file. The filename parameter is the actual name of the database file, with a path where necessary.

filename A filename without an explicit directory is created in the same directory as the main database file. Any relative directory is relative to the main database file. The filename is relative to the database server. When you are using the database server for NetWare, the filename should use a volume name (not a drive letter) when an absolute directory is specified.

toggle Usage

The CREATE DBSPACE statement creates a new database file. When a database is created, it is composed of one file. All tables and indexes created are placed in that file. CREATE DBSPACE adds a new file to the database. This file can be on a different disk drive than the main file, which means that the database can be larger than one physical device.

For each database, there is a limit of twelve dbspaces in addition to the main file.

Each table is contained entirely within one database file. The IN clause of the CREATE TABLE statement specifies the dbspace into which a table is placed. Tables are put into the main database file by default.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit. Automatic checkpoint.

toggle See also
  • DROP statement
  • Using additional dbspaces
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

Create a dbspace called library to hold the LibraryBooks table and its indexes.

CREATE DBSPACE library
AS 'e:\\dbfiles\\library.db';
CREATE TABLE LibraryBooks (
  title char(100),
  author char(50),
  isbn char(30),
) IN library;


CREATE DECRYPTED FILE statement

toggle Description

This statement decrypts strongly encrypted databases.

toggle Syntax

CREATE DECRYPTED FILE newfile
FROM oldfile KEY
key

toggle Parameters

FROM Lists the filename of the encrypted file.

KEY Lists the key required to access the encrypted file.

toggle Usage

This statement decrypts an encrypted database, transaction log file, or dbspace and creates a new, unencrypted file. The original file must be strongly encrypted using an encryption key. The resulting file is an exact copy of the encrypted file, without encryption and therefore requiring no encryption key.

If a database is decrypted using this statement, the corresponding transaction log file (and any dbspaces) must also be decrypted in order to use the database.

If a database requiring recovery is decrypted, its transaction log file must also be decrypted and recovery on the new database will still be necessary.

The name of the transaction log file remains the same in this process, so if the database and transaction log file are renamed, then you need to run dblog -t on the resulting database.

If you want to encrypt an existing database, you need to either use the CREATE ENCRYPTED FILE statement, or unload and reload the database using the -an option with either -ek or -ep. You can also use this method to change an existing encryption key.

toggle Permissions

Must be a user with DBA authority.

toggle Side effects

None.

toggle Example

The following example decrypts the contacts database and creates a new unencrypted database called contacts2.

CREATE DECRYPTED FILE 'contacts2.db'
FROM 'contacts.db'
KEY 'Sd8f6654*Mnn'


CREATE DOMAIN statement

toggle Description

Use this statement to create a domain in a database.

toggle Syntax

CREATE { DOMAIN | DATATYPE } [ AS ] domain-name data-type
[ [ NOT ] NULL ]
[ DEFAULT default-value ]
[ CHECK ( condition ) ]

domain-name : identifier

data-type : built-in data type, with precision and scale

toggle Parameters

DOMAIN | DATATYPE It is recommended that you use CREATE DOMAIN, rather than CREATE DATATYPE because CREATE DOMAIN is the ANSI/ISO SQL3 term.

NULL By default, domains allow NULLs unless the allow_nulls_by_default option is set to OFF. In this case, new domains by default do not allow NULLs. The nullability of a column created on a domain depends on the setting of the definition of the domain, not on the setting of the allow_nulls_by_default option when the column is referenced. Any explicit setting of NULL or NOT NULL in the column definition overrides the domain setting.

CHECK clause When creating a CHECK condition, you can use a variable name prefixed with the @ sign in the condition. When the data type is used in the definition of a column, such a variable is replaced by the column name. This allows CHECK conditions to be defined on data types and used by columns of any name.

toggle Usage

Domains are aliases for built-in data types, including precision and scale values where applicable. They improve convenience and encourage consistency in the database.

Domains are objects within the database. Their names must conform to the rules for identifiers. Domain names are always case insensitive, as are built-in data type names.

The user who creates a data type is automatically made the owner of that data type. No owner can be specified in the CREATE DATATYPE statement. The domain name must be unique, and all users can access the data type without using the owner as prefix.

Domains can have CHECK conditions and DEFAULT values, and you can indicate whether the data type permits NULL values or not. These conditions and values are inherited by any column defined on the data type. Any conditions or values explicitly specified on the column override those specified for the data type.

To drop the data type from the database, use the DROP statement. You must be either the owner of the data type or have DBA authority in order to drop a domain.

toggle Permissions

Must have RESOURCE authority.

toggle Side effects

Automatic commit.

toggle See also
  • DROP statement
  • SQL Data Types
toggle Standards and compatibility

  • SQL/92 Intermediate-level feature.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported by Adaptive Server Enterprise. Transact-SQL provides similar functionality using the sp_addtype system procedure and the CREATE DEFAULT and CREATE RULE statements.

toggle Example

The following statement creates a data type named address, which holds a 35-character string, and which may be NULL.

CREATE DOMAIN address CHAR( 35 ) NULL

The following statement creates a data type named id, which does not allow NULLS, and which is autoincremented by default.

CREATE DOMAIN id INT
NOT NULL
DEFAULT AUTOINCREMENT


CREATE ENCRYPTED FILE statement

toggle Description

This statement encrypts strongly encrypted databases, transaction log files, or dbspaces.

toggle Syntax

CREATE ENCRYPTED FILE newfile
FROM oldfile
KEY key
[ ALGORITHM { AES | AES_FIPS } ]

toggle Parameters

FROM Lists the filename of the unencrypted file.

KEY Lists the key assigned to the encrypted file.

ALGORITHM Specifies the algorithm used to encrypt the file. If you do not specify an algorithm, AES is used by default.

toggle Usage

This statement takes an unencrypted database, transaction log file, or dbspace and creates a new encrypted file. The original file must not be encrypted. The resulting file is an exact copy of the original file, except that it is encrypted using the specified algorithm and key.

If a database is encrypted using this statement, the corresponding transaction log file (and any dbspaces) must also be encrypted with the same algorithm and key in order to use the database. You cannot mix encrypted and unencrypted files, nor can you mix encrypted files with different encryption algorithms or different keys.

If a database requiring recovery is encrypted, its transaction log file must also be encrypted and recovery on the new database will still be necessary.

The name of the transaction log file remains the same in this process, so if the database and transaction log file are renamed, then you need to run dblog -t on the resulting database.

You can encrypt an existing database or change an existing encryption key by unloading and reloading the database using the -an option with either -ek or -ep. You can also use the CREATE ENCRYPTED FILE statement in conjunction with the CREATE DECRYPTED FILE statement to change an encryption key.

toggle Permissions

Must be a user with DBA authority.

On Windows CE, only the AES algorithm is supported.

toggle Side effects

None.

toggle Example

The following example encrypts the contacts database and creates a new database called contacts2 that is encrypted with AES_FIPS encryption.

CREATE ENCRYPTED FILE 'contacts2.db'
FROM 'contacts.db'
KEY 'Sd8f6654*Mnn'
ALGORITHM AES_FIPS

The following example encrypts the contacts database and the contacts log file, renaming the both files. You will need to run dblog -ek abcd -t contacts2.log contacts.db, since the log has been renamed and the database file still points at the old log.

CREATE ENCRYPTED FILE 'contacts2.db'
FROM 'contacts.db'
KEY 'Sd8f6654*Mnn'
CREATE ENCRYPTED FILE 'contacts2.log'
FROM 'contacts.db'
KEY 'Te9g7765*Noo'
toggle Example 3

The following example encrypts the contacts database and the contacts log file, leaving the original log file name untouched. In this case, you do not need to run dblog, since the name of the file remains the same.

CREATE ENCRYPTED FILE 'newpath\contacts.db'
FROM 'contacts.db'
KEY 'Sd8f6654*Mnn'
CREATE ENCRYPTED FILE 'newpath\contacts.log'
FROM 'contacts.log'
KEY 'Sd8f6654*Mnn'
toggle Example 4

The following example changes the encryption key of the contacts database.

CREATE DECRYPTED FILE 'temp.db'
FROM 'contacts.db'
KEY 'oldkey'
del contacts.db
CREATE ENCRYPTED FILE 'contacts.db'
FROM 'temp.db'
KEY 'newkey'
del temp.db


CREATE EVENT statement

toggle Description

Use this statement to define an event and its associated handler for automating predefined actions. Also, to define scheduled actions.

toggle Syntax

CREATE EVENT event-name
[ TYPE event-type
[ WHERE trigger-condition [ AND trigger-condition ] ... ]
| SCHEDULE schedule-spec, ... ]
[ ENABLE | DISABLE ]
[ AT { CONSOLIDATED | REMOTE | ALL } ]
[ HANDLER
BEGIN
...
END ]

event-type :
BackupEnd | "Connect"
| ConnectFailed | DatabaseStart
| DBDiskSpace | "Disconnect"
| GlobalAutoincrement | GrowDB
| GrowLog | GrowTemp
| LogDiskSpace | "RAISERROR"
| ServerIdle | TempDiskSpace

trigger-condition :
event_condition( condition-name ) { = | < | > | != | <= | >= } value

schedule-spec :
[ schedule-name ]
{ START TIME start-time | BETWEEN start-time AND end-time }
[ EVERY period { HOURS | MINUTES | SECONDS } ]
[ ON { ( day-of-week, ... ) | ( day-of-month, ... ) } ]
[ START DATE start-date ]

event-name | schedule-name : identifier

day-of-week : string

day-of-month | value | period : integer

start-time | end-time : time

start-date : date

toggle Parameters

CREATE EVENT clause The event name is an identifier. An event has a creator, which is the user creating the event, and the event handler executes with the permissions of that creator. This is the same as stored procedure execution. You cannot create events owned by other users.

TYPE clause You can specify the TYPE clause with an optional WHERE clause; or specify the SCHEDULE.

The event-type is one of the listed set of system-defined event types. The event types are case insensitive. To specify the conditions under which this event-type triggers the event, use the WHERE clause. For a description of event-types not listed below, see Choosing a system event.

  • DiskSpace event types If the database contains an event handler for one of the DiskSpace types, the database server checks the available space on each device associated with the relevant file every 30 seconds.

    In the event the database has more than one dbspace, on separate drives, DBDiskSpace checks each drive and acts depending on the lowest available space.

    The LogDiskSpace event type checks the location of the transaction log and any mirrored transaction log, and reports based on the least available space.

    Disk space event types are not supported on Windows CE or on very early releases of Windows 95.

    The TempDiskSpace event type checks the amount of temporary disk space.

    If the appropriate event handlers have been defined (DBDiskSpace, LogDiskSpace, or TempDiskSpace), the server checks the available space on each device associated with a database file every 30 seconds. Similarly, if an event has been defined to handle the system event type ServerIdle, the server notifies the handler when no requests have been process during the previous 30 seconds.

    You can specify the -fc option when starting the database server to implement a callback function when the database server encounters a file system full condition.

    For more information, see -fc server option.

  • GlobalAutoIncrement event type The event fires on each insert when the number of remaining values for a GLOBAL AUTOINCREMENT is less than 1% of the end of its range. A typical action for the handler could be to request a new value for the GLOBAL_DATABASE_ID option, based on the table and number of remaining values which are supplied as parameters to this event.

    You can use the event_condition function with RemainingValues as an argument for this event type.

  • ServerIdle event type If the database contains an event handler for the ServerIdle type, the server checks for server activity every 30 seconds.

WHERE clause The trigger condition determines the condition under which an event is fired. For example, to take an action when the disk containing the transaction log becomes more than 80% full, use the following triggering condition:

...
WHERE event_condition( 'LogDiskSpacePercentFree' ) < 20
...

The argument to the event_condition function must be valid for the event type.

You can use multiple AND conditions to make up the WHERE clause, but you cannot use OR conditions or other conditions.

For information on valid arguments, see EVENT_CONDITION function [System].

SCHEDULE clause This clause specifies when scheduled actions are to take place. The sequence of times acts as a set of triggering conditions for the associated actions defined in the event handler.

You can create more than one schedule for a given event and its associated handler. This permits complex schedules to be implemented. While it is compulsory to provide a schedule-name when there is more than one schedule, it is optional if you provide only a single schedule.

A scheduled event is recurring if its definition includes EVERY or ON; if neither of these reserved words is used, the event will execute at most once. An attempt to create a non-recurring scheduled event for which the start time has passed will generate an error. When a non-recurring scheduled event has passed, its schedule is deleted, but the event handler is not deleted.

Scheduled event times are calculated when the schedules are created, and again when the event handler completes execution. The next event time is computed by inspecting the schedule or schedules for the event, and finding the next schedule time that is in the future. If an event handler is instructed to run every hour between 9:00 and 5:00, and it takes 65 minutes to execute, it runs at 9:00, 11:00, 1:00, 3:00, and 5:00. If you want execution to overlap, you must create more than one event.

The subclauses of a schedule definition are as follows:

  • START TIME The first scheduled time for each day on which the event is scheduled. If a START DATE is specified, the START TIME refers to that date. If no START DATE is specified, the START TIME is on the current day (unless the time has passed) and each subsequent day (if the schedule includes EVERY or ON).

  • BETWEEN ... AND A range of times during the day outside of which no scheduled times occur. If a START DATE is specified, the scheduled times do not occur until that date.

  • EVERY An interval between successive scheduled events. Scheduled events occur only after the START TIME for the day, or in the range specified by BETWEEN ... AND.

  • ON A list of days on which the scheduled events occur. The default is every day if EVERY is specified. Days can be specified as days of the week or days of the month.

    Days of the week are Mon, Tues, and so on. You may also use the full forms of the day, such as Monday. You must use the full forms of the day names if the language you are using is not English, is not the language requested by the client in the connection string, and is not the language which appears in the server window.

    Days of the month are integers from 0 to 31. A value of 0 represents the last day of any month.

  • START DATE The date on which scheduled events are to start occurring. The default is the current date.

Each time a scheduled event handler is completed, the next scheduled time and date is calculated.

  1. If the EVERY clause is used, find whether the next scheduled time falls on the current day, and is before the end of the BETWEEN ... AND range. If so, that is the next scheduled time.

  2. If the next scheduled time does not fall on the current day, find the next date on which the event is to be executed.

  3. Find the START TIME for that date, or the beginning of the BETWEEN ... AND range.

ENABLE | DISABLE By default, event handlers are enabled. When DISABLE is specified, the event handler does not execute even when the scheduled time or triggering condition occurs. A TRIGGER EVENT statement does not cause a disabled event handler to be executed.

AT clause If you wish to execute events at remote or consolidated databases in a SQL Remote setup, you can use this clause to restrict the databases at which the event is handled. By default, all databases execute the event.

HANDLER clause Each event has one handler.

toggle Usage

Events can be used in two main ways:

  • Scheduling actions The database server carries out a set of actions on a schedule of times. You could use this capability to schedule backups, validity checks, queries to fill up reporting tables, and so on.

  • Event handling actions The database server carries out a set of actions when a predefined event occurs. The events that can be handled include disk space restrictions (when a disk fills beyond a specified percentage), when the server is idle, and so on.

An event definition includes two distinct pieces. The trigger condition can be an occurrence, such as a disk filling up beyond a defined threshold. A schedule is a set of times, each of which acts as a trigger condition. When a trigger condition is satisfied, the event handler executes. The event handler includes one or more actions specified inside a compound statement (BEGIN... END).

If no trigger condition or schedule specification is supplied, only an explicit TRIGGER EVENT statement can trigger the event. During development, you may wish to develop and test event handlers using TRIGGER EVENT, and add the schedule or WHERE clause once testing is complete.

Event errors are logged to the database server console.

When event handlers are triggered, the server makes context information, such as the connection ID that caused the event to be triggered, available to the event handler using the event_parameter function. For more information about event_parameter, see EVENT_PARAMETER function [System].

toggle Permissions

Must have DBA authority.

Event handlers execute on a separate connection, with the permissions of the event owner. To execute with permissions other than DBA, you can call a procedure from within the event handler: the procedure executes with the permissions of its owner. The separate connection does not count towards the ten-connection limit of the personal database server.

toggle Side effects

Automatic commit.

The actions of an event handler are committed if no error is detected during execution, and rolled back if errors are detected.

toggle See also
  • BEGIN statement
  • ALTER EVENT statement
  • COMMENT statement
  • DROP statement
  • TRIGGER EVENT statement
  • EVENT_PARAMETER function [System]
  • Choosing a system event
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

Instruct the database server to carry out an automatic backup to tape using the first tape drive on a Windows NT machine, every day at 1 am.

CREATE EVENT DailyBackup
SCHEDULE daily_backup
START TIME '1:00AM' EVERY 24 HOURS
HANDLER
   BEGIN
      BACKUP DATABASE TO '\\\\.\\tape0'
      ATTENDED OFF
   END

Instruct the database server to carry out an automatic backup of the transaction log only, every hour, Monday to Friday between 8 am and 6 pm.

CREATE EVENT HourlyLogBackup
SCHEDULE hourly_log_backup
BETWEEN '8:00AM' AND '6:00PM'
EVERY 1 HOURS ON
   ('Monday','Tuesday','Wednesday','Thursday','Friday')
HANDLER
   BEGIN
      BACKUP DATABASE DIRECTORY 'c:\\database\\backup'
      TRANSACTION LOG ONLY
      TRANSACTION LOG RENAME
   END

For more examples see Defining trigger conditions for events.


CREATE EXISTING TABLE statement

toggle Description

Use this statement to create a new proxy table, which represents an existing object on a remote server.

toggle Syntax

CREATE EXISTING TABLE [owner.]table-name
[ (column-definition, ...) ]
AT location-string

column-definition :
column-name data-type [NOT NULL]

location-string :
remote-server-name.[db-name].[owner].object-name
| remote-server-name;[db-name];[owner];object-name

toggle Parameters

AT clause The AT clause specifies the location of the remote object. The AT clause supports the semicolon (;) as a delimiter. If a semicolon is present anywhere in the location-string string, the semicolon is the field delimiter. If no semicolon is present, a period is the field delimiter. This allows filenames and extensions to be used in the database and owner fields. For example, the following statement maps the table a1 to the MS Access file mydbfile.mdb:

CREATE EXISTING TABLE a1
AT 'access;d:\mydbfile.mdb;;a1'
toggle Usage

The CREATE EXISTING TABLE statement creates a new local, proxy table that maps to a table at an external location. The CREATE EXISTING TABLE statement is a variant of the CREATE TABLE statement. The EXISTING keyword is used with CREATE TABLE to specify that a table already exists remotely and that its metadata is to be imported into Adaptive Server Anywhere. This establishes the remote table as a visible entity to Adaptive Server Anywhere users. Adaptive Server Anywhere verifies that the table exists at the external location before it creates the table.

If the object does not exist (either host data file or remote server object), the statement is rejected with an error message.

Index information from the host data file or remote server table is extracted and used to create rows for the system table sysindexes. This defines indexes and keys in server terms and enables the query optimizer to consider any indexes that may exist on this table.

Referential constraints are passed to the remote location when appropriate.

If column-definitions are not specified, Adaptive Server Anywhere derives the column list from the metadata it obtains from the remote table. If column-definitions are specified, Adaptive Server Anywhere verifies the column-definitions. Column names, data types, lengths, identity property, and null properties are checked for the following:

  • Column names must match identically (although case is ignored).

  • Data types in the CREATE EXISTING TABLE statement must match or be convertible to the data types of the column on the remote location. For example, a local column data type is defined as money, while the remote column data type is numeric.

  • Each column's NULL property is checked. If the local column's NULL property is not identical to the remote column's NULL property, a warning message is issued, but the statement is not aborted.

  • Each column's length is checked. If the length of char, varchar, binary, varbinary, decimal and numeric columns do not match, a warning message is issued, but the command is not aborted.

    You may choose to include only a subset of the actual remote column list in your CREATE EXISTING statement.

toggle Permissions

Must have RESOURCE authority. To create a table for another user, you must have DBA authority.

Not supported on Windows CE.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE TABLE statement
  • Specifying proxy table locations
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Open Client/Open Server.

toggle Example

Create a proxy table named blurbs for the blurbs table at the remote server server_a.

CREATE EXISTING TABLE blurbs
( author_id id not null,
copy text not null)
AT 'server_a.db1.joe.blurbs'

Create a proxy table named blurbs for the blurbs table at the remote server server_a. Adaptive Server Anywhere derives the column list from the metadata it obtains from the remote table.

CREATE EXISTING TABLE blurbs
AT 'server_a.db1.joe.blurbs'

Create a proxy table named rda_employee for the employee table at the Adaptive Server Anywhere remote server asademo.

CREATE EXISTING TABLE rda_employee
AT 'asademo..DBA.employee'


CREATE EXTERNLOGIN statement

toggle Description

Use this statement to assign an alternate login name and password to be used when communicating with a remote server.

toggle Syntax

CREATE EXTERNLOGIN login-name
TO remote-server
REMOTE LOGIN remote-user
[ IDENTIFIED BY remote-password ]

toggle Parameters

login-name specifies the local user login name. When using integrated logins, the login-name is the database user to which the Windows user or group is mapped.

TO clause The TO clause specifies the name of the remote server.

REMOTE LOGIN clause The REMOTE LOGIN clause specifies the user account on remote-server for the local user login-name.

IDENTIFIED BY clause The IDENTIFIED BY clause specifies the remote-password for remote-user. The remote-user and remote-password combination must be valid on the remote-server.

toggle Usage

By default, Adaptive Server Anywhere uses the names and passwords of its clients whenever it connects to a remote server on behalf of those clients. CREATE EXTERNLOGIN assigns an alternate login name and password to be used when communicating with a remote server.

The password is stored internally in encrypted form. The remote-server must be known to the local server by an entry in the SYSERVERS table. For more information, see CREATE SERVER statement.

Sites with automatic password expiration should plan for periodic updates of passwords for external logins.

CREATE EXTERNLOGIN cannot be used from within a transaction.

toggle Permissions

Only the login-name and the DBA account can add or modify an external login for login-name.

Not supported on Windows CE.

toggle Side effects

Automatic commit.

toggle See also
  • DROP EXTERNLOGIN statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Open Client/Open Server.

toggle Example

Map the local user named DBA to the user sa with password Plankton when connecting to the server sybase1.

CREATE EXTERNLOGIN DBA
TO sybase1
REMOTE LOGIN sa
IDENTIFIED BY Plankton


CREATE FUNCTION statement

toggle Description

Use this statement to create a new function in the database.

toggle Syntax 1

CREATE FUNCTION [ owner.]function-name ( [ parameter, ... ] )
RETURNS data-type routine-characteristics
{ compound-statement
| AS tsql-compound-statement
| external-name }

toggle Syntax 2

CREATE FUNCTION [ owner.]procedure-name ( [ parameter, ... ] )
RETURNS data-type
URL url-string
[ TYPE { 'HTTP[:{GET|POST}]' | 'SOAP[:{RPC|DOC}]' } ]
[ NAMESPACE namespace-string ]
[ CERTIFICATE certificate-string ]
[ CLIENTPORT clientport-string ]
[ PROXY proxy-string ]

url-string :
'{HTTP|HTTPS}://[user:password@]hostname[:port][/path]'

parameter :
[ IN ] parameter-name data-type

routine-characteristics
ON EXCEPTION RESUME | [ NOT ] DETERMINISTIC

tsql-compound-statement:
sql-statement
sql-statement
...

external-name:
EXTERNAL NAME library-call
| EXTERNAL NAME java-call LANGUAGE JAVA

library-call :
'[operating-system:]function-name@library; ...'

operating-system :
Windows95 | WindowsNT | NetWare | UNIX

java-call :
'[package-name.]class-name.method-name method-signature'

method-signature :
([field-descriptor, ... ]) return-descriptor

field-descriptor | return-descriptor :
Z | B | S | I | J | F | D | C | V | [descriptor | L class-name;

toggle Parameters

CREATE FUNCTION clause Parameter names must conform to the rules for database identifiers. They must have a valid SQL data type, and must be prefixed by the keyword IN, signifying that the argument is an expression that provides a value to the function.

compound-statement A set of SQL statements bracketed by BEGIN and END, and separated by semicolons. See BEGIN statement

tsql-compound-statement A batch of Transact-SQL statements. See Transact-SQL batch overview, and CREATE PROCEDURE statement [T-SQL].

EXTERNAL NAME clause A function using the EXTERNAL NAME clause is a wrapper around a call to a function in an external library. A function using EXTERNAL NAME can have no other clauses following the RETURNS clause. The library name may include the file extension, which is typically .dll on Windows, .so on UNIX, and .nlm on NetWare. In the absence of the extension, the software appends the platform-specific default file extension for libraries. On NetWare, if no NLM name is given, the NLM containing the symbol must already be loaded when the function is called.

For information about external library calls, see Calling external libraries from procedures.

EXTERNAL NAME LANGUAGE JAVA clause A function that uses EXTERNAL NAME with a LANGUAGE JAVA clause is a wrapper around a Java method.

For information on calling Java procedures, see CREATE PROCEDURE statement.

ON EXCEPTION RESUME clause Use Transact-SQL -like error handling. For more information, see CREATE PROCEDURE statement.

NOT DETERMINISTIC clause A function specified as NOT DETERMINISTIC is re-evaluated each time it is called in a query. The results of functions not specified in this manner may be cached for better performance, and re-used each time the function is called with the same parameters during query evaluation.

Functions that have side effects such as modifying the underlying data should be declared as NOT DETERMINISTIC. For example, a function that generates primary key values and is used in an INSERT ... SELECT statement should be declared NOT DETERMINISTIC:

CREATE FUNCTION keygen( increment INTEGER )
RETURNS INTEGER
NOT DETERMINISTIC
BEGIN
  DECLARE keyval INTEGER;
  UPDATE counter SET x = x + increment;
  SELECT counter.x INTO keyval FROM counter;
  RETURN keyval
END
INSERT INTO new_table
SELECT keygen(1), ...
FROM old_table

Functions may be declared as DETERMINISTIC if they always return the same value for given input parameters. Future versions of the software may use this declaration to allow optimizations that are unsafe for functions that could return different values for the same input.

URL clause For use only when defining a HTTP or SOAP web services client function. Specifies the URI of the web service. The optional username and password parameters provide a means of supplying the credentials needed for HTTP Basic Authentication. HTTP Basic Authentication base-64 encodes the user and password information and passes it in the "Authentication" header of the HTTP request.

TYPE clause Used to specify the format used when making the web service request. If SOAP is specified or no type clause is included, the default type SOAP:RPC is used. HTTP implies HTTP:POST. Since SOAP requests are always sent as XML documents, HTTP:POST is always used to send SOAP requests.

NAMESPACE clause Applies to SOAP client functions only. This clause identifies the method namespace usually required for both SOAP:RPC and SOAP:DOC requests. The SOAP server handling the request uses this namespace to interpret the names of the entities in the SOAP request message body. The namespace can be obtained from the WSDL description of the SOAP service available from the web service server. The default value is the procedure's URL, up to but not including the optional path component.

CERTIFICATE clause In order to make a secure (HTTPS) request, a client must have access to the certificate used by the HTTPS server. The necessary information is specified in a string of semicolon-separated key/value pairs. The certificate may be placed in a file and the name of the file provided using the file key, or the whole certificate may be placed in a string, but not both. The following keys are available:

Key | Abbreviation | Description
file |  | The filename of the certificate.
certificate | cert | The certificate itself.
company | co | The company specified in the certificate.
unit |  | The company unit specified in the certificate.
name |  | The common name specified in the certificate.

Certificates are required only for requests that are either direced to an HTTPS server, or may be redirected from a non-secure to a secure server. A certificate value is not required when sent to an Adpative Server Anywhere database server that accepts HTTPS requests, unless a certificate parameter was used when the database server was started.

CLIENTPORT clause Identifies the port number on which the HTTP client procedure communicates using TCP/IP. It is provided for and recommended only for connections across firewalls, as firewalls filter according to the TCP/UDP port. You may specify a single port numbers, ranges of port numbers, or a combination of both; for example, CLIENTPORT '85,90-97'.

For more information, see ClientPort protocol option [CPORT].

PROXY clause Specifies the URI of a proxy server. For use when the client must access the network through a proxy. Indicates that the procedure is to connect to the proxy server and send the request to the web service through it.

toggle Usage

The CREATE FUNCTION statement creates a user-defined function in the database. A function can be created for another user by specifying an owner name. Subject to permissions, a user-defined function can be used in exactly the same way as other non-aggregate functions.

Adaptive Server Anywhere treats all user-defined functions as idempotent unless they are declared NOT DETERMINISTIC. Idempotent functions return a consistent result for the same parameters and are free of side effects. That is, the server assumes that two successive calls to the same function with the same parameters will return the same result, and will not have any unwanted side-effects on the query's semantics.

If a function returns a result set, it cannot also set output parameters or return a return value.

For web service client functions, the return type of SOAP and HTTP functions must one of the character data types, such as VARCHAR. The value returned is the body of the HTTP response. No HTTP header information is included. If more information is required, such as status information, use a procedure instead of a function.

Parameter values are passed as part of the request. The syntax used depends on the type of request. For HTTP:GET, the paramters are passed as part of the URL; for HTTP:POST requests, the values are placed in the body of the request. Parameters to SOAP requests are always bundled in the request body.

toggle Permissions

Must have RESOURCE authority.

External functions, including Java functions, must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • ALTER FUNCTION statement
  • CREATE PROCEDURE statement
  • DROP statement
  • BEGIN statement
  • CREATE PROCEDURE statement
  • RETURN statement
  • Using Procedures, Triggers, and Batches
toggle Standards and compatibility

  • SQL/92 Persistent Stored Module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase Not supported by Adaptive Server Enterprise. The CREATE FUNCTION statement is supported by Microsoft SQL Server.

toggle Examples

The following function concatenates a firstname string and a lastname string.

CREATE FUNCTION fullname (
   firstname CHAR(30),
   lastname CHAR(30) )
RETURNS CHAR(61)
BEGIN
   DECLARE name CHAR(61);
   SET name = firstname || ' ' || lastname;
   RETURN (name);
END

The following examples illustrate the use of the fullname function.

Return a full name from two supplied strings:

SELECT fullname ('joe','smith')
fullname('joe', 'smith')
joe smith

List the names of all employees:

SELECT fullname (emp_fname, emp_lname)
FROM employee
fullname (emp_fname, emp_lname)
Fran Whitney
Matthew Cobb
Philip Chin
Julie Jordan
...

The following function uses Transact-SQL syntax:

CREATE FUNCTION DoubleIt ( @Input INT )
RETURNS INT
AS
  DECLARE @Result INT
  SELECT @Result = @Input * 2
  RETURN @Result

The statement SELECT DoubleIt( 5 ) returns a value of 10.

The following statement creates an external function written in Java:

CREATE FUNCTION dba.encrypt( IN name char(254) )
RETURNS VARCHAR
EXTERNAL NAME
  'Scramble.encrypt (Ljava/lang/String;)Ljava/lang/String;'
LANGUAGE JAVA


CREATE INDEX statement

toggle Description

Use this statement to create an index on a specified table. Indexes can improve database performance.

toggle Syntax

CREATE [ VIRTUAL ] [ UNIQUE ] [ CLUSTERED ] INDEX index-name
ON [ owner.]table-name
( column-name [ ASC | DESC ], ...
| function-name ( argument [ ,... ] ) AS column-name )
[ { IN | ON } dbspace-name ]

toggle Parameters

VIRTUAL keyword The VIRTUAL keyword is primarily for use by the Index Consultant. A virtual index mimics the properties of a real physical index during the evaluation of query plans by the Index Consultant and when the PLAN function is used. You can use virtual indexes together with the PLAN function to explore the performance impact of an index, without the often time-consuming and resource-consuming effects of creating a real index.

Virtual indexes are not visible to other connections, and are dropped when the connection is closed. Virtual indexes are not used when evaluating plans for the actual execution of queries, and so do not interfere with performance.

Virtual indexes have a limit of four columns.

For more information, see Starting the Index Consultant, and Index Consultant overview.

CLUSTERED keyword The CLUSTERED attribute causes table rows to be stored in an approximate key order corresponding to the index. While the server makes an attempt to preserve key order, total clustering is not guaranteed.

If a clustered index exists, the LOAD TABLE statement inserts rows into the table in the order of the index key, and the INSERT statement attempts to put new rows on the same table page as the one containing adjacent rows, as defined by the key order.

For more information, see Using clustered indexes.

UNIQUE keyword The UNIQUE attribute ensures that there will not be two rows in the table with identical values in all the columns in the index. Each index key must be unique or contain a NULL in at least one column.

There is a difference between a unique constraint on a table and a unique index. Columns of a unique index are allowed to be NULL, while columns in a unique constraint are not. A foreign key can reference either a primary key or a column with a unique constraint, but not a unique index, because it can include multiple instances of NULL.

ASC | DESC option Columns are sorted in ascending (increasing) order unless descending (DESC) is explicitly specified. An index will be used for both an ascending and a descending ORDER BY, whether the index was ascending or descending. However, if an ORDER BY is performed with mixed ascending and descending attributes, an index will be used only if the index was created with the same ascending and descending attributes.

function-name parameter The function-name parameter creates an index on a built-in function. This form of the CREATE INDEX statement is a convenience method that carries out the following operations:

  1. Adds a computed column named column-name to the table. The column is defined with a COMPUTE clause that is the specified built-in function, along with any specified arguments. The data type of the column is based on the result type of the function.

  2. Populates the computed column for the existing rows in the table.

  3. Creates an index on the column.

Dropping the index does not cause the associated column to be dropped. This form of CREATE INDEX cannot be used on declared temporary tables.

For more information about computed columns, see Working with computed columns

IN | ON clause By default, the index is placed in the same database file as its table. You can place the index in a separate database file by specifying a dbspace name in which to put the index. This feature is useful mainly for large databases to circumvent file size limitations.

For more information on limitations, see Size and number limitations.

toggle Usage

The CREATE INDEX statement creates a sorted index on the specified columns of the named table. Indexes are automatically used to improve the performance of queries issued to the database, and to sort queries with an ORDER BY clause. Once an index is created, it is never referenced in a SQL statement again except to validate it (VALIDATE INDEX) or delete it (DROP INDEX).

You cannot create indexes on views.

  • Index ownership There is no way of specifying the index owner in the CREATE INDEX statement. Indexes are always owned by the owner of the table. The index name must be unique for each owner.

  • No indexes on views Indexes cannot be created for views.

  • Index name space The name of each index must be unique for a given table.

  • Exclusive table use CREATE INDEX is prevented whenever the statement affects a table currently being used by another connection. CREATE INDEX can be time consuming and the server will not process requests referencing the same table while the statement is being processed.

  • Automatically created indexes Adaptive Server Anywhere automatically creates indexes for primary keys and for unique constraints. These automatically created indexes are held in the same database file as the table.

toggle Permissions

Must be the owner of the table or have either DBA authority or REFERENCES permission.

toggle Side effects

Automatic commit. Creating an index on a built-in function also causes a checkpoint.

Column statistics are updated.

toggle See also
  • DROP statement
  • Indexes
  • Types of index
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Adaptive Server Enterprise has a more complex CREATE INDEX statement than Adaptive Server Anywhere. While the Adaptive Server Enterprise syntax is permitted in Adaptive Server Anywhere, some clauses and keywords are ignored.

    • The full syntax for Adaptive Server Enterprise 11.5 is as follows:

      CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ]
      INDEX index-name
      ON [ [ database.]owner.]table_name
      (column_name [, column_name], ...)
      [ WITH {
      { FILLFACTOR | MAX_ROWS_PER_PAGE } = x,
      CONSUMERS = x,
      ... IGNORE_DUP_KEY,
      ... SORTED_DATA,
      [ IGNORE_DUP_ROW | ALLOW_DUP_ROW ]
      } ]
      [ ON segment_name ]

    Adaptive Server Anywhere allows, by ignoring, the following keywords:

    • FILLFACTOR

    • IGNORE_DUP_KEY

    • SORTED_DATA

    • IGNORE_DUP_ROW

    • ALLOW_DUP_ROW

    Physical placement of an index is carried out differently in Adaptive Server Enterprise and Adaptive Server Anywhere. The ON segment-name clause is supported in Adaptive Server Anywhere, but segment-name refers to a dbspace.

    Unique indexes in Adaptive Server Anywhere permit entries that contain NULL, and are otherwise identical. Unique indexes in Adaptive Server Enterprise do not permit entries that contain NULL and are otherwise identical.

    Index names must be unique on a given table for both Adaptive Server Anywhere and Enterprise.

toggle Example

Create a two-column index on the employee table.

CREATE INDEX employee_name_index
ON employee
( emp_lname, emp_fname )

Create an index on the sales_order_items table for the prod_id column.

CREATE INDEX item_prod
ON sales_order_items
( prod_id )

Use the SORTKEY function to create an index on the description column of the product table, sorted according to a Russian collation. As a side effect, the statement adds a computed column desc_ru to the table.

CREATE INDEX ix_desc_ru
ON product (
 SORTKEY( description, 'rusdict' )
 AS desc_ru )


CREATE MESSAGE statement [T-SQL]

toggle Description

Use this statement to add a user-defined message to the SYSUSERMESSAGES system table for use by PRINT and RAISERROR statements.

toggle Syntax

CREATE MESSAGE message-number AS message-text

message-number : integer

message-text : string

toggle Parameters

message_number The message number of the message to add. The message number for a user-defined message must be 20000 or greater.

message_text The text of the message to add. The maximum length is 255 bytes. PRINT and RAISERROR recognize placeholders in the message text. A single message can contain up to 20 unique placeholders in any order. These placeholders are replaced with the formatted contents of any arguments that follow the message when the text of the message is sent to the client.

The placeholders are numbered to allow reordering of the arguments when translating a message to a language with a different grammatical structure. A placeholder for an argument appears as "%nn!": a percent sign (%), followed by an integer from 1 to 20, followed by an exclamation mark (!), where the integer represents the position of the argument in the argument list. "%1!" is the first argument, "%2!" is the second argument, and so on.

There is no parameter corresponding to the language argument for sp_addmessage.

toggle Usage

CREATE MESSAGE associates a message number with a message string. The message number can be used in PRINT and RAISERROR statements.

To drop a message, see DROP statement.

toggle Permissions

Must have RESOURCE authority

toggle Side effects

Automatic commit.

toggle See also
  • PRINT statement [T-SQL]
  • RAISERROR statement [T-SQL]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase The functionality of CREATE MESSAGE is provided by the sp_addmessage procedure in Adaptive Server Enterprise.


CREATE PROCEDURE statement

toggle Description

Use this statement to create a procedure in the database.

toggle Syntax 1

CREATE PROCEDURE [ owner.]procedure-name ( [ parameter, ... ] )
{ [ RESULT ( result-column, ... ) | NO RESULT SET ]
[ ON EXCEPTION RESUME ]
compound-statement
| AT location-string
| EXTERNAL NAME library-call
| [ DYNAMIC RESULT SETS integer-expression ]
[ EXTERNAL NAME java-call LANGUAGE JAVA ]
}

toggle Syntax 2

CREATE PROCEDURE [ owner.]procedure-name ( [ parameter, ... ] )
compound-statement

toggle Syntax 3

CREATE PROCEDURE [ owner.]procedure-name ( [ parameter, ... ] )
URL url-string
[ TYPE { 'HTTP[:{GET|POST}]' | 'SOAP[:{RPC|DOC}]' } ]
[ NAMESPACE namespace-string ]
[ CERTIFICATE certificate-string ]
[ CLIENTPORT clientport-string ]
[ PROXY proxy-string ]

url-string :
'{HTTP|HTTPS}://[user:password@]hostname[:port][/path]'

parameter :
parameter_mode parameter-name data-type [ DEFAULT expression ]
| SQLCODE
| SQLSTATE

parameter_mode : IN | OUT | INOUT

result-column : column-name data-type

library-call :
'[operating-system:]function-name@library; ...'

operating-system :
Windows95 | WindowsNT | NetWare | UNIX

java-call :
'[package-name.]class-name.method-name method-signature'

method-signature :
([field-descriptor, ... ] ) return-descriptor

field-descriptor | return-descriptor :
Z | B | S | I | J | F | D | C | V | [descriptor | L class-name;

toggle Parameters

CREATE PROCEDURE clause Parameter names must conform to the rules for other database identifiers such as column names. They must be a valid SQL data type (see SQL Data Types). Parameters can be prefixed them with one of the keywords IN, OUT, or INOUT. If you do not specify one of these values, parameters are INOUT parameters by default. The keywords have the following meanings:

  • IN The parameter is an expression that provides a value to the procedure.

  • OUT The parameter is a variable that could be given a value by the procedure.

  • INOUT The parameter is a variable that provides a value to the procedure, and could be given a new value by the procedure.

When procedures are executed using the CALL statement, not all parameters need to be specified. If a default value is provided in the CREATE PROCEDURE statement, missing parameters are assigned the default values. If an argument is not provided in the CALL statement, and no default is set, an error is given.

SQLSTATE and SQLCODE are special parameters that output the SQLSTATE or SQLCODE value when the procedure ends (they are OUT parameters). Whether or not a SQLSTATE and SQLCODE parameter is specified, the SQLSTATE and SQLCODE special values can always be checked immediately after a procedure call to test the return status of the procedure.

The SQLSTATE and SQLCODE special values are modified by the next SQL statement. Providing SQLSTATE or SQLCODE as procedure arguments allows the return code to be stored in a variable.

RESULT clause The RESULT clause declares the number and type of columns in the result set. The parenthesized list following the RESULT keyword defines the result column names and types. This information is returned by the Embedded SQL DESCRIBE or by ODBC SQLDescribeCol when a CALL statement is being described. Allowable data types are listed in SQL Data Types.

For more information on returning result sets from procedures, see Returning results from procedures.

Some procedures can produce more than one result set, with different numbers of columns, depending on how they are executed. For example, the following procedure returns two columns under some circumstances, and one in others.

CREATE PROCEDURE names( IN formal char(1))
BEGIN
   IF formal = 'n' THEN
      SELECT emp_fname
      FROM employee
   ELSE
      SELECT emp_lname,emp_fname
      FROM employee
   END IF
END

Procedures with variable result sets must be written without a RESULT clause, or in Transact-SQL. Their use is subject to the following limitations:

  • Embedded SQL You must DESCRIBE the procedure call after the cursor for the result set is opened, but before any rows are returned, in order to get the proper shape of result set. The CURSOR cursor-name clause on the DESCRIBE statement is required.

  • ODBC, OLE DB, ADO.NET Variable result-set procedures can be used by applications using these interfaces. The proper description of the result sets is carried out by the driver or provider.

  • Open Client applications Variable result-set procedures can be used by Open Client applications.

If your procedure returns only one result set, you should use a RESULT clause. The presence of this clause prevents ODBC and Open Client applications from redescribing the result set after a cursor is open.

In order to handle multiple result sets, ODBC must describe the currently executing cursor, not the procedure's defined result set. Therefore, ODBC does not always describe column names as defined in the RESULT clause of the procedure definition. To avoid this problem, use column aliases in the SELECT statement that generates the result set.

NO RESULT SET clause Declares that no result set is returned by this procedure. This is useful when an external environment needs to know that a procedure does not return a result set.

ON EXCEPTION RESUME clause This clause enables Transact-SQL -like error handling to be used within a Watcom-SQL syntax procedure.

If you use ON EXCEPTION RESUME, the procedure takes an action that depends on the setting of the ON_TSQL_ERROR option. If ON_TSQL_ERROR is set to CONDITIONAL (which is the default) the execution continues if the next statement handles the error; otherwise, it exits.

Error-handling statements include the following:

  • IF

  • SELECT @variable =

  • CASE

  • LOOP

  • LEAVE

  • CONTINUE

  • CALL

  • EXECUTE

  • SIGNAL

  • RESIGNAL

  • DECLARE

  • SET VARIABLE

You should not use explicit error handling code with an ON EXCEPTION RESUME clause.

For more information, see ON_TSQL_ERROR option [compatibility].

EXTERNAL NAME clause A procedure using the EXTERNAL NAME clause is a wrapper around a call to an external library. A stored procedure using EXTERNAL NAME can have no other clauses following the parameter list. The library name may include the file extension, which is typically .dll on Windows, .so on UNIX, and .nlm on NetWare. In the absence of the extension, the software appends the platform-specific default file extension for libraries. On NetWare, if no NLM name is given, the NLM containing the symbol must already be loaded when the function is called.

For information about external library calls, see Calling external libraries from procedures.

AT location-string clause Create a proxy stored procedure on the current database for a remote procedure specified by location-string. The AT clause supports the semicolon (;) as a field delimiter in location-string. If no semicolon is present, a period is the field delimiter. This allows filenames and extensions to be used in the database and owner fields.

For example, the following statement creates a proxy procedure (remotewho) that calls the dbo.sp_who procedure on the master database of the bostonase server:

CREATE PROCEDURE remotewho ()
AT 'bostonase.master.dbo.sp_who

Remote procedures can return only up to 254 characters in output variables.

For information on remote servers, see CREATE SERVER statement. For information on using remote procedures, see Using remote procedure calls (RPCs).

DYNAMIC RESULT SETS clause This clause is for use with procedures that are wrappers around Java methods. If the DYNAMIC RESULT SETS clause is not provided, it is assumed that the method returns no result set.

URL clause For use only when defining a HTTP or SOAP web services client function. Specifies the URI of the web service. The optional username and password parameters provide a means of supplying the credentials needed for HTTP Basic Authentication. HTTP Basic Authentication base-64 encodes the user and password information and passes it in the "Authentication" header of the HTTP request.

TYPE clause Used to specify the format used when making the web service request. If SOAP is specified or no type clause is included, the default type SOAP:RPC is used. HTTP implies HTTP:POST. Since SOAP requests are always sent as XML documents, HTTP:POST is always used to send SOAP requests.

NAMESPACE clause Applies to SOAP client procedures only. This clause identifies the method namespace usually required for both SOAP:RPC and SOAP:DOC requests. The SOAP server handling the request uses this namespace to interpret the names of the entities in the SOAP request message body. The namespace can be obtained from the WSDL description of the SOAP service available from the web service server. The default value is the procedure's URL, up to but not including the optional path component.

CERTIFICATE clause In order to make a secure (HTTPS) request, a client must have access to the certificate used by the HTTPS server. The necessary information is specified in a string of semicolon-separated key/value pairs. The certificate may be placed in a file and the name of the file provided using the file key, or the whole certificate may be placed in a string, but not both. The following keys are available:

Key | Abbreviation | Description
file |  | The filename of the certificate.
certificate | cert | The certificate itself.
company | co | The company specified in the certificate.
unit |  | The company unit specified in the certificate.
name |  | The common name specified in the certificate.

Certificates are required only for requests that are either direced to an HTTPS server, or may be redirected from a non-secure to a secure server. A certificate value is not required when sent to an Adpative Server Anywhere database server that accepts HTTPS requests, unless a certificate parameter was used when the database server was started.

CLIENTPORT clause Identifies the port number on which the HTTP client procedure communicates using TCP/IP. It is provided for and recommended only for connections across firewalls, as firewalls filter according to the TCP/UDP port. You may specify a single port numbers, ranges of port numbers, or a combination of both; for example, CLIENTPORT '85,90-97'.

For more information, see ClientPort protocol option [CPORT].

PROXY clause Specifies the URI of a proxy server. For use when the client must access the network through a proxy. Indicates that the procedure is to connect to the proxy server and send the request to the web service through it.

EXTERNAL NAME LANGUAGE JAVA clause A procedure that uses EXTERNAL NAME with a LANGUAGE JAVA clause is a wrapper around a Java method.

If the number of parameters is less than the number indicated in the method-signature then the difference must equal the number specified in DYNAMIC RESULT SETS, and each parameter in the method signature in excess of those in the procedure parameter list must have a method signature of [Ljava/SQL/ResultSet;.

A Java method signature is a compact character representation of the types of the parameters and the type of the return value. It is an error to put a space before the signature.

The field-descriptor and return-descriptor have the following meanings:

Field type | Java data type
B | byte
C | char
D | double
F | float
I | int
J | long
L class-name; | an instance of the class class-name. The class name must be fully qualified, and any dot in the name must be replaced by a /. For example, java/lang/String
S | short
V | void
Z | Boolean
[ | use one for each dimension of an array

For example,

double some_method(
  boolean a,
  int b,
  java.math.BigDecimal c,
  byte [][] d,
  java.SQL.ResultSet[] rs ) {
}

would have the following signature:

'(ZILjava/math/BigDecimal;[[B[Ljava/SQL/ResultSet;)D'

For more information, see Returning result sets from Java methods.

toggle Usage

The CREATE PROCEDURE statement creates a procedure in the database. Users with DBA authority can create procedures for other users by specifying an owner. A procedure is invoked with a CALL statement.

If a stored procedure returns a result set, it cannot also set output parameters or return a return value.

Parameter values are passed as part of the request. The syntax used depends on the type of request. For HTTP:GET, the paramters are passed as part of the URL; for HTTP:POST requests, the values are placed in the body of the request. Parameters to SOAP requests are always bundled in the request body.

For web service client procedures, parameter values are passed as part of the request. The syntax used depends on the type of request. For HTTP:GET, the paramters are passed as part of the URL; for HTTP:POST requests, the values are placed in the body of the request. Parameters to SOAP requests are always bundled in the request body.

toggle Permissions

Must have RESOURCE authority.

Must have DBA authority for external procedures or to create a procedure for another user.

toggle Side effects

Automatic commit.

toggle See also
  • BEGIN statement
  • CALL statement
  • CREATE FUNCTION statement
  • CREATE PROCEDURE statement [T-SQL]
  • ALTER PROCEDURE statement
  • DROP statement
  • EXECUTE IMMEDIATE statement [SP]
  • GRANT statement
  • Using Procedures, Triggers, and Batches
toggle Standards and compatibility

  • SQL/92 Persistent Stored Module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase The Transact-SQL CREATE PROCEDURE statement is different.

  • SQLJ The syntax extensions for Java result sets are as specified in the proposed SQLJ1 standard.

toggle Examples

The following procedure uses a case statement to classify the results of a query.

CREATE PROCEDURE ProductType (IN product_id INT, OUT type CHAR(10))
BEGIN
   DECLARE prod_name CHAR(20);
   SELECT name INTO prod_name FROM "DBA"."product"
   WHERE id = product_id;
   CASE prod_name
   WHEN 'Tee Shirt' THEN
      SET type = 'Shirt'
   WHEN 'Sweatshirt' THEN
      SET type = 'Shirt'
   WHEN 'Baseball Cap' THEN
      SET type = 'Hat'
   WHEN 'Visor' THEN
      SET type = 'Hat'
   WHEN 'Shorts' THEN
      SET type = 'Shorts'
   ELSE
      SET type = 'UNKNOWN'
   END CASE;
END

The following procedure uses a cursor and loops over the rows of the cursor to return a single value.

CREATE PROCEDURE TopCustomer (OUT TopCompany CHAR(35), OUT TopValue INT)
BEGIN
   DECLARE err_notfound EXCEPTION
   FOR SQLSTATE '02000';
   DECLARE curThisCust CURSOR FOR
      SELECT company_name,
          CAST(sum(sales_order_items.quantity *
          product.unit_price) AS INTEGER) VALUE
      FROM customer
      LEFT OUTER JOIN sales_order
      LEFT OUTER JOIN sales_order_items
      LEFT OUTER JOIN product
      GROUP BY company_name;
   DECLARE ThisValue INT;
   DECLARE ThisCompany CHAR(35);
   SET TopValue = 0;
   OPEN curThisCust;
   CustomerLoop:
   LOOP
      FETCH NEXT curThisCust
      INTO ThisCompany, ThisValue;
      IF SQLSTATE = err_notfound THEN
         LEAVE CustomerLoop;
      END IF;
      IF ThisValue > TopValue THEN
         SET TopValue = ThisValue;
         SET TopCompany = ThisCompany;
         END IF;
   END LOOP CustomerLoop;
   CLOSE curThisCust;
END


CREATE PROCEDURE statement [T-SQL]

toggle Description

Use this statement to create a new procedure in the database in a manner compatible with Adaptive Server Enterprise.

toggle Syntax 1

The following subset of the Transact-SQL CREATE PROCEDURE statement is supported in Adaptive Server Anywhere.

CREATE PROCEDURE [owner.]procedure_name
[ NO RESULT SET ]
[ [ ( ] @parameter_name data-type [ = default ] [ OUTPUT ], ... [ ) ] ]
[ WITH RECOMPILE ] AS statement-list

toggle Parameters

NO RESULT SET clause Declares that no result set is returned by this procedure. This is useful when an external environment needs to know that a procedure does not return a result set.

toggle Usage

The following differences between Transact-SQL and Adaptive Server Anywhere statements (Watcom-SQL) are listed to help those writing in both dialects.

  • Variable names prefixed by @ The "@" sign denotes a Transact-SQL variable name, while Watcom-SQL variables can be any valid identifier, and the @ prefix is optional.

  • Input and output parameters Watcom-SQL procedure parameters are INOUT by default or can specified as IN, OUT, or INOUT. Transact-SQL procedure parameters are INPUT parameters by default or can be specified as OUTPUT. Those parameters that would be declared as INOUT or as OUT in Adaptive Server Anywhere should be declared with OUTPUT in Transact-SQL.

  • Parameter default values Watcom-SQL procedure parameters are given a default value using the keyword DEFAULT, while Transact-SQL uses an equality sign (=) to provide the default value.

  • Returning result sets Watcom-SQL uses a RESULT clause to specify returned result sets. In Transact-SQL procedures, the column names or alias names of the first query are returned to the calling environment.

    The following Transact-SQL procedure illustrates how result sets are returned from Transact-SQL stored procedures:

    CREATE PROCEDURE showdept @deptname varchar(30)
AS
   SELECT employee.emp_lname, employee.emp_fname
   FROM department, employee
   WHERE department.dept_name = @deptname
   AND department.dept_id = employee.dept_id

    The following is the corresponding Watcom-SQL procedure:

    CREATE PROCEDURE showdept(in deptname
         varchar(30) )
RESULT ( lastname char(20), firstname char(20))
ON EXCEPTION RESUME
BEGIN
   SELECT employee.emp_lname, employee.emp_fname
   FROM department, employee
   WHERE department.dept_name = deptname
   AND department.dept_id = employee.dept_id
END

  • Procedure body The body of a Transact-SQL procedure is a list of Transact-SQL statements prefixed by the AS keyword. The body of a Watcom-SQL procedure is a compound statement, bracketed by BEGIN and END keywords.

toggle Permissions

Must have RESOURCE authority.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE PROCEDURE statement
toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Anywhere supports a subset of the Adaptive Server Enterprise CREATE PROCEDURE statement syntax.

    If the Transact-SQL WITH RECOMPILE optional clause is supplied, it is ignored. Adaptive Server Anywhere always recompiles procedures the first time they are executed after a database is started, and stores the compiled procedure until the database is stopped.

    Groups of procedures are not supported.


CREATE PUBLICATION statement

toggle Description

Use this statement to create a publication. In MobiLink, a publication identifies synchronized data in UltraLite or Adaptive Server Anywhere remote databases.

In SQL Remote, publications identify replicated data in both consolidated and remote databases.

toggle Syntax

CREATE PUBLICATION [ owner.]publication-name
( TABLE article-description, ... )

owner, publication-name : identifier

article-description :
table-name [ ( column-name, ... ) ]
[ WHERE search-condition ]
[ SUBSCRIBE BY expression ]

toggle Parameters

article-description Publications are built from articles. Each article is a table or part of a table. An article may be a vertical partition of a table (a subset of the table's columns), a horizontal partition (a subset of the table's rows) or a vertical and horizontal partition.

WHERE clause The WHERE clause is a way of defining the subset of rows of a table to be included in an article. It is useful if the same subset is to be received by all subscribers to the publication.

SUBSCRIBE BY clause In SQL Remote, one way of defining a subset of rows of a table to be included in an article is to use a SUBSCRIBE BY clause. This clause allows many different subscribers to receive different rows from a table in a single publication definition. This clause is ignored during MobiLink synchronization.

You can combine WHERE and SUBSCRIBE BY clauses in an article definition, but the SUBSCRIBE BY clause is used only by SQL Remote.

toggle Usage

This statement is applicable only to MobiLink and SQL Remote.

The CREATE PUBLICATION statement creates a publication in the database. A publication can be created for another user by specifying an owner name.

In MobiLink, publications are required in Adaptive Server Anywhere remote databases, and are optional in UltraLite databases. These publications and the subscriptions to them determine which data will be uploaded to the MobiLink synchronization server. You can construct a remote database by creating publications and subscriptions directly. Alternatively, you can create publications and subscriptions in an Adaptive Server Anywhere reference database, which acts as a template for the remote databases, and then construct the remote databases using the MobiLink extraction utility.

You set options for a MobiLink publication with the ADD OPTION clause in the ALTER SYNCHRONIZATION SUBSCRIPTION statement or CREATE SYNCHRONIZATION SUBSCRIPTION statement.

In SQL Remote, publishing is a two-way operation, as data can be entered at both consolidated and remote databases. In a SQL Remote installation, any consolidated database and all remote databases must have the same publication defined. Running the SQL Remote extraction utility from a consolidated database automatically executes the correct CREATE PUBLICATION statement in the remote database.

toggle Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the statement.

toggle Side effects

Automatic commit.

toggle See also
  • ALTER PUBLICATION statement
  • DROP PUBLICATION statement
  • ALTER SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • sp_create_publication procedure
  • Adaptive Server Anywhere MobiLink clients: Publishing data
  • UltraLite MobiLink clients: Choosing data to synchronize
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Example

The following statement publishes all columns and rows of two tables.

CREATE PUBLICATION pub_contact (
   TABLE contact,
   TABLE company
)

The following statement publishes only some columns of one table.

CREATE PUBLICATION pub_customer (
   TABLE customer ( id, company_name, city )
)

The following statement publishes only the active customer rows by including a WHERE clause that tests the status column of the customer table.

CREATE PUBLICATION pub_customer (
   TABLE customer ( id, company_name, city, state )
   WHERE status = 'active'
)

The following statement publishes only some rows by providing a subscribe-by value. This method can be used only with SQL Remote.

CREATE PUBLICATION pub_customer (
   TABLE customer ( id, company_name, city, state )
   SUBSCRIBE BY state
)

The subscribe-by value is used as follows when you create a SQL Remote subscription.

CREATE SUBSCRIPTION TO pub_customer ( 'NY' )
   FOR jsmith


CREATE REMOTE MESSAGE TYPE statement [SQL Remote]

toggle Description

Use this statement to identify a message-link and return address for outgoing messages from a database.

toggle Syntax

CREATE REMOTE MESSAGE TYPE message-system
ADDRESS address

message-system: FILE | FTP | MAPI | SMTP | VIM

address: string

toggle Parameters

message-system One of the supported message systems.

address The address for the specified message system.

toggle Usage

The Message Agent sends outgoing messages from a database using one of the supported message links. Return messages for users employing the specified link are sent to the specified address as long as the remote database is created by the extraction utility. The Message Agent starts links only if it has remote users for those links.

The address is the publisher's address under the specified message system. If it is an e-mail system, the address string must be a valid e-mail address. If it is a file-sharing system, the address string is a subdirectory of the directory set in the SQLREMOTE environment variable, or of the current directory if that is not set. You can override this setting on the GRANT CONSOLIDATE statement at the remote database.

The initialization utility creates message types automatically, without an address. Unlike other CREATE statements, the CREATE REMOTE MESSAGE TYPE statement does not give an error if the type exists; instead it alters the type.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • GRANT PUBLISH statement [SQL Remote]
  • GRANT REMOTE statement [SQL Remote]
  • GRANT CONSOLIDATE statement [SQL Remote]
  • DROP REMOTE MESSAGE TYPE statement [SQL Remote]
  • sp_remote_type procedure
  • Using message types
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Example

When remote databases are extracted using the extraction utility, the following statement sets all recipients of file message-system messages to send messages back to the company subdirectory.

The statement also instructs dbremote to look in the company subdirectory for incoming messages.

CREATE REMOTE MESSAGE TYPE file
ADDRESS 'company'


CREATE SCHEMA statement

toggle Description

Use this statement to create a collection of tables, views, and permissions for a database user.

toggle Syntax

CREATE SCHEMA AUTHORIZATION userid
[
create-table-statement
| create-view-statement
| grant-statement
], ...

toggle Usage

The CREATE SCHEMA statement creates a schema. A schema is a collection of tables, views, and their associated permissions.

The userid must be the user ID of the current connection. You cannot create a schema for another user.

If any statement contained in the CREATE SCHEMA statement fails, the entire CREATE SCHEMA statement is rolled back.

The CREATE SCHEMA statement is simply a way of collecting together individual CREATE and GRANT statements into one operation. There is no SCHEMA database object created in the database, and to drop the objects you must use individual DROP TABLE or DROP VIEW statements. To revoke permissions, you must use a REVOKE statement for each permission granted.

The individual CREATE or GRANT statements are not separated by statement delimiters. The statement delimiter marks the end of the CREATE SCHEMA statement itself.

The individual CREATE or GRANT statements must be ordered such that the objects are created before permissions are granted on them.

Although you can currently create more than one schema for a user, this is not recommended, and may not be supported in future releases.

toggle Permissions

Must have RESOURCE authority.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE TABLE statement
  • CREATE VIEW statement
  • GRANT statement
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Adaptive Server Anywhere does not support the use of REVOKE statements within the CREATE SCHEMA statement, and does not allow its use within Transact-SQL batches or procedures.

toggle Example

The following CREATE SCHEMA statement creates a schema consisting of two tables. The statement must be executed by the user ID sample_user, who must have RESOURCE authority. If the statement creating table t2 fails, neither table is created.

CREATE SCHEMA AUTHORIZATION sample_user
CREATE TABLE t1 ( id1 INT PRIMARY KEY )
CREATE TABLE t2 ( id2 INT PRIMARY KEY );

The statement delimiter in the following CREATE SCHEMA statement is placed after the first CREATE TABLE statement. As the statement delimiter marks the end of the CREATE SCHEMA statement, the example is interpreted as a two statement batch by the database server. Consequently, if the statement creating table t2 fails, the table t1 is still created.

CREATE SCHEMA AUTHORIZATION sample_user
CREATE TABLE t1 ( id1 INT PRIMARY KEY );
CREATE TABLE t2 ( id2 INT PRIMARY KEY );


CREATE SERVER statement

toggle Description

Use this statement to add a server to the SYSSERVERS system table.

toggle Syntax

CREATE SERVER server-name
CLASS 'server-class'
USING 'connection-info'
[ READ ONLY ]

server-class :
ASAJDBC | ASEJDBC
| ASAODBC | ASEODBC
| DB2ODBC | MSSODBC
| ORAODBC | ODBC

connection-info :
{ machine-name:port-number [/dbname ] | data-source-name | asa-connection-string }

toggle Parameters

CLASS clause Specifies the server class you want to use for a remote connection. Server classes contain detailed server capability information. If you are using NetWare, only the asajdbc class is supported.

USING clause The USING clause supplies a connection string for the server. The appropriate connection string depends on the driver being used, which in turn depends on the server-class.

If a JDBC-based server class is used, the USING clause is of the form hostname:portnumber [/dbname], where:

  • hostname is the machine the remote server runs on

  • portnumber is the TCP/IP port number the remote server listens on. The default port number for Adaptive Server Anywhere is 2638.

  • dbname For Adaptive Server Anywhere remote servers, if you do not specify a dbname, then the default database is used. For Adaptive Server Enterprise, the default is the master database, and an alternative to using dbname is to another database by some other means (for example, in the FORWARD TO statement).

If an ODBC-based server class is used, the USING clause is the data-source-name. The data-source-name is the ODBC Data Source Name.

For Adaptive Server Anywhere remote servers (ASAJDBC or ASAODBC server classes), the connection-info parameter can be any valid Adaptive Server Anywhere connection string. You can use any Adaptive Server Anywhere connection parameters. For example, if you have connection problems, you can include a LOG connection parameter to troubleshoot the connection attempt.

For more information on Adaptive Server Anywhere connection strings, see Connection parameters.

On UNIX platforms, you need to reference the ODBC driver manager as well. For example, using the supplied iAnywhere Solutions ODBC drivers, the syntax is as follows:

USING 'driver=/opt/sybase/SYBSsa9/drivers/lib/libodbc.so;dsn=my_dsn'

READ ONLY The READ ONLY clause specifies that the remote server is a read-only data source. Any update request is rejected by Adaptive Server Anywhere.

toggle Usage

The CREATE SERVER statement defines a remote server from the Adaptive Server Anywhere catalogs.

For more information on server classes and how to configure a server, see Server Classes for Remote Data Access.

toggle Permissions

Must have DBA authority to execute this command.

Not supported on Windows CE.

toggle Side effects

Automatic commit.

toggle See also
  • ALTER SERVER statement
  • DROP SERVER statement
  • Server Classes for Remote Data Access
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Open Client/Open Server.

toggle Example

The following example creates an Adaptive Server Anywhere remote server named testasa, located on the machine apple and listening on port number 2638, use:

CREATE SERVER testasa
CLASS 'asajdbc'
USING 'apple:2638'

The following example creates a remote server for the JDBC-based Adaptive Server named ase_prod. Its machine name is banana and port number is 3025.

CREATE SERVER ase_prod
CLASS 'asejdbc'
USING 'banana:3025'

The following example creates a remote server for the Oracle server named oracle723. Its ODBC Data Source Name is oracle723.

CREATE SERVER oracle723
CLASS 'oraodbc'
USING 'oracle723'


CREATE SERVICE statement

toggle Description

Use this statement to permit a database server to act as a web server.

toggle Syntax 1

CREATE SERVICE service-name
TYPE 'DISH'
[ GROUP { group-name | NULL } ]
[ FORMAT { 'DNET' | 'CONCRETE' | 'XML' | NULL } ]
[ common-attributes ]

toggle Syntax 2

CREATE SERVICE service-name
TYPE 'SOAP'
[ FORMAT { 'DNET' | 'CONCRETE' | 'XML' | NULL } ]
[ common-attributes ]
AS statement

toggle Syntax 3

CREATE SERVICE service-name
TYPE { 'RAW' | 'HTML' | 'XML' }
[ URL [ PATH ] { ON | OFF | ELEMENTS } ]
[ common-attributes ]
[ AS { statement | NULL } ]

common-attributes:
[ AUTHORIZATION { ON | OFF } ]
[ SECURE { ON | OFF } ]
[ USER { user-name | NULL } ]

toggle Parameters

service-name Web service names may be any sequence of alpha-numeric characters or "/", "-", "_", ".", "!", "~", "*", "'", "(", or "")", except that the first character must not begin with a slash (/) and the name must not contain two or more consecutive slash characters.

service-type-string Identifies the type of the service. The type must be one of the listed service types. There is no default value.

AUTHORIZATION clause Determines whether users must specify a user name and password when connecting to the service. If authorization is OFF, the AS clause is required and a single user must be identified by the USER clause. All requests are run using that user's account and permissions.

If authorization is ON, all users must provide a user name and password. Optionally, you may limit the users that are permitted to use the service by providing a user or group name using the USER clause. If the user name is NULL, all known users can access the service.

The default value is ON. It is recommended that production systems be run with authorization turned on and that you grant permission to use the service by adding users to a group.

SECURE clause Indicates whether unsecure connections are accepted. ON indicates that only HTTPS connections are to be accepted. Service requests received on the HTTP port are automatically redirected to the HTTPS port. If set to OFF, both HTTP and HTTPS connections are accepted. The default value is OFF.

USER clause If authorization is disabled, this parameter becomes mandatory and specifies the user id used to execute all service requests. If authorization is enabled (the default), this optional clause identifies the user or group permitted to access the service. The default value is NULL, which grants access to all users.

URL clause Determines whether URI paths are accepted and, if so, how they are processed. OFF indicates that nothing must follow the service name in a URI request. ON indicates that the remainder of the URI is interpreted as the value of a variable named url. ELEMENTS indicates that the remainder of the URI path is to be split at the slash characters into a list of up to 10 elements. The values are assigned to variables named url plus a numeric suffix of between 1 and 10; for example, the first three variable names are url1, url2, and url3. If fewer than 10 values are supplied, the remaining variables are set to NULL. If the service name ends with the character /, then URL must be set to OFF. The default value is OFF.

GROUP clause Applies to DISH services only. Specifies a common prefix that controls which SOAP services the DISH service exposes. For example, specifying GROUP xyz exposes only SOAP services xyz/aaaa, xyz/bbbb, or xyz/cccc, but does not expose abc/aaaa or xyzaaaa. If no group name is specified, the DISH service exposes all the SOAP services in the database. SOAP services may be exposed by more than one DISH service. The same characters are permitted in group names as in service names.

FORMAT clause Applies to DISH and SOAP services only. Generates output formats compatible with various types of SOAP clients, such as .NET or Java JAX-RPC. If the format of a SOAP service is not specified, the format is inherited from the service's DISH service declaration. If the DISH service also does not declare a format, it defaults to DNET, which is compatible with .NET clients. A SOAP service that does not declare a format may be used with different types of SOAP clients by defining multiple DISH services, each having a different FORMAT type.

statement If the statement is NULL, the URI must specify the statement to be executed. Otherwise, the specified SQL statement is the only one that can be executed through the service. The statement is mandatory for SOAP services, and ignored for DISH services. The default value is NULL.

It is strongly recommended that all services run in production systems define a statement. The statement can be NULL only if authorization is enabled.

Format types

  • DNET Microsoft DataSet format for use with .NET SOAP clients. DNET is the default FORMAT value and was the only format available before version 9.0.2.

  • CONCRETE A platform-neutral DataSet format for use with clients such as JAX-RPC, or with clients that automatically generate interfaces based on the format of the returned data structure. Specifying this format type exposes an ASADataset element within the WSDL. This element describes the result set as a containment hierarchy of a rowset composed of an array of rows, each of which contains an array of column elements.

  • XML A simple XML string format. The DataSet is returned as a string that can be passed to an XML parser. This format is the most portable between SOAP clients.

Service types

  • RAW The result set is sent to the client without any further formatting. You can produce formatted documents by generating the required tags explicitly within your procedure.

  • HTML The result set of a statement or procedure are automatically formatted into an HTML document that contains a table.

  • XML The result set is returned as XML. If the result set is already XML, no additional formatting is applied. If it is not already XML, it is automatically formatted as XML. The effect is similar to that of using the FOR XML RAW clause in a SELECT statement.

  • SOAP The result set is returned as a SOAP response. The format of the data is determined by the FORMAT clause. All requests to a SOAP service must be valid SOAP requests, not just a simple HTTP requests. For more information about the SOAP standards, see [external link] www.w3.org/TR/SOAP.

  • DISH A DISH service (Determine SOAP Handler) acts as a proxy for those SOAP services identified by the GROUP clause, and generates a WSDL (Web Services Description Language) file for each of these SOAP services.

toggle Usage

The create service statement causes the database server to act as a web server. A new entry is created in the SYSWEBSERVICE system table.

toggle Permissions

Must have DBA authority.

toggle Side effects

None.

toggle See also
  • ALTER SERVICE statement, DROP SERVICE statement
toggle Examples

To quickly set up a web server, start a database server with the -xs switch, then execute the following statement:

CREATE SERVICE tables TYPE 'XML'
   AUTHORIZATION OFF
   USER DBA
   AS SELECT *
      FROM SYS.SYSTABLE

After executing this statement, use any web browser to open the URL http://localhost/tables.

The following example demonstrates how to write a Hello World program.

CREATE PROCEDURE hello_world_proc
RESULT (html_doc long varchar)
BEGIN
   CALL dbo.sa_set_http_header( 'Content-Type', 'text/html' );
   SELECT '<html>\n'
       || '<head><title>Hello World</title></head>\n'
       || '<body>\n'
       || '<h1>Hello World!</h1>\n'
       || '</body>\n'
       || '</html>\n';
END;
CREATE SERVICE hello_world TYPE 'RAW'
AUTHORIZATION OFF
USER DBA
AS CALL hello_world_proc;


CREATE STATISTICS statement

toggle Description

This statement should be used only in rare circumstances. It explicitly recreates the statistics that are used by the optimizer.

toggle Syntax

CREATE STATISTICS table-name [ ( column-list ) ]

toggle Usage

This statement recreates the statistics that Adaptive Server Anywhere uses to optimize database queries. These statistics analyze the distribution of data in the database for the specified table. The process of running CREATE STATISTICS performs a sequential scan of the entire table.

In rare circumstances, when your database queries are very variable, and when data distribution is not uniform or the data is changing frequently, you may improve performance by running CREATE STATISTICS against a table or column. This causes a sequential scan of the table or column, using an index if possible.

CREATE STATISTICS overwrites existing statistics. You do not need to drop statistics before executing it.

CREATE STATISTICS creates histograms for the specified table, regardless of the size of the table (by default, histograms are created for tables with five or more rows).

You can also create statistics using the LOAD TABLE statement.

toggle Permissions

Must have DBA authority.

toggle Side effects

Query plans will probably change.

toggle See also
  • DROP STATISTICS statement
  • ALTER DATABASE statement
  • LOAD TABLE statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.


CREATE SUBSCRIPTION statement [SQL Remote]

toggle Description

Use this statement to create a subscription for a user to a publication.

toggle Syntax

CREATE SUBSCRIPTION
TO publication-name [ ( subscription-value ) ]
FOR subscriber-id

publication-name: identifier

subscription-value, subscriber-id: string

subscriber-id: string

toggle Usage

In a SQL Remote installation, data is organized into publications for replication. In order to receive SQL Remote messages, a subscription must be created for a user ID with REMOTE permissions.

If a string is supplied in the subscription, it is matched against each SUBSCRIBE BY expression in the publication. The subscriber receives all rows for which the value of the expression is equal to the supplied string.

In SQL Remote, publications and subscriptions are two-way relationships. If you create a subscription for a remote user to a publication on a consolidated database, you should also create a subscription for the consolidated database on the remote database. The extraction utility carries this out automatically.

toggle Parameters

publication-name The name of the publication to which the user is being subscribed. This may include the owner of the publication.

subscription-value A string that is compared to the subscription expression of the publication. The subscriber receives all rows for which the subscription expression matches the subscription value.

subscriber-id The user ID of the subscriber to the publication. This user must have been granted REMOTE permissions.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • DROP SUBSCRIPTION statement [SQL Remote]
  • GRANT REMOTE statement [SQL Remote]
  • SYNCHRONIZE SUBSCRIPTION statement [SQL Remote]
  • START SUBSCRIPTION statement [SQL Remote]
  • sp_subscription procedure
toggle Example

The following statement creates a subscription for the user p_chin to the publication pub_sales. The subscriber receives all rows for which the subscription expression has a value of Eastern.

CREATE SUBSCRIPTION
TO pub_sales ( 'Eastern' )
FOR p_chin


CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]

toggle Description

Use this statement in an Adaptive Server Anywhere remote database to subscribe a MobiLink user to a publication.

toggle Syntax

CREATE SYNCHRONIZATION SUBSCRIPTION
TO publication-name
[ FOR ml_username, ... ]
[ TYPE protocol-type ]
[ ADDRESS protocol-options]
[ OPTION option=value, ... ]

ml_username: identifier

protocol-type: http | https | https_fips | tcpip | ActiveSync

protocol-options: string

value: string | integer

toggle Parameters

TO clause Specify the name of a publication.

FOR clause Specify one or more MobiLink user names.

ml_username is a name identifying a remote database. This name must be unique.

For more information about synchronization user names, see About MobiLink users.

Omit the FOR clause to set the protcol type, protocol options, and extended options for a publication.

For information about how dbmlsync processes options that are specified in different locations, see Priority order for extended options and connection parameters.

TYPE clause This clause specifies the network protocol to use for synchronization. The default protocol is tcpip.

For more information about network protocols, see CommunicationType (ctp) extended option.

ADDRESS clause This clause specifies network protocol options such as the location of the MobiLink synchronization server. Multiple options must be separated with semi-colons.

For a complete list of protocol options, see CommunicationAddress (adr) extended option.

OPTION clause This clause allows you to set extended options for the subscription. If no FOR clause is provided, the extended options act as default settings for the publication, and are overridden by any extended options set for a synchronization user.

For information about how dbmlsync processes options that are specified in different locations, see Priority order for extended options and connection parameters.

For a complete list of options, see dbmlsync extended options.

toggle Usage

Use this statement to create a synchronization subscription within a MobiLink remote or reference database.

toggle Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the publication.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE PUBLICATION statement
  • CREATE SYNCHRONIZATION USER statement [MobiLink]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Examples

Create a default subscription, which contains default subscription values, for the sales publication (by omitting the FOR clause). Indicate the address of the MobiLink synchronization server and specify that only the Certicom root certificate is to be trusted.

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   ADDRESS 'host=test.internal;port=2439;
      security=ecc_tls'
   OPTION memory='2m';

Subscribe MobiLink user ml_user1 to the sales publication. Set the memory option to 3 Mb, rather than the value specified in the default publication.

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION memory='3m';


CREATE SYNCHRONIZATION USER statement [MobiLink]

toggle Description

Use this statement in an Adaptive Server Anywhere remote database to create a synchronization user.

toggle Syntax

CREATE SYNCHRONIZATION USER ml_username
[ TYPE protocol-type ]
[ ADDRESS protocol-options ]
[ OPTION option=value, ... ]

ml_username: identifier

protocol-type: tcpip | http | https | https_fips | ActiveSync

protocol-options: string

value: string | integer

toggle Parameters

ml_username A name identifying a remote database. This name must be unique.

For more information about synchronization user names, see About MobiLink users.

TYPE clause This clause specifies the communication protocol to use for synchronization. The options are tcpip, http, https, https_fips, and ActiveSync. The default protocol is tcpip.

For more information about communication protocols, see CommunicationType (ctp) extended option.

ADDRESS clause This clause specifies protocol-options in the form keyword=value, separated by semi-colons. Which settings you supply depends on the communication protocol you are using (TCPIP, HTTP, HTTPS, or ActiveSync).

For a complete list of protocol options, see CommunicationAddress (adr) extended option.

OPTION clause The OPTION clause allows you to set extended options using option=value in a comma-separated list.

The values for each option cannot contain equal signs or semicolons. The database server accepts any option that you enter without checking for its validity. Therefore, if you misspell an option or enter an invalid value, no error message appears until you run the dbmlsync command to perform synchronization.

Options set for a synchronization user can be overridden in individual subscriptions or on the dbmlsync command line.

For information about extended options, see dbmlsync extended options.

toggle Description

The protocol-type, protocol-options, and options can be set in several places.

For information about how dbmlsync processes options that are specified in different locations, see Priority order for extended options and connection parameters.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • ALTER SYNCHRONIZATION USER statement [MobiLink]
  • CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • CREATE PUBLICATION statement
  • MobiLink Transport-Layer Security
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Open Client/Open Server.

toggle Examples

The following example creates a user named SSinger, who synchronizes over TCP/IP with a server machine named mlserver.mycompany.com using the password Sam. The use of a password in the user definition is not secure.

CREATE SYNCHRONIZATION USER SSinger
TYPE http
ADDRESS 'host=mlserver.mycompany.com'
OPTION MobiLinkPwd='Sam'

The following creates a synchronization user called factory014 that will cause dbmlsync to hover and synchronize via Certicom-encrypted TCP/IP at a random time in every 8-hour interval. The randomness helps prevent performance degradation at the MobiLink server due to multiple simultaneous synchronizations:

CREATE SYNCHRONIZATION USER factory014
TYPE tcpip
ADDRESS 'host=mycompany.manufacturing.mobilink1;security=certicom_tls(certificate=mycompany_mobilink.crt;certificate_password=thepassword)'
OPTION Schedule='EVERY:08:00'

The following creates a synchronization user called sales5322 that will be used to synchronize with HTTP. In this example, the MobiLink synchronization server runs behind the corporate firewall, and synchronization requests are redirected to it using the Redirector (a reverse proxy to an NSAPI Web server).

CREATE SYNCHRONIZATION USER sales5322
TYPE https
ADDRESS 'host=www.mycompany.com;port=80;url_suffix=mlredirect/ml/'


CREATE TABLE statement

toggle Description

Use this statement to create a new table in the database and, optionally, to create a table on a remote server.

toggle Syntax

CREATE [ GLOBAL TEMPORARY ] TABLE [ owner.]table-name
( { column-definition | table-constraint | pctfree }, ... )
[ { IN | ON } dbspace-name ]
[ ON COMMIT { DELETE | PRESERVE } ROWS
| NOT TRANSACTIONAL]
[ AT location-string ]

column-definition :
column-name data-type [ [ NOT ] NULL ]
[ DEFAULT default-value ] [ column-constraint ... ]

default-value :
special-value
| string
| global variable
| [ - ] number
| ( constant-expression )
| built-in-function( constant-expression )
| AUTOINCREMENT
| CURRENT DATABASE
| CURRENT REMOTE USER
| CURRENT UTC TIMESTAMP
| GLOBAL AUTOINCREMENT [ ( partition-size ) ]
| NULL
| TIMESTAMP
| UTC TIMESTAMP
| LAST USER

special-value:
CURRENT { DATE | TIME | TIMESTAMP
| UTC TIMESTAMP | USER | PUBLISHER }
| USER

column-constraint :
[ CONSTRAINT constraint-name ] {
UNIQUE
| PRIMARY KEY [ CLUSTERED ]
| REFERENCES table-name
[ ( column-name ) ] [ actions ] [ CLUSTERED ]
}
| [ CONSTRAINT constraint-name ] CHECK ( condition )
| COMPUTE ( expression )

table-constraint :
[ CONSTRAINT constraint-name ] {
UNIQUE ( column-name, ... )
| PRIMARY KEY [ CLUSTERED ] ( column-name, ... )
| CHECK ( condition )
| foreign-key-constraint
}

foreign-key-constraint :
[ NOT NULL ] FOREIGN KEY [ role-name ] [ (column-name, ... ) ]
REFERENCES table-name [ (column-name, ... ) ] [ CLUSTERED ]
[ actions ] [ CHECK ON COMMIT ]

action :
ON { UPDATE | DELETE }
...{ CASCADE | SET NULL | SET DEFAULT | RESTRICT }

location-string :
remote-server-name.[db-name].[owner].object-name
| remote-server-name;[db-name];[owner];object-name

pctfree : PCTFREE percent-free-space

percent-free-space : integer

toggle Parameters

IN clause The IN clause specifies the dbspace in which the table is to be created. If the table is a GLOBAL TEMPORARY table, the IN clause is ignored.

For more information about dbspaces, see CREATE DBSPACE statement.

ON COMMIT clause The ON COMMIT clause is allowed only for temporary tables. By default, the rows of a temporary table are deleted on COMMIT.

NOT TRANSACTIONAL The NOT TRANSACTIONAL clause is allowed only for temporary tables. A table created using NOT TRANSACTIONAL is not affected by either COMMIT or ROLLBACK.

The NOT TRANSACTIONAL clause provides performance improvements in some circumstances because operations on non-transactional temporary tables do not cause entries to be made in the rollback log. For example, NOT TRANSACTIONAL may be useful if procedures that use the temporary table are called repeatedly with no intervening COMMITs or ROLLBACKs.

AT clause Create a remote table on a different server specified by location-string and also a proxy table on the current database that maps to the remote table. The AT clause supports the semicolon (;) as a field delimiter in location-string. If no semicolon is present, a period is the field delimiter. This allows filenames and extensions to be used in the database and owner fields.

For example, the following statement maps the table a1 to the MS Access file mydbfile.mdb:

CREATE TABLE a1
AT 'access;d:\mydbfile.mdb;;a1'

For information on remote servers, see CREATE SERVER statement. For information on proxy tables, see CREATE EXISTING TABLE statement and Specifying proxy table locations.

Foreign key definitions are ignored on remote tables. Foreign key definitions on local tables that refer to remote tables are also ignored. Primary key definitions are sent to the remote server if the server supports primary keys.

The COMPUTE clause is ignored for remote tables.

column-definition Define a column in the table. The following are part of column definitions.

  • column-name The column name is an identifier. Two columns in the same table cannot have the same name. For more information, see Identifiers.

  • data-type For information on data types, see SQL Data Types.

  • NOT NULL If NOT NULL is specified, or if the column is in a UNIQUE or PRIMARY KEY constraint, the column cannot contain NULL in any row.

  • DEFAULT For more information on the special-value, see Special values.

    If a DEFAULT value is specified, it is used as the value for the column in any INSERT statement that does not specify a value for the column. If no DEFAULT is specified, it is equivalent to DEFAULT NULL.

    Some of the defaults require more description:

    • AUTOINCREMENT When using AUTOINCREMENT, the column must be one of the integer data types, or an exact numeric type.

      On inserts into the table, if a value is not specified for the AUTOINCREMENT column, a unique value larger than any other value in the column is generated. If an INSERT specifies a value for the column, it is used; if the specified value is larger than the current maximum value for the column, that value will be used as a starting point for subsequent inserts.

      Deleting rows does not decrement the AUTOINCREMENT counter. Gaps created by deleting rows can only be filled by explicit assignment when using an insert. After an explicit insert of a row number less then the maximum, subsequent rows without explicit assignment are still automatically incremented with a value of one greater than the previous maximum.

      The next value to be used for each column is stored as an integer. Using values greater than (231 – 1) may cause wraparound to incorrect values, and AUTOINCREMENT should not be used in such cases.

      You can find the most recently inserted value of the column by inspecting the @@identity global variable.

      The identity column is a Transact-SQL-compatible alternative to using the AUTOINCREMENT default. In Adaptive Server Anywhere, the identity column is implemented as AUTOINCREMENT default. For information, see The special IDENTITY column.

    • GLOBAL AUTOINCREMENT This default is intended for use when multiple databases will be used in a SQL Remote replication or MobiLink synchronization environment.

      This default is similar to AUTOINCREMENT, except that the domain is partitioned. Each partition contains the same number of values. You assign each copy of the database a unique global database identification number. Adaptive Server Anywhere supplies default values in a database only from the partition uniquely identified by that database's number.

      The partition size can be specified in parentheses immediately following the AUTOINCREMENT keyword. The partition size may be any positive integer, although the partition size is generally chosen so that the supply of numbers within any one partition will rarely, if ever, be exhausted.

      If the column is of type BIGINT or UNSIGNED BIGINT, the default partition size is 232 = 4294967296; for columns of all other types the default partition size is 216 = 65536. Since these defaults may be inappropriate, especially if our column is not of type INT or BIGINT, it is best to specify the partition size explicitly.

      When using this default, the value of the public option Global_database_id in each database must be set to a unique, non-negative integer. This value uniquely identifies the database and indicates from which partition default values are to be assigned. The range of allowed values is n p + 1 to (n + 1) p, where n is the value of the public option Global_database_id and p is the partition size. For example, if you define the partition size to be 1000 and set Global_database_id to 3, then the range is from 3001 to 4000.

      If the previous value is less than (n + 1) p, the next default value will be one greater than the previous largest value in column. If the column contains no values, the first default value is n p + 1. Default column values are not affected by values in the column outside of the current partition; that is, by numbers less than pn + 1 or greater than p(n + 1). Such values may be present if they have been replicated from another database via MobiLink synchronization.

      Because the public option Global_database_id cannot be set to negative values, the values chosen are always positive. The maximum identification number is restricted only by the column data type and the partition size.

      If the public option Global_database_id is set to the default value of 2147483647, a null value is inserted into the column. Should null values not be permitted, attempting to insert the row causes an error. This situation arises, for example, if the column is contained in the table's primary key.

      Null default values are also generated when the supply of values within the partition has been exhausted. In this case, a new value of Global_database_id should be assigned to the database to allow default values to be chosen from another partition. Attempting to insert the null value causes an error if the column does not permit nulls. To detect that the supply of unused values is low and handle this condition, create an event of type GlobalAutoincrement.

      You cannot use DEFAULT GLOBAL AUTOINCREMENT in databases created with version 6 or earlier software, even if they have been upgraded.

    • Constant expressions Constant expressions that do not reference database objects are allowed in a DEFAULT clause, so functions such as GETDATE or DATEADD can be used. If the expression is not a function or simple value, it must be enclosed in parentheses.

    • TIMESTAMP Provides a way of indicating when each row in the table was last modified. When a column is declared with DEFAULT TIMESTAMP, a default value is provided for inserts, and the value is updated with the current date and time whenever the row is updated.

      To provide a default value on insert, but not update the column whenever the row is updated, use DEFAULT CURRENT TIMESTAMP instead of DEFAULT TIMESTAMP.

      For more information on timestamp columns, see The special Transact-SQL timestamp column and data type.

      Columns declared with DEFAULT TIMESTAMP contain unique values, so that applications can detect near-simultaneous updates to the same row. If the current timestamp value is the same as the last value, it is incremented by the value of the DEFAULT_TIMESTAMP_INCREMENT option.

      For more information, see DEFAULT_TIMESTAMP_INCREMENT option [database].

      You can automatically truncate timestamp values in Adaptive Server Anywhere based on the DEFAULT_TIMESTAMP_INCREMENT option. This is useful for maintaining compatibility with other database software that records less precise timestamp values.

      For more information, see TRUNCATE_TIMESTAMP_VALUES option [database].

      The global variable @@dbts returns a TIMESTAMP value representing the last value generated for a column using DEFAULT TIMESTAMP. For more information, see Global variables.

    • string For more information, see Strings.

    • global-variable For more information, see Global variables.

  • column-constraint A column constraint restricts the values the column can hold.

table-constraint A table constraint restricts the values that one or more columns in the table can hold.

Constraints Column and table constraints help ensure the integrity of data in the database. If a statement would cause a violation of a constraint, execution of the statement does not complete, any changes made by the statement before error detection are undone, and an error is reported. Column constraints are abbreviations for the corresponding table constraints.

  • For example, the following statements are equivalent:

CREATE TABLE Product (
   product_num INTEGER UNIQUE
)
CREATE TABLE Product (
   product_num INTEGER,
   UNIQUE ( product_num )
)

Column constraints are normally used unless the constraint references more than one column in the table. In these cases, a table constraint must be used.

Constraints include the following:

  • CHECK This allows arbitrary conditions to be verified. For example, a check constraint could be used to ensure that a column called Sex only contains the values M or F.

    No row in a table is allowed to violate a constraint. If an INSERT or UPDATE statement would cause a row to violate a constraint, the operation is not permitted and the effects of the statement are undone.

    The change is rejected only if a constraint condition evaluates to FALSE, the change is allowed if a constraint condition evaluates to TRUE or UNKNOWN.

    For more information about TRUE, FALSE, and UNKNOWN conditions, see NULL value and Search conditions.

  • COMPUTE The COMPUTE constraint is a column constraint only. When a column is created using a COMPUTE constraint, its value in any row is the value of the supplied expression. Columns created with this constraint are read-only columns for applications: the value is changed by the database server when the expression is evaluated.

    Any UPDATE statement that attempts to change the value of a computed column does fire any triggers associated with the column.

  • UNIQUE Identifies one or more columns that uniquely identify each row in the table. No two rows in the table can have the same values in all the named column(s). A table may have more than one unique constraint.

    There is a difference between a unique constraint and a unique index. Columns of a unique index are allowed to be NULL, while columns in a unique constraint are not. A foreign key can reference either a primary key or a column with a unique constraint, but not a unique index, because it can include multiple instances of NULL.

    For information about unique indexes, see CREATE INDEX statement.

  • PRIMARY KEY This is the same as a unique constraint, except that a table can have only one primary key constraint. The primary key usually identifies the best identifier for a row. For example, the customer number might be the primary key for the customer table.

    Columns included in primary keys cannot allow NULL. Each row in the table has a unique primary key value. A table can have only one PRIMARY KEY.

    The order of the columns in a primary key is the order in which the columns were created in the table, not the order in which they are listed when the primary key is created.

    For more information about the CLUSTERED option and clustered indexes, see Using clustered indexes.

  • Foreign key A foreign key constraint can be implemented using a REFERENCES column constraint (single column only) or a FOREIGN KEY table constraint. It restricts the values for a set of columns to match the values in a primary key or, less commonly, a unique constraint of another table (the primary table). For example, a foreign key constraint could be used to ensure that a customer number in an invoice table corresponds to a customer number in the customer table.

    If you specify column name in a REFERENCES column constraint, it must be a column in the primary table, must be subject to a unique constraint or primary key constraint, and that constraint must consist of only that one column. If you do not specify column-name, the foreign key references the primary key of the primary table.

    For more information about the CLUSTERED option and clustered indexes, see Using clustered indexes.

    If you do not explicitly define a foreign key column, it is created with the same data type as the corresponding column in the primary table. These automatically-created columns cannot be part of the primary key of the foreign table. Thus, a column used in both a primary key and foreign key of the same table must be explicitly created.

    If foreign key column names are specified, then primary key column names must also be specified, and the column names are paired according to position in the lists. If the primary table column names are not specified in a FOREIGN KEY table constraint, then the primary key columns are used. If foreign key column names are not specified then the foreign key columns are give the same names as the columns in the primary table.

    If at least one value in a multi-column foreign key is NULL, there is no restriction on the values that can be held in other columns of the key.

    A temporary table cannot have a foreign key that references a base table and a base table cannot have a foreign key that references a temporary table.

    • NOT NULL Disallow NULL in the foreign key columns. A NULL in a foreign key means that no row in the primary table corresponds to this row in the foreign table.

    • role-name The role name is the name of the foreign key. The main function of the role name is to distinguish two foreign keys to the same table. If no role name is specified, the role name is assigned as follows:

      1. If there is no foreign key with a role name the same as the table name, the table name is assigned as the role name.

      2. If the table name is already taken, the role name is the table name concatenated with a zero-padded three-digit number unique to the table.

  • action The referential integrity action defines the action to be taken to maintain foreign key relationships in the database. Whenever a primary key value is changed or deleted from a database table, there may be corresponding foreign key values in other tables that should be modified in some way. You can specify either an ON UPDATE clause, an ON DELETE clause, or both, followed by one of the following actions:

    • CASCADE When used with ON UPDATE, updates the corresponding foreign keys to match the new primary key value. When used with ON DELETE, deletes the rows from the foreign table that match the deleted primary key.

    • SET NULL Sets to NULL all the foreign key values that correspond to the updated or deleted primary key.

    • SET DEFAULT Sets foreign key values that match the updated or deleted primary key value to values specified on the DEFAULT clause of each foreign key column.

    • RESTRICT Generates an error if an attempt is made to update or delete a primary key value while there are corresponding foreign keys elsewhere in the database. RESTRICT is the default action.

  • CHECK ON COMMIT The CHECK ON COMMIT clause overrides the WAIT_FOR_COMMIT database option, and causes the database server to wait for a COMMIT before checking RESTRICT actions on a foreign key. The CHECK ON COMMIT clause does not delay CASCADE, SET NULL, or SET DEFAULT actions.

    If you use CHECK ON COMMIT with out specifying any actions, then RESTRICT is implied as an action for UPDATE and DELETE.

PCTFREE Specifies the percentage of free space you want to reserve for each table page. The free space is used if rows increase in size when the data is updated. If there is no free space in a table page, every increase in the size of a row on that page requires the row to be split across multiple table pages, causing row fragmentation and possible performance degradation.

The value percent-free-space is an integer between 0 and 100. The former specifies that no free space is to be left on each page—each page is to be fully packed. A high value causes each row to be inserted into a page by itself. If PCTFREE is not set, 200 bytes are reserved in each page.

The value for PCTFREE is stored in the SYSATTRIBUTE system table.

For more information, see SYSATTRIBUTE system table.

toggle Usage

The CREATE TABLE statement creates a new table. A table can be created for another user by specifying an owner name. If GLOBAL TEMPORARY is specified, the table is a temporary table. Otherwise, the table is a base table.

The definition of a temporary table exists in the database, like that of a base table, and remains in the database until it is explicitly removed by a DROP TABLE statement. The rows in a temporary table are visible only to the connection that inserted the rows. Multiple connections from the same or different applications can use the same temporary table at the same time, and each connection will see only its own rows. The rows of a temporary table for a connection are deleted when the connection ends.

toggle Permissions

Must have RESOURCE authority.

Must have DBA authority to create a table for another user.

The AT clause to create proxy tables is not supported on Windows CE.

toggle Side effects

Automatic commit.

toggle See also
  • ALTER TABLE statement
  • CREATE DBSPACE statement
  • CREATE EXISTING TABLE statement
  • DECLARE LOCAL TEMPORARY TABLE statement
  • DROP statement
  • Special values
  • SQL Data Types
  • Creating tables
  • ALLOW_NULLS_BY_DEFAULT option [compatibility]
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

    The following are vendor extensions:

    • The { IN | ON } dbspace-name clause.

    • The ON COMMIT clause

    • Some of the default values.

  • Sybase Supported by Adaptive Server Enterprise, with some differences.

    • Temporary tables You can create a temporary table by preceding the table name in a CREATE TABLE statement with a pound sign (#). In Adaptive Server Anywhere, these are declared temporary tables, which are available only in the current connection. For information, see DECLARE LOCAL TEMPORARY TABLE statement.

    • Physical placement Physical placement of a table is carried out differently in Adaptive Server Anywhere and in Adaptive Server Enterprise. The ON segment-name clause supported by Adaptive Server Enterprise is supported in Adaptive Server Anywhere, but segment-name refers to a dbspace name.

    • Constraints Adaptive Server Anywhere does not support named constraints or named defaults, but does support domains, which allow constraint and default definitions to be encapsulated in the data type definition. It also supports explicit defaults and CHECK conditions in the CREATE TABLE statement.

    • NULL default By default, columns in Adaptive Server Enterprise default to NOT NULL, whereas in Adaptive Server Anywhere the default setting is NULL. This setting can be controlled using the ALLOW_NULLS_BY_DEFAULT database option. You should explicitly specify NULL or NOT NULL to make your data definition statements transferable between Adaptive Server Anywhere and Adaptive Server Enterprise.

      For more information, see ALLOW_NULLS_BY_DEFAULT option [compatibility].

toggle Example

The following example creates a table for a library database to hold book information.

CREATE TABLE library_books (
-- NOT NULL is assumed for primary key columns
isbn CHAR(20)      PRIMARY KEY,
copyright_date     DATE,
title              CHAR(100),
author             CHAR(50),
-- column(s) corresponding to primary key of room
-- are created automatically
FOREIGN KEY location REFERENCES room
)

The following example creates a table for a library database to hold information on borrowed books. The default value for date_borrowed indicates that the book is borrowed on the day the entry is made. The date_returned column is NULL until the book is returned.

CREATE TABLE borrowed_book (
date_borrowed DATE NOT NULL DEFAULT CURRENT DATE,
date_returned       DATE,
book                CHAR(20)
                    REFERENCES library_books (isbn),
-- The check condition is UNKNOWN until
-- the book is returned, which is allowed
CHECK( date_returned >= date_borrowed )
)

The following example creates tables for a sales database to hold order and order item information.

CREATE TABLE Orders (
   order_num INTEGER NOT NULL PRIMARY KEY,
   date_ordered DATE,
   name CHAR(80)
);
CREATE TABLE Order_item (
   order_num        INTEGER NOT NULL,
   item_num         SMALLINT NOT NULL,
   PRIMARY KEY (order_num, item_num),
   -- When an order is deleted, delete all of its
   -- items.
   FOREIGN KEY (order_num)
   REFERENCES Orders (order_num)
   ON DELETE CASCADE
)

The following example creates a table named t1 at the remote server SERVER_A and creates a proxy table named t1 that is mapped to the remote table.

CREATE TABLE t1
( a  INT,
  b  CHAR(10))
AT 'SERVER_A.db1.joe.t1'


CREATE TRIGGER statement

toggle Description

Use this statement to create a trigger on a table.

toggle Syntax

CREATE TRIGGER trigger-name trigger-time { trigger-event-list | UPDATE OF column-list }
[ ORDER integer ] ON table-name
[ REFERENCING [ OLD AS old-name ]
[ NEW AS new-name ] ]
[ REMOTE AS remote-name ] ]
[ FOR EACH { ROW | STATEMENT } ]
[ WHEN ( search-condition ) ]
compound-statement

trigger-time : BEFORE | AFTER | RESOLVE

trigger-event-list : trigger-event [ , trigger-event ]

trigger-event :
DELETE | INSERT | UPDATE

toggle Parameters

Trigger events Triggers can be fired by one or more of the following events:

  • DELETE Invoked whenever a row of the associated table is deleted.

  • INSERT Invoked whenever a new row is inserted into the table associated with the trigger.

  • UPDATE Invoked whenever a row of the associated table is updated.

  • UPDATE OF column-list Invoked whenever a row of the associated table is updated and a column in the column-list is modified.

You may write separate triggers for each event that you need to handle or, if you have some shared actions and some actions that depend on the event, you can create a trigger for all events and use an IF statement to distinguish the action taking place.

For more information, see IF statement.

trigger-time Row-level triggers can be defined to execute BEFORE or AFTER the insert, update, or delete. Statement-level triggers execute AFTER the statement. The RESOLVE trigger time is for use with SQL Remote: it fires before row-level UPDATE or UPDATE OF column-lists only.

BEFORE UPDATE triggers fire any time an UPDATE occurs on a row, whether or not the new value differs from the old value. AFTER UPDATE triggers fire only if the new value is different from the old value.

FOR EACH clause To declare a trigger as a row-level trigger, use the FOR EACH ROW clause. To declare a trigger as a statement-level trigger, you can either use a FOR EACH STATEMENT clause or omit the FOR EACH clause. For clarity, it is recommended that you enter the FOR EACH STATEMENT clause if declaring a statement-level trigger.

ORDER clause Triggers of the same type (insert, update, or delete) that fire at the same time (before, after, or resolve) can use the ORDER clause to determine the order that the triggers are fired. Specifying ORDER 0 is equivalent to omitting the ORDER clause.

REFERENCING clause The REFERENCING OLD and REFERENCING NEW clauses allow you to refer to the inserted, deleted or updated rows. For the purposes of this clause, an UPDATE is treated as a delete followed by an insert.

An INSERT takes the REFERENCING NEW clause, which represents the inserted row. There is no REFERENCING OLD clause.

A DELETE takes the REFERENCING OLD clause, which represents the deleted row. There is no REFERENCING NEW clause.

An UPDATE takes the REFERENCING OLD clause, which represents the row before the update, and it takes the REFERENCING NEW clause, which represents the row after the update.

The meaning of REFERENCING OLD and REFERENCING NEW differs, depending on whether the trigger is a row-level or a statement-level trigger. For row-level triggers, the REFERENCING OLD clause allows you to refer to the values in a row prior to an update or delete, and the REFERENCING NEW clause allows you to refer to the inserted or updated values. The OLD and NEW rows can be referenced in BEFORE and AFTER triggers. The REFERENCING NEW clause allows you to modify the new row in a BEFORE trigger before the insert or update operation takes place.

The REFERENCING REMOTE clause is for use with SQL Remote. It allows you to refer to the values in the VERIFY clause of an UPDATE statement. It should be used only with RESOLVE UPDATE or RESOLVE UPDATE OF column-list triggers.

WHEN clause The trigger fires only for rows where the search-condition evaluates to true. The WHEN clause can be used only with row level triggers.

toggle Usage

The CREATE TRIGGER statement creates a trigger associated with a table in the database, and stores the trigger in the database.

The trigger is declared as either a row-level trigger, in which case it executes before or after each row is modified, or as a statement-level trigger, in which case it executes after the entire triggering statement is completed.

toggle Permissions

Must have RESOURCE authority and have ALTER permissions on the table, or must be the owner of the table or have DBA authority. CREATE TRIGGER puts a table lock on the table, and thus requires exclusive use of the table.

toggle Side effects

Automatic commit.

toggle See also
  • BEGIN statement
  • CREATE PROCEDURE statement
  • CREATE TRIGGER statement [T-SQL]
  • DROP statement
  • Using Procedures, Triggers, and Batches
toggle Standards and compatibility

  • SQL/92 Persistent stored module feature. Some clauses are vendor extensions.

  • SQL/99 Persistent Stored Module feature. Some clauses are vendor extensions.

  • Sybase This syntax is different to that supported by Adaptive Server Enterprise.

toggle Example

The first example creates a row-level trigger. When a new department head is appointed, update the manager_id column for employees in that department.

CREATE TRIGGER tr_manager
BEFORE UPDATE OF dept_head_id
ON department
REFERENCING OLD AS old_dept NEW AS new_dept
FOR EACH ROW
BEGIN
   UPDATE employee
   SET employee.manager_id=new_dept.dept_head_id
   WHERE employee.dept_id=old_dept.dept_id
END

The next example, which is more complex, deals with a statement-level trigger. First, create a table as follows:

CREATE TABLE "DBA"."t0"
(
   "id"           integer NOT NULL,
   "times"        timestamp NULL DEFAULT current timestamp,
   "remarks"            text NULL,
   PRIMARY KEY ("id")
)

Next, create a statement-level trigger for this table:

CREATE TRIGGER DBA."insert-st" AFTER INSERT ORDER 4 ON
DBA.t0
REFERENCING NEW AS new_name
FOR EACH STATEMENT
BEGIN
  DECLARE @id1 INTEGER;
  DECLARE @times1 TIMESTAMP;
  DECLARE @remarks1 LONG VARCHAR;

  DECLARE @err_notfound EXCEPTION FOR SQLSTATE VALUE '02000';

//declare a cursor for table new_name
  DECLARE new1 CURSOR FOR
   SELECT ID,times,remarks FROM
      new_name;
  OPEN new1;
 //Open the cursor, and get the value
  LoopGetRow:
  LOOP
      FETCH NEXT new1
   INTO @id1, @times1,@remarks1;

      IF SQLSTATE = @err_notfound THEN
   LEAVE LoopGetRow
      END IF;

      //print the value or for other use
      PRINT (@remarks1);

  END LOOP LoopGetRow;
  CLOSE new1

END


CREATE TRIGGER statement [SQL Remote]

toggle Description

Use this statement to create a new trigger in the database. One form of trigger is designed specifically for use by SQL Remote.

toggle Syntax

CREATE TRIGGER trigger-name trigger-time
trigger-event, ...
[ ORDER integer ] ON table-name
[ REFERENCING [ OLD AS old-name ]
[ NEW AS new-name ] ]
[ REMOTE AS remote-name ] ]
[ FOR EACH { ROW | STATEMENT } ]
[ WHEN ( search-condition ) ]
[ IF UPDATE ( column-name ) THEN
[ { AND | OR } UPDATE ( column-name ) ] ... ]
compound-statement
[ ELSEIF UPDATE ( column-name ) THEN
[ { AND | OR } UPDATE ( column-name ) ] ...
compound-statement
END IF ] ]

trigger-time:
BEFORE | AFTER | RESOLVE

trigger-event:
DELETE | INSERT | UPDATE
| UPDATE OF column-name [, column-name, ...]

toggle Parameters

trigger-time Row-level triggers can be defined to execute BEFORE or AFTER the insert, update, or delete. Statement-level triggers execute AFTER the statement. The RESOLVE trigger time is for use with SQL Remote: it fires before row-level UPDATE or UPDATE OF column-lists only.

BEFORE UPDATE triggers fire any time an UPDATE occurs on a row, whether or not the new value differs from the old value. AFTER UPDATE triggers fire only if the new value is different from the old value.

Trigger events Triggers can be fired by one or more of the following events:

  • DELETE Invoked whenever a row of the associated table is deleted.

  • INSERT Invoked whenever a new row is inserted into the table associated with the trigger.

  • UPDATE Invoked whenever a row of the associated table is updated.

  • UPDATE OF column-list Invoked whenever a row of the associated table is updated and a column in the column-list is modified.

toggle Usage

Anywhere.

toggle Permissions

Must have RESOURCE authority and have ALTER permissions on the table, or must have DBA authority. CREATE TRIGGER puts a table lock on the table and thus requires exclusive use of the table.

toggle Side effects

Automatic commit.

toggle See also
  • UPDATE statement
toggle Description

The CREATE TRIGGER statement creates a trigger associated with a table in the database and stores the trigger in the database.

BEFORE UPDATE triggers fire any time an update occurs on a row, regardless of whether or not the new value differs from the old value. AFTER UPDATE triggers will fire only if the new value is different from the old value.

Row and statement-level triggers

The trigger is declared as either a row-level trigger, in which case it executes before or after each row is modified, or as a statement-level trigger, in which case it executes after the entire triggering statement is completed.

Row-level triggers can be defined to execute BEFORE or AFTER the insert, update, or delete. Statement-level triggers execute AFTER the statement. The RESOLVE trigger time is for use with SQL Remote; it fires before row-level UPDATE or UPDATE OF column-lists only.

To declare a trigger as a row-level trigger, use the FOR EACH ROW clause. To declare a trigger as a statement-level trigger, you can either use a FOR EACH STATEMENT clause or omit the FOR EACH clause. For clarity, it is recommended that you enter the FOR EACH STATEMENT clause if declaring a statement-level trigger.

Order of firing

Triggers of the same type (insert, update, or delete) that fire at the same time (before, after, or resolve) can use the ORDER clause to determine the order that the triggers are fired.

Referencing deleted and inserted values

The REFERENCING OLD and REFERENCING NEW clauses allow you to refer to the deleted and inserted rows. For the purposes of this clause, an UPDATE is treated as a delete followed by an insert.

The REFERENCING REMOTE clause is for use with SQL Remote. It allows you to refer to the values in the VERIFY clause of an UPDATE statement. It should be used only with RESOLVE UPDATE or RESOLVE UPDATE OF column-list triggers.

The meaning of REFERENCING OLD and REFERENCING NEW differs, depending on whether the trigger is a row-level or a statement-level trigger. For row-level triggers, the REFERENCING OLD clause allows you to refer to the values in a row prior to an update or delete, and the REFERENCING NEW clause allows you to refer to the inserted or updated values. The OLD and NEW rows can be referenced in BEFORE and AFTER triggers. The REFERENCING NEW clause allows you to modify the new row in a BEFORE trigger before the insert or update operation takes place.

For statement-level triggers, the REFERENCING OLD and REFERENCING NEW clauses refer to declared temporary tables holding the old and new values of the rows. The default names for these tables are deleted and inserted.

The WHEN clause causes the trigger to fire only for rows where the search-condition evaluates to true.

Updating values with the same value

BEFORE UPDATE triggers fire any time an UPDATE occurs on a row, whether or not the new value differs from the old value. AFTER UPDATE triggers fire only if the new value is different from the old value.

toggle Example

  • When a new department head is appointed, update the manager_id column for employees in that department.

    CREATE TRIGGER
tr_manager BEFORE UPDATE OF dept_head_id ON department
REFERENCING OLD AS old_dept
NEW AS new_dept
FOR EACH ROW
BEGIN
   UPDATE employee
   SET employee.manager_id=new_dept.dept_head_id
   WHERE employee.dept_id=old_dept.dept_id
END


CREATE TRIGGER statement [T-SQL]

toggle Description

Use this statement to create a new trigger in the database in a manner compatible with Adaptive Server Enterprise.

toggle Syntax 1

CREATE TRIGGER [owner.]trigger_name
ON [owner.]table_name
FOR { INSERT, UPDATE, DELETE }
AS statement-list

toggle Syntax 2

CREATE TRIGGER [owner.]trigger_name
ON [owner.]table_name
FOR {INSERT, UPDATE}
AS
[ IF UPDATE ( column_name )
[ { AND | OR } UPDATE ( column_name ) ] ... ]
statement-list
[ IF UPDATE ( column_name )
[ { AND | OR} UPDATE ( column_name ) ] ... ]
statement-list

toggle Usage

The rows deleted or inserted are held in two temporary tables. In the Transact-SQL form of triggers, they can be accessed using the table names deleted, and inserted, as in Adaptive Server Enterprise. In the Watcom-SQL CREATE TRIGGER statement, these rows are accessed using the REFERENCING clause.

Trigger names must be unique in the database.

Transact-SQL triggers are executed AFTER the triggering statement.

toggle Permissions

Must have RESOURCE authority and have ALTER permissions on the table, or must have DBA authority.

CREATE TRIGGER locks all the rows on the table, and thus requires exclusive use of the table.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE TRIGGER statement
toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/92 Transact-SQL extension.

  • Sybase Anywhere supports a subset of the Adaptive Server Enterprise syntax.


CREATE VARIABLE statement

toggle Description

Use this statement to create a SQL variable.

toggle Syntax

CREATE VARIABLE identifier data-type

toggle Usage

The CREATE VARIABLE statement creates a new variable of the specified data type. The variable contains the NULL value until it is assigned a different value by the SET statement.

A variable can be used in a SQL expression anywhere a column name is allowed. If a column name exists with the same name as the variable, the variable value is used.

Variables belong to the current connection, and disappear when you disconnect from the database or when you use the DROP VARIABLE statement. Variables are not visible to other connections. Variables are not affected by COMMIT or ROLLBACK statements.

Variables are useful for creating large text or binary objects for INSERT or UPDATE statements from embedded SQL programs.

Local variables in procedures and triggers are declared within a compound statement (see Using compound statements).

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • BEGIN statement
  • SQL Data Types
  • DROP VARIABLE statement
  • SET statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

For an example, see SET statement


CREATE VIEW statement

toggle Description

Use this statement to create a view on the database. Views are used to give a different perspective on the data, even though it is not stored that way.

toggle Syntax

CREATE VIEW
[ owner.]view-name [ ( column-name, ... ) ]
AS select-statement
[ WITH CHECK OPTION ]

toggle Parameters

view-name The view-name is an identifier. The default owner is the current user ID.

column-name The columns in the view are given the names specified in the column-name list. If the column name list is not specified, the view columns are given names from the select list items. In order to use the names from the select list items, each item must be a simple column name or have an alias-name specified (see SELECT statement). All items in the select list must have unique names.

AS clause The SELECT statement on which the view is based must not have an ORDER BY clause on it. It may have a GROUP BY clause and may be a UNION. The SELECT statement must not refer to local temporary tables.

WITH CHECK OPTION clause The WITH CHECK OPTION clause rejects any updates and inserts to the view that do not meet the criteria of the views as defined by its SELECT statement.

toggle Usage

The CREATE VIEW statement creates a view with the given name. You can create a view owned by another user by specifying the owner. You must have DBA authority to create a view for another user.

A view name can be used in place of a table name in SELECT, DELETE, UPDATE, and INSERT statements. Views, however, do not physically exist in the database as tables. They are derived each time they are used. The view is derived as the result of the SELECT statement specified in the CREATE VIEW statement. Table names used in a view should be qualified by the user ID of the table owner. Otherwise, a different user ID might not be able to find the table or might get the wrong table.

Views can be updated unless the SELECT statement defining the view contains a GROUP BY clause, an aggregate function, or involves a UNION operation. An update to the view causes the underlying table(s) to be updated.

toggle Permissions

Must have RESOURCE authority and SELECT permission on the tables in the view definition.

toggle Side effects

Automatic commit.

toggle See also
  • DROP statement
  • CREATE TABLE statement
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Example

The following example creates a view showing information for male employees only. This view has the same column names as the base table.

CREATE VIEW male_employee
AS SELECT *
FROM Employee
WHERE Sex = 'M'

The following example creates a view showing employees and the departments they belong to.

CREATE VIEW emp_dept
AS SELECT emp_lname, emp_fname, dept_name
FROM Employee JOIN Department
ON Employee.dept_id = Department.dept_id


CREATE WRITEFILE statement (deprecated)

toggle Description

Use this statement to create a write file for a database.

Deprecated statement
The use of writefiles is deprecated.
toggle Syntax

CREATE WRITEFILE write-file-name
FOR DATABASE db-file-name [ KEY key ]
[ LOG OFF | LOG ON [ log-file-name [ MIRROR mirror-file-name ] ] ]

write-file-name | db-file-name | log-file-name | mirror-file-name : string

toggle Usage

Creates a database write file with the supplied name and attributes.

The file names (write-file-name, db-file-name, log-file-name, mirror-file-name) are strings containing operating system file names.

For information on strings, see Strings.

If you specify no path, or a relative path, the file is created relative to the current working directory of the server.

You cannot create a write file for a database that is currently loaded.

toggle Permissions

The permissions required to execute this statement are set on the server command line, using the -gu option. The default setting is to require DBA authority.

The account under which the server is running must have write permissions on the directories where files are created.

Not supported on Windows CE.

You must specify a KEY value if you want to create a writefile for a strongly encrypted database.

toggle Side effects

An operating system file is created.

toggle See also
  • CREATE DATABASE statement
  • The Write File utility (deprecated)
  • Working with write files (deprecated)
  • DatabaseKey connection parameter [DBKEY]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement creates a write file.

CREATE WRITEFILE 'c:\\sybase\\my_db.wrt'
FOR DATABASE 'c:\\sybase\\my_db.db'
LOG ON 'e:\\logdrive\\my_db.log'


DEALLOCATE statement

toggle Description

Use this statement to free resources associated with a cursor.

toggle Syntax

DEALLOCATE [ CURSOR ] cursor-name

cursor-name : identifier

toggle Usage

Frees all memory associated with a cursor, including the data items, indicator variables, and the structure itself.

This option has no effect in Adaptive Server Anywhere. It is provided for compatibility with Adaptive Server Enterprise and Microsoft SQL Server. In Adaptive Server Enterprise, the CURSOR keyword is required. In Microsoft SQL Server, the keyword is not permitted. Adaptive Server Anywhere recognizes both forms.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • DECLARE CURSOR statement [ESQL] [SP]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Adaptive Server Enterprise.


DEALLOCATE DESCRIPTOR statement [ESQL]

toggle Description

Use this statement to free memory associated with a SQL descriptor area.

toggle Syntax

DEALLOCATE DESCRIPTOR descriptor-name

descriptor-name : string

toggle Usage

Frees all memory associated with a descriptor area, including the data items, indicator variables, and the structure itself.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • ALLOCATE DESCRIPTOR statement [ESQL]
  • The SQL descriptor area (SQLDA)
  • SET DESCRIPTOR statement [ESQL]
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Supported by Open Client/Open Server.

toggle Example

For an example, see ALLOCATE DESCRIPTOR statement [ESQL].


Declaration section [ESQL]

toggle Description

Use this statement to declare host variables in an embedded SQL program. Host variables are used to exchange data with the database.

toggle Syntax

EXEC SQL BEGIN DECLARE SECTION;
C declarations
EXEC SQL END DECLARE SECTION;

toggle Usage

A declaration section is simply a section of C variable declarations surrounded by the BEGIN DECLARE SECTION and END DECLARE SECTION statements. A declaration section makes the SQL preprocessor aware of C variables that will be used as host variables. Not all C declarations are valid inside a declaration section. See Using host variables for more information.

toggle Permissions

None.

toggle See also
  • BEGIN statement
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Compatible with Adaptive Server Enterprise.

toggle Example
EXEC SQL BEGIN DECLARE SECTION;
char *emp_lname, initials[5];
int dept;
EXEC SQL END DECLARE SECTION;


DECLARE statement

toggle Description

Use this statement to declare a SQL variable within a compound statement (BEGIN ... END).

toggle Syntax

DECLARE variable-name data-type

toggle Usage

Variables used in the body of a procedure, trigger, or batch can be declared using the DECLARE statement. The variable persists for the duration of the compound statement in which it is declared.

The body of a Watcom-SQL procedure or trigger is a compound statement, and variables must be declared immediately following BEGIN. In a Transact-SQL procedure or trigger, there is no such restriction.

toggle Standards and compatibility

  • SQL/92 Persistent Stored Module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase Supported by Adaptive Server Enterprise.

    • To be compatible with Adaptive Server Enterprise, the variable name must be preceded by an @.

    • In Adaptive Server Enterprise, a variable that is declared in a procedure or trigger exists for the duration of the procedure or trigger. In Adaptive Server Anywhere, if a variable is declared inside a compound statement, it exists only for the duration of that compound statement (whether it is declared in a Watcom-SQL or Transact-SQL compound statement).

toggle Example

The following batch illustrates the use of the DECLARE statement and prints a message on the server window:

BEGIN
  DECLARE varname CHAR(61);
  SET varname = 'Test name';
  MESSAGE varname;
END


DECLARE CURSOR statement [ESQL] [SP]

toggle Description

Use this statement to declare a cursor. Cursors are the primary means for manipulating the results of queries.

toggle Syntax 1 [ESQL]

DECLARE cursor-name
[ UNIQUE ]
[ NO SCROLL
| DYNAMIC SCROLL
| SCROLL
| INSENSITIVE
| SENSITIVE
]
CURSOR FOR
{ select-statement
| statement-name
[ FOR { UPDATE [ cursor-concurrency ] | READ ONLY } ]
| call-statement }

toggle Syntax 2 [SP]

DECLARE cursor-name
[ NO SCROLL
| DYNAMIC SCROLL
| SCROLL
| INSENSITIVE
| SENSITIVE
]
CURSOR FOR
{ select-statement
[ FOR { UPDATE [ cursor-concurrency ] | READ ONLY } ]
| call-statement
| USING variable-name }

cursor-name : identifier

statement-name : identifier | hostvar

variable-name : identifier

cursor-concurrency :
BY { VALUES | TIMESTAMP | LOCK }

toggle Parameters

UNIQUE When a cursor is declared UNIQUE, the query is forced to return all the columns required to uniquely identify each row. Often this means ensuring that all columns in the primary key or a uniqueness table constraint are returned. Any columns that are required but were not specified in the query are added to the result set.

A DESCRIBE done on a UNIQUE cursor sets the following additional flags in the indicator variables:

  • DT_KEY_COLUMN The column is part of the key for the row

  • DT_HIDDEN_COLUMN The column was added to the query because it was required to uniquely identify the rows

NO SCROLL A cursor declared NO SCROLL is restricted to moving forwards through the result set using FETCH NEXT and FETCH RELATIVE 0 seek operations.

As rows cannot be returned to once the cursor leaves the row, there are no sensitivity restrictions on the cursor. Consequently, when a NO SCROLL cursor is requested, Adaptive Server Anywhere supplies the most efficient kind of cursor, which is an asensitive cursor.

For more information, see Asensitive cursors.

DYNAMIC SCROLL DYNAMIC SCROLL is the default cursor type. DYNAMIC SCROLL cursors can use all formats of the FETCH statement.

When a DYNAMIC SCROLL cursor is requested, Adaptive Server Anywhere supplies an asensitive cursor. When using cursors there is always a trade-off between efficiency and consistency. Asensitive cursors provide efficient performance at the expense of consistency.

For more information, see Asensitive cursors.

SCROLL A cursor declared SCROLL can use all formats of the FETCH statement. When a SCROLL cursor is requested, Adaptive Server Anywhere supplies a value-sensitive cursor.

For more information, see Value-sensitive cursors.

Adaptive Server Anywhere must execute value-sensitive cursors in such a way that result set membership is guaranteed. DYNAMIC SCROLL cursors are more efficient and should be used unless the consistent behavior of SCROLL cursors is required.

INSENSITIVE A cursor declared INSENSITIVE has its membership fixed when it is opened; a temporary table is created with a copy of all the original rows. FETCHING from an INSENSITIVE cursor does not see the effect of any other INSERT, UPDATE, or DELETE statement, or any other PUT, UPDATE WHERE CURRENT, DELETE WHERE CURRENT operations on a different cursor. It does see the effect of PUT, UPDATE WHERE CURRENT, DELETE WHERE CURRENT operations on the same cursor.

For more information, see Insensitive cursors.

SENSITIVE A cursor declared SENSITIVE is sensitive to changes to membership or values of the result set.

For more information, see Sensitive cursors.

FOR statement-name Statements are named using the PREPARE statement. Cursors can be declared only for a prepared SELECT or CALL.

FOR UPDATE | READ ONLY A cursor declared FOR READ ONLY may not be used in an UPDATE (positioned) or a DELETE (positioned) operation. FOR UPDATE is the default.

In response to any request for a cursor that specifies FOR UPDATE, Adaptive Server Anywhere provides either a value-sensitive cursor or an asensitive cursor. Insensitive and asensitive cursors are not updateable.

USING variable-name For use within stored procedures only. The variable is a string containing a SELECT statement for the cursor. The variable must be available when the DECLARE is processed, and so must be one of the following:

  • A parameter to the procedure. For example,

    create function get_row_count(in qry long varchar)
returns int
begin
  declare crsr cursor using qry;
  declare rowcnt int;

  set rowcnt = 0;
  open crsr;
  lp: loop
    fetch crsr;
    if SQLCODE <> 0 then leave lp end if;
    set rowcnt = rowcnt + 1;
  end loop;
  return rowcnt;
end

  • Nested inside another BEGIN... END after the variable has been assigned a value. For example,

    create procedure get_table_name(
  in id_value int, out tabname char(128)
)
begin
  declare qry long varchar;

  set qry = 'select table_name from SYS.SYSTABLE ' ||
            'where table_id=' || string(id_value);
  begin
    declare crsr cursor using qry;

    open crsr;
    fetch crsr into tabname;
    close crsr;
  end
end
toggle Usage

The DECLARE CURSOR statement declares a cursor with the specified name for a SELECT statement or a CALL statement.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • PREPARE statement [ESQL]
  • OPEN statement [ESQL] [SP]
  • EXPLAIN statement [ESQL]
  • SELECT statement
  • CALL statement
  • FOR statement
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Supported by Open Client/Open Server.

toggle Example

The following example illustrates how to declare a scroll cursor in Embedded SQL:

EXEC SQL DECLARE cur_employee SCROLL CURSOR
FOR SELECT * FROM employee;

The following example illustrates how to declare a cursor for a prepared statement in Embedded SQL:

EXEC SQL PREPARE employee_statement
FROM 'SELECT emp_lname FROM employee';
EXEC SQL DECLARE cur_employee CURSOR
FOR employee_statement;

The following example illustrates the use of cursors in a stored procedure:

BEGIN
  DECLARE cur_employee CURSOR FOR
      SELECT emp_lname
      FROM employee;
  DECLARE name CHAR(40);
  OPEN cur_employee;
  lp: LOOP
    FETCH NEXT cur_employee INTO name;
    IF SQLCODE <> 0 THEN LEAVE lp END IF;
    ...
  END LOOP;
  CLOSE cur_employee;
END


DECLARE CURSOR statement [T-SQL]

toggle Description

Use this statement to declare a cursor in a manner compatible with Adaptive Server Enterprise.

toggle Syntax

DECLARE cursor-name
CURSOR FOR select-statement
[ FOR { READ ONLY | UPDATE } ]

cursor-name : identifier

select-statement : string

toggle Usage

Adaptive Server Anywhere supports a DECLARE CURSOR syntax that is not supported in Adaptive Server Enterprise. For information on the full DECLARE CURSOR syntax, see DECLARE CURSOR statement [ESQL] [SP].

This section describes the overlap between the Adaptive Server Anywhere and Enterprise flavors of DECLARE CURSOR.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • DECLARE CURSOR statement [ESQL] [SP]
toggle Standards and compatibility

  • SQL/92 Entry-level feature. The FOR UPDATE and FOR READ ONLY options are Transact-SQL extensions.

  • SQL/92 Core feature. The FOR UPDATE and FOR READ ONLY options are Transact-SQL extensions.

  • Sybase There are some features of the Adaptive Server Enterprise DECLARE CURSOR statement that are not supported in Adaptive Server Anywhere.

    • Adaptive Server Enterprise supports cursors opened for update of a list of columns from the tables specified in the select-statement. This is not supported in Adaptive Server Anywhere.

    • In the Watcom-SQL dialect, a DECLARE CURSOR statement in a procedure, trigger, or batch must immediately follow the BEGIN keyword. In the Transact-SQL dialect, there is no such restriction.

    • In Adaptive Server Enterprise, when a cursor is declared in a procedure, trigger, or batch, it exists for the duration of the procedure, trigger, or batch. In Adaptive Server Anywhere, if a cursor is declared inside a compound statement, it exists only for the duration of that compound statement (whether it is declared in a Watcom-SQL or Transact-SQL compound statement).

    • CURSOR type (UNIQUE, NO SCROLL, and so on) and CURSOR FOR statement-name are not supported in Adaptive Server Anywhere.


DECLARE LOCAL TEMPORARY TABLE statement

toggle Description

Use this statement to declare a local temporary table.

toggle Syntax

DECLARE LOCAL TEMPORARY TABLE table-name
( { column-definition [ column-constraint ... ] | table-constraint | pctfree }, ... )
[ ON COMMIT { DELETE | PRESERVE } ROWS
| NOT TRANSACTIONAL ]

pctfree : PCTFREE percent-free-space

percent-free-space : integer

toggle Parameters

ON COMMIT By default, the rows of a temporary table are deleted on a COMMIT. You can use the ON COMMIT clause to preserve rows on a COMMIT.

NOT TRANSACTIONAL A table created using this clause is not affected by either COMMIT or ROLLBACK. The clause is useful if procedures that use the temporary table are called repeatedly with no intervening COMMITs or ROLLBACKs.

The NOT TRANSACTIONAL clause provides performance improvements in some circumstances because operations on non-transactional temporary tables do not cause entries to be made in the rollback log. For example, NOT TRANSACTIONAL may be useful if procedures that use the temporary table are called repeatedly with no intervening COMMITs or ROLLBACKs.

PCTFREE Specifies the percentage of free space you want to reserve for each table page. The free space is used if rows increase in size when the data is updated. If there is no free space in a table page, every increase in the size of a row on that page requires the row to be split across multiple table pages, causing row fragmentation and possible performance degradation.

The value percent-free-space is an integer between 0 and 100.The former specifies that no free space is to be left on each page—each page is to be fully packed. A high value causes each row to be inserted into a page by itself. If PCTFREE is not set, 200 bytes are reserved in each page.

toggle Usage

The DECLARE LOCAL TEMPORARY TABLE statement declares a temporary table. For definitions of column-definition, column-constraint, and table-constraint, see CREATE TABLE statement.

Declared local temporary tables within compound statements exist within the compound statement. (See Using compound statements). Otherwise, the declared local temporary table exists until the end of the connection.

The rows of a declared temporary table are deleted when the table is explicitly dropped and when the table goes out of scope. You can also explicitly delete rows using TRUNCATE or DELETE.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • CREATE TABLE statement
  • Using compound statements
toggle Standards and compatibility

  • SQL/92 Conforms to the SQL/92 standard.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Adaptive Server Enterprise does not support DECLARE TEMPORARY TABLE.

toggle Example

The following example illustrates how to declare a temporary table in Embedded SQL:

EXEC SQL DECLARE LOCAL TEMPORARY TABLE MyTable (
  number INT
   );

The following example illustrates how to declare a temporary table in a stored procedure:

BEGIN
  DECLARE LOCAL TEMPORARY TABLE TempTab (
    number INT
  );
  ...
END


DELETE statement

toggle Description

Use this statement to delete rows from the database.

toggle Syntax

DELETE [ FIRST | TOP n ]
[ FROM ] [ owner.]table-name
[ FROM table-list ]
[ WHERE search-condition ]

toggle Usage

The DELETE statement deletes all the rows from the named table that satisfy the search condition. If no WHERE clause is specified, all rows from the named table are deleted.

The DELETE statement can be used on views, provided the SELECT statement defining the view has only one table in the FROM clause and does not contain a GROUP BY clause, an aggregate function, or involve a UNION operation.

The optional second FROM clause in the DELETE statement allows rows to be deleted based on joins. If the second FROM clause is present, the WHERE clause qualifies the rows of this second FROM clause. Rows are deleted from the table name given in the first FROM clause.

The second FROM clause can contain arbitrary complex table expressions, such as KEY and NATURAL joins. For a full description of the FROM clause and joins, see FROM clause.

The following statement illustrates a potential ambiguity in table names in DELETE statements with two FROM clauses that use correlation names:

DELETE
FROM table_1
FROM table_1 AS alias_1, table_2 AS alias_2
WHERE ...

The table table_1 is identified without a correlation name in the first FROM clause, but with a correlation name in the second FROM clause. In this case, table_1 in the first clause is identified with alias_1 in the second clause—there is only one instance of table_1 in this statement.

This is an exception to the general rule that where a table is identified with a correlation name and without a correlation name in the same statement, two instances of the table are considered.

Consider the following example:

DELETE
FROM table_1
FROM table_1 AS alias_1, table_1 AS alias_2
WHERE ...

In this case, there are two instances of table_1in the second FROM clause. The statement will fail with a syntax error as it is ambiguous which instance of the table_1 from the second FROM clause matches the first instance of table_1 in the first FROM clause.

Deleting a significant amount of data using the DELETE statement will also update column statistics.

toggle Permissions

Must have DELETE permission on the table.

toggle Side effects

None.

toggle See also
  • TRUNCATE TABLE statement
  • INSERT statement
  • INPUT statement [Interactive SQL]
  • FROM clause
toggle Standards and compatibility

  • SQL/92 Entry-level compliant. The use of more than one table in the FROM clause is a vendor extension.

  • SQL/99 Core feature. The use of more than one table in the FROM clause is a vendor extension.

  • Sybase Supported by Adaptive Server Enterprise, including the vendor extension.

toggle Example

Remove employee 105 from the database.

DELETE
FROM employee
WHERE emp_id = 105

Remove all data prior to 2000 from the fin_data table.

DELETE
FROM fin_data
WHERE year < 2000

Remove all orders from sales_order_items table if their ship date is older than 2001-01-01 and their region is Central.

DELETE
FROM sales_order_items
FROM sales_order
WHERE sales_order_items.id = sales_order.id
  and ship_date < '2001-01-01' and region ='Central'


DELETE (positioned) statement [ESQL] [SP]

toggle Description

Use this statement to delete the data at the current location of a cursor.

toggle Syntax

DELETE [ FROM table-spec ] WHERE CURRENT OF cursor-name

cursor-name : identifier | hostvar

table-spec : [ owner.]correlation-name

owner : identifier

toggle Usage

This form of the DELETE statement deletes the current row of the specified cursor. The current row is defined to be the last row fetched from the cursor.

The table from which rows are deleted is determined as follows:

  • If no FROM clause is included, the cursor must be on a single table only.

  • If the cursor is for a joined query (including using a view containing a join), then the FROM clause must be used. Only the current row of the specified table is deleted. The other tables involved in the join are not affected.

  • If a FROM clause is included, and no table owner is specified, table-spec is first matched against any correlation names.

    • If a correlation name exists, table-spec is identified with the correlation name.

    • If a correlation name does not exist, table-spec must be unambiguously identifiable as a table name in the cursor.

  • If a FROM clause is included, and a table owner is specified, table-spec must be unambiguously identifiable as a table name in the cursor.

  • The positioned DELETE statement can be used on a cursor open on a view as long as the view is updateable.

toggle Permissions

Must have DELETE permission on tables used in the cursor.

toggle Side effects

None.

toggle See also
  • UPDATE statement
  • UPDATE (positioned) statement [ESQL] [SP]
  • INSERT statement
  • PUT statement [ESQL]
toggle Standards and compatibility

  • SQL/92 Entry-level feature. The range of cursors that can be updated may contain vendor extensions if the ANSI_UPDATE_CONSTRAINTS option is set to OFF.

  • SQL/99 Core feature. The range of cursors that can be updated may contain vendor extensions if the ANSI_UPDATE_CONSTRAINTS option is set to OFF.

  • Sybase Embedded SQL use is supported by Open Client/Open Server. Procedure and trigger use is supported only in Adaptive Server Anywhere.

toggle Example

The following statement removes the current row from the database.

DELETE
WHERE CURRENT OF cur_employee


DESCRIBE statement [ESQL]

toggle Description

Use this statement to get information about the host variables required to store data retrieved from the database, or host variables required to pass data to the database.

toggle Syntax

DESCRIBE
[ USER TYPES ]
[ ALL | BIND VARIABLES FOR | INPUT | OUTPUT
| SELECT LIST FOR ]
[ LONG NAMES [long-name-spec ] | WITH VARIABLE RESULT ]
[ FOR ] { statement-name | CURSOR cursor-name }
INTO sqlda-name

long-name-spec :
OWNER.TABLE.COLUMN | TABLE.COLUMN | COLUMN

statement-name : identifier | hostvar

cursor-name : declared cursor

sqlda-name : identifier

toggle Parameters

USER TYPES A DESCRIBE statement with the USER TYPES clause returns information about domains of a column. Typically, such a DESCRIBE will be done when a previous DESCRIBE returns an indicator of DT_HAS_USERTYPE_INFO.

The information returned is the same as for a DESCRIBE without the USER TYPES keywords, except that the sqlname field holds the name of the domain, instead of the name of the column.

If the DESCRIBE uses the LONG NAMES clause, the sqldata field holds this information.

ALL DESCRIBE ALL allows you to describe INPUT and OUTPUT with one request to the database server. This has a performance benefit. The INPUT information will be filled in the SQLDA first, followed by the OUTPUT information. The sqld field contains the total number of INPUT and OUTPUT variables. The DT_DESCRIBE_INPUT bit in the indicator variable is set for INPUT variables and clear for OUTPUT variables.

INPUT A bind variable is a value supplied by the application when the database executes the statements. Bind variables can be considered parameters to the statement. DESCRIBE INPUT fills in the name fields in the SQLDA with the bind variable names. DESCRIBE INPUT also puts the number of bind variables in the sqld field of the SQLDA.

DESCRIBE uses the indicator variables in the SQLDA to provide additional information. DT_PROCEDURE_IN and DT_PROCEDURE_OUT are bits that are set in the indicator variable when a CALL statement is described. DT_PROCEDURE_IN indicates an IN or INOUT parameter and DT_PROCEDURE_OUT indicates an INOUT or OUT parameter. Procedure RESULT columns will have both bits clear. After a describe OUTPUT, these bits can be used to distinguish between statements that have result sets (need to use OPEN, FETCH, RESUME, CLOSE) and statements that do not (need to use EXECUTE). DESCRIBE INPUT only sets DT_PROCEDURE_IN and DT_PROCEDURE_OUT appropriately when a bind variable is an argument to a CALL statement; bind variables within an expression that is an argument in a CALL statement will not set the bits.

OUTPUT The DESCRIBE OUTPUT statement fills in the data type and length for each select list item in the SQLDA. The name field is also filled in with a name for the select list item. If an alias is specified for a select list item, the name will be that alias. Otherwise, the name will be derived from the select list item: if the item is a simple column name, it will be used; otherwise, a substring of the expression will be used. DESCRIBE will also put the number of select list items in the sqld field of the SQLDA.

If the statement being described is a UNION of two or more SELECT statements, the column names returned for DESCRIBE OUTPUT are the same column names which would be returned for the first SELECT statement.

If you describe a CALL statement, the DESCRIBE OUTPUT statement fills in the data type, length, and name in the SQLDA for each INOUT or OUT parameter in the procedure. DESCRIBE OUTPUT also puts the number of INOUT or OUT parameters in the sqld field of the SQLDA.

If you describe a CALL statement with a result set, the DESCRIBE OUTPUT statement fills in the data type, length, and name in the SQLDA for each RESULT column in the procedure definition. DESCRIBE OUTPUT will also put the number of result columns in the sqld field of the SQLDA.

LONG NAMES The LONG NAMES clause is provided to retrieve column names for a statement or cursor. Without this clause, there is a 29-character limit on the length of column names; with the clause, names of an arbitrary length are supported.

If LONG NAMES is used, the long names are placed into the SQLDATA field of the SQLDA, as if you were fetching from a cursor. None of the other fields (SQLLEN, SQLTYPE, and so on) are filled in. The SQLDA must be set up like a FETCH SQLDA: it must contain one entry for each column, and the entry must be a string type. If there is an indicator variable, truncation is indicated in the usual fashion.

The default specification for the long names is TABLE.COLUMN.

WITH VARIABLE RESULT This clause is used to describe procedures that may have more than one result set, with different numbers or types of columns.

If WITH VARIABLE RESULT is used, the database server sets the SQLCOUNT value after the DESCRIBE statement to one of the following values:

  • 0 The result set may change. The procedure call should be described again following each OPEN statement.

  • 1 The result set is fixed. No redescribing is required.

For more information on the use of the SQLDA structure, see The SQL descriptor area (SQLDA).

toggle Usage

The DESCRIBE statement sets up the named SQLDA to describe either the OUTPUT (equivalently SELECT LIST) or the INPUT (BIND VARIABLES) for the named statement.

In the INPUT case, DESCRIBE BIND VARIABLES does not set up the data types in the SQLDA: this needs to be done by the application. The ALL keyword allows you to describe INPUT and OUTPUT in one SQLDA.

If you specify a statement name, the statement must have been previously prepared using the PREPARE statement with the same statement name and the SQLDA must have been previously allocated (see the ALLOCATE DESCRIPTOR statement [ESQL]).

If you specify a cursor name, the cursor must have been previously declared and opened. The default action is to describe the OUTPUT. Only SELECT statements and CALL statements have OUTPUT. A DESCRIBE OUTPUT on any other statement, or on a cursor that is not a dynamic cursor, indicates no output by setting the sqld field of the SQLDA to zero.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • ALLOCATE DESCRIPTOR statement [ESQL]
  • DECLARE CURSOR statement [ESQL] [SP]
  • OPEN statement [ESQL] [SP]
  • PREPARE statement [ESQL]
toggle Standards and compatibility

  • SQL/92 Part of the SQL/92 standard. Some clauses are vendor extensions.

  • SQL/99 Core feature. Some clauses are vendor extensions.

  • Sybase Some clauses supported by Open Client/Open Server.

toggle Example

The following example shows how to use the DESCRIBE statement:

sqlda = alloc_sqlda( 3 );
EXEC SQL DESCRIBE OUTPUT
  FOR employee_statement
  INTO sqlda;
if( sqlda->sqld  >  sqlda->sqln ) {
  actual_size = sqlda->sqld;
  free_sqlda( sqlda );
  sqlda = alloc_sqlda( actual_size );
  EXEC SQL DESCRIBE OUTPUT
    FOR employee_statement
    INTO sqlda;
}


DISCONNECT statement [ESQL] [Interactive SQL]

toggle Description

Use this statement to drop the current connection to a database.

toggle Syntax

DISCONNECT [ connection-name | CURRENT | ALL ]

connection-name : identifier, string, or hostvar

toggle Usage

The DISCONNECT statement drops a connection with the database server and releases all resources used by it. If the connection to be dropped was named on the CONNECT statement, the name can be specified. Specifying ALL will drop all of the application's connections to all database environments. CURRENT is the default, and will drop the current connection.

An implicit ROLLBACK is executed on connections that are dropped.

For information on dropping connections other than the current connection, see DROP CONNECTION statement.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • CONNECT statement [ESQL] [Interactive SQL]
  • SET CONNECTION statement [Interactive SQL] [ESQL]
toggle Standards and compatibility

  • SQL/92 Intermediate-level feature.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Supported by Open Client/Open Server.

toggle Example

The following statement shows how to use DISCONNECT in Embedded SQL:

EXEC SQL DISCONNECT :conn_name

The following statement shows how to use DISCONNECT from Interactive SQL to disconnect all connections:

DISCONNECT ALL


DROP statement

toggle Description

Use this statement to remove objects from the database.

toggle Syntax

DROP
{ DATATYPE | DOMAIN } datatype-name
| DBSPACE dbspace-name
| EVENT event-name
| FUNCTION [ owner.]function-name
| INDEX [ [owner.]table-name.]index-name
| MESSAGE msgnum
| PROCEDURE [ owner.]procedure-name
| TABLE [ owner.]table-name
| TRIGGER [ [ owner.]table-name.]trigger-name
| VIEW [ owner.]view-name

toggle Usage

The DROP statement removes the definition of the indicated database structure. If the structure is a dbspace, all tables in that dbspace must be dropped prior to dropping the dbspace. If the structure is a table, all data in the table is automatically deleted as part of the dropping process. Also, all indexes and keys for the table are dropped by the DROP TABLE statement.

DROP TABLE, DROP INDEX, and DROP DBSPACE are prevented whenever the statement affects a table that is currently being used by another connection.

DROP PROCEDURE and DROP FUNCTION are prevented when the procedure or function is in use by another connection.

DROP DATATYPE is prevented if the data type is used in a table. You must change data types on all columns defined on the domain in order to drop the data type. It is recommended that you use DROP DOMAIN rather than DROP DATATYPE, as DROP DOMAIN is the syntax used in the ANSI/ISO SQL3 draft.

toggle Permissions

Any user who owns the object, or has DBA authority, can execute the DROP statement.

For DROP DBSPACE, you must be the only connection to the database.

A user with ALTER permissions on the table can execute DROP TRIGGER.

A user with REFERENCES permissions on the table can execute DROP INDEX.

Global temporary tables cannot be dropped unless all users that have referenced the temporary table have disconnected.

toggle Side effects

Automatic commit. Clears the Results tab in the Results pane in Interactive SQL. DROP TABLE and DROP INDEX close all cursors for the current connection.

DROP INDEX cannot be used to drop an index on a local temporary table. An attempt to do so will result in an Index not found error.

Local temporary tables is an exception; no commit is performed when one is dropped.

When a view is dropped, all procedures and triggers are unloaded from memory, so that any procedure or trigger that references the view reflects the fact that the view does not exist. The unloading and loading of procedures and triggers can have a performance impact if you are regularly dropping and creating views.

toggle See also
  • CREATE DATABASE statement
  • CREATE DOMAIN statement
  • CREATE INDEX statement
  • CREATE FUNCTION statement
  • CREATE PROCEDURE statement
  • CREATE TABLE statement
  • CREATE TRIGGER statement
  • CREATE VIEW statement
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Supported by Adaptive Server Enterprise for those objects that exist in Adaptive Server Enterprise.

toggle Example

  • Drop the department table from the database.

DROP TABLE department

Drop the emp_dept view from the database.

DROP VIEW emp_dept


DROP DATABASE statement

toggle Description

Use this statement to delete all database files associated with a database.

toggle Syntax

DROP DATABASE database-name [ KEY key ]

toggle Usage

The DROP DATABASE statement physically deletes all associated database files from disk. If the database file does not exist, or is not in a suitable condition for the database to be started, an error is generated.

DROP DATABASE cannot be used in a stored procedure.

toggle Permissions

Required permissions are set using the database server -gu option. The default setting is to require DBA authority.

The database must not be in use in order to be dropped.

You must specify a key if you want to drop a strongly encrypted database

Not supported on Windows CE.

toggle Side effects

In addition to deleting the database files from disk, any associated transaction log file or transaction log mirror file is deleted.

toggle See also
  • CREATE DATABASE statement
  • DatabaseKey connection parameter [DBKEY]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

Drop the database temp.db, in the C:\temp directory..

DROP DATABASE 'c:\temp\temp.db'


DROP CONNECTION statement

toggle Description

Use this statement to drop a connection to the database, belonging to any user.

toggle Syntax

DROP CONNECTION connection-id

toggle Usage

The DROP CONNECTION statement disconnects a user from the database by dropping the connection to the database.

You can obtain the connection-id by using the connection_property function to request the connection number. The following statement returns the connection ID of the current connection:

SELECT connection_property( 'number' )
toggle Permissions

Must have DBA authority.

toggle Side effects

None.

toggle See also
  • CONNECT statement [ESQL] [Interactive SQL]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement drops the connection with ID number 4.

DROP CONNECTION 4


DROP EXTERNLOGIN statement

toggle Description

Use this statement to drop an external login from the Adaptive Server Anywhere catalogs.

toggle Syntax

DROP EXTERNLOGIN login-name TO remote-server

toggle Parameters

DROP clause Specifies the local user login name

TO clause Specifies the name of the remote server. The local user's alternate login name and password for that server is the external login that is deleted.

toggle Usage

DROP EXTERNLOGIN deletes an external login from the Adaptive Server Anywhere catalogs.

toggle Permissions

Must be the owner of login-name or have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE EXTERNLOGIN statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Open Client/Open Server.

toggle Example
DROP EXTERNLOGIN DBA TO sybase1


DROP PUBLICATION statement

toggle Description

Use this statement to drop a publication. In MobiLink a publication identifies synchronized data in a Adaptive Server Anywhere remote database. In SQL Remote, publications identify replicated data in both consolidated and remote databases.

toggle Syntax

DROP PUBLICATION [ owner.]publication-name

owner, publication-name : identifier

toggle Usage

This statement is applicable only to MobiLink and SQL Remote.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit. All subscriptions to the publication are dropped.

toggle See also
  • ALTER PUBLICATION statement
  • CREATE PUBLICATION statement
  • sp_drop_publication procedure
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Example

The following statement drops the pub_contact publication.

DROP PUBLICATION pub_contact


DROP REMOTE MESSAGE TYPE statement [SQL Remote]

toggle Description

Use this statement to delete a message type definition from a database.

toggle Syntax

DROP REMOTE MESSAGE TYPE message-system

message-system: FILE | FTP | MAPI | SMTP | VIM

toggle Usage

The statement removes a message type from a database.

toggle Permissions

Must have DBA authority. To be able to drop the type, there must be no user granted REMOTE or CONSOLIDATE permissions with this type.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE REMOTE MESSAGE TYPE statement [SQL Remote]
  • sp_drop_remote_type procedure
  • Using message types.
toggle Example

The following statement drops the FILE message type from a database.

DROP REMOTE MESSAGE TYPE file


DROP SERVER statement

toggle Description

Use this statement to drop a remote server from the Adaptive Server Anywhere catalog.

toggle Syntax

DROP SERVER server-name

toggle Usage

DROP SERVER deletes a remote server from the Adaptive Server Anywhere catalogs. You must drop all the proxy tables that have been defined for the remote server before this statement will succeed.

toggle Permissions

Only the DBA account can delete a remote server.

Not supported on Windows CE.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE SERVER statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Open Client/Open Server.

toggle Example
DROP SERVER ase_prod


DROP SERVICE statement

toggle Description

Use this statement to permit a database server to act as a web server.

toggle Syntax

DROP SERVICE service-name

toggle Usage

This statement deletes a web service.

toggle Permissions

Must have DBA authority.

toggle Side effects

None.

toggle See also
  • ALTER SERVICE statement, CREATE SERVICE statement
toggle Example

To drop a web service named tables, execute the following statement:

CREATE SERVICE tables


DROP STATEMENT statement [ESQL]

toggle Description

Use this statement to free statement resources.

toggle Syntax

DROP STATEMENT [ owner.]statement-name

statement-name : identifier | hostvar

toggle Usage

The DROP STATEMENT statement frees resources used by the named prepared statement. These resources are allocated by a successful PREPARE statement, and are normally not freed until the database connection is released.

toggle Permissions

Must have prepared the statement.

toggle Side effects

None.

toggle See also
  • PREPARE statement [ESQL]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported in Open Client/Open Server

toggle Example

The following are examples of DROP STATEMENT use:

EXEC SQL DROP STATEMENT S1;
EXEC SQL DROP STATEMENT :stmt;


DROP STATISTICS statement

toggle Description

Use this statement to erase all optimizer statistics on the specified columns.

toggle Syntax

DROP STATISTICS [ ON ] [owner.]table-name [ ( column-list ) ]

toggle Usage

The Adaptive Server Anywhere optimizer uses statistical information to determine the best strategy for executing each statement. Adaptive Server Anywhere automatically gathers and updates these statistics. These statistics are stored permanently in the database in the system table SYSCOLSTAT. Statistics gathered while processing one statement are available when searching for efficient ways to execute subsequent statements.

Occasionally, the statistics may become inaccurate or relevant statistics may be unavailable. This condition is most likely to arise when few queries have been executed since a large amount of data was added, updated, or deleted.

The DROP STATISTICS statement deletes all internal statistical data from the system table SYSCOLSTAT for the specified columns. This drastic step leaves the optimizer with no access to essential statistical information. Without these statistics, the optimizer may generate very inefficient data access plans, causing poor database performance.

This statement should be used only during problem determination or when reloading data into a database that differs substantially from the original data.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE STATISTICS statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.


DROP SUBSCRIPTION statement [SQL Remote]

toggle Description

Use this statement to drop a subscription for a user from a publication.

toggle Syntax

DROP SUBSCRIPTION TO publication-name [ ( subscription-value ) ]
FOR subscriber-id, ...

subscription-value: string

subscriber-id: string

toggle Parameters

publication-name The name of the publication to which the user is being subscribed. This may include the owner of the publication.

subscription-value A string that is compared to the subscription expression of the publication. This value is required because a user may have more than one subscription to a publication.

subscriber-id The user ID of the subscriber to the publication.

toggle Usage

Drops a SQL Remote subscription for a user ID to a publication in the current database. The user ID will no longer receive updates when data in the publication is changed.

In SQL Remote, publications and subscriptions are two-way relationships. If you drop a subscription for a remote user to a publication on a consolidated database, you should also drop the subscription for the consolidated database on the remote database to prevent updates on the remote database being sent to the consolidated database.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Adaptive Server Anywhere version 7.0.

toggle See also
  • CREATE SUBSCRIPTION statement [SQL Remote]
toggle Example

The following statement drops a subscription for the user ID SamS to the publication pub_contact.

DROP SUBSCRIPTION TO pub_contact
FOR SamS


DROP SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]

toggle Description

Use this statement to drop a synchronization subscription within a MobiLink remote database or a MobiLink reference database. You can also use it to drop a default subscription, which contains default subscription values, for the specified publication.

toggle Syntax

DROP SYNCHRONIZATION SUBSCRIPTION
TO publication-name
[ FOR ml_username, ... ]

toggle Parameters

TO clause Specify the name of a publication.

FOR clause Specify one more MobiLink users.

Omitting this clause drops the default subscription for the publication. MobiLink users subscribed to a publication inherit as defaults the values in a default publication.

toggle Usage

Drop a synchronization subscription in a MobiLink remote or reference database.

toggle Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the publication.

toggle Side Effects

Automatic commit.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Examples

Unsubscribe MobiLink user ml_user1 to the sales publication.

DROP SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR "ml_user1"

Drop the default subscription, which contains default subscription values, for the sales publication (by omitting the FOR clause).

DROP SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication


DROP SYNCHRONIZATION USER statement [MobiLink]

toggle Description

Use this statement to drop a synchronization user from a MobiLink remote database.

toggle Syntax

DROP SYNCHRONIZATION USER ml_username, ...

ml_username: identifier

toggle Usage

Drop one or more synchronization users from a MobiLink remote database.

toggle Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the publication.

toggle Side Effects

All subscriptions associated with the user are also deleted.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Example

Remove MobiLink user ml_user1 from the database.

DROP SYNCHRONIZATION USER ml_user1


DROP VARIABLE statement

toggle Description

Use this statement to eliminate a SQL variable.

toggle Syntax

DROP VARIABLE identifier

toggle Usage

The DROP VARIABLE statement eliminates a SQL variable that was previously created using the CREATE VARIABLE statement. Variables will be automatically eliminated when the database connection is released. Variables are often used for large objects, so eliminating them after use or setting them to NULL may free up significant resources (primarily disk space).

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • CREATE VARIABLE statement
  • SET statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported in Adaptive Server Enterprise.


EXCEPT operation

toggle Description

Computes the difference between the result sets of two or more queries.

toggle Syntax

select-statement
EXCEPT [ ALL | DISTINCT ] select-statement
[ EXCEPT [ ALL | DISTINCT ] select-statement ] ...
[ ORDER BY [ integer | select-list-expression-name ] [ ASC | DESC ], ... ]

toggle Usage

The differences between the result sets of several SELECT statements can be obtained as a single result using EXCEPT or EXCEPT ALL. EXCEPT DISTINCT is identical to EXCEPT.

The component SELECT statements must each have the same number of items in the select list, and cannot contain an ORDER BY clause.

The number of rows in the result set of EXCEPT ALL is exactly the difference between the number of rows in the result sets of the separate queries.

The results of EXCEPT are the same as EXCEPT ALL, except that when using EXCEPT, duplicate rows are eliminated before the difference between the result sets is computed.

If corresponding items in two select lists have different data types, Adaptive Server Anywhere will choose a data type for the corresponding column in the result and automatically convert the columns in each component SELECT statement appropriately. The first query specification of the UNION is used to determine the names to be matched with the ORDER BY clause.

The column names displayed are the same column names that are displayed for the first SELECT statement. An alternative way of customizing result set column names is to use the WITH clause on the SELECT statement.

toggle Permissions

Must have SELECT permission for each of the component SELECT statements.

toggle Side effects

None

toggle See also

INTERSECT operation

UNION operation

toggle Standards and compatibility

  • SQL/92 Entry-level.

  • SQL/99 EXCEPT DISTINCT is a core feature. EXCEPT ALL is feature F304.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Example

For examples of EXCEPT usage, see Set operators and NULL.


EXECUTE statement [ESQL]

toggle Description

Use this statement to execute a prepared SQL statement.

toggle Syntax 1

EXECUTE statement
[ USING { hostvar-list | DESCRIPTOR sqlda-name } ]
[ INTO { into-hostvar-list | DESCRIPTOR into-sqlda-name } ]
[ ARRAY :integer ]

statement : { identifier | hostvar | string }

sqlda-name : identifier

into-sqlda-name : identifier

toggle Syntax 2

EXECUTE IMMEDIATE statement

statement : { string | hostvar }

toggle Parameters

USING clause Results from a SELECT statement or a CALL statement are put into either the variables in the variable list or the program data areas described by the named SQLDA. The correspondence is one-to-one from the OUTPUT (selection list or parameters) to either the host variable list or the SQLDA descriptor array.

INTO clause If EXECUTE INTO is used with an INSERT statement, the inserted row is returned in the second descriptor. For example, when using auto-increment primary keys or BEFORE INSERT triggers that generate primary key values, the EXECUTE statement provides a mechanism to re-fetch the row immediately and determine the primary key value that was assigned to the row. The same thing can be achieved by using @@identity with auto-increment keys.

ARRAY clause The optional ARRAY clause can be used with prepared INSERT statements to allow wide inserts, which insert more than one row at a time and which may improve performance. The integer value is the number of rows to be inserted. The SQLDA must contain a variable for each entry (number of rows * number of columns). The first row is placed in SQLDA variables 0 to (columns per row)-1, and so on.

toggle Usage

The EXECUTE statement can be used for any SQL statement that can be prepared. Cursors are used for SELECT statements or CALL statements that return many rows from the database (see Using cursors in embedded SQL).

After successful execution of an INSERT, UPDATE or DELETE statement, the sqlerrd[2] field of the SQLCA (SQLCOUNT) is filled in with the number of rows affected by the operation.

Syntax 1 Execute the named dynamic statement, which was previously prepared. If the dynamic statement contains host variable place holders which supply information for the request (bind variables), either the sqlda-name must specify a C variable which is a pointer to an SQLDA containing enough descriptors for all of the bind variables occurring in the statement, or the bind variables must be supplied in the hostvar -list.

Syntax 2 A short form to PREPARE and EXECUTE a statement that does not contain bind variables or output. The SQL statement contained in the string or host variable is immediately executed, and is dropped on completion.

toggle Permissions

Permissions are checked on the statement being executed.

toggle Side effects

None.

toggle See also
  • EXECUTE IMMEDIATE statement [SP]
  • PREPARE statement [ESQL]
  • DECLARE CURSOR statement [ESQL] [SP]
toggle Standards and compatibility

  • SQL/92 Intermediate-level feature.

  • SQL/99 Feature outside of core SQL.

  • Sybase Supported in Open Client/Open Server.

toggle Example

Execute a DELETE.

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

Execute a prepared DELETE statement.

EXEC SQL PREPARE del_stmt FROM
'DELETE FROM employee WHERE emp_id = :a';
EXEC SQL EXECUTE del_stmt USING :employee_number;

Execute a prepared query.

EXEC SQL PREPARE sel1 FROM
'SELECT emp_lname FROM employee WHERE emp_id = :a';
EXEC SQL EXECUTE sel1 USING :employee_number INTO :emp_lname;


EXECUTE statement [T-SQL]

toggle Description

Use Syntax 1 to invoke a procedure, as an Adaptive Server Enterprise-compatible alternative to the CALL statement. You can also execute statements within Transact-SQL stored procedures and triggers. For more information, see EXECUTE IMMEDIATE statement [SP]. Use Syntax 2 to execute a prepared SQL statement in Transact-SQL.

toggle Syntax 1

EXECUTE [ @return_status = ] [creator.]procedure_name [ argument, ... ]

argument :
[ @parameter-name = ] expression
| [ @parameter-name = ] @variable [ output ]

toggle Syntax 2

EXECUTE ( string-expression )

toggle Usage

Syntax 1 executes a stored procedure, optionally supplying procedure parameters and retrieving output values and return status information.

The EXECUTE statement is implemented for Transact-SQL compatibility, but can be used in either Transact-SQL or Watcom-SQL batches and procedures.

With Syntax 2, you can execute statements within Transact-SQL stored procedures and triggers. The EXECUTE statement extends the range of statements that can be executed from within procedures and triggers. It lets you execute dynamically prepared statements, such as statements that are constructed using the parameters passed in to a procedure. Literal strings in the statement must be enclosed in single quotes, and the statement must be on a single line.

toggle Permissions

Must be the owner of the procedure, have EXECUTE permission for the procedure, or have DBA authority.

toggle Side effects

None.

toggle See also
  • CALL statement
  • EXECUTE statement [ESQL]
  • EXECUTE IMMEDIATE statement [SP]
toggle Example

The following procedure illustrates Syntax 1.

CREATE PROCEDURE p1( @var INTEGER = 54 )
AS
PRINT 'on input @var = %1!', @var
DECLARE @intvar integer
SELECT @intvar=123
SELECT @var=@intvar
PRINT 'on exit @var = %1!', @var

The following statement executes the procedure, supplying the input value of 23 for the parameter. If you are connected from an Open Client or JDBC application, the PRINT messages are displayed on the client window. If you are connected from an ODBC or Embedded SQL application, the messages are displayed on the database server window.

EXECUTE p1 23

The following is an alternative way of executing the procedure, which is useful if there are several parameters.

EXECUTE p1 @var = 23

The following statement executes the procedure, using the default value for the parameter

EXECUTE p1

The following statement executes the procedure, and stores the return value in a variable for checking return status.

EXECUTE @status = p1 23


EXECUTE IMMEDIATE statement [SP]

toggle Description

Use this statement to enable dynamically-constructed statements to be executed from within a procedure.

toggle Syntax 1

EXECUTE IMMEDIATE [ execute-option ] string-expression

execute-option:
WITH QUOTES [ ON | OFF ]
| WITH ESCAPES { ON | OFF }
| WITH RESULT SET { ON | OFF }

toggle Syntax 2

EXECUTE ( string-expression )

toggle Parameters

WITH QUOTES When you specify WITH QUOTES or WITH QUOTES ON, any double quotes in the string expression are assumed to delimit an identifier. When you do not specify WITH QUOTES, or specify WITH QUOTES OFF, the treatment of double quotes in the string expression depends on the current setting of the QUOTED_IDENTIFIER option.

WITH QUOTES is useful when an object name that is passed into the stored procedure is used to construct the statement that is to be executed, but the name might require double quotes and the procedure might be called when QUOTED_IDENTIFIER is set to OFF.

For more information, see the QUOTED_IDENTIFIER option [compatibility].

WITH ESCAPES WITH ESCAPES OFF causes any escape sequences (such as \n, \x, or \\) in the string expression to be ignored. For example, two consecutive backslashes remain as two backslashes, rather than being converted to a single backslash. The default setting is equivalent to WITH ESCAPES ON.

One use of WITH ESCAPES OFF is for easier execution of dynamically-constructed statements referencing filenames that contain backslashes.

In some contexts, escape sequences in the string-expression are transformed before the EXECUTE IMMEDIATE statement is executed. For example, compound statements are parsed before being executed, and escape sequences are transformed during this parsing, regardless of the WITH ESCAPES setting. In these contexts, WITH ESCAPES OFF prevents further translations from occurring. For example:

BEGIN
   DECLARE String1 LONG VARCHAR;
   DECLARE String2 LONG VARCHAR;
   EXECUTE IMMEDIATE
        'SET String1 = ''One backslash: \\\\ ''';
     EXECUTE IMMEDIATE WITH ESCAPES OFF
        'SET String2 = ''Two backslashes: \\\\ ''';
   SELECT String1, String2
END

WITH RESULT SET You can have an EXECUTE IMMEDIATE statement return a result set by specifying WITH RESULT SET ON. With this clause, the containing procedure is marked as returning a result set. If you do not include this clause, an error is reported when the procedure is called if the statement produces a result set.

Note
The default option is WITH RESULT SET OFF, meaning that no result set is produced when the statement is executed.
toggle Usage

The EXECUTE statement extends the range of statements that can be executed from within procedures and triggers. It lets you execute dynamically-prepared statements, such as statements that are constructed using the parameters passed in to a procedure.

Literal strings in the statement must be enclosed in single quotes, and the statement must be on a single line.

Only global variables can be referenced in a statement executed by EXECUTE IMMEDIATE.

Only syntax 2 can be used inside Transact-SQL stored procedures and triggers.

toggle Permissions

None. The statement is executed with the permissions of the owner of the procedure, not with the permissions of the user who calls the procedure.

toggle Side effects

None. However, if the statement is a data definition statement with an automatic commit as a side effect, that commit does take place.

For more information about using the EXECUTE IMMEDIATE statement in procedures, see Using the EXECUTE IMMEDIATE statement in procedures.

toggle See also
  • CREATE PROCEDURE statement
  • BEGIN statement
  • EXECUTE statement [ESQL]
toggle Standards and compatibility

  • SQL/92 Intermediate-level feature.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Supported in Open Client/Open Server.

toggle Examples

The following procedure creates a table, where the table name is supplied as a parameter to the procedure. The EXECUTE IMMEDIATE statement must all be on a single line.

CREATE PROCEDURE CreateTableProc(
                  IN tablename char(30)
                  )
BEGIN
   EXECUTE IMMEDIATE
   'CREATE TABLE ' || tablename ||
   ' ( column1 INT PRIMARY KEY)'
END

To call the procedure and create a table called mytable:

CALL CreateTableProc( 'mytable' )

For an example of EXECUTE IMMEDIATE with a query that returns a result set, see Using the EXECUTE IMMEDIATE statement in procedures.


EXIT statement [Interactive SQL]

toggle Description

Use this statement to leave Interactive SQL.

toggle Syntax

{ EXIT | QUIT | BYE } [ return-code ]

return-code: number | connection-variable

toggle Usage

This statement closes your connection with the database, then closes the Interactive SQL environment. Before closing the database connection, Interactive SQL automatically executes a COMMIT statement if the COMMIT_ON_EXIT option is set to ON. If this option is set to OFF, Interactive SQL performs an implicit ROLLBACK. By default, the COMMIT_ON_EXIT option is set to ON.

The optional return code can be used in batch files to indicate success or failure of the commands in an Interactive SQL command file. The default return code is 0.

toggle Permissions

None.

toggle Side effects

This statement automatically performs a commit if option COMMIT_ON_EXIT is set to ON (the default); otherwise it performs an implicit rollback.

On Windows operating systems the optional return value is available as ERRORLEVEL.

toggle See also
  • SET OPTION statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable in Adaptive Server Enterprise.

toggle Examples

The following example sets the Interactive SQL return value to 1 if there are any rows in table T, or to 0 if T contains no rows.

CREATE VARIABLE rowCount INT;
CREATE VARIABLE retcode INT;
SELECT COUNT(*) INTO rowCount FROM T;
IF( rowCount > 0 ) THEN
    SET retcode = 1;
ELSE
    SET retcode = 0;
END IF;
EXIT retcode;
Note
You cannot write the following the statement
CREATE VARIABLE rowCount INT;
SELECT COUNT(*) INTO rowCount FROM T;
IF( rowCount > 0 ) THEN
    EXIT 1;        //  <-- not allowed
ELSE
    EXIT 0;    //  <-- not allowed
END IF;

because EXIT is an Interactive SQL statement (not a SQL statement), and you cannot include any Interactive SQL statement in other SQL block statements.

The following Windows batch file prints Error = 1 on the command prompt.

dbisql -c "dsn=ASA 9.0 Sample" EXIT 1
if errorlevel 1 echo "Errorlevel is 1"


EXPLAIN statement [ESQL]

toggle Description

Use this statement to retrieve a text specification of the optimization strategy used for a particular cursor.

toggle Syntax

EXPLAIN PLAN FOR CURSOR cursor-name
{ INTO hostvar | USING DESCRIPTOR sqlda-name }

cursor-name : identifier or hostvar

sqlda-name : identifier

toggle Usage

The EXPLAIN statement retrieves a text representation of the optimization strategy for the named cursor. The cursor must be previously declared and opened.

The hostvar or sqlda-name variable must be of string type. The optimization string specifies in what order the tables are searched, and also which indexes are being used for the searches if any.

This string may be long, depending on the query, and has the following format:

table (index), table (index), ...

If a table has been given a correlation name, the correlation name will appear instead of the table name. The order that the table names appear in the list is the order in which they will be accessed by the database server. After each table is a parenthesized index name. This is the index that will be used to access the table. If no index will be used (the table will be scanned sequentially) the letters "seq" will appear for the index name. If a particular SQL SELECT statement involves subqueries, a colon (:) will separate each subquery's optimization string. These subquery sections will appear in the order that the database server executes the queries.

After successful execution of the EXPLAIN statement, the sqlerrd[3] field of the SQLCA (SQLIOESTIMATE) will be filled in with an estimate of the number of input/output operations required to fetch all rows of the query.

A discussion with quite a few examples of the optimization string can be found in Monitoring and Improving Performance.

toggle Permissions

Must have opened the named cursor.

toggle Side effects

None.

toggle See also
  • DECLARE CURSOR statement [ESQL] [SP]
  • PREPARE statement [ESQL]
  • FETCH statement [ESQL] [SP]
  • CLOSE statement [ESQL] [SP]
  • OPEN statement [ESQL] [SP]
  • Using cursors in embedded SQL
  • The SQL Communication Area (SQLCA)
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported in Adaptive Server Enterprise.

toggle Example

The following example illustrates the use of EXPLAIN:

EXEC SQL BEGIN DECLARE SECTION;
char plan[300];
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE employee_cursor CURSOR FOR
   SELECT emp_id, emp_lname
   FROM employee
   WHERE emp_lname like :pattern;
EXEC SQL OPEN employee_cursor;
EXEC SQL EXPLAIN PLAN FOR CURSOR employee_cursor INTO :plan;
printf( "Optimization Strategy: '%s'.n", plan );

The plan variable contains the following string:

'employee <seq>'


FETCH statement [ESQL] [SP]

toggle Description

Use this statement to reposition a cursor and then get data from it.

toggle Syntax

FETCH cursor-position cursor-name
[ INTO { hostvar-list | variable-list }
| USING DESCRIPTOR sqlda-name ]
[ PURGE ]
[ BLOCK n ]
[ FOR UPDATE ]
[ ARRAY fetch-count ]
INTO variable-list [ FOR UPDATE ]

cursor-position :
NEXT | PRIOR | FIRST | LAST
| { ABSOLUTE | RELATIVE } row-count

row-count : number or hostvar

cursor-name : identifier or hostvar

hostvar-list : may contain indicator variables

variable-list : stored procedure variables

sqlda-name : identifier

fetch-count : integer or hostvar

toggle Parameters

INTO The INTO clause is optional. If it is not specified, the FETCH statement positions the cursor only. The hostvar-list is for Embedded SQL use only.

cursor position An optional positional parameter allows the cursor to be moved before a row is fetched. If the fetch includes a positioning parameter and the position is outside the allowable cursor positions, the SQLE_NOTFOUND warning is issued and the SQLCOUNT field indicates the offset from a valid position.

The OPEN statement initially positions the cursor before the first row.

  • NEXT Next is the default positioning, and causes the cursor to be advanced one row before the row is fetched.

  • PRIOR Causes the cursor to be backed up one row before fetching.

  • RELATIVE RELATIVE positioning is used to move the cursor by a specified number of rows in either direction before fetching. A positive number indicates moving forward and a negative number indicates moving backwards. Thus, a NEXT is equivalent to RELATIVE 1 and PRIOR is equivalent to RELATIVE -1. RELATIVE 0 retrieves the same row as the last fetch statement on this cursor.

  • ABSOLUTE The ABSOLUTE positioning parameter is used to go to a particular row. A zero indicates the position before the first row (see Using cursors in procedures and triggers).

    A one (1) indicates the first row, and so on. Negative numbers are used to specify an absolute position from the end of the cursor. A negative one (-1) indicates the last row of the cursor.

  • FIRST A short form for ABSOLUTE 1.

  • LAST A short form for ABSOLUTE -1.

Cursor positioning problems
Inserts and some updates to DYNAMIC SCROLL cursors can cause problems with cursor positioning. The database server does not put inserted rows at a predictable position within a cursor unless there is an ORDER BY clause on the SELECT statement. In some cases, the inserted row does not appear at all until the cursor is closed and opened again.

This occurs if a temporary table had to be created to open the cursor (see Use of work tables in query processing for a description).

The UPDATE statement may cause a row to move in the cursor. This will happen if the cursor has an ORDER BY that uses an existing index (a temporary table is not created).

BLOCK clause Rows may be fetched by the client application more than one at a time. This is referred to as block fetching, prefetching, or multi-row fetching. The first fetch causes several rows to be sent back from the server. The client buffers these rows, and subsequent fetches are retrieved from these buffers without a new request to the server.

The BLOCK clause is for use in Embedded SQL only. It gives the client and server a hint as to how many rows may be fetched by the application. The special value of 0 means the request will be sent to the server and a single row will be returned (no row blocking). The BLOCK clause will reduce the number of rows included in the next prefetch to the BLOCK value. To increase the number of rows prefetched, use the PrefetchRows connection parameter.

If no BLOCK clause is specified, the value specified on OPEN is used. For more information, see OPEN statement [ESQL] [SP].

FETCH RELATIVE 0 always re-fetches the row.

PURGE clause The PURGE clause is for use in embedded SQL only. It causes the client to flush its buffers of all rows, and then send the fetch request to the server. Note that this fetch request may return a block of rows.

FOR UPDATE clause The FOR UPDATE clause indicates that the fetched row will subsequently be updated with an UPDATE WHERE CURRENT OF CURSOR statement. This clause causes the database server to put a write lock on the row. The lock will be held until the end of the current transaction. See How locking works.

ARRAY clause The ARRAY clause is for use in Embedded SQL only. It allows so-called wide fetches, which retrieve more than one row at a time, and which may improve performance.

To use wide fetches in embedded SQL, include the fetch statement in your code as follows:

EXEC SQL FETCH . . . ARRAY nnn

where ARRAY nnn is the last item of the FETCH statement. The fetch count nnn can be a host variable. The SQLDA must contain nnn * (columns per row) variables. The first row is placed in SQLDA variables 0 to (columns per row)-1, and so on.

For a detailed example of using wide fetches, see the section Fetching more than one row at a time.

toggle Usage

The FETCH statement retrieves one row from the named cursor. The cursor must have been previously opened.

Embedded SQL use A DECLARE CURSOR statement must appear before the FETCH statement in the C source code, and the OPEN statement must be executed before the FETCH statement. If a host variable is being used for the cursor name, the DECLARE statement actually generates code and thus must be executed before the FETCH statement.

The server returns in SQLCOUNT the number of records fetched, and always returns a SQLCOUNT greater than zero unless there is an error or warning. A SQLCOUNT of zero with no error condition indicates that one valid row has been fetched.

If the SQLSTATE_NOTFOUND warning is returned on the fetch, the sqlerrd[2] field of the SQLCA (SQLCOUNT) contains the number of rows by which the attempted fetch exceeded the allowable cursor positions. The value is 0 if the row was not found but the position is valid; for example, executing FETCH RELATIVE 1 when positioned on the last row of a cursor. The value is positive if the attempted fetch was beyond the end of the cursor, and negative if the attempted fetch was before the beginning of the cursor.

After successful execution of the fetch statement, the sqlerrd[1] field of the SQLCA (SQLIOCOUNT) is incremented by the number of input/output operations required to perform the fetch. This field is actually incremented on every database statement.

Single row fetch One row from the result of the SELECT statement is put into the variables in the variable list. The correspondence is one-to-one from the select list to the host variable list.

Multi-row fetch One or more rows from the result of the SELECT statement are put into either the variables in variable-list or the program data areas described by sqlda-name. In either case, the correspondence is one-to-one from the select-list to either the hostvar-list or the sqlda-name descriptor array.

toggle Permissions

The cursor must be opened, and the user must have SELECT permission on the tables referenced in the declaration of the cursor.

toggle Side effects

None.

toggle See also
  • DECLARE CURSOR statement [ESQL] [SP]
  • PREPARE statement [ESQL]
  • OPEN statement [ESQL] [SP]
  • Using cursors in embedded SQL
  • Using cursors in procedures and triggers
  • FETCH in PowerScript Reference
toggle Standards and compatibility

  • SQL/92 Entry-level feature. Use in procedures is a Persistent Stored Module feature.

  • SQL/99 Core feature. Use in procedures is a Persistent Stored Module feature.

  • Sybase Supported in Adaptive Server Enterprise.

toggle Example

The following is an Embedded SQL example.

EXEC SQL DECLARE cur_employee CURSOR FOR
SELECT emp_id, emp_lname FROM employee;
EXEC SQL OPEN cur_employee;
EXEC SQL FETCH cur_employee
INTO :emp_number, :emp_name:indicator;

The following is a procedure example:

BEGIN
   DECLARE cur_employee CURSOR FOR
      SELECT emp_lname
      FROM employee;
   DECLARE name CHAR(40);
   OPEN cur_employee;
   LOOP
      FETCH NEXT cur_employee into name;
       ...
   END LOOP
   CLOSE cur_employee;
END


FOR statement

toggle Description

Use this statement to repeat the execution of a statement list once for each row in a cursor.

toggle Syntax

[ statement-label : ]
FOR for-loop-name AS cursor-name
CURSOR FOR statement
[ FOR UPDATE | FOR READ ONLY ]
DO statement-list
END FOR [ statement-label ]

toggle Usage

The FOR statement is a control statement that allows you to execute a list of SQL statements once for each row in a cursor. The FOR statement is equivalent to a compound statement with a DECLARE for the cursor and a DECLARE of a variable for each column in the result set of the cursor followed by a loop that fetches one row from the cursor into the local variables and executes statement-list once for each row in the cursor.

Valid cursor types include dynamic scroll (default), scroll, no scroll, sensitive, and insensitive.

The name and data type of each local variable is derived from the statement used in the cursor. With a SELECT statement, the data types will be the data types of the expressions in the select list. The names will be the select list item aliases, if they exist; otherwise, they will be the names of the columns. Any select list item that is not a simple column reference must have an alias. With a CALL statement, the names and data types will be taken from the RESULT clause in the procedure definition.

The LEAVE statement can be used to resume execution at the first statement after the END FOR. If the ending statement-label is specified, it must match the beginning statement-label.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • DECLARE CURSOR statement [ESQL] [SP]
  • FETCH statement [ESQL] [SP]
  • LEAVE statement
  • LOOP statement
toggle Standards and compatibility

  • SQL/92 Persistent Stored Module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following fragment illustrates the use of the FOR loop.

FOR names AS curs CURSOR FOR
SELECT emp_lname
FROM employee
DO
   CALL search_for_name( emp_lname );
END FOR;


FORWARD TO statement

toggle Description

Use this statement to send native syntax SQL statements to a remote server.

toggle Syntax 1

FORWARD TO server-name sql-statement

toggle Syntax 2

FORWARD TO [ server-name ]

toggle Usage

The FORWARD TO statement enables users to specify the server to which a passthrough connection is required. The statement can be used in two ways:

  • Syntax 1 Send a single statement to a remote server.

  • Syntax 2 Place Adaptive Server Anywhere into passthrough mode for sending a series of statements to a remote server. All subsequent statements are passed directly to the remote server. To turn passthrough mode off, issue FORWARD TO without a server-name specification.

    If you encounter an error from the remote server while in passthrough mode, you must still issue a FORWARD TO statement to turn passthrough off.

When establishing a connection to server-name on behalf of the user, the server uses:

  • A remote login alias set using CREATE EXTERNLOGIN, or

  • If a remote login alias is not set up, the name and password used to communicate with Adaptive Server Anywhere

If the connection cannot be made to the server specified, the reason is contained in a message returned to the user.

After statements are passed to the requested server, any results are converted into a form that can be recognized by the client program.

server-name The name of the remote server.

SQL-statement A command in the native SQL syntax of the remote server. The command or group of commands is enclosed in curly brackets ({}).

Note
The FORWARD TO statement is a server directive and cannot be used within procedures or batches.
toggle Permissions

None

toggle Side effects

The remote connection is set to AUTOCOMMIT (unchained) mode for the duration of the FORWARD TO session. Any work that was pending prior to the FORWARD TO statement is automatically committed.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Open Client/Open Server.

toggle Example

The following example shows a passthrough session with the remote server ase_prod:

FORWARD TO aseprod
  'SELECT * FROM titles;  SELECT * FROM authors';
FORWARD TO


FROM clause

toggle Description

Use this clause to specify the database tables or views involved in a SELECT, UPDATE, or DELETE statement.

toggle Syntax

FROM table-expression, ...

table-expression:
table
| view
| procedure
| derived-table
| lateral-derived-table
| joined table
| ( table-expression, ... )

table :
[ userid.] table-name
[ [ AS ] correlation-name ]
[ WITH ( table-hint | INDEX ( index-name ) ) | FORCE INDEX ( index-name ) ]

view :
[ userid.] view-name [ [ AS ] correlation-name ]
[ WITH ( table-hint ) ]

procedure :
[ owner.]procedure-name ( [ parameter, ... ] )
[ WITH( column-name data-type, ... ) ]
[ [ AS ] correlation-name ]

derived-table :
( select-statement )
[ AS ] correlation-name [ ( column-name, ... ) ]

lateral-derived-table :
LATERAL ( select-statement | table-expression )
[ AS ] correlation-name [ ( column-name, ... ) ]

joined table:
table-expression join-operator table-expression
[ ON join-condition ]

join-operator :
[ KEY | NATURAL ] [ join-type ] JOIN
| CROSS JOIN

join-type:
INNER
| LEFT [ OUTER ]
| RIGHT [ OUTER ]
| FULL [ OUTER ]

table-hint:
NOLOCK
| XLOCK
| READUNCOMMITTED
| READCOMMITTED
| REPEATABLEREAD
| HOLDLOCK
| SERIALIZABLE
| FASTFIRSTROW

toggle Parameters

table A base table or temporary table. Tables owned by a different user can be qualified by specifying the user ID. Tables owned by groups to which the current user belongs will be found by default without specifying the user ID (see Referring to tables owned by groups).

The WITH ( INDEX ( index-name ) ) or the equivalent FORCE INDEX ( index-name ) clauses specify index hints for the table. It overrides the query optimizer plan selection algorithms, requiring the optimized query to access the table using the specified index, regardless of other access plans that may be available. You can specify only one index hint per correlation name. You can specify index hints only on base tables or temporary tables.

Advanced feature
Index hints override the query optimizer, and so should be used only by experienced users. Using index hints may lead to suboptimal access plans and hence to poor performance.

view Specifies a view to include in the query. As with tables, views owned by a different user can be qualified by specifying the user ID. Views owned by groups to which the current user belongs are found by default without specifying the user ID.

Although the syntax permits table hints on views, such hints have no effect.

procedure A stored procedure that returns a result set. Procedures can be used only in the FROM clause of SELECT statements, not UPDATE or DELETE statements. The parentheses following the procedure name are required even if the procedure does not take parameters. If the stored procedure returns multiple result sets, only the first is used.

The WITH clause provides a way of specifying column name aliases for the procedure result set. If a WITH clause is specified, the number of columns must match the number of columns in the procedure result set, and the data types must be compatible with those in the procedure result set. If no WITH clause is specified, the column names and types are those defined by the procedure definition. The following query illustrates the use of the WITH clause:

SELECT sp.customer, sp.quantity, product.name
FROM sp_customer_products( 149 ) WITH ( customer int, quantity int ) sp
   JOIN product
ON sp.customer = product.id

derived-table You can supply SELECT statements instead of table or view names in the FROM clause. This allows you to use groups on groups, or joins with groups, without creating a view. The tables that you create in this way are derived tables.

lateral-derived-table A derived table, stored procedure, or joined table that may include outer references. You must use a lateral derived table if you wish to use an outer reference in the FROM clause. For information about outer references, see Outer references.

You can use outer references only to tables that precede the lateral derived table in the FROM clause. For example, you cannot use an outer reference to an item in the select-list.

The table and the outer reference must be separated by a comma. For example, the following queries (with outer references highlighted) are valid:

SELECT *
FROM A, LATERAL( B LEFT OUTER JOIN C ON ( A.x = B.x ) ) LDT
SELECT *
FROM A, LATERAL( SELECT * FROM B WHERE A.x = B.x ) LDT
SELECT *
FROM A, LATERAL( procedure-name( A.x ) ) LDT

correlation-name An identifier to use when referencing an object elsewhere in the statement.

If the same correlation name is used twice for the same table in a table expression, that table is treated as if it were listed only once. For example, in:

SELECT *
FROM sales_order
KEY JOIN sales_order_items,
sales_order
KEY JOIN employee

the two instances of the sales_order table are treated as one instance, and so is equivalent to:

SELECT *
FROM sales_order
KEY JOIN sales_order_items
KEY JOIN employee

Whereas:

SELECT *
FROM Person HUSBAND, Person WIFE

would be treated as two instances of the Person table, with different correlation names HUSBAND and WIFE.

WITH table-hint allows you to specify the behavior of Adaptive Server Anywhere to be used only for this table, and only for this statement. You can use WITH table-hint to change Adaptive Server Anywhere's behavior without changing the isolation level or setting a database or connection option. Table hints can be used only on base tables and temporary tables.

Caution WITH table-hint is an advanced feature that should be used only if needed, and only by experienced database administrators. In addition, the setting may not be respected in all situations.

  • Isolation level hints The following table hints can be used to specify isolation level settings for tables. They specify a locking method to be used only for this table, and only for this statement.

    The table hints set the following isolation levels:

    Table hint | Isolation level
    NOLOCK | 0
    READUNCOMMITTED | 0
    READCOMMITTED | 1
    REPEATABLEREAD | 2
    HOLDLOCK | 3
    SERIALIZABLE | 3
    XLOCK | All isolation levels
    Note
    XLOCK indicates that rows processed by the statement from the hinted table are to be locked exclusively. The affected rows remain locked until the end of the transaction. XLOCK works at all isolation levels.

  • Optimization hints The FASTFIRSTROW table hint allows you to set the optimization goal for the query without setting the OPTIMIZATION_GOAL option to first-row. When you use FASTFIRSTROW, Adaptive Server Anywhere chooses an access plan that is intended to reduce the time to fetch the first row of the query's result.

    For more information, see OPTIMIZATION_GOAL option [database].

toggle Usage

The SELECT, UPDATE, and DELETE statements require a table list, to specify which tables are used by the statement.

Views and derived tables
Although this description refers to tables, it also applies to views and derived tables unless otherwise noted.

The FROM clause creates a result set consisting of all the columns from all the tables specified. Initially, all combinations of rows in the component tables are in the result set, and the number of combinations is usually reduced by JOIN conditions and/or WHERE conditions.

You cannot use an ON phrase with CROSS JOIN.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • DELETE statement
  • SELECT statement
  • UPDATE statement
  • Joins: Retrieving Data from Several Tables
toggle Standards and compatibility

  • SQL/92 Entry-level feature. The complexity of the FROM clause means that you should check individual clauses against the standard.

  • SQL/99 Core feature, except for KEY JOIN, which is a vendor extension; and FULL OUTER JOIN and NATURAL JOIN, which are SQL/foundation features outside of core SQL. The complexity of the FROM clause means that you should check individual clauses against the standard.

  • Sybase The ON phrase is not supported in Adaptive Server Enterprise prior to version 12. In earlier versions, you must use the WHERE clause to build joins.

toggle Example

The following are valid FROM clauses:

...
FROM employee
...
...
FROM employee NATURAL JOIN department
...
...
FROM customer
KEY JOIN sales_order
KEY JOIN sales_order_items
KEY JOIN product
...

The following query illustrates how to use derived tables in a query:

SELECT lname, fname, number_of_orders
FROM customer JOIN
     ( SELECT cust_id, count(*)
       FROM sales_order
        GROUP BY cust_id )
     AS sales_order_counts ( cust_id,
                             number_of_orders )
ON ( customer.id = sales_order_counts.cust_id )
WHERE number_of_orders > 3

The following query illustrates how to select rows from stored procedure result sets:

SELECT t.id, t.quantity_ordered AS q, p.name
FROM sp_customer_products( 149 ) t JOIN product p
ON t.id = p.id


GET DATA statement [ESQL]

toggle Description

Use this statement to get string or binary data for one column of the current row of a cursor. GET DATA is usually used to fetch LONG BINARY or LONG VARCHAR fields. See SET statement.

toggle Syntax

GET DATA cursor-name
COLUMN column-num
OFFSET start-offset
[ WITH TEXTPTR ]
USING DESCRIPTOR sqlda-name | INTO hostvar [, ... ]

cursor-name : identifier, or hostvar

column-num : integer or hostvar

start-offset : integer or hostvar

sqlda-name : identifier

toggle Parameters

COLUMN clause The value of column-num starts at one, and identifies the column whose data is to be fetched. That column must be of a string or binary type.

OFFSET clause The start-offset indicates the number of bytes to skip over in the field value. Normally, this would be the number of bytes previously fetched. The number of bytes fetched on this GET DATA statement is determined by the length of the target host variable.

The indicator value for the target host variable is a short integer, so it cannot always contain the number of bytes truncated. Instead, it contains a negative value if the field contains the NULL value, a positive value (NOT necessarily the number of bytes truncated) if the value is truncated, and zero if a non-NULL value is not truncated.

Similarly, if a LONGVARCHAR or a LONGVARCHAR host variable is used with an offset greater than zero, the untrunc_len field does not accurately indicate the size before truncation.

WITH TEXTPTR clause If the WITH TEXTPTR clause is given, a text pointer is retrieved into a second host variable or into the second field in the SQLDA. This text pointer can be used with the Transact-SQL READ TEXT and WRITE TEXT statements. The text pointer is a 16-bit binary value, and can be declared as follows:

DECL_BINARY( 16 ) textptr_var;

WITH TEXTPTR can be used only with long data types (LONG BINARY, LONG VARCHAR, TEXT, IMAGE). If you attempt to use it with another data type, the error INVALID_TEXTPTR_VALUE is returned.

The total length of the data is returned in the SQLCOUNT field of the SQLCA structure.

toggle Usage

Get a piece of one column value from the row at the current cursor position.

toggle Permissions

The cursor must be opened and positioned on a row, using FETCH.

toggle Side effects

None.

toggle See also
  • FETCH statement [ESQL] [SP]
  • READTEXT statement [T-SQL]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Open Client/Open Server. An alternative is the Transact-SQL READTEXT statement.

toggle Example

The following example uses GET DATA to fetch a binary large object (often called a blob).

EXEC SQL BEGIN DECLARE SECTION;
DECL_BINARY(1000) piece;
short ind;

EXEC SQL END DECLARE SECTION;
int size;
/* Open a cursor on a long varchar field */
EXEC SQL DECLARE big_cursor CURSOR FOR
SELECT long_data FROM some_table
WHERE key_id = 2;
EXEC SQL OPEN big_cursor;
EXEC SQL FETCH big_cursor INTO :piece;
for( offset = 0; ; offset += piece.len ) {
   EXEC SQL GET DATA big_cursor COLUMN 1
   OFFSET :offset INTO :piece:ind;
   /* Done if the NULL value */
   if( ind < 0 ) break;
   write_out_piece( piece );
   /* Done when the piece was not truncated */
   if( ind == 0 ) break;
}
EXEC SQL CLOSE big_cursor;


GET DESCRIPTOR statement [ESQL]

toggle Description

Use this statement to retrieve information about a variable within a descriptor area, or retrieves its value.

toggle Syntax

GET DESCRIPTOR descriptor-name
{ hostvar = COUNT | VALUE { integer | hostvar } assignment [, ...] }

assignment :
hostvar = TYPE | LENGTH | PRECISION | SCALE | DATA
| INDICATOR | NAME | NULLABLE | RETURNED_LENGTH

toggle Usage

The GET DESCRIPTOR statement is used to retrieve information about a variable within a descriptor area, or to retrieve its value.

The value { integer | hostvar } specifies the variable in the descriptor area about which the information will be retrieved. Type checking is performed when doing GET ... DATA to ensure that the host variable and the descriptor variable have the same data type. LONGVARCHAR and LONGBINARY are not supported by GET DESCRIPTOR ... DATA.

If an error occurs, it is returned in the SQLCA.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • ALLOCATE DESCRIPTOR statement [ESQL]
  • DEALLOCATE DESCRIPTOR statement [ESQL]
  • SET DESCRIPTOR statement [ESQL]
  • The SQL descriptor area (SQLDA)
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Supported by Open Client/Open Server.

toggle Example

The following example returns the type of the column with position col_num in sqlda.

int get_type( SQLDA *sqlda, int col_num )
{
    EXEC SQL BEGIN DECLARE SECTION;
    int ret_type;
    int col = col_num;
    EXEC SQL END DECLARE SECTION;
EXEC SQL GET DESCRIPTOR sqlda VALUE :col :ret_type = TYPE;
    return( ret_type );
}

For a longer example, see ALLOCATE DESCRIPTOR statement [ESQL].


GET OPTION statement [ESQL]

toggle Description

You can use this statement to get the current setting of an option. It is recommended that you use the connection_property function instead.

toggle Syntax

GET OPTION [ userid.]option-name
[ INTO hostvar ]
[ USING DESCRIPTOR sqlda-name ]

userid : identifier, string, or hostvar

option-name : identifier, string, or hostvar

hostvar : indicator variable allowed

sqlda-name : identifier

toggle Usage

The GET OPTION statement is provided for compatibility with older versions of the software. The recommended way to get the values of options is to use the connection_property system function.

The GET OPTION statement gets the option setting of the option option-name for the user userid or for the connected user if userid is not specified. This will be either the user's personal setting or the PUBLIC setting if there is no setting for the connected user. If the option specified is a database option and the user has a temporary setting for that option, then the temporary setting is retrieved.

If option-name does not exist, GET OPTION returns the warning SQLE_NOTFOUND.

toggle Permissions

None required.

toggle Side effects

None.

toggle See also
  • SET OPTION statement
  • System and catalog stored procedures
  • CONNECTION_PROPERTY function [System]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement illustrates use of GET OPTION.

EXEC SQL GET OPTION 'date_format' INTO :datefmt;


GOTO statement [T-SQL]

toggle Description

Use this statement to branch to a labeled statement.

toggle Syntax

label : GOTO label

toggle Usage

Any statement in a Transact-SQL procedure, trigger, or batch can be labeled. The label name is a valid identifier followed by a colon. In the GOTO statement, the colon is not used.

toggle Permissions

None.

toggle Side effects

None.

toggle Standards and compatibility

  • SQL/92 Persistent Stored Module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase Adaptive Server Enterprise supports the GOTO statement.

toggle Example

The following Transact-SQL batch prints the message "yes" on the server window four times:

declare @count smallint
select @count = 1
restart:
   print 'yes'
   select @count = @count + 1
   while @count <=4
    goto restart


GRANT statement

toggle Description

Use this statement to create new user IDs, to grant or deny permissions to specific users, and to create or change passwords.

toggle Syntax 1

GRANT CONNECT TO userid, ...
[ AT starting-id ]
IDENTIFIED BY password, ...

toggle Syntax 2

GRANT {
DBA,
GROUP,
MEMBERSHIP IN GROUP userid, ...,
[ RESOURCE | ALL ]
}
TO userid, ...

toggle Syntax 3

GRANT {
ALL [ PRIVILEGES ],
ALTER,
DELETE,
INSERT,
REFERENCES [ ( column-name, ... ) ],
SELECT [ ( column-name, ... ) ],
UPDATE [ ( column-name, ... ) ],
}
ON [ owner.]table-name
TO userid, ...
[ WITH GRANT OPTION ]
[ FROM userid ]

toggle Syntax 4

GRANT EXECUTE ON [ owner.]procedure-name TO userid, ...

toggle Syntax 5

GRANT INTEGRATED LOGIN TO user_profile_name, ... AS USER userid

toggle Parameters

CONNECT TO Creates a new user. GRANT CONNECT can also be used by any user to change their own password. To create a user with the empty string as the password, type:

GRANT CONNECT TO userid IDENTIFIED BY ""

To create a user with no password, type:

GRANT CONNECT TO userid

A user with no password cannot connect to the database. This is useful if you are creating a group and do not want anyone to connect to the database using the group user ID. The password must be a valid identifier, as described in Identifiers. Passwords have a maximum length of 255 bytes.

The following are invalid for database user IDs and passwords:

  • names that begin with white space or single or double quotes

  • names that end with white space

  • names that contain semicolons

It is recommended that the password be composed of 7-bit ASCII characters as 8-bit ASCII characters above 127 may not work correctly when character set translation is turned on and the character sets do not match.

If you want to use characters above 127, you should do one of the following:

  • specify CharSet=none in your connection string to turn off character set translation

  • specify the character set using the CharSet connection parameter

  • specify the -ct- option to turn off character set translation on the database server

AT starting-id This clause is not for general purpose use. The clause specifies the internal numeric value to be used for the first user ID in the list.

The clause is implemented primarily for use by the Unload utility.

DBA Database Administrator authority gives a user permission to do anything. This is usually reserved for the person in the organization who is looking after the database.

GROUP Allows the user(s) to have members.

For more information, see Managing groups.

MEMBERSHIP IN GROUP This allows the user(s) to inherit table permissions from a group and to reference tables created by the group without qualifying the table name.

For more information, see Managing groups.

Syntax 3 of the GRANT statement is used to grant permission on individual tables or views. The table permissions can be specified individually, or you can use ALL to grant all six permissions at once.

RESOURCE Allows the user to create tables and views. In syntax 2, ALL is a synonym for RESOURCE that is compatible with Sybase Adaptive Server Enterprise.

ALL In Syntax 3, this grants all of the permissions outlined below.

ALTER The users will be allowed to alter the named table with the ALTER TABLE statement. This permission is not allowed for views.

DELETE The users will be allowed to delete rows from the named table or view.

INSERT The users will be allowed to insert rows into the named table or view.

REFERENCES [(column-name, ...)] The users will be allowed to create indexes on the named table, and foreign keys which reference the named tables. If column names are specified, the users will be allowed to reference only those columns. REFERENCES permissions on columns cannot be granted for views, only for tables.

INDEX is a synonym for REFERENCES.

SELECT [(column-name, ...)] The users will be allowed to look at information in this view or table. If column names are specified, the users will be allowed to look at only those columns. SELECT permissions on columns cannot be granted for views, only for tables.

UPDATE [(column-name, ...)] The users will be allowed to update rows in this view or table. If column names are specified, the users will be allowed to update only those columns. UPDATE permissions on columns cannot be granted for views, only for tables.

FROM If FROM userid is specified, the userid is recorded as a grantor user ID in the system tables. This clause is for use by the Unload utility (dbunload). Do not use or modify this option directly.

toggle Usage

The GRANT statement is used to grant database permissions to individual user IDs and groups. It is also used to create and delete users and groups.

If WITH GRANT OPTION is specified, then the named user ID is also given permission to GRANT the same permissions to other user IDs.

Syntax 4 of the GRANT statement is used to grant permission to execute a procedure.

Syntax 5 of the GRANT statement creates an explicit integrated login mapping between one or more Windows user or group profiles and an existing database user ID, allowing users who successfully log in to their local machine to connect to a database without having to provide a user ID or password.

For more information on integrated logins, see Using integrated logins.

toggle Permissions

Syntax 1 or 2 One of the following conditions must be met.

  • You are changing your own password using GRANT CONNECT.

  • You have DBA authority.

If you are changing another user's password (with DBA authority), the other user must not be connected to the database.

Syntax 3 If the FROM clause is specified you must have DBA authority. Otherwise, at least one of the following conditions must be met:

  • You own the table

  • You have been granted permissions on the table with GRANT OPTION

  • You have DBA authority

Syntax 4 One of the following conditions must be met:

  • You own the procedure

  • You have DBA authority

Syntax 5 The following condition must be met:

  • You have DBA authority

toggle Side effects

Automatic commit.

toggle See also
  • REVOKE statement
toggle Standards and compatibility

  • SQL/92 Syntax 3 is an entry-level feature. Syntax 4 is a Persistent Stored Module feature. Other syntaxes are vendor extensions.

  • SQL/99 Syntax 3 is a core feature. Syntax 4 is a Persistent Stored Module feature. Other syntaxes are vendor extensions.

  • Sybase Syntaxes 2 and 3 are supported in Adaptive Server Enterprise. The security model is different in Adaptive Server Enterprise and Adaptive Server Anywhere, so other syntaxes differ.

toggle Example

Make two new users for the database.

GRANT
CONNECT TO Laurel, Hardy
IDENTIFIED BY Stan, Ollie

Grant permissions on the employee table to user Laurel.

GRANT
SELECT, UPDATE ( street )
ON employee
TO Laurel

More than one permission can be granted in a single statement. Separate the permissions with commas.

Allow the user Hardy to execute the Calculate_Report procedure.

GRANT
EXECUTE ON Calculate_Report
TO Hardy


GRANT CONSOLIDATE statement [SQL Remote]

toggle Description

Use this statement to identify the database immediately above the current database in a SQL Remote hierarchy, who will receive messages from the current database.

toggle Syntax

GRANT CONSOLIDATE
TO userid
TYPE message-system, ...
ADDRESS address-string, ...
[ SEND { EVERY | AT }'hh:mm:ss' ]

message-system: FILE | FTP | MAPI | SMTP | VIM

address: string

toggle Parameters

userid The user ID for the user to be granted the permission

message-system One of the message systems supported by SQL Remote.

address The address for the specified message system.

toggle Usage

In a SQL Remote installation, the database immediately above the current database in a SQL Remote hierarchy must be granted CONSOLIDATE permissions. GRANT CONSOLIDATE is issued at a remote database to identify its consolidated database. Each database can have only one user ID with CONSOLIDATE permissions: you cannot have a database that is a remote database for more than one consolidated database.

The consolidated user is identified by a message system, identifying the method by which messages are sent to and received from the consolidated user. The address-name must be a valid address for the message-system, enclosed in single quotes. There can be only one consolidated user per remote database.

For the FILE message type, the address is a subdirectory of the directory pointed to by the SQLREMOTE environment variable.

The GRANT CONSOLIDATE statement is required for the consolidated database to receive messages, but does not by itself subscribe the consolidated database to any data. To subscribe to data, a subscription must be created for the consolidated user ID to one of the publications in the current database. Running the database extraction utility at a consolidated database creates a remote database with the proper GRANT CONSOLIDATE statement already issued.

The optional SEND EVERY and SEND AT clauses specify a frequency at which messages are sent. The string contains a time that is a length of time between messages (for SEND EVERY) or a time of day at which messages are sent (for SEND AT). With SEND AT, messages are sent once per day.

If a user has been granted remote permissions without a SEND EVERY or SEND AT clause, the Message Agent processes messages, and then stops. In order to run the Message Agent continuously, you must ensure that every user with REMOTE permission has either a SEND AT or SEND EVERY frequency specified.

It is anticipated that at many remote databases, the Message Agent will be run periodically, and that the consolidated database will have no SEND clause specified.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • GRANT PUBLISH statement [SQL Remote]
  • GRANT REMOTE statement [SQL Remote]
  • REVOKE CONSOLIDATE statement [SQL Remote]
  • sp_grant_consolidate procedure
toggle Example
GRANT CONSOLIDATE TO con_db
TYPE mapi
ADDRESS 'Consolidated Database'


GRANT PUBLISH statement [SQL Remote]

toggle Description

Use this statement to identify the publisher of the current database.

toggle Syntax

GRANT PUBLISH TO userid

toggle Usage

Each database in a SQL Remote installation is identified in outgoing messages by a user ID, called the publisher. The GRANT PUBLISH statement identifies the publisher user ID associated with these outgoing messages.

Only one user ID can have PUBLISH authority. The user ID with PUBLISH authority is identified by the special constant CURRENT PUBLISHER. The following query identifies the current publisher:

SELECT CURRENT PUBLISHER

If there is no publisher, the special constant is NULL.

The current publisher special constant can be used as a default setting for columns. It is often useful to have a CURRENT PUBLISHER column as part of the primary key for replicating tables, as this helps prevent primary key conflicts due to updates at more than one site.

In order to change the publisher, you must first drop the current publisher using the REVOKE PUBLISH statement, and then create a new publisher using the GRANT PUBLISH statement.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • GRANT PUBLISH statement [SQL Remote]
  • GRANT CONSOLIDATE statement [SQL Remote]
  • REVOKE PUBLISH statement [SQL Remote]
  • CREATE SUBSCRIPTION statement [SQL Remote]
  • sp_publisher procedure
toggle Example
GRANT PUBLISH TO publisher_ID


GRANT REMOTE statement [SQL Remote]

toggle Description

Use this statement to identify a database immediately below the current database in a SQL Remote hierarchy, who will receive messages from the current database. These are called remote users.

toggle Syntax

GRANT REMOTE TO userid, ...
TYPE message-system, ...
ADDRESS address-string, ...
[ SEND { EVERY | AT } send-time ]

toggle Parameters

userid The user ID for the user to be granted the permission

message-system One of the message systems supported by SQL Remote. It must be one of the following values:

  • FILE

  • FTP

  • MAPI

  • SMTP

  • VIM

address-string A string containing a valid address for the specified message system.

send-time A string containing a time specification in the form hh:mm:ss.

toggle Usage

In a SQL Remote installation, each database receiving messages from the current database must be granted REMOTE permissions.

The single exception is the database immediately above the current database in a SQL Remote hierarchy, which must be granted CONSOLIDATE permissions.

The remote user is identified by a message system, identifying the method by which messages are sent to and received from the consolidated user. The address-name must be a valid address for the message-system, enclosed in single quotes.

For the FILE message type, the address is a subdirectory of the directory pointed to by the SQLREMOTE environment variable.

The GRANT REMOTE statement is required for the remote database to receive messages, but does not by itself subscribe the remote user to any data. To subscribe to data, a subscription must be created for the user ID to one of the publications in the current database, using the database extraction utility or the CREATE SUBSCRIPTION statement.

The optional SEND EVERY and SEND AT clauses specify a frequency at which messages are sent. The string contains a time that is a length of time between messages (for SEND EVERY) or a time of day at which messages are sent (for SEND AT). With SEND AT, messages are sent once per day.

If a user has been granted remote permissions without a SEND EVERY or SEND AT clause, the Message Agent processes messages, and then stops. In order to run the Message Agent continuously, you must ensure that every user with REMOTE permission has either a SEND AT or SEND EVERY frequency specified.

It is anticipated that at many consolidated databases, the Message Agent will be run continuously, so that all remote databases would have a SEND clause specified. A typical setup may involve sending messages to laptop users daily (SEND AT) and to remote servers every hour or two (SEND EVERY). You should use as few different times as possible, for efficiency.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • GRANT PUBLISH statement [SQL Remote]
  • REVOKE REMOTE statement [SQL Remote]
  • GRANT CONSOLIDATE statement [SQL Remote]
  • sp_grant_remote procedure
  • Granting and revoking REMOTE and CONSOLIDATE permissions
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Example

  • The following statement grants remote permissions to user SamS, using a MAPI e-mail system, sending messages to the address Singer, Samuel once every two hours:

    GRANT REMOTE TO SamS
TYPE mapi
ADDRESS 'Singer, Samuel'
SEND EVERY '02:00'


GRANT REMOTE DBA statement [SQL Remote]

toggle Description

Use this statement to provide DBA privileges to a user ID, but only when connected from the Message Agent.

toggle Syntax

GRANT REMOTE DBA
TO userid, ...
IDENTIFIED BY password

toggle Usage

REMOTE DBA authority enables the Message Agent to have full access to the database in order to make any changes contained in the messages, while avoiding security problems associated with distributing DBA user IDs passwords.

REMOTE DBA has the following properties.

  • No distinct permissions when not connected from the Message Agent. A user ID granted REMOTE DBA authority has no extra privileges on any connection apart from the Message Agent. Even if the user ID and password for a REMOTE DBA user is widely distributed, there is no security problem. As long as the user ID has no permissions beyond CONNECT granted on the database, no one can use this user ID to access data in the database.

  • Full DBA permissions when connected from the Message Agent.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • The Message Agent and replication security
  • REVOKE REMOTE DBA statement [SQL Remote]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.


GROUP BY clause

toggle Description

Use this clause to group columns, alias names, and functions as a part of the SELECT statement.

toggle Syntax

GROUP BY [ group-by-list
| ROLLUP ( group-by-list )
| ( group-by-list ) WITH ROLLUP
| CUBE ( group-by-list )
| ( group-by-list ) WITH CUBE
| GROUPING SETS ( grouping-sets ) ]
[ HAVING search-condition ]

toggle Parameters

ROLLUP keyword The ROLLUP operation adds summary (or subtotalled) rows into the result set of a query with a GROUP BY clause.

A prefix is a subset of the items in the group-by-list. A prefix is defined by excluding one or more of the rightmost items from those in the group-by-list. An additional row is added to the result set for each prefix. The additional row contains subtotal information for a set of rows in the GROUP BY result set. Each subtotal row includes the following:

  • Column excluded from the prefix NULL.

  • Column included in the prefix The value of the column.

  • Aggregate function An aggregate over the values of the excluded columns.

For more information about ROLLUP operations, see Using ROLLUP.

WITH ROLLUP keyword This is an alternate way to construct ROLLUP queries. It returns the same result set as the ROLLUP syntax. For more information about ROLLUP operations, see Using ROLLUP.

CUBE keyword The CUBE operation generates subtotal rows for a GROUP BY by considering grouping across all possible subsets of the group-by-list. For more information about CUBE operations, see Using CUBE.

WITH CUBE keyword This is an alternate way to construct CUBE queries. It returns the same result set as the CUBE syntax. For more information about CUBE operations, see Using CUBE.

GROUPING SETS keyword The GROUPING SETS operation lets you compute groups on several different sets of grouping columns (called GROUPING SETS) in the same query. The items in parentheses each represent a family of one or more GROUPING SETS. All GROUPING SETS contained in these families are computed when the GROUPING SETS keyword is used. Rows returned for GROUPING SETS that do not group by all non-aggregate columns of the select-list will contain NULL values in the non-grouping, non-aggregate columns. To distinguish between NULL values present in the input data and NULL values inserted by the grouping operator, use the GROUPING() aggregate function. For more information about the GROUPING SETS operation, see Using GROUPING SETS.

Note
In a GROUPING SETS query, ( ) denotes a GROUPING SET that uses no grouping columns and therefore generates a single row of output in the result set.

HAVING clause This clause selects rows based on the group values and not on the individual row values. The HAVING clause can only be used if either the statement has a GROUP BY clause or the select list consists solely of aggregate functions. Any column names referenced in the HAVING clause must either be in the GROUP BY clause or be used as a parameter to an aggregate function in the HAVING clause.

toggle Usage

You can group by columns, alias names, or functions. The result of the query contains one row for each distinct set of values in the named columns, aliases, or functions. All NULL-containing rows are treated as a single set. The resulting rows are often referred to as groups since there is one row in the result for each group of rows from the table list. Aggregate functions can then be applied to these groups to get meaningful results.

Note
When GROUP BY is used, the select-list, HAVING clause, and ORDER BY clause can reference only identifiers named in the GROUP BY clause. The exception is that the select-list and HAVING clause may contain aggregate functions.
toggle See also
  • Expressions
  • SELECT statement
  • FROM clause
  • Search conditions
  • UNION operation
  • Joins: Retrieving Data from Several Tables
  • About OLAP operations
  • Using ROLLUP
  • Using CUBE
  • Using GROUPING SETS
toggle Standards and compatibility

  • SQL/92 Entry-level feature. The complexity of the SELECT statement means that you should check individual clauses against the standard.

  • SQL/99 Core feature. The complexity of the SELECT statement means that you should check individual clauses against the standard. For example, the ROLLUP keyword is part of feature T431.

  • Sybase Supported by Adaptive Server Enterprise, with some differences in syntax. OLAP features are not supported in Adaptive Server Enterprise.

toggle Examples

The following ROLLUP query example returns a result set showing the total number of orders, and then provides subtotals for the number of orders in each year (2000 and 2001).

SELECT year (order_date) Year, quarter (order_date) Quarter, count (*) Orders
FROM sales_order
GROUP BY ROLLUP (Year, Quarter)
ORDER BY Year, Quarter

Like the preceding ROLLUP operation example, the following CUBE query example returns a result set showing the total number of orders and provides subtotals for the number of orders in each year (2000 and 2001). Unlike ROLLUP, this query also gives subtotals for the number of orders in each quarter (1, 2, 3, and 4).

SELECT year (order_date) Year, quarter (order_date) Quarter, count (*) Orders
FROM sales_order
GROUP BY CUBE (Year, Quarter)
ORDER BY Year, Quarter

The following GROUPING SETS query example returns a result set that gives subtotals for the number of orders in the years 2000 and 2001. The GROUPING SETS operation lets you select the columns to be subtotalled instead of returning all combinations of subtotals like the CUBE operation.

SELECT year (order_date) Year, quarter (order_date) Quarter, count (*) Orders
FROM sales_order
GROUP BY GROUPING SETS ((Year, Quarter), (Year))
ORDER BY Year, Quarter


HELP statement [Interactive SQL]

toggle Description

Use this statement to receive help in the Interactive SQL environment.

toggle Syntax

HELP [topic]

toggle Usage

The HELP statement is used to access SQL Anywhere Studio documentation.

The topic for help can be optionally specified. If topic is a reserved word, it must be enclosed in single quotes. In some help formats, the topic cannot be specified; in this case, a link to the home page of the online books is provided.

toggle Permissions

None.

toggle Side effects

None.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable


IF statement

toggle Description

Use this statement to control conditional execution of SQL statements.

toggle Syntax

IF search-condition THEN statement-list
[ ELSEIF { search-condition | operation-type } THEN statement-list ] ...
[ ELSE statement-list ]
END IF

toggle Usage

The IF statement is a control statement that allows you to conditionally execute the first list of SQL statements whose search-condition evaluates to TRUE. If no search-condition evaluates to TRUE, and an ELSE clause exists, the statement-list in the ELSE clause is executed.

Execution resumes at the first statement after the END IF.

IF statement is different from IF expression
Do not confuse the syntax of the IF statement with that of the IF expression.

For information on the IF expression, see IF expressions.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • BEGIN statement
  • Using Procedures, Triggers, and Batches
toggle Standards and compatibility

  • SQL/92 Persistent Stored Module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase The Transact-SQL IF statement has a slightly different syntax.

toggle Example

The following procedure illustrates the use of the IF statement:

CREATE PROCEDURE TopCustomer (OUT TopCompany CHAR(35),                               OUT TopValue INT)
BEGIN
   DECLARE err_notfound EXCEPTION
   FOR SQLSTATE '02000';
   DECLARE curThisCust CURSOR FOR
   SELECT company_name, CAST(    sum(sales_order_items.quantity *
   product.unit_price) AS INTEGER) VALUE
   FROM customer
   LEFT OUTER JOIN sales_order
   LEFT OUTER JOIN sales_order_items
   LEFT OUTER JOIN product
   GROUP BY company_name;
   DECLARE ThisValue INT;
   DECLARE ThisCompany CHAR(35);
   SET TopValue = 0;
   OPEN curThisCust;
   CustomerLoop:
   LOOP
      FETCH NEXT curThisCust
      INTO ThisCompany, ThisValue;
      IF SQLSTATE = err_notfound THEN
         LEAVE CustomerLoop;
      END IF;
      IF ThisValue > TopValue THEN
         SET TopValue = ThisValue;
         SET TopCompany = ThisCompany;
      END IF;
   END LOOP CustomerLoop;
   CLOSE curThisCust;
END


IF statement [T-SQL]

toggle Description

Use this statement to control conditional execution of a SQL statement, as an alternative to the Watcom-SQL IF statement.

toggle Syntax

IF expression
statement
[ ELSE
[ IF expression ]
statement ]

toggle Usage

The Transact-SQL IF conditional and the ELSE conditional each control the execution of only a single SQL statement or compound statement (between the keywords BEGIN and END).

In comparison to the Watcom-SQL IF statement, there is no THEN in the Transact-SQL IF statement. The Transact-SQL version also has no ELSEIF or END IF keywords.

toggle Permissions

None.

toggle Side effects

None.

toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Adaptive Server Enterprise supports the Transact-SQL IF statement.

toggle Example

The following example illustrates the use of the Transact-SQL IF statement:

IF (SELECT max(id) FROM sysobjects) < 100
   RETURN
ELSE

      PRINT 'These are the user-created objects'
      SELECT name, type, id
      FROM sysobjects
      WHERE id < 100
   END

The following two statement blocks illustrate Transact-SQL and Watcom-SQL compatibility:

/* Transact-SQL IF statement */
IF @v1 = 0
   PRINT '0'
ELSE IF @v1 = 1
   PRINT '1'
ELSE
   PRINT 'other'
/* Watcom-SQL IF statement */
IF v1 = 0 THEN
   PRINT '0'
ELSEIF v1 = 1 THEN
   PRINT '1'
ELSE
   PRINT 'other'
END IF


INCLUDE statement [ESQL]

toggle Description

Use this statement to include a file into a source program to be scanned by the SQL preprocessor.

toggle Syntax

INCLUDE filename

filename : SQLDA | SQLCA | string

toggle Usage

The INCLUDE statement is very much like the C preprocessor #include directive. The SQL preprocessor reads an embedded SQL source file and replaces all the embedded SQL statements with C-language source code. If a file contains information that the SQL preprocessor requires, include it with the embedded SQL INCLUDE statement.

Two file names are specially recognized: SQLCA and SQLDA. The following statement must appear before any embedded SQL statements in all embedded SQL source files.

EXEC SQL INCLUDE SQLCA;

This statement must appear at a position in the C program where static variable declarations are allowed. Many embedded SQL statements require variables (invisible to the programmer), which are declared by the SQL preprocessor at the position of the SQLCA include statement. The SQLDA file must be included if any SQLDAs are used.

toggle Permissions

None.

toggle Side effects

None.

toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Supported by Open Client/Open Server.


INPUT statement [Interactive SQL]

toggle Description

Use this statement to import data into a database table from an external file or from the keyboard.

toggle Syntax

INPUT INTO [ owner.]table-name
[ FROM filename | PROMPT ]
[ FORMAT input-format ]
[ ESCAPE CHARACTER character ]
[ ESCAPES { ON | OFF }
[ BY ORDER | BY NAME ]
[ DELIMITED BY string ]
[ COLUMN WIDTHS (integer, ...) ]
[ NOSTRIP ]
[ ( column-name, ... ) ]
[ ENCODING encoding ]

input-format :
ASCII | DBASE | DBASEII | DBASEIII
| EXCEL | FIXED | FOXPRO | LOTUS

encoding : identifier or string

toggle Parameters

FROM clause The filename is passed to the server as a quoted string. The string is therefore subject to the same formatting requirements as other SQL strings. In particular:

  • To indicate directory paths, the backslash character (\) must be represented by two backslashes. The statement to load data from the file c:\temp\input.dat into the employee table is:

    INPUT INTO employee
FROM 'c:\\temp\\input.dat'

  • The path name is relative to the machine Interactive SQL is running on.

PROMPT clause The PROMPT clause allows the user to enter values for each column in a row. When running in windowed mode, a dialog appears where the user can enter the values for the new row. If the user is running Interactive SQL on the command line, then Interactive SQL prompts the user to type the value for each column on the command line.

FORMAT clause Each set of values must be in the format specified by the FORMAT clause, or the format set by the SET OPTION INPUT_FORMAT statement if the FORMAT clause is not specified. When input is entered by the user, a dialog is provided for the user to enter one row per line in the input format.

Certain file formats contain information about column names and types. Using this information, the INPUT statement will create the database table if it does not already exist. This is a very easy way to load data into the database. The formats that have enough information to create the table are: DBASEII, DBASEIII, FOXPRO, and LOTUS.

Input from a command file is terminated by a line containing END. Input from a file is terminated at the end of the file.

Allowable input formats are:

  • ASCII Input lines are assumed to be ASCII characters, one row per line, with values separated by commas. Alphabetic strings may be enclosed in apostrophes (single quotes) or quotation marks (double quotes). Strings containing commas must be enclosed in either single or double quotes. If the string itself contains single or double quotes, double the quote character to use it within the string. Optionally, you can use the DELIMITED BY clause to specify a different delimiter string than the default, which is a comma.

    Three other special sequences are also recognized. The two characters \n represent a newline character, \\ represents a single (\), and the sequence \xDD represents the character with hexadecimal code DD.

  • DBASE The file is in dBASE II or dBASE III format. Interactive SQL will attempt to determine which format, based on information in the file. If the table doesn't exist, it will be created.

  • DBASEII The file is in dBASE II format. If the table doesn't exist, it will be created.

  • DBASEIII The file is in dBASE III format. If the table doesn't exist, it will be created.

  • EXCEL Input file is in the format of Microsoft Excel 2.1. If the table doesn't exist, it will be created.

  • FIXED Input lines are in fixed format. The width of the columns can be specified using the COLUMN WIDTHS clause. If they are not specified, column widths in the file must be the same as the maximum number of characters required by any value of the corresponding database column's type.

    The FIXED format cannot be used with binary columns that contain embedded newline and End of File character sequences.

  • FOXPRO The file is in FoxPro format. If the table doesn't exist, it will be created.

  • LOTUS The file is a Lotus WKS format worksheet. INPUT assumes that the first row in the Lotus WKS format worksheet is column names. If the table doesn't exist, it will be created. In this case, the types and sizes of the columns created may not be correct because the information in the file pertains to a cell, not to a column.

ESCAPE CHARACTER clause The default escape character for hexadecimal codes and symbols is a backslash (\), so \x0A is the linefeed character, for example.

The escape character can be changed, using the ESCAPE CHARACTER clause. For example, to use the exclamation mark as the escape character, you would enter:

... ESCAPE CHARACTER '!'

Only one single-byte character can be used as an escape character.

ESCAPES clause With ESCAPES turned on (the default), characters following the backslash character are recognized and interpreted as special characters by the database server. New line characters can be included as the combination \n, other characters can be included in data as hexadecimal ASCII codes, such as \x09 for the tab character. A sequence of two backslash characters ( \\ ) is interpreted as a single backslash. A backslash followed by any character other than n, x, X or \ is interpreted as two separate characters. For example, \q inserts a backslash and the letter q.

BY clause The BY clause allows the user to specify whether the columns from the input file should be matched up with the table columns based on their ordinal position in the lists (ORDER, the default) or by their names (NAME). Not all input formats have column name information in the file. NAME is allowed only for those formats that do. They are the same formats that allow automatic table creation: DBASEII, DBASEIII, FOXPRO, and LOTUS.

DELIMITED BY clause The DELIMITED BY clause allows you to specify a string to be used as the delimiter in ASCII input format.

COLUMN WIDTHS clause COLUMN WIDTHS can be specified for FIXED format only. It specifies the widths of the columns in the input file. If COLUMN WIDTHS is not specified, the widths are determined by the database column types. This clause should not be used if inserting LONG VARCHAR or BINARY data in FIXED format.

NOSTRIP clause Normally, for ASCII input format, trailing blanks will be stripped from unquoted strings before the value is inserted. NOSTRIP can be used to suppress trailing blank stripping. Trailing blanks are not stripped from quoted strings, regardless of whether the option is used. Leading blanks are stripped from unquoted strings, regardless of the NOSTRIP option setting.

If the ASCII file has entries such that a column appears to be null, it is treated as NULL. If the column in that position cannot be NULL, a zero is inserted in numeric columns and an empty string in character columns.

ENCODING clause The encoding argument allows you to specify the encoding that is used to read the file. The ENCODING clause can only be used with the ASCII format.

If encoding is not specified, Interactive SQL determines the code page that is used to read the file as follows, where code page values occurring earlier in the list take precedence over those occurring later in the list:

  • the code page specified with the DEFAULT_ISQL_ENCODING option (if this option is set)

  • the code page specified with the -codepage option when Interactive SQL was started

  • the default code page for the computer Interactive SQL is running on

For more information about Interactive SQL and encodings, see DEFAULT_ISQL_ENCODING option [Interactive SQL].

toggle Usage

The INPUT statement allows efficient mass insertion into a named database table. Lines of input are read either from the user via an input window (if PROMPT is specified) or from a file (if FROM filename is specified). If neither is specified, the input will be read from the command file that contains the INPUT statement—in Interactive SQL, this can even be directly from the SQL Statements pane. In this case, input is ended with a line containing only the string END.

If a column list is specified for any input format, the data is inserted into the specified columns of the named table. By default, the INPUT statement assumes that column values in the input file appear in the same order as they appear in the database table definition. If the input file's column order is different, you must list the input file's actual column order at the end of the INPUT statement.

For example, if you create a table with the following statement:

CREATE TABLE inventory (
quantity INTEGER,
item VARCHAR(60)
)

and you want to import ASCII data from the input file stock.txt that contains the name value before the quantity value,

'Shirts', 100
'Shorts', 60

then you must list the input file's actual column order at the end of the INPUT statement for the data to be inserted correctly:

INPUT INTO inventory
FROM stock.txt
FORMAT ASCII
(item, quantity);

By default, the INPUT statement stops when it attempts to insert a row that causes an error. Errors can be treated in different ways by setting the ON_ERROR and CONVERSION_ERROR options (see SET OPTION). Interactive SQL prints a warning in the Messages pane if any string values are truncated on INPUT. Missing values for NOT NULL columns are set to zero for numeric types and to the empty string for non-numeric types. If INPUT attempts to insert a NULL row, the input file contains an empty row.

toggle Permissions

Must have INSERT permission on the table or view.

toggle Side effects

None.

toggle See also
  • OUTPUT statement [Interactive SQL]
  • INSERT statement
  • UPDATE statement
  • DELETE statement
  • SET OPTION statement
  • LOAD TABLE statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

The following is an example of an INPUT statement from an ASCII text file.

INPUT INTO employee
FROM new_emp.inp
FORMAT ASCII;


INSERT statement

toggle Description

Use this statement to insert a single row (syntax 1) or a selection of rows from elsewhere in the database (syntax 2) into a table.

toggle Syntax 1

INSERT [ INTO ] [ owner.]table-name [ ( column-name, ... ) ]
[ ON EXISTING { ERROR | SKIP | UPDATE } ]
VALUES ( expression | DEFAULT, ... )

toggle Syntax 2

INSERT [ INTO ] [ owner.]table-name [ ( column-name, ... ) ]
[ ON EXISTING { ERROR | SKIP | UPDATE } ]
[ WITH AUTO NAME ]
select-statement

toggle Parameters

WITH AUTO NAME clause WITH AUTO NAME applies only to syntax 2. If you specify WITH AUTO NAME, the names of the items in the SELECT statement determine which column the data belongs in. The SELECT statement items should be either column references or aliased expressions. Destination columns not defined in the SELECT statement will be assigned their default value. This is useful when the number of columns in the destination table is very large.

ON EXISTING clause The ON EXISTING clause of the INSERT statement applies to both syntaxes. It updates existing rows in a table, based on primary key lookup, with new values. This clause can only be used on tables that have a primary key. Attempting to use this clause on tables without primary keys generates a syntax error. You cannot insert values into a proxy table with the ON EXISTING clause.

If you specify the ON EXISTING clause, the server does a primary key lookup for each input row. If the corresponding row does not already exist in the table, it inserts the new row as usual. For rows that already exist in the table, you can choose to silently ignore the input row (SKIP), update the values in the input row (UPDATE), or generate an error message for duplicate key values (ERROR).

By default, if you do not specify ON EXISTING, attempting to insert rows into a table where the row already exist results in a duplicate key value error. This is equivalent to specifying ON EXISTING ERROR.

toggle Usage

The INSERT statement is used to add new rows to a database table.

Syntax 1 Insert a single row with the specified expression values. The keyword DEFAULT can be used to cause the default value for the column to be inserted. If the optional list of column names is given, the values are inserted one for one into the specified columns. If the list of column names is not specified, the values are inserted into the table columns in the order they were created (the same order as retrieved with SELECT *). The row is inserted into the table at an arbitrary position. (In relational databases, tables are not ordered.)

Syntax 2 Carry out mass insertion into a table with the results of a fully general SELECT statement. Insertions are done in an arbitrary order unless the SELECT statement contains an ORDER BY clause.

If you specify column names, the columns from the select list are matched ordinally with the columns specified in the column list, or sequentially in the order in which the columns were created.

Inserts can be done into views, if the query specification defining the view is updateable and has only one table in the FROM clause.

An inherently non-updateable view consists of a query expression or query specification containing any of the following:

  • DISTINCT clause

  • GROUP BY clause

  • Aggregate function

  • A select-list item that is not a base table.

Character strings inserted into tables are always stored in the same case as they are entered, regardless of whether the database is case sensitive or not. Thus a string Value inserted into a table is always held in the database with an upper-case V and the remainder of the letters lower case. SELECT statements return the string as Value. If the database is not case sensitive, however, all comparisons make Value the same as value, VALUE, and so on. Further, if a single-column primary key already contains an entry Value, an INSERT of value is rejected, as it would make the primary key not unique.

Inserting a significant amount of data using the INSERT statement will also update column statistics.

Performance tips
To insert many rows into a table, it is more efficient to declare a cursor and insert the rows through the cursor, where possible, than to carry out many separate INSERT statements. Before inserting data, you can specify the percentage of each table page that should be left free for later updates. For more information, see ALTER TABLE statement.
toggle Permissions

Must have INSERT permission on the table.

toggle Side effects

None.

toggle See also
  • INPUT statement [Interactive SQL]
  • LOAD TABLE statement
  • UPDATE statement
  • DELETE statement
  • PUT statement [ESQL]
toggle Standards and compatibility

  • SQL/92 Entry-level feature. INSERT ... ON EXISTING is a vendor extension.

  • SQL/99 Core feature. INSERT ... ON EXISTING is a vendor extension.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Examples

Add an Eastern Sales department to the database.

INSERT
INTO department ( dept_id, dept_name )
VALUES ( 230, 'Eastern Sales' )

Create the table dept_head and fill it with the names of department heads and their departments.

CREATE TABLE dept_head(
      pk int primary key default autoincrement,
      dept_name varchar(128),
      manager_name varchar (128) );
INSERT
INTO dept_head (manager_name, dept_name)
SELECT emp_fname || ' ' || emp_lname, dept_name
FROM employee JOIN department
ON emp_id = dept_head_id

Create the table dept_head and fill it with the names of department heads and their departments using the WITH AUTO NAME syntax.

CREATE TABLE dept_head(
      pk int primary key default autoincrement,
      dept_name varchar(128),
      manager varchar (128) );
INSERT
INTO dept_head WITH AUTO NAME
SELECT emp_fname || ' ' || emp_lname AS manager,
      dept_name
FROM employee JOIN department
ON emp_id = dept_head_id

Create the table mytab and populate it using the WITH AUTO NAME syntax.

CREATE TABLE mytab(
      pk int primary key default autoincrement,
      table_name char(128),
      len int );
INSERT into mytab WITH AUTO NAME
SELECT
      length(t.table_name) AS len,
      t.table_name
FROM SYS.SYSTABLE t
WHERE table_id<=10


INSTALL JAVA statement

toggle Description

Use this statement to make Java classes available for use within a database.

toggle Syntax

INSTALL JAVA
[ NEW | UPDATE ]
[ JAR jar-name ]
FROM { FILE filename | expression }

toggle Parameters

NEW | UPDATE keyword If you specify an install mode of NEW, the referenced Java classes must be new classes, rather than updates of currently installed classes. An error occurs if a class with the same name exists in the database and the NEW install mode is used.

If you specify UPDATE, the referenced Java classes may include replacements for Java classes that are already installed in the given database.

If install-mode is omitted, the default is NEW.

JAR clause If this is specified, then the filename must designate a jar file. JAR files typically have extensions of .jar or .zip.

Installed jar and zip files can be compressed or uncompressed.

If the JAR option is specified, the jar is retained as a jar after the classes that it contains have been installed. That jar is the associated jar of each of those classes. The jars installed in a database with the JAR option are called the retained jars of the database.

The jar-name is a character string value, of up to 255 bytes long. The jar-name is used to identify the retained jar in subsequent INSTALL JAVA, UPDATE, and REMOVE JAVA statements.

FROM FILE clause Specifies the location of the Java class(es) to be installed.

The formats supported for file-name include fully qualified file names, such as 'c:\libs\jarname.jar' and '/usr/u/libs/jarname.jar', and relative file names, which are relative to the current working directory of the database server.

The filename must identify either a class file, or a jar file.

FROM expression clause Expressions must evaluate to a binary type whose value contains a valid class file or jar file.

toggle Usage

The class definition for each class is loaded by each connection's VM the first time that class is used. When you INSTALL a class, the VM on your connection is implicitly restarted. Therefore, you have immediate access to the new class, whether the INSTALL has an install-mode of NEW or UPDATE. Because the VM is restarted, any values stored in Java static variables are lost, and any SQL variables with Java class types are dropped.

For other connections, the new class is loaded the next time a VM accesses the class for the first time. If the class is already loaded by a VM, that connection does not see the new class until the VM is restarted for that connection (for example, with a STOP JAVA and START JAVA).

toggle Permissions

DBA permissions are required to execute the INSTALL JAVA statement.

All installed classes can be referenced in any way by any user.

Not supported on Windows CE.

toggle See also
  • REMOVE JAVA statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

The following statement installs the user-created Java class named Demo, by providing the filename and location of the class.

INSTALL JAVA NEW
FROM FILE 'D:\JavaClass\Demo.class'

After installation, the class is referenced using its name. Its original file path location is no longer used. For example, the following statement uses the class installed in the previous statement.

create variable d Demo

If the Demo class was a member of the package sybase.work, the fully qualified name of the class must be used, for example,

CREATE VARIABLE d sybase.work.Demo

The following statement installs all the classes contained in a zip file, and associates them within the database with a JAR file name.

INSTALL JAVA
JAR 'Widgets'
FROM FILE 'C:\Jars\Widget.zip'

Again, the location of the zip file is not retained and classes must be referenced using the fully qualified class name (package name and class name).


INTERSECT operation

toggle Description

Computes the intersection between the result sets of two or more queries.

toggle Syntax

select-statement
INTERSECT [ ALL | DISTINCT ] select-statement
[ INTERSECT [ ALL | DISTINCT ] select-statement ] ...
[ ORDER BY [ integer | select-list-expression-name ] [ ASC | DESC ], ... ]

toggle Usage

The intersection between the result sets of several SELECT statements can be obtained as a single result using INTERSECT or INTERSECT ALL. INTERSECT DISTINCT is identical to INTERSECT.

The component SELECT statements must each have the same number of items in the select list, and cannot contain an ORDER BY clause.

The results of INTERSECT are the same as INTERSECT ALL, except that when using INTERSECT, duplicate rows are eliminated before the intersection between the result sets is computed.

If corresponding items in two select lists have different data types, Adaptive Server Anywhere chooses a data type for the corresponding column in the result and automatically convert the columns in each component SELECT statement appropriately. The first query specification of the UNION is used to determine the names to be matched with the ORDER BY clause.

The column names displayed are the same column names that are displayed for the first SELECT statement. An alternative way of customizing result set column names is to use the WITH clause on the SELECT statement.

toggle Permissions

Must have SELECT permission for each of the component SELECT statements.

toggle Side effects

None.

toggle See also

EXCEPT operation

UNION operation

toggle Standards and compatibility

  • SQL/92 Entry-level.

  • SQL/99 Feature F302.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Example

For examples of INTERSECT usage, see Set operators and NULL.


LEAVE statement

toggle Description

Use this statement to leave a compound statement or loop.

toggle Syntax

LEAVE statement-label

toggle See also
  • LOOP statement
  • FOR statement
  • BEGIN statement
  • Using Procedures, Triggers, and Batches
toggle Usage

The LEAVE statement is a control statement that allows you to leave a labeled compound statement or a labeled loop. Execution resumes at the first statement after the compound statement or loop.

The compound statement that is the body of a procedure or trigger has an implicit label that is the same as the name of the procedure or trigger.

toggle Permissions

None.

toggle Side effects

None.

toggle Standards and compatibility

  • SQL/92 Persistent Stored Module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase Not supported in Adaptive Server Enterprise. The BREAK statement provides a similar feature for Transact-SQL compatible procedures.

toggle Example

The following fragment shows how the LEAVE statement is used to leave a loop.

SET i = 1;
lbl:
LOOP
   INSERT
   INTO Counters ( number )
   VALUES ( i );
   IF i >= 10 THEN
      LEAVE lbl;
   END IF;
   SET i = i + 1
END LOOP lbl

The following example fragment uses LEAVE in a nested loop.

outer_loop:
LOOP
   SET i = 1;
   inner_loop:
   LOOP
      ...
      SET i = i + 1;
      IF i >= 10 THEN
         LEAVE outer_loop
      END IF
   END LOOP inner_loop
END LOOP outer_loop


LOAD STATISTICS statement

toggle Description

This statement loads statistics into the system table SYSCOLSTAT. It is used by the dbunload utility to unload column statistics from the old database. It should not be used manually.

toggle Syntax

LOAD STATISTICS [ [ owner.]table-name.]column-name
format-id, density, max-steps, actual-steps, step-values, frequencies

toggle Parameters

format_id Internal field used to determine the format of the rest of the row in the SYSCOLSTAT system table.

density An estimate of the weighted average selectivity of a single value for the column, not counting the selectivity of large single value selectivities stored in the row.

max_steps The maximum number of steps allowed in the histogram.

actual_steps The number of steps actually used at this time.

step_values Boundary values of the histogram steps.

frequencies Selectivities of histogram steps.

toggle Permissions

Must have DBA authority.

toggle Side effects

None.

toggle See also
  • SYSCOLSTAT system table
  • Unloading a database using the dbunload command-line utility
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.


LOAD TABLE statement

toggle Description

Use this statement to import bulk data into a database table from an external ASCII-format file. Inserts are not recorded in the log file, raising the risk that data will be lost in the event of a crash and making this statement unusable with SQL Remote or with MobiLink remote databases.

toggle Syntax

LOAD [ INTO ] TABLE [ owner.]table-name [ ( column-name, ... ) ]
FROM filename
[ load-option ... ]
[ statistics-limitation-options ]

load-option :
CHECK CONSTRAINTS { ON | OFF }
| COMPUTES { ON | OFF }
| DEFAULTS { ON | OFF }
| DELIMITED BY string
| ESCAPE CHARACTER character
| ESCAPES { ON | OFF }
| FORMAT { ASCII | BCP }
| HEXADECIMAL {ON | OFF}
| ORDER {ON | OFF}
| PCTFREE percent-free-space
| QUOTES { ON | OFF }
| SKIP integer
| STRIP { ON | OFF }
| WITH CHECKPOINT { ON | OFF }

statistics-limitation-options :
STATISTICS { ON [ ALL COLUMNS ] | OFF | ON KEY COLUMNS | ON ( column-list ) }

filename : { string | variable }

toggle Parameters

Column-name Any columns not present in the column list become NULL if the DEFAULTS option is off. If DEFAULTS is on and the column has a default value, that value will be used. If DEFAULTS is off and a non-nullable column is omitted from the column list, the engine attempts to convert the empty string to the column's type.

When a column list is specified, it lists the columns that are expected to exist in the file and the order in which they are to appear. Column names cannot be repeated. Column names that do not appear in the list will be set to null/zero/empty or DEFAULT (depending on column nullability, data type, and the DEFAULT setting). Columns that exist in the input file that are to be ignored by LOAD TABLE can be specified using the column name "filler()".

FROM option The filename-string is passed to the server as a string. The string is therefore subject to the same formatting requirements as other SQL strings. In particular:

  • To indicate directory paths, the backslash character \ must be represented by two backslashes. The statement to load data from the file c:\temp\input.dat into the employee table is:

    LOAD TABLE employee
FROM 'c:\\temp\\input.dat' ...

  • The path name is relative to the database server, not to the client application. If you are running the statement on a database server on another computer, the directory names refer to directories on the server machine, not on the client machine.

  • You can use UNC path names to load data from files on computers other than the server. For example, on a Windows 95 or Windows NT network, you may use the following statement to load data from a file on the client machine:

    LOAD TABLE employee
FROM '\\\\client\\temp\\input.dat'

CHECK CONSTRAINTS option This option is on by default, but the Unload utility writes out LOAD TABLE statements with the option set to off.

Setting CHECK CONSTRAINTS to off disables check constraints. This can be useful, for example, during database rebuilding. If a table has check constraints that call user-defined functions that are not yet created, the rebuild fails unless this option is set to off.

COMPUTES option By default, COMPUTES is ON. Setting COMPUTES to ON enables recalculation of computed columns.

Setting COMPUTES to OFF disables computed column recalculations. This option is useful, for example, if you are rebuilding a database, and a table has a computed column that calls a user-defined function that is not yet created. The rebuild would fail unless this option was set to OFF.

The Unload utility (dbunload) writes out LOAD TABLE statements with the COMPUTES option set to OFF.

DEFAULTS option By default, DEFAULTS is OFF. If DEFAULTS is OFF, any column not present in the column list is assigned NULL. If DEFAULTS is OFF and a non-nullable column is omitted from the column list, the database server attempts to convert the empty string to the column's type. If DEFAULTS is ON and the column has a default value, that value is used.

DELIMITED BY option The default column delimiter character is a comma. You can specify an alternative column delimiter by providing a string. The same formatting requirements apply as to other SQL strings. In particular, if you wanted to specify tab-delimited values, the hexadecimal ASCII code of the tab character (9) is used. The DELIMITED BY clause is as follows:

...DELIMITED BY '\x09' ...

You can specify delimiters that are up to 255 bytes in length. For example,

...DELIMITED BY '###' ...

ESCAPE CHARACTER option The default escape character for characters stored as hexadecimal codes and symbols is a backslash (\), so \x0A is the linefeed character, for example.

This can be changed using the ESCAPE CHARACTER clause. For example, to use the exclamation mark as the escape character, you would enter

... ESCAPE CHARACTER '!'

Only one single-byte character can be used as an escape character.

ESCAPES option With ESCAPES turned on (the default), characters following the backslash character are recognized and interpreted as special characters by the database server. New line characters can be included as the combination \n, other characters can be included in data as hexadecimal ASCII codes, such as \x09 for the tab character. A sequence of two backslash characters ( \\ ) is interpreted as a single backslash. A backslash followed by any character other than n, x, X or \ is interpreted as two separate characters. For example, \q inserts a backslash and the letter q.

FORMAT option If you choose ASCII, input lines are assumed to be ASCII characters, one row per line, with values separated by the column delimiter character. Choosing BCP allows the import of ASE generated BCP out files containing blobs.

HEXADECIMAL option By default, HEXADECIMAL is ON. With HEXADECIMAL ON, binary column values are read as 0x nnnnnn..., where each n is a hexadecimal digit. It is important to use HEXADECIMAL ON when dealing with multi-byte character sets.

The HEXADECIMAL option can be used only with the FORMAT ASCII option.

ORDER option The default for ORDER is ON. If ORDER is ON, and a clustered index has been declared, then LOAD TABLE sorts the input data according to the clustered index and inserts rows in the same order. If the data you are loading is already sorted, you should set ORDER to OFF.

For more information, see Using clustered indexes.

QUOTES option With QUOTES turned on (the default), the LOAD TABLE statement expects strings to be enclosed in quote characters. The quote character is either an apostrophe (single quote) or a quotation mark (double quote). The first such character encountered in a string is treated as the quote character for the string. Strings must be terminated by a matching quote.

With quotes on, column delimiter characters can be included in column values. Also, quote characters are assumed not to be part of the value. Therefore, a line of the form

'123 High Street, Anytown',(715)398-2354

is treated as two values, not three, despite the presence of the comma in the address. Also, the quotes surrounding the address are not inserted into the database.

To include a quote character in a value, with QUOTES on, you must use two quotes. The following line includes a value in the third column that is a single quote character:

'123 High Street, Anytown','(715)398-2354',''''

SKIP option Include a SKIP option to ignore the first few lines of a file. The integer argument specifies the number of lines to skip. You can use this option to skip over a line containing column headings, for example. If the row delimiter is not the default (newline), then skipping may not work correctly if the data contains the row delimiter embedded with a quoted string.

STRIP option With STRIP turned on (the default), trailing blanks are stripped from values before they are inserted. To turn the STRIP option off, the clause is as follows:

...STRIP OFF ...

Trailing blanks are stripped only for non-quoted strings. Quoted strings retain their trailing blanks. Leading blanks are trimmed, regardless of the STRIP setting, unless they are enclosed in quotes.

WITH CHECKPOINT option The default setting is OFF. If set to ON, a checkpoint is issued after successfully completing and logging the statement.

If WITH CHECKPOINT ON is not specified, and the database requires automatic recovery before a CHECKPOINT is issued, the data file used to load the table must be present for the recovery to complete successfully. If WITH CHECKPOINT ON is specified, and recovery is subsequently required, recovery begins after the checkpoint, and the data file need not be present.

Caution If you set the database option CONVERSION_ERROR to OFF, you may load bad data into your table without any error being reported. If you do not specify WITH CHECKPOINT ON, and the database needs to be recovered, the recovery may fail as CONVERSION_ERROR is ON (the default value) during recovery. It is recommended that you do not load tables with CONVERSION_ERROR set to OFF and WITH CHECKPOINT ON not specified.

For more information, see CONVERSION_ERROR option.

The data files are required, regardless of this option, if the database becomes corrupt and you need to use a backup and apply the current log file.

PCTFREE option Specifies the percentage of free space you want to reserve for each table page. This setting overrides any permanent setting for the table, but only for the duration of the load.

The value percent-free-space is an integer between 0 and 100. The former specifies that no free space is to be left on each page—each page is to be fully packed. A high value causes each row to be inserted into a page by itself.

For more information about PCTFREE, see CREATE TABLE statement.

statistics-limitation-options Allows you to limit the columns for which statistics are generated during the execution of LOAD TABLE. Otherwise, statistics are generated for all columns. You should only use this option if you are certain that statistics will not be used on some columns. You can specify ON ALL COLUMNS (the default), OFF, ON KEY COLUMNS, or a list of columns for which statistics should be generated.

toggle Usage
Caution LOAD TABLE is intended solely for fast loading of large amounts of data. LOAD TABLE does not write individual rows to the transaction log.

The LOAD TABLE statement allows efficient mass insertion into a database table from an ASCII file. LOAD TABLE is more efficient than the Interactive SQL statement INPUT. Before inserting data, you can specify the percentage of each table page that should be left free for later updates. For more information, see the ALTER TABLE statement.

LOAD TABLE places an exclusive lock on the whole table.

You can use LOAD TABLE on temporary tables, but the temporary table must have been created with the ON COMMIT PRESERVE ROWS clause because LOAD TABLE does a COMMIT after the load.

If the ASCII file has entries such that a column appears to be NULL, LOAD TABLE treats it as null. If the column in that position cannot be NULL, it inserts a zero in numeric columns and an empty string in character columns. LOAD TABLE skips empty lines in the input file.

LOAD TABLE and statistics LOAD TABLE captures column statistics when it loads data in order to create histograms on table columns. If a histogram already exists for a column, LOAD TABLE leaves the existing histogram alone and does not create a new one. If you are loading into an empty table, it may be beneficial to drop statistics first.

LOAD TABLE does not generate statistics for columns that contain NULL values for more than 90% of the rows being loaded.

LOAD TABLE saves statistics on base tables for future use. It does not save statistics on global temporary tables.

LOAD TABLE adds statistics only if the table has five or more rows. If the table has at least five rows, histograms are added as follows:

Data already in table? | Histogram present? | Action taken
Yes | Yes | Update existing histograms
Yes | No | Don't build histograms
No | Yes | Update existing histograms
No | No | Build new histograms

For more information, see Optimizer estimates and histograms.

Using dynamically constructed filenames You can execute a LOAD TABLE statement with a dynamically constructed filename by dynamically constructing the entire statement, then executing it using the EXECUTE IMMEDIATE statement. For more information, see the EXECUTE IMMEDIATE statement [SP].

toggle Permissions

The permissions required to execute a LOAD TABLE statement depend on the database server –gl command line option, as follows:

  • If the -gl option is ALL, you must be the owner of the table or have DBA authority or have ALTER privilege.

  • If the -gl option is DBA, you must have DBA authority.

  • If the -gl option is NONE, LOAD TABLE is not permitted.

For more information, see -gl server option.

Requires an exclusive lock on the table.

toggle Side effects

Inserts are not recorded in the log file. Thus, the inserted rows may not be recovered in the event of a crash. In addition, the LOAD TABLE statement should never be used in a database involved in SQL Remote replication or databases used as MobiLink clients because these technologies replicate changes through analysis of the log file.

The LOAD TABLE statement does not fire any triggers associated with the table.

A checkpoint is carried out at the beginning of the operation. A second checkpoint, at the end of the operation, is optional.

Column statistics are updated if a significant amount of data is loaded.

toggle Side effects

Automatic commit.

toggle See also
  • UNLOAD TABLE statement
  • INSERT statement
  • INPUT statement [Interactive SQL]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

Following is an example of LOAD TABLE. First, we create a table, then load data into it using a file called input.txt.

CREATE TABLE T( a char(100), let_me_default int DEFAULT 1, c char(100) )

Following is the content of a file called input.txt:

ignore_me, this_is_for_column_c, this_is_for_column_a

The following LOAD statement loads the file called input.txt:

LOAD TABLE T ( filler(), c, a ) FROM 'input.txt' FORMAT ASCII DEFAULTS ON

The command SELECT * FROM t yields the result set:

this_is_for_column_a, 1, this_is_for_column_c

Execute the LOAD TABLE statement with a dynamically-constructed filename, via the EXECUTE IMMEDIATE statement:

CREATE PROCEDURE LoadData( IN from_file LONG VARCHAR )
BEGIN
    DECLARE cmd LONG VARCHAR;
    SET cmd = 'LOAD TABLE DBA.MyTable FROM ' ||
      '''d:\\data\\' || from_file || '''';
    EXECUTE IMMEDIATE WITH ESCAPES OFF cmd;
END


LOCK TABLE statement

toggle Description

Use this statement to prevent other concurrent transactions from accessing or modifying a table.

toggle Syntax

LOCK TABLE table-name
[ WITH HOLD ]
IN { SHARE | EXCLUSIVE } MODE

toggle Parameters

table-name The table must be a base table, not a view. As temporary table data is local to the current connection, locking global or local temporary tables has no effect.

WITH HOLD clause If this clause is specified, the lock is held until the end of the connection. If the clause is not specified, the lock is release when the current transaction is committed or rolled back.

SHARE mode Prevent other transactions from modifying the table, but allow them read access. In this mode you can change data in the table as long as no other transaction has locked the row being modified, either indirectly or explicitly using LOCK TABLE.

EXCLUSIVE mode Prevent other transactions from accessing the table. No other transaction can execute queries, updates of any kind, or any other action against the table. If a table t is locked exclusively with LOCK TABLE t IN EXCLUSIVE MODE, the default server behavior is to not acquire row locks for t. This behavior can be disabled by setting the SUBSUME_ROW_LOCKS option OFF.

toggle Usage

The LOCK TABLE statement allows direct control over concurrency at a table level, independent of the current isolation level.

While the isolation level of a transaction generally governs the kinds of locks that are set when the current transaction executes a request, the LOCK TABLE statement allows more explicit control locking of the rows in a table.

The locks placed by LOCK TABLE in SHARE mode are phantom and anti-phantom locks, which are displayed by the sa_locks procedure as PT and AT.

toggle Permissions

To lock a table in SHARE mode, SELECT privileges are required.

To lock a table in EXCLUSIVE mode; you must be the table owner or have DBA authority.

toggle Side effects

Other transactions that require access to the locked table may be delayed or blocked.

toggle See also
  • SELECT statement
  • sa_locks system procedure
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported in Adaptive Server Enterprise. The WITH HOLD clause is not supported in Adaptive Server Enterprise. Adaptive Server Enterprise provides a WAIT clause that is not supported in Adaptive Server Anywhere.

toggle Example

The following statement prevents other transactions from modifying the customer table for the duration of the current transaction:

LOCK TABLE customer
IN SHARE MODE


LOOP statement

toggle Description

Use this statement to repeat the execution of a statement list.

toggle Syntax

[ statement-label : ]
[ WHILE search-condition ] LOOP
statement-list
END LOOP [ statement-label ]

toggle Usage

The WHILE and LOOP statements are control statements that allow you to execute a list of SQL statements repeatedly while a search-condition evaluates to TRUE. The LEAVE statement can be used to resume execution at the first statement after the END LOOP.

If the ending statement-label is specified, it must match the beginning statement-label.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • FOR statement
  • LEAVE statement
toggle Standards and compatibility

  • SQL/92 Persistent Stored Module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase Not supported in Adaptive Server Enterprise. The WHILE statement provides looping in Transact-SQL stored procedures.

toggle Example

A While loop in a procedure.

...
SET i = 1;
WHILE i <= 10 LOOP
   INSERT INTO Counters( number ) VALUES ( i );
   SET i = i + 1;
END LOOP;
...

A labeled loop in a procedure.

SET i = 1;
lbl:
LOOP
   INSERT
   INTO Counters( number )
   VALUES ( i );
   IF i >= 10 THEN
      LEAVE lbl;
   END IF;
   SET i = i + 1;
END LOOP lbl


MESSAGE statement

toggle Description

Use this statement to display a message.

toggle Syntax

MESSAGE expression, ...
[ TYPE { INFO | ACTION | WARNING | STATUS } ]
[ TO { CONSOLE
| CLIENT [ FOR { CONNECTION conn_id | ALL } ]
| LOG }
[ DEBUG ONLY ]
]

conn_id : integer

toggle Parameters

TYPE clause The TYPE clause only has an effect if the message is sent to the client. The client application must decide how to handle the message. Interactive SQL displays messages in the following locations:

  • INFO The Messages pane. INFO is the default type.

  • ACTION A Message box with an OK button.

  • WARNING A Message box with an OK button.

  • STATUS The Messages pane.

TO clause This clause specifies the destination of a message:

  • CONSOLE Send messages to the database server window. CONSOLE is the default.

  • CLIENT Send messages to the client application. Your application must decide how to handle the message, and you can use the TYPE as information on which to base that decision.

  • LOG Send messages to the server log file specified by the -o option.

FOR clause For messages TO CLIENT, this clause specifies which connections receive notification about the message:

  • CONNECTION conn_id Specify the recipient's connection ID for the message.

  • ALL Specify that all open connections receive the message.

DEBUG ONLY This clause allows you to control whether debugging messages added to stored procedures and triggers are enabled or disabled by changing the setting of the DEBUG_MESSAGES option. When DEBUG ONLY is specified, the MESSAGE statement is executed only when the DEBUG_MESSAGES option is set to ON.

Note
DEBUG ONLY messages are inexpensive when the DEBUG_MESSAGES option is set to OFF, so these statements can usually be left in stored procedures on a production system. However, they should be used sparingly in locations where they would be executed frequently; otherwise, they may result in a small performance penalty.
toggle Usage

The MESSAGE statement displays a message, which can be any expression. Clauses can specify the message type and where the message appears.

The procedure issuing a MESSAGE ... TO CLIENT statement must be associated with a connection.

For example, the message box is not displayed in the following example because the event occurs outside of a connection.

CREATE EVENT CheckIdleTime
TYPE ServerIdle
WHERE event_condition( 'IdleTime' ) > 100
HANDLER
BEGIN
   MESSAGE 'Idle engine' type warning to client;
END;

However, in the following example, the message is written to the server console.

CREATE EVENT CheckIdleTime
TYPE ServerIdle
WHERE event_condition( 'IdleTime' ) > 100
HANDLER
BEGIN
   MESSAGE 'Idle engine' type warning to console;
END;

Valid expressions can include a quoted string or other constant, variable, or function.

The FOR clause can be used to notify another application of an event detected on the server without the need for the application to explicitly check for the event. When the FOR clause is used, recipients receive the message the next time that they execute a SQL statement. If the recipient is currently executing a SQL statement, the message is received when the statement completes. If the statement being executed is a stored procedure call, the message is received before the call is completed.

If an application requires notification within a short time after the message is sent and when the connection is not executing SQL statements, you can use a second connection. This connection can execute one or more WAITFOR DELAY statements. These statements do not consume significant resources on the server or network (as would happen with a polling approach), but permit applications to receive notification of the message shortly after it is sent.

ESQL and ODBC clients receive messages via message callback functions. In each case, these functions must be registered. To register ESQL message handlers, use the db_register_callback function.

ODBC clients can register callback functions using the SQLSetConnectAttr function.

toggle Permissions

DBA authority is required to execute a MESSAGE statement containing a FOR clause.

toggle Side effects

None.

toggle See also
  • CREATE PROCEDURE statement
  • DEBUG_MESSAGES option [database]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported in Adaptive Server Enterprise. The Transact-SQL PRINT statement provides a similar feature, and is also available in Adaptive Server Anywhere.

toggle Examples

  1. The following procedure displays a message on the server message window:

    CREATE PROCEDURE message_test ()
BEGIN
MESSAGE 'The current date and time: ', Now();
END

    The statement:

    CALL message_test()

    displays the string The current date and time, and the current date and time, on the database server message window.

  2. To register a callback in ODBC, first declare the message handler:

    void SQL_CALLBACK my_msgproc(
   void *    sqlca,
   unsigned char     msg_type,
   long              code,
   unsigned short    len,
   char*             msg )
{ ... }

    Install the declared message handler by calling the SQLSetConnectAttr function.

    rc = SQLSetConnectAttr(
   dbc,
   ASA_REGISTER_MESSAGE_CALLBACK,
   (SQLPOINTER) &my_msgproc, SQL_IS_POINTER );


OPEN statement [ESQL] [SP]

toggle Description

Use this statement to open a previously declared cursor to access information from the database.

toggle Syntax

OPEN cursor-name
[ USING [ DESCRIPTOR sqlda-name | hostvar, ...] ]
[ WITH HOLD ]
[ ISOLATION LEVEL n ]
[ BLOCK n ]

cursor-name : identifier or hostvar

sqlda-name : identifier

toggle Parameters

Embedded SQL usage After successful execution of the OPEN statement, the sqlerrd[3] field of the SQLCA (SQLIOESTIMATE) is filled in with an estimate of the number of input/output operations required to fetch all rows of the query. Also, the sqlerrd[2] field of the SQLCA (SQLCOUNT) is filled with either the actual number of rows in the cursor (a value greater than or equal to 0), or an estimate thereof (a negative number whose absolute value is the estimate). It will be the actual number of rows if the database server can compute it without counting the rows. The database can also be configured to always return the actual number of rows (see ROW_COUNTS option [database]), but this can be expensive.

If cursor-name is specified by an identifier or string, the corresponding DECLARE CURSOR must appear prior to the OPEN in the C program; if the cursor-name is specified by a host variable, the DECLARE CURSOR statement must execute before the OPEN statement.

USING DESCRIPTOR clause The USING DESCRIPTOR clause is for Embedded SQL only. It specifies the host variables to be bound to the place-holder bind variables in the SELECT statement for which the cursor has been declared.

WITH HOLD clause By default, all cursors are automatically closed at the end of the current transaction (COMMIT or ROLLBACK). The optional WITH HOLD clause keeps the cursor open for subsequent transactions. It will remain open until the end of the current connection or until an explicit CLOSE statement is executed. Cursors are automatically closed when a connection is terminated.

ISOLATION LEVEL clause The ISOLATION LEVEL clause allows this cursor to be opened at an isolation level different from the current setting of the ISOLATION_LEVEL option. All operations on this cursor will be performed at the specified isolation level regardless of the option setting. If this clause is not specified, then the cursor's isolation level for the entire time the cursor is open is the value of the ISOLATION_LEVEL option when the cursor is opened. See How locking works.

The cursor is positioned before the first row (see Using cursors in embedded SQL or Using cursors in procedures and triggers).

BLOCK clause This clause is for Embedded SQL use only. Rows may be fetched by the client application more than one at a time. This is referred to as block fetching, prefetching, or multi-row fetching. The BLOCK clause can reduce the number of rows prefetched. Specifying the BLOCK clause on OPEN is the same as specifying the BLOCK clause on each FETCH.

For more information, see FETCH statement [ESQL] [SP].

toggle Usage

The OPEN statement opens the named cursor. The cursor must be previously declared.

When the cursor is on a CALL statement, OPEN causes the procedure to execute until the first result set (SELECT statement with no INTO clause) is encountered. If the procedure completes and no result set is found, the SQLSTATE_PROCEDURE_COMPLETE warning is set.

toggle Permissions

Must have SELECT permission on all tables in a SELECT statement, or EXECUTE permission on the procedure in a CALL statement.

toggle Side effects

None.

toggle See also
  • DECLARE CURSOR statement [ESQL] [SP]
  • RESUME statement
  • PREPARE statement [ESQL]
  • FETCH statement [ESQL] [SP]
  • RESUME statement
  • CLOSE statement [ESQL] [SP]
toggle Standards and compatibility

  • SQL/92 Embedded SQL use is an entry-level feature. Procedures use is a Persistent Stored Modules feature.

  • SQL/99 Embedded SQL use is a core feature. Procedures use is a Persistent Stored Modules feature.

  • Sybase The simple OPEN cursor-name syntax is supported by Adaptive Server Enterprise. None of the other clauses are supported in Adaptive Server Enterprise stored procedures. Open Client/Open Server supports the USING descriptor or host variable syntax.

toggle Example

The following examples show the use of OPEN in Embedded SQL.

EXEC SQL OPEN employee_cursor;

and

EXEC SQL PREPARE emp_stat FROM
'SELECT empnum, empname FROM employee WHERE name like ?';
EXEC SQL DECLARE employee_cursor CURSOR FOR emp_stat;
EXEC SQL OPEN employee_cursor USING :pattern;

The following example is from a procedure or trigger.

BEGIN
DECLARE cur_employee CURSOR FOR
   SELECT emp_lname
   FROM employee;
DECLARE name CHAR(40);
OPEN cur_employee;
LOOP
FETCH NEXT cur_employee into name;
    ...
END LOOP
CLOSE cur_employee;
END


OUTPUT statement [Interactive SQL]

toggle Description

Use this statement to output the current query results to a file.

toggle Syntax

OUTPUT TO filename
[ APPEND ]
[ VERBOSE ]
[ FORMAT output-format ]
[ ESCAPE CHARACTER character ]
[ ESCAPES { ON | OFF }
[ DELIMITED BY string ]
[ QUOTE string [ ALL ] ]
[ COLUMN WIDTHS (integer, ...) ]
[ HEXADECIMAL { ON | OFF | ASIS } ]
[ ENCODING encoding ]

output-format :
ASCII | DBASEII | DBASEIII | EXCEL
| FIXED | FOXPRO | HTML | LOTUS | SQL | XML

encoding : string or identifier

toggle Parameters

APPEND clause This optional keyword is used to append the results of the query to the end of an existing output file without overwriting the previous contents of the file. If the APPEND clause is not used, the OUTPUT statement overwrites the contents of the output file by default. The APPEND keyword is valid if the output format is ASCII, FIXED, or SQL.

VERBOSE clause When the optional VERBOSE keyword is included, error messages about the query, the SQL statement used to select the data, and the data itself are written to the output file. Lines that do not contain data are prefixed by two hyphens. If VERBOSE is omitted (the default) only the data is written to the file. The VERBOSE keyword is valid if the output format is ASCII, FIXED, or SQL.

FORMAT clause Allowable output formats are:

  • ASCII The output is an ASCII format file with one row per line in the file. All values are separated by commas, and strings are enclosed in apostrophes (single quotes). The delimiter and quote strings can be changed using the DELIMITED BY and QUOTE clauses. If ALL is specified in the QUOTE clause, all values (not just strings) are quoted.

    Three other special sequences are also used. The two characters \n represent a newline character, \\ represents a single \, and the sequence \xDD represents the character with hexadecimal code DD. This is the default output format.

  • DBASEII The output is a dBASE II format file which includes column definitions. Note that a maximum of 32 columns can be output. Column names are truncated to 11 characters, and each row of data in each column is truncated to 255 characters.

  • DBASEIII The output is a dBASE III format file which includes column definitions. Note that a maximum of 128 columns can be output. Column names are truncated to 11 characters, and each row of data in each column is truncated to 255 characters.

  • EXCEL The output is an Excel 2.1 worksheet. The first row of the worksheet contains column labels (or names if there are no labels defined). Subsequent worksheet rows contain the actual table data.

  • FIXED The output is fixed format with each column having a fixed width. The width for each column can be specified using the COLUMN WIDTHS clause. No column headings are output in this format.

    If the COLUMN WIDTHS clause is omitted, the width for each column is computed from the data type for the column, and is large enough to hold any value of that data type. The exception is that LONG VARCHAR and LONG BINARY data default to 32 kb.

  • FOXPRO The output is a FoxPro format file which includes column definitions. Note that a maximum of 128 columns can be output. Column names are truncated to 11 characters. Column names are truncated to 11 characters, and each row of data in each column is truncated to 255 characters.

  • HTML The output is in the Hyper Text Markup Language format.

  • LOTUS The output is a Lotus WKS format worksheet. Column names will be put as the first row in the worksheet. Note that there are certain restrictions on the maximum size of Lotus WKS format worksheets that other software (such as Lotus 1-2-3) can load. There is no limit to the size of file Interactive SQL can produce.

  • SQL The output is an Interactive SQL INPUT statement required to recreate the information in the table.

  • XML The output is an XML file encoded in UTF-8 and containing an embedded DTD. Binary values are encoded in CDATA blocks with the binary data rendered as 2-hex-digit strings. The INPUT statement does not accept XML as a file format.

ESCAPE CHARACTER clause The default escape character for characters stored as hexadecimal codes and symbols is a backslash (\), so \x0A is the linefeed character, for example.

This can be changed using the ESCAPE CHARACTER clause. For example, to use the exclamation mark as the escape character, you would enter

... ESCAPE CHARACTER '!'

ESCAPES clause With ESCAPES turned on (the default), characters following the backslash character are recognized and interpreted as special characters by the database server. New line characters can be included as the combination \n, other characters can be included in data as hexadecimal ASCII codes, such as \x09 for the tab character. A sequence of two backslash characters ( \\ ) is interpreted as a single backslash. A backslash followed by any character other than n, x, X or \ is interpreted as two separate characters. For example, \q inserts a backslash and the letter q.

DELIMITED BY clause The DELIMITED BY clause is for the ASCII output format only. The delimiter string is placed between columns (default comma).

QUOTE clause The QUOTE clause is for the ASCII output format only. The quote string is placed around string values. The default is a single quote character. If ALL is specified in the QUOTE clause, the quote string is placed around all values, not just around strings.

COLUMN WIDTHS clause The COLUMN WIDTHS clause is used to specify the column widths for the FIXED format output.

HEXADECIMAL clause The HEXADECIMAL clause specifies how binary data is to be unloaded for the ASCII format only. When set to ON, binary data is unloaded in the format 0xabcd. When set to OFF, binary data is escaped when unloaded (\xab\xcd). When set to ASIS, values are written as is, that is, without any escaping—even if the value contains control characters. ASIS is useful for text that contains formatting characters such as tabs or carriage returns.

ENCODING clause The encoding argument allows you to specify the encoding that is used to write the file. The ENCODING clause can only be used with the ASCII format.

If encoding is not specified, Interactive SQL determines the code page that is used to write the file as follows, where code page values occurring earlier in the list take precedence over those occurring later in the list:

  • the code page specified with the DEFAULT_ISQL_ENCODING option (if this option is set)

  • the code page specified with the -codepage option when Interactive SQL was started

  • the default code page for the computer Interactive SQL is running on

For more information about Interactive SQL and encodings, see DEFAULT_ISQL_ENCODING option [Interactive SQL].

toggle Usage

The OUTPUT statement copies the information retrieved by the current query to a file.

The output format can be specified with the optional FORMAT clause. If no FORMAT clause is specified, the Interactive SQL OUTPUT_FORMAT option setting is used (see OUTPUT_FORMAT option [Interactive SQL]).

The current query is the SELECT or INPUT statement which generated the information that appears on the Results tab in the Results pane. The OUTPUT statement reports an error if there is no current query.

toggle Permissions

None.

toggle Side effects

In Interactive SQL, the Results tab displays only the results of the current query. All previous query results are replaced with the current query results.

toggle See also
  • SELECT statement
  • INPUT statement [Interactive SQL]
  • UNLOAD TABLE statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Examples

Place the contents of the employee table in a file in ASCII format:

SELECT *
FROM employee;
OUTPUT TO employee.txt
FORMAT ASCII

Place the contents of the employee table at the end of an existing file, and include any messages about the query in this file as well:

SELECT *
FROM employee;
OUTPUT TO employee.txt APPEND VERBOSE

Suppose you need to export a value that contains an embedded line feed character. A line feed character has the numeric value 10, which you can represent as the string '\x0a' in a SQL statement. If you execute the following statement, with HEXADECIMAL set to ON,

SELECT 'line1\x0aline2';
OUTPUT TO file.txt HEXADECIMAL ON

you get a file with one line in it containing the following text:

line10x0aline2

But if you execute the same statement with HEXADEMICAL set to OFF, you get the following:

line1\x0aline2

Finally, if you set HEXADECIMAL to ASIS, you get a file with two lines:

line1
line2

You get two lines when you use ASIS because the embedded line feed character has been exported without being converted to a two digit hex representation, and without being prefixed by anything.


PARAMETERS statement [Interactive SQL]

toggle Description

Use this statement to specify parameters to an Interactive SQL command file.

toggle Syntax

PARAMETERS parameter1, parameter2, ...

toggle Usage

The PARAMETERS statement names the parameters for a command file, so that they can be referenced later in the command file.

Parameters are referenced by putting:

{parameter1}

into the file where you wish the named parameter to be substituted. There must be no spaces between the braces and the parameter name.

If a command file is invoked with less than the required number of parameters, Interactive SQL prompts for values of the missing parameters.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • READ statement [Interactive SQL]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

The following Interactive SQL command file takes two parameters.

PARAMETERS department_id, file;
SELECT emp_lname
FROM employee
WHERE dept_id = {department_id}
>#{file}.dat;

If you save this script in a file named test.sql, you can run it from Interactive SQL using the following command:

READ test.SQL [100] [data]


PASSTHROUGH statement [SQL Remote]

toggle Description

Use this statement to start or stop passthrough mode for SQL Remote administration. Forms 1 and 2 start passthrough mode, while form 3 stops passthrough mode.

toggle Syntax 1

PASSTHROUGH [ ONLY ] FOR userid, ...

toggle Syntax 2

PASSTHROUGH [ ONLY ] FOR SUBSCRIPTION
TO [ ( owner ) ].publication-name [ ( constant ) ]

toggle Syntax 3

PASSTHROUGH STOP

toggle Usage

In passthrough mode, any SQL statements are executed by the database server, and are also placed into the transaction log to be sent in messages to subscribers. If the ONLY keyword is used to start passthrough mode, the statements are not executed at the server; they are sent to recipients only. When a passthrough session contains calls to stored procedures, the procedures must exist in the server that is issuing the passthrough commands, even if they are not being executed locally at the server. The recipients of the passthrough SQL statements are either a list of user IDs (syntax 1) or all subscribers to a given publication. Passthrough mode may be used to apply changes to a remote database from the consolidated database or send statements from a remote database to the consolidated database.

Syntax 2 sends statements to remote databases whose subscriptions are started, and does not send statements to remote databases whose subscriptions are created and not started.

toggle Permissions

Must have DBA authority.

toggle Side effects

None.

toggle See also
  • sp_passthrough procedure
toggle Example
PASSTHROUGH FOR rem_db ;
...
( SQL statements to be executed at the remote database )
...
PASSTHROUGH STOP ;


PREPARE statement [ESQL]

toggle Description

Use this statement to prepare a statement to be executed later, or used to define a cursor.

toggle Syntax

PREPARE statement-name
FROM statement
[ DESCRIBE describe-type INTO [ [ SQL ] DESCRIPTOR ] descriptor ]
[ WITH EXECUTE ]

statement-name : identifier or hostvar

statement : string or hostvar

describe-type :
[ ALL | BIND VARIABLES | INPUT | OUTPUT | SELECT LIST ]
[ LONG NAMES [ [ [ OWNER. ]TABLE. ]COLUMN ]
| WITH VARIABLE RESULT ]

toggle Parameters

statement-name The statement name can be an identifier or host variable. However, you should not use an identifier when using multiple SQLCAs. If you do, two prepared statements may have the same statement number, which could cause the wrong statement to be executed or opened.

DESCRIBE clause If DESCRIBE INTO DESCRIPTOR is used, the prepared statement is described into the specified descriptor. The describe type may be any of the describe types allowed in the DESCRIBE statement.

WITH EXECUTE clause If the WITH EXECUTE clause is used, the statement is executed if and only if it is not a CALL or SELECT statement, and it has no host variables. The statement is immediately dropped after a successful execution. If the PREPARE and the DESCRIBE (if any) are successful but the statement cannot be executed, a warning SQLCODE 111, SQLSTATE 01W08 is set, and the statement is not dropped.

The DESCRIBE INTO DESCRIPTOR and WITH EXECUTE clauses may improve performance because they cut down on the required client/server communication.

WITH VARIABLE RESULT clause The WITH VARIABLE RESULT clause is used to describe procedures that may have more than one result set, with different numbers or types of columns.

If WITH VARIABLE RESULT is used, the database server sets the SQLCOUNT value after the describe to one of the following values:

  • 0 The result set may change: The procedure call should be described again following each OPEN statement.

  • 1 The result set is fixed. No redescribing is required.

Static and dynamic
For compatibility reasons, preparing COMMIT, PREPARE TO COMMIT, and ROLLBACK statements is still supported. However, we recommend that you do all transaction management operations with static Embedded SQL because certain application environments may require it. Also, other Embedded SQL systems do not support dynamic transaction management operations.
toggle Usage

The PREPARE statement prepares a SQL statement from the statement and associates the prepared statement with statement-name. This statement name is referenced to execute the statement, or to open a cursor if the statement is a SELECT statement. The statement-name may be a host variable of type a_sql_statement_number defined in the sqlca.h header file that is automatically included. If an identifier is used for the statement-name, only one statement per module may be prepared with this statement-name.

If a host variable is used for statement-name, it must have the type short int. There is a typedef for this type in sqlca.h called a_sql_statement_number. This type is recognized by the SQL preprocessor and can be used in a DECLARE section. The host variable is filled in by the database during the PREPARE statement, and need not be initialized by the programmer.

toggle Permissions

None.

toggle Side effects

Any statement previously prepared with the same name is lost.

The statement is dropped after use only if you use WITH EXECUTE and the execution is successful. You should ensure that you DROP the statement after use in other circumstances. If you do not, the memory associated with the statement is not reclaimed.

toggle See also
  • DECLARE CURSOR statement [ESQL] [SP]
  • DESCRIBE statement [ESQL]
  • OPEN statement [ESQL] [SP]
  • EXECUTE statement [ESQL]
  • DROP STATEMENT statement [ESQL]
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Supported by Open Client/Open Server.

toggle Example

The following statement prepares a simple query:

EXEC SQL PREPARE employee_statement FROM
'SELECT emp_lname FROM employee';


PREPARE TO COMMIT statement

toggle Description

Use this statement to check whether a COMMIT can be performed successfully.

toggle Syntax

PREPARE TO COMMIT

toggle Usage

The PREPARE TO COMMIT statement tests whether a COMMIT can be performed successfully. The statement will cause an error if a COMMIT is impossible without violating the integrity of the database.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • COMMIT statement
  • ROLLBACK statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported in Adaptive Server Enterprise.

toggle Example

The following sequence of statements leads to an error because of foreign key checking on the employee table.

EXECUTE IMMEDIATE
   "SET OPTION wait_for_commit = 'on'";
EXECUTE IMMEDIATE "DELETE FROM employee
   WHERE emp_id = 160";
EXECUTE IMMEDIATE "PREPARE TO COMMIT";

The following sequence of statements does not cause an error when the delete statement is executed, even though it causes integrity violations. The PREPARE TO COMMIT statement returns an error.

SET OPTION wait_for_commit= 'ON';
DELETE
FROM department
WHERE dept_id = 100;
PREPARE TO COMMIT;


PRINT statement [T-SQL]

toggle Description

Use this statement to return a message to the client, or display a message in the message window of the database server.

toggle Syntax

PRINT format-string [, arg-list]

toggle Usage

The PRINT statement returns a message to the client window if you are connected from an Open Client application or jConnect application. If you are connected from an embedded SQL or ODBC application, the message is displayed on the database server window.

The format string can contain placeholders for the arguments in the optional argument list. These placeholders are of the form %nn!, where nn is an integer between 1 and 20.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • MESSAGE statement
toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Example

The following statement displays a message:

PRINT 'Display this message'

The following statement illustrates the use of placeholders in the PRINT statement:

DECLARE @var1 INT, @var2 INT
SELECT @var1 = 3, @var2 = 5
PRINT 'Variable 1 = %1!, Variable 2 = %2!', @var1, @var2


PUT statement [ESQL]

toggle Description

Use this statement to insert a row into the specified cursor.

toggle Syntax

PUT cursor-name
[ USING DESCRIPTOR sqlda-name | FROM hostvar-list ]
[ INTO { DESCRIPTOR into-sqlda-name | into-hostvar-list } ]
[ ARRAY :nnn ]

cursor-name : identifier or hostvar

sqlda-name : identifier

hostvar-list : may contain indicator variables

toggle Usage

Inserts a row into the named cursor. Values for the columns are taken from the first SQLDA or the host variable list, in a one-to-one correspondence with the columns in the INSERT statement (for an INSERT cursor) or the columns in the select list (for a SELECT cursor).

The PUT statement can be used only on a cursor over an INSERT or SELECT statement that references a single table in the FROM clause, or that references an updateable view consisting of a single base table.

If the sqldata pointer in the SQLDA is the null pointer, no value is specified for that column. If the column has a DEFAULT VALUE associated with it, that will be used; otherwise, a NULL value will be used.

The second SQLDA or host variable list contains the results of the PUT statement.

The optional ARRAY clause can be used to carry out wide puts, which insert more than one row at a time and which may improve performance. The value nnn is the number of rows to be inserted. The SQLDA must contain nnn * (columns per row) variables. The first row is placed in SQLDA variables 0 to (columns per row)-1, and so on.

Inserting into a cursor
For scroll (values sensitive) cursors, the inserted row will appear if the new row matches the WHERE clause and the keyset cursor has not finished populating. For dynamic cursors, if the inserted row matches the WHERE clause, the row may appear. Insensitive cursors cannot be updated.

For information on putting LONG VARCHAR or LONG BINARY values into the database, see SET statement.

toggle Permissions

Must have INSERT permission.

toggle Side effects

When inserting rows into a value-sensitive (keyset driven) cursor, the inserted rows appear at the end of the result set, even when they do not match the WHERE clause of the query or if an ORDER BY clause would normally have placed them at another location in the result set. For more information, see Modifying rows through a cursor.

toggle See also
  • UPDATE statement
  • UPDATE (positioned) statement [ESQL] [SP]
  • DELETE statement
  • DELETE (positioned) statement [ESQL] [SP]
  • INSERT statement
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Supported by Open Client/Open Server.

toggle Example

The following statement illustrates the use of PUT in Embedded SQL:

EXEC SQL PUT cur_employee FROM :emp_id, :emp_lname;


RAISERROR statement [T-SQL]

toggle Description

Use this statement to signal an error and to send a message to the client.

toggle Syntax

RAISERROR error-number [ format-string ] [, arg-list ]

toggle Parameters

error-number The error-number is a five-digit integer greater than 17000. The error number is stored in the global variable @@error.

format-string If format-string is not supplied or is empty, the error number is used to locate an error message in the system tables. Adaptive Server Enterprise obtains messages 17000-19999 from the SYSMESSAGES table. In Adaptive Server Anywhere this table is an empty view, so errors in this range should provide a format string. Messages for error numbers of 20000 or greater are obtained from the SYS.SYSUSERMESSAGES table.

In Adaptive Server Anywhere, the format-string length can be up to 255 bytes.

The extended values supported by the Adaptive Server Enterprise RAISERROR statement are not supported in Adaptive Server Anywhere.

The format string can contain placeholders for the arguments in the optional argument list. These placeholders are of the form %nn!, where nn is an integer between 1 and 20.

Intermediate RAISERROR status and code information is lost after the procedure terminates. If at return time an error occurs along with the RAISERROR then the error information is returned and the RAISERROR information is lost. The application can query intermediate RAISERROR statuses by examining @@error global variable at different execution points.

toggle Usage

The RAISERROR statement allows user-defined errors to be signaled and sends a message on the client.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • CREATE TRIGGER statement [T-SQL]
  • ON_TSQL_ERROR option [compatibility]
  • CONTINUE_AFTER_RAISERROR option [compatibility]
toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Example

The following statement raises error 23000, which is in the range for user-defined errors, and sends a message to the client. Note that there is no comma between the error-number and the format-string parameters. The first item following a comma is interpreted as the first item in the argument list.

RAISERROR 23000 'Invalid entry for this column: %1!', @val

The next example uses RAISERROR to disallow connections.

create procedure DBA.login_check()
begin
    // Allow a maximum of 3 concurrent connections
    if( db_property('ConnCount') > 3 ) then
   raiserror 28000
      'User %1! is not allowed to connect -- there are already %2! users logged on',
      current user,
      cast(db_property('ConnCount') as int)-1;
    else
   call sp_login_environment;
    end if;
end
go
grant execute on DBA.login_check to PUBLIC
go
set option PUBLIC.Login_procedure='DBA.login_check'
go

For an alternate way to disallow connections, see LOGIN_PROCEDURE option [database].


READ statement [Interactive SQL]

toggle Description

Use this statement to read Interactive SQL statements from a file.

toggle Syntax

READ [ ENCODING encoding ] filename [ parameters ]

encoding : identifier or string

toggle Usage

The READ statement reads a sequence of Interactive SQL statements from the named file. This file can contain any valid Interactive SQL statement, including other READ statements. READ statements can be nested to any depth. If the file name does not contain an absolute path, Interactive SQL searches for the file. Interactive SQL will first search the current directory, and then the directories specified in the environment variable SQLPATH, and then the directories specified in the environment variable PATH. If the named file has no file extension, Interactive SQL searches each directory for the same file name with the extension .SQL.

The encoding argument allows you to specify the encoding that is used to read the file. The READ statement does not process escape characters when it reads a file. It assumes that the entire file is in the specified encoding.

If encoding is not specified, Interactive SQL determines the code page that is used to read the file as follows, where code page values occurring earlier in the list take precedence over those occurring later in the list:

  • the code page specified with the DEFAULT_ISQL_ENCODING option (if this option is set)

  • the code page specified with the -codepage option when Interactive SQL was started

  • the default code page for the computer Interactive SQL is running on

For more information about Interactive SQL and encodings, see DEFAULT_ISQL_ENCODING option [Interactive SQL].

Parameters can be listed after the name of the command file. These parameters correspond to the parameters named on the PARAMETERS statement at the beginning of the statement file (see PARAMETERS statement [Interactive SQL]). Interactive SQL substitutes the corresponding parameter wherever the source file contains

{parameter-name}

where parameter-name is the name of the appropriate parameter.

The parameters passed to a command file can be identifiers, numbers, quoted identifiers, or strings. When quotes are used around a parameter, the quotes are put into the text during the substitution. Parameters that are not identifiers, numbers, or strings (contain spaces or tabs) must be enclosed in square brackets ([ ]). This allows for arbitrary textual substitution in the command file.

If not enough parameters are passed to the command file, Interactive SQL prompts for values for the missing parameters.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • PARAMETERS statement [Interactive SQL]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

The following are examples of the READ statement.

READ status.rpt '160'
READ birthday.SQL [>= '1988-1-1'] [<= '1988-1-30']


READTEXT statement [T-SQL]

toggle Description

Use this statement to read text and image values from the database, starting from a specified offset and reading a specified number of bytes.

toggle Syntax

READTEXT table-name.column-name
text-pointer offset size
[HOLDLOCK]

toggle Usage

READTEXT is used to read image and text values from the database. You cannot perform READTEXT operations on views.

toggle Permissions

SELECT permissions on the table.

toggle Side effects

None.

toggle See also
  • WRITETEXT statement [T-SQL]
  • GET DATA statement [ESQL]
  • TEXTPTR function [Text and image]
toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Supported by Adaptive Server Enterprise.

    Adaptive Server Enterprise supports the following clause, which is not supported by Adaptive Server Anywhere:

    USING { BYTES | CHARS | CHARACTERS }

    These options are identical for all single-byte character sets. Adaptive Server Anywhere uses bytes only, which is the Adaptive Server Enterprise default setting.

    Adaptive Server Enterprise also provides isolation level control in the READTEXT statement. This is not supported in Adaptive Server Anywhere.


RELEASE SAVEPOINT statement

toggle Description

Use this statement to release a savepoint within the current transaction.

toggle Syntax

RELEASE SAVEPOINT [savepoint-name]

toggle Usage

Release a savepoint. The savepoint-name is an identifier specified on a SAVEPOINT statement within the current transaction. If savepoint-name is omitted, the most recent savepoint is released.

Releasing a savepoint does not do any type of COMMIT. It simply removes the savepoint from the list of currently active savepoints.

toggle Permissions

There must have been a corresponding SAVEPOINT within the current transaction.

toggle Side effects

None.

toggle See also
  • BEGIN TRANSACTION statement
  • COMMIT statement
  • ROLLBACK statement
  • ROLLBACK TO SAVEPOINT statement
  • SAVEPOINT statement
  • Savepoints within transactions
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise. A similar feature is available in an Adaptive Server Enterprise-compatible manner using nested transactions.


REMOTE RESET statement [SQL Remote]

toggle Description

Use this statement in custom database-extraction procedures to start all subscriptions for a remote user in a single transaction.

toggle Syntax

REMOTE RESET userid

toggle Usage

This command starts all subscriptions for a remote user in a single transaction. It sets the log_sent and confirm_sent values in SYSREMOTEUSER table to the current position in the transaction log. It also sets the created and started values in SYSSUBSCRIPTION to the current position in the transaction log for all subscriptions for this remote user. The statement does not do a commit. You must do an explicit commit after this call.

In order to write an extraction process that is safe on a live database, the data must be extracted at isolation level 3 in the same transaction as the subscriptions are started.

This statement is an alternative to start subscription. START SUBSCRIPTION has an implicit commit as a side effect, so that if a remote user has several subscriptions, it is impossible to start them all in one transaction using START SUBSCRIPTION.

toggle Permissions

Must have DBA authority.

toggle Side effects

No automatic commit is done by this statement.

toggle See also
  • START SUBSCRIPTION statement [SQL Remote]
toggle Example

  • The following statement resets the subscriptions for remote user SamS:

    REMOTE RESET SamS


REMOVE JAVA statement

toggle Description

Use this statement to remove a class or a jar file from a database. When a class is removed it is no longer available for use as a column or variable type.

The class or jar must already be installed.

toggle Syntax

REMOVE JAVA classes_to_remove

classes_to_remove :
CLASS java_class_name [, java_class_name, ...]
| JAR jar_name [, jar_name, ...]

toggle Parameters

CLASS The java_class_name parameter is the name of one or more Java class to be removed. These classes must be installed classes in the current database.

JAR The jar_name is a character string value of maximum length 255.

Each jar_name must be equal to the jar_name of a retained jar in the current database. Equality of jar_name is determined by the character string comparison rules of the SQL system.

toggle Usage

Removes a class or jar file from the database.

toggle Permissions

Must have DBA authority.

Not supported on Windows CE.

toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise. A similar feature is available in an Adaptive Server Enterprise-compatible manner using nested transactions.

toggle Example

The following statement removes a Java class named Demo from the current database.

REMOVE JAVA CLASS Demo


REORGANIZE TABLE statement

toggle Description

Use this statement to defragment tables when a full rebuild of the database is not possible due to the requirements for continuous access to the database.

toggle Syntax

REORGANIZE TABLE [ owner.]table-name
[ { PRIMARY KEY
| FOREIGN KEY foreign_key_name
| INDEX index_name }
| ORDER {ON | OFF}
]

toggle Parameters

PRIMARY KEY Reorganizes the primary key index for the table.

FOREIGN KEY Reorganizes the specified foreign key.

INDEX Reorganizes the specified index.

ORDER option With ORDER ON (the default), the data is ordered by clustered index if one exists. If a clustered index does not exist, the data is ordered by primary key values. With ORDER OFF, the data is ordered by primary key.

For more information about clustered indexes, see Using clustered indexes

toggle Usage

Table fragmentation can impede performance. Use this statement to defragment rows in a table, or to compress indexes which have become sparse due to DELETEs. It may also reduce the total number of pages used to store the table and its indexes, and it may reduce the number of levels in an index tree. However, it will not result in a reduction of the total size of the database file. It is recommended that you use the sa_table_fragmentation and sa_index_density system procedures to select tables worth processing.

If an index or key is not specified, the reorganization process defragments rows in the table by deleting and re-inserting groups of rows. For each group, an exclusive lock on the table is obtained. Once the group has been processed, the lock is released and re-acquired (waiting if necessary), providing an opportunity for other connections to access the table. Checkpoints are suspended while the group is being processed; once the group is finished, a checkpoint may occur. The rows are processed in order by primary key (if it exists) or clustered index; if the table has no primary key or clustered index, an error results. The processed rows are re-inserted at the end of the table, resulting in the rows being clustered by primary key at the end of the process. Note that the same amount of work is required, regardless of how fragmented the rows initially were.

If an index or key is specified, the specified index is processed. This form of the statement can only be used with databases created with Adaptive Server Anywhere version 7.0 or above. For the duration of the operation, an exclusive lock is held on the table and checkpoints are suspended. Any attempts to access the table by other connections will block or fail, depending on their setting of the BLOCKING option. The duration of the lock is minimized by pre-reading the index pages prior to obtaining the exclusive lock.

Since both forms of reorganization may modify many pages, the checkpoint log can become large. For version 7.0 or earlier databases, this may result in growth of the database file. For version 8.0 or later databases, this will result in only a temporary increase in the database file size, since the checkpoint log is deleted at shutdown and the file is truncated at that point. Also, more contiguous allocation of table pages may result for version 8.0 or later databases.

Neither form of the statement is logged to the transaction log.

toggle Permissions

  • Must be either the owner of the table, or a user with DBA authority.

  • Not supported on Windows CE.

toggle Side effects

Prior to starting the reorganization, a checkpoint is done to try to maximize the number of free pages.

toggle Examples

The following statement reorganizes the primary key index for the employee table:

REORGANIZE TABLE employee
PRIMARY KEY

The following statement reorganizes the table pages of the employee table:

REORGANIZE TABLE  employee

The following statement reorganizes the index ix_prod_name on the product table:

REORGANIZE TABLE product
   INDEX ix_prod_name

The following statement reorganizes the foreign key ky_dept_id for the employee table:

REORGANIZE TABLE employee
   FOREIGN KEY ky_dept_id


RESIGNAL statement

toggle Description

Use this statement to resignal an exception condition.

toggle Syntax

RESIGNAL [ exception-name ]

toggle Usage

Within an exception handler, RESIGNAL allows you to quit the compound statement with the exception still active, or to quit reporting another named exception. The exception will be handled by another exception handler or returned to the application. Any actions by the exception handler before the RESIGNAL are undone.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • SIGNAL statement
  • BEGIN statement
  • Using exception handlers in procedures and triggers
  • RAISERROR statement [T-SQL]
toggle Standards and compatibility

  • SQL/92 Persistent stored module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase Not supported in Adaptive Server Enterprise. Signaling of errors in Transact-SQL procedures is carried out using the RAISERROR statement.

toggle Example

The following fragment returns all exceptions except Column Not Found to the application.

...
DECLARE COLUMN_NOT_FOUND EXCEPTION
   FOR SQLSTATE '52003';
...
EXCEPTION
WHEN COLUMN_NOT_FOUND THEN
SET message='Column not found';
WHEN OTHERS THEN
RESIGNAL;


RESTORE DATABASE statement

toggle Description

Use this statement to restore a backed up database from an archive.

toggle Syntax

RESTORE DATABASE filename
FROM archive-root
[ CATALOG ONLY |
[ [ RENAME dbspace-name TO new-dbspace-name ] ...] ]
[ HISTORY { ON | OFF } ]

filename : { string | variable }
archive-root : { string | variable }
new-dbspace-name : { string | variable }

toggle Parameters

CATALOG ONLY clause Retrieve information about the named archive, and place it in the backup history file (backup.syb), but do not restore any data from the archive.

RENAME clause Specifies a new location to restore each dbspace to.

HISTORY clause By default, each RESTORE DATABASE operation appends a line to the backup.syb. You can prevent updates to the backup.syb file by specifying HISTORY OFF. You may want to prevent the file from being updated if all of the following conditions apply:

  • your RESTORE DATABASE operations occur frequently

  • there is no procedure to periodically archive or delete the backup.syb file

  • disk space is very limited

toggle Usage

Each RESTORE DATABASE operation updates a history file called backup.syb.

For more information about the backup.syb file, see ASLOGDIR environment variable.

The RENAME clause provides a way to change the restore location for each dbspace. The dbspace name in a RENAME clause cannot be SYSTEM or TRANSLOG.

RESTORE DATABASE replaces the database that is being restored. If you need incremental backups, use the image format of the BACKUP command and save only the transaction log; however, image backups to tape are not supported.

toggle Permissions

The permissions required to execute this statement are set on the server command line, using the -gu option. The default setting is to require DBA authority.

This statement is not supported on Windows CE.

For more information, see -gu server option.

toggle Side effects

None.

toggle See also
  • BACKUP statement
  • Backup and Data Recovery
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported in Adaptive Server Enterprise.

  • Windows CE Not supported on the Windows CE platform.

toggle Example

The following example restores a database from a Windows NT tape drive. The number of backslashes that are required depends on which database you are connected to when you execute RESTORE DATABASE. The database affects the setting of the ESCAPE_CHARACTER option. It is normally ON, but is OFF in utility_db. When connected to any database other than utility_db, the extra backslashes are required.

RESTORE DATABASE 'd:\\dbhome\\cust.db'
FROM '\\\\.\\tape0'


RESUME statement

toggle Description

Use this statement to resume execution of a cursor that returns result sets.

toggle Syntax

RESUME cursor-name

cursor-name : identifier or hostvar

toggle Usage

This statement resumes execution of a procedure that returns result sets. The procedure executes until the next result set (SELECT statement with no INTO clause) is encountered. If the procedure completes and no result set is found, the SQLSTATE_PROCEDURE_COMPLETE warning is set. This warning is also set when you RESUME a cursor for a SELECT statement.

toggle Permissions

The cursor must have been previously opened.

toggle Side effects

None.

toggle See also
  • DECLARE CURSOR statement [ESQL] [SP]
  • Returning results from procedures
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise.

toggle Example

Following are Embedded SQL examples.

1. EXEC SQL RESUME cur_employee;
2. EXEC SQL RESUME :cursor_var;

Following is an Interactive SQL example.

CALL sample_proc();
RESUME ALL;


RETURN statement

toggle Description

Use this statement to exit from a function or procedure unconditionally, optionally providing a return value.

toggle Syntax

RETURN [ expression ]

toggle Usage

A RETURN statement causes an immediate exit from a function or procedure. If expression is supplied, the value of expression is returned as the value of the function or procedure.

Statements following a RETURN statement are not executed.

Within a function, the expression should be of the same data type as the function's RETURNS data type.

Within a procedure, RETURN is used for Transact-SQL-compatibility, and is used to return an integer error code.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • CREATE FUNCTION statement
  • CREATE PROCEDURE statement
  • BEGIN statement
toggle Standards and compatibility

  • SQL/92 Persistent stored module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase Transact-SQL procedures use the RETURN statement to return an integer error code.

toggle Example

The following function returns the product of three numbers:

CREATE FUNCTION product (
   a numeric,
   b numeric,
   c numeric )
RETURNS numeric
BEGIN
   RETURN ( a * b * c );
END

Calculate the product of three numbers:

SELECT product (2, 3, 4)
product(2, 3, 4)
24

The following procedure uses the RETURN statement to avoid executing a complex query if it is meaningless:

CREATE PROCEDURE customer_products
( in customer_id integer DEFAULT NULL)
RESULT ( id integer, quantity_ordered integer )
BEGIN
   IF customer_id NOT IN (SELECT id FROM customer)
   OR customer_id IS NULL THEN
      RETURN
   ELSE
      SELECT product.id,sum(
         sales_order_items.quantity )
      FROM  product,
            sales_order_items,
            sales_order
      WHERE sales_order.cust_id=customer_id
      AND sales_order.id=sales_order_items.id
      AND sales_order_items.prod_id=product.id
      GROUP BY product.id
   END IF
END


REVOKE statement

toggle Description

Use this statement to remove permissions for the specified users.

toggle Syntax 1

REVOKE special-priv, ... FROM userid, ...

special-priv :
CONNECT
| DBA
| INTEGRATED LOGIN
| GROUP
| MEMBERSHIP IN GROUP userid, ...
| RESOURCE

toggle Syntax 2

REVOKE table-priv, ...
ON [ owner.]table-name
FROM userid, ...

table-priv :
ALL [PRIVILEGES]
| ALTER
| DELETE
| INSERT
| REFERENCES [ ( column-name, ...) ]
| SELECT [ ( column-name, ...) ]
| UPDATE [ ( column-name, ...) ]

toggle Syntax 3

REVOKE EXECUTE
ON [ owner.]procedure-name
FROM userid, ...

toggle Usage

The REVOKE statement removes permissions given using the GRANT statement. Syntax 1 revokes special user permissions. Syntax 2 revokes table permissions. Syntax 3 revokes permission to execute a procedure. REVOKE CONNECT removes a user ID from a database, and also destroys any objects (tables, views, procedures, etc.) owned by that user and any permissions granted by that user. REVOKE GROUP automatically REVOKES MEMBERSHIP from all members of the group.

When you add a user to a group, the user inherits all the permissions assigned to that group. Adaptive Server Anywhere does not allow you to revoke a subset of the permissions that a user inherits as a member of a group because you can only revoke permissions that are explicitly given by a GRANT statement. If you need to have different permissions for different users, you can create different groups with the appropriate permissions, or you can explicitly grant each user the permissions they require.

When you grant or revoke group permissions for tables, views, or procedures, all members of the group inherit those changes. The DBA, RESOURCE, and GROUP permissions are not inherited: you must assign them individually to each individual user ID that requires them.

If you give a user GRANT option permission, and later revoke that permission, you also revoke any permissions that that user granted to others while they had the GRANT option.

toggle Permissions

Must be the grantor of the permissions that are being revoked or have DBA authority.

If you are revoking connect permissions or table permissions from another user, the other user must not be connected to the database. You cannot revoke connect permissions from DBO.

toggle Side effects

Automatic commit.

toggle See also
  • GRANT statement
toggle Standards and compatibility

  • SQL/92 Syntax 1 is a vendor extension. Syntax 2 is an entry-level feature. Syntax 3 is a Persistent Stored Modules feature.

  • SQL/99 Syntax 1 is a vendor extension. Syntax 2 is a core feature. Syntax 3 is a Persistent Stored Modules feature.

  • Sybase Syntax 2 and 3 are supported by Adaptive Server Enterprise. Syntax 1 is not supported by Adaptive Server Enterprise. User management and security models are different for Adaptive Server Anywhere and Adaptive Server Enterprise.

toggle Example

Prevent user Dave from updating the employee table.

REVOKE UPDATE ON employee FROM dave;

Revoke resource permissions from user Jim.

REVOKE RESOURCE FROM Jim;

Revoke integrated login mapping from user profile name Administrator.

REVOKE INTEGRATED LOGIN FROM Administrator;

Disallow the Finance group from executing the procedure sp_customer_list.

REVOKE EXECUTE ON sp_customer_list
FROM finance;

Drop user ID FranW from the database.

REVOKE CONNECT FROM FranW


REVOKE CONSOLIDATE statement [SQL Remote]

toggle Description

Use this statement to stop a consolidated database from receiving SQL Remote messages from this database.

toggle Syntax

REVOKE CONSOLIDATE FROM userid

toggle Usage

CONSOLIDATE permissions must be granted at a remote database for the user ID representing the consolidated database. The REVOKE CONSOLIDATE statement removes the consolidated database user ID from the list of users receiving messages from the current database.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit. Drops all subscriptions for the user.

toggle See also
  • REVOKE PUBLISH statement [SQL Remote]
  • REVOKE REMOTE statement [SQL Remote]
  • REVOKE REMOTE DBA statement [SQL Remote]
  • GRANT CONSOLIDATE statement [SQL Remote]
  • sp_revoke_consolidate procedure
toggle Example

  • The following statement revokes consolidated status from the user ID condb:

    REVOKE CONSOLIDATE FROM condb


REVOKE PUBLISH statement [SQL Remote]

toggle Description

Use this statement to terminate the identification of the named user ID as the CURRENT publisher.

toggle Syntax

REVOKE PUBLISH FROM userid

toggle Usage

Each database in a SQL Remote installation is identified in outgoing messages by a publisher user ID. The current publisher user ID can be found using the CURRENT PUBLISHER special constant. The following query identifies the current publisher:

SELECT CURRENT PUBLISHER

The REVOKE PUBLISH statement ends the identification of the named user ID as the publisher.

You should not REVOKE PUBLISH from a database while the database has active SQL Remote publications or subscriptions.

Issuing a REVOKE PUBLISH statement at a database has several consequences for a SQL Remote installation:

  • You will not be able to insert data into any tables with a CURRENT PUBLISHER column as part of the primary key. Any outgoing messages will not be identified with a publisher user ID, and so will not be accepted by recipient databases.

If you change the publisher user ID at any consolidated or remote database in a SQL Remote installation, you must ensure that the new publisher user ID is granted REMOTE permissions on all databases receiving messages from the database. This will generally require all subscriptions to be dropped and recreated.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • GRANT PUBLISH statement [SQL Remote]
  • REVOKE REMOTE statement [SQL Remote]
  • REVOKE REMOTE DBA statement [SQL Remote]
  • REVOKE CONSOLIDATE statement [SQL Remote]
  • sp_publisher procedure
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Example
REVOKE PUBLISH FROM publisher_ID


REVOKE REMOTE statement [SQL Remote]

toggle Description

Use this statement to stop a user from being able to receive SQL Remote messages from this database.

toggle Syntax

REVOKE REMOTE FROM userid, ...

toggle Usage

REMOTE permissions are required for a user ID to receive messages in a SQL Remote replication installation. The REVOKE REMOTE statement removes a user ID from the list of users receiving messages from the current database.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit. Drops all subscriptions for the user.

toggle See also
  • REVOKE PUBLISH statement [SQL Remote]
  • GRANT REMOTE statement [SQL Remote]
  • REVOKE REMOTE DBA statement [SQL Remote]
  • REVOKE CONSOLIDATE statement [SQL Remote]
  • sp_revoke_remote procedure
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Example
REVOKE REMOTE FROM SamS


REVOKE REMOTE DBA statement [SQL Remote]

toggle Description

Use this statement to provide DBA privileges to a user ID, but only when connected from the Message Agent.

toggle Syntax 1

REVOKE REMOTE DBA
FROM userid, ...

toggle Usage

REMOTE DBA authority enables the Message Agent to have full access to the database in order to make any changes contained in the messages, while avoiding security problems associated with distributing DBA user IDs passwords.

  • This statement revokes REMOTE DBA authority from a user ID.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • REVOKE PUBLISH statement [SQL Remote]
  • REVOKE REMOTE statement [SQL Remote]
  • GRANT REMOTE DBA statement [SQL Remote]
  • REVOKE CONSOLIDATE statement [SQL Remote]
  • The Message Agent and replication security
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.


ROLLBACK statement

toggle Description

Use this statement to end a transaction and undo any changes made since the last COMMIT or ROLLBACK.

toggle Syntax

ROLLBACK [ WORK ]

toggle Usage

A transaction is the logical unit of work done on one database connection to a database between COMMIT or ROLLBACK statements. The ROLLBACK statement ends the current transaction and undoes all changes made to the database since the previous COMMIT or ROLLBACK.

toggle Permissions

None.

toggle Side effects

Closes all cursors not opened WITH HOLD.

toggle See also
  • COMMIT statement
  • ROLLBACK TO SAVEPOINT statement
toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Supported by Adaptive Server Enterprise.


ROLLBACK TO SAVEPOINT statement

toggle Description

To cancel any changes made since a SAVEPOINT.

toggle Syntax

ROLLBACK TO SAVEPOINT [savepoint-name]

toggle Usage

The ROLLBACK TO SAVEPOINT statement will undo any changes that have been made since the SAVEPOINT was established. Changes made prior to the SAVEPOINT are not undone; they are still pending.

The savepoint-name is an identifier that was specified on a SAVEPOINT statement within the current transaction. If savepoint-name is omitted, the most recent savepoint is used. Any savepoints since the named savepoint are automatically released.

toggle Permissions

There must have been a corresponding SAVEPOINT within the current transaction.

toggle Side effects

None.

toggle See also
  • BEGIN TRANSACTION statement
  • COMMIT statement
  • RELEASE SAVEPOINT statement
  • ROLLBACK statement
  • SAVEPOINT statement
  • Savepoints within transactions
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Savepoints are not supported by Adaptive Server Enterprise. To implement similar features in an Adaptive Server Enterprise-compatible manner, you can use nested transactions.

    For more information on nested transactions, see BEGIN TRANSACTION statement.


ROLLBACK TRANSACTION statement

toggle Description

Use this statement to cancel any changes made since a SAVE TRANSACTION.

toggle Syntax

ROLLBACK TRANSACTION [ savepoint-name ]

toggle Usage

The ROLLBACK TRANSACTION statement undoes any changes that have been made since a savepoint was established using SAVE TRANSACTION. Changes made prior to the SAVE TRANSACTION are not undone; they are still pending.

The savepoint-name is an identifier that was specified on a SAVE TRANSACTION statement within the current transaction. If savepoint-name is omitted, all outstanding changes are rolled back. Any savepoints since the named savepoint are automatically released.

toggle Permissions

There must be a corresponding SAVE TRANSACTION within the current transaction.

toggle Side effects

None.

toggle See also
  • ROLLBACK TO SAVEPOINT statement
  • BEGIN TRANSACTION statement
  • COMMIT statement SAVE TRANSACTION statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Examples

The following example displays five rows with values 10, 20, and so on. The effect of the DELETE, but not the prior INSERTs or UPDATE, is undone by the ROLLBACK TRANSACTION statement.

BEGIN
    SELECT row_num INTO #tmp
    FROM sa_rowgenerator( 1, 5 )
    UPDATE #tmp SET row_num=row_num*10
    SAVE TRANSACTION before_delete
    DELETE FROM #tmp WHERE row_num >= 3
    ROLLBACK TRANSACTION before_delete
    SELECT * FROM #tmp
END


ROLLBACK TRIGGER statement

toggle Description

Use this statement to undo any changes made in a trigger.

toggle Syntax

ROLLBACK TRIGGER [ WITH raiserror-statement ]

toggle Usage

The ROLLBACK TRIGGER statement rolls back the work done in a trigger, including the data modification that caused the trigger to fire.

Optionally, a RAISERROR statement can be issued. If a RAISERROR statement is issued, an error is returned to the application. If no RAISERROR statement is issued, no error is returned.

If a ROLLBACK TRIGGER statement is used within a nested trigger and without a RAISERROR statement, only the innermost trigger and the statement which caused it to fire are undone.

toggle Permissions

None.

toggle Side effects

None

toggle See also
  • CREATE TRIGGER statement
  • ROLLBACK statement
  • ROLLBACK TO SAVEPOINT statement
  • RAISERROR statement [T-SQL]
toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Supported by Adaptive Server Enterprise.


SAVE TRANSACTION statement

toggle Description

Use this statement to establish a savepoint within the current transaction.

toggle Syntax

SAVE TRANSACTION savepoint-name

toggle Usage

Establish a savepoint within the current transaction. The savepoint-name is an identifier that can be used in a ROLLBACK TRANSACTION statement. All savepoints are automatically released when a transaction ends.

For more information, see Savepoints within transactions.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • SAVEPOINT statement
  • BEGIN TRANSACTION statement
  • COMMIT statement
  • ROLLBACK TRANSACTION statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Examples

The following example displays five rows with values 10, 20, and so on. The effect of the DELETE, but not the prior INSERTs or UPDATE, is undone by the ROLLBACK TRANSACTION statement.

BEGIN
    SELECT row_num INTO #tmp
    FROM sa_rowgenerator( 1, 5 )
    UPDATE #tmp SET row_num=row_num*10
    SAVE TRANSACTION before_delete
    DELETE FROM #tmp WHERE row_num >= 3
    ROLLBACK TRANSACTION before_delete
    SELECT * FROM #tmp
END


SAVEPOINT statement

toggle Description

Use this statement to establish a savepoint within the current transaction.

toggle Syntax

SAVEPOINT [ savepoint-name ]

toggle Usage

Establish a savepoint within the current transaction. The savepoint-name is an identifier that can be used in a RELEASE SAVEPOINT or ROLLBACK TO SAVEPOINT statement. All savepoints are automatically released when a transaction ends. See Savepoints within transactions.

Savepoints that are established while a trigger or atomic compound statement is executing are automatically released when the atomic operation ends.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • RELEASE SAVEPOINT statement
  • ROLLBACK TO SAVEPOINT statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Not supported in Adaptive Server Enterprise. To implement similar features in an Adaptive Server Enterprise-compatible manner, you can use the SAVE TRANSACTION statement.


SELECT statement

toggle Description

Use this statement to retrieve information from the database.

toggle Syntax

[ WITH temporary-views ]
SELECT [ ALL | DISTINCT ] [ row-limitation ] select-list
[ INTO { hostvar-list | variable-list | table-name } ]
[ FROM table-expression ]
[ WHERE search-condition ]
[ GROUP BY [ group-by-expression ]
[ HAVING search-condition ]
[ WINDOW window-name AS window-spec
[ , window-name AS window-spec ... ] ]
[ ORDER BY { expression | integer } [ ASC | DESC ], ... ]
[ FOR { UPDATE [ cursor-concurrency ] | READ ONLY } ]
[ FOR XML xml-mode ]

temporary-views :
regular-view, ...
| RECURSIVE { regular-view | recursive-view }, ...

regular-view :
view-name [ ( column-name, ... ) ]
AS ( subquery )

recursive-view :
view-name ( column-name, ... )
AS ( initial-subquery UNION ALL recursive-subquery )

row-limitation :
FIRST | TOP n [ START AT m ]

select-list :
{ column-name | expression } [ [ AS ] alias-name ], ...
| *| window-function OVER { window-name | window-spec }

group-by-expression:

See GROUP BY clause.

cursor-concurrency :
BY { VALUES | TIMESTAMP | LOCK }

xml-mode :
RAW [ , ELEMENTS ] | AUTO [ , ELEMENTS ] | EXPLICIT
window-function :RANK ( )
| DENSE_RANK ( )
| PERCENT_RANK ( )
| CUME_DIST ( )
| ROW_NUMBER ( )
| aggregate-function

window-spec:
( [window-name ]
[ PARTITION BY column-reference [ collate-clause ]
[ , column-reference [ collate-clause ] ... ] ]
[ ORDER BY order-by-expression, ... ]
[ { ROWS | RANGE } { window-frame-start | window-frame-between } ]
)

window-frame-start :
{ UNBOUNDED | integer-expression } PRECEDING
| CURRENT ROW

window-frame-between :
BETWEEN window-frame-bound-1
AND window-frame-bound-2

window-frame-bound:
window-frame-start
| { UNBOUNDED | integer-expression } FOLLOWING

toggle Parameters

WITH or WITH RECURSIVE Define one or more common table expressions, also known as temporary views, to be used elsewhere in the remainder of the statement. These expressions may be non-recursive, or may be self-recursive. Recursive common table expressions may appear alone, or intermixed with non-recursive expressions, only if the RECURSIVE keyword is specified. Mutually recursive common table expressions are not supported.

This clause is permitted only if the SELECT statement appears in one of the following locations:

  • Within a top-level SELECT statement

  • Within the top-level SELECT statement of a VIEW definition

  • Within a top-level SELECT statement within an INSERT statement

Recursive expressions consist of an initial subquery and a recursive subquery. The initial-query implicitly defines the schema of the view. The recursive subquery must contain a reference to the view within the FROM clause. During each iteration, this reference refers only to the rows added to the view in the previous iteration. The reference must not appear on the null-supplying side of an outer join. A recursive common table expression must not use aggregate functions and must not contain a GROUP BY, ORDER BY, or DISTINCT clause.

The WITH clause is not supported with remote tables.

For more information, see Common Table Expressions.

ALL or DISTINCT All (the default) returns all rows that satisfy the clauses of the SELECT statement. If DISTINCT is specified, duplicate output rows are eliminated. Many statements take significantly longer to execute when DISTINCT is specified, so you should reserve DISTINCT for cases where it is necessary.

row-limitation Explicitly limit the rows of queries that include ORDER BY clauses. The TOP value must be an integer constant or integer variable with value greater than or equal to 0. The START AT value must be an integer constant or integer variable with a value greater than 0.

For more information about the use of FIRST and TOP, see Explicitly limiting the number of rows returned by a query.

select list The select list is a list of expressions, separated by commas, specifying what will be retrieved from the database. An asterisk (*) means select all columns of all tables in the FROM clause.

Aggregate functions are allowed in the select list (see SQL Functions). Subqueries are also allowed in the select list (see Expressions). Each subquery must be within parentheses.

Alias names can be used throughout the query to represent the aliased expression.

Alias names are also displayed by Interactive SQL at the top of each column of output from the SELECT statement. If the optional alias name is not specified after an expression, Interactive SQL will display the expression itself.

INTO hostvar-list This clause is used in Embedded SQL only. It specifies where the results of the SELECT statement will go. There must be one host variable item for each item in the select list. Select list items are put into the host variables in order. An indicator host variable is also allowed with each host variable, so the program can tell if the select list item was NULL.

INTO variable-list This clause is used in procedures and triggers only. It specifies where the results of the SELECT statement will go. There must be one variable for each item in the select list. Select list items are put into the variables in order.

INTO table-name This clause is used to create a table and fill it with data.

If the table name starts # then it is created as a temporary table. Otherwise, the table is created as a permanent base table. For permanent tables to be created, the query must satisfy the following conditions:

  • The select-list contains more than one item, and the INTO target is a single table-name identifier, or

  • The select-list contains a * and the INTO target is specified as owner.table.

To create a permanent table with one column, the table name must be specified as owner.table.

This statement causes a COMMIT before execution as a side effect of creating the table. RESOURCE authority is required to execute this statement. No permissions are granted on the new table: the statement is a short form for CREATE TABLE followed by INSERT ... SELECT.

Tables created using this statement do not have a primary key defined. You can add a primary key using ALTER TABLE. A primary key should be added before applying any UPDATEs or DELETEs to the table; otherwise, these operations result in all column values being logged in the transaction log for the affected rows.

FROM clause Rows are retrieved from the tables and views specified in the table expression. A SELECT statement with no FROM clause can be used to display the values of expressions not derived from tables. For example,

SELECT @@version

displays the value of the global variable @@version. This is equivalent to:

SELECT @@version
FROM DUMMY

For more information, see FROM clause.

WHERE clause This clause specifies which rows will be selected from the tables named in the FROM clause. It can be used to do joins between multiple tables, as an alternative to the ON phrase (which is part of the FROM clause).

For more information, see Search conditions and FROM clause.

GROUP BY clause You can group by columns, alias names, or functions. The result of the query contains one row for each distinct set of values in the named columns, aliases, or functions. All NULL-containing rows are treated as a single set. The resulting rows are often referred to as groups since there is one row in the result for each group of rows from the table list. Aggregate functions can then be applied to these groups to get meaningful results.

When GROUP BY is used, the select-list, HAVING clause, and ORDER BY clause must not reference any identifier that is not named in the GROUP BY clause. The exception is that the select-list and HAVING clause may contain aggregate functions.

HAVING clause This clause selects rows based on the group values and not on the individual row values. The HAVING clause can only be used if either the statement has a GROUP BY clause or the select list consists solely of aggregate functions. Any column names referenced in the HAVING clause must either be in the GROUP BY clause or be used as a parameter to an aggregate function in the HAVING clause.

ORDER BY clause This clause sorts the results of a query. Each item in the ORDER BY list can be labeled as ASC for ascending order (the default) or DESC for descending order. If the expression is an integer n, then the query results will be sorted by the nth item in the select list.

The only way to ensure that rows are returned in a particular order is to use ORDER BY. In the absence of an ORDER BY clause, Adaptive Server Anywhere returns rows in whatever order is most efficient. This means that the appearance of result sets may vary depending on when you last accessed the row and other factors.

In embedded SQL, the SELECT statement is used for retrieving results from the database and placing the values into host variables via the INTO clause. The SELECT statement must return only one row. For multiple row queries, you must use cursors.

FOR UPDATE or FOR READ ONLY clause This clause specifies whether updates are allowed through a cursor opened on the query. Note that this clause cannot be used with the FOR XML clause.

If you do not use a FOR clause in the SELECT statement, the updatability is specified by the API. For ODBC and OLE DB, the default is read only. For JDBC, Open Client, and embedded SQL, the default is update.

This clause overrides the embedded SQL DECLARE CURSOR statement. However, it may be overridden by the concurrency setting in other programming interfaces. In ODBC and OLE DB, the read-only default setting overrides the FOR clause, but if you change the default to something other than read only, the FOR clause is not overridden. In JDBC and Open Client, the current setting always overrides the FOR clause, whether or not it is the default (updatable cursors).

Statement updatability is dependent on the setting of the ANSI_UPDATE_CONSTRAINTS database option. Other characteristics of the statement are also considered, including whether the statement contains a DISTINCT, GROUP BY, HAVING, UNION, aggregate functions, joins, or non-updatable views.

For more information about cursor sensitivity, see Adaptive Server Anywhere cursors.

For more information about ODBC concurrency, see the discussion of SQLSetStmtAttr in Choosing a cursor characteristics.

For more information about the ANSI_UPDATE_CONSTRAINTS database option, see ANSI_UPDATE_CONSTRAINTS option [compatibility].

FOR XML clause This clause specifies that the result set is to be returned as an XML document. The format of the XML depends on the mode you specify. Note that this clause cannot be used with the FOR UPDATE or FOR READ ONLY clause.

When you specify RAW mode, each row in the result set is represented as an XML <row> element, and each column is represented as an attribute of the <row> element.

AUTO mode returns the query results as nested XML elements. Each table referenced in the select-list is represented as an element in the XML. The order of nesting for the elements is based on the order that tables are referenced in the select-list.

EXPLICIT mode allows you to control the form of the generated XML document. Using EXPLICIT mode offers more flexibility in naming elements and specifying the nesting structure than either RAW or AUTO mode.

For information about writing a query using EXPLICIT mode, see Using FOR XML EXPLICIT.

For more information about using the FOR XML clause, see Using the FOR XML clause to retrieve query results as XML.

toggle Usage

The SELECT statement is used for retrieving results from the database.

A SELECT statement can be used in Interactive SQL to browse data in the database, or to export data from the database to an external file.

A SELECT statement can also be used in procedures and triggers or in embedded SQL. The SELECT statement with an INTO clause is used for retrieving results from the database when the SELECT statement only returns one row. For multiple row queries, you must use cursors.

A SELECT statement can also be used to return a result set from a procedure.

toggle Permissions

Must have SELECT permission on the named tables and views.

toggle Side effects

None.

toggle See also
  • Expressions
  • FROM clause
  • Search conditions
  • UNION operation
  • Joins: Retrieving Data from Several Tables
toggle Standards and compatibility

  • SQL/92 Entry-level feature. The complexity of the SELECT statement means that you should check individual clauses against the standard.

  • SQL/99 Core feature. The complexity of the SELECT statement means that you should check individual clauses against the standard. For example, the ROLLUP keyword is part of feature T431.

  • Sybase Supported by Adaptive Server Enterprise, with some differences in syntax.

toggle Example

How many employees are there?

SELECT count(*)
FROM employee

List all customers and the total value of their orders.

SELECT company_name,
   CAST( sum(sales_order_items.quantity *
   product.unit_price) AS INTEGER) VALUE
FROM customer
   JOIN sales_order
   JOIN sales_order_items
   JOIN product
GROUP BY company_name
ORDER BY VALUE DESC

The following statement shows an Embedded SQL SELECT statement:

SELECT count(*) INTO :size
FROM employee


SET statement

toggle Description

Use this statement to assign a value to a SQL variable.

toggle Syntax

SET identifier = expression

toggle Usage

The SET statement assigns a new value to a variable. The variable must have been previously created using a CREATE VARIABLE statement or DECLARE statement, or it must be an OUTPUT parameter for a procedure. The variable name can optionally use the Transact-SQL convention of an @ sign preceding the name. For example,

SET @localvar = 42

A variable can be used in a SQL statement anywhere a column name is allowed. If a column name exists with the same name as the variable, the variable value is used.

Variables are local to the current connection, and disappear when you disconnect from the database or use the DROP VARIABLE statement. They are not affected by COMMIT or ROLLBACK statements.

Variables are necessary for creating large text or binary objects for INSERT or UPDATE statements from embedded SQL programs because embedded SQL host variables are limited to 32,767 bytes.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • CREATE VARIABLE statement
  • DECLARE statement
  • DROP VARIABLE statement
  • Expressions
toggle Standards and compatibility

  • SQL/92 Persistent stored module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase Not supported. In Adaptive Server Enterprise, variables are assigned using the SELECT statement with no table, a Transact-SQL syntax that is also supported by Adaptive Server Anywhere. The SET statement is used to set database options in Adaptive Server Enterprise.

toggle Example

The following code fragment inserts a large text value into the database.

EXEC SQL BEGIN DECLARE SECTION;
DECL_VARCHAR( 500 ) buffer;
/* Note: maximum DECL_VARCHAR size is 32765 */
EXEC SQL END DECLARE SECTION;

EXEC SQL CREATE VARIABLE hold_blob LONG VARCHAR;
EXEC SQL SET hold_blob = '';
for(;;) {
   /* read some data into buffer ... */
   size = fread( buffer, 1, 5000, fp );
   if( size <= 0 ) break;
   /* Does not work if data contains null chars */
   EXEC SQL SET hold_blob = hold_blob || :buffer;
}
EXEC SQL INSERT INTO some_table VALUES( 1, hold_blob );
EXEC SQL DROP VARIABLE hold_blob;

The following code fragment inserts a large binary value into the database.

EXEC SQL BEGIN DECLARE SECTION;
DECL_BINARY( 5000 ) buffer;
EXEC SQL END DECLARE SECTION;

EXEC SQL CREATE VARIABLE hold_blob LONG BINARY;
EXEC SQL SET hold_blob = '';
for(;;) {
   /* read some data into buffer ... */
   size = fread( &(buffer.array), 1, 5000, fp );
   if( size <= 0 ) break;
   buffer.len = size;
   /* add data to blob using concatenation */
   EXEC SQL SET hold_blob = hold_blob || :buffer;
}
EXEC SQL INSERT INTO some_table VALUES ( 1, hold_blob );
EXEC SQL DROP VARIABLE hold_blob;


SET statement [T-SQL]

toggle Description

Use this statement to set database options for the current connection in an Adaptive Server Enterprise-compatible manner.

toggle Syntax

SET option-name option-value

toggle Usage

The available options are as follows:

Option name | Option value
ANSINULL | ON | OFF
ANSI_PERMISSIONS | ON | OFF
CLOSE_ON_ENDTRANS | ON | OFF
DATEFIRST | 1 | 2 | 3 | 4 | 5 | 6 | 7
QUOTED_IDENTIFIER | ON | OFF
ROWCOUNT | integer
SELF_RECURSION | ON | OFF
STRING_RTRUNCATION | ON | OFF
TEXTSIZE | integer
TRANSACTION ISOLATION LEVEL | 0 | 1 | 2 | 3

Database options in Adaptive Server Anywhere are set using the SET OPTION statement. However, Adaptive Server Anywhere also provides support for the Adaptive Server Enterprise SET statement for options that are particularly useful for compatibility.

The following options can be set using the Transact-SQL SET statement in Adaptive Server Anywhere as well as in Adaptive Server Enterprise:

  • SET ANSINULL { ON | OFF }

    The default behavior for comparing values to NULL in Adaptive Server Anywhere and Adaptive Server Enterprise is different. Setting ANSINULL to OFF provides Transact-SQL compatible comparisons with NULL.

    Adaptive Server Anywhere also supports the following syntax:

    SET ANSI_NULLS { ON | OFF }

  • SET ANSI_PERMISSIONS { ON | OFF } The default behavior in Adaptive Server Anywhere and Adaptive Server Enterprise regarding permissions required to carry out an UPDATE or DELETE containing a column reference is different. Setting ANSI_PERMISSIONS to OFF provides Transact-SQL-compatible permissions on UPDATE and DELETE.

  • SET CLOSE_ON_ENDTRANS { ON | OFF } The default behavior in Adaptive Server Anywhere and Adaptive Server Enterprise for closing cursors at the end of a transaction is different. Setting CLOSE_ON_ENDTRANS to OFF provides Transact-SQL compatible behavior.

  • SET DATEFIRST { 1 | 2 | 3 | 4 | 5 | 6 | 7 } The default is 7, which means that the first day of the week is by default Sunday. To set this option permanently, see FIRST_DAY_OF_WEEK option [database].

  • SET QUOTED_IDENTIFIER { ON | OFF } Controls whether strings enclosed in double quotes are interpreted as identifiers (ON) or as literal strings (OFF). For information about this option, see Setting options for Transact-SQL compatibility.

  • SET ROWCOUNT integer The Transact-SQL ROWCOUNT option limits the number of rows fetched for any cursor to the specified integer. This includes rows fetched by re-positioning the cursor. Any fetches beyond this maximum return a warning. The option setting is considered when returning the estimate of the number of rows for a cursor on an OPEN request.

    SET ROWCOUNT also limits the number of rows affected by a searched UPDATE or DELETE statement to integer. This might be used, for example, to allow COMMIT statements to be performed at regular intervals to limit the size of the rollback log and lock table. The application (or procedure) would need to provide a loop to cause the update/delete to be re-issued for rows that are not affected by the first operation. A simple example is given below:

    begin
   declare @count integer
   set rowcount 20
   while(1=1) begin
      update employee set emp_lname='new_name'
      where emp_lname <> 'old_name'
      /* Stop when no rows changed */
      select @count = @@rowcount
      if @count = 0 break
      print string('Updated ',
               @count,' rows; repeating...')
      commit
   end
   set rowcount 0
end

    In Adaptive Server Anywhere, if the ROWCOUNT setting is greater than the number of rows that Interactive SQL can display, Interactive SQL may do some extra fetches to reposition the cursor. Thus, the number of rows actually displayed may be less than the number requested. Also, if any rows are re-fetched due to truncation warnings, the count may be inaccurate.

    A value of zero resets the option to get all rows.

  • SET SELF_RECURSION { ON | OFF } The self_recursion option is used within triggers to enable (ON) or prevent (OFF) operations on the table associated with the trigger from firing other triggers.

  • SET STRING_RTRUNCATION { ON | OFF } The default behavior in Adaptive Server Anywhere and Adaptive Server Enterprise when non-space characters are truncated on assigning SQL string data is different. Setting STRING_RTRUNCATION to ON provides Transact-SQL-compatible string comparisons.

  • SET TEXTSIZE Specifies the maximum size (in bytes) of text or image type data to be returned with a select statement. The @@textsize global variable stores the current setting. To reset to the default size (32K), use the command:

    set textsize 0

  • SET TRANSACTION-ISOLATION-LEVEL { 0 | 1 | 2 | 3 } Sets the locking isolation level for the current connection, as described in Isolation levels and consistency. For Adaptive Server Enterprise, only 1 and 3 are valid options. For Adaptive Server Anywhere, any of 0, 1, 2, or 3 is a valid option.

In addition, the SET statement is allowed by Adaptive Server Anywhere for the PREFETCH option, for compatibility, but has no effect.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • SET OPTION statement
  • Setting options for Transact-SQL compatibility
  • Compatibility options
toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Adaptive Server Anywhere supports a subset of the Adaptive Server Enterprise database options.


SET CONNECTION statement [Interactive SQL] [ESQL]

toggle Description

Use this statement to change the active database connection.

toggle Syntax

SET CONNECTION [connection-name]

connection-name :
identifier, string, or hostvar

toggle Usage

The SET CONNECTION statement changes the active database connection to connection-name. The current connection state is saved, and will be resumed when it again becomes the active connection. If connection-name is omitted and there is a connection that was not named, that connection becomes the active connection.

When cursors are opened in embedded SQL, they are associated with the current connection. When the connection is changed, the cursor names of the previously active connection become inaccessible. These cursors remain active and in position, and become accessible when the associated connection becomes active again.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • CONNECT statement [ESQL] [Interactive SQL]
  • DISCONNECT statement [ESQL] [Interactive SQL]
toggle Standards and compatibility

  • SQL/92 Interactive SQL use is a vendor extension. Embedded SQL is a Full level feature.

  • SQL/99 Interactive SQL is a vendor extension. Embedded SQL is a core feature.

  • Sybase Supported by Open Client/Open Server.

toggle Example

The following example is in Embedded SQL.

EXEC SQL SET CONNECTION :conn_name;

From Interactive SQL, set the current connection to the connection named conn1.

SET CONNECTION conn1;


SET DESCRIPTOR statement [ESQL]

toggle Description

Use this statement to describe the variables in a SQL descriptor area and to place data into the descriptor area.

toggle Syntax

SET DESCRIPTOR descriptor-name
{ COUNT = { integer | hostvar }
| VALUE { integer | hostvar } assignment [, ...] }

assignment :
{ TYPE | SCALE | PRECISION | LENGTH | INDICATOR }
= { integer | hostvar }
| DATA = hostvar

toggle Usage

The SET DESCRIPTOR statement is used to describe the variables in a descriptor area, and to place data into the descriptor area.

The SET ... COUNT statement sets the number of described variables within the descriptor area. The value for count must not exceed the number of variables specified when the descriptor area was allocated.

The value { integer | hostvar } specifies the variable in the descriptor area upon which the assignment(s) will be performed.

Type checking is performed when doing SET ... DATA, to ensure that the variable in the descriptor area has the same type as the host variable. LONGVARCHAR and LONGBINARY are not supported by SET DESCRIPTOR ... DATA.

If an error occurs, the code is returned in the SQLCA.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • ALLOCATE DESCRIPTOR statement [ESQL]
  • DEALLOCATE DESCRIPTOR statement [ESQL]
  • The SQL descriptor area (SQLDA)
toggle Standards and compatibility

  • SQL/92 Intermediate-level feature.

  • SQL/99 SQL/foundation feature outside of core SQL.

  • Sybase Supported by Open Client/Open Server.

toggle Example

The following example sets the type of the column with position col_num in sqlda.

void set_type( SQLDA *sqlda, int col_num, int new_type )
{
    EXEC SQL BEGIN DECLARE SECTION;
    int new_type1 = new_type;
    int col = col_num;
    EXEC SQL END DECLARE SECTION;
EXEC SQL SET DESCRIPTOR sqlda VALUE :col TYPE = :new_type1;
}

For a longer example, see ALLOCATE DESCRIPTOR statement [ESQL].


SET OPTION statement

toggle Description

Use this statement to change the values of database options.

toggle Syntax

SET [ EXISTING ] [ TEMPORARY ] OPTION
[ userid.| PUBLIC.]option-name = [ option-value ]

userid : identifier | string | hostvar

option-name : identifier | string | hostvar

option-value : hostvar (indicator allowed)
| string
| identifier
| number

toggle Usage

The SET OPTION statement is used to change options that affect the behavior of the database server. Setting the value of an option can change the behavior for all users or only for an individual user. The scope of the change can be either temporary or permanent.

The classes of options are:

  • General database options

  • Transact-SQL compatibility

  • Replication database options

For a listing and description of all available options, see Database Options.

You can set options at three levels of scope: public, user, and temporary. A temporary option takes precedence over other options, and user options take precedence over public options. If you set a user level option for the current user, the corresponding temporary option gets set as well.

If you use the EXISTING keyword, option values cannot be set for an individual user ID unless there is already a PUBLIC user ID setting for that option.

If you specify a user ID, the option value applies to that user (or, for a group user ID, the members of that group). If you specify PUBLIC, the option value applies to all users who don't have an individual setting for the option. By default, the option value applies to the currently logged on user ID that issued the SET OPTION statement..

For example, the following statement applies an option change to the user DBA, if DBA is the user issuing the SQL statement:

SET OPTION login_mode = mixed

However the following statement applies the change to the PUBLIC user ID, a user group to which all users belong.

SET OPTION Public.login_mode = standard

Only users with DBA privileges have the authority to set an option for the PUBLIC user ID.

In embedded SQL, database options can be set only temporarily.

Users can use the SET OPTION statement to change the values for their own user ID. Setting the value of an option for a user id other then your own is permitted only if you have DBA authority.

Adding the TEMPORARY keyword to the SET OPTION statement changes the duration that the change takes effect. By default, the option value is permanent: it will not change until it is explicitly changed using the SET OPTION statement.

When the SET TEMPORARY OPTION statement is not qualified with a user ID, the new option value is in effect only for the current connection.

When SET TEMPORARY OPTION is used for the PUBLIC user ID, the change is in place for as long as the database is running. When the database is shut down, TEMPORARY options for the PUBLIC group revert back to their permanent value.

Setting temporary options for the PUBLIC user ID offers a security benefit. For example, when the LOGIN_MODE option is enabled, the database relies on the login security of the system on which it is running. Enabling it temporarily means that a database relying on the security of a Windows domain will not be compromised if the database is shut down and copied to a local machine. In that case, the temporary enabling of the LOGIN_MODE option reverts to its permanent value, which could be Standard, a mode where integrated logins are not permitted.

If option-value is omitted, the specified option setting will be deleted from the database. If it was a personal option setting, the value will revert back to the PUBLIC setting. If a TEMPORARY option is deleted, the option setting will revert back to the permanent setting.

Caution Changing option settings while fetching rows from a cursor is not supported, as it can lead to ill-defined behavior. For example, changing the DATE_FORMAT setting while fetching from a cursor would lead to different date formats among the rows in the result set. Do not change option settings while fetching rows.
toggle Permissions

None required to set your own options.

DBA authority is required to set database options for another user or PUBLIC.

toggle Side effects

If TEMPORARY is not specified, an automatic commit is performed.

toggle See also
  • Database options
  • Compatibility options
  • Replication options
  • SET OPTION statement [Interactive SQL]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Adaptive Server Enterprise. Adaptive Server Anywhere does support some Adaptive Server Enterprise options using the SET statement.

toggle Example

Set the date format option to on:

SET OPTION public.date_format = 'Mmm dd yyyy';

Set the date format option to its default setting:

SET OPTION public.date_format =;

Set the wait_for_commit option to on:

SET OPTION wait_for_commit = 'on';

Following are two embedded SQL examples.

1. EXEC SQL SET OPTION :user.:option_name = :value;
2. EXEC SQL SET TEMPORARY OPTION Date_format = 'mm/dd/yyyy';


SET OPTION statement [Interactive SQL]

toggle Description

Use this statement to change the values of Interactive SQL options.

toggle Syntax 1

SET [ TEMPORARY ] OPTION
[ userid. | PUBLIC. ]option-name = [ option-value ]

userid : identifier, string or hostvar

option-name : identifier, string or hostvar

option-value : hostvar (indicator allowed), string, identifier, or number

toggle Syntax 2

SET PERMANENT

toggle Syntax 3

SET

toggle Usage

SET PERMANENT (syntax 2) saves all current Interactive SQL options. These settings are automatically established every time Interactive SQL is started for the current user ID.

Syntax 3 displays all of the current option settings. If there are temporary options set for Interactive SQL or the database server, these will be displayed; otherwise, the permanent option settings are displayed.

toggle See also
  • Interactive SQL options


SET REMOTE OPTION statement [SQL Remote]

toggle Description

Use this statement to set a message control parameter for a SQL Remote message link.

toggle Syntax

SET REMOTE link-name OPTION
[ userid.| PUBLIC.]link-option-name = link-option-value

link-name:
file | ftp | mapi | smtp | vim

link-option-name:
common-option | file-option | ftp-option
| mapi-option | smtp-option | vim-option

common-option:
debug | output_log_send_on_error
| output_log_send_limit | output_log_send_now

file-option:
directory | unlink_delay

ftp-option:
active_mode | host | password | port | root_directory | user

mapi-option:
force_download | ipm_receive | ipm_send | profile

smtp-option:
local_host | pop3_host | pop3_password | pop3_userid
| smtp_host | top_supported

vim-option:
password | path | receive_all | send_vim_mail | userid

link-option-value:
string

toggle Parameters

userid If no userid is specified, then the current publisher is assumed.

Option values The option values are message-link dependent. For more information, see the following locations:

  • The file message system.

  • The ftp message system.

  • The MAPI message system.

  • The SMTP message system.

  • The VIM message system.

toggle Usage

The Message Agent saves message link parameters when the user enters them in the message link dialog box when the message link is first used. In this case, it is not necessary to use this statement explicitly. This statement is most useful when preparing a consolidated database for extracting many databases.

The option names are case sensitive. The case sensitivity of option values depends on the option: Boolean values are case insensitive, while the case sensitivity of passwords, directory names, and other strings depend on the cases sensitivity of the file system (for directory names), or the database (for user IDs and passwords).

toggle Permissions

Must have DBA authority. The publisher can set their own options.

toggle Side effects

Automatic commit.

toggle See also
  • sp_link_option procedure
  • Troubleshooting errors at remote sites
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Examples

The following statement sets the FTP host to ftp.mycompany.com for the ftp link for user myuser:

SET REMOTE FTP OPTION myuser.host = 'ftp.mycompany.com'


SET SQLCA statement [ESQL]

toggle Description

Use this statement to tell the SQL preprocessor to use a SQLCA other than the default, global sqlca.

toggle Syntax

SET SQLCA sqlca

sqlca : identifier or string

toggle Usage

The SET SQLCA statement tells the SQL preprocessor to use a SQLCA other than the default global sqlca. The sqlca must be an identifier or string that is a C language reference to a SQLCA pointer.

The current SQLCA pointer is implicitly passed to the database interface library on every embedded SQL statement. All embedded SQL statements that follow this statement in the C source file will use the new SQLCA.

This statement is necessary only when you are writing code that is reentrant (see SQLCA management for multi-threaded or reentrant code). The sqlca should reference a local variable. Any global or module static variable is subject to being modified by another thread.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • SQLCA management for multi-threaded or reentrant code
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not supported by Open Client/Open Server.

toggle Example

The owning function could be found in a Windows DLL. Each application that uses the DLL has its own SQLCA.

an_sql_code FAR PASCAL ExecuteSQL( an_application *app, char *com )
{
   EXEC SQL BEGIN DECLARE SECTION;
   char *sqlcommand;
   EXEC SQL END DECLARE SECTION;
   EXEC SQL SET SQLCA "&app->.sqlca";
   sqlcommand = com;
   EXEC SQL WHENEVER SQLERROR CONTINUE;
   EXEC SQL EXECUTE IMMEDIATE :sqlcommand;
return( SQLCODE );
}


SETUSER statement

toggle Description

Use this statement to allow a database administrator to impersonate another user, and to enable connection pooling.

toggle Syntax

{ SET SESSION AUTHORIZATION | SETUSER }
[ [ WITH OPTION ] userid ]

toggle Parameters

WITH OPTION By default, only permissions (including group membership) are altered. If WITH OPTION is specified, the database options in effect are changed to the current database options of userid.

userid The user ID is an identifier (SETUSER syntax) or a string (SET SESSION AUTHORIZATION syntax). For more information, see Identifiers and Strings.

toggle Usage

The SETUSER statement is provided to make database administration easier. It enables a user with DBA authority to impersonate another user of the database. After running a SETUSER statement, you can check which user you are impersonating by running one of the following commands:

  • SELECT USER

  • SELECT CURRENT USER

SETUSER can also be used from an application server to take advantage of connection pooling. Connection pooling cuts down the number of distinct connections that need to be made, which can improve performance.

SETUSER with no user ID undoes all earlier SETUSER statements.

The SETUSER statement cannot be used inside a procedure, trigger, event handler or batch.

There are several uses for the SETUSER statement, including the following:

  • Creating objects You can use SETUSER to create a database object that is to be owned by another user.

  • Permissions checking By acting as another user, with their permissions and group memberships, a DBA can test the permissions and name resolution of queries, procedures, views, and so on.

  • Providing a safer environment for administrators The DBA has permission to carry out any action in the database. If you wish to ensure that you do not accidentally carry out an unintended action, you can use SETUSER to switch to a different user ID with fewer permissions.

Note
The SETUSER statement cannot be used within procedures, triggers, events, or batches.
toggle Permissions

Must have DBA authority.

toggle See also
  • EXECUTE IMMEDIATE statement [SP]
  • GRANT statement
  • REVOKE statement
  • SET OPTION statement
toggle Standards and compatibility

  • SQL/92 SET SESSION AUTHORIZATION is SQL 92 compliant. SETUSER is a vendor extension.

  • SQL/99 SET SESSION AUTHORIZATION is a core feature. SETUSER is a vendor extension.

  • Sybase Adaptive Server Enterprise supports SETUSER, but not the WITH OPTIONS keywords.

toggle Example

The following statements, executed by a user named DBA, change the user ID to be Joe, then Jane, and then back to DBA.

SETUSER "Joe"
// ... operations...
SETUSER WITH OPTION "Jane"
// ... operations...
SETUSER

The following statement sets the user to Jane. The user ID is supplied as a string rather than as an identifier.

SET SESSION AUTHORIZATION 'Jane'


SIGNAL statement

toggle Description

Use this statement to signal an exception condition.

toggle Syntax

SIGNAL exception-name

toggle Usage

SIGNAL allows you to raise an exception. See Using exception handlers in procedures and triggers for a description of how exceptions are handled.

exception-name The name of an exception declared using a DECLARE statement at the beginning of the current compound statement. The exception must correspond to a system-defined SQLSTATE or a user-defined SQLSTATE. User-defined SQLSTATE values must be in the range 99000 to 99999.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • DECLARE statement
  • RESIGNAL statement
  • BEGIN statement
  • Using exception handlers in procedures and triggers
toggle Standards and compatibility

  • SQL/92 Persistent Stored Module feature.

  • SQL/99 Persistent Stored Module feature.

  • Sybase SIGNAL is not supported by Adaptive Server Enterprise.

toggle Example

The following compound statement declares and signals a user-defined exception. If you execute this example from Interactive SQL, the message is displayed in the Messages pane.

BEGIN
   DECLARE myexception EXCEPTION
   FOR SQLSTATE '99001';
   SIGNAL myexception;
   EXCEPTION
      WHEN myexception THEN
         MESSAGE 'My exception signaled'
         TO CLIENT;
END


START DATABASE statement [Interactive SQL]

toggle Description

Use this statement to start a database on the current database server.

toggle Syntax

START DATABASE database-file
[ AS database-name ]
[ ON engine-name ]
[ WITH TRUNCATE AT CHECKPOINT ]
[ FOR READ ONLY ]
[ AUTOSTOP { ON | OFF } ]
[ KEY key ]

toggle Parameters

START DATABASE clause The database-file parameter is a string. If a relative path is supplied in database-file, it is relative to the database server starting directory.

AS clause If database-name is not specified, a default name is assigned to the database. This default name is the root of the database file. For example, a database in file C:\Database Files\asademo.db would be given the default name of asademo.

ON clause This clause is supported from Interactive SQL only. In Interactive SQL, if engine-name is not specified, the default database is the first started server among those currently running.

WITH TRUNCATE AT CHECKPOINT clause Starts a database with log truncation on checkpoint enabled.

FOR READ ONLY Starts a database in read-only mode.

AUTOSTOP clause The default setting for the AUTOSTOP clause is ON. With AUTOSTOP set to ON, the database is unloaded when the last connection to it is dropped. If AUTOSTOP is set to OFF, the database is not unloaded.

In Interactive SQL, you can use YES or NO as alternatives to ON and OFF.

KEY clause If the database is strongly encrypted, enter the KEY value (password) using this clause

toggle Usage

Starts a specified database on the current database server.

The START DATABASE statement does not connect the current application to the specified database: an explicit connection is still needed.

Interactive SQL supports the ON clause, which allows the database to be started on a database server other than the current.

toggle Permissions

The required permissions are specified by the database server -gd option. This option defaults to all on the personal database server, and DBA on the network server.

toggle Side effects

None

toggle See also
  • STOP DATABASE statement
  • CONNECT statement [ESQL] [Interactive SQL]
  • -gd server option
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

Start the database file C:\Database Files\sample_2.db on the current server.

START DATABASE 'c:\database files\sample_2.db'

From Interactive SQL, start the database file c:\Database Files\sample_2.db as sam2 on the server named sample.

START DATABASE 'c:\database files\sample_2.db'
AS sam2
ON sample


START ENGINE statement [Interactive SQL]

toggle Description

Use this statement to start a database server.

toggle Syntax

START ENGINE AS engine-name [ STARTLINE command-string ]

toggle Usage

The START ENGINE statement starts a database server. If you wish to specify a set of options for the server, use the STARTLINE keyword together with a command string. Valid command strings are those that conform to the database server description in The database server.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • STOP ENGINE statement
  • The database server
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

Start a database server, named sample, without starting any databases on it.

START ENGINE AS sample

The following example shows the use of a STARTLINE clause.

START ENGINE AS eng1 STARTLINE 'dbeng9 -c 8M'


START JAVA statement

toggle Description

Use this statement to start the Java VM.

toggle Syntax

START JAVA

toggle Usage

The START JAVA statement starts the Java VM. The main use is to load the Java VM at a convenient time so that when the user starts to use Java functionality there is no initial pause while the Java VM is loaded.

toggle Permissions

Java in the database must be installed and the database must be Java-enabled.

This statement is not supported on Windows CE.

toggle Side effects

None

toggle See also
  • STOP JAVA statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

Start the Java VM.

START JAVA


START LOGGING statement [Interactive SQL]

toggle Description

Use this statement to start logging executed SQL statements to a log file.

toggle Syntax

START LOGGING filename

toggle Usage

The START LOGGING statement starts copying all subsequent executed SQL statements to the log file that you specify. If the file does not exist, Interactive SQL creates it. Logging continues until you explicitly stop the logging process with the STOP LOGGING statement, or until you end the current Interactive SQL session. You can also start and stop logging by clicking SQL > Start Logging and SQL > Stop Logging.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • STOP LOGGING statement [Interactive SQL]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

Start logging to a file called filename.sql, located in the c: directory.

START LOGGING 'c:\filename.sql'


START SUBSCRIPTION statement [SQL Remote]

toggle Description

Use this statement to start a subscription for a user to a publication.

toggle Syntax

START SUBSCRIPTION
TO publication-name [ ( subscription-value ) ]
FOR subscriber-id, ...

toggle Parameters

publication-name The name of the publication to which the user is being subscribed. This may include the owner of the publication.

subscription-value A string that is compared to the subscription expression of the publication. The value is required here because each subscriber may have more than one subscription to a publication.

subscriber-id The user ID of the subscriber to the publication. This user must have a subscription to the publication.

toggle Usage

A SQL Remote subscription is said to be started when publication updates are being sent from the consolidated database to the remote database.

The START SUBSCRIPTION statement is one of a set of statements that manage subscriptions. The CREATE SUBSCRIPTION statement defines the data that the subscriber is to receive. The SYNCHRONIZE SUBSCRIPTION statement ensures that the consolidated and remote databases are consistent with each other. The START SUBSCRIPTION statement is required to start messages being sent to the subscriber.

Data at each end of the subscription must be consistent before a subscription is started. It is recommended that you use the database extraction utility to manage the creation, synchronization, and starting of subscriptions. If you use the database extraction utility, you do not need to execute an explicit START SUBSCRIPTION statement. Also, the Message Agent starts subscriptions once they are synchronized.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE SUBSCRIPTION statement [SQL Remote]
  • REMOTE RESET statement [SQL Remote]
  • SYNCHRONIZE SUBSCRIPTION statement [SQL Remote]
  • sp_subscription procedure
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

The following statement starts the subscription of user SamS to the pub_contact publication.

START SUBSCRIPTION TO pub_contact
FOR SamS


START SYNCHRONIZATION DELETE statement [MobiLink]

toggle Description

Use this statement to restart logging of deletes for MobiLink synchronization.

toggle Syntax

START SYNCHRONIZATION DELETE

toggle Usage

Ordinarily, Adaptive Server Anywhere and UltraLite automatically log any changes made to tables or columns that are part of a synchronization, and upload these changes to the consolidated database during the next synchronization. You can temporarily suspend automatic logging of delete operations using the STOP SYNCHRONIZATION DELETE statement. The START SYNCHRONIZATION DELETE statement allows you to restart the automatic logging.

When a STOP SYNCHRONIZATION DELETE statement is executed, none of the delete operations executed on that connection will be synchronized. The effect continues until a START SYNCHRONIZATION DELETE statement is executed. Repeating STOP SYNCHRONIZATION DELETE has no additional effect.

A single START SYNCHRONIZATION DELETE statement restarts the logging, regardless of the number of STOP SYNCHRONIZATION DELETE statements preceding it.

Do not use START SYNCHRONIZATION DELETE if your application does not synchronize data.

toggle Permissions

Must have DBA authority.

toggle Side effects

None.

toggle See also
  • STOP SYNCHRONIZATION DELETE statement [MobiLink]
  • StartSynchronizationDelete method
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

The following sequence of SQL statements illustrates how to use START SYNCHRONIZATION DELETE and STOP SYNCHRONIZATION DELETE.

-- Prevent deletes from being sent
-- to the consolidated database
STOP SYNCHRONIZATION DELETE;

-- Remove all records older than 1 month
-- from the remote database,
-- NOT the consolidated database
DELETE FROM PROPOSAL
WHERE last_modified < months( CURRENT TIMESTAMP, -1 )

-- Re-enable all deletes to be sent
-- to the consolidated database
-- DO NOT FORGET to start this
START SYNCHRONIZATION DELETE;

-- Commit the entire operation,
-- otherwise rollback everything
-- including the stopping of the deletes
commit;


STOP DATABASE statement

toggle Description

Use this statement to stop a database on the current database server.

toggle Syntax

STOP DATABASE database-name
[ ON engine-name ]
[ UNCONDITIONALLY ]

toggle Parameters

STOP DATABASE clause The database-name is the name of a database (other than the current database) running on the current server.

ON clause This clause is supported in Interactive SQL only. If engine-name is not specified in Interactive SQL, all running engines will be searched for a database of the specified name.

When not using this statement in Interactive SQL, the database is stopped only if it is started on the current database server.

UNCONDITIONALLY keyword Stop the database even if there are connections to the database. By default, the database is not stopped if there are connections to it.

toggle Usage

The STOP DATABASE statement stops a specified database on the current database server.

toggle Permissions

The required permissions are specified by the database server -gk option. This option defaults to all on the personal database server, and DBA on the network server.

You cannot use STOP DATABASE on the database to which you are currently connected.

toggle Side effects

None

toggle See also
  • START DATABASE statement [Interactive SQL]
  • DISCONNECT statement [ESQL] [Interactive SQL]
  • -gd server option
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

Stop the database named sample on the current server.

STOP DATABASE sample


STOP ENGINE statement

toggle Description

Use this statement to stop a database server.

toggle Syntax

STOP ENGINE [ engine-name ] [ UNCONDITIONALLY ]

toggle Parameters

STOP ENGINE clause The engine-name can be used in Interactive SQL only. If you are not running this statement in Interactive SQL, the current database server is stopped.

UNCONDITIONALLY keyword If you are the only connection to the database server, you do not need to use UNCONDITIONALLY. If there are other connections, the database server stops only if you use the UNCONDITIONALLY keyword.

toggle Usage

The STOP ENGINE statement stops the specified database server. If the UNCONDITIONALLY keyword is supplied, the database server is stopped even if there are connections to the server. By default, the database server will not be stopped if there are connections to it.

toggle Permissions

The permissions to shut down a server depend on the -gk setting on the database server command line. The default setting is all for the personal server, and DBA for the network server.

toggle Side effects

None

toggle See also
  • START ENGINE statement [Interactive SQL]
  • -gk server option
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

Stop the current database server, as long as there are no other connections.

STOP ENGINE


STOP JAVA statement

toggle Description

Use this statement to stop the Java VM.

toggle Syntax

STOP JAVA

toggle Usage

The STOP JAVA statement unloads the Java VM when it is not in use. The main use is to economize on the use of system resources.

toggle Permissions

Java in the database must be installed and the database must be Java-enabled.

This statement is not supported on Windows CE.

toggle Side effects

None

toggle See also
  • START JAVA statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

Stop the Java VM.

STOP JAVA


STOP LOGGING statement [Interactive SQL]

toggle Description

Use this statement to stop logging of SQL statements in the current session.

toggle Syntax

STOP LOGGING

toggle Usage

The STOP LOGGING statement stops Interactive SQL from writing each SQL statement you execute to a log file. You can start logging with the START LOGGING statement. You can also start and stop logging by clicking SQL > Start Logging and SQL > Stop Logging.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • START LOGGING statement [Interactive SQL]
toggle Example

The following example stops the current logging session.

STOP LOGGING


STOP SUBSCRIPTION statement [SQL Remote]

toggle Description

Use this statement to stop a subscription for a user to a publication.

toggle Syntax

STOP SUBSCRIPTION
TO publication-name [ ( subscription-value ) ]
FOR subscriber-id, ...

toggle Parameters

publication-name The name of the publication to which the user is being subscribed. This may include the owner of the publication.

subscription-value A string that is compared to the subscription expression of the publication. The value is required here because each subscriber may have more than one subscription to a publication.

subscriber-id The user ID of the subscriber to the publication. This user must have a subscription to the publication.

toggle Usage

A SQL Remote subscription is said to be started when publication updates are being sent from the consolidated database to the remote database.

The STOP SUBSCRIPTION statement prevents any further messages being sent to the subscriber. The START SUBSCRIPTION statement is required to restart messages being sent to the subscriber. However, you should ensure that the subscription is properly synchronized before restarting: that no messages have been missed.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • DROP SUBSCRIPTION statement [SQL Remote]
  • SYNCHRONIZE SUBSCRIPTION statement [SQL Remote]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Example

The following statement starts the subscription of user SamS to the pub_contact publication.

STOP SUBSCRIPTION TO pub_contact
FOR SamS


STOP SYNCHRONIZATION DELETE statement [MobiLink]

toggle Description

Use this statement to temporarily stop logging of deletes for MobiLink synchronization.

toggle Syntax

STOP SYNCHRONIZATION DELETE

toggle Usage

Ordinarily, Adaptive Server Anywhere and UltraLite remote databases automatically log any changes made to tables or columns that are included in a synchronization, and then upload these changes to the consolidated database during the next synchronization. This statement allows you to temporarily suspend logging of changes to an Adaptive Server Anywhere or UltraLite remote database.

When a STOP SYNCHRONIZATION DELETE statement is executed, none of the subsequent delete operations executed on that connection will be synchronized. The effect continues until a START SYNCHRONIZATION DELETE statement is executed.

Repeating STOP SYNCHRONIZATION DELETE has no additional effect. A single START SYNCHRONIZATION DELETE statement restarts the logging, regardless of the number of STOP SYNCHRONIZATION DELETE statements preceding it.

This command can be useful to make corrections to a remote database, but should be used with caution as it effectively disables MobiLink synchronization.

Do not use STOP SYNCHRONIZATION DELETE if your application does not synchronize data.

toggle Permissions

Must have DBA authority.

toggle Side Effects

None.

toggle See also
  • StartSynchronizationDelete method
  • StopSynchronizationDelete method
  • START SYNCHRONIZATION DELETE statement [MobiLink]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

For an example, see START SYNCHRONIZATION DELETE statement [MobiLink].


SYNCHRONIZE SUBSCRIPTION statement [SQL Remote]

toggle Description

Use this statement to synchronize a subscription for a user to a publication.

toggle Syntax

SYNCHRONIZE SUBSCRIPTION
TO publication-name [ ( subscription-value ) ]
FOR remote-user, ...

toggle Parameters

publication-name The name of the publication to which the user is being subscribed. This may include the owner of the publication.

subscription-value A string that is compared to the subscription expression of the publication. The value is required here because each subscriber may have more than one subscription to a publication.

remote-user The user ID of the subscriber to the publication. This user must have a subscription to the publication.

toggle Usage

A SQL Remote subscription is said to be synchronized when the data in the remote database is consistent with that in the consolidated database, so that publication updates sent from the consolidated database to the remote database will not result in conflicts and errors.

To synchronize a subscription, a copy of the data in the publication at the consolidated database is sent to the remote database. The SYNCHRONIZE SUBSCRIPTION statement does this through the message system. It is recommended that where possible you use the database extraction utility instead to synchronize subscriptions without using a message system.

toggle Permissions

Must have DBA authority.

toggle Side effects

Automatic commit.

toggle See also
  • CREATE SUBSCRIPTION statement [SQL Remote]
  • START SUBSCRIPTION statement [SQL Remote]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Example

The following statement synchronizes the subscription of user SamS to the pub_contact publication.

SYNCHRONIZE SUBSCRIPTION
   TO pub_contact
   FOR SamS


SYSTEM statement [Interactive SQL]

toggle Description

Use this statement to launch an executable file from within Interactive SQL.

toggle Syntax

SYSTEM ' [path] filename '

toggle Usage

Launches the specified executable file.

  • The SYSTEM statement must be entirely contained on one line.

  • Comments are not allowed at the end of a SYSTEM statement.

  • Enclose the path and filename in single quotation marks.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • CONNECT statement [ESQL] [Interactive SQL]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

toggle Example

The following statement launches the Notepad program, assuming that the Notepad executable is in your path.

SYSTEM 'notepad.exe'


TRIGGER EVENT statement

toggle Description

Use this statement to trigger a named event. The event may be defined for event triggers or be a scheduled event.

toggle Syntax

TRIGGER EVENT event-name [ ( parm = value, ... ) ]

toggle Parameters

parm = value When a triggering condition causes an event handler to execute, the database server can provide context information to the event handler using the event_parameter function. The TRIGGER EVENT statement allows you to explicitly supply these parameters, in order to simulate a context for the event handler.

toggle Usage

Actions are tied to particular trigger conditions or schedules by a CREATE EVENT statement. You can use the TRIGGER EVENT statement to force the event handler to execute, even when the scheduled time or trigger condition has not occurred. TRIGGER EVENT does not execute disabled event handlers.

toggle Permissions

Must have DBA authority.

toggle Side effects

None.

toggle See also
  • ALTER EVENT statement
  • CREATE EVENT statement
  • EVENT_PARAMETER function [System]
toggle Example

The following example shows how to pass a string parameter to an event. The event displays the time it was triggered on the server console.

CREATE EVENT ev_PassedParameter
HANDLER
BEGIN
  MESSAGE 'ev_PassedParameter - was triggered at ' || event_parameter('time');
END;
TRIGGER EVENT ev_PassedParameter("Time"=string(current timestamp));


TRUNCATE TABLE statement

toggle Description

Use this statement to delete all rows from a table, without deleting the table definition.

toggle Syntax

TRUNCATE TABLE [ owner.]table-name

toggle Usage

The TRUNCATE TABLE statement deletes all rows from a table. It is equivalent to a DELETE statement without a WHERE clause, except that no triggers are fired as a result of the TRUNCATE TABLE statement and each individual row deletion is not entered into the transaction log.

After a TRUNCATE TABLE statement, the table structure and all of the indexes continue to exist until you issue a DROP TABLE statement. The column definitions and constraints remain intact, and triggers and permissions remain in effect.

The TRUNCATE TABLE statement is entered into the transaction log as a single statement, like data definition statements. Each deleted row is not entered into the transaction log.

If the TRUNCATE_WITH_AUTO_COMMIT option is set to ON (the default), and all the following criteria are satisfied, a fast form of table truncation is executed:

  • There are no foreign keys either to or from the table.

  • The TRUNCATE TABLE statement is not executed within a trigger.

  • The TRUNCATE TABLE statement is not executed within an atomic statement.

If a fast truncation is carried out, then a COMMIT is carried out before and after the operation.

toggle Permissions

Must be the table owner, or have DBA authority, or have ALTER permissions on the table.

For base tables, the TRUNCATE TABLE statement requires exclusive access to the table, as the operation is atomic (either all rows are deleted, or none are). This means that any cursors that were previously opened and that reference the table being truncated must be closed and a COMMIT or ROLLBACK must be issued to release the reference to the table.

For temporary tables, each user has their own copy of the data, and exclusive access is not required.

toggle Side effects

Delete triggers are not fired by the TRUNCATE TABLE statement.

If TRUNCATE_WITH_AUTO_COMMIT is set to ON, then a COMMIT is performed before and after the table is truncated.

Individual deletions of rows are not entered into the transaction log, so the TRUNCATE TABLE operation is not replicated. Do not use this statement in SQL Remote replication or on a MobiLink remote database.

If the table contains a column defined as DEFAULT AUTOINCREMENT or DEFAULT GLOBAL AUTOINCREMENT, TRUNCATE TABLE resets the next available value for the column.

In UltraLite embedded SQL applications, use DELETE instead of TRUNCATE TABLE to delete all the rows in a table. TRUNCATE TABLE marks the rows for deletion, but unless you synchronize it does not physically remove them from the UltraLite database.

toggle See also
  • DELETE statement
  • TRUNCATE_WITH_AUTO_COMMIT option [database]
toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Example

Delete all rows from the department table.

TRUNCATE TABLE department


UNION operation

toggle Description

Use this statement to combine the results of two or more select statements.

toggle Syntax

select-statement
UNION [ ALL | DISTINCT ] select-statement
[ UNION [ ALL | DISTINCT ] select-statement ] ...
[ ORDER BY [ integer | select-list-expression-name ] [ ASC | DESC ], ... ]

toggle Usage

The results of several SELECT statements can be combined into a larger result using UNION. The component SELECT statements must each have the same number of items in the select list, and cannot contain an ORDER BY clause.

The results of UNION ALL are the combined results of the component SELECT statements. The results of UNION are the same as UNION ALL, except that duplicate rows are eliminated. Eliminating duplicates requires extra processing, so UNION ALL should be used instead of UNION where possible. UNION DISTINCT is identical to UNION.

If corresponding items in two select lists have different data types, Adaptive Server Anywhere will choose a data type for the corresponding column in the result and automatically convert the columns in each component SELECT statement appropriately.

The first query specification of the UNION is used to determine the names to be matched with the ORDER BY clause.

The column names displayed are the same column names that are displayed for the first SELECT statement. An alternative way of customizing result set column names is to use the WITH clause on the SELECT statement.

toggle Permissions

Must have SELECT permission for each of the component SELECT statements.

toggle Side effects

None.

toggle See also
  • SELECT statement
toggle Standards and compatibility

  • SQL/92 Entry-level.

  • SQL/99 Core feature.

  • Sybase Supported by Adaptive Server Enterprise, which also supports a COMPUTE clause.

toggle Example

List all distinct surnames of employees and customers.

SELECT emp_lname
FROM Employee
UNION
SELECT lname
FROM Customer


UNLOAD statement

toggle Description

Use this statement to export data from a database into an external ASCII-format file.

toggle Syntax

UNLOAD select-statement
TO filename
[ unload-option ... ]

unload-option :
APPEND {ON|OFF}
| DELIMITED BY string
| ESCAPE CHARACTER character
| ESCAPES {ON | OFF}
| FORMAT {ASCII | BCP}
| HEXADECIMAL {ON | OFF}
| QUOTES {ON | OFF}

filename : { string | variable }

toggle Parameters

filename The filename to which the data is to be unloaded. Because it is the database server that executes the statements, filenames specify files on the database server machine. Relative filenames specify files relative to the database server's starting directory. To unload data onto a client machine, see OUTPUT statement [Interactive SQL].

toggle Usage

The UNLOAD statement allows the result set of a query to be exported to a comma-delimited file. The result set is not ordered unless the query itself contains an ORDER BY clause.

When unloading result set columns with binary data types, UNLOAD writes hexadecimal strings, of the form \xnnnn where n is a hexadecimal digit.

For a description of the unload-option parameters, see UNLOAD TABLE statement.

When unloading and reloading a database that has proxy tables, you must create an external login to map the local user to the remote user, even if the user has the same password on both the local and remote databases. If you do not have an external login, the reload may fail because you cannot connect to the remote server.

For more information about external logins, see Working with external logins.

When the APPEND option is ON, unloaded data is appended to the end of the file specified. When the APPEND option is OFF, unloaded data replaces the contents of the file specified. This option is OFF by default.

toggle Permissions

The permissions required to execute an UNLOAD statement are set on the database server command line, using the –gl option.

For more information, see -gl server option.

toggle Side effects

None. The query is executed at the current isolation level.

toggle See also
  • UNLOAD TABLE statement
  • OUTPUT statement [Interactive SQL]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase UNLOAD is not supported by Adaptive Server Enterprise.


UNLOAD TABLE statement

toggle Description

Use this statement to export data from a database table into an external ASCII-format file.

toggle Syntax

UNLOAD [ FROM ] TABLE [ owner. ]table-name TO filename
[ unload-option ... ]

unload-option :
APPEND{ON | OFF}
| DELIMITED BY string
| ESCAPE CHARACTER character
| ESCAPES {ON | OFF}
| FORMAT {ASCII | BCP}
| HEXADECIMAL {ON | OFF}
| ORDER {ON | OFF}
| QUOTES {ON | OFF}

filename : { string | variable }

toggle Parameters

filename The filename to which the data is to be unloaded. Because it is the database server that executes the statements, filenames specify files on the database server machine. Relative filenames specify files relative to the database server's starting directory. To unload data onto a client machine, see OUTPUT statement [Interactive SQL].

APPEND option When the APPEND option is ON, unloaded data is appended to the end of the file specified. When the APPEND option is OFF, unloaded data replaces the contents of the file specified. This option is OFF by default.

ESCAPES option With ESCAPES on (the default), backslash-character combinations are used to identify special characters where necessary on export.

FORMAT option Outputs data in either ASCII format or in BCP out format.

HEXADECIMAL option By default, HEXADECIMAL is ON. Binary column values are written as 0x nnnnnn..., where each n is a hexadecimal digit. It is important to use HEXADECIMAL ON when dealing with multi-byte character sets.

The HEXADECIMAL option can be used only with the FORMAT ASCII option.

ORDER option With ORDER ON (the default), the exported data is ordered by clustered index if one exists. If a clustered index does not exist, the exported data is ordered by primary key values. With ORDER OFF, the data is exported in the same order you see when selecting from the table without an ORDER BY clause.

Exporting is slower with ORDER ON. However, reloading using the LOAD TABLE statement is quicker because of the simplicity of the indexing step.

For more information on clustered indexes, see Using clustered indexes.

QUOTES option With QUOTES turned on (the default), single quotes are placed around all exported strings.

toggle Usage

The UNLOAD TABLE statement allows efficient mass exporting from a database table into an ASCII file. UNLOAD TABLE is more efficient than the Interactive SQL statement OUTPUT, and can be called from any client application.

UNLOAD TABLE places an exclusive lock on the whole table.

When unloading columns with binary data types, UNLOAD TABLE writes hexadecimal strings, of the form \x nnnn where n is a hexadecimal digit.

For descriptions of the FORMAT, DELIMITED BY, and ESCAPE CHARACTER options, see LOAD TABLE statement.

toggle Permissions

The permissions required to execute an UNLOAD TABLE statement depend on the database server –gl command line option, as follows:

  • If the -gl option is ALL, you must have SELECT permissions on the table or tables referenced in the UNLOAD TABLE statement.

  • If the -gl option is DBA, you must have DBA authority.

  • If the -gl option is NONE, UNLOAD TABLE is not permitted.

For more information, see -gl server option.

toggle Side effects

None.

toggle See also
  • LOAD TABLE statement
  • OUTPUT statement [Interactive SQL]
  • UNLOAD statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase UNLOAD TABLE is not supported by Adaptive Server Enterprise. Similar functionality is provided by the Adaptive Server Enterprise bulk copy utility (bcp).


UPDATE statement

toggle Description

Use this statement to modify existing rows in database tables.

toggle Syntax 1

UPDATE [ FIRST | TOP n ] table-list
SET set-item, ...
[ FROM table-list ]
[ WHERE search-condition ]
[ ORDER BY expression [ ASC | DESC ], ... ]

toggle Syntax 2

UPDATE table-name
SET set-item, ...
VERIFY ( column-name, ... ) VALUES ( expression, ... )
[ WHERE search-condition ]
[ ORDER BY expression [ ASC | DESC ], ... ]

toggle Syntax 3

UPDATE table
PUBLICATION publication
{ SUBSCRIBE BY expression
| OLD SUBSCRIBE BY expression NEW SUBSCRIBE BY expression
}
WHERE search-condition

set-item :
column-name [.field-name...] = expression
| column-name[.field-name...].method-name( [ expression ] )
| @variable-name = expression

toggle Parameters

UPDATE clause The table is either a base table, a temporary table, or a view. Views can be updated unless the SELECT statement defining the view contains a GROUP BY clause or aggregate function, or involves a UNION operation.

FIRST or TOP clause Primarily for use with the ORDER BY clause, this clause allows you to update only a certain subset of the rows that satisfy the WHERE clause. You cannot use a variable as input with FIRST or TOP.

SET clause If you are updating Java columns, you can use field-name to update the value of a public field in the column. Alternatively, you can use a method to set the value. The following clause updates name field of the JProd column using a method:

SET JProd.setName( 'Tank Top' )

If you are updating non-Java columns, the SET clause is of the following form:

SET column-name = expression, ...

and/or

SET @variable-name = expression, ...

Each named column is set to the value of the expression on the right hand side of the equal sign. There are no restrictions on the expression. If the expression is a column-name, the old value is used. When assigning a variable, the variable must already be declared, and its name must begin with the "at" sign (@). Variable and column assignments can be mixed together, and any number can be used. If a name on the left side of an assignment in the SET list matches a column in the updated table as well as the variable name, the statement will update the column.

Following is an example of part of an UPDATE statement. It assigns a variable in addition to updating the table:

UPDATE T SET @var = expression1, col1 = expression2
WHERE...

This is equivalent to:

SELECT @var = expression1
FROM T
WHERE... ;
UPDATE T SET col1 = expression2
WHERE...

FROM clause The optional FROM clause allows tables to be updated based on joins. If the FROM clause is present, the WHERE clause qualifies the rows of the FROM clause. Data is updated only in the table list of the UPDATE clause.

If a FROM clause is used, it is important to qualify the table name the same way in both parts of the statement. If a correlation name is used in one place, the same correlation name must be used elsewhere. Otherwise, an error is generated.

This clause is allowed only if ANSI_UPDATE_CONSTRAINTS is set to OFF. See ANSI_UPDATE_CONSTRAINTS option [compatibility].

For a full description of joins, see Joins: Retrieving Data from Several Tables.

For more information, see FROM clause.

WHERE clause If a WHERE clause is specified, only rows satisfying the search condition are updated. If no WHERE clause is specified, every row is updated.

ORDER BY clause Normally, the order in which rows are updated does not matter. However, in conjunction with the FIRST or TOP clause the order can be significant.

You cannot use ordinal column numbers in the ORDER BY clause.

You must not update columns that appear in the ORDER BY clause unless you set the ANSI_UPDATE_CONSTRAINTS option to OFF. See ANSI_UPDATE_CONSTRAINTS option [compatibility].

Case sensitivity Character strings inserted into tables are always stored in the same case as they are entered, regardless of whether the database is case sensitive or not. A CHAR data type column updated with a string Value is always held in the database with an upper case V and the remainder of the letters lower case. SELECT statements return the string as Value. If the database is not case sensitive, however, all comparisons make Value the same as value, VALUE, and so on. Further, if a single-column primary key already contains an entry Value, an INSERT of value is rejected, as it would make the primary key not unique.

Updates that leave a row unchanged If the new value does not differ from the old value, no change is made to the data. However, BEFORE UPDATE triggers fire any time an UPDATE occurs on a row, whether or not the new value differs from the old value. AFTER UPDATE triggers fire only if the new value is different from the old value.

toggle Usage

Syntax 1 of the UPDATE statement modifies values in rows of one or more tables. Syntax 2 and 3 are applicable only to SQL Remote.

Syntax 2 is intended for use with SQL Remote only, in single-row updates of a single table executed by the Message Agent. The VERIFY clause contains a set of values that are expected to be present in the row being updated. If the values do not match, any RESOLVE UPDATE triggers are fired before the UPDATE proceeds. The UPDATE does not fail simply because the VERIFY clause fails to match.

Syntax 3 of the UPDATE statement is used to implement a specific SQL Remote feature, and is to be used inside a BEFORE trigger. It provides a full list of SUBSCRIBE BY values any time the list changes. It is placed in SQL Remote triggers so that the database server can compute the current list of SUBSCRIBE BY values. Both lists are placed in the transaction log.

The Message Agent uses the two lists to make sure that the row moves to any remote database that did not have the row and now needs it. The Message Agent also removes the row from any remote database that has the row and no longer needs it. A remote database that has the row and still needs it is not be affected by the UPDATE statement.

For publications created using a subquery in a SUBSCRIBE BY clause, you must write a trigger containing syntax 3 of the UPDATE statement in order to ensure that the rows are kept in their proper subscriptions.

Syntax 3 of the UPDATE statement allows the old SUBSCRIBE BY list and the new SUBSCRIBE BY list to be explicitly specified, which can make SQL Remote triggers more efficient. In the absence of these lists, the database server computes the old SUBSCRIBE BY list from the publication definition. Since the new SUBSCRIBE BY list is commonly only slightly different from the old SUBSCRIBE BY list, the work to compute the old list may be done twice. By specifying both the old and new lists, you can avoid this extra work.

The SUBSCRIBE BY expression is either a value or a subquery.

Syntax 3 of the UPDATE statement makes an entry in the transaction log, but does not change the database table.

Updating a significant amount of data using the UPDATE statement will also update column statistics.

toggle Permissions

Must have UPDATE permission for the columns being modified.

toggle Side effects

Column statistics are updated.

toggle See also
  • DELETE statement
  • INSERT statement
  • FROM clause
  • Joins: Retrieving Data from Several Tables
toggle Standards and compatibility

  • SQL/92 Syntax 1 is an entry-level feature, except for the FROM and ORDER BY clauses, which are vendor extensions. Syntax 2 and 3 are vendor extensions for use only with SQL Remote.

  • SQL/99 Syntax 1 is a core feature, except for the FROM and ORDER BY clauses, which are vendor extensions. Syntax 2 and 3 are vendor extensions for use only with SQL Remote.

    To enforce SQL/92 compatibility, ensure that the ANSI_UPDATE_CONSTRAINTS option is set to STRICT.

    For more information, see ANSI_UPDATE_CONSTRAINTS option [compatibility].

  • Sybase Subject to the expressions being compatible, the syntax of the UPDATE statement (syntax 1) is compatible between Adaptive Server Enterprise and Adaptive Server Anywhere. Syntax 2 and 3 are not supported.

toggle Example

Transfer employee Philip Chin (employee 129) from the sales department to the marketing department.

UPDATE employee
SET dept_id = 400
WHERE emp_id = 129;

Sales orders currently start at ID 2001. Renumber all existing sales orders by subtracting 2000 from the ID.

UPDATE sales_order AS orders
SET orders.id = orders.id - 2000
ORDER BY items.id ASC

This update is possible only if the foreign key of the sales_order_items table (referencing the primary key sales_order.id) is defined with the action ON UPDATE CASCADE. The sales_order_items table is then updated as well.

For more information on foreign key properties, see ALTER TABLE statement and CREATE TABLE statement.


UPDATE (positioned) statement [ESQL] [SP]

toggle Description

Use this statement to modify the data at the current location of a cursor.

toggle Syntax 1

UPDATE WHERE CURRENT OF cursor-name
{ USING DESCRIPTOR sqlda-name | FROM hostvar-list }

toggle Syntax 2

UPDATE table-list
SET set-item, ...
WHERE CURRENT OF cursor-name

hostvar-list : indicator variables allowed

set-item :
column-name [.field-name...] = expression
| column-name [.field-name...].method-name( [ expression ] )

sqlda-name : identifier

toggle Parameters

SET clause The columns that are referenced in set-item must be in the base table that is updated. They cannot refer to aliases, nor to columns from other tables or views. If the table you are updating is given a correlation name in the cursor specification, you must use the correlation name in the SET clause.

When assigning a variable, the variable must already be declared, and its name must begin with the "at" sign (@). Variable and column assignments can be mixed together, and any number can be used. If a name on the left side of an assignment in the SET list matches a column in the updated table as well as the variable name, the statement will update the column.

The expression on the right side of the SET clause may use constants, variables, expressions from the select list of the query, or combinations of the above using operators such as +, -, ..., COALESCE, IF, and so on. The expression cannot contain aggregate functions, subqueries, or subselects.

toggle Usage

This form of the UPDATE statement updates the current row of the specified cursor. The current row is defined to be the last row successfully fetched from the cursor, and the last operation on the cursor must not have been a positioned DELETE statement.

For syntax 1, columns from the SQLDA or values from the host variable list correspond one-to-one with the columns returned from the specified cursor. If the sqldata pointer in the SQLDA is the null pointer, the corresponding select list item is not updated.

In syntax 2, the requested columns are set to the specified values for the row at the current row of the specified query. The columns do not need to be in the select list of the specified open cursor. This format can be prepared.

The USING DESCRIPTOR, FROM hostvar-list, and hostvar formats are for embedded SQL only.

toggle Permissions

Must have UPDATE permission on the columns being modified.

toggle Side effects

None.

toggle See also
  • DELETE statement
  • DELETE (positioned) statement [ESQL] [SP]
  • UPDATE statement
toggle Standards and compatibility

  • SQL/92 Entry-level feature. The range of cursors that can be updated may contain vendor extensions if the ANSI_UPDATE_CONSTRAINTS option is set to OFF.

  • SQL/99 Core feature. The range of cursors that can be updated may contain vendor extensions if the ANSI_UPDATE_CONSTRAINTS option is set to OFF.

  • Sybase Embedded SQL use is supported by Open Client/Open Server, and procedure and trigger use is supported in Adaptive Server Anywhere.

toggle Example

The following is an example of an UPDATE statement WHERE CURRENT OF cursor:

UPDATE Employee
SET emp_lname = 'Jones'
WHERE CURRENT OF emp_cursor;


UPDATE statement [SQL Remote]

toggle Description

Use this statement to modify data in the database.

toggle Syntax 1

UPDATE table-list
SET column-name = expression, ...
[ VERIFY ( column-name, ... ) VALUES ( expression, ... ) ]
[ WHERE search-condition ]
[ ORDER BY expression [ ASC | DESC ], ... ]

toggle Syntax 2

UPDATE table
PUBLICATION publication
{ SUBSCRIBE BY expression |
OLD SUBSCRIBE BY expression
NEW SUBSCRIBE BY expression }
WHERE search-condition

expression: value | subquery

toggle Usage

Syntax 1 and Syntax 2 are applicable only to SQL Remote.

Syntax 2 with no OLD and NEW SUBSCRIBE BY expressions must be used in a BEFORE trigger.

Syntax 2 with OLD and NEW SUBSCRIBE BY expressions can be used anywhere.

The UPDATE statement is used to modify rows of one or more tables. Each named column is set to the value of the expression on the right hand side of the equal sign. There are no restrictions on the expression. Even column-name can be used in the expression—the old value will be used.

If no WHERE clause is specified, every row will be updated. If a WHERE clause is specified, then only those rows which satisfy the search condition will be updated.

Normally, the order that rows are updated doesn't matter. However, in conjunction with the NUMBER(*) function, an ordering can be useful to get increasing numbers added to the rows in some specified order. Also, if you wish to do something like add 1 to the primary key values of a table, it is necessary to do this in descending order by primary key, so that you do not get duplicate primary keys during the operation.

Views can be updated provided the SELECT statement defining the view does not contain a GROUP BY clause, an aggregate function, or involve a UNION operation.

Character strings inserted into tables are always stored in the case they are entered, regardless of whether the database is case sensitive or not. Thus a character data type column updated with a string Value is always held in the database with an upper-case V and the remainder of the letters lower case. SELECT statements return the string as Value. If the database is not case sensitive, however, all comparisons make Value the same as value, VALUE, and so on. Further, if a single-column primary key already contains an entry Value, an INSERT of value is rejected, as it would make the primary key not unique.

The optional FROM clause allows tables to be updated based on joins. If the FROM clause is present, the WHERE clause qualifies the rows of the FROM clause. Data is updated only in the table list immediately following the UPDATE keyword.

If a FROM clause is used, it is important to qualify the table name that is being updated the same way in both parts of the statement. If a correlation name is used in one place, the same correlation name must be used in the other. Otherwise, an error is generated.

Syntax 1 is intended for use with SQL Remote only, in single-row updates executed by the Message Agent. The VERIFY clause contains a set of values that are expected to be present in the row being updated. If the values do not match, any RESOLVE UPDATE triggers are fired before the UPDATE proceeds. The UPDATE does not fail if the VERIFY clause fails to match. When the VERIFY clause is specified, only one table can be updated at a time.

Syntax 2 is intended for use with SQL Remote only. If no OLD and NEW expressions are used, it must be used inside a BEFORE trigger so that it has access to the relevant values. The purpose is to provide a full list of subscribe by values any time the list changes. It is placed in SQL Remote triggers so that the database server can compute the current list of SUBSCRIBE BY values. Both lists are placed in the transaction log.

The Message Agent uses the two lists to make sure that the row moves to any remote database that did not have the row and now needs it. The Message Agent also removes the row from any remote database that has the row and no longer needs it. A remote database that has the row and still needs it is not be affected by the UPDATE statement.

Syntax 2 of the UPDATE statement allows the old SUBSCRIBE BY list and the new SUBSCRIBE BY list to be explicitly specified, which can make SQL Remote triggers more efficient. In the absence of these lists, the database server computes the old SUBSCRIBE BY list from the publication definition. Since the new SUBSCRIBE BY list is commonly only slightly different from the old SUBSCRIBE BY list, the work to compute the old list may be done twice. By specifying both the old and new lists, this extra work can be avoided.

The OLD and NEW SUBSCRIBE BY syntax is especially useful when many tables are being updated in the same trigger with the same subscribe by expressions. This can dramatically increase performance.

The SUBSCRIBE BY expression is either a value or a subquery.

Syntax 2 of the UPDATE statement is used to implement a specific SQL Remote feature, and is to be used inside a BEFORE trigger.

For publications created using a subquery in a subscription expression, you must write a trigger containing syntax 2 of the UPDATE statement in order to ensure that the rows are kept in their proper subscriptions.

For a full description of this feature, see Territory realignment in the Contact example.

Syntax 2 of the UPDATE statement makes an entry in the transaction log, but does not change the database table.

toggle Permissions

Must have UPDATE permission for the columns being modified.

toggle Side effects

None.

toggle See also
  • CREATE TRIGGER statement [SQL Remote]
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

toggle Examples

  • Transfer employee Philip Chin (employee 129) from the sales department to the marketing department.

    UPDATE employee
VERIFY( dept_id ) VALUES( 300 )
SET dept_id = 400
WHERE emp_id = 129


VALIDATE CHECKSUM statement

toggle Description

Use this statement to validate a database using checksums.

toggle Syntax

VALIDATE CHECKSUM

toggle Usage

Ensures that database pages have not been modified on disk. When a database is created with checksums enabled, a checksum is calculated for each database page before it is written to disk. VALIDATE CHECKSUM reads each database page from disk and calculates the checksum for each page. If the calculated checksum for a page does not match the stored checksum for that page, an error occurs and information about the invalid page appears in the server messages window.

This type of validation can only be used on databases that were created with checksums enabled. You can check whether a database has checksums enabled by executing the following statement:

SELECT db_property ( 'Checksum' )
toggle Permissions

None

toggle Side effects

None

toggle See also
  • CREATE DATABASE statement
  • sa_validate system procedure
  • The Validation utility


VALIDATE INDEX statement

toggle Description

Use this statement to validate an index, including index statistics.

toggle Syntax

VALIDATE INDEX [ [ owner.]table-name.] { index-name | table-name }

toggle Usage

Ensures that every row referenced in the index actually exists in the table. For foreign key indexes, it also ensures that the corresponding row exists in the primary table. This check complements the validity checking carried out by the VALIDATE TABLE statement.

The VALIDATE INDEX statement also verifies that the statistics reported on the specified index(es) are accurate. If they are not accurate, an error is generated.

index-name | table-name If you supply a table-name instead of an index-name, the primary key index is validated.

toggle Permissions

Must be the owner of the table on which the index is created, have DBA authority, or have REMOTE DBA authority (SQL Remote).

toggle Side effects

None.

toggle See also
  • CREATE INDEX statement
  • VALIDATE TABLE statement
  • The Validation utility


VALIDATE TABLE statement

toggle Description

Use this statement to validate a table in the database.

toggle Syntax

VALIDATE TABLE [ owner.]table-name
[ WITH { DATA | EXPRESS | FULL | INDEX } CHECK ]

toggle Parameters

WITH DATA CHECK If you have LONG BINARY, LONG VARCHAR, TEXT, or IMAGE entries, they may span more than one database page. In addition to the default checks, this option instructs the database server to check all pages used by each entry.

WITH EXPRESS CHECK In addition to the default and WITH DATA checks, check that the number of rows in the table matches the number of entries in the index. This option does not perform individual index lookups for each row. This option can significantly improve performance when validating large databases with a small cache.

WITH FULL CHECK In addition to the default checks, carry out a DATA CHECK and an INDEX CHECK.

WITH INDEX CHECK In addition to the default checks, validate each index on the table. For information on index validation, see VALIDATE INDEX statement.

toggle Usage

With no additional options, VALIDATE TABLE scans every row of a table. For each entry that is in an index, it checks the validity of the database page that the entry starts on, and checks that an entry for the row exists in the proper index. The VALIDATE TABLE statement also ensures, for each index in the table, that the number of rows referenced by the index is not greater than the number of rows in the table.

This default validation is sufficient for most purposes. Options are provided for additional validation, which may be helpful in unusual circumstances. Depending on the contents of your database, these additional checks may significantly extend the time required to validate.

If the table is corrupt, an error is reported. If you do have errors reported, you can drop all of the indexes and keys on a table and recreate them. Any foreign keys to the table will also need to be recreated. Another solution to errors reported by VALIDATE TABLE is to unload and reload your entire database. You should use the -u option of DBUNLOAD so that it will not try to use a possibly corrupt index to order the data.

toggle Permissions

Must be the owner of the table, have DBA authority, or have REMOTE DBA authority (SQL Remote).

toggle Side effects

None.

toggle See also
  • The Validation utility
  • VALIDATE INDEX statement
  • sa_validate system procedure
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase VALIDATE TABLE is not supported in Adaptive Server Enterprise. The procedure dbcc checktable provides a similar function.

  • WITH EXPRESS CHECK option This option is only supported for databases created with Adaptive Server Anywhere version 7.0 or later.


WAITFOR statement

toggle Description

Use this statement to delay processing for the current connection for a specified amount of time or until a given time.

toggle Syntax

WAITFOR { DELAY time | TIME time }
[ CHECK EVERY integer ]
[ AFTER MESSAGE BREAK ]

time: string

toggle Parameters

DELAY If DELAY is used, processing is suspended for the given interval.

TIME If TIME is specified, processing is suspended until the server time reaches the time specified.

If the current server time is greater than the time specified, processing is suspended until that time on the following day.

CHECK EVERY This optional clause controls how often the WAITFOR statement wakes up. By default, it wakes up every 5 seconds. The value is in milliseconds, and the minimum value is 250 milliseconds.

AFTER MESSAGE BREAK The WAITFOR statement can be used to wait for a message from another connection. In most cases, when a message is received it is forwarded to the application that executed the WAITFOR statement and the WAITFOR statement continues to wait. If the AFTER MESSAGE BREAK clause is specified, when a message is received from another connection, the WAITFOR statement completes. The message text is not forwarded to the application, but it can be accessed by obtaining the value of the MessageReceived connection property.

For more information about the MessageReceived property, see Connection-level properties.

toggle Usage

The WAITFOR statement wakes up periodically (every 5 seconds by default) to check if it has been cancelled or if messages have been received. If neither of these has happened, the statement continues to wait.

WAITFOR provides an alternative to the following statement, and may be useful for customers who choose not to license Java in the database:

call java.lang.Thread.sleep( <time_to_wait_in_millisecs> )

In many cases, scheduled events are a better choice than using WAITFOR TIME, because scheduled events execute on their own connection.

toggle Permissions

None

toggle Side effects

The implementation of this statement uses a worker thread while it is waiting. This uses up one of the threads specified by the -gn database option (the default is 20 threads).

toggle See also
  • CREATE EVENT statement
toggle Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase This statement is also implemented by Adaptive Server Enterprise.

toggle Examples

The following example waits for three seconds:

WAITFOR DELAY '00:00:03'

The following example waits for 0.5 seconds (500 milliseconds):

WAITFOR DELAY '00:00:00:500'

The following example waits until 8 PM:

WAITFOR TIME '20:00'

In the following example, connection 1's WAITFOR statement completes when it receives the message from connection 2:

// connection 1:

BEGIN
  DECLARE msg LONG VARCHAR;
  LOOP  // forever
    WAITFOR DELAY '00:05:00' AFTER MESSAGE BREAK;
    SET msg = connection_property('MessageReceived');
    IF msg != '' THEN
      MESSAGE 'Msg: ' || msg TO CONSOLE;
    END IF;
  END LOOP
END

// connection 2:

MESSAGE 'here it is' FOR connection 1


WHENEVER statement [ESQL]

toggle Description

Use this statement to specify error handling in embedded SQL programs.

toggle Syntax

WHENEVER { SQLERROR | SQLWARNING | NOTFOUND }
GOTO label | STOP | CONTINUE | { C-code; }

label : identifier

toggle Usage

The WHENEVER statement is used to trap errors, warnings and exceptional conditions encountered by the database when processing SQL statements. The statement can be put anywhere in an embedded SQL program and does not generate any code. The preprocessor will generate code following each successive SQL statement. The error action remains in effect for all embedded SQL statements from the source line of the WHENEVER statement until the next WHENEVER statement with the same error condition, or the end of the source file.

Errors based on source position
The error conditions are in effect based on positioning in the C language source file, not based on when the statements are executed.

The default action is CONTINUE.

Note that this statement is provided for convenience in simple programs. Most of the time, checking the sqlcode field of the SQLCA (SQLCODE) directly is the easiest way to check error conditions. In this case, the WHENEVER statement would not be used. If fact, all the WHENEVER statement does is cause the preprocessor to generate an if ( SQLCODE ) test after each statement.

toggle Permissions

None.

toggle Side effects

None.

toggle Standards and compatibility

  • SQL/92 Entry-level feature.

  • SQL/99 Core feature.

  • Sybase Supported by Open Client/Open Server.

toggle Example

The following are examples of the WHENEVER statement:

EXEC SQL WHENEVER NOTFOUND GOTO done;
EXEC SQL WHENEVER SQLERROR
   {
      PrintError( &sqlca );
      return( FALSE );
   };


WHILE statement [T-SQL]

toggle Description

Use this statement to provide repeated execution of a statement or compound statement.

toggle Syntax

WHILE search-condition-statement

toggle Usage

The WHILE conditional affects the execution of only a single SQL statement, unless statements are grouped into a compound statement between the keywords BEGIN and END.

The BREAK statement and CONTINUE statement can be used to control execution of the statements in the compound statement. The BREAK statement terminates the loop, and execution resumes after the END keyword marking the end of the loop. The CONTINUE statement causes the WHILE loop to restart, skipping any statements after the CONTINUE.

toggle Permissions

None.

toggle Side effects

None.

toggle See also
  • LOOP statement
toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Example

The following code illustrates the use of WHILE:

WHILE ( SELECT AVG(unit_price) FROM product ) < $30
BEGIN
   UPDATE product
   SET unit_price = unit_price + 2
   IF ( SELECT MAX(unit_price) FROM product ) > $50
      BREAK
END

The BREAK statement breaks the WHILE loop if the most expensive product has a price above $50. Otherwise, the loop continues until the average price is greater than or equal to $30.


WRITETEXT statement [T-SQL]

toggle Description

Permits non-logged, interactive updating of an existing text or image column.

toggle Syntax

WRITETEXT table-name.column-name
text_pointer [ WITH LOG ] data

toggle Usage

Updates an existing text or image value. The update is not recorded in the transaction log, unless the WITH LOG option is supplied. You cannot carry out WRITETEXT operations on views.

toggle Permissions

None.

toggle Side effects

WRITETEXT does not fire triggers, and by default WRITETEXT operations are not recorded in the transaction log.

toggle See also
  • READTEXT statement [T-SQL]
  • TEXTPTR function [Text and image]
toggle Standards and compatibility

  • SQL/92 Transact-SQL extension.

  • SQL/99 Transact-SQL extension.

  • Sybase Supported by Adaptive Server Enterprise.

toggle Example

The following code fragment illustrates the use of the WRITETEXT statement. The SELECT statement in this example returns a single row. The example replaces the contents of the column_name column on the specified row with the value newdata.

EXEC SQL create variable textpointer binary(16);
EXEC SQL set textpointer =
   (  SELECT textptr(column_name)
      FROM table_name WHERE id = 5 );
EXEC SQL writetext table_name.column_name
   textpointer 'newdata';


System Tables

About this chapter

The structure of every database is described in a number of system tables.

The system tables are owned by the SYS user ID. The contents of these tables can be changed only by the database server. The UPDATE, DELETE, and INSERT commands cannot be used to modify the contents of these tables. Further, the structure of these tables cannot be changed using the ALTER TABLE and DROP commands.

This chapter contains descriptions of each of the system tables. Several of the columns have only two possible values. Usually these values are Y and N for yes and no respectively. These columns are designated by (Y/N).

DUMMY system table
RowGenerator system table
SYSARTICLE system table
SYSARTICLECOL system table
SYSATTRIBUTE system table
SYSATTRIBUTENAME system table
SYSCAPABILITY system table
SYSCAPABILITYNAME system table
SYSCHECK system table
SYSCOLLATION system table
SYSCOLLATIONMAPPINGS system table
SYSCOLPERM system table
SYSCOLSTAT system table
SYSCOLUMN system table
SYSCONSTRAINT system table
SYSDOMAIN system table
SYSEVENT system table
SYSEVENTTYPE system table
SYSEXTENT system table
SYSEXTERNLOGINS system table
SYSFILE system table
SYSFKCOL system table
SYSFOREIGNKEY system table
SYSGROUP system table
SYSHISTORY system table
SYSINDEX system table
SYSINFO system table (deprecated)
SYSIXCOL system table
SYSJAR system table
SYSJARCOMPONENT system table
SYSJAVACLASS system table
SYSLOGIN system table
SYSOPTBLOCK system table
SYSOPTION system table
SYSOPTJOINSTRATEGY system table
SYSOPTORDER system table
SYSOPTQUANTIFIER system table
SYSOPTREQUEST system table
SYSOPTREWRITE system table
SYSOPTSTAT system table
SYSPROCEDURE system table
SYSPROCPARM system table
SYSPROCPERM system table
SYSPUBLICATION system table
SYSREMOTEOPTION system table
SYSREMOTEOPTIONTYPE system table
SYSREMOTETYPE system table
SYSREMOTEUSER system table
SYSSCHEDULE system table
SYSSERVERS system table
SYSSQLSERVERTYPE system table
SYSSUBSCRIPTION system table
SYSSYNC system table
SYSTABLE system table
SYSTABLEPERM system table
SYSTRIGGER system table
SYSTYPEMAP system table
SYSUSERMESSAGES system table
SYSUSERPERM system table
SYSUSERTYPE system table
SYSWEBSERVICE system table
Other system tables


DUMMY system table

Column name | Column type | Column constraint | Table constraints
dummy_col | INTEGER | NOT NULL |

The DUMMY table is provided as a read-only table that always has exactly one row. This can be useful for extracting information from the database, as in the following example that gets the current user ID and the current date from the database.

SELECT USER, today(*) FROM SYS.DUMMY

Use of SYS.DUMMY in the FROM clause is optional. If no table is specified in the FROM clause, the table is assumed to be SYS.DUMMY. The above example could be written as follows:

SELECT USER, today(*)

dummy_col This column is not used. It is present because a table cannot be created with no columns.

The cost of reading from the SYS.DUMMY table is less than the cost of reading from a similar user created table because there is no latch placed on the table page of SYS.DUMMY. Further, the SYS.DUMMY table does not appear in a Lock node in the graphical plan, and if only the SYS.DUMMY table is present, a Lock node is not added.


RowGenerator system table

Column name | Column type | Column constraint | Table constraints
row_num | SMALLINT | NOT NULL |

The dbo.RowGenerator table is provided as a read-only table that has 255 rows. This table can be useful for queries which produce small result sets and which need a range of numeric values.

The RowGenerator table is used by system stored procedures and views, and should not be modified in any way.

You can also use the sa_rowgenerator stored procedure to generate a range of numeric values.

For more information, see sa_rowgenerator system procedure.

row_num A value between 1 and 255.

The following query returns a result set containing one row for each day of the current month.

select dateadd(day,row_num-1,
        ymd(datepart(year,current date),
            datepart(month,current date),
            1)) as day_of_month
from dbo.RowGenerator
where row_num < 32
and datepart(month,day_of_month) =
   datepart(month,current date)
order by row_num


SYSARTICLE system table

Column name | Column type | Column constraint | Table constraints
publication_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSPUBLICATION.
table_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSTABLE.
where_expr | LONG VARCHAR |  |
subscribe_by_expr | LONG VARCHAR |  |
query | CHAR(1) | NOT NULL |

Each row of SYSARTICLE describes an article in a publication.

publication_id The publication of which this article is a part.

table_id Each article consists of columns and rows from a single table. This column contains the table ID for this table.

where_expr For articles that contain a subset of rows defined by a WHERE clause, this column contains the search condition.

subscribe_by_expr For articles that contain a subset of rows defined by a SUBSCRIBE BY expression, this column contains the expression.

query Indicates information about the article type to the database server.


SYSARTICLECOL system table

Column name | Column type | Column constraint | Table constraints
publication_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSARTICLE.
table_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSARTICLE, SYSCOLUMN.
column_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSCOLUMN.

Each row identifies a column in an article.

publication_id A unique identifier for the publication of which the column is a part.

table_id The table to which the column belongs.

column_id The column identifier, from the SYSCOLUMN system table.


SYSATTRIBUTE system table

SYSATTRIBUTE and SYSATTRIBUTENAME were created so that new information about database objects could be added to the system tables without changing the schema.

Each row of SYSATTRIBUTE describes one system object, such as a particular table or index. Rows are added when the attribute is specified; for example, every table with a table page percent free setting is added to SYSATTRIBUTE. Similarly, a row for index depth appears in SYSATTRIBUTE only when the index depth increases to 2.

Statistics are maintained for all indexes, including those on catalog tables, as each index is updated. The VALIDATE statement verifies that the statistics on the specified index(es) are accurate and generates an error if they are not. This provides accurate statistics to the optimizer at virtually no performance cost. Statistics persist in SYSATTRIBUTE in the form of one row for each statistic for an index.

 | object_type | object_id | attribute_id (from SYSATTRIBUTENAME | sub_object_id1 | sub_object_id2 | attribute_value
Table page percent free | T | table_id |  | NULL | NULL | percentage of free space left in each table page
Clustered index | T | table_id | 2 | index_number | NULL | NULL
Number of distinct key values | I | table_id | 3 | NULL | NULL | number of distinct key values
Number of leaf pages | I | table_id | 4 | index_number | NULL | number of leaf pages
Index depth | I | table_id | 5 | index_number | NULL | index depth
Maximum index key value distance | I | table_id | 6 | index_number | NULL | maximum distance, in pages, between rows containing the same key value

Columns in the SYSATTRIBUTE table exhibit the following characteristics:

Column name | Column type | Column constraint
object_type | CHAR(1) | NOT NULL
object_id | UNSIGNED INT | NOT NULL
attribute_id | UNSIGNED INT | NOT NULL. Foreign key references SYSATTRIBUTENAME.
sub_object_id1 | UNSIGNED INT |
sub_object_id2 | UNSIGNED INT |
attribute_value | LONG VARCHAR |

object_type The type of object the attribute describes. For example, T represents a table, I an index.

object_id The id of the particular object. Object id information can be obtained from the table_id column after executing SELECT * FROM SYSTABLE.

attribute_id The number representing the attribute that is being described. A descriptive name for each attribute ID is stored in SYSATTRIBUTENAME.

sub_object_id1 Additional information about the attribute, or NULL if there is none.

sub_object_id2 Additional information about the attribute, or NULL if there is none.

attribute_value The value of the attribute.


SYSATTRIBUTENAME system table

Column name | Column type | Column constraint
attribute_id | UNSIGNED INT | NOT NULL.
attribute_name | CHAR(128) | NOT NULL.

This table provides attribute names for the attribute IDs that are used in SYSATTRIBUTE.

attribute_id The ID of the attribute.

attribute_name The name of the attribute.


SYSCAPABILITY system table

Column name | Column type | Column constraint | Table constraints
capid | INTEGER | NOT NULL | Primary key. Foreign key references SYSCAPABILITYNAME.
srvid | INTEGER | NOT NULL | Primary key. Foreign key references SYSSERVERS.
capvalue | CHAR(128) | NOT NULL |

Each row identifies a capability of a remote server.

capid The capability, as listed in SYSCAPABILITYNAME.

srvid The server to which the capability applies, as listed in SYSSERVERS.

capvalue The value of the capability.


SYSCAPABILITYNAME system table

Column name | Column type | Column constraint | Table constraints
capid | INTEGER | NOT NULL | Primary key.
capname | CHAR(128) | NOT NULL |

Each row identifies a capability.

capid The capability ID.

capname The name of the capability.


SYSCHECK system table

Column name | Column type | Column constraint | Table constraints
check_id | INTEGER | NOT NULL | Primary key. Foreign key references SYSCONSTRAINT.
check_defn | LONG VARCHAR | NOT NULL |

Each row identifies a named check constraint in a table.

check_id An identifier for the constraint.

check_defn The CHECK expression.


SYSCOLLATION system table

Column name | Column type | Column constraint | Table constraint
collation_id | SMALLINT | NOT NULL | Primary key.
collation_label | CHAR(10) | NOT NULL |
collation_name | CHAR(128) | NOT NULL |
collation_order | BINARY(1280) | NOT NULL |

This table contains the collation sequence information for the database. There is no way to modify the contents of this table.

collation_id A unique number identifying the collation sequence.

collation_label A string identifying the collation sequence. The collation sequence to be used is selected when the database is created, by specifying the collation label with the -z option.

collation_name The name of the collation sequence.

collation_order An array of bytes defining how each of the 256 character codes are treated for comparison purposes. All string comparisons translate each character according to the collation order table before comparing the characters. For the different ASCII code pages, the only difference is how accented characters are sorted. In general, an accented character is sorted as if it were the same as the nonaccented character.


SYSCOLLATIONMAPPINGS system table

Column name | Column type | Column constraint | Table Constraints
collation_label | CHAR(10) | NOT NULL | Primary key.
collation_name | CHAR(128) | NOT NULL |
cs_label | CHAR(128) |  |
so_case_label | CHAR(128) |  |
so_caseless_label | CHAR(128) |  |
jdk_label | CHAR(128) |  |

collation_label A string identifying the collation sequence. The collation sequence to be used is selected when the database is created, by specifying the collation label with the -z option.

collation_name The collation name used to describe the character set encoding.

cs_label The Adaptive Server Enterprise character set mapping label.

so_case_label The collation sort order for case-sensitive Adaptive Server Enterprise character set mapping.

so_caseless_label The collation sort order for case-insensitive Adaptive Server Enterprise character set mapping.

jdk_label The JDK character set label.

This table contains only one row with the database collation mapping.


SYSCOLPERM system table

Column name | Column type | Column constraint | Table constraint
table_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSCOLUMN.
grantee | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSUSERPERM.
grantor | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSUSERPERM.
column_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSCOLUMN.
privilege_type | SMALLINT | NOT NULL | Primary key.
is_grantable | CHAR(1) | NOT NULL |

The GRANT statement can give UPDATE, SELECT, or REFERENCES permission to individual columns in a table. Each column with UPDATE , SELECT, or REFERENCES permission is recorded in one row of SYSCOLPERM.

table_id The table number for the table containing the column.

grantee The user number of the user ID that is given permission on the column. If the grantee is the user number for the special PUBLIC user ID, the permission is given to all user IDs.

grantor The user number of the user ID that grants the permission.

column_id This column number, together with the table_id, identifies the column for which permission has been granted.

privilege_type The number in this column indicates the kind of column permission (16=REFERENCES, 1=SELECT, or 8=UPDATE).

is_grantable (Y/N) Indicates if the permission on the column was granted WITH GRANT OPTION.


SYSCOLSTAT system table

Column name | Column type | Column constraint | Table constraints
table_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSCOLUMN.
column_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSCOLUMN.
format_id | SMALLINT | NOT NULL |
update_time | TIMESTAMP | NOT NULL |
density | FLOAT | NOT NULL |
max_steps | SMALLINT | NOT NULL |
actual_steps | SMALLINT | NOT NULL |
step_values | LONG BINARY |  |
frequencies | LONG BINARY |  |

This table stores the column statistics that are stored as histograms and used by the optimizer. The contents of this table are best retrieved using the sa_get_histogram stored procedure or the Histogram utility.

table_id A number that uniquely identifies the table or view to which this column belongs.

column_id A number that, together with table_id, uniquely identifies the column.

format_id Internal field used to determine the format of the rest of the row.

update_time The time of the last update of this row.

density An estimate of the weighted average selectivity of a single value for the column, not counting the selectivity of large single value selectivities stored in the row.

max_steps The maximum number of steps allowed in the histogram.

actual_steps The number of steps actually used at this time.

step_values Boundary values of the histogram steps.

frequencies Selectivities of histogram steps.


SYSCOLUMN system table

Column name | Column type | Column constraint | Table constraints
table_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSTABLE.
column_id | UNSIGNED INT | NOT NULL | Primary key.
pkey | CHAR(1) | NOT NULL |
domain_id | SMALLINT | NOT NULL | Foreign key references SYSDOMAIN.
nulls | CHAR(1) | NOT NULL |
width | SMALLINT | NOT NULL |
scale | SMALLINT | NOT NULL |
unused | INTEGER | NOT NULL |
max_identity | BIGINT | NOT NULL |
column_name | CHAR(128) | NOT NULL |
remarks | LONG VARCHAR |  |
"default" | LONG VARCHAR |  |
unused2 | LONG VARCHAR |  |
user_type | SMALLINT |  | Foreign key references SYSUSERTYPE.
format_str | CHAR(128) |  |
column_type | CHAR(1) | NOT NULL |
remote_name | VARCHAR(128) |  |
remote_type | UNSIGNED INT |  |

Each column in every table or view is described by one row in SYSCOLUMN.

table_id A number that uniquely identifies the table or view to which this column belongs.

column_id Each table starts numbering columns at 1. The order of column numbers determines the order that columns are displayed in the command

SELECT * FROM TABLE

pkey (Y/N) Indicate whether this column is part of the primary key for the table.

domain_id The data type for the column, indicated by a data type number listed in the SYSDOMAIN table.

nulls (Y/N) Indicates whether the NULL value is allowed in this column.

width The length of a string column, the precision of numeric columns or the number of bytes of storage for any other data type.

scale The number of digits after the decimal point for numeric data type columns, and zero for all other data types.

unused Not used.

max_identity The largest value of the column, if it is an AUTOINCREMENT, IDENTITY, or GLOBAL AUTOINCREMENT column.

column_name The name of the column.

remarks A comment string.

default The default value for the column. This value is only used when an INSERT statement does not specify a value for the column.

unused2 Not used.

user_type If the column is defined using a user-defined data type, the data type is held here.

format_str Currently unused.

column_type The type of column. Contains C for a computed column and R for other columns.

remote_name For columns in proxy tables, the name of the remote column.

remote_type For columns in proxy tables, the type of the remote column. This value is defined by the remote server or interface.


SYSCONSTRAINT system table

Column name | Column type | Column constraint | Table constraints
constraint_id | INTEGER | NOT NULL | Primary key.
table_id | INTEGER | NOT NULL | Foreign key references SYSTABLE, SYSCOLUMN, and SYSINDEX.
column_id | INTEGER |  | Foreign key references SYSCOLUMN.
index_id | INTEGER |  | Foreign key references SYSINDEX.
fkey_id | SMALLINT |  | Foreign key references SYSFOREIGNKEY.
constraint_type | CHAR(1) | NOT NULL |
constraint_name | CHAR(128) | NOT NULL |

Each row describes a named constraint. This table does not contain rows for catalog tables.

constraint_id The unique constraint ID.

table_id The table ID of the table to which the constraint applies.

column_id The column ID of the column to which the constraint applies. The column is NULL for any constraints that are not column constraints.

index_id The index ID for a unique constraint. The column is NULL for all constraints that are not unique constraints.

fkey_id The foreign key ID for a foreign key constraint. The column is NULL for all constraints that are not foreign key constraints.

constraint_type Set to one of the following values:

  • C if the constraint is a column check constraint.

  • T if the constraint is a table constraint.

  • P if the constraint is a primary key.

  • F if the constraint is a foreign key.

  • U if the constraint is a unique constraint.

constraint_name The name of the constraint.


SYSDOMAIN system table

Column name | Column type | Column constraint | Table constraints
domain_id | SMALLINT | NOT NULL | Primary key.
domain_name | CHAR(128) | NOT NULL |
type_id | SMALLINT | NOT NULL |
precision | SMALLINT |  |

Each of the predefined data types (sometimes called domains) is assigned a unique number. The SYSDOMAIN table is provided for informational purposes, to show the association between these numbers and the appropriate data types. This table is never changed.

domain_id The unique number assigned to each data type. These numbers cannot be changed.

domain_name A string containing the data type normally found in the CREATE TABLE command, such as char or integer.

type_id The ODBC data type. This corresponds to "data_type" in the Transact-SQL-compatibility dbo.SYSTYPES table.

precision The number of significant digits that can be stored using this data type. The column value is NULL for non-numeric data types.


SYSEVENT system table

Column name | Column type | Column constraint | Table constraints
event_id | INTEGER | NOT NULL | Primary key.
creator | UNSIGNED INT | NOT NULL | Foreign key references SYSUSERPERM.
event_name | VARCHAR(128) | NOT NULL | Foreign key references SYSEVENTTYPE.
enabled | CHAR(1) | NOT NULL |
location | CHAR(1) | NOT NULL |
event_type_id | INTEGER |  |
action | LONG VARCHAR |  |
external_action | LONG VARCHAR |  |
condition | LONG VARCHAR |  |
remarks | LONG VARCHAR |  |
source | LONG VARCHAR |  |

Each row in SYSEVENT describes an event created with CREATE EVENT.

event_id The unique number assigned to each event.

creator The user number of the owner of the event. The name of the user can be found by looking in SYSUSERPERM.

event_name The name of the event.

enabled (Y/N) Indicates whether or not the event is allowed to fire.

location The location where the event is to fire:

  • C = consolidated

  • R = remote

  • A = all

event_type_id For system events, the event type as listed in SYSEVENTTYPE.

action The event handler definition.

external_action Not used.

condition The WHERE condition used to control firing of the event handler.

remarks A comment string.

source This column contains the original source for the event handler if the preserve_source_format option is ON. It is used to maintain the appearance of the original text. For more information, see PRESERVE_SOURCE_FORMAT option [database].


SYSEVENTTYPE system table

Column name | Column type | Column constraint | Table constraints
event_type_id | INTEGER | NOT NULL | Primary key.
name | VARCHAR(128) | NOT NULL |
description | LONG VARCHAR |  |

This table lists the system event types which can be referenced by CREATE EVENT.

event_type_id The unique number assigned to each event type.

name The name of the system event type.

description A description of the system event type.


SYSEXTENT system table

Column name | Column type | Column constraint | Table constraint
file_id | SMALLINT | NOT NULL | Primary key. Foreign key references SYSFILE.
extent_id | SMALLINT | NOT NULL | Primary key.
first_page | INTEGER | NOT NULL |
last_page | INTEGER | NOT NULL |
file_name | LONG VARCHAR | NOT NULL |

This table is not used.


SYSEXTERNLOGINS system table

Column name | Column type | Column constraint | Table constraints
user_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key to SYSUSERPERM.
srvid | INTEGER | NOT NULL | Primary key. Foreign key to SYSSERVERS.
remote_login | VARCHAR(128) |  |
remote_password | VARBINARY(128) |  |

Each row describes an external login for remote data access.

user_id The user ID on the local database.

srvid The remote server, as listed in SYSSERVERS.

remote_login The login name for this user, for the remote server.

remote_password The password for this user, for the remote server.


SYSFILE system table

Column name | Column type | Column constraint | Table constraint
file_id | SMALLINT | NOT NULL | Primary key.
file_name | LONG VARCHAR | NOT NULL | Unique index.
dbspace_name | CHAR(128) | NOT NULL |
store_type | CHAR(8) | NOT NULL |

Every database consists of one or more dbspaces. Each dbspace corresponds to an operating system file. Each dbspace is recorded in SYSFILE.

file_id Each file in a database is assigned a unique number. This file identifier is the primary key for SYSFILE. All system tables are stored in file_id 0.

file_name The file name for the dbspace. For the SYSTEM dbspace, the value is the name of the database file when the database was created. This value is for informational purposes only and cannot be changed. For other dbspaces, the file name can be changed using the following statement:

ALTER DBSPACE dbspace RENAME 'new-file-name'

dbspace_name Every file has a dbspace name that is unique. It is used in the CREATE TABLE command.

store_type This field is for internal use.


SYSFKCOL system table

Column name | Column type | Column constraint | Table constraints
foreign_table_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSCOLUMN and SYSFOREIGNKEY.
foreign_key_id | SMALLINT | NOT NULL | Primary key. Foreign key references SYSFOREIGNKEY.
foreign_column_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSCOLUMN.
primary_column_id | UNSIGNED INT | NOT NULL |

Each row of SYSFKCOL describes the association between a foreign column in the foreign table of a relationship and the primary column in the primary table.

foreign_table_id The table number of the foreign table.

foreign_key_id The key number of the FOREIGN KEY for the foreign table. Together, foreign_table_id and foreign_key_id uniquely identify one row in SYSFOREIGNKEY. The table number for the primary table can be obtained from that row (using the SYSFOREIGNKEY table).

foreign_column_id This column number and the foreign_table_id identify the foreign column description in SYSCOLUMN.

primary_column_id This column number and the primary_table_id obtained from SYSFOREIGNKEY identify the primary column description in SYSCOLUMN.


SYSFOREIGNKEY system table

Column name | Column type | Column constraint | Table constraints
foreign_table_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSTABLE.table_id. Unique index.
foreign_key_id | SMALLINT | NOT NULL | Primary key.
primary_table_id | UNSIGNED INT | NOT NULL | Foreign key references SYSTABLE.table_id.
root | INTEGER | NOT NULL |
check_on_commit | CHAR(1) | NOT NULL |
nulls | CHAR(1) | NOT NULL |
role | CHAR(128) | NOT NULL | Unique index.
remarks | LONG VARCHAR |  |
primary_index_id | UNSIGNED INT | NOT NULL |
fk_not_enforced | CHAR(1) | NOT NULL |
hash_limit | SMALLINT | NOT NULL |

A foreign key is a relationship between two tables—the foreign table and the primary table. Every foreign key is defined by one row in SYSFOREIGNKEY and one or more rows in SYSFKCOL. SYSFOREIGNKEY contains general information about the foreign key while SYSFKCOL identifies the columns in the foreign key and associates each column in the foreign key with a column in the primary key of the primary table.

foreign_table_id The table number of the foreign table.

foreign_key_id Each foreign key has a foreign key number that is unique with respect to:

  • The key number of all other foreign keys for the foreign table

  • The key number of all foreign keys for the primary table

  • The index number of all indexes for the foreign table

primary_table_id The table number of the primary table.

root The root identifies the location of the root page of the foreign key in the database file.

check_on_commit (Y/N) Indicates whether INSERT and UPDATE statements should wait until the next COMMIT to check if foreign keys are valid. A foreign key is valid if, for each row in the foreign table, the values in the columns of the foreign key either contain the NULL value or match the primary key values in some row of the primary table.

nulls (Y/N) Indicates whether the columns in the foreign key are allowed to contain the NULL value. Note that this setting is independent of the nulls setting in the columns contained in the foreign key.

role The name of the relationship between the foreign table and the primary table. Unless otherwise specified, the role name will be the same as the name of the primary table. The foreign table cannot have two foreign keys with the same role name.

remarks A comment string.

primary_index_id The index_id of the primary key.

fk_not_enforced (Y/N) Is N if one of the tables is remote.

hash_limit Contains information about physical index representation.


SYSGROUP system table

Column name | Column type | Column constraint | Table constraints
group_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSUSERPERM.user_id.
group_member | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSUSERPERM.user_id.

There is one row in SYSGROUP for every member of every group. This table describes a many-to-many relationship between groups and members. A group may have many members, and a user may be a member of many groups.

group_id The user number of the group.

group_member The user number of a member.


SYSHISTORY system table

Column name | Column type | Column constraint | Table constraints
operation | CHAR(12) | NOT NULL | Primary key.
version | CHAR(15) | NOT NULL | Primary key.
platform | CHAR(50) | NOT NULL | Primary key.
first_time | TIMESTAMP | NOT NULL |
last_time | TIMESTAMP | NOT NULL |
details | VARCHAR(2048) |  |

A new row is added to the SYSHISTORY table each time the database is started with a different version of the software and/or on a different platform. Each software version/platform combination is entered only once in the table.

operation The type of operation performed on the database file. The operation must be one of the following values:

  • INIT Information about when the database was created.

  • UPGRADE Information about when the database was upgraded.

  • START Information about when the database was started using a specific version of the database server on a particular operating system.

  • LAST_START Information about the most recent time the database server was started.

    A LAST_START operation is converted to a START operation when the database is started with a different version of the database server and/or on a different operating system than those values currently stored in the LAST_START row.

version The version and build number of the database server used to carry out the operation.

platform The operating system on which the operation was carried out.

first_time The date and time the database was first started on a particular operating system with a particular version of the software.

last_time The most recent date and time the database was started on a particular operating system with a particular version of the software.

details This column stores information such as command-line options used to start the database server or the capability bits enabled for the database. This information is for use by technical support.


SYSINDEX system table

Column name | Column type | Column constraint | Table constraints
table_id | UNSIGNED INT | NOT NULL | Primary key, unique index. Foreign key references SYSTABLE.
index_id | UNSIGNED INT | NOT NULL | Primary key.
root | INTEGER | NOT NULL |
file_id | SMALLINT | NOT NULL |
"unique" | CHAR(1) | NOT NULL |
creator | UNSIGNED INT | NOT NULL | Foreign key references SYSUSERPERM.user_id.
index_name | CHAR(128) | NOT NULL | Unique index.
hash_limit | SMALLINT | NOT NULL |
index_owner | CHAR(4) | NOT NULL |
index_type | CHAR(4) | NOT NULL |
remarks | LONG, VARCHAR |  |

Each index in the database is described by one row in SYSINDEX. Each column in the index is described by one row in SYSIXCOL.

table_id Uniquely identifies the table to which this index applies.

index_id Each index for one particular table is assigned a unique index number.

root The root identifies the location of the root page of the index in the database file.

file_id The index is completely contained in the file with this file_id (see SYSFILE).

unique Indicates whether the index is a unique index ("Y"), a non-unique index ("N"), or a unique constraint ("U"). A unique index prevents two rows in the indexed table from having the same values in the index columns.

creator The user number of the creator of the index. This user is always the same as the creator of the table identified by table_id.

index_name The name of the index. A table cannot have two indexes with the same name.

index_owner The owner. This field is always USER.

index_type The type. This field is always SA.

remarks A comment string.


SYSINFO system table (deprecated)

Column name | Column type | Column constraint | Table constraints
page_size | INTEGER | NOT NULL |
encryption | CHAR(1) | NOT NULL |
blank_padding | CHAR(1) | NOT NULL |
case_sensitivity | CHAR(1) | NOT NULL |
default_collation | CHAR(10) |  |
database_version | SMALLINT | NOT NULL |
classes_version | CHAR(10) |  |

This table indicates the database characteristics, as defined when the database was created. It always contains only one row.

Note
Use of this table is deprecated. It is recommended that you use the db_property function instead. The following parameter values to db_property can be used to obtain The information in SYSINFO:

  • 'PageSize'

  • 'Encryption'

  • 'BlankPadding'

  • 'CaseSensitive'

  • 'Collation'

  • 'FileVersion'

  • 'JDKVersion'

For more information about The db_property function, see DB_PROPERTY function [System].

page_size The page size specified, in bytes. The default value is 1024.

encryption (Y/N) Indicates whether The database is encrypted.

blank_padding (Y/N) Indicates whether The database was created to use blank padding for string comparisons in The database.

case_sensitivity (Y/N) Indicates whether The database is created as case sensitive. Case sensitivity affects value comparisons, but not table and column name comparisons. For example, if a database is case sensitive, table names such as SYSCATALOG can be specified in either case, but in a case-sensitive database 'abc' = 'ABC' is not true.

default_collation A string corresponding to The collation_label in SYSCOLLATION, which also corresponds to the collation sequence specified with the Initialization utility. The collation sequence is used for all string comparisons, including searches for character strings as well as column and table name comparison.

database_version A small integer value indicating the database format.

classes_version A small string describing the current version of the Java runtime library that is used by this database.


SYSIXCOL system table

Column name | Column type | Column constraint | Table constraints
table_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSCOLUMN. Foreign key references SYSINDEX.
index_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSINDEX.
sequence | SMALLINT | NOT NULL | Primary key.
column_id | UNSIGNED INT | NOT NULL | Foreign key references SYSCOLUMN.
"order" | CHAR(1) | NOT NULL |

Every index has one row in SYSIXCOL for each column in the index.

table_id Identifies the table to which the index applies.

index_id Identifies in which index this column is used. Together, table_id and index_id identify one index described in SYSINDEX.

sequence Each column in an index is assigned a unique number starting at 0. The order of these numbers determines the relative significance of the columns in the index. The most important column has sequence number 0.

column_id The column number identifies which column is indexed. Together, table_id and column_id identify one column described in SYSCOLUMN.

order (A/D) Indicates whether this column in the index is kept in ascending or descending order.


SYSJAR system table

Column name | Column type | Column constraint | Table constraints
jar_id | INTEGER | NOT NULL | Primary key.
creator | UNSIGNED INT | NOT NULL |
jar_name | LONG VARCHAR | NOT NULL | Unique index.
jar_file | LONG VARCHAR |  |
create_time | TIMESTAMP | NOT NULL |
update_time | TIMESTAMP | NOT NULL |
remarks | LONG VARCHAR |  |

jar_id A field containing the id of the JAR file.

creator The user number of the creator of the JAR file.

jar_name The name of the JAR file.

jar_file The file name of the JAR file.

create_time The time the JAR file was created.

update_time The time the JAR file was last updated.

remarks A comment field.


SYSJARCOMPONENT system table

Column name | Column type | Column constraint | Table constraints
component_id | INTEGER | NOT NULL | Primary key.
jar_id | INTEGER |  | Foreign key references SYSJAR.
component_name | LONG VARCHAR |  |
component_type | CHAR(1) |  |
create_time | TIMESTAMP | NOT NULL |
contents | LONG BINARY |  |
remarks | LONG VARCHAR |  |

component_id The primary key containing the id of the component.

jar_id A field containing the ID number of the JAR.

component_name The name of the component.

component_type The type of the component.

create_time A field containing the creation time of the component.

contents The byte code of the JAR file.

remarks A comment field.


SYSJAVACLASS system table

Column name | Column type | Column constraint | Table constraints
class_id | INTEGER | NOT NULL | Primary key.
replaced_by | INTEGER |  | Foreign key references SYSJAVACLASSES. class_id.
creator | UNSIGNED INT | NOT NULL | Foreign key references SYSUSERPERM.user_id.
jar_id | INTEGER |  |
type_id | SMALLINT |  | Foreign key references SYSUSERTYPE.
class_name | LONG VARCHAR | NOT NULL |
public | CHAR(1) | NOT NULL |
component_id | INTEGER |  | Foreign key references SYSJARCOMPONENT.
create_time | TIMESTAMP | NOT NULL |
update_time | TIMESTAMP | NOT NULL |
class_descriptor | LONG BINARY |  |
remarks | LONG VARCHAR |  |

The SYSJAVACLASS system table contains all information related to Java classes.

class_id This field contains the id of the java class. Also the primary key for the table.

replaced_by A field that references the primary key field, class_id.

creator The user number of the creator of the class.

jar_id The id of the JAR file from which the class came.

type_id The id of the user type.

class_name The name of the Java class.

public Indicates whether the class is public (Y) or private (N).

component_id The id of the component in SYSJARCOMPONENT.

create_time Contains the creation time of the class.

update_time Contains the last update time of the class.

class_descriptor Not used.

remarks Contains a comment string.


SYSLOGIN system table

Column name | Column type | Column constraint | Table constraints
integrated_login_id | CHAR(128) | NOT NULL | Primary key.
login_uid | UNSIGNED INT | NOT NULL | Foreign key references SYSUSERPERM.user_id.
remarks | LONG VARCHAR |  |

This table contains all the User Profile names that can be used to connect to the database using an integrated logon. As a security measure, only users with DBA authority can view the contents of this table.

integrated_login_id A string value containing the User Profile name that is used to map to a user ID in the database. When a user successfully logs on using this User Profile name, and the database is enabled to accept integrated logons, the user can connect to the database without providing a user ID or password.

login_uid A foreign key to the system table SYSUSERPERM.

remarks A comment string


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Tables

SYSOPTBLOCK system table

This table is reserved for system use.


SYSOPTION system table

Column name | Column type | Column constraint | Table constraints
user_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSUSERPERM.
"option" | CHAR(128) | NOT NULL | Primary key.
"setting" | LONG VARCHAR | NOT NULL |

Options settings are stored in the SYSOPTION table by the SET command. Each user can have their own setting for each option. In addition, settings for the PUBLIC user ID define the default settings to be used for user IDs that do not have their own setting.

user_id The user number to whom this option setting applies.

option The name of the option.

setting The current setting for the named option.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Tables

SYSOPTJOINSTRATEGY system table

This table is reserved for system use.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Tables

SYSOPTORDER system table

This table is reserved for system use.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Tables

SYSOPTQUANTIFIER system table

This table is reserved for system use.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Tables

SYSOPTREQUEST system table

This table is reserved for system use.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Tables

SYSOPTREWRITE system table

This table is reserved for system use.


SYSOPTSTAT system table

This table stores information about the cost model. It is reserved for system use.


SYSPROCEDURE system table

Column name | Column type | Column constraint | Table constraints
proc_id | UNSIGNED INT | NOT NULL | Primary key.
creator | UNSIGNED INT | NOT NULL | Unique index on this column and proc_name. Foreign key references SYSUSERPERM.user_id.
proc_name | CHAR(128) | NOT NULL | Unique index on this column and creator.
proc_defn | LONG VARCHAR |  |
remarks | LONG VARCHAR |  |
replicate | CHAR(1) | NOT NULL |
srvid | INTEGER |  | Foreign key references SYSSERVERS.
source | LONG VARCHAR |  |
avg_num_rows | FLOAT |  |
avg_cost | FLOAT |  |
stats | LONG BINARY |  |

Each procedure in the database is described by one row in SYSPROCEDURE.

proc_id Each procedure is assigned a unique number (the procedure number), which is the primary key for SYSPROCEDURE.

creator This user number identifies the owner of the procedure. The name of the user can be found by looking in SYSUSERPERM.

proc_name The name of the procedure. One creator cannot have two procedures with the same name.

proc_defn The command that was used to create the procedure.

remarks A comment string.

replicate (Y/N) Indicates whether the procedure is a primary data source in a Replication Server installation.

srvid If the procedure is a proxy for a procedure on a remote database server, indicates the remote server.

source This column contains the original source for the procedure if the preserve_source_format option is ON. It is used to maintain the appearance of the original text. For more information, see PRESERVE_SOURCE_FORMAT option [database].

avg_num_rows Information collected for use in query optimization when the procedure appears in the FROM clause.

avg_cost Information collected for use in query optimization when the procedure appears in the FROM clause.

stats Information collected for use in query optimization when the procedure appears in the FROM clause.


SYSPROCPARM system table

Column name | Column type | Column constraint | Table constraint
proc_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSPROCEDURE.
parm_id | SMALLINT | NOT NULL | Primary key.
parm_type | SMALLINT | NOT NULL |
parm_mode_in | CHAR(1) | NOT NULL |
parm_mode_out | CHAR(1) | NOT NULL |
domain_id | SMALLINT | NOT NULL | Foreign key references SYSDOMAIN.
width | SMALLINT | NOT NULL |
scale | SMALLINT | NOT NULL |
parm_name | CHAR(128) | NOT NULL |
remarks | LONG VARCHAR |  |
"default" | LONG VARCHAR |  |
user_type | INTEGER |  |

Each parameter to a procedure in the database is described by one row in SYSPROCPARM.

proc_id Uniquely identifies the procedure to which this parameter belongs.

parm_id Each procedure starts numbering parameters at 1. The order of parameter numbers corresponds to the order in which they were defined.

For functions, the first parameter has the name of the function and represents the return value for the function.

parm_type The type of parameter will be one of the following:

  • 0 Normal parameter (variable)

  • 1 Result variable - used with a procedure that return result sets

  • 2 SQLSTATE error value

  • 3 SQLCODE error value

  • 4 Return value from function

parm_mode_in (Y/N) Indicates whether this parameter supplies a value to the procedure (IN or INOUT parameters).

parm_mode_out (Y/N) Indicates whether this parameter returns a value from the procedure (OUT or INOUT parameters) or columns in the RESULT clause.

domain_id Identifies the data type for the parameter, by the data type number listed in the SYSDOMAIN table.

width Contains the length of a string parameter, the precision of a numeric parameter, or the number of bytes of storage for any other data type.

scale The number of digits after the decimal point for numeric data type parameters, and zero for all other data types.

parm_name The name of the procedure parameter.

remarks A comment string.

default Unused.

user_type The user type of the parameter.


SYSPROCPERM system table

Column name | Column type | Column constraint | Table constraints
proc_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSPROCEDURE.
grantee | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSUSERPERM.user_id.

Only users who have been granted permission can call a procedure. Each row of the SYSPROCPERM table corresponds to one user granted permission to call one procedure.

proc_id The procedure number uniquely identifies the procedure for which permission has been granted.

grantee The user number of the user ID receiving the permission.


SYSPUBLICATION system table

Column name | Column type | Column constraint | Table constraints
publication_id | UNSIGNED INT | NOT NULL | Primary key.
creator | UNSIGNED INT | NOT NULL | Unique index. Foreign key references SYSUSERPERM.user_id.
publication_name | CHAR(128) | NOT NULL | Unique index.
remarks | LONG VARCHAR |  |
type | CHAR(1) | NOT NULL |

Each row describes a SQL Remote or MobiLink publication.

publication_id A unique identifying number for the publication.

creator The owner of the publication.

publication_name The name of the publication.

remarks Descriptive comments.

type This column is deprecated.


SYSREMOTEOPTION system table

toggle Function

Each row describes the values of a SQL Remote message link parameter.

Columns
Column | Data type | Column Constraint | Table constraints
option_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references to SYSREMOTEOPTIONTYPE.
user_id | UNSIGNED INT | NOT NULL | Primary key.
"setting" | VARCHAR(255) | NOT NULL |

Some columns in this table contain potentially sensitive data. For that reason, access to this table is restricted to users with DBA authority. The SYSREMOTEOPTION2 view provides public access to the data in this table except for the potentially sensitive columns.

option_id An identification number for the message link parameter.

user_id The user ID for which the parameter is set.

setting The value of the message link parameter.


SYSREMOTEOPTIONTYPE system table

toggle Function

Each row describes one of the SQL Remote message link parameters.

Columns
Column | Data type | Column constraint | Table constraints
option_id | UNSIGNED INT | NOT NULL | Primary key.
type_id | UNSIGNED INT | NOT NULL | Foreign key references SYSREMOTETYPE.
"option" | VARCHAR(128) | NOT NULL |

option_id An identification number for the message link parameter.

type_id An identification number for the message type that uses this parameter.

option The name of the message link parameter.


SYSREMOTETYPE system table

Column name | Column type | Column constraint | Table constraints
type_id | SMALLINT | NOT NULL | Primary key.
type_name | CHAR(128) | NOT NULL | Unique index.
publisher_address | LONG VARCHAR | NOT NULL |
remarks | LONG VARCHAR |  |

The SYSREMOTETYPE system table contains information about SQL Remote.

type_id Identifies which of the message systems supported by SQL Remote is to be used to send messages to this user.

type_name The name of the message system supported by SQL Remote.

publisher_address The address of the remote database publisher.

remarks Descriptive comments.


SYSREMOTEUSER system table

Column name | Column type | Column constraint | Table constraints
user_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSUSERPERM.
consolidate | CHAR(1) | NOT NULL |
type_id | SMALLINT | NOT NULL | Foreign key references SYSREMOTETYPE.
address | LONG VARCHAR | NOT NULL |
frequency | CHAR(1) | NOT NULL | Unique index.
send_time | TIME |  | Unique index.
log_send | NUMERIC(20,0) | NOT NULL |
time_sent | TIMESTAMP |  |
log_sent | NUMERIC(20,0) | NOT NULL |
confirm_sent | NUMERIC(20,0) | NOT NULL |
send_count | INTEGER | NOT NULL |
resend_count | INTEGER | NOT NULL |
time_received | TIMESTAMP |  |
log_received | NUMERIC(20,0) | NOT NULL |
confirm_received | NUMERIC(20,0) |  |
receive_count | INTEGER | NOT NULL |
rereceive_count | INTEGER | NOT NULL |

Each row describes a user ID with REMOTE permissions (a subscriber), together with the status of SQL Remote messages that were sent to and from that user.

user_id The user number of the user with REMOTE permissions.

consolidate (Y/N) Indicates whether the user was granted CONSOLIDATE permissions (Y) or REMOTE permissions (N).

type_id Identifies which of the message systems supported by SQL Remote is used to send messages to this user.

address The address to which SQL Remote messages are to be sent. The address must be appropriate for the address_type.

frequency How frequently SQL Remote messages are sent.

send_time The next time messages are to be sent to this user.

log_send Messages are sent only to subscribers for whom log_send is greater than log_sent.

time_sent The time the most recent message was sent to this subscriber.

log_sent The log offset for the most recently sent operation.

confirm_sent The log offset for the most recently confirmed operation from this subscriber.

send_count How many SQL Remote messages have been sent.

resend_count Counter to ensure that messages are applied only once at the subscriber database.

time_received The time when the most recent message was received from this subscriber.

log_received The log offset in the subscriber's database for the operation that was most recently received at the current database.

confirm_received The log offset in the subscriber's database for the most recent operation for which a confirmation message has been sent.

receive_count How many messages have been received.

rereceive_count Counter to ensure that messages are applied only once at the current database.


SYSSCHEDULE system table

Column name | Column type | Column constraint | Table constraints
event_id | INTEGER | NOT NULL | Primary key. Foreign key references SYSEVENT.
sched_name | VARCHAR(128) | NOT NULL | Primary key.
recurring | TINYINT | NOT NULL |
start_time | TIME | NOT NULL |
stop_time | TIME |  |
start_date | DATE |  |
days_of_week | TINYINT |  |
days_of_month | UNSIGNED INT |  |
interval_units | CHAR(10) |  |
interval_amt | INTEGER |  |

Each row in SYSSCHEDULE describes the times at which an event is to fire, as specified by the SCHEDULE clause of CREATE EVENT.

event_ id The unique number assigned to each event.

sched_name The name associated with a schedule.

recurring (0/1) Indicates if the schedule is repeating.

start_time The schedule start time.

stop_time The schedule stop time if BETWEEN was used.

start_date The first date on which the event is scheduled to execute.

days_of_week A bit mask indicating the days of the week on which the event is scheduled:

  • x01 = Sunday

  • x02 = Monday

  • x04 = Tuesday

  • x08 = Wednesday

  • x10 = Thursday

  • x20 = Friday

  • x40 = Saturday

days_of_month A bit mask indicating the days of the month on which the event is scheduled:

  • x01 = first day

  • x02 = second day

  • x40000000 = 31st day

  • x80000000 = last day of month

interval_units The interval unit specified by EVERY:

  • HH = hours

  • NN = minutes

  • SS = seconds

interval_amt The period specified by EVERY.


SYSSERVERS system table

Column name | Column type | Column constraint | Table Constraints
srvid | INTEGER | NOT NULL | Primary key.
srvname | VARCHAR(128) | NOT NULL |
srvclass | LONG VARCHAR | NOT NULL |
srvinfo | LONG VARCHAR |  |
srvreadonly | CHAR(1) | NOT NULL |

Each row describes a remote server.

srvid An identifier for the remote server.

srvname The name of the remote server.

srvclass The server class, as specified in the CREATE SERVER statement.

srvinfo Server information.

srvreadonly Y if the server is read only, and N otherwise.


SYSSQLSERVERTYPE system table

Column name | Column type | Column constraint | Table constraints
ss_user_type | SMALLINT | NOT NULL | Primary key.
ss_domain_id | SMALLINT | NOT NULL |
ss_type_name | VARCHAR (30) | NOT NULL |
primary_sa_domain_id | SMALLINT | NOT NULL |
primary_sa_user_type | SMALLINT |  |

This table contains information relating to compatibility with Adaptive Server Enterprise.

ss_user_type The Adaptive Server Enterprise user type.

ss_domain_id The Adaptive Server Enterprise domain id.

ss_type_name Contains the Adaptive Server Enterprise type name.

primary_sa_domain_id The Adaptive Server Anywhere primary domain id.

primary_sa_user_type A UNSIGNED INT field containing the Adaptive Server Anywhere primary user type.


SYSSUBSCRIPTION system table

Column name | Column type | Column constraint | Table constraints
publication_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSPUBLICATION.
user_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSUSERPERM.
subscribe_by | CHAR(128) | NOT NULL | Primary key.
created | NUMERIC(20,0) | NOT NULL |
started | NUMERIC(20,0) |  |

Each row describes a subscription from one user ID (which must have REMOTE permissions) to one publication.

publication_id The identifier for the publication to which the user ID is subscribed.

user_id The user number that is subscribed to the publication.

subscribe_by The value of the SUBSCRIBE BY expression, if any, for the subscription.

created The offset in the transaction log at which the subscription was created.

started The offset in the transaction log at which the subscription was started.


SYSSYNC system table

Column name | Column type | Column constraint | Table constraints
sync_id | UNSIGNED INT | NOT NULL | Primary key.
type | CHAR(1) | NOT NULL |
publication_id | UNSIGNED INT |  | Foreign key references SYSPUBLICATION.
progress | NUMERIC(20,0) |  |
site_name | CHAR(128) |  |
option | LONG VARCHAR |  |
server_connect | LONG VARCHAR |  |
server_conn_type | LONG VARCHAR |  |
last_download_time | TIMESTAMP |  |
last_upload_time | TIMESTAMP | NOT NULL default 'jan-1-1900' |
created | NUMERIC( 20, 0) |  |
log_sent | NUMERIC(20,0) |  |
generation_number | INTEGER | NOT NULL default 0 |
extended_state | VARCHAR(1024) | NOT NULL default '' |

This table contains information relating to MobiLink synchronization. Some columns in this table contain potentially sensitive data. For that reason, access to this table is restricted to users with DBA authority. The SYSSYNC2 view provides public access to the data in this table except for the potentially sensitive columns.

sync_id A SMALLINT field uniquely identifying the row.

type A CHAR(1) field describing the type of synchronization object: 'D' means definition, 'T' means template, and 'S' means site.

publication_id A publication_id found in the SYSPUBLICATION table.

progress The log offset of the last successful upload.

site_name A MobiLink user name.

option Synchronization options.

server_connect The address or URL of the MobiLink synchronization server.

server_conn_type The communication protocol, such as TCP/IP, to use when synchronizing.

last_download_time Indicates the last time a download stream was received from the MobiLink synchronization server.

last_upload_time Indicates the last time (measured at the MobiLink synchronization server) that information was successfully uploaded.

created The log offset at which the subscription was created.

log_sent The log progress up to which information has been uploaded. It is not necessary that an acknowledgement of the upload be received for the entry in this column to be updated.

generation_number For file-base downloads, the last generation number received for this subscription.

extended_state Reserved for internal use.


SYSTABLE system table

Column name | Column type | Column constraint | Table constraints
table_id | UNSIGNED INT | NOT NULL | Primary key.
file_id | SMALLINT | NOT NULL | Foreign key references SYSFILE.
count | UNSIGNED BIGINT | NOT NULL |
first_page | INTEGER | NOT NULL |
last_page | INTEGER | NOT NULL |
primary_root | INTEGER | NOT NULL |
creator | UNSIGNED INT | NOT NULL | Unique index. Foreign key references SYSUSERPERM.user_id.
first_ext_page | INTEGER | NOT NULL |
last_ext_page | INTEGER | NOT NULL |
table_page_count | INTEGER | NOT NULL |
ext_page_count | INTEGER | NOT NULL |
table_name | CHAR(128) | NOT NULL | Unique index.
table_type | CHAR(10) | NOT NULL |
view_def | LONG VARCHAR |  |
remarks | LONG VARCHAR |  |
replicate | CHAR(1) | NOT NULL |
existing_obj | CHAR(1) |  |
remote_location | LONG VARCHAR |  |
remote_objtype | CHAR(1) |  |
srvid | INTEGER |  | Foreign key references SYSSERVERS.
server_type | CHAR(4) | NOT NULL |
primary_hash_limit | SMALL INT | NOT NULL |
page_map_start | INTEGER | NOT NULL |
source | LONG VARCHAR |  |

Each row of SYSTABLE describes one table or view in the database.

table_id Each table or view is assigned a unique number (the table number) which is the primary key for SYSTABLE.

file_id Indicates which database file contains the table.

count The number of rows in the table is updated during each successful checkpoint. This number is used by Adaptive Server Anywhere when optimizing database access. The count is always 0 for a view.

first_page Each database is divided into a number of fixed-size pages. This value identifies the first page that contains information for this table, and is used internally to find the start of this table. The first_page is always 0 for a view.

last_page The last page that contains information for this table. The last_page is always 0 for a view. For global temporary tables, 0 indicates that the table was created using ON COMMIT PRESERVE ROWS while 1 indicates that the table was created using ON COMMIT DELETE ROWS.

primary_root The primary_root locates the root page of the index for the primary key for the table. It will be 0 for a view and for a table with no primary key.

creator The user number of the owner of the table or view.

first_ext_page The first page used for storing row extensions and blobs.

last_ext_page The last page used for storing row extensions and blobs. The pages are maintained as a doubly-linked list.

table_page_count The total number of main pages used by this table.

ext_page_count The total number of extension (blob) pages used by this table.

table_name The name of the table or view. One creator cannot have two tables or views with the same name.

table_type This column is BASE for base tables, VIEW for views, and GBL TEMP for global temporary tables. No entry is created for local temporary tables.

view_def For a view, this column contains the CREATE VIEW command that was used to create the view.

remarks A comment string.

replicate (Y/N) Indicates whether the table is a primary data source in a Replication Server installation.

existing_obj (Y/N) Indicates whether the table previously existed or not.

remote_location Indicates the storage location of the remote object.

remote_objtype Indicates the type of remote object: T if table; V if view; R if rpc; B if JavaBean.

srvid The unique ID for the server if this is a proxy table.

server_type The location of the data for the table. It is either SA or OMNI.

primary_hash_limit The hash size for the primary key index for this table.

page_map_start The start of the page map maintained for this table. Page maps are used to facilitate blocked I/O during sequential scans.

source This column contains the original source for a view if the preserve_source_format option is ON. It is used to maintain the appearance of the original text. For more information, see PRESERVE_SOURCE_FORMAT option [database].


SYSTABLEPERM system table

Column name | Column type | Column constraint | Table constraints
stable_id | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSTABLE.table_id.
grantee | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSUSERPERM.user_id.
grantor | UNSIGNED INT | NOT NULL | Primary key. Foreign key references SYSUSERPERM.user_id.
ttable_id | UNSIGNED INT | NOT NULL | Foreign key references SYSTABLE.table_id.
selectauth | CHAR(1) | NOT NULL |
insertauth | CHAR(1) | NOT NULL |
deleteauth | CHAR(1) | NOT NULL |
updateauth | CHAR(1) | NOT NULL |
updatecols | CHAR(1) | NOT NULL |
alterauth | CHAR(1) | NOT NULL |
referenceauth | CHAR(1) | NOT NULL |

Permissions given by the GRANT command are stored in SYSTABLEPERM. Each row in this table corresponds to one table, one user ID granting the permission (grantor) and one user ID granted the permission (grantee).

There are several types of permission that can be granted. Each permission can have one of the following three values.

  • N No, the grantee has not been granted this permission by the grantor.

  • Y Yes, the grantee has been given this permission by the grantor.

  • G The grantee has been given this permission and can grant the same permission to another user (with grant options).

toggle Permissions
The grantee might have been given permission for the same table by another grantor. If so, this information would be recorded in a different row of SYSTABLEPERM.

stable_id The table number of the table or view to which the permissions apply.

grantor The user number of the user ID granting the permission.

grantee The user number of the user ID receiving the permission.

ttable_id In the current version of Adaptive Server Anywhere, this table number is always the same as stable_id.

selectauth (Y/N/G) Indicates whether SELECT permission has been granted.

insertauth (Y/N/G) Indicates whether INSERT permission has been granted.

deleteauth (Y/N/G) Indicates whether DELETE permission has been granted.

updateauth (Y/N/G) Indicates whether UPDATE permission has been granted for all columns in the table.

updatecols (Y/N) Indicates whether UPDATE permission has only been granted for some of the columns in the table. If updatecols has the value Y, there will be one or more rows in SYSCOLPERM granting update permission for the columns in this table.

alterauth (Y/N/G) Indicates whether ALTER permission has been granted.

referenceauth (Y/N/G) Indicates whether REFERENCE permission has been granted.


SYSTRIGGER system table

Column name | Column type | Column constraint | Table constraints
trigger_id | UNSIGNED INT | NOT NULL | Primary key.
table_id | UNSIGNED INT | NOT NULL | Foreign key references SYSTABLE.table_id.
event | CHAR(1) | NOT NULL | Unique.
trigger_time | CHAR(1) | NOT NULL | Unique.
trigger_order | SMALLINT |  | Unique.
foreign_table_id | UNSIGNED INT |  | Unique. Foreign key references SYSFOREIGNKEY.
foreign_key_id | SMALLINT |  | Unique. Foreign key references SYSFOREIGNKEY.
referential_action | CHAR(1) |  |
trigger_name | CHAR(128) |  | Unique.
trigger_defn | LONG VARCHAR | NOT NULL |
remarks | LONG VARCHAR |  |
source | LONG VARCHAR |  |

Each trigger in the database is described by one row in SYSTRIGGER. The table also contains triggers that are automatically created for foreign key definitions which have a referential triggered action (such as ON DELETE CASCADE).

trigger_id Each trigger is assigned a unique number (the trigger number), which is the primary key for SYSTRIGGER.

table_id The table number uniquely identifies the table to which this trigger belongs.

event The event or events that cause the trigger to fire. This single-character value corresponds to the trigger event that was specified when the trigger was created.

  • A INSERT, DELETE

  • B INSERT, UPDATE

  • C UPDATE

  • D DELETE

  • E DELETE, UPDATE

  • I INSERT

  • U UPDATE

  • M INSERT, DELETE, UPDATE

trigger_time The time at which the trigger will fire. This single-character value corresponds to the trigger time that was specified when the trigger was created.

  • A AFTER

  • B BEFORE

trigger_order The order in which the trigger will fire. This determines the order that triggers are fired when there are triggers of the same type (insert, update, or delete) that fire at the same time (before or after).

foreign_table_id The table number of the table containing a foreign key definition which has a referential triggered action (such as ON DELETE CASCADE).

foreign_key_id The foreign key number of the foreign key for the table referenced by foreign_table_id.

referential_action The action defined by a foreign key. This single-character value corresponds to the action that was specified when the foreign key was created.

  • C CASCADE

  • D SET DEFAULT

  • N SET NULL

  • R RESTRICT

trigger_name The name of the trigger. One table cannot have two triggers with the same name.

trigger_defn The command that was used to create the trigger.

remarks A comment string.

source This column contains the original source for the trigger if the preserve_source_format option is ON. It is used to maintain the appearance of the original text. For more information, see PRESERVE_SOURCE_FORMAT option [database].


SYSTYPEMAP system table

Column name | Column type | Column constraint | Table constraints
ss_user_type | SMALLINT | NOT NULL |
sa_domain_id | SMALLINT | NOT NULL | Foreign key references SYSDOMAIN.
sa_user_type | SMALLINT |  |
nullable | CHAR(1) |  |

The SYSTYPEMAP system table contains the compatibility mapping values for the SYSSQLSERVERTYPE system table.

ss_user_type Contains the Adaptive Server Enterprise user type.

sa_domain_id Contains the Adaptive Server Anywhere domain_id.

sa_user_type Contains the Adaptive Server Anywhere user type.

nullable This field describes whether or not the type can be null.


SYSUSERMESSAGES system table

Column name | Column type | Column constraint | Table constraints
error | INTEGER | NOT NULL | Unique.
uid | UNSIGNED INT | NOT NULL |
description | VARCHAR(255) | NOT NULL |
langid | SMALLINT | NOT NULL | Unique.

Each row holds a user-defined message for an error condition.

error A unique identifying number for the error condition.

uid The user number that defined the message.

description The message corresponding to the error condition.

langid Reserved.


SYSUSERPERM system table

Column name | Column type | Column constraint | Table constraints
user_id | UNSIGNED INT | NOT NULL | Primary key.
user_name | CHAR(128) | NOT NULL | Unique index.
password | BINARY(36) |  |
resourceauth | CHAR(1) | NOT NULL |
dbaauth | CHAR(1) | NOT NULL |
scheduleauth | CHAR(1) | NOT NULL |
publishauth | CHAR(1) | NOT NULL |
remotedbaauth | CHAR(1) | NOT NULL |
user_group | CHAR(1) | NOT NULL |
remarks | LONG VARCHAR |  |
DBA permissions required
SYSUSERPERM contains passwords, so DBA permissions are required to SELECT from it.

Each row of SYSUSERPERM describes one user ID.

user_id Each new user ID is assigned a unique number, which is the primary key for SYSUSERPERM.

user_name A string containing a unique name for the user ID.

password The password for the user ID. The password contains the NULL value for the special user IDs SYS, PUBLIC, and dbo. This prevents anyone from connecting to these user IDs.

resourceauth (Y/N) Indicates whether the user has RESOURCE authority. Resource authority is required to create tables.

dbaauth (Y/N) Indicates whether the user has DBA (database administrator) authority. DBA authority is very powerful, and should be restricted to as few user IDs as possible for security purposes.

scheduleauth (Y/N) Indicates whether the user has SCHEDULE authority. This is currently not used.

publishauth (Y/N) Indicates whether the user has the SQL Remote publisher authority.

remotedbaauth (Y/N) Indicates whether the user has the SQL Remote remote DBA authority.

user_group (Y/N) Indicates whether the user is a group.

remarks A comment string.

When a database is initialized, the following user IDs are created:

  • SYS The creator of all the system tables.

  • PUBLIC A special user ID used to record PUBLIC permissions.

  • DBA The database administrator user ID is the only usable user ID in an initialized system. The initial password is SQL.

  • dbo The owner of many of the system stored procedures and Transact-SQL capability views.

There is no way to connect to the SYS, PUBLIC, or dbo user IDs.


SYSUSERTYPE system table

Column name | Column type | Column constraint | Table constraints
type_id | SMALLINT | NOT NULL | Primary key.
creator | UNSIGNED INT | NOT NULL | Foreign key references SYSUSERPERM.user_id.
domain_id | SMALLINT | NOT NULL | Foreign key references SYSDOMAIN.
nulls | CHAR(1) | NOT NULL |
width | SMALLINT | NOT NULL |
scale | SMALLINT | NOT NULL |
type_name | CHAR(128) | NOT NULL | Unique.
"default" | LONG VARCHAR |  |
"check" | LONG VARCHAR |  |
format_str | CHAR(128) |  |
super_type_id | SMALLINT |  | Foreign key references SYSUSERTYPE.type_id.

Each row holds a description of a user-defined data type.

type_id A unique identifying number for the user-defined data type.

creator The user number of the owner of the data type.

domain_id The data type on which this user defined data type is based, indicated by a data type number listed in the SYSDOMAIN table.

nulls (Y/N/U) Indicates whether the user-defined data type allows nulls. A value of U indicates that nullability is unspecified.

width The length of a string column, the precision of a numeric column, or the number of bytes of storage for any other data type.

scale The number of digits after the decimal point for numeric data type columns, and zero for all other data types.

type_name The name for the data type.

default The default value for the data type.

check The CHECK condition for the data type.

format_str Currently unused.


SYSWEBSERVICE system table

Column name | Column type | Column constraint | Table constraints
service_id | UNSIGNED INT | NOT NULL | Primary key.
service_name | CHAR(128) | NOT NULL |
service_type | VARCHAR(40) | NOT NULL |
auth_required | CHAR(1) | NOT NULL |
secure_required | CHAR(1) | NOT NULL |
url_path | CHAR(1) | NOT NULL |
user_id | UNSIGNED INT |  |
parameter | VARCHAR(250) |  |
statement | LONG VARCHAR |  |
remarks | LONG VARCHAR |  |

Each row holds a description of a web service.

service_id A unique identifying number for the web service.

service_name The name assigned to the web service.

service_type The type of the service; for example, RAW, HTTP, XML, SOAP, or DISH.

auth_required (Y/N) Indicates whether all requests must contain a valid user name and password.

secure_required (Y/N) Indicates whether insecure connections, such as HTTP, are to be accepted, or only secure connections, such as HTTPS.

url_path Controls the interpretation of URLs.

user_id If authentication is enabled, identifies the user, or group of users, that have permission to use the service. If authentication is disabled, specifies the account to use when processing requests.

parameter A prefix that identifies the SOAP services to be included in a DISH service.

statement A SQL statement that is always executed in response to a request. If NULL, arbitrary statements contained in each request are executed instead. Ignored for services of type DISH.


Other system tables

Following is information about system tables used by Java in the database and SQL Remote.


Java system tables

The system tables that are used for Java in the database are listed below. Foreign key relations between tables are indicated by arrows: the arrow leads from the foreign table to the primary table.

Java system tables: SYSJAVACLASS, SYSJARCOMPONENT, AND SYSJAR.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Tables

Other system tables

MobiLink system tables

For information about the MobiLink system tables, see MobiLink System Tables.


SQL Remote system tables

For information about the SQL Remote system tables, see SQL Remote system tables.


System Views

About this chapter

This chapter lists predefined views for the system tables.


Introduction

The system tables described in System Tables use numbers to identify tables, user IDs, and so forth. While this is efficient for internal use, it makes these tables difficult for people to interpret. A number of predefined system views are provided that present the information in the system tables in a more readable format.

System view definitions
SYSARTICLECOLS system view
SYSARTICLES system view
SYSCAPABILITIES system view
SYSCATALOG system view
SYSCOLAUTH system view
SYSCOLSTATS system view
SYSCOLUMNS system view
SYSFOREIGNKEYS system view
SYSGROUPS system view
SYSINDEXES system view
SYSOPTIONS system view
SYSOPTORDERS system view
SYSOPTPLANS system view
SYSOPTSTRATEGIES system view
SYSPROCAUTH system view
SYSPROCPARMS system view
SYSPUBLICATIONS system view
SYSREMOTEOPTION2 system view
SYSREMOTEOPTIONS system view
SYSREMOTETYPES system view
SYSREMOTEUSERS system view
SYSSUBSCRIPTIONS system view
SYSSYNCDEFINITIONS system view (deprecated)
SYSSYNCPUBLICATIONDEFAULTS system view
SYSSYNC2 system view
SYSSYNCS system view
SYSSYNCSUBSCRIPTIONS system view
SYSSYNCUSERS system view
SYSTABAUTH system view
SYSTRIGGERS system view
SYSUSERAUTH system view
SYSUSERLIST system view
SYSUSEROPTIONS system view
SYSUSERPERMS system view
SYSVIEWS system view


System view definitions

Detailed information about system views, including the view definition, is available in Sybase Central:

  • To view system views, right-click a connected database, choose Filter Objects by Owner, and select SYS.

  • Open the Views folder for the database.

  • You can see the view definition by selecting the view in the left pane and then clicking the SQL tab in the right pane. To display the data, open the View folder in the left pane and select a view. In the right pane, click the Data tab.


SYSARTICLECOLS system view

View name | Base table | Remarks
SYSARTICLECOLS | SYSARTICLECOL system table |


SYSARTICLES system view

View name | Base table | Remarks
SYSARTICLES | SYSARTICLE system table |


SYSCAPABILITIES system view

View name | Base tables | Remarks
SYSCAPABILITIES | SYSCAPABILITY system table SYSCAPABILITYNAME system table |


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Views

Introduction

SYSCATALOG system view

View name | Base table | Remarks
SYSCATALOG | SYSTABLE system table |


SYSCOLAUTH system view

View name | Base table | Remarks
SYSCOLAUTH | SYSCOLPERM system table | Presents column update information from SYSCOLPERM in a more readable format.


SYSCOLSTATS system view

View name | Base table | Remarks
SYSCOLSTATS | SYSCOLSTAT system table |


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Views

Introduction

SYSCOLUMNS system view

View name | Base table | Remarks
SYSCOLUMNS | SYSCOLUMN system table |


SYSFOREIGNKEYS system view

View name | Base tables | Remarks
SYSFOREIGNKEYS | SYSFOREIGNKEY system table SYSFKCOL system table |


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Views

Introduction

SYSGROUPS system view

View name | Base table | Remarks
SYSGROUPS | SYSGROUP system table |


SYSINDEXES system view

View name | Base tables | Remarks
SYSINDEXES | SYSINDEX system table SYSIXCOL system table |


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Views

Introduction

SYSOPTIONS system view

View name | Base table | Remarks
SYSOPTIONS | SYSOPTION system table |


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Views

Introduction

SYSOPTORDERS system view

This view is reserved for system use.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Views

Introduction

SYSOPTPLANS system view

This view is reserved for system use.


Web Links Browse Collapse Expand PDF Previous Next

ASA SQL Reference

System Views

Introduction

SYSOPTSTRATEGIES system view

This view is reserved for system use.


SYSPROCAUTH system view

View name | Base table | Remarks
SYSPROCAUTH | SYSPROCPERM system table | Presents procedure permissions information from SYSPROCPERM in a more readable format.


SYSPROCPARMS system view

View name | Base table | Remarks
SYSPROCPARMS | SYSPROCPARM system table | Presents the procedure parameters from SYSPROCPARM in a more readable format.


SYSPUBLICATIONS system view

View name | Base tables | Remarks
SYSPUBLICATIONS | SYSUSERPERM system table SYSPUBLICATION system table | Presents the user name from the SYSUSERPERM table for all creators and displays the publication name and remarks from the SYSPUBLICATION table in a more readable format.


SYSREMOTEOPTION2 system view

View name | Base tables | Remarks
SYSREMOTEOPTION2 | SYSREMOTEOPTION system table See the SYSREMOTEOPTIONTYPE system table | Presents the columns from SYSREMOTEOPTION and SYSREMOTEOPTIONTYPE that do not contain sensitive data in a more readable format.


SYSREMOTEOPTIONS system view

View name | Base tables | Remarks
SYSREMOTEOPTIONS | SYSREMOTEOPTION system table For more information see SYSREMOTEOPTIONTYPE system table | Some columns in this view contain potentially sensitive data. For that reason, access to this view is restricted to users with DBA authority. The SYSREMOTEOPTION2 view provides public access to the insensitive data.


SYSREMOTETYPES system view

View name | Base table | Remarks
SYSREMOTETYPES | SYSREMOTETYPE system table | Presents the remote types from the SYSREMOTETYPE table.


SYSREMOTEUSERS system view

View name | Base table | Remarks
SYSREMOTEUSERS | SYSREMOTEUSER system table |


SYSSUBSCRIPTIONS system view

View name | Base table | Remarks
SYSSUBSCRIPTIONS | SYSPUBLICATION system table | Presents subscription information, such as the publication name, creation time, and start time from the SYSPUBLICATION table in a more readable format.


SYSSYNCDEFINITIONS system view (deprecated)

A view of synchronization definitions for MobiLink synchronization. This view is deprecated.


SYSSYNCPUBLICATIONDEFAULTS system view

View name | Base table | Remarks
SYSSYNCPUBLICATIONDEFAULTS | SYSSYNC system table SYSPUBLICATION system table | A view of default synchronization settings associated with publications involved in MobiLink synchronization.


SYSSYNC2 system view

View name | Base table | Remarks
SYSSYNC2 | SYSSYNC system table | A union of the columns in SYSSYNCPUBLICATIONDEFAULTS, SYSSYNCUSERS, and SYSSYNCSUBSCRIPTIONS that do not contain sensitive data.


SYSSYNCS system view

View name | Base tables | Remarks
SYSSYNCS | SYSSYNC system table SYSPUBLICATION system table | A union of SYSSYNCPUBLICATIONDEFAULTS, SYSSYNCUSERS and SYSSYNCSUBSCRIPTIONS. Some columns in this view contain potentially sensitive data. For that reason, access to this view is restricted to users with DBA authority. The SYSSYNC2 view provides public access to the insensitive data.


SYSSYNCSUBSCRIPTIONS system view

View name | Base table | Remarks
SYSSYNCSUBSCRIPTIONS | SYSSYNC system table SYSPUBLICATION system table | A view of synchronization settings associated with MobiLink synchronization subscriptions.


SYSSYNCUSERS system view

View name | Base table | Remarks
SYSSYNCUSERS | SYSSYNC system table | A view of synchronization settings associated with MobiLink synchronization users.


SYSTABAUTH system view

View name | Base table | Remarks
SYSTABAUTH | SYSTABLEPERM system table |


SYSTRIGGERS system view

View name | Base table | Remarks
SYSTRIGGERS | SYSTRIGGER system table |


SYSUSERAUTH system view

View name | Base table | Remarks
SYSUSERAUTH | SYSUSERPERM system table | Presents all the information in the table SYSUSERPERM except for user numbers. Because this view displays passwords, this system view does not have PUBLIC select permission. (All other system views have PUBLIC select permission.)


SYSUSERLIST system view

View name | Base table | Remarks
SYSUSERAUTH | SYSUSERPERM system table | Presents all the information in SYSUSERAUTH except passwords.


SYSUSEROPTIONS system view

View name | Base table | Remarks
SYSUSEROPTIONS | SYSOPTIONS system view | Presents permanent option settings that are in effect for each user. If a user has no setting for an option, this view displays the public setting for the option.


SYSUSERPERMS system view

View name | Base table | Remarks
SYSUSERPERMS | SYSUSERPERM system table | Contains exactly the same information as the table SYSUSERPERM, except the password is omitted. All users have read access to this view, but only the DBA has access to the underlying table (SYSUSERPERM).


SYSVIEWS system view

View name | Base table | Remarks
SYSVIEWS | SYSTABLE system table SYSUSERPERM system table | Lists views along with their definitions.


Views for Transact-SQL compatibility

Adaptive Server Enterprise and Adaptive Server Anywhere have different system catalogs, reflecting the different uses for the two products.

In Adaptive Server Enterprise, a single master database contains a set of system tables with information that applies to all databases on the server. Many databases may exist within the master database, and each has additional system tables associated with it.

In Adaptive Server Anywhere, each database exists independently, and contains its own system tables. There is no master database that contains system information on a collection of databases. Each server may run several databases at a time, dynamically loading and unloading each database as needed.

The Adaptive Server Enterprise and Adaptive Server Anywhere system catalogs are different. The Adaptive Server Enterprise system tables and views are owned by the special user dbo, and exist partly in the master database, partly in the sybsecurity database, and partly in each individual database; the Adaptive Server Anywhere system tables and views are owned by the special user SYS and exist separately in each database.

To assist in preparing compatible applications, Adaptive Server Anywhere provides a set of views owned by the special user dbo, which correspond to the Adaptive Server Enterprise system tables and views. Where architectural differences make the contents of a particular Adaptive Server Enterprise table or view meaningless in a Adaptive Server Anywhere context, the view is empty, containing just the column names and data types.

The following tables list the Adaptive Server Enterprise system tables and their implementation in the Adaptive Server Anywhere system catalog. The owner of all tables is dbo in each DBMS.

Tables existing in each Adaptive Server Enterprise database
Table name | Description | Data?
sysalternates | One row for each user mapped to a database user | No
syscolumns | One row for each column in a table or view, and for each parameter in a procedure | Yes
syscomments | One or more rows for each view, rule, default, trigger, and procedure, giving the SQL definition statement | Yes
sysconstraints | One row for each referential or check constraint associated with a table or column | No
sysdepends | One row for each procedure, view, or table that is referenced by a procedure, view, or trigger | No
sysindexes | One row for each clustered or nonclustered index, one row for each table with no indexes, and an additional row for each table containing text or image data. | Yes
syskeys | One row for each primary, foreign, or common key; set by the user (not maintained by Adaptive Server Enterprise) | No
syslogs | Transaction log | No
sysobjects | One row for each table, view, procedure, rule, trigger default, log, or (in tempdb only) temporary object | Contains compatible data only
sysprocedures | One row for each view, rule, default, trigger, or procedure, giving the internal definition | No
sysprotects | User permissions information | No
sysreferences | One row for each referential integrity constraint declared on a table or column | No
sysroles | Maps server-wide roles to local database groups | No
syssegments | One row for each segment (named collection of disk pieces) | No
systhresholds | One row for each threshold defined for the database | No
systypes | One row for each system-supplied or user-defined data type | Yes
sysusermessages | One row for each user-defined message | Yes (this is an Adaptive Server Anywhere system table)
sysusers | One row for each user allowed in the database | Yes
Tables existing in the Adaptive Server Enterprise master database
Table name | Description | Data?
syscharsets | One row for each character set or sort order | No
sysconfigures | One row for each user-settable configuration parameter | No
syscurconfigs | Information about configuration parameters currently being used by the server | No
sysdatabases | One row for each database on the server | No
sysdevices | One row for each tape dump device, disk dump device, disk for databases, or disk partition for databases | No
sysengines | One row for each server currently online | No
syslanguages | One row for each language (except U.S. English) known to the server | No
syslocks | Information about active locks | No
sysloginroles | One row for each server login that possesses a system-defined role | No
syslogins | One row for each valid user account | Yes
sysmessages | One row for each system error or warning | No
sysprocesses | Information about server processes | No
sysremotelogins | One row for each remote user | No
sysservers | One row for each remote server | No
syssrvroles | One row for each server-wide role | No
sysusages | One row for each disk piece allocated to a database | No
Tables existing in the Adaptive Server Enterprise sybsecurity database
Table name | Description | Data?
sysaudits | One row for each audit record | No
sysauditoptions | One row for each global audit option | No


System Procedures and Functions

About this chapter

This chapter documents the system-supplied stored procedures in Adaptive Server Anywhere databases. The chapter also documents system-supplied extended procedures, including procedures for sending e-mail messages.

System procedure overview
System and catalog stored procedures
System extended stored procedures
Adaptive Server Enterprise system and catalog procedures


System procedure overview

Adaptive Server Anywhere includes the following kinds of system procedures:

  • Catalog stored procedures, for displaying system information in tabular form.

  • Extended stored procedures for e-mail support and other functions.

  • Miscellaneous procedures for controlling server behavior

  • Transact-SQL system and catalog procedures.

    For a list of these system procedures see Adaptive Server Enterprise system and catalog procedures.

  • System functions that are implemented as stored procedures.

    For information see System functions.

This chapter documents the first three types of procedures listed above.

System procedure and function definitions


System procedure and function definitions

Detailed information about system procedures and functions is available in Sybase Central:

  • To view system procedures and functions, right-click a connected database, choose Filter Objects by Owner, and select DBO.

  • Open the Procedures & Functions folder for the database.

  • You can see the procedure definition by selecting the procedure in the left pane and then clicking the SQL tab in the right pane.


System and catalog stored procedures

System and catalog stored procedures are owned by the user ID dbo. Some of these procedures are for internal system use. This section documents only those not intended solely for system and internal use. You cannot call external functions on Windows CE.

sa_audit_string system procedure
sa_check_commit system procedure
sa_conn_activity system procedure
sa_conn_compression_info system procedure
sa_conn_info system procedure
sa_conn_properties system procedure
sa_conn_properties_by_conn system procedure
sa_conn_properties_by_name system procedure
sa_db_info system procedure
sa_db_properties system procedure
sa_disable_auditing_type
sa_disk_free_space system procedure
sa_enable_auditing_type
sa_eng_properties system procedure
sa_flush_cache system procedure
sa_flush_statistics system procedure
sa_get_dtt system procedure
sa_get_histogram system procedure
sa_get_request_profile system procedure
sa_get_request_times system procedure
sa_get_server_messages system procedure
sa_http_header_info system procedure
sa_http_variable_info system procedure
sa_index_density system procedure
sa_index_levels system procedure
sa_java_loaded_classes system procedure
sa_locks system procedure
sa_make_object system procedure
sa_migrate system procedure
sa_migrate_create_fks system procedure
sa_migrate_create_remote_fks_list system procedure
sa_migrate_create_remote_table_list system procedure
sa_migrate_create_tables system procedure
sa_migrate_data system procedure
sa_migrate_drop_proxy_tables system procedure
sa_procedure_profile system procedure
sa_procedure_profile_summary system procedure
sa_recompile_views system procedure
sa_report_deadlocks system procedure
sa_reset_identity system procedure
sa_rowgenerator system procedure
sa_send_udp system procedure
sa_server_option system procedure
sa_set_http_header system procedure
sa_set_http_option system procedure
sa_statement_text system procedure
sa_table_fragmentation system procedure
sa_table_page_usage system procedure
sa_validate system procedure
sa_verify_password system procedure
sp_login_environment system procedure
sp_remote_columns system procedure
sp_remote_exported_keys system procedure
sp_remote_imported_keys system procedure
sp_remote_primary_keys system procedure
sp_remote_tables system procedure
sp_servercaps system procedure
sp_tsql_environment system procedure


sa_audit_string system procedure

toggle Function

Adds a string to the transaction log.

toggle Syntax

sa_audit_string ( log-string )

toggle Arguments

  • log-string A string of characters to add to the transaction log.

toggle Remarks

If auditing is turned on, this system procedure adds a comment into the audit log. The string can be a maximum of 200 bytes long.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also
  • AUDITING option [database]
  • Auditing database activity
toggle Example

The following example uses sa_audit_string to add a comment into the audit log:

CALL sa_audit_string( 'Auditing test' )


sa_check_commit system procedure

toggle Function

Checks for outstanding referential integrity violations before a commit.

toggle Syntax

sa_check_commit ( out_table_name, out_key_name )

toggle Arguments

  • out_table_name A varchar(128) parameter containing the name of a table with a row that is currently violating referential integrity.

  • out_key_name A varchar(128) parameter containing the name of the corresponding foreign key index.

toggle Remarks

If the database option WAIT_FOR_COMMIT is ON, or if a foreign key is defined using CHECK ON COMMIT in the CREATE TABLE statement, you can update the database in such a way as to violate referential integrity, as long as these violations are resolved before the changes are committed.

You can use the sa_check_commit system procedure to check whether there are any outstanding referential integrity violations before attempting to commit your changes.

The returned parameters indicate the name of a table containing a row that is currently violating referential integrity, and the name of the corresponding foreign key index.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also
  • WAIT_FOR_COMMIT option [database]
  • CREATE TABLE statement
toggle Example

The following set of commands can be executed from Interactive SQL. They delete rows from the department table in the sample database, in such a way as to violate referential integrity. The call to sa_check_commit checks which tables and keys have outstanding violations, and the rollback cancels the change:

SET TEMPORARY OPTION WAIT_FOR_COMMIT='ON'
go
DELETE FROM department
go
CREATE VARIABLE tname VARCHAR( 128 );
CREATE VARIABLE keyname VARCHAR( 128 )
go
CALL sa_check_commit( tname, keyname )
go
SELECT tname, keyname
go
ROLLBACK
go


sa_conn_activity system procedure

toggle Function

Returns the most recently-prepared SQL statement for each connection to databases on the server.

toggle Syntax

sa_conn_activity ( )

toggle Result sets
Column name | Data type | Description
Number | integer | The ID number of the connection.
Name | varchar(255) | The name of the connection.
Userid | varchar(255) | The user ID for the connection.
DBNumber | integer | The ID number of the database.
LastReqTime | varchar(255) | The time at which the last request for the specified connection started.
LastStatement | long varchar | The most recently-prepared SQL statement for the connection.
toggle Remarks

The sa_conn_activity procedure returns a result set consisting of the most recently-prepared SQL statement for each connection if the server has been told to collect the information. Recording of statements must be turned on the database server prior to calling sa_conn_activity. To do this, specify the -zl option when starting the database server or execute the following:

CALL sa_server_option('RememberLastStatement','ON')

This procedure is useful when the database server is busy and you want to obtain information about what SQL statement is prepared for each connection. This feature can be used as an alternative to request logging.

For information on the LastStatement property these values are derived from, see Connection-level properties.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • -zl server option
  • sa_server_option system procedure


sa_conn_compression_info system procedure

toggle Function

Summarizes compression rates.

toggle Syntax

sa_conn_compression_info ( [ connection-id ] )

toggle Arguments

  • connection-id This optional integer parameter specifies the ID number of a connection.

toggle Result sets
Column name | Data type | Description
Type | varchar(20) | A string identifying whether the compression statistics that follow represent either one Connection, or all connections to the Server.
ConnNumber | integer | An integer representing a connection ID. Returns NULL if the Type is Server.
Compression | varchar(10) | A string representing whether or not compression is enabled for the connection. Returns NULL if Type is Server, or ON/OFF if Type is Connection.
TotalBytes | integer | An integer representing the total number of actual bytes both sent and received.
TotalBytesUnComp | integer | An integer representing the number of bytes that would have been sent and received if compression was disabled.
CompRate | numeric(5,2) | A numeric (5,2) representing the overall compression rate. For example, a value of 0 indicates that no compression occurred. A value of 75 indicates that the data was compressed by 75%, or down to one quarter of its original size.
CompRateSent | numeric(5,2) | A numeric (5,2) representing the compression rate for data sent to the client.
CompRateReceived | numeric(5,2) | A numeric (5,2) representing the compression rate for data received from the client.
TotalPackets | integer | An integer representing the total number of actual packets both sent and received.
TotalPacketsUnComp | integer | An integer representing the total number of packets that would have been sent and received if compression was disabled.
CompPktRate | numeric(5,2) | A numeric (5,2) representing the overall compression rate of packets.
CompPktRateSent | numeric(5,2) | A numeric (5,2) representing the compression rate of packets sent to the client.
CompPktRateReceived | numeric(5,2) | A numeric (5,2) representing the compression rate of packets received from the client.
toggle Remarks

If you specify the connection ID number, sa_conn_compression_info procedure returns a result set consisting of compression properties for the supplied connection. If no connection-id is supplied, this system procedure returns information for all current connections to databases on the server.

For information on the properties these values are derived from, see Connection-level properties.

toggle Permissions

None

toggle Side effects

None

toggle Example

The following example uses the sa_conn_compression_info stored procedure to return a result set summarizing compression properties for all connections to the server.

CALL sa_conn_compression_info()
Type | ConnNumber | Compression | TotalBytes | ...
Connection | 79 | Off | 7841 | ...
Server | (NULL) | (NULL) | 2737761 | ...
... | ... | ... | ... | ...


sa_conn_info system procedure

toggle Function

Reports connection property information.

toggle Syntax

sa_conn_info ( [ connection-id ] )

toggle Arguments

  • connection-id This optional integer parameter specifies the ID number of a connection.

toggle Result sets
Column name | Data type | Description
Number | integer | The ID number of the connection.
Name | varchar(255) | The name of the current connection.
Userid | varchar(255) | The user ID for the connection.
DBNumber | integer | The ID number of the database.
LastReqTime | varchar(255) | The time at which the last request for the specified connection started.
ReqType | varchar(255) | A string for the type of the last request.
CommLink | varchar(255) | The communication link for the connection. This is one of the network protocols supported by Adaptive Server Anywhere, or local for a same-machine connection.
NodeAddr | varchar(255) | The node for the client in a client/server connection.
LastIdle | integer | The number of ticks between requests.
BlockedOn | integer | If the current connection is not blocked, this is zero. If it is blocked, the connection number on which the connection is blocked because of a locking conflict.
LockName | unsigned bigint | A 64-bit unsigned integer value representing the lock for which a connection is waiting.
UncmtOps | integer | The number of uncommitted operations.
toggle Remarks

If you specify the connection ID number, sa_conn_compression_info procedure returns a result set consisting of connection properties for the supplied connection. If no connection-id is supplied, this system procedure returns information for all current connections to databases on the server.

In a block situation, the BlockedOn value returned by this procedure allows you to check which users are blocked, and who they are blocked on. The sa_locks procedure can be used to display the locks held by the blocking connection; and if a connection holds locks on several tables you can match the LockName value between sa_locks and sa_conn_info.

For information on these properties, see Connection-level properties.

toggle Permissions

None

toggle Side effects

None

toggle Example

The following example uses the sa_conn_info stored procedure to return a result set summarizing connection properties for all connections to the server.

CALL sa_conn_info()
Number | Name | Userid | DBNumber | ...
79 |  | DBA | 0 | ...
46 | Sybase Central 1 | DBA | 0 | ...
... | ... | ... | ... | ...


sa_conn_properties system procedure

toggle Function

Reports connection property information.

toggle Syntax

sa_conn_properties ( [ connection-id ] )

toggle Arguments

  • connection-id This optional integer parameter specifies the ID number of a connection.

toggle Result sets
Column name | Data type | Description
Number | integer | The ID number of the connection.
PropNum | integer | The connection property number.
PropName | varchar(255) | The connection property name.
PropDescription | varchar(255) | The connection property description.
Value | long varchar | The connection property value.
toggle Remarks

Returns the connection ID as Number, and the PropNum, PropName, PropDescription, and Value for each available connection property.

If no connection-id is supplied, properties for all connections to the current database are returned.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_conn_properties_by_conn system procedure
  • sa_conn_properties_by_name system procedure
  • System functions
  • Connection-level properties
toggle Example

The following example uses the sa_conn_properties stored procedure to return a result set summarizing connection property information for all connections.

CALL sa_conn_properties()
Number | PropNum | PropName | ...
79 | 37 | CacheHits | ...
79 | 38 | CacheRead | ...
... | ... | ... | ...


sa_conn_properties_by_conn system procedure

toggle Function

Reports connection property information.

toggle Syntax

sa_conn_properties_by_conn ( [ property-name ] )

toggle Arguments

  • property-name This optional varchar(255) parameter specifies a connection property name.

toggle Result sets
Column name | Data type | Description
Number | integer | The ID number of the connection.
PropNum | integer | The connection property number.
PropName | varchar(255) | The connection property name.
PropDescription | varchar(255) | The connection property description.
Value | long varchar | The connection property value.
toggle Remarks

This is a variant on the sa_conn_properties system procedure, and returns the same result columns. It returns results only for connection properties that match the property-name string. You can use wildcards in property-name, as the comparison uses a LIKE operator. The result set is sorted by connection number and property name.

For a list of available connection properties, see Connection-level properties.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_conn_properties system procedure
  • Connection-level properties
toggle Example

The following statement returns the AnsiNull option setting for all connections:

CALL sa_conn_properties_by_conn( 'ansinull' )

The following statement returns the ANSI-related option settings for all connections:

CALL sa_conn_properties_by_conn( 'ansi%' )

Note that the same result can also be obtained by using:

SELECT *
FROM sa_conn_properties()
WHERE propname LIKE 'ansi%'
ORDER BY number, propname


sa_conn_properties_by_name system procedure

toggle Function

Reports connection property information.

toggle Syntax

sa_conn_properties_by_name ( [ connection-id ] )

toggle Arguments

  • connection-id This optional varchar(255) parameter specifies the ID number of a connection.

toggle Result sets
Column name | Data type | Description
Number | integer | The ID number of the connection.
PropNum | integer | The connection property number.
PropName | varchar(255) | The connection property name.
PropDescription | varchar(255) | The connection property description.
Value | long varchar | The connection property value.
toggle Remarks

This is a variant on the sa_conn_properties system procedure, and returns the same result columns. For sa_conn_properties_by_name, however, the information is sorted by property name and connection number.

For a list of available connection properties, see System functions.

Note that the same result can be obtained using the following:

SELECT *
FROM sa_conn_properties()
ORDER BY propname, number
toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_conn_properties system procedure
  • Connection-level properties
toggle Example

The following example uses the sa_conn_properties_by_name stored procedure to return a result set summarizing connection property information sorted by property name and connection number.

CALL sa_conn_properties_by_name()
Number | PropNum | PropName | ...
46 | 279 | Allow_nulls_by_default | ...
50 | 279 | Allow_nulls_by_default | ...
... | ... | ... | ...


sa_db_info system procedure

toggle Function

Reports database property information.

toggle Syntax

sa_db_info ( [ database-id ] )

toggle Arguments

  • database-id This optional integer parameter specifies the ID number of a database.

toggle Result sets
Column name | Data type | Description
Number | integer | The ID number of the connection.
Alias | varchar(255) | The database name.
File | varchar(255) | The file name of the database root file, including path.
ConnCount | integer | The number of connections to the database.
PageSize | integer | The page size of the database, in bytes.
LogName | varchar(255) | The file name of the transaction log, including path.
toggle Remarks

If you specify a database ID, sa_db_info returns a single row containing the Number, Alias, File, ConnCount, PageSize, and LogName for the specified database.

If no database-id is supplied, properties for all databases are returned.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_db_properties system procedure
  • Database-level properties
toggle Example

The following statement returns a row for each database that is running on the server:

it returns one row for each database running

CALL sa_db_info()
Property | Value
Number | 0
Alias | asademo
File | C:\Program Files\Sybase\SQL Anywhere 9\asademo.db
ConnCount | 1
PageSize | 2048
LogName | C:\Program Files\Sybase\SQL Anywhere 9\asademo.log


sa_db_properties system procedure

toggle Function

Reports database property information.

toggle Syntax

sa_db_properties ( [ database-id ] )

toggle Arguments

  • database-id This optional integer parameter specifies the ID number of a database.

toggle Result sets
Column name | Data type | Description
Number | integer | The ID number of the database.
PropNum | integer | The database property number.
PropName | varchar(255) | The database property name.
PropDescription | varchar(255) | The database property description.
Value | long varchar | The database property value.
toggle Remarks

If you specify a database ID, sa_db_properties returns the database ID number and the PropNum, PropName, PropDescription, and Value for each available database property.

If no database-id is supplied, properties for all databases are returned.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_db_info system procedure
  • Database-level properties
toggle Example

The following example uses the sa_db_properties() stored procedure to return a result set summarizing database property information for all databases.

CALL sa_db_properties()
Number | PropNum | PropName | ...
0 | 0 | ConnCount | ...
0 | 1 | IdleCheck | ...
0 | 2 | IdleWrite | ...
... | ... | ... | ...


sa_disable_auditing_type

toggle Function

Disables auditing of specific events.

toggle Syntax

sa_disable_auditing_type ( string )

toggle Arguments

  • string This varchar(128) parameter is a comma-delimited string containing one or more of:

    all disables all types of auditing.

    connect disables auditing of both successful and failed connection attempts.

    connectFailed disables auditing of failed connection attempts.

    DDL disables auditing of DDL statements.

    options disables auditing of public options.

    permission disables auditing of permission checks, user checks, and SETUSER statements.

    permissionDenied disables auditing of failed permission and user checks.

    triggers disables auditing in response to trigger events.

toggle Remarks

You can use the sa_disable_auditing_type system procedure to disable auditing of one or more categories of information.

Setting this option to all disables all auditing. You can also disable auditing by setting the PUBLIC.AUDITING option to OFF.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also
  • Auditing database activity
  • AUDITING option [database]
toggle Example

To disable all auditing:

CALL sa_disable_auditing_type('all')


sa_disk_free_space system procedure

toggle Function

Reports information about space available for a dbspace, transaction log, transaction log mirror, and/or temporary file.

toggle Syntax

sa_disk_free_space ( [ string ] )

toggle Arguments

  • string This string parameter can be one of dbspace-name, log, mirror, or temp.

    If there is a dbspace called log, mirror, or temp, you can prefix the keyword with an underscore. For example, use _log to get information about the log file when a dbspace exists called log.

toggle Result sets
Column name | Data type | Description
dbspace_name | varchar(128) | This is the dbspace name, Transaction Log, Mirror Log, or Temporary File.
free_space | unsigned bigint | The number of free bytes on the volume.
toggle Remarks

If the string parameter is not specified or is null, then the result set contains one row for each dbspace, plus one row for each of the transaction log, transaction log mirror, and temporary file, if they exist. If string is specified, then exactly one or zero rows will be returned (zero if no such dbspace exists, or if log or mirror is specified and there is no log or mirror file).

toggle Permissions

DBA authority required

toggle Side effects

None

toggle Example

The following example uses the sa_disk_free_space stored procedure to return a result set containing information about available space.

CALL sa_disk_free_space()
dbspace_name | free_space
SYSTEM | 10952101888
Transaction Log | 10952101888
Temporary File | 10952101888


sa_enable_auditing_type

toggle Function

Enables auditing and specifies which events to audit.

toggle Syntax

sa_enable_auditing_type ( string )

toggle Arguments

  • string This varchar(128) parameter is a comma-delimited string containing one or more of:

    all enables all types of auditing.

    connect enables auditing of both successful and failed connection attempts.

    connectFailed enables auditing of failed connection attempts.

    DDL enables auditing of DDL statements.

    options enables auditing of public options.

    permission enables auditing of permission checks, user checks, and setuser statements.

    permissionDenied enables auditing of failed permission and user checks.

    triggers enables auditing after a trigger event.

toggle Remarks

sa_enable_auditing_type works in conjunction with the PUBLIC.AUDITING option to enable auditing of specific types of information.

If you set the PUBLIC.AUDITING option to ON, and do not specify which type of information to audit, the default setting (all) takes effect. In this case, all types of auditing information are recorded.

If you set the PUBLIC.AUDITING option to ON, and disable all types of auditing using sa_disable_auditing_type, no auditing information is recorded. In order to re-establish auditing, you must use sa_enable_auditing_type to specify which type of information you want to audit.

If you set the PUBLIC.AUDITING option to OFF, then no auditing information is recorded, regardless of the sa_enable_auditing_type setting.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also
  • Auditing database activity
  • AUDITING option [database]
toggle Example

To enable only option auditing:

CALL sa_disable_auditing_type('all')
CALL sa_enable_auditing_type('options')


sa_eng_properties system procedure

toggle Function

Reports database server property information.

toggle Syntax

sa_eng_properties ( )

toggle Result sets
Column name | Data type | Description
PropNum | integer | The database server property number.
PropName | varchar(255) | The database server property name.
PropDescription | varchar(255) | The database server property description.
Value | long varchar | The database server property value.
toggle Remarks

Returns the PropNum, PropName, PropDescription, and Value for each available server property.

For a list of available database server properties, see System functions.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • Server-level properties
toggle Example

The following statement returns a set of available server properties

CALL sa_eng_properties()
PropNum | PropName | ...
1 | IdleWrite | ...
2 | IdleChkPt | ...
... | ... | ...


sa_flush_cache system procedure

toggle Function

Empties all pages for the current database in the database server cache.

toggle Syntax

sa_flush_cache ( )

toggle Remarks

Database administrators can use this procedure to empty the contents of the database server cache for the current database. This is of use in performance measurement to ensure repeatable results.

toggle Permissions

DBA authority required

toggle Side effects

None


sa_flush_statistics system procedure

toggle Function

Saves all cost model statistics in the database server cache.

toggle Syntax

sa_flush_statistics ( )

toggle Remarks

Database administrators can use this procedure to ensure that cost model statistics in the database server cache that have been created and/or gathered, but not yet saved to disk, are flushed out with immediate effect. Under normal operation it should not be necessary to execute this procedure because the server automatically writes out statistics to disk on a periodic basis.

toggle Permissions

DBA authority required

toggle Side effects

None


sa_get_dtt system procedure

toggle Function

Reports the current value of the Disk Transfer Time (DTT) model, which is part of the cost model.

toggle Syntax

sa_get_dtt ( file-id )

toggle Arguments

  • file-id This unsigned smallint parameter specifies the database file ID.

toggle Remarks

You can obtain the file-id from the system table SYSFILE.

This procedure, intended for internal diagnostic purposes, retrieves data from the system table SYSOPTSTAT.

toggle Result sets
Column name | Data type | Description
BandSize | unsigned integer | Size, in pages, of disk over which random access takes place.
ReadTime | unsigned integer | Amortized cost, in milliseconds, of reading one page.
WriteTime | unsigned integer | Amortized cost, in milliseconds, of writing one page.
toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also

  • SYSFILE system table

  • SYSOPTSTAT system table


sa_get_histogram system procedure

toggle Function

Retrieves the histogram for a column.

toggle Syntax

sa_get_histogram (
column,
table
[, owner ]
)

toggle Arguments

  • column This char(128) parameter specifies the column.

  • table This char(128) parameter specifies the table.

  • owner This optional char(128) parameter specifies the owner.

toggle Result sets
Column name | Data type | Description
StepNumber | smallint | Histogram bucket number. The frequency of the first bucket ( StepNumber = 0) indicates the selectivity of NULLs.
Low | char(128) | Lowest (inclusive) column value in the bucket.
High | char(128) | Highest (exclusive) column value in the bucket.
Frequency | double | Selectivity of values in the bucket.
toggle Remarks

This procedure, intended for internal diagnostic purposes, retrieves column statistics from the system table SYSCOLSTAT.

A singleton bucket is indicated by a Low value in the result set being equal to the corresponding High value.

For more information about histograms and query optimization and execution in Adaptive Server Anywhere, see Optimizer estimates and histograms.

It is recommended that you view histograms using the Histogram utility.

For more information about the Histogram utility, see The Histogram utility.

To determine the selectivity of a predicate over a string column, you should use the ESTIMATE or ESTIMATE_SOURCE functions. For string columns, both sa_get_histogram and the Histogram utility retrieve nothing from SYSCOLSTAT. Attempting to retrieve string data generates an error.

toggle Permissions

SELECT permission required

toggle Side effects

None

toggle See also
  • The Histogram utility
  • Optimizer estimates and histograms
  • ESTIMATE function [Miscellaneous]
  • ESTIMATE_SOURCE function [Miscellaneous]
  • SYSCOLSTAT system table


sa_get_request_profile system procedure

toggle Function

Analyzes the request log to determine the execution times of similar statements.

toggle Syntax

sa_get_request_profile (
[ filename
[, conn_id
[, first_file
[, num_files ] ]
)

toggle Arguments

  • filename This optional long varchar parameter specifies the request logging filename.

  • conn_id This optional unsigned integer parameter specifies the ID number of a connection.

  • first_file This optional integer parameter specifies the first request log file to analyze.

  • num_files This optional integer parameter specifies the number of request log files to analyze.

toggle Remarks

This procedure calls sa_get_request_times to process a request log file, and then summarizes the results into the global temporary table satmp_request_profile. This table contains the statements from the log along with how many times each was executed, and their total, average, and maximum execution times. The table can be sorted in various ways to identify targets for performance optimization efforts.

If you do not specify a log file, the default is the current log file that is specified at the command prompt with -zo, or that has been specified by

sa_server_option( 'RequestLogFile', filename )

If a connection ID is specified, it is used to filter information from the log so that only requests for that connection are retrieved.

toggle Permissions

DBA authority required

toggle Side effects

Automatic commit

toggle Example

The following command obtains the request times for the requests in the files req.out.3, req.out.4, and req.out.5.

CALL sa_get_request_profile('req.out',0,3,3)
toggle See also
  • sa_get_request_times system procedure
  • sa_statement_text system procedure
  • sa_server_option system procedure


sa_get_request_times system procedure

toggle Function

Analyzes the request log to determine statement execution times.

toggle Syntax

sa_get_request_times (
filename
[, conn_id
[, first_file
[, num_files ] ]
)

toggle Arguments

  • filename This optional LONG VARCHAR parameter specifies the request logging filename.

  • conn_id This optional UNSIGNED INTEGER parameter specifies the ID number of a connection.

  • first_file This optional INTEGER parameter specifies the first file to analyze.

  • num_files This optional INTEGER parameter specifies the number of request log files to analyze.

toggle Remarks

This procedure reads the specified request log and populates the global temporary table satmp_request_time with the statements from the log and their execution times.

For statements such as inserts and updates, the execution time is straightforward. For queries, the time is calculated from preparing the statement to dropping it, including describing it, opening a cursor, fetching rows, and closing the cursor. For most queries, this is an accurate reflection of the amount of time taken. In cases where the cursor is left open while other actions are performed, the time appears as a large value but is not a true indication that the query is costly.

This procedure recognizes host variables in the request log and populates the global temporary table satmp_request_hostvar with their values. For older databases where this temporary table does not exist, host variable values are ignored.

If you do not specify a log file, the default is the current log file that is specified at the command prompt with -zo, or that has been specified by

sa_server_option( 'RequestLogFile', filename )

If a connection ID is specified, it is used to filter information from the log so that only requests for that connection are retrieved.

toggle Permissions

DBA authority required

toggle Side effects

Automatic commit

toggle Example

The following command obtains the execution times for the requests in the files req.out.3, req.out.4, and req.out.5.

CALL sa_get_request_times('req.out',0,3,3)
toggle See also
  • sa_get_request_profile system procedure
  • sa_statement_text system procedure
  • sa_server_option system procedure


sa_get_server_messages system procedure

toggle Function

Allows you to return constants from the server messages window as a result set.

toggle Syntax

sa_get_server_messages ( integer )

toggle Arguments

  • integer This integer parameter indicates the line number to start displaying server messages.

toggle Result sets
Column name | Data type | Description
line_num | integer | The line number of a server message.
message_text | varchar(255) | The server message text.
message_time | timestamp | The time of the message.
toggle Remarks

This procedure takes an integer parameter that specifies the starting line number to display, and returns a row for that line and for all subsequent lines. If the starting line is negative, the result set starts at the first available line. The result set includes the line number, message text, and message time.

toggle Permissions

None

toggle Side effects

None

toggle Example

The following example uses the sa_get_server_messages stored procedure to return a result set containing the content of the server messages window starting on line 16.

CALL sa_get_server_messages(16)
line_num | message_text | ...
16 | Running on Windows 2000 Build 2195... | ...
17 | 2132K of memory used for caching | ...
... | ... | ...


sa_http_header_info system procedure

toggle Function

Returns HTTP header names and values.

toggle Syntax

sa_http_header_info ( [header_parm] )

toggle Arguments

  • header_parm This optional varchar(255) parameter specifies a HTTP header name.

toggle Result sets
Column name | Data type | Description
Name | varchar(255) | The HTTP header name.
Value | long varchar | The HTTP header value.
toggle Remarks

The sa_http_header_info stored procedure returns header names and values. If you do not specify the header name using the optional parameter, the result set contains values for all headers.

This procedure returns a non-empty result set if it is called while processing an HTTP request within a web service.

toggle Permissions

None

toggle Side effects

None

toggle See also

Using Web Services

sa_http_variable_info system procedure


sa_http_variable_info system procedure

toggle Function

Returns HTTP variable names and values.

toggle Syntax

sa_http_variable_info ( [variable_parm] )

toggle Arguments

  • variable_parm This optional varchar(255) parameter specifies a HTTP variable name.

toggle Result sets
Column name | Data type | Description
Name | varchar(255) | The HTTP variable name.
Value | long varchar | The HTTP variable value.
toggle Remarks

The sa_http_variable_info stored procedure returns variable names and values. If you do not specify the variable name using the optional parameter, the result set contains values for all variables.

This procedure returns a non-empty result set if it is called while processing an HTTP request within a web service.

toggle Permissions

None

toggle Side effects

None

toggle See also

Using Web Services

sa_http_header_info system procedure


sa_index_density system procedure

toggle Function

Reports information about the amount of fragmentation within database indexes.

toggle Syntax

sa_index_density (
[ table_name
[, owner_name ] ]
)

toggle Arguments

  • table_name This optional char(128) parameter specifies the table name.

  • owner_name This optional char(128) parameter specifies the owner name.

toggle Result sets
Column name | Data type | Description
TableName | char(128) | The name of a table.
TableId | unsigned integer | The table ID.
IndexName | char(128) | The name of an index.
IndexId unsigned integer The index ID. This column contains one of the following values:

  • 0 for primary keys

  • SYSFOREIGNKEY.foreign_key_id for foreign keys

  • SYSINDEX.index_id for all other indexes
IndexType char(4) The index type. This column contains one of the following values:

  • PKEY for primary keys

  • FKEY for foreign keys

  • UI for unique indexes

  • UC for unique constraints

  • NUI for non-unique indexes
LeafPages | unsigned integer | The number of leaf pages.
Density | numeric(8,6) | A fraction between 0 and 1 providing an indication of how full each index page is (on average).
toggle Remarks

Database administrators can use this procedure to obtain information about the degree of fragmentation in a database's indexes.

The procedure returns a result set containing the table name, the table ID, the index name, the index ID, the index type, the number of leaf pages, and the index's density.

If you do not specify parameters, the information for all tables appears. Otherwise, the procedure examines only the named table.

For indexes with a high number of leaf pages, higher density values are desirable.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also
  • Index fragmentation
toggle Example

The following example uses the sa_index_density stored procedure to return a result set summarizing the amount of fragmentation within database indexes.

CALL sa_index_density()
TableName | TableId | IndexName | ... | Density
Products | 436 | Products | ... | 0.012451
... | ... | ... | ... | ...


sa_index_levels system procedure

toggle Function

Assists in performance tuning by reporting the number of levels in an index.

toggle Syntax

sa_index_levels ( [ table_name [, owner_name ] ] )

toggle Arguments

  • table_name This optional char(128) parameter specifies the table name.

  • owner_name This optional char(128) parameter specifies the owner name.

toggle Result sets
Column name | Data type | Description
TableName | char(128) | The name of a table.
TableId | unsigned integer | The table ID.
IndexName | char(128) | The name of an index.
IndexId unsigned integer The index ID. This column contains one of the following:

  • 0 for primary keys

  • SYSFOREIGNKEY.foreign_key_id for foreign keys

  • SYSINDEX.index_id for all other indexes
IndexType char(4) The index type. This column contains one of the following values:

  • PKEY for primary keys

  • FKEY for foreign keys

  • UI for unique indexes

  • UC for unique constraints

  • NUI for non-unique indexes
Levels | integer | The number of levels in the index.
toggle Remarks

The number of levels in the index tree determines the number of I/O operations needed to access a row using the index. Indexes with a small number of levels are more efficient than indexes with a large number of levels.

The procedure returns a result set containing the table name, the table ID, the index name, the index ID, the index type, and the number of levels in the index.

If no arguments are supplied, levels are returned for all indexes in the database. If only table_name is supplied, levels for all indexes on that table are supplied. If table_name is NULL and an owner_name is given, only levels for indexes on tables owned by that user are returned.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also
  • CREATE INDEX statement
  • Using indexes
toggle Example

The following example uses the sa_index_levels stored procedure to return the number of levels in the Products index.

CALL sa_index_levels()
TableName | TableId | IndexName | ... | Levels
Products | 436 | Products | ... | 1
... | ... | ... | ... | ...


sa_java_loaded_classes system procedure

toggle Function

Lists the classes currently loaded by the database Java virtual machine.

toggle Syntax

sa_java_loaded_classes ( )

toggle Result sets
Column name | Data type | Description
class_name | varchar(512) | The name of a class currently loaded by the database Java virtual machine.
toggle Remarks

Returns a result set containing all the names of the Java classes currently loaded by the database Java virtual machine.

When the virtual machine is first called, it loads a number of classes. If you call sa_java_loaded_classes without using any Java in the database features beforehand, it returns this set of classes.

The procedure can be useful to diagnose missing classes. It can also be used to identify which classes from a particular jar are used by a given application.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also
  • Installing Java classes into a database.


sa_locks system procedure

toggle Function

Displays all locks in the database.

toggle Syntax

sa_locks (
[ connection
[ , table_name
[ , max_locks ] ] ]
)

toggle Arguments

  • connection This integer parameter specifies a connection ID. The procedure returns lock information only about the specified connection. The default value is zero, in which case information is returned about all connections.

  • table_name This char(128) parameter specifies a table name. The procedure returns information only about the specified tables. The default value is NULL, in which case information is returned about all tables.

    If the table_name string contains a period, the value to the left of the period is interpreted as the owner name.

  • max_locks This integer parameter specifies the maximum number of locks for which to return information. The default value is 1000. The value -1 means return all lock information.

toggle Result sets
Column name | Data type | Description
connection | integer | The connection ID that has the lock.
user_id | char(128) | The user connected through connection ID.
table_name | char(128) | The table on which the lock is held.
lock_type | char(32) | The lock type is a string of characters indicating the type of lock.
lock_name | unsigned bigint | The lock name value identifying the lock. This value can be matched with sa_conn_info output to determine the responsible locks in a blocking situation. Lock_names can be a row ID or can be NULL.
toggle Remarks

The sa_locks procedure returns a result set containing information about all the locks in the database.

The lock_type field in the result set is a string of characters indicating the type of lock. For non-NULL lock_name values, the lock_type characters are:

  • S Shared

  • E Exclusive

  • P Phantom

  • A Anti-phantom

All locks listed have exactly one of S or E specified, and may also have P, A, or both. If a lock is a phantom or anti-phantom lock, a qualifier is added to the lock type. The qualifier is as follows:

  • T The lock is with respect to a sequential scan.

  • * The lock is with respect to all scans.

  • nnn An index number. The lock is with respect to a particular index.

NULL lock_name

If the lock_name is NULL, then the row contains information about two types of lock: a schema lock, and a lock on rows. The lock_type values can be a combination of:

  • S Shared schema lock

  • E Exclusive schema lock

  • AT Shared row lock

  • PT Intent mode on a row lock

The schema lock means that other transactions are prevented from modifying the table schema. This schema lock can be acquired in shared (S) or exclusive (E) mode.

The row lock applies to the rows in the table. It can be acquired in shared mode or intent mode. Shared mode is represented by lock_type AT, and intent mode by lock_type PT. If acquired in shared mode, other transactions cannot modify the rows unless they acquire the lock in intent mode. However, the lock can only be acquired in shared mode if there are no uncommitted modifications to the table by other transactions.

For example, if a connection has modified a table but not yet done a commit or rollback, then sa_locks returns a NULL lock_name for the table, and a lock_type of at least SPT. S indicates a shared lock on the schema of the table and PT indicates an intent lock on the rows in the table.

For more information, see Connection-level properties, and sa_conn_info system procedure.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also
  • How locking works


sa_make_object system procedure

toggle Function

Ensures that a skeletal instance of an object exists before executing an ALTER statement.

toggle Syntax

sa_make_object (
object-type,
objname
[, owner
[, tabname ] ])

object-type:
'procedure' | 'function' | 'view' | 'trigger' | 'service'

toggle Arguments

  • object-type This char(30) parameter specifies the type of object being created.

  • objname This char(128) parameter specifies the name of the object to be created.

  • owner This char(128) parameter specifies the owner of the object to be created. The default value is CURRENT USER.

  • tabname This char(128) parameter is required only if objtype is 'trigger', in which case it specifies the name of the table on which the trigger is to be created.

toggle Remarks

This procedure is particularly useful in scripts or command files that are run repeatedly to create or modify a database schema. A common problem in such scripts is that the first time they are run, a CREATE statement must be executed, but subsequent times an ALTER statement must be executed. This procedure avoids the necessity of querying the system tables to find out whether the object exists.

To use the procedure, follow it by an ALTER statement that contains the entire object definition.

toggle Permissions

Resource authority is required to create or modify database objects

toggle Side effects

Automatic commit

toggle See also
  • ALTER FUNCTION statement
  • ALTER PROCEDURE statement
  • ALTER TRIGGER statement
  • ALTER VIEW statement
  • ALTER SERVICE statement
toggle Examples

The following statements ensure that a skeleton procedure definition is created, define the procedure, and grant permissions on it. A command file containing these instructions could be run repeatedly against a database without error.

CALL sa_make_object( 'procedure','myproc' );
ALTER PROCEDURE myproc( in p1 int, in p2 char(30) )
BEGIN
    // ...
END;
GRANT EXECUTE ON myproc TO public;

The following example uses the sa_make_object system procedure to add a skeleton web service.

CALL sa_make_object( 'service','my_web_service' )


sa_migrate system procedure

toggle Function

Migrates a set of remote tables to an Adaptive Server Anywhere database.

toggle Syntax

sa_migrate ( local_table_owner,
server_name
[, table_name ]
[, owner_name ]
[, database_name ]
[, migrate_data ]
[, drop_proxy_tables ]
[, migrate_fkeys ]
)

toggle Arguments

  • local_table_owner This varchar(128) parameter specifies the user on the target Adaptive Server Anywhere database who owns the migrated tables. Use the GRANT CONNECT statement to create this user. A value is required for this parameter.

    For more information, see GRANT statement.

  • server_name This varchar(128) parameter specifies the name of the remote server that is being used to connect to the remote database. Use the CREATE SERVER statement to create this server. A value is required for this parameter.

    For more information, see CREATE SERVER statement.

  • table_name If you are migrating a single table, use this varchar(128) parameter to specify the table name. Otherwise, you should specify NULL (the default) for this parameter. Do not specify NULL for both the table_name and owner_name parameters.

  • owner_name If you are migrating only tables that belong to one owner, use this varchar(128) parameter to specify the owner's name. Otherwise, you should enter NULL (the default) for this parameter. Do not specify NULL for both the table_name and owner_name parameters.

  • database_name This varchar(128) parameter specifies the name of the remote database. You must specify the database name if you want to migrate tables from only one database on the remote server. Otherwise, enter NULL (the default) for this parameter.

  • migrate_data Specifies whether the data in the remote tables is migrated. This parameter can be 0 (do not migrate data) or 1 (migrate data). By default, data is migrated.

  • drop_proxy_tables Specifies whether the proxy tables created for the migration process are dropped once the migration is complete. This parameter can be 0 (proxy tables are not dropped) or 1 (proxy tables are dropped). By default, the proxy tables are dropped.

  • migrate_fkeys Specifies whether the foreign key mappings are migrated. This parameter can be 0 (do not migrate foreign key mappings) or 1 (migrate foreign key mappings). By default, the foreign key mappings are migrated.

toggle Remarks

You can use this procedure to migrate tables to Adaptive Server Anywhere from a remote Oracle, DB2, SQL Server, Adaptive Server Enterprise, Adaptive Server Anywhere, or Access database. This procedure allows you to migrate in one step a set of remote tables, including their foreign key mappings, from the specified server. The sa_migrate stored procedure calls the following stored procedures:

  • sa_migrate_create_remote_table_list

  • sa_migrate_create_tables

  • sa_migrate_data

  • sa_migrate_create_remote_fks_list

  • sa_migrate_create_fks

  • sa_migrate_drop_proxy_tables

You might want to use these stored procedures instead of sa_migrate if you need more flexibility. For example, if you are migrating tables with foreign key relationships that are owned by different users, you cannot retain the foreign key relationships if you use sa_migrate.

Before you can migrate any tables, you must first create a remote server to connect to the remote database using the CREATE SERVER statement. You may also need to create an external login to the remote database using the CREATE EXTERNLOGIN statement.

For more information, see CREATE SERVER statement and CREATE EXTERNLOGIN statement.

You can migrate all the tables from the remote database to an Adaptive Server Anywhere database by specifying only the local_table_owner and server_name parameters. However, if you specify only these two parameters, all the tables that are migrated will belong to one owner in the target Adaptive Server Anywhere database. If tables have different owners on the remote database and you want them to have different owners on the Adaptive Server Anywhere database, then you must migrate the tables for each owner separately, specifying the local_table_owner and owner_name parameters each time you call the sa_migrate procedure. In order to use this procedure, you must have the necessary permissions to create tables for the local Adaptive Server Anywhere user.

Caution Do not specify NULL for both the table_name and owner_name parameters. Supplying NULL for both the table_name and owner_name parameters migrates all the tables in the database, including system tables. As well, tables that have the same name, but different owners in the remote database all belong to one owner in the target database. It is recommended that you migrate tables associated with one owner at a time.
toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_migrate_create_remote_table_list system procedure
  • sa_migrate_create_tables system procedure
  • sa_migrate_data system procedure
  • sa_migrate_create_remote_fks_list system procedure
  • sa_migrate_create_fks system procedure
  • sa_migrate_drop_proxy_tables system procedure
  • Migrating databases to Adaptive Server Anywhere
toggle Examples

The following statement migrates all the tables belonging to user p_chin from the remote database, including foreign key mappings; migrates the data in the remote tables; and drops the proxy tables when migration is complete. In this example, all the tables that are migrated belong to local_user in the target Adaptive Server Anywhere database.

CALL sa_migrate( 'local_user', 'server_a', NULL, 'p_chin', NULL, 1, 1, 1 )

The following statement migrates only the tables that belong to user remote_a from the remote database. In the target Adaptive Server Anywhere database, these tables belong to the user local_a. Proxy tables created during the migration are not dropped at completion.

CALL sa_migrate( 'local_a', 'server_a', NULL, 'remote_a', NULL, 1, 0, 1 )


sa_migrate_create_fks system procedure

toggle Function

Creates foreign keys for each table listed in the dbo.migrate_remote_fks_list table.

toggle Syntax

sa_migrate_create_fks ( local_table_owner )

toggle Arguments

  • local_table_owner This varchar(128) parameter specifies the user on the target Adaptive Server Anywhere database who owns the migrated foreign keys. If you want to migrate tables that belong to different user, you must execute this procedure for each user whose tables you want to migrate. The local_table_owner is created using the GRANT CONNECT statement. A value is required for this parameter.

    For more information, see GRANT statement.

toggle Remarks

The sa_migrate_create_fks stored procedure is used with the other migration stored procedures. These procedures must be executed in the following order:

  1. sa_migrate_create_remote_table_list

  2. sa_migrate_create_tables

  3. sa_migrate_data

  4. sa_migrate_create_remote_fks_list

  5. sa_migrate_create_fks

  6. sa_migrate_drop_proxy_tables

This procedure creates foreign keys for each table that is listed in the dbo.migrate_remote_fks_list table. The user specified by the local_table_owner argument owns the foreign keys in the target database.

If the tables in the target Adaptive Server Anywhere database do not all have the same owner, you must execute this procedure for each user who owns tables for which you need to migrate foreign keys.

As an alternative, you can migrate all tables in one step using the sa_migrate system procedure.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_migrate system procedure
  • sa_migrate_create_remote_table_list system procedure
  • sa_migrate_create_tables system procedure
  • sa_migrate_data system procedure
  • sa_migrate_create_remote_fks_list system procedure
  • sa_migrate_drop_proxy_tables system procedure
  • Migrating databases to Adaptive Server Anywhere
toggle Example

The following statement creates foreign keys based on the dbo.migrate_remote_fks_list table. The foreign keys belong to the user local_a on the local Adaptive Sever Anywhere database.

CALL sa_migrate_create_fks( 'local_a' )


sa_migrate_create_remote_fks_list system procedure

toggle Function

Populates the dbo.migrate_remote_fks_list table.

toggle Syntax

sa_migrate_create_remote_fks_list ( server_name )

toggle Arguments

  • server_name This varchar(128) parameter specifies the name of the remote server that is being used to connect to the remote database. The remote server is created with the CREATE SERVER statement. A value is required for this parameter.

    For more information, see CREATE SERVER statement.

toggle Remarks

The sa_migrate_create_remote_fks_list stored procedure is used with the other migration stored procedures. These procedures must be executed in the following order:

  1. sa_migrate_create_remote_table_list

  2. sa_migrate_create_tables

  3. sa_migrate_data

  4. sa_migrate_create_remote_fks_list

  5. sa_migrate_create_fks

  6. sa_migrate_drop_proxy_tables

This procedure populates the dbo.migrate_remote_fks_list table with a list of foreign keys that can be migrated from the remote database. You can delete rows from this table for foreign keys that you do not want to migrate.

As an alternative, you can migrate all tables in one step using the sa_migrate system procedure.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_migrate system procedure
  • sa_migrate_create_remote_table_list system procedure
  • sa_migrate_create_tables system procedure
  • sa_migrate_data system procedure
  • sa_migrate_create_fks system procedure
  • sa_migrate_drop_proxy_tables system procedure
  • Migrating databases to Adaptive Server Anywhere
toggle Example

The following statement creates a list of foreign keys that are in the remote database.

CALL sa_migrate_create_remote_fks_list ( 'server_a' )


sa_migrate_create_remote_table_list system procedure

toggle Function

Populates the dbo.migrate_remote_table_list table.

toggle Syntax

sa_migrate_create_remote_table_list (
server_name
[, table_name
[, owner_name
[, database_name ] ] ]
)

toggle Arguments

  • server_name This varchar(128) parameter specifies the name of the remote server that is being used to connect to the remote database. The remote server is created with the CREATE SERVER statement. A value is required for this parameter.

    For more information, see CREATE SERVER statement.

  • table_name This varchar(128) parameter specifies the name(s) of the tables that you want to migrate, or NULL to migrate all the tables. The default is NULL. Do not specify NULL for both the table_name and owner_name parameters.

  • owner_name This varchar(128) parameter specifies the user who owns the tables on the remote database that you want to migrate, or NULL to migrate all the tables. The default is NULL. Do not specify NULL for both the table_name and owner_name parameters

  • database_name This varchar(128) parameter specifies the name of the remote database from which you want to migrate tables. This parameter is NULL by default. When migrating tables from Adaptive Server Enterprise and Microsoft SQL Server databases, you must specify the database name.

toggle Remarks

The sa_migrate_create_remote_table_list stored procedure is used with the other migration stored procedures. These procedures must be executed in the following order:

  1. sa_migrate_create_remote_table_list

  2. sa_migrate_create_tables

  3. sa_migrate_data

  4. sa_migrate_create_remote_fks_list

  5. sa_migrate_create_fks

  6. sa_migrate_drop_proxy_tables

This procedure populates the dbo.migrate_remote_table_list table with a list of tables that can be migrated from the remote database. You can delete rows from this table for remote tables that you do not want to migrate.

If you do not want all the migrated tables to have the same owner on the target Adaptive Server Anywhere database, you must execute this procedure for each user whose tables you want to migrate.

As an alternative, you can migrate all tables in one step using the sa_migrate system procedure.

Caution Do not specify NULL for both the table_name and owner_name parameters. Supplying NULL for both the table_name and owner_name parameters migrates all the tables in the database, including system tables. As well, tables that have the same name, but different owners in the remote database all belong to one owner in the target database. It is recommended that you migrate tables associated with one owner at a time.
toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_migrate system procedure
  • sa_migrate_create_tables system procedure
  • sa_migrate_data system procedure
  • sa_migrate_create_remote_fks_list system procedure
  • sa_migrate_create_fks system procedure
  • sa_migrate_drop_proxy_tables system procedure
  • Migrating databases to Adaptive Server Anywhere
toggle Example

The following statement creates a list of tables that belong to the user remote_a on the remote database.

CALL sa_migrate_create_remote_table_list( 'server_a', NULL, 'remote_a', NULL )


sa_migrate_create_tables system procedure

toggle Function

Creates a proxy table and base table for each table listed in the dbo.migrate_remote_table_list table.

toggle Syntax

sa_migrate_create_tables ( local_table_owner )

toggle Arguments

  • local_table_owner This varchar(128) parameter specifies the user on the target Adaptive Server Anywhere database who owns the migrated tables. This user is created using the GRANT CONNECT statement. A value is required for this parameter.

    For more information, see GRANT statement.

toggle Remarks

The sa_migrate_create_tables stored procedure is used with the other migration stored procedures. These procedures must be executed in the following order:

  1. sa_migrate_create_remote_table_list

  2. sa_migrate_create_tables

  3. sa_migrate_data

  4. sa_migrate_create_remote_fks_list

  5. sa_migrate_create_fks

  6. sa_migrate_drop_proxy_tables

This procedure creates a base table and proxy table for each table listed in the dbo.migrate_remote_table_list table (created using the sa_migrate_create_remote_table_list procedure). These proxy tables and base tables are owned by the user specified by the local_table_owner argument. This procedure also creates the same primary key indexes and other indexes for the new table that the remote table has in the remote database.

If you do not want all the migrated tables to have the same owner on the target Adaptive Server Anywhere database, you must execute the sa_migrate_create_remote_table_list procedure and the sa_migrate_create_tables procedure for each user who will own migrated tables.

As an alternative, you can migrate all tables in one step using the sa_migrate system procedure.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_migrate system procedure
  • sa_migrate_create_remote_table_list system procedure
  • sa_migrate_data system procedure
  • sa_migrate_create_remote_fks_list system procedure
  • sa_migrate_create_fks system procedure
  • sa_migrate_drop_proxy_tables system procedure
  • Migrating databases to Adaptive Server Anywhere
toggle Example

The following statement creates base tables and proxy tables on the target Adaptive Server Anywhere database. These tables belong to the user local_a.

CALL sa_migrate_create_tables( 'local_a' )


sa_migrate_data system procedure

toggle Function

Migrates data from the remote database tables to the target Adaptive Server Anywhere database.

toggle Syntax

sa_migrate_data ( local_table_owner )

toggle Arguments

  • local_table_owner This varchar(128) parameter specifies the user on the target Adaptive Server Anywhere database who owns the migrated tables. This user is created using the GRANT CONNECT statement. A value is required for this parameter.

    For more information, see GRANT statement.

toggle Remarks

The sa_migrate_data stored procedure is used with the other migration stored procedures. These procedures must be executed in the following order:

  1. sa_migrate_create_remote_table_list

  2. sa_migrate_create_tables

  3. sa_migrate_data

  4. sa_migrate_create_remote_fks_list

  5. sa_migrate_create_fks

  6. sa_migrate_drop_proxy_tables

This procedure migrates the data from the remote database to the Adaptive Server Anywhere database for tables belonging to the user specified by the local_table_owner argument.

When the tables on the target Adaptive Server Anywhere database do not all have the same owner, you must execute this procedure for each user whose tables have data that you want to migrate.

As an alternative, you can migrate all tables in one step using the sa_migrate system procedure.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_migrate system procedure
  • sa_migrate_create_remote_table_list system procedure
  • sa_migrate_create_tables system procedure
  • sa_migrate_create_remote_fks_list system procedure
  • sa_migrate_create_fks system procedure
  • sa_migrate_drop_proxy_tables system procedure
  • Migrating databases to Adaptive Server Anywhere
toggle Example

The following statement migrates data to the target Adaptive Server Anywhere database for tables that belong to the user local_a.

CALL sa_migrate_data( 'local_a' )


sa_migrate_drop_proxy_tables system procedure

toggle Function

Drops the proxy tables that were created for migration purposes.

toggle Syntax

sa_migrate_drop_proxy_tables ( local_table_owner )

toggle Arguments

  • local_table_owner This varchar(128) parameter specifies the user on the target Adaptive Server Anywhere database who owns the proxy tables. This user is created using the GRANT CONNECT statement. A value is required for this parameter.

    For more information, see GRANT statement.

toggle Remarks

The sa_migrate_drop_proxy_tables stored procedure is used with the other migration stored procedures. These procedures must be executed in the following order:

  1. sa_migrate_create_remote_table_list

  2. sa_migrate_create_tables

  3. sa_migrate_data

  4. sa_migrate_create_remote_fks_list

  5. sa_migrate_create_fks

  6. sa_migrate_drop_proxy_tables

This procedure drops the proxy tables that were created for the migration. The user who owns these proxy tables is specified by the local_table_owner argument.

If the migrated tables are not all owned by the same user on the target Adaptive Server Anywhere database, you must call this procedure for each user in order to drop all the proxy tables.

As an alternative, you can migrate all tables in one step using the sa_migrate system procedure.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_migrate system procedure
  • sa_migrate_create_remote_table_list system procedure
  • sa_migrate_create_tables system procedure
  • sa_migrate_data system procedure
  • sa_migrate_create_remote_fks_list system procedure
  • sa_migrate_create_fks system procedure
  • Migrating databases to Adaptive Server Anywhere
toggle Example

The following statement drops the proxy tables on the target Adaptive Server Anywhere database that belong to the user local_a.

CALL sa_migrate_drop_proxy_tables( 'local_a' )


sa_procedure_profile system procedure

toggle Function

Reports information about the execution time for each line within procedures that have been executed in a database.

toggle Syntax

sa_procedure_profile (
[ p_object_name
[, p_owner_name
[, p_table_name ] ] ]
)

toggle Arguments

  • p_object_name This optional char(128) parameter specifies the name of the stored procedure, function, event, or trigger.

  • p_owner_name This optional char(128) parameter specifies the object's owner.

  • p_table_name This optional char(128) parameter specifies the table associated with a trigger (the value is NULL for other object types).

toggle Result sets
Column name | Data type | Description
object_type | char(1) | The type of object.
object_name | char(128) | The name of the stored procedure, function, event, or trigger. If the object_type is C or D, then this is the name of the foreign key for which the system trigger was defined.
owner_name | char(128) | The object's owner.
table_name | char(128) | The table associated with a trigger (the value is NULL for other object types).
line_num | unsigned integer | The line number within the procedure.
executions | unsigned integer | The number of times the line has been executed.
millisecs | unsigned integer | The time to execute the line, in milliseconds.
percentage | double | The percentage of the total execution time required for the specific line.
foreign_owner | char(128) | The database user who owns the foreign table for a system trigger.
foreign_table | char(128) | The name of the foreign table for a system trigger.
toggle Remarks

Before you can profile your database, you must enable profiling.

For more information about enabling procedure profiling, see sa_server_option system procedure.

The procedure accepts three optional arguments. If you specify more than one of these arguments, you must list them in the order shown (p_object_name, p_owner_name, p_table_name). The arguments are strings, and must be enclosed in single quotes. The server returns data for all procedures in the database if you do not include any arguments.

The result set includes information about the execution times for individual lines within procedures, and what percentage of the total procedure execution time those lines use. The DBA can use this profiling information to fine-tune slower procedures that may decrease performance. The procedure returns the same information for stored procedures, functions, events, and triggers as the Profile tab in Sybase Central.

The object_type field of the result set can be:

  • P stored procedure

  • F function

  • E event

  • T trigger

  • C ON UPDATE system trigger

  • D ON DELETE system trigger

By calling the procedures of interest before you begin a profiling session, you eliminate the start-up time required for procedures to load and for the database to access tables for the first time.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also
  • sa_server_option system procedure
  • sa_procedure_profile_summary system procedure
toggle Example

The following statement returns profiling information about the tr_manager trigger:

CALL sa_procedure_profile (p_object_name = 'tr_manager')


sa_procedure_profile_summary system procedure

toggle Function

Reports summary information about the execution times for all procedures that have been executed in a database.

toggle Syntax

sa_procedure_profile_summary (
[p_table_name
[, p_owner_name
[, p_object_name
[, p_object_type
[, p_ordering ] ] ] ] ]
)

toggle Arguments

The procedure accepts five optional arguments:

  • p_object_name This optional char(128) parameter specifies the name of the stored procedure, function, event, or trigger.

  • p_owner_name This optional char(128) parameter specifies the object's owner.

  • p_table_name This optional char(128) parameter specifies the table associated with a trigger (the value is NULL for other object types).

  • p_object_type This optional char(1) parameter specifies the type of object to profile. It can be one of the following:

    • P stored procedure

    • F function

    • E event

    • T trigger

    • S system trigger

    • C ON UPDATE system trigger

    • D ON DELETE system trigger

  • p_ordering This optional char(1) parameter determines the order of columns in the result set. If no value is given, the results are listed from the longest execution time to the shortest execution time. Values and the resulting order are:

    • P object_type, owner_name, object_name, table_name desc

    • N object_name, owner_name, table_name, object_type desc

    • O owner_name, object_type, object_name, table_name desc

    • T table_name, owner_name, object_name, object_type desc

    • E executions desc, object_name, owner_name, table_name, object_type desc

toggle Result sets
Column name | Data type | Description
object_type | char(1) | The type of object.
object_name | char(128) | The name of the stored procedure, function, event, or trigger.
owner_name | char(128) | The object's owner.
table_name | char(128) | The table associated with a trigger (the value is NULL for other object types).
executions | unsigned integer | The number of times each procedure has been executed.
millisecs | unsigned integer | The time to execute the procedure, in milliseconds.
foreign_owner | char(128) | The database user who owns the foreign table for a system trigger.
foreign_table | char(128) | The name of the foreign table for a system trigger.
toggle Remarks

Before you can profile your database, you must enable profiling.

For more information about enabling procedure profiling, see sa_server_option system procedure.

The procedure displays information about the usage frequency and efficiency of stored procedures, functions, events, and triggers. You can use this information to fine-tune slower procedures to improve database performance. The procedure returns the same information for stored procedures, functions, events, and triggers as the Profile tab in Sybase Central.

If you specify more than one argument, you must list them in the order shown (p_object_name, p_owner_name, p_table_name, p_object_type, p_ordering). If you specify any of these arguments, the procedure returns only rows that match the parameters; otherwise, the server returns data for all procedures in the database. Note that the argument values are strings, and must be enclosed in quotes.

The object_type field of the result set can be:

  • P stored procedure

  • F function

  • E event

  • T trigger

  • S system trigger

  • C ON UPDATE system trigger

  • D ON DELETE system trigger

By calling the procedures of interest before you begin a profiling session, you eliminate the start-up time required for procedures to load and for the database to access tables for the first time.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also
  • sa_server_option system procedure
  • sa_procedure_profile system procedure
toggle Example

The following statement returns profiling information about all the triggers owned by the DBA on the Product table:

CALL sa_procedure_profile_summary
(p_owner_name = 'dba', p_table_name = 'Product', p_object_type = 'T')


sa_recompile_views system procedure

toggle Function

Locates view definitions stored in the catalog that do not have column definitions and causes the column definitions to be created.

toggle Syntax

sa_recompile_views ( [ integer ] )

toggle Arguments

  • integer A non-zero value for this optional integer parameter will suppress errors.

toggle Remarks

This procedure is used to locate views in the catalog that do not have column definitions and execute an ALTER VIEW statement with the RECOMPILE clause to create the column definitions. The procedure does this for each view that does not have a column definition until there are none left that require compilation or until any remaining column definitions cannot be created. If the procedure is unable to recompile any views, an error is reported. Errors can be suppressed by specifying a non-zero parameter to this procedure.

Caution The sa_recompile_views system procedure should only be called from within a reload.sql script. This procedure is used by the Unload utility (dbunload) and should not be used explicitly.
toggle Permissions

DBA authority required

toggle Side effects

If any views exist for which column definitions have not been stored, an ALTER VIEW owner.viewname RECOMPILE statement is executed, causing an automatic commit.

toggle See also

  • FORCE_VIEW_CREATION option [database]

  • ALTER VIEW statement


sa_report_deadlocks system procedure

toggle Function

Retrieves information about deadlocks from an internal buffer created by the database server.

toggle Syntax

sa_report_deadlocks( )

toggle Result sets
Column name | Data type | Description
snapshotId | bigint | The deadlock instance (all rows pertaining to a particular deadlock have the same ID).
snapshotAt | timestamp | The time when the deadlock occurred.
waiter | int | The connection handle of the waiting connection.
who | varchar(128) | The user ID associated with the connection that is waiting.
what | long varchar | The command being executed by the waiting connection. This information is only available if you have turned on capturing of the most recently-prepared SQL statement by specifying the -zl option on the database server command line or have turned this feature on using the sa_server_option system procedure.
wait_on | bigint | The name of the lock being waited on.
owner | int | The connection handle of the connection owning the lock being waited on.
toggle Remarks

When the LOG_DEADLOCKS option is set to ON, the database server logs information about deadlocks in an internal buffer. You can view the information in the log using the sa_report_deadlocks stored procedure.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also

LOG_DEADLOCKS option [database]

Determining who is blocked


sa_reset_identity system procedure

toggle Function

Allows the next available identity value to be set for a table. Use this to change the autoincrement value for the next row.

toggle Syntax

sa_reset_identity (
[ table_name
[, owner
[, new_identity_value ] ] ]
)

toggle Arguments

  • table_name This optional varchar(128) parameter specifies the table you want to set the identity value for.

  • owner This optional varchar(128) parameter specifies the owner of the table you want to set the identity value for.

  • new_identity_value This optional bigint parameter specifies identifies the number from which you want to start the value counting.

toggle Remarks

The next value generated for a row inserted into the table will be new_identity_value + 1.

No checking occurs on the new_identity_value to ensure that it does not conflict with existing rows in the table. An invalid value could cause subsequent inserts to fail.

toggle Permissions

DBA authority required

toggle Side effects

Causes a checkpoint to occur after the value has been updated.

toggle Example

The following statement resets the identity value to 101:

CALL sa_reset_identity ('employee', 'dba', 100)


sa_rowgenerator system procedure

toggle Function

Returns a result set with rows between a specified start and end value.

toggle Syntax

sa_rowgenerator (
[ rstart
[, rend
[, rstep ] ] ])

toggle Arguments

  • rstart This optional integer parameter specifies the starting value. The default value is 0.

  • rend This optional integer parameter specifies the ending value. The default value is 100.

  • rstep This optional integer parameter specifies the increment by which the sequence values are increased. The default value is 1.

toggle Result sets
Column name | Data type | Description
row_num | integer | Sequence number.
toggle Remarks

The sa_rowgenerator procedure can be used in the FROM clause of a query to generate a sequence of numbers. This procedure is an alternative to using the RowGenerator system table. You can use sa_rowgenerator for such tasks as:

  • generating test data for a known number of rows in a result set.

  • generating a result set with rows for values in every range. For example, you can generate a row for every day of the month, or you can generate ranges of zip codes.

  • generating a query that has a specified number of rows in the result set. This may be useful for testing the performance of queries.

You can emulate the behavior of the RowGenerator table with the following statement:

SELECT row_num FROM sa_rowgenerator(1255)
toggle Permissions

None

toggle Side effects

None

toggle See also

RowGenerator system table

toggle Example

The following query returns a result set containing one row for each day of the current month.

SELECT dateadd(day,row_num-1,
        ymd(datepart(year,CURRENT DATE),
            datepart(month,CURRENT DATE),
            1)) AS day_of_month
FROM sa_RowGenerator(1,31,1)
WHERE datepart(month,day_of_month) =
   datepart(month,CURRENT DATE)
ORDER BY row_num

The following query shows how many employees live in zip code ranges (0-9999), (10000-19999), ..., (90000-99999). Some of these ranges have no employees, which causes the warning Null value eliminated in aggregate function (-109). The sa_rowgenerator procedure can be used to generate these ranges, even though no employees have a zip code in the range.

SELECT row_num AS r1, row_num+9999
 AS r2, count(zip_code) AS zips_in_range
FROM sa_rowgenerator(0,99999,10000) D LEFT JOIN employee
   ON zip_code BETWEEN r1 AND r2
GROUP BY r1, r2
ORDER BY 1

The following example generates 10 rows of data and inserts them into the emp table:

INSERT INTO emp(id, salary, name)
SELECT row_num,
   CAST( rand() * 1000 AS INTEGER),
   'Mary'
FROM sa_rowgenerator(1, 10)


sa_send_udp system procedure

toggle Function

Sends a UDP packet to the specified address.

toggle Syntax

sa_send_udp ( destAddress, destPort, msg )

toggle Arguments

  • destAddress This char(254) parameter can be either the host name or IP number.

  • destPort This UNSIGNED SMALLINT parameter specifies the port number to use.

  • msg This LONG BINARY parameter contains the message to send to the specified address. If this value is a string, it must be enclosed in single quotes.

toggle Remarks

This procedure sends a single UDP packet to the specified address. The procedure returns 0 if the message is sent successfully, and returns an error code if an error occurs. The error code is one of the following:

  • -1 if the message is too large to send over a UDP socket (as determined by the operating system) or if there is a problem with the destination address

  • the Winsock/Posix error code that is returned by the operating system

If the msg parameter contains binary data or is more complex than a string, you may want to use a variable. For example,

CREATE VARIABLE v LONG BINARY;
SET v='This is a UDP message';
SELECT dbo.sa_send_udp( '10.25.99.124', 1234, v );
DROP VARIABLE v;

This procedure can be used with MobiLink server-initiated synchronization to wake up the Listener utility (dblsn.exe). If you use sa_send_udp as a way to notify the Listener, you should append a 1 to your UDP packet. This number is a server-initiated synchronization protocol number. In future versions of MobiLink, new protocol versions may cause the Listener to behave differently.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also

Notifying the Listener with sa_send_udp

toggle Example

The following example sends the message "This is a test" to IP address 10.25.99.196 on port 2345:

CALL sa_send_udp ( 10.25.99.196, 2345, 'This is a test' )


sa_server_option system procedure

toggle Function

Overrides a server option while the server is running.

toggle Syntax

sa_server_option ( option_name, option_value )

toggle Arguments

  • option_name This char(128) parameter specifies a server option name.

  • option_value This char(128) parameter specifies the new value for the server option.

toggle Remarks

Database administrators can use this procedure to override some database server options without restarting the database server.

The option values that are changed using this procedure are reset to their default values when the server shuts down. If you want to change an option value every time the server is started, you can specify the corresponding server option if one exists.

The options that can be reset are as follows:

Option name | Values | Default | Server option
ConnsDisabled | ON or OFF | OFF |
LivenessTimeout | integer, in seconds | 120 | -tl server option
Procedure_profiling | ON, OFF, RESET, CLEAR | OFF |
ProfileFilterConn | connection-id |  |
ProfileFilterUser | user-id |  |
QuittingTime | valid date and time |  | -tq server option
RememberLastStatement | ON or OFF | OFF | -zl server option
RequestFilterConn | connection-id, -1 |  |
RequestFilterDB | database-id, -1 |  |
RequestLogFile | Filename |  | -zo server option
RequestLogging | ALL, SQL, NONE, SQL+hostvars | NONE | -zr server option
RequestLogMaxSize | File-size, in bytes |  | -zs server option
RequestLogNumFiles | integer |  | -zn server option

ConnsDisabled

When set to ON, no other connections are allowed to any databases on the database server.

LivenessTimeout

A liveness packet is sent periodically across a client/server TCP/IP or SPX network to confirm that a connection is intact. If the network server runs for a LivenessTimeout period without detecting a liveness packet, the communication is severed.

For more information, see -tl server option.

Procedure_profiling

Controls procedure profiling for stored procedures, functions, events, and triggers. Procedure profiling shows you how long it takes your stored procedures, functions, events, and triggers to execute, as well as how long each line takes to execute. You can also set procedure profiling options on the Database property sheet in Sybase Central.

  • ON enables procedure profiling for the database you are currently connected to.

  • OFF disables procedure profiling and leaves the profiling data available for viewing.

  • RESET returns the profiling counters to zero, without changing the ON or OFF setting.

  • CLEAR returns the profiling counters to zero and disables procedure profiling.

Once profiling is enabled, you can use the sa_procedure_profile_summary and sa_procedure_profile stored procedures to retrieve profiling information from the database.

For more information about procedure profiling, see Profiling database procedures.

ProfileFilterConn

Instruct the database server to capture profiling information for a specific connection ID.

ProfileFilterUser

Instruct the database server to capture profiling information for a specific user ID.

QuittingTime

Instruct the database server to shut down at the specified time.

For more information, see -tq server option.

RememberLastStatement

Instruct the database server to capture the most recently-prepared SQL statement for each connection to databases on the server. For stored procedure calls, only the outermost procedure call appears, not the statements within the procedure.

You can obtain the current value of the RememberLastStatement setting using the RememberLastStatement property function as follows:

SELECT property( 'RememberLastStatement' )

For more information, see Server-level properties and -zl server option.

When RememberLastStatement is turned on, the following statement returns the most recently-prepared statement for the specified connection.

SELECT connection_property( 'LastStatement', conn_id )

The stored procedure sa_conn_activity returns this same information for all connections.

Caution When -zl is specified or when the RememberLastStatement server setting is turned on, any user can call the sa_conn_activity system procedure or obtain the value of the LastStatement connection property to find out the most recently-prepared SQL statement for any other user. This option should be used with caution and turned off when it is not required.

RequestFilterConn

Filter the request logging information so that only information for a particular connection is logged. This can help reduce the size of the request log file when monitoring a server with many active connections or multiple databases. You can obtain the connection ID by executing the following:

CALL sa_conn_info()

To specify a specific connection to be logged once you have obtained the connection ID, execute the following:

CALL sa_server_option( 'RequestFilterConn', connection-id )

Filtering remains in effect until it is explicitly reset, or until the database server is shut down. To reset filtering, use the following statement:

CALL sa_server_option( 'RequestFilterConn', -1)

RequestFilterDB

Filter the request logging information so that only information for a particular database is logged. This can help reduce the size of the request log file when monitoring a server with many active connections or multiple databases. You can obtain the database ID by executing the following statement when you are connected to the desired database:

SELECT connection_property( 'DBNumber' )

To specify that only information for a particular database is to be logged, execute the following:

CALL sa_server_option( 'RequestFilterDB', database-id )

Filtering remains in effect until it is explicitly reset, or until the database server is shut down. To reset filtering, use the following statement:

CALL sa_server_option( 'RequestFilterDB', -1 )

RequestLogFile

The name of the file used to record logging information. A name of NULL stops logging to file. Any backslash characters in the filename must be doubled as this is a SQL string.

For more information, see -zo server option.

RequestLogging

Can be ALL, SQL, NONE, or SQL+hostvars. ON and ALL are equivalent. OFF and NONE are equivalent. This call turns on logging of individual SQL statements sent to the database server, for use in troubleshooting, in conjunction with the database server -zr and -zo options.

When you set RequestLogging to OFF, the request log file is closed.

If you select SQL, only the following types of request are recorded:

  • START DATABASE

  • STOP ENGINE

  • STOP DATABASE

  • Statement preparation

  • Statement execution

  • EXECUTE IMMEDIATE statements

  • Option settings

  • COMMIT statements

  • ROLLBACK statements

  • PREPARE TO COMMIT operations

  • Connections

  • Disconnections

  • Beginnings of transactions

  • DROP STATEMENT statement

  • Cursor explanations

  • Cursor closings

  • Cursor resume

  • Errors

Setting RequestLogging to SQL+hostvars outputs both SQL (as though you specified ('RequestLogging', 'SQL')) and host variable values to the log.

You can find the current value of the RequestLogging setting using property('RequestLogging').

For more information, see -zr server option, and Server-level properties.

RequestLogMaxSize

The maximum size of the file used to record logging information, in bytes.

When the request log file reaches the size specified by either the sa_server_option system procedure or the -zs server option, the file is renamed with the extension .old appended (replacing an existing file with the same name if one exists). The request log file is then restarted.

For more information, see -zs server option.

RequestLogNumFiles

The number of request log file copies to retain.

If request logging is enabled over a long period of time, the request log file can become large. The –zn option allows you to specify the number of request log file copies to retain.

For more information, see -zn server option.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle Example

The following statement disallows new connections to the database server.

CALL sa_server_option( 'ConnsDisabled', 'ON')


sa_set_http_header system procedure

toggle Function

Permits a web service to set an HTTP header in the result.

toggle Syntax

sa_set_http_header ( field-name, value )

toggle Arguments

  • field-name This char(128) parameter specifies a string containing the name of one of the HTTP header fields.

  • value This long varchar parameter specifies the value to which the named parameter should be set.

toggle Remarks

Setting the special header field @HttpStatus sets the status code returned with the request. For example, the following command sets the status code to 404 Not Found.

call dbo.sa_set_http_header( '@HttpStatus', '404' )

The body of the error message is inserted automatically. Only valid HTTP error codes can be used. Setting the status to an invalid code causes a SQL error.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_set_http_option system procedure
toggle Example

The following example sets the Content-Type header field to text/html.

call dbo.sa_set_http_header( 'Content-Type', 'text/html' )


sa_set_http_option system procedure

toggle Function

Permits a web service to set an HTTP option in the result.

toggle Syntax

sa_set_http_option ( option-name, value )

toggle Arguments

  • option-name This char(128) parameter specifies a string containing the name of one of the HTTP options.

  • value This long varchar parameter specifies the value to which the named option should be set.

toggle Remarks

Use this procedure within statements or procedures that handle web services to set options within an HTTP result set.

Currently only one option is supported:

  • CharsetConversion Controls whether the result set is to be automatically converted from the character set of the database to the character set of the client. The only permitted values are ON and OFF. The default value is ON.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_set_http_header system procedure


sa_statement_text system procedure

toggle Function

Formats a SELECT statement so that individual items appear on separate lines. This is useful when viewing long statements from the request log, in which all newline characters are removed.

toggle Syntax

sa_statement_text ( select-statement )

toggle Arguments

  • select-statement This long varchar parameter contains a select statement.

toggle Remarks

The select-statement that is entered must be a string (in single quotes) or a string expression.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sa_get_request_times system procedure
  • sa_get_request_profile system procedure
toggle Example

The following call formats a SELECT statement so that individual items appear on separate lines.

CALL sa_statement_text('SELECT * FROM car WHERE name=''Audi''')
 | stmt_text
1 | select *
2 | FROM car
3 | WHERE name = 'Audi'


sa_table_fragmentation system procedure

toggle Function

Reports information about the fragmentation of database tables.

toggle Syntax

sa_table_fragmentation (
[ table_name
[, owner_name ] ]
)

toggle Arguments

  • table_name This char(128) parameter specifies a table name.

  • owner_name This char(128) parameter specifies an owner name.

toggle Result sets
Column name | Data type | Description
TableName | char(128) | Name of the table.
rows | unsigned integer | Number of rows in the table.
row_segments | unsigned bigint | Number of row segments in the table.
segs_per_row | double | Number of segments per row.
toggle Remarks

Database administrators can use this procedure to obtain information about the fragmentation in a database's tables. If no arguments are supplied, results are returned for all tables in the database.

When database tables become excessively fragmented, you can run REORGANIZE TABLE or rebuild the database to reduce table fragmentation and improve performance.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also
  • Table fragmentation
  • Defragmenting tables
  • Rebuilding databases
  • REORGANIZE TABLE statement


sa_table_page_usage system procedure

toggle Function

Reports information about the page usage of database tables.

toggle Syntax

sa_table_page_usage ( )

toggle Result sets
Column name | Data type | Description
TableId | unsigned integer | The table id.
TablePages | integer | The number of table pages used by the table.
PctUsedT | integer | The percentage of used table page space.
IndexPages | integer | The number of index pages used by the table.
PctUsedI | integer | The percentage of used index page space.
PctOfFile | integer | The percentage of the total database file the table occupies.
TableName | char(128) | The table name.
toggle Remarks

The results include the same information provided by the Information utility.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle See also
  • The Information utility


sa_validate system procedure

toggle Function

Validates all tables in a database.

toggle Syntax

sa_validate (
[ tbl_name
[, owner_name
[, check_type ] ] ] )

toggle Arguments

  • tbl_name This varchar(128) parameter specifies a table name. If this parameter is NULL (the default), sa_validate validates all tables.

  • owner_name This varchar(128) parameter specifies an owner name. If this parameter is NULL (the default), sa_validate validates tables for all users.

  • check_type When this char(10) parameter is NULL (the default), each table is checked using a VALIDATE TABLE statement with no additional checks. The check_type value can be one of the following:

    • data Validate tables using WITH DATA CHECK.

    • index Validate tables using WITH INDEX CHECK.

    • full Validate tables using WITH FULL CHECK.

    • express Validate tables using WITH EXPRESS CHECK.

    • checksum Validate database pages using checksums.

      For more information about checksum validation, see Ensuring your database is valid.

toggle Permissions

DBA authority required

toggle Side effects

None

toggle Remarks

This procedure is equivalent to calling the VALIDATE TABLE statement for each table in the database.

For information, see VALIDATE TABLE statement.

All of the values for the tbl_name, owner_name, and check_type arguments are strings and they must be enclosed in quotes.

The procedure returns a single column, named Messages. If all tables are valid, the column contains No error detected.

Caution Validating a table or an entire database should be performed while no connections are making changes to the database; otherwise, spurious errors may be reported indicating some form of database corruption even though no corruption actually exists.
toggle Example

The following statement validates all of the tables owned by the DBA with an index check:

CALL sa_validate (owner_name = 'DBA', check_type = 'index')


sa_verify_password system procedure

toggle Function

Validates the password of the current user.

toggle Syntax

sa_verify_password ( string )

toggle Arguments

  • string This char(128) parameter specifies the password of the current database user.

toggle Remarks

This procedure is used by sp_password. If the password matches, the procedure simply returns. If it does not match, the error Invalid user ID or password is returned.

toggle Permissions

None

toggle Side effects

None

toggle See also

Adaptive Server Enterprise system procedures


sp_login_environment system procedure

toggle Function

Sets connection options when users log in.

toggle Syntax

sp_login_environment ( )

toggle Remarks

sp_login_environment is the default procedure called by the LOGIN_PROCEDURE database option.

It is recommended that you do not edit this procedure. Instead, to change the login environment, set the LOGIN_PROCEDURE option to point to a different procedure.

Here is the text of the sp_login_environment procedure:

CREATE PROCEDURE dbo.sp_login_environment()
BEGIN
  IF connection_property('CommProtocol')='TDS' THEN
    CALL dbo.sp_tsql_environment()
  END IF
END
toggle Permissions

None

toggle Side effects

None

toggle See also
  • LOGIN_PROCEDURE option [database]


sp_remote_columns system procedure

toggle Function

Produces a list of the columns in a remote table and a description of their data types.

The server must be defined with the CREATE SERVER statement to use this system procedure.

toggle Syntax

sp_remote_columns (
@server_name,
@table_name
[, @table_owner
[, @table_qualifier] ]
)

toggle Arguments

  • @server_name This char(128) parameter specifies a string containing the server name as specified by the CREATE SERVER statement.

  • @table_name This char(128) parameter specifies a table name.

  • @table_owner This optional char(128) parameter specifies the table owner.

  • @table_qualifier This optional char(128) parameter specifies the database name.

toggle Result sets
Column name | Data type | Description
database | char(128) | The database name.
owner | char(128) | The database owner name.
table_name | char(128) | The table name.
column_name | char(128) | The name of a column.
domain_id | smallint | An integer which indicates the data type of the column.
width | smallint | The meaning of this field depends on the data type. For character types width represents the number of characters.
scale | smallint | The meaning of this field depends on the data type. For numeric data types scale is the number of digits after the decimal point.
nullable | smallint | If null column values are allowed this field is 1. Otherwise nullable is 0.
toggle Remarks

If you are entering a CREATE EXISTING statement and you are specifying a column list, it may be helpful to get a list of the columns that are available on a remote table. sp_remote_columns produces a list of the columns on a remote table and a description of their data types. If you specify a database, you must either specify an owner or provide the value null.

toggle Standards and compatibility

  • Sybase Supported by Open Client/Open Server.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • Accessing Remote Data
  • Server Classes for Remote Data Access
  • CREATE SERVER statement
toggle Example

The following example returns columns from the SYSOBJECTS table in the production database on an Adaptive Server Enterprise server named asetest. The owner is unspecified.

CALL sp_remote_columns( 'asetest', 'sysobjects',
null, 'production' )


sp_remote_exported_keys system procedure

toggle Function

Provides information about tables with foreign keys on a specified primary table.

The server must be defined with the CREATE SERVER statement to use this system procedure.

toggle Syntax

sp_remote_exported_keys (
@server_name,
@sp_name
[, @sp_owner
[, @sp_qualifier ] ]
)

toggle Arguments

  • @server_name This char(128) parameter specifies identifies the server the primary table is located on. A value is required for this parameter.

  • @sp_name This char(128) parameter specifies the table containing the primary key. A value is required for this parameter.

  • @sp_owner This optional char(128) parameter specifies the primary table's owner.

  • @sp_qualifier This optional char(128) parameter specifies the database containing the primary table. This parameter is optional.

toggle Result sets
Column name | Data type | Description
pk_database | char(128) | The database containing the primary key table.
pk_owner | char(128) | The owner of the primary key table.
pk_table | char(128) | The primary key table.
pk_column | char(128) | The name of the primary key column.
fk_database | char(128) | The database containing the foreign key table.
fk_owner | char(128) | The foreign key table's owner.
fk_table | char(128) | The foreign key table.
fk_column | char(128) | The name of the foreign key column.
key_seq | smallint | The key sequence number.
fk_name | char(128) | The foreign key name.
pk_name | char(128) | The primary key name.
toggle Remarks

This procedure provides information about the remote tables that have a foreign key on a particular primary table. The sp_remote_exported_keys stored procedure's result set includes the database, owner, table, column, and name for both the primary and the foreign key, as well as the foreign key sequence for the foreign key columns. The result set may vary because of the underlying ODBC and JDBC calls, but information about the table and column for a foreign key is always returned.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • CREATE SERVER statement
  • Tables are related by foreign keys
toggle Example

To get information about the remote tables with foreign keys on the SYSOBJECTS table, in the production database, in a server named asetest:

CALL sp_remote_exported_keys (
     @server_name='asetest',
     @sp_name='sysobjects',
     @sp_qualifier='production')


sp_remote_imported_keys system procedure

toggle Function

Provides information about remote tables with primary keys that correspond to a specified foreign key.

The server must be defined with the CREATE SERVER statement to use this system procedure.

toggle Syntax

sp_remote_imported_keys (
@server_name,
@sp_name
[, @sp_owner
[, @sp_qualifier ] ]
)

toggle Arguments

  • @server_name This optional char(128) parameter specifies the server the foreign key table is located on. A value is required for this parameter.

  • @sp_name This optional char(128) parameter specifies the table containing the foreign key. A value is required for this parameter.

  • @sp_owner This optional char(128) parameter specifies the foreign key table's owner.

  • @sp_qualifier This optional char(128) parameter specifies the database containing the foreign key table.

toggle Result sets
Column name | Data type | Description
pk_database | char(128) | The database containing the primary key table.
pk_owner | char(128) | The owner of the primary key table.
pk_table | char(128) | The primary key table.
pk_column | char(128) | The name of the primary key column.
fk_database | char(128) | The database containing the foreign key table.
fk_owner | char(128) | The foreign key table's owner.
fk_table | char(128) | The foreign key table.
fk_column | char(128) | The name of the foreign key column.
key_seq | smallint | The key sequence number.
fk_name | char(128) | The foreign key name.
pk_name | char(128) | The primary key name.
toggle Remarks

Foreign keys reference a row in a separate table that contains the corresponding primary key. This procedure allows you to obtain a list of the remote tables with primary keys that correspond to a particular foreign table. The sp_remote_imported_keys result set includes the database, owner, table, column, and name for both the primary and the foreign key, as well as the foreign key sequence for the foreign key columns. The result set may vary because of the underlying ODBC and JDBC calls, but information about the table and column for a primary key is always returned.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • CREATE SERVER statement
  • Tables are related by foreign keys
toggle Example

To get information about the tables with primary keys that correspond to a foreign key on the SYSOBJECTS table in the asetest server:

CALL sp_remote_imported_keys (
     @server_name='asetest',
     @sp_name='sysobjects',
     @sp_qualifier='production')


sp_remote_primary_keys system procedure

toggle Function

Provides primary key information about remote tables using remote data access.

toggle Syntax

sp_remote_primary_keys (
@server_name
[, @table_name
[, @table_owner
[, @table_qualifier ] ] ]
)

toggle Arguments

  • @server_name This char(128) parameter specifies the server the remote table is located on.

  • @table_name This optional char(128) parameter specifies the remote table.

  • @table_owner This optional char(128) parameter specifies the owner of the remote table.

  • @table_qualifier This optional char(128) parameter specifies the name of the remote database.

toggle Result sets
Column name | Data type | Description
database | char(128) | The name of the remote database.
owner | char(128) | The owner of the remote table.
table_name | char(128) | The remote table.
column_name | char(128) | The column name.
key_seq | smallint | The primary key sequence number.
pk_name | char(128) | The primary key name.
toggle Remarks

This stored procedure provides primary key information about remote tables using remote data access.

Because of differences in the underlying ODBC/JDBC calls, the information returned differs slightly in terms of the catalog/database value depending upon the remote data access class that is specified for the server. However, the important information (for example, column name) is as expected.

toggle Standards and compatibility

Sybase Supported by Open Client/Open Server.

toggle Permissions

None

toggle Side effects

None


sp_remote_tables system procedure

toggle Function

Returns a list of the tables on a server.

The server must be defined with the CREATE SERVER statement to use this system procedure.

toggle Syntax

sp_remote_tables (
@server_name
[, @table_name
[, @table_owner
[, @table_qualifier
[, @with_table_type ] ] ] ]
)

toggle Arguments

  • @server_name This char(128) parameter specifies the server the remote table is located on.

  • @table_name This char(128) parameter specifies the remote table.

  • @table_owner This char(128) parameter specifies the owner of the remote table.

  • @table_qualifier This char(128) parameter specifies the database.

  • @with_table_type Specifies the type of remote table. This argument is a bit type and accepts two values, 0 (the default) and 1. You must enter the value 1 if you want the result set to include a column that lists table types.

toggle Result sets
Column name | Data type | Description
database | char(128) | The name of the remote database.
owner | char(128) | The name of the remote database owner.
table_name | char(128) | The remote table.
table_type | char(128) | Specifies the table type. The value of this field depends on the type of remote server. For example, TABLE, VIEW, SYS, and GBL TEMP are possible values.
toggle Remarks

It may be helpful when you are configuring your database server to get a list of the remote tables available on a particular server. This procedure returns a list of the tables on a server.

The procedure accepts five parameters. If a table, owner, or database name is given, the list of tables will be limited to only those that match the arguments.

toggle Standards and compatibility

  • Sybase Supported by Open Client/Open Server.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • Accessing Remote Data
  • Server Classes for Remote Data Access
  • CREATE SERVER statement
toggle Examples

To get a list of all of the Microsoft Excel worksheets available from an ODBC data source referenced by a server named excel:

call sp_remote_tables ( 'excel' )

To get a list of all of the tables owned by fred in the production database in an Adaptive Server Enterprise server named asetest:

call sp_remote_tables ( 'asetest', null, 'fred', 'production' )


sp_servercaps system procedure

toggle Function

Displays information about a remote server's capabilities.

The server must be defined with the CREATE SERVER statement to use this system procedure.

toggle Syntax

sp_servercaps ( servername )

toggle Arguments

  • severname This char(64) parameter specifies a server defined with the CREATE SERVER statement.

toggle Remarks

This procedure displays information about a remote server's capabilities. Adaptive Server Anywhere uses this capability information to determine how much of a SQL statement can be forwarded to a remote server. The system tables that contain server capabilities are not populated until after Adaptive Server Anywhere first connects to the remote server. This information comes from SYSCAPABILITY and SYSCAPABILITYNAME. The servername specified must be the same servername used in the CREATE SERVER statement.

toggle Standards and compatibility

  • Sybase Supported by Open Client/Open Server.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • Accessing Remote Data
  • Server Classes for Remote Data Access
  • CREATE SERVER statement
toggle Example

To display information about the remote server testasa:

CALL sp_servercaps ( 'testasa' )


sp_tsql_environment system procedure

toggle Function

Sets connection options when users connect from jConnect or Open Client applications.

toggle Syntax

sp_tsql_environment ( )

toggle Remarks

The sp_login_environment procedure is the default procedure specified by the LOGIN_PROCEDURE database option. For each new connection, the procedure specified by LOGIN_PROCEDURE is called. If the connection uses the TDS communications protocol (that is, if it is an Open Client or jConnect connection), then sp_login_environment in turn calls sp_tsql_environment.

This procedure sets database options so that they are compatible with default Sybase Adaptive Server Enterprise behavior.

If you wish to change the default behavior, it is recommended that you create new procedures and alter your LOGIN_PROCEDURE option to point to these new procedures.

toggle Permissions

None

toggle Side effects

None

toggle See also
  • sp_login_environment system procedure
  • LOGIN_PROCEDURE option [database].
toggle Example

Here is the text of the sp_tsql_environment procedure:

CREATE PROCEDURE dbo.sp_tsql_environment()
BEGIN
  IF db_property('IQStore')='OFF' THEN
    -- ASA datastore
    SET TEMPORARY OPTION AUTOMATIC_TIMESTAMP='ON'
  END IF;
  SET TEMPORARY OPTION ANSINULL='OFF';
  SET TEMPORARY OPTION TSQL_VARIABLES='ON';
  SET TEMPORARY OPTION ANSI_BLANKS='ON';
  SET TEMPORARY OPTION TSQL_HEX_CONSTANT='ON';
  SET TEMPORARY OPTION CHAINED='OFF';
  SET TEMPORARY OPTION QUOTED_IDENTIFIER='OFF';
  SET TEMPORARY OPTION ALLOW_NULLS_BY_DEFAULT='OFF';
  SET TEMPORARY OPTION FLOAT_AS_DOUBLE='ON';
  SET TEMPORARY OPTION ON_TSQL_ERROR='CONTINUE';
  SET TEMPORARY OPTION ISOLATION_LEVEL='1';
  SET TEMPORARY OPTION DATE_FORMAT='YYYY-MM-DD';
  SET TEMPORARY OPTION TIMESTAMP_FORMAT='YYYY-MM-DD HH:NN:SS.SSS';
  SET TEMPORARY OPTION TIME_FORMAT='HH:NN:SS.SSS';
  SET TEMPORARY OPTION DATE_ORDER='MDY';
  SET TEMPORARY OPTION ESCAPE_CHARACTER='OFF'
  SET TEMPORARY OPTION CLOSE_ON_ENDTRANS='OFF'
END


System extended stored procedures

A set of system extended procedures are included in Adaptive Server Anywhere databases. These procedures are owned by the dbo user ID. Users must be granted EXECUTE permission before they can use these procedures, unless they already have DBA authority.

The following sections describe each of the stored procedures.


Extended stored procedures for MAPI and SMTP

Adaptive Server Anywhere includes system procedures for sending electronic mail using the Microsoft Messaging API standard (MAPI) or the Internet standard Simple Mail Transfer Protocol (SMTP). These system procedures are implemented as extended stored procedures: each procedure calls a function in an external DLL.

In order to use the MAPI or SMTP stored procedures, a MAPI or SMTP e-mail system must be accessible from the database server machine.

The stored procedures are:

  • xp_startmail Starts a mail session in a specified mail account by logging onto the MAPI message system

  • xp_startsmtp Starts a mail session in a specified mail account by logging onto the SMTP message system

  • xp_sendmail Sends a mail message to specified users

  • xp_stopmail Closes the MAPI mail session

  • xp_stopsmtp Closes the SMTP mail session

The following procedure notifies a set of people that a backup has been completed.

CREATE PROCEDURE notify_backup()
BEGIN
   CALL xp_startmail( mail_user='ServerAccount',
                  mail_password='ServerPassword'
                     );
   CALL xp_sendmail( recipient='IS Group',
                     subject='Backup',
                     "message"='Backup completed'
                     );
   CALL xp_stopmail( )
END

The mail system procedures are discussed in the following sections.

xp_startmail system procedure
xp_startsmtp system procedure
xp_sendmail system procedure
xp_stopmail system procedure
xp_stopsmtp system procedure
Return codes for MAPI and SMTP stored procedures


xp_startmail system procedure
toggle Function

Starts an e-mail session under MAPI.

toggle Syntax

[ [ variable = ] CALL ] xp_startmail (
[ mail_user = mail-login-name ]
[, mail_password = mail-password ] )

toggle Arguments

  • mail_user This long varchar parameter specifies the MAPI login name.

  • mail_password This long varchar parameter specifies the MAPI password.

toggle Permissions

Not supported on NetWare.

toggle Remarks

xp_startmail is a system stored procedure that starts an e-mail session.

If you are using Microsoft Exchange, the mail-login-name argument is an Exchange profile name, and you should not include a password in the procedure call.

toggle Return codes

For a list of return codes, see MAPI return codes.


xp_startsmtp system procedure
toggle Function

Starts an e-mail session under SMTP.

toggle Syntax

[ [ variable = ] CALL ] xp_startsmtp (
smtp_sender = email-address,
smtp_server = smtp-server
[ , smtp_port = port-number ]
[ , timeout = timeout ] )

toggle Arguments

  • smtp_sender This long varchar parameter specifies the e-mail address of the sender.

  • smtp_server This long varchar parameter specifies which SMTP server to use, and is the server name or IP address.

  • smtp_port This integer parameter specifies the port number to connect to on the SMTP server. The default is 25.

  • timeout This integer parameter specifies how long to wait, in seconds, for a response from the server before aborting the current call to xp_sendmail. The default is 60 seconds.

toggle Permissions

Not supported on NetWare.

toggle Remarks

xp_startsmtp is a system stored procedure that starts a mail session for a specified e-mail address by connecting to an SMTP server.

xp_startsmtp starts a connection to a server. This connection will time out. Therefore, it is recommended that you start SMTP just before you want to execute xp_sendmail.

xp_sendmail over SMTP does not support attachments.

toggle Return codes

For a list of return codes, see SMTP return codes.


xp_sendmail system procedure
toggle Function

Sends an e-mail message.

toggle Syntax

[ [ variable = ] CALL ] xp_sendmail (
recipient = mail-address
[, subject = subject ]
[, cc_recipient = mail-address ]
[, bcc_recipient = mail-address ]
[, "message" = message-body ]
[, include_file = file-name ] )

toggle Arguments

  • recipient This long varchar parameter specifies the recipient mail address.

  • subject This long varchar parameter specifies the subject field of the message.

  • cc_recipient This long varchar parameter specifies the cc recipient field of the message.

  • bcc_recipient This long varchar parameter specifies the cc recipient field of the message.

  • "message" This long varchar parameter specifies the message contents.

  • include_file This long varchar parameter specifies an attachment file.

toggle Permissions

Must have executed xp_startmail to start an e-mail session under MAPI, or xp_startsmtp to start an e-mail session under SMTP.

Not supported on NetWare.

toggle Remarks

xp_sendmail is a system stored procedure that sends an e-mail message to the specified recipients once a session has been started with xp_startmail or xp_startsmtp. The procedure accepts messages of any length.

The argument values are strings. The length of each argument is limited only by the amount of available memory on your system. The "message" parameter name requires double quotes around it because MESSAGE is a reserved word.

An attachment file specified by include_file must exist on the database server machine.

xp_sendmail over SMTP does not support attachments.

toggle Return codes

For a list of return codes, see Return codes for MAPI and SMTP stored procedures.

toggle Example

The following call sends a message to the user ID Sales Group containing the file prices.doc as a mail attachment:

CALL xp_sendmail(recipient='Sales Group',
      subject='New Pricing',
      include_file = 'C:\\DOCS\\PRICES.DOC' )


xp_stopmail system procedure
toggle Function

Closes a MAPI e-mail session.

toggle Syntax

[ variable = ] [ CALL ] xp_stopmail ()

toggle Permissions

Not supported on NetWare.

toggle Remarks

xp_stopmail is a system stored procedure that ends an e-mail session.

toggle Return codes

For a list of return codes, see MAPI return codes.


xp_stopsmtp system procedure
toggle Function

Closes an SMTP e-mail session.

toggle Syntax

[ variable = ] [ CALL ] xp_stopsmtp ()

toggle Permissions

Not supported on NetWare

toggle Remarks

xp_stopsmtp is a system stored procedure that ends an e-mail session.

toggle Return codes

For a list of return codes, see SMTP return codes.


Return codes for MAPI and SMTP stored procedures

Extended stored procedures for MAPI and SMTP use the following return codes.

MAPI return codes
Return code | Meaning
0 | Success.
2 | xp_startmail failed.
3 | xp_stopmail failed.
5 | xp_sendmail failed.
11 | Ambiguous recipient.
12 | Attachment not found.
13 | Disk full.
14 | Failure
15 | Insufficient memory.
16 | Invalid session.
17 | Text too large.
18 | Too many files.
19 | Too many recipients.
20 | Unknown recipient.
21 | Login failure.
22 | Too many sessions.
23 | User abort.
24 | No MAPI.
25 | No startmail.
SMTP return codes
Return code | Meaning
0 | Success.
100 | Socket error.
101 | Socket timeout.
102 | Unable to resolve the SMTP server hostname.
103 | Unable to connect to the SMTP server.
104 | Server error; response not understood. (For example, the message is poorly formatted, or the server is not SMTP).
421 | <domain> service not available, closing transmission channel.
450 | Requested mail action not taken: mailbox unavailable.
451 | Requested action not taken: local error in processing.
452 | Requested action not taken: insufficient system storage.
500 | Syntax error, command unrecognized. (This may include errors such as a command that is too long).
501 | Syntax error in parameters or arguments.
502 | Command not implemented.
503 | Bad sequence of commands.
504 | Command parameter not implemented.
550 | Requested action not taken: mailbox unavailable. (For example, the mailbox is not found, there is no access, or no relay is allowed).
551 | User not local; please try <forward-path>
552 | Request mail action aborted: exceeded storage allocation.
553 | Requested action not taken: mailbox name not allowed. (For example, the mailbox syntax is incorrect).
554 | Transaction failed.


Other system extended stored procedures

Additional system extended stored procedures allow you to execute system commands. For example, you can use these stored procedures for file I/O and string operations.

xp_cmdshell system procedure
xp_msver system procedure
xp_read_file system procedure
xp_sprintf system procedure
xp_scanf system procedure
xp_write_file system procedure


xp_cmdshell system procedure
toggle Function

Carries out an operating system command from a procedure.

toggle Syntax

[ variable = CALL ] xp_cmdshell ( string [ , 'no_output' ] )

toggle Arguments

  • string This char(254) parameter specifies a system command.

  • 'no_output' If this parameter is the string 'no_output', no output is displayed.

toggle Remarks

xp_cmdshell executes a system command and then returns control to the calling environment.

The default behavior is to display output. If the second parameter is the string 'no_output', no output is displayed.

The second parameter affects only console applications on Windows NT/2000/XP operating systems. For UNIX, no output is displayed regardless of the setting for the second parameter. For NetWare, any commands executed are visible on the server console; regardless of the setting for the second parameter.

toggle Permissions

None

toggle Example

The following statement lists the files in the current directory in the file c:\temp.txt

xp_cmdshell('dir > c:\\temp.txt')

The following statement carries out the same operation, but does so without displaying a command window.

xp_cmdshell('dir > c:\\temp.txt', 'no_output' )


xp_msver system procedure
toggle Function

Retrieves version and name information about the database server.

toggle Syntax

xp_msver ( string )

  • string The string must be one of the following, enclosed in string delimiters.

    Argument | Description
    ProductName | The name of the product (Sybase Adaptive Server Anywhere).
    ProductVersion The version number, followed by the build number. The format is as follows:
    9.0.0 (1200)
    CompanyName Returns the following string:
    iAnywhere Solutions, Inc.
    FileDescription | Returns the name of the product, followed by the name of the operating system.
    LegalCopyright | Returns a copyright string for the software.
    LegalTrademarks | Returns trademark information for the software.
toggle Remarks

xp_msver returns product, company, version, and other information.

toggle Permissions

None

toggle See also
  • System functions
toggle Example

The following statement requests the version and operating system description:

SELECT xp_msver( 'ProductVersion') Version,
   xp_msver('FileDescription') Description

Sample output is as follows:

Version | Description
9.0.0 (1912) | Sybase Adaptive Server Anywhere Windows NT


xp_read_file system procedure
toggle Function

Returns the contents of a file as a LONG BINARY variable.

toggle Syntax

[ variable = CALL ] xp_read_file ( filename )

toggle Arguments

  • filename This long varchar parameter specifies a file name.

toggle Remarks

The function reads the contents of the named file, and returns the result as a LONG BINARY value.

The filename is relative to the starting directory of the database server.

The function can be useful for inserting entire documents or images stored in files into tables. If the file cannot be read, the function returns NULL.

toggle Permissions

DBA authority required

toggle See also
  • xp_write_file system procedure
toggle Example

The following statement inserts an image into a column named picture of the table t1 (assuming all other columns can accept NULL):

INSERT INTO t1 ( picture)
   SELECT xp_read_file( 'portrait.gif' )


xp_sprintf system procedure
toggle Function

Builds up a string from a format string and a set of input strings

toggle Syntax

[ variable = CALL ] xp_sprintf (
out-string,
format-string
[, input-string ]
)

toggle Arguments

  • out-string This char(254) OUT parameter contains the result string.

  • format-string This char(254) parameter specifies the format string.

  • input-string This char(254) parameter specifies the input string.

toggle Remarks

xp_sprintf builds up a string from a format string and a set of input strings. The format-string can contain up to fifty string placeholders (%s). These placeholders are filled in by the input-string arguments.

All arguments must be strings of less than 254 characters.

toggle Permissions

None

toggle Example

The following statements put the string Hello World! into the variable mystring.

CREATE VARIABLE mystring CHAR(254) ;
call xp_sprintf( mystring, 'Hello %s', 'World!' );


xp_scanf system procedure
toggle Function

Extracts substrings from an input string and a format string.

toggle Syntax

[ variable = CALL ] xp_scanf (
in-string,
format-string
[, output-string ]
)

toggle Arguments

  • in-string This char(254) parameter specifies the input string.

  • format-string This char(254) parameter specifies the format string.

  • output-string This char(254) OUT parameter contains the result string.

toggle Remarks

xp_scanf extracts substrings from an input string and a format string. The format-string can contain up to fifty string placeholders (%s). The values of these placeholders are placed in the output-string variables.

All arguments must be strings of less than 254 characters.

toggle Permissions

None

toggle Example

The following statements put the string World! into the variable mystring.

CREATE VARIABLE mystring CHAR(254) ;
call xp_scanf( 'Hello World!', 'Hello %s', mystring );


xp_write_file system procedure
toggle Function

Writes data to a file from a SQL statement.

toggle Syntax

[ variable = CALL ] xp_write_file ( filename, file_contents )

toggle Arguments

  • filename This long varchar parameter specifies the file name.

  • file_contents This long binary parameter specifies the contents to write to the file.

toggle Remarks

The function writes file_contents to the file filename. It returns 0 if successful, and non-zero if it fails.

The filename is relative to the current working directory of the database server. If the file already exists, its contents are overwritten.

This function can be useful for unloading long binary data into files.

toggle Permissions

DBA authority required

toggle See also
  • xp_read_file system procedure
toggle Example

Consider a table t1 that has the following columns:

  • filename A filename relative to the server.

  • picture A LONG BINARY column holding an image.

The following statement unloads the pictures into the named files:

SELECT xp_write_file( filename, picture)
FROM t1


Adaptive Server Enterprise system and catalog procedures

Adaptive Server Enterprise provides system and catalog procedures to carry out many administrative functions and to obtain system information. Adaptive Server Anywhere has implemented support for some of these procedures.

System procedures are built-in stored procedures used for getting reports from and updating system tables. Catalog stored procedures retrieve information from the system tables in tabular form.


Adaptive Server Enterprise system procedures

The following list describes the Adaptive Server Enterprise system procedures that are provided in Adaptive Server Anywhere.

While these procedures perform the same functions as they do in Adaptive Server Enterprise and pre-Version 12 Adaptive Server IQ, they are not identical. If you have preexisting scripts that use these procedures, you may want to examine the procedures. To see the text of a stored procedure, you can open it in Sybase Central or, in Interactive SQL, run the following command.

sp_helptext procedure_name

You may need to reset the width of your Interactive SQL output to see the full text, by selecting Command > Options and entering a new Limit Display Columns value.

System procedure Description
sp_addgroup group-name
 Adds a group to a database
sp_addlogin userid, password[, defdb [, deflanguage [, fullname]]]
 Adds a new login ID to a database
sp_addmessage message-num, message_text [, language]
 Adds a user-defined message to SYSUSERMESSAGES, for use by stored procedure PRINT and RAISERROR calls
sp_addtype typename, data-type [, "identity" | nulltype]
 Creates a user-defined data type
sp_adduser login_name [, name_in_db [, grpname]]
 Adds a new user ID to a database
sp_changegroup new-group-name, userid
 Changes a user's group or adds a user to a group
sp_dboption [dbname, optname, {true | false}]
 Displays or changes a database option
sp_dropgroup group-name
 Drops a group from a database
sp_droplogin userid
 Drops a login ID from a database
sp_dropmessage message-number [, language]
 Drops a user-defined message
sp_droptype typename
 Drops a user-defined data type
sp_dropuser userid
 Drops a user ID from a database
sp_getmessage message-num, @msg-var output [, language]
 Retrieves a stored message string from SYSUSERMESSAGES, for PRINT and RAISERROR statements.
sp_helptext object-name
 Displays the text of a system procedure, trigger, or view
sp_password caller_passwd, new_passwd [, userid]
 Adds or changes a password for a user ID


Adaptive Server Enterprise catalog procedures

Adaptive Server Anywhere implements a subset of the Adaptive Server Enterprise catalog procedures. The implemented catalog procedures are described in the following table.

Catalog procedure Description
sp_column_privileges
 Unsupported
sp_columns table-name [, table-owner ] [, table-qualifier] [, column-name]
 Returns the data types of the specified columns
sp_databases
 Unsupported
sp_datatype_info
 Unsupported
sp_fkeys pktable_name [, pktable-owner][, pktable-qualifier] [, fktable-name] [, fktable_owner] [, fktable-qualifier]
 Returns foreign key information about the specified table
sp_pkeys table-name [, table_owner] [, table_qualifier]
 Returns primary key information about the specified table
sp_server_info
 Unsupported
sp_special_columns table_name [, table-owner] [, table-qualifier] [, col-type]
 Returns the optimal set of columns that uniquely identify a row in the specified table
sp_sproc_columns proc-name [, proc_owner] [, proc-qualifier] [, column-name]
 Returns information about a stored procedure's input and return parameters
sp_stored_procedures [sp-name] [, sp-owner] [, sp-qualifier]
 Returns information about one or more stored procedures
sp_statistics [table_name] [, table_owner] [, table_qualities] [, index_name] [, is_unique]
 Returns information about tables and their indexes
sp_tables table-name [, table-owner] [, table-qualifier] [, table-type]
 Returns a list of objects that can appear in a FROM clause for the specified table


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Version 9.0.2

DC38130-01-0902-01

October 2004

Copyright
About This Manual
Programming Interface Overview
Using SQL in Applications
Introduction to Java in the Database
Using Java in the Database
JDBC Programming
Embedded SQL Programming
ODBC Programming
The Database Tools Interface
The OLE DB and ADO Programming Interfaces
Introduction to the Adaptive Server Anywhere .NET Data Provider
Using the Adaptive Server Anywhere .NET Data Provider Sample Applications
Developing Applications with the .NET Data Provider
Adaptive Server Anywhere .NET Data Provider API Reference
The Open Client Interface
The DBD::ASAny Perl Interface
Using the SQLAnywhere PHP module
Three-Tier Computing and Distributed Transactions
Deploying Databases and Applications
SQL Preprocessor Error Messages


About This Manual

Subject

This book describes how to build and deploy database applications using the C, C++, and Java programming languages, as well as Visual Studio .NET. Users of tools such as Visual Basic and PowerBuilder can use the programming interfaces provided by those tools.

Audience

This manual is intended for application developers writing programs that work directly with one of the Adaptive Server Anywhere interfaces.

You do not need to read this manual if you are using a development tool such as PowerBuilder or Visual Basic, each of which has its own database interface on top of ODBC.


SQL Anywhere Studio documentation

This book is part of the SQL Anywhere documentation set. This section describes the books in the documentation set and how you can use them.

The SQL Anywhere Studio documentation

The SQL Anywhere Studio documentation is available in a variety of forms: in an online form that combines all books in one large help file; as separate Adobe Acrobat files for each book; and as printed books that you can purchase. The documentation consists of the following books:

  • Introducing SQL Anywhere Studio This book provides an overview of the SQL Anywhere Studio database management and synchronization technologies. It includes tutorials to introduce you to each of the pieces that make up SQL Anywhere Studio.

  • What's New in SQL Anywhere Studio This book is for users of previous versions of the software. It lists new features in this and previous releases of the product and describes upgrade procedures.

  • Adaptive Server Anywhere Database Administration Guide This book covers material related to running, managing, and configuring databases and database servers.

  • Adaptive Server Anywhere SQL User's Guide This book describes how to design and create databases; how to import, export, and modify data; how to retrieve data; and how to build stored procedures and triggers.

  • Adaptive Server Anywhere SQL Reference This book provides a complete reference for the SQL language used by Adaptive Server Anywhere. It also describes the Adaptive Server Anywhere system tables and procedures.

  • Adaptive Server Anywhere Programming Guide This book describes how to build and deploy database applications using the C, C++, and Java programming languages. Users of tools such as Visual Basic and PowerBuilder can use the programming interfaces provided by those tools. It also describes the Adaptive Server Anywhere ADO.NET data provider.

  • Adaptive Server Anywhere Error Messages This book provides a complete listing of Adaptive Server Anywhere error messages together with diagnostic information.

  • SQL Anywhere Studio Security Guide This book provides information about security features in Adaptive Server Anywhere databases. Adaptive Server Anywhere 7.0 was awarded a TCSEC (Trusted Computer System Evaluation Criteria) C2 security rating from the U.S. Government. This book may be of interest to those who wish to run the current version of Adaptive Server Anywhere in a manner equivalent to the C2-certified environment.

  • MobiLink Administration Guide This book describes how to use the MobiLink data synchronization system for mobile computing, which enables sharing of data between a single Oracle, Sybase, Microsoft or IBM database and many Adaptive Server Anywhere or UltraLite databases.

  • MobiLink Clients This book describes how to set up and synchronize Adaptive Server Anywhere and UltraLite remote databases.

  • MobiLink Server-Initiated Synchronization User's Guide This book describes MobiLink server-initiated synchronization, a feature of MobiLink that allows you to initiate synchronization from the consolidated database.

  • MobiLink Tutorials This book provides several tutorials that walk you through how to set up and run MobiLink applications.

  • QAnywhere User's Guide This manual describes MobiLink QAnywhere, a messaging platform that enables the development and deployment of messaging applications for mobile and wireless clients, as well as traditional desktop and laptop clients.

  • ODBC Drivers for MobiLink and Remote Data Access This manual describes how to use the iAnywhere Solutions ODBC drivers for Oracle, DB2, and Sybase Adaptive Server Enterprise. These ODBC drivers are included with SQL Anywhere Studio for use with MobiLink synchronization and Adaptive Server Anywhere remote data access.

  • SQL Remote User's Guide This book describes all aspects of the SQL Remote data replication system for mobile computing, which enables sharing of data between a single Adaptive Server Anywhere or Adaptive Server Enterprise database and many Adaptive Server Anywhere databases using an indirect link such as e-mail or file transfer.

  • Sybase Central Help This book includes the context-sensitive help for Sybase Central, Interactive SQL, and other graphical tools. It is not included in the printed documentation set.

  • Adaptive Server Anywhere SNMP Extension Agent User's Guide This book covers material related to running and configuring the Adaptive Server Anywhere SNMP Extension Agent.

  • UltraLite Database User's Guide This book is intended for all UltraLite developers. It introduces the UltraLite database system and provides information common to all UltraLite programming interfaces.

  • Native UltraLite for Java User's Guide This manual describes Native UltraLite for Java. With Native UltraLite for Java you can develop and deploy database applications to Windows CE devices running the Jeode or CrEme VMs.

  • UltraLite Static Java User's Guide This manual describes the UltraLite Static Java API. It is a complement for the UltraLite Database User's Guide.

  • UltraLite.NET User's Guide This manual describes UltraLite.NET. With UltraLite.NET you can develop and deploy database applications to computers, or handheld, mobile, or embedded devices.

  • UltraLite for MobileVB User's Guide This manual describes UltraLite for MobileVB. With UltraLite for MobileVB you can develop and deploy database applications to handheld, mobile, or embedded devices, running Palm OS or Windows CE.

  • UltraLite ActiveX User's Guide This manual describes UltraLite ActiveX. With UltraLite ActiveX you can develop and deploy database applications to handheld, mobile, or embedded devices running Windows CE.

  • UltraLite C/C++ User's Guide This manual describes UltraLite C and C++ programming interfaces. With UltraLite you can develop and deploy database applications to handheld, mobile, or embedded devices.

  • UltraLite for M-Business Anywhere User's Guide This manual describes UltraLite for M-Business Anywhere. With UltraLite for M-Business Anywhere you can develop and deploy web-based database applications to handheld, mobile, or embedded devices, running Palm OS, Windows CE, or Windows XP.

In addition to this documentation set, PowerDesigner and InfoMaker include their own online documentation.

Documentation formats

SQL Anywhere Studio provides documentation in the following formats:

  • Online documentation The online documentation contains the complete SQL Anywhere Studio documentation, including both the books and the context-sensitive help for SQL Anywhere tools. The online documentation is updated with each maintenance release of the product, and is the most complete and up-to-date source of documentation.

    To access the online documentation on Windows operating systems, choose Start > Programs > SQL Anywhere 9 > Online Books. You can navigate the online documentation using the HTML Help table of contents, index, and search facility in the left pane, as well as using the links and menus in the right pane.

    To access the online documentation on UNIX operating systems, see the HTML documentation under your SQL Anywhere installation.

  • PDF books The SQL Anywhere books are provided as a set of Adobe Acrobat files, viewable with Adobe Acrobat Reader.

    The PDF books are accessible from the online books, or from the Windows Start menu.

  • Printed books The complete set of books is available from Sybase sales or from eShop, the Sybase online store at [external link] http://eshop.sybase.com/eshop/documentation.


Finding out more and providing feedback

We would like to receive your opinions, suggestions, and feedback on this documentation.

You can provide feedback on this documentation and on the software through newsgroups set up to discuss SQL Anywhere technologies. These newsgroups can be found on the forums.sybase.com news server.

The newsgroups include the following:

  • [external link] sybase.public.sqlanywhere.general

  • [external link] sybase.public.sqlanywhere.linux

  • [external link] sybase.public.sqlanywhere.mobilink

  • [external link] sybase.public.sqlanywhere.product_futures_discussion

  • [external link] sybase.public.sqlanywhere.replication

  • [external link] sybase.public.sqlanywhere.ultralite

Newsgroup disclaimer
iAnywhere Solutions has no obligation to provide solutions, information or ideas on its newsgroups, nor is iAnywhere Solutions obliged to provide anything other than a systems operator to monitor the service and insure its operation and availability.

iAnywhere Solutions Technical Advisors as well as other staff assist on the newsgroup service when they have time available. They offer their help on a volunteer basis and may not be available on a regular basis to provide solutions and information. Their ability to help is based on their workload.

You can e-mail comments and suggestions to the SQL Anywhere documentation team at [external link] iasdoc@ianywhere.com. Although we do not undertake to reply to e-mails at that address, you can be sure we will read your suggestions with interest.


Programming Interface Overview

About this chapter

This chapter introduces each of the programming interfaces for Adaptive Server Anywhere. Any client application uses one of these interfaces to communicate with the database.

The ODBC programming interface
The ADO.NET programming interface
The OLE DB and ADO programming interface
The Embedded SQL programming interface
The JDBC programming interface
The Open Client programming interface
The Perl DBD::ASAny driver for the DBI module
Code samples and other programming interfaces


The ODBC programming interface

ODBC (Open Database Connectivity) is a standard call level interface (CLI) developed by Microsoft. It is based on the SQL Access Group CLI specification. ODBC applications can run against any data source that provides an ODBC driver. ODBC is a good choice for a programming interface if you would like your application to be portable to other data sources that have ODBC drivers.

ODBC is a low-level interface. Almost all the Adaptive Server Anywhere functionality is available with this interface. ODBC is available as a DLL under Windows operating systems with the exception of Windows CE. It is provided as a library for UNIX.

The primary documentation for ODBC is the Microsoft ODBC Software Development Kit. The current book provides some additional notes specific to Adaptive Server Anywhere for ODBC developers.

ODBC is described in ODBC Programming.


The ADO.NET programming interface

ADO.NET is the latest data access API from Microsoft in the line of ODBC, OLE DB, and ADO. It is the preferred data access component for the Microsoft .NET Framework and allows you to access relational database systems.

The Adaptive Server Anywhere .NET data provider implements the iAnywhere.Data.AsaClient namespace and allows you to write programs in any of the .NET supported languages, such as C# and Visual Basic .NET, and access data from Adaptive Server Anywhere.

In addition to this book, you may wish to consult other materials on .NET data access to help in your development efforts. For example, [external link] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/daag.asp.

The ADO.NET programming interface is described in Introduction to the Adaptive Server Anywhere .NET Data Provider, Using the Adaptive Server Anywhere .NET Data Provider Sample Applications, Developing Applications with the .NET Data Provider, and Adaptive Server Anywhere .NET Data Provider API Reference.


The OLE DB and ADO programming interface

OLE DB is a set of Component Object Model (COM) interfaces developed by Microsoft, which provide applications with uniform access to data stored in diverse information sources and which also provide the ability to implement additional database services. These interfaces support the amount of DBMS functionality appropriate to the data store, enabling it to share its data.

ADO is an object model for programmatically accessing, editing, and updating a wide variety of data sources through OLE DB system interfaces. ADO is also developed by Microsoft. Most developers using the OLE DB programming interface do so by writing to the ADO API rather than directly to the OLE DB API.

Adaptive Server Anywhere includes an OLE DB provider for OLE DB and ADO programmers.

The primary documentation for OLE DB and ADO programming is the Microsoft Developer Network. The current book provides some additional notes specific to Adaptive Server Anywhere for OLE DB and ADO developers.

The OLE DB provider is described in The OLE DB and ADO Programming Interfaces.

Do not confuse the ADO interface with ADO.NET. ADO.NET is a separate interface. For more information, see The ADO.NET programming interface.


The Embedded SQL programming interface

Embedded SQL is a system in which SQL commands are embedded right in a C or C++ source file. A preprocessor translates these statements into calls to a runtime library. Embedded SQL is an ISO/ANSI and IBM standard.

Embedded SQL is portable to other databases and other environments, and is functionally equivalent in all operating environments. It is a comprehensive, low-level interface that provides all of the functionality available in the product. Embedded SQL requires knowledge of C or C++ programming languages.

Embedded SQL is described in Embedded SQL Programming.


The JDBC programming interface

JDBC is a call-level interface for Java applications. Developed by Sun Microsystems, JDBC provides Java programmers with a uniform interface to a wide range of relational databases, and provides a common base on which higher level tools and interfaces can be built. JDBC is now a standard part of Java and is included in the JDK.

SQL Anywhere Studio includes a pure Java JDBC driver, named Sybase jConnect. It also includes the iAnywhere JDBC driver, which is a type 2 driver. Both are described in JDBC Programming. For information on choosing a driver, see Choosing a JDBC driver.

In addition to using JDBC as a client side application programming interface, you can also use JDBC inside the database server to access data from Java in the database.

The JDBC interface is described in JDBC Programming.


The Open Client programming interface

Sybase Open Client provides customer applications, third-party products, and other Sybase products with the interfaces needed to communicate with Adaptive Server Anywhere and other Open Servers.

When to use Open Client

You should consider using the Open Client interface if you are concerned with Adaptive Server Enterprise compatibility or if you are using other Sybase products that support the Open Client interface, such as Replication Server.

For more information about the Open Client interface, see Adaptive Server Anywhere as an Open Server.

Open Client architecture


Open Client architecture

Open Client can be thought of as comprising two components: programming interfaces and network services.

Client Library and DB-Library

Open Client provides two core programming interfaces for writing client applications: DB-Library and Client-Library.

Open Client DB-Library provides support for older Open Client applications, and is a completely separate programming interface from Client-Library. DB-Library is documented in the Open Client DB-Library/C Reference Manual, provided with the Sybase Open Client product.

Client-Library programs also depend on CS-Library, which provides routines that are used in both Client-Library and Server-Library applications. Client-Library applications can also use routines from Bulk-Library to facilitate high-speed data transfer.

Both CS-Library and Bulk-Library are included in the Sybase Open Client, available separately.

Network services

Open Client network services include Sybase Net-Library, which provides support for specific network protocols such as TCP/IP and DECnet. The Net-Library interface is invisible to application programmers. However, on some platforms, an application may need a different Net-Library driver for different system network configurations. Depending on your host platform, the Net-Library driver is specified either by the system's Sybase configuration or when you compile and link your programs.

Instructions for driver configuration can be found in the Open Client/Server Configuration Guide.

Instructions for building Client-Library programs can be found in the Open Client/Server Programmer's Supplement.


The Perl DBD::ASAny driver for the DBI module

The DBD::ASAny interface provides access to Adaptive Server Anywhere databases from scripts written in Perl. ASAny is a driver for the Database Independent Interface for Perl (DBI) module written by Tim Bunce. Once you have installed the DBI module and DBD::ASAny, your can access and change the information in Adaptive Server Anywhere databases from Perl.

For instructions on installing these components and writing Perl scripts that use them, see The DBD::ASAny Perl Interface.


Code samples and other programming interfaces

Unsupported code that provides other interfaces to Adaptive Server Anywhere is available for download.

  • PHP module The Adaptive Server Anywhere PHP module can be used to retrieve data from Adaptive Server Anywhere databases. To make PHP connect to Adaptive Server Anywhere using the PHP module, you must add the Adaptive Server Anywhere module's files to PHP's source tree, then re-compile PHP.

    The PHP module is available as a separate download. For more information, see [external link] http://www.ianywhere.com/developer/code_samples/sqlany_php_module.html.

  • Perl DBI driver DBD::ASAny is the Adaptive Server Anywhere database driver for DBI, which is a database access Application Programming Interface (API) for the Perl Language. The DBI API Specification defines a set of functions, variables and conventions that provide a consistent database interface independent of the actual database being used. Using DBI and DBD::ASAny, your perl scripts will have direct access to Sybase Adaptive Server Anywhere database servers.

    For more information, see [external link] http://www.ianywhere.com/developer/code_samples/dbd_asa_perl.html.

Code samples

Application code samples are one of the most useful tools for application developers. Code samples, utilities, and solution samples are available on the iAnywhere website at [external link] http://www.ianywhere.com/downloads.


Using SQL in Applications

About this chapter

Many aspects of database application development depend on your application development tool, database interface, and programming language, but there are some common problems and principles that affect multiple aspects of database application development.

This chapter describes some principles and techniques common to most or all interfaces and provides pointers for more information. It does not provide a detailed guide for programming using any one interface.

Executing SQL statements in applications
Preparing statements
Introduction to cursors
Working with cursors
Choosing cursor types
Adaptive Server Anywhere cursors
Describing result sets
Controlling transactions in applications


Executing SQL statements in applications

The way you include SQL statements in your application depends on the application development tool and programming interface you use.

  • ODBC If you are writing directly to the ODBC programming interface, your SQL statements appear in function calls. For example, the following C function call executes a DELETE statement:

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

  • ADO.NET You can execute SQL statements using a variety of ADO.NET objects. The AsaCommand object is one example:

    AsaCommand cmd = new AsaCommand(
     "select emp_lname from employee", conn );
AsaDataReader reader = cmd.ExecuteReader();

  • JDBC If you are using the JDBC programming interface, you can execute SQL statements by invoking methods of the statement object. For example,

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

  • Embedded SQL If you are using embedded SQL, you prefix your C language SQL statements with the keyword EXEC SQL. The code is then run through a preprocessor before compiling. For example,

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

  • Sybase Open Client If you use the Sybase Open Client interface, your SQL statements appear in function calls. For example, the following pair of calls executes a DELETE statement:

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

  • Application Development Tools Application development tools such as the members of the Sybase Enterprise Application Studio family provide their own SQL objects, which use either ODBC (PowerBuilder) or JDBC (Power J) under the covers.

For more detailed information on how to include SQL in your application, see your development tool documentation. If you are using ODBC or JDBC, consult the software development kit for those interfaces.

For a detailed description of embedded SQL programming, see Embedded SQL Programming.

Applications inside the server

In many ways, stored procedures and triggers act as applications or parts of applications running inside the server. You can use many of the techniques here in stored procedures also. Stored procedures use statements very similar to embedded SQL statements.

For more information about stored procedures and triggers, see Using Procedures, Triggers, and Batches.

Java classes in the database can use the JDBC interface in the same way as Java applications outside the server. This chapter discusses some aspects of JDBC. For other information on using JDBC, see JDBC Programming.


Preparing statements

Each time a statement is sent to a database, the server must first prepare the statement. Preparing the statement can include:

  • Parsing the statement and transforming it into an internal form.

  • Verifying the correctness of all references to database objects by checking, for example, that columns named in a query actually exist.

  • Causing the query optimizer to generate an access plan if the statement involves joins or subqueries.

  • Executing the statement after all these steps have been carried out.

Reusing prepared statements can improve performance

If you find yourself using the same statement repeatedly, for example, inserting many rows into a table, repeatedly preparing the statement causes a significant and unnecessary overhead. To remove this overhead, some database programming interfaces provide ways of using prepared statements. A prepared statement is a statement containing a series of placeholders. When you want to execute the statement, all you have to do is assign values to the placeholders, rather than prepare the entire statement over again.

Using prepared statements is particularly useful when carrying out many similar actions, such as inserting many rows.

Generally, using prepared statements requires the following steps:

  1. Prepare the statement In this step you generally provide the statement with some placeholder character instead of the values.

  2. Repeatedly execute the prepared statement In this step you supply values to be used each time the statement is executed. The statement does not have to be prepared each time.

  3. Drop the statement In this step you free the resources associated with the prepared statement. Some programming interfaces handle this step automatically.

Do not prepare statements that are used only once

In general, you should not prepare statements if you'll only execute them once. There is a slight performance penalty for separate preparation and execution, and it introduces unnecessary complexity into your application.

In some interfaces, however, you do need to prepare a statement to associate it with a cursor.

For information about cursors, see Introduction to cursors.

The calls for preparing and executing statements are not a part of SQL, and they differ from interface to interface. Each of the Adaptive Server Anywhere programming interfaces provides a method for using prepared statements.

How to use prepared statements


How to use prepared statements

This section provides a brief overview of how to use prepared statements. The general procedure is the same, but the details vary from interface to interface. Comparing how to use prepared statements in different interfaces illustrates this point.

toggle To use a prepared statement (generic)

  1. Prepare the statement.

  2. Set up bound parameters, which will hold values in the statement.

  3. Assign values to the bound parameters in the statement.

  4. Execute the statement.

  5. Repeat steps 3 and 4 as needed.

  6. Drop the statement when finished. This step is not required in JDBC, as Java's garbage collection mechanisms handle this for you.

toggle To use a prepared statement (embedded SQL)

  1. Prepare the statement using the EXEC SQL PREPARE command.

  2. Assign values to the parameters in the statement.

  3. Execute the statement using the EXE SQL EXECUTE command.

  4. Free the resources associated with the statement using the EXEC SQL DROP command.

toggle To use a prepared statement (ODBC)

  1. Prepare the statement using SQLPrepare.

  2. Bind the statement parameters using SQLBindParameter.

  3. Execute the statement using SQLExecute.

  4. Drop the statement using SQLFreeStmt.

    For more information, see Executing prepared statements and the ODBC SDK documentation.

toggle To use a prepared statement (ADO.NET)

  1. Create an AsaCommand object holding the statement.

    AsaCommand cmd = new AsaCommand(
     "select emp_lname from employee", conn );

  2. Declare data types for the parameters in the statement.

    Use the AsaCommand.CreateParameter method.

  3. Prepare the statement using the Prepare method.

    cmd.Prepare();

  4. Execute the statement.

    AsaDataReader reader = cmd.ExecuteReader();

For more information, see

toggle To use a prepared statement (JDBC)

  1. Prepare the statement using the prepareStatement method of the connection object. This returns a prepared statement object.

  2. Set the statement parameters using the appropriate set Type methods of the prepared statement object. Here, Type is the data type assigned.

  3. Execute the statement using the appropriate method of the prepared statement object. For inserts, updates, and deletes this is the executeUpdate method.

    For more information on using prepared statements in JDBC, see Using prepared statements for more efficient access.

toggle To use a prepared statement (Open Client)

  1. Prepare the statement using the ct_dynamic function, with a CS_PREPARE type parameter.

  2. Set statement parameters using ct_param.

  3. Execute the statement using ct_dynamic with a CS_EXECUTE type parameter.

  4. Free the resources associated with the statement using ct_dynamic with a CS_DEALLOC type parameter.

    For more information on using prepared statements in Open Client, see Using SQL in Open Client applications.


Introduction to cursors

When you execute a query in an application, the result set consists of a number of rows. In general, you do not know how many rows the application is going to receive before you execute the query. Cursors provide a way of handling query result sets in applications.

The way you use cursors, and the kinds of cursors available to you, depend on the programming interface you use. For a list of cursor types available from each interface, see Availability of cursors.

With cursors, you can carry out the following tasks within any programming interface:

  • Loop over the results of a query.

  • Carry out inserts, updates, and deletes on the underlying data at any point within a result set.

In addition, some programming interfaces allow you to use special features to tune the way result sets return to your application, providing substantial performance benefits for your application.

For more information on the kinds of cursors available through different programming interfaces, see Availability of cursors.


What are cursors?

A cursor is a name associated with a result set. The result set is obtained from a SELECT statement or stored procedure call.

A cursor is a handle on the result set. At any time, the cursor has a well-defined position within the result set. With a cursor you can examine and possibly manipulate the data one row at a time. Adaptive Server Anywhere cursors support forward and backward movement through the query results.

Cursor positions

Cursors can be positioned in the following places:

  • Before the first row of the result set.

  • On a row in the result set.

  • After the last row of the result set.

Cursors can be positioned before the first row, after the last row, or on a row. When counting from the start, position 0 is before the first row. When counting from the end, position 0 is after the last row.

Cursor position and result set are maintained in the database server. Rows are fetched by the client for display and processing either one at a time or a few at a time. The entire result set does not need to be delivered to the client.


Benefits of using cursors

You do not need to use cursors in database applications, but they do provide a number of benefits. These benefits follow from the fact that if you do not use a cursor, the entire result set must be transferred to the client for processing and display:

  • Client-side memory For large results, holding the entire result set on the client can lead to demanding memory requirements.

  • Response time Cursors can provide the first few rows before the whole result set is assembled. If you do not use cursors, the entire result set must be delivered before any rows are displayed by your application.

  • Concurrency control If you make updates to your data and do not use cursors in your application, you must send separate SQL statements to the database server to apply the changes. This raises the possibility of concurrency problems if the result set has changed since it was queried by the client. In turn, this raises the possibility of lost updates.

    Cursors act as pointers to the underlying data, and so impose proper concurrency constraints on any changes you make.


Steps in using cursors

Using a cursor in embedded SQL is different than using a cursor in other interfaces.

toggle To use a cursor (embedded SQL)

  1. Prepare a statement.

    Cursors generally use a statement handle rather than a string. You need to prepare a statement to have a handle available.

    For information on preparing a statement, see Preparing statements.

  2. Declare the cursor.

    Each cursor refers to a single SELECT or CALL statement. When you declare a cursor, you state the name of the cursor and the statement it refers to.

    For more information, see DECLARE CURSOR statement [ESQL] [SP].

  3. Open the cursor.

    For more information, see OPEN statement [ESQL] [SP].

    In the case of a CALL statement, opening the cursor executes the query up to the point where the first row is about to be obtained.

  4. Fetch results.

    Although simple fetch operations move the cursor to the next row in the result set, Adaptive Server Anywhere permits more complicated movement around the result set. How you declare the cursor determines which fetch operations are available to you.

    For more information, see FETCH statement [ESQL] [SP], and Fetching data.

  5. Close the cursor.

    When you have finished with the cursor, close it. This frees any locks held on the underlying data.

    For more information, see CLOSE statement [ESQL] [SP].

  6. Drop the statement.

    To free the memory associated with the cursor and its associated statement, you must free the statement.

    For more information, see DROP STATEMENT statement [ESQL].

toggle To use a cursor (ODBC, ADO.NET, JDBC, Open Client)

  1. Prepare and execute a statement.

    Execute a statement using the usual method for the interface. You can prepare and then execute the statement, or you can execute the statement directly.

    With ADO.NET, only the AsaCommand.ExecuteReader command returns a cursor. It provides a read-only, forward-only cursor.

  2. Test to see if the statement returns a result set.

    A cursor is implicitly opened when a statement that creates a result set is executed. When the cursor is opened, it is positioned before the first row of the result set.

  3. Fetch results.

    Although simple fetch operations move the cursor to the next row in the result set, Adaptive Server Anywhere permits more complicated movement around the result set.

  4. Close the cursor.

    When you have finished with the cursor, close it to free associated resources.

  5. Free the statement.

    If you used a prepared statement, free it to reclaim memory.

Prefetching rows

In some cases the interface library may carry out performance optimizations under the covers (such as prefetching results), so these steps in the client application may not correspond exactly to software operations.


Working with cursors

This section describes how to carry out different kinds of operations using cursors.

Cursor positioning
Configuring cursors on opening
Fetching rows through a cursor
Fetching multiple rows
Fetching with scrollable cursors
Modifying rows through a cursor
Canceling cursor operations


Cursor positioning

When a cursor is opened, it is positioned before the first row. You can move the cursor position to an absolute position from the start or the end of the query results, or to a position relative to the current cursor position. The specifics of how you change cursor position, and what operations are possible, is governed by the programming interface.

The number of row positions you can fetch in a cursor is governed by the size of an integer. You can fetch rows numbered up to number 2147483646, which is one less than the value that can be held in an integer. When using negative numbers (rows from the end) you can fetch down to one more than the largest negative value that can be held in an integer.

You can use special positioned update and delete operations to update or delete the row at the current position of the cursor. If the cursor is positioned before the first row or after the last row, a No current row of cursor error is returned.

Cursor positioning problems
Inserts and some updates to asensitive cursors can cause problems with cursor positioning. Adaptive Server Anywhere does not put inserted rows at a predictable position within a cursor unless there is an ORDER BY clause on the SELECT statement. In some cases, the inserted row does not appear at all until the cursor is closed and opened again.

With Adaptive Server Anywhere, this occurs if a work table had to be created to open the cursor (see Use of work tables in query processing for a description).

The UPDATE statement may cause a row to move in the cursor. This happens if the cursor has an ORDER BY clause that uses an existing index (a work table is not created). Using STATIC SCROLL cursors alleviates these problems but requires more memory and processing.


Configuring cursors on opening

You can configure the following aspects of cursor behavior when you open the cursor:

  • Isolation level You can explicitly set the isolation level of operations on a cursor to be different from the current isolation level of the transaction. To do this, set the ISOLATION_LEVEL option.

    For more information, see ISOLATION_LEVEL option [compatibility].

  • Holding By default, cursors in embedded SQL close at the end of a transaction. Opening a cursor WITH HOLD allows you to keep it open until the end of a connection, or until you explicitly close it. ODBC, JDBC and Open Client leave cursors open at the end of transactions by default.


Fetching rows through a cursor

The simplest way of processing the result set of a query using a cursor is to loop through all the rows of the result set until there are no more rows.

toggle To loop through the rows of a result set

  1. Declare and open the cursor (embedded SQL), or execute a statement that returns a result set (ODBC, JDBC, Open Client) or AsaDataReader object (ADO.NET).

  2. Continue to fetch the next row until you get a Row Not Found error.

  3. Close the cursor.

How step 2 of this operation is carried out depends on the interface you use. For example,

  • ODBC SQLFetch, SQLExtendedFetch, or SQLFetchScroll advances the cursor to the next row and returns the data.

    For more information on using cursors in ODBC, see Working with result sets.

  • ADO.NET Use the AsaDataReader.NextResult method. See NextResult method.

  • Embedded SQL The FETCH statement carries out the same operation.

    For more information on using cursors in embedded SQL, see Using cursors in embedded SQL.

  • JDBC The next method of the ResultSet object advances the cursor and returns the data.

    For more information on using the ResultSet object in JDBC, see Queries using JDBC.

  • Open Client The ct_fetch function advances the cursor to the next row and returns the data.

    For more information on using cursors in Open Client applications, see Using cursors.


Fetching multiple rows

This section discusses how fetching multiple rows at a time can improve performance.

Multiple-row fetching should not be confused with prefetching rows, which is described in the next section. Multiple row fetching is performed by the application, while prefetching is transparent to the application, and provides a similar performance gain.

Multiple-row fetches

Some interfaces provide methods for fetching more than one row at a time into the next several fields in an array. Generally, the fewer separate fetch operations you execute, the fewer individual requests the server must respond to, and the better the performance. A modified FETCH statement that retrieves multiple-rows is also sometimes called a wide fetch. Cursors that use multiple-row fetches are sometimes called block cursors or fat cursors.

Using multiple-row fetching

  • In ODBC, you can set the number of rows that will be returned on each call to SQLFetchScroll or SQLExtendedFetch by setting the SQL_ROWSET_SIZE attribute.

  • In embedded SQL, the FETCH statement uses an ARRAY clause to control the number of rows fetched at a time.

  • Open Client and JDBC do not support multi-row fetches. They do use prefetching.


Fetching with scrollable cursors

ODBC and embedded SQL provide methods for using scrollable cursors and dynamic scrollable cursors. These methods allow you to move several rows forward at a time, or to move backwards through the result set.

The JDBC and Open Client interfaces do not support scrollable cursors.

Prefetching does not apply to scrollable operations. For example, fetching a row in the reverse direction does not prefetch several previous rows.


Modifying rows through a cursor

Cursors can do more than just read result sets from a query. You can also modify data in the database while processing a cursor. These operations are commonly called positioned insert, update, and delete operations, or PUT operations if the action is an insert.

Not all query result sets allow positioned updates and deletes. If you carry out a query on a non-updatable view, then no changes occur to the underlying tables. Also, if the query involves a join, then you must specify which table you wish to delete from, or which columns you wish to update, when you carry out the operations.

Inserts through a cursor can only be executed if any non-inserted columns in the table allow NULL or have defaults.

If multiple rows are inserted into a value-sensitive (keyset driven) cursor, they appear at the end of the cursor result set. The rows appear at the end even if they do not match the WHERE clause of the query or if an ORDER BY clause would normally have placed them at another location in the result set. This behavior is independent of programming interface. For example, it applies when using the embedded SQL PUT statement or the ODBC SQLBulkOperations function. The value of an autoincrement column for the most recent row inserted can be found by selecting the last row in the cursor. For example, in embedded SQL the value could be obtained using FETCH ABSOLUTE -1 cursor-name. As a result of this behavior, the first multiple-row insert for a value-sensitive cursor may be expensive.

ODBC, embedded SQL, and Open Client permit data modification using cursors, but JDBC 1.1 does not. With Open Client, you can delete and update rows, but you can only insert rows on a single-table query.

Which table are rows deleted from?

If you attempt a positioned delete through a cursor, the table from which rows are deleted is determined as follows:

  1. If no FROM clause is included in the DELETE statement, the cursor must be on a single table only.

  2. If the cursor is for a joined query (including using a view containing a join), then the FROM clause must be used. Only the current row of the specified table is deleted. The other tables involved in the join are not affected.

  3. If a FROM clause is included, and no table owner is specified, the table-spec value is first matched against any correlation names.

    For more information, see the FROM clause.

  4. If a correlation name exists, the table-spec value is identified with the correlation name.

  5. If a correlation name does not exist, the table-spec value must be unambiguously identifiable as a table name in the cursor.

  6. If a FROM clause is included, and a table owner is specified, the table-spec value must be unambiguously identifiable as a table name in the cursor.

  7. The positioned DELETE statement can be used on a cursor open on a view as long as the view is updatable.


Canceling cursor operations

You can cancel a request through an interface function. From Interactive SQL, you can cancel a request by pressing the Interrupt SQL Statement button on the toolbar (or by choosing Stop from the SQL menu).

If you cancel a request that is carrying out a cursor operation, the position of the cursor is indeterminate. After canceling the request, you must locate the cursor by its absolute position, or close it.


Choosing cursor types

This section describes mappings between Adaptive Server Anywhere cursors and the options available to you from the programming interfaces supported by Adaptive Server Anywhere.

For information on Adaptive Server Anywhere cursors, see Adaptive Server Anywhere cursors.


Availability of cursors

Not all interfaces provide support for all types of cursors.

  • ODBC and OLE DB (ADO) support all types of cursors.

    For more information, see Working with result sets.

  • Embedded SQL supports all the types of cursors.

  • ADO.NET provides only forward-only, read-only cursors.

  • For JDBC:

    • jConnect 4.x provides only asensitive cursors.

    • jConnect 5.x supports all types of cursors, but there is a severe performance penalty for scrollable cursors.

    • The iAnywhere JDBC driver supports all types of cursors.

  • Sybase Open Client supports only asensitive cursors. Also, a severe performance penalty results when using updatable, non-unique cursors.


Cursor properties

You request a cursor type, either explicitly or implicitly, from the programming interface. Different interface libraries offer different choices of cursor types. For example, JDBC and ODBC specify different cursor types.

Each cursor type is defined by a number of characteristics:

  • Uniqueness Declaring a cursor to be unique forces the query to return all the columns required to uniquely identify each row. Often this means returning all the columns in the primary key. Any columns required but not specified are added to the result set. The default cursor type is non-unique.

  • Updatability A cursor declared as read only may not be used in a positioned update or delete operation. The default cursor type us updatable.

  • Scrollability You can declare cursors to behave different ways as you move through the result set. Some cursors can fetch only the current row or the following row. Others can move backwards and forwards through the result set.

  • Sensitivity Changes to the database may or may not be visible through a cursor.

These characteristics may have significant side effects on performance and on database server memory usage.

Adaptive Server Anywhere makes available cursors with a variety of mixes of these characteristics. When you request a cursor of a given type, Adaptive Server Anywhere matches those characteristics as well as it can. The details of how Adaptive Server Anywhere cursors match the cursor types specified in the programming interfaces are the subject of the following sections.

There are some occasions when not all characteristics can be supplied. For example, insensitive cursors in Adaptive Server Anywhere must be read-only, for reasons described below. If your application requests an updatable insensitive cursor, a different cursor type (value-sensitive) is supplied instead.


Requesting Adaptive Server Anywhere cursors

When you request a cursor type from your client application, Adaptive Server Anywhere provides a cursor. Adaptive Server Anywhere cursors are defined, not by the type as specified in the programming interface, but by the sensitivity of the result set to changes in the underlying data. Depending on the cursor type you ask for, Adaptive Server Anywhere provides a cursor with behavior to match the type.

Adaptive Server Anywhere cursor sensitivity is set in response to the client cursor type request.


ODBC and OLE DB

The following table illustrates the cursor sensitivity that is set in response to different ODBC scrollable cursor types.

ODBC scrollable cursor type | Adaptive Server Anywhere cursor
STATIC | Insensitive
KEYSET | Value-sensitive
DYNAMIC | Sensitive
MIXED | Value-sensitive

For information on Adaptive Server Anywhere cursors and their behavior, see Adaptive Server Anywhere cursors. For information on how to request a cursor type in ODBC, see Choosing a cursor characteristics.

Exceptions

If a STATIC cursor is requested as updatable, a value-sensitive cursor is supplied instead and a warning is issued.

If a DYNAMIC or MIXED cursor is requested and the query cannot be executed without using work tables, a warning is issued and an asensitive cursor is supplied instead.


ADO.NET

Forward-only, read-only cursors are available by using AsaCommand.ExecuteReader. The AsaDataAdapter object uses a client-side result set instead of cursors.


Embedded SQL

To request a cursor from an embedded SQL application, you specify the cursor type on the DECLARE statement. The following table illustrates the cursor sensitivity that is set in response to different requests:

Cursor type | Adaptive Server Anywhere cursor
NO SCROLL | Asensitive
DYNAMIC SCROLL | Asensitive
SCROLL | Value-sensitive
INSENSITIVE | Insensitive
SENSITIVE | Sensitive
Exceptions

If an DYNAMIC SCROLL or NO SCROLL cursor is requested as UPDATABLE, then a sensitive or value-sensitive cursor is supplied. It is not guaranteed which of the two is supplied. This uncertainty fits the definition of asensitive behavior.

If an INSENSITIVE cursor is requested as UPDATABLE, then a value-sensitive cursor is supplied.

If a DYNAMIC SCROLL cursor is requested, if the PREFETCH database option is set to OFF, and if the query execution plan involves no work tables, then a sensitive cursor may be supplied. Again, this uncertainty fits the definition of asensitive behavior.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Using SQL in Applications

Choosing cursor types

Requesting Adaptive Server Anywhere cursors

JDBC

Only one kind of cursor is available to JDBC applications. This is an asensitive cursor. In JDBC you execute an ExecuteQuery statement to open a cursor.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Using SQL in Applications

Choosing cursor types

Requesting Adaptive Server Anywhere cursors

Open Client

Only one kind of cursor is available to Open Client applications. This is an asensitive cursor.


Bookmarks and cursors

ODBC provides bookmarks, or values, used to identify rows in a cursor. Adaptive Server Anywhere supports bookmarks for all kinds of cursors except DYNAMIC cursors.


Block cursors

ODBC provides a cursor type called a block cursor. When you use a BLOCK cursor, you can use SQLFetchScroll or SQLExtendedFetch to fetch a block of rows, rather than a single row. Block cursors behave identically to embedded SQL ARRAY fetches.


Adaptive Server Anywhere cursors

Any cursor, once opened, has an associated result set. The cursor is kept open for a length of time. During that time, the result set associated with the cursor may be changed, either through the cursor itself or, subject to isolation level requirements, by other transactions. Some cursors permit changes to the underlying data to be visible, while others do not reflect these changes. The different behavior of cursors with respect to changes to the underlying data is the sensitivity of the cursor.

Adaptive Server Anywhere provides cursors with a variety of sensitivity characteristics. This section describes what sensitivity is, and describes the sensitivity characteristics of cursors.

This section assumes that you have read What are cursors?.

Membership, order, and value changes

Changes to the underlying data can affect the result set of a cursor in the following ways:

  • Membership The set of rows in the result set, as identified by their primary key values.

  • Order The order of the rows in the result set.

  • Value The values of the rows in the result set.

For example, consider the following simple table with employee information (emp_id is the primary key column):

emp_id | emp_lname
1 | Whitney
2 | Cobb
3 | Chin

A cursor on the following query returns all results from the table in primary key order:

SELECT emp_id, emp_lname
FROM employee
ORDER BY emp_id

The membership of the result set could be changed by adding a new row or deleting a row. The values could be changed by changing one of the names in the table. The order could be changed by changing the primary key value of one of the employees.

Visible and invisible changes

Subject to isolation level requirements, the membership, order, and values of the result set of a cursor can be changed after the cursor is opened. Depending on the type of cursor in use, the result set as seen by the application may change to reflect these changes or may not.

Changes to the underlying data may be visible or invisible through the cursor. A visible change is a change that is reflected in the result set of the cursor. Changes to the underlying data that are not reflected in the result set seen by the cursor are invisible.

Cursor sensitivity overview
Cursor sensitivity example: a deleted row
Cursor sensitivity example: an updated row
Insensitive cursors
Sensitive cursors
Asensitive cursors
Value-sensitive cursors
Cursor sensitivity and performance
Cursor sensitivity and isolation levels


Cursor sensitivity overview

Adaptive Server Anywhere cursors are classified by their sensitivity with respect to changes of the underlying data. In particular, cursor sensitivity is defined in terms of which changes are visible.

  • Insensitive cursors The result set is fixed when the cursor is opened. No changes to the underlying data are visible.

    For more information, see Insensitive cursors.

  • Sensitive cursors The result set can change after the cursor is opened. All changes to the underlying data are visible.

    For more information, see Sensitive cursors.

  • Asensitive cursors Changes may be reflected in the membership, order, or values of the result set seen through the cursor, or may not be reflected at all.

    For more information, see Asensitive cursors.

  • Value-sensitive cursors Changes to the order or values of the underlying data. The membership of the result set is fixed when the cursor is opened.

    For more information, see Value-sensitive cursors.

The differing requirements on cursors place different constraints on execution, and so performance. For more information, see Cursor sensitivity and performance.


Cursor sensitivity example: a deleted row

This example uses a simple query to illustrate how different cursors respond to a row in the result set being deleted.

Consider the following sequence of events:

  1. An application opens a cursor on the following query against the sample database.

    SELECT emp_id, emp_lname
FROM employee
ORDER BY emp_id
    emp_id | emp_lname
    102 | Whitney
    105 | Cobb
    160 | Breault
    ... ...

  2. The application fetches the first row through the cursor (102).

  3. The application fetches the next row through the cursor (105).

  4. A separate transaction deletes employee 102 (Whitney) and commits the change.

The results of cursor actions in this situation depend on the cursor sensitivity:

  • Insensitive cursors The DELETE is not reflected in either the membership or values of the results as seen through the cursor:

    Action | Result
    Fetch previous row | Returns the original copy of the row (102).
    Fetch the first row (absolute fetch) | Returns the original copy of the row (102).
    Fetch the second row (absolute fetch) | Returns the unchanged row (105).

  • Sensitive cursors The membership of the result set has changed so that row 105 is now the first row in the result set:

    Action | Result
    Fetch previous row | Returns Row Not Found error. There is no previous row.
    Fetch the first row (absolute fetch) | Returns row 105.
    Fetch the second row (absolute fetch) | Returns row 160.

  • Value-sensitive cursors The membership of the result set is fixed, and so row 105 is still the second row of the result set. The DELETE is reflected in the values of the cursor, and creates an effective "hole" in the result set.

    Action | Result
    Fetch previous row | Returns No current row of cursor. There is a hole in the cursor where the first row used to be.
    Fetch the first row (absolute fetch) | Returns No current row of cursor. There is a hole in the cursor where the first row used to be.
    Fetch the second row (absolute fetch) | Returns row 105.

  • Asensitive cursors The membership and values of the result set are indeterminate with respect to the changes. The response to a fetch of the previous row, the first row, or the second row depends on the particular optimization method for the query, whether that method involved the formation of a work table, and whether the row being fetched was prefetched from the client.

    The benefit of asensitive cursors is that for many applications, sensitivity is unimportant. In particular, if you are using a forward-only, read-only cursor, no underlying changes are seen. Also, if you are running at a high isolation level, underlying changes are disallowed.


Cursor sensitivity example: an updated row

This example uses a simple query to illustrate how different cursor types respond to a row in the result set being updated in such a way as to change the order of the result set.

Consider the following sequence of events:

  1. An application opens a cursor on the following query against the sample database.

    SELECT emp_id, emp_lname
FROM employee
    emp_id | emp_lname
    102 | Whitney
    105 | Cobb
    160 | Breault
    ... ...

  2. The application fetches the first row through the cursor (102).

  3. The application fetches the next row through the cursor (105).

  4. A separate transaction updates the employee ID of employee 102 (Whitney) to 165 and commits the change.

The results of the cursor actions in this situation depend on the cursor sensitivity:

  • Insensitive cursors The UPDATE is not reflected in either the membership or values of the results as seen through the cursor:

    Action | Result
    Fetch previous row | Returns the original copy of the row (102).
    Fetch the first row (absolute fetch) | Returns the original copy of the row (102).
    Fetch the second row (absolute fetch) | Returns the unchanged row (105).

  • Sensitive cursors The membership of the result set has changed so that row 105 is now the first row in the result set:

    Action | Result
    Fetch previous row | Returns Row Not Found. The membership of the result set has changed so that 105 is now the first row. The cursor is moved to the position before the first row.
    Fetch the first row (absolute fetch) | Returns row 105.
    Fetch the second row (absolute fetch) | Returns row 160.

    In addition, a fetch on a sensitive cursor returns the warning SQLE_ROW_UPDATED_WARNING if the row has changed since the last reading. The warning is given only once. Subsequent fetches of the same row do not produce the warning.

    Similarly, a positioned update or delete through the cursor on a row since it was last fetched returns the SQLE_ROW_UPDATED_SINCE_READ error. An application must fetch the row again for an update or delete on a sensitive cursor to work.

    An update to any column causes the warning/error, even if the column is not referenced by the cursor. For example, a cursor on a query returning emp_lname would report the update even if only the salary column was modified.

  • Value-sensitive cursors The membership of the result set is fixed, and so row 105 is still the second row of the result set. The UPDATE is reflected in the values of the cursor, and creates an effective "hole" in the result set.

    Action | Result
    Fetch previous row | Returns Row Not Found. The membership of the result set has changed so that 105 is now the first row: The cursor is positioned on the hole: it is before row 105.
    Fetch the first row (absolute fetch) | Returns Row Not Found. The membership of the result set has changed so that 105 is now the first row: The cursor is positioned on the hole: it is before row 105.
    Fetch the second row (absolute fetch) | Returns row 105.

  • Asensitive cursors The membership and values of the result set are indeterminate with respect to the changes. The response to a fetch of the previous row, the first row, or the second row depends on the particular optimization method for the query, whether that method involved the formation of a work table, and whether the row being fetched was prefetched from the client.

No warnings or errors in bulk operations mode
Update warning and error conditions do not occur in bulk operations mode (-b database server option).

Previous Next


Insensitive cursors

These cursors have insensitive membership, order, and values. No changes made after cursor open time are visible.

Insensitive cursors are used only for read-only cursor types.

Standards

Insensitive cursors correspond to the ISO/ANSI standard definition of insensitive cursors, and to ODBC static cursors.

Programming interfaces
Interface | Cursor type | Comment
ODBC, OLE DB, and ADO | Static | If an updatable static cursor is requested, a value-sensitive cursor is used instead.
Embedded SQL | INSENSITIVE or NO SCROLL |
JDBC | Unsupported |
Open Client | Unsupported |
Description

Insensitive cursors always return rows that match the query's selection criteria, in the order specified by any ORDER BY clause.

The result set of an insensitive cursor is fully materialized as a work table when the cursor is opened. This has the following consequences:

  • If the result set is very large, the disk space and memory requirements for managing the result set may be significant.

  • No row is returned to the application before the entire result set is assembled as a work table. For complex queries, this may lead to a delay before the first row is returned to the application.

  • Subsequent rows can be fetched directly from the work table, and so are returned quickly. The client library may prefetch several rows at a time, further improving performance.

  • Insensitive cursors are not affected by ROLLBACK or ROLLBACK TO SAVEPOINT.


Sensitive cursors

These cursors have sensitive membership, order, and values.

Sensitive cursors can be used for read-only or updatable cursor types.

Standards

Sensitive cursors correspond to the ISO/ANSI standard definition of sensitive cursors, and to ODBC dynamic cursors.

Programming interfaces
Interface | Cursor type | Comment
ODBC, OLE DB, and ADO | Dynamic |
Embedded SQL | SENSITIVE | Also supplied in response to a request for a DYNAMIC SCROLL cursor when no work table is required and PREFETCH is off.
Description

All changes are visible through the cursor, including changes through the cursor and from other transactions. Higher isolation levels may hide some changes made in other transactions because of locking.

Changes to cursor membership, order, and all column values are all visible. For example, if a sensitive cursor contains a join, and one of the values of one of the underlying tables is modified, then all result rows composed from that base row show the new value. Result set membership and order may change at each fetch.

Sensitive cursors always return rows that match the query's selection criteria, and are in the order specified by any ORDER BY clause. Updates may affect the membership, order, and values of the result set.

The requirements of sensitive cursors place restrictions on the implementation of sensitive cursors:

  • Rows cannot be prefetched, as changes to the prefetched rows would not be visible through the cursor. This may impact performance.

  • Sensitive cursors must be implemented without any work tables being constructed, as changes to those rows stored as work tables would not be visible through the cursor.

  • The no work table limitation restricts the choice of join method by the optimizer and therefore may impact performance.

  • For some queries, the optimizer is unable to construct a plan that does not include a work table that would make a cursor sensitive.

    Work tables are commonly used for sorting and grouping intermediate results. A work table is not needed for sorting if the rows can be accessed through an index. It is not possible to state exactly which queries employ work tables, but the following queries do employ them:

    • UNION queries, although UNION ALL do not necessarily use work tables.

    • Statements with an ORDER BY clause, if there is no index on the ORDER BY column.

    • Any query that is optimized using a hash join.

    • Many queries involving DISTINCT or GROUP BY clauses.

    In these cases, Adaptive Server Anywhere either returns an error to the application, or changes the cursor type to an asensitive cursor and returns a warning.

    For more information on query optimization and the use of work tables, see Query Optimization and Execution.


Asensitive cursors

These cursors do not have well-defined sensitivity in their membership, order, or values. The flexibility that is allowed in the sensitivity permits asensitive cursors to be optimized for performance.

Asensitive cursors are used only for read-only cursor types.

Standards

Asensitive cursors correspond to the ISO/ANSI standard definition of asensitive cursors, and to ODBC cursors with unspecific sensitivity.

Programming interfaces
Interface | Cursor type
ODBC, OLE DB, and ADO | Unspecified sensitivity
Embedded SQL | DYNAMIC SCROLL
Description

A request for an asensitive cursor places few restrictions on the methods Adaptive Server Anywhere can use to optimize the query and return rows to the application. For these reasons, asensitive cursors provide the best performance. In particular, the optimizer is free to employ any measure of materialization of intermediate results as work tables, and rows can be prefetched by the client.

Adaptive Server Anywhere makes no guarantees about the visibility of changes to base underlying rows. Some changes may be visible, others not. Membership and order may change at each fetch. In particular, updates to base rows may result in only some of the updated columns being reflected in the cursor's result.

Asensitive cursors do not guarantee to return rows that match the query's selection and order. The row membership is fixed at cursor open time, but subsequent changes to the underlying values are reflected in the results.

Asensitive cursors always return rows that matched the customer's WHERE and ORDER BY clauses at the time the cursor membership is established. If column values change after the cursor is opened, rows may be returned that no longer match WHERE and ORDER BY clauses.


Value-sensitive cursors

These cursors are insensitive with respect to their membership, and sensitive with respect to the order and values of the result set.

Value-sensitive cursors can be used for read-only or updatable cursor types.

Standards

Value-sensitive cursors do not correspond to an ISO/ANSI standard definition. They correspond to ODBC keyset-driven cursors.

Programming interfaces
Interface | Cursor type
ODBC, OLE DB, and ADO | Keyset-driven
Embedded SQL | SCROLL
JDBC | Keyset-driven
Open Client | Keyset-driven
Description

If the application fetches a row composed of a base underlying row that has changed, then the application must be presented with the updated value, and the SQL_ROW_UPDATED status must be issued to the application. If the application attempts to fetch a row that was composed of a base underlying row that was deleted, a SQL_ROW_DELETED status must be issued to the application.

Changes to primary key values remove the row from the result set (treated as a delete, followed by an insert). A special case occurs when a row in the result set is deleted (either from cursor or outside) and a new row with the same key value is inserted. This will result in the new row replacing the old row where it appeared.

There is no guarantee that rows in the result set match the query's selection or order specification. Since row membership is fixed at open time, subsequent changes that make a row not match the WHERE clause or ORDER BY do not change a row's membership nor position.

All values are sensitive to changes made through the cursor. The sensitivity of membership to changes made through the cursor is controlled by the ODBC option SQL_STATIC_SENSITIVITY. If this option is on, then inserts through the cursor add the row to the cursor. Otherwise, they are not part of the result set. Deletes through the cursor remove the row from the result set, preventing a hole returning the SQL_ROW_DELETED status.

Value-sensitive cursors use a key set table. When the cursor is opened, Adaptive Server Anywhere populates a work table with identifying information for each row contributing to the result set. When scrolling through the result set, the key set table is used to identify the membership of the result set, but values are obtained, if necessary, from the underlying tables.

The fixed membership property of value-sensitive cursors allows your application to remember row positions within a cursor and be assured that these positions will not change. For more information, see Cursor sensitivity example: a deleted row.

  • If a row was updated or may have been updated since the cursor was opened, Adaptive Server Anywhere returns a SQLE_ROW_UPDATED_WARNING when the row is fetched. The warning is generated only once: fetching the same row again does not produce the warning.

    An update to any column of the row causes the warning, even if the updated column is not referenced by the cursor. For example, a cursor on emp_lname and emp_fname would report the update even if only the birthdate column was modified. These update warning and error conditions do not occur in bulk operations mode (-b database server option) when row locking is disabled. See Performance aspects of bulk operations.

    For more information, see Row has been updated since last time read

  • An attempt to execute a positioned update or delete on a row that has been modified since it was last fetched returns a SQLE_ROW_UPDATED_SINCE_READ error and cancels the statement. An application must FETCH the row again before the UPDATE or DELETE is permitted.

    An update to any column of the row causes the error, even if the updated column is not referenced by the cursor. The error does not occur in bulk operations mode.

    For more information, see Row has changed since last read -- operation canceled.

  • If a row has been deleted after the cursor is opened, either through the cursor or from another transaction, a hole is created in the cursor. The membership of the cursor is fixed, so a row position is reserved, but the DELETE operation is reflected in the changed value of the row. If you fetch the row at this hole, you receive a No Current Row of Cursor error (SQL state 24503), indicating that there is no current row, and the cursor is left positioned on the hole. You can avoid holes by using sensitive cursors, as their membership changes along with the values.

    For more information, see No current row of cursor.

Rows cannot be prefetched for value-sensitive cursors. This requirement may impact performance in some cases.

Inserting multiple rows

When inserting multiple rows through a value-sensitive cursor, the new rows appear at the end of the result set. For more information, see Modifying rows through a cursor.


Cursor sensitivity and performance

There is a trade-off between performance and other cursor properties. In particular, making a cursor updatable places restrictions on the cursor query processing and delivery that constrain performance. Also, putting requirements on cursor sensitivity may constrain cursor performance.

To understand how the updatability and sensitivity of cursors affects performance, you need to understand how the results that are visible through a cursor are transmitted from the database to the client application.

In particular, results may be stored at two intermediate locations for performance reasons:

  • Work tables Either intermediate or final results may be stored as work tables. Value-sensitive cursors employ a work table of primary key values. Query characteristics may also lead the optimizer to use work tables in its chosen execution plan.

  • Prefetching The client side of the communication may retrieve rows into a buffer on the client side to avoid separate requests to the database server for each row.

Architecture diagram showing prefetched rows stored in ODBC driver of client application.

Sensitivity and updatability limit the use of intermediate locations.

Any updatable cursor is prevented from using work tables and from prefetching results. If either of these were used, the cursor would be vulnerable to lost updates. The following example illustrates this problem:

  1. An application opens a cursor on the following query against the sample database.

    SELECT id, quantity
FROM product
    id | quantity
    300 | 28
    301 | 54
    302 | 75
    ... ...

  2. The application fetches the row with id = 300 through the cursor.

  3. A separate transaction updates the row is updated using the following statement:

    UPDATE product
SET quantity = quantity - 10
WHERE id = 300

  4. The application updates the row through the cursor to a value of (quantity - 5 ).

  5. The correct final value for the row would be 13. If the cursor had prefetched the row, the new value of the row would be 23. The update from the separate transaction is lost.

Similar restrictions govern sensitivity. For more information, see the descriptions of distinct cursor types.

Prefetching rows


Prefetching rows

Prefetches and multiple-row fetches are different. Prefetches can be carried out without explicit instructions from the client application. Prefetching retrieves rows from the server into a buffer on the client side, but does not make those rows available to the client application until the application fetches the appropriate row.

By default, the Adaptive Server Anywhere client library prefetches multiple rows whenever an application fetches a single row. The Adaptive Server Anywhere client library stores the additional rows in a buffer.

Prefetching assists performance by cutting down on client/server traffic, and increases throughput by making many rows available without a separate request to the server for each row or block of rows.

For more information on controlling prefetches, see PREFETCH option [database].

Controlling prefetching from an application

  • The PREFETCH option controls whether or not prefetching occurs. You can set the PREFETCH option to ON or OFF for a single connection. By default, it is set to ON.

  • In embedded SQL, you can control prefetching on a per-cursor basis when you open a cursor on an individual FETCH operation using the BLOCK clause.

    The application can specify a maximum number of rows contained in a single fetch from the server by specifying the BLOCK clause. For example, if you are fetching and displaying 5 rows at a time, you could use BLOCK 5. Specifying BLOCK 0 fetches 1 record at a time and also causes a FETCH RELATIVE 0 to always fetch the row from the server again.

    Although you can also turn off prefetch by setting a connection parameter on the application, it is more efficient to set BLOCK=0 than to set the PREFETCH option to OFF.

    For more information, see PREFETCH option [database]

  • In Open Client, you can control prefetching behavior using ct_cursor with CS_CURSOR_ROWS after the cursor is declared, but before it is opened.


Cursor sensitivity and isolation levels

Both cursor sensitivity and transaction isolation levels address the problem of concurrency, but in different ways.

By choosing an isolation level for a transaction (often at the connection level), you determine when locks are placed on rows in the database. Locks prevent other transactions from accessing or modifying values in the database.

By choosing a cursor sensitivity, you determine which changes are visible to the application using the cursor. By setting cursor sensitivity you are not determining when locks are placed on rows in the database, and you do not limit the changes that can be made to the database itself.


Describing result sets

Some applications build SQL statements which cannot be completely specified in the application. In some cases, for example, statements depend on a response from the user before the application knows exactly what information to retrieve, such as when a reporting application allows a user to select which columns to display.

In such a case, the application needs a method for retrieving information about both the nature of the result set and the contents of the result set. The information about the nature of the result set, called a descriptor, identifies the data structure, including the number and type of columns expected to be returned. Once the application has determined the nature of the result set, retrieving the contents is straightforward.

This result set metadata (information about the nature and content of the data) is manipulated using descriptors. Obtaining and managing the result set metadata is called describing.

Since cursors generally produce result sets, descriptors and cursors are closely linked, although some interfaces hide the use of descriptors from the user. Typically, statements needing descriptors are either SELECT statements or stored procedures that return result sets.

A sequence for using a descriptor with a cursor-based operation is as follows:

  1. Allocate the descriptor. This may be done implicitly, although some interfaces allow explicit allocation as well.

  2. Prepare the statement.

  3. Describe the statement. If the statement is a stored procedure call or batch, and the result set is not defined by a result clause in the procedure definition, then the describe should occur after opening the cursor.

  4. Declare and open a cursor for the statement (embedded SQL) or execute the statement.

  5. Get the descriptor and modify the allocated area if necessary. This is often done implicitly.

  6. Fetch and process the statement results.

  7. Deallocate the descriptor.

  8. Close the cursor.

  9. Drop the statement. Some interfaces do this automatically.

Implementation notes

  • In embedded SQL, a SQLDA (SQL Descriptor Area) structure holds the descriptor information.

    For more information, see The SQL descriptor area (SQLDA).

  • In ODBC, a descriptor handle allocated using SQLAllocHandle provides access to the fields of a descriptor. You can manipulate these fields using SQLSetDescRec, SQLSetDescField, SQLGetDescRec, and SQLGetDescField.

    Alternatively, you can use SQLDescribeCol and SQLColAttributes to obtain column information.

  • In Open Client, you can use ct_dynamic to prepare a statement and ct_describe to describe the result set of the statement. However, you can also use ct_command to send a SQL statement without preparing it first and use ct_results to handle the returned rows one by one. This is the more common way of operating in Open Client application development.

  • In JDBC, the java.SQL.ResultSetMetaData class provides information about result sets.

  • You can also use descriptors for sending data to the engine (for example, with the INSERT statement); however, this is a different kind of descriptor than for result sets.

    For more information about input and output parameters of the DESCRIBE statement, see the DESCRIBE statement [ESQL].


Controlling transactions in applications

Transactions are sets of atomic SQL statements. Either all statements in the transaction are executed, or none. This section describes a few aspects of transactions in applications.

For more information about transactions, see Using Transactions and Isolation Levels.


Setting autocommit or manual commit mode

Database programming interfaces can operate in either manual commit mode or autocommit mode.

  • Manual commit mode Operations are committed only when your application carries out an explicit commit operation or when the database server carries out an automatic commit, for example when executing an ALTER TABLE statement or other data definition statement. Manual commit mode is also sometimes called chained mode.

    To use transactions in your application, including nested transactions and savepoints, you must operate in manual commit mode.

  • Autocommit mode Each statement is treated as a separate transaction. Autocommit mode is equivalent to appending a COMMIT statement to the end of each of your commands. Autocommit mode is also sometimes called unchained mode.

Autocommit mode can affect the performance and behavior of your application. Do not use autocommit if your application requires transactional integrity.

For information on autocommit impact on performance, see Turn off autocommit mode.


Controlling autocommit behavior

The way to control the commit behavior of your application depends on the programming interface you are using. The implementation of autocommit may be client-side or server-side, depending on the interface.

For more information, see Autocommit implementation details.

toggle To control autocommit mode (ODBC)

  • By default, ODBC operates in autocommit mode. The way you turn off autocommit depends on whether you are using ODBC directly, or using an application development tool. If you are programming directly to the ODBC interface, set the SQL_ATTR_AUTOCOMMIT connection attribute.

toggle To control autocommit mode (ADO.NET)

  • By default, the ADO.NET provider operates in autocommit mode. To use explicit transactions, use the AsaConnection.BeginTransaction method.

    For more information, see Transaction processing.

toggle To control autocommit mode (JDBC)

  • By default, JDBC operates in autocommit mode. To turn off autocommit, use the setAutoCommit method of the connection object:

    conn.setAutoCommit( false );
toggle To control autocommit mode (Open Client)

  • By default, a connection made through Open Client operates in autocommit mode. You can change this behavior by setting the CHAINED database option to ON in your application using a statement such as the following:

    SET OPTION CHAINED='ON'
toggle To control autocommit mode (embedded SQL)

  • By default, embedded SQL applications operate in manual commit mode. To turn on autocommit, set the CHAINED database option to OFF using a statement such as the following:

    SET OPTION CHAINED='OFF'


Autocommit implementation details

The previous section, Controlling autocommit behavior, describes how autocommit behavior can be controlled from each of the Adaptive Server Anywhere programming interfaces. Autocommit mode has slightly different behavior depending on the interface you are using and how you control the autocommit behavior.

Autocommit mode can be implemented in one of two ways:

  • Client-side autocommit When an application uses autocommit, the client-library sends a COMMIT statement after each SQL statement executed.

    Adaptive Server Anywhere uses client-side autocommit for ODBC and OLE DB applications.

  • Server-side autocommit When an application uses autocommit, the database server issues a commit after each SQL statement. This behavior is controlled, implicitly in the case of JDBC, by the CHAINED database option.

    Adaptive Server Anywhere uses server-side autocommit for embedded SQL, JDBC, and Open Client applications.

There is a difference between client-side and server-side autocommit in the case of compound statements such as stored procedures or triggers. From the client side, a stored procedure is a single statement, and so autocommit sends a single commit statement after the whole procedure is executed. From the database server perspective, the stored procedure may be composed of many SQL statements, and so server-side autocommit issues a COMMIT after each SQL statement within the procedure.

Do not mix client-side and server-side implementations
Do not combine use of the CHAINED option with autocommit in your ODBC or OLE DB application.

Previous Next


Controlling the isolation level

You can set the isolation level of a current connection using the ISOLATION_LEVEL database option.

Some interfaces, such as ODBC, allow you to set the isolation level for a connection at connection time. You can reset this level later using the ISOLATION_LEVEL database option.


Cursors and transactions

In general, a cursor closes when a COMMIT is performed. There are two exceptions to this behavior:

  • The CLOSE_ON_ENDTRANS database option is set to OFF.

  • A cursor is opened WITH HOLD, which is the default with Open Client and JDBC.

If either of these two cases is true, the cursor remains open on a COMMIT.

ROLLBACK and cursors

If a transaction rolls back, then cursors close except for those cursors opened WITH HOLD. However, don't rely on the contents of any cursor after a rollback.

The draft ISO SQL3 standard states that on a rollback, all cursors (even those cursors opened WITH HOLD) should close. You can obtain this behavior by setting the ANSI_CLOSE_CURSORS_AT_ROLLBACK option to ON.

Savepoints

If a transaction rolls back to a savepoint, and if the ANSI_CLOSE_CURSORS_AT_ROLLBACK option is ON, then all cursors (even those cursors opened WITH HOLD) opened after the SAVEPOINT close.

Cursors and isolation levels

You can change the isolation level of a connection during a transaction using the SET OPTION statement to alter the ISOLATION_LEVEL option. However, this change affects only closed cursors.


Introduction to Java in the Database

About this chapter

This chapter provides motivation and concepts for using Java in the database.

Adaptive Server Anywhere is a runtime environment for Java. Java provides an alternative to the SQL stored procedure language.


Introduction

Adaptive Server Anywhere is a runtime environment for Java. This means that Java classes can be executed in the database server. Building a runtime environment for Java classes into the database server provides powerful ways of adding programming logic to a database.

Java in the database offers the following:

  • You can reuse Java components in the different layers of your application—client, middle-tier, or server—and use them wherever makes the most sense to you. Adaptive Server Anywhere becomes a platform for distributed computing.

  • Java is a more powerful language than stored procedures for building logic into the database.

  • Java can be used in the database without jeopardizing the integrity, security, and robustness of the database.

Separately-licensable component

Java in the database is a separately licensable component and must be ordered before you can install it. To order this component, see the card in your SQL Anywhere Studio package or see [external link] http://www.sybase.com/detail?id=1015780.

The SQLJ standard

Java in the database is based on the SQLJ Part 1 proposed standard. SQLJ Part 1 provides specifications for calling Java static methods as SQL stored procedures and user-defined functions.


Learning about Java in the database

The following table outlines the documentation regarding the use of Java in the database.

Title | Purpose
Introduction to Java in the Database (this chapter) | Java concepts and how to apply them in Adaptive Server Anywhere.
Using Java in the Database | Practical steps to using Java in the database.
JDBC Programming | Accessing data from Java classes, including distributed computing.
Debugging Logic in the Database | Testing and debugging Java code running in the database.


Using the Java documentation

The following table is a guide to which parts of the Java documentation apply to you, depending on your interests and background.

If you ... | Consider reading ...
Are new to object-oriented programming. | A Java seminar
Want an explanation of terms such as instantiated, field, and class method. | A Java seminar
Are a Java developer who wants to just get started. | The runtime environment for Java in the database Tutorial: A Java in the database exercise
Want to know the key features of Java in the database. | Java in the database Q & A
Want to find out how to access data from Java. | JDBC Programming
Want to prepare a database for Java. | Java-enabling a database


Java in the database Q & A

This section describes the key features of Java in the database.

What are the key features of Java in the database?
How do I store Java instructions in the database?
How does Java get executed in a database?
Why Java?
On what platforms is Java in the database supported?
How do I use Java and SQL together?
How do I access Java from SQL?
Which Java classes are supported?
How can I use my own Java classes in databases?
Can I access data using Java?
Can I move classes from client to server?
What can I not do with Java in the database?


What are the key features of Java in the database?

Detailed explanations of all the following points appear in later sections.

  • You can run Java in the database server An internal Java Virtual Machine (VM) runs Java code in the database server.

  • You can call Java from SQL You can call Java functions (methods) from SQL statements. Java methods provide a more powerful language than SQL stored procedures for adding logic to the database.

  • You can access data from Java An internal JDBC driver lets you access data from Java.

  • You can debug Java in the database You can use the Adaptive Server Anywhere debugger to test and debug your Java classes in the database.

  • SQL is preserved The use of Java does not alter the behavior of existing SQL statements or other aspects of non-Java relational database behavior.


How do I store Java instructions in the database?

Java is an object-oriented language, so its instructions (source code) come in the form of classes. To execute Java in a database, you write the Java instructions outside the database and compile them outside the database into compiled classes (byte code) which are binary files holding Java instructions.

You then install these compiled classes into a database. Once installed, you can execute these classes in the database server as a stored procedure. For example, the following statement creates a Java stored procedure:

CREATE PROCEDURE insertfix()
EXTERNAL NAME 'JDBCExample.InsertFixed ()V'
LANGUAGE JAVA;

Adaptive Server Anywhere is a runtime environment for Java classes, not a Java development environment. You need a Java development environment, such as the Sun Microsystems Java Development Kit, to write and compile Java.

For more information, see Installing Java classes into a database.


How does Java get executed in a database?

Adaptive Server Anywhere includes a Java Virtual Machine (VM) which runs in the database environment. The Adaptive Server Anywhere Java VM interprets compiled Java instructions and runs them in the database server.

In addition to the VM, the SQL request processor in the database server has been extended so it can call into the VM to execute Java instructions. It can also process requests from the VM to enable data access from Java.

Differences from a standalone VM

There is a difference between executing Java code using a standard VM such as the Sun Java VM java.exe and executing Java code in the database. The Sun VM runs from a command line, while the Adaptive Server Anywhere Java VM is available at all times to perform a Java operation whenever it is required as part of the execution of a SQL statement.

You cannot access the Java VM externally. It is only used when the execution of a SQL statement requires a Java operation to take place. The database server starts the VM automatically when needed: you do not have to take any explicit action to start or stop the VM.


Why Java?

Java provides a number of features that make it ideal for use in the database:

  • Thorough error checking at compile time.

  • Built-in error handing with a well-defined error handling methodology.

  • Built-in garbage collection (memory recovery).

  • Elimination of many bug-prone programming techniques.

  • Strong security features.

  • Java code is interpreted, so no operations get executed without being acceptable to the VM.


On what platforms is Java in the database supported?

Java in the database is not supported on Windows CE. It is supported on other Windows operating systems, UNIX, and NetWare.


How do I use Java and SQL together?

Java methods are declared as stored procedures, and can then be called just like SQL stored procedures.

You can use many of the classes that are part of the Java API as included in the Sun Microsystems Java Development Kit. You can also use classes created and compiled by Java developers.


How do I access Java from SQL?

You can treat Java methods as stored procedures, which can be called from SQL.

You must create a stored procedure that runs your method. For example:

CREATE PROCEDURE javaproc()
EXTERNAL NAME 'JDBCExample.MyMethod ()V'
LANGUAGE JAVA;

For more information, see CREATE PROCEDURE statement.

For example, the SQL function PI(*) returns the value for pi. The Java API class java.lang.Math has a parallel field named PI returning the same value. But java.lang.Math also has a field named E that returns the base of the natural logarithms, as well as a method that computes the remainder operation on two arguments as prescribed by the IEEE 754 standard.

Other members of the Java API offer even more specialized functionality. For example, java.util.Stack generates a last-in, first-out queue that can store ordered lists; java.util.HashTable maps values to keys; java.util.StringTokenizer breaks a string of characters into individual word units.


Which Java classes are supported?

The database does not support all Java API classes. Some classes, for example the java.awt package containing user interface components for applications, are inappropriate inside a database server. Other classes, including parts of java.io, deal with writing information to disk, and this also is unsupported in the database server environment.


How can I use my own Java classes in databases?

You can install your own Java classes into a database. For example, a developer could design, write in Java, and compile with a Java compiler a user-created Employee class or Package class.

User-created Java classes can contain both information about the subject and some computational logic. Once installed in a database, Adaptive Server Anywhere lets you use these classes in all parts and operations of the database and execute their functionality (in the form of class or instance methods) as easily as calling a stored procedure.

Java classes and stored procedures are different
Java classes are different from stored procedures. Whereas stored procedures are written in SQL, Java classes provide a more powerful language, and can be called from client applications as easily and in the same way as stored procedures.

For more information, see Installing Java classes into a database.


Can I access data using Java?

The JDBC interface is an industry standard, designed specifically to access database systems. The JDBC classes are designed to connect to a database, request data using SQL statements, and return result sets that can be processed in the client application.

Normally, client applications use JDBC classes, and the database system vendor supplies a JDBC driver that allows the JDBC classes to establish a connection.

You can connect from a client application to Adaptive Server Anywhere via JDBC, using jConnect or the iAnywhere JDBC driver. Adaptive Server Anywhere also provides an internal JDBC driver which permits Java classes installed in a database to use JDBC classes that execute SQL statements.

For more information, see JDBC Programming.


Can I move classes from client to server?

You can create Java classes that can be moved between levels of an enterprise application. The same Java class can be integrated into either the client application, a middle tier, or the database—wherever is most appropriate.

You can move a class containing business logic to any level of the enterprise system, including the server, allowing you complete flexibility to make the most appropriate use of resources. It also enables enterprise customers to develop their applications using a single programming language in a multi-tier architecture with unparalleled flexibility.


What can I not do with Java in the database?

Adaptive Server Anywhere is a runtime environment for Java classes, not a Java development environment.

You cannot carry out the following tasks in the database:

  • Edit class source files (*.java files).

  • Compile Java class source files (*.java files).

  • Execute unsupported Java APIs, such as applet and visual classes.

  • Execute Java methods that require the execution of native methods. All user classes installed into the database must be 100% Java.

The Java classes used in Adaptive Server Anywhere must be written and compiled using a Java application development tool, and then installed into a database for use, testing, and debugging.


A Java seminar

This section introduces key Java concepts. After reading this section you should be able to examine Java code, such as a simple class definition or the invocation of a method, and understand what is taking place.

Java samples directory
Some of the classes used as examples in this manual are located in the Java samples directory, which is the Samples\ASA\Java subdirectory of your SQL Anywhere directory.

Two files represent each Java class example: the Java source and the compiled class. You can immediately install to a database (without modification) the compiled version of the Java class examples.

Understanding Java classes
Understanding Java objects
Understanding fields
Understanding methods
Object oriented and procedural languages
A Java glossary
Java error handling


Understanding Java classes

A Java class combines data and functionality—the ability to hold information and perform computational operations. One way of understanding the concept of a class is to view it as an entity, an abstract representation of a thing.

You could design an Invoice class, for example, to mimic paper invoices, such as those used every day in business operations. Just as a paper invoice contains certain information (line-item details, who is being invoiced, the date, payment amount, payment due-date), so also does an instance of an Invoice class. Classes hold information in fields.

In addition to describing data, a class can make calculations and perform logical operations. For example, the Invoice class could calculate the tax on a list of line items for every Invoice object, and add it to the sub total to produce a final total, without any user intervention. Such a class could also ensure all essential pieces of information are present in the Invoice and even indicate when payment is over due or partially paid. Calculations and other logical operations are carried out by the methods of the class.

Example

The following Java code declares a class called Invoice. This class declaration would be stored in a file named Invoice.java, and then compiled into a Java class using a Java compiler.

Compiling Java classes
Compiling the source for a Java class creates a new file with the same name as the source file, but with a different extension. Compiling Invoice.java creates a file called Invoice.class which could be used in a Java application and executed by a Java VM.

The Sun JDK tool for compiling class declarations is javac.exe.

public class Invoice {
  // So far, this class does nothing and knows nothing
}

The class keyword is used, followed by the name of the class. There is an opening and closing brace: everything declared between the braces, such as fields and methods, becomes part of the class.

In fact, no Java code exists outside class declarations. Even the Java procedure that a Java interpreter runs automatically to create and manage other objects—the main method that is often the start of your application—is itself located within a class declaration.

The Java runtime classes (rt.jar or classes.zip) in the database are built with 1.1 target as installed by JDKs. Any target other than 1.1 will result in ClassFormatErrors. When compiling classes for installation into the database with JDK version, the Java compiler option "target" should be set to 1.1. For example:

javac -target 1.1 Invoice.java

When using JDK 1.3, and earlier, the default target for the compiler is already 1.1.

Subclasses in Java


Subclasses in Java

You can define classes as subclasses of other classes. A class that is a subclass of another class can use the fields and method of its parent: this is called inheritance. You can define additional methods and fields that apply only to the subclass, and redefine the meaning of inherited fields and methods.

Java is a single-hierarchy language, meaning that all classes you create or use eventually inherit from one class. This means the low-level classes (classes further up in the hierarchy) must be present before higher-level classes can be used. The base set of classes required to run Java applications is called the runtime Java classes, or the Java API.


Understanding Java objects

A class is a template that defines what an object is capable of doing, just as an invoice form is a template that defines what information the invoice should contain.

Classes contain no specific information about objects. Rather, your application creates, or instantiates, objects based on the class (template), and the objects hold the data or perform calculations. The instantiated object is an instance of the class. For example, an Invoice object is an instance of the Invoice class. The class defines what the object is capable of but the object is the incarnation of the class that gives the class meaning and usefulness.

In the invoice example, the invoice form defines what all invoices based on that form can accomplish. There is one form and zero or many invoices based on the form. The form contains the definition but the invoice encapsulates the usefulness.

The Invoice object is created, stores information, is stored, retrieved, edited, updated, and so on.

Just as one invoice template can create many invoices, with each invoice separate and distinct from the other in its details, you can generate many objects from one class.

Methods and fields

A method is a part of a class that does something—a function that performs a calculation or interacts with other objects—on behalf of the class. Methods can accept arguments, and return a value to the calling function. If no return value is necessary, a method can return void. Classes can have any number of methods.

A field is a part of a class that holds information. When you create an object of type JavaClass, the fields in JavaClass hold the state unique to that object.

Class constructors


Class constructors

You create an object by invoking a class constructor. A constructor is a method that has the following properties:

  • A constructor method has the same name as the class, and has no declared data type. For example, a simple constructor for the Product class would be declared as follows:

    Product () {
...constructor code here...
}

  • If you include no constructor method in your class definition, a default method is used that is provided by the Java base object.

  • You can supply more than one constructor for each class, with different numbers and types of arguments. When a constructor is invoked, the one with the proper number and type of arguments is used.


Understanding fields

There are two categories of Java fields:

  • Instance fields Each object has its own set of instance fields, created when the object was created. They hold information specific to that instance. For example, a lineItem1Description field in the Invoice class holds the description for a line item on a particular invoice. You can access instance fields only through an object reference.

  • Class fields A class field holds information that is independent of any particular instance. A class field is created when the class is first loaded, and no further instances are created no matter how many objects are created. Class fields can be accessed either through the class name or the object reference.

To declare a field in a class, state its type, then its name, followed by a semicolon. To declare a class field, use the static Java keyword in the declaration. You declare fields in the body of the class and not within a method; declaring a variable within a method makes it a part of the method, not of the class.

Examples

The following declaration of the class Invoice has four fields, corresponding to information that might be contained on two line items on an invoice.

public class Invoice {

    // Fields of an invoice contain the invoice data
    public String lineItem1Description;
    public int lineItem1Cost;

    public String lineItem2Description;
    public int lineItem2Cost;

}


Understanding methods

There are two categories of Java methods:

  • Instance methods A totalSum method in the Invoice class could calculate and add the tax, and return the sum of all costs, but would only be useful if it is called in conjunction with an Invoice object, one that had values for its line item costs. The calculation can only be performed for an object, since the object (not the class) contains the line items of the invoice.

  • Class methods Class methods (also called static methods) can be invoked without first creating an object. Only the name of the class and method is necessary to invoke a class method.

    Similar to instance methods, class methods accept arguments and return values. Typically, class methods perform some sort of utility or information function related to the overall functionality of the class.

    Class methods cannot access instance fields.

To declare a method, you state its return type, its name and any parameters it takes. Like a class declaration, the method uses an opening and closing brace to identify the body of the method where the code goes.

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;
    }
}

Within the body of the totalSum method, a variable named runningsum is declared. First, this holds the sub total of the first and second line item cost. This sub total is then multiplied by 15 per cent (the rate of taxation) to determine the total sum.

The local variable (as it is known within the method body) is then returned to the calling function. When you invoke the totalSum method, it returns the sum of the two line item cost fields plus the cost of tax on those two items.

Example

The parseInt method of the java.lang.Integer class, which is supplied with Adaptive Server Anywhere, is one example of a class method. When given a string argument, the parseInt method returns the integer version of the string.

For example given the string value "1", the parseInt method returns 1, the integer value, without requiring an instance of the java.lang.Integer class to first be created, as illustrated by this Java code fragment:

String num = "1";
int i = java.lang.Integer.parseInt( num );
Example

The following version of the Invoice class now includes both an instance method and a class method. The class method named rateOfTaxation returns the rate of taxation used by the class to calculate the total sum of the invoice.

The advantage of making the rateOfTaxation method a class method (as opposed to an instance method or field) is that other classes and procedures can use the value returned by this method without having to create an instance of the class first. Only the name of the class and method is required to return the rate of taxation used by this class.

Making rateofTaxation a method, as opposed to a field, allows the application developer to change how the rate is calculated without adversely affecting any objects, applications, or procedures that use its return value. Future versions of Invoice could make the return value of the rateOfTaxation class method based on a more complicated calculation without affecting other methods that use its return value.

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;
    }
}


Object oriented and procedural languages

If you are more familiar with procedural languages such as C, or the SQL stored procedure language, than object-oriented languages, this section explains some of the key similarities and differences between procedural and object-oriented languages.

Java is based on classes

The main structural unit of code in Java is a class.

A Java class could be looked at as just a collection of procedures and variables that have been grouped together because they all relate to a specific, identifiable category.

However the manner in which a class gets used sets object-oriented languages apart from procedural languages. When an application written in a procedural language is executed, it is typically loaded into memory once and takes the user down a pre-defined course of execution.

In object-oriented languages such as Java, a class is used like a template: a definition of potential program execution. Multiple copies of the class can be created and loaded dynamically, as needed, with each instance of the class capable of containing its own data, values, and course of execution. Each loaded class could be acted on or executed independently of any other class loaded into memory.

A class that is loaded into memory for execution is said to have been instantiated. An instantiated class is called an object: it is an application derived from the class that is prepared to hold unique values or have its methods executed in a manner independent of other class instances.


A Java glossary

The following items outline some of the details regarding Java classes. It is by no means an exhaustive source of knowledge about the Java language, but may aid in the use of Java classes in Adaptive Server Anywhere.

For more information about the Java language, see the online book Thinking in Java, by Bruce Eckel, included with Adaptive Server Anywhere in the file Samples\ASA\Java\Tjava.pdf.

Packages

A package is a grouping of classes that share a common purpose or category. One member of a package has special privileges to access data and methods in other members of the package, hence the protected access modifier.

A package is the Java equivalent of a library. It is a collection of classes which can be made available using the import statement. The following Java statement imports the utility library from the Java API:

import java.util.*

Packages are typically held in JAR files, which have the extension .jar or .zip.

Public versus private

An access modifier determines the visibility (essentially the public, private, or protected keyword used in front of any declaration) of a field, method or class to other Java objects.

  • A public class, method, or field is visible everywhere.

  • A private class, method, or field is visible only in methods defined within that class.

  • A protected method or field is visible to methods defined within that class, within sublclasses of the class, or within other classes in the same package.

  • The default visibility, known as package, means that the method or field is visible within the class and to other classes in the same package.

Constructors

A constructor is a special method of a Java class that is called when an instance of the class is created.

Classes can define their own constructors, including multiple, overriding constructors. Which arguments were used in the attempt to create the object determine which constructor is used. When the type, number, and order of arguments used to create an instance of the class match one of the class's constructors, that constructor is used when creating the object.

Garbage collection

Garbage collection automatically removes any object with no references to it, with the exception of objects stored as values in a table.

There is no such thing as a destructor method in Java (as there is in C++). Java classes can define their own finalize method for clean up operations when an object is discarded during garbage collection.

Interfaces

Java classes can inherit only from one class. Java uses interfaces instead of multiple-inheritance. A class can implement multiple interfaces. Each interface defines a set of methods and method profiles that must be implemented by the class for the class to be compiled.

An interface defines what methods and static fields the class must declare. The implementation of the methods and fields declared in an interface is located within the class that uses the interface: the interface defines what the class must declare; it is up to the class to determine how it is implemented.


Java error handling

Java error handling code is separate from the code for normal processing.

Errors generate an exception object representing the error. This is called throwing an exception. A thrown exception terminates a Java program unless it is caught and handled properly at some level of the application.

Both Java API classes and custom-created classes can throw exceptions. In fact, users can create their own exception classes which throw their own custom-created classes.

If there is no exception handler in the body of the method where the exception occurred, then the search for an exception handler continues up the call stack. If the top of the call stack is reached and no exception handler has been found, the default exception handler of the Java interpreter running the application is called and the program terminates.

In Adaptive Server Anywhere, if a SQL statement calls a Java method, and an unhandled exception is thrown, a SQL error is generated.

Error types in Java

All errors in Java come from two types of error classes: Exception and Error. Usually, Exception-based errors are handled by error handling code in your method body. Error type errors are specifically for internal errors and resource exhaustion errors inside the Java run-time system.

Exception class errors are thrown and caught. Exception handling code is characterized by try, catch, and finally code blocks.

A try block executes code that may generate an error. A catch block is code that executes if the execution of a try block generates (or throws) an error.

A finally block defines a block of code that executes regardless of whether an error was generated and caught and is typically used for cleanup operations. It is used for code that, under no circumstances, can be omitted.

There are two types of exception class errors: those that are runtime exceptions and those that are not runtime exceptions.

Errors generated by the runtime system are known as implicit exceptions, in that they do not have to be explicitly handled as part of every class or method declaration.

For example, an array out of bounds exception can occur whenever an array is used, but the error does not have to be part of the declaration of the class or method that uses the array.

All other exceptions are explicit. If the method being invoked can throw an error, it must be explicitly caught by the class using the exception-throwing method, or this class must explicitly throw the error itself by identifying the exception it may generate in its class declaration. Essentially, explicit exceptions must be dealt with explicitly. A method must declare all the explicit errors it throws, or catch all the explicit errors that may potentially be thrown.

Non-runtime exceptions are checked at compile time. Java catches many such errors during compilation, before running the code.

Every Java method is given an alternative path of execution so that all Java methods complete, even if they are unable to complete normally. If the type of error thrown is not caught, it's passed to the next code block or method in the stack.


The runtime environment for Java in the database

This section describes the Adaptive Server Anywhere runtime environment for Java, and how it differs from a standard Java runtime environment.

Supported versions of Java and JDBC
The runtime Java classes
Java is case sensitive
Strings in Java and SQL
Printing to the command line
Using the main method
Scope and persistence
Java escape characters in SQL statements
Use of import statements
Using the CLASSPATH variable
Public fields


Supported versions of Java and JDBC

The Java VM provides you with the choice of using the JDK 1.1, JDK 1.2, or JDK 1.3 programming interfaces. The specific versions provided are JDK versions 1.1.8 and 1.3.

Between release 1.0 of the JDK and release 1.1, several new APIs were introduced. As well, a number were deprecated—the use of certain APIs became no longer recommended and support for them may be dropped in future releases.

A Java class file using deprecated APIs generates a warning when compiled, but does still execute on a Java virtual machine built to release 1.1 standards, such as the Adaptive Server Anywhere VM.

The internal JDBC driver supports JDBC version 2.

For information on how to create a database that supports Java, see Java-enabling a database.


The runtime Java classes

The runtime Java classes are the low-level classes that are made available to a database when it is created or Java-enabled. These classes include a subset of the Java API. These classes are part of the Sun Java Development Kit.

The runtime classes provide basic functionality on which to build applications. The runtime classes are always available to classes in the database.

You can incorporate the runtime Java classes in your own user-created classes: either inheriting their functionality or using it within a calculation or operation in a method.

Examples

Some Java API classes included in the runtime Java classes include:

  • Primitive Java data types All primitive (native) data types in Java have a corresponding class. In addition to being able to create objects of these types, the classes have additional, often useful, functionality.

    The Java int data type has a corresponding class in java.lang.Integer.

  • The utility package The package java.util.* contains a number of very helpful classes whose functionality has no parallel in the SQL functions available in Adaptive Server Anywhere.

    Some of the classes include:

    • Hashtable which maps keys to values.

    • StringTokenizer which breaks a String down into individual words.

    • Vector which holds an array of objects whose size can change dynamically

    • Stack which holds a last-in, first-out stack of objects.

  • JDBC for SQL operations The package java.SQL.* contains the classes needed by Java objects to extract data from the database using SQL statements.

Unlike user-defined classes, the runtime classes are not stored in the database. Instead, they are stored in files in the java subdirectory of the Adaptive Server Anywhere installation directory.

User-defined classes


User-defined classes

User-defined classes are installed into a database using the INSTALL JAVA statement. Once installed, they become available to other classes in the database. If they are public classes, they are available from SQL as domains.

For more information about installing classes, see Installing Java classes into a database.


Java is case sensitive

Java syntax works as you would expect it to, and SQL syntax is unaltered by the presence of Java classes. This is true even if the same SQL statement contains both Java and SQL syntax. It's a simple statement, but with far-reaching implications.

Java is case sensitive. The Java class FindOut is a completely different class from the class Findout. SQL is case insensitive with respect to keywords and identifiers.

Java case sensitivity is preserved even when embedded in a SQL statement that is case insensitive. The Java parts of the statement must be case sensitive, even though the parts previous to and following the Java syntax can be in either upper or lower case.

For example, the following SQL statements successfully execute because the case of Java objects, classes, and operators is respected even though there is variation in the case of the remaining SQL parts of the statement.

SeLeCt java.lang.Math.random();


Strings in Java and SQL

A set of double quotes identifies string literals in Java, as in the following Java code fragment:

String str = "This is a string";

In SQL, however, single quotes mark strings, and double quotes indicate an identifier, as illustrated by the following SQL statement:

INSERT INTO TABLE DBA.t1
VALUES( 'Hello' )

You should always use the double quote in Java source code, and single quotes in SQL statements.

For example, the following SQL statements are valid.

CREATE VARIABLE str char(20);
SET str = NEW java.lang.String( 'Brand new object' )

The following Java code fragment is also valid, if used within a Java class.

String str = new java.lang.String(
            "Brand new object" );


Printing to the command line

Printing to the standard output is a quick way of checking variable values and execution results at various points of code execution. When the method in the second line of the following Java code fragment is encountered, the string argument it accepts prints out to standard output.

String str = "Hello world";
System.out.println( str );

In Adaptive Server Anywhere, standard output is the server window, so the string appears there. Executing the above Java code within the database is the equivalent of the following SQL statement.

MESSAGE 'Hello world'


Using the main method

When a class contains a main method matching the following declaration, most Java run time environments, such as the Sun Java interpreter, execute it automatically. Normally, this static method executes only if it is the class being invoked by the Java interpreter

public static void main( String args[ ] ) { }

Useful for testing the functionality of Java objects, you are always guaranteed this method will be called first, when the Sun Java runtime system starts.

In Adaptive Server Anywhere, the Java runtime system is always available. The functionality of objects and methods can be tested in an ad hoc, dynamic manner using SQL statements. In many ways this is far more flexible for testing Java class functionality.


Scope and persistence

SQL variables are persistent only for the duration of the connection. This is unchanged from previous versions of Adaptive Server Anywhere, and is unaffected by whether the variable is a Java class or a native SQL data type.

The persistence of Java classes is analogous to tables in a database: tables exist in the database until you drop them, regardless of whether they hold data or even whether they are ever used. Java classes installed to a database are similar: they are available for use until you explicitly remove them with a REMOVE JAVA statement.

For more information on removing classes, see REMOVE JAVA statement.

A class method in an installed Java class can be called at any time from a SQL statement. You can execute the following statement anywhere you can execute SQL statements.

SELECT java.lang.Math.abs(-342)

A Java object is only available in two forms: as the value of a variable, or as a value in a table.


Java escape characters in SQL statements

In Java code, you can use escape characters to insert certain special characters into strings. Consider the following code, which inserts a new line and tab in front of a sentence containing an apostrophe.

String str = "\n\t\This is an object\'s string literal";

Adaptive Server Anywhere permits the use of Java escape characters only when being used by Java classes. From within SQL, however, you must follow the rules that apply to strings in SQL.

For example, to pass a string value to a field using a SQL statement, you could use the following statement (which includes SQL escape characters), but the Java escape characters could not be used.

SET obj.str = '\nThis is the object''s string field';

For more information on SQL string handling rules, see Strings.


Use of import statements

It is common in a Java class declaration to include an import statement to access classes in another package. You can reference imported classes using unqualified class names.

For example, you can reference the Stack class of the java.util package in two ways:

  • explicitly using the name java.util.Stack, or

  • using the name Stack, and including the following import statement:

    import java.util.*;
Classes further up in the hierarchy must also be installed.

A class referenced by another class, either explicitly with a fully qualified name or implicitly using an import statement, must also be installed in the database.

The import statement works as intended within compiled classes. However, within the Adaptive Server Anywhere runtime environment, no equivalent to the import statement exists. All class names used in SQL statements or stored procedures must be fully qualified. For example, to create a variable of type String, you would reference the class using the fully qualified name: java.lang.String.


Using the CLASSPATH variable

Sun's Java runtime environment and the Sun JDK Java compiler use the CLASSPATH environment variable to locate classes referenced within Java code. A CLASSPATH variable provides the link between Java code and the actual file path or URL location of the classes being referenced. For example, import java.io.* allows all the classes in the java.io package to be referenced without a fully qualified name. Only the class name is required in the following Java code to use classes from the java.io package. The CLASSPATH environment variable on the system where the Java class declaration is to be compiled must include the location of the Java directory, the root of the java.io package.

CLASSPATH ignored at runtime

The CLASSPATH environment variable does not affect the Adaptive Server Anywhere runtime environment for Java during the execution of Java operations because the classes are stored in the database, instead of in external files or archives.

CLASSPATH used to install classes

The CLASSPATH variable can, however, be used to locate a file during the installation of classes. For example, the following statement installs a user-created Java class to a database, but only specifies the name of the file, not its full path and name. (Note that this statement involves no Java operations.)

INSTALL JAVA NEW
FROM FILE 'Invoice.class'

If the file specified is in a directory or zip file specified by the CLASSPATH environmental variable, Adaptive Server Anywhere will successfully locate the file and install the class.


Public fields

It is a common practice in object-oriented programming to define class fields as private and make their values available only through public methods.

Many of the examples used in this documentation render fields public to make examples more compact and easier to read. Using public fields in Adaptive Server Anywhere also offers a performance advantage over accessing public methods.

The general convention followed in this documentation is that a user-created Java class designed for use in Adaptive Server Anywhere exposes its main values in its fields. Methods contain computational automation and logic that may act on these fields.


Tutorial: A Java in the database exercise

This tutorial is a primer for invoking Java operations on Java classes and objects using SQL statements. It describes how to install a Java class into the database. It also describes how to access the class and its members and methods from SQL statements. The tutorial uses the Invoice class created in A Java seminar.

Requirements

The tutorial assumes that you have installed Java in the database software. It also assumes that you have a Java Development Kit (JDK) installed, including the Java compiler (javac).

If you do not have Java installed into the database, the following SQL can be used:

ALTER DATABASE UPGRADE JAVA ON;

You must restart the database server for this operation to take effect.

If you do not have a database, you can initialize a database with Java enabled, using the Sybase Central Wizard or dbinit for example:

dbinit –ja mydb.db
Resources

Source code and batch files for this sample are provided in the folder samples/ASA/Java under your SQL Anywhere folder.


Create and compile the sample Java class

The first step is to write the Java code and compile it. This is done outside the database

toggle To create and compile the class

  1. Create the sample Java class.

    The sample code is installed. For your convenience, the sample code is included here. Paste the following code into Invoice.java:

    public class Invoice {
    public static String lineItem1Description;
    public static double lineItem1Cost;

    public static String lineItem2Description;
    public static double lineItem2Cost;

    public static double totalSum() {
        double runningsum;
        double taxfactor = 1 + Invoice.rateOfTaxation();

          runningsum = lineItem1Cost + lineItem2Cost;
          runningsum = runningsum * taxfactor;

          return runningsum;
    }

    public static double rateOfTaxation() {
          double rate;
          rate = .15;

          return rate;
    }

    public static void init( String item1desc, double item1cost,
                                                                                String item2desc, double item2cost ) {
          lineItem1Description = item1desc;
          lineItem1Cost = item1cost;
          lineItem2Description = item2desc;
          lineItem2Cost = item2cost;
    }

    public static String getLineItem1Description() {
        return lineItem1Description;
    }

    public static double getLineItem1Cost() {
        return lineItem1Cost;
    }

    public static String getLineItem2Description() {
        return lineItem2Description;
    }

    public static double getLineItem2Cost() {
        return lineItem2Cost;
    }
}

    You can find source code for this class as the file Samples\ASA\JavaInvoice\Invoice.java under your SQL Anywhere directory.

  2. Compile the file to create the file Invoice.class.

    From a command prompt, change to the directory samples\ASA\Java and execute the following command.

    javac -target 1.1 *.java

    The Java runtime classes (rt.jar or classes.zip) in the database are built with 1.1 target as installed by JDKs. Any target other than 1.1 will result in ClassFormatErrors. When compiling classes for installation into the database with JDK version, the Java compiler option "target" should be set to 1.1.

    When using JDK 1.3, and earlier, the default target for the compiler is already 1.1.

    The class is now compiled and ready to be installed into the database.


Install the sample Java class

Java classes must be installed into a database before they can be used. You can install classes from Sybase Central or Interactive SQL. This section provides instructions for both. Choose whichever you prefer.

toggle To install the class to the sample database (Sybase Central)

  1. Start Sybase Central and connect to the sample database.

  2. Open the Java Objects folder and double-click Add Java Class.

    The Java Class Creation wizard appears.

  3. Use the Browse button to locate Invoice.class in the Samples/ASA/Java subfolder of your SQL Anywhere installation folder.

  4. Click Finish to exit the wizard.

toggle To install the class to the sample database (Interactive SQL)

  1. Start Interactive SQL and connect to the sample database.

  2. In the SQL Statements pane of Interactive SQL, type the following command:

    INSTALL JAVA NEW
FROM FILE
'path/samples/ASA/Java/Invoice.class'

    where path is your SQL Anywhere folder. The class is now installed into the sample database.

Notes

  • At this point no Java in the database operations have taken place. The class has been installed into the database and is ready for use.

  • Changes made to the class file from now on are not automatically reflected in the copy of the class in the database. You must re-install the classes if you want the changes reflected.

For more information on installing classes, and for information on updating an installed class, see Installing Java classes into a database.


Access fields and methods of the Java object

To access the Java methods in the class, you must creating stored procedures or user-defined functions that act as wrappers for the methods in the class.

toggle To create stored procedures/functions for the methods in the class

  1. To pass arguments to a Java method, create the following SQL wrapper:

    CREATE PROCEDURE init( IN arg1 CHAR(10),
                       IN arg2 DOUBLE,
                       IN arg3 CHAR(10),
                       IN arg4 DOUBLE)
EXTERNAL NAME 'Invoice.init (Ljava/lang/String;DLjava/lang/String;D)V'
LANGUAGE JAVA;

    For more information about the syntax of this command, see CREATE PROCEDURE statement.

  2. To retrieve return codes from a Java method, create the following SQL wrappers:

    CREATE FUNCTION taxationrate()
RETURNS DOUBLE
EXTERNAL NAME      'Invoice.rateOfTaxation ()D'
LANGUAGE JAVA;
CREATE FUNCTION totalSum()
RETURNS DOUBLE
EXTERNAL NAME 'Invoice.totalSum ()D'
LANGUAGE JAVA;
CREATE FUNCTION linedesc1()
RETURNS CHAR(10)
EXTERNAL NAME
      'Invoice.getLineItem1Description ()Ljava/lang/String;'
LANGUAGE JAVA;

    For more information about the syntax of these commands, see CREATE FUNCTION statement.

  3. To retrieve return codes from a Java attribute, create the following SQL wrapper:

    CREATE FUNCTION linecost2()
RETURNS DOUBLE
EXTERNAL NAME
      'Invoice.getLineItem2Cost ()D'
LANGUAGE JAVA;

    Note that there is a space between the signature and the name of the method/attribute. Also note the case of the signature of Java method is case sensitive.

Using the Java functionality

We can now invoke the methods and access attributes from SQL with stored procedures and functions.

CALL init('prod1',10.00,'prod2',25.00);
SELECT taxationrate(),totalSum(),linedesc1(),linecost2();

The query returns four columns with values as follows:

Taxationrate(*) | totalSum(*) | linedesc1(*) | linecost2(*)
.15 | 40.25 | prod1 | 25


Using Java in the Database

About this chapter

This chapter describes how to add Java classes to your database, and how to use these classes in a relational database.

Introduction
Java-enabling a database
Installing Java classes into a database
Special features of Java classes in the database
Configuring memory for Java
Java classes reference


Introduction

This chapter describes how to accomplish tasks using Java in the database, including the following:

  • How to Java-enable a database You need to follow certain steps to enable your database to use Java.

  • Installing Java classes You need to install Java classes in a database to make them available for use in Adaptive Server Anywhere.


Setting up the Java sample

Some of the examples in this chapter require you to add the JDBCExamples class to the sample database.

Setting up the Java examples involves two steps:

  1. Java-enable the sample database. Adaptive Server Anywhere databases are not Java-enabled by default.

  2. Add the JDBCExamples class to the database.

toggle To Java-enable the sample database

  1. Start Sybase Central and connect to the sample database (ASA 9.0 Sample ODBC data source). An asademo9 database server appears with an asademo database.

  2. In the left pane of Sybase Central, right click the asademo database and choose Upgrade Database from the popup menu. The Upgrade a Database wizard appears.

  3. Follow the instructions in the Upgrade a Database wizard. Choose the option to Install Java Support with a JDK version of 1.3.

  4. Restart the sample database.

    When the Upgrade a Database wizard has completed, disconnect and ensure that the sample database is shut down. The database must be shut down and restarted before Java support can be used.

  5. Confirm that Java support has been added:

    • From Sybase Central, connect to the sample database.

    • In the left pane of Sybase Central, right click the asademo database and choose Properties from the popup menu.

    • Confirm that Java JDK version is set to 1.3.

toggle To add the JDBCExamples class to the sample database

  1. Start Sybase Central and connect to the sample database (ASA 9.0 Sample ODBC data source). An asademo9 database server appears with an asademo database.

  2. In the left pane of Sybase Central, open the Java Objects folder.

  3. Right-click the right pane and choose New > Java Class from the popup menu. The Create a New Java Class wizard appears.

  4. Click Browse and locate JDBCExamples.class in the Samples\ASA\Java subdirectory of your SQL Anywhere installation.

  5. Click OK and click Finish to complete the installation.


Managing the runtime environment for Java

The runtime environment for Java consists of:

  • The Adaptive Server Anywhere Java Virtual Machine Running within the database server, the Adaptive Server Anywhere Java Virtual Machine interprets and executes the compiled Java class files.

  • The runtime Java classes When you create a database, a set of Java classes becomes available to the database. Java applications in the database require these runtime classes to work properly.

Management tasks for Java

To provide a runtime environment for Java, you need to carry out the following tasks:

  • Java-enable your database This task involves ensuring the availability of built-in classes and the upgrading of the database to Version 9.

    For more information, see Java-enabling a database.

  • Install other classes your users need This task involves ensuring that classes other than the runtime classes are installed and up to date.

    For more information, see Installing Java classes into a database.

  • Configuring your server You must configure your server to make the necessary memory available to run Java tasks.

    For more information, see Configuring memory for Java.

Tools for managing Java

You can carry out all these tasks from Sybase Central or from Interactive SQL.


Java-enabling a database

The Adaptive Server Anywhere Runtime environment for Java requires a Java VM and the Adaptive Server Anywhere runtime Java classes. You need to Java-enable a database for it to be able to use the runtime Java classes.

Java in the database is a separately-licensed component of SQL Anywhere Studio.

New databases are not Java-enabled by default
By default, databases created with Adaptive Server Anywhere are not Java-enabled.

Java is a single-hierarchy language, meaning that all classes you create or use eventually inherit from one class. This means the low-level classes (classes further up in the hierarchy) must be present before you can use higher-level classes. The base set of classes required to run Java applications are the runtime Java classes, or the Java API.

When not to Java-enable a database

Java-enabling a database adds many entries into the system tables. This adds to the size of the database and, more significantly, adds about 200K to the memory requirements for running the database, even if you do not use any Java functionality.

If you are not going to use Java, and if you are running in a limited-memory environment, you may wish to not Java-enable your database.

The Adaptive Server Anywhere runtime Java classes
Ways of Java-enabling a database
New databases and Java
Upgrading databases and Java
Java-enabling a database
Using Sybase Central to Java-enable a database


The Adaptive Server Anywhere runtime Java classes

The Adaptive Server Anywhere runtime Java classes are held on disk rather than stored in a database like other classes. The following files contain the Adaptive Server Anywhere runtime Java classes. The files are in the Java subdirectory of your SQL Anywhere directory:

  • 1.1\classes.zip This file, licensed from Sun Microsystems, contains a subset of the Sun Microsystems Java runtime classes for JDK 1.1.8.

  • 1.3\rt.jar This file, licensed from Sun Microsystems, contains a subset of the Sun Microsystems Java runtime classes for JDK 1.3.

  • asajdbc.zip This file contains Adaptive Server Anywhere internal JDBC driver classes for JDK 1.1.

  • asajrt12.zip This file contains Adaptive Server Anywhere internal JDBC driver classes for JDK 1.2 and JDK 1.3.

When you Java-enable a database, you also update the system tables with a list of available classes from the system JAR files. You can then browse the class hierarchy from Sybase Central, but the classes themselves are not present in the database.

JAR files

The database stores runtime class names the under the following JAR files:

  • ASACIS Classes required for remote data access are stored here.

  • ASAJDBCDRV Class names from jdbcdrv.zip are held here. (com.sybase.jdbc package).

  • ASAJIO

  • ASAJRT Class names from asajdbc.zip are held here.

  • ASASystem Class names from classes.zip are held here.

  • ASASystemUNIX Class names from classes.zip are held here.

Installed packages

These runtime classes include the following packages:

  • java Packages stored here include the supported Java runtime classes from Sun Microsystems.

  • com.sybase Packages stored here provide server-side JDBC support.

  • sun Sun Microsystems provides the packages stored here.

  • sybase.sql Packages stored here are part of the server-side JDBC support.

Caution: do not install classes from another version of Sun's JDK Classes in Sun's JDK share names with the Adaptive Server Anywhere runtime Java classes that must be installed in any database intended to execute Java operations.

You must not replace the classes.zip file included with Adaptive Server Anywhere. Using another version of these classes could cause compatibility problems with the Adaptive Server Anywhere Java Virtual Machine.

You must only Java-enable a database using the methods outlined in this section.


Ways of Java-enabling a database

You can Java-enable databases when you create them, when you upgrade them, or in a separate operation at a later time.

Creating databases

You can create a Java-enabled database using:

  • the CREATE DATABASE statement.

    For details of the syntax, see CREATE DATABASE statement.

  • the dbinit utility.

    For details, see Creating a database using the dbinit command-line utility.

  • Sybase Central.

    For details, see Creating a database.

Upgrading databases

You can upgrade a database to a Java-enabled Version 9 database using:

  • the ALTER DATABASE statement.

    For details of the syntax, see ALTER DATABASE statement.

  • the dbupgrad.exe upgrade utility.

    For details, see Upgrading a database using the dbupgrad command-line utility.

  • Sybase Central.

    For details, see Java-enabling a database.

If you choose not to install Java in the database, all database operations not involving Java operations remain fully functional and work as expected.


New databases and Java

By default, Adaptive Server Anywhere does not install Adaptive Server Anywhere runtime Java classes each time you create a database. The installation of this separately-licensable component is optional, and controlled by the method you use to create the database.

CREATE DATABASE options

The CREATE DATABASE SQL statement has an option called JAVA. To Java-enable a database, you can set the option to ON. To disable Java, set the option to OFF. This option is set to OFF by default.

For example, the following statement creates a Java-enabled database file named temp.db:

CREATE DATABASE 'c:\\sybase\\asa9\\temp' JAVA ON

The following statement creates a database file named temp2.db, which does not support Java.

CREATE DATABASE 'c:\\sybase\\asa9\\temp2'
Database initialization utility

You can create databases using the dbinit.exe database initialization utility. This utility has options that control whether or not to install the runtime Java classes in the newly-created database. By default, the classes are not installed.

The same options are available when creating databases using Sybase Central.


Upgrading databases and Java

You can upgrade existing databases created with earlier versions of the software using the Upgrade utility or the ALTER DATABASE statement.

Database upgrade utility

You can upgrade databases to Adaptive Server Anywhere Version 9 standards using the dbupgrad.exe utility. Using the –jr Upgrade utility option prevents the installation of Adaptive Server Anywhere runtime Java classes.

For information on the conditions under which Java in the database is included in the upgraded database, see Upgrading a database using the dbupgrad command-line utility.


Java-enabling a database

Java-enabling a database

If you have created a database, or upgraded a database to standards, but have chosen not to Java-enable the database, you can add the necessary Java classes at a later date, using either Sybase Central or Interactive SQL.

toggle To add the Java runtime classes to a database (Sybase Central)

  1. Connect to the database from Sybase Central as a user with DBA authority.

  2. Right-click the database and choose Upgrade Database.

  3. Click Next on the introductory page of the wizard.

  4. Select the database you want to upgrade from the list.

  5. You can choose to create a backup of the database if you wish. Click Next.

  6. You can choose to install jConnect meta-information support if you wish. Click Next.

  7. Select the Install Java Support option. You must also choose which version of the JDK you want to install. The default classes are the JDK 1.3 classes.

  8. Follow the remaining instructions in the wizard.

toggle To add the Java runtime classes to a database (SQL)

  1. Connect to the database from Interactive SQL as a user with DBA authority.

  2. Execute the following statement:

    ALTER DATABASE UPGRADE JAVA ON

    For more information, see ALTER DATABASE statement.

  3. Restart the database for the Java support to take effect.


Using Sybase Central to Java-enable a database

You can use Sybase Central to create databases using wizards. During the creation or upgrade of a database, the wizard prompts you to choose whether or not you have the Adaptive Server Anywhere runtime Java classes installed. By default, this option Java-enables the database.

Using Sybase Central, you can create or upgrade a database by choosing:

  • Choosing File > Create Database to create a new database.

  • Clicking the database server in the left pane, clicking the Utilities tab in the right pane, and double-clicking Upgrade Database to upgrade a database from a previous version of the software to a database with Java capabilities.


Installing Java classes into a database

Before you install a Java class into a database, you must compile it. You can install Java classes into a database as:

  • A single class You can install a single class into a database from a compiled class file. Class files typically have extension .class.

  • A JAR You can install a set of classes all at once if they are in either a compressed or uncompressed JAR file. JAR files typically have the extension .jar or .zip. Adaptive Server Anywhere supports all compressed JAR files created with the Sun JAR utility, and some other JAR compression schemes as well.

This section describes how to install Java classes once you have compiled them. You must have DBA authority to install a class or JAR.


Creating a class

Although the details of each step may differ depending on whether you are using a Java development tool, the steps involved in creating your own class generally include the following:

toggle To create a class

  1. Define your class Write the Java code that defines your class. If you are using the Sun Java SDK then you can use a text editor. If you are using a development tool, the development tool provides instructions.

    Use only supported classes
    User classes must be 100% Java. Native methods are not allowed.

  2. Name and save your class Save your class declaration (Java code) in a file with the extension .java. Make certain the name of the file is the same as the name of the class and that the case of both names is identical.

    For example, a class called Utility should be saved in a file called Utility.java.

  3. Compile your class This step turns your class declaration containing Java code into a new, separate file containing byte code. The name of the new file is the same as the Java code file but has an extension of .class. You can run a compiled Java class in a Java runtime environment, regardless of the platform you compiled it on or the operating system of the runtime environment.

    The Sun JDK contains a Java compiler, Javac.exe.

    Java-enabled databases only
    You can install any compiled Java class file in a database. However, Java operations using an installed class can only take place if the database has been Java-enabled as described in Java-enabling a database.

Previous Next


Installing a class

To make your Java class available within the database, you install the class into the database either from Sybase Central, or using the INSTALL JAVA statement from Interactive SQL or other application. You must know the path and file name of the class you wish to install.

You require DBA authority to install a class.

toggle To install a class (Sybase Central)

  1. Connect to a database with DBA authority.

  2. Open the Java Objects folder for the database.

  3. Right-click in the right pane and choose New > Java Class from the popup menu.

  4. Follow the instructions in the wizard.

toggle To install a class (SQL)

  1. Connect to a database with DBA authority.

  2. Execute the following statement:

    INSTALL JAVA NEW
FROM FILE 'path\\ClassName.class'

    where path is the directory where the class file is, and ClassName.class is the name of the class file.

    The double backslash ensures that the backslash is not treated as an escape character.

    For example, to install a class in a file named Utility.class, held in the directory c:\source, you would enter the following statement:

    INSTALL JAVA NEW
FROM FILE 'c:\\source\\Utility.class'

    If you use a relative path, it must be relative to the current working directory of the database server.

    For more information, see INSTALL JAVA statement.


Installing a JAR

It is useful and common practice to collect sets of related classes together in packages, and to store one or more packages in a JAR file.

You install a JAR file the same way as you install a class file. A JAR file can have the extension JAR or ZIP. Each JAR file must have a name in the database. Usually, you use the same name as the JAR file, without the extension. For example, if you install a JAR file named myjar.zip, you would generally give it a JAR name of myjar.

For more information, see INSTALL JAVA statement.

toggle To install a JAR (Sybase Central)

  1. Connect to a database with DBA authority.

  2. Open the Java Objects folder for the database.

  3. Right click in the right pane and choose New > Jar File from the popup menu.

  4. Follow the instructions in the wizard.

toggle To install a JAR (SQL)

  1. Connect to a database with DBA authority.

  2. Enter the following statement:

    INSTALL JAVA NEW
JAR 'jarname'
FROM FILE 'path\\JarName.jar'


Updating classes and Jars

You can update classes and JAR files using Sybase Central or by entering an INSTALL JAVA statement in Interactive SQL or some other client application.

To update a class or JAR, you must have DBA authority and a newer version of the compiled class file or JAR file available in a file on disk.

When updated classes take effect

Only new connections established after installing the class, or which use the class for the first time after installing the class, use the new definition. Once the Virtual Machine loads a class definition, it stays in memory until the connection closes.

If you have been using a Java class or objects based on a class in the current connection, you need to disconnect and reconnect to use the new class definition.

To understand why the updated classes take effect in this manner, you need to know a little about how the VM works. For information, see Configuring memory for Java.

toggle To update a class or JAR (Sybase Central)

  1. Connect to a database with DBA authority.

  2. Open the Java Objects folder.

  3. Locate the class or JAR file you wish to update.

  4. Right-click the class or JAR file and choose Update from the popup menu.

  5. In the resulting dialog, specify the name and location of the class or JAR file to be updated. You can click Browse to search for it.

Tip
You can also update a Java class or JAR file by clicking Update Now on the General tab of its property sheet.
toggle To update a class or JAR (SQL)

  1. Connect to a database with DBA authority.

  2. Execute the following statement:

    INSTALL JAVA UPDATE
[ JAR 'jarname' ]
FROM FILE 'filename'

    If you are updating a JAR, you must enter the name by which the JAR is known in the database.

    For more information, see INSTALL JAVA statement.


Special features of Java classes in the database

This section describes features of Java classes when used in the database.

Supported classes
Calling the main method
Using threads in Java applications
Procedure Not Found error
Returning result sets from Java methods
Returning values from Java via stored procedures
Security management for Java
Implementing your own security manager


Supported classes

You cannot use all classes from the JDK. The runtime Java classes available for use in the database server belong to a subset of the Java API.

For more information about supported packages, see Supported Java packages.


Calling the main method

You typically start Java applications (outside the database) by running the Java VM on a class that has a main method.

For example, the JDBCExamples class in the file Samples\ASA\Java\JDBCExamples.java under your SQL Anywhere directory has a main method. When you execute the class from the command line using a command such as the following, it is the main method that executes:

java JDBCExamples

For more information about how to run the JDBCExamples class, see Establishing JDBC connections.

toggle To call the main method of a class from SQL

  1. Declare the method with an array of strings as an argument:

    public static void main( java.lang.String[] args ){
...
}

  2. Create a stored procedure that wraps this method.

    For more information, see CREATE PROCEDURE statement.

  3. Invoke the main method using the CALL statement.

    Each member of the array of strings must be of CHAR or VARCHAR data type, or a literal string.


Using threads in Java applications

With features of the java.lang.Thread package, you can use multiple threads in a Java application. Each Java thread is an engine thread, and comes from the number of threads permitted by the -gn database server option.

You can synchronize, suspend, resume, interrupt, or stop threads in Java applications.

For more information about database server threads, see -gn server option.

Serialization of JDBC calls

All calls to the server-side JDBC driver are serialized, such that only one thread is actively executing JDBC at any one time.


Procedure Not Found error

If you supply an incorrect number of arguments when calling a Java method, or if you use an incorrect data type, the server responds with a Procedure Not Found error. You should check the number and type of arguments.


Returning result sets from Java methods

This section describes how to make result sets available from Java methods. You must write a Java method that returns a result set to the calling environment, and wrap this method in a SQL stored procedure declared to be EXTERNAL NAME of LANGUAGE JAVA.

toggle To return result sets from a Java method

  1. Ensure that the Java method is declared as public and static in a public class.

  2. For each result set you expect the method to return, ensure that the method has a parameter of type java.sql.ResultSet[]. These result set parameters must all occur at the end of the parameter list.

  3. In the method, first create an instance of java.sql.ResultSet and then assign it to one of the ResultSet[] parameters.

  4. Create a SQL stored procedure of type EXTERNAL NAME LANGUAGE JAVA. This type of procedure is a wrapper around a Java method. You can use a cursor on the SQL procedure result set in the same way as any other procedure that returns result sets.

    For more information about the syntax for stored procedures that are wrappers for Java methods, see CREATE PROCEDURE statement.

Example

The following simple class has a single method which executes a query and passes the result set back to the calling environment.

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;
  }
}

You can expose the result set using a CREATE PROCEDURE statement that indicates the number of result sets returned from the procedure and the signature of the Java method.

A CREATE PROCEDURE statement indicating a result set could be defined as follows:

CREATE PROCEDURE result_set()
  DYNAMIC RESULT SETS 1
  EXTERNAL NAME
     'MyResultSet.return_rset ([Ljava/sql/ResultSet;)V'
  LANGUAGE JAVA

You can open a cursor on this procedure, just as you can with any ASA procedure returning result sets.

The string (Ljava/sql/ResultSet;)V is a Java method signature which is a compact character representation of the number and type of the parameters and return value.

For more information about Java method signatures, see CREATE PROCEDURE statement.


Returning values from Java via stored procedures

You can use stored procedures created using the EXTERNAL NAME LANGUAGE JAVA as wrappers around Java methods. This section describes how to write your Java method to exploit OUT or INOUT parameters in the stored procedure.

Java does not have explicit support for INOUT or OUT parameters. Instead, you can use an array of the parameter. For example, to use an integer OUT parameter, create an array of exactly one integer:

public class TestClass {
  public static boolean testOut( int[] param ){
    param[0] = 123;
    return true;
  }
}

The following procedure uses the testOut method:

CREATE PROCEDURE sp_testOut ( OUT p INTEGER )
EXTERNAL NAME 'TestClass/testOut ([I)Z'
LANGUAGE JAVA

The string ([I)Z is a Java method signature, indicating that the method has a single parameter, which is an array of integers, and returns a Boolean value. You must define the method so that the method parameter you wish to use as an OUT or INOUT parameter is an array of a Java data type that corresponds to the SQL data type of the OUT or INOUT parameter.

For more information about the syntax, including the method signature, see CREATE PROCEDURE statement.


Security management for Java

Java provides security managers than you can use to control user access to security-sensitive features of your applications, such as file access and network access. Adaptive Server Anywhere provides the following support for Java security managers in the database:

  • Adaptive Server Anywhere provides a default security manager.

  • You can provide your own security manager.

    For information, see Implementing your own security manager.

The default security manager

The default security manager is the class com.sybase.asa.jrt.SAGenericSecurityManager. It carries out the following tasks:

  1. It checks the value of the database option JAVA_INPUT_OUTPUT.

  2. It checks whether the database server was started in C2 security mode using the -sc database server option.

  3. If the connection property is OFF, it disallows access to Java file I/O features.

  4. If the database server is running in C2 security mode, it disallows access to java.net packages.

  5. When the security manager prevents a user from accessing a feature, it returns a java.lang.SecurityException.

For more information, see JAVA_INPUT_OUTPUT option [database], and -sc server option.

Controlling Java file I/O using the default security manager

Java file I/O is controlled through the JAVA_INPUT_OUTPUT database option. By default this option is set to OFF, disallowing file I/O.

toggle To permit file access using the default security manager

  • Set the JAVA_INPUT_OUTPUT option to ON:

    SET OPTION JAVA_INPUT_OUTPUT='ON'


Implementing your own security manager

There are several steps to implementing your own security manager.

toggle To provide your own security manager

  1. Implement a class that extends java.lang.SecurityManager.

    The SecurityManager class has a number of methods to check whether a particular action is allowed. If the action is permitted, the method returns silently. If the method returns a value a SecurityException is thrown.

    You must override methods that govern actions you wish to permit with methods that return silently. You can do this by implementing a public void method.

  2. Assign appropriate users to your security manager.

    You use the add_user_security_manager, update_user_security_manager, and delete_user_security_manager system stored procedures to assign security managers to a user. For example, to assign the MySecurityManager class as the security manager for a user, you would execute the following command:

    call dbo.add_user_security_manager(
  user_name, 'MySecurityManager', NULL )
Example

The following class allows reading from files but disallows writing:

public class MySecurityManager extends SecurityManager
{ public void checkRead(FileDescriptor) {}
  public void checkRead(String) {}
  public void checkRead(String, Object) {}
}

The SecurityManager.checkWrite methods are not overridden, and prevent write operations on files. The checkRead methods return silently, permitting the action.


Configuring memory for Java

This section describes the memory requirements for running Java in the database and how to set up your server to meet those requirements.

The Java VM requires a significant amount of cache memory.

For information on tuning the cache, see Using the cache to improve performance.

Database and connection-level requirements

The Java VM uses memory on both a per-database and on a per-connection basis.

  • The per-database requirements are not relocatable: they cannot be paged out to disk. They must fit into the server cache. This type of memory is not for the server; it is for each database. When estimating cache requirements, you must sum the requirements for each database you run on the server.

  • The per-connection requirements are relocatable, but only as a unit. The requirements for one connection are either all in cache, or all in the temporary file.

How memory is used


How memory is used

Java in the database requires memory for several purposes:

  • When Java is first used when a server is running, the VM is loaded into memory, requiring over 1.5 Mb of memory. This is part of the database-wide requirements. An additional VM is loaded for each database that uses Java.

  • For each connection that uses Java, a new instance of the VM loads for that connection. The new instance requires about 200K per connection.

  • Each class definition that is used in a Java application is loaded into memory. This is held in database-wide memory: separate copies are not required for individual connections.

  • Each connection requires a working set of Java variables and application stack space (used for method arguments and so on).

Managing memory

You can control memory use in the following ways:

  • Set the overall cache size You must use a cache size sufficient to meet all the requirements for non-relocatable memory.

    The cache size is set when the server is started using the -c option.

    In many cases, a cache size of 8 Mb is sufficient.

  • Set the namespace size The Java namespace size is the maximum size, in bytes, of the per database memory allocation.

    You can set this using the JAVA_NAMESPACE_SIZE option. The option is global, and can only be set by a user with DBA authority.

  • Set the heap size This JAVA_HEAP_SIZE option sets the maximum size, in bytes, of per-connection memory.

    This option can be set for individual connections, but as it affects the memory available for other users it can be set only by a user with DBA authority.

Starting and stopping the VM

In addition to setting memory parameters for Java, you can unload the VM when Java is not in use using the STOP JAVA statement. Only a user with DBA authority can execute this statement. The syntax is simply:

STOP JAVA

The VM loads whenever a Java operation is carried out. If you wish to explicitly load it in readiness for carrying out Java operations, you can do so by executing the following statement:

START JAVA


Java classes reference

This section provides reference material on JDK classes and packages supported within Adaptive Server Anywhere. User-defined classes and packages are must be installed into the database by a user with DBA authority before they can be used.


Supported Java packages

This section lists the packages of built-in classes available for use in a Java-enabled database. For information about any classes within the package that may be unsupported or partially supported, see Unsupported Java packages and classes, and Partially supported packages and classes.

Packages not listed here must be installed into your database before you can use them.

  • java.beans

  • java.io. The classes that govern file access are supported only on certain Windows operating systems, and only if the JAVA_INPUT_OUTPUT option is set to ON. See JAVA_INPUT_OUTPUT option [database].

  • java.lang

  • java.lang.reflect

  • java.lang.Thread

  • java.math

  • java.net

  • java.net.PlainDatagramSocketImpl

  • java.rmi

  • java.rmi.dgc

  • java.rmi.registry

  • java.rmi.server

  • java.security

  • java.security.acl

  • java.security.interfaces

  • java.SQL. For details on support for JDBC 2.0 features, see JDBC in the database features.

  • java.text

  • java.util

  • java.util.zip


Unsupported Java packages and classes

Classes in the following packages are not supported in Adaptive Server Anywhere:

  • java.applet

  • java.awt

  • java.awt.datatransfer

  • java.awt.event

  • java.awt.image

  • All packages prefixed by sun. For example, sun.audio.


Partially supported packages and classes

The following classes are partially supported . They have some unsupported native methods:

  • java.lang.ClassLoader

  • java.lang.Compiler

  • java.lang.Runtime (exec/load/loadlibrary)

  • java.io.File

  • java.io.FileDescriptor

  • java.io.FileInputStream

  • java.io.FileOutputStream

  • java.io.RandomAccessFile

  • java.util.zip.Deflater

  • java.util.zip.Inflater


JDBC Programming

About this chapter

This chapter describes how to use JDBC to access data.

JDBC can be used both from client applications and inside the database. Java classes using JDBC provide a more powerful alternative to SQL stored procedures for incorporating programming logic in the database.

JDBC overview
Using the jConnect JDBC driver
Using the iAnywhere JDBC driver
Establishing JDBC connections
Using JDBC to access data
Using JDBC escape syntax


JDBC overview

JDBC provides a SQL interface for Java applications: if you want to access relational data from Java, you do so using JDBC calls.

Rather than a thorough guide to the JDBC database interface, this chapter provides some simple examples to introduce JDBC and illustrates how you can use it on the client and in the database.

The examples illustrate the distinctive features of using JDBC in Adaptive Server Anywhere. For more information about JDBC programming, see any JDBC programming book.

JDBC and Adaptive Server Anywhere

You can use JDBC with Adaptive Server Anywhere in the following ways:

  • JDBC on the client Java client applications can make JDBC calls to Adaptive Server Anywhere. The connection takes place through a JDBC driver. SQL Anywhere Studio includes two JDBC drivers: the jConnect driver for pure Java applications and the iAnywhere JDBC driver, which is a type 2 JDBC driver.

    In this chapter, the phrase client application applies both to applications running on a user's machine and to logic running on a middle-tier application server.

  • JDBC in the database Java classes installed into a database can make JDBC calls to access and modify data in the database using an internal JDBC driver.

JDBC resources

  • Required software You need TCP/IP to use the Sybase jConnect driver.

    The Sybase jConnect driver may already be available, depending on your installation of Adaptive Server Anywhere.

    For more information about the jConnect driver and its location, see The jConnect driver files.

  • Example source code You can find source code for the examples in this chapter in the file Samples\ASA\Java\JDBCExamples.java in your SQL Anywhere directory.

    For more information about how to set up the Java examples, including the JDBCExamples class, see Setting up the Java sample.


Choosing a JDBC driver

Two JDBC drivers are provided for Adaptive Server Anywhere:

  • jConnect This driver is a 100% pure Java driver. It communicates with Adaptive Server Anywhere using the TDS client/server protocol.

    For jConnect documentation, see [external link] http://sybooks.sybase.com/jc.html.

  • iAnywhere JDBC driver This driver communicates with Adaptive Server Anywhere using the Command Sequence client/server protocol. Its behavior is consistent with ODBC, embedded SQL, and OLE DB applications.

When choosing which driver to use, you may want to consider the following factors:

  • Features Both drivers are JDK 2 compliant. The iAnywhere JDBC driver provides fully-scrollable cursors, which are not available in jConnect.

  • Pure Java The jConnect driver is a pure Java solution. The iAnywhere JDBC driver requires the Adaptive Server Anywhere ODBC driver and is not a pure Java solution.

  • Performance The iAnywhere JDBC driver provides better performance for most purposes than the jConnect driver.

  • Compatibility The TDS protocol used by the jConnect driver is shared with Adaptive Server Enterprise. Some aspects of the driver's behavior are governed by this protocol, and are configured to be compatible with Adaptive Server Enterprise.

Both drivers are available on Windows 95/98/Me and Windows NT/2000/XP, as well as supported UNIX and Linux operating systems. They are not available on NetWare or Windows CE.


JDBC program structure

The following sequence of events typically occur in JDBC applications:

  1. Create a Connection object Calling a getConnection class method of the DriverManager class creates a Connection object, and establishes a connection with a database.

  2. Generate a Statement object The Connection object generates a Statement object.

  3. Pass a SQL statement A SQL statement that executed within the database environment passes to the Statement object. If the statement is a query, this action returns a ResultSet object.

    The ResultSet object contains the data returned from the SQL statement, but exposes it one row at a time (similar to the way a cursor works).

  4. Loop over the rows of the result set The next method of the ResultSet object performs two actions:

    • The current row (the row in the result set exposed through the ResultSet object) advances one row.

    • A Boolean value (true/false) returns to indicate whether there is, in fact, a row to advance to.

  5. For each row, retrieve the values Values are retrieved for each column in the ResultSet object by identifying either the name or position of the column. You can use the getDate method to get the value from a column on the current row.

Java objects can use JDBC objects to interact with a database and get data for their own use, for example to manipulate or for use in other queries.


JDBC in the database features

The version of JDBC that you can use from Java in the database is determined by the JDK version that the database is set up to use.

  • If your database is initialized with JDK 1.2 or JDK 1.3, you can use the JDBC 2.0 API.

    For information on upgrading databases to JDK 1.2 or JDK 1.3, see ALTER DATABASE statement or Upgrading a database using the dbupgrad command-line utility.

  • If your database is initialized with JDK 1.1, you can use JDBC 1.2 features. The internal JDBC driver for JDK 1.1 (asajdbc) makes some features of JDBC 2.0 available from server-side Java applications, but does not provide full JDBC 2.0 support.

    For more information, see Using JDBC 2.0 features from JDK 1.1 databases.

Using JDBC 2.0 features from JDK 1.1 databases


Using JDBC 2.0 features from JDK 1.1 databases

This section describes how to access JDBC 2.0 features from databases initialized with JDK 1.1 support. For many purposes, a better solution is to upgrade your version of Java in the database to 1.3.

For databases initialized with JDK 1.1 support, the sybase.sql.ASA package contains features that are part of JDBC 2.0. To use these JDBC 2.0 features you must cast your JDBC objects into the corresponding classes in the sybase.sql.ASA package, rather than the java.sql package. Classes that are declared as java.sql are restricted to JDBC 1.2 functionality only.

The classes in sybase.sql.ASA are as follows:

JDBC class | Sybase internal driver class
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

The following function provides a ResultSetMetaData object for a prepared statement without requiring a ResultSet or executing the statement. This function is not part of the JDBC 1.2 standard.

ResultSetMetaData sybase.sql.ASA.SAPreparedStatement.describe()

The following code fetches the previous row in a result set, a feature not supported in JDBC 1.2:

import java.sql.*;
import sybase.sql.asa.*;
ResultSet rs;
// more code here
( ( sybase.sql.asa.SAResultSet)rs ).previous();
JDBC 2.0 restrictions

The following classes are part of the JDBC 2.0 core interface, but are not available in the sybase.sql.ASA package:

  • java.sql.Blob

  • java.sql.Clob

  • java.sql.Ref

  • java.sql.Struct

  • java.sql.Array

  • java.sql.Map

The following JDBC 2.0 core functions are not available in the sybase.sql.ASA package:

Class in sybase.sql.ASA | Missing functions
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 )
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 )


Differences between client- and server-side JDBC connections

A difference between JDBC on the client and in the database server lies in establishing a connection with the database environment.

  • Client side In client-side JDBC, establishing a connection requires the Sybase jConnect JDBC driver or the iAnywhere JDBC driver. Passing arguments to the DriverManager.getConnection establishes the connection. The database environment is an external application from the perspective of the client application.

  • Server-side When using JDBC within the database server, a connection already exists. A value of jdbc:default:connection passes to DriverManager.getConnection, which provides the JDBC application with the ability to work within the current user connection. This is a quick, efficient, and safe operation because the client application has already passed the database security to establish the connection. The user ID and password, having been provided once, do not need to be provided again. The internal JDBC driver can only connect to the database of the current connection.

You can write JDBC classes in such a way that they can run both at the client and at the server by employing a single conditional statement for constructing the URL. An external connection requires the machine name and port number, while the internal connection requires jdbc:default:connection.


Using the jConnect JDBC driver

If you wish to use JDBC from a client application or applet, you must have the jConnect JDBC driver to connect to Adaptive Server Anywhere databases.

jConnect is included with SQL Anywhere Studio. If you received Adaptive Server Anywhere as part of another package, jConnect may or may not be included. You must have jConnect in order to use JDBC from client applications. You can use JDBC in the database without jConnect.

For jConnect documentation, see [external link] http://sybooks.sybase.com/jc.html.


The jConnect driver files

The jConnect JDBC driver is installed into a set of directories under the Sybase\Shared directory. Two versions of jConnect are supplied:

  • jConnect 4.5 This version of jConnect is for use when developing JDK 1.1 applications. jConnect 4.5 is installed into the Sybase\Shared\jConnect-4_5 directory.

    jConnect 4.5 is supplied as a set of classes.

  • jConnect 5.5 This version of jConnect is for use when developing JDK 1.2 or later applications. jConnect 5.5 is installed into the Sybase\Shared\jConnect-5_5 directory.

    jConnect 5.5 is supplied as a jar file named jconn2.jar.

Examples in this chapter use jConnect 5.5. Users of jConnect 4.5 must make appropriate substitutions.

Setting the CLASSPATH for jConnect

For your application to use jConnect, the jConnect classes must be in your classpath at compile time and run time, so the Java compiler and Java runtime can locate the necessary files.

The following command adds the jConnect 5.5 driver to an existing CLASSPATH environment variable where path is your Sybase\Shared directory.

set classpath=%classpath%;path\jConnect-5_5\classes\jconn2.jar

The following command adds the jConnect 4.5 driver to an existing CLASSPATH environment variable:

set classpath=%classpath%;path\jConnect-4_5\classes
Importing the jConnect classes

The classes in jConnect are all in the com.sybase package.

If you are using jConnect 5.5, your application must access classes in com.sybase.jdbc2.jdbc. You must import these classes at the beginning of each source file:

import com.sybase.jdbc2.jdbc.*

If you are using jConnect 4.5, the classes are in com.sybase.jdbc. You must import these classes at the beginning of each source file:

import com.sybase. jdbc.*


Installing jConnect system objects into a database

If you wish to use jConnect to access system table information (database metadata), you must add the jConnect system objects to your database.

By default, the jConnect system objects are added to any new database. You can choose to add the jConnect objects to the database when creating, when upgrading, or at a later time.

You can install the jConnect system objects from Sybase Central or from Interactive SQL.

toggle To add jConnect system objects to a database (Sybase Central )

  1. Connect to the database from Sybase Central as a user with DBA authority.

  2. In the left pane, right-click the database and choose Upgrade database from the popup menu.

    The Upgrade a Database Wizard appears.

  3. Follow the instructions in the wizard to add jConnect support to the database.

toggle To add jConnect system objects to a database (Interactive SQL)

  • Connect to the database from Interactive SQL as a user with DBA authority, and enter the following command in the SQL Statements pane:

    read path\scripts\jcatalog.sql

    where path is your SQL Anywhere directory.

Tip
You can also use a command prompt to add the jConnect system objects to a database. At the command prompt, type:
dbisql -c "uid=user;pwd=pwd" path\scripts\jcatalog.sql

where user and pwd identify a user with DBA authority, and path is your SQL Anywhere directory.


Loading the jConnect driver

Before you can use jConnect in your application, load the driver by entering the following statement:

Class.forName("com.sybase.jdbc2.jdbc.SybDriver").newInstance();

Using the newInstance method works around issues in some browsers.


Supplying a URL for the server

To connect to a database via jConnect, you need to supply a Uniform Resource Locator (URL) for the database. An example given in the section Connecting from a JDBC client application using jConnect is as follows:

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 );

The URL is put together in the following way:

jdbc:sybase:Tds:machine-name:port-number

The individual components are:

  • jdbc:sybase:Tds The Sybase jConnect JDBC driver, using the TDS application protocol.

  • machine-name The IP address or name of the machine on which the server is running. If you are establishing a same-machine connection, you can use localhost, which means the current machine

  • port number The port number on which the database server listens. The port number assigned to Adaptive Server Anywhere is 2638. Use that number unless there are specific reasons not to do so.

The connection string must be less than 253 characters in length.


Specifying a database on a server

Each Adaptive Server Anywhere server may have one or more databases loaded at a time. The URL in the previous section specifies a server, but does not specify a database. The connection attempt is made to the default database on the server.

You can specify a particular database by providing an extended form of the URL in one of the following ways.

Using the ServiceName parameter
jdbc:sybase:Tds:machine-name:port-number?ServiceName=DBN

The question mark followed by a series of assignments is a standard way of providing arguments to a URL. The case of servicename is not significant, and there must be no spaces around the = sign. The DBN parameter is the database name.

Using the RemotePWD parameter

A more general method allows you to provide additional connection parameters such as the database name, or a database file, using the RemotePWD field. You set RemotePWD as a Properties field using the setRemotePassword() method.

Here is sample code that illustrates how to use the field.

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 );

Using the database file parameter DBF, you can start a database on a server using jConnect. By default, the database is started with autostop=YES. If you specify a DBF or DBN of utility_db, then the utility database will automatically be started.

For more information on the utility database, see Using the utility database.

For complete jConnect documentation, see [external link] http://sybooks.sybase.com/jc.html.


Database options set for jConnect connections

When an application connects to the database using the jConnect driver, two stored procedures are called:

  1. sp_tsql_environment sets some database options for compatibility with Adaptive Server Enterprise behavior.

  2. The sp_mda procedure is then called, and sets some other options. In particular, the sp_mda procedure determines the QUOTED_IDENTIFIER setting. To change the default behavior, you should modify the sp_mda procedure.


Using the iAnywhere JDBC driver

The iAnywhere JDBC driver provides a JDBC driver that has some performance benefits and feature benefits compared to the pure Java jConnect JDBC driver, but which is not a pure-Java solution.

For information on choosing which JDBC driver to use, see Choosing a JDBC driver.

Required files

The Java component of the iAnywhere JDBC driver is included in the jodbc.jar file installed into the Java subdirectory of your SQL Anywhere installation. For Windows, the native component is dbjodbc9.dll in the win32 subdirectory of your SQL Anywhere installation; for UNIX and Linux, the native component is dbjodbc9.so. This component must be in the system path. When deploying applications using this driver, you must also deploy the ODBC driver files.

Establishing a connection

The following code illustrates how to establish a connection using the iAnywhere JDBC driver:

String     driver, url;
Connection  conn;
driver="ianywhere.ml.jdbcodbc.IDriver";
url = "jdbc:odbc:dsn=ASA 9.0 Sample";
Class.forName( driver );
conn = DriverManager.getConnection( url );

There are several things to note about this code:

  • As the classes are loaded using Class.forName, the package containing the iAnywhere JDBC driver does not have to be imported using import statements.

  • jodbc.jar must be in your classpath when you run the application.

  • The URL contains jdbc:odbc: followed by a standard ODBC connection string. The connection string is commonly an ODBC data source, but you can also use explicit semicolon separated individual connection parameters in addition to or instead of the data source. For more information on the parameters that you can use in a connection string, see Connection parameters.

    If you do not use a data source, you should specify the ODBC driver to use by including the driver parameter in your connection string:

    url = "jdbc:odbc:";
url += "driver=Adaptive Server Anywhere 9.0;...";
Character sets

On UNIX the iAnywhere JDBC driver does not use ODBC Unicode bindings or calls and does not carry out character translations. Sending non-ASCII data through the iAnywhere JDBC driver leads to data corruption.

On Windows the iAnywhere JDBC driver does use ODBC Unicode bindings and calls to translate among character sets.


Establishing JDBC connections

This section presents classes that establish a JDBC database connection from a Java application. The examples in this section use jConnect (client side) or Java in the database (server side). For information on establishing connections using the iAnywhere JDBC driver, see Using the iAnywhere JDBC driver.


Connecting from a JDBC client application using jConnect

If you wish to access database system tables (database metadata) from a JDBC application, you must add a set of jConnect system objects to your database. The internal JDBC driver classes and jConnect share stored procedures for database metadata support. These procedures are installed to all databases by default. The dbinit -i option prevents this installation.

For more information about adding the jConnect system objects to a database, see Using the jConnect JDBC driver.

The following complete Java application is a command-line application that connects to a running database, prints a set of information to your command-line, and terminates.

Establishing a connection is the first step any JDBC application must take when working with database data.

This example illustrates an external connection, which is a regular client/server connection. For information on how to create an internal connection from Java classes running inside the database server, see Establishing a connection from a server-side JDBC class.


External connection example code

The following is the source code for the methods used to make a connection. The source code can be found in the main method and the ASAConnect method of the file JDBCExamples.java in the Samples\ASA\Java directory under your SQL Anywhere directory:

import java.sql.*;             // JDBC
import com.sybase.jdbc2.jdbc.*;      // Sybase jConnect
import java.util.Properties;   // Properties
import sybase.sql.*;           // Sybase utilities
import asademo.*;              // Example classes
public class JDBCExamples{
  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 );
    }
    catch ( Exception e ) {
      System.out.println( "Error: " + e.getMessage() );
      e.printStackTrace();
    }
  }
}


How the external connection example works

The external connection example is a Java command-line application.

Importing packages

The application requires several libraries, which are imported in the first lines of JDBCExamples.java:

  • The java.sql package contains the Sun Microsystems JDBC classes, which are required for all JDBC applications. You'll find it in the classes.zip file in your Java subdirectory.

  • Imported from com.sybase.jdbc2.jdbc, the Sybase jConnect JDBC driver is required for all applications that connect using jConnect.

  • The application uses a property list. The java.util.Properties class is required to handle property lists. You'll find it in the classes.zip file in your Java subdirectory.

  • The asademo package contains classes used in some samples. You'll find it in the Samples\ASA\Java\asademo.jar file.

The main method

Each Java application requires a class with a method named main, which is the method invoked when the program starts. In this simple example, JDBCExamples.main is the only public method in the application.

The JDBCExamples.main method carries out the following tasks:

  1. Processes the command-line argument, using the machine name if supplied. By default, the machine name is localhost, which is appropriate for the personal database server.

  2. Calls the ASAConnect method to establish a connection.

  3. Executes several methods that scroll data to your command-line.

The ASAConnect method

The JDBCExamples.ASAConnect method carries out the following tasks:

  1. Connects to the default running database using Sybase jConnect.

    • Class.forName loads jConnect. Using the newInstance method, it works around issues in some browsers.

    • The StringBuffer statements build up a connection string from the literal strings and the supplied machine name provided on the command-line.

    • DriverManager.getConnection establishes a connection using the connection string.

  2. Returns control to the calling method.


Running the external connection example

This section describes how to run the external connection example.

toggle To create and execute the external connection example application

  1. Open the command prompt.

  2. Change to your SQL Anywhere directory.

  3. Change to the Samples\ASA\Java subdirectory.

  4. Ensure the database is loaded onto a database server running TCP/IP. You can start such a server on your local machine using the following command (from the Samples\ASA\Java subdirectory):

    start dbeng9 ..\..\..\asademo

  5. Enter the following at the command prompt to run the example:

    java JDBCExamples

    If you wish to try this against a server running on another machine, you must enter the correct name of that machine. The default is localhost, which is an alias for the current machine name.

  6. Confirm that a list of people and products appears at the command prompt.

    If the attempt to connect fails, an error message appears instead. Confirm that you have executed all the steps as required. Check that your CLASSPATH is correct. An incorrect CLASSPATH results in a failure to locate a class.

For more information about using jConnect, see Using the jConnect JDBC driver, and see the online documentation for jConnect.


Establishing a connection from a server-side JDBC class

SQL statements in JDBC are built using the createStatement method of a Connection object. Even classes running inside the server need to establish a connection to create a Connection object.

Establishing a connection from a server-side JDBC class is more straightforward than establishing an external connection. Because a user already connected executes the server-side class, the class simply uses the current connection.


Server-side connection example code

The following is the source code for the example. You can find the source code in the InternalConnect method of Samples\ASA\Java\JDBCExamples.java under your SQL Anywhere directory:

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();
    }
  }
}


How the server-side connection example works

In this simple example, InternalConnect() is the only method used in the application.

The application requires only one of the libraries (JDBC) imported in the first line of the JDBCExamples.java class. The others are for external connections. The package named java.sql contains the JDBC classes.

The InternalConnect() method carries out the following tasks:

  1. Connects to the default running database using the current connection:

    • DriverManager.getConnection establishes a connection using a connection string of jdbc:default:connection.

  2. Prints Hello World to the current standard output, which is the server window. System.out.println carries out the printing.

  3. If there is an error in the attempt to connect, an error message appears in the server window, together with the place where the error occurred.

    The try and catch instructions provide the framework for the error handling.

  4. Terminates the class.


Running the server-side connection example

This section describes how to run the server-side connection example.

toggle To create and execute the internal connection example application

  1. If you have not already done so, compile the JDBCExamples.java file. If you are using the JDK, you can do the following in the Samples\ASA\Java directory from a command prompt:

    javac JDBCExamples.java

  2. Start a database server using the sample database. You can start such a server on your local machine using the following command (from the Samples\ASA\Java subdirectory):

    start dbeng9 ..\..\..\asademo

    The TCP/IP network protocol is not necessary in this case since you are not using jConnect.

  3. Install the class into the sample database. Once connected to the sample database, you can do this from Interactive SQL using the following command:

    INSTALL JAVA NEW
FROM FILE 'path\Samples\ASA\Java\JDBCExamples.class'

    where path is the path to your installation directory.

    You can also install the class using Sybase Central. While connected to the sample database, open the Java Objects folder and choose File > New > Java Class. Then follow the instructions in the wizard.

  4. You can now call the InternalConnect method of this class just as you would a stored procedure:

    CALL JDBCExamples>>InternalConnect()

    The first time a Java class is called in a session, the internal Java virtual machine must be loaded. This can take a few seconds.

  5. Confirm that the message Hello World prints on the server screen.


Notes on JDBC connections

  • Autocommit behavior The JDBC specification requires that, by default, a COMMIT is performed after each data modification statement. Currently, the server-side JDBC behavior is to commit. You can control this behavior using a statement such as the following:

    conn.setAutoCommit( false ) ;

    where conn is the current connection object.

  • Connection defaults From server-side JDBC, only the first call to getConnection( "jdbc:default:connection" ) creates a new connection with the default values. Subsequent calls return a wrapper of the current connection with all connection properties unchanged. If you set AutoCommit to OFF in your initial connection, any subsequent getConnection calls within the same Java code return a connection with AutoCommit set to OFF.

    You may wish to ensure that closing a connection resets the connection properties to their default values, so that subsequent connections are obtained with standard JDBC values. The following type of code achieves this:

    Connection conn = DriverManager.getConnection("");
boolean oldAutoCommit = conn.getAutoCommit();
try {
     // do code here
}
finally {
    conn.setAutoCommit( oldAutoCommit );
}

    This discussion applies not only to AutoCommit, but also to other connection properties such as TransactionIsolation and isReadOnly.


Using JDBC to access data

Java applications that hold some or all classes in the database have significant advantages over traditional SQL stored procedures. At an introductory level, however, it may be helpful to use the parallels with SQL stored procedures to demonstrate the capabilities of JDBC. In the following examples, we write Java classes that insert a row into the Department table.

As with other interfaces, SQL statements in JDBC can be either static or dynamic. Static SQL statements are constructed in the Java application and sent to the database. The database server parses the statement, selects an execution plan, and executes the statement. Together, parsing and selecting an execution plan are referred to as preparing the statement.

If a similar statement has to be executed many times (many inserts into one table, for example), there can be significant overhead in static SQL because the preparation step has to be executed each time.

In contrast, a dynamic SQL statement contains placeholders. The statement, prepared once using these placeholders, can be executed many times without the additional expense of preparing.

In this section, we use static SQL. Dynamic SQL is discussed in a later section.

Preparing for the examples
Inserts, updates, and deletes using JDBC
Passing arguments to Java methods
Queries using JDBC
Using prepared statements for more efficient access
Miscellaneous JDBC notes


Preparing for the examples

This section describes how to prepare for the examples in the remainder of the chapter.

Sample code

The code fragments in this section are taken from the complete class Samples\ASA\Java\JDBCExamples.java.

toggle To install the JDBCExamples class

  • If you have not already done so, install the JDBCExamples.class file into the sample database. Once connected to the sample database from Interactive SQL, enter the following command in the SQL Statements pane:

    INSTALL JAVA NEW
FROM FILE 'path\Samples\ASA\Java\JDBCExamples.class'

    where path is the path to your installation directory.

    You can also install the class using Sybase Central. While connected to the sample database, open the Java Objects folder and choose File > New > Java Class. Then follow the instructions in the wizard.


Inserts, updates, and deletes using JDBC

The Statement object executes static SQL statements. You execute SQL statements such as INSERT, UPDATE, and DELETE, which do not return result sets, using the executeUpdate method of the Statement object. Statements, such as CREATE TABLE and other data definition statements, can also be executed using executeUpdate.

The following code fragment illustrates how JDBC carries out INSERT statements. It uses an internal connection held in the Connection object named conn. The code for inserting values from an external application using JDBC would need to use a different connection, but otherwise would be unchanged.

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" );
  }
Source code available
This code fragment is part of the InsertFixed method of the JDBCExamples class included in the Samples\ASA\Java subdirectory of your installation directory.
Notes

  • The setAutoCommit method turns off the AutoCommit behavior so changes are only committed if you execute an explicit COMMIT instruction.

  • The executeUpdate method returns an integer which reflects the number of rows affected by the operation. In this case, a successful INSERT would return a value of one (1).

  • The integer return type converts to an Integer object. The Integer class is a wrapper around the basic int data type, providing some useful methods such as toString().

  • The Integer IRows converts to a string to be printed. The output goes to the server window.

toggle To run the JDBC Insert example

  1. Using Interactive SQL, connect to the sample database as user ID DBA.

  2. Ensure the JDBCExamples class has been installed. It is installed together with the other Java examples classes.

    For more information about installing the Java examples classes, see Setting up the Java sample.

  3. Call the method as follows:

    CALL JDBCExamples>>InsertFixed()

  4. Confirm that a row has been added to the department table.

    SELECT *
FROM department

    The row with ID 201 is not committed. You can execute a ROLLBACK statement to remove the row.

In this example, you have seen how to create a very simple JDBC class. Subsequent examples expand on this.


Passing arguments to Java methods

We can expand the InsertFixed method to illustrate how arguments are passed to Java methods.

The following method uses arguments passed in the call to the method as the values to insert:

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();
    }
  }
Notes

  • The two arguments are the department ID (an integer) and the department name (a string). Here, both arguments pass to the method as strings because they are part of the SQL statement string.

  • The INSERT is a static statement and takes no parameters other than the SQL itself.

  • If you supply the wrong number or type of arguments, you receive the Procedure Not Found error.

toggle To use a Java method with arguments

  1. If you have not already installed the JDBCExamples.class file into the sample database, do so.

  2. Connect to the sample database from Interactive SQL and enter the following command:

    call JDBCExamples>>InsertArguments(
    '203', 'Northern Sales' )

  3. Verify that an additional row has been added to the Department table:

    SELECT *
FROM Department

  4. Roll back the changes to leave the database unchanged:

    ROLLBACK


Queries using JDBC

The Statement object executes static queries, as well as statements that do not return result sets. For queries, you use the executeQuery method of the Statement object. This returns the result set in a ResultSet object.

The following code fragment illustrates how queries can be handled within JDBC. The code fragment places the total inventory value for a product into a variable named inventory. The product name is held in the String variable prodname. This example is available as the Query method of the JDBCExamples class.

The example assumes an internal or external connection has been obtained and is held in the Connection object named 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 ) {
      System.out.println("Error: " + e.getMessage());
      e.printStackTrace();
    }
      return max_price;
  }
Running the example

Once you have installed the JDBCExamples class into the sample database, you can execute this method using the following statement in Interactive SQL:

CALL JDBCExamples>>Query()
Notes

  • The query selects the quantity and unit price for all products named prodname. These results are returned into the ResultSet object named result.

  • There is a loop over each of the rows of the result set. The loop uses the next method.

  • For each row, the value of each column is retrieved into an integer variable using the getInt method. ResultSet also has methods for other data types, such as getString, getDate, and getBinaryString.

    The argument for the getInt method is an index number for the column, starting from 1.

  • Adaptive Server Anywhere supports bidirectional scrolling cursors. However, JDBC provides only the next method, which corresponds to scrolling forward through the result set.

  • The method returns the value of max_price to the calling environment, and Interactive SQL displays it on the Results tab in the Results pane.


Using prepared statements for more efficient access

If you use the Statement interface, you parse each statement you send to the database, generate an access plan, and execute the statement. The steps prior to actual execution are called preparing the statement.

You can achieve performance benefits if you use the PreparedStatement interface. This allows you to prepare a statement using placeholders, and then assign values to the placeholders when executing the statement.

Using prepared statements is particularly useful when carrying out many similar actions, such as inserting many rows.

For more information about prepared statements, see Preparing statements.

Example

The following example illustrates how to use the PreparedStatement interface, although inserting a single row is not a good use of prepared statements.

The following method of the JDBCExamples class carries out a prepared statement:

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();
    }
  }
Running the example

Once you have installed the JDBCExamples class into the sample database, you can execute this example by entering the following statement:

call JDBCExamples>>InsertPrepared(
                           202, 'Eastern Sales' )

The string argument is enclosed in single quotes, which is appropriate for SQL. If you invoke this method from a Java application, use double quotes to delimit the string.


Miscellaneous JDBC notes

  • Access permissions Like all Java classes in the database, classes containing JDBC statements can be accessed by any user. There is no equivalent to the GRANT EXECUTE statement that grants permission to execute procedures, and there is no need to qualify the name of a class with the name of its owner.

  • Execution permissions Java classes are executed with the permissions of the connection executing them. This behavior is different to that of stored procedures, which execute with the permissions of the owner.


Using JDBC escape syntax

You can use JDBC escape syntax from any JDBC application, including Interactive SQL. This escape syntax allows you to call stored procedures regardless of the database management system you are using. The general form for the escape syntax is

{{ keyword parameters }}

The braces must be doubled. This doubling is specific to Interactive SQL. There must not be a space between successive braces: "{{" is acceptable, but "{ {" is not. As well, you cannot use newline characters in the statement. The escape syntax cannot be used in stored procedures because they are not executed by Interactive SQL.

You can use the escape syntax to access a library of functions implemented by the JDBC driver that includes number, string, time, date, and system functions.

For example, to obtain the name of the current user in a database management system-neutral way, you would type the following:

select {{ fn user() }}

The functions that are available depend on the JDBC driver that you are using. The following tables list the functions that are supported by jConnect, and by the iAnywhere JDBC driver.

jConnect supported functions
Numeric functions | String functions | System functions | Time/Date functions
ABS | ASCII | DATABASE | CURDATE
ACOS | CHAR | IFNULL | CURTIME
ASIN | CONCAT | USER | DAYNAME
ATAN | DIFFERENCE | CONVERT | DAYOFMONTH
ATAN2 | LCASE |  | DAYOFWEEK
CEILING | LENGTH |  | HOUR
COS | REPEAT |  | MINUTE
COT | RIGHT |  | MONTH
DEGREES | SOUNDEX |  | MONTHNAME
EXP | SPACE |  | NOW
FLOOR | SUBSTRING |  | QUARTER
LOG | UCASE |  | SECOND
LOG10 |  |  | TIMESTAMPADD
PI |  |  | TIMESTAMPDIFF
POWER |  |  | YEAR
RADIANS |  |  |
RAND |  |  |
ROUND |  |  |
SIGN |  |  |
SIN |  |  |
SQRT |  |  |
TAN |  |  |
iAnywhere JDBC driver supported functions
Numeric functions | String functions | System functions | Time/Date functions
ABS | ASCII | IFNULL | CURDATE
ACOS | CHAR | USERNAME | CURTIME
ASIN | CONCAT |  | DAYNAME
ATAN | DIFFERENCE |  | DAYOFMONTH
ATAN2 | INSERT |  | DAYOFWEEK
CEILING | LCASE |  | DAYOFYEAR
COS | LEFT |  | HOUR
COT | LENGTH |  | MINUTE
DEGREES | LOCATE |  | MONTH
EXP | LOCATE_2 |  | MONTHNAME
FLOOR | LTRIM |  | NOW
LOG | REPEAT |  | QUARTER
LOG10 | RIGHT |  | SECOND
MOD | RTRIM |  | WEEK
PI | SOUNDEX |  | YEAR
POWER | SPACE |  |
RADIANS | SUBSTRING |  |
RAND | UCASE |  |
ROUND |  |  |
SIGN |  |  |
SIN |  |  |
SQRT |  |  |
TAN |  |  |
TRUNCATE |  |  |

A statement using the escape syntax should work in Adaptive Server Anywhere, Adaptive Server Enterprise, Oracle, SQL Server, or another database management system to which you are connected.

For example, to obtain database properties with the sa_db_info procedure using SQL escape syntax, you would type the following in the SQL Statements pane in Interactive SQL:

{{CALL sa_db_info( 1 ) }}


Embedded SQL Programming

About this chapter

This chapter describes how to use the embedded SQL programming interface to Adaptive Server Anywhere.

Introduction
Sample embedded SQL programs
Embedded SQL data types
Using host variables
The SQL Communication Area (SQLCA)
Fetching data
Static and dynamic SQL
The SQL descriptor area (SQLDA)
Sending and retrieving long values
Using stored procedures
Embedded SQL programming techniques
The SQL preprocessor
Library function reference
Embedded SQL command summary


Introduction

Embedded SQL is a database-programming interface for the C and C++ programming languages. It consists of SQL statements intermixed with (embedded in) C or C++ source code. These SQL statements are translated by a SQL preprocessor into C or C++ source code, which you then compile.

At runtime, embedded SQL applications use an Adaptive Server Anywhere interface library to communicate with database server. The interface library is a dynamic link library (DLL) or shared library on most platforms.

  • On Windows operating systems, the interface library is dblib9.dll.

  • On UNIX operating systems, the interface library is libdblib9.so, libdblib9.sl, or libdblib9.a, depending on the operating system.

Adaptive Server Anywhere provides two flavors of embedded SQL. Static embedded SQL is simpler to use but less flexible than dynamic embedded SQL. Both flavors are discussed in this chapter.

Development process overview
Running the SQL preprocessor
Supported compilers
Embedded SQL header files
Import libraries
A simple example
Structure of embedded SQL programs
Loading the interface library dynamically
Building NetWare Loadable Modules


Development process overview

Overview of the embedded SQL development process

Once the program has been successfully preprocessed and compiled, it is linked with the import library for the Adaptive Server Anywhere interface library to form an executable file. When the database is running, this executable file uses the Adaptive Server Anywhere DLL to interact with the database. The database does not have to be running when the program is preprocessed.

For Windows, there are separate import libraries for Watcom C/C++, for Microsoft Visual C++, and for Borland C++.

Using import libraries is the standard development method for applications that call functions in DLLs. Adaptive Server Anywhere also provides an alternative, and recommended method which avoids the use of import libraries. For more information, see Loading the interface library dynamically.


Running the SQL preprocessor

The SQL preprocessor is an executable named sqlpp.exe.

Command line

The SQLPP command line is as follows:

sqlpp [ options ] sql-filename [output-filename]

The SQL preprocessor processes a C program with embedded SQL before the C or C++ compiler is run. The preprocessor translates the SQL statements into C/C++ language source that is put into the output file. The normal extension for source programs with embedded SQL is .sqc. The default output filename is the sql-filename with an extension of .c. If the sql-filename already has a .c extension, then the output filename extension is .cc by default.

For a full listing of the command-line options, see The SQL preprocessor.


Supported compilers

The C language SQL preprocessor has been used in conjunction with the following compilers:

Operating system | Compiler | Version
Windows | Watcom C/C++ | 9.5 and above
Windows | Microsoft Visual C/C++ | 1.0 and above
Windows | Borland C++ | 4.5
Windows CE | Microsoft Visual C/C++ | 5.0
UNIX | GNU or native compiler |
NetWare | Watcom C/C++ | 10.6, 11

For instructions on building NetWare NLMs, see Building NetWare Loadable Modules.


Embedded SQL header files

All header files are installed in the h subdirectory of your SQL Anywhere installation directory.

Filename | Description
sqlca.h | Main header file included in all embedded SQL programs. This file includes the structure definition for the SQL Communication Area (SQLCA) and prototypes for all embedded SQL database interface functions.
sqlda.h | SQL Descriptor Area structure definition included in embedded SQL programs that use dynamic SQL.
sqldef.h | Definition of embedded SQL interface data types. This file also contains structure definitions and return codes needed for starting the database server from a C program.
sqlerr.h | Definitions for error codes returned in the sqlcode field of the SQLCA.
sqlstate.h | Definitions for ANSI/ISO SQL standard error states returned in the sqlstate field of the SQLCA.
pshpk1.h, pshpk2.h, poppk.h | These headers ensure that structure packing is handled correctly. They support Watcom C/C++, Microsoft Visual C++, IBM Visual Age, and Borland C/C++ compilers.


Import libraries

All import libraries are installed in the lib subdirectory, under the operating system subdirectory of the SQL Anywhere installation directory. For example, Windows import libraries are stored in the win32\lib subdirectory.

Operating system | Compiler | Import library
Windows | Watcom C/C++ | dblibtw.lib
Windows | Microsoft Visual C++ | dblibtm.lib
Windows CE | Microsoft Visual C++ | dblib9.lib
NetWare | Watcom C/C++ | dblib9.lib
Solaris (unthreaded applications) | All compilers | libdblib9.so, libdbtasks9.so
Solaris (threaded applications) | All compilers | libdblib9_r.so, libdbtasks9_r.so

The libdbtasks9 libraries are called by the libdblib9 library. Some compilers locate libdbtasks9 automatically, while for others you need to specify it explicitly.


A simple example

The following is a very simple example of an embedded SQL program.

#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:
   printf( "update unsuccessful -- sqlcode = %ld\n",
      sqlca.sqlcode );
   db_fini( &sqlca );
   return( -1 );
}

This example connects to the database, updates the last name of employee number 195, commits the change, and exits. There is virtually no interaction between the SQL and C code. The only thing the C code is used for in this example is control flow. The WHENEVER statement is used for error checking. The error action (GOTO in this example) is executed after any SQL statement that causes an error.

For a description of fetching data, see Fetching data.


Structure of embedded SQL programs

SQL statements are placed (embedded) within regular C or C++ code. All embedded SQL statements start with the words EXEC SQL and end with a semicolon (;). Normal C language comments are allowed in the middle of embedded SQL statements.

Every C program using embedded SQL must contain the following statement before any other embedded SQL statements in the source file.

EXEC SQL INCLUDE SQLCA;

The first embedded SQL statement executed by the C program must be a CONNECT statement. The CONNECT statement is used to establish a connection with the database server and to specify the user ID that is used for authorizing all statements executed during the connection.

The CONNECT statement must be the first embedded SQL statement executed. Some embedded SQL commands do not generate any C code, or do not involve communication with the database. These commands are thus allowed before the CONNECT statement. Most notable are the INCLUDE statement and the WHENEVER statement for specifying error processing.


Loading the interface library dynamically

The usual practice for developing applications that use functions from DLLs is to link the application against an import library, which contains the required function definitions.

This section describes an alternative to using an import library for developing Adaptive Server Anywhere applications. The Adaptive Server Anywhere interface library can be loaded dynamically, without having to link against the import library, using the esqldll.c module in the src subdirectory of your installation directory. Using esqldll.c is recommended because it is easier to use and more robust in its ability to locate the interface DLL.

toggle To load the interface DLL dynamically

  1. Your program must call db_init_dll to load the DLL, and must call db_fini_dll to free the DLL. The db_init_dll call must be before any function in the database interface, and no function in the interface can be called after db_fini_dll.

    You must still call the db_init and db_fini library functions.

  2. You must #include the esqldll.h header file before the EXEC SQL INCLUDE SQLCA statement or #include <sqlca.h> line in your embedded SQL program.

  3. A SQL OS macro must be defined. The header file sqlca.h, which is included by esqdll.c, attempts to determine the appropriate macro and define it. However, certain combinations of platforms and compilers may cause this to fail. In this case, you must add a #define to the top of this file, or make the definition using a compiler option.

    Macro | Platforms
    _SQL_OS_WINNT | All Windows operating systems
    _SQL_OS_UNIX | UNIX
    _SQL_OS_NETWARE | NetWare

  4. Compile esqldll.c.

  5. Instead of linking against the imports library, link the object module esqldll.obj with your embedded SQL application objects.

Sample

You can find a sample program illustrating how to load the interface library dynamically in the Samples\ASA\ESQLDynamicLoad subdirectory of your SQL Anywhere directory. The source code is in Samples\ASA\ESQLDynamicLoad\sample.sqc.


Building NetWare Loadable Modules

You must use the Watcom C/C++ compiler, version 10.6 or 11.0, to compile embedded SQL programs as NetWare Loadable Modules (NLM).

toggle To create an embedded SQL NLM

  1. On Windows, preprocess the embedded SQL file using the following command:

    sqlpp -o NETWARE srcfile.sqc

    This instruction creates a file with .c extension.

  2. Compile file.c using the Watcom compiler (10.6 or 11.0), using the /bt=netware option.

  3. Link the resulting object file using the Watcom linker with the following options:

    FORMAT NOVELL
MODULE dblib9
OPTION CASEEXACT
IMPORT @dblib9.imp
LIBRARY dblib9.lib

    The files dblib9.imp and dblib9.lib are shipped with Adaptive Server Anywhere, in the nlm\lib directory. The IMPORT and LIBRARY lines may require a full path.


Sample embedded SQL programs

Sample embedded SQL programs are included with the Adaptive Server Anywhere installation. They are placed in the Samples\ASA\C subdirectory of your SQL Anywhere directory.

  • The static cursor embedded SQL example, Samples\ASA\C\cur.sqc, demonstrates the use of static SQL statements.

  • The dynamic cursor embedded SQL example, Samples\ASA\C\dcur.sqc, demonstrates the use of dynamic SQL statements.

To reduce the amount of code that is duplicated by the sample programs, the mainlines and the data printing functions have been placed into a separate file. This is mainch.c for character mode systems and mainwin.c for windowing environments.

The sample programs each supply the following three routines, which are called from the mainlines.

  • WSQLEX_Init Connects to the database and opens the cursor.

  • WSQLEX_Process_Command Processes commands from the user, manipulating the cursor as necessary.

  • WSQLEX_Finish Closes the cursor and disconnect from the database.

The function of the mainline is to:

  1. Call the WSQLEX_Init routine

  2. Loop, getting commands from the user and calling WSQL_Process_Command until the user quits

  3. Call the WSQLEX_Finish routine

Connecting to the database is accomplished with the embedded SQL CONNECT command supplying the appropriate user ID and password.

In addition to these samples, you may find other programs and source files as part of SQL Anywhere Studio which demonstrate features available for particular platforms.


Building the sample programs

Files to build the sample programs are supplied with the sample code.

  • For Windows and NetWare operating systems, hosted on Windows operating systems, use makeall.bat to compile the sample programs.

  • For UNIX, use the shell script makeall.

  • For Windows CE, use the dcur.dsp project file for Microsoft Visual C++.

The format of the command is as follows:

makeall {Example} {Platform} {Compiler}

The first parameter is the name of the example program that you want to compile. It is one of the following:

  • CUR static cursor example

  • DCUR dynamic cursor example

  • ODBC ODBC example

The second parameter is the target platform. It is one of the following:

  • WINNT compile for Windows.

  • NETWARE compile for NetWare NLM

The third parameter is the compiler to use to compile the program. The compiler can be one of:

  • WC use Watcom C/C++

  • MC use Microsoft C

  • BC use Borland C


Running the sample programs

The executable files are held in the Samples\ASA\C directory, together with the source code.

toggle To run the static cursor sample program

  1. Start the program:

    • Start the Adaptive Server Anywhere Personal Server Sample database.

    • Run the file Samples\ASA\C\curwnt.exe.

  2. Follow the on-screen instructions.

    The various commands manipulate a database cursor and print the query results on the screen. Type the letter of the command you wish to perform. Some systems may require you to press Enter after the letter.

toggle To run the dynamic cursor sample program

  1. Start the program:

    • Run the file Samples\ASA\C\dcurwnt.exe.

  2. Connect to a database:

    • Each sample program presents a console-type user interface and prompts you for a command. Enter the following connection string to connect to the sample database:

      DSN=ASA 9.0 Sample

  3. Choose a table:

    • Each sample program prompts you for a table. Choose one of the tables in the sample database. For example, you may enter Customer or Employee.

  4. Follow the on-screen instructions.

    The various commands manipulate a database cursor and print the query results on the screen. Type the letter of the command you wish to perform. Some systems may require you to press Enter after the letter.

Windows samples

The Windows versions of the example programs are real Windows programs. However, to keep the user interface code relatively simple, some simplifications have been made. In particular, these applications do not repaint their Windows on WM_PAINT messages except to reprint the prompt.


Static cursor sample

This example demonstrates the use of cursors. The particular cursor used here retrieves certain information from the employee table in the sample database. The cursor is declared statically, meaning that the actual SQL statement to retrieve the information is "hard coded" into the source program. This is a good starting point for learning how cursors work. The next example (Dynamic cursor sample) takes this first example and converts it to use dynamic SQL statements.

For information on where the source code can be found and how to build this example program, see Sample embedded SQL programs.

The open_cursor routine both declares a cursor for the specific SQL command and also opens the cursor.

Printing a page of information is accomplished by the print routine. It loops pagesize times, fetching a single row from the cursor and printing it out. Note that the fetch routine checks for warning conditions (such as Row not found) and prints appropriate messages when they arise. In addition, the cursor is repositioned by this program to the row before the one that appears at the top of the current page of data.

The move, top, and bottom routines use the appropriate form of the FETCH statement to position the cursor. Note that this form of the FETCH statement doesn't actually get the data—it only positions the cursor. Also, a general relative positioning routine, move, has been implemented to move in either direction depending on the sign of the parameter.

When the user quits, the cursor is closed and the database connection is also released. The cursor is closed by a ROLLBACK WORK statement, and the connection is release by a DISCONNECT.


Dynamic cursor sample

This sample demonstrates the use of cursors for a dynamic SQL SELECT statement. It is a slight modification of the static cursor example. If you have not yet looked at Static cursor sample, it would be helpful to do so before looking at this sample.

For information on where the source code can be found and how to build this sample program, see Sample embedded SQL programs.

The dcur program allows the user to select a table to look at with the n command. The program then presents as much information from that table as fits on the screen.

When this program is run, it prompts for a connection string of the form:

uid=DBA;pwd=SQL;dbf=c:\asa\asademo.db

The C program with the embedded SQL is held in the Samples\ASA\C subdirectory of your SQL Anywhere directory. The program looks much like the static cursor sample with the exception of the connect, open_cursor, and print functions.

The connect function uses the embedded SQL interface function db_string_connect to connect to the database. This function provides the extra functionality to support the connection string that is used to connect to the database.

The open_cursor routine first builds the SELECT statement

SELECT * FROM tablename

where tablename is a parameter passed to the routine. It then prepares a dynamic SQL statement using this string.

The embedded SQL DESCRIBE command is used to fill in the SQLDA structure the results of the SELECT statement.

Size of the SQLDA
An initial guess is taken for the size of the SQLDA (3). If this is not big enough, the actual size of the select list returned by the database server is used to allocate a SQLDA of the correct size.

The SQLDA structure is then filled with buffers to hold strings that represent the results of the query. The fill_s_sqlda routine converts all data types in the SQLDA to DT_STRING and allocates buffers of the appropriate size.

A cursor is then declared and opened for this statement. The rest of the routines for moving and closing the cursor remain the same.

The fetch routine is slightly different: it puts the results into the SQLDA structure instead of into a list of host variables. The print routine has changed significantly to print results from the SQLDA structure up to the width of the screen. The print routine also uses the name fields of the SQLDA to print headings for each column.


Service examples

The example programs cur.sqc and dcur.sqc, when compiled for a version of Windows that supports services, run optionally as services.

The two files containing the example code for Windows services are the source file ntsvc.c and the header file ntsvc.h. The code allows a linked executable to be run either as a regular executable or as a Windows service.

toggle To run one of the compiled examples as a Windows service

  1. Start Sybase Central.

  2. In the left pane, select Adaptive Server Anywhere 9.

  3. In the right pane, select the Services tab.

  4. From the File menu, choose New > Service.

    The Service Creation wizard appears.

  5. On the first page, enter a name for the service.

  6. On the second page, select Sample program.

  7. On the third page, browse to the sample program (curwnt.exe or dcurwnt.exe) from the Samples\ASA\C subdirectory of your SQL Anywhere directory.

  8. Complete the wizard to install the service.

  9. Click Start on the main window to start the service.

When run as a service, the programs display the normal user interface if possible. They also write the output to the Application Event Log. If it is not possible to start the user interface, the programs print one page of data to the Application Event Log and stop.

These examples have been tested with the Watcom C/C++ 10.5 compiler and the Microsoft Visual C++ compiler.


Embedded SQL data types

To transfer information between a program and the database server, every piece of data must have a data type. The embedded SQL data type constants are prefixed with DT_, and can be found in the sqldef.h header file. You can create a host variable of any one of the supported types. You can also use these types in a SQLDA structure for passing data to and from the database.

You can define variables of these data types using the DECL_ macros listed in sqlca.h. For example, a variable holding a BIGINT value could be declared with DECL_BIGINT.

The following data types are supported by the embedded SQL programming interface:

  • DT_BIT 8-bit signed integer

  • DT_SMALLINT 16-bit signed integer.

  • DT_UNSSMALLINT 16-bit unsigned integer

  • DT_TINYINT 8-bit signed integer

  • DT_BIGINT 64-bit signed integer

  • DT_INT 32-bit signed integer.

  • DT_UNSINT 16-bit unsigned integer

  • DT_FLOAT 4-byte floating point number.

  • DT_DOUBLE 8-byte floating point number.

  • DT_DECIMAL Packed decimal number.

    typedef struct DECIMAL {
  char array[1];
} DECIMAL;

  • DT_STRING NULL-terminated character string. The string is blank-padded if the database is initialized with blank-padded strings.

  • DT_DATE NULL-terminated character string that is a valid date.

  • DT_TIME NULL-terminated character string that is a valid time.

  • DT_TIMESTAMP NULL-terminated character string that is a valid timestamp.

  • DT_FIXCHAR Fixed-length blank padded character string.

  • DT_VARCHAR Varying length character string with a two-byte length field. When supplying information to the database server, you must set the length field. When fetching information from the database server, the server sets the length field (not padded).

    typedef struct VARCHAR {
   unsigned short int len;
   char array[1];
} VARCHAR;

  • DT_LONGVARCHAR Long varying length character data. The macro defines a structure, as follows:

    #define DECL_LONGVARCHAR( size )         \
  struct { a_sql_uint32    array_len;    \
           a_sql_uint32    stored_len;   \
           a_sql_uint32    untrunc_len;  \
           char            array[size+1];\
         }

    The DECL_LONGVARCHAR struct may be used with more than 32K of data. Large data may be fetched all at once, or in pieces using the GET DATA statement. Large data may be supplied to the server all at once, or in pieces by appending to a database variable using the SET statement. The data is not null terminated.

    For more information, see Sending and retrieving long values.

  • DT_BINARY Varying length binary data with a two-byte length field. When supplying information to the database server, you must set the length field. When fetching information from the database server, the server sets the length field.

    typedef struct BINARY {
  unsigned short int len;
  char array[1];
} BINARY;

  • DT_LONGBINARY Long binary data. The macro defines a structure, as follows:

    #define DECL_LONGBINARY( size )          \
  struct { a_sql_uint32    array_len;    \
           a_sql_uint32    stored_len;   \
           a_sql_uint32    untrunc_len;  \
           char            array[size];  \
         }

    The DECL_LONGBINARY struct may be used with more than 32K of data. Large data may be fetched all at once, or in pieces using the GET DATA statement. Large data may be supplied to the server all at once, or in pieces by appending to a database variable using the SET statement.

    For more information, see Sending and retrieving long values.

  • DT_TIMESTAMP_STRUCT SQLDATETIME structure with fields for each part of a timestamp.

    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;

    The SQLDATETIME structure can be used to retrieve fields of DATE, TIME, and TIMESTAMP type (or anything that can be converted to one of these). Often, applications have their own formats and date manipulation code. Fetching data in this structure makes it easier for a programmer to manipulate this data. Note that DATE, TIME, and TIMESTAMP fields can also be fetched and updated with any character type.

    If you use a SQLDATETIME structure to enter a date, time, or timestamp into the database, the day_of_year and day_of_week members are ignored.

    For more information, see the DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT, and DATE_ORDER database options in Database Options.

  • DT_VARIABLE NULL-terminated character string. The character string must be the name of a SQL variable whose value is used by the database server. This data type is used only for supplying data to the database server. It cannot be used when fetching data from the database server.

The structures are defined in the sqlca.h file. The VARCHAR, BINARY, and DECIMAL types contain a one-character array and are thus not useful for declaring host variables but they are useful for allocating variables dynamically or typecasting other variables.

DATE and TIME database types

There are no corresponding embedded SQL interface data types for the various DATE and TIME database types. These database types are all fetched and updated using either the SQLDATETIME structure or character strings.

For more information see GET DATA statement [ESQL] and SET statement.


Using host variables

Host variables are C variables that are identified to the SQL preprocessor. Host variables can be used to send values to the database server or receive values from the database server.

Host variables are quite easy to use, but they have some restrictions. Dynamic SQL is a more general way of passing information to and from the database server using a structure known as the SQL Descriptor Area (SQLDA). The SQL preprocessor automatically generates a SQLDA for each statement in which host variables are used.

For information on dynamic SQL, see Static and dynamic SQL.


Declaring host variables

Host variables are defined by putting them into a declaration section. According to the IBM SAA and ANSI embedded SQL standards, host variables are defined by surrounding the normal C variable declarations with the following:

EXEC SQL BEGIN DECLARE SECTION;
/* C variable declarations */
EXEC SQL END DECLARE SECTION;

These host variables can then be used in place of value constants in any SQL statement. When the database server executes the command, the value of the host variable is used. Note that host variables cannot be used in place of table or column names: dynamic SQL is required for this. The variable name is prefixed with a colon (:) in a SQL statement to distinguish it from other identifiers allowed in the statement.

A standard SQL preprocessor does not scan C language code except inside a DECLARE SECTION. Thus, TYPEDEF types and structures are not allowed. Initializers on the variables are allowed inside a DECLARE SECTION.

Example

  • The following sample code illustrates the use of host variables on an INSERT command. The variables are filled in by the program and then inserted into the database:

    EXEC SQL BEGIN DECLARE SECTION;
long employee_number;
char employee_name[50];
char employee_initials[8];
char employee_phone[15];
EXEC SQL END DECLARE SECTION;
/* program fills in variables with appropriate values
*/
EXEC SQL INSERT INTO Employee
VALUES (:employee_number, :employee_name,
:employee_initials, :employee_phone );

    For a more extensive example, see Static cursor sample.


C host variable types

Only a limited number of C data types are supported as host variables. Also, certain host variable types do not have a corresponding C type.

Macros defined in the sqlca.h header file can be used to declare host variables of the following types: VARCHAR, FIXCHAR, BINARY, PACKED DECIMAL, LONG VARCHAR, LONG BINARY, or SQLDATETIME structure. They are used as follows:

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;

The preprocessor recognizes these macros within a declaration section and treats the variable as the appropriate type.

The following table lists the C variable types that are allowed for host variables and their corresponding embedded SQL interface data types.

C Data Type Embedded SQL Interface Type Description
short i;
short int i;
unsigned short int i;
 DT_SMALLINT 16-bit signed integer
long l;
long int l;
unsigned long int l;
 DT_INT 32-bit signed integer
float f;
 DT_FLOAT 4-byte floating point
double d;
 DT_DOUBLE 8-byte floating point
DECL_DECIMAL(p,s)
 DT_DECIMAL(p,s) Packed decimal
char a; /*n=1*/
DECL_FIXCHAR(n) a;
DECL_FIXCHAR a[n];
 DT_FIXCHAR(n) Fixed length character string blank padded.
char a[n]; /*n>=1*/
 DT_STRING(n) NULL-terminated string. The string is blank-padded if the database is initialized with blank-padded strings.
char *a;
 DT_STRING(32767) NULL-terminated string
DECL_VARCHAR(n) a;
 DT_VARCHAR(n) Varying length character string with 2-byte length field. Not blank padded
DECL_BINARY(n) a;
 DT_BINARY(n) Varying length binary data with 2-byte length field
DECL_DATETIME a;
 DT_TIMESTAMP_STRUCT SQLDATETIME structure
DECL_LONGVARCHAR( n ) a;
 DT_LONGVARCHAR Varying length long character string with three 4-byte length fields. Not blank padded or NULL terminated.
DECL_LONGBINARY( n ) a;
 DT_LONGBINARY Varying length long binary data with three 4-byte length fields. Not blank padded.
Pointers to char

A host variable declared as a pointer to char (char *a) is considered by the database interface to be 32 767 bytes long. Any host variable of type pointer to char used to retrieve information from the database must point to a buffer large enough to hold any value that could possibly come back from the database.

This is potentially quite dangerous because somebody could change the definition of the column in the database to be larger than it was when the program was written. This could cause random memory corruption problems. If you are using a 16-bit compiler, requiring 32 767 bytes could make the program stack overflow. It is better to use a declared array, even as a parameter to a function, where it is passed as a pointer to char. This lets the PREPARE statements know the size of the array.

Scope of host variables

A standard host-variable declaration section can appear anywhere that C variables can normally be declared. This includes the parameter declaration section of a C function. The C variables have their normal scope (available within the block in which they are defined). However, since the SQL preprocessor does not scan C code, it does not respect C blocks.

As far as the SQL preprocessor is concerned, host variables are global; two host variables cannot have the same name.


Host variable usage

Host variables can be used in the following circumstances:

  • SELECT, INSERT, UPDATE and DELETE statements in any place where a number or string constant is allowed.

  • The INTO clause of SELECT and FETCH statements.

  • Host variables can also be used in place of a statement name, a cursor name, or an option name in commands specific to embedded SQL.

  • For CONNECT, DISCONNECT, and SET CONNECT, a host variable can be used in place of a user ID, password, connection name, connection string, or database environment name.

  • For SET OPTION and GET OPTION, a host variable can be used in place of a user ID, option name, or option value.

  • Host variables cannot be used in place of a table name or a column name in any statement.

Examples

  • The following is valid embedded SQL:

    INCLUDE SQLCA;
long SQLCODE;
sub1() {
   char SQLSTATE[6];
   exec SQL CREATE TABLE ...
}

  • The following is not valid embedded SQL:

    INCLUDE SQLCA;
sub1() {
   char SQLSTATE[6];
   exec SQL CREATE TABLE...
}
sub2() {
   exec SQL DROP TABLE...
   // No SQLSTATE in scope of this statement
}

  • The case of SQLSTATE and SQLCODE is important and the ISO/ANSI standard requires that their definitions be exactly as follows:

    long SQLCODE;
char SQLSTATE[6];


Indicator variables

Indicator variables are C variables that hold supplementary information when you are fetching or putting data. There are several distinct uses for indicator variables:

  • NULL values To enable applications to handle NULL values.

  • String truncation To enable applications to handle cases when fetched values must be truncated to fit into host variables.

  • Conversion errors To hold error information.

An indicator variable is a host variable of type short int that is placed immediately following a regular host variable in a SQL statement. For example, in the following INSERT statement, :ind_phone is an indicator variable:

EXEC SQL INSERT INTO Employee
   VALUES (:employee_number, :employee_name,
   :employee_initials, :employee_phone:ind_phone );

Using indicator variables to handle NULL
Using indicator variables for truncated values
Using indicator values for conversion errors
Summary of indicator variable values


Using indicator variables to handle NULL

In SQL data, NULL represents either an unknown attribute or inapplicable information. The SQL concept of NULL is not to be confused with the C language constant by the same name (NULL). The C constant is used to represent a non-initialized or invalid pointer.

When NULL is used in the Adaptive Server Anywhere documentation, it refers to the SQL database meaning given above. The C language constant is referred to as the null pointer (lower case).

NULL is not the same as any value of the column's defined type. Thus, in order to pass NULL values to the database or receive NULL results back, something extra is required beyond regular host variables. Indicator variables are used for this purpose.

Using indicator variables when inserting NULL

An INSERT statement could include an indicator variable as follows:

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 );

If the indicator variable has a value of –1, a NULL is written. If it has a value of 0, the actual value of employee_phone is written.

Using indicator variables when fetching NULL

Indicator variables are also used when receiving data from the database. They are used to indicate that a NULL value was fetched (indicator is negative). If a NULL value is fetched from the database and an indicator variable is not supplied, an error is generated (SQLE_NO_INDICATOR). Errors are explained in the next section.


Using indicator variables for truncated values

Indicator variables indicate whether any fetched values were truncated to fit into a host variable. This enables applications to handle truncation appropriately.

If a value is truncated on fetching, the indicator variable is set to a positive value, containing the actual length of the database value before truncation. If the length of the value is greater than 32 767, then the indicator variable contains 32 767.


Using indicator values for conversion errors

By default, the CONVERSION_ERROR database option is set to ON, and any data type conversion failure leads to an error, with no row returned.

You can use indicator variables to tell which column produced a data type conversion failure. If you set the database option CONVERSION_ERROR to OFF, any data type conversion failure gives a CANNOT_CONVERT warning, rather than an error. If the column that suffered the conversion error has an indicator variable, that variable is set to a value of –2.

If you set the CONVERSION_ERROR option to OFF when inserting data into the database, a value of NULL is inserted when a conversion failure occurs.


Summary of indicator variable values

The following table provides a summary of indicator variable usage.

Indicator Value | Supplying Value to database | Receiving value from database
> 0 | Host variable value | Retrieved value was truncated — actual length in indicator variable
0 | Host variable value | Fetch successful, or CONVERSION_ERROR set to ON
–1 | NULL value | NULL result
–2 | NULL value | Conversion error (when CONVERSION_ERROR is set to OFF only). SQLCODE indicates a CANNOT_CONVERT warning
< –2 | NULL value | NULL result

For more information on retrieving long values, see GET DATA statement [ESQL].


The SQL Communication Area (SQLCA)

The SQL Communication Area (SQLCA) is an area of memory that is used on every database request for communicating statistics and errors from the application to the database server and back to the application. The SQLCA is used as a handle for the application-to-database communication link. It is passed in to all database library functions that need to communicate with the database server. It is implicitly passed on all embedded SQL statements.

A global SQLCA variable is defined in the interface library. The preprocessor generates an external reference for the global SQLCA variable and an external reference for a pointer to it. The external reference is named sqlca and is of type SQLCA. The pointer is named sqlcaptr. The actual global variable is declared in the imports library.

The SQLCA is defined by the sqlca.h header file, included in the h subdirectory of your installation directory.

SQLCA provides error codes

You reference the SQLCA to test for a particular error code. The sqlcode and sqlstate fields contain error codes when a database request has an error (see below). Some C macros are defined for referencing the sqlcode field, the sqlstate field, and some other fields.


SQLCA fields

The fields in the SQLCA have the following meanings:

  • sqlcaid An 8-byte character field that contains the string SQLCA as an identification of the SQLCA structure. This field helps in debugging when you are looking at memory contents.

  • sqlcabc A long integer that contains the length of the SQLCA structure (136 bytes).

  • sqlcode A long integer that specifies the error code when the database detects an error on a request. Definitions for the error codes can be found in the header file sqlerr.h. The error code is 0 (zero) for a successful operation, positive for a warning and negative for an error.

    For a full listing of error codes, see ASA Error Messages.

  • sqlerrml The length of the information in the sqlerrmc field.

  • sqlerrmc Zero or more character strings to be inserted into an error message. Some error messages contain one or more placeholder strings (%1, %2, ...) which are replaced with the strings in this field.

    For example, if a Table Not Found error is generated, sqlerrmc contains the table name, which is inserted into the error message at the appropriate place.

    For a full listing of error messages, see ASA Error Messages.

  • sqlerrp Reserved.

  • sqlerrd A utility array of long integers.

  • sqlwarn Reserved.

  • sqlstate The SQLSTATE status value. The ANSI SQL standard (SQL-92) defines a new type of return value from a SQL statement in addition to the SQLCODE value in previous standards. The SQLSTATE value is always a five-character null-terminated string, divided into a two-character class (the first two characters) and a three-character subclass. Each character can be a digit from 0 through 9 or an upper case alphabetic character A through Z.

    Any class or subclass that begins with 0 through 4 or A through H is defined by the SQL standard; other classes and subclasses are implementation defined. The SQLSTATE value '00000' means that there has been no error or warning.

    For more SQLSTATE values, see ASA Error Messages.

sqlerror array

The sqlerror field array has the following elements.

  • sqlerrd[1] (SQLIOCOUNT) The actual number of input/output operations that were required to complete a command.

    The database does not start this number at zero for each command. Your program can set this variable to zero before executing a sequence of commands. After the last command, this number is the total number of input/output operations for the entire command sequence.

  • sqlerrd[2] (SQLCOUNT) The value of this field depends on which statement is being executed.

    • INSERT, UPDATE, PUT, and DELETE statements The number of rows that were affected by the statement.

      On a cursor OPEN, this field is filled in with either the actual number of rows in the cursor (a value greater than or equal to 0) or an estimate thereof (a negative number whose absolute value is the estimate). It is the actual number of rows if the database server can compute it without counting the rows. The database can also be configured to always return the actual number of rows using the ROW_COUNT option.

    • FETCH cursor statement The SQLCOUNT field is filled if a SQLE_NOTFOUND warning is returned. It contains the number of rows by which a FETCH RELATIVE or FETCH ABSOLUTE statement goes outside the range of possible cursor positions (a cursor can be on a row, before the first row, or after the last row). In the case of a wide fetch, SQLCOUNT is the number of rows actually fetched, and is less than or equal to the number of rows requested. During a wide fetch, SQLE_NOTFOUND is not set.

      For more information on wide fetches, see Fetching more than one row at a time.

      The value is 0 if the row was not found but the position is valid, for example, executing FETCH RELATIVE 1 when positioned on the last row of a cursor. The value is positive if the attempted fetch was beyond the end of the cursor, and negative if the attempted fetch was before the beginning of the cursor.

    • GET DATA statement The SQLCOUNT field holds the actual length of the value.

    • DESCRIBE statement In the WITH VARIABLE RESULT clause used to describe procedures that may have more than one result set, SQLCOUNT is set to one of the following values:

      • 0 The result set may change: the procedure call should be described again following each OPEN statement.

      • 1 The result set is fixed. No re-describing is required.

      In the case of a syntax error, SQLE_SYNTAX_ERROR, this field contains the approximate character position within the command string where the error was detected.

  • sqlerrd[3] (SQLIOESTIMATE) The estimated number of input/output operations that are to complete the command. This field is given a value on an OPEN or EXPLAIN command.


SQLCA management for multi-threaded or reentrant code

You can use embedded SQL statements in multi-threaded or reentrant code. However, if you use a single connection, you are restricted to one active request per connection. In a multi-threaded application, you should not use the same connection to the database on each thread unless you use a semaphore to control access.

There are no restrictions on using separate connections on each thread that wishes to use the database. The SQLCA is used by the runtime library to distinguish between the different thread contexts. Thus, each thread wishing to use the database must have its own SQLCA.

Any given database connection is accessible only from one SQLCA, with the exception of the cancel instruction, which must be issued from a separate thread.

For information on canceling requests, see Implementing request management.


Using multiple SQLCAs

toggle To manage multiple SQLCAs in your application

  1. You must use the option on the SQL preprocessor that generates reentrant code (-r). The reentrant code is a little larger and a little slower because statically initialized global variables cannot be used. However, these effects are minimal.

  2. Each SQLCA used in your program must be initialized with a call to db_init and cleaned up at the end with a call to db_fini.

    Caution Failure to call db_fini for each db_init on NetWare can cause the database server to fail and the NetWare file server to fail.

  3. The embedded SQL statement SET SQLCA (SET SQLCA statement [ESQL]) is used to tell the SQL preprocessor to use a different SQLCA for database requests. Usually, a statement such as: EXEC SQL SET SQLCA 'task_data->sqlca'; is used at the top of your program or in a header file to set the SQLCA reference to point at task specific data. This statement does not generate any code and thus has no performance impact. It changes the state within the preprocessor so that any reference to the SQLCA uses the given string.

For information about creating SQLCAs, see SET SQLCA statement [ESQL].


When to use multiple SQLCAs

You can use the multiple SQLCA support in any of the supported embedded SQL environments, but it is only required in reentrant code.

The following list details the environments where multiple SQLCAs must be used:

  • Multi-threaded applications If more than one thread uses the same SQLCA, a context option can cause more than one thread to be using the SQLCA at the same time. Each thread must have its own SQLCA. This can also happen when you have a DLL that uses embedded SQL and is called by more than one thread in your application.

  • Dynamic link libraries and shared libraries A DLL has only one data segment. While the database server is processing a request from one application, it may yield to another application that makes a request to the database server. If your DLL uses the global SQLCA, both applications are using it at the same time. Each Windows application must have its own SQLCA.

  • A DLL with one data segment A DLL can be created with only one data segment or one data segment for each application. If your DLL has only one data segment, you cannot use the global SQLCA for the same reason that a DLL cannot use the global SQLCA. Each application must have its own SQLCA.


Connection management with multiple SQLCAs

You do not need to use multiple SQLCAs to connect to more than one database or have more than one connection to a single database.

Each SQLCA can have one unnamed connection. Each SQLCA has an active or current connection (see SET CONNECTION statement [Interactive SQL] [ESQL]). All operations on a given database connection must use the same SQLCA that was used when the connection was established.

Record locking
Operations on different connections are subject to the normal record locking mechanisms and may cause each other to block and possibly to deadlock. For information on locking, see the chapter Using Transactions and Isolation Levels.

Previous Next


Fetching data

Fetching data in embedded SQL is done using the SELECT statement. There are two cases:

  • The SELECT statement returns at most one row Use an INTO clause to assign the returned values directly to host variables.

    For information, see SELECT statements that return at most one row.

  • The SELECT statement may return multiple rows Use cursors to manage the rows of the result set.

    For more information, see Using cursors in embedded SQL.

LONG VARCHAR and LONG BINARY data types are handled differently to other data types. For more information, see Retrieving LONG data.


SELECT statements that return at most one row

A single row query retrieves at most one row from the database. A single-row query SELECT statement has an INTO clause following the select list and before the FROM clause. The INTO clause contains a list of host variables to receive the value for each select list item. There must be the same number of host variables as there are select list items. The host variables may be accompanied by indicator variables to indicate NULL results.

When the SELECT statement is executed, the database server retrieves the results and places them in the host variables. If the query results contain more than one row, the database server returns an error.

If the query results in no rows being selected, a Row Not Found warning is returned. Errors and warnings are returned in the SQLCA structure, as described in The SQL Communication Area (SQLCA).

Example

For example, the following code fragment returns 1 if a row from the employee table is fetched successfully, 0 if the row doesn't exist, and –1 if an error occurs.

EXEC SQL BEGIN DECLARE SECTION;
   long         emp_id;
   char         name[41];
   char         sex;
   char         birthdate[15];
   short int   ind_birthdate;
EXEC SQL END DECLARE SECTION;
. . .
int find_employee( long employee )
{
   emp_id = employee;
   EXEC SQL   SELECT emp_fname ||
            ' ' || emp_lname, sex, birth_date
            INTO :name, :sex,
                  :birthdate:ind_birthdate
            FROM "DBA".employee
            WHERE emp_id = :emp_id;
   if( SQLCODE == SQLE_NOTFOUND ) {
      return( 0 ); /* employee not found */
   } else if( SQLCODE < 0 ) {
      return( -1 ); /* error */
   } else {
      return( 1 ); /* found */
   }
}


Using cursors in embedded SQL

A cursor is used to retrieve rows from a query that has multiple rows in its result set. A cursor is a handle or an identifier for the SQL query and a position within the result set.

For an introduction to cursors, see Working with cursors.

toggle To manage a cursor in embedded SQL

  1. Declare a cursor for a particular SELECT statement, using the DECLARE statement.

  2. Open the cursor using the OPEN statement.

  3. Retrieve results one row at a time from the cursor using the FETCH statement.

  4. Fetch rows until the Row Not Found warning is returned.

    Errors and warnings are returned in the SQLCA structure, described in The SQL Communication Area (SQLCA).

  5. Close the cursor, using the CLOSE statement.

By default, cursors are automatically closed at the end of a transaction (on COMMIT or ROLLBACK). Cursors that are opened with a WITH HOLD clause are kept open for subsequent transactions until they are explicitly closed.

The following is a simple example of cursor usage:

void print_employees( void )
{
   EXEC SQL BEGIN DECLARE SECTION;
   char name[50];
   char sex;
   char birthdate[15];
   short int ind_birthdate;
   EXEC SQL END DECLARE SECTION;
   EXEC SQL DECLARE C1 CURSOR FOR
      SELECT   emp_fname || ' ' || emp_lname,
               sex, birth_date
      FROM "DBA".employee;
   EXEC SQL OPEN C1;
   for( ;; ) {
      EXEC SQL FETCH C1 INTO :name, :sex,
        :birthdate:ind_birthdate;
      if( SQLCODE == SQLE_NOTFOUND ) {
         break;
      } else if( SQLCODE < 0 ) {
         break;
      }
      if( ind_birthdate < 0 ) {
         strcpy( birthdate, "UNKNOWN" );
      }
      printf( "Name: %s Sex: %c Birthdate:
               %s.n",name, sex, birthdate );
   }
EXEC SQL CLOSE C1;
}

For complete examples using cursors, see Static cursor sample and Dynamic cursor sample.

Cursor positioning

A cursor is positioned in one of three places:

  • On a row

  • Before the first row

  • After the last row

Cursors can be positioned before the first row, after the last row, or on a row. When counting from the start, position 0 is before the first row. When counting from the end, position 0 is after the last row.

When a cursor is opened, it is positioned before the first row. The cursor position can be moved using the FETCH command (see FETCH statement [ESQL] [SP] ). It can be positioned to an absolute position either from the start or from the end of the query results. It can also be moved relative to the current cursor position.

There are special positioned versions of the UPDATE and DELETE statements that can be used to update or delete the row at the current position of the cursor. If the cursor is positioned before the first row or after the last row, a No Current Row of Cursor error is returned.

The PUT statement can be used to insert a row into a cursor.

Cursor positioning problems

Inserts and some updates to DYNAMIC SCROLL cursors can cause problems with cursor positioning. The database server does not put inserted rows at a predictable position within a cursor unless there is an ORDER BY clause on the SELECT statement. In some cases, the inserted row does not appear at all until the cursor is closed and opened again.

With Adaptive Server Anywhere, this occurs if a temporary table had to be created to open the cursor.

For a description, see Use of work tables in query processing.

The UPDATE statement may cause a row to move in the cursor. This happens if the cursor has an ORDER BY clause that uses an existing index (a temporary table is not created).


Fetching more than one row at a time

The FETCH statement can be modified to fetch more than one row at a time, which may improve performance. This is called a wide fetch or an array fetch.

Adaptive Server Anywhere also supports wide puts and inserts. For information on these, see PUT statement [ESQL] and EXECUTE statement [ESQL].

To use wide fetches in embedded SQL, include the fetch statement in your code as follows:

EXEC SQL FETCH . . . ARRAY nnn

where ARRAY nnn is the last item of the FETCH statement. The fetch count nnn can be a host variable. The number of variables in the SQLDA must be the product of nnn and the number of columns per row. The first row is placed in SQLDA variables 0 to (columns per row) – 1, and so on.

Each column must be of the same type in each row of the SQLDA, or a SQLDA_INCONSISTENT error is returned.

The server returns in SQLCOUNT the number of records that were fetched, which is always greater than zero unless there is an error or warning. On a wide fetch, a SQLCOUNT of one with no error condition indicates that one valid row has been fetched.

Example

The following example code illustrates the use of wide fetches. You can also find this code as samples\ASA\esqlwidefetch\widefetch.sqc in your SQL Anywhere directory.

#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_number   stat0,
   unsigned      width,
   unsigned      *cols_per_row )
/*********************************************/
/* Allocate a SQLDA to be used for fetching from
   the statement identified by "stat0". "width"
   rows will be retrieved on each FETCH request.
   The number of columns per row is assigned to
   "cols_per_row". */
{
    int                     num_cols;
    unsigned                row, col, offset;
    SQLDA *                 sqlda;
    EXEC SQL BEGIN DECLARE SECTION;
    a_sql_statement_number  stat;
    EXEC SQL END DECLARE SECTION;
    stat = stat0;
    sqlda = alloc_sqlda( 100 );
    if( sqlda == NULL ) return( NULL );
    EXEC SQL DESCRIBE :stat INTO sqlda;
    *cols_per_row = num_cols = sqlda->sqld;
    if( num_cols * width > sqlda->sqln ) {
        free_sqlda( sqlda );
        sqlda = alloc_sqlda( num_cols * width );
        if( sqlda == NULL ) return( NULL );
        EXEC SQL DESCRIBE :stat INTO sqlda;
    }
    // copy first row in SQLDA setup by describe
    // to following (wide) rows
    sqlda->sqld = num_cols * width;
    offset = num_cols;
    for( row = 1; row < 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++ ) {
          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 );
}
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 );
}
Notes on using wide fetches

  • In the function PrepareSQLDA, the SQLDA memory is allocated using the alloc_sqlda function. This allows space for indicator variables, rather than using the alloc_sqlda_noind function.

  • If the number of rows fetched is fewer than the number requested, but is not zero (at the end of the cursor for example), the SQLDA items corresponding to the rows that were not fetched are returned as NULL by setting the indicator value. If no indicator variables are present, an error is generated (SQLE_NO_INDICATOR: no indicator variable for NULL result).

  • If a row being fetched has been updated, generating a SQLE_ROW_UPDATED_WARNING warning, the fetch stops on the row that caused the warning. The values for all rows processed to that point (including the row that caused the warning) are returned. SQLCOUNT contains the number of rows that were fetched, including the row that caused the warning. All remaining SQLDA items are marked as NULL.

  • If a row being fetched has been deleted or is locked, generating an SQLE_NO_CURRENT_ROW or SQLE_LOCKED error, SQLCOUNT contains the number of rows that were read prior to the error. This does not include the row that caused the error. The SQLDA does not contain values for any of the rows since SQLDA values are not returned on errors. The SQLCOUNT value can be used to reposition the cursor, if necessary, to read the rows.


Static and dynamic SQL

There are two ways to embed SQL statements into a C program:

  • Static statements

  • Dynamic statements

Until now, we have been discussing static SQL. This section compares static and dynamic SQL.


Static SQL statements

All standard SQL data manipulation and data definition statements can be embedded in a C program by prefixing them with EXEC SQL and suffixing the command with a semicolon (;). These statements are referred to as static statements.

Static statements can contain references to host variables, as described in Using host variables. All examples to this point have used static embedded SQL statements.

Host variables can only be used in place of string or numeric constants. They cannot be used to substitute column names or table names; dynamic statements are required to perform those operations.


Dynamic SQL statements

In the C language, strings are stored in arrays of characters. Dynamic statements are constructed in C language strings. These statements can then be executed using the PREPARE and EXECUTE statements. These SQL statements cannot reference host variables in the same manner as static statements since the C language variables are not accessible by name when the C program is executing.

To pass information between the statements and the C language variables, a data structure called the SQL Descriptor Area (SQLDA) is used. This structure is set up for you by the SQL preprocessor if you specify a list of host variables on the EXECUTE command in the USING clause. These variables correspond by position to place holders in the appropriate positions of the prepared command string.

For information on the SQLDA, see The SQL descriptor area (SQLDA).

A place holder is put in the statement to indicate where host variables are to be accessed. A place holder is either a question mark (?) or a host variable reference as in static statements (a host variable name preceded by a colon). In the latter case, the host variable name used in the actual text of the statement serves only as a place holder indicating a reference to the SQL descriptor area.

A host variable used to pass information to the database is called a bind variable.

Example

For example:

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;

This method requires the programmer to know how many host variables there are in the statement. Usually, this is not the case. So, you can set up your own SQLDA structure and specify this SQLDA in the USING clause on the EXECUTE command.

The DESCRIBE BIND VARIABLES statement returns the host variable names of the bind variables that are found in a prepared statement. This makes it easier for a C program to manage the host variables. The general method is as follows:

EXEC SQL BEGIN DECLARE SECTION;
   char comm[200];
EXEC SQL END DECLARE SECTION;
. . .
sprintf( comm, "update %s set address = :address,
          city = :city"
         " where employee_number = :empnum",
         tablename );
EXEC SQL PREPARE S1 FROM :comm;
/* Assume that there are no more than 10 host variables. See next example if you can't put
a limit on it */
sqlda = alloc_sqlda( 10 );
EXEC SQL DESCRIBE BIND VARIABLES FOR S1 USING DESCRIPTOR sqlda;
/* sqlda->sqld will tell you how many host variables there were. */
/* Fill in SQLDA_VARIABLE fields with values based on
name fields in sqlda */
. . .
EXEC SQL EXECUTE S1 USING DESCRIPTOR sqlda;
free_sqlda( sqlda );
SQLDA contents

The SQLDA consists of an array of variable descriptors. Each descriptor describes the attributes of the corresponding C program variable or the location that the database stores data into or retrieves data from:

  • data type

  • length if type is a string type

  • precision and scale if type is a numeric type

  • memory address

  • indicator variable

For a complete description of the SQLDA structure, see The SQL descriptor area (SQLDA)

Indicator variables and NULL

The indicator variable is used to pass a NULL value to the database or retrieve a NULL value from the database. The indicator variable is also used by the database server to indicate truncation conditions encountered during a database operation. The indicator variable is set to a positive value when not enough space was provided to receive a database value.

For more information, see Indicator variables.


Dynamic SELECT statement

A SELECT statement that returns only a single row can be prepared dynamically, followed by an EXECUTE with an INTO clause to retrieve the one-row result. SELECT statements that return multiple rows, however, are managed using dynamic cursors.

With dynamic cursors, results are put into a host variable list or a SQLDA that is specified on the FETCH statement (FETCH INTO and FETCH USING DESCRIPTOR). Since the number of select list items is usually unknown to the C programmer, the SQLDA route is the most common. The DESCRIBE SELECT LIST statement sets up a SQLDA with the types of the select list items. Space is then allocated for the values using the fill_sqlda() function, and the information is retrieved by the FETCH USING DESCRIPTOR statement.

The typical scenario is as follows:

EXEC SQL BEGIN DECLARE SECTION;
   char comm[200];
EXEC SQL END DECLARE SECTION;
   int actual_size;
   SQLDA * sqlda;

. . .
sprintf( comm, "select * from %s", table_name );
EXEC SQL PREPARE S1 FROM :comm;
/* Initial guess of 10 columns in result. If it is
   wrong, it is corrected right after the first
   DESCRIBE by reallocating sqlda and doing DESCRIBE    again. */
sqlda = alloc_sqlda( 10 );
EXEC SQL DESCRIBE SELECT LIST FOR S1 USING DESCRIPTOR sqlda;
if( sqlda->sqld > sqlda->sqln ){
   actual_size = sqlda->sqld;
   free_sqlda( sqlda );
   sqlda = alloc_sqlda( actual_size );
   EXEC SQL DESCRIBE SELECT LIST FOR S1
      USING DESCRIPTOR sqlda;
}
fill_sqlda( sqlda );
EXEC SQL DECLARE C1 CURSOR FOR S1;
EXEC SQL OPEN C1;
EXEC SQL WHENEVER NOTFOUND {break};
for( ;; ){
   EXEC SQL FETCH C1 USING DESCRIPTOR sqlda;
   /* do something with data */
}
EXEC SQL CLOSE C1;
EXEC SQL DROP STATEMENT S1;
Drop statements after use
To avoid consuming unnecessary resources, ensure that statements are dropped after use.

For a complete example using cursors for a dynamic select statement, see Dynamic cursor sample.

For details of the functions mentioned above, see Library function reference.


The SQL descriptor area (SQLDA)

The SQLDA (SQL Descriptor Area) is an interface structure that is used for dynamic SQL statements. The structure passes information regarding host variables and SELECT statement results to and from the database. The SQLDA is defined in the header file sqlda.h.

There are functions in the database interface library or DLL that you can use to manage SQLDAs. For descriptions, see Library function reference.

When host variables are used with static SQL statements, the preprocessor constructs a SQLDA for those host variables. It is this SQLDA that is actually passed to and from the database server.


The SQLDA header file

The contents of sqlda.h are as follows:

#ifndef _SQLDA_H_INCLUDED
#define _SQLDA_H_INCLUDED
#define II_SQLDA

#include "sqlca.h"

#if defined( _SQL_PACK_STRUCTURES )
#include "pshpk1.h"
#endif

#define SQL_MAX_NAME_LEN  30

#define _sqldafar
typedef   short int   a_SQL_type;
struct sqlname {
    short int length; /* length of char data */
    char      data[ SQL_MAX_NAME_LEN ]; /* data */
};
struct sqlvar {    /* array of variable descriptors   */
    short int  sqltype; /* type of  host variable    */
    short int   sqllen; /* length of host variable    */
    void      *sqldata; /* address of variable  */
    short int  *sqlind; /* indicator variable pointer */
    struct sqlname  sqlname;
};
struct sqlda{
    unsigned char  sqldaid[8]; /* eye catcher "SQLDA"*/
    a_SQL_int32  sqldabc; /* length of sqlda structure*/
    short int  sqln;
             /* descriptor size in number of entries */
    short int  sqld;
             /* number of variables found by DESCRIBE*/
    struct sqlvar       sqlvar[1];
             /* array of variable descriptors */
};
#define SCALE(sqllen)           ((sqllen)/256)
#define PRECISION(sqllen)       ((sqllen)&0xff)
#define SET_PRECISION_SCALE(sqllen,precision,scale)     \
                          sqllen = (scale)*256 + (precision)
#define DECIMALSTORAGE(sqllen)  (PRECISION(sqllen)/2 + 1)

typedef struct sqlda    SQLDA;
typedef struct sqlvar   SQLVAR, SQLDA_VARIABLE;
typedef struct sqlname  SQLNAME, SQLDA_NAME;
#ifndef SQLDASIZE
#define SQLDASIZE(n)    ( sizeof( struct sqlda ) +  \
                          (n-1) * sizeof( struct sqlvar) )
#endif
#if defined( _SQL_PACK_STRUCTURES )
#include "poppk.h"
#endif
#endif


SQLDA fields

The SQLDA fields have the following meanings:

Field | Description
sqldaid | An 8-byte character field that contains the string SQLDA as an identification of the SQLDA structure. This field helps in debugging when you are looking at memory contents.
sqldabc | A long integer containing the length of the SQLDA structure.
sqln | The number of variable descriptors in the sqlvar array.
sqld | The number of variable descriptors which are valid (contain information describing a host variable). This field is set by the DESCRIBE statement and sometimes by the programmer when supplying data to the database server.
sqlvar | An array of descriptors of type struct sqlvar, each describing a host variable.


SQLDA host variable descriptions

Each sqlvar structure in the SQLDA describes a host variable. The fields of the sqlvar structure have the following meanings:

  • sqltype The type of the variable that is described by this descriptor (see Embedded SQL data types).

    The low order bit indicates whether NULL values are allowed. Valid types and constant definitions can be found in the sqldef.h header file.

    This field is filled by the DESCRIBE statement. You can set this field to any type when supplying data to the database server or retrieving data from the database server. Any necessary type conversion is done automatically.

  • sqllen The length of the variable. What the length actually means depends upon the type information and how the SQLDA is being used.

    For DECIMAL types, this field is divided into two 1-byte fields. The high byte is the precision and the low byte is the scale. The precision is the total number of digits. The scale is the number of digits that appear after the decimal point.

    For LONG VARCHAR and LONG BINARY data types, the array_len field of the DT_LONGBINARY and DT_LONGVARCHAR data type structure is used instead of the sqllen field.

    For more information on the length field, see SQLDA sqllen field values.

  • sqldata A four-byte pointer to the memory occupied by this variable. This memory must correspond to the sqltype and sqllen fields.

    For storage formats, see Embedded SQL data types.

    For UPDATE and INSERT commands, this variable is not involved in the operation if the sqldata pointer is a null pointer. For a FETCH, no data is returned if the sqldata pointer is a null pointer. In other words, the column returned by the sqldata pointer is an unbound column.

    If the DESCRIBE statement uses LONG NAMES, this field holds the long name of the result set column. If, in addition, the DESCRIBE statement is a DESCRIBE USER TYPES statement, then this field holds the long name of the user-defined data type, instead of the column. If the type is a base type, the field is empty.

  • sqlind A pointer to the indicator value. An indicator value is a short int. A negative indicator value indicates a NULL value. A positive indicator value indicates that this variable has been truncated by a FETCH statement, and the indicator value contains the length of the data before truncation. A value of –2 indicates a conversion error if the CONVERSION_ERROR database option is set to OFF.

    For more information, see Indicator variables.

    If the sqlind pointer is the null pointer, no indicator variable pertains to this host variable.

    The sqlind field is also used by the DESCRIBE statement to indicate parameter types. If the type is a user-defined data type, this field is set to DT_HAS_USERTYPE_INFO. In such a case, you may wish to carry out a DESCRIBE USER TYPES to obtain information on the user-defined data types.

  • sqlname A VARCHAR-like structure, as follows:

    struct sqlname {
   short int  length;
   char      data[ SQL_MAX_NAME_LEN ];
};

    It is filled by a DESCRIBE statement and is not otherwise used. This field has a different meaning for the two formats of the DESCRIBE statement:

    • SELECT LIST The name buffer is filled with the column heading of the corresponding item in the select list.

    • BIND VARIABLES The name buffer is filled with the name of the host variable that was used as a bind variable, or "?" if an unnamed parameter marker is used.

    On a DESCRIBE SELECT LIST command, any indicator variables present are filled with a flag indicating whether the select list item is updatable or not. More information on this flag can be found in the sqldef.h header file.

    If the DESCRIBE statement is a DESCRIBE USER TYPES statement, then this field holds the long name of the user-defined data type instead of the column. If the type is a base type, the field is empty.


SQLDA sqllen field values

The sqllen field length of the sqlvar structure in a SQLDA is used in the following kinds of interactions with the database server:

  • describing values The DESCRIBE statement gets information about the host variables required to store data retrieved from the database, or host variables required to pass data to the database.

    See Describing values.

  • retrieving values Retrieving values from the database.

    See Retrieving values.

  • sending values Sending information to the database.

    See Sending values.

  • These interactions are described in this section.

The following tables detail each of these interactions. These tables list the interface constant types (the DT_ types) found in the sqldef.h header file. These constants would be placed in the SQLDA sqltype field.

For information about sqltype field values, see Embedded SQL data types.

In static SQL, a SQLDA is still used but it is generated and completely filled in by the SQL preprocessor. In this static case, the tables give the correspondence between the static C language host variable types and the interface constants.


Describing values

The following table indicates the values of the sqllen and sqltype structure members returned by the DESCRIBE command for the various database types (both SELECT LIST and BIND VARIABLE DESCRIBE statements). In the case of a user-defined database data type, the base type is described.

Your program can use the types and lengths returned from a DESCRIBE, or you may use another type. The database server performs type conversions between any two types. The memory pointed to by the sqldata field must correspond to the sqltype and sqllen fields.

For information on embedded SQL data types, see Embedded SQL data types.

Database field type | Embedded SQL type returned | Length returned on describe
BIGINT | DT_BIGINT | 8
BINARY(n) | DT_BINARY | n
BIT | DT_BIT | 1
CHAR(n) | DT_FIXCHAR | n
DATE | DT_DATE | length of longest formatted string
DECIMAL(p,s) | DT_DECIMAL | high byte of length field in SQLDA set to p, and low byte set to s
DOUBLE | DT_DOUBLE | 8
FLOAT | DT_FLOAT | 4
INT | DT_INT | 4
LONG BINARY | DT_LONGBINARY | 32767
LONG VARCHAR | DT_LONGVARCHAR | 32767
REAL | DT_FLOAT | 4
SMALLINT | DT_SMALLINT | 2
TIME | DT_TIME | length of longest formatted string
TIMESTAMP | DT_TIMESTAMP | length of longest formatted string
TINYINT | DT_TINYINT | 1
UNSIGNED BIGINT | DT_UNSBIGINT | 8
UNSIGNED INT | DT_UNSINT | 4
UNSIGNED SMALLINT | DT_UNSSMALLINT | 2
VARCHAR(n) | DT_VARCHAR | n


Sending values

The following table indicates how you specify lengths of values when you supply data to the database server in the SQLDA.

Only the data types displayed in the table are allowed in this case. The DT_DATE, DT_TIME, and DT_TIMESTAMP types are treated the same as DT_STRING when supplying information to the database; the value must be a NULL-terminated character string in an appropriate date format.

Embedded SQL Data Type | Program action to set the length
DT_BIGINT | No action required
DT_BINARY(n) | Length taken from field in BINARY structure
DT_BIT | No action required
DT_DATE | Length determined by terminating \0
DT_DECIMAL(p,s) | high byte of length field in SQLDA set to p, and low byte set to s
DT_DOUBLE | No action required
DT_FIXCHAR(n) | Length field in SQLDA determines length of string
DT_FLOAT | No action required
DT_INT | No action required
DT_LONGBINARY | Length field ignored. See Sending LONG data
DT_LONGVARCHAR | Length field ignored. See Sending LONG data
DT_SMALLINT | No action required
DT_STRING | Length determined by terminating \0
DT_TIME | Length determined by terminating \0
DT_TIMESTAMP | Length determined by terminating \0
DT_TIMESTAMP_STRUCT | No action required
DT_UNSBIGINT | No action required
DT_UNSINT | No action required
DT_UNSSMALLINT | No action required
DT_VARCHAR(n) | Length taken from field in VARCHAR structure
DT_VARIABLE | Length determined by terminating \0


Retrieving values

The following table indicates the values of the length field when you retrieve data from the database using a SQLDA. The sqllen field is never modified when you retrieve data.

Only the interface data types displayed in the table are allowed in this case. The DT_DATE, DT_TIME, and DT_TIMESTAMP data types are treated the same as DT_STRING when you retrieve information from the database. The value is formatted as a character string in the current date format.

Embedded SQL Data Type | What the program must set length field to when receiving | How the database returns length information after fetching a value
DT_BIGINT | No action required | No action required
DT_BINARY(n) | Maximum length of BINARY structure (n+2) | len field of BINARY structure set to actual length
DT_BIT | No action required | No action required
DT_DATE | Length of buffer | \0 at end of string
DT_DECIMAL(p,s) | High byte set to p and low byte set to s | No action required
DT_DOUBLE | No action required | No action required
DT_FIXCHAR(n) | Length of buffer | Padded with blanks to length of buffer
DT_FLOAT | No action required | No action required
DT_INT | No action required | No action required
DT_LONGBINARY | Length field ignored. See Retrieving LONG data | Length field ignored. See Retrieving LONG data
DT_LONGVARCHAR | Length field ignored. See Retrieving LONG data | Length field ignored. See Retrieving LONG data
DT_SMALLINT | No action required | No action required
DT_STRING | Length of buffer | \0 at end of string
DT_TIME | Length of buffer | \0 at end of string
DT_TIMESTAMP | Length of buffer | \0 at end of string
DT_TIMESTAMP_ STRUCT | No action required | No action required
DT_UNSBIGINT | No action required | No action required
DT_UNSINT | No action required | No action required
DT_UNSSMALLINT | No action required | No action required
DT_VARCHAR(n) | Maximum length of VARCHAR structure (n+2) | len field of VARCHAR structure set to actual length


Sending and retrieving long values

The method for sending and retrieving LONG VARCHAR and LONG BINARY values in embedded SQL applications is different from that for other data types. Although the standard SQLDA fields can be used, they are limited to 32 kb data as the fields holding the information (sqldata, sqllen, sqlind) are 16-bit values. Changing these values to 32-bit values would break existing applications.

The method of describing LONG VARCHAR and LONG BINARY values is the same as for other data types.

For information about how to retrieve and send values, see Retrieving LONG data, and Sending LONG data.

Static SQL usage

Separate structures are used to hold the allocated, stored, and untruncated lengths of LONG BINARY and LONG VARCHAR data types. The static SQL data types are defined in sqlca.h as follows:

#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];  \
         }
Dynamic SQL usage

For dynamic SQL, set the sqltype field to DT_LONGVARCHAR or DT_LONGBINARY as appropriate. The associated LONGBINARY and LONGVARCHAR structures are as follows:

typedef struct LONGVARCHAR {
    a_sql_uint32    array_len;
           /* number of allocated bytes in array */
    a_sql_uint32    stored_len;
           /* number of bytes stored in array
            * (never larger than array_len)
            */
    a_sql_uint32    untrunc_len;
           /* number of bytes in untruncated expression
            * (may be larger than array_len)
            */
    char            array[1];   /* the data */
} LONGVARCHAR, LONGBINARY;

For information about how to implement this feature in your applications, see Retrieving LONG data, and Sending LONG data.


Retrieving LONG data

This section describes how to retrieve LONG values from the database. For background information, see Sending and retrieving long values.

The procedures are different depending on whether you are using static or dynamic SQL.

toggle To receive a LONG VARCHAR or LONG BINARY value (static SQL)

  1. Declare a host variable of type DECL_LONGVARCHAR or DECL_LONGBINARY, as appropriate.

  2. Retrieve the data using FETCH, GET DATA, or EXECUTE INTO. Adaptive Server Anywhere sets the following information:

    • indicator variable The indicator variable is negative if the value is NULL, 0 if there is no truncation, and is the positive untruncated length in bytes up to a maximum of 32767.

      For more information, see Indicator variables.

    • stored_len This DECL_LONGVARCHAR or DECL_LONGBINARY field holds the number of bytes retrieved into the array. It is never greater than array_len.

    • untrunc_len This DECL_LONGVARCHAR or DECL_LONGBINARY field holds the number of bytes held by the database server. It is at least equal to the stored_len value. It is set even if the value is not truncated.

toggle To receive a value into a LONGVARCHAR or LONGBINARY structure (dynamic SQL)

  1. Set the sqltype field to DT_LONGVARCHAR or DT_LONGBINARY as appropriate.

  2. Set the sqldata field to point to the LONGVARCHAR or LONGBINARY structure.

    You can use the LONGVARCHARSIZE( n ) or LONGBINARYSIZE( n ) macros to determine the total number of bytes to allocate to hold n bytes of data in the array field.

  3. Set the array_len field of the LONGVARCHAR or LONGBINARY structure to the number of bytes allocated for the array field.

  4. Retrieve the data using FETCH, GET DATA, or EXECUTE INTO. Adaptive Server Anywhere sets the following information:

    • * sqlind This sqlda field is negative if the value is NULL, 0 if there is no truncation, and is the positive untruncated length in bytes up to a maximum of 32767.

    • stored_len This LONGVARCHAR or LONGBINARY field holds the number of bytes retrieved into the array. It is never greater than array_len.

    • untrunc_len This LONGVARCHAR or LONGBINARY field holds the number of bytes held by the database server. It is at least equal to the stored_len value. It is set even if the value is not truncated.

The following code snippet illustrates the mechanics of retrieving LONG VARCHAR data using dynamic embedded SQL. It is not intended to be a practical application:

#define DATA_LEN 128000
void get_test_var()
/*****************/
{
    LONGVARCHAR *longptr;
    SQLDA *sqlda;
    SQLVAR *sqlvar;

    sqlda = alloc_sqlda( 1 );
    longptr = (LONGVARCHAR *)malloc(
                 LONGVARCHARSIZE( DATA_LEN ) );
    if( sqlda == NULL || longptr == NULL ) {
        fatal_error( "Allocation failed" );
    }

    // init longptr for receiving data
    longptr->array_len = DATA_LEN;

    // init sqlda for receiving data
    // (sqllen is unused with DT_LONG types)
    sqlda->sqld = 1;   // using 1 sqlvar
    sqlvar = &sqlda->sqlvar[0];
    sqlvar->sqltype = DT_LONGVARCHAR;
    sqlvar->sqldata = longptr;

    printf( "fetching test_var\n" );
    EXEC SQL PREPARE select_stmt FROM 'SELECT test_var';
    EXEC SQL EXECUTE select_stmt INTO DESCRIPTOR sqlda;
    EXEC SQL DROP STATEMENT select_stmt;
    printf( "stored_len: %d, untrunc_len: %d,
       1st char: %c, last char: %c\n",
        longptr->stored_len,
        longptr->untrunc_len,
        longptr->array[0],
        longptr->array[DATA_LEN-1] );
    free_sqlda( sqlda );
    free( longptr );
}


Sending LONG data

This section describes how to send LONG values to the database from embedded SQL applications. For background information, see Sending and retrieving long values.

The procedures are different depending on whether you are using static or dynamic SQL.

toggle To send a LONG VARCHAR or LONG BINARY value (static SQL)

  1. Declare a host variable of type DECL_LONGVARCHAR or DECL_LONGBINARY, as appropriate.

  2. If you are sending NULL and using an indicator variable, set the indicator variable to a negative value.

    For more information, see Indicator variables.

  3. Set the stored_len field of the DECL_LONGVARCHAR or DECL_LONGBINARY structure to the number of bytes of data in the array field.

  4. Send the data by opening the cursor or executing the statement.

The following code snippet illustrates the mechanics of sending a LONG VARCHAR using static embedded SQL. It is not intended to be a practical application.

#define DATA_LEN 12800
EXEC SQL BEGIN DECLARE SECTION;
// SQLPP initializes longdata.array_len
DECL_LONGVARCHAR(128000) longdata;
EXEC SQL END DECLARE SECTION;

void set_test_var()
/*****************/
{
    // init longdata for sending data
    memset( longdata.array, 'a', DATA_LEN );
    longdata.stored_len = DATA_LEN;

    printf( "Setting test_var to %d a's\n", DATA_LEN );
    EXEC SQL SET test_var = :longdata;
}
toggle To send a value using a LONGVARCHAR or LONGBINARY structure (dynamic SQL)

  1. Set the sqltype field to DT_LONGVARCHAR or DT_LONGBINARY as appropriate.

  2. If you are sending NULL, set * sqlind to a negative value.

  3. Set the sqldata field to point to the LONGVARCHAR or LONGBINARY structure.

    You can use the LONGVARCHARSIZE( n ) or LONGBINARYSIZE( n ) macros to determine the total number of bytes to allocate to hold n bytes of data in the array field.

  4. Set the array_len field of the LONGVARCHAR or LONGBINARY structure to the number of bytes allocated for the array field.

  5. Set the stored_len field of the LONGVARCHAR or LONGBINARY structure to the number of bytes of data in the array field. This must not be more than array_len.

  6. Send the data by opening the cursor or executing the statement.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Embedded SQL Programming

Using stored procedures

This section describes the use of SQL procedures in embedded SQL.


Using simple stored procedures

You can create and call stored procedures in embedded SQL.

You can embed a CREATE PROCEDURE just like any other data definition statement, such as CREATE TABLE. You can also embed a CALL statement to execute a stored procedure. The following code fragment illustrates both creating and executing a stored procedure in embedded SQL:

EXEC SQL CREATE PROCEDURE pettycash( IN amount
   DECIMAL(10,2) )
BEGIN
   UPDATE account
   SET balance = balance - amount
   WHERE name = 'bank';

   UPDATE account
   SET balance = balance + amount
   WHERE name = 'pettycash expense';
END;
EXEC SQL CALL pettycash( 10.72 );

If you wish to pass host variable values to a stored procedure or to retrieve the output variables, you prepare and execute a CALL statement. The following code fragment illustrates the use of host variables. Both the USING and INTO clauses are used on the EXECUTE statement.

EXEC SQL BEGIN DECLARE SECTION;
   double  hv_expense;
   double  hv_balance;
EXEC SQL END DECLARE SECTION;

// code here
EXEC SQL CREATE PROCEDURE pettycash(
         IN expense    DECIMAL(10,2),
         OUT endbalance DECIMAL(10,2) )
   BEGIN
      UPDATE account
      SET balance = balance - expense
      WHERE name = 'bank';

      UPDATE account
      SET balance = balance + expense
      WHERE name = 'pettycash expense';

      SET endbalance = ( SELECT balance FROM account
                         WHERE name = 'bank' );
   END;

EXEC SQL PREPARE S1 FROM 'CALL pettycash( ?, ? )';
EXEC SQL EXECUTE S1 USING :hv_expense INTO :hv_balance;

For more information, see EXECUTE statement [ESQL], and PREPARE statement [ESQL].


Stored procedures with result sets

Database procedures can also contain SELECT statements. The procedure is declared using a RESULT clause to specify the number, name, and types of the columns in the result set. Result set columns are different from output parameters. For procedures with result sets, the CALL statement can be used in place of a SELECT statement in the cursor declaration:

EXEC SQL BEGIN DECLARE SECTION;
   char   hv_name[100];
EXEC SQL END DECLARE SECTION;

EXEC SQL CREATE PROCEDURE female_employees()
   RESULT( name char(50) )
   BEGIN
      SELECT emp_fname || emp_lname FROM employee
      WHERE sex = 'f';
   END;

EXEC SQL PREPARE S1 FROM 'CALL female_employees()';

EXEC SQL DECLARE C1 CURSOR FOR S1;
EXEC SQL OPEN C1;
for(;;) {
   EXEC SQL FETCH C1 INTO :hv_name;
   if( SQLCODE != SQLE_NOERROR ) break;
   printf( "%s\\n", hv_name );
}
EXEC SQL CLOSE C1;

In this example, the procedure has been invoked with an OPEN statement rather than an EXECUTE statement. The OPEN statement causes the procedure to execute until it reaches a SELECT statement. At this point, C1 is a cursor for the SELECT statement within the database procedure. You can use all forms of the FETCH command (backward and forward scrolling) until you are finished with it. The CLOSE statement terminates execution of the procedure.

If there had been another statement following the SELECT in the procedure, it would not have been executed. In order to execute statements following a SELECT, use the RESUME cursor-name command. The RESUME command either returns the warning SQLE_PROCEDURE_COMPLETE or it returns SQLE_NOERROR indicating that there is another cursor. The example illustrates a two-select procedure:

EXEC SQL CREATE PROCEDURE people()
RESULT( name char(50) )
BEGIN

   SELECT emp_fname || emp_lname
   FROM employee;

   SELECT fname || lname
   FROM customer;
END;

EXEC SQL PREPARE S1 FROM 'CALL people()';

EXEC SQL DECLARE C1 CURSOR FOR S1;
EXEC SQL OPEN C1;
while( SQLCODE == SQLE_NOERROR ) {
   for(;;) {
      EXEC SQL FETCH C1 INTO :hv_name;
      if( SQLCODE != SQLE_NOERROR ) break;
      printf( "%s\\n", hv_name );
   }
   EXEC SQL RESUME C1;
}
EXEC SQL CLOSE C1;
Dynamic cursors for CALL statements

These examples have used static cursors. Full dynamic cursors can also be used for the CALL statement.

For a description of dynamic cursors, see Dynamic SELECT statement.

The DESCRIBE statement works fully for procedure calls. A DESCRIBE OUTPUT produces a SQLDA that has a description for each of the result set columns.

If the procedure does not have a result set, the SQLDA has a description for each INOUT or OUT parameter for the procedure. A DESCRIBE INPUT statement produces a SQLDA having a description for each IN or INOUT parameter for the procedure.

DESCRIBE ALL

DESCRIBE ALL describes IN, INOUT, OUT, and RESULT set parameters. DESCRIBE ALL uses the indicator variables in the SQLDA to provide additional information.

The DT_PROCEDURE_IN and DT_PROCEDURE_OUT bits are set in the indicator variable when a CALL statement is described. DT_PROCEDURE_IN indicates an IN or INOUT parameter and DT_PROCEDURE_OUT indicates an INOUT or OUT parameter. Procedure RESULT columns have both bits clear.

After a describe OUTPUT, these bits can be used to distinguish between statements that have result sets (need to use OPEN, FETCH, RESUME, CLOSE) and statements that do not (need to use EXECUTE).

For a complete description, see DESCRIBE statement [ESQL].

Multiple result sets

If you have a procedure that returns multiple result sets, you must re-describe after each RESUME statement if the result sets change shapes.

You need to describe the cursor, not the statement, to re-describe the current position of the cursor.


Embedded SQL programming techniques

This section contains a set of tips for developers of embedded SQL programs.


Implementing request management

The default behavior of the interface DLL is for applications to wait for completion of each database request before carrying out other functions. This behavior can be changed using request management functions. For example, when using Interactive SQL, the operating system is still active while Interactive SQL is waiting for a response from the database and Interactive SQL carries out some tasks in that time.

You can achieve application activity while a database request is in progress by providing a callback function. In this callback function you must not do another database request except db_cancel_request. You can use the db_is_working function in your message handlers to determine if you have a database request in progress.

The db_register_a_callback function is used to register your application callback functions.

For more information, see the following:

  • db_register_a_callback function

  • db_cancel_request function

  • db_is_working function


Backup functions

The db_backup function provides support for online backup in embedded SQL applications. The backup utility makes use of this function. You should only need to write a program to use this function if your backup requirements are not satisfied by the Adaptive Server Anywhere backup utility.

BACKUP statement is recommended
Although this function provides one way to add backup features to an application, the recommended way to accomplish this task is to use the BACKUP statement. For more information, see BACKUP statement.

You can also access the backup utility directly using the Database Tools DBBackup function. For more information on this function, see DBBackup function.

For more information, see db_backup function.


The SQL preprocessor

The SQL preprocessor processes a C or C++ program containing embedded SQL, before the compiler is run.

Syntax

sqlpp [ options ] input-file [ output-file ]

Option | Description
–c "keyword=value;..." | Supply reference database connection parameters [UltraLite]
–d | Favor data size
–e level | Flag non-conforming SQL syntax as an error
–f | Put the far keyword on generated static data
–g | Do not display UltraLite warnings
–h line–width | Limit the maximum line length of output
–k | Include user declaration of SQLCODE
–m version | Specify the version name for generated synchronization scripts
–n | Line numbers
–o operating–sys | Target operating system.
–p project | UltraLite project name
–q | Quiet mode—do not print banner
–r | Generate reentrant code
–s string–len | Maximum string length for the compiler
–w level | Flag non-conforming SQL syntax as a warning
–x | Change multibyte SQL strings to escape sequences
–z sequence | Specify collation sequence
See also

Introduction

Description

The SQL preprocessor processes a C or C++ program containing embedded SQL before the compiler is run. SQLPP translates the SQL statements in the input-file into C language source that is put into the output-file. The normal extension for source programs with embedded SQL is .sqc. The default output filename is the input-file with an extension of .c. If input-file has a .c extension, the default output filename extension is .cc.

Options

-c Required when preprocessing files that are part of an UltraLite application. The connection string must give the SQL preprocessor access to read and modify your reference database.

-d Generate code that reduces data space size. Data structures are reused and initialized at execution time before use. This increases code size.

-e This option flags any embedded SQL that is not part of a specified set of SQL/92 as an error.

The allowed values of level and their meanings are as follows:

  • e flag syntax that is not entry-level SQL/92 syntax

  • i flag syntax that is not intermediate-level SQL/92 syntax

  • f flag syntax that is not full-SQL/92 syntax

  • t flag non-standard host variable types

  • u flag syntax that is not supported by UltraLite

  • w allow all supported syntax

-g Do not display warning specific to UltraLite code generation.

-h Limits the maximum length of lines output by sqlpp to num. The continuation character is a backslash (\) and the minimum value of num is ten.

-k Notifies the preprocessor that the program to be compiled includes a user declaration of SQLCODE.

-m Specify the version name for generated synchronization scripts. The generated synchronization scripts can be used in a MobiLink consolidated database for simple synchronization.

-n Generate line number information in the C file. This consists of #line directives in the appropriate places in the generated C code. If the compiler that you are using supports the #line directive, this option makes the compiler report errors on line numbers in the SQC file (the one with the embedded SQL) as opposed to reporting errors on line numbers in the C file generated by the SQL preprocessor. Also, the #line directives are used indirectly by the source level debugger so that you can debug while viewing the SQC source file.

-o Specify the target operating system. Note that this option must match the operating system where you run the program. A reference to a special symbol is generated in your program. This symbol is defined in the interface library. If you use the wrong operating system specification or the wrong library, an error is detected by the linker. The supported operating systems are:

  • WINDOWS Windows 95/98/Me, Windows CE

  • WINNT Microsoft Windows NT/2000/XP

  • NETWARE Novell NetWare

  • UNIX UNIX

-p Identifies the UltraLite project to which the embedded SQL files belong. Applies only when processing files that are part of an UltraLite application.

-q Do not print the banner.

-r For more information on re-entrant code, see SQLCA management for multi-threaded or reentrant code.

-s Set the maximum size string that the preprocessor puts into the C file. Strings longer than this value are initialized using a list of characters ('a','b','c', etc). Most C compilers have a limit on the size of string literal they can handle. This option is used to set that upper limit. The default value is 500.

-w This option flags any embedded SQL that is not part of a specified set of SQL/92 as a warning.

The allowed values of level and their meanings are as follows:

  • e flag syntax that is not entry-level SQL/92 syntax

  • i flag syntax that is not intermediate-level SQL/92 syntax

  • f flag syntax that is not full-SQL/92 syntax

  • t flag non-standard host variable types

  • u flag syntax that is not supported by UltraLite

  • w allow all supported syntax

-x Change multibyte strings to escape sequences so that they can pass through compilers.

-z This option specifies the collation sequence. For a listing of recommended collation sequences, type dbinit –l at the command prompt.

The collation sequence is used to help the preprocessor understand the characters used in the source code of the program, for example, in identifying alphabetic characters suitable for use in identifiers. If -z is not specified, the preprocessor attempts to determine a reasonable collation to use based on the operating system and SQLLOCALE environment variable.


Library function reference

The SQL preprocessor generates calls to functions in the interface library or DLL. In addition to the calls generated by the SQL preprocessor, a set of library functions is provided to make database operations easier to perform. Prototypes for these functions are included by the EXEC SQL INCLUDE SQLCA command.

This section contains a reference description of these various functions.

DLL entry points

The DLL entry points are the same except that the prototypes have a modifier appropriate for DLLs.

You can declare the entry points in a portable manner using _esqlentry_, which is defined in sqlca.h. It resolves to the value __stdcall:

alloc_sqlda function
alloc_sqlda_noind function
db_backup function
db_cancel_request function
db_delete_file function
db_find_engine function
db_fini function
db_get_property function
db_init function
db_is_working function
db_locate_servers function
db_locate_servers_ex function
db_register_a_callback function
db_start_database function
db_start_engine function
db_stop_database function
db_stop_engine function
db_string_connect function
db_string_disconnect function
db_string_ping_server function
fill_s_sqlda function
fill_sqlda function
free_filled_sqlda function
free_sqlda function
free_sqlda_noind function
sql_needs_quotes function
sqlda_storage function
sqlda_string_length function
sqlerror_message function


alloc_sqlda function

Prototype

SQLDA *alloc_sqlda( unsigned numvar );

Description

Allocates a SQLDA with descriptors for numvar variables. The sqln field of the SQLDA is initialized to numvar. Space is allocated for the indicator variables, the indicator pointers are set to point to this space, and the indicator value is initialized to zero. A null pointer is returned if memory cannot be allocated. It is recommended that you use this function instead of alloc_sqlda_noind function.


alloc_sqlda_noind function

Prototype

SQLDA *alloc_sqlda_noind( unsigned numvar );

Description

Allocates a SQLDA with descriptors for numvar variables. The sqln field of the SQLDA is initialized to numvar. Space is not allocated for indicator variables; the indicator pointers are set to the null pointer. A null pointer is returned if memory cannot be allocated.


db_backup function

Prototype

void db_backup(
SQLCA * sqlca,
int op,
int file_num,
unsigned long page_num,
SQLDA * sqlda );

Authorization

Must be connected to a user ID with DBA authority or REMOTE DBA authority (SQL Remote).

Description
BACKUP statement is recommended
Although this function provides one way to add backup features to an application, the recommended way to accomplish this task is to use the BACKUP statement. For more information, see BACKUP statement.

The action performed depends on the value of the op parameter:

  • DB_BACKUP_START Must be called before a backup can start. Only one backup can be running at one time against any given database server. Database checkpoints are disabled until the backup is complete (db_backup is called with an op value of DB_BACKUP_END). If the backup cannot start, the SQLCODE is SQLE_BACKUP_NOT_STARTED. Otherwise, the SQLCOUNT field of the sqlca is set to the size of each database page. (Backups are processed one page at a time.)

    The file_num, page_num and sqlda parameters are ignored.

  • DB_BACKUP_OPEN_FILE Open the database file specified by file_num, which allows pages of the specified file to be backed up using DB_BACKUP_READ_PAGE. Valid file numbers are 0 through DB_BACKUP_MAX_FILE for the root database files, DB_BACKUP_TRANS_LOG_FILE for the transaction log file, and DB_BACKUP_WRITE_FILE for the database write file if it exists. If the specified file does not exist, the SQLCODE is SQLE_NOTFOUND. Otherwise, SQLCOUNT contains the number of pages in the file, SQLIOESTIMATE contains a 32-bit value (POSIX time_t) which identifies the time that the database file was created, and the operating system file name is in the sqlerrmc field of the SQLCA.

    The page_num and sqlda parameters are ignored.

  • DB_BACKUP_READ_PAGE Read one page of the database file specified by file_num. The page_num should be a value from 0 to one less than the number of pages returned in SQLCOUNT by a successful call to db_backup with the DB_BACKUP_OPEN_FILE operation. Otherwise, SQLCODE is set to SQLE_NOTFOUND. The sqlda descriptor should be set up with one variable of type DT_BINARY pointing to a buffer. The buffer should be large enough to hold binary data of the size returned in the SQLCOUNT field on the call to db_backup with the DB_BACKUP_START operation.

    DT_BINARY data contains a two-byte length followed by the actual binary data, so the buffer must be two bytes longer than the page size.

    Application must save buffer
    This call makes a copy of the specified database page into the buffer, but it is up to the application to save the buffer on some backup media.

  • DB_BACKUP_READ_RENAME_LOG This action is the same as DB_BACKUP_READ_PAGE, except that after the last page of the transaction log has been returned, the database server renames the transaction log and starts a new one.

    If the database server is unable to rename the log at the current time (for example in version 7.x or earlier databases there may be incomplete transactions), the SQLE_BACKUP_CANNOT_RENAME_LOG_YET error is set. In this case, do not use the page returned, but instead reissue the request until you receive SQLE_NOERROR and then write the page. Continue reading the pages until you receive the SQLE_NOTFOUND condition.

    The SQLE_BACKUP_CANNOT_RENAME_LOG_YET error may be returned multiple times and on multiple pages. In your retry loop, you should add a delay so as not to slow the server down with too many requests.

    When you receive the SQLE_NOTFOUND condition, the transaction log has been backed up successfully and the file has been renamed. The name for the old transaction file is returned in the sqlerrmc field of the SQLCA.

    You should check the sqlda->sqlvar[0].sqlind value after a db_backup call. If this value is greater than zero, the last log page has been written and the log file has been renamed. The new name is still in sqlca.sqlerrmc, but the SQLCODE value is SQLE_NOERROR.

    You should not call db_backup again after this, except to close files and finish the backup. If you do, you get a second copy of your backed up log file and you receive SQLE_NOTFOUND.

  • DB_BACKUP_CLOSE_FILE Must be called when processing of one file is complete to close the database file specified by file_num.

    The page_num and sqlda parameters are ignored.

  • DB_BACKUP_END Must be called at the end of the backup. No other backup can start until this backup has ended. Checkpoints are enabled again.

    The file_num, page_num and sqlda parameters are ignored.

The dbbackup program uses the following algorithm. Note that this is not C code, and does not include error checking.

db_backup( ... DB_BACKUP_START ... )
allocate page buffer based on page size in SQLCODE
sqlda = alloc_sqlda( 1 )
sqlda->sqld = 1;
sqlda->sqlvar[0].sqltype = DT_BINARY
sqlda->sqlvar[0].sqldata = allocated buffer
for file_num = 0 to DB_BACKUP_MAX_FILE
  db_backup( ... DB_BACKUP_OPEN_FILE, file_num ... )
  if SQLCODE == SQLE_NO_ERROR
    /* The file exists */
    num_pages = SQLCOUNT
    file_time = SQLE_IO_ESTIMATE
    open backup file with name from sqlca.sqlerrmc
    for page_num = 0 to num_pages - 1
      db_backup( ... DB_BACKUP_READ_PAGE,
                file_num, page_num, sqlda )
      write page buffer out to backup file
    next page_num
    close backup file
    db_backup( ... DB_BACKUP_CLOSE_FILE, file_num ... )
  end if
next file_num
backup up file DB_BACKUP_WRITE_FILE as above
backup up file DB_BACKUP_TRANS_LOG_FILE as above
free page buffer
db_backup( ... DB_BACKUP_END ... )


db_cancel_request function

Prototype

int db_cancel_request( SQLCA *sqlca );

Description

Cancels the currently active database server request. This function checks to make sure a database server request is active before sending the cancel request. If the function returns 1, then the cancel request was sent; if it returns 0, then no request was sent.

A non-zero return value does not mean that the request was canceled. There are a few critical timing cases where the cancel request and the response from the database or server "cross". In these cases, the cancel simply has no effect, even though the function still returns TRUE.

The db_cancel_request function can be called asynchronously. This function and db_is_working are the only functions in the database interface library that can be called asynchronously using an SQLCA that might be in use by another request.

If you cancel a request that is carrying out a cursor operation, the position of the cursor is indeterminate. You must locate the cursor by its absolute position or close it, following the cancel.


db_delete_file function

Prototype

void db_delete_file(
SQLCA * sqlca,
char * filename );

Authorization

Must be connected to a user ID with DBA authority or REMOTE DBA authority (SQL Remote).

Description

The db_delete_file function requests the database server to delete filename. This can be used after backing up and renaming the transaction log (see DB_BACKUP_READ_RENAME_LOG in db_backup function) to delete the old transaction log. You must be connected to a user ID with DBA authority.


db_find_engine function

Prototype

unsigned short db_find_engine(
SQLCA *sqlca,
char *name );

Description

Returns an unsigned short value, which indicates status information about the database server whose name is name. If no server can be found with the specified name, the return value is 0. A non-zero value indicates that the server is currently running.

Each bit in the return value conveys some information. Constants that represent the bits for the various pieces of information are defined in the sqldef.h header file. If a null pointer is specified for name, information is returned about the default database environment.


db_fini function

Prototype

unsigned short db_fini( SQLCA *sqlca );

Description

This function frees resources used by the database interface or DLL. You must not make any other library calls or execute any embedded SQL commands after db_fini is called. If an error occurs during processing, the error code is set in SQLCA and the function returns 0. If there are no errors, a non-zero value is returned.

You need to call db_fini once for each SQLCA being used.

Caution Failure to call db_fini for each db_init on NetWare can cause the database server to fail and the NetWare file server to fail.
See also

For information on using db_init in UltraLite applications, see db_fini function.


db_get_property function

Prototype

unsigned int db_get_property(
SQLCA * sqlca,
a_db_property property,
char * value_buffer,
int value_buffer_size );

Description

This function is used to obtain the address of the server to which you are currently connected. It is used by the dbping utility to print out the server address.

The function can also be used to obtain the value of database properties. Database properties can also be obtained in an interface-independent manner by executing a SELECT statement, as described in Database properties.

The arguments are as follows:

  • a_db_property An enum with the value DB_PROP_SERVER_ADDRESS. DB_PROP_SERVER_ADDRESS gets the current connection's server network address as a printable string. Shared memory and NamedPipes protocols always return the empty string for the address. TCP/IP and SPX protocols return non-empty string addresses.

  • value_buffer This argument is filled with the property value as a null terminated string.

  • value_buffer_size The maximum length of the string value_buffer, including the terminating null character.

See also

Database properties


db_init function

Prototype

unsigned short db_init( SQLCA *sqlca );

Description

This function initializes the database interface library. This function must be called before any other library call is made and before any embedded SQL command is executed. The resources the interface library requires for your program are allocated and initialized on this call.

Use db_fini to free the resources at the end of your program. If there are any errors during processing, they are returned in the SQLCA and 0 is returned. If there are no errors, a non-zero value is returned and you can begin using embedded SQL commands and functions.

In most cases, this function should be called only once (passing the address of the global sqlca variable defined in the sqlca.h header file). If you are writing a DLL or an application that has multiple threads using embedded SQL, call db_init once for each SQLCA that is being used.

For more information, see SQLCA management for multi-threaded or reentrant code.

Caution Failure to call db_fini for each db_init on NetWare can cause the database server to fail, and the NetWare file server to fail.
See also

For information on using db_init in UltraLite applications, see db_init function.


db_is_working function

Prototype

unsigned db_is_working( SQLCA *sqlca );

Description

Returns 1 if your application has a database request in progress that uses the given sqlca and 0 if there is no request in progress that uses the given sqlca.

This function can be called asynchronously. This function and db_cancel_request are the only functions in the database interface library that can be called asynchronously using an SQLCA that might be in use by another request.


db_locate_servers function

Prototype

unsigned int db_locate_servers(
SQLCA *sqlca,
SQL_CALLBACK_PARM callback_address,
void *callback_user_data );

Description

Provides programmatic access to the information displayed by the dblocate utility, listing all the Adaptive Server Anywhere database servers on the local network that are listening on TCP/IP.

The callback function must have the following prototype:

int (*)( SQLCA *sqlca,
a_server_address *server_addr,
void *callback_user_data );

The callback function is called for each server found. If the callback function returns 0, db_locate_servers stops iterating through servers.

The sqlca and callback_user_data passed to the callback function are those passed into db_locate_servers. The second parameter is a pointer to an a_server_address structure. a_server_address is defined in sqlca.h, with the following definition:

typedef struct a_server_address {
    a_SQL_uint32   port_type;
    a_SQL_uint32   port_num;
    char       *name;
    char       *address;
} a_server_address;

  • port_type Is always PORT_TYPE_TCP at this time (defined to be 6 in sqlca.h).

  • port_num Is the TCP port number on which this server is listening.

  • name Points to a buffer containing the server name.

  • address Points to a buffer containing the IP address of the server.

For more information, see The Server Location utility.


db_locate_servers_ex function

Prototype

unsigned int db_locate_servers_ex(
SQLCA *sqlca,
SQL_CALLBACK_PARM callback_address,,
void *callback_user_data
unsigned int bitmask);

Description

Provides programmatic access to the information displayed by the dblocate utility, listing all the Adaptive Server Anywhere database servers on the local network that are listening on TCP/IP, but provides a mask parameter used to select addresses passed to the callback routine.

The callback function must have the following prototype:

int (*)( SQLCA *sqlca,
a_server_address *server_addr,
void *callback_user_data );

The callback function is called for each server found that satisfies the bit mask. If the callback function returns 0, db_locate_servers_ex stops iterating through servers.

The sqlca and callback_user_data passed to the callback function are those passed into db_locate_servers. The second parameter is a pointer to an a_server_address structure. a_server_address is defined in sqlca.h, with the following definition:

typedef struct a_server_address {
    a_SQL_uint32   port_type;
    a_SQL_uint32   port_num;
    char       *name;
    char       *address;
} a_server_address;

  • port_type Is always PORT_TYPE_TCP at this time (defined to be 6 in sqlca.h).

  • port_num Is the TCP port number on which this server is listening.

  • name Points to a buffer containing the server name.

  • address Points to a buffer containing the IP address of the server.

Only one bit mask flag is currently supported, DB_LOOKUP_FLAG_NUMERIC. This flag is defined in sqlca.h. It ensures that the addresses passed to the callback routine are IP addresses, instead of host names.

For more information, see The Server Location utility.


db_register_a_callback function

Prototype

void db_register_a_callback(
SQLCA *sqlca,
a_db_callback_index index,
( SQL_CALLBACK_PARM ) callback );

Description

This function registers callback functions.

If you do not register a DB_CALLBACK_WAIT callback, the default action is to do nothing. Your application blocks, waiting for the database response, and Windows changes the cursor to an hourglass.

To remove a callback, pass a null pointer as the callback function.

The following values are allowed for the index parameter:

  • DB_CALLBACK_DEBUG_MESSAGE The supplied function is called once for each debug message and is passed a null-terminated string containing the text of the debug message. The string normally has a newline character (\n) immediately before the terminating null character. The prototype of the callback function is as follows:

    void SQL_CALLBACK debug_message_callback(
    SQLCA *sqlca,
    char * message_string );

  • DB_CALLBACK_START The prototype is as follows:

    void SQL_CALLBACK start_callback( SQLCA *sqlca );

    This function is called just before a database request is sent to the server. DB_CALLBACK_START is used only on Windows.

  • DB_CALLBACK_FINISH The prototype is as follows:

    void SQL_CALLBACK finish_callback( SQLCA * sqlca );

    This function is called after the response to a database request has been received by the interface DLL. DB_CALLBACK_FINISH is used only on Windows operating systems.

  • DB_CALLBACK_CONN_DROPPED The prototype is as follows:

    void SQL_CALLBACK conn_dropped_callback (
    SQLCA *sqlca,
    char *conn_name );

    This function is called when the database server is about to drop a connection because of a liveness timeout, through a DROP CONNECTION statement, or because the database server is being shut down. The connection name conn_name is passed in to allow you to distinguish between connections. If the connection was not named, it has a value of NULL.

  • DB_CALLBACK_WAIT The prototype is as follows:

    void SQL_CALLBACK wait_callback( SQLCA *sqlca );

    This function is called repeatedly by the interface library while the database server or client library is busy processing your database request.

    You would register this callback as follows:

    db_register_a_callback( &sqlca,
   DBCALLBACK_WAIT,
   (SQL_CALLBACK_PARM)&db_wait_request );

  • DB_CALLBACK_MESSAGE This is used to enable the application to handle messages received from the server during the processing of a request.

    The callback prototype is as follows:

    void SQL_CALLBACK message_callback(
    SQLCA* sqlca,
    unsigned char msg_type,
    an_SQL_code code,
    unsigned short length,
    char* msg
    );

    The msg_type parameter states how important the message is and you may wish to handle different message types in different ways. The available message types are MESSAGE_TYPE_INFO, MESSAGE_TYPE_WARNING, MESSAGE_TYPE_ACTION, and MESSAGE_TYPE_STATUS. These constants are defined in sqldef.h. The code field is an identifier. The length field tells you how long the message is. The message is not null-terminated.

    For example, the Interactive SQL callback displays STATUS and INFO message in the Messages pane, while messages of type ACTION and WARNING go to a dialog. If an application does not register this callback, there is a default callback, which causes all messages to be written to the server logfile (if debugging is on and a logfile is specified). In addition, messages of type MESSAGE_TYPE_WARNING and MESSAGE_TYPE_ACTION are more prominently displayed, in an operating system-dependent manner.


db_start_database function

Prototype

unsigned int db_start_database( SQLCA * sqlca, char * parms );

Arguments

sqlca A pointer to a SQLCA structure. For information, see The SQL Communication Area (SQLCA).

parms A NULL-terminated string containing a semi-colon-delimited list of parameter settings, each of the form KEYWORD=value. For example,

"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"

For an available list of connection parameters, see Connection parameters.

Description

If the database is not already running. The database is started on an existing server, if possible. Otherwise, a new server is started. The steps carried out to start a database are described in Locating a server.

If the database was already running or was successfully started, the return value is true (non-zero) and SQLCODE is set to 0. Error information is returned in the SQLCA.

If a user ID and password are supplied in the parameters, they are ignored.

The permission required to start and stop a database is set on the server command line. For information, see The database server.


db_start_engine function

Prototype

unsigned int db_start_engine( SQLCA * sqlca, char * parms );

Arguments

sqlca A pointer to a SQLCA structure. For information, see The SQL Communication Area (SQLCA).

parms A NULL-terminated string containing a semi-colon-delimited list of parameter settings, each of the form KEYWORD=value. For example,

"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"

For an available list of connection parameters, see Connection parameters.

Description

Starts the database server if it is not running and the DBF parameter is provided. The steps carried out by this function are those listed in Locating a server.

If the database server was already running or was successfully started, the return value is true (non-zero) and SQLCODE is set to 0. Error information is returned in the SQLCA.

The following call to db_start_engine starts the database server and names it asademo, but does not load the database, despite the DBF connection parameter:

db_start_engine( &sqlca,
    "DBF=c:\\asa9\\asademo.db; Start=dbeng9" );

If you wish to start a database as well as the server, include the database file in the START connection parameter:

db_start_engine( &sqlca,
   "ENG=eng_name;START=dbeng9 c:\\asa\\asademo.db" );

This call starts the server, names it eng_name, and starts the asademo database on that server.

The db_start_engine function attempts to connect to a server before starting one, to avoid attempting to start a server that is already running.

The FORCESTART connection parameter is used only by the db_start_engine function. When set to YES, there is no attempt to connect to a server before trying to start one. This enables the following pair of commands to work as expected:

  1. Start a database server named server_1:

    start dbeng9 -n server_1 asademo.db

  2. Force a new server to start and connect to it:

    db_start_engine( &sqlda,
  "START=dbeng9 -n server_2 asademo.db;ForceStart=YES" )

If FORCESTART was not used, and without an ENG parameter, the second command would have attempted to connect to server_1. The db_start_engine function does not pick up the server name from the -n option of the START parameter.


db_stop_database function

Prototype

unsigned int db_stop_database( SQLCA * sqlca, char * parms );

Arguments

sqlca A pointer to a SQLCA structure. For information, see The SQL Communication Area (SQLCA).

parms A NULL-terminated string containing a semi-colon-delimited list of parameter settings, each of the form KEYWORD=value. For example,

"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"

For an available list of connection parameters, see Connection parameters.

Description

Stop the database identified by DatabaseName on the server identified by EngineName. If EngineName is not specified, the default server is used.

By default, this function does not stop a database that has existing connections. If Unconditional is yes, the database is stopped regardless of existing connections.

A return value of TRUE indicates that there were no errors.

The permission required to start and stop a database is set on the server command line. For information, see The database server.


db_stop_engine function

Prototype

unsigned int db_stop_engine( SQLCA * sqlca, char * parms );

Arguments

sqlca A pointer to a SQLCA structure. For information, see The SQL Communication Area (SQLCA).

parms A NULL-terminated string containing a semi-colon-delimited list of parameter settings, each of the form KEYWORD=value. For example,

"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"

For an available list of connection parameters, see Connection parameters.

Description

Terminates execution of the database server. The steps carried out by this function are:

  • Look for a local database server that has a name that matches the EngineName parameter. If no EngineName is specified, look for the default local database server.

  • If no matching server is found, this function fails.

  • Send a request to the server to tell it to checkpoint and shut down all databases.

  • Unload the database server.

By default, this function does not stop a database server that has existing connections. If Unconditional is yes, the database server is stopped regardless of existing connections.

A C program can use this function instead of spawning DBSTOP. A return value of TRUE indicates that there were no errors.

The use of db_stop_engine is subject to the permissions set with the -gk server option.

For more information, see -gk server option.


db_string_connect function

Prototype

unsigned int db_string_connect( SQLCA * sqlca, char * parms );

Arguments

sqlca A pointer to a SQLCA structure. For information, see The SQL Communication Area (SQLCA).

parms A NULL-terminated string containing a semi-colon-delimited list of parameter settings, each of the form KEYWORD=value. For example,

"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"

For an available list of connection parameters, see Connection parameters.

Description

Provides extra functionality beyond the embedded SQL CONNECT command. This function carries out a connection using the algorithm described in Troubleshooting connections.

The return value is true (non-zero) if a connection was successfully established and false (zero) otherwise. Error information for starting the server, starting the database, or connecting is returned in the SQLCA.


db_string_disconnect function

Prototype

unsigned int db_string_disconnect(
SQLCA * sqlca,
char * parms );

Arguments

sqlca A pointer to a SQLCA structure. For information, see The SQL Communication Area (SQLCA).

parms A NULL-terminated string containing a semi-colon-delimited list of parameter settings, each of the form KEYWORD=value. For example,

"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"

For an available list of connection parameters, see Connection parameters.

Description

This function disconnects the connection identified by the ConnectionName parameter. All other parameters are ignored.

If no ConnectionName parameter is specified in the string, the unnamed connection is disconnected. This is equivalent to the embedded SQL DISCONNECT command. The Boolean return value is true if a connection was successfully ended. Error information is returned in the SQLCA.

This function shuts down the database if it was started with the AutoStop=yes parameter and there are no other connections to the database. It also stops the server if it was started with the AutoStop=yes parameter and there are no other databases running.


db_string_ping_server function

Prototype

unsigned int db_string_ping_server(
SQLCA * sqlca,
char * connect_string,
unsigned int connect_to_db );

Description

The connect_string is a normal connect string that may or may not contain server and database information.

If connect_to_db is non-zero (true), then the function attempts to connect to a database on a server. It returns a non-zero (true) value only if the connect string is sufficient to connect to the named database on the named server.

If connect_to_db is zero, then the function only attempts to locate a server. It returns a non-zero value only if the connect string is sufficient to locate a server. It makes no attempt to connect to the database.


fill_s_sqlda function

Prototype

struct sqlda * fill_s_sqlda(
struct sqlda * sqlda,
unsigned int maxlen );

Description

The same as fill_sqlda, except that it changes all the data types in sqlda to type DT_STRING. Enough space is allocated to hold the string representation of the type originally specified by the SQLDA, up to a maximum of maxlen bytes. The length fields in the SQLDA (sqllen) are modified appropriately. Returns sqlda if successful and returns the null pointer if there is not enough memory available.


fill_sqlda function

Prototype

struct sqlda * fill_sqlda( struct sqlda * sqlda );

Description

Allocates space for each variable described in each descriptor of sqlda, and assigns the address of this memory to the sqldata field of the corresponding descriptor. Enough space is allocated for the database type and length indicated in the descriptor. Returns sqlda if successful and returns the null pointer if there is not enough memory available.


free_filled_sqlda function

Prototype

void free_filled_sqlda( struct sqlda * sqlda );

Description

Free the memory allocated to each sqldata pointer and the space allocated for the SQLDA itself. Any null pointer is not freed.

Calling this function causes free_sqlda to be called automatically, and so any descriptors allocated by alloc_sqlda are freed.


free_sqlda function

Prototype

void free_sqlda( struct sqlda * sqlda );

Description

Free space allocated to this sqlda and free the indicator variable space, as allocated in fill_sqlda. Do not free the memory referenced by each sqldata pointer.


free_sqlda_noind function

Prototype

void free_sqlda_noind( struct sqlda * sqlda );

Description

Free space allocated to this sqlda. Do not free the memory referenced by each sqldata pointer. The indicator variable pointers are ignored.

Database properties

The Ping utility


sql_needs_quotes function

Prototype

unsigned int sql_needs_quotes( SQLCA *sqlca, char *str );

Description

Returns a Boolean value that indicates whether the string requires double quotes around it when it is used as a SQL identifier. This function formulates a request to the database server to determine if quotes are needed. Relevant information is stored in the sqlcode field.

There are three cases of return value/code combinations:

  • return = FALSE, sqlcode = 0 In this case, the string definitely does not need quotes.

  • return = TRUE In this case, sqlcode is always SQLE_WARNING, and the string definitely does need quotes.

  • return = FALSE If sqlcode is something other than SQLE_WARNING, the test is inconclusive.


sqlda_storage function

Prototype

unsigned long sqlda_storage( struct sqlda *sqlda, int varno );

Description

Returns the amount of storage required to store any value for the variable described in sqlda->sqlvar[varno].


sqlda_string_length function

Prototype

unsigned long sqlda_string_length( SQLDA *sqlda, int varno );

Description

Returns the length of the C string (type DT_STRING) that would be required to hold the variable sqlda->sqlvar[varno] (no matter what its type is).


sqlerror_message function

Prototype

char *sqlerror_message( SQLCA *sqlca, char * buffer, int max );

Description

Return a pointer to a string that contains an error message. The error message contains text for the error code in the SQLCA. If no error was indicated, a null pointer is returned. The error message is placed in the buffer supplied, truncated to length max if necessary.


Embedded SQL command summary

EXEC SQL
ALL embedded SQL statements must be preceded with EXEC SQL and end with a semicolon (;).

There are two groups of embedded SQL commands. Standard SQL commands are used by simply placing them in a C program enclosed with EXEC SQL and a semi-colon (;). CONNECT, DELETE, SELECT, SET, and UPDATE have additional formats only available in embedded SQL. The additional formats fall into the second category of embedded SQL specific commands.

For descriptions of the standard SQL commands, see SQL Statements.

Several SQL commands are specific to embedded SQL and can only be used in a C program.

For more information about these embedded SQL commands, see SQL Language Elements.

Standard data manipulation and data definition statements can be used from embedded SQL applications. In addition the following statements are specifically for embedded SQL programming:

  • ALLOCATE DESCRIPTOR allocate memory for a descriptor

    See ALLOCATE DESCRIPTOR statement [ESQL]

  • CLOSE close a cursor

    See CLOSE statement [ESQL] [SP]

  • CONNECT connect to the database

    See CONNECT statement [ESQL] [Interactive SQL]

  • DEALLOCATE DESCRIPTOR reclaim memory for a descriptor

    See DEALLOCATE DESCRIPTOR statement [ESQL]

  • Declaration Section declare host variables for database communication

    See Declaration section [ESQL]

  • DECLARE CURSOR declare a cursor

    See DECLARE CURSOR statement [ESQL] [SP]

  • DELETE (positioned) delete the row at the current position in a cursor

    See DELETE (positioned) statement [ESQL] [SP]

  • DESCRIBE describe the host variables for a particular SQL statement

    See DESCRIBE statement [ESQL]

  • DISCONNECT disconnect from database server

    See DISCONNECT statement [ESQL] [Interactive SQL]

  • DROP STATEMENT free resources used by a prepared statement

    See DROP STATEMENT statement [ESQL]

  • EXECUTE execute a particular SQL statement

    See EXECUTE statement [ESQL]

  • EXPLAIN explain the optimization strategy for a particular cursor

    See EXPLAIN statement [ESQL]

  • FETCH fetch a row from a cursor

    See FETCH statement [ESQL] [SP]

  • GET DATA fetch long values from a cursor

    See GET DATA statement [ESQL]

  • GET DESCRIPTOR retrieve information about a variable in a SQLDA.

    See GET DESCRIPTOR statement [ESQL]

  • GET OPTION get the setting for a particular database option

    See GET OPTION statement [ESQL]

  • INCLUDE include a file for SQL preprocessing

    See INCLUDE statement [ESQL]

  • OPEN open a cursor

    See OPEN statement [ESQL] [SP]

  • PREPARE prepare a particular SQL statement

    See PREPARE statement [ESQL]

  • PUT insert a row into a cursor

    See PUT statement [ESQL]

  • SET CONNECTION change active connection

    See SET CONNECTION statement [Interactive SQL] [ESQL]

  • SET DESCRIPTOR describe the variables in a SQLDA and place data into the SQLDA

    See SET DESCRIPTOR statement [ESQL]

  • SET SQLCA use an SQLCA other than the default global one

    See SET SQLCA statement [ESQL]

  • UPDATE (positioned) update the row at the current location of a cursor

    See UPDATE (positioned) statement [ESQL] [SP]

  • WHENEVER specify actions to occur on errors in SQL statements

    See WHENEVER statement [ESQL]


ODBC Programming

About this chapter

This chapter presents information for developing applications that call the ODBC programming interface directly.

The primary documentation for ODBC application development is the Microsoft [external link] ODBC SDK documentation, available as part of the Microsoft Data Access Components (MDAC) SDK. This chapter provides introductory material and describes features specific to Adaptive Server Anywhere, but is not an exhaustive guide to ODBC application programming.

Some application development tools that already have ODBC support provide their own programming interface that hides the ODBC interface. This chapter is not intended for users of those tools.

Introduction to ODBC
Building ODBC applications
ODBC samples
ODBC handles
Connecting to a data source
Executing SQL statements
Working with result sets
Calling stored procedures
Handling errors


Introduction to ODBC

The Open Database Connectivity (ODBC) interface is an application programming interface defined by Microsoft Corporation as a standard interface to database-management systems on Windows operating systems. ODBC is a call-based interface.

To write ODBC applications for Adaptive Server Anywhere, you need:

  • Adaptive Server Anywhere.

  • A C compiler capable of creating programs for your environment.

  • Microsoft ODBC Software Development Kit. This is available on the Microsoft Developer Network, and provides documentation and additional tools for testing ODBC applications.

Supported platforms

Adaptive Server Anywhere supports the ODBC API on UNIX and Windows CE, in addition to Windows. Having multi-platform ODBC support makes portable database application development much easier.

For information on enlisting the ODBC driver in distributed transactions, see Three-Tier Computing and Distributed Transactions.

ODBC conformance


ODBC conformance

Adaptive Server Anywhere provides support for ODBC 3.5, which is supplied as part of the Microsoft Data Access Kit 2.7.

Levels of ODBC support

ODBC features are arranged according to level of conformance. Features are either Core, Level 1, or Level 2, with Level 2 being the most complete level of ODBC support. These features are listed in the ODBC Programmer's Reference, which is available from Microsoft Corporation as part of the ODBC software development kit or from the Microsoft Web site, at [external link] http://msdn.microsoft.com/library/en-us/odbc/htm/odbcabout_this_manual.asp.

Features supported by Adaptive Server Anywhere

Adaptive Server Anywhere supports the ODBC 3.5 specification.

  • Core conformance Adaptive Server Anywhere supports all Core level features.

  • Level 1 conformance Adaptive Server Anywhere supports all Level 1 features, except for asynchronous execution of ODBC functions.

    Adaptive Server Anywhere supports multiple threads sharing a single connection. The requests from the different threads are serialized by Adaptive Server Anywhere.

  • Level 2 conformance Adaptive Server Anywhere supports all Level 2 features, except for the following:

    • Three part names of tables and views. This is not applicable for Adaptive Server Anywhere.

    • Asynchronous execution of ODBC functions for specified individual statements.

    • Ability to time out login request and SQL queries.

ODBC backwards compatibility

Applications developed using older versions of ODBC continue to work with Adaptive Server Anywhere and the newer ODBC Driver Manager. The new ODBC features are not provided for older applications.

The ODBC Driver Manager

The ODBC Driver Manager is part of the ODBC software supplied with Adaptive Server Anywhere. The ODBC Version 3 Driver Manager has a new interface for configuring ODBC data sources.


Building ODBC applications

This section describes how to compile and link simple ODBC applications.


Including the ODBC header file

Every C source file that calls ODBC functions must include a platform-specific ODBC header file. Each platform-specific header file includes the main ODBC header file odbc.h, which defines all the functions, data types and constant definitions required to write an ODBC program.

toggle To include the ODBC header file in a C source file

  1. Add an include line referencing the appropriate platform-specific header file to your source file. The lines to use are as follows:

    Operating system | Include line
    Windows | #include "ntodbc.h"
    UNIX | #include "unixodbc.h"
    Windows CE | #include "ntodbc.h"

  2. Add the directory containing the header file to the include path for your compiler.

    Both the platform-specific header files and odbc.h are installed in the h subdirectory of your SQL Anywhere directory.


Linking ODBC applications on Windows

This section does not apply to Windows CE. For more information see Linking ODBC applications on Windows CE.

When linking your application, you must link against the appropriate import library file to have access to the ODBC functions. The import library defines entry points for the ODBC Driver Manager odbc32.dll. The Driver Manager in turn loads the Adaptive Server Anywhere ODBC driver dbodbc9.dll.

Separate import libraries are supplied for Microsoft, Watcom, and Borland compilers.

toggle To link an ODBC application (Windows)

  • Add the directory containing the platform-specific import library to the list of library directories.

    The import libraries are stored in the lib subdirectory of the directory containing your Adaptive Server Anywhere executables and are named as follows:

    Operating system | Compiler | Import library
    Windows | Microsoft | odbc32.lib
    Windows | Watcom C/C++ | wodbc32.lib
    Windows | Borland | bodbc32.lib
    Windows CE | Microsoft | dbodbc9.lib


Linking ODBC applications on Windows CE

On Windows CE operating systems there is no ODBC Driver Manager. The import library (dbodbc9.lib) defines entry points directly into the Adaptive Server Anywhere ODBC driver dbodbc9.dll.

Separate versions of this DLL are provided for the different chips on which Windows CE is available. The files are in operating-system specific subdirectories of the ce directory in your SQL Anywhere directory. For example, the ODBC driver for Windows CE on the ARM chip is in the following location:

C:\Program Files\Sybase\SQL Anywhere 9\ce\arm.30

For a list of supported versions of Windows CE, see Windows and NetWare operating systems.

toggle To link an ODBC application (Windows CE)

  1. Add the directory containing the platform-specific import library to the list of library directories.

    The import library is named dbodbc9.lib and is stored in an operating-system specific location under the ce directory in your SQL Anywhere directory. For example, the import library for Windows CE on the ARM chip is in the following location:

    C:\Program Files\Sybase\SQL Anywhere 9\ce\arm.30\lib

  2. Specify the DRIVER= parameter in the connection string supplied to the SQLDriverConnect function.

    szConnStrIn = "driver=ospath\dbodbc9.dll;dbf=c:\asademo.db"

    where ospath is the full path to the chip-specific subdirectory of your SQL Anywhere directory on the Windows CE device. For example:

    \Program Files\Sybase\SQL Anywhere 9\ce\arm.30\lib

The sample program (odbc.c) uses a File data source (FileDSN connection parameter) called ASA 9.0 Sample.dsn. You can create File data sources on your desktop system from the ODBC Driver Manager and copy them to your Windows CE device.

Windows CE and Unicode

Adaptive Server Anywhere uses an encoding known as UTF-8, a multi-byte character encoding which can be used to encode Unicode.

The Adaptive Server Anywhere ODBC driver supports either ASCII (8-bit) strings or Unicode code (wide character) strings. The UNICODE macro controls whether ODBC functions expect ASCII or Unicode strings. If your application must be built with the UNICODE macro defined, but you want to use the ASCII ODBC functions, then the SQL_NOUNICODEMAP macro must also be defined.

The Samples\ASA\C\odbc.c sample file illustrates how to use the Unicode ODBC features.


Linking ODBC applications on UNIX

An ODBC Driver Manager is not included with Adaptive Server Anywhere, but there are third party Driver Managers available. This section describes how to build ODBC applications that do not use an ODBC Driver Manager.

ODBC driver

The ODBC driver is a shared object or shared library. Separate versions of the Adaptive Server Anywhere ODBC driver are supplied for single-threaded and multi-threaded applications.

The ODBC drivers are the following files:

Operating system | Threading model | ODBC driver
Solaris/Sparc | Single threaded | dbodbc9.so (dbodbc9.so.1)
Solaris/Sparc | Multi-threaded | dbodbc_r.so (dbodbc_r.so.1)

The libraries are installed as symbolic links to the shared library with a version number (in parentheses).

toggle To link an ODBC application (UNIX)

  1. Link your application directly against the appropriate ODBC driver.

  2. When deploying your application, ensure that the appropriate ODBC driver is available in the user's library path.

Data source information

If Adaptive Server Anywhere does not detect the presence of an ODBC Driver Manager, it uses ~/.odbc.ini for data source information.

Using an ODBC Driver Manager on UNIX


Using an ODBC Driver Manager on UNIX

Third-party ODBC Driver Managers for UNIX are available. An ODBC Driver Manager includes the following files:

Operating system | Files
Solaris/Sparc | libodbc.so (libodbc.so.1) libodbcinst.so (libodbcinst.so.1)

If your are deploying an application that requires an ODBC Driver Manager and you are not using a third-party Driver Manager, create symbolic links for both the libodbc and libodbcinst shared libraries to the Adaptive Server Anywhere ODBC driver.

If an ODBC Driver Manager is present, Adaptive Server Anywhere queries the Driver Manager rather than ~/.odbc.ini for data source information.

Standard ODBC applications do not link directly against the ODBC driver. Instead, ODBC function calls go through the ODBC Driver Manager. On UNIX and Windows CE operating systems, Adaptive Server Anywhere does not include an ODBC Driver Manager. You can still create ODBC applications by linking directly against the Adaptive Server Anywhere ODBC driver, but you can then access only Adaptive Server Anywhere data sources.


ODBC samples

Several ODBC samples are included with Adaptive Server Anywhere. You can find the samples in the Samples\ASA subdirectory of your SQL Anywhere directory. By default, this is

C:\Program Files\Sybase\SQL Anywhere 9\Samples\ASA

The samples in directories starting with ODBC illustrate separate and simple ODBC tasks, such as connecting to a database and executing statements. A complete sample ODBC program is supplied as Samples\ASA\C\odbc.c. The program performs the same actions as the embedded SQL dynamic cursor example program that is in the same directory.

For a description of the associated embedded SQL program, see Sample embedded SQL programs.


Building the sample ODBC program

The ODBC sample program in Samples\ASA\C includes a batch file (shell script for UNIX) that can be used to compile and link the sample application.

toggle To build the sample ODBC program

  1. Open a command prompt and change directory to the Samples\ASA\C subdirectory of your SQL Anywhere directory.

  2. Run the makeall batch file or shell script

    The format of the command is as follows:

    makeall api platform compiler

    The parameters are as follows:

    • API Specify odbc to compile the ODBC example rather than an embedded SQL version of the application.

    • Platform Specify WINNT to compile for Windows operating systems.

    • Compiler Specify the compiler to use to compile the program. The compiler can be one of the following:

      • WC use Watcom C/C++

      • MC use Microsoft Visual C++

      • BC use Borland C++ Builder


Running the sample ODBC program

The sample program odbc.c, when compiled for versions of Windows that support services, runs optionally as a service.

The two files containing the example code for Windows services are the source file ntsvc.c and the header file ntsvc.h. The code allows the linked executable to be run either as a regular executable or as a Windows service.

toggle To run the ODBC sample

  1. Start the program:

    • Run the file Samples\ASA\C\odbcwnt.exe.

  2. Choose a table:

    • Choose one of the tables in the sample database. For example, you may enter Customer or Employee.

toggle To run the ODBC sample as a Windows service

  1. Start Sybase Central.

  2. In the left pane, select Adaptive Server Anywhere 9.

  3. In the right pane, select the Services tab.

  4. From the File menu, choose New > Service.

    The Service Creation wizard appears.

  5. On the first page, enter a name for the service.

  6. On the second page, select Sample program.

  7. On the third page, browse to the sample program (odbcwnt.exe) from the Samples\ASA\C subdirectory of your SQL Anywhere directory.

  8. Complete the wizard to install the service.

  9. Click Start on the main window to start the service.

When run as a service, the program displays the normal user interface if possible. It also writes the output to the Application Event Log. If it is not possible to start the user interface, the program prints one page of data to the Application Event Log and stops.


ODBC handles

ODBC applications use a small set of handles to define basic features such as database connections and SQL statements. A handle is a 32-bit value.

The following handles are used in essentially all ODBC applications.

  • Environment The environment handle provides a global context in which to access data. Every ODBC application must allocate exactly one environment handle upon starting, and must free it at the end.

    The following code illustrates how to allocate an environment handle:

    SQLHENV env;
SQLRETURN rc;
rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL
   _NULL_HANDLE, &env );

  • Connection A connection is specified by an ODBC driver and a data source. An application can have several connections associated with its environment. Allocating a connection handle does not establish a connection; a connection handle must be allocated first and then used when the connection is established.

    The following code illustrates how to allocate a connection handle:

    SQLHDBC  dbc;
SQLRETURN rc;
rc = SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc );

  • Statement A statement handle provides access to a SQL statement and any information associated with it, such as result sets and parameters. Each connection can have several statements. Statements are used both for cursor operations (fetching data) and for single statement execution (e.g. INSERT, UPDATE, and DELETE).

    The following code illustrates how to allocate a statement handle:

    SQLHSTMT stmt;
SQLRETURN rc;
rc = SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );


Allocating ODBC handles

The handle types required for ODBC programs are as follows:

Item | Handle type
Environment | SQLHENV
Connection | SQLHDBC
Statement | SQLHSTMT
Descriptor | SQLHDESC
toggle To use an ODBC handle

  1. Call the SQLAllocHandle function.

    SQLAllocHandle takes the following parameters:

    • an identifier for the type of item being allocated

    • the handle of the parent item

    • a pointer to the location of the handle to be allocated

      For a full description, see [external link] SQLAllocHandle in the Microsoft ODBC Programmer's Reference.

  2. Use the handle in subsequent function calls.

  3. Free the object using SQLFreeHandle.

    SQLFreeHandle takes the following parameters:

    • an identifier for the type of item being freed

    • the handle of the item being freed

      For a full description, see [external link] SQLFreeHandle in the Microsoft ODBC Programmer's Reference.

Example

The following code fragment allocates and frees an environment handle:

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 );

For more information on return codes and error handling, see Handling errors.


A first ODBC example

The following is a simple ODBC program that connects to the Adaptive Server Anywhere sample database and immediately disconnects.

You can find this sample as Samples\ASA\ODBCConnect\odbcconnect.cpp in your SQL Anywhere directory.

#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,
          (SQLCHAR*) "ASA 9.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;
}


Connecting to a data source

This section describes how to use ODBC functions to establish a connection to an Adaptive Server Anywhere database.


Choosing an ODBC connection function

ODBC supplies a set of connection functions. Which one you use depends on how you expect your application to be deployed and used:

  • SQLConnect The simplest connection function.

    SQLConnect takes a data source name and optional user ID and password. You may wish to use SQLConnect if you hard-code a data source name into your application.

    For more information, see [external link] SQLConnect in the Microsoft ODBC Programmer's Reference.

  • SQLDriverConnect Connects to a data source using a connection string.

    SQLDriverConnect allows the application to use Adaptive Server Anywhere-specific connection information that is external to the data source. Also, you can use SQLDriverConnect to request that the Adaptive Server Anywhere driver prompt for connection information.

    SQLDriverConnect can also be used to connect without specifying a data source.

    For more information, see [external link] SQLDriverConnect in the Microsoft ODBC Programmer's Reference.

  • SQLBrowseConnect Connects to a data source using a connection string, like SQLDriverConnect.

    SQLBrowseConnect allows your application to build its own dialog boxes to prompt for connection information and to browse for data sources used by a particular driver (in this case the Adaptive Server Anywhere driver).

    For more information, see [external link] SQLBrowseConnect in the Microsoft ODBC Programmer's Reference.

The examples in this chapter mainly use SQLDriverConnect.

For a complete list of connection parameters that can be used in connection strings, see Connection parameters.


Establishing a connection

Your application must establish a connection before it can carry out any database operations.

toggle To establish an ODBC connection

  1. Allocate an ODBC environment.

    For example:

    SQLHENV   env;
SQLRETURN retcode;
retcode = SQLAllocHandle( SQL_HANDLE_ENV,
  SQL_NULL_HANDLE, &env );

  2. Declare the ODBC version.

    By declaring that the application follows ODBC version 3, SQLSTATE values and some other version-dependent features are set to the proper behavior. For example:

    retcode = SQLSetEnvAttr( env,
  SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);

  3. If necessary, assemble the data source or connection string.

    Depending on your application, you may have a hard-coded data source or connection string, or you may store it externally for greater flexibility.

  4. Allocate an ODBC connection item.

    For example:

    retcode = SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc );

  5. Set any connection attributes that must be set before connecting.

    Some connection attributes must be set before establishing a connection, while others can be set either before or after. For example:

    retcode = SQLSetConnectAttr( dbc,
   SQL_AUTOCOMMIT,
   (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0 );

    For more information, see Setting connection attributes.

  6. Call the ODBC connection function.

    For example:

    if (retcode == SQL_SUCCESS
    || retcode == SQL_SUCCESS_WITH_INFO) {
   printf( "dbc allocated\n" );
   retcode = SQLConnect( dbc,
      (SQLCHAR*) "ASA 9.0 Sample", SQL_NTS,
      (SQLCHAR* ) "DBA", SQL_NTS,
      (SQLCHAR*) "SQL", SQL_NTS );
   if (retcode == SQL_SUCCESS
         || retcode == SQL_SUCCESS_WITH_INFO){
   // successfully connected.

You can find a complete sample as Samples\ASA\ODBCConnect\odbcconnect.cpp in your SQL Anywhere directory.

Notes

  • SQL_NTS Every string passed to ODBC has a corresponding length. If the length is unknown, you can pass SQL_NTS indicating that it is a Null Terminated String whose end is marked by the null character (\0).

  • SQLSetConnectAttr By default, ODBC operates in auto-commit mode. This mode is turned off by setting SQL_AUTOCOMMIT to false.

    For more information, see Setting connection attributes.


Setting connection attributes

You use the SQLSetConnectAttr function to control details of the connection. For example, the following statement turns off ODBC autocommit behavior.

retcode = SQLSetConnectAttr( dbc, SQL_AUTOCOMMIT,
   (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0 );

For more information including a list of connection attributes, see [external link] SQLSetConnectAttr in the Microsoft ODBC Programmer's Reference.

Many aspects of the connection can be controlled through the connection parameters. For information, see Connection parameters.


Threads and connections in ODBC applications

You can develop multi-threaded ODBC applications for Adaptive Server Anywhere. It is recommended that you use a separate connection for each thread.

You can use a single connection for multiple threads. However, the database server does not allow more than one active request for any one connection at a time. If one thread executes a statement that takes a long time, all other threads must wait until the request is complete.


Executing SQL statements

ODBC includes several functions for executing SQL statements:

  • Direct execution Adaptive Server Anywhere parses the SQL statement, prepares an access plan, and executes the statement. Parsing and access plan preparation are called preparing the statement.

  • Prepared execution The statement preparation is carried out separately from the execution. For statements that are to be executed repeatedly, this avoids repeated preparation and so improves performance.

    See Executing prepared statements.


Executing statements directly

The SQLExecDirect function prepares and executes a SQL statement. The statement may be optionally include parameters.

The following code fragment illustrates how to execute a statement without parameters. The SQLExecDirect function takes a statement handle, a SQL string, and a length or termination indicator, which in this case is a null-terminated string indicator.

The procedure described in this section is straightforward but inflexible. The application cannot take any input from the user to modify the statement. For a more flexible method of constructing statements, see Executing statements with bound parameters.

toggle To execute a SQL statement in an ODBC application

  1. Allocate a handle for the statement using SQLAllocHandle.

    For example, the following statement allocates a handle of type SQL_HANDLE_STMT with name stmt, on a connection with handle dbc:

    SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );

  2. Call the SQLExecDirect function to execute the statement:

    For example, the following lines declare a statement and execute it. The declaration of deletestmt would usually occur at the beginning of the function:

    SQLCHAR deletestmt[ STMT_LEN ] =
  "DELETE FROM department WHERE dept_id = 201";
SQLExecDirect( stmt, deletestmt, SQL_NTS) ;

For a complete sample with error checking, see Samples\ASA\ODBCExecute\odbcexecute.cpp.

For more information on SQLExecDirect, see [external link] SQLExecDirect in the Microsoft ODBC Programmer's Reference.


Executing statements with bound parameters

This section describes how to construct and execute a SQL statement, using bound parameters to set values for statement parameters at runtime.

toggle To execute a SQL statement with bound parameters in an ODBC application

  1. Allocate a handle for the statement using SQLAllocHandle.

    For example, the following statement allocates a handle of type SQL_HANDLE_STMT with name stmt, on a connection with handle dbc:

    SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );

  2. Bind parameters for the statement using SQLBindParameter.

    For example, the following lines declare variables to hold the values for the department ID, department name, and manager ID, as well as for the statement string itself. They then bind parameters to the first, second, and third parameters of a statement executed using the stmt statement handle.

    #defined DEPT_NAME_LEN 20
SQLINTEGER 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,
    &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. Assign values to the parameters.

    For example, the following lines assign values to the parameters for the fragment of step 2.

    deptID = 201;
strcpy( (char * ) deptname, "Sales East" );
managerID = 902;

    Commonly, these variables would be set in response to user action.

  4. Execute the statement using SQLExecDirect.

    For example, the following line executes the statement string held in insertstmt on the statement handle stmt.

    SQLExecDirect( stmt, insertstmt, SQL_NTS) ;

Bind parameters are also used with prepared statements to provide performance benefits for statements that are executed more than once. For more information, see Executing prepared statements

The above code fragments to not include error checking. For a complete sample, including error checking, see Samples\ASA\ODBCExecute\odbcexecute.cpp.

For more information on SQLExecDirect, see [external link] SQLExecDirect in the Microsoft ODBC Programmer's Reference.


Executing prepared statements

Prepared statements provide performance advantages for statements that are used repeatedly. ODBC provides a full set of functions for using prepared statements.

For an introduction to prepared statements, see Preparing statements.

toggle To execute a prepared SQL statement

  1. Prepare the statement using SQLPrepare.

    For example, the following code fragment illustrates how to prepare an INSERT statement:

    SQLRETURN   retcode;
SQLHSTMT    stmt;
retcode = SQLPrepare( stmt,
            "INSERT INTO department
             ( dept_id, dept_name, dept_head_id )
             VALUES (?, ?, ?,)",
          SQL_NTS);

    In this example:

    • retcode Holds a return code that should be tested for success or failure of the operation.

    • stmt Provides a handle to the statement so that it can be referenced later.

    • ? The question marks are placeholders for statement parameters.

  2. Set statement parameter values using SQLBindParameter.

    For example, the following function call sets the value of the dept_id variable:

    SQLBindParameter( stmt,
                 1,
                 SQL_PARAM_INPUT,
                 SQL_C_SSHORT,
                 SQL_INTEGER,
                 0,
                 0,
                 &sDeptID,
                 0,
                 &cbDeptID);

    In this example:

    • stmt is the statement handle

    • 1 indicates that this call sets the value of the first placeholder.

    • SQL_PARAM_INPUT indicates that the parameter is an input statement.

    • SQL_C_SHORT indicates the C data type being used in the application.

    • SQL_INTEGER indicates SQL data type being used in the database.

    • The next two parameters indicate the column precision and the number of decimal digits: both zero for integers.

    • &sDeptID is a pointer to a buffer for the parameter value.

    • 0 indicates the length of the buffer, in bytes.

    • &cbDeptID is a pointer to a buffer for the length of the parameter value.

  3. Bind the other two parameters and assign values to sDeptId.

  4. Execute the statement:

    retcode = SQLExecute( stmt);

    Steps 2 to 4 can be carried out multiple times.

  5. Drop the statement.

    Dropping the statement frees resources associated with the statement itself. You drop statements using SQLFreeHandle.

For a complete sample, including error checking, see Samples\ASA\ODBCPrepare\odbcprepare.cpp.

For more information on SQLPrepare, see [external link] SQLPrepare in the Microsoft ODBC Programmer's Reference.


Working with result sets

ODBC applications use cursors to manipulate and update result sets. Adaptive Server Anywhere provides extensive support for different kinds of cursors and cursor operations.

For an introduction to cursors, see Working with cursors.


Choosing a cursor characteristics

ODBC functions that execute statements and manipulate result sets use cursors to carry out their tasks. Applications open a cursor implicitly whenever they execute a SQLExecute or SQLExecDirect function.

For applications that move through a result set only in a forward direction and do not update the result set, cursor behavior is relatively straightforward. By default, ODBC applications request this behavior. ODBC defines a read-only, forward-only cursor, and Adaptive Server Anywhere provides a cursor optimized for performance in this case.

For a simple example of a forward-only cursor, see Retrieving data.

For applications that need to scroll both forward and backward through a result set, such as many graphical user interface applications, cursor behavior is more complex. What does the application when it returns to a row that has been updated by some other application? ODBC defines a variety of scrollable cursors to allow you to build in the behavior that suits your application. Adaptive Server Anywhere provides a full set of cursors to match the ODBC scrollable cursor types.

You set the required ODBC cursor characteristics by calling the SQLSetStmtAttr function that defines statement attributes. You must call SQLSetStmtAttr before executing a statement that creates a result set.

You can use SQLSetStmtAttr to set many cursor characteristics. The characteristics that determine the cursor type that Adaptive Server Anywhere supplies include the following:

  • SQL_ATTR_CURSOR_SCROLLABLE Set to SQL_SCROLLABLE for a scrollable cursor and SQL_NONSCROLLABLE for a forward-only cursor. SQL_NONSCROLLABLE is the default.

  • SQL_ATTR_CONCURRENCY Set to one of the following values:

    • SQL_CONCUR_READ_ONLY Disallow updates. SQL_CONCUR_READ_ONLY is the default.

    • SQL_CONCUR_LOCK Use the lowest level of locking sufficient to ensure that the row can be updated.

    • SQL_CONCUR_ROWVER Use optimistic concurrency control, comparing row versions such as SQLBase ROWID or Sybase TIMESTAMP.

    • SQL_CONCUR_VALUES Use optimistic concurrency control, comparing values.

For more information, see [external link] SQLSetStmtAttr in the Microsoft ODBC Programmer's Reference.

Example

The following fragment requests a read-only, scrollable cursor:

SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );
SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_SCROLLABLE,
      SQL_SCROLLABLE, 0 );


Retrieving data

To retrieve rows from a database, you execute a SELECT statement using SQLExecute or SQLExecDirect. This opens a cursor on the statement. You then use SQLFetch or SQLExtendedFetch to fetch rows through the cursor. When an application free the statement using SQLFreeHandle it closes the cursor.

To fetch values from a cursor, your application can use either SQLBindCol or SQLGetData. If you use SQLBindCol, values are automatically retrieved on each fetch. If you use SQLGetData, you must call it for each column after each fetch.

SQLGetData is used to fetch values in pieces for columns such as LONG VARCHAR or LONG BINARY. As an alternative, you can set the SQL_MAX_LENGTH statement attribute to a value large enough to hold the entire value for the column. The default value for SQL_ATTR_MAX_LENGTH is 256 kb.

The following code fragment opens a cursor on a query and retrieves data through the cursor. Error checking has been omitted to make the example easier to read. The fragment is taken from a complete sample, which can be found at Samples\ASA\ODBCSelect\odbcselect.cpp.

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 9.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 );

The number of row positions you can fetch in a cursor is governed by the size of an integer. You can fetch rows numbered up to number 2147483646, which is one less than the value that can be held in an integer. When using negative numbers (rows from the end) you can fetch down to one more than the largest negative value that can be held in an integer.


Updating and deleting rows through a cursor

The Microsoft ODBC Programmer's Reference suggests that you use SELECT... FOR UPDATE to indicate that a query is updateable using positioned operations. You do not need to use the FOR UPDATE clause in Adaptive Server Anywhere: SELECT statements are automatically updateable as long as the following conditions are met:

  • The underlying query supports updates.

    That is to say, as long as a data modification statement on the columns in the result is meaningful, then positioned data modification statements can be carried out on the cursor.

    The ANSI_UPDATE_CONSTRAINTS database option limits the type of queries that are updateable.

    For more information, see ANSI_UPDATE_CONSTRAINTS option [compatibility].

  • The cursor type supports updates.

    If you are using a read-only cursor, you cannot update the result set.

ODBC provides two alternatives for carrying out positioned updates and deletes:

  • Use the SQLSetPos function.

    Depending on the parameters supplied (SQL_POSITION, SQL_REFRESH, SQL_UPDATE, SQL_DELETE) SQLSetPos sets the cursor position and allows an application to refresh data, or update, or delete data in the result set.

    This is the method to use with Adaptive Server Anywhere.

  • Send positioned UPDATE and DELETE statements using SQLExecute. This method should not be used with Adaptive Server Anywhere.


Using bookmarks

ODBC provides bookmarks, which are values used to identify rows in a cursor. Adaptive Server Anywhere supports bookmarks for all kinds of cursors except dynamic cursors.

Before ODBC 3.0, a database could specify only whether it supported bookmarks or not: there was no interface to provide this information for each cursor type. There was no way for a database server to indicate for what kind of cursor bookmarks were supported. For ODBC 2 applications, Adaptive Server Anywhere returns that it does support bookmarks. There is therefore nothing to prevent you from trying to use bookmarks with dynamic cursors; however, you should not use this combination.


Calling stored procedures

This section describes how to create and call stored procedures and process the results from an ODBC application.

For a full description of stored procedures and triggers, see Using Procedures, Triggers, and Batches.

Procedures and result sets

There are two types of procedures: those that return result sets and those that do not. You can use SQLNumResultCols to tell the difference: the number of result columns is zero if the procedure does not return a result set. If there is a result set, you can fetch the values using SQLFetch or SQLExtendedFetch just like any other cursor.

Parameters to procedures should be passed using parameter markers (question marks). Use SQLBindParameter to assign a storage area for each parameter marker, whether it is an INPUT, OUTPUT, or INOUT parameter.

To handle multiple result sets, ODBC must describe the currently executing cursor, not the procedure-defined result set. Therefore, ODBC does not always describe column names as defined in the RESULT clause of the stored procedure definition. To avoid this problem, you can use column aliases in your procedure result set cursor.

Example

This example creates and calls a procedure that does not return a result set. The procedure takes one INOUT parameter, and increments its value. In the example, the variable num_col will have the value zero, since the procedure does not return a result set. Error checking has been omitted to make the example easier to read.

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,
            0, &i, NULL );
SQLExecDirect( stmt, "CALL Increment( ? )",
            SQL_NTS );
SQLNumResultCols( stmt, &num_col );
do_something( i );
Example

This example calls a procedure that returns a result set. In the example, the variable num_col will have the value 2 since the procedure returns a result set with two columns. Again, error checking has been omitted to make the example easier to read.

HDBC dbc;
HSTMT stmt;
SWORD num_col;
RETCODE retcode;
char emp_id[ 10 ];
char emp_lname[ 20 ];

/* Create the procedure */
SQLExecDirect( stmt,
      "CREATE PROCEDURE employees()" \
      " RESULT( emp_id CHAR(10), emp_lname CHAR(20))"\
      " BEGIN" \
      " SELECT emp_id, emp_lname 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 );
   }
}


Handling errors

Errors in ODBC are reported using the return value from each of the ODBC function calls and either the SQLError function or the SQLGetDiagRec function. The SQLError function was used in ODBC versions up to, but not including, version 3. As of version 3 the SQLError function has been deprecated and replaced by the SQLGetDiagRec function.

Every ODBC function returns a SQLRETURN, which is one of the following status codes:

Status code | Description
SQL_SUCCESS | No error.
SQL_SUCCESS_WITH_INFO | The function completed, but a call to SQLError will indicate a warning. The most common case for this status is that a value being returned is too long for the buffer provided by the application.
SQL_ERROR | The function did not complete because of an error. Call SQLError to get more information on the problem.
SQL_INVALID_HANDLE | An invalid environment, connection, or statement handle was passed as a parameter. This often happens if a handle is used after it has been freed, or if the handle is the null pointer.
SQL_NO_DATA_FOUND | There is no information available. The most common use for this status is when fetching from a cursor; it indicates that there are no more rows in the cursor.
SQL_NEED_DATA | Data is needed for a parameter. This is an advanced feature described in the ODBC SDK documentation under SQLParamData and SQLPutData.

Every environment, connection, and statement handle can have one or more errors or warnings associated with it. Each call to SQLError or SQLGetDiagRec returns the information for one error and removes the information for that error. If you do not call SQLError or SQLGetDiagRec to remove all errors, the errors are removed on the next function call that passes the same handle as a parameter.

Each call to SQLError passes three handles for an environment, connection, and statement. The first call uses SQL_NULL_HSTMT to get the error associated with a connection. Similarly, a call with both SQL_NULL_DBC and SQL_NULL_HSTMT get any error associated with the environment handle.

Each call to SQLGetDiagRec can pass either an environment, connection or statement handle. The first call passes in a handle of type SQL_HANDLE_DBC to get the error associated with a connection. The second call passes in a handle of type SQL_HANDLE_STMT to get the error associated with the statement that was just executed.

SQLError and SQLGetDiagRec return SQL_SUCCESS if there is an error to report (not SQL_ERROR), and SQL_NO_DATA_FOUND if there are no more errors to report.

Example 1

The following code fragment uses SQLError and return codes:

/* 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;
}
Example 2

The following code fragment uses SQLGetDiagRec and return codes:

/* 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;
}


The Database Tools Interface

About this chapter

This chapter describes how to use the database tools library that is provided with Adaptive Server Anywhere to add database management features to C or C++ applications.


Introduction to the database tools interface

Sybase Adaptive Server Anywhere includes Sybase Central and a set of utilities for managing databases. These database management utilities carry out tasks such as backing up databases, creating databases, translating transaction logs to SQL, and so on.

Supported platforms

All the database management utilities use a shared library called the database tools library. It is supplied for Windows operating systems and for UNIX. The name of this library is dbtool9.dll for Windows, and libdbtool9.so (non-threaded) or libdbtool9_r.so (threaded) for UNIX.

Non-threaded library for UNIX deprecated
The non-threaded library for UNIX is deprecated: it is fully supported in the current software but will not be supported in the next major release of SQL Anywhere Studio.

You can develop your own database management utilities or incorporate database management features into your applications by calling the database tools library. This chapter describes the interface to the database tools library. In this chapter, we assume you are familiar with how to call DLLs from the development environment you are using.

The database tools library has functions, or entry points, for each of the database management utilities. In addition, functions must be called before use of other database tools functions and when you have finished using other database tools functions.

Windows CE

The dbtool9.dll library is supplied for Windows CE, but includes only entry points for DBToolsInit, DBToolsFini, DBRemoteSQL, and DBSynchronizeLog. Other tools are not provided for Windows CE.

The dbtools.h header file

The dbtools header file included with Adaptive Server Anywhere lists the entry points to the DBTools library and also the structures used to pass information to and from the library. The dbtools.h file is installed into the h subdirectory under your installation directory. You should consult the dbtools.h file for the latest information about the entry points and structure members.

The dbtools.h header file includes two other files:

  • sqlca.h This is included for resolution of various macros, not for the SQLCA itself.

  • dllapi.h Defines preprocessor macros for operating-system dependent and language-dependent macros.

Also, the sqldef.h header file includes error return values.


Using the database tools interface

This section provides an overview of how to develop applications that use the DBTools interface for managing databases.

Using the import libraries
Starting and finishing the DBTools library
Calling the DBTools functions
Software component return codes
Using callback functions
Version numbers and compatibility
Using bit fields
A DBTools example


Using the import libraries

In order to use the DBTools functions, you must link your application against a DBTools import library which contains the required function definitions.

Supported platforms

Import libraries are compiler-specific and are supplied for Windows operating systems with the exception of Windows CE. Import libraries for the DBTools interface are provided with Adaptive Server Anywhere, and can be found in the lib subdirectory of each operating system's directory, under your installation directory. The provided DBTools import libraries are as follows:

Compiler | Library
Watcom | win32\dbtlstw.lib
Microsoft | win32\dbtlstM.lib
Borland | win32\dbtlstB.lib


Starting and finishing the DBTools library

Before using any other DBTools functions, you must call DBToolsInit. When you are finished using the DBTools DLL, you must call DBToolsFini.

The primary purpose of the DBToolsInit and DBToolsFini functions is to allow the DBTools DLL to load the Adaptive Server Anywhere language DLL. The language DLL contains localized versions of all error messages and prompts that DBTools uses internally. If DBToolsFini is not called, the reference count of the language DLL is not decremented and it will not be unloaded, so be careful to ensure there is a matched pair of DBToolsInit/DBToolsFini calls.

The following code fragment illustrates how to initialize and clean up DBTools:

// Declarations
a_dbtools_info   info;
short            ret;

//Initialize the a_dbtools_info structure
memset( &info, 0, sizeof( a_dbtools_info) );
info.errorrtn = (MSG_CALLBACK)MyErrorRtn;

// initialize DBTools
ret = DBToolsInit( &info );
if( ret != EXIT_OKAY ) {
   // DLL initialization failed
   ...
}
// call some DBTools routines . . .
...
// cleanup the DBTools dll
DBToolsFini( &info );


Calling the DBTools functions

All the tools are run by first filling out a structure, and then calling a function (or entry point) in the DBTools DLL. Each entry point takes a pointer to a single structure as argument.

The following example shows how to use the DBBackup function on a Windows operating system.

// Initialize the structure
a_backup_db backup_info;
memset( &backup_info, 0, sizeof( backup_info ) );

// Fill out the structure
backup_info.version = DB_TOOLS_VERSION_NUMBER;
backup_info.output_dir = "C:\\BACKUP";
backup_info.connectparms ="uid=DBA;pwd=SQL;dbf=asademo.db";

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 backup
DBBackup( &backup_info );

For information about the members of the DBTools structures, see DBTools structures.


Software component return codes

All database tools are provided as entry points in a DLL. These entry points use the following return codes:

Code | Explanation
0 | Success
1 | General failure
2 | Invalid file format
3 | File not found, unable to open
4 | Out of memory
5 | Terminated by the user
6 | Failed communications
7 | Missing a required database name
8 | Client/server protocol mismatch
9 | Unable to connect to the database server
10 | Database server not running
11 | Database server not found
254 | Reached stop time
255 | Invalid parameters on the command-line


Using callback functions

Several elements in DBTools structures are of type MSG_CALLBACK. These are pointers to callback functions.

Uses of callback functions

Callback functions allow DBTools functions to return control of operation to the user's calling application. The DBTools library uses callback functions to handle messages sent to the user by the DBTools functions for four purposes:

  • Confirmation Called when an action needs to be confirmed by the user. For example, if the backup directory does not exist, the tools DLL asks if it needs to be created.

  • Error message Called to handle a message when an error occurs, such as when an operation is out of disk space.

  • Information message Called for the tools to display some message to the user (such as the name of the current table being backed up).

  • Status information Called for the tools to display the status of an operation (such as the percentage done when unloading a table).

Assigning a callback function to a structure

You can directly assign a callback routine to the structure. The following statement is an example using a backup structure:

backup_info.errorrtn = (MSG_CALLBACK) MyFunction

MSG_CALLBACK is defined in the dllapi.h header file supplied with Adaptive Server Anywhere. Tools routines can call back to the Calling application with messages that should appear in the appropriate user interface, whether that be a windowing environment, standard output on a character-based system, or other user interface.

Confirmation callback function example

The following example confirmation routine asks the user to answer YES or NO to a prompt and returns the user's selection:

extern short _callback ConfirmRtn(
      char * question )
{
   int ret;
   if( question != NULL ) {
      ret = MessageBox( HwndParent, question,
      "Confirm", MB_ICONEXCLAMTION|MB_YESNO );
   }
   return( 0 );
}
Error callback function example

The following is an example of an error message handling routine, which displays the error message in a message box.

extern short _callback ErrorRtn(
      char * errorstr )
{
   if( errorstr != NULL ) {
      ret = MessageBox( HwndParent, errorstr,
      "Backup Error", MB_ICONSTOP|MB_OK );
   }
   return( 0 );
}
Message callback function example

A common implementation of a message callback function outputs the message to the screen:

extern short _callback MessageRtn(
      char * errorstr )
{
   if( messagestr != NULL ) {
   OutputMessageToWindow( messagestr );
   }
   return( 0 );
}
Status callback function example

A status callback routine is called when the tools needs to display the status of an operation (like the percentage done unloading a table). Again, a common implementation would just output the message to the screen:

extern short _callback StatusRtn(
      char * statusstr )
{
   if( statusstr == NULL ) {
      return FALSE;
   }
   OutputMessageToWindow( statustr );
   return TRUE;
}


Version numbers and compatibility

Each structure has a member that indicates the version number. You should use this version member to hold the version of the DBTools library that your application was developed against. The current version of the DBTools library is included as the constant in the dbtools.h header file.

toggle To assign the current version number to a structure

  • Assign the version constant to the version member of the structure before calling the DBTools function. The following line assigns the current version to a backup structure:

    backup_info.version = DB_TOOLS_VERSION_NUMBER;
Compatibility

The version number allows your application to continue working against newer versions of the DBTools library. The DBTools functions use the version number supplied by your application to allow the application to work, even if new members have been added to the DBTools structure.

Applications will not work against older versions of the DBTools library.


Using bit fields

Many of the DBTools structures use bit fields to hold Boolean information in a compact manner. For example, the backup structure includes the following bit fields:

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;
a_bit_field  server_backup   : 1;

Each bit field is one bit long, indicated by the 1 to the right of the colon in the structure declaration. The specific data type used depends on the value assigned to a_bit_field, which is set at the top of dbtools.h, and is operating system-dependent.

You assign an integer value of 0 or 1 to a bit field to pass Boolean information in the structure.


A DBTools example

You can find this sample and instructions for compiling it in the Samples\ASA\DBTools subdirectory of your SQL Anywhere directory. The sample program itself is Samples\ASA\DBTools\main.cpp. The sample illustrates how to use the DBTools library to carry out a backup of a database.

#define WINNT

#include <stdio.h>
#include "windows.h"
#include "string.h"
#include "dbtools.h"
extern short _callback ConfirmCallBack( char * str )
{
   if( MessageBox( NULL, str, "Backup",
       MB_YESNO|MB_ICONQUESTION ) == IDYES )
   {
      return 1;
   }
   return 0;
}
extern short _callback MessageCallBack( char * str )
{
   if( str != NULL )
   {
      fprintf( stdout, "%s", str );
      fprintf( stdout, "\n" );
      fflush( stdout );
   }
   return 0;
}
extern short _callback StatusCallBack( char * str )
{
   if( str != NULL )
   {
      fprintf( stdout, "%s", str );
      fprintf( stdout, "\n" );
      fflush( stdout );
   }
   return 0;
}
extern short _callback ErrorCallBack( char * str )
{
   if( str != NULL )
   {
      fprintf( stdout, "%s", str );
      fprintf( stdout, "\n" );
      fflush( stdout );
   }
   return 0;
}
typedef void (CALLBACK *DBTOOLSPROC)( void * );

// Main entry point into the program.
int main( int argc, char * argv[] )
{
   a_dbtools_info      dbt_info;
   a_backup_db      backup_info;
   char         dir_name[ _MAX_PATH + 1];
   char         connect[ 256 ];
   HINSTANCE      hinst;
   DBTOOLSPROC      dbbackup;
   DBTOOLSPROC      dbtoolsinit;
   DBTOOLSPROC      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_NUMBER;
   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) a trailing slash
      strcpy( dir_name, "c:\\temp" );
   }
   backup_info.output_dir = dir_name;
if( argc > 2 )
   {
      strncpy( connect, argv[2], 255 );
   }
   else
   {
      strcpy( connect, "DSN=ASA 9.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.rename_log = 0;
   backup_info.truncate_log = 0;
hinst = LoadLibrary( "dbtool9.dll" );
   if( hinst == NULL )
   {
      // Failed
      return 0;
   }
   dbt_info.errorrtn = (MSG_CALLBACK)ErrorCallBack;
   dbbackup = (DBTOOLSPROC) GetProcAddress( (HMODULE)hinst,
      "_DBBackup@4" );
   dbtoolsinit = (DBTOOLSPROC) GetProcAddress( (HMODULE)hinst,
      "_DBToolsInit@4" );
   dbtoolsfini = (DBTOOLSPROC) GetProcAddress( (HMODULE)hinst,
      "_DBToolsFini@4" );
   (*dbtoolsinit)( &dbt_info );
   (*dbbackup)( &backup_info );
   (*dbtoolsfini)( &dbt_info );
   FreeLibrary( hinst );
   return 0;
}


DBTools functions

This section describes the functions available in the DBTools library. The functions are listed alphabetically.

DBBackup function
DBChangeLogName function
DBChangeWriteFile function
DBCollate function
DBCompress function
DBCreate function
DBCreateWriteFile function
DBErase function
DBExpand function
DBInfo function
DBInfoDump function
DBInfoFree function
DBLicense function
DBStatusWriteFile function
DBSynchronizeLog function
DBToolsFini function
DBToolsInit function
DBToolsVersion function
DBTranslateLog function
DBTruncateLog function
DBUnload function
DBUpgrade function
DBValidate function


DBBackup function

Function

Database backup function. This function is used by the dbbackup command-line utility.

Prototype

short DBBackup ( const a_backup_db * backup-db );

Parameters
Parameter | Description
backup-db | Pointer to a_backup_db structure
Return value

A return code, as listed in Software component return codes.

Usage

The DBBackup function manages all database backup tasks.

For descriptions of these tasks, see The Backup utility.

See also

a_backup_db structure


DBChangeLogName function

Function

Changes the name of the transaction log file. This function is used by the dblog command-line utility.

Prototype

short DBChangeLogName ( const a_change_log * change-log );

Parameters
Parameter | Description
change-log | Pointer to a_change_log structure
Return value

A return code, as listed in Software component return codes.

Usage

The -t option of the dblog command-line utility changes the name of the transaction log. DBChangeLogName provides a programmatic interface to this function.

For descriptions of the dblog utility, see The Transaction Log utility.

See also

a_change_log structure


DBChangeWriteFile function

Function

Changes a write file to refer to another database file. This function is used by the dbwrite command-line utility when the -d option is applied.

Prototype

short DBChangeWriteFile ( const a_writefile * writefile );

Parameters
Parameter | Description
writefile | Pointer to a_writefile structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the Write File utility and its features, see The Write File utility (deprecated).

See also

DBCreateWriteFile function

DBStatusWriteFile function

a_writefile structure


DBCollate function

Function

Extracts a collation sequence from a database.

Prototype

short DBCollate ( const a_db_collation * db-collation );

Parameters
Parameter | Description
db-collation | Pointer to a_db_collation structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the collation utility and its features, see The Collation utility

See also

a_db_collation structure


DBCompress function

Function

Compresses a database file. This function is used by the dbshrink command-line utility.

Prototype

short DBCompress ( const a_compress_db * compress-db );

Parameters
Parameter | Description
compress-db | Pointer to a_compress_db structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the Compression utility and its features, see The Compression utility (deprecated).

See also

a_compress_db structure


DBCreate function

Function

Creates a database. This function is used by the dbinit command-line utility.

Prototype

short DBCreate ( const a_create_db * create-db );

Parameters
Parameter | Description
create-db | Pointer to a_create_db structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the initialization utility, see The Initialization utility.

See also

a_create_db structure


DBCreateWriteFile function

Function

Creates a write file. This function is used by the dbwrite command-line utility when the -c option is applied.

Prototype

short DBCreateWriteFile ( const a_writefile * writefile );

Parameters
Parameter | Description
writefile | Pointer to a_writefile structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the Write File utility and its features, see The Write File utility (deprecated).

See also

DBChangeWriteFile function

DBStatusWriteFile function

a_writefile structure


DBErase function

Function

Erases a database file and/or transaction log file. This function is used by the dberase command-line utility.

Prototype

short DBErase ( const an_erase_db * erase-db );

Parameters
Parameter | Description
erase-db | Pointer to an_erase_db structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the Erase utility and its features, see The Erase utility.

See also

an_erase_db structure


DBExpand function

Function

Uncompresses a database file. This function is used by the dbexpand command-line utility.

Prototype

short DBExpand ( const an_expand_db * expand-db );

Parameters
Parameter | Description
expand_db | Pointer to an_expand_db structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the Uncompression utility and its features, see The Uncompression utility (deprecated).

See also

an_expand_db structure


DBInfo function

Function

Returns information about a database file. This function is used by the dbinfo command-line utility.

Prototype

short DBInfo ( const a_db_info * db-info );

Parameters
Parameter | Description
db-info | Pointer to a_db_info structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the Information utility and its features, see The Information utility.

See also

DBInfoDump function

DBInfoFree function

a_db_info structure


DBInfoDump function

Function

Returns information about a database file. This function is used by the dbinfo command-line utility when the -u option is used.

Prototype

short DBInfoDump ( const a_db_info * db-info );

Parameters
Parameter | Description
db-info | Pointer to a_db_info structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the Information utility and its features, see The Information utility.

See also

DBInfo function

DBInfoFree function

a_db_info structure


DBInfoFree function

Function

Called to free resources after the DBInfoDump function is called.

Prototype

short DBInfoFree ( const a_db_info * db-info );

Parameters
Parameter | Description
db-info | Pointer to a_db_info structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the Information utility and its features, see The Information utility.

See also

DBInfo function

DBInfoDump function

a_db_info structure


DBLicense function

Function

Called to modify or report the licensing information of the database server.

Prototype

short DBLicense ( const a_db_lic_info * db-lic-info );

Parameters
Parameter | Description
db-lic-info | Pointer to a_dblic_info structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the Information utility and its features, see The Information utility.

See also

a_dblic_info structure


DBStatusWriteFile function

Function

Gets the status of a write file. This function is used by the dbwrite command-line utility when the -s option is applied.

Prototype

short DBStatusWriteFile ( const a_writefile * writefile );

Parameters
Parameter | Description
writefile | Pointer to a_writefile structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the Write File utility and its features, see The Write File utility (deprecated).

See also

DBChangeWriteFile function

DBCreateWriteFile function

a_writefile structure


DBSynchronizeLog function

Function

Synchronize a database with a MobiLink synchronization server.

Prototype

short DBSynchronizeLog( const a _sync_db * sync-db );

Parameters
Parameter | Description
sync-db | Pointer to a_sync_db structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the features you can access, see Initiating synchronization.

See also

DBTools Interface for dbmlsync


DBToolsFini function

Function

Decrements the counter and frees resources when an application is finished with the DBTools library.

Prototype

short DBToolsFini ( const a_dbtools_info * dbtools-info );

Parameters
Parameter | Description
dbtools-info | Pointer to a_dbtools_info structure
Return value

A return code, as listed in Software component return codes.

Usage

The DBToolsFini function must be called at the end of any application that uses the DBTools interface. Failure to do so can lead to lost memory resources.

See also

DBToolsInit function

a_dbtools_info structure


DBToolsInit function

Function

Prepares the DBTools library for use.

Prototype

short DBToolsInit( const a_dbtools_info * dbtools-info );

Parameters
Parameter | Description
dbtools-info | Pointer to a_dbtools_info structure
Return value

A return code, as listed in Software component return codes.

Usage

The primary purpose of the DBToolsInit function is to load the Adaptive Server Anywhere language DLL. The language DLL contains localized versions of error messages and prompts that DBTools uses internally.

The DBToolsInit function must be called at the start of any application that uses the DBTools interface, before any other DBTools functions.

Example

  • The following code sample illustrates how to initialize and clean up DBTools:

    a_dbtools_info   info;
short         ret;

memset( &info, 0, sizeof( a_dbtools_info) );
info.errorrtn = (MSG_CALLBACK)MakeProcInstance(             (FARPROC)MyErrorRtn, hInst );

// initialize DBTools
ret = DBToolsInit( &info );
if( ret != EXIT_OKAY ) {
      // DLL initialization failed
      ...
   }
   // call some DBTools routines . . .
   ...
   // cleanup the DBTools dll
   DBToolsFini( &info );
See also

DBToolsFini function

a_dbtools_info structure


DBToolsVersion function

Function

Returns the version number of the DBTools library.

Prototype

short DBToolsVersion ( void );

Return value

A short integer indicating the version number of the DBTools library.

Usage

Use the DBToolsVersion function to check that the DBTools library is not older than one against which your application is developed. While applications can run against newer versions of DBTools, they cannot run against older versions.

See also

Version numbers and compatibility


DBTranslateLog function

Function

Translates a transaction log file to SQL. This function is used by the dbtran command-line utility.

Prototype

short DBTranslateLog ( const a_translate_log * translate-log );

Parameters
Parameter | Description
translate-log | Pointer to a_translate_log structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the log translation utility, see The Log Translation utility.

See also

a_translate_log structure


DBTruncateLog function

Function

Truncates a transaction log file. This function is used by the dbbackup command-line utility.

Prototype

short DBTruncateLog ( const a_truncate_log * truncate-log );

Parameters
Parameter | Description
truncate-log | Pointer to a_truncate_log structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the backup utility, see The Backup utility

See also

a_truncate_log structure


DBUnload function

Function

Unloads a database. This function is used by the dbunload command-line utility and also by the dbxtract utility for SQL Remote.

Prototype

short DBUnload ( const an_unload_db * unload-db );

Parameters
Parameter | Description
unload-db | Pointer to an_unload_db structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the Unload utility, see The Unload utility.

See also

an_unload_db structure


DBUpgrade function

Function

Upgrades a database file. This function is used by the dbupgrade command-line utility.

Prototype

short DBUpgrade ( const an_upgrade_db * upgrade-db );

Parameters
Parameter | Description
upgrade-db | Pointer to an_upgrade_db structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the upgrade utility, see The Upgrade utility.

See also

an_upgrade_db structure


DBValidate function

Function

Validates all or part of a database. This function is used by the dbvalid command-line utility.

Prototype

short DBValidate ( const a_validate_db * validate-db );

Parameters
Parameter | Description
validate-db | Pointer to a_validate_db structure
Return value

A return code, as listed in Software component return codes.

Usage

For information about the upgrade utility, see The Validation utility.

Caution Validating a table or an entire database should be performed while no connections are making changes to the database; otherwise, spurious errors may be reported indicating some form of database corruption even though no corruption actually exists.
See also

a_validate_db structure


DBTools structures

This section lists the structures that are used to exchange information with the DBTools library. The structures are listed alphabetically.

Many of the structure elements correspond to command-line options on the corresponding utility. For example, several structures have a member named quiet, which can take on values of 0 or 1. This member corresponds to the quiet operation (-q) command-line option used by many of the utilities.

a_backup_db structure
a_change_log structure
a_compress_db structure
a_compress_stats structure
a_create_db structure
a_db_collation structure
a_db_info structure
a_dblic_info structure
a_dbtools_info structure
an_erase_db structure
an_expand_db structure
a_name structure
a_stats_line structure
a_sync_db structure
a_syncpub structure
a_sysinfo structure
a_table_info structure
a_translate_log structure
a_truncate_log structure
an_unload_db structure
an_upgrade_db structure
a_validate_db structure
a_writefile structure


a_backup_db structure

Function

Holds the information needed to carry out backup tasks using the DBTools library.

Syntax

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_bit_field server_backup : 1;
} a_backup_db;

Members
Member | Description
Version | DBTools version number
output_dir Path to the output directory. For example:
"c:\backup"
connectparms Parameters needed to connect to the database. They take the form of connection strings, such as the following:
"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"
The database server would be started by the connection string START parameter. The following is an example.
"START=d:\asa90\win32\dbeng9.exe"
A full example connection string including the START parameter:
"userid=dba;password=sql;dbf=d:\asa90\asademo.db;start=d:\asa90\win32\dbeng9.exe"
For the full range of connection string options, see Connection parameters
startline | Obsolete: The startline field is no longer used. The database server would be started by the connection string START parameter. Refer to connectparams for details.
confirmrtn | Callback routine for confirming an action
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
statusrtn | Callback routine for handling a status message
backup_database | Backup the database file (1) or not (0)
backup_logfile | Backup the transaction log file (1) or not (0)
backup_writefile | Backup the database write file (1) or not (0), if a write file is being used
no_confirm | Operate with (0) or without (1) confirmation
quiet | Operate without printing messages (1), or print messages (0)
rename_log | Rename the transaction log
truncate_log | Delete the transaction log
rename_local_log | Rename the local backup of the transaction log
hotlog_filename | File name for the live backup file
backup_interrupted | Indicates that the operation was interrupted
server_backup
See also

DBBackup function

For more information on callback functions, see Using callback functions.


a_change_log structure

Function

Holds the information needed to carry out dblog tasks using the DBTools library.

Syntax

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;
char * zap_current_offset;
char * zap_starting_offset;
char * encryption_key;
} a_change_log;

Members
Member | Description
version | DBTools version number
dbname | Database file name
logname | The name of the transaction log. If set to NULL, there is no log
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
query_only | If 1, just display the name of the transaction log. If 0, permit changing of the log name
quiet | Operate without printing messages (1), or print messages (0)
mirrorname_present | Set to 1. Indicates that the version of DBTools is recent enough to support the mirrorname field
change_mirrorname | If 1, permit changing of the log mirror name
change_logname | If 1, permit changing of the transaction log name
ignore_ltm_trunc | When using the Log Transfer Manager, performs the same function as the dbcc settrunc( 'ltm', 'gen_id', n ) Replication Server function: For information on dbcc, see your Replication Server documentation
ignore_remote_trunc | For SQL Remote. Resets the offset kept for the purposes of the DELETE_OLD_LOGS option, allowing transaction logs to be deleted when they are no longer needed
set_generation_number | When using the Log Transfer Manager, used after a backup is restored to set the generation number
ignore_dbsync_trunc | When using dbmlsync, resets the offset kept for the purposes of the DELETE_OLD_LOGS option, allowing transaction logs to be deleted when they are no longer needed
mirrorname | The new name of the transaction log mirror file
generation_number | The new generation number. Used together with set_generation_number
key_file | A file holding the encryption key
zap_current_offset | Change the current offset to the specified value. This is for use only in resetting a transaction log after an unload and reload to match dbremote or dbmlsync settings.
zap_starting_offset | Change the starting offset to the specified value. This is for use only in resetting a transaction log after an unload and reload to match dbremote or dbmlsync settings.
encryption_key | The encryption key for the database file.
See also

DBChangeLogName function

For more information on callback functions, see Using callback functions.


a_compress_db structure

Function

Holds the information needed to carry out database compression tasks using the DBTools library.

Syntax

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;

Members
Member | Description
version | DBTools version number
dbname | The file name of the database to compress
compress_name | The file name of the compressed database
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
statusrtn | Callback routine for handling a status message
display_free_pages | Display the free page information.
quiet | Operate without printing messages (1), or print messages (0)
record_unchanged | Set to 1. Indicates that the a_compress_stats structure is recent enough to have an unchanged member
a_compress_stats | Pointer to a structure of type a_compress_stats. This is filled in if the member is not NULL and display_free_pages is not zero
confirmrtn | Callback routine for confirming an action
noconfirm | Operate with (0) or without (1) confirmation
encryption_key | The encryption key for the database file.
See also

DBCompress function

a_compress_stats structure

For more information on callback functions, see Using callback functions.


a_compress_stats structure

Function

Holds information describing compressed database file statistics.

Syntax

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;

Members
Member | Description
tables | Holds compression information regarding tables
indices | Holds compression information regarding indexes
other | Holds other compression information
free | Holds information regarding free space
total | Holds overall compression information
free_pages | Holds information regarding free pages
unchanged | The number of pages that the compression algorithm was unable to shrink
See also

DBCompress function

a_compress_db structure


a_create_db structure

Function

Holds the information needed to create a database using the DBTools library.

Syntax

typedef struct a_create_db {
unsigned short version;
const char * dbname;
const char * logname;
const char * startline;
unsigned 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;
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_bit_field respect_password_case : 1;
a_bit_field checksum : 1;
} a_create_db;

Members
Member | Description
version | DBTools version number
dbname | Database file name
logname | New transaction log name
startline The command-line used to start the database server. The following is an example start line:
"c:\asa\win32\dbeng9.exe"
The default start line is used if this member is NULL

The following is the default START parameter:

"dbeng9 -gp <PAGE_SIZE> -C 10M"
(The -c 10M is added only when the page size is >=2048)
page_size | The page size of the database
default_collation | The collation for the database
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
database_version | The version number of the database
verbose | Run in verbose mode
blank_pad | Treat blanks as significant in string comparisons and hold index information to reflect this
respect_case | Make string comparisons case sensitive and hold index information to reflect this
encrypt | Encrypt the database
debug | Reserved
dbo_avail | Set to 1. The dbo user is available in this database
mirrorname_present | Set to 1. Indicates that the version of DBTools is recent enough to support the mirrorname field
avoid_view_collisions | Omit the generation of Watcom SQL compatibility views SYS.SYSCOLUMNS and SYS.SYSINDEXES
collation_id | Collation identifier
dbo_username | Obsolete
mirrorname | Transaction log mirror name
encryption_dllname | The DLL used to encrypt the database.
java_classes | Create a Java-enabled database.
jconnect | Include system procedures needed for jConnect
data_store_type | Reserved. Use NULL.
encryption_key | The encryption key for the database file.
encryption_algorithm | The encryption algorithm (AES).
jdk_version | One of the values for the dbinit -jdk option.
respect_password_case
checksum
See also

DBCreate function

For more information on callback functions, see Using callback functions.


a_db_collation structure

Function

Holds the information needed to extract a collation sequence from a database using the DBTools library.

Syntax

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;
} a_db_collation;

Members
Member | Description
version | DBTools version number
connectparms Parameters needed to connect to the database. They take the form of connection strings, such as the following:
"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"
The database server would be started by the connection string START parameter. The following is an example.
"START=d:\asa90\win32\dbeng9.exe"
A full example connection string including the START parameter:
"userid=dba;password=sql;dbf=d:\asa90\asademo.db;start=d:\asa90\win32\dbeng9.exe"
For the full range of connection string options, see Connection parameters
startline | Obsolete: The startline field is no longer used. The database server would be started by the connection string START parameter. Refer to connectparams for details.
confirmrtn | Callback routine for confirming an action
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
include_empty | Write empty mappings for gaps in the collations sequence
hex_for_extended | Use two-digit hexadecimal numbers to represent high-value characters
replace | Operate without confirming actions
quiet | Operate without messages
input_filename | Input collation definition
See also

DBCollate function

For more information on callback functions, see Using callback functions.


a_db_info structure

Function

Holds the information needed to return dbinfo information using the DBTools library.

Syntax

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;
a_sql_uint32 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;
a_sql_uint32 file_size;
a_sql_uint32 unused_pages;
a_sql_uint32 other_pages;
unsigned short mirrorbufsize;
char * mirrornamebuffer;
char * collationnamebuffer;
unsigned short collationnamebufsize;
char * classesversionbuffer;
unsigned short classesversionbufsize;
a_bit_field checksum : 1;
} a_db_info;

Members
Member | Description
version | DBTools version number
errortrn | Callback routine for handling an error message
dbname | Database file name
dbbufsize | The length of the dbnamebuffer member
dbnamebuffer | Database file name
logbufsize | The length of the lognamebuffer member
lognamebuffer | Transaction log file name
wrtbufsize | The length of the wrtnamebuffer member
wrtnamebuffer | The write file name
quiet | Operate without confirming messages
mirrorname_present | Set to 1. Indicates that the version of DBTools is recent enough to support the mirrorname field
sysinfo | Pointer to a_sysinfo structure
free_pages | Number of free pages
compressed | 1 if compressed, otherwise 0
connectparms Parameters needed to connect to the database. They take the form of connection strings, such as the following:
"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"
The database server would be started by the connection string START parameter. The following is an example.
"START=d:\asa90\win32\dbeng9.exe"
A full example connection string including the START parameter:
"userid=dba;password=sql;dbf=d:\asa90\asademo.db;start=d:\asa90\win32\dbeng9.exe"
For the full range of connection string options, see Connection parameters
startline | Obsolete: The startline field is no longer used. The database server would be started by the connection string START parameter. Refer to connectparams for details.
msgrtn | Callback routine for handling an information message
statusrtn | Callback routine for handling a status message
page_usage | 1 to report page usage statistics, otherwise 0
totals | Pointer to a_table_info structure
file_size | Size of database file
unused_pages | Number of unused pages
other_pages | Number of pages that are neither table nor index pages
mirrorbufsize | The length of the mirrornamebuffer member
mirrornamebuffer | The transaction log mirror name
collationnamebuffer | The database collation name and label (the maximum size is 128+1)
collationnamebufsize | The length of the collationnamebuffer member
classesversionbuffer | The JDK version of the installed Java classes, such as 1.1.3, 1.1.8, 1.3, or an empty string if Java classes are not installed in the database (the maximum size is 10+1)
classesversionbufsize | The length of the classesversionbuffer member
checksum | Database page checksums enabled if 1, disabled if 0
See also

DBInfo function

For more information on callback functions, see Using callback functions.


a_dblic_info structure

Function

Holds information containing licensing information. You must use this information only in a manner consistent with your license agreement.

Syntax

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;
a_bit_field quiet : 1;
a_bit_field query_only : 1;
} a_dblic_info;

Members
Member | Description
version | DBTools version number
exename | Executable name
username | User name for licensing
compname | Company name for licensing
platform_str | Operating system: WinNT or NLM or UNIX
nodecount | Number of nodes licensed.
conncount | Must be 1000000L
type | See lictype.h for values
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
quiet | Operate without printing messages (1), or print messages (0)
query_only | If 1, just display the license information. If 0, permit changing the information


a_dbtools_info structure

Function

Holds the information needed to start and finish working with the DBTools library.

Syntax

typedef struct a_dbtools_info {
MSG_CALLBACK errorrtn;
} a_dbtools_info;

Members
Member | Description
errorrtn | Callback routine for handling an error message
See also

DBToolsFini function

DBToolsInit function

For more information on callback functions, see Using callback functions.


an_erase_db structure

Function

Holds information needed to erase a database using the DBTools library.

Syntax

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;

Members
Member | Description
version | DBTools version number
dbname | Database file name to erase
confirmrtn | Callback routine for confirming an action
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
quiet | Operate without printing messages (1), or print messages (0)
erase | Erase without confirmation (1) or with confirmation (0)
encryption_key | The encryption key for the database file.
See also

DBErase function

For more information on callback functions, see Using callback functions.


an_expand_db structure

Function

Holds information needed for database expansion using the DBTools library.

Syntax

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 * unused_field;
const char * encryption_key;
} an_expand_db;

Members
Member | Description
version | DBTools version number
compress_name | Name of compressed database file
dbname | Database file name
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
statusrtn | Callback routine for handling a status message
quiet | Operate without printing messages (1), or print messages (0)
confirmrtn | Callback routine for confirming an action
noconfirm | Operate with (0) or without (1) confirmation
key_file | A file holding the encryption key
encryption_key | The encryption key for the database file.
See also

DBExpand function

For more information on callback functions, see Using callback functions.


a_name structure

Function

Holds a linked list of names. This is used by other structures requiring lists of names.

Syntax

typedef struct a_name {
struct a_name * next;
char name[1];
} a_name, * p_name;

Members
Member | Description
next | Pointer to the next a_name structure in the list
name | The name
p_name | Pointer to the previous a_name structure
See also

a_translate_log structure

a_validate_db structure

an_unload_db structure


a_stats_line structure

Function

Holds information needed for database compression and expansion using the DBTools library.

Syntax

typedef struct a_stats_line {
a_sql_int32 pages;
a_sql_int32 bytes;
a_sql_int32 compressed_bytes;
} a_stats_line;

Members
Member | Description
pages | Number of pages
bytes | Number of bytes for uncompressed database
compressed_bytes | Number of bytes for compressed database
See also

a_compress_stats structure


a_sync_db structure

Function

Holds information needed for the dbmlsync utility using the DBTools library.

Syntax

typedef struct a_sync_db {
unsigned short version;
char * connectparms;
char * publication;
const char * offline_dir;
char * extended_options;
char * script_full_path;
const char * include_scan_range;
const char * 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;
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_sql_uint32 dlg_launch_focus;
char * mlpassword;
char * new_mlpassword;
char * verify_mlpassword;

a_sql_uint32 pub_name_cnt;
char ** pub_name_list;
USAGE_CALLBACK usage_rtn;
a_sql_uint32 log_size;
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;
a_bit_short ping : 1;
a_bit_short _unused : 9;
char * encryption_key;
a_syncpub * upload_defs;
char * log_file_name;
char * user_name;

a_bit_short verbose_minimum : 1;
a_bit_short verbose_hook : 1;
a_bit_short verbose_row_data : 1;
a_bit_short verbose_row_cnts : 1;
a_bit_short verbose_option_info : 1;
a_bit_short strictly_ignore_trigger_ops : 1;
a_bit_short _unused2 : 10;
a_sql_uint32 est_upld_row_cnt;
STATUS_CALLBACK status_rtn;
MSG_CALLBACK warningrtn;
char ** ce_reproc_argv;

a_bit_short upload_only : 1;
a_bit_short download_only : 1;
a_bit_short allow_schema_change : 1;
a_bit_short dnld_gen_num : 1;
a_bit_short _unused3 :12;
const char * apply_dnld_file;
const char * create_dnld_file;
char * sync_params;
const char * dnld_file_extra;

COMServer * com_server;
a_bit_short trans_upload : 1;
a_bit_short continue_download : 1;
a_sql_uint32 dnld_read_size;
a_sql_uint32 dnld_fail_len;
a_sql_uint32 upld_fail_len;
} a_sync_db;

Members
Member | Description
version | DBTools version number
connectparms Parameters needed to connect to the database. They take the form of connection strings, such as the following:
"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"
The database server would be started by the connection string START parameter. The following is an example.
"START=d:\asa90\win32\dbeng9.exe"
A full example connection string including the START parameter:
"userid=dba;password=sql;dbf=d:\asa90\asademo.db;start=d:\asa90\win32\dbeng9.exe"
For the full range of connection string options, see Connection parameters
publication | Deprecated; use NULL
offline_dir | Log directory, as specified on the command line after the switches
extended_options | Extended options, as specified with -e
script_full_path | Deprecated; use Null
include_scan_range | Reserved; use NULL
raw_file | Reserved; use NULL
confirmrtn | Reserved; use NULL
errorrtn | Function to display error messages
msgrtn | Function to write messages to the user interface and, optionally, to the log file
logrtn | Function to write messages only to the log file
debug_dump_size | Reserved; use 0
dl_insert_width | Reserved; use 0
verbose | Deprecated; use 0
debug | Deprecated; use 0
debug_dump_hex | Deprecated; use 0
debug_dump_char | Deprecated; use 0
debug_page_offsets | Deprecated; use 0
use_hex_offsets | Deprecated; use 0
use_relative_offsets | Deprecated; use 0
output_to_file | Deprecated; use 0
output_to_mobile_link | Deprecated; use 1
dl_use_put | Deprecated; use 0
dl_use_upsert | Deprecated; use 0
kill_other_connections | TRUE if -d option is specified
retry_remote_behind | TRUE if -r or -rb is specified
ignore_debug_interrupt | Reserved—use 0
set_window_title_rtn | Function to call to change the title of the dbmlsync window (Windows NT/2000/XP only)
default_window_title | Name of the program to display in the window caption (for example, DBMLSync)
msgqueuertn Function called by DBMLSync when it wants to sleep. The parameter specifies the desired sleep period in milliseconds. The function should return the following, as defined in dllapi.h .

  • MSGQ_SLEEP_THROUGH indicates that the routine slept for the requested number of milliseconds. In most cases this is the value you should return.

  • MSGQ_SHUTDOWN_REQUESTED indicates that you would like the synchronization to terminate as soon as possible.

  • MSGQ_SYNC_REQUESTED indicates that the routine slept for less than the requested number of milliseconds and that the next synchronization should begin immediately if a synchronization is not currently in progress.

progress_msg_rtn | Function to change the text in the status window, above the progress bar
progress_index_rtn | Function to update the state of the progress bar
argv | argv array for this run; the last element of the array must be NULL
ce_argv | Reserved; use NULL
connectparms_allocated | Reserved; use 0
entered_dialog | Reserved; use 0
used_dialog_allocation | Reserved; use 0
ignore_scheduling | TRUE if -is was specified
ignore_hook_errors | TRUE if -eh was specified
changing_pwd | TRUE if -mn was specified
prompt_again | Reserved—use 0
retry_remote_ahead | TRUE if -ra was specified
rename_log | TRUE if -x was specified, in which case the log file is renamed and restarted
hide_conn_str | TRUE unless -vc was specified
hide_ml_pwd | TRUE unless -vp was specified
delay_ml_disconn | TRUE if -x was specified
dlg_launch_focus | Reserved; use 0
mlpassword | MobiLink password specified with -mp; NULL otherwise
new_mlpassword | New MobiLink password specified with -mn; NULL otherwise
verify_mlpassword | Reserved; use NULL
pub_name_cnt | Deprecated; use 0
pub_name_list | Deprecated; use NULL
usage_rtn | Reserved; use NULL
log_size | Log size in bytes, as specified with -x; otherwise 0
hovering_frequency | Hovering frequency in seconds; as set with -pp
ignore_hovering | True if -p was specified
verbose_upload | True if -vu was specified
verbose_upload_data | Reserved; use 0
verbose_download | Reserved; use 0
verbose_download_data | Reserved; use 0
autoclose | TRUE if -k was specified
ping | TRUE if -pi was specified
_unused | Reserved; use 0
encryption_key | Database key, as specified with -ek
upload_defs | Linked list of publications to be uploaded together—see a_syncpub
log_file_name | output log file name specified with -o or -ot
user_name | MobiLink user name, specifed with -u
verbose_minimum | TRUE if -v was specified
verbose_hook | TRUE if -vs was specified
verbose_row_data | TRUE if -vr was specified
verbose_row_cnts | TRUE if -vn was specified
verbose_option_info | TRUE if -vo was specified
strictly_ignore_trigger_ops | Reserved; use 0
_unused2 | Reserved; use 0
est_upld_row_cnt | Estimated number of rows to upload, specified with -urc
status_rtn | Reserved; use NULL
warningrtn | Function to display warning messages
ce_reproc_argv | Reserved, use NULL
upload_only | True if -uo was specified
download_only | TRUE if -ds was specified
allow_schema_change | TRUE if -sc was specified
dnld_gen_num | TRUE if -bg was specified
_unused3 | Reserved; use 0
apply_dnld_file | File specified with -ba; otherwise NULL
create_dnld_file | File specified with -bc; otherwise NULL
sync_params | User authentication parameters -- specified with -ap
dnld_file_extra | String specified with -be
com_server | Reserved, use NULL
trans_upload | TRUE if -tu was specified
continue_download | TRUE if -dc is specified
dnld_read_size | Value specified by -drs switch
dnld_fail_len | Reserved, use 0
upld_fail_len | Reserved, use 0

Some members correspond to features accessible from the dbmlsync command-line utility. Unused members should be assigned the value 0, FALSE, or NULL, depending on datatype.

See the dbtools.h header file for additional comments.

For more information, see MobiLink synchronization client.

See also

DBTools Interface for dbmlsync

DBSynchronizeLog function


a_syncpub structure

Function

Holds information needed for the dbmlsync utility.

Syntax

typedef struct a_syncpub {
struct a_syncpub * next;
char * pub_name;
char * ext_opt;
a_bit_field alloced_by_dbsync: 1;
} a_syncpub;

Members
Member | Description
a_syncpub | pointer to the next node in the list, NULL for the last node
pub_name | publication name(s) specified for this -n option. This is the exact string following -n on the command line.
ext_opt | extended options specified using the -eu option
alloced_by_dbsync | Reserved; use FALSE
See also

DBTools Interface for dbmlsync


a_sysinfo structure

Function

Holds information needed for dbinfo and dbunload utilities using the DBTools library.

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;
a_bit_field pwd_case_sensitivity: 1;
char default_collation[11];
unsigned short page_size;
} a_sysinfo;

Members
Member | Description
valid_date | Bit-field indicating whether the following values are set
blank_padding | 1 if blank padding is used in this database, 0 otherwise
case_sensitivity | 1 if the database is case-sensitive, 0 otherwise
encryption | 1 if the database is encrypted, 0 otherwise
pwd_case_sensitivity |
default_collation | The collation sequence for the database
page_size | The page size for the database
See also

a_db_info structure


a_table_info structure

Function

Holds information about a table needed as part of the a_db_info structure.

Syntax

typedef struct a_table_info {
struct a_table_info * next;
a_sql_uint32 table_id;
a_sql_uint32 table_pages;
a_sql_uint32 index_pages;
a_sql_uint32 table_used;
a_sql_uint32 index_used;
char * table_name;
a_sql_uint32 table_used_pct;
a_sql_uint32 index_used_pct;
} a_table_info;

Members
Member | Description
next | Next table in the list
table_id | ID number for this table
table_pages | Number of table pages
index_pages | Number of index pages
table_used | Number of bytes used in table pages
index_used | Number of bytes used in index pages
table_name | Name of the table
table_used_pct | Table space utilization as a percentage
index_used_pct | Index space utilization as a percentage
See also

a_db_info structure


a_translate_log structure

Function

Holds information needed for transaction log translation using the DBTools library.

Syntax

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;
a_sql_uint32 since_time;
const char * connectparms;
MSG_CALLBACK logrtn;
const char * reserved_1;
const char * 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 * include_source_sets;
const char * include_destination_sets;
const char * include_scan_range;
const char * repserver_users;
const char * include_tables;
const char * include_publications;
const char * queueparms;
a_bit_field generate_reciprocals :1;
a_bit_field match_mode :1;
const char * match_pos;
MSG_CALLBACK statusrtn;
const char * encryption_key;
a_bit_field show_undo :1;
a_bit_field quiet :1;
const char * logs_dir;
} a_translate_log;

Members
Member | Description
version | DBTools version number
logname | The name of the transaction log. If set to NULL, there is no log.
sqlname
userlist
confirmrtn | Callback routine for confirming an action
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
userlisttype
remove_rollback
ansi_sql
since_checkpoint
omit_comments
replace | Operate without confirming actions
debug | Reserved
include_trigger_trans
comment_trigger_trans
since_time
connectparms Parameters needed to connect to the database. They take the form of connection strings, such as the following:
"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"
The database server would be started by the connection string START parameter. The following is an example.
"START=d:\asa90\win32\dbeng9.exe"
A full example connection string including the START parameter:
"userid=dba;password=sql;dbf=d:\asa90\asademo.db;start=d:\asa90\win32\dbeng9.exe"
For the full range of connection string options, see Connection parameters
logrtn | Function to write messages only to the log file
reserved_1 | Reserved, use NULL
reserved_2 | Reserved, use NULL
debug_dump_size | Reserved, use zero
debug_sql_remote | Reserved, use false
debug_dump_hex | Reserved, use false
debug_dump_char | Reserved, use false
debug_page_offsets | Reserved, use false
reserved_3 | Reserved, use false
use_hex_offsets | Reserved, use false
use_relative_offsets | Reserved, use false
include_audit | Reserved, use false
chronological_order | Reserved, use false
force_recovery | Reserved, use false
include_subsets | Reserved, use false
force_chaining | Reserved, use false
recovery_ops | Rreserved, use zero
recovery_bytes | Reserved, use zero
include_source_sets | Reserved, use NULL
include_destination_sets | Reserved, use NULL
include_scan_range | Reserved, use NULL
repserver_users | Reserved, use NULL
include_tables | Reserved, use NULL
include_publications | Reserved, use NULL
queueparms | Reserved for sstran only
generate_reciprocals | Reserved, use false
match_mode | Reserved, use false
match_pos | Reserved, use NULL
statusrtn | Callback routine for handling a status message
encryption_key | -ek sets string
show_undo | reserved, use false
quiet | Operate without printing messages (1), or print messages (0)
logs_dir

The members correspond to features accessible from the dbtran command-line utility.

See the dbtools.h header file for additional comments.

See also

DBTranslateLog function

a_name structure

dbtran_userlist_type enumeration

For more information on callback functions, see Using callback functions.


a_truncate_log structure

Function

Holds information needed for transaction log truncation using the DBTools library.

Syntax

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;
a_bit_field server_backup : 1;
char truncate_interrupted;
} a_truncate_log;

Members
Member | Description
version | DBTools version number.
connectparms Parameters needed to connect to the database. They take the form of connection strings, such as the following:
"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"
The database server would be started by the connection string START parameter. The following is an example.
"START=d:\asa90\win32\dbeng9.exe"
A full example connection string including the START parameter:
"userid=dba;password=sql;dbf=d:\asa90\asademo.db;start=d:\asa90\win32\dbeng9.exe"
For the full range of connection string options, see Connection parameters
startline | Obsolete: The startline field is no longer used. The database server would be started by the connection string START parameter. Refer to connectparams for details.
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
quiet | Operate without printing messages (1), or print messages (0)
server_backup
truncate_interrupted | Indicates that the operation was interrupted
See also

DBTruncateLog function

For more information on callback functions, see Using callback functions.


an_unload_db structure

Function

Holds information needed to unload a database using the DBTools library or extract a remote database for SQL Remote. Those fields used by the dbxtract SQL Remote extraction utility are indicated.

Syntax

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;

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;
a_bit_short use_internal_reload : 1;

unsigned short view_iterations;
char escape_char;
char * reload_connectparms;
char * reload_db_filename;
a_bit_field output_connections:1;
char unload_interrupted;
a_bit_field replace_db:1;
const char * locale;
const char * site_name;
const char * template_name;
a_bit_field preserve_ids:1;
a_bit_field exclude_hooks:1;
char * reload_db_logname;
const char * encryption_key;
const char * encryption_algorithm;
a_bit_field syntax_version_7:1;
a_bit_field remove_java:1;
unsigned short reload_page_size;
} an_unload_db;

Members
Members | Description
version | DBTools version number.
connectparms Parameters needed to connect to the database. They take the form of connection strings, such as the following:
"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"
The database server would be started by the connection string START parameter. The following is an example.
"START=d:\asa90\win32\dbeng9.exe"
A full example connection string including the START parameter:
"userid=dba;password=sql;dbf=d:\asa90\asademo.db;start=d:\asa90\win32\dbeng9.exe"
For the full range of connection string options, see Connection parameters
startline | Obsolete: The startline field is no longer used. The database server would be started by the connection string START parameter. Refer to connectparams for details.
temp_dir | directory for unloading data files
reload_filename | dbunload -r option, something like "reload.sql"
errorrtn | optional user callback
msgrtn | optional user callback
statusrtn | optional user callback
confirmrtn | optional user callback
unload_type | UNLOAD_xxx (shown above)
verbose | VB_xxx (shown above)
unordered | dbunload -u sets TRUE
no_confirm | dbunload -y sets TRUE
use_internal_unload | dbunload -i? sets TRUE
dbo_avail | Obsolete
extract | TRUE if dbxtract, otherwise FALSE
table_list_provided | dbunload -e <list> or -i sets TRUE
exclude_tables | dbunload -e sets TRUE dbunload -i (undocumented) sets FALSE
more_flag_bits_present | usually set TRUE
sysinfo | (internal use)
remote_dir | (like temp_dir) but for internal unloads // on server side
dbo_username | The dbo_username functionality has been dropped as of 6.0 // you can leave it set to NULL
subscriber_username | argument to dbxtract
publisher_address_type | (unused)
publisher_address | (unused)
isolation_level | dbxtract -l sets value
start_subscriptions | dbxtract TRUE by default, -b sets FALSE
exclude_foreign_keys | dbxtract -xf sets TRUE
exclude_procedures | dbxtract -xp sets TRUE
exclude_triggers | dbxtract -xt sets TRUE
exclude_views | dbxtract -xv sets TRUE
isolation_set | dbxtract -l sets TRUE
include_where_subscribe | dbxtract -f sets TRUE/mlxtract sets TRUE
debug | (internal use)
table_list | selective table list
escape_char_present | -p sets TRUE and // escape_char must be set
view_iterations_present | (unused)
use_internal_reload | usually set TRUE // -ix/-xx sets FALSE // -ii/-xi sets TRUE
view_iterations | (unused)
escape_char | used when escape_char_present is TRUE
reload_connectparms | userid,password,database for reload database
reload_db_filename | filename of reload database to create
output_connections | (internal use)
unload_interrupted | (internal use)
replace_db | dbunload -ar sets TRUE
locale | (internal use) locale (language and charset)
site_name | for dbxtract: specify a site name
template_name | for dbxtract: specify a template name
preserve_ids | dbunload sets TRUE/-m sets FALSE
exclude_hooks | dbxtract -hx sets TRUE
reload_db_logname | log filename for the reload database
encryption_key | -ek sets string
encryption_algorithm | -ea sets, "aes" or "aes_fips"
syntax_version_7 | mlxtract -s7 sets TRUE
remove_java | -jr sets TRUE
reload_page_size | dbunload -ap sets value

The members correspond to features accessible from the dbunload and dbxtract, and mlxtract command-line utilities.

See the dbtools.h header file for additional comments.

See also

DBUnload function

a_name structure

dbunload type enumeration

For more information on callback functions, see Using callback functions.


an_upgrade_db structure

Function

Holds information needed to upgrade a database using the DBTools library.

Syntax

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;

Members
Member | Description
version | DBTools version number.
connectparms Parameters needed to connect to the database. They take the form of connection strings, such as the following:
"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"
The database server would be started by the connection string START parameter. The following is an example.
"START=d:\asa90\win32\dbeng9.exe"
A full example connection string including the START parameter:
"userid=dba;password=sql;dbf=d:\asa90\asademo.db;start=d:\asa90\win32\dbeng9.exe"
For the full range of connection string options, see Connection parameters
startline | Obsolete: The startline field is no longer used. The database server would be started by the connection string START parameter. Refer to connectparams for details.
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
statusrtn | Callback routine for handling a status message
quiet | Operate without printing messages (1), or print messages (0)
dbo_avail | Obsolete
dbo_username | The dbo_username functionality has been dropped as of 6.0 -- leave it set to NULL
java_classes | Upgrade the database to be Java-enabled
jconnect | Upgrade the database to include jConnect procedures
remove_java | Upgrade the database, removing the Java features
java_switch_specified
jdk_version | One of the values for the dbinit -jdk option.
See also

DBUpgrade function

For more information on callback functions, see Using callback functions.


a_validate_db structure

Function

Holds information needed for database validation using the DBTools library.

Syntax

typedef struct a_validate_db {
unsigned short version;
const char * connectparms;
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;

Members
Member | Description
version | DBTools version number.
connectparms Parameters needed to connect to the database. They take the form of connection strings, such as the following:
"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"
The database server would be started by the connection string START parameter. The following is an example.
"START=d:\asa90\win32\dbeng9.exe"
A full example connection string including the START parameter:
"userid=dba;password=sql;dbf=d:\asa90\asademo.db;start=d:\asa90\win32\dbeng9.exe"
For the full range of connection string options, see Connection parameters
startline | Obsolete: The startline field is no longer used. The database server would be started by the connection string START parameter. Refer to connectparams for details.
tables | Pointer to a linked list of table names
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
statusrtn | Callback routine for handling a status message
quiet | Operate without printing messages (1), or print messages (0)
index | Validate indexes
type | See a_validate_type enumeration
See also

DBValidate function

a_name structure

For more information on callback functions, see Using callback functions.


a_writefile structure

Function

Holds information needed for database write file management using the DBTools library.

Syntax

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;

Members
Member | Description
version | DBTools version number
writename | Write file name
wlogname | Used only when creating write files
dbname | Used when changing and creating write files
forcename | Forced file name reference
confirmrtn | Callback routine for confirming an action. Only used when creating a write file
errorrtn | Callback routine for handling an error message
msgrtn | Callback routine for handling an information message
action | Reserved for use by Sybase
quiet | Operate without printing messages (1), or print messages (0)
erase | Used for creating write files only. Erase without confirmation (1) or with confirmation (0)
force | If 1, force the write file to point to a named file
mirrorname_present | Used when creating only. Set to 1. Indicates that the version of DBTools is recent enough to support the mirrorname field
wlogmirrorname | Name of the transaction log mirror
make_log_and_mirror_names | If TRUE, use the values in wlogname and wlogmirrorname to determine filenames.
encryption_key | The encryption key for the database file.
See also

DBChangeWriteFile function

DBCreateWriteFile function

DBStatusWriteFile function

For more information on callback functions, see Using callback functions.


DBTools enumeration types

This section lists the enumeration types that are used by the DBTools library. The enumerations are listed alphabetically.


Verbosity enumeration

Function

Specifies the volume of output.

Syntax

enum {
VB_QUIET,
VB_NORMAL,
VB_VERBOSE
};

Parameters
Value | Description
VB_QUIET | No output
VB_NORMAL | Normal amount of output
VB_VERBOSE | Verbose output, useful for debugging
See also

a_create_db structure

an_unload_db structure


Blank padding enumeration

Function

Used in the a_create_db structure, to specify the value of blank_pad.

Syntax

enum {
NO_BLANK_PADDING,
BLANK_PADDING
};

Parameters
Value | Description
NO_BLANK_PADDING | Does not use blank padding
BLANK_PADDING | Uses blank padding
See also

a_create_db structure


dbtran_userlist_type enumeration

Function

The type of a user list, as used by an a_translate_log structure.

Syntax

typedef enum dbtran_userlist_type {
DBTRAN_INCLUDE_ALL,
DBTRAN_INCLUDE_SOME,
DBTRAN_EXCLUDE_SOME
} dbtran_userlist_type;

Parameters
Value | Description
DBTRAN_INCLUDE_ALL | Include operations from all users
DBTRAN_INCLUDE_SOME | Include operations only from the users listed in the supplied user list
DBTRAN_EXCLUDE_SOME | Exclude operations from the users listed in the supplied user list
See also

a_translate_log structure


dbunload type enumeration

Function

The type of unload being performed, as used by the an_unload_db structure.

Syntax

enum {
UNLOAD_ALL,
UNLOAD_DATA_ONLY,
UNLOAD_NO_DATA
};

Parameters
Value | Description
UNLOAD_ALL | Unload both data and schema
UNLOAD_DATA_ONLY | Unload data. Do not unload schema
UNLOAD_NO_DATA | Unload schema only
See also

an_unload_db structure


a_validate_type enumeration

Function

The type of validation being performed, as used by the a_validate_db structure.

Syntax

typedef enum {
VALIDATE_NORMAL = 0,
VALIDATE_DATA,
VALIDATE_INDEX,
VALIDATE_EXPRESS,
VALIDATE_FULL
} a_validate_type;

Parameters
Value | Description
VALIDATE_NORMAL | Validate with the default check only.
VALIDATE_DATA | Validate with data check in addition to the default check.
VALIDATE_INDEX | Validate with index check in addition to the default check.
VALIDATE_EXPRESS | Validate with express check in addition to the default and data checks.
VALIDATE_FULL | Validate with both data and index check in addition toe the default check.
See also

Validating a database using the dbvalid command-line utility

VALIDATE TABLE statement


The OLE DB and ADO Programming Interfaces

About this chapter

This chapter describes how to use the OLE DB interface to Adaptive Server Anywhere.

Many applications that use the OLE DB interface do so through the Microsoft ActiveX Data Objects (ADO) programming model, rather than directly. This chapter also describes ADO programming with Adaptive Server Anywhere.


Introduction to OLE DB

OLE DB is a data access model from Microsoft. It uses the Component Object Model (COM) interfaces and, unlike ODBC, OLE DB does not assume that the data source uses a SQL query processor.

Adaptive Server Anywhere includes an OLE DB provider named ASAProv. This provider is available for current Windows and Windows CE platforms.

You can also access Adaptive Server Anywhere using the Microsoft OLE DB Provider for ODBC (MSDASQL), together with the Adaptive Server Anywhere ODBC driver.

Using the Adaptive Server Anywhere OLE DB provider brings several benefits:

  • Some features, such as updating through a cursor, are not available using the OLE DB/ODBC bridge.

  • If you use the Adaptive Server Anywhere OLE DB provider, ODBC is not required in your deployment.

  • MSDASQL allows OLE DB clients to work with any ODBC driver but does not guarantee that you can use the full range of functionality of each ODBC driver. Using the Adaptive Server Anywhere provider, you can get full access to Adaptive Server Anywhere features from OLE DB programming environments.


Supported platforms

The Adaptive Server Anywhere OLE DB provider is designed to work with OLE DB 2.5 and later. For Windows CE and its successors, the OLE DB provider is designed for ADOCE 3.0 and later.

ADOCE is the Microsoft ADO for Windows CE SDK and provides database functionality for applications developed with the Windows CE Toolkits for Visual Basic 5.0 and Visual Basic 6.0.

For a list of supported platforms, see Operating system versions.


Distributed transactions

The OLE DB driver can be used as a resource manager in a distributed transaction environment.

For more information, see Three-Tier Computing and Distributed Transactions.


ADO programming with Adaptive Server Anywhere

ADO (ActiveX Data Objects) is a data access object model exposed through an Automation interface, which allows client applications to discover the methods and properties of objects at runtime without any prior knowledge of the object. Automation allows scripting languages like Visual Basic to use a standard data access object model. ADO uses OLE DB to provide data access.

Using the Adaptive Server Anywhere OLE DB provider, you get full access to Adaptive Server Anywhere features from an ADO programming environment.

This section describes how to carry out basic tasks while using ADO from Visual Basic. It is not a complete guide to programming using ADO.

Code samples from this section can be found in the following files:

Development tool | Sample
Microsoft Visual Basic 6.0 | Samples\ASA\VBSampler\vbsampler.vbp
Microsoft eMbedded Visual Basic 3.0 | Samples\ASA\ADOCE\OLEDB_PocketPC.ebp

For information on programming in ADO, see your development tool documentation.

Connecting to a database with the Connection object
Executing statements with the Command object
Querying the database with the Recordset object
Working with Recordset object
Updating data through a cursor
Using transactions


Connecting to a database with the Connection object

This section describes a simple Visual Basic routine that connects to a database.

Sample code

You can try this routine by placing a command button named Command1 on a form, and pasting the routine into its Click event. Run the program and click the button to connect and then disconnect.

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 9.0 Sample"
    myConn.Open
    MsgBox "Connection succeeded"
    myConn.Close
    Exit Sub

HandleError:
    MsgBox "Connection failed"
    Exit Sub
End Sub
Notes

The sample carries out the following tasks:

  • It declares the variables used in the routine.

  • It establishes a connection, using the Adaptive Server Anywhere OLE DB provider, to the sample database.

  • It uses a Command object to execute a simple statement, which displays a message on the database server window.

  • It closes the connection.

When the ASAProv provider is installed, it registers itself. This registration process includes making registry entries in the COM section of the registry, so that ADO can locate the DLL when the ASAProv provider is called. If you change the location of your DLL, you must reregister it.

toggle To register the OLE DB provider

  1. Open a command prompt.

  2. Change to the directory where the OLE DB provider is installed.

  3. Enter the following command to register the provider:

    regsvr32 dboledb9.dll

For more information about connecting to a database using OLE DB, see Connecting to a database using OLE DB.


Executing statements with the Command object

This section describes a simple routine that sends a simple SQL statement to the database.

Sample code

You can try this routine by placing a command button named Command2 on a form, and pasting the routine into its Click event. Run the program and click the button to connect, display a message on the database server window, and then disconnect.

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 9.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.Close
End Sub
Notes

After establishing a connection, the example code creates a Command object, sets its CommandText property to an update statement, and sets its ActiveConnection property to the current connection. It then executes the update statement and displays the number of rows affected by the update in a message box.

In this example, the update is sent to the database and committed as soon as it is executed.

For information on using transactions within ADO, see Using transactions.

You can also carry out updates through a cursor.

For more information, see Updating data through a cursor.


Querying the database with the Recordset object

The ADO Recordset object represents the result set of a query. You can use it to view data from a database.

Sample code

You can try this routine by placing a command button named cmdQuery on a form and pasting the routine into its Click event. Run the program and click the button to connect, display a message on the database server window, execute a query and display the first few rows in message boxes, and then disconnect.

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 9.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
      MsgBox myRS.Fields("company_name"), vbInformation
      myRS.MoveNext
    Next

    myRS.Close
    myConn.Close
    Exit Sub
ErrorHandler:
    MsgBox Error(Err)
    Exit Sub
End Sub
Notes

The Recordset object in this example holds the results from a query on the Customer table. The For loop scrolls through the first several rows and displays the company_name value for each row.

This is a simple example of using a cursor from ADO.

For more advanced examples of using a cursor from ADO, see Working with Recordset object.


Working with Recordset object

When working with Adaptive Server Anywhere, the ADO Recordset represents a cursor. You can choose the type of cursor by declaring a CursorType property of the Recordset object before you open the Recordset. The choice of cursor type controls the actions you can take on the Recordset and has performance implications.

Cursor types

The set of cursor types supported by Adaptive Server Anywhere is described in Cursor properties. ADO has its own naming convention for cursor types.

The available cursor types, the corresponding cursor type constants, and the Adaptive Server Anywhere types they are equivalent to, are as follows:

ADO cursor type | ADO constant | Adaptive Server Anywhere type
Dynamic cursor | adOpenDynamic | Dynamic scroll cursor
Keyset cursor | adOpenKeyset | Scroll cursor
Static cursor | adOpenStatic | Insensitive cursor
Forward only | adOpenForwardOnly | No-scroll cursor

For information on choosing a cursor type that is suitable for your application, see Choosing cursor types.

Sample code

The following code sets the cursor type for an ADO Recordset object:

Dim myRS As New ADODB.Recordset
myRS.CursorType = adOpenDynamic


Updating data through a cursor

The Adaptive Server Anywhere OLE DB provider lets you update a result set through a cursor. This capability is not available through the MSDASQL provider.

Updating record sets

You can update the database through a record set.

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 9.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")), _
             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.Close
End Sub
Notes

If you use the adLockBatchOptimistic setting on the recordset, the myRS.Update method does not make any changes to the database itself. Instead, it updates a local copy of the Recordset.

The myRS.UpdateBatch method makes the update to the database server, but does not commit it, because it is inside a transaction. If an UpdateBatch method was invoked outside a transaction, the change would be committed.

The myConn.CommitTrans method commits the changes. The Recordset object has been closed by this time, so there is no issue of whether the local copy of the data is changed or not.


Using transactions

By default, any change you make to the database using ADO is committed as soon as it is executed. This includes explicit updates, as well as the UpdateBatch method on a Recordset. However, the previous section illustrated that you can use the BeginTrans and RollbackTrans or CommitTrans methods on the Connection object to use transactions.

Transaction isolation level is set as a property of the Connection object. The IsolationLevel property can take on one of the following values:

ADO isolation level | Constant | ASA level
Unspecified | adXactUnspecified | Not applicable. Set to 0
Chaos | adXactChaos | Unsupported. Set to 0
Browse | adXactBrowse | 0
Read uncommitted | adXactReadUncommitted | 0
Cursor stability | adXactCursorStability | 1
Read committed | adXactReadCommitted | 1
Repeatable read | adXactRepeatableRead | 2
Isolated | adXactIsolated | 3
Serializable | adXactSerializable | 3

For more information on isolation levels, see Isolation levels and consistency.


Supported OLE DB interfaces

The OLE DB API consists of a set of interfaces. The following table describes the support for each interface in the Adaptive Server Anywhere OLE DB driver.

Interface | Purpose | Limitations
IAccessor | Define bindings between client memory and data store values. | DBACCESSOR_PASSBYREF not supported. DBACCESSOR_OPTIMIZED not supported.
IAlterIndex IAlterTable | Alter tables, indexes, and columns. | Not supported.
IChapteredRowset | A chaptered rowset allows rows of a rowset to be accessed in separate chapters. | Not supported. Adaptive Server Anywhere does not support chaptered rowsets.
IColumnsInfo | Get simple information about the columns of a rowset. | Not on CE.
IColumnsRowset | Get information about optional metadata columns in a rowset, and get a rowset of column metadata. | Not on CE.
ICommand | Execute SQL commands. | Does not support calling. IcommandProperties: GetProperties with DBPROPSET_PROPERTIESINERROR to find properties that could not have been set.
ICommandPersist | Persist the state of a command object (but not any active rowsets). These persistent command objects can subsequently be enumerated using the PROCEDURES or VIEWS rowset. | Not on CE.
ICommandPrepare | Prepare commands. | Not on CE.
ICommandProperties | Set Rowset properties for rowsets created by a command. Most commonly used to specify the interfaces the rowset should support. | Supported.
ICommandText | Set the SQL command text for ICommand. | Only the DBGUID_DEFAULT SQL dialect is supported.
IcommandWithParameters | Set or get parameter information for a command. | No support for parameters stored as vectors of scalar values. No support for BLOB parameters. Not on CE.
IConvertType |  | Supported. Limited on CE.
IDBAsynchNotify IDBAsyncStatus | Asynchronous processing. Notify client of events in the asynchronous processing of data source initialization, populating rowsets, and so on. | Not supported.
IDBCreateCommand | Create commands from a session. | Supported.
IDBCreateSession | Create a session from a data source object. | Supported.
IDBDataSourceAdmin | Create/destroy/modify data source objects, which are COM objects used by clients. This interface is not used to manage data stores (databases). | Not supported.
IDBInfo | Find information about keywords unique to this provider (that is, to find non-standard SQL keywords). Also, find information about literals, special characters used in text matching queries, and other literal information. | Not on CE.
IDBInitialize | Initialize data source objects and enumerators. | Not on CE.
IDBProperties | Manage properties on a data source object or enumerator. | Not on CE.
IDBSchemaRowset | Get information about system tables, in a standard form (a rowset). | Not on CE.
IErrorInfo IErrorLookup IErrorRecords | ActiveX error object support. | Not on CE.
IGetDataSource | Returns an interface pointer to the session's data source object. | Supported.
IIndexDefinition | Create or drop indexes in the data store. | Not supported.
IMultipleResults | Retrieve multiple results (rowsets or row counts) from a command. | Supported.
IOpenRowset | Non-SQL way to access a database table by its name. | Supported. Opening a table by its name is supported, not by a GUID.
IParentRowset | Access chaptered/hierarchical rowsets. | Not supported.
IRowset | Access rowsets. | Supported.
IRowsetChange | Allow changes to rowset data, reflected back to the data store. InsertRow/SetData for blobs not yet implemented. | Not on CE.
IRowsetChapterMember | Access chaptered/hierarchical rowsets. | Not supported.
IRowsetCurrentIndex | Dynamically change the index for a rowset. | Not supported.
IRowsetFind | Find a row within a rowset matching a specified value. | Not supported.
IRowsetIdentity | Compare row handles. | Not supported.
IRowsetIndex | Access database indexes. | Not supported.
IRowsetInfo | Find information about a rowset properties or to find the object that created the rowset. | Not on CE.
IRowsetLocate | Position on rows of a rowset, using bookmarks. | Not on CE.
IRowsetNotify | Provides a COM callback interface for rowset events. | Supported.
IRowsetRefresh | Get the latest value of data that is visible to a transaction. | Not supported.
IRowsetResynch | Old OLEDB 1.x interface, superseded by IRowsetRefresh. | Not supported.
IRowsetScroll | Scroll through rowset to fetch row data. | Not supported.
IRowsetUpdate | Delay changes to rowset data until Update is called. | Supported. Not on CE.
IRowsetView | Use views on an existing rowset. | Not supported.
ISequentialStream | Retrieve a blob column. | Supported for reading only. No support for SetData with this interface. Not on CE.
ISessionProperties | Get session property information. | Supported.
ISourcesRowset | Get a rowset of data source objects and enumerators. | Not on CE.
ISQLErrorInfo ISupportErrorInfo | ActiveX error object support. | Optional on CE.
ITableDefinition ITableDefinitionWithConstraints | Create, drop, and alter tables, with constraints. | Not on CE.
ITransaction | Commit or abort transactions. | Not all the flags are supported. Not on CE.
ITransactionJoin | Support distributed transactions. | Not all the flags are supported. Not on CE.
ITransactionLocal | Handle transactions on a session. Not all the flags are supported. | Not on CE.
ITransactionOptions | Get or set options on a transaction. | Not on CE.
IViewChapter | Work with views on an existing rowset, specifically to apply post-processing filters/sorting on rows. | Not supported.
IViewFilter | Restrict contents of a rowset to rows matching a set of conditions. | Not supported.
IViewRowset | Restrict contents of a rowset to rows matching a set of conditions, when opening a rowset. | Not supported.
IViewSort | Apply sort order to a view. | Not supported.


Introduction to the Adaptive Server Anywhere .NET Data Provider

About this chapter

This chapter introduces you to the Adaptive Server Anywhere .NET data provider.


Adaptive Server Anywhere .NET data provider features

If you are using Visual Studio .NET on Windows NT/2000/XP, the following data providers are supported for accessing Adaptive Server Anywhere:

  • iAnywhere.Data.AsaClient uses the Adaptive Server Anywhere .NET data provider described in this book.

  • System.Data.Oledb is a general-purpose data provider for OLE DB data sources. It is part of the Microsoft .NET Framework. You can use System.Data.Oledb together with the Adaptive Server Anywhere OLE DB driver to access Adaptive Server Anywhere databases.

  • System.Data.Odbc is a general-purpose data provider for ODBC data sources. It is part of the Microsoft .NET Framework. You can use System.Data.Odbc together with the Adaptive Server Anywhere ODBC driver to access Adaptive Server Anywhere databases.

On Windows CE, only the Adaptive Server Anywhere .NET data provider is supported.

There are some key benefits to using the Adaptive Server Anywhere .NET data provider:

  • The Adaptive Server Anywhere .NET data provider is faster than the OLE DB provider.

  • In the .NET environment, the Adaptive Server Anywhere .NET data provider provides native access to Adaptive Server Anywhere. Unlike the other supported providers, it communicates directly with Adaptive Server Anywhere and does not require bridge technology.


Running the sample projects

There are three sample projects included with the Adaptive Server Anywhere .NET data provider. They are:

  • SimpleCE A Compact Framework Windows CE sample that demonstrates a simple list box that is filled with the names from the employee table when you click the Connect button.

  • SimpleWin32 A Windows sample that demonstrates a simple list box that is filled with the names from the employee table when you click the Connect button.

  • TableViewer A Windows program that allows you to enter and execute SQL statements.

For tutorials explaining the win32 and Table Viewer samples, see Using the Adaptive Server Anywhere .NET Data Provider Sample Applications.

Note

If your SQL Anywhere installation directory is not the default (C:\Program Files\Sybase\SQL Anywhere 9), you may receive an error referencing the data provider DLL when you load the sample projects. If this happens, add a new reference to iAnywhere.Data.AsaClient.dll.

For instructions on adding a reference to the DLL, see Adding a reference to the data provider DLL in your project.


Using the Adaptive Server Anywhere .NET Data Provider Sample Applications

About this chapter

This chapter explains how to use the Simple and Table Viewer sample projects included with the Adaptive Server Anywhere .NET data provider.

If your SQL Anywhere installation directory is not the default (C:\Program Files\Sybase\SQL Anywhere 9), you may receive an error referencing the data provider DLL when you load the sample projects. If this happens, add a new reference to iAnywhere.Data.AsaClient.dll.

For instructions on adding a reference to the DLL, see Adding a reference to the data provider DLL in your project.


Tutorial: Using the Simple code sample

This tutorial is based on the Simple project that is included with the .NET data provider.

The complete application can be found in your SQL Anywhere installation directory at Samples\ASA\ADO.NET\SimpleWin32\Simple.csproj.

The Simple project illustrates the following features:

  • connecting to a database

  • executing a query using the AsaCommand object

  • using the AsaDataReader object

  • basic error handling

For more information about how the sample works, see Understanding the Simple sample project.

toggle To run the Simple code sample in Visual Studio .NET

  1. Start Visual Studio .NET.

  2. Choose File > Open > Project.

  3. Browse to Samples\ASA\ADO.NET\SimpleWin32 in your SQL Anywhere installation directory and open the Simple.csproj project.

  4. When you use the Adaptive Server Anywhere .NET data provider in a project, you must add a reference to the data provider DLL. This has already been done in the Simple code sample. You can view the reference to the data provider DLL in the following location:

    • In the Solution Explorer window, open the References folder.

    • You should see iAnywhere.Data.AsaClient in the list.

      For instructions about adding a reference to the data provider DLL, see Adding a reference to the data provider DLL in your project.

  5. You must also add a using directive to your source code to reference the data provider classes. This has already been done in the Simple code sample. To view the using directive:

    • Open the source code for the project.

      • In the Solution Explorer window, select Form1.cs.

      • Choose View > Code.

    • In the using directives in the top section, you should see the following line:

      using iAnywhere.Data.AsaClient;

      This line is required for C# projects. If you are using Visual Basic .NET, you need to add a different line to your source code.

      For more information, see Referencing the data provider classes in your source code.

  6. To run the Simple sample, choose Debug > Start Without Debugging or press Ctrl+F5.

    The AsaSample dialog appears.

    • In the AsaSample dialog, click Connect.

      The application connects to the Adaptive Server Anywhere sample database and puts the last name of each employee in the dialog, as follows:

      Screen shot showing simple window containing a list of employee names and a Connect button

  7. Click the X in the upper right corner of the screen to terminate the application and disconnect from the sample database. This also shuts down the database server.

You have now run the application. The next section describes the application code.

Understanding the Simple sample project


Understanding the Simple sample project

This section illustrates some key features of the Adaptive Server Anywhere .NET data provider by walking through some of the code from the Simple code sample. The Simple code sample uses the Adaptive Server Anywhere sample database, asademo.db, which is held in your SQL Anywhere installation directory.

For information about the sample database, including the tables in the database and the relationships between them, see About the sample database.

In this section, the code is described a few lines at a time. Not all code from the sample is included here. To see the whole code, open the sample project at Samples\ASA\ADO.NET\SimpleWin32\Simple.csproj.

Declaring controls The following code declares a button named btnConnect and a ListBox named listEmployees.

private System.Windows.Forms.Button btnConnect;
private System.Windows.Forms.ListBox listEmployees;

Connecting to the database The btnConnect_Click method declares and initializes a connection object (new AsaConnection).

private void btnConnect_Click(object sender,
   System.EventArgs e)
   AsaConnection conn = new AsaConnection(
    "Data Source=ASA 9.0 Sample;UID=DBA;PWD=SQL" );

The AsaConnection object uses the connection string to connect to the sample database.

conn.Open();

For more information about the AsaConnection object, see AsaConnection class.

Executing a query The following code uses the Command object (AsaCommand) to define and execute a SQL statement (SELECT emp_lname FROM employee). Then, it returns the DataReader object (AsaDataReader).

AsaCommand cmd = new AsaCommand(
     "select emp_lname from employee", conn );
AsaDataReader reader = cmd.ExecuteReader();

For more information about the Command object, see AsaCommand class.

Displaying the results The following code loops through the rows held in the AsaDataReader object and adds them to the ListBox control. The DataReader uses GetString( 0 ) to get the first value from the row.

Each time the Read method is called, the DataReader gets another row back from the result set. A new item is added to the ListBox for each row that is read.

listEmployees.BeginUpdate();
while( reader.Read() ) {
     listEmployees.Items.Add( reader.GetString( 0 ) );
}
listEmployees.EndUpdate();

For more information about the AsaDataReader object, see AsaDataReader class.

Finishing off The following code at the end of the method closes the reader and connection objects.

reader.Close();
conn.Close();

Error handling Any errors that occur during execution and that originate with Adaptive Server Anywhere .NET data provider objects are handled by displaying them in a message box. The following code catches the error and displays its message:

catch( AsaException ex ) {
    MessageBox.Show( ex.Errors[0].Message );
}

For more information about the AsaException object, see AsaException class.


Tutorial: Using the Table Viewer code sample

This tutorial is based on the Table Viewer project that is included with the Adaptive Server Anywhere .NET data provider.

The complete application can be found in your SQL Anywhere installation directory at Samples\ASA\ado.net\TableViewer\TableViewer.csproj.

The Table Viewer project is more complex than the Simple project. It illustrates the following features:

  • connecting to a database

  • working with the AsaDataAdapter object

  • more advanced error handling and result checking

For more information about how the sample works, see Understanding the Table Viewer sample project.

toggle To run the Table Viewer code sample in Visual Studio .NET

  1. Start Visual Studio .NET.

  2. Choose File > Open > Project.

  3. Browse to SamplesASA\ado.net\TableViewer in your SQL Anywhere installation directory and open the TableViewer.csproj project.

  4. If you want to use the Adaptive Server Anywhere .NET data provider in a project, you must add a reference to the data provider DLL. This has already been done in the Table Viewer code sample. You can view the reference to the data provider DLL in the following location:

    • In the Solution Explorer window, Open the References folder.

    • You should see iAnywhere.Data.AsaClient in the list.

      For instructions about adding a reference to the data provider DLL, see Adding a reference to the data provider DLL in your project.

  5. You must also add a using directive to your source code to reference the data provider classes. This has already been done in the Table Viewer code sample. To view the using directive:

    • Open the source code for the project.

      • In the Solution Explorer window, select TableViewer.cs.

      • Choose View > Code.

    • In the using directives in the top section, you should see the following line:

      using iAnywhere.Data.AsaClient;

      This line is required for C# projects. If you are using Visual Basic .NET, you need to add an Imports line to your source code.

      For more information, see Referencing the data provider classes in your source code.

  6. Choose Debug > Start Without Debugging to run the Table Viewer project.

    The Table Viewer dialog appears.

    • In the Table Viewer dialog, click Connect.

      The application connects to the Adaptive Server Anywhere sample database.

    • In the Table Viewer dialog, click Execute.

      The application retrieves the data from the employee table in the sample database and puts the query results in the Results DataList, as follows:

      Screen shot of table viewer with the Employee table of the sample database selected

      If you attempt to execute the query without first connecting to a database, a message appears instructing you to connect to a database.

    • You can also execute other SQL statements from this application: enter a SQL statement in the SQL Statement pane and then click Execute.

  7. Click the X in the upper right corner of the screen to terminate the application and disconnect from the sample database. This also shuts down the database server.

You have now run the application. The next section describes the application code.

Understanding the Table Viewer sample project


Understanding the Table Viewer sample project

This section illustrates some key features of the Adaptive Server Anywhere .NET data provider by walking through some of the code from the Table Viewer code sample. The Table Viewer project uses the Adaptive Server Anywhere sample database, asademo.db, which is held in your SQL Anywhere installation directory.

For information about the sample database, including the tables in the database and the relationships between them, see About the sample database.

In this section the code is described a few lines at a time. Not all code from the sample is included here. To see the whole code, open the sample project at Samples\ASA\ado.net\Tableviewer\TableViewer.csproj.

Declaring controls The following code declares a TextBox labeled Connection String, a button named btnConnect, a TextBox labeled txtSQLStatement, a button named btnExecute, and a DataGrid labeled dgResults.

Private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox txtConnectString;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button btnConnect;
private System.Windows.Forms.TextBox txtSQLStatement;
private System.Windows.Forms.Button btnExecute;
private System.Windows.Forms.DataGrid dgResults;

Declaring a global variable The AsaConnection function is used to declare a global variable. This connection is used for the initial connection to the database, as well as when you click Execute to retrieve the result set from the database.

private AsaConnection    _conn;

For more information about the AsaConnection function, see AsaConnection constructors.

Connecting to the database The following code provides a default value for the connection string that appears in the Connection String field by default.

this.txtConnectString.Text =
  "Data Source=ASA 9.0 Sample";

The Connection object later uses the connection string ("Data Source=ASA 9.0 Sample") to connect to the sample database.

_conn = new AsaConnection( txtConnectString.Text );
_conn.Open();

For more information about the Connection object, see AsaConnection class.

Defining a query The following code defines the default query that appears in the SQL Statement field.

this.txtSQLStatement.Text = "SELECT * FROM employee";

Displaying the results Before the results are fetched, the application checks whether the Connection object has been initialized. If it has, it ensures that the connection state is open.

if( _conn == null || _conn.State !=
  ConnectionState.Open ) {
  MessageBox.Show( "Connect to a database first",
   "Not connected" );
  return;

Once you are connected to the database, the following code creates a new DataSet and uses the DataAdapter object (AsaDataAdapter) to execute a SQL statement (SELECT * FROM employee), and fill the DataSet. The last two lines bind the DataSet to the grid on the screen.

DataSet ds =new DataSet ();
AsaDataAdapter da=new AsaDataAdapter(
     txtSQLStatement.Text, _conn);
da.Fill(ds, "Results")
dgResults.DataSource = ds.Tables["Results"];

Because a global variable is used to declare the connection, the connection that was opened earlier is reused to execute the SQL statement.

For more information about the DataAdapter object, see AsaDataAdapter class.

Error handling If there is an error when the application attempts to connect to the database, the following code catches the error and displays its message:

try {
    _conn = new AsaConnection( txtConnectString.Text );
    _conn.Open();
  } catch( AsaException ex ) {
    MessageBox.Show( ex.Errors[0].Source + " : "
     + ex.Errors[0].Message + " (" +
     ex.Errors[0].NativeError.ToString() + ")",
         "Failed to connect" );
}


Developing Applications with the .NET Data Provider

About this chapter

This chapter describes how to develop and deploy applications with the Adaptive Server Anywhere .NET data provider.

Using the .NET provider in a Visual Studio .NET project
Connecting to a database
Accessing and manipulating data
Using stored procedures
Transaction processing
Error handling and the Adaptive Server Anywhere .NET data provider
Deploying the Adaptive Server Anywhere .NET data provider


Using the .NET provider in a Visual Studio .NET project

Once you have installed the Adaptive Server Anywhere .NET data provider, you must make two changes to your Visual Studio .NET project to be able to use it:

  • add a reference to the Adaptive Server Anywhere .NET data provider DLL

  • add a line to your source code to reference the Adaptive Server Anywhere .NET data provider classes

For information about installing and registering the Adaptive Server Anywhere .NET data provider, see Deploying the Adaptive Server Anywhere .NET data provider.

Adding a reference to the data provider DLL in your project

Adding a reference tells Visual Studio .NET which DLL to include to find the code for the Adaptive Server Anywhere .NET data provider.

toggle To add a reference to the Adaptive Server Anywhere .NET data provider in a Visual Studio .NET project

  1. Start Visual Studio .NET and open your project.

  2. In the Solution Explorer window, right-click the References folder and choose Add Reference from the popup menu.

    The Add Reference dialog appears.

  3. On the .NET tab, click Browse to locate iAnywhere.Data.AsaClient.dll. (The default location is \Program Files\Sybase\SQL Anywhere 9\win32). Select the DLL and click Open.

    Note that there is a separate version of the DLL for each of Windows and Windows CE.

    For a complete list of installed DLLs, see Adaptive Server Anywhere .NET data provider required files.

  4. You can verify that the DLL is added to your project. Open the Add Reference dialog and then click the .NET tab. iAnywhere.Data.AsaClient.dll appears in the Selected Components list. Click OK to close the dialog.

    The DLL is added to the References folder in the Solution Explorer window of your project.

Referencing the data provider classes in your source code

In order to use the Adaptive Server Anywhere .NET data provider, you must also add a line to your source code to reference the data provider. You must add a different line for C# than for Visual Basic .NET.

toggle To reference the data provider classes in your code

  1. Start Visual Studio .NET and open your project.

  2. If you are using C#, add the following line to the list of using directives at the beginning of your project:

    using iAnywhere.Data.AsaClient;

  3. If you are using Visual Basic .NET, add the following line at the beginning of your project before the line Public Class Form1:

    Imports iAnywhere.Data.AsaClient

    This line is not strictly required. However, it allows you to use short forms for the Adaptive Server Anywhere classes. Without it, you can still use

    iAnywhere.Data.AsaClient.AsaConnection
 conn = new iAnywhere.Data.AsaClient.AsaConnection()

    instead of

    AsaConnection   conn = new AsaConnection()

    in your code.


Connecting to a database

Before you can carry out any operations on the data, your application must connect to the database. This section describes how to write code to connect to an Adaptive Server Anywhere database.

For more information, see AsaConnection class and ConnectionString property.

toggle To connect to an Adaptive Server Anywhere database

  1. Allocate an AsaConnection object.

    The following code creates an AsaConnection object named conn:

    AsaConnection conn = new AsaConnection(

    You can have more than one connection to a database from your application. Some applications use a single connection to an Adaptive Server Anywhere database, and keep the connection open all the time. To do this, you can declare a global variable for the connection:

    private AsaConnection      _conn;

    For more information, see the sample code in Samples\ASA\ado.net\TableViewer\TableViewer.csproj and Understanding the Table Viewer sample project.

  2. Specify the connection string used to connect to the database.

    For example:

    "Data Source=ASA 9.0 Sample;UID=DBA;PWD=SQL" );

    For a complete list of connection parameters, see Connection parameters.

    Instead of supplying a connection string, you could prompt users for their user ID and password if you wish.

  3. Open a connection to the database.

    The following code attempts to connect to a database. It autostarts the database server if necessary.

    conn.Open();

  4. Catch connection errors.

    Your application should be designed to catch any errors that occur when attempting to connect to the database. The following code demonstrates how to catch an error and display its message:

    try {
    _conn = new AsaConnection( txtConnectString.Text );
    _conn.Open();
  } catch( AsaException ex ) {
    MessageBox.Show( ex.Errors[0].Source + " : "
     + ex.Errors[0].Message + " (" +
     ex.Errors[0].NativeError.ToString() + ")",
         "Failed to connect" );

    Alternately, you can use the ConnectionString property to set the connection string, rather than passing the connection string when the AsaConnection object is created:

    AsaConnection   _conn;
    _conn = new AsaConnection();
    _conn.ConnectionString =
     "Data Source=ASA 9.0 Sample;UID=DBA;PWD=SQL";
    _conn.Open();

  5. Close the connection to the database. Connections to the database stay open until they are explicitly closed using the conn.Close() method.

Visual Basic .NET connection example

The following Visual Basic .NET code opens a connection to the Adaptive Server Anywhere sample database:

Private Sub Button1_Click(ByVal sender As _
    System.Object, ByVal e As System.EventArgs) _
    Handles Button1.Click
    ' Declare the connection object
    Dim myConn As New _
      iAnywhere.Data.AsaClient.AsaConnection()
    myConn.ConnectionString = _
      "Data Source=ASA 9.0 Sample;UID=DBA;PWD=SQL"
    myConn.Open()
    myConn.Close()
End Sub


Connection pooling

The Adaptive Server Anywhere .NET provider supports connection pooling. Connection pooling allows your application to reuse existing connections from a pool by saving the connection handle to a pool so it can be reused, rather than repeatedly creating a new connection to the database. Connection pooling is turned on by default.

The pool size is set in your connection string using the POOLING option. You can also specify the minimum and maximum pool sizes. For example,

"Data Source=ASA 9.0 Sample;UID=DBA;PWD=SQL;POOLING=TRUE;Max Pool Size=50;Min Pool Size=5"

When your application first attempts to connect to the database, it checks the pool for an existing connection that uses the same connection parameters you have specified. If a matching connection is found, that connection is used. Otherwise, a new connection is used. When you disconnect, the connection is returned to the pool so that it can be reused.

For more information about connection pooling, see ConnectionString property.


Checking the connection state

Once your application has established a connection to the database, you can check the connection state to ensure that the connection is open before you fetch data from the database to update it. If a connection is lost or is busy, or if another command is being processed, you can return an appropriate message to the user.

The AsaConnection class has a state property that checks the state of the connection. Possible state values are Open and Closed.

The following code checks whether the Connection object has been initialized, and if it has, it ensures that the connection is open. A message is returned to the user if the connection is not open.

if( _conn == null || _conn.State !=
  ConnectionState.Open ) {
  MessageBox.Show( "Connect to a database first",
   "Not connected" );
  return;

For more information, see State property.


Accessing and manipulating data

With the Adaptive Server Anywhere .NET data provider, there are two ways you can access data: using the AsaCommand object or using the AsaDataAdapter object.

  • AsaCommand object The AsaCommand object is the recommended way of accessing and manipulating data in .NET.

    The AsaCommand object allows you to execute SQL statements that retrieve or modify data directly from the database. Using the AsaCommand object, you can issue SQL statements and call stored procedures directly against the database.

    Within an AsaCommand object, the AsaDataReader is used to return read-only result sets from a query or stored procedure. The AsaDataReader returns only one row at a time, but this does not degrade performance because the Adaptive Server Anywhere client-side libraries use prefetch buffering to prefetch several rows at a time.

    Using the AsaCommand object allows you to group your changes into transactions rather than operating in autocommit mode. When you use the AsaTransaction object, locks are placed on the rows so that other users cannot modify them.

    For more information, see AsaCommand class and AsaDataReader class.

  • AsaDataAdapter object The AsaDataAdapter object retrieves the entire result set into a DataSet. A DataSet is a disconnected store for data that is retrieved from a database. You can then edit the data in the DataSet and when you are finished, the AsaDataAdapter object updates the database with the changes made to the DataSet. When you use the AsaDataAdapter, there is no way to prevent other users from modifying the rows in your DataSet. You need to include logic within your application to resolve any conflicts that may occur.

    For more information about conflicts, see Resolving conflicts when using the AsaDataAdapter.

    For more information about the AsaDataAdapter object, see AsaDataAdapter class.

There is no performance impact from using the AsaDataReader within an AsaCommand object to fetch rows from the database rather than the AsaDataAdapter object.

Using the AsaCommand object to retrieve and manipulate data
Using the AsaDataAdapter object to access and manipulate data
Obtaining primary key values
Handling BLOBs
Obtaining time values


Using the AsaCommand object to retrieve and manipulate data

The following sections describe how to retrieve data and how to insert, update, or delete rows using the AsaDataReader.


Getting data using the AsaCommand object

The AsaCommand object allows you to issue a SQL statement or call a stored procedure against an Adaptive Server Anywhere database. You can issue the following types of commands to retrieve data from the database:

  • ExecuteReader Used to issue a command that returns a result set. This method uses a forward-only, read-only cursor. You can loop quickly through the rows of the result set only in one direction.

    For more information, see ExecuteReader method.

  • ExecuteScalar Used to issue a command that returns a single value. This can be the first column in the first row of the result set, or a SQL statement that returns an aggregate value such as COUNT or AVG. This method uses a forward-only, read-only cursor.

    For more information, see ExecuteScalar method.

When using the AsaCommand object you can use the AsaDataReader to retrieve a result set that is based on a join. However, you can only make changes (inserts, updates, or deletes) to data that is from a single table. You cannot update result sets that are based on joins.

The following instructions use the Simple code sample included with the .NET data provider.

For more information about the Simple code sample, see Understanding the Simple sample project.

toggle To issue a command that returns a complete result set

  1. Declare and initialize a Connection object.

    AsaConnection conn = new AsaConnection(
    "Data Source=ASA 9.0 Sample;UID=DBA;PWD=SQL" );

  2. Open the connection.

    try {
    conn.Open();

  3. Add a Command object to define and execute a SQL statement.

    AsaCommand cmd = new AsaCommand(
     "select emp_lname from employee", conn );

    If you are calling a stored procedure, you must specify the parameters for the stored procedure.

    For more information, see Using stored procedures and AsaParameter class.

  4. Call the ExecuteReader method to return the DataReader object.

    AsaDataReader reader = cmd.ExecuteReader();

  5. Display the results.

    listEmployees.BeginUpdate();
while( reader.Read() ) {
     listEmployees.Items.Add( reader.GetString( 0 ) );
}
listEmployees.EndUpdate();

  6. Close the DataReader and Connection objects.

    reader.Close();
conn.Close();
toggle To issue a command that returns only one value

  1. Declare and initialize an AsaConnection object.

    AsaConnection conn = new AsaConnection(
    "Data Source=ASA 9.0 Sample" );

  2. Open the connection.

    conn.Open();

  3. Add an AsaCommand object to define and execute a SQL statement.

    AsaCommand cmd = new AsaCommand(
    "select count(*) from employee where sex = 'M'",
    conn );

    If you are calling a stored procedure, you must specify the parameters for the stored procedure.

    For more information, see Using stored procedures.

  4. Call the ExecuteScalar method to return the object containing the value.

    int count = (int) cmd.ExecuteScalar();

  5. Close the AsaConnection object.

    conn.Close();

When using the AsaDataReader, there are several Get methods available that you can use to return the results in desired the data type.

For more information, see AsaDataReader class.

Visual Basic .NET DataReader example

The following Visual Basic .NET code opens a connection to the Adaptive Server Anywhere sample database and uses the DataReader to return the last name of the first five employees in the result set:

Dim myConn As New .AsaConnection()
Dim myCmd As _
  New .AsaCommand _
  ("select emp_lname from employee", myConn)
Dim myReader As AsaDataReader
Dim counter As Integer
myConn.ConnectionString = _
  "Data Source=ASA 9.0 Sample;UID=DBA;PWD=SQL"
myConn.Open()
myReader = myCmd.ExecuteReader()
counter = 0
Do While (myReader.Read())
  MsgBox(myReader.GetString(0))
  counter = counter + 1
  If counter >= 5 Then Exit Do
Loop
myConn.Close()


Inserting, updating, and deleting rows using the AsaCommand object

In order to perform an insert, update, or delete with the AsaCommand object, you use the ExecuteNonQuery function. The ExecuteNonQuery function issues a command (SQL statement or stored procedure) that does not return a result set.

For more information, see ExecuteNonQuery method.

You can only make changes (inserts, updates, or deletes) to data that is from a single table. You cannot update result sets that are based on joins. You must be connected to a database to use the AsaCommand object.

For information about obtaining primary key values for autoincrement primary keys, see Obtaining primary key values.

If you want to set the isolation level for a command, you must use the AsaCommand object as part of an AsaTransaction object. When you modify data without an AsaTransaction object, the .NET provider operates in autocommit mode and any changes that you make are applied immediately.

For more information, see Transaction processing.

toggle To issue a command that inserts a row

  1. Declare and initialize an AsaConnection object.

    AsaConnection   conn = new AsaConnection(
    c_connStr );

  2. Open the connection.

    conn.Open();

  3. Add an AsaCommand object to define and execute an INSERT statement.

    You can use an INSERT, UPDATE, or DELETE statement with the ExecuteNonQuery method.

    AsaCommand      insertCmd = new AsaCommand(
    "INSERT INTO department( dept_id, dept_name )
    VALUES( ?, ? )", conn );

    If you are calling a stored procedure, you must specify the parameters for the stored procedure.

    For more information, see Using stored procedures and AsaParameter class.

  4. Set the parameters for the AsaCommand object.

    The following code defines parameters for the dept_id and dept_name columns respectively.

    AsaParameter parm = new AsaParameter();
parm.AsaDbType = AsaDbType.Integer;
insertCmd.Parameters.Add( parm );
parm = new AsaParameter();
parm.AsaDbType = AsaDbType.Char;
insertCmd.Parameters.Add( parm );

  5. Insert the new values and call the ExecuteNonQuery method to apply the changes to the database.

    insertCmd.Parameters[0].Value = 600;
insertCmd.Parameters[1].Value = "Eastern Sales";
int recordsAffected = insertCmd.ExecuteNonQuery();
insertCmd.Parameters[0].Value = 700;
insertCmd.Parameters[1].Value = "Western Sales";
int recordsAffected = insertCmd.ExecuteNonQuery();

  6. Display the results and bind them to the grid on the screen.

    AsaCommand      selectCmd = new AsaCommand(
    "SELECT * FROM department", conn );
AsaDataReader   dr = selectCmd.ExecuteReader();
dataGrid.DataSource = dr;

  7. Close the AsaDataReader and AsaConnection objects.

    dr.Close();
conn.Close();
toggle To issue a command that updates a row

  1. Declare and initialize an AsaConnection object.

    AsaConnection   conn = new AsaConnection(
    c_connStr );

  2. Open the connection.

    conn.Open();

  3. Add an AsaCommand object to define and execute an UPDATE statement.

    You can use an INSERT, UPDATE, or DELETE statement with the ExecuteNonQuery method.

    AsaCommand      updateCmd = new AsaCommand(
    "UPDATE department SET dept_name = 'Engineering'
    WHERE dept_id=100", conn );

    If you are calling a stored procedure, you must specify the parameters for the stored procedure.

    For more information, see Using stored procedures and AsaParameter class.

  4. Call the ExecuteNonQuery method to apply the changes to the database.

    int recordsAffected = updateCmd.ExecuteNonQuery();

  5. Display the results and bind them to the grid on the screen.

    AsaCommand      selectCmd = new AsaCommand(
    "SELECT * FROM department", conn );
AsaDataReader   dr = selectCmd.ExecuteReader();
dataGrid.DataSource = dr;

  6. Close the AsaDataReader and AsaConnection objects.

    dr.Close();
conn.Close();
toggle To issue a command that deletes a row

  1. Declare and initialize an AsaConnection object.

    AsaConnection   conn = new AsaConnection(
    c_connStr );

  2. Open the connection.

    conn.Open();

  3. Create an AsaCommand object to define and execute a DELETE statement.

    You can use an INSERT, UPDATE, or DELETE statement with the ExecuteNonQuery method.

    AsaCommand      deleteCmd = new AsaCommand(
    "DELETE FROM department WHERE ( dept_id > 500 )", conn );

    If you are calling a stored procedure, you must specify the parameters for the stored procedure.

    For more information, see Using stored procedures and AsaParameter class.

  4. Call the ExecuteNonQuery method to apply the changes to the database.

    int recordsAffected = deleteCmd.ExecuteNonQuery();

  5. Close the AsaConnection object.

    conn.Close();


Obtaining DataReader schema information

You can obtain schema information about columns in the result set.

If you are using the AsaDataReader, you can use the GetSchemaTable method to obtain information about the result set. The GetSchemaTable method returns the standard .NET DataTable object, which provides information about all the columns in the result set, including column properties.

For more information about the GetSchemaTable method, see GetSchemaTable method.

toggle To obtain information about a result set using the GetSchemaTable method

  1. Declare and initialize a connection object.

    AsaConnection conn = new AsaConnection(
    c_connStr );

  2. Open the connection.

    conn.Open();

  3. Create an AsaCommand object with the SELECT statement you want to use. The schema is returned for the result set of this query.

    AsaCommand cmd = new AsaCommand(
    "SELECT * FROM employee", conn );

  4. Create an AsaDataReader object and execute the Command object you created.

    AsaDataReader   dr = cmd.ExecuteReader();

  5. Fill the DataTable with the schema from the data source.

    DataTable       schema = dr.GetSchemaTable();

  6. Close the AsaDataReader and AsaConnection objects.

    dr.Close();
conn.Close();

  7. Bind the DataTable to the grid on the screen.

    dataGrid.DataSource = schema;


Using the AsaDataAdapter object to access and manipulate data

The following sections describe how to retrieve data and how to insert, update, or delete rows using the AsaDataAdapter.

Getting data using the AsaDataAdapter object
Inserting, updating, and deleting rows using the AsaDataAdapter object
Obtaining AsaDataAdapter schema information


Getting data using the AsaDataAdapter object

The AsaDataAdapter allows you to view the entire result set by using the Fill method to fill a DataSet with the results from a query by binding the DataSet to the display grid.

Using the AsaDataAdapter, you can pass any string (SQL statement or stored procedure) that returns a result set. When you use the AsaDataAdapter, all the rows are fetched in one operation using a forward-only, read-only cursor. Once all the rows in the result set have been read, the cursor is closed. The AsaDataAdapter allows you to make changes to the DataSet. Once your changes are complete, you must reconnect to the database to apply the changes.

You can use the AsaDataAdapter object to retrieve a result set that is based on a join. However, you can only make changes (inserts, updates, or deletes) to data that is from a single table. You cannot update result sets that are based on joins.

Caution
Any changes you make to the DataSet are made while you are disconnected. This means that your application does not have locks on these rows in the database. Your application must be designed to resolve any conflicts that may occur when changes from the DataSet are applied to the database in the event that another user changes the data you are modifying before your changes are applied to the database.

For more information about the AsaDataAdapter, see AsaDataAdapter class.

AsaDataAdapter example

The following example shows how to fill a DataSet using the AsaDataAdapter.

toggle To retrieve data using the AsaDataAdapter object

  1. Connect to the database.

  2. Create a new DataSet. In this case, the DataSet is called Results.

    DataSet ds =new DataSet ();

  3. Create a new AsaDataAdapter object to execute a SQL statement and fill the DataSet.

    AsaDataAdapter da=new AsaDataAdapter(
     txtSQLStatement.Text, _conn);
da.Fill(ds, "Results")

  4. Bind the DataSet to the grid on the screen.

    dgResults.DataSource = ds.Tables["Results"]


Inserting, updating, and deleting rows using the AsaDataAdapter object

The AsaDataAdapter retrieves the result set into a DataSet. A DataSet is a collection of tables and the relationships and constraints between those tables. The DataSet is built into the .NET Framework, and is independent of the data provider used to connect to your database.

When you use the AsaDataAdapter, you must be connected to the database to fill the DataSet and to update the database with changes made to the DataSet. However, once the DataSet is filled, you can modify the DataSet while disconnected from the database.

If you do not want to apply your changes to the database right away, you can write the DataSet, including the data and/or the schema, to an XML file using the WriteXML method. Then, you apply the changes at a later time by loading a DataSet with the ReadXML method.

For more information, see the .NET Framework documentation for WriteXML and ReadXML.

When you call the Update method to apply changes from the DataSet to the database, the AsaDataAdapter analyzes the changes that have been made and then invokes the appropriate commands, INSERT, UPDATE, or DELETE, as necessary. When you use the DataSet, you can only make changes (inserts, updates, or deletes) to data that is from a single table. You cannot update result sets that are based on joins. If another user has a lock on the row you are trying to update, an exception is thrown.

Caution
Any changes you make to the DataSet are made while you are disconnected. This means that your application does not have locks on these rows in the database. Your application must be designed to resolve any conflicts that may occur when changes from the DataSet are applied to the database in the event that another user changes the data you are modifying before your changes are applied to the database.
Resolving conflicts when using the AsaDataAdapter

When you use the AsaDataAdapter, no locks are placed on the rows in the database. This means there is the potential for conflicts to arise when you apply changes from the DataSet to the database. Your application should include logic to resolve or log conflicts that arise.

Some of the conflicts that your application logic should address include:

  • Unique primary keys If two users insert new rows into a table, each row must have a unique primary key. For tables with autoincrement primary keys, the values in the DataSet may become out of sync with the values in the data source.

    For information about obtaining primary key values for autoincrement primary keys, see Obtaining primary key values.

  • Updates made to the same value If two users modify the same value, your application should include logic to determine which value is correct.

  • Schema changes If a user modifies the schema of a table you have updated in the DataSet, the update will fail when you apply the changes to the database.

  • Data concurrency Concurrent applications should see a consistent set of data. The AsaDataAdapter does not place a lock on rows that it fetches, so another user can update a value in the database once you have retrieved the DataSet and are working offline.

Many of these potential problems can be avoided by using the AsaCommand, AsaDataReader, and AsaTransaction objects to apply changes to the database. The AsaTransaction object is recommended because it allows you to set the isolation level for the transaction and it places locks on the rows so that other users cannot modify them.

For more information about using transactions to apply your changes to the database, see Inserting, updating, and deleting rows using the AsaCommand object.

To simplify the process of conflict resolution, you can design your insert, update, or delete statement to be a stored procedure call. By including INSERT, UPDATE, and DELETE statements in stored procedures, you can catch the error if the operation fails. In addition to the statement, you can add error handling logic to the stored procedure so that if the operation fails the appropriate action is taken, such as recording the error to a log file, or trying the operation again.

toggle To insert rows into a table using the AsaDataAdapter

  1. Declare and initialize an AsaConnection object.

    AsaConnection   conn = new AsaConnection(
    c_connStr );

  2. Open the connection.

    conn.Open();

  3. Create a new AsaDataAdapter object.

    AsaDataAdapter adapter = new AsaDataAdapter();
adapter.MissingMappingAction =
    MissingMappingAction.Passthrough;
adapter.MissingSchemaAction =
    MissingSchemaAction.Add;

  4. Create the necessary AsaCommand objects and define any necessary parameters.

    The following code creates a SELECT and an INSERT command and defines the parameters for the INSERT command.

    adapter.SelectCommand = new AsaCommand(
    "SELECT * FROM department", conn );
adapter.InsertCommand = new AsaCommand(
    "INSERT INTO department( dept_id, dept_name )
    VALUES( ?, ? )", conn );
adapter.InsertCommand.UpdatedRowSource =
    UpdateRowSource.None;
AsaParameter parm = new AsaParameter();
parm.AsaDbType = AsaDbType.Integer;
parm.SourceColumn = "dept_id";
parm.SourceVersion = DataRowVersion.Current;
adapter.InsertCommand.Parameters.Add(
    parm );
parm = new AsaParameter();
parm.AsaDbType = AsaDbType.Char;
parm.SourceColumn = "dept_name";
parm.SourceVersion = DataRowVersion.Current;
adapter.InsertCommand.Parameters.Add( parm );

  5. Fill the DataTable with the results of the SELECT statement.

    DataTable dataTable = new DataTable( "department" );
int rowCount = adapter.Fill( dataTable );

  6. Insert the new rows into the DataTable and apply the changes to the database.

    DataRow row1 = dataTable.NewRow();
row1[0] = 600;
row1[1] = "Eastern Sales";
dataTable.Rows.Add( row1 );
DataRow row2 = dataTable.NewRow();
row2[0] = 700;
row2[1] = "Western Sales";
dataTable.Rows.Add( row2 );
recordsAffected = adapter.Update( dataTable );

  7. Display the results of the updates.

    dataTable.Clear();
rowCount = adapter.Fill( dataTable );
dataGrid.DataSource = dataTable;

  8. Close the connection.

    conn.Close();
toggle To update rows using the AsaDataAdapter object

  1. Declare and initialize an AsaConnection object.

    AsaConnection conn = new AsaConnection( c_connStr );

  2. Open the connection.

    conn.Open();

  3. Create a new AsaDataAdapter object.

    AsaDataAdapter adapter = new AsaDataAdapter();
adapter.MissingMappingAction =
    MissingMappingAction.Passthrough;
adapter.MissingSchemaAction =
    MissingSchemaAction.Add;

  4. Create an AsaCommand object and define its parameters.

    The following code creates a SELECT and an UPDATE command and defines the parameters for the UPDATE command.

    adapter.SelectCommand = new AsaCommand(
    "SELECT * FROM department WHERE dept_id > 500",
    conn );
adapter.UpdateCommand = new AsaCommand(
    "UPDATE department SET dept_name = ?
    WHERE dept_id = ?", conn );
adapter.UpdateCommand.UpdatedRowSource =
    UpdateRowSource.None;
AsaParameter parm = new AsaParameter();
parm.AsaDbType = AsaDbType.Char;
parm.SourceColumn = "dept_name";
parm.SourceVersion = DataRowVersion.Current;
adapter.UpdateCommand.Parameters.Add( parm );
parm = new AsaParameter();
parm.AsaDbType = AsaDbType.Integer;
parm.SourceColumn = "dept_id";
parm.SourceVersion = DataRowVersion.Original;
adapter.UpdateCommand.Parameters.Add( parm );

  5. Fill the DataTable with the results of the SELECT statement.

    DataTable dataTable = new DataTable( "department" );
int rowCount = adapter.Fill( dataTable );

  6. Update the DataTable with the updated values for the rows and apply the changes to the database.

    foreach ( DataRow row in dataTable.Rows )
{
row[1] = ( string ) row[1] + "_Updated";
}
recordsAffected = adapter.Update( dataTable );

  7. Bind the results to the grid on the screen.

    dataTable.Clear();
adapter.SelectCommand.CommandText =
    "SELECT * FROM department";
rowCount = adapter.Fill( dataTable );
dataGrid.DataSource = dataTable;

  8. Close the connection.

    conn.Close();
toggle To delete rows from a table using the AsaDataAdapter object

  1. Declare and initialize an AsaConnection object.

    AsaConnection conn = new AsaConnection( c_connStr );

  2. Open the connection.

    conn.Open();

  3. Create an AsaDataAdapter object.

    AsaDataAdapter adapter = new AsaDataAdapter();
adapter.MissingMappingAction =
    MissingMappingAction.Passthrough;
adapter.MissingSchemaAction =
    MissingSchemaAction.AddWithKey;

  4. Create the required AsaCommand objects and define any necessary parameters.

    The following code creates a SELECT and a DELETE command and defines the parameters for the DELETE command.

    adapter.SelectCommand = new AsaCommand(
    "SELECT * FROM department WHERE dept_id > 500",
    conn );
adapter.DeleteCommand = new AsaCommand(
    "DELETE FROM department WHERE dept_id = ?",
    conn );
adapter.DeleteCommand.UpdatedRowSource =
    UpdateRowSource.None;
AsaParameter parm = new AsaParameter();
parm.AsaDbType = AsaDbType.Integer;
parm.SourceColumn = "dept_id";
parm.SourceVersion = DataRowVersion.Original;
adapter.DeleteCommand.Parameters.Add( parm );

  5. Fill the DataTable with the results of the SELECT statement.

    DataTable dataTable = new DataTable( "department" );
int rowCount = adapter.Fill( dataTable );

  6. Modify the DataTable and apply the changes to the database.

    for each ( DataRow in dataTable.Rows )
{
    row.Delete();
}
recordsAffected = adapter.Update( dataTable )

  7. Bind the results to the grid on the screen.

    dataTable.Clear();
rowCount = adapter.Fill( dataTable );
dataGrid.DataSource = dataTable;

  8. Close the connection.

    conn.Close();


Obtaining AsaDataAdapter schema information

When using the AsaDataAdapter, you can use the FillSchema method to obtain schema information about the result set in the DataSet. The FillSchema method returns the standard .NET DataTable object, which provides the names of all the columns in the result set.

For more information about the FillSchema method, see FillSchema method.

toggle To obtain DataSet schema information using the FillSchema method

  1. Declare and initialize an AsaConnection object.

    AsaConnection   conn = new AsaConnection(
    c_connStr );

  2. Open the connection.

    conn.Open();

  3. Create an AsaDataAdapter with the SELECT statement you want to use. The schema is returned for the result set of this query.

    AsaDataAdapter  adapter = new AsaDataAdapter(
    "SELECT * FROM employee", conn );

  4. Create a new DataTable object, in this case called Table, to fill with the schema.

    DataTable       dataTable = new DataTable(
    "Table" );

  5. Fill the DataTable with the schema from the data source.

    adapter.FillSchema( dataTable, SchemaType.Source );

  6. Close the AsaConnection object.

    conn.Close();

  7. Bind the DataSet to the grid on the screen.

    dataGrid.DataSource = dataTable;


Obtaining primary key values

If the table you are updating has an autoincremented primary key, uses UUIDs, or if the primary key comes from a primary key pool, you can use a stored procedure to obtain values generated by the data source.

When using the AsaDataAdapter, this technique can be used to fill the columns in the DataSet with the primary key values generated by the data source. If you want to use this technique with the AsaCommand object, you can either get the key columns from the parameters or reopen the DataReader.

Examples

The following examples use a table called adodotnet_primarykey that contains two columns, id and name. The primary key for the table is id. It is an INTEGER and contains an autoincremented value. The name column is CHAR(40).

These examples call the following stored procedure to retrieve the autoincremented primary key value from the database.

CREATE PROCEDURE sp_adodotnet_primarykey( out p_id int, in p_name char(40) )
BEGIN
    INSERT INTO adodotnet_primarykey( name ) VALUES(
      p_name );
    SELECT @@IDENTITY INTO p_id;
END
toggle To insert a new row with an autoincremented primary key using the AsaCommand object

  1. Connect to the database.

    AsaConnection   conn = OpenConnection();

  2. Create a new AsaCommand object to insert new rows into the DataTable. In the following code, the line int id1 = ( int ) parmId.Value; verifies the primary key value of the row.

    AsaCommand      cmd = conn.CreateCommand();
cmd.CommandText = "sp_adodotnet_primarykey";
cmd.CommandType = CommandType.StoredProcedure;
AsaParameter parmId = new AsaParameter();
parmId.AsaDbType = AsaDbType.Integer;
parmId.Direction = ParameterDirection.Output;
cmd.Parameters.Add( parmId );
AsaParameter parmName = new AsaParameter();
parmName.AsaDbType = AsaDbType.Char;
parmName.Direction = ParameterDirection.Input;
cmd.Parameters.Add( parmName );
parmName.Value = "R & D --- Command";
cmd.ExecuteNonQuery();
int id1 = ( int ) parmId.Value;
parmName.Value = "Marketing --- Command";
cmd.ExecuteNonQuery();
int id2 = ( int ) parmId.Value;
parmName.Value = "Sales --- Command";
cmd.ExecuteNonQuery();
int id3 = ( int ) parmId.Value;
parmName.Value = "Shipping --- Command";
cmd.ExecuteNonQuery();
int id4 = ( int ) parmId.Value;

  3. Bind the results to the grid on the screen and apply the changes to the database.

    cmd.CommandText = "select * from " +
    adodotnet_primarykey";
cmd.CommandType = CommandType.Text;
AsaDataReader dr = cmd.ExecuteReader();
dataGrid.DataSource = dr;

  4. Close the connection.

    conn.Close();
toggle To insert a new row with an autoincremented primary key using the AsaDataAdapter object

  1. Create a new AsaDataAdapter.

    DataSet         dataSet = new DataSet();
AsaConnection   conn = OpenConnection();
AsaDataAdapter  adapter = new AsaDataAdapter();
adapter.MissingMappingAction =
    MissingMappingAction.Passthrough;
adapter.MissingSchemaAction =
    MissingSchemaAction.AddWithKey;

  2. Fill the data and schema of the DataSet. The SelectCommand is called by the AsaDataAdapter.Fill method to do this. You can also create the DataSet manually without using the Fill method and SelectCommand if you do not need the existing records.

    adapter.SelectCommand = new AsaCommand( "select * from  + adodotnet_primarykey", conn );

  3. Create a new AsaCommand to obtain the primary key values from the database.

    adapter.InsertCommand = new AsaCommand(
    "sp_adodotnet_primarykey", conn );
adapter.InsertCommand.CommandType =
    CommandType.StoredProcedure;
adapter.InsertCommand.UpdatedRowSource =
    UpdateRowSource.OutputParameters;
AsaParameter parmId = new AsaParameter();
parmId.AsaDbType = AsaDbType.Integer;
parmId.Direction = ParameterDirection.Output;
parmId.SourceColumn = "id";
parmId.SourceVersion = DataRowVersion.Current;
adapter.InsertCommand.Parameters.Add( parmId );
AsaParameter parmName = new AsaParameter();
parmName.AsaDbType = AsaDbType.Char;
parmName.Direction = ParameterDirection.Input;
parmName.SourceColumn = "name";
parmName.SourceVersion = DataRowVersion.Current;
adapter.InsertCommand.Parameters.Add( parmName );

  4. Fill the DataSet.

    adapter.Fill( dataSet );

  5. Insert the new rows into the DataSet.

    DataRow row = dataSet.Tables[0].NewRow();
row[0] = -1;
row[1] = "R & D --- Adapter";
dataSet.Tables[0].Rows.Add( row );
row = dataSet.Tables[0].NewRow();
row[0] = -2;
row[1] = "Marketing --- Adapter";
dataSet.Tables[0].Rows.Add( row );
row = dataSet.Tables[0].NewRow();
row[0] = -3;
row[1] = "Sales --- Adapter";
dataSet.Tables[0].Rows.Add( row );
row = dataSet.Tables[0].NewRow();
row[0] = -4;
row[1] = "Shipping --- Adapter";
dataSet.Tables[0].Rows.Add( row );

  6. Apply the changes in the DataSet to the database. When the Update() method is called, the primary key values are changed to the values obtained from the database.

    adapter.Update( dataSet );
dataGrid.DataSource = dataSet.Tables[0];

    When you add new rows to the DataTable and call the Update method, the AsaDataAdapter calls the InsertCommand and maps the output parameters to the key columns for each new row. The Update method is called only once, but the InsertCommand is called by the Update method as many times as necessary for each new row being added.

  7. Close the connection to the database.

    conn.Close();


Handling BLOBs

When fetching long string values or binary data, there are methods that you can use to fetch the data in pieces. For binary data, use the GetBytes method, and for string data, use the GetChars method. Otherwise, BLOB data is treated in the same manner as any other data you fetch from the database.

For more information, see GetBytes method and GetChars method.

toggle To issue a command that returns a string using the GetChars method

  1. Declare and initialize a Connection object.

  2. Open the connection.

  3. Add a Command object to define and execute a SQL statement.

    AsaCommand cmd = new AsaCommand(
    "select int_col, blob_col from test", conn );

  4. Call the ExecuteReader method to return the DataReader object.

    AsaDataReader reader = cmd.ExecuteReader();

    The following code reads the two columns from the result set. The first column is an integer (GetInt32( 0 )), while the second column is a LONG VARCHAR. GetChars is used to read 100 characters at a time from the LONG VARCHAR column.

    int length = 100;
char[] buf = new char[ length ];
int intValue;
long dataIndex = 0;
long charsRead = 0;
long blobLength = 0;
while( reader.Read() ) {
    intValue = reader.GetInt32( 0 );
    while ( ( charsRead = reader.GetChars(
        1, dataIndex, buf, 0, length ) ) == ( long )
            length ) {
    dataIndex += length;
}
blobLength = dataIndex + charsRead;
}

  5. Close the DataReader and Connection objects.

    reader.Close();
conn.Close();


Obtaining time values

The .NET Framework does not have a Time structure. If you want to fetch time values from Adaptive Server Anywhere, you must use the GetTimeSpan method. Using this method returns the data as a .NET Framework TimeSpan object.

For more information about the GetTimeSpan method, see GetTimeSpan method.

toggle To convert a time value using the GetTimeSpan method

  1. Declare and initialize a connection object.

    AsaConnection conn = new AsaConnection(
    "Data Source=dsn-time-test;uid=dba;pwd=sql" );

  2. Open the connection.

    conn.Open();

  3. Add a Command object to define and execute a SQL statement.

    AsaCommand cmd = new AsaCommand(
    "SELECT id, time_col FROM time_test", conn )

  4. Call the ExecuteReader method to return the DataReader object.

    AsaDataReader reader = cmd.ExecuteReader();

    The following code uses the GetTimeSpan method to return the time as TimeSpan.

    while ( reader.Read() )
{
    int id = reader.GetInt32();
    TimeSpan time = reader.GetTimeSpan();
}

  5. Close the DataReader and Connection objects.

    reader.Close();
conn.Close();


Using stored procedures

You can use stored procedures with the .NET data provider. The ExecuteReader method is used to call stored procedures that return a result set, while the ExecuteNonQuery method is used to call stored procedures that do not return a result set. The ExecuteScalar method is used to call stored procedures that return only a single value.

When you call a stored procedure, you must create an AsaParameter object. Use a question mark as a placeholder for parameters, as follows:

sp_producttype( ?, ? )

For more information about the Parameter object, see AsaParameter class.

toggle To execute a stored procedure

  1. Declare and initialize an AsaConnection object.

    AsaConnection conn = new AsaConnection(
    "Data Source=ASA 9.0 Sample" );

  2. Open the connection.

    conn.Open();

  3. Add an AsaCommand object to define and execute a SQL statement. The following code uses the CommandType property to identify the command as a stored procedure.

    AsaCommand cmd = new AsaCommand( "sp_product_info",
    conn );
cmd.CommandType = CommandType.StoredProcedure;

    If you do not specify the CommandType property, then you must use a question mark as a placeholder for parameters, as follows:

    AsaCommand cmd = new AsaCommand(
    "call sp_product_info(?)", conn );
cmd.CommandType = CommandType.Text;

  4. Add an AsaParameter object to define the parameters for the stored procedure. You must create a new AsaParameter object for each parameter the stored procedure requires.

    AsaParameter param = cmd.CreateParameter();
param.AsaDbType = AsaDbType.Int32;
param.Direction = ParameterDirection.Input;
param.Value = 301;
cmd.Parameters.Add( param );

    For more information about the Parameter object, see AsaParameter class.

  5. Call the ExecuteReader method to return the DataReader object. The Get methods are used to return the results in the desired data type.

    AsaDataReader reader = cmd.ExecuteReader();
reader.Read();
int id = reader.GetInt32(0);
string name = reader.GetString(1);
string descrip = reader.GetString(2);
decimal price = reader.GetDecimal(6);

  6. Close the AsaDataReader and AsaConnection objects.

    reader.Close();
conn.Close();
Alternative way to call a stored procedure

Step 3 in the above instructions presents two ways you can call a stored procedure. Another way you can call a stored procedure, without using a Parameter object, is to call the stored procedure from your source code, as follows:

AsaCommand cmd = new AsaCommand(
    "call sp_product_info( 301 )", conn );

For information about calling stored procedures that return a result set or a single value, see Getting data using the AsaCommand object.

For information about calling stored procedures that do not return a result set, see Inserting, updating, and deleting rows using the AsaCommand object.


Transaction processing

With the Adaptive Server Anywhere .NET provider, you can use the AsaTransaction object to group statements together. Each transaction ends with a COMMIT or ROLLBACK, which either makes your changes to the database permanent or cancels all the operations in the transaction. Once the transaction is complete, you must create a new AsaTransaction object to make further changes. This behavior is different from ODBC and embedded SQL, where a transaction persists after you execute a COMMIT or ROLLBACK until the transaction is closed.

If you do not create a transaction, the Adaptive Server Anywhere .NET provider operates in autocommit mode by default. There is an implicit COMMIT after each insert, update, or delete, and once an operation is completed, the change is made to the database. In this case, the changes cannot be rolled back.

For more information about the AsaTransaction object, see AsaTransaction class.

Setting the isolation level for transactions

The database isolation level is used by default for transactions. However, you may choose to specify the isolation level for a transaction using the IsolationLevel property when you begin the transaction. The isolation level applies to all commands executed within the transaction.

For more information about isolation levels, see Isolation levels and consistency.

The locks that Adaptive Server Anywhere uses when you enter a SELECT statement depend on the transaction's isolation level.

For more information about locking and isolation levels, see Locking during queries.

The following example uses an AsaTransaction object to issue and then roll back a SQL statement. The transaction uses isolation level 2 (RepeatableRead), which places a write lock on the row being modified so that no other database user can update the row.

toggle To use an AsaTransaction object to issue a command

  1. Declare and initialize an AsaConnection object.

    AsaConnection conn = new AsaConnection(
    "Data Source=ASA 9.0 Sample" );

  2. Open the connection.

    conn.Open();

  3. Issue a SQL statement to change the price of Tee shirts.

    string stmt = "update product set unit_price =
    2000.00 where name = 'Tee shirt'";

  4. Create an AsaTransaction object to issue the SQL statement using a Command object.

    Using a transaction allows you to specify the isolation level. Isolation level 2 (RepeatableRead ) is used in this example so that another database user cannot update the row.

    AsaTransaction trans = conn.BeginTransaction(
    IsolationLevel.RepeatableRead );
AsaCommand cmd = new AsaCommand( stmt, conn,
    trans );
int rows = cmd.ExecuteNonQuery();

  5. Roll back the changes.

    trans.Rollback();

    The AsaTransaction object allows you to commit or roll back your changes to the database. If you do not use a transaction, the .NET data provider operates in autocommit mode and you cannot roll back any changes that you make to the database. If you want to make the changes permanent, you would use the following:

    trans.Commit();

  6. Close the AsaConnection object.

    conn.Close();


Error handling and the Adaptive Server Anywhere .NET data provider

Your application must be designed to handle any errors that occur, including ADO.NET errors. ADO.NET errors are handled within your code in the same way that you handle other errors in your application.

The Adaptive Server Anywhere .NET data provider throws AsaException objects whenever errors occur during execution. Each AsaException object consists of a list of AsaError objects, and these error objects include the error message and code.

Errors are different from conflicts. Conflicts arise when changes are applied to the database. Your application should include a process to compute correct values or to log conflicts when they arise.

For more information about handling conflicts, see Resolving conflicts when using the AsaDataAdapter.

.NET provider error handling example

The following example is from the Simple sample project. Any errors that occur during execution and that originate with Adaptive Server Anywhere .NET data provider objects are handled by displaying them in a message box. The following code catches the error and displays its message:

catch( AsaException ex ) {
    MessageBox.Show( ex.Errors[0].Message );
}
Connection error handling example

The following example is from the Table Viewer sample project. If there is an error when the application attempts to connect to the database, the following code uses a try and catch block to catch the error and display its message:

try {
    _conn = new AsaConnection( txtConnectString.Text );
    _conn.Open();
  } catch( AsaException ex ) {
    MessageBox.Show( ex.Errors[0].Source + " : "
     + ex.Errors[0].Message + " (" +
     ex.Errors[0].NativeError.ToString() + ")",
         "Failed to connect" );

For more error handling examples, see Understanding the Simple sample project and Understanding the Table Viewer sample project.

For more information about error handling, see AsaException class and AsaError class.


Deploying the Adaptive Server Anywhere .NET data provider

The following sections describe how to deploy the Adaptive Server Anywhere .NET data provider.


Adaptive Server Anywhere .NET data provider system requirements

In order to use the Adaptive Server Anywhere .NET data provider, you must have the following installed on your machine or handheld device:

  • the .NET Framework and/or .NET Compact Framework

  • Visual Studio .NET 1.0, Visual Studio .NET 2003, or a .NET language compiler, such as C# (required only for development)


Adaptive Server Anywhere .NET data provider required files

The Adaptive Server Anywhere .NET data provider consists of two DLLs for each platform.

Windows required files

For Windows (except Windows CE) the following DLLs are required:

  • win32\iAnywhere.Data.AsaClient.dll

  • win32\dbdata9.dll

The first DLL (iAnywhere.Data.AsaClient.dll) is the main DLL that is referenced by Visual Studio projects. The second DLL (dbdata9.dll) contains utility code.

Windows CE required files

These files must be installed in your SQL Anywhere installation directory (the default location is C:\Program Files\Sybase\SQL Anywhere 9\win32) because they require the language DLLs that are also located in your SQL Anywhere installation directory.

For Windows CE, iAnywhere.Data.AsaClient.dll is the main DLL that is referenced by Visual Studio projects. There is a separate dbdata9.dll file for each of the supported Windows CE platforms. The Windows CE DLLs are:

  • ce\iAnywhere.Data.AsaClient.dll

  • ce\arm.30\dbdata9.dll

  • ce\emulator.30\dbdata9.dll

  • ce\mips.30\dbdata9.dll

  • ce\x86\dbdata9.dll

The utility DLL (dbdata9.dll) must be placed in the Windows directory on your device. Visual Studio .NET deploys the .NET data provider DLL (iAnywhere.Data.Asaclient.dll) to your device along with your program. If you are not using Visual Studio .NET, you need to copy the data provider DLL to the device along with your program. It can go in the same directory as your application, or in the Windows directory.

Registering the Adaptive Server Anywhere .NET data provider DLL


Registering the Adaptive Server Anywhere .NET data provider DLL

The Adaptive Server Anywhere .NET data provider DLL (win32\iAnywhere.Data.AsaClient.dll) needs to be registered in the Global Assembly Cache on Windows (except Windows CE). The Global Assembly Cache lists all the registered programs on your machine. When you install the .NET data provider, the .NET data provider installation program registers it. On Windows CE you do not need to register the DLL.

If you are deploying the .NET data provider, you must register the .NET data provider DLL (win32\iAnywhere.Data.AsaClient.dll) using the gacutil utility that is included with the .NET Framework.


Adaptive Server Anywhere .NET Data Provider API Reference

About this chapter

This chapter describes the API for the Adaptive Server Anywhere .NET data provider.

Note: Many of the properties and methods in this chapter are very similar to the OLE DB .NET data provider. You can find more information and examples in the Microsoft .NET Framework documentation.

AsaCommand class
AsaCommandBuilder class
AsaConnection class
AsaDataAdapter class
AsaDataReader class
AsaDbType enum
AsaError class
AsaErrorCollection class
AsaException class
AsaInfoMessageEventArgs class
AsaInfoMessageEventHandler delegate
AsaParameter class
AsaParameterCollection class
AsaPermission class
AsaPermissionAttribute class
AsaRowUpdatedEventArgs class
AsaRowUpdatingEventArgs class
AsaRowUpdatedEventHandler delegate
AsaRowUpdatingEventHandler delegate
AsaTransaction class


AsaCommand class

Description

A SQL statement or stored procedure that is executed against an Adaptive Server Anywhere database.

Base classes

Component

Implemented interfaces

IDbCommand, IDisposable

See also

Using the AsaCommand object to retrieve and manipulate data

Accessing and manipulating data

AsaCommand constructors
Cancel method
CommandText property
CommandTimeout property
CommandType property
Connection property
CreateParameter method
DesignTimeVisible property
ExecuteNonQuery method
ExecuteReader method
ExecuteScalar method
Parameters property
Prepare method
ResetCommandTimeout method
Transaction property
UpdatedRowSource property


AsaCommand constructors

Description

Initializes an AsaCommand object.

Syntax 1

void AsaCommand( )

Syntax 2

void AsaCommand( string cmdText )

Syntax 3

void AsaCommand(
string cmdText,
AsaConnection connection
)

Syntax 4

void AsaCommand(
string cmdText,
AsaConnection connection,
AsaTransaction transaction
)

Parameters

cmdText The text of the SQL statement or stored procedure. For parameterized statements, use a question mark (?) placeholder to pass parameters.

connection The current connection.

transaction The AsaTransaction in which the AsaConnection executes.


Cancel method

Description

Cancels the execution of an AsaCommand object.

Syntax

void Cancel( )

Usage

If there is nothing to cancel, nothing happens. If there is a command in process and the attempt to cancel fails, no exception is generated.

Implements

IDbCommand.Cancel


CommandText property

Description

The text of a SQL statement or stored procedure.

Syntax

string CommandText

Access

Read-write

Property value

The SQL statement or the name of the stored procedure to execute. The default is an empty string.

Implements

IDbCommand.CommandText

See also

AsaCommand constructors


CommandTimeout property

Description

The wait time in seconds before terminating an attempt to execute a command and generating an error.

Syntax

int CommandTimeout

Access

Read-write

Implements

IDbCommand.CommandTimeout

Default

30 seconds

Usage

A value of 0 indicates no limit. This should be avoided because it may cause the attempt to execute a command to wait indefinitely.


CommandType property

Description

The type of command represented by an AsaCommand.

Syntax

CommandType CommandType

Access

Read-write

Implements

IDbCommand.CommandType

Usage

Supported command types are as follows:

  • CommandType.StoredProcedure When you specify this CommandType, the command text must be the name of a stored procedure and you must supply any arguments as AsaParameter objects.

  • CommandType.Text This is the default value.

When the CommandType property is set to StoredProcedure, the CommandText property should be set to the name of the stored procedure. The command executes this stored procedure when you call one of the Execute methods.

Use a question mark (?) placeholder to pass parameters. For example:

SELECT * FROM Customers WHERE CustomerID = ?

The order in which AsaParameter objects are added to the AsaParameterCollection must directly correspond to the position of the question mark placeholder for the parameter.


Connection property

Description

The connection object to which the AsaCommand object applies.

Syntax

AsaConnection Connection

Access

Read-write

Default

The default value is a null reference. In Visual Basic it is Nothing.


CreateParameter method

Description

Provides an AsaParameter object for supplying parameters to AsaCommand objects.

Syntax

AsaParameter CreateParameter( )

Return value

A new parameter, as an AsaParameter object.

Usage

Stored procedures and some other SQL statements can take parameters, indicated in the text of a statement by a question mark (?).

The CreateParameter method provides an AsaParameter object. You can set properties on the AsaParameter to specify the value, data type, and so on for the parameter.

See also

AsaParameter class


DesignTimeVisible property

Description

A value that indicates if the AsaCommand should be visible in a customized Windows Form Designer control. The default is false.

Syntax

bool DesignTimeVisible

Access

Read-write


ExecuteNonQuery method

Description

Executes a statement that does not return a result set, such as an INSERT, UPDATE, DELETE, or a data definition statement.

Syntax

int ExecuteNonQuery( )

Return value

The number of rows affected.

Implements

IDbCommand.ExecuteNonQuery

Usage

You can use ExecuteNonQuery to change the data in a database without using a DataSet. Do this by executing UPDATE, INSERT, or DELETE statements.

Although ExecuteNonQuery does not return any rows, output parameters or return values that are mapped to parameters are populated with data.

For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command. For all other types of statements, and for rollbacks, the return value is -1.


ExecuteReader method

Description

Executes a SQL statement that returns a result set.

Syntax 1

AsaDataReader ExecuteReader( )

Syntax 2

AsaDataReader ExecuteReader( CommandBehavior behavior )

Parameters

behavior One of CloseConnection, Default, KeyInfo, SchemaOnly, SequentialAccess, SingleResult, or SingleRow.

For more information about this parameter, see the .NET Framework documentation for CommandBehavior Enumeration.

Return value

The result set as an AsaDataReader object.

Usage

The statement is the current AsaCommand object, with CommandText and Parameters as needed. The AsaDataReader object is a read-only, forward-only result set. For modifiable result sets, use an AsaDataAdapter.

See also

AsaDataReader class

AsaDataAdapter class


ExecuteScalar method

Description

Executes a statement that returns a single value. If this method is called on a query that returns multiple rows and columns, only the first column of the first row is returned.

Syntax

object ExecuteScalar( )

Return Value

The first column of the first row in the result set, or a null reference if the result set is empty.

Implements

IDbCommand.ExecuteScalar


Parameters property

Description

A collection of parameters for the current statement. Use question marks in the CommandText to indicate parameters.

Syntax

AsaParameterCollection Parameters

Access

Read-only

Property Value

The parameters of the SQL statement or stored procedure. The default value is an empty collection.

Usage

When CommandType is set to Text, pass parameters using the question mark placeholder. For example:

SELECT * FROM Customers WHERE CustomerID = ?

The order in which AsaParameter objects are added to the AsaParameterCollection must directly correspond to the position of the question mark placeholder for the parameter in the command text.

When the parameters in the collection do not match the requirements of the query to be executed, an error may result or an exception may be thrown.

See also

AsaParameterCollection class


Prepare method

Description

Prepares or compiles the AsaCommand on the data source.

Syntax

void Prepare( )

Implements

IDbCommand.Prepare

Usage

Before you call Prepare, specify the data type of each parameter in the statement to be prepared.

If you call an Execute method after calling Prepare, any parameter value that is larger than the value specified by the Size property is automatically truncated to the original specified size of the parameter, and no truncation errors are returned.

Output parameters (whether prepared or not) must have a user-specified data type.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaCommand class

ResetCommandTimeout method

Description

Resets the CommandTimeout property to its default value of 30 seconds.

Syntax

void ResetCommandTimeout( )


Transaction property

Description

Associates the current command with a transaction.

Syntax

AsaTransaction Transaction

Access

Read-write

Usage

The default value is a null reference. In Visual Basic this is Nothing.

You cannot set the Transaction property if it is already set to a specific value and the command is executing. If you set the transaction property to an AsaTransaction object that is not connected to the same AsaConnection as the AsaCommand object, an exception will be thrown the next time you attempt to execute a statement.

See also

AsaTransaction class

Transaction processing


UpdatedRowSource property

Description

How command results are applied to the DataRow when used by the Update method of the AsaDataAdapter.

Syntax

UpdateRowSource UpdatedRowSource

Access

Read-write

Implements

IDbCommand.UpdatedRowSource

Property value

One of the UpdatedRowSource values. If the command is automatically generated, the default is None. Otherwise, the default is Both.


AsaCommandBuilder class

Description

A way to generate single-table SQL statements that reconcile changes made to a DataSet with the data in the associated database.

Base classes

Component

Implemented interfaces

IDisposable

AsaCommandBuilder constructors
DataAdapter property
DeriveParameters method
GetDeleteCommand method
GetInsertCommand method
GetUpdateCommand method
QuotePrefix property
QuoteSuffix property
RefreshSchema method


AsaCommandBuilder constructors

Description

Initializes an AsaCommandBuilder object.

Syntax 1

void AsaCommandBuilder( )

Syntax 2

void AsaCommandBuilder( AsaDataAdapter adapter )

Parameters

adapter An AsaDataAdapter object for which to generate reconciliation statements.


DataAdapter property

Description

The AsaDataAdapter for which to generate statements.

Syntax

AsaDataAdapter DataAdapter

Access

Read-write

Property value

An AsaDataAdapter object.

Usage

When you create a new instance of AsaCommandBuilder, any existing AsaCommandBuilder that is associated with this AsaDataAdapter is released.


DeriveParameters method

Description

Populates the Parameters collection of the specified AsaCommand object. This is used for the stored procedure specified in the AsaCommand.

Syntax

void DeriveParameters( AsaCommand command )

Parameters

command An AsaCommand object for which to derive parameters.

Usage

DeriveParameters overwrites any existing parameter information for the AsaCommand.

DeriveParameters requires an extra call to the database server. If the parameter information is known in advance, it is more efficient to populate the Parameters collection by setting the information explicitly.


GetDeleteCommand method

Description

The generated AsaCommand object that performs DELETE operations on the database when AsaDataAdapter.Update() is called.

Syntax

AsaCommand GetDeleteCommand( )

Return value

The automatically generated AsaCommand object required to perform deletions.

Usage

The GetDeleteCommand method returns the AsaCommand object to be executed, so it may be useful for informational or troubleshooting purposes.

You can also use GetDeleteCommand as the basis of a modified command. For example, you might call GetDeleteCommand and modify the CommandTimeout value, and then explicitly set that value on the AsaDataAdapter.

SQL statements are first generated when the application calls Update or GetDeleteCommand. After the SQL statement is first generated, the application must explicitly call RefreshSchema if it changes the statement in any way. Otherwise, the GetDeleteCommand will still be using information from the previous statement.


GetInsertCommand method

Description

The generated AsaCommand object that performs INSERT operations on the database when an AsaDataAdapter.Update() is called.

Syntax

AsaCommand GetInsertCommand( )

Return value

The automatically generated AsaCommand object required to perform insertions.

Usage

The GetInsertCommand method returns the AsaCommand object to be executed, so it may be useful for informational or troubleshooting purposes.

You can also use GetInsertCommand as the basis of a modified command. For example, you might call GetInsertCommand and modify the CommandTimeout value, and then explicitly set that value on the AsaDataAdapter.

SQL statements are first generated either when the application calls Update or GetInsertCommand. After the SQL statement is first generated, the application must explicitly call RefreshSchema if it changes the statement in any way. Otherwise, the GetInsertCommand will be still be using information from the previous statement, which might not be correct.


GetUpdateCommand method

Description

The generated AsaCommand object that performs UPDATE operations on the database when an AsaDataAdapter.Update() is called.

Syntax

AsaCommand GetUpdateCommand( )

Return value

The automatically generated AsaCommand object required to perform updates.

Usage

The GetUpdateCommand method returns the AsaCommand object to be executed, so it may be useful for informational or troubleshooting purposes.

You can also use GetUpdateCommand as the basis of a modified command. For example, you might call GetUpdateCommand and modify the CommandTimeout value, and then explicitly set that value on the AsaDataAdapter.

SQL statements are first generated when the application calls Update or GetUpdateCommand. After the SQL statement is first generated, the application must explicitly call RefreshSchema if it changes the statement in any way. Otherwise, the GetUpdateCommand will be still be using information from the previous statement, which might not be correct.


QuotePrefix property

Description

The beginning character or characters to use when specifying database object names that contain characters such as spaces.

Syntax

string QuotePrefix

Access

Read-write

Property value

The beginning character or characters to use. This can be square brackets, or, if the Adaptive Server Anywhere QUOTED_IDENTIFIER option is set to off, it can be double quotes. The default is an empty string.

Usage

Adaptive Server Anywhere objects can contain characters such as spaces, commas, and semicolons. The QuotePrefix and QuoteSuffix properties specify delimiters to encapsulate the object name.

Although you cannot change the QuotePrefix or QuoteSuffix properties after an INSERT, UPDATE, or DELETE operation, you can change their settings after calling the Update method of a DataAdapter.

See also

Identifiers

QUOTED_IDENTIFIER option [compatibility]


QuoteSuffix property

Description

The ending character or characters to use when specifying database objects whose names contain characters such as spaces.

Syntax

string QuoteSuffix

Access

Read-write

Property value

The ending character or characters to use. This can be square brackets, or, if the Adaptive Server Anywhere QUOTED_IDENTIFIER option is set to off, it can be double quotes. The default is an empty string.

Usage

Adaptive Server Anywhere objects can contain characters such as spaces, commas, and semicolons. The QuotePrefix and QuoteSuffix properties specify delimiters to encapsulate the object name.

Although you cannot change the QuotePrefix or QuoteSuffix properties after an INSERT, UPDATE, or DELETE operation, you can change their settings after calling the Update method of a DataAdapter.

See also

Identifiers

QUOTED_IDENTIFIER option [compatibility]


RefreshSchema method

Description

Refreshes the database schema information used to generate INSERT, UPDATE, or DELETE statements.

Syntax

void RefreshSchema( )

Usage

Call RefreshSchema whenever the SelectCommand value of the associated AsaDataAdapter changes.


AsaConnection class

Description

Represents a connection to an Adaptive Server Anywhere database.

Base classes

Component

Implemented interfaces

IDbConnection, IDisposable

See also

Connecting to a database

AsaConnection constructors
BeginTransaction method
ChangeDatabase method
Close method
ConnectionString property
ConnectionTimeout property
CreateCommand method
Database property
DataSource property
InfoMessage event
Open method
ServerVersion property
State property
StateChange event


AsaConnection constructors

Description

Initializes an AsaConnection object. The connection must then be opened before you can carry out any operations against the database.

Syntax 1

void AsaConnection( )

Syntax 2

void AsaConnection( string connectionString )

Parameters

connectionString An Adaptive Server Anywhere connection string. A connection string is a semicolon-separated list of keyword-value pairs.

For a list of parameters, see Connection parameters.

Example

The following statement initializes an AsaConnection object for a connection to a database named policies running on an Adaptive Server Anywhere database server named hr. The connection uses a user ID of admin with a password of money.

AsaConnection conn = new AsaConnection(
"uid=admin;pwd=money;eng=hr;dbn=policies" );
conn.Open();


BeginTransaction method

Description

Returns a transaction object. Commands associated with a transaction object are executed as a single transaction. The transaction is terminated with a Commit() or Rollback().

Syntax 1

AsaTransaction BeginTransaction( )

Syntax 2

AsaTransaction BeginTransaction( IsolationLevel isolationLevel )

Parameters

isolationLevel A member of the IsolationLevel enumeration. The default value is ReadCommitted.

Return value

An object representing the new transaction.

Usage

To associate a command with a transaction object, use the AsaCommand.Transaction property.

Example
AsaTransaction tx = conn.BeginTransaction(
    IsolationLevel.ReadUncommitted );
See also

Commit method

Rollback method

Transaction processing

Typical types of inconsistency


ChangeDatabase method

Description

Changes the current database for an open AsaConnection.

Syntax

void ChangeDatabase( string database )

Parameters

database The name of the database to use instead of the current database.

Implements

IDbConnection.ChangeDatabase


Close method

Description

Closes a database connection.

Syntax

void Close( )

Implements

IDbConnection.Close

Usage

The Close method rolls back any pending transactions. It then releases the connection to the connection pool, or closes the connection if connection pooling is disabled. If Close is called while handling a StateChange event, no additional StateChange events are fired. An application can call Close more than one time.


ConnectionString property

Description

A database connection string.

Syntax

string ConnectionString

Access

Read-write

Implements

IDbConnection.ConnectionString

Usage

The default value of connection pooling is true (pooling=true).

The ConnectionString is designed to match the Adaptive Server Anywhere connection string format as closely as possble with the following exception:

  • When Persist Security Info value is set to false (the default), the connection string that is returned is the same as the user-set ConnectionString minus security information. The Adaptive Server Anywhere .NET data provider does not persist or return the password in a connection string unless you set Persist Security Info to true.

You can use the ConnectionString property to connect to a variety of data sources.

You can set the ConnectionString property only when the connection is closed. Many of the connection string values have corresponding read-only properties. When the connection string is set, all of these properties are updated, unless an error is detected. If an error is detected, none of the properties are updated. AsaConnection properties return only those settings contained in the ConnectionString.

If you reset the ConnectionString on a closed connection, all connection string values and related properties are reset, including the password.

When the property is set, a preliminary validation of the connection string is performed. When an application calls the Open method, the connection string is fully validated. A runtime exception is generated if the connection string contains invalid or unsupported properties.

Values may be delimited by single or double quotes. Either single or double quotes may be used within a connection string by using the other delimiter, for example, name="value's" or name= 'value"s', but not name='value's' or name= ""value"". Blank characters are ignored unless they are placed within a value or within quotes. Keyword-value pairs must be separated by a semicolon. If a semicolon is part of a value, it must also be delimited by quotes. Escape sequences are not supported, and the value type is irrelevant. Names are not case sensitive. If a property name occurs more than once in the connection string, the value associated with the last occurrence is used.

You should use caution when constructing a connection string based on user input, such as when retrieving a user ID and password from a dialog box, and appending it to the connection string. The application should not allow a user to embed extra connection string parameters in these values.

Example

The following statements set a connection string for an ODBC data source named ASA 9.0 Sample and open the connection.

AsaConnection conn = new AsaConnection();
conn.ConnectionString = "dsn=ASA 9.0 Sample";
conn.Open();


ConnectionTimeout property

Description

The number of seconds before a connection attempt times out with an error.

Syntax

int ConnectionTimeout

Access

Read-only

Default

15 seconds

Implements

IDbConnection.ConnectionTimeout

Example

The following statement displays the value of the ConnectionTimeout.

MessageBox.Show( conn.ConnectionTimeout.ToString() );


CreateCommand method

Description

Initializes an AsaCommand object. You can use the properties of the AsaCommand to control its behavior.

Syntax

AsaCommand CreateCommand( )

Return value

An AsaCommand object.

Usage

The command object is associated with the AsaConnection.


Database property

Description

The name of the current database to be used after a connection is opened.

Syntax

string Database

Access

Read-only

Implements

IDbConnection.Database

Usage

AsaConnection looks in the connection string in the following order: DatabaseName, dbn, DataSourceName, DataSource, dsn, DatabaseFile, dbf.


DataSource property

Description

The name of a running database server to which to connect.

Syntax

string DataSource

Access

Read-only

Usage

AsaConnection looks in the connection string in the following order: Enginename, Servername, Eng.


InfoMessage event

Description

Occurs when the provider sends a warning or an informational message.

Syntax

event AsaInfoMessageEventHandler InfoMessage

Usage

The event handler receives an argument of type AsaInfoMessageEventArgs containing data related to this event. The following AsaInfoMessageEventArgs properties provide information specific to this event: ErrorCode, Errors, Message, and Source.

For more information, see the .NET Framework documentation for OleDbConnection.InfoMessage Event.


Open method

Description

Opens a connection to a database, using the previously-specified connection string.

Syntax

void Open( )

Implements

IDbConnection.Open

Usage

The AsaConnection draws an open connection from the connection pool if one is available. Otherwise, it establishes a new connection to the data source.

If the AsaConnection goes out of scope, it is not closed. Therefore, you must explicitly close the connection by calling Close or Dispose.


ServerVersion property

Description

The software version of the Adaptive Server Anywhere database server.

Syntax

string ServerVersion

Access

Read-only

Usage

The version is ##.##.####, where the first two digits are the major version, the next two digits are the minor version, and the last four digits are the release version. The appended string is of the form major.minor.build, where major and minor are two digits and build is four digits.


State property

Description

The current state of the connection.

Syntax

ConnectionState State

Access

Read-only

Default

The default value is Closed.

Implements

IDbConnection.State

See also

Checking the connection state


StateChange event

Description

Occurs when the state of the connection changes.

Syntax

event StateChangeEventHandler StateChange

Usage

The event handler receives an argument of type StateChangeEventArgs with data related to this event. The following StateChangeEventArgs properties provide information specific to this event: CurrentState and OriginalState.

For more information, see the .NET Framework documentation for OleDbConnection.StateChange Event.


AsaDataAdapter class

Description

Represents a set of commands and a database connection used to fill a DataSet and to update a database.

Base classes

Component

Implemented interfaces

IDbDataAdapter, IDisposable

Usage

The DataSet provides a way to work with data offline. The AsaDataAdapter provides methods to associate a DataSet with a set of SQL statements.

See also

Using the AsaDataAdapter object to access and manipulate data

Accessing and manipulating data

AsaDataAdapter constructors
AcceptChangesDuringFill property
ContinueUpdateOnError property
DeleteCommand property
Fill method
FillError event
FillSchema method
GetFillParameters method
InsertCommand property
MissingMappingAction property
MissingSchemaAction property
RowUpdated event
RowUpdating event
SelectCommand property
TableMappings property
Update method
UpdateCommand property


AsaDataAdapter constructors

Description

Initializes an AsaDataAdapter object.

Syntax 1

void AsaDataAdapter( )

Syntax 2

void AsaDataAdapter( AsaCommand selectCommand )

Syntax 3

void AsaDataAdapter(
string selectCommandText,
AsaConnection selectConnection
)

Syntax 4

void AsaDataAdapter(
string selectCommandText,
string selectConnectionString
)

Parameters

selectCommand An AsaCommand object that is used during Fill to select records from the data source for placement in the DataSet.

selectCommandText A SELECT statement or stored procedure to be used by the SelectCommand property of the AsaDataAdapter.

selectConnection An AsaConnection object that defines a connection to a database.

selectConnectionString A connection string for an Adaptive Server Anywhere database.

Example

The following code initializes an AsaDataAdapter object:

AsaDataAdapter da = new AsaDataAdapter(
"SELECT emp_id, emp_lname FROM employee, conn );


AcceptChangesDuringFill property

Description

A value that indicates whether AcceptChanges is called on a DataRow after it is added to the DataTable.

Syntax

bool AcceptChangesDuringFill

Access

Read-write

Usage

When this property is true, DataAdapter calls the AcceptChanges function on the DataRow. If false, AcceptChanges is not called, and the newly added rows are treated as inserted rows. The default is true.


ContinueUpdateOnError property

Description

A value that specifies whether to generate an exception when an error is encountered during a row update.

Syntax

bool ContinueUpdateOnError

Access

Read-write

Usage

The default is false. Set this property to true to continue the update without generating an exception.

If ContinueUpdateOnError is true, no exception is thrown when an error occurs during the update of a row. The update of the row is skipped and the error information is placed in the RowError property of the row. The DataAdapter continues to update subsequent rows.

If ContinueUpdateOnError is false, an exception is thrown when an error occurs.


DeleteCommand property

Description

An AsaCommand object that is executed against the database when Update() is called to delete rows in the database that correspond to deleted rows in the DataSet.

Syntax

AsaCommand DeleteCommand

Access

Read-write

Usage

If this property is not set and primary key information is present in the DataSet during Update, DeleteCommand can be generated automatically by setting SelectCommand and using the AsaCommandBuilder. In that case, the AsaCommandBuilder generates any additional commands that you do not set. This generation logic requires key column information to be present in the SelectCommand.

When DeleteCommand is assigned to an existing AsaCommand object, the AsaCommand object is not cloned. The DeleteCommand maintains a reference to the existing AsaCommand.

See also

Update method

SelectCommand property


Fill method

Description

Adds or refreshes rows in a DataSet or DataTable object with data from the database.

Syntax 1

int Fill( DataSet dataSet )

Syntax 2

int Fill(
DataSet dataSet,
string srcTable
)

Syntax 3

int Fill(
DataSet dataSet,
int startRecord,
int maxRecords,
string srcTable
)

Syntax 4

int Fill( DataTable dataTable )

Parameters

dataSet A DataSet to fill with records and optionally schema.

srcTable The name of the source table to use for table mapping.

startRecord The zero-based record number to start with.

maxRecords The maximum number of records to be read into the DataSet.

dataTable A DataTable to fill with records and optionally schema.

Return Value

The number of rows successfully added or refreshed in the DataSet.

Usage

Even if you use the startRecord argument to limit the number of records that are copied to the DataSet, all records in the AsaDataAdapter query are fetched from the database to the client. For large result sets, this can have a significant performance impact.

An alternative is to use an AsaDataReader when a read-only, forward-only result set is sufficient, perhaps with SQL statements (ExecuteNonQuery) to carry out modifications. Another alternative is to write a stored procedure that returns only the result you need.

If SelectCommand does not return any rows, no tables are added to the DataSet and no exception is raised.

See also

Getting data using the AsaDataAdapter object


FillError event

Description

Returned when an error occurs during a fill operation.

Syntax

event FillErrorEventHandler FillError

Usage

The FillError event allows you to determine whether or not the fill operation should continue after the error occurs. Examples of when the FillError event might occur are:

  • The data being added to a DataSet cannot be converted to a common language runtime type without losing precision.

  • The row being added contains data that violates a Constraint that must be enforced on a DataColumn in the DataSet.


FillSchema method

Description

Adds DataTables to a DataSet and configures the schema to match the schema in the data source.

Syntax 1

DataTable[ ] FillSchema(
DataSet dataSet,
SchemaType schemaType
)

Syntax 2

DataTable[ ] FillSchema(
DataSet dataSet,
SchemaType schemaType,
string srcTable
)

Syntax 3

DataTable FillSchema(
DataTable dataTable,
SchemaType schemaType
)

Parameters

dataSet A DataSet to fill with records and optionally schema.

schemaType One of the SchemaType values that specify how to insert the schema.

srcTable The name of the source table to use for table mapping.

dataTable A DataTable.

Return Value

For syntax 1 and 2, the return value is a reference to a collection of DataTable objects that were added to the DataSet. For syntax 3, the return value is a reference to a DataTable.

See also

Obtaining AsaDataAdapter schema information


GetFillParameters method

Description

The parameters set by the user when executing a SELECT statement.

Syntax

AsaParameter[ ] GetFillParameters( )

Return value

An array of IDataParameter objects that contains the parameters set by the user.

Implements

IDataAdapter.GetFillParameters


InsertCommand property

Description

An AsaCommand that is executed against the database when an Update() is called that adds rows to the database to correspond to rows that were inserted in the DataSet.

Syntax

AsaCommand InsertCommand

Access

Read-write

Usage

The AsaCommandBuilder does not require key columns to generate InsertCommand.

When InsertCommand is assigned to an existing AsaCommand object, the AsaCommand is not cloned. The InsertCommand maintains a reference to the existing AsaCommand.

If this command returns rows, the rows may be added to the DataSet depending on how you set the UpdatedRowSource property of the AsaCommand object.

See also

Update method

Inserting, updating, and deleting rows using the AsaCommand object

Inserting, updating, and deleting rows using the AsaDataAdapter object


MissingMappingAction property

Description

Determines the action to take when incoming data does not have a matching table or column.

Syntax

MissingMappingAction MissingMappingAction

Access

Read-write

Property Value

One of the MissingMappingAction values. The default is Passthrough.

Implements

IDataAdapter.MissingMappingAction


MissingSchemaAction property

Description

Determines the action to take when the existing DataSet schema does not match incoming data.

Syntax

MissingSchemaAction MissingSchemaAction

Access

Read-write

Property Value

One of the MissingSchemaAction values. The default is Add.

Implements

IDataAdapter.MissingSchemaAction


RowUpdated event

Description

Occurs during update after a command is executed against the data source. The attempt to update is made, so the event fires.

Syntax

event AsaRowUpdatedEventHandler RowUpdated

Usage

The event handler receives an argument of type AsaRowUpdatedEventArgs containing data related to this event. The following AsaRowUpdatedEventArgs properties provide information specific to this event:

  • Command

  • Errors

  • RecordsAffected

  • Row

  • StatementType

  • Status

  • TableMapping

For more information, see the .NET Framework documentation for OleDbDataAdapter.RowUpdated Event.


RowUpdating event

Description

Occurs during update before a command is executed against the data source. The attempt to update is made, so the event fires.

Syntax

event AsaRowUpdatingEventHandler RowUpdating

Usage

The event handler receives an argument of type AsaRowUpdatingEventArgs containing data related to this event. The following AsaRowUpdatingEventArgs properties provide information specific to this event:

  • Command

  • Errors

  • Row

  • StatementType

  • Status

  • TableMapping

For more information, see the .NET Framework documentation for OleDbDataAdapter.RowUpdating Event.


SelectCommand property

Description

An AsaCommand that is used during Fill or FillSchema to obtain a result set from the database for copying into a DataSet.

Syntax

AsaCommand SelectCommand

Access

Read-write

Usage

When SelectCommand is assigned to a previously created AsaCommand, the AsaCommand is not cloned. The SelectCommand maintains a reference to the previously created AsaCommand object.

If the SelectCommand does not return any rows, no tables are added to the DataSet, and no exception is raised.

The SELECT statement can also be specified in the AsaDataAdapter constructor.


TableMappings property

Description

A collection that provides the master mapping between a source table and a DataTable.

Syntax

DataTableMappingCollection TableMappings

Access

Read-only

Usage

The default value is an empty collection.

When reconciling changes, the AsaDataAdapter uses the DataTableMappingCollection collection to associate the column names used by the data source with the column names used by the DataSet.


Update method

Description

Updates the tables in a database with the changes made to the DataSet.

Syntax 1

int Update( DataSet dataSet )

Syntax 2

int Update(
DataSet dataSet,
string srcTable
)

Syntax 3

int Update( DataTable dataTable )

Syntax 4

int Update( DataRow[ ] dataRows )

Parameters

dataSet A DataSet to update with records and optionally schema.

srcTable The name of the source table to use for table mapping.

dataTable A DataTable to update with records and optionally schema.

dataRows An array of DataRow objects used to update the data source.

Return Value

The number of rows successfully updated from the DataSet.

Usage

The Update is carried out using the InsertCommand, UpdateCommand, and DeleteCommand on each row in the data set that has been inserted, updated, or deleted.

See also

DeleteCommand property

InsertCommand property

UpdateCommand property

Inserting, updating, and deleting rows using the AsaDataAdapter object


UpdateCommand property

Description

An AsaCommand that is executed against the database when Update() is called to update rows in the database that correspond to updated rows in the DataSet.

Syntax

AsaCommand UpdateCommand

Access

Read-write

Usage

During Update, if this property is not set and primary key information is present in the SelectCommand, the UpdateCommand can be generated automatically if you set the SelectCommand property and use the AsaCommandBuilder. Then, any additional commands that you do not set are generated by the AsaCommandBuilder. This generation logic requires key column information to be present in the SelectCommand.

When UpdateCommand is assigned to a previously created AsaCommand, the AsaCommand is not cloned. The UpdateCommand maintains a reference to the previously created AsaCommand object.

If execution of this command returns rows, these rows may be merged with the DataSet depending on how you set the UpdatedRowSource property of the AsaCommand object.

See also

Update method


AsaDataReader class

Description

A read-only, forward-only result set from a query or stored procedure.

Base classes

MarshalByRefObject

Implemented interfaces

IDataReader, IDisposable, IDataRecord

Usage

There is no constructor for AsaDataReader. To get an AsaDataReader object, execute an AsaCommand:

AsaCommand cmd = new AsaCommand(
    "Select emp_id from employee", conn );
AsaDataReader reader = cmd.ExecuteReader();

You can only move forward through an AsaDataReader. If you need a more flexible object to manipulate results, use an AsaDataAdapter.

The AsaDataReader retrieves rows as needed, whereas the AsaDataAdapter must retrieve all rows of a result set before you can carry out any action on the object. For large result sets, this difference gives the AsaDataReader a much faster response time.

See also

ExecuteReader method

Accessing and manipulating data

Close method
Depth property
Dispose method
FieldCount property
GetBoolean method
GetByte method
GetBytes method
GetChar method
GetChars method
GetDataTypeName method
GetDateTime method
GetDecimal method
GetDouble method
GetFieldType method
GetFloat method
GetGuid method
GetInt16 method
GetInt32 method
GetInt64 method
GetName method
GetOrdinal method
GetSchemaTable method
GetString method
GetTimeSpan method
GetUInt16 method
GetUInt32 method
GetUInt64 method
GetValue method
GetValues method
IsClosed property
IsDBNull method
Item property
NextResult method
Read method
RecordsAffected property


Close method

Description

Closes the AsaDataReader.

Syntax

void Close( )

Implements

IDataReader.Close

Usage

You must explicitly call the Close method when you are through using the AsaDataReader.


Depth property

Description

A value indicating the depth of nesting for the current row. The outermost table has a depth of zero.

Syntax

int Depth

Access

Read-only

Property Value

The depth of nesting for the current row.

Implements

IDataReader.Depth


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaDataReader class

Dispose method

Description

Frees the resources associated with the object.

Syntax

void Dispose( )


FieldCount property

Description

The number of columns in the result set.

Syntax

int FieldCount

Access

Read-only

Property Value

When not positioned in a valid record set, 0; otherwise the number of columns in the current record. The default is -1.

Implements

IDataRecord.FieldCount

Usage

When not positioned in a valid record set, this property has a value of 0; otherwise it is the number of columns in the current record. The default is -1. After executing a query that does not return rows, FieldCount returns 0.


GetBoolean method

Description

The value of the specified column as a Boolean.

Syntax

bool GetBoolean( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return value

The value of the column.

Implements

IDataRecord.GetBoolean

Usage

No conversions are performed, so the data retrieved must already be a Boolean.


GetByte method

Description

The value of the specified column as a Byte.

Syntax

byte GetByte( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return value

The value of the column.

Implements

IDataRecord.GetByte

Usage

No conversions are performed, so the data retrieved must already be a byte.


GetBytes method

Description

Reads a stream of bytes from the specified column offset into the buffer as an array starting at the given buffer offset.

Syntax

long GetBytes(
int ordinal,
long dataIndex,
byte[ ] buffer,
int bufferIndex,
int length
)

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

dataIndex The index within the column value from which to read bytes.

buffer An array in which to store the data.

bufferIndex The index in the array to start copying data.

length The maximum length to copy into the specified buffer.

Return value

The number of bytes read.

Implements

IDataRecord.GetBytes

Usage

GetBytes returns the number of available bytes in the field. In most cases this is the exact length of the field. However, the number returned may be less than the true length of the field if GetBytes has already been used to obtain bytes from the field. This may be the case, for example, when the AsaDataReader is reading a large data structure into a buffer.

If you pass a buffer that is a null reference (Nothing in Visual Basic), GetBytes returns the length of the field in bytes.

No conversions are performed, so the data retrieved must already be a byte array.


GetChar method

Description

The value of the specified column as a character.

Syntax

char GetChar( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return value

The value of the column.

Implements

IDataRecord.GetChar

Usage

No conversions are performed, so the data retrieved must already be a character.

Call AsaDataReader.IsDBNull to check for null values before calling this method.

See also

IsDBNull method


GetChars method

Description

Reads a stream of characters from the specified column offset into the buffer as an array starting at the given buffer offset.

Syntax

long GetChars(
int ordinal,
long dataIndex,
char[ ] buffer,
int bufferIndex,
int length
)

Parameters

ordinal The zero-based column ordinal.

dataIndex The index within the row from which to begin the read operation.

buffer The buffer into which to copy data.

bufferIndex The index for buffer to begin the read operation.

length The number of characters to read.

Return value

The actual number of characters read.

Implements

IDataRecord.GetChars

Usage

GetChars returns the number of available characters in the field. In most cases this is the exact length of the field. However, the number returned may be less than the true length of the field if GetChars has already been used to obtain characters from the field. This may be the case, for example, when the AsaDataReader is reading a large data structure into a buffer.

If you pass a buffer that is a null reference (Nothing in Visual Basic), GetChars returns the length of the field in characters.

No conversions are performed, so the data retrieved must already be a character array.

See also

Handling BLOBs


GetDataTypeName method

Description

The name of the source data type.

Syntax

string GetDataTypeName( int index )

Parameters

index The zero-based column ordinal.

Return Value

The name of the back-end data type.

Implements

IDataRecord.GetDataTypeName


GetDateTime method

Description

The value of the specified column as a DateTime object.

Syntax

DateTime GetDateTime( int ordinal )

Parameters

ordinal The zero-based column ordinal.

Return Value

The value of the specified column.

Implements

IDataRecord.GetDateTime

Usage

No conversions are performed, so the data retrieved must already be a DateTime object.

Call AsaDataReader.IsDBNull to check for null values before calling this method.

See also

IsDBNull method


GetDecimal method

Description

The value of the specified column as a Decimal object.

Syntax

decimal GetDecimal( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value of the specified column.

Implements

IDataRecord.GetDecimal

Usage

No conversions are performed, so the data retrieved must already be a Decimal object.

Call AsaDataReader.IsDBNull to check for null values before calling this method.

See also

IsDBNull method


GetDouble method

Description

The value of the specified column as a double-precision floating point number.

Syntax

double GetDouble( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value of the specified column.

Implements

IDataRecord.GetDouble

Usage

No conversions are performed, so the data retrieved must already be a double-precision floating point number.

Call AsaDataReader.IsDBNull to check for null values before calling this method.

See also

IsDBNull method


GetFieldType method

Description

The Type that is the data type of the object.

Syntax

Type GetFieldType( int index )

Parameters

index The zero-based column ordinal.

Return Value

The type that is the data type of the object.

Implements

IDataRecord.GetFieldType


GetFloat method

Description

The value of the specified column as a single-precision floating point number.

Syntax

float GetFloat( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value of the specified column.

Implements

IDataRecord.GetFloat

Usage

No conversions are performed, so the data retrieved must already be a single-precision floating point number.

Call AsaDataReader.IsDBNull to check for null values before calling this method.

See also

IsDBNull method


GetGuid method

Description

The value of the specified column as a global unique identifier (GUID).

Syntax

Guid GetGuid( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value of the specified column.

Implements

IDataRecord.GetGuid

Usage

The data retrieved must already be a globally-unique identifier or binary(16).

Call AsaDataReader.IsDBNull to check for null values before calling this method.

See also

IsDBNull method


GetInt16 method

Description

The value of the specified column as a 16-bit signed integer.

Syntax

short GetInt16( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value of the specified column.

Implements

IDataRecord.GetInt16

Usage

No conversions are performed, so the data retrieved must already be a 16-bit signed integer.


GetInt32 method

Description

The value of the specified column as a 32-bit signed integer.

Syntax

int GetInt32( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value of the specified column.

Implements

IDataRecord.GetInt32

Usage

No conversions are performed, so the data retrieved must already be a 32-bit signed integer.


GetInt64 method

Description

The value of the specified column as a 64-bit signed integer.

Syntax

long GetInt64( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value of the specified column.

Implements

IDataRecord.GetInt64

Usage

No conversions are performed, so the data retrieved must already be a 64-bit signed integer.


GetName method

Description

The name of the specified column.

Syntax

string GetName( int index )

Parameters

index The zero-based index of the column.

Return value

The name of the specified column.

Implements

IDataRecord.GetName


GetOrdinal method

Description

The column ordinal, given the column name.

Syntax

int GetOrdinal( string name )

Parameters

name The column name.

Return Value

The zero-based column ordinal.

Implements

IDataRecord.GetOrdinal

Usage

GetOrdinal performs a case-sensitive lookup first. If it fails, a second case-insensitive search is made.

GetOrdinal is Japanese kana-width insensitive.

Because ordinal-based lookups are more efficient than named lookups, it is inefficient to call GetOrdinal within a loop. Save time by calling GetOrdinal once and assigning the results to an integer variable for use within the loop.


GetSchemaTable method

Description

Returns a DataTable that describes the column metadata of the AsaDataReader.

Syntax

DataTable GetSchemaTable( )

Return value

A DataTable that describes the column metadata.

Implements

IDataReader.GetSchemaTable

Usage

This method returns metadata about each column in the following order:

  • ColumnName

  • ColumnOrdinal

  • ColumnSize

  • NumericPrecision

  • NumericScale

  • IsUnique

  • IsKey

  • BaseCatalogName

  • BaseColumnName

  • BaseSchemaName

  • BaseTableName

  • DataType

  • AllowDBNull

  • ProviderType

  • IsAliased

  • IsExpression

  • IsIdentity

  • IsAutoIncrement

  • IsRowVersion

  • Is Hidden

  • IsLong

  • IsReadOnly

For more information about these columns, see the .NET Framework documentation for SqlDataReader.GetSchemaTable.

See also

Obtaining DataReader schema information


GetString method

Description

The value of the specified column as a string.

Syntax

string GetString( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value of the specified column.

Implements

IDataRecord.GetString

Usage

No conversions are performed, so the data retrieved must already be a string.

Call AsaDataReader.IsDBNull to check for null values before calling this method.

See also

IsDBNull method


GetTimeSpan method

Description

The value of the specified column as a TimeSpan object.

Syntax

TimeSpan GetTimeSpan( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value of the specified column.

Usage

The column must be ASA time data type. The data is converted to TimeSpan. The Days property of TimeSpan is always set to 0.

Call AsaDataReader.IsDBNull to check for null values before calling this method.

See also

Obtaining time values


GetUInt16 method

Description

The value of the specified column as a 16-bit unsigned integer.

Syntax

UInt16 GetUInt16( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value of the specified column.

Usage

No conversions are performed, so the data retrieved must already be a 16-bit unsigned integer.


GetUInt32 method

Description

The value of the specified column as a 32-bit unsigned integer.

Syntax

UInt32 GetUInt32( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value of the specified column.

Usage

No conversions are performed, so the data retrieved must already be a 32-bit unsigned integer.


GetUInt64 method

Description

The value of the specified column as a 64-bit unsigned integer.

Syntax

UInt64 GetUInt64( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value of the specified column.

Usage

No conversions are performed, so the data retrieved must already be a 64-bit unsigned integer.


GetValue method

Description

The value of the column at the specified ordinal in its native format.

Syntax

object GetValue( int ordinal )

Parameters

ordinal An ordinal number indicating the column from which the value is obtained. The numbering is zero-based.

Return Value

The value to return.

Implements

IDataRecord.GetValue

Usage

This method returns DBNull for null database columns.


GetValues method

Description

All the attribute columns in the current row.

Syntax

int GetValues( object[ ] values )

Parameters

values An array of objects that holds an entire row of the result set.

Return value

The number of objects in the array.

Implements

IDataRecord GetValues

Usage

For most applications, the GetValues method provides an efficient means for retrieving all columns, rather than retrieving each column individually.

You can pass an Object array that contains fewer than the number of columns contained in the resulting row. Only the amount of data the Object array holds is copied to the array. You can also pass an Object array whose length is more than the number of columns contained in the resulting row.

This method returns DBNull for null database columns.

Gets the value of the column at the specified ordinal in its native format.


IsClosed property

Description

Returns true if the AsaDataReader is closed. Otherwise it returns false.

Syntax

bool IsClosed

Access

Read-only

Property Value

True if the AsaDataReader is closed; otherwise, false.

Implements

IDataReader.IsClosed

Usage

IsClosed and RecordsAffected are the only properties that you can call after the AsaDataReader is closed.


IsDBNull method

Description

A value indicating whether the column contains null values.

Syntax

bool IsDBNull( int ordinal )

Parameters

ordinal The zero-based column ordinal.

Return value

True if the specified column value is equivalent to DBNull. Otherwise, false.

Implements

IDataRecord.IsDbNull

Usage

Call this method to check for null column values before calling the typed get methods (for example, GetByte, GetChar, and so on) to avoid raising an exception.


Item property

Description

The value of a column in its native format. In C#, this property is the indexer for the AsaDataReader class.

Syntax 1

object this[ int index ]

Syntax 2

object this[ string name ]

Parameters

index The column ordinal.

name The column name.

Access

Read-only

Implements

IDataRecord.Item


NextResult method

Description

Advances the AsaDataReader to the next result, when reading the results of batch SQL statements.

Syntax

bool NextResult( )

Return value

True if there are more result sets. Otherwise, false.

Implements

IDataReader.NextResult

Usage

Used to process multiple results, which can be generated by executing batch SQL statements.

By default, the data reader is positioned on the first result.


Read method

Description

Reads the next row of the result set and moves the AsaDataReader to that row.

Syntax

bool Read( )

Return value

Returns true if there are more rows. Otherwise, it returns false.

Implements

IDataReader.Read

Usage

The default position of the AsaDataReader is prior to the first record. Therefore, you must call Read to begin accessing any data.

Example

The following code fills a list box with the values in a single column of results.

while( reader.Read() )
{
    listResults.Items.Add(
        reader.GetValue( 0 ).ToString() );
}
listResults.EndUpdate();
reader.Close();


RecordsAffected property

Description

The number of rows changed, inserted, or deleted by execution of the SQL statement.

Syntax

int RecordsAffected

Access

Read-only

Property Value

The number of rows changed, inserted, or deleted. This is 0 if no rows were affected or the statement failed, or -1 for SELECT statements.

Implements

IDataReader.RecordsAffected

Usage

The number of rows changed, inserted, or deleted. The value is 0 if no rows were affected or the statement failed, and -1 for SELECT statements.

The value of this property is cumulative. For example, if two records are inserted in batch mode, the value of RecordsAffected will be two.

IsClosed and RecordsAffected are the only properties that you can call after the AsaDataReader is closed.


AsaDbType enum

Specifies Adaptive Server Anywhere data types.

Members

BigInt

Binary

Bit

Char

Date

Decimal

Double

Float

Integer

LongBinary

LongVarchar

Numeric

SmallInt

Time

TimeStamp

TinyInt

UnsignedBigInt

UnsignedInt

UnsignedSmallInt

VarBinary

VarChar

UniqueIdentifier


AsaError class

Description

Collects information relevant to a warning or error returned by the data source.

Base classes

Object

There is no constructor for AsaError.

See also

Error handling and the Adaptive Server Anywhere .NET data provider


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaError class

Message property

Description

A short description of the error.

Syntax

string Message

Access

Read-only


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaError class

NativeError property

Description

Database-specific error information.

Syntax

int NativeError

Access

Read-only


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaError class

Source property

Description

The name of the provider that generated the error.

Syntax

string Source

Access

Read-only


SqlState property

Description

The Adaptive Server Anywhere five-character SQL state following the ANSI SQL standard. If the error can be issued from more than one place, the five-character error code identifies the source of the error.

Syntax

string SqlState

Access

Read-only


ToString method

Description

The complete text of the error message.

Syntax

string ToString( )

Usage

The return value is a string is in the form "AsaError:", followed by the Message. For example,

AsaError:UserId or Password not valid.


AsaErrorCollection class

Description

Collects all errors generated by the Adaptive Server Anywhere ADO.NET data provider.

Base classes

Object

Implemented interfaces

ICollection, IEnumerable

There is no constructor for AsaErrorCollection. Typically, an AsaErrorCollection is obtained from the AsaException.Errors property.

See also

Errors property

Error handling and the Adaptive Server Anywhere .NET data provider


CopyTo method

Description

Copies the elements of the AsaErrorCollection into an array, starting at the given index within the array.

Syntax

void CopyTo(
Array array,
int index
)

Parameters

array The array into which to copy the elements.

index The starting index of the array.

Implements

ICollection.CopyTo


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaErrorCollection class

Count property

Description

The number of errors in the collection.

Syntax

int Count

Access

Read-only

Implements

ICollection.Count


Item property

Description

The error at the specified index.

Syntax

AsaError this[ int index ]

Parameters

index The zero-based index of the error to retrieve.

Property Value

An AsaError that contains the error at the specified index.

Access

Read-only


AsaException class

Description

The exception that is thrown when Adaptive Server Anywhere returns a warning or error.

Base classes

SystemException

There is no constructor for AsaException. Typically, an AsaException object is declared in a catch. For example:

...
catch( AsaException ex )
{
    MessageBox.Show( ex.Errors[0].Message, "Error" );
}
See also

Error handling and the Adaptive Server Anywhere .NET data provider


Errors property

Description

A collection of one or more AsaError objects.

Syntax

AsaErrorCollection Errors

Access

Read-only

Usage

The AsaErrorCollection class always contains at least one instance of the AsaError class.


GetObjectData method

Description

This member overrides Exception.GetObjectData.

Syntax

void GetObjectData(
SerializationInfo info,
StreamingContext context
)

Parameters

info The SerializationInfo that holds the serialized object data about the exception being thrown.

context The StreamingContext that contains contextual information about the source or destination.


Message property

Description

The text describing the error.

Syntax

string Message

Access

Read-only

Usage

This method returns a single string that contains a concatenation of all of the Message properties of all of the AsaError objects in the Errors collection. Each message, except the last one, is followed by a carriage return.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaException class

Source property

Description

The name of the provider that generated the error.

Syntax

string Source

Access

Read-only


AsaInfoMessageEventArgs class

Description

Provides data for the InfoMessage event.

Base classes

EventArgs

There is no constructor for AsaInfoMessageEventArgs.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaInfoMessageEventArgs class

Errors property

Description

The collection of warnings sent from the data source.

Syntax

AsaErrorCollection Errors

Access

Read-only


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaInfoMessageEventArgs class

Message property

Description

The full text of the error sent from the data source.

Syntax

string Message

Access

Read-only


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaInfoMessageEventArgs class

Source property

Description

The name of the object that generated the error.

Syntax

string Source

Access

Read-only


ToString method

Description

Retrieves a string representation of the InfoMessage event.

Syntax

string ToString( )

Return value

A string representing the InfoMessage event.


AsaInfoMessageEventHandler delegate

Description

Represents the method that will handle the InfoMessage event of an AsaConnection.

Syntax

void AsaInfoMessageEventHandler (
object sender,
AsaInfoMessageEventArgs e
)

Parameters

sender The source of the event.

e The AsaInfoMessageEventArgs object that contains the event data.


AsaParameter class

Description

Represents a parameter to an AsaCommand and optionally, its mapping to a DataSet column.

Base classes

MarshalByRefObject

Implemented interfaces

IDbDataParameter, IDataParameter

AsaParameter constructors
AsaDbType property
DbType property
Direction property
IsNullable property
Offset property
ParameterName property
Precision property
Scale property
Size property
SourceColumn property
SourceVersion property
ToString method
Value property


AsaParameter constructors

Syntax 1

void AsaParameter( )

Syntax 2

void AsaParameter(
string parameterName,
object value
)

Syntax 3

void AsaParameter(
string parameterName,
AsaDbType dbType
)

Syntax 4

void AsaParameter(
string parameterName,
AsaDbType dbType,
int size
)

Syntax 5

void AsaParameter(
string parameterName,
AsaDbType dbType,
int size,
string sourceColumn
)

Syntax 6

void AsaParameter(
string parameterName,
AsaDbType dbType,
int size,
ParameterDirection direction,
bool isNullable,
byte precision,
byte scale,
string sourceColumn,
DataRowVersion sourceVersion,
object value
)

Parameters

value An Object that is the value of the parameter.

size The length of the parameter.

sourceColumn The name of the source column to map.

parameterName The name of the parameter.

dbType One of the AsaDbType values.

direction One of the ParameterDirection values.

isNullable True if the value of the field can be null; otherwise, false.

precision The total number of digits to the left and right of the decimal point to which Value is resolved.

scale The total number of decimal places to which Value is resolved.

sourceVersion One of the DataRowVersion values.


AsaDbType property

Description

The AsaDbType of the parameter.

Syntax

AsaDbType AsaDbType

Access

Read-write

Usage

The AsaDbType and DbType are linked. Therefore, setting the DbType changes the AsaDbType to a supporting AsaDbType.

The value must be a member of the AsaDbType enumerator.


DbType property

Description

The DbType of the parameter.

Syntax

DbType DbType

Access

Read-write

Usage

The AsaDbType and DbType are linked. Therefore, setting the DbType changes the AsaDbType to a supporting AsaDbType.

The value must be a member of the AsaDbType enumerator.


Direction property

Description

A value indicating whether the parameter is input-only, output-only, bidirectional, or a stored procedure return value parameter.

Syntax

ParameterDirection Direction

Access

Read-write

Usage

If the ParameterDirection is output, and execution of the associated AsaCommand does not return a value, the AsaParameter contains a null value. After the last row from the last result set is read, Output, InputOut, and ReturnValue parameters are updated.


IsNullable property

Description

A value indicating whether the parameter accepts null values.

Syntax

bool IsNullable

Access

Read-write

Usage

This property is true if null values are accepted; otherwise it is false. The default is false. Null values are handled using the DBNull class.


Offset property

Description

The offset to the Value property.

Syntax

int Offset

Access

Read-write

Property value

The offset to the value. The default is 0.


ParameterName property

Description

The name of the AsaParameter.

Syntax

string ParameterName

Access

Read-write

Implements

IDataParameter.ParameterName

Usage

The Adaptive Server Anywhere .NET data provider uses positional parameters that are marked with a question mark (?) instead of named parameters.

The default is an empty string.


Precision property

Description

The maximum number of digits used to represent the Value property.

Syntax

byte Precision

Access

Read-write

Implements

IDbDataParameter.Precision

Usage

The value of this property is the maximum number of digits used to represent the Value property. The default value is 0, which indicates that the data provider sets the precision for the Value property.

The Precision property is only used for decimal and numeric input parameters.


Scale property

Description

The number of decimal places to which Value is resolved.

Syntax

byte Scale

Access

Read-write

Implements

IDbDataParameter.Scale

Usage

The default is 0. The Scale property is only used for decimal and numeric input parameters.


Size property

Description

The maximum size, in bytes, of the data within the column.

Syntax

int Size

Access

Read-write

Implements

IDbDataParameter.Size

Usage

The value of this property is the maximum size, in bytes, of the data within the column. The default value is inferred from the parameter value.

The Size property is used for binary and string types.

For variable length data types, the Size property describes the maximum amount of data to transmit to the server. For example, the Size property can be used to limit the amount of data sent to the server for a string value to the first one hundred bytes.

If not explicitly set, the size is inferred from the actual size of the specified parameter value. For fixed width data types, the value of Size is ignored. It can be retrieved for informational purposes, and returns the maximum amount of bytes the provider uses when transmitting the value of the parameter to the server.


SourceColumn property

Description

The name of the source column mapped to the DataSet and used for loading or returning the value.

Syntax

string SourceColumn

Access

Read-write

Implements

IDbDataParameter.SourceColumn

Usage

When SourceColumn is set to anything other than an empty string, the value of the parameter is retrieved from the column with the SourceColumn name. If Direction is set to Input, the value is taken from the DataSet. If Direction is set to Output, the value is taken from the data source. A Direction of InputOutput is a combination of both.


SourceVersion property

Description

The DataRowVersion to use when loading Value.

Syntax

DataRowVersion SourceVersion

Access

Read-write

Implements

IDbDataParameter.SourceVersion

Usage

Used by UpdateCommand during an Update operation to determine whether the parameter value is set to Current or Original. This allows primary keys to be updated. This property is ignored by InsertCommand and DeleteCommand. This property is set to the version of the DataRow used by the Item property, or the GetChildRows method of the DataRow object.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaParameter class

ToString method

Description

A string containing the ParameterName.

Syntax

string ToString( )

Access

Read-write


Value property

Description

The value of the parameter.

Syntax

object Value

Access

Read-write

Implements

IDataParameter.Value

Usage

For input parameters, the value is bound to the AsaCommand that is sent to the server. For output and return value parameters, the value is set on completion of the AsaCommand and after the AsaDataReader is closed.

When sending a null parameter value to the server, the user must specify DBNull, not null. The null value in the system is an empty object that has no value. DBNull is used to represent null values.

If the application specifies the database type, the bound value is converted to that type when the provider sends the data to the server. The provider attempts to convert any type of value if it supports the IConvertible interface. Conversion errors may result if the specified type is not compatible with the value.

Both the DbType and AsaDbType properties can be inferred by setting the Value.

The Value property is overwritten by Update.


AsaParameterCollection class

Description

Represents all parameters to an AsaCommand and optionally, their mapping to a DataSet column.

Base classes

Object

Implemented interfaces

ICollection, IEnumerable, IDataParameterCollection

Usage

There is no constructor for AsaParameterCollection. You obtain an AsaParameterCollection from the AsaCommand.Parameters property.

See also

Parameters property


Add method

Description

Adds an AsaParameter to the AsaCommand.

Syntax 1

int Add( object value )

Syntax 2

int Add( AsaParameter value )

Syntax 3

int Add(
string parameterName,
object value
)

Syntax 4

int Add(
string parameterName,
AsaDbType asaDbType
)

Syntax 5

int Add(
string parameterName,
AsaDbType asaDbType,
int size
)

Syntax 6

int Add(
string parameterName,
AsaDbType asaDbType,
int size,
string sourceColumn
)

Parameters

value For syntax 1 and 2, value is the AsaParameter object to add to the collection. For syntax 3, value is the value of the parameter to add to the connection.

parameterName The name of the parameter.

asaDbType One of the AsaDbType values.

size The length of the column.

sourceColumn The name of the source column.

Return Value

The index of the new AsaParameter object.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaParameterCollection class

Clear method

Description

Removes all items from the collection.

Syntax

void Clear( )

Implements

IList.Clear


Contains method

Description

A value indicating whether an AsaParameter exists in the collection.

Syntax 1

bool Contains( object value )

Syntax 2

bool Contains( string value )

Parameters

value The value of the AsaParameter object to find. In syntax 2, this is the name.

Return value

True if the collection contains the AsaParameter. Otherwise, it is false.

Implements

Syntax 1 implements IList.Contains

Syntax 2 implements IDataParameterCollection.Contains


CopyTo method

Description

Copies AsaParameter objects from the AsaParameterCollection to the specified array.

Syntax

void CopyTo(
array array
int index
)

Parameters

array The array into which to copy the AsaParameter objects.

index The starting index of the array.

Implements

ICollection.CopyTo


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaParameterCollection class

Count property

Description

The number of AsaParameter objects in the collection.

Syntax

int Count

Access

Read-only

Implements

ICollection.Count


IndexOf method

Description

The location of the AsaParameter in the collection.

Syntax 1

int IndexOf( object value )

Syntax 2

int IndexOf( string parameterName )

Parameters

value The AsaParameter object to locate.

parameterName The name of the AsaParameter object to locate.

Return Value

The zero-based location of the AsaParameter in the collection.

Implements

Syntax 1 implements IList.IndexOf

Syntax 2 implements IDataParameterCollection.IndexOf


Insert method

Description

Inserts an AsaParameter in the collection at the specified index.

Syntax

void Insert(
int index
object value )

Parameters

index The zero-based index where the parameter is to be inserted within the collection.

value The AsaParameter to add to the collection.

Implements

IList.Insert


Item property

Description

The AsaParameter at the specified index or name.

Syntax 1

AsaParameter this[ int index ]

Syntax 2

AsaParameter this[ string parameterName ]

Parameters

index The zero-based index of the parameter to retrieve.

parameterName The name of the parameter to retrieve.

Property value

An AsaParameter.

Access

Read-write

Usage

In C#, this property is the indexer for the AsaParameterCollection class.


Remove method

Description

Removes the specified AsaParameter from the collection.

Syntax

void Remove( object value )

Parameters

value The AsaParameter object to remove from the collection.

Implements

IList.Remove


RemoveAt method

Description

Removes the specified AsaParameter from the collection.

Syntax 1

void RemoveAt( int index )

Syntax 2

void RemoveAt( string parameterName )

Parameters

index The zero-based index of the parameter to remove.

parameterName The name of the AsaParameter object to remove.

Implements

Syntax 1 implements IList.RemoveAt

Syntax 2 implements IDataParameterCollection.RemoveAt


AsaPermission class

Description

Enables the Adaptive Server Anywhere .NET data provider to ensure that a user has a security level adequate to access an Adaptive Server Anywhere data source.

Base classes

DBDataPermission

AsaPermission constructors


AsaPermission constructors

Description

Initializes a new instance of the AsaPermission class.

Syntax 1

void AsaPermission( )

Syntax 2

void AsaPermission( PermissionState state )

Syntax 3

void AsaPermission(
PermissionState state,
bool allowBlankPassword
)

Parameters

state One of the PermissionState values.

allowBlankPassword Indicates whether a blank password is allowed.


AsaPermissionAttribute class

Description

Associates a security action with a custom security attribute.

Base classes

DBDataPermissionAttribute


AsaPermissionAttribute constructor

Description

Initializes a new instance of the AsaPermissionAttribute class.

Syntax

void AsaPermissionAttribute( SecurityAction action )

Parameters

action One of the SecurityAction values representing an action that can be performed using declarative security.

Return Value

An AsaPermissionAttribute object.


CreatePermission method

Description

Returns an AsaPermission object that is configured according to the attribute properties.

Syntax

IPermission CreatePermission( )


AsaRowUpdatedEventArgs class

Description

Provides data for the RowUpdated event.

Base classes

RowUpdatedEventArgs

AsaRowUpdatedEventArgs constructors
Command property
Errors property
RecordsAffected property
Row property
StatementType property
Status property
TableMapping property


AsaRowUpdatedEventArgs constructors

Description

Initializes a new instance of the AsaRowUpdatedEventArgs class.

Syntax

void AsaRowUpdatedEventArgs(
DataRow dataRow,
IDbCommand command,
StatementType statementType,
DataTableMapping tableMapping
)

Parameters

dataRow The DataRow sent through an Update.

command The IDbCommand executed when Update is called.

statementType One of the StatementType values that specifies the type of query executed.

tableMapping The DataTableMapping sent through an Update.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaRowUpdatedEventArgs class

Command property

Description

The AsaCommand executed when Update is called.

Syntax

AsaCommand Command

Access

Read-only


Errors property

Description

Any errors generated by Adaptive Server Anywhere when the Command was executed. Inherited from RowUpdatedEventArgs.

Syntax

Exception Errors

Property value

The errors generated by Adaptive Server Anywhere when the Command was executed.

Access

Read-write


RecordsAffected property

Description

The number of rows changed, inserted, or deleted by execution of the SQL statement. Inherited from RowUpdatedEventArgs.

Syntax

int RecordsAffected

Property value

The number of rows changed, inserted, or deleted; 0 if no rows were affected or the statement failed; and -1 for SELECT statements.

Access

Read-only


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaRowUpdatedEventArgs class

Row property

Description

The DataRow sent through an Update. Inherited from RowUpdatedEventArgs.

Syntax

DataRow Row

Access

Read-only


StatementType property

Description

The type of the SQL statement that was executed. Inherited from RowUpdatedEventArgs.

Syntax

StatementType StatementType

Access

Read-only

Usage

StatementType can be one of Select, Insert, Update, or Delete.


Status property

Description

The UpdateStatus of the Command property. Inherited from RowUpdatedEventArgs.

Syntax

UpdateStatus Status

Property Value

One of the UpdateStatus values: Continue, ErrorsOccurred, SkipAllRemainingRows, or SkipCurrentRow. The default is Continue.

Access

Read-write


TableMapping property

Description

The DataTableMapping sent through an Update. Inherited from RowUpdatedEventArgs.

Syntax

DataTableMapping TableMapping

Access

Read-only


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaRowUpdatingEventArgs class

Description

Provides data for the RowUpdating event.

Base classes

RowUpdatingEventArgs


AsaRowUpdatingEventArgs constructors

Description

Initializes a new instance of the AsaRowUpdatingEventArgs class.

Syntax

void AsaRowUpdatingEventArgs(
DataRow row,
IDbCommand command,
StatementType statementType,
DataTableMapping tableMapping
)

Parameters

row The DataRow to update.

command The IDbCommand to execute during update.

statementType One of the StatementType values that specifies the type of query executed.

tableMapping The DataTableMapping sent through an Update.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaRowUpdatingEventArgs class

Command property

Description

The AsaCommand to execute when performing the Update.

Syntax

AsaCommand Command

Access

Read-write


Errors property

Description

Any errors generated by Adaptive Server Anywhere when the Command was executed. Inherited from RowUpdatingEventArgs.

Syntax

Exception Errors

Property value

The errors generated by Adaptive Server Anywhere when the Command was executed.

Access

Read-write


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaRowUpdatingEventArgs class

Row property

Description

The DataRow sent through an Update. Inherited from RowUpdatingEventArgs.

Syntax

DataRow Row

Access

Read-only


StatementType property

Description

The type of the SQL statement that was executed. Inherited from RowUpdatingEventArgs.

Syntax

StatementType StatementType

Access

Read-only

Usage

StatementType can be one of Select, Insert, Update, or Delete.


Status property

Description

The UpdateStatus of the Command property. Inherited from RowUpdatingEventArgs.

Syntax

UpdateStatus Status

Property Value

One of the UpdateStatus values: Continue, ErrorsOccurred, SkipAllRemainingRows, or SkipCurrentRow. The default is Continue.

Access

Read-write


TableMapping property

Description

The DataTableMapping sent through an Update. Inherited from RowUpdatingEventArgs.

Syntax

DataTableMapping TableMapping

Access

Read-only


AsaRowUpdatedEventHandler delegate

Description

Represents the method that will handle the RowUpdated event of an AsaDataAdapter.

Syntax

void AsaRowUpdatedEventHandler (
object sender,
AsaRowUpdatedEventArgs e
)

Parameters

sender The source of the event.

e The AsaRowUpdatedEventArgs that contains the event data.


AsaRowUpdatingEventHandler delegate

Description

Represents the method that will handle the RowUpdating event of an AsaDataAdapter.

Syntax

void AsaRowUpdatingEventHandler (
object sender,
AsaRowUpdatingEventArgs e
)

Parameters

sender The source of the event.

e The AsaRowUpdatingEventArgs that contains the event data.


AsaTransaction class

Description

Represents a SQL transaction.

Base classes

Object

Implemented interfaces

IDbTransaction

Usage

There is no constructor for AsaTransaction. To obtain an AsaTransaction object, use the AsaConnection.BeginTransaction() method.

To associate a command with a transaction, use the AsaCommand.Transaction property.

See also

BeginTransaction method

Transaction property

Transaction processing

Inserting, updating, and deleting rows using the AsaCommand object


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

Adaptive Server Anywhere .NET Data Provider API Reference

AsaTransaction class

Commit method

Description

Commits the database transaction.

Syntax

void Commit( )

Implements

IDbTransaction.Commit


Connection property

Description

The AsaConnection object associated with the transaction, or a null reference (Nothing in Visual Basic) if the transaction is no longer valid.

Syntax

AsaConnection Connection

Access

Read-only

Usage

A single application may have multiple database connections, each with zero or more transactions. This property enables you to determine the connection object associated with a particular transaction created by BeginTransaction.


IsolationLevel property

Description

Specifies the isolation level for this transaction.

Syntax

IsolationLevel IsolationLevel

Access

Read-only

Property Value

The IsolationLevel for this transaction. This can be one of ReadCommitted, ReadUncommitted, RepeatableRead, or Serializable. The default is ReadCommitted.

Implements

IDbTransaction.IsolationLevel

Usage

Parallel transactions are not supported. Therefore, the IsolationLevel applies to the entire transaction.


Rollback method

Description

Rolls back a transaction from a pending state.

Syntax 1

void Rollback( )

Syntax 2

void Rollback( string savePoint )

Parameters

savePoint The name of the savepoint to which to roll back.

Usage

The transaction can only be rolled back from a pending state (after BeginTransaction has been called, but before Commit is called).


Save method

Description

Creates a savepoint in the transaction that can be used to roll back a portion of the transaction, and specifies the savepoint name.

Syntax

void Save( string savePoint )

Parameters

savePoint The name of the savepoint to which to roll back.


The Open Client Interface

About this chapter

This chapter describes the Open Client programming interface for Adaptive Server Anywhere.

The primary documentation for Open Client application development is the Open Client documentation, available from Sybase. This chapter describes features specific to Adaptive Server Anywhere, but it is not an exhaustive guide to Open Client application programming.

What you need to build Open Client applications
Data type mappings
Using SQL in Open Client applications
Known Open Client limitations of Adaptive Server Anywhere


What you need to build Open Client applications

To run Open Client applications, you must install and configure Open Client components on the machine where the application is running. You may have these components present as part of your installation of other Sybase products or you can optionally install these libraries with Adaptive Server Anywhere, subject to the terms of your license agreement.

Open Client applications do not need any Open Client components on the machine where the database server is running.

To build Open Client applications, you need the development version of Open Client, available from Sybase.

By default, Adaptive Server Anywhere databases are created as case-insensitive, while Adaptive Server Enterprise databases are case sensitive.

For more information on running Open Client applications with Adaptive Server Anywhere, see Adaptive Server Anywhere as an Open Server.


Data type mappings

Open Client has its own internal data types, which differ in some details from those available in Adaptive Server Anywhere. For this reason, Adaptive Server Anywhere internally maps some data types between those used by Open Client applications and those available in Adaptive Server Anywhere.

To build Open Client applications, you need the development version of Open Client. To use Open Client applications, the Open Client runtimes must be installed and configured on the computer where the application runs.

The Adaptive Server Anywhere server does not require any external communications runtime in order to support Open Client applications.

Each Open Client data type is mapped onto the equivalent Adaptive Server Anywhere data type. All Open Client data types are supported

Adaptive Server Anywhere data types with no direct counterpart in Open Client

The following table lists the mappings of data types supported in Adaptive Server Anywhere that have no direct counterpart in Open Client.

ASA data type | Open Client data type
unsigned short | int
unsigned int | bigint
unsigned bigint | bigint
date | smalldatetime
time | smalldatetime
serialization | longbinary
string | varchar
timestamp struct | datetime

Range limitations in data type mapping


Range limitations in data type mapping

Some data types have different ranges in Adaptive Server Anywhere than in Open Client. In such cases, overflow errors can occur during retrieval or insertion of data.

The following table lists Open Client application data types that can be mapped to Adaptive Server Anywhere data types, but with some restriction in the range of possible values.

In most cases, the Open Client data type is mapped to an Adaptive Server Anywhere data type that has a greater range of possible values. As a result, it is possible to pass a value to Adaptive Server Anywhere that will be accepted and stored in a database, but one that is too large to be fetched by an Open Client application.

Data type | Open Client lower range | Open Client upper range | ASA lower range | ASA upper range
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
Example

For example, the Open Client MONEY and SMALLMONEY data types do not span the entire numeric range of their underlying Adaptive Server Anywhere implementations. Therefore, it is possible to have a value in an Adaptive Server Anywhere column which exceeds the boundaries of the Open Client data type MONEY. When the client fetches any such offending values via Adaptive Server Anywhere, an error is generated.

Timestamps

The Adaptive Server Anywhere implementation of the Open Client TIMESTAMP data type, when such a value is passed in Adaptive Server Anywhere, is different from that of Adaptive Server Enterprise. In Adaptive Server Anywhere, the value is mapped to the Adaptive Server Anywhere DATETIME data type. The default value is NULL in Adaptive Server Anywhere and no guarantee is made of its uniqueness. By contrast, Adaptive Server Enterprise ensures that the value is monotonically increasing in value, and so, is unique.

By contrast, the Adaptive Server Anywhere TIMESTAMP data type contains year, month, day, hour, minute, second, and fraction of second information. In addition, the DATETIME data type has a greater range of possible values than the Open Client data types that are mapped to it by Adaptive Server Anywhere.


Using SQL in Open Client applications

This section provides a very brief introduction to using SQL in Open Client applications, with a particular focus on Adaptive Server Anywhere-specific issues.

For an introduction to the concepts, see Using SQL in Applications. For a complete description, see your Open Client documentation.


Executing SQL statements

You send SQL statements to a database by including them in Client Library function calls. For example, the following pair of calls executes a DELETE statement:

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

The ct_command function is used for a wide range of purposes.


Using prepared statements

The ct_dynamic function is used to manage prepared statements. This function takes a type parameter which describes the action you are taking.

toggle To use a prepared statement in Open Client

  1. Prepare the statement using the ct_dynamic function, with a CS_PREPARE type parameter.

  2. Set statement parameters using ct_param.

  3. Execute the statement using ct_dynamic with a CS_EXECUTE type parameter.

  4. Free the resources associated with the statement using ct_dynamic with a CS_DEALLOC type parameter.

For more information on using prepared statements in Open Client, see your Open Client documentation


Using cursors

The ct_cursor function is used to manage cursors. This function takes a type parameter which describes the action you are taking.

Supported cursor types

Not all the types of cursor that Adaptive Server Anywhere supports are available through the Open Client interface. You cannot use scroll cursors, dynamic scroll cursors, or insensitive cursors through Open Client.

Uniqueness and updatability are two properties of cursors. Cursors can be unique (each row carries primary key or uniqueness information, regardless of whether it is used by the application) or not. Cursors can be read only or updatable. If a cursor is updatable and not unique, performance may suffer, as no prefetching of rows is done in this case, regardless of the CS_CURSOR_ROWS setting (see below).

The steps in using cursors

In contrast to some other interfaces, such as Embedded SQL, Open Client associates a cursor with a SQL statement expressed as a string. Embedded SQL first prepares a statement and then the cursor is declared using the statement handle.

toggle To use cursors in Open Client

  1. To declare a cursor in Open Client, you use ct_cursor with CS_CURSOR_DECLARE as the type parameter.

  2. After declaring a cursor, you can control how many rows are prefetched to the client side each time a row is fetched from the server using ct_cursor with CS_CURSOR_ROWS as the type parameter.

    Storing prefetched rows at the client side cuts down the number of calls to the server and this improves overall throughput as well as turnaround time. Prefetched rows are not immediately passed on to the application; they are stored in a buffer at the client side ready for use.

    The setting of the PREFETCH database option controls prefetching of rows for other interfaces. It is ignored by Open Client connections. The CS_CURSOR_ROWS setting is ignored for non-unique, updatable cursors.

  3. To open a cursor in Open Client, you use ct_cursor with CS_CURSOR_OPEN as the type parameter.

  4. To fetch each row in to the application, you use ct_fetch.

  5. To close a cursor, you use ct_cursor with CS_CURSOR_CLOSE.

  6. In Open Client, you also need to deallocate the resources associated with a cursor. You do this using ct_cursor with CS_CURSOR_DEALLOC. You can also use CS_CURSOR_CLOSE with the additional parameter CS_DEALLOC to carry out these operations in a single step.

Modifying rows through a cursor


Modifying rows through a cursor

With Open Client, you can delete or update rows in a cursor, as long as the cursor is for a single table. The user must have permissions to update the table and the cursor must be marked for update.

toggle To modify rows through a cursor

  • Instead of carrying out a fetch, you can delete or update the current row of the cursor using ct_cursor with CS_CURSOR_DELETE or CS_CURSOR_UPDATE, respectively.

You cannot insert rows through a cursor in Open Client applications.


Describing query results in Open Client

Open Client handles result sets in a different way than some other Adaptive Server Anywhere interfaces.

In Embedded SQL and ODBC, you describe a query or stored procedure in order to set up the proper number and types of variables to receive the results. The description is done on the statement itself.

In Open Client, you do not need to describe a statement. Instead, each row returned from the server can carry a description of its contents. If you use ct_command and ct_send to execute statements, you can use the ct_results function to handle all aspects of rows returned in queries.

If you do not wish to use this row-by-row method of handling result sets, you can use ct_dynamic to prepare a SQL statement and use ct_describe to describe its result set. This corresponds more closely to the describing of SQL statements in other interfaces.


Known Open Client limitations of Adaptive Server Anywhere

Using the Open Client interface, you can use an Adaptive Server Anywhere database in much the same way as you would an Adaptive Server Enterprise database. There are some limitations, including the following:

  • Commit Service Adaptive Server Anywhere does not support the Adaptive Server Enterprise Commit Service.

  • Capabilities A client/server connection's capabilities determine the types of client requests and server responses permitted for that connection. The following capabilities are not supported:

    • 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

  • Security options, such as SSL and encrypted passwords, are not supported.

  • Open Client applications may connect to Adaptive Server Anywhere using TCP/IP or using local machine NamedPipes protocol where available.

    For more information on capabilities, see the Open Server Server-Library C Reference Manual.


The DBD::ASAny Perl Interface

About this chapter

This chapter describes how to install and use the DBD::ASAny interface. This interface allows scripts written in Perl to access and manipulate information stored in Adaptive Server Anywhere databases.


About DBD::ASAny

The DBD::ASAny interface provides access to Adaptive Server Anywhere databases from scripts written in Perl. ASAny is a driver for the Database Independent Interface for Perl (DBI) module written by Tim Bunce. Once you have installed the DBI module and DBD::ASAny, you can access and change the information in Adaptive Server Anywhere databases from Perl.

The DBD::ASAny driver is thread-safe when using Perl with ithreads.

Requirements

The DBD::ASAny interface requires the following components.

  • Perl 5.6.0 or newer. On Windows, ActivePerl 5.6.0 build 616 or later is required.

  • DBI 1.34 or newer

  • A C compiler. On Windows, only the Microsoft Visual C compiler is supported.


Installing DBD::ASAny on Windows

The following procedure documents how to install the DBD::ASAny interface on Windows.

toggle To prepare your machine

  1. Install ActivePerl 5.6.0 or later. You can use the ActivePerl installer to install Perl and configure your machine. You do not need to recompile Perl.

  2. Install Microsoft Visual C or Microsoft Visual Studio .NET and configure your environment.

    If you did not choose to configure your environment at install time, you must set your PATH, LIB, and INCLUDE environment variables correctly before proceeding. Microsoft provides a batch file for this purpose. For example, a batch file called vsvars32.bat is included in the Common7\Tools subdirectory of the Visual Studio .NET 2003 installation. Open a new system command prompt and run this batch file before continuing.

toggle To install the DBI Perl module on Windows

  1. At a command prompt, change to the bin subdirectory of your ActivePerl installation directory.

    The system command prompt is strongly recommended as the following steps may not work from alternative shells.

  2. Start the Perl Module Manager by executing the following command.

    ppm

    If ppm fails to start, check that Perl is installed correctly.

  3. Enter the following command at the ppm prompt.

    query dbi

    This command should generate two lines of text similar to those shown below. In this case, the information indicates that ActivePerl version 5.8.1 build 807 is running and that DBI version 1.38 is installed.

    Querying target 1 (ActivePerl 5.8.1.807)
  1. DBI [1.38] Database independent interface for Perl

    If DBI is not installed, you must install it. To do so, enter the following command at the ppm prompt.

    install dbi
toggle To install DBD::ASAny on Windows

  1. At a system command prompt, change to the src\perl subdirectory of your SQL Anywhere Studio installation.

  2. Enter the following commands to build and test ASAny.

    perl Makefile.PL
    nmake

    If for any reason your need to start over, you can run the command make clean to remove any partially built targets.

  3. To test DBD::ASAny, copy the Adaptive Anywhere Sample Database file to your DBD::ASAny directory and make the tests.

    copy "C:\Program Files\Sybase\SQL Anywhere 9\asademo.db" .
    dbeng9 asademo
    nmake test

    If the tests do not run, ensure that the win32 subdirectory of the SQL Anywhere installation is in your path.

  4. To complete the installation, execute the following command at the same prompt.

    nmake install

The DBD::ASAny interface is now ready to use.


Installing DBD::ASAny on UNIX

The following procedure documents how to install the DBD::ASAny interface on the supported UNIX platforms, including Mac OS X.

toggle To prepare your machine

  1. Install 5.6.0 build 616 or later.

  2. Install a C compiler.

toggle To install the DBI Perl module on UNIX

  1. Download the DBI module source from [external link] www.cpan.org. Extract the contents of this file into a new directory.

  2. At a command prompt, change to the new directory and execute the following commands to build the DBI module.

    perl Makefile.PL
    make

    If for any reason your need to start over, you can use the command make clean to remove any partially built targets.

  3. Use the following command to test the DBI module.

    make test

  4. To complete the installation, execute the following command at the same prompt.

    make install

  5. Optionally, you can now delete the DBI source tree. It is no longer required.

toggle To install DBD::ASAny on UNIX

  1. Make sure the environment is set up for Adaptive Server Anywhere.

    Depending on which shell you're using, enter the appropriate command to source the Adaptive Server Anywhere configuration script from the SQL Anywhere Studio installation directory:

    In this shell ... | ... use this command
    sh, ksh, or bash | . /bin/asa_config.sh
    csh or tcsh | source /bin/asa_config.csh

  2. At a shell prompt, change to the src/perl subdirectory of your SQL Anywhere Studio installation.

  3. At a system command prompt, enter the following commands to build ASAny.

    perl Makefile.PL
    make

    If for any reason your need to start over, you can use the command make clean to remove any partially built targets.

  4. To test DBD::ASAny, copy the Adaptive Anywhere Sample Database file to your DBD::ASAny directory and make the tests.

    cp /opt/sybase/SYBSsa9/asademo.db .
    dbeng9 asademo
    make test

    If the tests do not run, ensure that the win32 subdirectory of the SQL Anywhere installation is in your path.

  5. To complete the installation, execute the following command at the same prompt.

    make install

The DBD::ASAny interface is now ready to use.


Writing Perl scripts that use DBD::ASAny

This section provides an overview of how to write Perl scripts that use the DBD::ASAny interface. DBD::ASAny is a driver for the DBI module. Complete documentation for the DBI module is available online at [external link] dbi.perl.org.


Loading the DBI module

To use the DBD::ASAny interface from a Perl script, you must first tell Perl that you plan to use the DBI module. To do so, include the following line at the top of the file.

use DBI;

In addition, it is highly recommended that you run Perl in strict mode. This statement, which for example makes explicit variable definitions mandatory, is likely to greatly reduce the chance that you will run into mysterious errors due to such common mistakes as typographical errors.

#!/usr/local/bin/perl -w
#
use DBI;
use strict;

The DBI module automatically loads the DBD drivers, of which ASAny is one, as required.


Opening and closing a connection

Generally, you open a single connection to a database and then perform all the required operations through it by executing a sequence of SQL statements. To open a connection, you use the connect method. The return value is a handle to the database connection that you use to perform subsequent operations on that connection.

The parameters to the connect method are as follows:

  1. "DBI:ASAny:" and additional connection parameters separated by semicolons.

  2. A user name. Unless this string is blank, ";UID=value" is appended to the connection string.

  3. A password value. Unless this string is blank, ";PWD=value" is appended to the connection string.

  4. A pointer to a hash of default values. Settings such as AutoCommit, RaiseError, and PrintError may be set in this manner.

The following code sample opens and closes a connection to the Adaptive Server Anywhere Sample database. You must start the database server and Sample database before running this script.

#!/usr/local/bin/perl -w
#
use DBI;
use strict;
my $database = "asademo";
my $data_src = "DBI:ASAny:ENG=$database;DBN=$database";
my $uid      = "dba";
my $pwd      = "sql";
my %defaults = (
     AutoCommit => 1, # Autocommit enabled.
     PrintError => 0  # Errors not automatically printed.
   );
my $dbh = DBI->connect($data_src, $uid, $pwd, \%defaults)
  or die "Can't connect to $data_source: $DBI::errstr\n";
$dbh->disconnect;
exit(0);
__END__

Optionally, you can append the user name or password value to the data-source string instead of supplying them as separate parameters. If you do so, supply a blank string for the corresponding argument. For example, in the above script may be altered by replacing the statement that opens the connections with these statements:

$data_src .= ";UID=$uid";
$data_src .= ";PWD=$pwd";
my $dbh = DBI->connect($data_src, '', '', \%defaults)
  or die "Can't connect to $data_source: $DBI::errstr\n";


Selecting data

Once you have obtained a handle to an open connection, you can access and modify data stored in the database. Perhaps the simplest operation is to retrieve some rows and print them out.

SQL statements that return row sets must be prepared before being executed. The prepare method returns a handle to the statement. You use the handle to execute the statement, then retrieve meta information about the result set and the rows of the result set.

#!/usr/local/bin/perl -w
#
use DBI;
use strict;
my $database = "asademo";
my $data_src = "DBI:ASAny:ENG=$database;DBN=$database";
my $uid      = "dba";
my $pwd      = "sql";
my $sel_stmt = "SELECT id, fname, lname
                FROM customer
                ORDER BY fname, lname";
my %defaults = (
     AutoCommit => 0, # Require explicit commit or rollback.
     PrintError => 0
   );
my $dbh = DBI->connect($data_src, $uid, $pwd, \%defaults)
  or die "Can't connect to $data_src: $DBI::errstr\n";
&db_query($sel_stmt, $dbh);
$dbh->rollback;
$dbh->disconnect;
exit(0);

sub db_query {
      my($sel, $dbh) = @_;
      my($row, $sth) = undef;
      $sth = $dbh->prepare($sel);
      $sth->execute;
      print "Fields:     $sth->{NUM_OF_FIELDS}\n";
      print "Params:     $sth->{NUM_OF_PARAMS}\n\n";
      print join("\t\t", @{$sth->{NAME}}), "\n\n";
      while($row = $sth->fetchrow_arrayref) {
         print join("\t\t", @$row), "\n";
      }
      $sth = undef;
}
__END__

Prepared statements are not dropped from the database server until the Perl statement handle is destroyed. To destroy a statement handle, reuse the variable or set it to undef. Calling the finish method does not drop the handle. In fact, the finish method should not be called, except when you have decided not to finish reading a result set.

To detect handle leaks, the Adaptive Server Anywhere database server limits the number of cursors and prepared statements permitted to a maximum of 50 per connection by default. The resource governor automatically generates an error if these limits are exceeded. If you get this error, check for undestroyed statement handles. Use prepare_cached sparingly, as the statement handles are not destroyed.

If necessary, you can alter these limits by setting the MAX_CURSOR_COUNT and MAX_STATEMENT_COUNT options.

For more information, see MAX_CURSOR_COUNT option [database] and MAX_STATEMENT_COUNT option [database]


Inserting rows

Inserting rows requires a handle to an open connection. The simplest method is to use a parameterized select statement, meaning that question marks are used as place holders for values. The statement is first prepared, then executed once per new row. The new row values are supplied as parameters to the execute method.

The following sample program inserts two new customers. Although the row values appear as literal strings, you may want to read the values from a file.

#!/usr/local/bin/perl -w
#
use DBI;
use strict;
my $database = "asademo";
my $data_src = "DBI:ASAny:ENG=$database;DBN=$database";
my $uid      = "dba";
my $pwd      = "sql";
my $ins_stmt = "INSERT INTO customer (id, fname, lname,
                        address, city, state, zip,
                        phone, company_name)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
my %defaults = (
     AutoCommit => 0, # Require explicit commit or rollback.
     PrintError => 0
   );
my $dbh = DBI->connect($data_src, $uid, $pwd, \%defaults)
     or die "Can't connect to $data_src: $DBI::errstr\n";
&db_insert($ins_stmt, $dbh);
$dbh->commit;
$dbh->disconnect;
exit(0);

sub db_insert {
      my($ins, $dbh) = @_;
      my($sth) = undef;
      my @rows = (
        "801,Alex,Alt,5 Blue Ave,New York,NY,78312,43234,BXM",
        "802,Zach,Zed,82 Fair St,New York,NY,12333,72234,Zap"
       );
      $sth = $dbh->prepare($ins);
      my $row = undef;
      foreach $row ( @rows ) {
        my @values = split(/,/, $row);
        $sth->execute(@values);
      }
}
__END__


Using the SQLAnywhere PHP module

About this chapter

This chapter describes how to install and use the SQLAnywhere PHP module, which provides access to SQL Anywhere databases from PHP scripts.

About the SQLAnywhere PHP module
Installing and configuring SQLAnywhere PHP
Running PHP test scripts in your web pages
Writing PHP scripts
Troubleshooting
SQLAnywhere PHP Module interface reference


About the SQLAnywhere PHP module

PHP, which stands for Hypertext Preprocessor, is an Open Source scripting language. Although it can be used as a general-purpose scripting language, it was designed to be a convenient language in which to write scripts that could be embedded with HTML documents. Unlike scripts written in JavaScript, which are frequently executed by the client, PHP scripts are processed by the Web Server, and the resulting HTML output sent to the clients. The syntax of PHP is derived from that of other popular languages, such as Java and Perl.

To make it a convenient language in which to develop dynamic web pages, PHP provides the ability to retrieve information from many popular databases, such as Adaptive Server Anywhere. Included with SQL Anywhere, are two modules that provide access to Adaptive Server Anywhere databases from PHP. You can use these modules and the PHP language to write stand-alone scripts and create dynamic web pages that rely on information stored in Adaptive Server Anywhere databases.

The PHP functionality is provided by a DLL on Windows versions of SQL Anywhere, and by a shared object on all versions of UNIX, Linux, and Mac OS X.

Requirements

The following is a list of the required software.

  • Adaptive Server Anywhere 9.0.2 or higher.

  • The PHP binaries for your platform, which can be downloaded from [external link] http://www.php.net.

  • A web server, if you want to run PHP scripts within a web server. Adaptive Server Anywhere can be run on the same machine as the web server, or on a different machine.

  • The Adaptive Server Anywhere client software dblib9.dll (Windows), libdblib9.so (Linux and UNIX), or libdblib9.dylib.1 (Mac OS X)


Installing and configuring SQLAnywhere PHP

The following sections describe how to install and configure the SQLAnywhere PHP module.


Choosing which PHP module to use

On Windows, SQL Anywhere includes a module for PHP version 4 and one for PHP version 5.

On UNIX, SQL Anywhere includes both a threaded and a non-threaded module for PHP version 4 and for PHP version 5. On UNIX, PHP is supplied in a CGI version that can be used on the command line, and also as part of the Apache web server. If you are using the CGI version of PHP or if you are using Apache 1.x, use the non-threaded module. If you are using Apache 2.x, use the threaded module.

The filenames are as follows:

Filename | Description
php4_sqlanywhere9.dll | PHP version 4 library for Windows
php5_sqlanywhere9.dll | PHP version 4 library for Windows
php4_sqlanywhere9.so | Non-threaded PHP version 4 library for UNIX
php4_sqlanywhere9_r.so | Threaded PHP version 4 library for UNIX
php5_sqlanywhere9.so | Non-threaded PHP version 5 library for UNIX
php5_sqlanywhere9_r.so | Threaded PHP version 5 library for UNIX


Installing the PHP module on UNIX and Mac OS X

To use the SQLAnywhere PHP module on UNIX, Linux, or Mac OS X, you must copy the shared object from the SQL Anywhere installation directory and add it to your PHP installation. Optionally, you may then add an entry to your PHP initialization file, php.ini, to load the module, so you do not need to load it manually in each script.

toggle To install the PHP module on UNIX or Mac OS X

  1. Locate the php.ini file of your PHP installation, and open it in a text editor. Locate the line that specifies the location of the extension_dir directory.

  2. Copy the shared object from the lib subdirectory of your SQL Anywhere installation to the directory specified by the extension_dir entry in the php.ini file.

    For information on which version of the shared object to use, see Choosing which PHP module to use.

  3. Optionally, add the following line to the php.ini file to automatically load the SQLAnywhere PHP driver. Alternatively, you can load it manually with a few extra lines of code at the start of each script that requires it. The entry must identify the shared object you copied, which will be either

    extension=phpX_sqlanywhere9.so

    or, for the thread-safe shared object,

    extension=phpX_sqlanywhere9_r.so

    where X is the PHP version number.

  4. Before attempting to use the PHP module, verify that your environment is set up for Adaptive Server Anywhere. Depending on which shell you're using, enter the appropriate command to source the Adaptive Server Anywhere configuration script from the SQL Anywhere Studio installation directory:

    In this shell ... | ... use this command
    sh, ksh, or bash | . /bin/asa_config.sh
    csh or tcsh | source /bin/asa_config.csh

  5. At a command prompt, change to the root directory of your SQL Anywhere installation. Enter the following command to start the Adaptive Server Anywhere Sample Database.

    dbeng9 asademo.db

  6. At a command prompt, change to the src/php/examples subdirectory of your SQL Anywhere installation. Enter the following command:

    php connect.php

    The message Connected successfully should appear. If the php command is not recognized, verify that it is in your path.

  7. When you are done, stop the database server by pressing Q in the console window where it is running.

For more information, see Creating PHP test pages.


Installing the PHP module on Windows

To use the SQLAnywhere PHP module on Windows, you must copy the DLL from the SQL Anywhere installation directory and add it to your PHP installation. Optionally, you may then add an entry to your PHP initialization file to load the module, so you do not need to load it manually in each script.

toggle To install the PHP module on Windows

  1. Locate the php.ini file of your PHP installation, and open it in a text editor. Locate the line that specifies the location of the extension_dir directory.

  2. Copy the file php_sqlanywhere9.dll from the win32 subdirectory of your SQL Anywhere installation to the directory specified by the extension_dir entry in the php.ini file.

  3. Add the following line to the php.ini file to automatically load the SQLAnywhere PHP driver.

    extension=phpX_sqlanywhere9.dll

    An alternative to automatically loading the PHP driver is to load it manually in each script that requires it. For more information, see Configuring SQLAnywhere PHP.

  4. At a command prompt, change to the root directory of your SQL Anywhere installation. Enter the following command to start the Adaptive Server Anywhere Sample Database.

    dbeng9 asademo.db

    The command starts a database server with a server name of asademo, as required by samples in this chapter. If you start the server from the Windows menu, it has a server name of asademo9, which is not compatible with the samples in this chapter.

  5. At a command prompt, change to the src\php\examples subdirectory of your SQL Anywhere installation. Enter the following command:

    php connect.php

    The message Connected successfully should appear. If the php command is not recognized, verify that it is in your path.

  6. When you are done, stop the Adaptive Server Anywhere database server by clicking Shutdown in the console window.

For more information, see Creating PHP test pages.


Configuring SQLAnywhere PHP

The behavior of the SQL Anywhere PHP driver can be controlled by setting values in the PHP initialization file, php.ini. The following entries are currently supported.

  • extension Causes PHP to automatically load the SQLAnywhere PHP module every time PHP starts. Adding this entry to your PHP initialization file is optional, but if you don't add it, each script you write must start with a few lines of code that ensure that this module is loaded. The following entry is used for Windows platforms.

    extension=phpX_sqlanywhere9.dll

    On UNIX platforms and Mac OS X, use one of the following entries. The second entry uses threads.

    extension=phpX_sqlanywhere9.so
    extension=phpX_sqlanywhere9_r.so

    To ensure that the SQLAnywhere PHP module is loaded, you can prefix each script you write with the following lines of code. They are required only if the SQLAnywhere module is not always automatically loaded when PHP starts.

    # Ensure that the SQLAnywhere PHP module is loaded
  if( !extension_loaded('sqlanywhere')) {
    if( strtoupper(substr(PHYP_OS, 0, 3) == 'WIN' )) {
       dl('phpX_sqlanywhere9.dll');
    } else {
        dl('phpX_sqlanywhere9.so');
    }
  }

  • allow_persistent The PHP module allows persistent connection when set to 1. It does not allow them when set to 0. The default value is 1.

    sqlanywhere.allow_persistent=1

  • max_persistent Sets the maximum number of persistent connections. The default value is -1, which means no limit. The default value is -1.

    sqlanywhere.max_persistent=-1

  • max_connections Sets the maximum number of connections that can be opened at once through the SQLAnywhere PHP module. The default value is -1, which means no limit.

    sqlanywhere.max_connections=-1

  • auto_commit The database server to perform a commit operation automatically immediately following the execution of each statement when set to 1. Transactions should be ended manually with either the sqlanywhere_commit() or sqlanywhere_rollback() procedures, as appropriate, when set to 0. The default value is 1.

    sqlanywhere.auto_commit=1

For more information, see sqlanywhere_set_option.


Running PHP test scripts in your web pages

This section describes how to write PHP test scripts that query the Adaptive Anywhere Sample database and display information about PHP.


Creating PHP test pages

The following instructions apply to all configurations.

To test whether PHP is set up properly, the following procedure describes how to create and run a web page that calls phpinfo(). phpinfo() is a PHP function that generates a page of system setup information. The output tells you whether PHP is working properly.

For information on installing PHP, see [external link] http://us2.php.net/install.

toggle To create a PHP information test page

  1. Create a file in your root web content directory named info.php.

    If you are not sure which directory to use, check your web server's configuration file. In Apache installations, the content directory is often called htdocs. If you are using Mac OS X, the web content directory name may depend on which account you are using:

    • If you are the System Administrator on a Mac OS X system, use /Library/WebServer/Documents.

    • If you are a Mac OS X user, place the file in /Users/[your username]/Sites/.

  2. Insert the following code into this file:

    <? phpinfo() ?>

    Alternatively, once PHP is properly installed and configured, you can also create a test web page by issuing the following command at a command prompt.

    php -i > info.html

    This confirms that your installation of PHP and Apache are working together properly.

  3. To test that PHP and Apache are working correctly with Adaptive Server Anywhere:

    1. Copy the file connect.php from your PHP examples directory to your root web content directory.

    2. From a web browser, access the connect.php page.

      The message Connected successfully should appear.

toggle To create the query page that uses the SQLAnywhere PHP module

  1. Create a file containing the following PHP code in your root web content directory named asa_test.php:

  2. Insert the following PHP code into this file:

    <?
  $conn = sqlanywhere_connect( "uid=DBA;pwd=SQL" );
  $result = sqlanywhere_query( $conn, "select * from employee" );
  sqlanywhere_result_all( $result );
  sqlanywhere_free_result( $result );
  sqlanywhere_disconnect( $conn );
?>


Accessing your test web pages

The following procedure describes how to view your test pages from a web browser, after installing and configuring PHP and the SQLAnywhere PHP module.

toggle To view your web pages

  1. Restart your web server.

    For example, to start the Apache web server, run the following command from the bin subdirectory of your Apache installation:

    apachectl start

  2. On UNIX or Mac OS X, set the Adaptive Server Anywhere environment variables using one of the supplied scripts.

    Depending on which shell you're using, enter the appropriate command to source the Adaptive Server Anywhere configuration script from your SQL Anywhere installation directory:

    In this shell ... | ... use this command
    sh, ksh, or bash | . /bin/asa_config.sh
    csh or tcsh | source /bin/asa_config.csh

  3. Start the Adaptive Server Anywhere database server.

    For example, to access the test web pages described above, use the following command to start the Adaptive Server Anywhere Sample database.

    dbeng9 asademo.db

  4. To access the test pages from a browser that is running on the same machine as the server, enter the following URLs:

    For this test page ... | ... use this URL
    info.php | http://localhost/info.php
    asa_test.php | http://localhost/asa_test.php

    If everything is configured correctly, the asa_test pages display the contents of the employee table.


Writing PHP scripts

This section describes how to write PHP scripts that use the SQLAnywhere PHP module to access Adaptive Server Anywhere databases.

The source code for these examples, as well as others, is located in the src/php/examples subdirectory of your SQL Anywhere installation.


Connecting to a database

To make a connection to a database, pass a standard Adaptive Server Anywhere connection string to the database server as a parameter to the sqlanywhere_connect function. The <? and ?> tags tell the web server that it should let PHP execute the code that lies between them and replace it with the PHP output.

The source code for this example is contained in your SQL Anywhere installation in a file called connect.php.

<?
  # Ensure that the SQLAnywhere PHP module is loaded
  if( !extension_loaded('sqlanywhere')) {
    if( strtoupper(substr(PHYP_OS, 0, 3) == 'WIN' )) {
       dl('phpX_sqlanywhere9.dll');
    } else {
        dl('phpX_sqlanywhere9.so');
    }
  }
  # Connect using the default userid and password
  $conn = sqlanywhere_connect( "uid=DBA;pwd=SQL" );
  if( ! $conn ) {
      echo "Connection failed\n";
      return 0;
  } else {
      echo "Connected successfully\n";
      sqlanywhere_disconnect( $conn );
  }
?>

The first block of code verifies that the PHP module is loaded. If you added the line to your PHP initialization file to load it automatically, this block of code is unnecessary. If you did not configure PHP to automatically load the SQLAnywhere PHP module at start time, you must add this code to the other sample scripts.

The second block attempts to make a connection. For this code to succeed, the Adaptive Server Anywhere Sample database must be running.


Retrieving data from a database

One use of PHP scripts in web pages is to retrieve and display information contained in a database. The following examples demonstrate some useful techniques.

Simple select query

The following PHP code demonstrates a convenient way to include the result set of a select statement in a web page. This sample is designed to connect to the Adaptive Server Anywhere sample database a return a list of customers.

This code can be embedded in a web page, provided your web server is configured to execute PHP scripts.

The source code for this sample is contained in your SQL Anywhere installation in a file called query.php.

<?
  # Connect using the default userid and password
  $conn = sqlanywhere_connect( "uid=DBA;pwd=SQL" );
  if( ! $conn ) {
      echo "Connection failed\n";
      return 0;
  } else {
      echo "Connected successfully\n";
      sqlanywhere_disconnect( $conn );
  }
  # Execute a SELECT statement
  $result = sqlanywhere_query( $conn, "SELECT * FROM CUSTOMER" );
  if( ! $result ) {
      echo "sqlanywhere_query failed!";
      return 0;
  } else {
      echo "query completed successfully\n";
  }
  # Generate HTML from the result set
  sqlanywhere_result_all( $result );
  sqlanywhere_free_result( $result );
  # Disconnect
  sqlanywhere_disconnect( $conn );
?>

The sqlanywhere_result_all function fetches all the rows of the result set and generates an HTML output table to display them. The sqlanywhere_free_result function releases the resources used to store the result set.

Fetching by column name

In certain cases, you may not want to display all the data from a result set, or you may wish to display the data in a different manner. The following sample illustrates how you can exercise greater control over the output format of the result set. PHP allows you to display as much information as you wish in whatever manner you choose.

The source code for this sample is contained in your SQL Anywhere installation in a file called fetch.php.

<?
  # Connect using the default userid and password
  $conn = sqlanywhere_connect( "uid=DBA;pwd=SQL" );
  if( ! $conn ) {
      echo "Connection failed\n";
      return 0;
  } else {
      echo "Connected successfully\n";
      sqlanywhere_disconnect( $conn );
  }
  # Execute a SELECT statement
  $result = sqlanywhere_query( $conn, "SELECT * FROM CUSTOMER" );
  if( ! $result ) {
      echo "sqlanywhere_query failed!";
      return 0;
  } else {
      echo "query completed successfully\n";
  }
  # Retrieve meta information about the results
  $num_cols = sqlanywhere_num_fields( $result );
  $num_rows = sqlanywhere_num_rows( $result );
  echo "Num of rows = $num_rows\n";
  echo "Num of cols = $num_cols\n";
  while( ($field = sqlanywhere_fetch_field( $result ) ) ) {
      echo "Field # : $field->id \n";
      echo "\tname   : $field->name \n";
      echo "\tlength : $field->length \n";
      echo "\ttype   : $field->type \n";
  }
  # Fetch all the rows
  $curr_row = 0;
  while( ($row = sqlanywhere_fetch_row( $result ))) {
      $curr_row++;
      $curr_col = 0;
      while( $curr_col < $num_cols ) {
          echo "$row[$curr_col]\t|";
          $curr_col++;
      }
      echo "\n";
  }
  # Clean up.
  sqlanywhere_free_result( $result );
  sqlanywhere_disconnect( $conn );
?>

The sqlanywhere_fetch_array function returns a single row from the table. The data can be retrieved by column names and column indexes. Two other similar methods are provided in the PHP interface: sqlanywhere_fetch_row returns a row that can be searched by column indexes only, while sqlanywhere_fetch_object returns a row that can be searched by column names only.

See the fetch_object.php example script for an example of sqlanywhere_fetch_object.

Nested result sets

When a SELECT statement is sent to the database, a result set is returned. The sqlanywhere_fetch_row and sqlanywhere_fetch_array functions retrieve data from the individual rows of a result set, returning each row as an array of columns that can be queried further.

The source code for this sample is contained in your SQL Anywhere installation in a file called nested.php.

<?
  # Connect using the default userid and password
  $conn = sqlanywhere_connect( "uid=DBA;pwd=SQL" );
  if( ! $conn ) {
      echo "Connection failed\n";
      return 0;
  } else {
      echo "Connected successfully\n";
      sqlanywhere_disconnect( $conn );
  }
  # Retrieve the data and output HTML
  echo "<BR>\n";
  $query1 = "select table_id, table_name from systable";
  $result = sqlanywhere_query( $conn, $query1 );
  if( $result ) {
    $num_rows = sqlanywhere_num_rows( $result );
    echo "Returned : $num_rows <BR>\n";
    $i = 1;
    while( ($row = sqlanywhere_fetch_array( $result ))) {
      echo "$i:  table_id:$row[table_id]" +
           " --- table_name:$row[table_name] <br>\n";
      $query2 = "select table_id, column_name " +
      "from syscolumn " +
      "where table_id = '$row[table_id]'";
      echo " $query2 <br>\n";
      echo "  Columns: ";
      $result2 = sqlanywhere_query( $conn, $query2 );
      if( $result2 ) {
     while(($detailed = sqlanywhere_fetch_array($result2))) {
         echo " $detailed[column_name]";
     }
     sqlanywhere_free_result( $result2 );
      } else {
     echo "******FAILED********";
      }
      echo "<br>\n";
      $i++;
    }
  }
  echo "<BR>\n";
?>

In the above sample, the table ID and name are selected for each table from SYSTABLE. The sqlanywhere_query function returns an array of rows. The script iterates through the rows using sqlanywhere_fetch_array to retrieve the columns of the row as an array. An inner iteration goes through the columns of the row and prints their names.


Web forms

PHP can take user input from a web form, pass it to the database server as a SQL query, and display the result that is returned. The following example demonstrates a simple web form that gives the user the ability to query the asademo sample database using SQL statements and display the results in an HTML table.

The source code for this sample is contained in your SQL Anywhere installation in a file called webisql.php.

<?
  # Connect using the default userid and password
  $conn = sqlanywhere_connect( "uid=DBA;pwd=SQL" )
           or die("Can not connect to database");
  echo "<HTML>\n";
  $qname = $_POST[qname];
  $qname = str_replace( "\\", "", $qname );
  echo "<form method=post action=webisql.php>\n";
  echo "<br>Query: <input type=text size=80 name=qname value=\"$qname\">\n";
  echo "<input type=submit>\n";
  echo "</form>\n";
  echo "<HR><br>\n";
  if( ! $qname ) {
      echo "No Current Query\n";
      return;
  }
  # Connect to the database
  $con_str = "uid=DBA;pwd=SQL;eng=asademo;links=tcpip";
  $conn = sqlanywhere_connect( $con_str );
  if( ! $conn ) {
      echo "sqlanywhere_connect failed\n";
      echo "</html>\n";
      return 0;
  }
  $qname = str_replace( "\\", "", $qname );
  $result = sqlanywhere_query( $conn, $qname );
  if( ! $result ) {
        echo "sqlanywhere_query failed!";
  } else {
        // echo "query completed successfully\n";
        sqlanywhere_result_all( $result, "border=1" );
      sqlanywhere_free_result( $result );
  }
  sqlanywhere_disconnect( $conn );
  echo "</html>\n";
?>

This design could be extended to handle complex web forms by formulating customized SQL queries based on the values entered by the user.


Working with BLOBs

Adaptive Server Anywhere databases have the ability to store any type of data as a binary large object (BLOB). If that data is of a type readable by a web browser, a PHP script can easily retrieve it from the database and display it on a dynamically generated page.

BLOB fields are often used for storing non-text data, such as images. Numerous types of data can be passed to a web browser without any need for third-party software or data type conversion. The following sample illustrates the process of adding an image to the database and then retrieving it again to be displayed in a web browser.

This sample example illustrates the use of a BLOB column for storing large pieces of text.

The source code for this sample is contained in your SQL Anywhere installation in a file called image_insert.php.

<?
  $conn = sqlanywhere_connect( "uid=DBA;pwd=SQL" )
        or die("Can not connect to database");
  $create_table = "CREATE TABLE images (id INTEGER PRIMARY KEY, img IMAGE)";
  sqlanywhere_query( $conn, $create_table);
  $insert = "INSERT INTO images VALUES (99, xp_read_file('ianywhere_logo.gif'))";
  sqlanywhere_query( $conn, $insert );
  $query = "SELECT img FROM images WHERE id = 99";
  $result = sqlanywhere_query($conn, $query);
  $data = sqlanywhere_fetch_row($result);
  $img = $data[0];
  header("Content-type: image/gif");
  echo $img;
  sqlanywhere_disconnect($conn);
?>

In order to be able to send the binary data from the database directly to a web browser, the script must set the data's MIME type using the header function. In this case, the browser is told to expect a GIF image so it can display it correctly.


Troubleshooting

  • For more help, you can look in the following places:

    • The Newsgroups sybase.public.sqlanywhere.general and sybase.public.sqlanywhere.linux are most likely to be relevant, and can be read from the web or with a newsgroup reader. Be sure to look through old threads for your problem, as it may already have been addressed.

      If you use a news reader, the newsgroups are available on forums.sybase.com. On the web, they can be viewed at [external link] http://www.sybase.com/support/newsgroups.

    • A FAQ is available for the UNIX version of Adaptive Server Anywhere at [external link] http://www.sybase.com/detail?id=1011965.

    • Check if there have been any bug fixes or updates posted at [external link] http://downloads.sybase.com/swx/sdmain.stm.


SQLAnywhere PHP Module interface reference

This section provides reference information about the procedures provided by the PHP module.

Connections
  • sqlanywhere_connect
  • sqlanywhere_pconnect
  • sqlanywhere_disconnect
Queries
  • sqlanywhere_query
  • sqlanywhere_free_result
Result Sets
  • sqlanywhere_data_seek
  • sqlanywhere_num_rows
  • sqlanywhere_num_fields
  • sqlanywhere_fetch_field
  • sqlanywhere_fetch_array
  • sqlanywhere_fetch_row
  • sqlanywhere_fetch_object
  • sqlanywhere_result_all
Transactions
  • sqlanywhere_commit
  • sqlanywhere_rollback
  • sqlanywhere_set_option

sqlanywhere_commit
sqlanywhere_connect
sqlanywhere_data_seek
sqlanywhere_disconnect
sqlanywhere_fetch_array
sqlanywhere_fetch_field
sqlanywhere_fetch_object
sqlanywhere_fetch_row
sqlanywhere_free_result
sqlanywhere_num_fields
sqlanywhere_num_rows
sqlanywhere_pconnect
sqlanywhere_query
sqlanywhere_result_all
sqlanywhere_rollback
sqlanywhere_set_option


sqlanywhere_commit

Prototype

bool sqlanywhere_commit( int link_identifier )

Description

Ends a transaction on the Adaptive Server Anywhere database and makes any changes made during the transaction permanent. Useful only when the AUTO_COMMIT option is OFF.

Parameters

  • link_identifier The link identifier returned by a sqlanywhere_connect function.

Returns

TRUE on success or FALSE on failure.

Example
$result = sqlanywhere_commit( $conn );
Related functions
  • sqlanywhere_rollback
  • sqlanywhere_set_option


sqlanywhere_connect

Prototype

int sqlanywhere_connect( string con_str )

Description

Establishes a connection to an Adaptive Server Anywhere database.

Parameters

  • con_str A connection string as recognized by Adaptive Server Anywhere.

Returns

A positive Adaptive Server Anywhere link identifier on success, or an error and 0 on failure.

Example
$conn = sqlanywhere_connect( "UID=dba;PWD=sql" );
Related functions
  • sqlanywhere_pconnect
  • sqlanywhere_disconnect


sqlanywhere_data_seek

Prototype

bool sqlanywhere_data_seek( int result_identifier, int row_num )

Description

Positions the cursor on row row_num on the result_identifier that was opened using sqlanywhere_query.

Parameters

  • result_identifier The result identifier returned by a sqlanywhere_query function.

  • row_num An integer that represents the position that you want to move to within the result_identifier. For example, specify 5 to move to the 5th row in the result set. Negative numbers represent a position prior to the current position or moving backwards through the result set.-1 moves you to the last row in the result set.

Returns

TRUE on success or FALSE on error.

Example
sqlanywhere_data_seek( $result, 5 );
Related functions
  • sqlanywhere_fetch_field
  • sqlanywhere_fetch_array
  • sqlanywhere_fetch_row
  • sqlanywhere_fetch_object
  • sqlanywhere_query


sqlanywhere_disconnect

Prototype

bool sqlanywhere_disconnect( int link_identifier )

Description

Closes a connection that has already been opened with sqlanywhere_connect.

Parameters

  • link_identifier The link identifier returned by a sqlanywhere_connect function.

Returns

TRUE on success or FALSE on error.

Example
sqlanywhere_disconnect( $conn );
Related functions
  • sqlanywhere_connect
  • sqlanywhere_pconnect


sqlanywhere_fetch_array

Prototype

array sqlanywhere_fetch_array( int result_identifier )

Description

Fetches one row from the result set. This row is returned as an array that can be indexed by the column names or by the column indexes.

Parameters

  • result_identifier The result set returned by a sqlanywhere_query function.

Returns

An array that represents a row from the result set, or FALSE when no rows are available.

Example
$result = sqlanywhere_query( $conn, "SELECT fname, lname FROM employee" );
  While( ($row = sqlanywhere_fetch_array( $result )) ) {
        echo " fname = $row["fname"] \n" ;
        echo " lname = $row[1] \n";
  }
Related functions
  • sqlanywhere_data_seek
  • sqlanywhere_fetch_field
  • sqlanywhere_fetch_row
  • sqlanywhere_fetch_object


sqlanywhere_fetch_field

Prototype

object sqlanywhere_fetch_field( int result_identifier [, field_offset ] )

Description

Returns an object that contains information about a specific column.

Parameters

  • result_identifier The result identifier returned by a sqlanywhere_query function.

  • field_offset An integer representing the column/field on which you wish to retrieve information. Columns are zero based; to get the first column, specify the value 0. If this parameter is omitted, then the next field object is returned.

Returns

An object that has the following properties:

  • id contains the field/column number

  • name contains the field/column name

  • numeric indicates whether or not the field is a numeric value length returns field length type returns field type

Example
while( ($field = sqlanywhere_fetch_field( $result )) ) {
        echo " Field id = $field->id \n";
        echo " Field name = $field->name \n";
  }
Related functions
  • sqlanywhere_data_seek
  • sqlanywhere_fetch_array
  • sqlanywhere_fetch_row
  • sqlanywhere_fetch_object


sqlanywhere_fetch_object

Prototype

array sqlanywhere_fetch_object( int result_identifier )

Description

Fetches one row from the result set. This row is returned as an array that can be indexed by the column name only.

Parameters

  • result_identifier The result identifier returned by a sqlanywhere_query function.

Returns

An array that represents a row from the result set, or FALSE when no rows are available.

Example
$result = sqlanywhere_query( $conn, "SELECT fname, lname FROM employee" );
  While( ($row = sqlanywhere_fetch_array( $result )) ) {
        echo "$row["fname"] \n";     # output the data in the first column only.
  }
Related functions
  • sqlanywhere_data_seek
  • sqlanywhere_fetch_field
  • sqlanywhere_fetch_array
  • sqlanywhere_fetch_row


sqlanywhere_fetch_row

Prototype

array sqlanywhere_fetch_row( int result_identifier )

Description

Fetches one row from the result set. This row is returned as an array that can be indexed by the column indexes only.

Parameters

  • result_identifier The result identifier returned by a sqlanywhere_query function.

Returns

An array that represents a row from the result set, or FALSE when no rows are available.

Example
while( ($row = sqlanywhere_fetch_array( $result )) ) {
        echo "$row[0] \n";     # output the data in the first col only.
  }
Related functions
  • sqlanywhere_data_seek
  • sqlanywhere_fetch_field
  • sqlanywhere_fetch_array
  • sqlanywhere_fetch_object


sqlanywhere_free_result

Prototype

bool sqlanywhere_free_result( int result_identifier )

Description

Frees database resources associated with a result identifier returned from sqlanywhere_query.

Parameters

  • result_identifier The result identifier returned by a sqlanywhere_query function.

Returns

TRUE on success or FALSE on error.

Example
sqlanywhere_free_result( $result );
Related functions
  • sqlanywhere_query


sqlanywhere_num_fields

Prototype

int sqlanywhere_num_fields( int result_identifier )

Description

Returns the number of columns (fields) the result_identifier contains.

Parameters

  • result_identifier The result identifier returned by a sqlanywhere_query function.

Returns

A positive number of columns, or an error if result_identifier is not valid.

Example
sqlanywhere_num_fields( $result );


sqlanywhere_num_rows

Prototype

int sqlanywhere_num_rows( int result_identifier )

Description

Returns the number of rows that the result_identifier contains.

Parameters

  • result_identifier The result identifier returned by a sqlanywhere_query function.

Returns

A positive number if the number of rows is exact, or a negative number if it is an estimate. To get the exact number of rows, the database option ROW_COUNTS must be set permanently on the database, or temporarily on the connection.

Example
sqlanywhere_num_rows( $result );
Related functions
  • sqlanywhere_query


sqlanywhere_pconnect

Prototype

int sqlanywhere_pconnect( string con_str )

Description

Establishes a persistent connection to an Adaptive Server Anywhere database. Because of the way Apache creates child processes, you may observe a performance gain when using sqlanywhere_pconnect instead of sqlanywhere_connect. Persistent connections may provide improved performance in a similar fashion to connection pooling. If your database server has a limited number of connections (for example, the personal database server is limited to 10 concurrent connections), caution should be exercised when using persistent connections. Persistent connections could be attached to each of the child processes, and if you have more child processes in Apache than there are available connections, you will receive connection errors.

Parameters

  • con_str A connection string as recognized by Adaptive Server Anywhere.

Returns

A positive SQLAnywhere persistent link identifier on success, or an error and 0 on failure.

Example
$conn = sqlanywhere_pconnect( "UID=dba;PWD=sql" );
Related functions
  • sqlanywhere_connect
  • sqlanywhere_disconnect


sqlanywhere_query

Prototype

int sqlanywhere_query( int link_identifier, string sql_str )

Description

Prepares and executes the SQL query sql_str on the connection identified by link_identifier that has already been opened using sqlanywhere_connect or sqlanywhere_pconnect.

Parameters

  • link_identifier The link identifier returned by a sqlanywhere_connect function.

  • sql_str A SQL statement supported by Adaptive Server Anywhere. For more information about SQL statements, see the Adaptive Server Anywhere SQL Reference manual.

Returns

A positive value representing the result ID on success, or 0 and an error message on failure.

Example
$result = sqlanywhere_query( $conn, "SELECT * FROM systable" );
Related functions
  • sqlanywhere_free_result


sqlanywhere_result_all

Prototype

bool sqlanywhere_result_all( int result_identifier [, html_table_format_string ] )

Description

Fetches all results of the result_identifier and generates an HTML output table with an optional formatting string.

Parameters

  • result_identifier The result identifier returned by a sqlanywhere_query function.

  • html_table_format_string A format string that applies to HTML tables. For example, "Border=1; Cellpadding=5".

Returns

TRUE on success or FALSE on failure.

Example
$result = sqlanywhere_query( $conn, "SELECT fname, lname FROM employee" );
  sqlanywhere_result_all( $result );
Related functions
  • sqlanywhere_query


sqlanywhere_rollback

Prototype

bool sqlanywhere_rollback( int link_identifier )

Description

Ends a transaction on the Adaptive Server Anywhere database and discards any changes made during the transaction. Useful only when the AUTO_COMMIT option is OFF.

Parameters

  • link_identifier The link identifier returned by a sqlanywhere_connect function.

Returns

TRUE on success or FALSE on failure.

Example
$result = sqlanywhere_rollback( $conn );
Related functions
  • sqlanywhere_commit
  • sqlanywhere_set_option


sqlanywhere_set_option

Prototype

bool sqlanywhere_rollback( int link_identifier, string option, string value )

Description

Sets the value of the specified option on the specified connection. Currently, the only supported option is AUTO_COMMIT. The default value of this option is ON, which causes the database server to commit after executing each statement.

You can change the default value to OFF by including the following line in the php.ini file.

sqlanywhere.auto_commit=0
Parameters

  • link_identifier The link identifier returned by a sqlanywhere_connect function.

  • option The name of the option you want to set.

  • value The new option value.

Returns

TRUE on success or FALSE on failure.

Example
$result = sqlanywhere_set_option( $conn, "AUTO_COMMIT", "OFF" );
Related functions
  • sqlanywhere_commit
  • sqlanywhere_rollback


Three-Tier Computing and Distributed Transactions

About this chapter

This chapter describes how to use Adaptive Server Anywhere in a three-tier environment with an application server. It focuses on how to enlist Adaptive Server Anywhere in distributed transactions.


Introduction

You can use Adaptive Server Anywhere as a database server or resource manager, participating in distributed transactions coordinated by a transaction server.

A three-tier environment, where an application server sits between client applications and a set of resource managers, is a common distributed-transaction environment. Sybase EAServer and some other application servers are also transaction servers.

Sybase EAServer and Microsoft Transaction Server both use the Microsoft Distributed Transaction Coordinator (DTC) to coordinate transactions. Adaptive Server Anywhere provides support for distributed transactions controlled by the DTC service, so you can use Adaptive Server Anywhere with either of these application servers, or any other product based on the DTC model.

When integrating Adaptive Server Anywhere into a three-tier environment, most of the work needs to be done from the Application Server. This chapter provides an introduction to the concepts and architecture of three-tier computing, and an overview of relevant Adaptive Server Anywhere features. It does not describe how to configure your Application Server to work with Adaptive Server Anywhere. For more information, see your Application Server documentation.


Three-tier computing architecture

In three-tier computing, application logic is held in an application server, such as Sybase EAServer, which sits between the resource manager and the client applications. In many situations, a single application server may access multiple resource managers. In the Internet case, client applications are browser-based, and the application server is generally a Web server extension.

A three-tier computing architecture, showing client applications access to multiple databases mediated by an application server.

Sybase EAServer stores application logic in the form of components, and makes these components available to client applications. The components may be PowerBuilder components, JavaBeans, or COM components.

For more information, see the Sybase EAServer documentation.

Distributed transactions in three-tier computing
The vocabulary of distributed transactions
How application servers use DTC
Distributed transaction architecture


Distributed transactions in three-tier computing

When client applications or application servers work with a single transaction processing database, such as Adaptive Server Anywhere, there is no need for transaction logic outside the database itself, but when working with multiple resource managers, transaction control must span the resources involved in the transaction. Application servers provide transaction logic to their client applications—guaranteeing that sets of operations are executed atomically.

Many transaction servers, including Sybase EAServer, use the Microsoft Distributed Transaction Coordinator (DTC) to provide transaction services to their client applications. DTC uses OLE transactions, which in turn use the two-phase commit protocol to coordinate transactions involving multiple resource managers. You must have DTC installed in order to use the features described in this chapter.

Adaptive Server Anywhere in distributed transactions

Adaptive Server Anywhere can take part in transactions coordinated by DTC, which means that you can use Adaptive Server Anywhere databases in distributed transactions using a transaction server such as Sybase EAServer or Microsoft Transaction Server. You can also use DTC directly in your applications to coordinate transactions across multiple resource managers.


The vocabulary of distributed transactions

This chapter assumes some familiarity with distributed transactions. For information, see your transaction server documentation. This section describes some commonly used terms.

  • Resource managers are those services that manage the data involved in the transaction.

    The Adaptive Server Anywhere database server can act as a resource manager in a distributed transaction when accessed through OLE DB or ODBC. The ODBC driver and OLE DB provider act as resource manager proxies on the client machine.

  • Instead of communicating directly with the resource manager, application components may communicate with resource dispensers, which in turn manage connections or pools of connections to the resource managers.

    Adaptive Server Anywhere supports two resource dispensers: the ODBC driver manager and OLE DB.

  • When a transactional component requests a database connection (using a resource manager), the application server enlists each database connection takes part in the transaction. DTC and the resource dispenser carry out the enlistment process.

Two-phase commit

Distributed transactions are managed using two-phase commit. When the work of the transaction is complete, the transaction manager (DTC) asks all the resource managers enlisted in the transaction whether they are ready to commit the transaction. This phase is called preparing to commit.

If all the resource managers respond that they are prepared to commit, DTC sends a commit request to each resource manager, and responds to its client that the transaction is completed. If one or more resource manager does not respond, or responds that it cannot commit the transaction, all the work of the transaction is rolled back across all resource managers.


How application servers use DTC

Sybase EAServer and Microsoft Transaction Server are both component servers. The application logic is held in the form of components, and made available to client applications.

Each component has a transaction attribute that indicates how the component participates in transactions. The application developer building the component must program the work of the transaction into the component—the resource manager connections, the operations on the data for which each resource manager is responsible. However, the application developer does not need to add transaction management logic to the component. Once the transaction attribute is set, to indicate that the component needs transaction management, EAServer uses DTC to enlist the transaction and manage the two-phase commit process.


Distributed transaction architecture

The following diagram illustrates the architecture of distributed transactions. In this case, the resource manager proxy is either ODBC or OLE DB.

Architecture of distributed transactions: Client system with application server, top, connects to two database server systems, below, through resource manager proxies.

In this case, a single resource dispenser is used. The Application Server asks DTC to prepare a transaction. DTC and the resource dispenser enlist each connection in the transaction. Each resource manager must be in contact with both DTC and the database, so as to carry out the work and to notify DTC of its transaction status when required.

A DTC service must be running on each machine in order to operate distributed transactions. You can control DTC services from the Services icon in the Windows control panel; the DTC service is named MSDTC.

For more information, see your DTC or EAServer documentation.


Using distributed transactions

While Adaptive Server Anywhere is enlisted in a distributed transaction, it hands transaction control over to the transaction server, and Adaptive Server Anywhere ensures that it does not carry out any implicit transaction management. The following conditions are imposed automatically by Adaptive Server Anywhere when it participates in distributed transactions:

  • Autocommit is automatically turned off, if it is in use.

  • Data definition statements (which commit as a side effect) are disallowed during distributed transactions.

  • An explicit COMMIT or ROLLBACK issued by the application directly to Adaptive Server Anywhere, instead of through the transaction coordinator, generates an error. The transaction is not aborted, however.

  • A connection can participate in only a single distributed transaction at a time.

  • There must be no uncommitted operations at the time the connection is enlisted in a distributed transaction.


DTC isolation levels

DTC has a set of isolation levels, which the application server specifies. These isolation levels map to Adaptive Server Anywhere isolation levels as follows:

DTC isolation level | Adaptive Server Anywhere isolation level
ISOLATIONLEVEL_UNSPECIFIED | 0
ISOLATIONLEVEL_CHAOS | 0
ISOLATIONLEVEL_READUNCOMMITTED | 0
ISOLATIONLEVEL_BROWSE | 0
ISOLATIONLEVEL_CURSORSTABILITY | 1
ISOLATIONLEVEL_READCOMMITTED | 1
ISOLATIONLEVEL_REPEATABLEREAD | 2
ISOLATIONLEVEL_SERIALIZABLE | 3
ISOLATIONLEVEL_ISOLATED | 3


Recovery from distributed transactions

If the database server faults while uncommitted operations are pending, it must either rollback or commit those operations on startup to preserve the atomic nature of the transaction.

If uncommitted operations from a distributed transaction are found during recovery, the database server attempts to connect to DTC and requests that it be re-enlisted in the pending or in-doubt transactions. Once the re-enlistment is complete, DTC instructs the database server to roll back or commit the outstanding operations.

If the reenlistment process fails, Adaptive Server Anywhere has no way of knowing whether the in-doubt operations should be committed or rolled back, and recovery fails. If you want the database in such a state to recover, regardless of the uncertain state of the data, you can force recovery using the following database server options:

  • -tmf If DTC cannot be located, the outstanding operations are rolled back and recovery continues.

    For more information, see -tmf server option.

  • -tmt If re-enlistment is not achieved before the specified time, the outstanding operations are rolled back and recovery continues.

    For more information, see -tmt server option.


Using EAServer with Adaptive Server Anywhere

This section provides an overview of the actions you need to take in EAServer 3.0 or later to work with Adaptive Server Anywhere. For more detailed information, see the EAServer documentation.


Configuring EAServer

All components installed in a Sybase EAServer share the same transaction coordinator.

EAServer 3.0 and later offer a choice of transaction coordinators. You must use DTC as the transaction coordinator if you are including Adaptive Server Anywhere in the transactions. This section describes how to configure EAServer 3.0 to use DTC as its transaction coordinator.

The component server in EAServer is named Jaguar.

toggle To configure an EAServer to use the Microsoft DTC transaction model

  1. Ensure that your Jaguar server is running.

    On Windows, the Jaguar server commonly runs as a service. To manually start the installed Jaguar server that comes with EAServer 3.0, select Start > Programs > Sybase > EAServer > EAServer.

  2. Start Jaguar Manager.

    From the Windows desktop, select Start > Programs > Sybase > EAServer > Jaguar Manager.

  3. Connect to the Jaguar server from Jaguar Manager.

    From the Sybase Central menu, choose Tools > Connect > Jaguar Manager. In the connection dialog, enter jagadmin as the User Name, leave the Password field blank, and enter a Host Name of localhost. Click OK to connect.

  4. Set the transaction model for the Jaguar server.

    In the left pane, open the Servers folder. In the right pane, right click on the server you wish to configure, and select Server Properties from the drop down menu. Click the Transactions tab, and choose Microsoft DTC as the transaction model. Click OK to complete the operation.


Setting the component transaction attribute

In EAServer you may implement a component that carries out operations on more than one database. You assign a transaction attribute to this component that defines how it participates in transactions. The transaction attribute can have the following values:

  • Not Supported The component's methods never execute as part of a transaction. If the component is activated by another component that is executing within a transaction, the new instance's work is performed outside the existing transaction. This is the default.

  • Supports Transaction The component can execute in the context of a transaction, but a connection is not required in order to execute the component's methods. If the component is instantiated directly by a base client, EAServer does not begin a transaction. If component A is instantiated by component B, and component B is executing within a transaction, component A executes in the same transaction.

  • Requires Transaction The component always executes in a transaction. When the component is instantiated directly by a base client, a new transaction begins. If component A is activated by component B, and B is executing within a transaction, then A executes within the same transaction; if B is not executing in a transaction, then A executes in a new transaction.

  • Requires New Transaction Whenever the component is instantiated, a new transaction begins. If component A is activated by component B, and B is executing within a transaction, then A begins a new transaction that is unaffected by the outcome of B's transaction; if B is not executing in a transaction, then A executes in a new transaction.

For example, in the Sybase Virtual University sample application, included with EAServer as the SVU package, the SVUEnrollment component enroll() method carries out two separate operations (reserves a seat in a course, bills the student for the course). These two operations need to be treated as a single transaction.

Microsoft Transaction Server provides the same set of attribute values.

toggle To set the transaction attribute of a component

  1. In Jaguar Manager, locate the component.

    To find the SVUEnrollment component in the Jaguar sample application, connect to the Jaguar server, open the Packages folder, and open the SVU package. The components in the package are listed in the right pane.

  2. Set the transaction attribute for the desired component.

    Right click the component, and select Component Properties from the popup menu. Click the Transaction tab, and choose the transaction attribute value from the list. Click OK to complete the operation.

    The SVUEnrollment component is already marked as Requires Transaction.

Once the component transaction attribute is set, you can carry out Adaptive Server Anywhere operations from that component, and be assured of transaction processing at the level you have specified.


Deploying Databases and Applications

About this chapter

This chapter describes how to deploy Adaptive Server Anywhere components. It identifies the files required for deployment, and addresses related issues such as connection settings.

Check your license agreement
Redistribution of files is subject to your license agreement. No statements in this document override anything in your license agreement. Please check your license agreement before considering deployment.

Deployment overview
Understanding installation directories and file names
Using InstallShield for deployment
Using a silent installation for deployment
Deploying client applications
Deploying administration tools
Deploying database servers
Deploying embedded database applications


Deployment overview

When you have completed a database application, you must deploy the application to your end users. Depending on the way in which your application uses Adaptive Server Anywhere (as an embedded database, in a client/server fashion, and so on) you may have to deploy components of the Adaptive Server Anywhere software along with your application. You may also have to deploy configuration information, such as data source names, that enable your application to communicate with Adaptive Server Anywhere.

Check your license agreement
Redistribution of files is subject to your license agreement with Sybase. No statements in this document override anything in your license agreement. Please check your license agreement before considering deployment.

The following deployment steps are examined in this chapter:

  • Determining required files based on the choice of application platform and architecture.

  • Configuring client applications.

Much of the chapter deals with individual files and where they need to be placed. However, the recommended way of deploying Adaptive Server Anywhere components is to use the InstallShield objects or to use a silent installation. For information, see Using InstallShield for deployment, and Using a silent installation for deployment.


Deployment models

The files you need to deploy depend on the deployment model you choose. Here are some possible deployment models:

  • Client deployment You may deploy only the client portions of Adaptive Server Anywhere to your end-users, so that they can connect to a centrally located network database server.

  • Network server deployment You may deploy network servers to offices, and then deploy clients to each of the users within those offices.

  • Embedded database deployment You may deploy an application that runs with the personal database server. In this case, both client and personal server need to be installed on the end-user's machine.

  • SQL Remote deployment Deploying a SQL Remote application is an extension of the embedded database deployment model.

  • MobiLink deployment For information on deploying MobiLink synchronization servers, see Deploying MobiLink Applications.

  • Administration tools deployment You may deploy Interactive SQL, Sybase Central and other management tools.


Ways to distribute files

There are two ways to deploy Adaptive Server Anywhere:

  • Use the Adaptive Server Anywhere installation You can make the Setup program available to your end-users. By selecting the proper option, each end-user is guaranteed of getting the files they need.

    This is the simplest solution for many deployment cases. In this case, you must still provide your end users with a method for connecting to the database server (such as an ODBC data source).

    For more information, see Using a silent installation for deployment.

  • Develop your own installation There may be reasons for you to develop your own installation program that includes Adaptive Server Anywhere files. This is a more complicated option, and most of this chapter addresses the needs of those who are developing their own installation.

    If Adaptive Server Anywhere has already been installed for the server type and operating system required by the client application architecture, the required files can be found in the appropriately named subdirectory, located in the Adaptive Server Anywhere installation directory.

    For example, assuming the default installation directory was chosen, the win32 subdirectory of your installation directory contains the files required to run the server for Windows operating systems.

    As well, users of InstallShield Professional 5.5 and up can use the SQL Anywhere Studio InstallShield Template Projects to deploy their own application. This feature allows you to quickly build your application's installation using the entire template project, or just the parts that apply to your install.

Whichever option you choose, you must not violate the terms of your license agreement.


Understanding installation directories and file names

For a deployed application to work properly, the database server and client libraries must each be able to locate the files they need. The deployed files should be located relative to each other in the same fashion as your Adaptive Server Anywhere installation.

In practice, this means that on PCs, most files belong in a single directory. For example, on Windows both client and database server required files are installed in a single directory, which is the win32 subdirectory of the Adaptive Server Anywhere installation directory.

For a full description of the places where the software looks for files, see How Adaptive Server Anywhere locates files.


UNIX deployment issues

UNIX deployments are different from PC deployments in some ways:

  • Directory structure For UNIX installations, the directory structure is as follows:

    Directory | Contents
    /opt/sybase/SYBSsa9/bin | Executable files
    /opt/sybase/SYBSsa9/lib | Shared objects and libraries
    /opt/sybase/SYBSsa9/res | String files

    On AIX, the default root directory is /usr/lpp/sybase/SYBSsa9 instead of /opt/sybase/SYBSsa9.

  • File extensions In the tables in this chapter, the shared objects are listed with an extension .so. For HP-UX, the extension is .sl.

    On the AIX operating system, shared objects that applications need to link to are given the extension .a.

  • Symbolic links Each shared object is installed as a symbolic link to a file of the same name with the additional extension .1 (one). For example, the libdblib9.so is a symbolic link to the file libdblib9.so.1 in the same directory.

    If patches are required to the Adaptive Server Anywhere installation, these will be supplied with extension .2, and the symbolic link must be redirected.

  • Threaded and unthreaded applications Most shared objects are provided in two forms, one of which has the additional characters _r before the file extension. For example, in addition to libdblib9.so, there is a file named libdblib9_r.so. In this case, threaded applications must be linked to the _r shared object, while non-threaded applications must be linked to the shared object without the _r characters.

  • Character set conversion If you want to use database server character set conversion (the -ct server option), you need to include the following files:

    • libunic.so

    • charsets/ directory subtree

    • asa.cvf

    • asa.cvu

  • Environment variables

    On UNIX, environment variables must be set for the system to be able to locate SQL Anywhere Studio applications and libraries. It is recommended that you use the appropriate file for your shell, either asa_config.sh or asa_config.csh (located in the directory /opt/sybase/SYBSsa9/bin) as a template for setting the required environment variables. Some of the environment variables set by these files include PATH, LD_LIBRARY_PATH, ASANY9, and ASANYSH9.

For a description of how Adaptive Server Anywhere looks for files, see How Adaptive Server Anywhere locates files.


File naming conventions

Adaptive Server Anywhere uses consistent file naming conventions to help identify and group system components.

These conventions include:

  • Version number The Adaptive Server Anywhere version number is indicated in the filename of the main server components (.exe and .dll files).

    For example, the file dbeng9.exe is a Version 9 executable.

  • Language The language used in a language resource library is indicated by a two-letter code within its filename. The two characters before the version number indicate the language used in the library. For example, dblgen9.dll is the language resource library for English. These two-letter codes are specified by ISO standard 639.

    For more information about language labels, see Understanding the locale language.

You can download an International Resources Deployment Kit containing language resource deployment DLLs free of charge from the Sybase Web site.

toggle To download the International Resources Deployment Kit from the Sybase Web site

  1. Open the following URL in your Web browser:

    [external link] http://www.ianywhere.com/developer/

  2. Under the heading Downloads on the left hand side of the page, click EBFs/Patches.

  3. Login to your Sybase Web account.

    Click Create a New Account to create a Sybase Web account if you do not have one already.

  4. From the list of available downloads, select the International Resources Deployment Kit that matches the platform and version of Adaptive Server Anywhere that you are currently using.

For a list of the languages available in Adaptive Server Anywhere, see Choosing collations.

Identifying other file types

The following table identifies the platform and function of Adaptive Server Anywhere files according to their file extension. Adaptive Server Anywhere follows standard file extension conventions where possible.

File extension | Platform | File type
.nlm | Novell NetWare | NetWare Loadable Module
.chm, .chw | Windows | Help system file
.lib | Varies by development tool | Static runtime libraries for the creation of embedded SQL executables
.cfg, .cpr, .dat, .loc, .spr, .srt, .xlt | Windows | Sybase Adaptive Server Enterprise components
.cmd .bat | Windows | Command files
.res | NetWare, UNIX | Language resource file for non-Windows environments
.dll | Windows | Dynamic Link Library
.so .sl .a | UNIX | Shared object (Sun Solaris and IBM AIX) or shared library (HP-UX) file. The equivalent of a Windows DLL.
Database file names

Adaptive Server Anywhere databases are composed of two elements:

  • Database file This is used to store information in an organized format. This file uses a .db file extension.

  • Transaction log file This is used to record all changes made to data stored in the database file. This file uses a .log file extension, and is generated by Adaptive Server Anywhere if no such file exists and a log file is specified to be used. A mirrored transaction log has the default extension of .mlg.

  • Write file If your application uses a write file, it typically has a .wrt file extension.

  • Compressed database file If you supply a read-only compressed database file, it typically has extension .cdb.

These files are updated, maintained and managed by the Adaptive Server Anywhere relational database-management system.


Using InstallShield for deployment

InstallShield has used a variety of ways for including install components into an InstallShield project:

  • If you are using InstallShield 7 or later, you can use SQL Anywhere Studio InstallShield Merge Module Projects. These projects can be found in the deployment\MergeModules subdirectory of your SQL Anywhere Studio installation. Merge Module Projects allow you to generate merge modules that you can use to deploy the software currently installed on your machine.

  • If you are using InstallShield 6 and later, you can use SQL Anywhere Studio InstallShield Object Projects. The projects for deploying clients, personal database servers, network servers, and administration tools are found in the deployment\Object directory under your SQL Anywhere directory. Object Projects allow you to generate objects that you can use to deploy the software currently installed on your machine.

  • If you are using InstallShield Professional 5.5 and later, you can use SQL Anywhere Studio InstallShield Template Projects to ease the deployment workload. Templates for deploying a network server, personal server, client interfaces, and administration tools can be found in the SQL Anywhere 9\deployment\Templates folder.

    When building the media, you may see warnings about empty file groups. These warnings are caused by empty file groups which have been added to the templates as placeholders for your application's files. To remove these warnings, you can either add your application's files to the file groups, or delete or rename the file groups.

If you are using InstallShield 7 or later, the Merge Module Projects are recommended. If you have InstallShield 6, the Object Projects are recommended rather than the templates, as they are more easily incorporated into an install along with other components.

For instructions on incorporating these InstallShield Projects and Templates into your install program, see your InstallShield documentation.


Using a silent installation for deployment

Silent installations run without user input and with no indication to the user that an installation is occurring. On Windows operating systems you can call the Adaptive Server Anywhere InstallShield setup program from your own setup program in such a way that the Adaptive Server Anywhere installation is silent. Silent installs are also used with Microsoft's Systems Management Server (see SMS Installation).

You can use a silent installation for any of the deployment models described in Deployment models. You can also use a silent installation for deploying MobiLink synchronization servers.


Creating a silent install

The installation options used by a silent installation are obtained from a response file. The response file is created by running the Adaptive Server Anywhere setup program using the –r option. A silent install is performed by running setup using the –s option.

Do not use the browse buttons
When creating a silent install do not use the browse buttons. The recording of the browse buttons is not reliable.
toggle To create a silent install

  1. (Optional) Remove any existing installations of Adaptive Server Anywhere.

  2. Open a system command prompt, and change to the directory containing the install image (including setup.exe, setup.ins, and so on).

  3. Install the software, using Record mode.

    Type the following command:

    setup –r

    This command runs the Adaptive Server Anywhere setup program and creates the response file from your selections. The response file is named setup.iss, and is located in your Windows directory. This file contains the responses you made to the dialog boxes during installation.

    When run in record mode, the installation program does not offer to reboot your operating system, even if a reboot is needed.

  4. Install Adaptive Server Anywhere using the options, and settings that you want to be used when you deploy Adaptive Server Anywhere on the end-user's machine for use with your application. You can override the paths during the silent install.


Running a silent install

Your own installation program must call the Adaptive Server Anywhere silent install using the –s option. This section describes how to use a silent install.

toggle To use a silent install

  1. Add the command to invoke the Adaptive Server Anywhere silent install to your installation procedure.

    If the response file is present in the install image directory, you can run the silent install by entering the following command from the directory containing the install image:

    setup –s

    If the response file is located elsewhere you must specify the response file location using the –f1 option. There must be no space between f1 and the quotation mark in the following command line.

    setup –s –f1"c:\winnt\setup.iss"

    To invoke the install from another InstallShield script you could use the following:

    DoInstall( "ASA_install_image_path\SETUP.INS",
   "-s", WAIT );

    You can use options to override the choices of paths for both the Adaptive Server Anywhere directory and the shared directory:

    setup TARGET_DIR=dirname SHARED_DIR=shared_dir –s

    The TARGET_DIR and SHARED_DIR arguments must precede all other options.

  2. Check whether the target computer needs to reboot.

    Setup creates a file named silent.log in the target directory. This file contains a single section called ResponseResult containing the following line:

    Reboot=value

    This line indicates whether the target computer needs to be rebooted to complete the installation, and has a value of 0 or 1, with the following meanings.

    • Reboot=0 No reboot is needed.

    • Reboot=1 The BATCH_INSTALL flag was set during the installation, and the target computer does need to be rebooted. The installation procedure that called the silent install is responsible for checking the Reboot entry and for rebooting the target computer, if necessary.

  3. Check that the setup completed properly.

    Setup creates a file named setup.log in the directory containing the response file. The log file contains a report on the silent install. The last section of this file is called ResponseResult, and contains the following line:

    ResultCode=value

    This line indicates whether the installation was successful. A non-zero ResultCode indicates an error occurred during installation. For a description of the error codes, see your InstallShield documentation.


SMS Installation

Microsoft System Management Server (SMS) requires a silent install that does not reboot the target computer. The Adaptive Server Anywhere silent install does not reboot the computer.

Your SMS distribution package should contain the response file, the install image and the asa9.pdf package definition file (provided on the Adaptive Server Anywhere CD ROM in the \extras folder). The setup command in the PDF file contains the following options:

  • The –s option for a silent install

  • The –SMS option to indicate that it is being invoked by SMS.

  • The –m option to generate a MIF file. The MIF file is used by SMS to determine whether the installation was successful.


Deploying client applications

In order to deploy a client application that runs against a network database server, you must provide each end user with the following items:

  • Client application The application software itself is independent of the database software, and so is not described here.

  • Database interface files The client application requires the files for the database interface it uses (ODBC, JDBC, embedded SQL, or Open Client).

  • Connection information Each client application needs database connection information.

The interface files and connection information required varies with the interface your application is using. Each interface is described separately in the following sections.

The simplest way to deploy clients is to use the supplied InstallShield objects. For more information, see Using InstallShield for deployment.


Deploying OLE DB and ADO clients

The simplest way to deploy OLE DB client libraries is to use the InstallShield objects or templates. For information, see Using InstallShield for deployment. If you wish to create your own installation, this section describes the files to deploy to the end users.

Each OLE DB client machine must have the following:

  • A working OLE DB installation OLE DB files and instructions for their redistribution are available for redistribution from Microsoft Corporation. They are not described in detail here.

  • The Adaptive Server Anywhere OLE DB provider The following table shows the files needed for a working Adaptive Server Anywhere OLE DB provider. These files should be placed in a single directory. The Adaptive Server Anywhere installation places them all in the operating-system subdirectory of your SQL Anywhere installation directory (for example: win32).

Description | Windows | Windows CE
OLE DB driver file | dboledb9.dll | dboledb9.dll
OLE DB driver file | dboledba9.dll | dboledba9.dll
Language-resource library | dblgen9.dll | dblgen9.dll
Connect dialog | dbcon9.dll | N/A

OLE DB providers require many registry entries. You can make these by self-registering the DLLs using the regsvr32 utility on Windows or the regsvrce utility on Windows CE.

For more information, see Creating databases for Windows CE, and Linking ODBC applications on Windows CE.


Deploying ODBC clients

The simplest way to deploy ODBC clients is to use the InstallShield objects or templates. For information, see Using InstallShield for deployment.

Each ODBC client machine must have the following:

  • A working ODBC installation ODBC files and instructions for their redistribution are available for redistribution from Microsoft Corporation. They are not described in detail here.

    Microsoft provides their ODBC Driver Manager for Windows operating systems. SQL Anywhere Studio includes an ODBC Driver Manager for UNIX. There is no ODBC Driver Manager for Windows CE.

    ODBC applications can run without the driver manager. On platforms for which an ODBC driver manager is available, this is not recommended.

    Update ODBC if needed
    The SQL Anywhere Setup program updates old installations of the Microsoft Data Access Components, including ODBC. If you are deploying your own application, you must ensure that the ODBC installation is sufficient for your application.

  • The Adaptive Server Anywhere ODBC driver This is the file dbodbc9.dll together with some additional files.

    For more information, see ODBC driver required files.

  • Connection information The client application must have access to the information needed to connect to the server. This information is typically included in an ODBC data source.


ODBC driver required files

The following table shows the files needed for a working Adaptive Server Anywhere ODBC driver. These files should be placed in a single directory. The Adaptive Server Anywhere installation places them all in the operating-system subdirectory of your SQL Anywhere installation directory (for example: win32).

Description | Windows | Windows CE | UNIX
ODBC driver | dbodbc9.dll | dbodbc9.dll | libdbodbc9.so libdbtasks9.so
Language-resource library | dblgen9.dll | dblgen9.dll | dblgen9.res
Connect dialog | dbcon9.dll | N/A | N/A
Notes

  • Your end user must have a working ODBC installation, including the driver manager. Instructions for deploying ODBC are included in the Microsoft ODBC SDK.

  • The Connect dialog is needed if your end users are to create their own data sources, if they need to enter user IDs and passwords when connecting to the database, or if they need to display the Connect dialog for any other purpose.

  • For multi-threaded applications on UNIX, use libdbodbc9_r.so and libdbtasks9_r.so.


Configuring the ODBC driver

In addition to copying the ODBC driver files onto disk, your Setup program must also make a set of registry entries to install the ODBC driver properly.

Windows

The Adaptive Server Anywhere Setup program makes changes to the Registry to identify and configure the ODBC driver. If you are building a setup program for your end users, you should make the same settings.

You can use the regedit utility to inspect registry entries.

The Adaptive Server Anywhere ODBC driver is identified to the system by a set of registry values in the following registry key:

HKEY_LOCAL_MACHINE\
   SOFTWARE\
      ODBC\
         ODBCINST.INI\
            Adaptive Server Anywhere 9.0

The values are as follows:

Value name | Value type | Value data
Driver | String | path\dbodbc9.dll
Setup | String | path\dbodbc9.dll

There is also a registry value in the following key:

HKEY_LOCAL_MACHINE\
   SOFTWARE\
      ODBC\
         ODBCINST.INI\
            ODBC Drivers

The value is as follows:

Value name | Value type | Value data
Adaptive Server Anywhere 9.0 | String | Installed
Third party ODBC drivers

If you are using a third-party ODBC driver on an operating system other than Windows, consult the documentation for that driver on how to configure the ODBC driver.


Deploying connection information

ODBC client connection information is generally deployed as an ODBC data source. You can deploy an ODBC data source in one of the following ways:

  • Programmatically Add a data source description to your end-user's Registry or ODBC initialization files.

  • Manually Provide your end-users with instructions, so that they can create an appropriate data source on their own machine.

    You create a data source manually using the ODBC Administrator, from the User DSN tab or the System DSN tab. The Adaptive Server Anywhere ODBC driver displays the configuration dialog for entering settings. Data source settings include the location of the database file, the name of the database server, as well as any start up parameters and other options.

This section provides you with the information you need to know for either approach.

Types of data source

There are three kinds of data sources: User data sources, System data sources, and File data sources.

User data source definitions are stored in the part of the registry containing settings for the specific user currently logged on to the system. System data sources, however, are available to all users and to Windows services, which run regardless of whether a user is logged onto the system or not. Given a correctly configured System data source named MyApp, any user can use that ODBC connection by providing DSN=MyApp in the ODBC connection string.

File data sources are not held in the registry, but are held in a special directory. A connection string must provide a FileDSN connection parameter to use a File data source.

Data source registry entries

Each user data source is identified to the system by registry entries.

You must enter a set of registry values in a particular registry key. For User data sources the key is as follows:

HKEY_CURRENT_USER\
   SOFTWARE\
      ODBC\
         ODBC.INI\
            userdatasourcename

For System data sources the key is as follows:

HKEY_LOCAL_MACHINE\
   SOFTWARE\
      ODBC\
         ODBC.INI\
            systemdatasourcename

The key contains a set of registry values, each of which corresponds to a connection parameter. For example, the ASA 9.0 Sample key corresponding to the ASA 9.0 Sample data source contains the following settings:

Value name | Value type | Value data
Autostop | String | Yes
DatabaseFile | String | Path\asademo.db
Description | String | Adaptive Server Anywhere Sample Database
Driver | String | Path\win32\dbodbc9.dll
PWD | String | sql
Start | String | Path\win32\dbeng9.exe -c 8m
UID | String | dba
Note
It is recommended that you include the EngineName parameter in connection strings for deployed applications. This ensures that the application connects to the correct server in the event that a machine is running multiple Adaptive Server Anywhere database servers and can help prevent timing-dependent connection failures

In these entries, path is the Adaptive Server Anywhere installation directory.

In addition, you must add the data source to the list of data sources in the registry. For User data sources, you use the following key:

HKEY_CURRENT_USER\
   SOFTWARE\
      ODBC\
         ODBC.INI\
            ODBC Data Sources

For System data sources, use the following key:

HKEY_LOCAL_MACHINE\
   SOFTWARE\
      ODBC\
         ODBC.INI\
            ODBC Data Sources

The value associates each data source with an ODBC driver. The value name is the data source name, and the value data is the ODBC driver name. For example, the User data source installed by Adaptive Server Anywhere is named ASA 9.0 Sample, and has the following value:

Value name | Value type | Value data
ASA 9.0 Sample | String | Adaptive Server Anywhere 9.0
Caution: ODBC settings are easily viewed User data source configurations can contain sensitive database settings such as a user's ID and password. These settings are stored in the registry in plain text, and can be view using the Windows registry editors regedit.exe or regedt32.exe, which are provided by Microsoft with the operating system. You can choose to encrypt passwords, or require users to enter them on connecting.
Required and optional connection parameters

You can identify the data source name in an ODBC configuration string in this manner,

DSN=userdatasourcename

When a DSN parameter is provided in the connection string, the Current User data source definitions in the Registry are searched, followed by System data sources. File data sources are searched only when FileDSN is provided in the ODBC connection string.

The following table illustrates the implications to the user and developer when a data source exists and is included in the application's connection string as a DSN or FileDSN parameter.

When the data source... | The connection string must also identify... | The user must supply...
Contains the ODBC driver name and location; the name of the database file/server; startup parameters; and the user ID and password. | No additional information | No additional information.
Contains only the name and location of the ODBC driver. | The name of the database file/ server; and, optionally, the user ID and the password. | User ID and password if not provided in the DSN or ODBC connection string.
Does not exist The name of the ODBC driver to be used, in the following format:
Driver={ODBCdrivername}
Also, the name of the database, the database file or the database server; and, optionally, other connection parameters such as user ID and password. 		User ID and password if not provided in the ODBC connection string.

For more information on ODBC connections and configurations, see the following:

  • Connecting to a Database.

  • The Open Database Connectivity (ODBC) SDK, available from Microsoft.


Deploying embedded SQL clients

The simplest way to deploy embedded SQL clients is to use the InstallShield objects or templates. For information, see Using InstallShield for deployment.

Deploying embedded SQL clients involves the following:

  • Installed files Each client machine must have the files required for an Adaptive Server Anywhere embedded SQL client application.

  • Connection information The client application must have access to the information needed to connect to the server. This information may be included in an ODBC data source.


Installing files for embedded SQL clients

The following table shows which files are needed for embedded SQL clients.

Description | Windows | UNIX
Interface library | dblib9.dll | libdblib9.so, libdbtasks9.so
Language resource library | dblgen9.dll | dblgen9.res
Connect dialog | dbcon9.dll | N/A
Notes

  • The network ports DLL is not required if the client is working only with the personal database server.

  • If the client application uses an ODBC data source to hold the connection parameters, your end user must have a working ODBC installation. Instructions for deploying ODBC are included in the Microsoft ODBC SDK.

    For more information on deploying ODBC information, see Deploying ODBC clients.

  • The Connect dialog is needed if your end users will be creating their own data sources, if they will need to enter user IDs and passwords when connecting to the database, or if they need to display the Connect dialog for any other purpose.

  • For multi-threaded applications on UNIX, use libdblib9_r.so and libdbtasks9_r.so.


Connection information

You can deploy embedded SQL connection information in one of the following ways:

  • Manual Provide your end-users with instructions for creating an appropriate data source on their machine.

  • File Distribute a file that contains connection information in a format that your application can read.

  • ODBC data source You can use an ODBC data source to hold connection information. In this case, you need a subset of the ODBC redistributable files, available from Microsoft. For details see Deploying ODBC clients.

  • Hard coded You can hard code connection information into your application. This is an inflexible method, which may be limiting, for example when databases are upgraded.


Deploying JDBC clients

In addition to a Java Runtime Environment, each JDBC client requires jConnect or the iAnywhere JDBC driver.

For jConnect documentation, see [external link] http://sybooks.sybase.com/jc.html.

To deploy the iAnywhere JDBC driver, you must deploy the following files:

  • jodbc.jar This must be in the application's classpath.

  • dbjodbc9.dll This must be in the system path. On UNIX or Linux environments, the file is a shared library (dbjodbc9.so).

  • The ODBC driver files. For more information, see ODBC driver required files.

Your Java application needs a URL in order to connect to the database. This URL specifies the driver, the machine to use, and the port on which the database server is listening.

For more information on URLs, see Supplying a URL for the server.


Deploying Open Client applications

In order to deploy Open Client applications, each client machine needs the Sybase Open Client product. You must purchase the Open Client software separately from Sybase. It contains its own installation instructions.

Connection information for Open Client clients is held in the interfaces file. For information on the interfaces file, see the Open Client documentation and Configuring Open Servers.


Deploying administration tools

Subject to your license agreement, you can deploy a set of administration tools including Interactive SQL, Sybase Central, and the Adaptive Server Anywhere Console utility.

The simplest way to deploy the administration tools is to use the supplied InstallShield merge modules or objects. For more information, see Using InstallShield for deployment.

Deploying Interactive SQL

If your customer application is running on machines with limited resources, you may want to deploy dbisqlc.exe instead of Interactive SQL. However, dbisqlc is a limited application. It does not contain all the features of Interactive SQL and compatibility between the two is not guaranteed.

The dbisqlc executable requires the standard embedded SQL client-side libraries.

For information on system requirements for administration tools, see SQL Anywhere Studio Supported Platforms.


Deploying administration tools on Windows without InstallShield

This section explains how to install Interactive SQL (dbisql), Sybase Central (including the Adaptive Server Anywhere and MobiLink plug-ins), and the Adaptive Server Anywhere Console utility (dbconsole) on a Windows machine without using InstallShield. It is intended for those who want to create an installer for these administration tools.

This information applies to all Windows platforms except Windows CE. The instructions given here are specific to version 9.0.2 and cannot be applied to earlier or later versions of the software.

Check your license agreement
Redistribution of files is subject to your license agreement. No statements in this document override anything in your license agreement. Check your license agreement before considering deployment.
Before you begin

Before reading this section, you should have an understanding of the Windows registry, including the REGEDIT application.

Modifying your registry is dangerous Modify your registry at your own risk. It is recommended that you back up your system before modifying the registry.

The following steps are required to deploy the administration tools:

  1. Decide what you want to deploy.

  2. Copy the required files.

  3. Register the administration tools with Windows.

  4. Update the system path.

  5. Register the plug-ins with Sybase Central.

  6. Register the Adaptive Server Anywhere ODBC driver with Windows.

  7. Register the online help files with Windows.

Each of these steps is explained in detail in the following sections.

Step 1: Deciding what software to deploy
Step 2:Copying the required files
Step 3: Registering the administration tools with Windows
Step 4: Updating the system path
Step 5: Registering the plug-ins
Step 6: Registering the Adaptive Server Anywhere ODBC driver
Step 7: Registering the online help files


Step 1: Deciding what software to deploy

You can install any combination of the following software bundles:

  • Interactive SQL

  • Sybase Central with the Adaptive Server Anywhere plug-in

  • Sybase Central with the MobiLink plug-in

  • Adaptive Server Anywhere Console utility (DBConsole)

The following components are required when installing any of the software bundles:

  • The Java Runtime Environment (JRE) version 1.4.2_02

  • The jConnect runtime library

  • The iAnywhere JDBC Driver and the Adaptive Server Anywhere ODBC Driver

The instructions in the following sections are structured so that you can install any (or all) of these four bundles without conflicts.


Step 2:Copying the required files

The administration tools require a specific directory structure. You are free to put the directory tree in any directory, on any drive, but it must have the following layout:

Directory | Description
SA9 | The root folder. While this document assumes you are installing into C:\SA9, you are free to put the directory anywhere (for example, C:\Program Files\SA9).
SA9\java | Holds the program JAR files.
SA9\win32 | Holds the native (Win32) components used by the program, including the programs that launch the applications.
SA9\Shared | This tree contains files that are shared among different applications.
SA9\Shared\java | Shared utility libraries.
SA9\Shared\jConnect-5_5 | The jConnect 5_5 runtime library.
SA9\Shared\Sun\JavaHelp-1_1 | The JavaHelp runtime library.
SA9\Shared\win32 | Shared utility libraries.
Itanium 64
This document assumes you are installing on a 32-bit Windows platform. If you are installing the administration tools on a 64-bit Windows XP Itanium machine, you must install the 64-bit versions of the software. Specifically, you must install the 64-bit version of the Java runtime environment and 64-bit versions of all .exe and .dll files. In general, the 32-bit versions of these files are found in folders called win32, while the 64-bit versions are in folders called ia64. Files with the .jar extension work on both 32- and 64-bit machines.

The following table lists the files required for each of the software bundles. Make a list of the files you need, and then copy them into the directory structure outlined above. In general, you should take the files from an already-installed copy of SQL Anywhere Studio 9.0.2.

File | Adaptive Server Anywhere plug-in | MobiLink plug-in | Interactive SQL | Adaptive Server Anywhere Console
java\jcchart400k.jar | X | X |  |
java\jlogon.jar | X | X | X | X
java\jodbc.jar | X | X | X | X
java\sybasecentral.jar | X | X |  |
java\ASA.jar | X |  |  |
java\asaplugin.jar | X |  |  |
java\debugger.jar | X |  |  |
java\dbconsole.jar |  |  |  | X
java\isql.jar | X |  | X |
java\mlplugin.jar |  | X |  |
java\xerces.jar | X |  | X |
java\xml4j.jar | X |  | X |
java\apache_files.txt | X |  | X |
java\apache_license.txt | X |  | X |
java\dbmaen9.jar | X | X | X | X
java\dbmaen9.chm | X | X | X | X
java\scjview.exe | X | X |  |
java\scjview.cls | X | X |  |
java\scjlgen.dll | X | X |  |
java\scvwen43.chm | X | X |  |
java\scvwen43.jar | X | X |  |
Shared\java\HelpManager11.jar | X | X | X | X
Shared\java\JComponents142.jar | X |  | X | X
Shared\java\jsyblib142.jar | X | X | X | X
Shared\java\SCEditor142.jar | X | X | X |
Shared\jConnect-5_5\classes\jconn2.jar | X | X | X | X
Shared\Sun\jre142\*.* 1 | X | X | X | X
Shared\Sun\JavaHelp-1_1\jh.jar | X | X | X | X
Shared\win32\jsyblib142.dll | X | X | X | X
win32\dbcon9.dll | X | X | X | X
win32\dbconsole.exe |  |  |  | X
win32\dbisql.exe |  |  | X |
win32\dbisqlg.exe |  |  | X |
win32\dbisql.cls |  |  | X |
win32\dbjodbc9.dll | X | X | X | X
win32\dblgen9.dll | X |  | X | X
win32\dblib9.dll | X | X | X | X
win32\dbmlput9.dll |  | X |  |
win32\dbodbc9.dll | X | X | X | X
win32\dbput9.dll | X |  |  |
win32\dbtool9.dll | X |  |  |
c:\windows\system32\keyhh.exe 2 | X | X | X | X
International message and help files

All displayed text and online help for the administration tools is translated from English into French, German, Japanese, and simplified Chinese. The resources for each language are held in separate files. The English files contain en in the file names. French files have similar names, but use fr instead of en. German file names contain de, Japanese file names contain ja, and Chinese files contain zh.

In the preceding procedures, only the English files are listed. If you want to install support for different languages, you have to add the resource and help files for those other languages. The translated files are as follows:

dbmaxx9.jar – SQL Anywhere Help Files
dbmaen9.jar   English
dbmafr9.jar   French
dbmade9.jar   German
dbmaja9.jar   Japanese
dbmazh9.jar   Chinese
dblgxx9.res – Adaptive Server Anywhere Messages Files
dblgen9.res   English
dblgfr9.res   French
dblgde9.res   German
dblgja9.res   Japanese
dblgzh9.res   Chinese
scvwen43.jar – Sybase Central Help Files
scvwen43.jar  English
scvwfr43.jar  French
scvwde43.jar  German
scvwja43.jar  Japanese
scvwzh43.jar  Chinese

These files are included with localized versions of SQL Anywhere Studio.

1 The administration tools require JRE 1.4.2_02. You should not substitute a later patch version of the JRE (e.g. 1.4.2_03) unless you have a specific need to do so. Copy the JRE files from an installed copy of Adaptive Server Anywhere 9.0.2 from the C:\Program Files\Sybase\Shared\Sun\jre142 directory. Copy the entire jre142 tree, including subdirectories.

2 The exact name of the Windows system directory differs depending on which operating system you are using.


Step 3: Registering the administration tools with Windows

You must set the following registry values for the administration tools.

  • In HKLM\SOFTWARE\Sybase\Sybase Central\4.3

    • Location The fully-qualified path to the folder containing the Sybase Central files.

    • Shared Location The fully-qualified path to the Shared folder.

    • Language The two-letter code for the language used by Sybase Central. This must be one of the following: en , fr , de , ja , zh for English, French, German, Japanese, and Simplified Chinese, respectively.

  • In HKLM\SOFTWARE\Sybase\Adaptive Server Anywhere\9.0

    • Location The fully-qualified path to the root of the installation folder.

    • Shared Location The fully-qualified path to the shared folder.

    Paths should not end in a backslash.

Your installer can encapsulate all this information by creating a .reg file and then executing it. The following is a sample .reg file:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\\SOFTWARE\\Sybase\\Sybase Central\\4.3]
Location=C:\\SA9\\java
Shared Location=C:\\SA9\\Shared
Language=EN

[HKEY_LOCAL_MACHINE\SOFTWARE\Sybase\Adaptive Server Anywhere\\9.0]
Location=c:\\SA9
Shared Location=c:\\SA9\\shared

Backslashes must be escaped by another backslash in a .reg file.


Step 4: Updating the system path

To run the administration tools, the directories with .exe and .dll files must be included in the path. You must add the SA9\win32, SA9\java, and SA9\Shared\win32 directories to the system path.

On Windows NT/2000/XP, the system path is stored in the following registry key:

HKLM\
  SYSTEM\
    CurrentControlSet\
      Control\
        Session Manager\
          Environment\Path.

When you deploy Interactive SQL or Sybase Central, add the following directories to the end of the existing path:

C:\SA9\win32;c:\SA9\java;C:\SA9\Shared\win32


Step 5: Registering the plug-ins

Sybase Central requires a configuration file that lists the installed plug-ins. Your installer should create this file.

The file is called .scRepository. It resides in the same directory as scjview.exe. It is a plain text file that contains some basic information about the plug-ins that Sybase Central should load.

Here is a sample .scRepository file that contains information for the Adaptive Server Anywhere and MobiLink plug-ins. Some entries have been split across multiple lines for display purposes. In the file, each entry must be on a single line:

SCRepositoryInfo/Version=4
#
Providers/asa90/Name=Adaptive Server Anywhere 9
Providers/asa90/Classpath=C:\\sa9\\java\\asaplugin.jar
Providers/asa90/UseClassloader=true
Providers/asa90/AdditionalClasspath=
C:\\sa9\\Shared\\jConnect-5_5\\classes\\jconn2.jar;
C:\\sa9\\java\\isql.jar;
C:\\SA9\\java\\asa.jar;
C:\\SA9\\shared\\java\\JComponents142.jar;
C:\\SA9\\java\\xerces.jar;
C:\\SA9\\java\\xml4j.jar;
C:\\SA9\\java\\jlogon.jar;
C:\\SA9\\java\\debugger.jar;
C:\\SA9\\java\\jodbc.jar
Providers/asa90/ProviderId=asa90
Providers/asa90/Version=9.0.2.0000
Providers/asa90/Provider=com.sybase.asa.plugin.ASAPlugin
#
Providers/mobilink90/Name=MobiLink Synchronization 9
Providers/mobilink90/Classpath=C:\\SA9\\java\\mlplugin.jar
Providers/mobilink90/UseClassloader=true
Providers/mobilink90/AdditionalClasspath=
C:\\SA9\\Shared\\jConnect-5_5\\classes\\jconn2.jar;
C:\\SA9\\java\\asa.jar;
C:\\SA9\\java\\jlogon.jar;
C:\\SA9\\java\\jodbc.jar
Providers/mobilink90/Version=9.0.2.0000
Providers/mobilink90/ProviderId=mobilink90
Providers/mobilink90/Provider=com.sybase.mobilink.plugin.MLPlugin
Notes

  • The AdditionalClasspath lines must be entered on a single line in the .scRepository file.

  • The first line indicates the version of the .scRepository file.

  • Lines beginning with a # are comments.

  • The next 7 lines are the information for the Adaptive Server Anywhere plug-in. These are followed by another comment line, and then the information for the MobiLink plug-in. Your installer should write out a file similar to this one. The only changes required are the fully-qualified paths to the JAR files in the Classpath and AdditionalClasspath lines.

  • The file should only contain information about the plug-ins you are deploying. For example, if you are not deploying the MobiLink plug-in, you should not include the last section of the file (the lines that start Providers/mobilink90).


Step 6: Registering the Adaptive Server Anywhere ODBC driver

You must install the Adaptive Server Anywhere ODBC driver before they can be used by the iAnywhere JDBC Driver in the administration tools.

For more information, see Configuring the ODBC driver.


Step 7: Registering the online help files

The administration tools come with HTML Help files for the online help. These files must be registered with Windows before they can be used. Registering them requires a registry string to be written that names the help file and gives its fully-qualified path.

For all of the administration tools, you need to define a string value called HKLM\SOFTWARE\Microsoft\Windows\HTML Help\dbmaen9.chm. Its value should be C:\SA9\java\dbmaen9.chm.

For the Sybase Central help file, you must also define a string value called HKLM\SOFTWARE\Microsoft\Windows\HTML Help\scvwen43.chm. Its value should be C:\SA9\java\scvwen43.chm.

If you are installing translated online help files, they must also be registered. Follow the procedure provided earlier for the English help file, but use the translated file name instead.

The computer must already have the HTML Help viewer installed. It comes with current versions of Windows, but may not be present on some older machines. You can check for its existence by looking for the hh.exe file that is installed in the C:\Windows or C:\WINNT folder.

For more information on deploying databases and database applications, see Deploying Databases and Applications.


Deploying administration tools on Linux and Solaris

This section explains how to install Interactive SQL (dbisql), Sybase Central (including the Adaptive Server Anywhere and MobiLink plug-ins), and the Adaptive Server Anywhere Console utility (dbconsole) on Linux and Solaris machines. It is intended for those who want to create an installer for these administration tools.

The instructions given here are specific to version 9.0.2 and cannot be applied to earlier or later versions of the software.

Check your license agreement
Redistribution of files is subject to your license agreement. No statements in this document override anything in your license agreement. Please check your license agreement before considering deployment.
Before you begin

Before you begin, you must install SQL Anywhere Studio on one machine as a source for program files. This is the reference installation for your deployment.

The general steps involved are as follows:

  1. Decide which programs you want to deploy.

  2. Copy the required files.

  3. Set environment variables.

  4. Register the Sybase Central plug-ins.

Each of these steps is explained in detail in the following sections.

Step 1: Deciding what you want to deploy
Step 2: Copying the required files
Step 3: Setting environment variables
Step 4: Register the Sybase Central plug-ins


Step 1: Deciding what you want to deploy

You can install any combination of the following software bundles:

  • Interactive SQL

  • Sybase Central with the Adaptive Server Anywhere plug-in

  • Sybase Central with the MobiLink plug-in

  • Adaptive Server Anywhere Console utility (DBConsole)

All of these bundles require the following components:

  • Version 1.4.2_02 of the Java Runtime Environment (JRE)

  • The jConnect runtime library

  • The iAnywhere JDBC Driver and the Adaptive Server Anywhere ODBC Driver

The instructions in the next section are structured so that you can install any (or all) of these four bundles without conflicts.


Step 2: Copying the required files

Your installer should copy a subset of the files that are installed by the SQL Anywhere Studio installer. You must keep the same directory structure.

You should preserve the permissions on the files when you copy them from your reference SQL Anywhere Studio installation. In general, all users and groups are allowed to read and execute all files.

Base component files
Interactive SQL files
Sybase Central with the Adaptive Server Anywhere plug-in
Sybase Central with the MobiLink plug-in
The Adaptive Server Anywhere Console
International message and help files


Base component files

All four bundles require the files and links listed in this section.

Copy the following files from your reference installation:

/opt/sybase/SYBSsa9/java/jodbc.jar
/opt/sybase/SYBSsa9/lib/libdbjodbc9.so.1
/opt/sybase/SYBSsa9/lib/libdbodbc9_r.so.1
/opt/sybase/SYBSsa9/lib/libdbodm9_r.so.1
/opt/sybase/SYBSsa9/lib/libdbtasks9_r.so.1

Copy the following directories:

/opt/sybase/shared/jre_1.4.2_linux_sun_i386 (Linux)
/opt/sybase/shared/jre_1.4.2_solaris_sun_sparc (Solaris)
/opt/sybase/shared/jConnect-5_5

Create the following symbolic links in /opt/SYBSsa9/lib:

libdbjodbc9.so -> libdbjodbc9.so.1
libdbodbc9_r.so -> libdbodbc9_r.so.1
libdbodm9_r.so -> libdbodm9_r.so.1
libdbtasks9_r.so -> libdbtasks9_r.so.1

Create the following symbolic links in /opt/Sybase/SYBSsa9:

jre142 -> /opt/sybase/shared/jre_1.4.2_linux_sun_i386 (Linux)
jre142 -> /opt/sybase/shared/jre_1.4.2_solaris_sun_sparc (Solaris)
shared -> /opt/sybase/shared


Interactive SQL files

Copy the following files from your reference installation:

/opt/sybase/SYBSsa9/bin/dbisql
/opt/sybase/SYBSsa9/java/dbmaen9.jar
/opt/sybase/SYBSsa9/java/isql.jar
/opt/sybase/SYBSsa9/java/jlogon.jar
/opt/sybase/SYBSsa9/java/xerces.jar
/opt/sybase/SYBSsa9/java/xml4j.jar
/opt/sybase/SYBSsa9/lib/libdblib9_r.so.1
/opt/sybase/SYBSsa9/lib/libdbtool9_r.so.1
/opt/sybase/SYBSsa9/res/asa.cvf
/opt/sybase/SYBSsa9/res/dblgen9.res
/opt/sybase/shared/java/HelpManager11.jar
/opt/sybase/shared/java/JComponents142.jar
/opt/sybase/shared/java/SCEditor142.jar
/opt/sybase/shared/java/jsyblib142.jar
/opt/sybase/shared/sun/javahelp-1_1/jh.jar

Create the following symbolic links in /opt/SYBSsa9/lib:

libdblib9_r.so -> libdblib9_r.so.1
libdbtool9_r.so -> libdbtool9_r.so.1


Sybase Central with the Adaptive Server Anywhere plug-in

Copy the following files from your reference installation:

/opt/sybase/SYBSsa9/bin/dbisql
/opt/sybase/SYBSsa9/java/asa.jar
/opt/sybase/SYBSsa9/java/asaplugin.jar
/opt/sybase/SYBSsa9/java/dbmaen9.jar
/opt/sybase/SYBSsa9/java/debugger.jar
/opt/sybase/SYBSsa9/java/isql.jar
/opt/sybase/SYBSsa9/java/jlogon.jar
/opt/sybase/SYBSsa9/java/jodbc.jar
/opt/sybase/SYBSsa9/java/xerces.jar
/opt/sybase/SYBSsa9/java/xml4j.jar
/opt/sybase/SYBSsa9/lib/libdblib9_r.so.1
/opt/sybase/SYBSsa9/lib/libdbput9_r.so.1
/opt/sybase/SYBSsa9/lib/libdbtool9_r.so.1
/opt/sybase/SYBSsa9/res/asa.cvf
/opt/sybase/SYBSsa9/res/dblgen9.res
/opt/sybase/shared/java/HelpManager11.jar
/opt/sybase/shared/java/JComponents142.jar
/opt/sybase/shared/java/SCEditor142.jar
/opt/sybase/shared/java/jsyblib142.jar
/opt/sybase/shared/sun/javahelp-1_1/jh.jar
/opt/sybase/shared/sybcentral43/jcchart400K.jar
/opt/sybase/shared/sybcentral43/scjview
/opt/sybase/shared/sybcentral43/scvwen43.jar
/opt/sybase/shared/sybcentral43/sybasecentral.jar

Create the following symbolic links in /opt/SYBSsa9/lib:

libdblib9_r.so -> libdblib9_r.so.1
libdbput9_r.so -> libdbput9_r.so.1
libdbtool9_r.so -> libdbtool9_r.so.1

Create the following links in /opt/sybase/shared/sybcentral43:

jre142 -> /opt/sybase/shared/jre_1.4.2_linux_sun_i386 (Linux)
jre142 -> /opt/sybase/shared/jre_1.4.2_solaris_sun_sparc (Solaris)


Sybase Central with the MobiLink plug-in

Copy the following files from your reference installation:

/opt/sybase/SYBSsa9/java/asa.jar
/opt/sybase/SYBSsa9/java/dbmaen9.jar
/opt/sybase/SYBSsa9/java/jlogon.jar
/opt/sybase/SYBSsa9/java/jodbc.jar
/opt/sybase/SYBSsa9/java/mlplugin.jar
/opt/sybase/SYBSsa9/lib/libdblib9_r.so.1
/opt/sybase/SYBSsa9/lib/libdbmlput9_r.so.1
/opt/sybase/SYBSsa9/lib/libdbtool9_r.so.1
/opt/sybase/shared/java/HelpManager11.jar
/opt/sybase/shared/java/JComponents142.jar
/opt/sybase/shared/java/SCEditor142.jar
/opt/sybase/shared/java/jsyblib142.jar
/opt/sybase/shared/sun/javahelp-1_1/jh.jar
/opt/sybase/shared/sybcentral43/jcchart400K.jar
/opt/sybase/shared/sybcentral43/scjview
/opt/sybase/shared/sybcentral43/scvwen43.jar
/opt/sybase/shared/sybcentral43/sybasecentral.jar

Copy this entire directory:

/opt/sybase/SYBSsa9/drivers

Create the following symbolic links in /opt/sybase/SYBSsa9/lib:

libdblib9_r.so -> libdblib9_r.so.1
libdbmlput9_r.so -> libdbmlput9_r.so.1
libdbtool9_r.so -> libdbtool9_r.so.1

Create the following symbolic links in /opt/sybase/shared/sybcentral43:

jre142 -> /opt/sybase/shared/jre_1.4.2_linux_sun_i386 (Linux)
jre142 -> /opt/sybase/shared/jre_1.4.2_solaris_sun_sparc (Solaris)


The Adaptive Server Anywhere Console

Copy the following files from your reference installation:

/opt/sybase/SYBSsa9/bin/dbconsole
/opt/sybase/SYBSsa9/java/DBConsole.jar
/opt/sybase/SYBSsa9/java/dbmaen9.jar
/opt/sybase/SYBSsa9/java/jlogon.jar
/opt/sybase/SYBSsa9/java/jodbc.jar
/opt/sybase/SYBSsa9/lib/libdblib9_r.so.1
/opt/sybase/SYBSsa9/lib/libdbtool9_r.so.1
/opt/sybase/SYBSsa9/res/asa.cvf
/opt/sybase/SYBSsa9/res/dblgen9.res
/opt/sybase/shared/java/HelpManager11.jar
/opt/sybase/shared/java/JComponents142.jar
/opt/sybase/shared/java/SCEditor142.jar
/opt/sybase/shared/java/jsyblib142.jar
/opt/sybase/shared/sun/javahelp-1_1/jh.jar

Create the following symbolic links in /opt/sybase/SYBSsa9/lib:

libdblib9_r.so   -> libdblib9_r.so.1
libdbtool9_r.so  -> libdbtool9_r.so.1


International message and help files

All displayed text and online help for the administration tools have been translated from English into French, German, Japanese, and simplified Chinese. The resources for each language are in separate files. The English files contain en in the file names. French files have similar names, but use fr instead of en. German file names contain de, Japanese file names contain ja, and Chinese files contain zh.

In the preceding procedures, only the English files were listed. If you want to install support for different languages, you have to add the resource and help files for those other languages. The translated files are as follows:

dbmaxx9.jar – SQL Anywhere Help Files
dbmaen9.jar   English
dbmafr9.jar   French
dbmade9.jar   German
dbmaja9.jar   Japanese
dbmazh9.jar   Chinese
dblgxx9.res – Adaptive Server Anywhere Messages Files
dblgen9.res   English
dblgfr9.res   French
dblgde9.res   German
dblgja9.res   Japanese
dblgzh9.res   Chinese
scvwen43.jar – Sybase Central Help Files
scvwen43.jar  English
scvwfr43.jar  French
scvwde43.jar  German
scvwja43.jar  Japanese
scvwzh43.jar  Chinese

These files are included with localized versions of SQL Anywhere Studio.


Step 3: Setting environment variables

To run the administration tools, a number of environment variables must be defined or modified. This is usually done in the asa_config.sh file, which is created by the SQL Anywhere Studio installer, but you have the flexibility to do this however is most appropriate for your application.

  1. Set the PATH to include the following:

    /opt/Sybase/SYBsa9/bin

    If you are deploying Sybase Central, you must also add

    /opt/sybase/shared/sybcentral43

  2. Set LD_LIBRARY_PATH to include the following:

    /opt/sybase/SYBsa9/jre142/lib/i386/client
/opt/sybase/SYBsa9/jre142/lib/i386
/opt/sybase/SYBsa9/jre142/lib/i386/native_threads

    If you are deploying the MobiLink plug-in, you must also include

    /opt/sybase/SYBsa9/drivers

  3. Set the following environment variables:

    ASANY9="/opt/sybase/SYBsa9"
ASANYSH="/opt/sybase/shared"


Step 4: Register the Sybase Central plug-ins

This step involves the configuration of Sybase Central. If you are not installing Sybase Central, you can skip it.

Sybase Central uses a configuration file that lists installed plug-ins. The file is called .scRepository. It resides in the same directory as scjview ( /opt/sybase/shared/sybcentral43).

Your installer must create this file. Note that it contains full paths to a number of JAR files that may change depending on where the software is installed.

The following is a sample .scRepository file that contains information for the Adaptive Server Anywhere and MobiLink plug-ins. Some entries have been split across multiple lines for display purposes. When you create a .scRepository file, each entry must be entered on a single line.

SCRepositoryInfo/Version=4
#
Providers/asa90/Version=9.0.2.0000
Providers/asa90/UseClassloader=true
Providers/asa90/Classpath=\_opt\_sybase\_SYBSsa9\_java\_asaplugin.jar
Providers/asa90/Name=Adaptive Server Anywhere 9
Providers/asa90/AdditionalClasspath=
  \_opt\_sybase\_SYBSsa9\_java\_isql.jar:
  \_opt\_sybase\_SYBSsa9\_java\_asa.jar:
  \_opt\_sybase\_SYBSsa9\_java\_xerces.jar:
  \_opt\_sybase\_SYBSsa9\_java\_xml4j.jar:
  \_opt\_sybase\_SYBSsa9\_java\_jlong.jar:
  \_opt\_sybase\_SYBSsa9\_java\_debugger.jar:
  \_opt\_sybase\_SYBSsa9\_java\_jlogon.jar:
  \_opt\_sybase\_SYBSsa9\_java\_jodbc.jar:
  \_opt\_sybase\_shared\_java\_JComponents142.jar:
  \_opt\_sybase\_shared\_jConnect-5_5\_classes\_jconn2.jar
Providers/asa90/Provider=com.sybase.asa.plugin.ASAPlugin
Providers/asa90/ProviderId=asa90
Providers/asa90/InitialLoadOrder=0
#
Providers/mobilink90/Version=9.0.2.0000
Providers/mobilink90/UseClassloader=true
Providers/mobilink90/Classpath=\_opt\_sybase\_SYBSsa9\_java\_mlplugin.jar
Providers/mobilink90/Name=MobiLink Synchronization 9
Providers/mobilink90/AdditionalClasspath=
  \_opt\_sybase\_SYBSsa9\_java\_asa.jar:
  \_opt\_sybase\_SYBSsa9\_java\_jlogon.jar:
  \_opt\_sybase\_SYBSsa9\_java\_jodbc.jar:
  \_opt\_sybase\_shared\_jConnect-5_5\_classes\_jconn2.jar
Providers/mobilink90/Provider=com.sybase.mobilink.plugin.MLPlugin
Providers/mobilink90/ProviderId=mobilink90
Providers/mobilink90/InitialLoadOrder=0
Notes

  • Your installer should write out a file similar to this one. The only changes required are the fully-qualified paths to the JAR files in the Classpath and AdditionalClasspath lines.

  • The AdditionalClasspath lines shown above have wrapped to take up additional lines. They must be on a single line in the .scRepository file.

  • Forward slash characters (/) are represented with an escape sequence of \_ in the .scRepository file.

  • The first line indicates the version of the .scRepository file.

  • The lines beginning with # are comments.

  • The 8 lines following the first comment line are the information for the Adaptive Server Anywhere plug-in. These are followed by another comment line, and then the information for the MobiLink plug-in.

  • The file should contain information only about the plug-ins you are deploying. For example, if you are not deploying the MobiLink plug-in, do not supply the last section of the file (the lines that start Providers/mobilink90).

For more information about deploying databases and database applications, see Deploying Databases and Applications.


Deploying database servers

You can deploy a database server by making the SQL Anywhere Studio Setup program available to your end-users. By selecting the proper option, each end-user is guaranteed of getting the files they need.

The simplest way to deploy a personal database server or a network database server is to use the supplied InstallShield objects. For more information, see Using InstallShield for deployment.

In order to run a database server, you need to install a set of files. The files are listed in the following table. All redistribution of these files is governed by the terms of your license agreement. You must confirm whether you have the right to redistribute the database server files before doing so.

Windows | UNIX | NetWare
dbeng9.exe | dbeng9 | N/A
dbsrv9.exe | dbsrv9 | dbsrv9.nlm
dbserv9.dll | libdbserv9.so, libdbtasks9_r.so | N/A
dblgen9.dll | dblgen9.res | dblgen9.res
dbjava9.dll (1) | libdbjava9.so (1) | dbjava9.nlm (1)
dbctrs9.dll | N/A | N/A
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) | N/A | N/A
dbunic9.dll | libunic.so | N/A
asa.cvf | asa.cvf | asa.cvf
charsets\ directory | charsets/ directory | N/A

1. Required only if using Java in the database. For databases initialized using JDK 1.1, distribute asajdbc.zip. For databases initialized using JDK 1.2 or JDK 1.3, distribute asajrt13.zip.

2. Required only if using system extended stored procedures and functions (xp_).

3. Install such that the CLASSPATH environment variable can locate classes in this file.

4. Required on Windows 95/98/Me if using dynamic cache sizing.

Registry entry

When deploying database servers on Windows NT/2000/XP, add the following registry key to ensure that messages written to the Event Log are formatted correctly:

HKEY_LOCAL_MACHINE\
   SYSTEM\
      CurrentControlSet\
         Services\
        Eventlog\
     Application\
      ASA 9.0\
         ODBC Data Sources

Within this key, add a REG_SZ value named EventMessageFile and assign it the data value of the fully qualified location of dblgen.dll, for example, C:\Program Files\Sybase\SQL Anywhere 9\win32\dblgen9.dll. The English DLL, dblgen.dll, can be specified regardless of the deployment language.

Notes

  • Depending on your situation, you should choose whether to deploy the personal database server (dbeng9) or the network database server (dbsrv9).

  • The Java DLL (dbjava9.dll) is required only if the database server is to use the Java in the Database functionality.

  • The table does not include files needed to run utilities such as dbbackup.

    For information about deploying utilities, see Deploying administration tools.

  • The zip files are required only for applications that use Java in the database, and must be installed into a location in the user's CLASSPATH environment variable.

Deploying databases


Deploying databases

You deploy a database file by installing the database file onto your end user's disk.

As long as the database server shuts down cleanly, you do not need to deploy a transaction log file with your database file. When your end-user starts running the database, a new transaction log is created.

For SQL Remote applications, the database should be created in a properly synchronized state, in which case no transaction log is needed. You can use the Extraction utility for this purpose.

Deploying databases on read-only media


Deploying databases on read-only media

You can distribute databases on read-only media, such as a CD-ROM, as long as you run them in read-only mode or use a write file.

For more information on running databases in read-only mode, see -r server option.

To enable changes to be made to Adaptive Server Anywhere databases distributed on read-only media such as a CD-ROM, you can use a write file. The write file records changes made to a read-only database file, and is located on a read/write storage media such as a hard disk.

In this case, the database file is placed on the CD-ROM, while the write file is placed on disk. The connection is made to the write file, which maintains a transaction log file on disk.

For more information on write files, see Working with write files (deprecated).


Deploying embedded database applications

This section provides information on deploying embedded database applications, where the application and the database both reside on the same machine.

An embedded database application includes the following:

  • Client application This includes the Adaptive Server Anywhere client requirements.

    For information on deploying client applications, see Deploying client applications.

  • Database server The Adaptive Server Anywhere personal database server.

    For information on deploying database servers, see Deploying database servers.

  • SQL Remote If your application uses SQL Remote replication, you must deploy the SQL Remote Message Agent.

  • The database You must deploy a database file holding the data the application uses.


Deploying personal servers

When you deploy an application that uses the personal server, you need to deploy both the client application components and the database server components.

The language resource library (dblgen9.dll) is shared between the client and the server. You need only one copy of this file.

It is recommended that you follow the Adaptive Server Anywhere installation behavior, and install the client and server files in the same directory.

Remember to provide the Java zip files and the Java DLL if your application takes advantage of Java in the Database.


Deploying database utilities

If you need to deploy database utilities (such as dbbackup.exe) along with your application, then you need the utility executable together with the following additional files:

Description | Windows | UNIX
Database tools library | dbtool9.dll | libdbtools9.so, libdbtasks9.so
Language resource library | dblgen9.dll | dblgen9.res
Connect dialog (dbisqlc only) | dbcon9.dll |
Notes

  • The database tools are embedded SQL applications, and you must supply the files required for such applications, as listed in Deploying embedded SQL clients.

  • For multi-threaded applications on UNIX, use libdbtools9_r.so and libdbtasks9_r.so.


Deploying SQL Remote

If you are deploying the SQL Remote Message Agent, you need to include the following files:

Description | Windows | UNIX
Message Agent | dbremote.exe | dbremote
Database tools library | dbtool9.dll | libdbtools9.so, libdbtasks9.so
Language resource library | dblgen9.dll | dblgen9.res
VIM message link library 1 | dbvim9.dll |
SMTP message link library 1 | dbsmtp9.dll |
FILE message link library 1 | dbfile9.dll | libdbfile9.so
FTP message link library 1 | dbftp9.dll |
MAPI message link library 1 | dbmapi9.dll |
Interface Library | dblib9.dll |

1 Only deploy the library for the message link you are using.

It is recommended that you follow the Adaptive Server Anywhere installation behavior, and install the SQL Remote files in the same directory as the Adaptive Server Anywhere files.

For multi-threaded applications on UNIX, use libdbtools9_r.so and libdbtasks9_r.so.


SQL Preprocessor Error Messages

About this chapter

This chapter presents a list of all SQL preprocessor errors and warnings.


SQL Preprocessor error messages indexed by error message value

Message value | Message
2601 | subscript value %1 too large
2602 | combined pointer and arrays not supported for host types
2603 | only one dimensional arrays supported for char type
2604 | VARCHAR type must have a length
2605 | arrays of VARCHAR not supported
2606 | VARCHAR host variables cannot be pointers
2607 | initializer not allowed on VARCHAR host variable
2608 | FIXCHAR type must have a length
2609 | arrays of FIXCHAR not supported
2610 | arrays of this type not supported
2611 | precision must be specified for decimal type
2612 | arrays of decimal not allowed
2613 | Unknown hostvar type
2614 | invalid integer
2615 | '%1' host variable must be a C string type
2617 | '%1' symbol already defined
2618 | invalid type for SQL statement variable
2619 | Cannot find include file '%1'
2620 | host variable '%1' is unknown
2621 | indicator variable '%1' is unknown
2622 | invalid type for indicator variable '%1'
2623 | invalid host variable type on '%1'
2625 | host variable '%1' has two different definitions
2626 | statement '%1' not previously prepared
2627 | cursor '%1' not previously declared
2628 | unknown statement '%1'
2629 | host variables not allowed for this cursor
2630 | host variables specified twice - on declare and open
2631 | must specify a host list or using clause on %1
2633 | no INTO clause on SELECT statement
2634 | incorrect SQL language usage -- that is a '%1' extension
2635 | incorrect Embedded SQL language usage -- that is a '%1' extension
2636 | incorrect Embedded SQL syntax
2637 | missing ending quote of string
2639 | token too long
2640 | '%1' host variable must be an integer type
2641 | must specify an SQLDA on a DESCRIBE
2642 | Two SQLDAs specified of the same type (INTO or USING)
2646 | cannot describe static cursors
2647 | Macros cannot be redefined
2648 | Invalid array dimension
2649 | invalid descriptor index
2650 | invalid field for SET DESCRIPTOR
2651 | field used more than once in SET DESCRIPTOR statement
2652 | data value must be a host variable
2660 | Into clause not allowed on declare cursor - ignored
2661 | unrecognized SQL syntax
2662 | unknown SQL function '%1'
2663 | wrong number of parameters to SQL function '%1'
2664 | static statement names will not work properly if used by 2 threads
2665 | host variable '%1' has been redefined
2666 | vendor extension
2667 | intermediate SQL feature
2668 | full SQL feature
2669 | transact SQL extension
2680 | no declare section and no INCLUDE SQLCA statement
2681 | unable to open temporary file
2682 | error reading temporary file
2683 | error writing output file
2690 | Inconsistent number of host variables for this cursor
2691 | Inconsistent host variable types for this cursor
2692 | Inconsistent indicator variables for this cursor
2693 | Feature not available with UltraLite
2694 | no OPEN for cursor '%1'
2695 | no FETCH or PUT for cursor '%1'
2696 | Host variable '%1' is in use more than once with different indicators
2697 | long binary/long varchar size limit is 65 535 for UltraLite


SQLPP errors

This section lists messages generated by the SQL preprocessor. The messages may be errors or warnings, or either depending on which command-line options are set.

For more information about the SQL Preprocessor and its command-line options, see The SQL preprocessor.

'%1' host variable must be a C string type
'%1' host variable must be an integer type
'%1' symbol already defined
Cannot find include file '%1'
FIXCHAR type must have a length
Feature not available with UltraLite
Host variable '%1' is in use more than once with different indicators
Inconsistent host variable types for this cursor
Inconsistent indicator variables for this cursor
Inconsistent number of host variables for this cursor
Into clause not allowed on declare cursor - ignored
Invalid array dimension
Macros cannot be redefined
Two SQLDAs specified of the same type (INTO or USING)
Unknown hostvar type
VARCHAR host variables cannot be pointers
VARCHAR type must have a length
arrays of FIXCHAR not supported
arrays of VARCHAR not supported
arrays of decimal not allowed
arrays of this type not supported
cannot describe static cursors
combined pointer and arrays not supported for host types
cursor '%1' not previously declared
data value must be a host variable
error reading temporary file
error writing output file
field used more than once in SET DESCRIPTOR statement
full SQL feature
host variable '%1' has been redefined
host variable '%1' has two different definitions
host variable '%1' is unknown
host variables not allowed for this cursor
host variables specified twice - on declare and open
incorrect Embedded SQL language usage -- that is a '%1' extension
incorrect Embedded SQL syntax
incorrect SQL language usage -- that is a '%1' extension
indicator variable '%1' is unknown
initializer not allowed on VARCHAR host variable
intermediate SQL feature
invalid descriptor index
invalid field for SET DESCRIPTOR
invalid host variable type on '%1'
invalid integer
invalid type for indicator variable '%1'
invalid type for SQL statement variable
long binary/long varchar size limit is 65 535 for UltraLite
missing ending quote of string
must specify a host list or using clause on %1
must specify an SQLDA on a DESCRIBE
no FETCH or PUT for cursor '%1'
no INTO clause on SELECT statement
no OPEN for cursor '%1'
no declare section and no INCLUDE SQLCA statement
only one dimensional arrays supported for char type
precision must be specified for decimal type
statement '%1' not previously prepared
static statement names will not work properly if used by 2 threads
subscript value %1 too large
token too long
transact SQL extension
unable to open temporary file
unknown SQL function '%1'
unknown statement '%1'
unrecognized SQL syntax
vendor extension
wrong number of parameters to SQL function '%1'


'%1' host variable must be a C string type

Message value | Message Type
2615 | Error
Probable cause

A C string was required in an embedded SQL statement (for a cursor name, option name etc.) and the value supplied was not a C string.


'%1' host variable must be an integer type

Message value | Message Type
2640 | Error
Probable cause

You have used a host variable that is not of integer type in a statement where only an integer type host variable is allowed.


'%1' symbol already defined

Message value | Message Type
2617 | Error
Probable cause

You defined a host variable twice.


Cannot find include file '%1'

Message value | Message Type
2619 | Error
Probable cause

The specified include file was not found. Note that the preprocessor will use the INCLUDE environment variable to search for include files.


FIXCHAR type must have a length

Message value | Message Type
2608 | Error
Probable cause

You have used the DECL_FIXCHAR macro to declare a host variable of type FIXCHAR but have not specified a length.


Feature not available with UltraLite

Message value | Message Type
2693 | Flag (warning or error)
Probable cause

You have used a feature that is not supported by UltraLite.


Host variable '%1' is in use more than once with different indicators

Message value | Message Type
2696 | Error
Probable cause

You have used the same host variable multiple times with different indicator variables in the same statement. This is not supported.


Inconsistent host variable types for this cursor

Message value | Message Type
2691 | Error
Probable cause

You have used a host variable with a different type or length than the type or length previously used with the cursor. Host variable types must be consistent for the cursor.


Inconsistent indicator variables for this cursor

Message value | Message Type
2692 | Error
Probable cause

You have used an indicator variable when one was not previously used with the cursor, or you have not used an indicator variable when one was previously used with the cursor. Indicator variable usage must be consistent for the cursor.


Inconsistent number of host variables for this cursor

Message value | Message Type
2690 | Error
Probable cause

You have used a different number of host variables than the number previously used with the cursor. The number of host variables must be consistent for the cursor.


Into clause not allowed on declare cursor - ignored

Message value | Message Type
2660 | Warning
Probable cause

You have used an INTO clause on a DECLARE CURSOR statement. The INTO clause will be ignored.


Invalid array dimension

Message value | Message Type
2648 | Error
Probable cause

The array dimension of the variable is negative.


Macros cannot be redefined

Message value | Message Type
2647 | Error
Probable cause

A preprocessor macro has been defined twice, possibly in a header file.


Two SQLDAs specified of the same type (INTO or USING)

Message value | Message Type
2642 | Error
Probable cause

You have specified two INTO DESCRIPTOR or two USING DESCRIPTOR clauses for this statement.


Unknown hostvar type

Message value | Message Type
2613 | Error
Probable cause

You declared a host variable of a type not understood by the SQL preprocessor.


VARCHAR host variables cannot be pointers

Message value | Message Type
2606 | Error
Probable cause

You have attempted to declare a host variable as a pointer to a VARCHAR or BINARY. This is not a legal host variable type.


VARCHAR type must have a length

Message value | Message Type
2604 | Error
Probable cause

You have attempted to declare a VARCHAR or BINARY host variable using the DECL_VARCHAR or DECL_BINARY macro but have not specified a size for the array.


arrays of FIXCHAR not supported

Message value | Message Type
2609 | Error
Probable cause

You have attempted to declare a host variable as an array of FIXCHAR arrays. This is not a legal host variable type.


arrays of VARCHAR not supported

Message value | Message Type
2605 | Error
Probable cause

You have attempted to declare a host variable as an array of VARCHAR or BINARY. This is not a legal host variable type.


arrays of decimal not allowed

Message value | Message Type
2612 | Error
Probable cause

You have attempted to declare a host variable as an array of DECIMAL. A decimal array is not a legal host variable type.


arrays of this type not supported

Message value | Message Type
2610 | Error
Probable cause

You have attempted to declare a host variable array of a type that is not supported.


cannot describe static cursors

Message value | Message Type
2646 | Error
Probable cause

You have described a static cursor. When describing a cursor, the cursor name must be specified in a host variable.


combined pointer and arrays not supported for host types

Message value | Message Type
2602 | Error
Probable cause

You have used an array of pointers as a host variable. This is not legal.


cursor '%1' not previously declared

Message value | Message Type
2627 | Error
Probable cause

An embedded SQL cursor name has been used (in a FETCH, OPEN, CLOSE etc.) without first being declared.


data value must be a host variable

Message value | Message Type
2652 | Error
Probable cause

The variable used in the SET DESCRIPTOR statement hasn't been declared as a host variable.


error reading temporary file

Message value | Message Type
2682 | Error
Probable cause

An error occurred while reading from a temporary file.


error writing output file

Message value | Message Type
2683 | Error
Probable cause

An error occurred while writing to the output file.


field used more than once in SET DESCRIPTOR statement

Message value | Message Type
2651 | Error
Probable cause

The same keyword has been used more than once inside a single SET DESCRIPTOR statement.


full SQL feature

Message value | Message Type
2668 | Flag (warning or error)
Probable cause

You have used a full-SQL/92 feature and preprocessed with the -ee, -ei, -we or -wi flagging switch.


host variable '%1' has been redefined

Message value | Message Type
2665 | Warning
Probable cause

You have redefined the same host variable with a different host type. As far as the preprocessor is concerned, host variables are global; two host variables with different types cannot have the same name.


host variable '%1' has two different definitions

Message value | Message Type
2625 | Error
Probable cause

The same host variable name was defined with two different types within the same module. Note that host variable names are global to a C module.


host variable '%1' is unknown

Message value | Message Type
2620 | Error
Probable cause

You have used a host variable in a statement and that host variable has not been declared in a declare section.


host variables not allowed for this cursor

Message value | Message Type
2629 | Error
Probable cause

Host variables are not allowed on the declare statement for the specified cursor. If the cursor name is provided through a host variable, then you should use full dynamic SQL and prepare the statement. A prepared statement may have host variables in it.


host variables specified twice - on declare and open

Message value | Message Type
2630 | Error
Probable cause

You have specified host variables for a cursor on both the declare and the open statements. In the static case, you should specify the host variables on the declare statement. In the dynamic case, specify them on the open.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

SQL Preprocessor Error Messages

SQLPP errors

incorrect Embedded SQL language usage -- that is a '%1' extension

Message value | Message Type
2635 | Error


incorrect Embedded SQL syntax

Message value | Message Type
2636 | Error
Probable cause

An embedded SQL specific statement (OPEN, DECLARE, FETCH etc.) has a syntax error.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

SQL Preprocessor Error Messages

SQLPP errors

incorrect SQL language usage -- that is a '%1' extension

Message value | Message Type
2634 | Error


indicator variable '%1' is unknown

Message value | Message Type
2621 | Error
Probable cause

You have used a indicator variable in a statement and that indicator variable has not been declared in a declare section.


initializer not allowed on VARCHAR host variable

Message value | Message Type
2607 | Error
Probable cause

You can not specify a C variable initializer for a host variable of type VARCHAR or BINARY. You must initialize this variable in regular C executable code.


intermediate SQL feature

Message value | Message Type
2667 | Flag (warning or error)
Probable cause

You have used an intermediate-SQL/92 feature and preprocessed with the -ee or -we flagging switch.


invalid descriptor index

Message value | Message Type
2649 | Error
Probable cause

You have allocated less than one variable with the ALLOCATE DESCRIPTOR statement.


invalid field for SET DESCRIPTOR

Message value | Message Type
2650 | Error
Probable cause

An invalid or unknown keyword is present in a SET DESCRIPTOR statement. The keywords can only be TYPE, PRECISION, SCALE, LENGTH, INDICATOR, or DATA.


invalid host variable type on '%1'

Message value | Message Type
2623 | Error
Probable cause

You have used a host variable that is not a string type in a place where the preprocessor was expecting a host variable of a string type.


invalid integer

Message value | Message Type
2614 | Error
Probable cause

An integer was required in an embedded SQL statement (for a fetch offset, or a host variable array index, etc.) and the preprocessor was unable to convert what was supplied into an integer.


invalid type for indicator variable '%1'

Message value | Message Type
2622 | Error
Probable cause

Indicator variables must be of type short int. You have used a variable of a different type as an indicator variable.


invalid type for SQL statement variable

Message value | Message Type
2618 | Error
Probable cause

A host variable used as a statement identifier should be of type a_sql_statement_number. You attempted to use a host variable of some other type as a statement identifier.


long binary/long varchar size limit is 65 535 for UltraLite

Message value | Message Type
2697 | Error
Probable cause

When using DECL_LONGBINARY or DECL_LONGVARCHAR with UltraLite, the maximum size for the array is 64kb.


missing ending quote of string

Message value | Message Type
2637 | Error
Probable cause

You have specified a string constant in an embedded SQL statement, but there is no ending quote before the end of line or end of file.


must specify a host list or using clause on %1

Message value | Message Type
2631 | Error
Probable cause

The specified statement requires host variables to be specified either in a host variable list or from an SQLDA.


Web Links Browse Collapse Expand PDF Previous Next

ASA Programming Guide

SQL Preprocessor Error Messages

SQLPP errors

must specify an SQLDA on a DESCRIBE

Message value | Message Type
2641 | Error


no FETCH or PUT for cursor '%1'

Message value | Message Type
2695 | Error
Probable cause

A cursor is declared and opened, but is never used.


no INTO clause on SELECT statement

Message value | Message Type
2633 | Error
Probable cause

You specified an embedded static SELECT statement but you did not specify an INTO clause for the results.


no OPEN for cursor '%1'

Message value | Message Type
2694 | Error
Probable cause

A cursor is declared, and possibly used, but is never opened.


no declare section and no INCLUDE SQLCA statement

Message value | Message Type
2680 | Error
Probable cause

The EXEC SQL INCLUDE SQLCA statement is missing from the source file.


only one dimensional arrays supported for char type

Message value | Message Type
2603 | Error
Probable cause

You have attempted to declare a host variable as an array of character arrays. This is not a legal host variable type.


precision must be specified for decimal type

Message value | Message Type
2611 | Error
Probable cause

You must specify the precision when declaring a packed decimal host variable using the DECL_DECIMAL macro. The scale is optional.


statement '%1' not previously prepared

Message value | Message Type
2626 | Error
Probable cause

An embedded SQL statement name has been used (EXECUTE) without first being prepared.


static statement names will not work properly if used by 2 threads

Message value | Message Type
2664 | Warning
Probable cause

You have used a static statement name and preprocessed with the -r re-entrancy switch. Static statement names cause static variables to be generated that are filled in by the database. If two threads use the same statement, contention arises over this variable. Use a local host variable as the statement identifier instead of a static name.


subscript value %1 too large

Message value | Message Type
2601 | Error
Probable cause

You have attempted to index a host variable that is an array with a value too large for the array.


token too long

Message value | Message Type
2639 | Error
Probable cause

The SQL preprocessor has a maximum token length of 2K. Any token longer than 2K will produce this error. For constant strings in embedded SQL commands (the main place this error shows up) use string concatenation to make a longer string.


transact SQL extension

Message value | Message Type
2669 | Flag (warning or error)
Probable cause

You have used a Sybase Transact SQL feature that is not defined by SQL/92 and preprocessed with the -ee, -ei, -ef, -we, -wi or -wf flagging switch.


unable to open temporary file

Message value | Message Type
2681 | Error
Probable cause

An error occurred while attempting to open a temporary file.


unknown SQL function '%1'

Message value | Message Type
2662 | Warning
Probable cause

You have used a SQL function that is unknown to the preprocessor and will probably cause an error when the statement is sent to the database engine.


unknown statement '%1'

Message value | Message Type
2628 | Error
Probable cause

You attempted to drop an embedded SQL statement that doesn't exist.


unrecognized SQL syntax

Message value | Message Type
2661 | Warning
Probable cause

You have used a SQL statement that will probably cause a syntax error when the statement is sent to the database engine.


vendor extension

Message value | Message Type
2666 | Flag (warning or error)
Probable cause

You have used an Adaptive Server Anywhere feature that is not defined by SQL/92 and preprocessed with the -ee, -ei, -ef, -we, -wi or -wf flagging switch.


wrong number of parameters to SQL function '%1'

Message value | Message Type
2663 | Warning
Probable cause

You have used a SQL function with the wrong number of parameters. This will likely cause an error when the statement is sent to the database engine.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

Version 9.0.2

DC38131-01-0902-01

October 2004

Copyright
About This Manual
Database Error Messages
MobiLink Synchronization Server Error Messages
MobiLink Synchronization Server Warning Messages
MobiLink Communication Error Messages


Copyright

Copyright © 1989–2004 Sybase, Inc. Portions copyright © 2001–2004 iAnywhere Solutions, Inc. All rights reserved.

No part of this publication may be reproduced, transmitted, or translated in any form or by any means, electronic, mechanical, manual, optical, or otherwise, without the prior written permission of iAnywhere Solutions, Inc. iAnywhere Solutions, Inc. is a subsidiary of Sybase, Inc.

Sybase, SYBASE (logo), 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-Library, APT-Translator, ASEP, AvantGo, AvantGo Application Alerts, AvantGo Mobile Delivery, AvantGo Mobile Document Viewer, AvantGo Mobile Inspection, AvantGo Mobile Marketing Channel, AvantGo Mobile Pharma, AvantGo Mobile Sales, AvantGo Pylon, AvantGo Pylon Application Server, AvantGo Pylon Conduit, AvantGo Pylon PIM Server, AvantGo Pylon Pro, Backup Server, BayCam, Bit-Wise, BizTracker, Certified PowerBuilder Developer, Certified SYBASE Professional, Certified SYBASE Professional Logo, 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, Dynamic Mobility Model, Dynamo, e-ADK, E-Anywhere, e-Biz Integrator, 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 Portal (logo), Enterprise SQL Server Manager, Enterprise Work Architecture, Enterprise Work Designer, Enterprise Work Modeler, eProcurement Accelerator, eremote, Everything Works Better When Everything Works Together, EWA, E-Whatever, Financial Fusion, Financial Fusion (and design), Financial Fusion Server, Formula One, Fusion Powered e-Finance, Fusion Powered Financial Destinations, Fusion Powered STP, Gateway Manager, GeoPoint, GlobalFIX, iAnywhere, iAnywhere Solutions, ImpactNow, Industry Warehouse Studio, InfoMaker, Information Anywhere, Information Everywhere, InformationConnect, InstaHelp, Intelligent Self-Care, InternetBuilder, iremote, iScript, Jaguar CTS, jConnect for JDBC, KnowledgeBase, Logical Memory Manager, Mail Anywhere Studio, MainframeConnect, Maintenance Express, Manage Anywhere Studio, MAP, M-Business Channel, M-Business Network, M-Business Server, MDI Access Server, MDI Database Gateway, media.splash, Message Anywhere Server, MetaWorks, MethodSet, ML Query, MobiCATS, My AvantGo, My AvantGo Media Channel, My AvantGo Mobile Marketing, MySupport, Net-Gateway, Net-Library, New Era of Networks, Next Generation Learning, Next Generation Learning Studio, O DEVICE, OASiS, OASiS logo, 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++, Orchestration Studio, Partnerships that Work, PB-Gen, PC APT Execute, PC DB-Net, PC Net Library, PhysicalArchitect, Pocket PowerBuilder, PocketBuilder, Power Through Knowledge, power.stop, Power++, 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, QAnywhere, Rapport, Relational Beans, RepConnector, Replication Agent, Replication Driver, Replication Server, Replication Server Manager, Replication Toolkit, Report Workbench, Report-Execute, Resource Manager, RW-DisplayLib, RW-Library, 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 (logo), 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, TotalFix, TradeForce, Transact-SQL, Translation Toolkit, Turning Imagination Into Reality, UltraLite, UltraLite.NET, UNIBOM, Unilib, Uninull, Unisep, Unistring, URK Runtime Kit for UniCode, Versacore, Viewer, 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, and XP Server are trademarks of Sybase, Inc. or its subsidiaries.

All other trademarks are property of their respective owners.

Last modified: March 2001. Part Number: XXXXXX.


About This Manual

Subject

This book provides a complete listing of Adaptive Server Anywhere error messages together with diagnostic information.

Audience

This manual is for all users of Adaptive Server Anywhere. It is to be used in conjunction with other manuals in the documentation set


SQL Anywhere Studio documentation

This book is part of the SQL Anywhere documentation set. This section describes the books in the documentation set and how you can use them.

The SQL Anywhere Studio documentation

The SQL Anywhere Studio documentation is available in a variety of forms: in an online form that combines all books in one large help file; as separate PDF files for each book; and as printed books that you can purchase. The documentation consists of the following books:

  • Introducing SQL Anywhere Studio This book provides an overview of the SQL Anywhere Studio database management and synchronization technologies. It includes tutorials to introduce you to each of the pieces that make up SQL Anywhere Studio.

  • What's New in SQL Anywhere Studio This book is for users of previous versions of the software. It lists new features in this and previous releases of the product and describes upgrade procedures.

  • Adaptive Server Anywhere Database Administration Guide This book covers material related to running, managing, and configuring databases and database servers.

  • Adaptive Server Anywhere SQL User's Guide This book describes how to design and create databases; how to import, export, and modify data; how to retrieve data; and how to build stored procedures and triggers.

  • Adaptive Server Anywhere SQL Reference Manual This book provides a complete reference for the SQL language used by Adaptive Server Anywhere. It also describes the Adaptive Server Anywhere system tables and procedures.

  • Adaptive Server Anywhere Programming Guide This book describes how to build and deploy database applications using the C, C++, and Java programming languages. Users of tools such as Visual Basic and PowerBuilder can use the programming interfaces provided by those tools. It also describes the Adaptive Server Anywhere ADO.NET data provider.

  • Adaptive Server Anywhere Error Messages This book provides a complete listing of Adaptive Server Anywhere error messages together with diagnostic information.

  • SQL Anywhere Studio Security Guide This book provides information about security features in Adaptive Server Anywhere databases. Adaptive Server Anywhere 7.0 was awarded a TCSEC (Trusted Computer System Evaluation Criteria) C2 security rating from the U.S. Government. This book may be of interest to those who wish to run the current version of Adaptive Server Anywhere in a manner equivalent to the C2-certified environment.

  • MobiLink Synchronization User's Guide This book describes how to use the MobiLink data synchronization system for mobile computing, which enables sharing of data between a single Oracle, Sybase, Microsoft or IBM database and many Adaptive Server Anywhere or UltraLite databases.

  • MobiLink Synchronization Reference This book is a reference guide to MobiLink command line options, synchronization scripts, SQL statements, stored procedures, utilities, system tables, and error messages.

  • MobiLink Server-Initiated Synchronization User's Guide This book describes MobiLink server-initiated synchronization, a feature of MobiLink that allows you to initiate synchronization from the consolidated database.

  • QAnywhere User's Guide This manual describes MobiLink QAnywhere, a messaging platform that enables the development and deployment of messaging applications for mobile and wireless clients, as well as traditional desktop and laptop clients.

  • iAnywhere Solutions ODBC Drivers This book describes how to set up ODBC drivers to access consolidated databases other than Adaptive Server Anywhere from the MobiLink synchronization server and from Adaptive Server Anywhere remote data access.

  • SQL Remote User's Guide This book describes all aspects of the SQL Remote data replication system for mobile computing, which enables sharing of data between a single Adaptive Server Anywhere or Adaptive Server Enterprise database and many Adaptive Server Anywhere databases using an indirect link such as e-mail or file transfer.

  • SQL Anywhere Studio Help This book includes the context-sensitive help for Sybase Central, Interactive SQL, and other graphical tools. It is not included in the printed documentation set.

  • UltraLite Database User's Guide This book is intended for all UltraLite developers. It introduces the UltraLite database system and provides information common to all UltraLite programming interfaces.

  • UltraLite Interface Guides A separate book is provided for each UltraLite programming interface. Some of these interfaces are provided as UltraLite components for rapid application development, and others are provided as static interfaces for C, C++, and Java development.

In addition to this documentation set, PowerDesigner and InfoMaker include their own online documentation.

Documentation formats

SQL Anywhere Studio provides documentation in the following formats:

  • Online documentation The online documentation contains the complete SQL Anywhere Studio documentation, including both the books and the context-sensitive help for SQL Anywhere tools. The online documentation is updated with each maintenance release of the product, and is the most complete and up-to-date source of documentation.

    To access the online documentation on Windows operating systems, choose Start > Programs > SQL Anywhere 9 > Online Books. You can navigate the online documentation using the HTML Help table of contents, index, and search facility in the left pane, as well as using the links and menus in the right pane.

    To access the online documentation on UNIX operating systems, see the HTML documentation under your SQL Anywhere installation.

  • PDF books The SQL Anywhere books are provided as a set of PDF files, viewable with Adobe Acrobat Reader.

    The PDF books are accessible from the online books, or from the Windows Start menu.

  • Printed books The complete set of books is available from Sybase sales or from eShop, the Sybase online store at [external link] http://eshop.sybase.com/eshop/documentation.


Database Error Messages

About this chapter

This chapter lists all database error messages reported by Adaptive Server Anywhere. Many of the errors contain the characters %1, %2 and so on. These are replaced by the parameters to the error message.

Each error has a numeric error code, called the SQLCODE. Negative codes are considered errors; positive codes are warnings. The SQLCODE 0 indicates successful completion.

The full listing of the error messages is ordered by SQLCODE value. To find an error message description if you do not have the SQLCODE value, look up the SQLCODE in the alphabetic or SQLSTATE listing.

Error messages indexed by Adaptive Server Anywhere SQLCODE
Error messages indexed by SQLSTATE
Error messages indexed by Sybase error code
Alphabetic list of error messages
Internal errors (assertion failed)


Error messages indexed by Adaptive Server Anywhere SQLCODE

Adaptive Server Anywhere SQLCODE | Error message
–1028 | Connection attempting BACKUP has uncommitted transactions
–1027 | Service type does not allow '%1' attribute
–1026 | USING attribute cannot coexist with FORMAT or GROUP attributes
–1025 | Duplicate attribute '%1' in service
–1024 | Unsupported property '%1' in service USING attribute
–1023 | Missing value for attribute '%1' in service
–1022 | Invalid value for attribute '%1' in service
–1021 | Invalid backup operation
–1020 | Unable to start specified database: Can't use log file '%1' since it is shorter than expected
–1019 | Unable to start specified database: Can't use log file '%1' since the database file has been used more recently
–1018 | Unable to start specified database: Can't use log file '%1' since the offsets don't match the offsets in the database file
–1017 | Unable to start specified database: '%1': transaction log file not found
–1016 | Unable to start specified database: Can't use log file '%1' since it has been used more recently than the database file
–1015 | Unable to start specified database: The database for write file '%1' has an incorrect modification time
–1014 | Unable to start specified database: '%1' is compressed -- use a write file or open in read-only mode
–1013 | Unable to start specified database: '%1' found, but database not found
–1012 | Unable to start specified database: '%1' must be upgraded to start with this server (capability %2 missing).
–1011 | Unable to start specified database: Unknown encryption algorithm.
–1010 | Unable to start specified database: '%1' not expecting any operations in transaction log
–1009 | Unable to start specified database: The transaction log '%1' or its mirror '%2' is invalid
–1008 | Unable to start specified database: '%1' is an invalid transaction log mirror
–1007 | Unable to start specified database: '%1' is an invalid transaction log
–1006 | Unable to start specified database: '%1' is not a valid database file
–1005 | Unable to start specified database: '%1' was created by a different version of the software
–1004 | Unable to start specified database: '%1' is not a database
–1003 | Too many distinct group mappings for integrated user
–1002 | The option '%1' is not recognized.
–1001 | Parameter '%1' in procedure or function '%2' does not have a default value
–1000 | Temporary space limit exceeded
–999 | Invalid request log format on line %1
–998 | Cannot close a remote JDBC connection that is not the current connection.
–997 | Specified local connection is not to the current database.
–996 | Specified local connection not found.
–995 | Warning detected when optimizing SELECT INTO is treated as an error
–994 | Too many arguments for function or procedure '%1'
–993 | LOAD TABLE not allowed on temporary table with ON COMMIT DELETE ROWS
–992 | The specified listener could not be registered
–991 | The %1 attribute '%2' is not valid
–990 | The secure connection to the remote host failed
–989 | NAMESPACE attribute is not valid with procedure type '%1'
–988 | Invalid response from the HTTP server
–987 | Invalid procedure subtype '%1' for type '%2'
–986 | Invalid procedure type '%1'
–985 | Could not load the encryption DLL '%1'
–984 | Could not initialize the encryption DLL: '%1'
–983 | HTTP request failed. Status code '%1'
–982 | Connection timed out
–981 | Unable to connect to the remote host specified by '%1'
–980 | The URI '%1' is invalid
–979 | Output file cannot be written
–978 | Output file directory does not exist
–977 | UltraLite runtime library is incompatible with the database file
–976 | Could not load the encryption DLL "%1"
–975 | Incorrect volume ID for '%1'
–974 | File I/O failed for '%1'
–973 | The string is too long (%1)
–972 | Database page size too small
–971 | Checksums are not enabled in this database
–970 | Invalid hint specified for table '%1'
–969 | Required operators excluded
–968 | User '%1' already has EXECUTE permission
–967 | Backup file '%1' already exists
–966 | Composite ORDER BY not allowed with RANGE
–965 | Window function requires ORDER BY
–964 | Window function used in predicate
–963 | Password contains an illegal character
–962 | Argument to GROUPING aggregate must be a grouping column in the GROUP BY clause
–961 | Input string is not base64-encoded
–960 | Decompression error: %1
–959 | Compression error: %1
–958 | Password cannot be longer than %1 characters
–957 | Invalid preceding or following size in OLAP function
–956 | Information for synchronization is incomplete or invalid, check '%1'
–955 | This connection already exists
–954 | The database '%1' was not found
–953 | A schema upgrade is not currently allowed
–952 | The status of the last synchronization upload is unknown
–951 | Cannot access schema file '%1'
–950 | Frame not allowed for window '%1'
–949 | ORDER BY not allowed in window '%1'
–948 | PARTITION BY not allowed in reference to window '%1'
–947 | Window '%1' not found
–946 | Result set not permitted in '%1'
–945 | Recursive column %1: conversion from '%2' to '%3' loses precision
–944 | Too many expressions in GROUP BY list for ROLLUP, CUBE, or GROUPING SETS operation.
–943 | No workload capture currently exists
–942 | A workload capture (%1) is already in progress
–941 | jConnect does not support encryption
–940 | Invalid setting for HTTP header '%1'
–939 | Invalid setting for HTTP option '%1'
–938 | Recursion is not allowed without the RECURSIVE keyword
–937 | Invalid reference to or operation on constraint '%1'
–936 | too many constraints in database
–935 | Unable to start specified database: Log file error
–934 | Unable to start specified database: Server must be upgraded to start database %1
–933 | A log is required for IQ databases
–931 | Service definition requires a statement when authorization is off
–930 | (no message)
–929 | Constraint '%1' not found
–928 | Constant expressions may not appear in GROUP BY clause
–927 | Service statement definition is inconsistent with service type
–926 | Host variable reference in service definition must be named
–925 | Invalid service name '%1'
–924 | Service '%1' in use
–923 | Too many recursive iterations
–922 | No column list for recursive query
–921 | Invalid recursive query
–920 | Service '%1' not found
–919 | Service '%1' already exists
–918 | A user name must be specified if AUTHORIZATION is OFF
–916 | '%1' is an unrecognized service type
–915 | Service type required for CREATE SERVICE
–914 | Cycle in common table expression references
–913 | A transaction log file is required for auditing
–912 | Insufficient memory for OPENXML query
–911 | Control character in XML output
–910 | System command failed with return code %1
–908 | Invalid operation on a closed '%1'
–907 | No name for argument
–906 | XMLGEN evaluation failure
–905 | Invalid XQuery constructor
–904 | Illegal ORDER BY in aggregate function
–903 | CDATA has a name
–902 | Too few columns
–901 | Undeclared tag id: '%1'
–900 | Parent not open: '%1'
–899 | Illegal column name: '%1'
–898 | Unknown FOR XML EXPLICIT directive: '%1'
–897 | Illegal FOR XML EXPLICIT tag value: '%1'
–896 | Cannot delete PUBLIC option '%1' since user settings exist
–895 | Encryption error: %1
–894 | Plan can not be generated for this type of statement
–893 | Illegal flags value passed to OPENXML
–892 | XPath parser error: %1
–891 | Cannot convert between requested character sets '%1' and '%2'
–890 | Statement size or complexity exceeds server limits
–889 | Statement contains an illegal usage of the non-deterministic function '%1'
–888 | XML parser error: %1
–887 | Virtual index creation with more than %1 columns.
–883 | Character conversion reporting is not available when the single byte converter is used
–882 | An output character could not be converted to the application character set
–881 | An input character could not be converted to database character set
–880 | An invalid multi-byte output character was encountered
–879 | An invalid multi-byte input character was encountered
–878 | Index '%1' can not be clustered
–877 | SETUSER not allowed in procedures, triggers, events or batches
–876 | Client out of memory
–875 | There is no way to join to '%1'
–874 | Column must be named: %1
–873 | %1 returned multiple result sets
–872 | %1 does not return a result set
–871 | The database needs to be restarted for this Java related command
–870 | Cannot convert between requested character set '%1' and database character set '%2'
–869 | Database server cannot convert data from/to character set '%1'
–868 | '%1' is an unknown character set label
–867 | Cannot change synchronization user_name when status of the last upload is unknown.
–866 | %1 returned a result set with a different schema than expected
–865 | Key constraint between temporary tables requires a primary key (not unique constraint)
–864 | Statement contains an illegal usage of the NUMBER(*) function
–863 | Grouped query contains more than one distinct aggregate function
–862 | The aggregate expression '%1' must appear in either the select list or a HAVING clause subquery
–861 | Aggregated expression '%1' contains multiple columns of which one or more are outer references
–860 | At least one of the specified dbspaces was not calibrated.
–859 | %1
–858 | CREATE/DROP STATISTICS statement cannot refer to virtual tables
–857 | Synchronization failed due to an error on the server: %1
–856 | Invalid sqllen field in SQLDA
–855 | Trigger name '%1' is ambiguous
–854 | Function or column reference to '%1' in the ORDER BY clause is invalid
–853 | Cursor not in a valid state
–852 | Table name '%1' is ambiguous
–851 | Decryption error: %1
–850 | Tables related by key constraint must both be permanent or both be temporary created with ON COMMIT PRESERVE ROWS
–849 | Referential integrity actions other than RESTRICT not allowed for temporary tables
–848 | Exception occurred while loading Java SecurityManager
–847 | Java SecurityManager class not found: %1
–846 | Set clause for column '%1' used incorrectly
–845 | Owner '%1' used in a qualified column reference does not match correlation name '%2'
–844 | Cannot find synchronization definition with the name '%1'
–843 | Cannot find synchronization user with the name '%1'
–842 | JDK '%1' is not a supported JDK
–841 | The JDK version in '%1' does not match '%2'
–840 | Incorrect or missing encryption key
–839 | Download failed because of conflicts with existing rows.
–838 | TLS initialization on server failed
–837 | Trigger or foreign key for table '%1' is no longer valid
–836 | Procedure '%1' is no longer valid
–835 | Event '%1' in use
–834 | Column '%1' not found in table '%2'
–833 | Row in table '%1' was modified or deleted in BEFORE trigger
–832 | Connection error: %1
–831 | Definition for alias '%1' must appear before its first reference
–830 | Alias '%1' is not unique
–829 | TLS handshake failure
–828 | A conflict with the DBMLSync download phase was detected
–827 | Database upgrade not possible; user tables have table ids in system table range
–826 | Database upgrade not possible; RowGenerator table not owned by user dbo
–825 | Previous error lost prior to RESIGNAL
–824 | Illegal reference to correlation name '%1'
–823 | OMNI cannot handle expressions involving remote tables inside stored procedures
–822 | Table '%1' is already included
–821 | Dbspace for table '%1' not found
–820 | Invalid scroll position '%1'
–819 | Table '%1' is part of a synchronization definition
–818 | The external function call is incompatible
–817 | too many temporary tables in connection
–816 | Specified database file already in use
–815 | Cannot update column '%1' since it does not appear in the SELECT clause.
–814 | Cannot update column '%1' since it appears in the ORDER BY clause.
–813 | FOR UPDATE has been incorrectly specified for a READ ONLY cursor.
–812 | The Select list for the derived table '%1' has no expression to match '%2'
–811 | Jar '%1' not found
–810 | Java class '%1' not found
–809 | Synchronization option is too long
–808 | An internal error was generated by the test harness
–807 | Host variables may not be used within a batch
–806 | System event type '%1' not found
–805 | Synchronization option '%1' not found
–804 | Unable to reenlist transaction; DTC may be down
–803 | Unable to enlist transaction; DTC may be down
–802 | Cannot enlist in a transaction with uncommitted data pending
–801 | Cannot enlist in a transaction while already enlisted in a transaction
–800 | Cannot commit or rollback while enlisted in a transaction
–799 | DTC transactions are not supported on this platform
–797 | Synchronization option '%1' contains semi-colon, equal sign or curly brace
–796 | Synchronization site '%1' is already defined
–795 | Undefined synchronization template '%1'
–794 | Synchronization server failed to commit the upload
–793 | Invalid start date/time for event '%1'
–792 | Invalid time '%1' for event '%2'
–791 | Invalid day of week or month '%1' for event '%2'
–790 | Cannot register connection to '%1' since automatic label exhausted
–789 | Cannot register '%1' since registration cookie exhausted
–788 | Another connection has already registered as '%1'
–787 | Current connection is already registered to '%1' as '%2'
–786 | Cannot deregister '%1' since active registered connection exists
–785 | Cannot deregister application because of invalid cookie
–784 | Cannot register connection because of invalid application cookie
–783 | Cannot register another '%1' as an exclusive application
–782 | Cannot register '%1' since another exclusive instance is running
–780 | Cannot update primary key for table '%1' involved in a publication
–779 | Cannot create synchronization entry for table '%1' with BLOB primary key
–778 | Must include primary key for table '%1' in the synchronization
–777 | Cannot synchronize table '%1' since it does not have a primary key
–774 | Schedule '%1' for event '%2' already exists
–773 | Schedule '%1' for event '%2' not found
–772 | Event '%1' already exists
–771 | Event '%1' not found
–770 | Cannot modify publication entry using ALTER SYNCHRONIZATION
–769 | Cannot modify synchronization entry using ALTER PUBLICATION
–768 | Cannot subscribe to '%1'
–767 | Cannot find synchronization subscription with the name '%1'
–766 | View references '%1', which is a temporary object. Views can only refer to permanent objects.
–765 | Synchronization message type '%1' not found
–764 | Server not found and unable to autostart
–763 | '%1' is not a public Java reference, and cannot be referenced from SQL
–762 | '%1' is not a public Java class, and cannot be referenced from SQL
–761 | Server capability name '%1' could not be found in the SYS.SYSCAPABILITYNAME table.
–760 | Invalid SQL identifier
–759 | SQLDA data type invalid
–758 | The database does not support the Java virtual machine
–757 | Modifications not permitted for read-only database
–756 | Cannot uniquely identify column '%2' of table '%1' in the current JDBC resultset
–755 | You cannot synchronize or upgrade with uncommitted transactions
–754 | Parse error: %1
–753 | The JDBC resultset must be positioned on an insert row in order to use the '%1' function
–752 | Cannot call the '%1' function on a JDBC resultset when it is positioned on an insert row
–751 | User owns tables in use
–750 | User owns procedures in use
–749 | Feature not available with UltraLite
–748 | Invalid JDBC resultset concurrency
–747 | Invalid JDBC resultset type
–746 | Cannot allocate System V resources
–745 | Cannot initialize IQ memory manager: %1
–744 | Invalid IQ database command line option or parameter value: %1
–743 | Seek absolute 0 was attempted on a JDBC SAResultSet
–742 | JDBC SAStatement batch execute abandoned
–740 | The communications environment could not be created
–739 | db_init has not been called or the call to db_init failed
–738 | Password must be at least %1 characters
–737 | Signature '%1' does not match procedure parameters
–736 | The data type of column '%1' is not supported
–735 | Invalid parameter
–734 | Cannot update or delete an all-NULL row from table '%1'
–733 | Number of columns allowing NULLs exceeds limit
–732 | Creating remote tables with computed columns is not supported
–731 | Cannot drop a user that owns objects involved in replication
–730 | Invalid jar file
–729 | The specified foreign key (%1) can not be enforced
–728 | Update operation attempted on non-updatable remote query
–727 | The optimizer was unable to construct a valid access plan
–726 | The table specification '%1' identifies more than one remote table
–725 | Identity attribute mismatch for column '%1'
–724 | Null attribute mismatch for column '%1'
–723 | The length specified for column '%1' is different than the actual length
–722 | The column '%1' does not exist in the remote table
–721 | The data type specified for column '%1' is not compatible with the actual data type
–720 | VALIDATE TABLE statement must refer to a base table
–719 | RESTORE unable to start database '%1'
–718 | RESTORE unable to write to file '%1'
–717 | RESTORE unable to open file '%1'
–716 | Backup file format is invalid
–715 | Contents of backup files are inconsistent
–714 | Invalid operation on a closed '%1'
–713 | An internal error occurred in a '%1'
–712 | External login for server '%1' could not be found
–711 | Incorrect store DLL (%1) version.
–710 | Invalid comparison
–709 | Computed columns are not supported in this database
–708 | READTEXT or WRITETEXT statement cannot refer to a view
–707 | Statement is not allowed in passthrough mode
–706 | Remote server does not have the ability to support this statement
–705 | Return type of void from procedure '%1' cannot be used in any expression
–704 | Cannot create an index on Java class '%1'
–703 | Cannot insert or update computed column '%1'
–702 | TRUNCATE TABLE statement cannot refer to a view
–701 | Cannot access instance member through a class
–700 | SQLDA fields inconsistent for a multi-row SQLDA
–699 | Cannot update member fields qualified with "final" modifier
–698 | The remote server does not support an auto-incrementing data type
–697 | Error during backup: %1
–696 | Invalid operation on a closed '%1'
–695 | An internal error occurred in a '%1'
–694 | Could not change an opened prepared statement or callable statement
–693 | JDBC feature '%1' not supported
–692 | Could not execute backup/restore DLL (%1) entry point.
–691 | Could not load the backup/restore DLL "%1"
–690 | Return value cannot be set
–689 | Input parameter index out of range
–688 | Strongly-encrypted database files are not supported in the runtime server
–687 | Syntax error, cannot specify IQ specific options without specifying IQ PATH
–686 | Insufficient cache to start Java virtual machine
–685 | Resource governor for '%1' exceeded
–684 | Rollback occurred due to deadlock during prefetch
–683 | The cursor name '%1' already exists
–682 | %1
–681 | Invalid join type used with Transact-SQL outer join
–680 | Invalid expression in WHERE clause of Transact-SQL outer join
–679 | Not enough memory is allocated to the Java virtual machine for remote access
–678 | Index name '%1' is ambiguous
–677 | Table '%1' has a foreign key with a referential action
–676 | The specified transaction isolation is invalid
–675 | Java virtual machine could not be started
–674 | statement's size limit is invalid.
–673 | Database upgrade not possible
–672 | Database upgrade failed
–671 | Parameter not registered as output parameter
–670 | Invalid class byte code
–669 | Method '%1' cannot be called at this time
–668 | Cursor is restricted to FETCH NEXT operations
–667 | Could not access column information for the table '%1'
–666 | The remote table '%1' could not be found
–665 | Database "%1" needs recovery
–664 | Database is active
–663 | Cannot deserialize Java object
–662 | Cannot serialize Java object with class '%1'
–661 | Backwards scrolling cursors are not supported for remote objects
–660 | Server '%1': %2
–659 | Remote server '%1' could not be found; Add the server using CREATE SERVER
–658 | Remote server '%1' is currently configured as read only
–657 | Unable to connect to server '%1': server definition is circular
–656 | Unable to connect to server '%1': %2
–655 | Error parsing connection parameter string
–654 | The connection parameters file could not be found
–653 | Cannot remove class '%1': member of Jar
–652 | Could not decompress class '%1' from Jar.
–651 | An attempt to delete database '%1' failed
–650 | Index type specification of '%1' is invalid
–649 | Field '%1' of class '%2' cannot be null
–648 | Cannot create item (%1) in the specified dbspace.
–647 | Could not execute store DLL (%1) entry point.
–646 | Could not load the store DLL "%1"
–645 | Database creation failed: %1
–644 | Invalid database page size
–643 | UNLOAD TABLE cannot be used to unload a view
–642 | Invalid SQL descriptor name
–641 | Error in assignment
–640 | Invalid descriptor index
–639 | Parameter name missing in call to procedure '%1'
–638 | Right truncation of string data
–637 | Duplicate insert column
–636 | Duplicate referencing column
–635 | GRANT of column permission on view not allowed
–634 | Unterminated C string
–633 | Update operation attempted on a read-only cursor
–632 | WITH CHECK OPTION violated for insert/update on base table '%1'
–631 | RAISERROR executed: %1
–630 | Invalid escape sequence '%1'
–629 | Invalid escape character '%1'
–628 | Division by zero
–627 | Disallowed language extension detected in syntax near '%1'
–626 | A thread used internally could not be started
–625 | Too many parameters to this external procedure call
–624 | Expression has unsupported data type
–623 | Data definition statements not allowed in procedures or triggers
–622 | Could not allocate resources to call external function
–621 | Could not find '%1' in dynamic library '%2'
–620 | Could not load dynamic library '%1'
–619 | Need a dynamic library name
–618 | Mismatch between external function platform specifier and current operating system
–617 | Calling functions outside the database server is not supported
–616 | Too many columns in table
–615 | Parameter '%1' not found in procedure '%2'
–614 | Cannot drop a user that owns messages or data types
–613 | User-defined type '%1' not found
–612 | User message %1 not found
–611 | Transact-SQL feature not supported
–610 | User message %1 already exists
–609 | Invalid data type for column in WRITETEXT or READTEXT
–608 | Invalid TEXTPTR value used with WRITETEXT or READTEXT
–607 | Cannot stop the database server
–606 | The pattern is too long
–605 | The server attempted to access a page beyond the end of the maximum allowable dbspace file size
–604 | A dbspace has reached its maximum file size
–602 | Cannot access file '%1' -- %2
–601 | '%1' is not a known file format for loading or unloading tables
–504 | (no message)
–503 | (no message)
–313 | The login ID '%1' has not been mapped to any database user ID
–312 | User '%1' already has membership in group '%2'
–311 | Internal rollback log corrupted
–310 | Attempt to read beyond end-of-file in a compressed database
–309 | Memory error -- transaction rolled back
–308 | Connection was terminated
–307 | All threads are blocked
–306 | Deadlock detected
–305 | I/O error %1 -- transaction rolled back
–304 | Disk full '%1' -- transaction rolled back
–303 | Disk write failure '%1' -- transaction rolled back
–302 | Terminated by user -- transaction rolled back
–301 | Internal database error %1 -- transaction rolled back
–300 | Run time SQL error -- %1
–299 | Statement interrupted by user
–298 | Attempted two active database requests
–297 | User-defined exception signaled
–296 | Error number %1 for RAISERROR may not be less than 17000
–295 | Cannot uniquely identify rows in cursor
–294 | Format string argument number %1 is invalid
–289 | Multiple consolidated users cannot be defined
–288 | Remote statement failed
–287 | Passthrough statement inconsistent with current passthrough
–286 | Remote message type '%1' not found
–285 | User '%1' is not a remote user for this database
–284 | User '%1' is already the publisher for this database
–283 | Subscription to '%1' for '%2' not found
–282 | Subscription to '%1' for '%2' already exists
–281 | Table '%1' has publications
–280 | Publication '%1' not found
–275 | Triggers and procedures not supported in runtime server
–274 | Procedure or trigger calls have nested too deeply
–273 | COMMIT/ROLLBACK not allowed within trigger actions
–272 | Invalid REFERENCES clause in trigger definition
–271 | Trigger definition conflicts with existing triggers
–270 | Cannot drop a user that owns procedures in runtime server
–269 | Cannot delete or rename a column referenced in a trigger definition
–268 | Trigger '%1' not found
–267 | COMMIT/ROLLBACK not allowed within atomic operation
–266 | %1
–265 | Procedure '%1' not found
–264 | Wrong number of variables in FETCH
–263 | Invalid absolute or relative offset in FETCH
–262 | Label '%1' not found
–261 | There is already a variable named '%1'
–260 | Variable '%1' not found
–251 | Foreign key '%1' for table '%2' duplicates an existing foreign key
–250 | Identifier '%1' too long
–249 | The login ID '%1' is already mapped to user ID '%2'
–248 | Cannot map a login ID to the sys or public user ID
–247 | The integrated login ID guest can only be mapped to the guest database user ID
–246 | Integrated logins are not supported for this database
–245 | Integrated login failed
–244 | Transaction log was truncated
–243 | Unable to delete database file
–242 | Incomplete transactions prevent transaction log renaming
–241 | Database backup not started
–240 | Unknown backup operation
–231 | Client/database server version mismatch
–230 | Sqlpp/dblib version mismatch
–222 | Result set not allowed from within an atomic compound statement
–221 | ROLLBACK TO SAVEPOINT not allowed
–220 | Savepoint '%1' not found
–218 | Authentication failed
–217 | The option '%1' cannot be set from within a procedure
–216 | The option '%1' can only be set as a temporary option
–215 | Procedure in use by '%1'
–214 | Table in use
–213 | Savepoints require a rollback log
–212 | CHECKPOINT statement requires a rollback log
–211 | Not allowed while '%1' is using the database
–210 | User '%1' has the row in '%2' locked
–209 | Constraint '%1' violated: Invalid value for column '%2' in table '%3'
–208 | Row has changed since last read -- operation canceled
–207 | Wrong number of values for INSERT
–206 | Integrated logins are required, standard logins are not permitted
–205 | Integrated logins are not permitted
–204 | Only the DBA can set the option '%1'
–203 | Cannot set a temporary option for user '%1'
–202 | Only PUBLIC settings are allowed for option '%1'
–201 | Invalid setting for option '%1'
–200 | Invalid option '%1' -- no PUBLIC setting exists
–199 | INSERT/DELETE on cursor can modify only one table
–198 | Primary key for row in table '%1' is referenced by foreign key '%2' in table '%3'
–197 | No current row of cursor
–196 | Index '%1' for table '%2' would not be unique
–195 | Column '%1' in table '%2' cannot be NULL
–194 | No primary key value for foreign key '%1' in table '%2'
–193 | Primary key for table '%1' is not unique
–192 | Update operation attempted on non-updatable query
–191 | Cannot modify column '%1' in table '%2'
–190 | Cannot update an expression
–189 | Unable to find in index '%1' for table '%2'
–188 | Not enough values for host variables
–187 | Illegal cursor operation attempt
–186 | Subquery cannot return more than one row
–185 | SELECT returns more than one row
–184 | Column '%1' in table '%2' cannot be NULL. The invalid data was supplied to load table in a data file on line %3.
–183 | Cannot find index named '%1'
–182 | Not enough fields allocated in SQLDA
–181 | No indicator variable provided for NULL result
–180 | Cursor not open
–172 | Cursor already open
–171 | Error opening cursor
–170 | Cursor has not been declared
–165 | Java VM heap exhausted at internal function: %1
–164 | Namespace heap exhausted at internal function: %1
–163 | Derived table '%1' has no name for column %2
–162 | Cannot convert %1 to a %2. The bad value was supplied for column '%3' on row %4 of the data file.
–161 | Invalid type on DESCRIBE statement
–160 | Can only describe a SELECT statement
–159 | Invalid column number
–158 | Value %1 out of range for destination
–157 | Cannot convert %1 to a %2
–156 | Invalid expression near '%1'
–155 | Invalid host variable
–154 | Wrong number of parameters to function '%1'
–153 | SELECT lists in UNION, INTERSECT or EXCEPT do not match in length
–152 | Invalid ORDER BY specification
–151 | Subquery allowed only one select list item
–150 | Invalid use of an aggregate function
–149 | Function or column reference to '%1' must also appear in a GROUP BY
–148 | Unknown function '%1'
–147 | There is more than one way to join '%1' to '%2'
–146 | There is no way to join '%1' to '%2'
–145 | Foreign key name '%1' not found
–144 | Column '%1' found in more than one table -- need a correlation name
–143 | Column '%1' not found
–142 | Correlation name '%1' not found
–141 | Table '%1' not found
–140 | User ID '%1' does not exist
–139 | More than one table is identified as '%1'
–138 | Dbspace '%1' not found
–137 | Table '%1' requires a unique correlation name
–136 | Table '%1' is in an outer join cycle
–135 | Language extension
–134 | Feature '%1' not implemented
–133 | Invalid prepared statement type
–132 | SQL statement error
–131 | Syntax error near '%1' %2
–130 | Invalid statement
–128 | Cannot drop a user that owns tables in runtime system
–127 | Cannot alter a column in an index
–126 | Table cannot have two primary keys
–125 | ALTER clause conflict
–124 | More columns are being dropped from table '%1' than are defined
–123 | User '%1' is not a user group
–122 | Operation would cause a group cycle
–121 | Permission denied: %1
–120 | User '%1' already has GRANT permission
–119 | Primary key column '%1' already defined
–118 | Table '%1' has no primary key
–116 | Table must be empty
–114 | Number of columns defined for the view does not match SELECT statement
–113 | Column '%1' in foreign key has a different definition than primary key
–112 | Table already has a primary key
–111 | Index name '%1' not unique
–110 | Item '%1' already exists
–109 | There are still active database connections
–108 | Connection not found
–107 | Error writing to transaction log file
–106 | Cannot open transaction log file -- %1
–105 | Database cannot be started -- %1
–104 | Invalid user ID or password on preprocessed module
–103 | Invalid user ID or password
–103 | Invalid user ID or password
–102 | Database server connection limit exceeded
–101 | Not connected to a database
–100 | Database server not found
–99 | Connections to database have been disabled
–98 | Authentication violation
–97 | Database page size too big
–96 | Database server already running
–95 | Parse error: %1
–94 | Invalid type for field reference
–93 | Class '%1' has no public field '%2'
–92 | '%1' is not a valid class file
–91 | Procedure '%1' terminated with unhandled exception '%2'
–90 | Argument %1 of procedure '%2' cannot be null
–89 | Database server not running in multi-user mode
–88 | Client/server communications protocol version mismatch
–87 | Database name required to start server
–86 | Not enough memory to start
–85 | Communication error
–84 | Specified database is invalid
–83 | Specified database not found
–82 | Unable to start specified database: %1
–81 | Invalid database server command line
–80 | Unable to start database server
–79 | Invalid local database switch
–78 | Dynamic memory exhausted
–77 | Database name not unique
–76 | Request denied -- no active databases
–75 | Request to start/stop database denied
–74 | The selected database is currently inactive
–72 | No database file specified
0 | (no message)
100 | Row not found
101 | Value truncated
102 | Using temporary table
103 | Invalid data conversion
104 | Row has been updated since last time read
105 | Procedure has completed
106 | Value for column '%1' in table '%2' has changed
107 | Language extension detected in syntax
109 | Null value eliminated in aggregate function
110 | Transaction log backup page only partially full
111 | Statement cannot be executed
112 | More information required
113 | Database option '%1' for user '%2' has an invalid setting
114 | Character set translation to '%1' cannot be performed; '%2' is used instead
115 | Database server cannot convert data from/to character set '%1', conversion may not be correct
116 | Language '%1' is not supported, '%2' will be used
117 | Unsupported character set '%1' and unsupported language '%2'; language used is '%3' instead
118 | Illegal user selectivity estimate specified
119 | Unable to open backup log '%1'
120 | '%1' is an unknown option
121 | Cursor option values changed
122 | The result returned is non-deterministic.
123 | Database created without any schema
124 | Invalid data conversion: NULL was inserted for column '%1' on row %2.
125 | An invalid multi-byte input character was encountered
126 | An invalid multi-byte output character was encountered
127 | An input character could not be converted to database character set and simple substitution took place
128 | An output character could not be converted to the application character set and simple substitution took place
129 | Plan may contain virtual indexes.
130 | A row could not be converted to the new schema format
132 | Cannot output the histogram for string column '%1'
133 | UltraLite connection was restored
134 | UltraLite cursor (or result set or table) was restored
135 | Compressed database is not encrypted
136 | The database was created.
137 | Row was dropped from table %1 to maintain referential integrity
200 | Warning: %1


Error messages indexed by SQLSTATE

Adaptive Server Anywhere supports the SQLSTATE error code defined by SQL/92. Each SQLSTATE value is a 5- character string containing a 2-character class followed by a 3-character subclass. Each character can be one of the uppercase letters A through Z or the digits 0 through 9. A class that begins with A through H or 0 through 4 has been defined by the ANSI standard; other classes are implementation defined. Similarly, subclasses of standard classes that start with the same characters (A-H, 0-4) are standard. The subclass 000 always means that no subclass code is defined. The most common SQLSTATE value is 00000, which indicates successful completion.

SQLSTATE | Error message
00000 | (no message)
01000 | Warning: %1
01003 | Null value eliminated in aggregate function
01004 | Value truncated
01S02 | Cursor option values changed
01W01 | Invalid data conversion: NULL was inserted for column '%1' on row %2.
01W02 | Using temporary table
01W03 | Invalid data conversion
01W04 | Row has been updated since last time read
01W05 | Procedure has completed
01W06 | Value for column '%1' in table '%2' has changed
01W07 | Language extension detected in syntax
01W08 | Statement cannot be executed
01W09 | More information required
01W10 | Transaction log backup page only partially full
01W11 | Database option '%1' for user '%2' has an invalid setting
01W12 | Character set translation to '%1' cannot be performed; '%2' is used instead
01W13 | Database server cannot convert data from/to character set '%1', conversion may not be correct
01W14 | Language '%1' is not supported, '%2' will be used
01W15 | Unsupported character set '%1' and unsupported language '%2'; language used is '%3' instead
01W16 | Illegal user selectivity estimate specified
01W17 | '%1' is an unknown option
01W18 | The result returned is non-deterministic.
01W19 | Database created without any schema
01W20 | Plan may contain virtual indexes.
01W21 | A row could not be converted to the new schema format
01W23 | Cannot output the histogram for string column '%1'
01W24 | Row was dropped from table %1 to maintain referential integrity
01WC1 | An invalid multi-byte input character was encountered
01WC2 | An invalid multi-byte output character was encountered
01WC3 | An input character could not be converted to database character set and simple substitution took place
01WC4 | An output character could not be converted to the application character set and simple substitution took place
02000 | Row not found
04W07 | A dbspace has reached its maximum file size
04W08 | The server attempted to access a page beyond the end of the maximum allowable dbspace file size
07001 | Not enough values for host variables
07002 | Not enough fields allocated in SQLDA
07003 | Error opening cursor
07005 | Can only describe a SELECT statement
07009 | Invalid descriptor index
07W01 | Invalid type on DESCRIBE statement
07W02 | Invalid statement
07W03 | Invalid prepared statement type
07W04 | SQLDA fields inconsistent for a multi-row SQLDA
07W05 | SQLDA data type invalid
07W06 | Invalid SQL identifier
07W07 | Host variables may not be used within a batch
07W08 | Invalid sqllen field in SQLDA
08001 | Database cannot be started -- %1
08003 | Not connected to a database
08004 | User ID '%1' does not exist
08005 | Password contains an illegal character
08W01 | Database server not found
08W02 | Connection not found
08W03 | Database server connection limit exceeded
08W04 | Connections to database have been disabled
08W05 | Cannot open transaction log file -- %1
08W06 | There are still active database connections
08W07 | Unable to start database server
08W08 | Invalid database server command line
08W09 | Unable to start specified database: %1
08W10 | Specified database not found
08W11 | Specified database is invalid
08W12 | Communication error
08W13 | Not enough memory to start
08W14 | Database name required to start server
08W15 | Client/server communications protocol version mismatch
08W16 | Database server not running in multi-user mode
08W17 | Error writing to transaction log file
08W18 | Sqlpp/dblib version mismatch
08W19 | Client/database server version mismatch
08W21 | Authentication violation
08W22 | Database page size too big
08W23 | Database server already running
08W24 | Invalid parameter
08W25 | Invalid local database switch
08W26 | Dynamic memory exhausted
08W27 | Database name not unique
08W28 | Request denied -- no active databases
08W29 | Request to start/stop database denied
08W30 | The selected database is currently inactive
08W32 | Invalid database page size
08W33 | Database creation failed: %1
08W34 | Could not load the store DLL "%1"
08W35 | Could not execute store DLL (%1) entry point.
08W36 | Cannot create item (%1) in the specified dbspace.
08W37 | The connection parameters file could not be found
08W38 | Error parsing connection parameter string
08W39 | No database file specified
08W40 | Database is active
08W41 | Database "%1" needs recovery
08W42 | Database upgrade failed
08W43 | Database upgrade not possible
08W44 | Could not load the backup/restore DLL "%1"
08W45 | Could not execute backup/restore DLL (%1) entry point.
08W46 | Error during backup: %1
08W47 | Incorrect store DLL (%1) version.
08W48 | Authentication failed
08W49 | Parse error: %1
08W51 | Invalid IQ database command line option or parameter value: %1
08W52 | Cannot initialize IQ memory manager: %1
08W53 | Cannot allocate System V resources
08W54 | Parse error: %1
08W55 | Server not found and unable to autostart
08W56 | Specified database file already in use
08W57 | Database upgrade not possible; RowGenerator table not owned by user dbo
08W58 | Database upgrade not possible; user tables have table ids in system table range
08W59 | TLS handshake failure
08W60 | Connection error: %1
08W61 | TLS initialization on server failed
08W62 | Incorrect or missing encryption key
08W63 | Decryption error: %1
08W64 | Database server cannot convert data from/to character set '%1'
08W65 | Client out of memory
08W66 | Encryption error: %1
08W67 | Unable to start specified database: Server must be upgraded to start database %1
08W68 | Unable to start specified database: Log file error
08W69 | jConnect does not support encryption
08W70 | Could not load the encryption DLL "%1"
08W71 | Parameter '%1' in procedure or function '%2' does not have a default value
08W72 | Unable to start specified database: '%1' is an invalid transaction log mirror
08W73 | Unable to start specified database: The transaction log '%1' or its mirror '%2' is invalid
08W74 | Unable to start specified database: '%1' not expecting any operations in transaction log
08W75 | Unable to start specified database: Unknown encryption algorithm.
08W76 | Unable to start specified database: '%1' must be upgraded to start with this server (capability %2 missing).
08W77 | Unable to start specified database: '%1' found, but database not found
08W78 | Unable to start specified database: '%1' is compressed -- use a write file or open in read-only mode
08W79 | Unable to start specified database: The database for write file '%1' has an incorrect modification time
08W80 | Unable to start specified database: Can't use log file '%1' since it has been used more recently than the database file
08W81 | Unable to start specified database: '%1': transaction log file not found
08W82 | Unable to start specified database: Can't use log file '%1' since the offsets don't match the offsets in the database file
08W83 | Unable to start specified database: Can't use log file '%1' since the database file has been used more recently
08W84 | Unable to start specified database: Can't use log file '%1' since it is shorter than expected
08W85 | Unable to start specified database: '%1' is not a database
08W86 | Unable to start specified database: '%1' was created by a different version of the software
08W87 | Unable to start specified database: '%1' is not a valid database file
08W88 | Unable to start specified database: '%1' is an invalid transaction log
09W02 | Illegal cursor operation attempt
09W03 | Result set not permitted in '%1'
09W04 | INSERT/DELETE on cursor can modify only one table
09W05 | Cannot uniquely identify rows in cursor
09W06 | Cursor is restricted to FETCH NEXT operations
09W07 | statement's size limit is invalid.
09W08 | Cannot update or delete an all-NULL row from table '%1'
0A000 | Feature '%1' not implemented
0AQ48 | A log is required for IQ databases
0AW01 | Language extension
0AW02 | Transact-SQL feature not supported
0AW03 | Disallowed language extension detected in syntax near '%1'
0AW04 | Triggers and procedures not supported in runtime server
0AW05 | Statement is not allowed in passthrough mode
0AW06 | Computed columns are not supported in this database
0AW07 | Feature not available with UltraLite
0AW08 | You cannot synchronize or upgrade with uncommitted transactions
0AW09 | Synchronization server failed to commit the upload
0AW10 | DTC transactions are not supported on this platform
0AW11 | Download failed because of conflicts with existing rows.
0AW12 | Synchronization failed due to an error on the server: %1
0AW13 | Cannot change synchronization user_name when status of the last upload is unknown.
0AW14 | Plan can not be generated for this type of statement
21000 | SELECT returns more than one row
21W01 | Subquery cannot return more than one row
22001 | Right truncation of string data
22002 | No indicator variable provided for NULL result
22003 | Value %1 out of range for destination
22005 | Error in assignment
22012 | Division by zero
22019 | Invalid escape character '%1'
22024 | Unterminated C string
22025 | Invalid escape sequence '%1'
22W02 | Row has changed since last read -- operation canceled
22W03 | Invalid TEXTPTR value used with WRITETEXT or READTEXT
22X13 | Invalid preceding or following size in OLAP function
23501 | Column '%1' in table '%2' cannot be NULL. The invalid data was supplied to load table in a data file on line %3.
23502 | Column '%1' in table '%2' cannot be NULL
23503 | No primary key value for foreign key '%1' in table '%2'
23504 | Number of columns allowing NULLs exceeds limit
23505 | Index '%1' for table '%2' would not be unique
23506 | Constraint '%1' violated: Invalid value for column '%2' in table '%3'
23507 | The specified foreign key (%1) can not be enforced
23W01 | Primary key for table '%1' is not unique
23W05 | Primary key for row in table '%1' is referenced by foreign key '%2' in table '%3'
24000 | Cursor not in a valid state
24501 | Cursor not open
24502 | Cursor already open
24503 | No current row of cursor
24504 | Invalid scroll position '%1'
24W01 | Cursor has not been declared
26501 | SQL statement error
28000 | The string is too long (%1)
28000 | Password cannot be longer than %1 characters
28000 | Password must be at least %1 characters
28000 | Invalid user ID or password
28000 | Invalid user ID or password
28W01 | Invalid user ID or password on preprocessed module
28W02 | Integrated logins are not permitted
28W03 | Integrated logins are required, standard logins are not permitted
28W04 | Integrated login failed
28W05 | Integrated logins are not supported for this database
28W06 | The integrated login ID guest can only be mapped to the guest database user ID
28W07 | Cannot map a login ID to the sys or public user ID
28W08 | The login ID '%1' is already mapped to user ID '%2'
28W09 | The login ID '%1' has not been mapped to any database user ID
28W10 | Too many distinct group mappings for integrated user
2D501 | COMMIT/ROLLBACK not allowed within trigger actions
33000 | Invalid SQL descriptor name
37505 | Wrong number of parameters to function '%1'
38W01 | System command failed with return code %1
3B001 | Savepoint '%1' not found
3B002 | ROLLBACK TO SAVEPOINT not allowed
3BW01 | Savepoints require a rollback log
3BW02 | Result set not allowed from within an atomic compound statement
40000 | Run time SQL error -- %1
40001 | Deadlock detected
40W01 | Internal database error %1 -- transaction rolled back
40W02 | Terminated by user -- transaction rolled back
40W03 | Disk full '%1' -- transaction rolled back
40W04 | I/O error %1 -- transaction rolled back
40W05 | Disk write failure '%1' -- transaction rolled back
40W06 | All threads are blocked
40W07 | Connection was terminated
40W08 | Memory error -- transaction rolled back
42501 | Permission denied: %1
42R01 | Referential integrity actions other than RESTRICT not allowed for temporary tables
42R02 | Tables related by key constraint must both be permanent or both be temporary created with ON COMMIT PRESERVE ROWS
42R03 | Key constraint between temporary tables requires a primary key (not unique constraint)
42U00 | View references '%1', which is a temporary object. Views can only refer to permanent objects.
42U01 | Illegal reference to correlation name '%1'
42U02 | Owner '%1' used in a qualified column reference does not match correlation name '%2'
42U03 | Set clause for column '%1' used incorrectly
42U04 | Constraint '%1' not found
42U05 | (no message)
42U06 | Invalid reference to or operation on constraint '%1'
42U07 | Invalid hint specified for table '%1'
42W01 | User '%1' already has GRANT permission
42W02 | Operation would cause a group cycle
42W03 | User '%1' is not a user group
42W04 | Syntax error near '%1' %2
42W05 | Unknown function '%1'
42W06 | Invalid use of an aggregate function
42W07 | Invalid host variable
42W08 | Invalid expression near '%1'
42W09 | SETUSER not allowed in procedures, triggers, events or batches
42W13 | Invalid column number
42W14 | Variable '%1' not found
42W15 | There is already a variable named '%1'
42W16 | Invalid option '%1' -- no PUBLIC setting exists
42W17 | Invalid setting for option '%1'
42W18 | User '%1' has the row in '%2' locked
42W19 | Not allowed while '%1' is using the database
42W20 | CHECKPOINT statement requires a rollback log
42W21 | Table in use
42W22 | Attempted two active database requests
42W23 | Procedure in use by '%1'
42W24 | Label '%1' not found
42W25 | Invalid absolute or relative offset in FETCH
42W26 | Wrong number of variables in FETCH
42W27 | %1
42W28 | COMMIT/ROLLBACK not allowed within atomic operation
42W29 | Procedure or trigger calls have nested too deeply
42W30 | Update operation attempted on a read-only cursor
42W31 | Update operation attempted on non-updatable query
42W32 | Cannot modify column '%1' in table '%2'
42W33 | Table '%1' not found
42W34 | User '%1' already has membership in group '%2'
42W35 | Update operation attempted on non-updatable remote query
42W36 | FOR UPDATE has been incorrectly specified for a READ ONLY cursor.
42W37 | Cannot update column '%1' since it appears in the ORDER BY clause.
42W38 | Cannot update column '%1' since it does not appear in the SELECT clause.
42W40 | Duplicate referencing column
42W41 | Duplicate insert column
42W42 | Parameter name missing in call to procedure '%1'
42W43 | Only PUBLIC settings are allowed for option '%1'
42W44 | More columns are being dropped from table '%1' than are defined
42W45 | Cannot set a temporary option for user '%1'
42W46 | Only the DBA can set the option '%1'
42W47 | Parameter '%1' not found in procedure '%2'
42W48 | Syntax error, cannot specify IQ specific options without specifying IQ PATH
42W49 | TRUNCATE TABLE statement cannot refer to a view
42W50 | READTEXT or WRITETEXT statement cannot refer to a view
42W51 | VALIDATE TABLE statement must refer to a base table
42W52 | The option '%1' can only be set as a temporary option
42W53 | The option '%1' cannot be set from within a procedure
42W54 | Signature '%1' does not match procedure parameters
42W55 | User owns procedures in use
42W56 | User owns tables in use
42W57 | Java class '%1' not found
42W58 | Jar '%1' not found
42W59 | The Select list for the derived table '%1' has no expression to match '%2'
42W60 | Alias '%1' is not unique
42W61 | Definition for alias '%1' must appear before its first reference
42W62 | Row in table '%1' was modified or deleted in BEFORE trigger
42W63 | Procedure '%1' is no longer valid
42W64 | Trigger or foreign key for table '%1' is no longer valid
42W65 | Function or column reference to '%1' in the ORDER BY clause is invalid
42W66 | Trigger name '%1' is ambiguous
42W67 | CREATE/DROP STATISTICS statement cannot refer to virtual tables
42W68 | Aggregated expression '%1' contains multiple columns of which one or more are outer references
42W69 | The aggregate expression '%1' must appear in either the select list or a HAVING clause subquery
42W70 | Grouped query contains more than one distinct aggregate function
42W71 | Statement contains an illegal usage of the NUMBER(*) function
42W73 | There is no way to join to '%1'
42W74 | Index '%1' can not be clustered
42W79 | Statement contains an illegal usage of the non-deterministic function '%1'
42W82 | Cannot delete PUBLIC option '%1' since user settings exist
42W83 | Invalid setting for HTTP option '%1'
42W84 | Invalid setting for HTTP header '%1'
42W90 | Illegal ORDER BY in aggregate function
42W91 | A transaction log file is required for auditing
42W92 | Service type required for CREATE SERVICE
42W93 | Cycle in common table expression references
42W94 | '%1' is an unrecognized service type
42W95 | Invalid service name '%1'
42W96 | A user name must be specified if AUTHORIZATION is OFF
42W97 | Service '%1' already exists
42W98 | Service '%1' not found
42W99 | Invalid recursive query
42W9A | No column list for recursive query
42W9B | Host variable reference in service definition must be named
42W9C | Service statement definition is inconsistent with service type
42W9D | Constant expressions may not appear in GROUP BY clause
42W9E | Service definition requires a statement when authorization is off
42WA0 | Recursion is not allowed without the RECURSIVE keyword
42WA1 | Too many expressions in GROUP BY list for ROLLUP, CUBE, or GROUPING SETS operation.
42WA2 | Recursive column %1: conversion from '%2' to '%3' loses precision
42WA3 | Window '%1' not found
42WA4 | PARTITION BY not allowed in reference to window '%1'
42WA5 | ORDER BY not allowed in window '%1'
42WA6 | Frame not allowed for window '%1'
42WA7 | Argument to GROUPING aggregate must be a grouping column in the GROUP BY clause
42WA8 | Window function used in predicate
42WA9 | Window function requires ORDER BY
42WAA | Composite ORDER BY not allowed with RANGE
42WAB | User '%1' already has EXECUTE permission
42WAC | Too many arguments for function or procedure '%1'
42WAD | Invalid value for attribute '%1' in service
42WAE | Missing value for attribute '%1' in service
42WAF | Unsupported property '%1' in service USING attribute
42WB0 | Duplicate attribute '%1' in service
42WB1 | USING attribute cannot coexist with FORMAT or GROUP attributes
42WB2 | Service type does not allow '%1' attribute
44000 | WITH CHECK OPTION violated for insert/update on base table '%1'
52002 | Column '%1' found in more than one table -- need a correlation name
52003 | Column '%1' not found
52004 | Derived table '%1' has no name for column %2
52005 | Column '%1' not found in table '%2'
52009 | Primary key column '%1' already defined
52010 | Item '%1' already exists
52012 | More than one table is identified as '%1'
52W02 | Correlation name '%1' not found
52W03 | Cannot find index named '%1'
52W04 | Index name '%1' not unique
52W05 | Table cannot have two primary keys
52W06 | Foreign key '%1' for table '%2' duplicates an existing foreign key
52W07 | Foreign key name '%1' not found
52W08 | There is more than one way to join '%1' to '%2'
52W09 | Procedure '%1' not found
52W10 | Trigger '%1' not found
52W11 | Trigger definition conflicts with existing triggers
52W12 | Invalid REFERENCES clause in trigger definition
52W13 | Dbspace '%1' not found
52W14 | Table '%1' is in an outer join cycle
52W15 | Table '%1' requires a unique correlation name
52W16 | User message %1 already exists
52W17 | User message %1 not found
52W18 | User-defined type '%1' not found
52W19 | Dbspace for table '%1' not found
52W20 | Too many columns in table
52W21 | Data definition statements not allowed in procedures or triggers
52W22 | GRANT of column permission on view not allowed
52W23 | Invalid expression in WHERE clause of Transact-SQL outer join
52W24 | Invalid join type used with Transact-SQL outer join
52W25 | Invalid comparison
52W40 | Index name '%1' is ambiguous
52W41 | too many temporary tables in connection
52W42 | Table name '%1' is ambiguous
53002 | Wrong number of values for INSERT
53003 | Function or column reference to '%1' must also appear in a GROUP BY
53005 | Invalid ORDER BY specification
53011 | Number of columns defined for the view does not match SELECT statement
53017 | Cannot convert %1 to a %2. The bad value was supplied for column '%3' on row %4 of the data file.
53018 | Cannot convert %1 to a %2
53019 | Return type of void from procedure '%1' cannot be used in any expression
53023 | Subquery allowed only one select list item
53026 | SELECT lists in UNION, INTERSECT or EXCEPT do not match in length
53030 | Column '%1' in foreign key has a different definition than primary key
53W01 | ALTER clause conflict
53W02 | Cannot update an expression
53W04 | There is no way to join '%1' to '%2'
53W05 | Cannot alter a column in an index
53W06 | Cannot delete or rename a column referenced in a trigger definition
53W07 | Error number %1 for RAISERROR may not be less than 17000
53W08 | Format string argument number %1 is invalid
53W09 | Invalid data type for column in WRITETEXT or READTEXT
54003 | Identifier '%1' too long
54W01 | Statement size or complexity exceeds server limits
54W02 | too many constraints in database
54W03 | Database page size too small
54W04 | The specified listener could not be registered
54W05 | Temporary space limit exceeded
54W50 | Virtual index creation with more than %1 columns.
55008 | Table '%1' has no primary key
55013 | Table already has a primary key
55W02 | Table must be empty
55W03 | Cannot drop a user that owns tables in runtime system
55W04 | Cannot drop a user that owns procedures in runtime server
55W05 | Cannot drop a user that owns messages or data types
55W06 | Cannot drop a user that owns objects involved in replication
55W07 | db_init has not been called or the call to db_init failed
55W08 | Modifications not permitted for read-only database
55W09 | Cannot commit or rollback while enlisted in a transaction
55W10 | Cannot enlist in a transaction while already enlisted in a transaction
55W11 | Cannot enlist in a transaction with uncommitted data pending
55W12 | %1
55W13 | Strongly-encrypted database files are not supported in the runtime server
55W14 | Invalid operation on a closed '%1'
55W15 | Service '%1' in use
56001 | Table '%1' has a foreign key with a referential action
57014 | Statement interrupted by user
57015 | Too many recursive iterations
5RW01 | Publication '%1' not found
5RW02 | Table '%1' has publications
5RW03 | Subscription to '%1' for '%2' already exists
5RW04 | Subscription to '%1' for '%2' not found
5RW05 | User '%1' is already the publisher for this database
5RW06 | User '%1' is not a remote user for this database
5RW07 | Remote message type '%1' not found
5RW08 | Passthrough statement inconsistent with current passthrough
5RW09 | Remote statement failed
5RW10 | Multiple consolidated users cannot be defined
5RW11 | Synchronization message type '%1' not found
5RW12 | Cannot find synchronization subscription with the name '%1'
5RW13 | Cannot subscribe to '%1'
5RW14 | Cannot modify synchronization entry using ALTER PUBLICATION
5RW15 | Cannot modify publication entry using ALTER SYNCHRONIZATION
5RW16 | Cannot synchronize table '%1' since it does not have a primary key
5RW17 | Must include primary key for table '%1' in the synchronization
5RW18 | Cannot create synchronization entry for table '%1' with BLOB primary key
5RW19 | Cannot update primary key for table '%1' involved in a publication
5RW21 | Cannot register '%1' since another exclusive instance is running
5RW22 | Cannot register another '%1' as an exclusive application
5RW23 | Cannot register connection because of invalid application cookie
5RW24 | Cannot deregister application because of invalid cookie
5RW25 | Cannot deregister '%1' since active registered connection exists
5RW26 | Current connection is already registered to '%1' as '%2'
5RW27 | Another connection has already registered as '%1'
5RW28 | Cannot register '%1' since registration cookie exhausted
5RW29 | Cannot register connection to '%1' since automatic label exhausted
5RW30 | Undefined synchronization template '%1'
5RW31 | Synchronization site '%1' is already defined
5RW32 | Synchronization option '%1' contains semi-colon, equal sign or curly brace
5RW33 | Synchronization option '%1' not found
5RW34 | Synchronization option is too long
5RW35 | Table '%1' is part of a synchronization definition
5RW36 | Table '%1' is already included
5RW37 | Cannot find synchronization user with the name '%1'
5RW39 | Cannot find synchronization definition with the name '%1'
99999 | User-defined exception signaled
WB001 | Unknown backup operation
WB002 | Database backup not started
WB003 | Incomplete transactions prevent transaction log renaming
WB004 | Unable to delete database file
WB005 | Transaction log was truncated
WB006 | Contents of backup files are inconsistent
WB007 | Backup file format is invalid
WB008 | RESTORE unable to open file '%1'
WB009 | RESTORE unable to write to file '%1'
WB010 | RESTORE unable to start database '%1'
WB011 | Unable to open backup log '%1'
WB012 | Backup file '%1' already exists
WB013 | Invalid backup operation
WB014 | Connection attempting BACKUP has uncommitted transactions
WC001 | '%1' is an unknown character set label
WC002 | Cannot convert between requested character set '%1' and database character set '%2'
WC003 | An invalid multi-byte input character was encountered
WC004 | An invalid multi-byte output character was encountered
WC005 | An input character could not be converted to database character set
WC006 | An output character could not be converted to the application character set
WC007 | Character conversion reporting is not available when the single byte converter is used
WC008 | Cannot convert between requested character sets '%1' and '%2'
WE001 | Event '%1' not found
WE002 | Event '%1' already exists
WE003 | Schedule '%1' for event '%2' not found
WE004 | Schedule '%1' for event '%2' already exists
WE005 | Invalid day of week or month '%1' for event '%2'
WE006 | Invalid time '%1' for event '%2'
WE007 | Invalid start date/time for event '%1'
WE008 | System event type '%1' not found
WE009 | Event '%1' in use
WI001 | Attempt to read beyond end-of-file in a compressed database
WI004 | Internal rollback log corrupted
WI005 | Unable to find in index '%1' for table '%2'
WI006 | (no message)
WI008 | (no message)
WI009 | Cannot serialize Java object with class '%1'
WI010 | The optimizer was unable to construct a valid access plan
WI011 | Required operators excluded
WJ001 | Method '%1' cannot be called at this time
WJ002 | Parameter not registered as output parameter
WJ003 | The specified transaction isolation is invalid
WJ004 | The cursor name '%1' already exists
WJ005 | Input parameter index out of range
WJ006 | Return value cannot be set
WJ007 | JDBC feature '%1' not supported
WJ008 | Could not change an opened prepared statement or callable statement
WJ009 | An internal error occurred in a '%1'
WJ010 | Invalid operation on a closed '%1'
WJ011 | Cannot access instance member through a class
WJ012 | Cannot update member fields qualified with "final" modifier
WJ013 | An internal error occurred in a '%1'
WJ014 | Invalid operation on a closed '%1'
WJ015 | JDBC SAStatement batch execute abandoned
WJ016 | Seek absolute 0 was attempted on a JDBC SAResultSet
WJ017 | Invalid JDBC resultset type
WJ018 | Invalid JDBC resultset concurrency
WJ019 | Cannot call the '%1' function on a JDBC resultset when it is positioned on an insert row
WJ020 | The JDBC resultset must be positioned on an insert row in order to use the '%1' function
WJ021 | Cannot uniquely identify column '%2' of table '%1' in the current JDBC resultset
WJ022 | The database does not support the Java virtual machine
WJ023 | '%1' is not a public Java class, and cannot be referenced from SQL
WJ024 | '%1' is not a public Java reference, and cannot be referenced from SQL
WJ025 | JDK '%1' is not a supported JDK
WJ026 | The JDK version in '%1' does not match '%2'
WJ027 | Java SecurityManager class not found: %1
WJ028 | Exception occurred while loading Java SecurityManager
WJ029 | The database needs to be restarted for this Java related command
WL001 | '%1' is not a known file format for loading or unloading tables
WL002 | Cannot access file '%1' -- %2
WL004 | UNLOAD TABLE cannot be used to unload a view
WL005 | Unable to enlist transaction; DTC may be down
WL006 | Unable to reenlist transaction; DTC may be down
WL007 | LOAD TABLE not allowed on temporary table with ON COMMIT DELETE ROWS
WO001 | Unable to connect to server '%1': %2
WO002 | Unable to connect to server '%1': server definition is circular
WO003 | Remote server '%1' is currently configured as read only
WO004 | Remote server '%1' could not be found; Add the server using CREATE SERVER
WO005 | Server '%1': %2
WO006 | Backwards scrolling cursors are not supported for remote objects
WO007 | The remote table '%1' could not be found
WO008 | Could not access column information for the table '%1'
WO009 | Not enough memory is allocated to the Java virtual machine for remote access
WO010 | %1
WO011 | The remote server does not support an auto-incrementing data type
WO012 | Remote server does not have the ability to support this statement
WO013 | External login for server '%1' could not be found
WO014 | Server capability name '%1' could not be found in the SYS.SYSCAPABILITYNAME table.
WO015 | The data type specified for column '%1' is not compatible with the actual data type
WO016 | The column '%1' does not exist in the remote table
WO017 | The length specified for column '%1' is different than the actual length
WO018 | Null attribute mismatch for column '%1'
WO019 | Identity attribute mismatch for column '%1'
WO020 | The table specification '%1' identifies more than one remote table
WO021 | Creating remote tables with computed columns is not supported
WO022 | The data type of column '%1' is not supported
WO023 | OMNI cannot handle expressions involving remote tables inside stored procedures
WO024 | Specified local connection not found.
WO025 | Specified local connection is not to the current database.
WO026 | Cannot close a remote JDBC connection that is not the current connection.
WP000 | Argument %1 of procedure '%2' cannot be null
WP001 | Procedure '%1' terminated with unhandled exception '%2'
WP002 | '%1' is not a valid class file
WP003 | Could not decompress class '%1' from Jar.
WP004 | Cannot remove class '%1': member of Jar
WP005 | Invalid class byte code
WP006 | Java virtual machine could not be started
WP007 | Namespace heap exhausted at internal function: %1
WP008 | Java VM heap exhausted at internal function: %1
WP009 | Resource governor for '%1' exceeded
WP010 | Invalid jar file
WP011 | Previous error lost prior to RESIGNAL
WP012 | %1 returned a result set with a different schema than expected
WP013 | %1 returned multiple result sets
WP014 | %1 does not return a result set
WP015 | Insufficient cache to start Java virtual machine
WP016 | Warning detected when optimizing SELECT INTO is treated as an error
WW001 | The pattern is too long
WW002 | Cannot stop the database server
WW003 | Calling functions outside the database server is not supported
WW004 | Mismatch between external function platform specifier and current operating system
WW005 | Need a dynamic library name
WW006 | Could not load dynamic library '%1'
WW007 | Could not find '%1' in dynamic library '%2'
WW008 | Could not allocate resources to call external function
WW009 | Expression has unsupported data type
WW010 | Too many parameters to this external procedure call
WW011 | A thread used internally could not be started
WW012 | RAISERROR executed: %1
WW013 | Class '%1' has no public field '%2'
WW014 | Invalid type for field reference
WW015 | Field '%1' of class '%2' cannot be null
WW016 | Index type specification of '%1' is invalid
WW017 | An attempt to delete database '%1' failed
WW018 | Cannot deserialize Java object
WW019 | Rollback occurred due to deadlock during prefetch
WW020 | Invalid request log format on line %1
WW022 | Cannot create an index on Java class '%1'
WW023 | Cannot insert or update computed column '%1'
WW024 | The communications environment could not be created
WW025 | An internal error was generated by the test harness
WW026 | The external function call is incompatible
WW027 | A conflict with the DBMLSync download phase was detected
WW028 | At least one of the specified dbspaces was not calibrated.
WW029 | A workload capture (%1) is already in progress
WW030 | No workload capture currently exists
WW031 | Cannot access schema file '%1'
WW032 | The status of the last synchronization upload is unknown
WW033 | A schema upgrade is not currently allowed
WW034 | The database '%1' was not found
WW035 | This connection already exists
WW036 | Information for synchronization is incomplete or invalid, check '%1'
WW037 | Compression error: %1
WW038 | Decompression error: %1
WW039 | Input string is not base64-encoded
WW040 | UltraLite connection was restored
WW041 | UltraLite cursor (or result set or table) was restored
WW042 | Checksums are not enabled in this database
WW043 | File I/O failed for '%1'
WW044 | Incorrect volume ID for '%1'
WW045 | Compressed database is not encrypted
WW046 | UltraLite runtime library is incompatible with the database file
WW047 | Output file directory does not exist
WW048 | Output file cannot be written
WW049 | The URI '%1' is invalid
WW050 | Unable to connect to the remote host specified by '%1'
WW051 | Connection timed out
WW052 | HTTP request failed. Status code '%1'
WW053 | Could not initialize the encryption DLL: '%1'
WW054 | Could not load the encryption DLL '%1'
WW055 | Invalid procedure type '%1'
WW056 | Invalid procedure subtype '%1' for type '%2'
WW057 | Invalid response from the HTTP server
WW058 | NAMESPACE attribute is not valid with procedure type '%1'
WW059 | The secure connection to the remote host failed
WW060 | The %1 attribute '%2' is not valid
WW061 | The database was created.
WW062 | The option '%1' is not recognized.
WX001 | Column must be named: %1
WX002 | XML parser error: %1
WX003 | XPath parser error: %1
WX004 | Illegal flags value passed to OPENXML
WX005 | Illegal FOR XML EXPLICIT tag value: '%1'
WX006 | Unknown FOR XML EXPLICIT directive: '%1'
WX007 | Illegal column name: '%1'
WX008 | Parent not open: '%1'
WX009 | Undeclared tag id: '%1'
WX010 | Too few columns
WX011 | CDATA has a name
WX012 | Invalid XQuery constructor
WX013 | XMLGEN evaluation failure
WX014 | No name for argument
WX015 | Control character in XML output
WX016 | Insufficient memory for OPENXML query


Error messages indexed by Sybase error code

Sybase error codes are a set of error codes for use by all Sybase products, including Adaptive Server Enterprise. For every Sybase error code returned by Adaptive Server Anywhere, there is a matching Adaptive Server Anywhere error code. In many cases Adaptive Server Anywhere error codes offer a finer level of granularity than their Sybase error code counterparts, thus some Sybase error codes in the following table are non-unique.

Sybase error code | Adaptive Server Anywhere SQLCODE | Error message
0 | –631 | RAISERROR executed: %1
102 | –171 | Error opening cursor
102 | –199 | INSERT/DELETE on cursor can modify only one table
102 | –933 | A log is required for IQ databases
102 | –275 | Triggers and procedures not supported in runtime server
102 | –273 | COMMIT/ROLLBACK not allowed within trigger actions
102 | –131 | Syntax error near '%1' %2
102 | –687 | Syntax error, cannot specify IQ specific options without specifying IQ PATH
102 | –875 | There is no way to join to '%1'
102 | –145 | Foreign key name '%1' not found
102 | –271 | Trigger definition conflicts with existing triggers
102 | –272 | Invalid REFERENCES clause in trigger definition
102 | –635 | GRANT of column permission on view not allowed
102 | –151 | Subquery allowed only one select list item
102 | –269 | Cannot delete or rename a column referenced in a trigger definition
103 | –250 | Identifier '%1' too long
104 | –854 | Function or column reference to '%1' in the ORDER BY clause is invalid
108 | –152 | Invalid ORDER BY specification
133 | –262 | Label '%1' not found
134 | –261 | There is already a variable named '%1'
137 | –260 | Variable '%1' not found
154 | –623 | Data definition statements not allowed in procedures or triggers
155 | –200 | Invalid option '%1' -- no PUBLIC setting exists
174 | –154 | Wrong number of parameters to function '%1'
176 | –611 | Transact-SQL feature not supported
176 | –148 | Unknown function '%1'
182 | –159 | Invalid column number
201 | –639 | Parameter name missing in call to procedure '%1'
201 | –615 | Parameter '%1' not found in procedure '%2'
201 | –737 | Signature '%1' does not match procedure parameters
205 | –153 | SELECT lists in UNION, INTERSECT or EXCEPT do not match in length
207 | –124 | More columns are being dropped from table '%1' than are defined
207 | –143 | Column '%1' not found
208 | –142 | Correlation name '%1' not found
209 | –144 | Column '%1' found in more than one table -- need a correlation name
209 | –163 | Derived table '%1' has no name for column %2
213 | –207 | Wrong number of values for INSERT
217 | –274 | Procedure or trigger calls have nested too deeply
220 | –158 | Value %1 out of range for destination
230 | –191 | Cannot modify column '%1' in table '%2'
230 | –190 | Cannot update an expression
233 | –195 | Column '%1' in table '%2' cannot be NULL
233 | –733 | Number of columns allowing NULLs exceeds limit
257 | –157 | Cannot convert %1 to a %2
257 | –705 | Return type of void from procedure '%1' cannot be used in any expression
262 | –121 | Permission denied: %1
264 | –637 | Duplicate insert column
285 | –708 | READTEXT or WRITETEXT statement cannot refer to a view
301 | –147 | There is more than one way to join '%1' to '%2'
301 | –680 | Invalid expression in WHERE clause of Transact-SQL outer join
301 | –146 | There is no way to join '%1' to '%2'
305 | –681 | Invalid join type used with Transact-SQL outer join
311 | –295 | Cannot uniquely identify rows in cursor
314 | –122 | Operation would cause a group cycle
315 | –136 | Table '%1' is in an outer join cycle
315 | –137 | Table '%1' requires a unique correlation name
401 | –134 | Feature '%1' not implemented
401 | –135 | Language extension
401 | –156 | Invalid expression near '%1'
401 | –994 | Too many arguments for function or procedure '%1'
404 | –890 | Statement size or complexity exceeds server limits
409 | 109 | Null value eliminated in aggregate function
409 | –90 | Argument %1 of procedure '%2' cannot be null
504 | –265 | Procedure '%1' not found
509 | –140 | User ID '%1' does not exist
512 | –186 | Subquery cannot return more than one row
518 | 103 | Invalid data conversion
532 | 104 | Row has been updated since last time read
532 | 106 | Value for column '%1' in table '%2' has changed
538 | –627 | Disallowed language extension detected in syntax near '%1'
546 | –194 | No primary key value for foreign key '%1' in table '%2'
547 | –198 | Primary key for row in table '%1' is referenced by foreign key '%2' in table '%3'
547 | –677 | Table '%1' has a foreign key with a referential action
548 | –196 | Index '%1' for table '%2' would not be unique
548 | –209 | Constraint '%1' violated: Invalid value for column '%2' in table '%3'
549 | –729 | The specified foreign key (%1) can not be enforced
550 | –632 | WITH CHECK OPTION violated for insert/update on base table '%1'
553 | –264 | Wrong number of variables in FETCH
554 | –208 | Row has changed since last read -- operation canceled
557 | –853 | Cursor not in a valid state
557 | –170 | Cursor has not been declared
558 | –172 | Cursor already open
559 | –180 | Cursor not open
560 | 100 | Row not found
560 | –197 | No current row of cursor
573 | –738 | Password must be at least %1 characters
590 | 111 | Statement cannot be executed
601 | –642 | Invalid SQL descriptor name
708 | –80 | Unable to start database server
708 | –86 | Not enough memory to start
708 | –679 | Not enough memory is allocated to the Java virtual machine for remote access
709 | –996 | Specified local connection not found.
710 | –997 | Specified local connection is not to the current database.
711 | –998 | Cannot close a remote JDBC connection that is not the current connection.
840 | –82 | Unable to start specified database: %1
840 | –87 | Database name required to start server
840 | –1008 | Unable to start specified database: '%1' is an invalid transaction log mirror
840 | –1009 | Unable to start specified database: The transaction log '%1' or its mirror '%2' is invalid
840 | –1010 | Unable to start specified database: '%1' not expecting any operations in transaction log
840 | –1011 | Unable to start specified database: Unknown encryption algorithm.
840 | –1012 | Unable to start specified database: '%1' must be upgraded to start with this server (capability %2 missing).
840 | –1013 | Unable to start specified database: '%1' found, but database not found
840 | –1014 | Unable to start specified database: '%1' is compressed -- use a write file or open in read-only mode
840 | –1015 | Unable to start specified database: The database for write file '%1' has an incorrect modification time
840 | –1016 | Unable to start specified database: Can't use log file '%1' since it has been used more recently than the database file
840 | –1017 | Unable to start specified database: '%1': transaction log file not found
840 | –1018 | Unable to start specified database: Can't use log file '%1' since the offsets don't match the offsets in the database file
840 | –1019 | Unable to start specified database: Can't use log file '%1' since the database file has been used more recently
840 | –1020 | Unable to start specified database: Can't use log file '%1' since it is shorter than expected
840 | –1004 | Unable to start specified database: '%1' is not a database
840 | –1005 | Unable to start specified database: '%1' was created by a different version of the software
840 | –1006 | Unable to start specified database: '%1' is not a valid database file
840 | –1007 | Unable to start specified database: '%1' is an invalid transaction log
911 | –83 | Specified database not found
924 | –816 | Specified database file already in use
927 | –97 | Database page size too big
927 | –644 | Invalid database page size
928 | –645 | Database creation failed: %1
932 | –311 | Internal rollback log corrupted
950 | –76 | Request denied -- no active databases
950 | –74 | The selected database is currently inactive
1205 | –306 | Deadlock detected
1205 | –307 | All threads are blocked
1205 | –684 | Rollback occurred due to deadlock during prefetch
1601 | –102 | Database server connection limit exceeded
1602 | –85 | Communication error
1602 | –88 | Client/server communications protocol version mismatch
1702 | –616 | Too many columns in table
1709 | –849 | Referential integrity actions other than RESTRICT not allowed for temporary tables
1709 | –850 | Tables related by key constraint must both be permanent or both be temporary created with ON COMMIT PRESERVE ROWS
1709 | –865 | Key constraint between temporary tables requires a primary key (not unique constraint)
1719 | –118 | Table '%1' has no primary key
1721 | –113 | Column '%1' in foreign key has a different definition than primary key
1801 | –77 | Database name not unique
1802 | –138 | Dbspace '%1' not found
1909 | –636 | Duplicate referencing column
1909 | –119 | Primary key column '%1' already defined
1909 | –251 | Foreign key '%1' for table '%2' duplicates an existing foreign key
1921 | –111 | Index name '%1' not unique
1921 | –678 | Index name '%1' is ambiguous
1923 | –126 | Table cannot have two primary keys
1923 | –112 | Table already has a primary key
2561 | –106 | Cannot open transaction log file -- %1
2601 | –193 | Primary key for table '%1' is not unique
2706 | –141 | Table '%1' not found
2715 | –613 | User-defined type '%1' not found
2727 | –189 | Unable to find in index '%1' for table '%2'
2732 | –296 | Error number %1 for RAISERROR may not be less than 17000
2748 | –612 | User message %1 not found
2749 | –294 | Format string argument number %1 is invalid
3013 | –305 | I/O error %1 -- transaction rolled back
3013 | –309 | Memory error -- transaction rolled back
3206 | –240 | Unknown backup operation
3206 | –241 | Database backup not started
3206 | –242 | Incomplete transactions prevent transaction log renaming
3206 | –1021 | Invalid backup operation
3451 | –672 | Database upgrade failed
3451 | –673 | Database upgrade not possible
3618 | –302 | Terminated by user -- transaction rolled back
3618 | –304 | Disk full '%1' -- transaction rolled back
3619 | –107 | Error writing to transaction log file
3621 | –299 | Statement interrupted by user
3702 | –214 | Table in use
3702 | –215 | Procedure in use by '%1'
3702 | –750 | User owns procedures in use
3702 | –751 | User owns tables in use
3819 | –160 | Can only describe a SELECT statement
4001 | –105 | Database cannot be started -- %1
4001 | –84 | Specified database is invalid
4001 | –72 | No database file specified
4002 | –103 | Invalid user ID or password
4002 | –103 | Invalid user ID or password
4002 | –104 | Invalid user ID or password on preprocessed module
4224 | –108 | Connection not found
4224 | –99 | Connections to database have been disabled
4224 | –308 | Connection was terminated
4406 | –703 | Cannot insert or update computed column '%1'
4409 | –114 | Number of columns defined for the view does not match SELECT statement
4412 | –766 | View references '%1', which is a temporary object. Views can only refer to permanent objects.
4708 | –702 | TRUNCATE TABLE statement cannot refer to a view
4901 | –116 | Table must be empty
4939 | –127 | Cannot alter a column in an index
5006 | –604 | A dbspace has reached its maximum file size
5006 | –605 | The server attempted to access a page beyond the end of the maximum allowable dbspace file size
5703 | 107 | Language extension detected in syntax
5849 | –201 | Invalid setting for option '%1'
5864 | –81 | Invalid database server command line
5864 | –735 | Invalid parameter
5864 | –79 | Invalid local database switch
5864 | –95 | Parse error: %1
5864 | –754 | Parse error: %1
5878 | –204 | Only the DBA can set the option '%1'
5878 | –216 | The option '%1' can only be set as a temporary option
5878 | –217 | The option '%1' cannot be set from within a procedure
6001 | –109 | There are still active database connections
6004 | –75 | Request to start/stop database denied
6226 | –183 | Cannot find index named '%1'
6259 | –263 | Invalid absolute or relative offset in FETCH
6267 | –814 | Cannot update column '%1' since it appears in the ORDER BY clause.
6401 | –220 | Savepoint '%1' not found
7123 | –608 | Invalid TEXTPTR value used with WRITETEXT or READTEXT
7139 | –609 | Invalid data type for column in WRITETEXT or READTEXT
7201 | –155 | Invalid host variable
7203 | –89 | Database server not running in multi-user mode
7301 | –192 | Update operation attempted on non-updatable query
7301 | –813 | FOR UPDATE has been incorrectly specified for a READ ONLY cursor.
7321 | –149 | Function or column reference to '%1' must also appear in a GROUP BY
7337 | 101 | Value truncated
7338 | –728 | Update operation attempted on non-updatable remote query
7364 | –139 | More than one table is identified as '%1'
7374 | –676 | The specified transaction isolation is invalid
7705 | –630 | Invalid escape sequence '%1'
7706 | –606 | The pattern is too long
7707 | –629 | Invalid escape character '%1'
7732 | –633 | Update operation attempted on a read-only cursor
7740 | –815 | Cannot update column '%1' since it does not appear in the SELECT clause.
7950 | –100 | Database server not found
7950 | –96 | Database server already running
8201 | –640 | Invalid descriptor index
8205 | –641 | Error in assignment
8405 | –210 | User '%1' has the row in '%2' locked
9119 | –78 | Dynamic memory exhausted
9502 | –638 | Right truncation of string data
9526 | –187 | Illegal cursor operation attempt
9819 | –268 | Trigger '%1' not found
10356 | –624 | Expression has unsupported data type
11205 | –698 | The remote server does not support an auto-incrementing data type
11205 | –732 | Creating remote tables with computed columns is not supported
11205 | –736 | The data type of column '%1' is not supported
11206 | –656 | Unable to connect to server '%1': %2
11207 | –667 | Could not access column information for the table '%1'
11208 | –722 | The column '%1' does not exist in the remote table
11209 | –721 | The data type specified for column '%1' is not compatible with the actual data type
11210 | –723 | The length specified for column '%1' is different than the actual length
11211 | –724 | Null attribute mismatch for column '%1'
11212 | –725 | Identity attribute mismatch for column '%1'
11214 | –659 | Remote server '%1' could not be found; Add the server using CREATE SERVER
11214 | –666 | The remote table '%1' could not be found
11215 | –726 | The table specification '%1' identifies more than one remote table
11221 | –712 | External login for server '%1' could not be found
11227 | –706 | Remote server does not have the ability to support this statement
11248 | –658 | Remote server '%1' is currently configured as read only
12006 | –110 | Item '%1' already exists
13075 | 102 | Using temporary table
13204 | –150 | Invalid use of an aggregate function
13482 | –1028 | Connection attempting BACKUP has uncommitted transactions
13483 | –1027 | Service type does not allow '%1' attribute
13484 | –1026 | USING attribute cannot coexist with FORMAT or GROUP attributes
13485 | –1025 | Duplicate attribute '%1' in service
13486 | –1024 | Unsupported property '%1' in service USING attribute
13487 | –1023 | Missing value for attribute '%1' in service
13488 | –1022 | Invalid value for attribute '%1' in service
13489 | 137 | Row was dropped from table %1 to maintain referential integrity
13490 | –1003 | Too many distinct group mappings for integrated user
13491 | –1001 | Parameter '%1' in procedure or function '%2' does not have a default value
13492 | –1000 | Temporary space limit exceeded
13493 | –999 | Invalid request log format on line %1
13494 | 136 | The database was created.
13494 | –1002 | The option '%1' is not recognized.
13495 | –995 | Warning detected when optimizing SELECT INTO is treated as an error
13496 | –993 | LOAD TABLE not allowed on temporary table with ON COMMIT DELETE ROWS
13497 | –992 | The specified listener could not be registered
13498 | –991 | The %1 attribute '%2' is not valid
13499 | –990 | The secure connection to the remote host failed
13500 | –989 | NAMESPACE attribute is not valid with procedure type '%1'
13501 | –988 | Invalid response from the HTTP server
13502 | –987 | Invalid procedure subtype '%1' for type '%2'
13503 | –986 | Invalid procedure type '%1'
13504 | –985 | Could not load the encryption DLL '%1'
13505 | –984 | Could not initialize the encryption DLL: '%1'
13506 | –983 | HTTP request failed. Status code '%1'
13507 | –982 | Connection timed out
13508 | –981 | Unable to connect to the remote host specified by '%1'
13509 | –980 | The URI '%1' is invalid
13510 | –979 | Output file cannot be written
13511 | –978 | Output file directory does not exist
13512 | –977 | UltraLite runtime library is incompatible with the database file
13513 | –976 | Could not load the encryption DLL "%1"
13514 | 135 | Compressed database is not encrypted
13515 | –973 | The string is too long (%1)
13516 | –972 | Database page size too small
13517 | –971 | Checksums are not enabled in this database
13518 | 134 | UltraLite cursor (or result set or table) was restored
13519 | 133 | UltraLite connection was restored
13520 | –970 | Invalid hint specified for table '%1'
13521 | –969 | Required operators excluded
13522 | –968 | User '%1' already has EXECUTE permission
13523 | –967 | Backup file '%1' already exists
13524 | –966 | Composite ORDER BY not allowed with RANGE
13525 | –965 | Window function requires ORDER BY
13526 | –964 | Window function used in predicate
13527 | –962 | Argument to GROUPING aggregate must be a grouping column in the GROUP BY clause
13528 | –963 | Password contains an illegal character
13528 | –961 | Input string is not base64-encoded
13529 | –959 | Compression error: %1
13530 | –958 | Password cannot be longer than %1 characters
13530 | –960 | Decompression error: %1
13531 | –957 | Invalid preceding or following size in OLAP function
13532 | –956 | Information for synchronization is incomplete or invalid, check '%1'
13533 | –955 | This connection already exists
13534 | –954 | The database '%1' was not found
13535 | –953 | A schema upgrade is not currently allowed
13536 | –952 | The status of the last synchronization upload is unknown
13537 | –951 | Cannot access schema file '%1'
13538 | –950 | Frame not allowed for window '%1'
13539 | –949 | ORDER BY not allowed in window '%1'
13540 | –948 | PARTITION BY not allowed in reference to window '%1'
13541 | –947 | Window '%1' not found
13542 | –946 | Result set not permitted in '%1'
13543 | –945 | Recursive column %1: conversion from '%2' to '%3' loses precision
13544 | –944 | Too many expressions in GROUP BY list for ROLLUP, CUBE, or GROUPING SETS operation.
13545 | –943 | No workload capture currently exists
13546 | –942 | A workload capture (%1) is already in progress
13547 | –940 | Invalid setting for HTTP header '%1'
13548 | –941 | jConnect does not support encryption
13548 | –939 | Invalid setting for HTTP option '%1'
13549 | –938 | Recursion is not allowed without the RECURSIVE keyword
13550 | –937 | Invalid reference to or operation on constraint '%1'
13551 | –936 | too many constraints in database
13552 | –934 | Unable to start specified database: Server must be upgraded to start database %1
13553 | –935 | Unable to start specified database: Log file error
13554 | –931 | Service definition requires a statement when authorization is off
13555 | –930 | (no message)
13556 | –929 | Constraint '%1' not found
13557 | –928 | Constant expressions may not appear in GROUP BY clause
13558 | –927 | Service statement definition is inconsistent with service type
13559 | –926 | Host variable reference in service definition must be named
13560 | –925 | Invalid service name '%1'
13561 | –923 | Too many recursive iterations
13562 | –922 | No column list for recursive query
13563 | –921 | Invalid recursive query
13564 | –920 | Service '%1' not found
13565 | –919 | Service '%1' already exists
13566 | –918 | A user name must be specified if AUTHORIZATION is OFF
13567 | –924 | Service '%1' in use
13568 | –916 | '%1' is an unrecognized service type
13569 | –915 | Service type required for CREATE SERVICE
13570 | –914 | Cycle in common table expression references
13571 | –913 | A transaction log file is required for auditing
13572 | –912 | Insufficient memory for OPENXML query
13573 | –911 | Control character in XML output
13574 | –910 | System command failed with return code %1
13575 | –908 | Invalid operation on a closed '%1'
13576 | –907 | No name for argument
13577 | –906 | XMLGEN evaluation failure
13578 | –905 | Invalid XQuery constructor
13579 | –904 | Illegal ORDER BY in aggregate function
13580 | –901 | Undeclared tag id: '%1'
13580 | –903 | CDATA has a name
13581 | –900 | Parent not open: '%1'
13581 | –902 | Too few columns
13582 | –899 | Illegal column name: '%1'
13583 | –898 | Unknown FOR XML EXPLICIT directive: '%1'
13584 | –897 | Illegal FOR XML EXPLICIT tag value: '%1'
13585 | 132 | Cannot output the histogram for string column '%1'
13587 | –896 | Cannot delete PUBLIC option '%1' since user settings exist
13588 | 130 | A row could not be converted to the new schema format
13589 | –895 | Encryption error: %1
13589 | –894 | Plan can not be generated for this type of statement
13590 | –893 | Illegal flags value passed to OPENXML
13591 | –892 | XPath parser error: %1
13592 | –891 | Cannot convert between requested character sets '%1' and '%2'
13593 | –657 | Unable to connect to server '%1': server definition is circular
13594 | –889 | Statement contains an illegal usage of the non-deterministic function '%1'
13595 | –888 | XML parser error: %1
13596 | 129 | Plan may contain virtual indexes.
13597 | –887 | Virtual index creation with more than %1 columns.
13600 | 0 | (no message)
13601 | –690 | Return value cannot be set
13602 | –693 | JDBC feature '%1' not supported
13603 | –694 | Could not change an opened prepared statement or callable statement
13604 | –695 | An internal error occurred in a '%1'
13605 | –696 | Invalid operation on a closed '%1'
13606 | –699 | Cannot update member fields qualified with "final" modifier
13607 | –701 | Cannot access instance member through a class
13608 | –713 | An internal error occurred in a '%1'
13609 | –714 | Invalid operation on a closed '%1'
13613 | 114 | Character set translation to '%1' cannot be performed; '%2' is used instead
13614 | 115 | Database server cannot convert data from/to character set '%1', conversion may not be correct
13615 | 116 | Language '%1' is not supported, '%2' will be used
13616 | 117 | Unsupported character set '%1' and unsupported language '%2'; language used is '%3' instead
13617 | 118 | Illegal user selectivity estimate specified
13618 | 105 | Procedure has completed
13619 | 200 | Warning: %1
13620 | –98 | Authentication violation
13621 | –218 | Authentication failed
13622 | –101 | Not connected to a database
13623 | –125 | ALTER clause conflict
13624 | –610 | User message %1 already exists
13625 | –120 | User '%1' already has GRANT permission
13626 | –123 | User '%1' is not a user group
13627 | –312 | User '%1' already has membership in group '%2'
13628 | –130 | Invalid statement
13629 | –132 | SQL statement error
13630 | –133 | Invalid prepared statement type
13631 | –707 | Statement is not allowed in passthrough mode
13632 | –614 | Cannot drop a user that owns messages or data types
13633 | –731 | Cannot drop a user that owns objects involved in replication
13634 | –161 | Invalid type on DESCRIBE statement
13635 | –181 | No indicator variable provided for NULL result
13636 | –182 | Not enough fields allocated in SQLDA
13637 | –185 | SELECT returns more than one row
13638 | –188 | Not enough values for host variables
13639 | –266 | %1
13640 | –267 | COMMIT/ROLLBACK not allowed within atomic operation
13641 | –270 | Cannot drop a user that owns procedures in runtime server
13642 | –280 | Publication '%1' not found
13643 | –281 | Table '%1' has publications
13644 | –282 | Subscription to '%1' for '%2' already exists
13645 | –283 | Subscription to '%1' for '%2' not found
13646 | –284 | User '%1' is already the publisher for this database
13647 | –285 | User '%1' is not a remote user for this database
13648 | –286 | Remote message type '%1' not found
13649 | –287 | Passthrough statement inconsistent with current passthrough
13650 | –288 | Remote statement failed
13652 | –211 | Not allowed while '%1' is using the database
13653 | –212 | CHECKPOINT statement requires a rollback log
13654 | –221 | ROLLBACK TO SAVEPOINT not allowed
13655 | –222 | Result set not allowed from within an atomic compound statement
13656 | –213 | Savepoints require a rollback log
13657 | –230 | Sqlpp/dblib version mismatch
13658 | –231 | Client/database server version mismatch
13660 | –243 | Unable to delete database file
13661 | –244 | Transaction log was truncated
13662 | –297 | User-defined exception signaled
13663 | –298 | Attempted two active database requests
13664 | –300 | Run time SQL error -- %1
13665 | –301 | Internal database error %1 -- transaction rolled back
13666 | –310 | Attempt to read beyond end-of-file in a compressed database
13669 | –601 | '%1' is not a known file format for loading or unloading tables
13670 | –602 | Cannot access file '%1' -- %2
13672 | –643 | UNLOAD TABLE cannot be used to unload a view
13673 | –607 | Cannot stop the database server
13674 | –617 | Calling functions outside the database server is not supported
13675 | –618 | Mismatch between external function platform specifier and current operating system
13676 | –619 | Need a dynamic library name
13677 | –620 | Could not load dynamic library '%1'
13678 | –621 | Could not find '%1' in dynamic library '%2'
13679 | –622 | Could not allocate resources to call external function
13680 | –625 | Too many parameters to this external procedure call
13681 | –626 | A thread used internally could not be started
13682 | –634 | Unterminated C string
13683 | 110 | Transaction log backup page only partially full
13685 | –202 | Only PUBLIC settings are allowed for option '%1'
13686 | 112 | More information required
13687 | –203 | Cannot set a temporary option for user '%1'
13688 | 113 | Database option '%1' for user '%2' has an invalid setting
13689 | –205 | Integrated logins are not permitted
13690 | –206 | Integrated logins are required, standard logins are not permitted
13691 | –245 | Integrated login failed
13692 | –503 | (no message)
13693 | –504 | (no message)
13694 | –246 | Integrated logins are not supported for this database
13695 | –247 | The integrated login ID guest can only be mapped to the guest database user ID
13696 | –248 | Cannot map a login ID to the sys or public user ID
13697 | –249 | The login ID '%1' is already mapped to user ID '%2'
13698 | –313 | The login ID '%1' has not been mapped to any database user ID
13699 | –646 | Could not load the store DLL "%1"
13700 | –647 | Could not execute store DLL (%1) entry point.
13701 | –711 | Incorrect store DLL (%1) version.
13702 | –648 | Cannot create item (%1) in the specified dbspace.
13703 | –93 | Class '%1' has no public field '%2'
13704 | –650 | Index type specification of '%1' is invalid
13705 | –651 | An attempt to delete database '%1' failed
13706 | –654 | The connection parameters file could not be found
13707 | –655 | Error parsing connection parameter string
13708 | –664 | Database is active
13709 | –665 | Database "%1" needs recovery
13710 | –668 | Cursor is restricted to FETCH NEXT operations
13711 | –669 | Method '%1' cannot be called at this time
13712 | –671 | Parameter not registered as output parameter
13713 | –674 | statement's size limit is invalid.
13714 | –683 | The cursor name '%1' already exists
13715 | –685 | Resource governor for '%1' exceeded
13717 | –689 | Input parameter index out of range
13718 | –691 | Could not load the backup/restore DLL "%1"
13719 | –692 | Could not execute backup/restore DLL (%1) entry point.
13720 | –697 | Error during backup: %1
13721 | –700 | SQLDA fields inconsistent for a multi-row SQLDA
13722 | –709 | Computed columns are not supported in this database
13723 | –761 | Server capability name '%1' could not be found in the SYS.SYSCAPABILITYNAME table.
13724 | –715 | Contents of backup files are inconsistent
13725 | –716 | Backup file format is invalid
13726 | –717 | RESTORE unable to open file '%1'
13727 | –718 | RESTORE unable to write to file '%1'
13728 | –719 | RESTORE unable to start database '%1'
13729 | –720 | VALIDATE TABLE statement must refer to a base table
13730 | –727 | The optimizer was unable to construct a valid access plan
13731 | –128 | Cannot drop a user that owns tables in runtime system
13732 | –660 | Server '%1': %2
13733 | –661 | Backwards scrolling cursors are not supported for remote objects
13734 | –682 | %1
13735 | –91 | Procedure '%1' terminated with unhandled exception '%2'
13736 | –92 | '%1' is not a valid class file
13737 | –730 | Invalid jar file
13738 | –94 | Invalid type for field reference
13739 | –164 | Namespace heap exhausted at internal function: %1
13740 | –165 | Java VM heap exhausted at internal function: %1
13741 | –649 | Field '%1' of class '%2' cannot be null
13742 | –652 | Could not decompress class '%1' from Jar.
13743 | –653 | Cannot remove class '%1': member of Jar
13744 | –662 | Cannot serialize Java object with class '%1'
13745 | –663 | Cannot deserialize Java object
13746 | –670 | Invalid class byte code
13747 | –675 | Java virtual machine could not be started
13748 | –704 | Cannot create an index on Java class '%1'
13749 | –710 | Invalid comparison
13750 | –734 | Cannot update or delete an all-NULL row from table '%1'
13751 | 120 | '%1' is an unknown option
13752 | –739 | db_init has not been called or the call to db_init failed
13753 | –740 | The communications environment could not be created
13755 | –742 | JDBC SAStatement batch execute abandoned
13756 | –743 | Seek absolute 0 was attempted on a JDBC SAResultSet
13757 | –744 | Invalid IQ database command line option or parameter value: %1
13758 | –745 | Cannot initialize IQ memory manager: %1
13759 | –746 | Cannot allocate System V resources
13760 | –747 | Invalid JDBC resultset type
13761 | –748 | Invalid JDBC resultset concurrency
13762 | –749 | Feature not available with UltraLite
13763 | –752 | Cannot call the '%1' function on a JDBC resultset when it is positioned on an insert row
13764 | –753 | The JDBC resultset must be positioned on an insert row in order to use the '%1' function
13765 | –755 | You cannot synchronize or upgrade with uncommitted transactions
13766 | –756 | Cannot uniquely identify column '%2' of table '%1' in the current JDBC resultset
13767 | –289 | Multiple consolidated users cannot be defined
13768 | –757 | Modifications not permitted for read-only database
13769 | –758 | The database does not support the Java virtual machine
13770 | –759 | SQLDA data type invalid
13771 | –760 | Invalid SQL identifier
13772 | –762 | '%1' is not a public Java class, and cannot be referenced from SQL
13773 | –763 | '%1' is not a public Java reference, and cannot be referenced from SQL
13774 | –764 | Server not found and unable to autostart
13775 | –765 | Synchronization message type '%1' not found
13776 | 119 | Unable to open backup log '%1'
13777 | –767 | Cannot find synchronization subscription with the name '%1'
13778 | –768 | Cannot subscribe to '%1'
13779 | –769 | Cannot modify synchronization entry using ALTER PUBLICATION
13780 | –770 | Cannot modify publication entry using ALTER SYNCHRONIZATION
13781 | –771 | Event '%1' not found
13782 | –772 | Event '%1' already exists
13783 | –773 | Schedule '%1' for event '%2' not found
13784 | –774 | Schedule '%1' for event '%2' already exists
13787 | –777 | Cannot synchronize table '%1' since it does not have a primary key
13788 | –778 | Must include primary key for table '%1' in the synchronization
13789 | –779 | Cannot create synchronization entry for table '%1' with BLOB primary key
13790 | –780 | Cannot update primary key for table '%1' involved in a publication
13792 | –782 | Cannot register '%1' since another exclusive instance is running
13793 | –783 | Cannot register another '%1' as an exclusive application
13794 | –784 | Cannot register connection because of invalid application cookie
13795 | –785 | Cannot deregister application because of invalid cookie
13796 | –786 | Cannot deregister '%1' since active registered connection exists
13797 | –787 | Current connection is already registered to '%1' as '%2'
13798 | –788 | Another connection has already registered as '%1'
13799 | –789 | Cannot register '%1' since registration cookie exhausted
13800 | –790 | Cannot register connection to '%1' since automatic label exhausted
13801 | –791 | Invalid day of week or month '%1' for event '%2'
13802 | –792 | Invalid time '%1' for event '%2'
13803 | –793 | Invalid start date/time for event '%1'
13804 | –794 | Synchronization server failed to commit the upload
13805 | –795 | Undefined synchronization template '%1'
13806 | –796 | Synchronization site '%1' is already defined
13807 | –797 | Synchronization option '%1' contains semi-colon, equal sign or curly brace
13809 | –799 | DTC transactions are not supported on this platform
13810 | –800 | Cannot commit or rollback while enlisted in a transaction
13811 | –801 | Cannot enlist in a transaction while already enlisted in a transaction
13812 | –802 | Cannot enlist in a transaction with uncommitted data pending
13813 | –803 | Unable to enlist transaction; DTC may be down
13814 | –804 | Unable to reenlist transaction; DTC may be down
13815 | –805 | Synchronization option '%1' not found
13816 | –806 | System event type '%1' not found
13817 | –807 | Host variables may not be used within a batch
13818 | –808 | An internal error was generated by the test harness
13819 | –809 | Synchronization option is too long
13820 | –810 | Java class '%1' not found
13821 | –811 | Jar '%1' not found
13822 | –812 | The Select list for the derived table '%1' has no expression to match '%2'
13823 | –817 | too many temporary tables in connection
13824 | –818 | The external function call is incompatible
13825 | –819 | Table '%1' is part of a synchronization definition
13826 | –820 | Invalid scroll position '%1'
13827 | –821 | Dbspace for table '%1' not found
13828 | –822 | Table '%1' is already included
13829 | –823 | OMNI cannot handle expressions involving remote tables inside stored procedures
13830 | –824 | Illegal reference to correlation name '%1'
13831 | –825 | Previous error lost prior to RESIGNAL
13832 | –826 | Database upgrade not possible; RowGenerator table not owned by user dbo
13833 | –827 | Database upgrade not possible; user tables have table ids in system table range
13834 | –828 | A conflict with the DBMLSync download phase was detected
13835 | –829 | TLS handshake failure
13836 | –830 | Alias '%1' is not unique
13837 | –831 | Definition for alias '%1' must appear before its first reference
13838 | –832 | Connection error: %1
13839 | –833 | Row in table '%1' was modified or deleted in BEFORE trigger
13840 | –834 | Column '%1' not found in table '%2'
13841 | –835 | Event '%1' in use
13842 | –836 | Procedure '%1' is no longer valid
13843 | –837 | Trigger or foreign key for table '%1' is no longer valid
13844 | –838 | TLS initialization on server failed
13845 | –839 | Download failed because of conflicts with existing rows.
13847 | –841 | The JDK version in '%1' does not match '%2'
13848 | –842 | JDK '%1' is not a supported JDK
13849 | –843 | Cannot find synchronization user with the name '%1'
13850 | –844 | Cannot find synchronization definition with the name '%1'
13851 | –845 | Owner '%1' used in a qualified column reference does not match correlation name '%2'
13852 | –846 | Set clause for column '%1' used incorrectly
13853 | –847 | Java SecurityManager class not found: %1
13854 | –848 | Exception occurred while loading Java SecurityManager
13855 | –851 | Decryption error: %1
13856 | –852 | Table name '%1' is ambiguous
13857 | 121 | Cursor option values changed
13858 | –855 | Trigger name '%1' is ambiguous
13859 | –856 | Invalid sqllen field in SQLDA
13860 | –857 | Synchronization failed due to an error on the server: %1
13861 | –858 | CREATE/DROP STATISTICS statement cannot refer to virtual tables
13863 | –859 | %1
13864 | –860 | At least one of the specified dbspaces was not calibrated.
13865 | –861 | Aggregated expression '%1' contains multiple columns of which one or more are outer references
13866 | –862 | The aggregate expression '%1' must appear in either the select list or a HAVING clause subquery
13867 | –863 | Grouped query contains more than one distinct aggregate function
13868 | –303 | Disk write failure '%1' -- transaction rolled back
13869 | –864 | Statement contains an illegal usage of the NUMBER(*) function
13870 | –866 | %1 returned a result set with a different schema than expected
13871 | –867 | Cannot change synchronization user_name when status of the last upload is unknown.
13872 | –868 | '%1' is an unknown character set label
13873 | –869 | Database server cannot convert data from/to character set '%1'
13874 | –870 | Cannot convert between requested character set '%1' and database character set '%2'
13875 | –871 | The database needs to be restarted for this Java related command
13876 | –872 | %1 does not return a result set
13877 | –873 | %1 returned multiple result sets
13878 | –686 | Insufficient cache to start Java virtual machine
13879 | –688 | Strongly-encrypted database files are not supported in the runtime server
13880 | –874 | Column must be named: %1
13882 | –876 | Client out of memory
13883 | 122 | The result returned is non-deterministic.
13884 | 123 | Database created without any schema
13885 | –184 | Column '%1' in table '%2' cannot be NULL. The invalid data was supplied to load table in a data file on line %3.
13886 | 124 | Invalid data conversion: NULL was inserted for column '%1' on row %2.
13887 | –162 | Cannot convert %1 to a %2. The bad value was supplied for column '%3' on row %4 of the data file.
13888 | –877 | SETUSER not allowed in procedures, triggers, events or batches
13889 | –878 | Index '%1' can not be clustered
13890 | –879 | An invalid multi-byte input character was encountered
13891 | –880 | An invalid multi-byte output character was encountered
13892 | 125 | An invalid multi-byte input character was encountered
13893 | 126 | An invalid multi-byte output character was encountered
13894 | –881 | An input character could not be converted to database character set
13895 | –882 | An output character could not be converted to the application character set
13896 | 127 | An input character could not be converted to database character set and simple substitution took place
13897 | 128 | An output character could not be converted to the application character set and simple substitution took place
13898 | –883 | Character conversion reporting is not available when the single byte converter is used
13959 | –974 | File I/O failed for '%1'
13960 | –975 | Incorrect volume ID for '%1'
16846 | –840 | Incorrect or missing encryption key
36007 | –628 | Division by zero


Alphabetic list of error messages

This section provides a full listing of error messages and descriptions.

Errors with an ODBC state marked "handled by ODBC driver" are not returned to ODBC applications, as the ODBC driver carries out the required actions.

(no message)
(no message)
(no message)
(no message)
%1
%1
%1
%1 does not return a result set
'%1' is an unknown character set label
'%1' is an unknown option
'%1' is an unrecognized service type
'%1' is not a known file format for loading or unloading tables
'%1' is not a public Java class, and cannot be referenced from SQL
'%1' is not a public Java reference, and cannot be referenced from SQL
'%1' is not a valid class file
%1 returned a result set with a different schema than expected
%1 returned multiple result sets
A conflict with the DBMLSync download phase was detected
A dbspace has reached its maximum file size
A log is required for IQ databases
A row could not be converted to the new schema format
A schema upgrade is not currently allowed
A thread used internally could not be started
A transaction log file is required for auditing
A user name must be specified if AUTHORIZATION is OFF
A workload capture (%1) is already in progress
Aggregated expression '%1' contains multiple columns of which one or more are outer references
Alias '%1' is not unique
All threads are blocked
ALTER clause conflict
An attempt to delete database '%1' failed
An input character could not be converted to database character set
An input character could not be converted to database character set and simple substitution took place
An internal error occurred in a '%1'
An internal error occurred in a '%1'
An internal error was generated by the test harness
An invalid multi-byte input character was encountered
An invalid multi-byte input character was encountered
An invalid multi-byte output character was encountered
An invalid multi-byte output character was encountered
An output character could not be converted to the application character set
An output character could not be converted to the application character set and simple substitution took place
Another connection has already registered as '%1'
Argument %1 of procedure '%2' cannot be null
Argument to GROUPING aggregate must be a grouping column in the GROUP BY clause
At least one of the specified dbspaces was not calibrated.
Attempt to read beyond end-of-file in a compressed database
Attempted two active database requests
Authentication failed
Authentication violation
Backup file '%1' already exists
Backup file format is invalid
Backwards scrolling cursors are not supported for remote objects
Calling functions outside the database server is not supported
Can only describe a SELECT statement
Cannot access file '%1' -- %2
Cannot access instance member through a class
Cannot access schema file '%1'
Cannot allocate System V resources
Cannot alter a column in an index
Cannot call the '%1' function on a JDBC resultset when it is positioned on an insert row
Cannot change synchronization user_name when status of the last upload is unknown.
Cannot close a remote JDBC connection that is not the current connection.
Cannot commit or rollback while enlisted in a transaction
Cannot convert %1 to a %2
Cannot convert %1 to a %2. The bad value was supplied for column '%3' on row %4 of the data file.
Cannot convert between requested character set '%1' and database character set '%2'
Cannot convert between requested character sets '%1' and '%2'
Cannot create an index on Java class '%1'
Cannot create item (%1) in the specified dbspace.
Cannot create synchronization entry for table '%1' with BLOB primary key
Cannot delete or rename a column referenced in a trigger definition
Cannot delete PUBLIC option '%1' since user settings exist
Cannot deregister '%1' since active registered connection exists
Cannot deregister application because of invalid cookie
Cannot deserialize Java object
Cannot drop a user that owns messages or data types
Cannot drop a user that owns objects involved in replication
Cannot drop a user that owns procedures in runtime server
Cannot drop a user that owns tables in runtime system
Cannot enlist in a transaction while already enlisted in a transaction
Cannot enlist in a transaction with uncommitted data pending
Cannot find index named '%1'
Cannot find synchronization definition with the name '%1'
Cannot find synchronization subscription with the name '%1'
Cannot find synchronization user with the name '%1'
Cannot initialize IQ memory manager: %1
Cannot insert or update computed column '%1'
Cannot map a login ID to the sys or public user ID
Cannot modify column '%1' in table '%2'
Cannot modify publication entry using ALTER SYNCHRONIZATION
Cannot modify synchronization entry using ALTER PUBLICATION
Cannot open transaction log file -- %1
Cannot output the histogram for string column '%1'
Cannot register '%1' since another exclusive instance is running
Cannot register '%1' since registration cookie exhausted
Cannot register another '%1' as an exclusive application
Cannot register connection because of invalid application cookie
Cannot register connection to '%1' since automatic label exhausted
Cannot remove class '%1': member of Jar
Cannot serialize Java object with class '%1'
Cannot set a temporary option for user '%1'
Cannot stop the database server
Cannot subscribe to '%1'
Cannot synchronize table '%1' since it does not have a primary key
Cannot uniquely identify column '%2' of table '%1' in the current JDBC resultset
Cannot uniquely identify rows in cursor
Cannot update an expression
Cannot update column '%1' since it appears in the ORDER BY clause.
Cannot update column '%1' since it does not appear in the SELECT clause.
Cannot update member fields qualified with "final" modifier
Cannot update or delete an all-NULL row from table '%1'
Cannot update primary key for table '%1' involved in a publication
CDATA has a name
Character conversion reporting is not available when the single byte converter is used
Character set translation to '%1' cannot be performed; '%2' is used instead
CHECKPOINT statement requires a rollback log
Checksums are not enabled in this database
Class '%1' has no public field '%2'
Client out of memory
Client/database server version mismatch
Client/server communications protocol version mismatch
Column '%1' found in more than one table -- need a correlation name
Column '%1' in foreign key has a different definition than primary key
Column '%1' in table '%2' cannot be NULL
Column '%1' in table '%2' cannot be NULL. The invalid data was supplied to load table in a data file on line %3.
Column '%1' not found
Column '%1' not found in table '%2'
Column must be named: %1
COMMIT/ROLLBACK not allowed within atomic operation
COMMIT/ROLLBACK not allowed within trigger actions
Communication error
Composite ORDER BY not allowed with RANGE
Compressed database is not encrypted
Compression error: %1
Computed columns are not supported in this database
Connection attempting BACKUP has uncommitted transactions
Connection error: %1
Connection not found
Connection timed out
Connection was terminated
Connections to database have been disabled
Constant expressions may not appear in GROUP BY clause
Constraint '%1' not found
Constraint '%1' violated: Invalid value for column '%2' in table '%3'
Contents of backup files are inconsistent
Control character in XML output
Correlation name '%1' not found
Could not access column information for the table '%1'
Could not allocate resources to call external function
Could not change an opened prepared statement or callable statement
Could not decompress class '%1' from Jar.
Could not execute backup/restore DLL (%1) entry point.
Could not execute store DLL (%1) entry point.
Could not find '%1' in dynamic library '%2'
Could not initialize the encryption DLL: '%1'
Could not load dynamic library '%1'
Could not load the backup/restore DLL "%1"
Could not load the encryption DLL "%1"
Could not load the encryption DLL '%1'
Could not load the store DLL "%1"
CREATE/DROP STATISTICS statement cannot refer to virtual tables
Creating remote tables with computed columns is not supported
Current connection is already registered to '%1' as '%2'
Cursor already open
Cursor has not been declared
Cursor is restricted to FETCH NEXT operations
Cursor not in a valid state
Cursor not open
Cursor option values changed
Cycle in common table expression references
Data definition statements not allowed in procedures or triggers
Database "%1" needs recovery
Database backup not started
Database cannot be started -- %1
Database created without any schema
Database creation failed: %1
Database is active
Database name not unique
Database name required to start server
Database option '%1' for user '%2' has an invalid setting
Database page size too big
Database page size too small
Database server already running
Database server cannot convert data from/to character set '%1'
Database server cannot convert data from/to character set '%1', conversion may not be correct
Database server connection limit exceeded
Database server not found
Database server not running in multi-user mode
Database upgrade failed
Database upgrade not possible
Database upgrade not possible; RowGenerator table not owned by user dbo
Database upgrade not possible; user tables have table ids in system table range
db_init has not been called or the call to db_init failed
Dbspace '%1' not found
Dbspace for table '%1' not found
Deadlock detected
Decompression error: %1
Decryption error: %1
Definition for alias '%1' must appear before its first reference
Derived table '%1' has no name for column %2
Disallowed language extension detected in syntax near '%1'
Disk full '%1' -- transaction rolled back
Disk write failure '%1' -- transaction rolled back
Division by zero
Download failed because of conflicts with existing rows.
DTC transactions are not supported on this platform
Duplicate attribute '%1' in service
Duplicate insert column
Duplicate referencing column
Dynamic memory exhausted
Encryption error: %1
Error during backup: %1
Error in assignment
Error number %1 for RAISERROR may not be less than 17000
Error opening cursor
Error parsing connection parameter string
Error writing to transaction log file
Event '%1' already exists
Event '%1' in use
Event '%1' not found
Exception occurred while loading Java SecurityManager
Expression has unsupported data type
External login for server '%1' could not be found
Feature '%1' not implemented
Feature not available with UltraLite
Field '%1' of class '%2' cannot be null
File I/O failed for '%1'
FOR UPDATE has been incorrectly specified for a READ ONLY cursor.
Foreign key '%1' for table '%2' duplicates an existing foreign key
Foreign key name '%1' not found
Format string argument number %1 is invalid
Frame not allowed for window '%1'
Function or column reference to '%1' in the ORDER BY clause is invalid
Function or column reference to '%1' must also appear in a GROUP BY
GRANT of column permission on view not allowed
Grouped query contains more than one distinct aggregate function
Host variable reference in service definition must be named
Host variables may not be used within a batch
HTTP request failed. Status code '%1'
I/O error %1 -- transaction rolled back
Identifier '%1' too long
Identity attribute mismatch for column '%1'
Illegal column name: '%1'
Illegal cursor operation attempt
Illegal flags value passed to OPENXML
Illegal FOR XML EXPLICIT tag value: '%1'
Illegal ORDER BY in aggregate function
Illegal reference to correlation name '%1'
Illegal user selectivity estimate specified
Incomplete transactions prevent transaction log renaming
Incorrect or missing encryption key
Incorrect store DLL (%1) version.
Incorrect volume ID for '%1'
Index '%1' can not be clustered
Index '%1' for table '%2' would not be unique
Index name '%1' is ambiguous
Index name '%1' not unique
Index type specification of '%1' is invalid
Information for synchronization is incomplete or invalid, check '%1'
Input parameter index out of range
Input string is not base64-encoded
INSERT/DELETE on cursor can modify only one table
Insufficient cache to start Java virtual machine
Insufficient memory for OPENXML query
Integrated login failed
Integrated logins are not permitted
Integrated logins are not supported for this database
Integrated logins are required, standard logins are not permitted
Internal database error %1 -- transaction rolled back
Internal rollback log corrupted
Invalid absolute or relative offset in FETCH
Invalid backup operation
Invalid class byte code
Invalid column number
Invalid comparison
Invalid data conversion
Invalid data conversion: NULL was inserted for column '%1' on row %2.
Invalid data type for column in WRITETEXT or READTEXT
Invalid database page size
Invalid database server command line
Invalid day of week or month '%1' for event '%2'
Invalid descriptor index
Invalid escape character '%1'
Invalid escape sequence '%1'
Invalid expression in WHERE clause of Transact-SQL outer join
Invalid expression near '%1'
Invalid hint specified for table '%1'
Invalid host variable
Invalid IQ database command line option or parameter value: %1
Invalid jar file
Invalid JDBC resultset concurrency
Invalid JDBC resultset type
Invalid join type used with Transact-SQL outer join
Invalid local database switch
Invalid operation on a closed '%1'
Invalid operation on a closed '%1'
Invalid operation on a closed '%1'
Invalid option '%1' -- no PUBLIC setting exists
Invalid ORDER BY specification
Invalid parameter
Invalid preceding or following size in OLAP function
Invalid prepared statement type
Invalid procedure subtype '%1' for type '%2'
Invalid procedure type '%1'
Invalid recursive query
Invalid reference to or operation on constraint '%1'
Invalid REFERENCES clause in trigger definition
Invalid request log format on line %1
Invalid response from the HTTP server
Invalid scroll position '%1'
Invalid service name '%1'
Invalid setting for HTTP header '%1'
Invalid setting for HTTP option '%1'
Invalid setting for option '%1'
Invalid SQL descriptor name
Invalid SQL identifier
Invalid sqllen field in SQLDA
Invalid start date/time for event '%1'
Invalid statement
Invalid TEXTPTR value used with WRITETEXT or READTEXT
Invalid time '%1' for event '%2'
Invalid type for field reference
Invalid type on DESCRIBE statement
Invalid use of an aggregate function
Invalid user ID or password
Invalid user ID or password
Invalid user ID or password on preprocessed module
Invalid value for attribute '%1' in service
Invalid XQuery constructor
Item '%1' already exists
Jar '%1' not found
Java class '%1' not found
Java SecurityManager class not found: %1
Java virtual machine could not be started
Java VM heap exhausted at internal function: %1
jConnect does not support encryption
JDBC feature '%1' not supported
JDBC SAStatement batch execute abandoned
JDK '%1' is not a supported JDK
Key constraint between temporary tables requires a primary key (not unique constraint)
Label '%1' not found
Language '%1' is not supported, '%2' will be used
Language extension
Language extension detected in syntax
LOAD TABLE not allowed on temporary table with ON COMMIT DELETE ROWS
Memory error -- transaction rolled back
Method '%1' cannot be called at this time
Mismatch between external function platform specifier and current operating system
Missing value for attribute '%1' in service
Modifications not permitted for read-only database
More columns are being dropped from table '%1' than are defined
More information required
More than one table is identified as '%1'
Multiple consolidated users cannot be defined
Must include primary key for table '%1' in the synchronization
NAMESPACE attribute is not valid with procedure type '%1'
Namespace heap exhausted at internal function: %1
Need a dynamic library name
No column list for recursive query
No current row of cursor
No database file specified
No indicator variable provided for NULL result
No name for argument
No primary key value for foreign key '%1' in table '%2'
No workload capture currently exists
Not allowed while '%1' is using the database
Not connected to a database
Not enough fields allocated in SQLDA
Not enough memory is allocated to the Java virtual machine for remote access
Not enough memory to start
Not enough values for host variables
Null attribute mismatch for column '%1'
Null value eliminated in aggregate function
Number of columns allowing NULLs exceeds limit
Number of columns defined for the view does not match SELECT statement
OMNI cannot handle expressions involving remote tables inside stored procedures
Only PUBLIC settings are allowed for option '%1'
Only the DBA can set the option '%1'
Operation would cause a group cycle
ORDER BY not allowed in window '%1'
Output file cannot be written
Output file directory does not exist
Owner '%1' used in a qualified column reference does not match correlation name '%2'
Parameter '%1' in procedure or function '%2' does not have a default value
Parameter '%1' not found in procedure '%2'
Parameter name missing in call to procedure '%1'
Parameter not registered as output parameter
Parent not open: '%1'
Parse error: %1
Parse error: %1
PARTITION BY not allowed in reference to window '%1'
Passthrough statement inconsistent with current passthrough
Password cannot be longer than %1 characters
Password contains an illegal character
Password must be at least %1 characters
Permission denied: %1
Plan can not be generated for this type of statement
Plan may contain virtual indexes.
Previous error lost prior to RESIGNAL
Primary key column '%1' already defined
Primary key for row in table '%1' is referenced by foreign key '%2' in table '%3'
Primary key for table '%1' is not unique
Procedure '%1' is no longer valid
Procedure '%1' not found
Procedure '%1' terminated with unhandled exception '%2'
Procedure has completed
Procedure in use by '%1'
Procedure or trigger calls have nested too deeply
Publication '%1' not found
RAISERROR executed: %1
READTEXT or WRITETEXT statement cannot refer to a view
Recursion is not allowed without the RECURSIVE keyword
Recursive column %1: conversion from '%2' to '%3' loses precision
Referential integrity actions other than RESTRICT not allowed for temporary tables
Remote message type '%1' not found
Remote server '%1' could not be found; Add the server using CREATE SERVER
Remote server '%1' is currently configured as read only
Remote server does not have the ability to support this statement
Remote statement failed
Request denied -- no active databases
Request to start/stop database denied
Required operators excluded
Resource governor for '%1' exceeded
RESTORE unable to open file '%1'
RESTORE unable to start database '%1'
RESTORE unable to write to file '%1'
Result set not allowed from within an atomic compound statement
Result set not permitted in '%1'
Return type of void from procedure '%1' cannot be used in any expression
Return value cannot be set
Right truncation of string data
Rollback occurred due to deadlock during prefetch
ROLLBACK TO SAVEPOINT not allowed
Row has been updated since last time read
Row has changed since last read -- operation canceled
Row in table '%1' was modified or deleted in BEFORE trigger
Row not found
Row was dropped from table %1 to maintain referential integrity
Run time SQL error -- %1
Savepoint '%1' not found
Savepoints require a rollback log
Schedule '%1' for event '%2' already exists
Schedule '%1' for event '%2' not found
Seek absolute 0 was attempted on a JDBC SAResultSet
SELECT lists in UNION, INTERSECT or EXCEPT do not match in length
SELECT returns more than one row
Server '%1': %2
Server capability name '%1' could not be found in the SYS.SYSCAPABILITYNAME table.
Server not found and unable to autostart
Service '%1' already exists
Service '%1' in use
Service '%1' not found
Service definition requires a statement when authorization is off
Service statement definition is inconsistent with service type
Service type does not allow '%1' attribute
Service type required for CREATE SERVICE
Set clause for column '%1' used incorrectly
SETUSER not allowed in procedures, triggers, events or batches
Signature '%1' does not match procedure parameters
Specified database file already in use
Specified database is invalid
Specified database not found
Specified local connection is not to the current database.
Specified local connection not found.
SQL statement error
SQLDA data type invalid
SQLDA fields inconsistent for a multi-row SQLDA
Sqlpp/dblib version mismatch
Statement cannot be executed
Statement contains an illegal usage of the non-deterministic function '%1'
Statement contains an illegal usage of the NUMBER(*) function
Statement interrupted by user
Statement is not allowed in passthrough mode
Statement size or complexity exceeds server limits
statement's size limit is invalid.
Strongly-encrypted database files are not supported in the runtime server
Subquery allowed only one select list item
Subquery cannot return more than one row
Subscription to '%1' for '%2' already exists
Subscription to '%1' for '%2' not found
Synchronization failed due to an error on the server: %1
Synchronization message type '%1' not found
Synchronization option '%1' contains semi-colon, equal sign or curly brace
Synchronization option '%1' not found
Synchronization option is too long
Synchronization server failed to commit the upload
Synchronization site '%1' is already defined
Syntax error near '%1' %2
Syntax error, cannot specify IQ specific options without specifying IQ PATH
System command failed with return code %1
System event type '%1' not found
Table '%1' has a foreign key with a referential action
Table '%1' has no primary key
Table '%1' has publications
Table '%1' is already included
Table '%1' is in an outer join cycle
Table '%1' is part of a synchronization definition
Table '%1' not found
Table '%1' requires a unique correlation name
Table already has a primary key
Table cannot have two primary keys
Table in use
Table must be empty
Table name '%1' is ambiguous
Tables related by key constraint must both be permanent or both be temporary created with ON COMMIT PRESERVE ROWS
Temporary space limit exceeded
Terminated by user -- transaction rolled back
The %1 attribute '%2' is not valid
The aggregate expression '%1' must appear in either the select list or a HAVING clause subquery
The column '%1' does not exist in the remote table
The communications environment could not be created
The connection parameters file could not be found
The cursor name '%1' already exists
The data type of column '%1' is not supported
The data type specified for column '%1' is not compatible with the actual data type
The database '%1' was not found
The database does not support the Java virtual machine
The database needs to be restarted for this Java related command
The database was created.
The external function call is incompatible
The integrated login ID guest can only be mapped to the guest database user ID
The JDBC resultset must be positioned on an insert row in order to use the '%1' function
The JDK version in '%1' does not match '%2'
The length specified for column '%1' is different than the actual length
The login ID '%1' has not been mapped to any database user ID
The login ID '%1' is already mapped to user ID '%2'
The optimizer was unable to construct a valid access plan
The option '%1' can only be set as a temporary option
The option '%1' cannot be set from within a procedure
The option '%1' is not recognized.
The pattern is too long
The remote server does not support an auto-incrementing data type
The remote table '%1' could not be found
The result returned is non-deterministic.
The secure connection to the remote host failed
The Select list for the derived table '%1' has no expression to match '%2'
The selected database is currently inactive
The server attempted to access a page beyond the end of the maximum allowable dbspace file size
The specified foreign key (%1) can not be enforced
The specified listener could not be registered
The specified transaction isolation is invalid
The status of the last synchronization upload is unknown
The string is too long (%1)
The table specification '%1' identifies more than one remote table
The URI '%1' is invalid
There are still active database connections
There is already a variable named '%1'
There is more than one way to join '%1' to '%2'
There is no way to join '%1' to '%2'
There is no way to join to '%1'
This connection already exists
TLS handshake failure
TLS initialization on server failed
Too few columns
Too many arguments for function or procedure '%1'
Too many columns in table
too many constraints in database
Too many distinct group mappings for integrated user
Too many expressions in GROUP BY list for ROLLUP, CUBE, or GROUPING SETS operation.
Too many parameters to this external procedure call
Too many recursive iterations
too many temporary tables in connection
Transaction log backup page only partially full
Transaction log was truncated
Transact-SQL feature not supported
Trigger '%1' not found
Trigger definition conflicts with existing triggers
Trigger name '%1' is ambiguous
Trigger or foreign key for table '%1' is no longer valid
Triggers and procedures not supported in runtime server
TRUNCATE TABLE statement cannot refer to a view
UltraLite connection was restored
UltraLite cursor (or result set or table) was restored
UltraLite runtime library is incompatible with the database file
Unable to connect to server '%1': %2
Unable to connect to server '%1': server definition is circular
Unable to connect to the remote host specified by '%1'
Unable to delete database file
Unable to enlist transaction; DTC may be down
Unable to find in index '%1' for table '%2'
Unable to open backup log '%1'
Unable to reenlist transaction; DTC may be down
Unable to start database server
Unable to start specified database: %1
Unable to start specified database: '%1' found, but database not found
Unable to start specified database: '%1' is an invalid transaction log
Unable to start specified database: '%1' is an invalid transaction log mirror
Unable to start specified database: '%1' is compressed -- use a write file or open in read-only mode
Unable to start specified database: '%1' is not a database
Unable to start specified database: '%1' is not a valid database file
Unable to start specified database: '%1' must be upgraded to start with this server (capability %2 missing).
Unable to start specified database: '%1' not expecting any operations in transaction log
Unable to start specified database: '%1' was created by a different version of the software
Unable to start specified database: '%1': transaction log file not found
Unable to start specified database: Can't use log file '%1' since it has been used more recently than the database file
Unable to start specified database: Can't use log file '%1' since it is shorter than expected
Unable to start specified database: Can't use log file '%1' since the database file has been used more recently
Unable to start specified database: Can't use log file '%1' since the offsets don't match the offsets in the database file
Unable to start specified database: Log file error
Unable to start specified database: Server must be upgraded to start database %1
Unable to start specified database: The database for write file '%1' has an incorrect modification time
Unable to start specified database: The transaction log '%1' or its mirror '%2' is invalid
Unable to start specified database: Unknown encryption algorithm.
Undeclared tag id: '%1'
Undefined synchronization template '%1'
Unknown backup operation
Unknown FOR XML EXPLICIT directive: '%1'
Unknown function '%1'
UNLOAD TABLE cannot be used to unload a view
Unsupported character set '%1' and unsupported language '%2'; language used is '%3' instead
Unsupported property '%1' in service USING attribute
Unterminated C string
Update operation attempted on a read-only cursor
Update operation attempted on non-updatable query
Update operation attempted on non-updatable remote query
User '%1' already has EXECUTE permission
User '%1' already has GRANT permission
User '%1' already has membership in group '%2'
User '%1' has the row in '%2' locked
User '%1' is already the publisher for this database
User '%1' is not a remote user for this database
User '%1' is not a user group
User ID '%1' does not exist
User message %1 already exists
User message %1 not found
User owns procedures in use
User owns tables in use
User-defined exception signaled
User-defined type '%1' not found
USING attribute cannot coexist with FORMAT or GROUP attributes
Using temporary table
VALIDATE TABLE statement must refer to a base table
Value %1 out of range for destination
Value for column '%1' in table '%2' has changed
Value truncated
Variable '%1' not found
View references '%1', which is a temporary object. Views can only refer to permanent objects.
Virtual index creation with more than %1 columns.
Warning detected when optimizing SELECT INTO is treated as an error
Warning: %1
Window '%1' not found
Window function requires ORDER BY
Window function used in predicate
WITH CHECK OPTION violated for insert/update on base table '%1'
Wrong number of parameters to function '%1'
Wrong number of values for INSERT
Wrong number of variables in FETCH
XML parser error: %1
XMLGEN evaluation failure
XPath parser error: %1
You cannot synchronize or upgrade with uncommitted transactions


(no message)

Item | Value
SQLCODE | 0
Constant | SQLE_NOERROR
SQLSTATE | 00000
Sybase error code | 13600
ODBC 2 State | 00000
ODBC 3 State | 00000
Probable cause

This code indicates that there was no error or warning.


(no message)

Item | Value
SQLCODE | –503
Constant | SQLE_PREEMPTED
SQLSTATE | WI006
Sybase error code | 13692
ODBC 2 State | ERROR
ODBC 3 State | ERROR


(no message)

Item | Value
SQLCODE | –504
Constant | SQLE_RETRY
SQLSTATE | WI008
Sybase error code | 13693
ODBC 2 State | ERROR
ODBC 3 State | ERROR


(no message)

Item | Value
SQLCODE | –930
Constant | SQLE_AMBIGUOUS_CONSTRAINT
SQLSTATE | 42U05
Sybase error code | 13555
ODBC 2 State | S0002
ODBC 3 State | 42S24
Probable cause

You have asked a unnamed column constraint to be altered, but there is at least one named constraint.


%1

Item | Value
SQLCODE | –266
Constant | SQLE_OLD_DBINIT
SQLSTATE | 42W27
Sybase error code | 13639
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The database is missing some system table definitions required for this statement. These system table definitions are normally created when a database is initialized. The database should be unloaded and reloaded into a database that has been initialized with a newer version of Adaptive Server Anywhere, or use DBUPGRADE to upgrade the database to the most recent version.


%1

Item | Value
SQLCODE | –682
Constant | SQLE_OMNI_DEBUG
SQLSTATE | WO010
Sybase error code | 13734
ODBC 2 State | OK
ODBC 3 State | OK
Parameter 1 | The debug message for the console
Probable cause

This message is used for displaying component integration services debug messages on the console.


%1

Item | Value
SQLCODE | –859
Constant | SQLE_JAVA_IN_USE
SQLSTATE | 55W12
Sybase error code | 13863
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Description of the reason Java cannot be removed
Probable cause

Java cannot be removed because it is being used by a table or procedure, or because an external jar or class is installed.


%1 does not return a result set

Item | Value
SQLCODE | –872
Constant | SQLE_NO_RESULT_SET
SQLSTATE | WP014
Sybase error code | 13876
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the procedure.
Probable cause

A procedure called in the FROM clause of a SELECT statement must return a result set.


'%1' is an unknown character set label

Item | Value
SQLCODE | –868
Constant | SQLE_UNKNOWN_CHARSET
SQLSTATE | WC001
Sybase error code | 13872
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The specified character set label is not recognized, so conversion from/to that character set is not possible.


'%1' is an unknown option

Item | Value
SQLCODE | 120
Constant | SQLE_UNKNOWN_OPTION
SQLSTATE | 01W17
Sybase error code | 13751
ODBC 2 State | 01000
ODBC 3 State | 01000
Probable cause

You attempted to set the value of an option which is not known to the server. You should make sure that you did intend to set the specified option as opposed to having made a typographical error.


'%1' is an unrecognized service type

Item | Value
SQLCODE | –916
Constant | SQLE_UNKNOWN_SERVICE_TYPE
SQLSTATE | 42W94
Sybase error code | 13568
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The service type that is unrecognized.
Probable cause

The service type you specified is unrecognized.


'%1' is not a known file format for loading or unloading tables

Item | Value
SQLCODE | –601
Constant | SQLE_UNSUPPORTED_LOAD_FORMAT
SQLSTATE | WL001
Sybase error code | 13669
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The specified format
Probable cause

An unsupported file format was specified for LOAD TABLE or UNLOAD TABLE.


'%1' is not a public Java class, and cannot be referenced from SQL

Item | Value
SQLCODE | –762
Constant | SQLE_NON_PUBLIC_JAVA_CLASS
SQLSTATE | WJ023
Sybase error code | 13772
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Java class name
Probable cause

Only public Java classes installed into the database are accessible from SQL.


'%1' is not a public Java reference, and cannot be referenced from SQL

Item | Value
SQLCODE | –763
Constant | SQLE_UNKNOWN_JAVA_REF
SQLSTATE | WJ024
Sybase error code | 13773
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | a dotted expression
Probable cause

The dotted expression is neither a public Java class nor a Java variable.


'%1' is not a valid class file

Item | Value
SQLCODE | –92
Constant | SQLE_BAD_CLASS_FILE
SQLSTATE | WP002
Sybase error code | 13736
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the invalid file.
Probable cause

A file passed to the INSTALL JAVA statement was not a valid Java class file.


%1 returned a result set with a different schema than expected

Item | Value
SQLCODE | –866
Constant | SQLE_BAD_RESULT_SET
SQLSTATE | WP012
Sybase error code | 13870
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the procedure that returned the incorrect result set.
Probable cause

When calling a procedure in the FROM clause of a SELECT statement, the expected schema of the result is taken from the WITH clause. If no WITH clause is given, the expected schema is taken from SYSPROCPARM. The result set returned from the call must match the expected schema or it must be possible to convert every column so that it matches.


%1 returned multiple result sets

Item | Value
SQLCODE | –873
Constant | SQLE_TOO_MANY_RESULT_SETS
SQLSTATE | WP013
Sybase error code | 13877
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the procedure.
Probable cause

A procedure called in the FROM clause of a SELECT statement cannot return multiple result sets.


A conflict with the DBMLSync download phase was detected

Item | Value
SQLCODE | –828
Constant | SQLE_RECORDING_CONFLICT_DETECTED
SQLSTATE | WW027
Sybase error code | 13834
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

DBMLSync uses this error to detect download phase conflicts with rows modified by other connections.


A dbspace has reached its maximum file size

Item | Value
SQLCODE | –604
Constant | SQLE_DBSPACE_FULL
SQLSTATE | 04W07
Sybase error code | 5006
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A dbspace has grown to its maximum number of disk pages, which is usually limited by the maximum operating system file size. This is a fatal error.


A log is required for IQ databases

Item | Value
SQLCODE | –933
Constant | SQLE_IQ_LOG_REQUIRED
SQLSTATE | 0AQ48
Sybase error code | 102
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

IQ databases require the use of a log file


A row could not be converted to the new schema format

Item | Value
SQLCODE | 130
Constant | SQLE_ROW_DROPPED_DURING_SCHEMA_UPGRADE
SQLSTATE | 01W21
Sybase error code | 13588
ODBC 2 State | OK
ODBC 3 State | OK
Probable cause

A row which was valid in the old schema is no longer valid. This could be because a column domain changed and the old value can not be cast to the new domain. Rows are also dropped if a uniqueness or foreign key constraint cannot be satisfied.


A schema upgrade is not currently allowed

Item | Value
SQLCODE | –953
Constant | SQLE_SCHEMA_UPGRADE_NOT_ALLOWED
SQLSTATE | WW033
Sybase error code | 13535
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A schema upgrade cannot proceed because of outstanding use of the database. For example, all cursors must be closed before a schema upgrade can occur.


A thread used internally could not be started

Item | Value
SQLCODE | –626
Constant | SQLE_THREAD_START_FAILURE
SQLSTATE | WW011
Sybase error code | 13681
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

This is a Windows95 specific error. An operating system thread could not be started that is required to execute external functions.


A transaction log file is required for auditing

Item | Value
SQLCODE | –913
Constant | SQLE_AUDITING_WITHOUT_TRANSACTION_LOG
SQLSTATE | 42W91
Sybase error code | 13571
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

This database is running without a transaction log file. You must use the dblog utility to create a transaction log file before using auditing.


A user name must be specified if AUTHORIZATION is OFF

Item | Value
SQLCODE | –918
Constant | SQLE_SERVICE_REQUIRES_USER_NAME
SQLSTATE | 42W96
Sybase error code | 13566
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A valid user name must be specified if AUTHORIZATION is OFF.


A workload capture (%1) is already in progress

Item | Value
SQLCODE | –942
Constant | SQLE_WORKLOAD_CAPTURE_ALREADY_EXISTS
SQLSTATE | WW029
Sybase error code | 13546
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You have tried to initiate a workload capture when one is already in progress. You need to wait for the other capture to be completed.


Aggregated expression '%1' contains multiple columns of which one or more are outer references

Item | Value
SQLCODE | –861
Constant | SQLE_MULTIPLE_AGGREGATE_COLUMNS
SQLSTATE | 42W68
Sybase error code | 13865
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | The aggregated expression in error.
Probable cause

A subselect within the nested query contains an aggregate function whose parameters include an outer reference. In such cases, the outer reference must be the only column referenced in the expression.


Alias '%1' is not unique

Item | Value
SQLCODE | –830
Constant | SQLE_ALIAS_NOT_UNIQUE
SQLSTATE | 42W60
Sybase error code | 13836
ODBC 2 State | 37000
ODBC 3 State | ERROR
Parameter 1 | Name of the alias.
Probable cause

The same alias is used more than once in a SELECT list.


All threads are blocked

Item | Value
SQLCODE | –307
Constant | SQLE_THREAD_DEADLOCK
SQLSTATE | 40W06
Sybase error code | 1205
ODBC 2 State | 40001
ODBC 3 State | 40001
Probable cause

You attempted to read or write a row and it is locked by another user. Also, all other threads (see the -gn server option) are blocked waiting for a lock to be released. This is a deadlock situation and your transaction has been chosen as the one to rollback.


ALTER clause conflict

Item | Value
SQLCODE | –125
Constant | SQLE_ALTER_CLAUSE_CONFLICT
SQLSTATE | 53W01
Sybase error code | 13623
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A primary key clause, foreign key clause, or a uniqueness clause must be the only clause of an ALTER TABLE statement.


An attempt to delete database '%1' failed

Item | Value
SQLCODE | –651
Constant | SQLE_DROP_DATABASE_FAILED
SQLSTATE | WW017
Sybase error code | 13705
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Your attempt to delete a database file failed. You may have attempted to delete a running database. Some parts of the database may have been deleted before failure.


An input character could not be converted to database character set

Item | Value
SQLCODE | –881
Constant | SQLE_INPUT_SIMPLE_SUBSTITUTION_ERROR
SQLSTATE | WC005
Sybase error code | 13894
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

While the server was performing character set conversion on an input string, some character(s) could not be represented in the database character set and need to be substituted. The operation was aborted. See document on the On_Charset_conversion_failure option.


An input character could not be converted to database character set and simple substitution took place

Item | Value
SQLCODE | 127
Constant | SQLE_INPUT_SIMPLE_SUBSTITUTION_WARNING
SQLSTATE | 01WC3
Sybase error code | 13896
ODBC 2 State | 01000
ODBC 3 State | 01000
Probable cause

While the server was performing character set conversion on an input string, some character(s) could not be represented in the database character set. Those character(s) were substituted. See document on the On_Charset_conversion_failure option.


An internal error occurred in a '%1'

Item | Value
SQLCODE | –695
Constant | SQLE_JDBC_OBJ_INTERNAL_ERR
SQLSTATE | WJ009
Sybase error code | 13604
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Java class of the object in error
Probable cause

This is an internal JDBC object error. If it can be reproduced, it should be reported to iAnywhere Solutions.


An internal error occurred in a '%1'

Item | Value
SQLCODE | –713
Constant | SQLE_JNAT_OBJ_INTERNAL_ERR
SQLSTATE | WJ013
Sybase error code | 13608
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Java class of the object in error
Probable cause

This is an internal native Java object error. If it can be reproduced, it should be reported to iAnywhere Solutions.


An internal error was generated by the test harness

Item | Value
SQLCODE | –808
Constant | SQLE_TEST_HARNESS
SQLSTATE | WW025
Sybase error code | 13818
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An internal error was generated by the test harness.


An invalid multi-byte input character was encountered

Item | Value
SQLCODE | –879
Constant | SQLE_INPUT_ILLEGAL_MULTIBYTE_ERROR
SQLSTATE | WC003
Sybase error code | 13890
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

While the server was performing character set conversion on an input string, an invalid multi-byte character was encountered. The operation is aborted.


An invalid multi-byte input character was encountered

Item | Value
SQLCODE | 125
Constant | SQLE_INPUT_ILLEGAL_MULTIBYTE_WARNING
SQLSTATE | 01WC1
Sybase error code | 13892
ODBC 2 State | 01000
ODBC 3 State | 01000
Probable cause

While the server was performing character set conversion on an input string, an invalid multi-byte character was encountered. The illegal character was directly copied without conversion. Data following the illegal character may be misinterpreted. See document on the On_Charset_conversion_failure option.


An invalid multi-byte output character was encountered

Item | Value
SQLCODE | –880
Constant | SQLE_OUTPUT_ILLEGAL_MULTIBYTE_ERROR
SQLSTATE | WC004
Sybase error code | 13891
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

While the server was performing character set conversion on an output string, an invalid multi-byte character was encountered. The operation is aborted. See document on the On_Charset_conversion_failure option.


An invalid multi-byte output character was encountered

Item | Value
SQLCODE | 126
Constant | SQLE_OUTPUT_ILLEGAL_MULTIBYTE_WARNING
SQLSTATE | 01WC2
Sybase error code | 13893
ODBC 2 State | 01000
ODBC 3 State | 01000
Probable cause

While the server was performing character set conversion on an output string, an invalid multi-byte character was encountered. The illegal character was directly copied without conversion. Data following the illegal character may be misinterpreted. See document on the On_Charset_conversion_failure option.


An output character could not be converted to the application character set

Item | Value
SQLCODE | –882
Constant | SQLE_OUTPUT_SIMPLE_SUBSTITUTION_ERROR
SQLSTATE | WC006
Sybase error code | 13895
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

While the server was performing character set conversion on an output string, some character(s) could not be represented in the application character set and need to be substituted. The operation was aborted. See document on the On_Charset_conversion_report option.


An output character could not be converted to the application character set and simple substitution took place

Item | Value
SQLCODE | 128
Constant | SQLE_OUTPUT_SIMPLE_SUBSTITUTION_WARNING
SQLSTATE | 01WC4
Sybase error code | 13897
ODBC 2 State | 01000
ODBC 3 State | 01000
Probable cause

While the server was performing character set conversion on an output string, some character(s) could not be represented in the application character set. Those character(s) were substituted. See document on the On_Charset_conversion_failure option.


Another connection has already registered as '%1'

Item | Value
SQLCODE | –788
Constant | SQLE_NOT_UNIQUE_CONN_REG_LABEL
SQLSTATE | 5RW27
Sybase error code | 13798
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | Registered connection label
Probable cause

You attempted to register a connection with a label already in use for the same application.


Argument %1 of procedure '%2' cannot be null

Item | Value
SQLCODE | –90
Constant | SQLE_ARGUMENT_CANNOT_BE_NULL
SQLSTATE | WP000
Sybase error code | 409
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The argument number which cannot be null.
Parameter 2 | The name of the procedure which cannot receive the null parameter.
Probable cause

You passed a null value to a procedure expecting a scalar argument. For example, a Java procedure which has an 'int' argument cannot receive a null value.


Argument to GROUPING aggregate must be a grouping column in the GROUP BY clause

Item | Value
SQLCODE | –962
Constant | SQLE_INVALID_GROUPING_AGGREGATE
SQLSTATE | 42WA7
Sybase error code | 13527
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

Only a grouping column is permitted as an argument to the GROUPING aggregate function. An argument that contain anything other than a single grouping column expression will not be accepted.


At least one of the specified dbspaces was not calibrated.

Item | Value
SQLCODE | –860
Constant | SQLE_DBSPACE_NOT_CALIBRATED
SQLSTATE | WW028
Sybase error code | 13864
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to calibrate a dbspace that was not open or was too small.


Attempt to read beyond end-of-file in a compressed database

Item | Value
SQLCODE | –310
Constant | SQLE_BEYOND_EOF
SQLSTATE | WI001
Sybase error code | 13666
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

While reading the database file, an attempt was made to read beyond the end of the file. This is a fatal internal error.


Attempted two active database requests

Item | Value
SQLCODE | –298
Constant | SQLE_DOUBLE_REQUEST
SQLSTATE | 42W22
Sybase error code | 13663
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

In Embedded SQL, you attempted to submit a database request while you have another request in process. This often occurs in Windows when processing the WM_PAINT message causes a database request, and you get a second WM_PAINT before the database request has completed.


Authentication failed

Item | Value
SQLCODE | –218
Constant | SQLE_AUTHENTICATION_FAILED
SQLSTATE | 08W48
Sybase error code | 13621
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

You set the database_authentication or connection_authentication option incorrectly.


Authentication violation

Item | Value
SQLCODE | –98
Constant | SQLE_AUTHENTICATION_VIOLATION
SQLSTATE | 08W21
Sybase error code | 13620
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

You attempted to connect to a server which has been authenticated for exclusive use with a specific application.


Backup file '%1' already exists

Item | Value
SQLCODE | –967
Constant | SQLE_BACKUP_FILE_EXISTS
SQLSTATE | WB012
Sybase error code | 13523
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the file.
Probable cause

A file which would normally be created by this BACKUP statement already exists.


Backup file format is invalid

Item | Value
SQLCODE | –716
Constant | SQLE_RESTORE_INVALID_FORMAT
SQLSTATE | WB007
Sybase error code | 13725
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The format of an archive file to be used during a RESTORE is invalid.


Backwards scrolling cursors are not supported for remote objects

Item | Value
SQLCODE | –661
Constant | SQLE_OMNI_BACKWARDS_CURSOR
SQLSTATE | WO006
Sybase error code | 13733
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Backwards scrolling cursors are not supported for remote objects. Change the client program to use forward scrolling cursors only.


Calling functions outside the database server is not supported

Item | Value
SQLCODE | –617
Constant | SQLE_EXTERNAL_CALLS_NOT_SUPPORTED
SQLSTATE | WW003
Sybase error code | 13674
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted to call a stored procedure that, in turn, calls a function in a dynamically loaded module. The operating system on which this stored procedure was called does not support such an action.


Can only describe a SELECT statement

Item | Value
SQLCODE | –160
Constant | SQLE_DESCRIBE_NONSELECT
SQLSTATE | 07005
Sybase error code | 3819
ODBC 2 State | OK
ODBC 3 State | OK
Probable cause

In the C language interface, you attempted to describe the select list of a statement other than a SELECT statement.


Cannot access file '%1' -- %2

Item | Value
SQLCODE | –602
Constant | SQLE_CANNOT_ACCESS_FILE
SQLSTATE | WL002
Sybase error code | 13670
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The filename
Parameter 2 | The cause of the error
Probable cause

A file cannot be accessed. For example, a file referenced by LOAD TABLE does not exist or cannot be read. The message will contain the reason for the error.


Cannot access instance member through a class

Item | Value
SQLCODE | –701
Constant | SQLE_CANNOT_ACCESS_INSTANCE_MEMBER
SQLSTATE | WJ011
Sybase error code | 13607
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Non-static fields or methods must be accessed through an object instance.


Cannot access schema file '%1'

Item | Value
SQLCODE | –951
Constant | SQLE_CANNOT_ACCESS_SCHEMA_FILE
SQLSTATE | WW031
Sybase error code | 13537
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the file or indication that no name was given.
Probable cause

UltraLite requires a schema file to perform the current operation. Either no schema file was specified or the one specified was not accessible or was corrupt.


Cannot allocate System V resources

Item | Value
SQLCODE | –746
Constant | SQLE_IQ_SYSTEM_V_FAILURE
SQLSTATE | 08W53
Sybase error code | 13759
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

IQ was unable to allocate System V resources. Please delete unused System V semaphores and shared memory segments or increase OS configuration values for these resources.


Cannot alter a column in an index

Item | Value
SQLCODE | –127
Constant | SQLE_COLUMN_IN_INDEX
SQLSTATE | 53W05
Sybase error code | 4939
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You may have attempted to delete or modify the definition of a column that is part of a primary or foreign key. You may have attempted to delete a column that has an index on it. In this case, DROP the index or key, perform the ALTER statement, and then add the index or key again.


Cannot call the '%1' function on a JDBC resultset when it is positioned on an insert row

Item | Value
SQLCODE | –752
Constant | SQLE_JDBC_INVALID_OPER_ON_INSERT_ROW
SQLSTATE | WJ019
Sybase error code | 13763
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the resultset function being called
Probable cause

Some resultset function such as 'updateRow' and 'deleteRow' are invalid when the cursor of the resultset is positioned at the insert row.


Cannot change synchronization user_name when status of the last upload is unknown.

Item | Value
SQLCODE | –867
Constant | SQLE_CANNOT_CHANGE_USER_NAME
SQLSTATE | 0AW13
Sybase error code | 13871
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

The synchronization server uses the user_name to track synchronizations. If the status of the previous upload is unknown then you must resolve this condition before changing the user.


Cannot close a remote JDBC connection that is not the current connection.

Item | Value
SQLCODE | –998
Constant | SQLE_CANNOT_CLOSE_JDBC_CONNECTION
SQLSTATE | WO026
Sybase error code | 711
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

When attempting to close a remote JDBC connection, the specified connection must be the local connection.


Cannot commit or rollback while enlisted in a transaction

Item | Value
SQLCODE | –800
Constant | SQLE_CANNOT_COMMIT_OR_ROLLBACK_WHILE_ENLISTED
SQLSTATE | 55W09
Sybase error code | 13810
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You tried to explicitly commit or rollback on a connection that is enlisted in a transaction. You must use the Commit/Abort protocol of the transaction instead.


Cannot convert %1 to a %2

Item | Value
SQLCODE | –157
Constant | SQLE_CONVERSION_ERROR
SQLSTATE | 53018
Sybase error code | 257
ODBC 2 State | 07006
ODBC 3 State | 07006
Parameter 1 | The value that could not be converted.
Parameter 2 | The name of the type for the conversion.
Probable cause

You supplied to or fetched from the database an invalid value. For example, the value 12X might have been supplied where a number was required.


Cannot convert %1 to a %2. The bad value was supplied for column '%3' on row %4 of the data file.

Item | Value
SQLCODE | –162
Constant | SQLE_CONVERSION_ERROR_LOAD_TABLE
SQLSTATE | 53017
Sybase error code | 13887
ODBC 2 State | 07006
ODBC 3 State | 07006
Parameter 1 | The value that could not be converted.
Parameter 2 | The name of the type for the conversion.
Parameter 3 | Name of the column where the value was to be inserted.
Parameter 4 | Line number of the data file where the invalid data conversion took place.
Probable cause

The data file supplied to LOAD TABLE contained an invalid value. For example, the value 12X might have been supplied where a number was required.


Cannot convert between requested character set '%1' and database character set '%2'

Item | Value
SQLCODE | –870
Constant | SQLE_FAILED_TO_START_CONVERTER
SQLSTATE | WC002
Sybase error code | 13874
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The server is unable to convert between the connection character set that was specified and the database character set. This could happen when the conversion tables are not properly installed.


Cannot convert between requested character sets '%1' and '%2'

Item | Value
SQLCODE | –891
Constant | SQLE_FAILED_TO_START_CONVERTER_2_CHARSETS
SQLSTATE | WC008
Sybase error code | 13592
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The server is unable to convert between the two specified character sets. This could happen when the conversion tables are not properly installed.


Cannot create an index on Java class '%1'

Item | Value
SQLCODE | –704
Constant | SQLE_CANNOT_INDEX_ON_JAVA_CLASS
SQLSTATE | WW022
Sybase error code | 13748
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the class.
Probable cause

An operation requiring an index was attempted in which at attempt was made to create an index on a Java class type.


Cannot create item (%1) in the specified dbspace.

Item | Value
SQLCODE | –648
Constant | SQLE_INVALID_DBSPACE_FOR_CREATE
SQLSTATE | 08W36
Sybase error code | 13702
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The dbspace specified is invalid. For example, an index must be created in a dbspace of the same type as the underlying table.


Cannot create synchronization entry for table '%1' with BLOB primary key

Item | Value
SQLCODE | –779
Constant | SQLE_BLOB_IN_SYNC_TABLE_PK
SQLSTATE | 5RW18
Sybase error code | 13789
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | Name of the table
Probable cause

You attempted to create a synchronization on a table with BLOB primary key.


Cannot delete or rename a column referenced in a trigger definition

Item | Value
SQLCODE | –269
Constant | SQLE_COLUMN_IN_TRIGGER
SQLSTATE | 53W06
Sybase error code | 102
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted to delete or rename a column referenced in a trigger definition. DROP the trigger before performing the ALTER statement.


Cannot delete PUBLIC option '%1' since user settings exist

Item | Value
SQLCODE | –896
Constant | SQLE_UNSET_PUBLIC_ID
SQLSTATE | 42W82
Sybase error code | 13587
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the option.
Probable cause

You tried to delete a PUBLIC option, but there are user settings for the same option. The user settings must be deleted before the PUBLIC option is deleted.


Cannot deregister '%1' since active registered connection exists

Item | Value
SQLCODE | –786
Constant | SQLE_DEREG_APP_IN_USE
SQLSTATE | 5RW25
Sybase error code | 13796
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | Name of the application
Probable cause

You attempted to deregister an application while there are still active connection registered to that application.


Cannot deregister application because of invalid cookie

Item | Value
SQLCODE | –785
Constant | SQLE_DEREG_APP_NOT_FOUND
SQLSTATE | 5RW24
Sybase error code | 13795
ODBC 2 State | 42000
ODBC 3 State | 42S02
Probable cause

Application has not been registered successfully or it has already been deregistered previously.


Cannot deserialize Java object

Item | Value
SQLCODE | –663
Constant | SQLE_JAVA_DESERIALIZATION_ERROR
SQLSTATE | WW018
Sybase error code | 13745
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The persisted Java object cannot be read from the database column. Possibly, the class of the object has been removed or modified.


Cannot drop a user that owns messages or data types

Item | Value
SQLCODE | –614
Constant | SQLE_USER_OWNS_MESSAGES_OR_DATATYPES
SQLSTATE | 55W05
Sybase error code | 13632
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You attempted to drop a user who is the creator of a message or user-defined data type. The message or user-defined data type must be dropped first.


Cannot drop a user that owns objects involved in replication

Item | Value
SQLCODE | –731
Constant | SQLE_USER_OWNS_REPLICATED_OBJECTS
SQLSTATE | 55W06
Sybase error code | 13633
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You attempted to drop a user who is the creator of a database object involved in replication. For example. the user may own a table that is part of a publication.


Cannot drop a user that owns procedures in runtime server

Item | Value
SQLCODE | –270
Constant | SQLE_USER_OWNS_PROCEDURES
SQLSTATE | 55W04
Sybase error code | 13641
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You attempted to drop a user who owns procedures while using the runtime server. This operation would result in dropping procedures, and the runtime server cannot drop procedures. Use the full server.


Cannot drop a user that owns tables in runtime system

Item | Value
SQLCODE | –128
Constant | SQLE_USER_OWNS_TABLES
SQLSTATE | 55W03
Sybase error code | 13731
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You attempted to drop a user who owns tables, while running the runtime server. This operation would result in dropping tables, which is not permitted in the runtime server. Use the full server.


Cannot enlist in a transaction while already enlisted in a transaction

Item | Value
SQLCODE | –801
Constant | SQLE_CANNOT_ENLIST_WHILE_ALREADY_ENLISTED
SQLSTATE | 55W10
Sybase error code | 13811
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You tried to enlist a second transaction on a connection that is already enlisted in a transaction.


Cannot enlist in a transaction with uncommitted data pending

Item | Value
SQLCODE | –802
Constant | SQLE_CANNOT_ENLIST_WITH_UNCOMMITTED_DATA
SQLSTATE | 55W11
Sybase error code | 13812
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You tried to enlist a transaction on a connection that has pending uncommitted data.


Cannot find index named '%1'

Item | Value
SQLCODE | –183
Constant | SQLE_INDEX_NOT_FOUND
SQLSTATE | 52W03
Sybase error code | 6226
ODBC 2 State | S0012
ODBC 3 State | 42S12
Parameter 1 | Name of the index that cannot be found.
Probable cause

You attempted to perform an operation using an index that does not exist. Check for spelling errors. Check whether the index name must be qualified by a user ID.


Cannot find synchronization definition with the name '%1'

Item | Value
SQLCODE | –844
Constant | SQLE_SYNC_DEFINITION_NOT_FOUND
SQLSTATE | 5RW39
Sybase error code | 13850
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the synchronization definition
Probable cause

You misspelled the name of a synchronization definition or you did not qualify it correctly with a user name.


Cannot find synchronization subscription with the name '%1'

Item | Value
SQLCODE | –767
Constant | SQLE_SYNCHRONIZATION_NOT_FOUND
SQLSTATE | 5RW12
Sybase error code | 13777
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the subscription
Probable cause

You misspelled the name of a synchronization subscription or you did not qualify it correctly with a user name.


Cannot find synchronization user with the name '%1'

Item | Value
SQLCODE | –843
Constant | SQLE_SYNC_SITE_NOT_FOUND
SQLSTATE | 5RW37
Sybase error code | 13849
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the synchronization user
Probable cause

You misspelled the name of a synchronization site or you did not qualify it correctly with a user name.


Cannot initialize IQ memory manager: %1

Item | Value
SQLCODE | –745
Constant | SQLE_IQ_MEMORY_MANAGER_FAILED
SQLSTATE | 08W52
Sybase error code | 13758
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

System V shared memory was requested but could not be allocated.


Cannot insert or update computed column '%1'

Item | Value
SQLCODE | –703
Constant | SQLE_COMPUTED_COLUMN_WRITE_ATTEMPTED
SQLSTATE | WW023
Sybase error code | 4406
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the column.
Probable cause

Computed column values cannot be modified explicitly. Their value is determined implicitly from the computed expression value.


Cannot map a login ID to the sys or public user ID

Item | Value
SQLCODE | –248
Constant | SQLE_INTEGRATED_LOGON_SYSMAP
SQLSTATE | 28W07
Sybase error code | 13696
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

You attempted to map a login ID to either sys or public


Cannot modify column '%1' in table '%2'

Item | Value
SQLCODE | –191
Constant | SQLE_CANNOT_MODIFY
SQLSTATE | 42W32
Sybase error code | 230
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the column that cannot be changed.
Parameter 2 | Name of the table containing the column.
Probable cause

You may have tried to modify a column that you do not have permission to modify. You may have tried to modify a column defined as an expression (such as column1+column2) in a view.


Cannot modify publication entry using ALTER SYNCHRONIZATION

Item | Value
SQLCODE | –770
Constant | SQLE_CANNOT_MODIFY_PUB_AS_SYNC
SQLSTATE | 5RW15
Sybase error code | 13780
ODBC 2 State | 42000
ODBC 3 State | 42S02
Probable cause

You attempted to modify a publication entry using an alter synchronization statement.


Cannot modify synchronization entry using ALTER PUBLICATION

Item | Value
SQLCODE | –769
Constant | SQLE_CANNOT_MODIFY_SYNC_AS_PUB
SQLSTATE | 5RW14
Sybase error code | 13779
ODBC 2 State | 42000
ODBC 3 State | 42S02
Probable cause

You attempted to modify a synchronization entry using an alter publication statement.


Cannot open transaction log file -- %1

Item | Value
SQLCODE | –106
Constant | SQLE_CANNOT_OPEN_LOG
SQLSTATE | 08W05
Sybase error code | 2561
ODBC 2 State | 08003
ODBC 3 State | 08003
Parameter 1 | Reason why transaction log file cannot be opened.
Probable cause

The database server was unable to open the named transaction log file. The log file name may include an invalid device or directory. If this is the case, you can use the DBLOG utility to find out where the transaction log should be and perhaps change it.


Cannot output the histogram for string column '%1'

Item | Value
SQLCODE | 132
Constant | SQLE_CANNOT_DUMP_STRING_HISTOGRAM
SQLSTATE | 01W23
Sybase error code | 13585
ODBC 2 State | OK
ODBC 3 State | OK
Parameter 1 | Name of the column containing string data.
Probable cause

You tried to get the histogram for a column containing strings. Histograms on string information cannot be output in a readable format; as a result, no information was retrieved. Consider using the ESTIMATE function to get information on a specific value or range in the column.


Cannot register '%1' since another exclusive instance is running

Item | Value
SQLCODE | –782
Constant | SQLE_SAME_EXCLUSIVE_APP_RUNNING
SQLSTATE | 5RW21
Sybase error code | 13792
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | Name of the application
Probable cause

You attempted to start an application but another exclusive instance of the same application is already registered.


Cannot register '%1' since registration cookie exhausted

Item | Value
SQLCODE | –789
Constant | SQLE_APP_REG_COOKIE_EXHAUSTED
SQLSTATE | 5RW28
Sybase error code | 13799
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | Name of the application
Probable cause

Cannot register until someone deregistered.


Cannot register another '%1' as an exclusive application

Item | Value
SQLCODE | –783
Constant | SQLE_SAME_APP_RUNNING
SQLSTATE | 5RW22
Sybase error code | 13793
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | Name of the application
Probable cause

You attempted to register an exclusive application but another instance of the same application is already registered.


Cannot register connection because of invalid application cookie

Item | Value
SQLCODE | –784
Constant | SQLE_CANNOT_REG_CONN
SQLSTATE | 5RW23
Sybase error code | 13794
ODBC 2 State | 42000
ODBC 3 State | 42S02
Probable cause

Application registration cannot be found for the given cookie.


Cannot register connection to '%1' since automatic label exhausted

Item | Value
SQLCODE | –790
Constant | SQLE_CONN_REG_AUTO_LABEL_EXHAUSTED
SQLSTATE | 5RW29
Sybase error code | 13800
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | Name of the application
Probable cause

You may register using a specified label instead.


Cannot remove class '%1': member of Jar

Item | Value
SQLCODE | –653
Constant | SQLE_CLASS_MEMBER_OF_JAR
SQLSTATE | WP004
Sybase error code | 13743
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the class file that can't be removed
Probable cause

You attempted to remove a class file which is still part of a Jar. (It must be removed with the Jar)


Cannot serialize Java object with class '%1'

Item | Value
SQLCODE | –662
Constant | SQLE_JAVA_SERIALIZATION_ERROR
SQLSTATE | WI009
Sybase error code | 13744
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The class of the value that cannot be serialized.
Probable cause

The Java object cannot be serialized as a persistent database column.


Cannot set a temporary option for user '%1'

Item | Value
SQLCODE | –203
Constant | SQLE_TEMPORARY_NOT_ALLOWED
SQLSTATE | 42W45
Sybase error code | 13687
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | user ID whose option was to be changed.
Probable cause

TEMPORARY options are set on a connection basis, and only for specific options known to the database server. To change an option for another user, do not specify TEMPORARY in the SET OPTION statement.


Cannot stop the database server

Item | Value
SQLCODE | –607
Constant | SQLE_CANNOT_STOP_SERVER
SQLSTATE | WW002
Sybase error code | 13673
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The server has determined that it cannot be shut down at this time. Normally, this error should not occur.


Cannot subscribe to '%1'

Item | Value
SQLCODE | –768
Constant | SQLE_CANNOT_SUBSCRIBE
SQLSTATE | 5RW13
Sybase error code | 13778
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | Name of the publication.
Probable cause

Some publications are not subscribable such as a synchronization publication.


Cannot synchronize table '%1' since it does not have a primary key

Item | Value
SQLCODE | –777
Constant | SQLE_CANNOT_SYNC_TABLE_WITHOUT_PK
SQLSTATE | 5RW16
Sybase error code | 13787
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | Name of the table
Probable cause

Table for synchronization must contain a primary key.


Cannot uniquely identify column '%2' of table '%1' in the current JDBC resultset

Item | Value
SQLCODE | –756
Constant | SQLE_JDBC_TBL_COL_NOT_FOUND_IN_RESULTSET
SQLSTATE | WJ021
Sybase error code | 13766
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Table name
Parameter 2 | Column name
Probable cause

Failed to identify a column in a JDBC resultset with the given table name and column name. This can happen either the given names are not found or they are ambiguous.


Cannot uniquely identify rows in cursor

Item | Value
SQLCODE | –295
Constant | SQLE_CANNOT_UNIQUELY_IDENTIFY_ROWS
SQLSTATE | 09W05
Sybase error code | 311
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You opened a UNIQUE cursor on a SELECT statement for which a set of columns uniquely identifying each row cannot be generated. One of the tables may not be defined with a primary key or uniqueness constraint, or the SELECT statement may involve a UNION, INTERSECT, EXCEPT or GROUP BY.


Cannot update an expression

Item | Value
SQLCODE | –190
Constant | SQLE_NON_UPDATEABLE_COLUMN
SQLSTATE | 53W02
Sybase error code | 230
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You tried to update a column in a query that is a database expression rather than a column in a table.


Cannot update column '%1' since it appears in the ORDER BY clause.

Item | Value
SQLCODE | –814
Constant | SQLE_CANNOT_UPDATE_ORDER_BY_COLUMN
SQLSTATE | 42W37
Sybase error code | 6267
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the column that appears in the ORDER BY clause.
Probable cause

You attempted to update a column that appears in the ORDER BY clause. The ANSI_UPDATE_CONSTRAINTS option controls whether this update is allowed.


Cannot update column '%1' since it does not appear in the SELECT clause.

Item | Value
SQLCODE | –815
Constant | SQLE_UPDATE_NOT_IN_SELECT
SQLSTATE | 42W38
Sybase error code | 7740
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the column that does not appear in the SELECT clause.
Probable cause

You attempted to update a column that does not explicitly appear in the SELECT list. The ANSI_UPDATE_CONSTRAINTS option controls whether this update is allowed.


Cannot update member fields qualified with "final" modifier

Item | Value
SQLCODE | –699
Constant | SQLE_CANNOT_UPDATE_FINAL_FIELD
SQLSTATE | WJ012
Sybase error code | 13606
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An attempt was made to modify a Java member that was qualified with the "final" modifier. Such members are constant and cannot be modified.


Cannot update or delete an all-NULL row from table '%1'

Item | Value
SQLCODE | –734
Constant | SQLE_CANNOT_UPDATE_NULL_ROW
SQLSTATE | 09W08
Sybase error code | 13750
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | The name of the table which cannot be modified.
Probable cause

You attempted to modify or delete a row in the specified table, which is part of the null-supplying side of an outer join. However, the cursor is currently positioned on a derived row that contains an all-NULL row for this table, which is the result of the failure of one or more ON conditions to evaluate to TRUE. Verify that the UPDATE or DELETE statement is correct.


Cannot update primary key for table '%1' involved in a publication

Item | Value
SQLCODE | –780
Constant | SQLE_ARTICLE_PK_CANNOT_BE_UPDATED
SQLSTATE | 5RW19
Sybase error code | 13790
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | Name of the table.
Probable cause

The primary key of a table involved in a publication cannot be updated. The database option "Prevent_article_pkey_update" can be set to "OFF" to allow updates to the primary key of table involved in a publication.


CDATA has a name

Item | Value
SQLCODE | –903
Constant | SQLE_FOR_XML_EXPLICIT_NAMED_CDATA
SQLSTATE | WX011
Sybase error code | 13580
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A CDATA directive in a FOR XML EXPLICIT query must not be given a name.


Character conversion reporting is not available when the single byte converter is used

Item | Value
SQLCODE | –883
Constant | SQLE_CHARACTER_CONVERSION_REPORT_NOT_AVAILABLE
SQLSTATE | WC007
Sybase error code | 13898
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted to set the On_Charset_conversion_failure option to produce either warning or error report. This setting is not available when the single-byte to single-byte converter is used.


Character set translation to '%1' cannot be performed; '%2' is used instead

Item | Value
SQLCODE | 114
Constant | SQLE_CANNOT_PERFORM_CHAR_TRANSLATION
SQLSTATE | 01W12
Sybase error code | 13613
ODBC 2 State | 01000
ODBC 3 State | 01000
Parameter 1 | Name of character set the application requested.
Parameter 2 | Name of character set the database will be using.
Probable cause

The server is unable to do a character translation from the character set the database is using to the character set the application requested.


CHECKPOINT statement requires a rollback log

Item | Value
SQLCODE | –212
Constant | SQLE_CHECKPOINT_REQUIRES_UNDO
SQLSTATE | 42W20
Sybase error code | 13653
ODBC 2 State | 40001
ODBC 3 State | 40001
Probable cause

You cannot use a CHECKPOINT statement when the database server is running in bulk mode without a rollback log.


Checksums are not enabled in this database

Item | Value
SQLCODE | –971
Constant | SQLE_CHECKSUMS_NOT_ENABLED
SQLSTATE | WW042
Sybase error code | 13517
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An attempt was made to perform checksum validation but the database does not have checksums enabled.


Class '%1' has no public field '%2'

Item | Value
SQLCODE | –93
Constant | SQLE_FIELD_NOT_FOUND
SQLSTATE | WW013
Sybase error code | 13703
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the class in which the named field could not be found.
Parameter 2 | The name of the field which could not be found.
Probable cause

An expression referenced a field which either does not exist or is not public.


Client out of memory

Item | Value
SQLCODE | –876
Constant | SQLE_CLIENT_OUT_OF_MEMORY
SQLSTATE | 08W65
Sybase error code | 13882
ODBC 2 State | S1001
ODBC 3 State | HY001
Probable cause

A failure occurred when the database client was trying to allocate memory.


Client/database server version mismatch

Item | Value
SQLCODE | –231
Constant | SQLE_DBLIB_ENGINE_MISMATCH
SQLSTATE | 08W19
Sybase error code | 13658
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

Your executable uses a database interface library that does not match the version number of the database server.


Client/server communications protocol version mismatch

Item | Value
SQLCODE | –88
Constant | SQLE_PROTOCOL_MISMATCH
SQLSTATE | 08W15
Sybase error code | 1602
ODBC 2 State | 08S01
ODBC 3 State | 08S01
Probable cause

The connection failed because the protocol versions of the client and the server do not match. Make sure the client and server software are the same version.


Column '%1' found in more than one table -- need a correlation name

Item | Value
SQLCODE | –144
Constant | SQLE_COLUMN_AMBIGUOUS
SQLSTATE | 52002
Sybase error code | 209
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the ambiguous column.
Probable cause

You have not put a correlation name on a column that is found in more than one of the tables referenced in a query. You need to add a correlation name to the reference.


Column '%1' in foreign key has a different definition than primary key

Item | Value
SQLCODE | –113
Constant | SQLE_INVALID_FOREIGN_KEY_DEF
SQLSTATE | 53030
Sybase error code | 1721
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the problem column.
Probable cause

The data type of the column in the foreign key is not the same as the data type of the column in the primary key. Change the definition of one of the columns using ALTER TABLE.


Column '%1' in table '%2' cannot be NULL

Item | Value
SQLCODE | –195
Constant | SQLE_COLUMN_CANNOT_BE_NULL
SQLSTATE | 23502
Sybase error code | 233
ODBC 2 State | 23000
ODBC 3 State | 23000
Parameter 1 | Name of the column that cannot be NULL.
Parameter 2 | Name of the table containing the column.
Probable cause

You have not supplied a value where a value is required. The column definition prohibits NULL values or the column is part of a NOT NULL foreign key.


Column '%1' in table '%2' cannot be NULL. The invalid data was supplied to load table in a data file on line %3.

Item | Value
SQLCODE | –184
Constant | SQLE_COLUMN_CANNOT_BE_NULL_LOAD_TABLE
SQLSTATE | 23501
Sybase error code | 13885
ODBC 2 State | 23000
ODBC 3 State | 23000
Parameter 1 | Name of the column that cannot be NULL.
Parameter 2 | Name of the table containing the column.
Parameter 3 | The line number of the data file containing the invalid data.
Probable cause

You either have not supplied a value where a value is required or a data conversion was necessary which resulted in a NULL value. The column definition prohibits NULL values or the column is part of a NOT NULL foreign key.


Column '%1' not found

Item | Value
SQLCODE | –143
Constant | SQLE_COLUMN_NOT_FOUND
SQLSTATE | 52003
Sybase error code | 207
ODBC 2 State | S0002
ODBC 3 State | 42S22
Parameter 1 | Name of the column that could not be found.
Probable cause

You misspelled the name of a column, or the column you are looking for is in a different table.


Column '%1' not found in table '%2'

Item | Value
SQLCODE | –834
Constant | SQLE_COLUMN_NOT_FOUND_IN_TABLE
SQLSTATE | 52005
Sybase error code | 13840
ODBC 2 State | S0002
ODBC 3 State | 42S22
Parameter 1 | Name of the column that could not be found.
Parameter 2 | Name of the table that was supposed to contain the column.
Probable cause

You misspelled the name of a column, or the column you are looking for is in a different table.


Column must be named: %1

Item | Value
SQLCODE | –874
Constant | SQLE_NO_XML_IDENTIFIER
SQLSTATE | WX001
Sybase error code | 13880
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Number of the column that must be named
Probable cause

Unnamed columns cannot be used as XML element or attribute names. Name unnamed columns in the SELECT list using AS.


COMMIT/ROLLBACK not allowed within atomic operation

Item | Value
SQLCODE | –267
Constant | SQLE_ATOMIC_OPERATION
SQLSTATE | 42W28
Sybase error code | 13640
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted a COMMIT or ROLLBACK statement while executing within an atomic operation.


COMMIT/ROLLBACK not allowed within trigger actions

Item | Value
SQLCODE | –273
Constant | SQLE_INVALID_TRIGGER_STATEMENT
SQLSTATE | 2D501
Sybase error code | 102
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to execute a statement that is not allowed while performing a trigger action. COMMIT and ROLLBACK statements cannot be executed from a trigger.


Communication error

Item | Value
SQLCODE | –85
Constant | SQLE_COMMUNICATIONS_ERROR
SQLSTATE | 08W12
Sybase error code | 1602
ODBC 2 State | 08S01
ODBC 3 State | 08S01
Probable cause

There is a communication problem between the application and the server.


Composite ORDER BY not allowed with RANGE

Item | Value
SQLCODE | –966
Constant | SQLE_ILLEGAL_COMPOSITE_ORDERBY
SQLSTATE | 42WAA
Sybase error code | 13524
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Window functions that use the RANGE keyword may only ORDER BY a single column.


Compressed database is not encrypted

Item | Value
SQLCODE | 135
Constant | SQLE_COMPRESSING_ENCRYPTED_DB
SQLSTATE | WW045
Sybase error code | 13514
ODBC 2 State | 01000
ODBC 3 State | 01000
Probable cause

The input database is encrypted, but the compressed database just created is not. Compressing a database removes the encryption.


Compression error: %1

Item | Value
SQLCODE | –959
Constant | SQLE_COMPRESSION_ERROR
SQLSTATE | WW037
Sybase error code | 13529
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An error occurred during compression. :EN-


Computed columns are not supported in this database

Item | Value
SQLCODE | –709
Constant | SQLE_COMPUTED_COLUMNS_NOT_SUPPORTED
SQLSTATE | 0AW06
Sybase error code | 13722
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

The current database is an older database and does not have catalog support for computed (materialized) columns. To use this feature, upgrade your database to the most recent version.


Connection attempting BACKUP has uncommitted transactions

Item | Value
SQLCODE | –1028
Constant | SQLE_BACKUP_HAS_UNCOMMITTED_TRANS
SQLSTATE | WB014
Sybase error code | 13482
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A connection attempting to do a "BACKUP ... WAIT BEFORE START" or "BACKUP ... WAIT AFTER END" has uncommitted transactions. A COMMIT or ROLLBACK must be performed before executing the backup.


Connection error: %1

Item | Value
SQLCODE | –832
Constant | SQLE_CONNECTION_ERROR
SQLSTATE | 08W60
Sybase error code | 13838
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | Description of the connection error.
Probable cause

An error occurred while attempting to establish a connection with the database server, but before attempting to connect to a database. Failure to initialize a communication link during the connection attempt is an example of this error. Creating a debug log file using the LogFile connection parameter may provide more information.


Connection not found

Item | Value
SQLCODE | –108
Constant | SQLE_CONNECTION_NOT_FOUND
SQLSTATE | 08W02
Sybase error code | 4224
ODBC 2 State | 08003
ODBC 3 State | 08003
Probable cause

The specified connection name on a DISCONNECT or SET CONNECTION statement is invalid.


Connection timed out

Item | Value
SQLCODE | –982
Constant | SQLE_REMOTE_CONNECTION_TIMED_OUT
SQLSTATE | WW051
Sybase error code | 13507
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The connection the remote host timed out due to inactivity.


Connection was terminated

Item | Value
SQLCODE | –308
Constant | SQLE_CONNECTION_TERMINATED
SQLSTATE | 40W07
Sybase error code | 4224
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Your database connection has been terminated and your transaction has been rolled back. The connection may have been terminated because a DBA executed a DROP CONNECTION statement, or because the database server was shut down, or because your network connection to the database server was interrupted.


Connections to database have been disabled

Item | Value
SQLCODE | –99
Constant | SQLE_CONNECTIONS_DISABLED
SQLSTATE | 08W04
Sybase error code | 4224
ODBC 2 State | 08005
ODBC 3 State | 08005
Probable cause

Connections to the network database server have been disabled. You will receive this error until connections have been enabled.


Constant expressions may not appear in GROUP BY clause

Item | Value
SQLCODE | –928
Constant | SQLE_NO_CONSTANTS_IN_GROUP_BY
SQLSTATE | 42W9D
Sybase error code | 13557
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You used a constant in the GROUP BY clause. Constants must not appear in the GROUP BY clause for a query. References to columns in a view that are constant are permitted in a GROUP BY clause. Also expressions which use a view column that is constant are also permitted.


Constraint '%1' not found

Item | Value
SQLCODE | –929
Constant | SQLE_CONSTRAINT_NOT_FOUND
SQLSTATE | 42U04
Sybase error code | 13556
ODBC 2 State | S0002
ODBC 3 State | 42S23
Parameter 1 | Name of the constraint that could not be found.
Probable cause

You misspelled the name of a constraint, or the constraint you are looking for is on a different table.


Constraint '%1' violated: Invalid value for column '%2' in table '%3'

Item | Value
SQLCODE | –209
Constant | SQLE_INVALID_COLUMN_VALUE
SQLSTATE | 23506
Sybase error code | 548
ODBC 2 State | 42000
ODBC 3 State | 23000
Parameter 1 | Name of the constraint (if defined) that was violated by an invalid value.
Parameter 2 | Name of the column that was assigned an invalid value.
Parameter 3 | Name of the table containing the column.
Probable cause

You attempted an insert or update that violates a CHECK constraint. A CHECK constraint is violated if it evaluates to FALSE; it is deemed to hold if the condition evaluates to TRUE or UNKNOWN.


Contents of backup files are inconsistent

Item | Value
SQLCODE | –715
Constant | SQLE_RESTORE_INCONSISTENT
SQLSTATE | WB006
Sybase error code | 13724
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

During a RESTORE, the contents of a backup that was done to two or more disk or tape devices were found to be inconsistent.


Control character in XML output

Item | Value
SQLCODE | –911
Constant | SQLE_CONTROL_CHARACTER_IN_XML_OUTPUT
SQLSTATE | WX015
Sybase error code | 13573
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A non-space character less than 0x20 was encountered while generating XML content. Consider base64 encoding strings that contain control characters before using them as XML content. This can be accomplished in a FOR XML query or SQLX function by casting the string to a type such as LONG BINARY.


Correlation name '%1' not found

Item | Value
SQLCODE | –142
Constant | SQLE_CORRELATION_NAME_NOT_FOUND
SQLSTATE | 52W02
Sybase error code | 208
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the invalid correlation name.
Probable cause

You misspelled a correlation name, or you used a table name instead of the correlation name.


Could not access column information for the table '%1'

Item | Value
SQLCODE | –667
Constant | SQLE_OMNI_RMT_COLUMNS_NOTFOUND
SQLSTATE | WO008
Sybase error code | 11207
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The complete name of the remote table
Probable cause

Column information for the table could not be accessed. Check privileges for the table.


Could not allocate resources to call external function

Item | Value
SQLCODE | –622
Constant | SQLE_ERROR_CALLING_FUNCTION
SQLSTATE | WW008
Sybase error code | 13679
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The external function could not be called due to a shortage of operating system resources. If the operating system supports threads, the maximum thread count should be increased.


Could not change an opened prepared statement or callable statement

Item | Value
SQLCODE | –694
Constant | SQLE_CANNOT_CHANGE_OPENED_STATEMENT
SQLSTATE | WJ008
Sybase error code | 13603
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted to change the SQL statement of an opened prepared statement or callable statement. Prepared statement and callable statement must be closed before attempting such changes.


Could not decompress class '%1' from Jar.

Item | Value
SQLCODE | –652
Constant | SQLE_CANNOT_DECOMPRESS_CLASS
SQLSTATE | WP003
Sybase error code | 13742
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the class file in the Jar
Probable cause

The Java runtime library must be installed to extract class files from .ZIPs or .JARs


Could not execute backup/restore DLL (%1) entry point.

Item | Value
SQLCODE | –692
Constant | SQLE_BACKUP_ENTRY_NOT_FOUND
SQLSTATE | 08W45
Sybase error code | 13719
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An attempt to locate or execute the backup/restore DLL entry point failed.


Could not execute store DLL (%1) entry point.

Item | Value
SQLCODE | –647
Constant | SQLE_STORE_ENTRY_NOT_FOUND
SQLSTATE | 08W35
Sybase error code | 13700
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An attempt to locate or execute the store DLL entry point failed.


Could not find '%1' in dynamic library '%2'

Item | Value
SQLCODE | –621
Constant | SQLE_COULD_NOT_FIND_FUNCTION
SQLSTATE | WW007
Sybase error code | 13678
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the function which could not be found.
Parameter 2 | Name of the dynamic library in which the function could not be found.
Probable cause

The external function could not be found in the dynamic library.


Could not initialize the encryption DLL: '%1'

Item | Value
SQLCODE | –984
Constant | SQLE_ENCRYPTION_INITIALIZATION_FAILED
SQLSTATE | WW053
Sybase error code | 13505
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Reason the initialization failed, if known.
Probable cause

An attempt to initialize the encryption DLL failed.


Could not load dynamic library '%1'

Item | Value
SQLCODE | –620
Constant | SQLE_COULD_NOT_LOAD_LIBRARY
SQLSTATE | WW006
Sybase error code | 13677
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the dynamic library which could not be loaded.
Probable cause

This error is usually caused by a failure to load a dynamic library named in an external function call. This error can also occur if other libraries such as the Java virtual machine library are missing.


Could not load the backup/restore DLL "%1"

Item | Value
SQLCODE | –691
Constant | SQLE_BACKUP_NOT_LOADED
SQLSTATE | 08W44
Sybase error code | 13718
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An attempt to load the backup/restore DLL failed.


Could not load the encryption DLL "%1"

Item | Value
SQLCODE | –976
Constant | SQLE_MISSING_ENCRYPTION_DLL
SQLSTATE | 08W70
Sybase error code | 13513
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An attempt to load the encryption DLL failed.


Could not load the encryption DLL '%1'

Item | Value
SQLCODE | –985
Constant | SQLE_ENCRYPTION_LIB_LOAD_FAILED
SQLSTATE | WW054
Sybase error code | 13504
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The encryption DLL
Probable cause

An attempt to load the encryption DLL failed.


Could not load the store DLL "%1"

Item | Value
SQLCODE | –646
Constant | SQLE_STORE_NOT_LOADED
SQLSTATE | 08W34
Sybase error code | 13699
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An attempt to load the store DLL failed.


CREATE/DROP STATISTICS statement cannot refer to virtual tables

Item | Value
SQLCODE | –858
Constant | SQLE_HISTOGRAMS_NOT_SUPPORTED_ON_OBJECT
SQLSTATE | 42W67
Sybase error code | 13861
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to use CREATE/DROP STATISTICS to create/drop one or more histograms on a virtual database object, such as a view or remote table. The CREATE STATISTICS and DROP STATISTICS statements can only refer to base tables, local temporary tables, or global temporary tables in the ASA database that you are connected to.


Creating remote tables with computed columns is not supported

Item | Value
SQLCODE | –732
Constant | SQLE_OMNI_COMPUTED_NOT_SUPPORTED
SQLSTATE | WO021
Sybase error code | 11205
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Computed columns are not supported in 'CREATE TABLE' statements which specify a remote location.


Current connection is already registered to '%1' as '%2'

Item | Value
SQLCODE | –787
Constant | SQLE_CONN_ALREADY_REGISTERED
SQLSTATE | 5RW26
Sybase error code | 13797
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | Name of the application
Parameter 2 | Registered connection label
Probable cause

You attempted to register this connection more than once.


Cursor already open

Item | Value
SQLCODE | –172
Constant | SQLE_CURSOR_ALREADY_OPEN
SQLSTATE | 24502
Sybase error code | 558
ODBC 2 State | 24000
ODBC 3 State | 24000
Probable cause

You attempted to OPEN a cursor that is already open.


Cursor has not been declared

Item | Value
SQLCODE | –170
Constant | SQLE_CURSOR_NOT_DECLARED
SQLSTATE | 24W01
Sybase error code | 557
ODBC 2 State | 24000
ODBC 3 State | 24000
Probable cause

You attempted to OPEN a cursor that has not been declared.


Cursor is restricted to FETCH NEXT operations

Item | Value
SQLCODE | –668
Constant | SQLE_NO_SCROLL_CURSOR
SQLSTATE | 09W06
Sybase error code | 13710
ODBC 2 State | S1106
ODBC 3 State | HY106
Probable cause

An illegal FETCH operation has been detected for a NO SCROLL cursor. For a forward-only cursor the only permitted FETCH operations are FETCH RELATIVE 0 and FETCH NEXT (FETCH RELATIVE 1).


Cursor not in a valid state

Item | Value
SQLCODE | –853
Constant | SQLE_CURSOR_INVALID_STATE
SQLSTATE | 24000
Sybase error code | 557
ODBC 2 State | 24000
ODBC 3 State | 24000
Probable cause

You attempted to use a cursor that is not in a valid state for the attempted operation. For example, the cursor may have encountered an error.


Cursor not open

Item | Value
SQLCODE | –180
Constant | SQLE_CURSOR_NOT_OPEN
SQLSTATE | 24501
Sybase error code | 559
ODBC 2 State | 34000
ODBC 3 State | 34000
Probable cause

You attempted to use a cursor that has not been opened.


Cursor option values changed

Item | Value
SQLCODE | 121
Constant | SQLE_CURSOR_OPTIONS_CHANGED
SQLSTATE | 01S02
Sybase error code | 13857
ODBC 2 State | 01S02
ODBC 3 State | 01S02
Probable cause

The engine could not support the requested cursor option values for the associated query, and similar option settings were substituted.


Cycle in common table expression references

Item | Value
SQLCODE | –914
Constant | SQLE_COMMON_TABLE_EXPRESSION_CYCLE
SQLSTATE | 42W93
Sybase error code | 13570
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

Cycles involving multiple common table expressions are not allowed.


Data definition statements not allowed in procedures or triggers

Item | Value
SQLCODE | –623
Constant | SQLE_DDL_NOT_ALLOWED_IN_PROCEDURES
SQLSTATE | 52W21
Sybase error code | 154
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The procedure or trigger definition contains a data definition statement (such as CREATE, DROP, GRANT, REVOKE, ALTER). These statements are not allowed within procedures or triggers.


Database "%1" needs recovery

Item | Value
SQLCODE | –665
Constant | SQLE_DATABASE_NEEDS_RECOVERY
SQLSTATE | 08W41
Sybase error code | 13709
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The filename of the database that needs recovery.
Probable cause

The database quit abnormally the last time it was used. Database recovery must be performed before proceeding.


Database backup not started

Item | Value
SQLCODE | –241
Constant | SQLE_BACKUP_NOT_STARTED
SQLSTATE | WB002
Sybase error code | 3206
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A database backup could not be started. Either you do not have DBA authority, or another backup has started and not completed.


Database cannot be started -- %1

Item | Value
SQLCODE | –105
Constant | SQLE_UNABLE_TO_CONNECT
SQLSTATE | 08001
Sybase error code | 4001
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | Reason that database cannot be started.
Probable cause

The specified database cannot be started. Either it does not exist, it is not a database, it is corrupt, or it is an older format.


Database created without any schema

Item | Value
SQLCODE | 123
Constant | SQLE_DATABASE_NEW
SQLSTATE | 01W19
Sybase error code | 13884
ODBC 2 State | OK
ODBC 3 State | OK
Probable cause

An UltraLite database was created without a schema provided. A schema upgrade must occur before any database operations can take place.


Database creation failed: %1

Item | Value
SQLCODE | –645
Constant | SQLE_DATABASE_NOT_CREATED
SQLSTATE | 08W33
Sybase error code | 928
ODBC 2 State | 08004
ODBC 3 State | 08004
Parameter 1 | Reason that the database was not created.
Probable cause

Your attempt to initialize a file for a database failed.


Database is active

Item | Value
SQLCODE | –664
Constant | SQLE_DATABASE_ACTIVE
SQLSTATE | 08W40
Sybase error code | 13708
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An attempt was made to create a writefile for a database that is currently active.


Database name not unique

Item | Value
SQLCODE | –77
Constant | SQLE_ALIAS_CLASH
SQLSTATE | 08W27
Sybase error code | 1801
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

The database cannot be started as its name is conflicting with a previously started database.


Database name required to start server

Item | Value
SQLCODE | –87
Constant | SQLE_DATABASE_NAME_REQUIRED
SQLSTATE | 08W14
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

You did not supply a database name. A database name is required to start a database server.


Database option '%1' for user '%2' has an invalid setting

Item | Value
SQLCODE | 113
Constant | SQLE_INVALID_OPTION_ON_CONNECT
SQLSTATE | 01W11
Sybase error code | 13688
ODBC 2 State | 01000
ODBC 3 State | 01000
Parameter 1 | Name of the database option that has the invalid value.
Parameter 2 | Name of the user attempting to connect.
Probable cause

Upon processing a connection request for a specific user, the server processed a database option from the SYSOPTIONS table which had an invalid setting. The erroneous option setting is ignored; in its place, the server will use the default option value for the current database.


Database page size too big

Item | Value
SQLCODE | –97
Constant | SQLE_PAGE_SIZE_TOO_BIG
SQLSTATE | 08W22
Sybase error code | 927
ODBC 2 State | 08004
ODBC 3 State | 08004
Probable cause

You attempted to start a database with a page size that exceeds the maximum page size of the running server. Either restart the server with this database named on the command line, or restart the server with a larger page size.


Database page size too small

Item | Value
SQLCODE | –972
Constant | SQLE_PAGE_SIZE_TOO_SMALL
SQLSTATE | 54W03
Sybase error code | 13516
ODBC 2 State | 08004
ODBC 3 State | 08004
Probable cause

You attempted to load statistics that were too large for the current database page size. Rebuilding this database with a larger page size could prevent this error.


Database server already running

Item | Value
SQLCODE | –96
Constant | SQLE_ENGINE_ALREADY_RUNNING
SQLSTATE | 08W23
Sybase error code | 7950
ODBC 2 State | S1000
ODBC 3 State | HY000
Probable cause

The database server was not able to start because a server with the same name was already running.


Database server cannot convert data from/to character set '%1'

Item | Value
SQLCODE | –869
Constant | SQLE_UNSUPPORTED_CHARACTER_SET_ERROR
SQLSTATE | 08W64
Sybase error code | 13873
ODBC 2 State | 08S01
ODBC 3 State | 08S01
Parameter 1 | Name of the requested character set.
Probable cause

The database server cannot convert character data from/to the character set requested by the application, possibly because the character set is not supported, or because database server character set translation is disabled (see -ct switch on database server). The connection fails.


Database server cannot convert data from/to character set '%1', conversion may not be correct

Item | Value
SQLCODE | 115
Constant | SQLE_UNSUPPORTED_CHARACTER_SET_WARNING
SQLSTATE | 01W13
Sybase error code | 13614
ODBC 2 State | 01000
ODBC 3 State | 01000
Parameter 1 | Name of the requested character set.
Probable cause

The database server cannot convert character data from/to the character set requested by the application, possibly because the character set is not supported, or because database server character set translation is disabled (see -ct switch on database server). The connection succeeds, but character conversion may not be correct for all characters.


Database server connection limit exceeded

Item | Value
SQLCODE | –102
Constant | SQLE_TOO_MANY_CONNECTIONS
SQLSTATE | 08W03
Sybase error code | 1601
ODBC 2 State | 08004
ODBC 3 State | 08004
Probable cause

You exceeded the number of computers allowed to connect to the server. If you are running the network database server, the limit is spelled out in your license agreement. The server may be running low on cache such that it cannot accept any more database connections. The personal database server is restricted to 10 connections.


Database server not found

Item | Value
SQLCODE | –100
Constant | SQLE_ENGINE_NOT_RUNNING
SQLSTATE | 08W01
Sybase error code | 7950
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

The database server is not running, or the interface library is unable to find it.


Database server not running in multi-user mode

Item | Value
SQLCODE | –89
Constant | SQLE_ENGINE_NOT_MULTIUSER
SQLSTATE | 08W16
Sybase error code | 7203
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

The database server was started for bulk loading (the -b switch) and cannot be used as a network server. Stop the database server, and start again without -b.


Database upgrade failed

Item | Value
SQLCODE | –672
Constant | SQLE_DATABASE_UPGRADE_FAILED
SQLSTATE | 08W42
Sybase error code | 3451
ODBC 2 State | 08004
ODBC 3 State | 08004
Probable cause

Your attempt to upgrade a database failed. This could be caused by a failure to locate one of the SQL script files used to define the system table changes.


Database upgrade not possible

Item | Value
SQLCODE | –673
Constant | SQLE_DATABASE_UPGRADE_NOT_POSSIBLE
SQLSTATE | 08W43
Sybase error code | 3451
ODBC 2 State | 08004
ODBC 3 State | 08004
Probable cause

An attempt to upgrade a database failed. The database is too old to be upgraded.


Database upgrade not possible; RowGenerator table not owned by user dbo

Item | Value
SQLCODE | –826
Constant | SQLE_DBO_DOES_NOT_OWN_ROWGENERATOR
SQLSTATE | 08W57
Sybase error code | 13832
ODBC 2 State | 08004
ODBC 3 State | 08004
Probable cause

An attempt to upgrade a database failed. The RowGenerator table is not owned by user dbo.


Database upgrade not possible; user tables have table ids in system table range

Item | Value
SQLCODE | –827
Constant | SQLE_USER_TABLES_IN_SYSTEM_RANGE
SQLSTATE | 08W58
Sybase error code | 13833
ODBC 2 State | 08004
ODBC 3 State | 08004
Probable cause

An attempt to upgrade a database failed. The RowGenerator table is not owned by user dbo.


db_init has not been called or the call to db_init failed

Item | Value
SQLCODE | –739
Constant | SQLE_DB_INIT_NOT_CALLED
SQLSTATE | 55W07
Sybase error code | 13752
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The SQLCA passed to a dblib entry point has not been initialized by a call to db_init or the call to db_init failed.


Dbspace '%1' not found

Item | Value
SQLCODE | –138
Constant | SQLE_DBSPACE_NOT_FOUND
SQLSTATE | 52W13
Sybase error code | 1802
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the dbspace that could not be found.
Probable cause

You tried to access a dbspace that the database server could not find.


Dbspace for table '%1' not found

Item | Value
SQLCODE | –821
Constant | SQLE_DBSPACE_FOR_TABLE_UNAVAILABLE
SQLSTATE | 52W19
Sybase error code | 13827
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the table whose dbspace could not be found.
Probable cause

You tried to access a table in a dbspace that the database server could not find. You may need to change the filename associated with the dbspace using the ALTER DBSPACE statement.


Deadlock detected

Item | Value
SQLCODE | –306
Constant | SQLE_DEADLOCK
SQLSTATE | 40001
Sybase error code | 1205
ODBC 2 State | 40001
ODBC 3 State | 40001
Probable cause

You attempted to read or write a row and it is locked by another user. Also, the other user is blocked directly or indirectly on your own transaction. This is a deadlock situation and your transaction has been chosen as the one to rollback.


Decompression error: %1

Item | Value
SQLCODE | –960
Constant | SQLE_DECOMPRESSION_ERROR
SQLSTATE | WW038
Sybase error code | 13530
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An error occurred during decompression. :EN-


Decryption error: %1

Item | Value
SQLCODE | –851
Constant | SQLE_DECRYPT_ERROR
SQLSTATE | 08W63
Sybase error code | 13855
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | Description of the error that occurred.
Probable cause

An error occurred during decryption.


Definition for alias '%1' must appear before its first reference

Item | Value
SQLCODE | –831
Constant | SQLE_ALIAS_NOT_YET_DEFINED
SQLSTATE | 42W61
Sybase error code | 13837
ODBC 2 State | 37000
ODBC 3 State | ERROR
Parameter 1 | Name of the alias.
Probable cause

An expression contains a reference to an alias, but the alias is defined later in the SELECT list. The alias definition must appear before its first reference.


Derived table '%1' has no name for column %2

Item | Value
SQLCODE | –163
Constant | SQLE_NO_COLUMN_NAME
SQLSTATE | 52004
Sybase error code | 209
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the derived table.
Parameter 2 | Number of the column for which there is no name.
Probable cause

The specified column of the derived table has no column name. Use a select list alias in the query specification or use a derived columns specifier.


Disallowed language extension detected in syntax near '%1'

Item | Value
SQLCODE | –627
Constant | SQLE_INVALID_SYNTAX_EXTENSION
SQLSTATE | 0AW03
Sybase error code | 538
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The word or symbol where the syntax has been detected.
Probable cause

The statement you are trying to execute contains extensions to ANSI 1992 Entry Level SQL. These extensions are not allowed by the current settings.


Disk full '%1' -- transaction rolled back

Item | Value
SQLCODE | –304
Constant | SQLE_DEVICE_FULL
SQLSTATE | 40W03
Sybase error code | 3618
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Your hard disk is out of space. A ROLLBACK WORK statement has been automatically executed.


Disk write failure '%1' -- transaction rolled back

Item | Value
SQLCODE | –303
Constant | SQLE_DISK_WRITE_FAILED
SQLSTATE | 40W05
Sybase error code | 13868
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A disk write failed. A ROLLBACK WORK statement has been automatically executed.


Division by zero

Item | Value
SQLCODE | –628
Constant | SQLE_DIV_ZERO_ERROR
SQLSTATE | 22012
Sybase error code | 36007
ODBC 2 State | 22012
ODBC 3 State | 22012
Probable cause

A division by zero operation was detected.


Download failed because of conflicts with existing rows.

Item | Value
SQLCODE | –839
Constant | SQLE_DOWNLOAD_CONFLICT
SQLSTATE | 0AW11
Sybase error code | 13845
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted a download-only synchronization with modified rows in the UltraLite database. These was a conflict between one or more rows in the download stream and rows in the UltraLite database.


DTC transactions are not supported on this platform

Item | Value
SQLCODE | –799
Constant | SQLE_DTC_TRANSACTIONS_NOT_SUPPORTED
SQLSTATE | 0AW10
Sybase error code | 13809
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You tried to enlist a DTC transactions on a platform that does not support this feature.


Duplicate attribute '%1' in service

Item | Value
SQLCODE | –1025
Constant | SQLE_SERVICE_PARM_DUPLICATE_PROPERTY
SQLSTATE | 42WB0
Sybase error code | 13485
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the duplicate attribute.
Probable cause

The service definition contains a duplicate attribute.


Duplicate insert column

Item | Value
SQLCODE | –637
Constant | SQLE_DUPLICATE_INSERT_COLUMN
SQLSTATE | 42W41
Sybase error code | 264
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You supplied a duplicate column name in the list of insert columns.


Duplicate referencing column

Item | Value
SQLCODE | –636
Constant | SQLE_DUPLICATE_REFERENCING_COLUMN
SQLSTATE | 42W40
Sybase error code | 1909
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You supplied a duplicate column name in the list of referencing columns.


Dynamic memory exhausted

Item | Value
SQLCODE | –78
Constant | SQLE_DYNAMIC_MEMORY_EXHAUSTED
SQLSTATE | 08W26
Sybase error code | 9119
ODBC 2 State | S1001
ODBC 3 State | HY001
Probable cause

A failure occurred when the database server was trying to allocate dynamic memory.


Encryption error: %1

Item | Value
SQLCODE | –895
Constant | SQLE_ENCRYPT_ERROR
SQLSTATE | 08W66
Sybase error code | 13589
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | Description of the error that occurred.
Probable cause

An error occurred during encryption.


Error during backup: %1

Item | Value
SQLCODE | –697
Constant | SQLE_BACKUP_ERROR
SQLSTATE | 08W46
Sybase error code | 13720
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An error occurred during a BACKUP statement.


Error in assignment

Item | Value
SQLCODE | –641
Constant | SQLE_ERROR_IN_ASSIGNMENT
SQLSTATE | 22005
Sybase error code | 8205
ODBC 2 State | 22005
ODBC 3 State | 22018
Probable cause

In a GET DESCRIPTOR statement, the data type of the host variable must correspond to the data type of the descriptor item.


Error number %1 for RAISERROR may not be less than 17000

Item | Value
SQLCODE | –296
Constant | SQLE_ERROR_NUMBER_OUT_OF_RANGE
SQLSTATE | 53W07
Sybase error code | 2732
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Error number.
Probable cause

You supplied an invalid error number in a RAISERROR statement. The number must be greater than or equal to 17000.


Error opening cursor

Item | Value
SQLCODE | –171
Constant | SQLE_OPEN_CURSOR_ERROR
SQLSTATE | 07003
Sybase error code | 102
ODBC 2 State | 24000
ODBC 3 State | 24000
Probable cause

You attempted to open a cursor on a statement that is not a SELECT statement or a CALL or EXEC statement.


Error parsing connection parameter string

Item | Value
SQLCODE | –655
Constant | SQLE_GEN_PARSE_ERROR
SQLSTATE | 08W38
Sybase error code | 13707
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

The connection string could not be parsed. The string or connection parameter file contains a syntax error.


Error writing to transaction log file

Item | Value
SQLCODE | –107
Constant | SQLE_ERROR_WRITING_LOG
SQLSTATE | 08W17
Sybase error code | 3619
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The database server got an I/O error writing the transaction log file. Perhaps the disk is full or the log file name is invalid.


Event '%1' already exists

Item | Value
SQLCODE | –772
Constant | SQLE_EVENT_ALREADY_EXISTS
SQLSTATE | WE002
Sybase error code | 13782
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the event that already exists.
Probable cause

You have attempted to create an event with a name that already exists in SYS.SYSEVENT.


Event '%1' in use

Item | Value
SQLCODE | –835
Constant | SQLE_EVENT_IN_USE
SQLSTATE | WE009
Sybase error code | 13841
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the event that is in use.
Probable cause

You have attempted to drop an event that is currently in use.


Event '%1' not found

Item | Value
SQLCODE | –771
Constant | SQLE_EVENT_NOT_FOUND
SQLSTATE | WE001
Sybase error code | 13781
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the event that could not be found.
Probable cause

You have attempted to reference an event with a name that does not exist in SYS.SYSEVENT.


Exception occurred while loading Java SecurityManager

Item | Value
SQLCODE | –848
Constant | SQLE_JAVA_SECMGR_EXCEPTION
SQLSTATE | WJ028
Sybase error code | 13854
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A Java exception occurred while loading the Java SecurityManager for this connection.


Expression has unsupported data type

Item | Value
SQLCODE | –624
Constant | SQLE_DATATYPE_NOT_ALLOWED
SQLSTATE | WW009
Sybase error code | 10356
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Either an external function or Java method is declared to have a parameter or result data type which is not supported, or a Java field reference with unsupported result type was attempted.


External login for server '%1' could not be found

Item | Value
SQLCODE | –712
Constant | SQLE_OMNI_EXTLOGIN_NOT_FOUND
SQLSTATE | WO013
Sybase error code | 11221
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the remote server.
Probable cause

An external login for the server and user does not exist.


Feature '%1' not implemented

Item | Value
SQLCODE | –134
Constant | SQLE_NOT_IMPLEMENTED
SQLSTATE | 0A000
Sybase error code | 401
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The unimplemented feature.
Probable cause

You attempted to carry out an operation or use a feature that is not implemented in this version of Adaptive Server Anywhere.


Feature not available with UltraLite

Item | Value
SQLCODE | –749
Constant | SQLE_NOT_SUPPORTED_IN_ULTRALITE
SQLSTATE | 0AW07
Sybase error code | 13762
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to execute a statement or use a feature that is not supported in an UltraLite database. For example, UltraLite does not support statements that modify the schema of the database.


Field '%1' of class '%2' cannot be null

Item | Value
SQLCODE | –649
Constant | SQLE_FIELD_CANNOT_BE_NULL
SQLSTATE | WW015
Sybase error code | 13741
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the field which cannot be null.
Parameter 2 | The name of the class which has the field.
Probable cause

An attempt was made to store a SQL null value in a Java object field which has a Java type that cannot be null. For example, the Java 'int' type cannot be null.


File I/O failed for '%1'

Item | Value
SQLCODE | –974
Constant | SQLE_DEVICE_IO_FAILED
SQLSTATE | WW043
Sybase error code | 13959
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The filename
Probable cause

An error occurred while trying to access the file. If the file is located on a removable media card, the card may have been removed.


FOR UPDATE has been incorrectly specified for a READ ONLY cursor.

Item | Value
SQLCODE | –813
Constant | SQLE_NON_UPDATEABLE_CURSOR
SQLSTATE | 42W36
Sybase error code | 7301
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You attempted to declare a cursor FOR UPDATE on a query that is not updatable. Queries that contain DISTINCT, GROUP BY, HAVING, INTERSECT, EXCEPT or UNION, or that contain aggregate functions are read only. If the ANSI_UPDATE_CONSTRAINTS option is on, then queries that contain an join are read only. If the query references a view then the view may be non-updatable.


Foreign key '%1' for table '%2' duplicates an existing foreign key

Item | Value
SQLCODE | –251
Constant | SQLE_DUPLICATE_FOREIGN_KEY
SQLSTATE | 52W06
Sybase error code | 1909
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | The role name of the new foreign key.
Parameter 2 | The table containing the foreign key.
Probable cause

You attempted to define a foreign key that already exists.


Foreign key name '%1' not found

Item | Value
SQLCODE | –145
Constant | SQLE_FOREIGN_KEY_NAME_NOT_FOUND
SQLSTATE | 52W07
Sybase error code | 102
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the non-existing foreign key.
Probable cause

You misspelled the name of a foreign key, or the foreign key does not exist.


Format string argument number %1 is invalid

Item | Value
SQLCODE | –294
Constant | SQLE_INVALID_FORMAT_STRING_ARG_NUM
SQLSTATE | 53W08
Sybase error code | 2749
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Argument number.
Probable cause

You supplied an invalid argument number in the format string for a PRINT or RAISERROR statement. The number must be between 1 and 20 and must not exceed the number of arguments provided.


Frame not allowed for window '%1'

Item | Value
SQLCODE | –950
Constant | SQLE_FRAME_NOT_ALLOWED
SQLSTATE | 42WA6
Sybase error code | 13538
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the window or function.
Probable cause

Frames are not allowed on rank functions or on windows referenced from inline window specifications.


Function or column reference to '%1' in the ORDER BY clause is invalid

Item | Value
SQLCODE | –854
Constant | SQLE_INVALID_ORDERBY_COLUMN
SQLSTATE | 42W65
Sybase error code | 104
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the column referenced directly, or in an expression, in the ORDER BY clause.
Probable cause

You specified a function or column reference in the ORDER BY clause that is semantically invalid. For example, for DISTINCT queries the ORDER BY clause may only refer to items in the query's SELECT list.


Function or column reference to '%1' must also appear in a GROUP BY

Item | Value
SQLCODE | –149
Constant | SQLE_INVALID_GROUP_SELECT
SQLSTATE | 53003
Sybase error code | 7321
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the column referenced directly, or in an expression, that must be in the GROUP BY clause.
Probable cause

You used a non-aggregate function or column reference in the select list or in a nested query block that does not appear in the GROUP BY clause. In a query using GROUP BY, select list items that are not aggregate functions must also appear in the GROUP BY clause. If the select list item is a column reference or an alias, you may add the column name or alias to the GROUP BY clause. If the select list item is a scalar function, ensure that the function's arguments in the GROUP BY clause match exactly with those in the select list. In some cases, you may want to use the MAX function on the column name (or another aggregate function) instead of adding the column to the GROUP BY clause.


GRANT of column permission on view not allowed

Item | Value
SQLCODE | –635
Constant | SQLE_NO_COLUMN_PERMS_FOR_VIEWS
SQLSTATE | 52W22
Sybase error code | 102
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You cannot grant permissions on columns for views.


Grouped query contains more than one distinct aggregate function

Item | Value
SQLCODE | –863
Constant | SQLE_INVALID_DISTINCT_AGGREGATE
SQLSTATE | 42W70
Sybase error code | 13867
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

Two or more DISTINCT aggregate functions were specified in the same grouped query. This is only permitted if the Hash Group By operator is available. Any query block can only contain at most one DISTINCT aggregate function if the Hash Group By operator is not available.


Host variable reference in service definition must be named

Item | Value
SQLCODE | –926
Constant | SQLE_HOSTVAR_MUST_BE_NAMED
SQLSTATE | 42W9B
Sybase error code | 13559
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You have attempted to create a service with an unnamed host variable reference.


Host variables may not be used within a batch

Item | Value
SQLCODE | –807
Constant | SQLE_HOSTVARS_IN_BATCH
SQLSTATE | 07W07
Sybase error code | 13817
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You have attempted to execute a batch which contains host variable references. Host variables are not supported within a batch.


HTTP request failed. Status code '%1'

Item | Value
SQLCODE | –983
Constant | SQLE_HTTP_REQUEST_FAILED
SQLSTATE | WW052
Sybase error code | 13506
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The HTTP status code
Probable cause

The HTTP request returned a status code that indicated failure.


I/O error %1 -- transaction rolled back

Item | Value
SQLCODE | –305
Constant | SQLE_DEVICE_ERROR
SQLSTATE | 40W04
Sybase error code | 3013
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Adaptive Server Anywhere has detected a problem with your hard disk. A ROLLBACK WORK statement has been automatically executed.


Identifier '%1' too long

Item | Value
SQLCODE | –250
Constant | SQLE_IDENTIFIER_TOO_LONG
SQLSTATE | 54003
Sybase error code | 103
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | The identifier in error.
Probable cause

An identifier is longer than 128 characters.


Identity attribute mismatch for column '%1'

Item | Value
SQLCODE | –725
Constant | SQLE_OMNI_IDENTITY_MISMATCH
SQLSTATE | WO019
Sybase error code | 11212
ODBC 2 State | OK
ODBC 3 State | OK
Parameter 1 | The name of the column.
Probable cause

The identity attribute of the column specified in the 'CREATE EXISTING' statement differs from the identity attribute of the actual column.


Illegal column name: '%1'

Item | Value
SQLCODE | –899
Constant | SQLE_BAD_FOR_XML_EXPLICIT_COLUMN_NAME
SQLSTATE | WX007
Sybase error code | 13582
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The reason the column name was illegal.
Probable cause

FOR XML EXPLICIT column names can consist of up to four fields separated by exclamation marks. The first two columns must be named 'Tag' and 'Parent'.


Illegal cursor operation attempt

Item | Value
SQLCODE | –187
Constant | SQLE_CURSOROP_NOT_ALLOWED
SQLSTATE | 09W02
Sybase error code | 9526
ODBC 2 State | 07005
ODBC 3 State | 07005
Probable cause

You attempted an illegal cursor operation. For example, you may be attempting to OPEN a cursor for a statement that is neither a SELECT nor a BATCH.


Illegal flags value passed to OPENXML

Item | Value
SQLCODE | –893
Constant | SQLE_BAD_OPENXML_FLAG
SQLSTATE | WX004
Sybase error code | 13590
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The flags value passed to OPENXML as the third argument must be either 1 (attribute-centric mapping), or 2 (element-centric mapping).


Illegal FOR XML EXPLICIT tag value: '%1'

Item | Value
SQLCODE | –897
Constant | SQLE_BAD_FOR_XML_EXPLICIT_TAG
SQLSTATE | WX005
Sybase error code | 13584
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The illegal tag value
Probable cause

FOR XML EXPLICIT tag values must be greater than 0 and less than 256. Also, NULL values are not allowed in the 'Tag' column.


Illegal ORDER BY in aggregate function

Item | Value
SQLCODE | –904
Constant | SQLE_INVALID_ORDERBY_IN_AGGREGATE
SQLSTATE | 42W90
Sybase error code | 13579
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

An ORDER BY can be used in an aggregate function only if there are no DISTINCT aggregates in the SELECT list, or there is a single DISTINCT aggregate with the DISTINCT column equal to the first column of the ORDER BY. Also, multiple ordered aggregates cannot be used in the same SELECT list unless they have the exact same ORDER BY clause.


Illegal reference to correlation name '%1'

Item | Value
SQLCODE | –824
Constant | SQLE_INVALID_CORRELATION_NAME_REFERENCE
SQLSTATE | 42U01
Sybase error code | 13830
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | The correlation name which is incorrectly referenced.
Probable cause

Your query contains a reference in a table expression to a correlation name that is not contained in that table expression.


Illegal user selectivity estimate specified

Item | Value
SQLCODE | 118
Constant | SQLE_INVALID_USER_ESTIMATE
SQLSTATE | 01W16
Sybase error code | 13617
ODBC 2 State | 01000
ODBC 3 State | 01000
Probable cause

You specified a user selectivity estimate that is either not a literal constant or is outside the range 0.0 to 100.0 (estimates are specified as percentages). The estimate has been ignored.


Incomplete transactions prevent transaction log renaming

Item | Value
SQLCODE | –242
Constant | SQLE_BACKUP_CANNOT_RENAME_LOG_YET
SQLSTATE | WB003
Sybase error code | 3206
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The last page in the transaction log was read by a call to db_backup. One or more currently active connections have partially completed transactions, preventing the transaction log file from being renamed. Reissue the db_backup call.


Incorrect or missing encryption key

Item | Value
SQLCODE | –840
Constant | SQLE_BAD_ENCRYPTION_KEY
SQLSTATE | 08W62
Sybase error code | 16846
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

The database is encrypted with a key. There was no key given to start the database, or the key given was incorrect.


Incorrect store DLL (%1) version.

Item | Value
SQLCODE | –711
Constant | SQLE_STORE_VERSION_MISMATCH
SQLSTATE | 08W47
Sybase error code | 13701
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The store and server DLL versions do not match.


Incorrect volume ID for '%1'

Item | Value
SQLCODE | –975
Constant | SQLE_INCORRECT_VOLUME_ID
SQLSTATE | WW044
Sybase error code | 13960
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The filename
Probable cause

The file can be accessed, but the volume ID has changed. Please insert the original removable media card.


Index '%1' can not be clustered

Item | Value
SQLCODE | –878
Constant | SQLE_CLUSTERED_INDEX_NOT_ALLOWED
SQLSTATE | 42W74
Sybase error code | 13889
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the index that could not be made clustered.
Probable cause

You attempted to create a clustered index (including key indexes) but the new index cannot be created, e.g., because the table already has a clustered index.


Index '%1' for table '%2' would not be unique

Item | Value
SQLCODE | –196
Constant | SQLE_INDEX_NOT_UNIQUE
SQLSTATE | 23505
Sybase error code | 548
ODBC 2 State | 23000
ODBC 3 State | 23000
Parameter 1 | Name of the index that would not be unique.
Parameter 2 | Name of the table that contains the index.
Probable cause

You attempted to insert or update a row that has the same value as another row in some column, and there is a constraint that does not allow two rows to have the same value in that column.


Index name '%1' is ambiguous

Item | Value
SQLCODE | –678
Constant | SQLE_AMBIGUOUS_INDEX_NAME
SQLSTATE | 52W40
Sybase error code | 1921
ODBC 2 State | S0011
ODBC 3 State | 42S11
Parameter 1 | Name of the ambiguous index.
Probable cause

A statement has referred to an index name which is not unique. Preface the index name by a table and/or owner name.


Index name '%1' not unique

Item | Value
SQLCODE | –111
Constant | SQLE_INDEX_NAME_NOT_UNIQUE
SQLSTATE | 52W04
Sybase error code | 1921
ODBC 2 State | S0011
ODBC 3 State | 42S11
Parameter 1 | Name of the invalid index.
Probable cause

You attempted to create an index with the same name as an existing index.


Index type specification of '%1' is invalid

Item | Value
SQLCODE | –650
Constant | SQLE_INVALID_INDEX_TYPE
SQLSTATE | WW016
Sybase error code | 13704
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

IQ index types can be specified for IQ indexes only.


Information for synchronization is incomplete or invalid, check '%1'

Item | Value
SQLCODE | –956
Constant | SQLE_SYNC_INFO_INVALID
SQLSTATE | WW036
Sybase error code | 13532
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the parameter not properly initialized
Probable cause

Information for synchronization is incomplete or invalid. Correct the indicated parameter before attempting to synchronize again. If 'init_verify' is indicated, the ULInitSynchInfo function was not called.


Input parameter index out of range

Item | Value
SQLCODE | –689
Constant | SQLE_BAD_PARAM_INDEX
SQLSTATE | WJ005
Sybase error code | 13717
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The range for valid parameters is from 1 up to the number of host variables specified in the prepared/callable statement.


Input string is not base64-encoded

Item | Value
SQLCODE | –961
Constant | SQLE_BASE64_DECODING_ERROR
SQLSTATE | WW039
Sybase error code | 13528
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An error occurred during base64 decoding.


INSERT/DELETE on cursor can modify only one table

Item | Value
SQLCODE | –199
Constant | SQLE_ONLY_ONE_TABLE
SQLSTATE | 09W04
Sybase error code | 102
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to insert into a cursor and have specified values for more than one table; or you attempted to delete from a cursor that involves a join. Insert into one table at a time. For DELETE, use the FROM clause to specify which table you wish to delete from.


Insufficient cache to start Java virtual machine

Item | Value
SQLCODE | –686
Constant | SQLE_JAVA_VM_INSUFFICIENT_CACHE
SQLSTATE | WP015
Sybase error code | 13878
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Insufficient cache was available to start the Java virtual machine. Restart the engine with a larger cache size.


Insufficient memory for OPENXML query

Item | Value
SQLCODE | –912
Constant | SQLE_XQUERY_MEMORY_ERROR
SQLSTATE | WX016
Sybase error code | 13572
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The memory used by an OPENXML query may be proportional to the size of the largest subtree in the xml document that has nodes referred to by a single row in the result. Try increasing the cache size or rewriting the query so that rows refer to smaller subtrees.


Integrated login failed

Item | Value
SQLCODE | –245
Constant | SQLE_INTEGRATED_LOGON_FAILED
SQLSTATE | 28W04
Sybase error code | 13691
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

The integrated login failed. You may not have a system account on the server machine.


Integrated logins are not permitted

Item | Value
SQLCODE | –205
Constant | SQLE_INVALID_STANDARD_LOGON
SQLSTATE | 28W02
Sybase error code | 13689
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

The LOGIN_MODE database option is set to STANDARD, and you attempted an integrated login. Change the option setting or supply an explicit user ID.


Integrated logins are not supported for this database

Item | Value
SQLCODE | –246
Constant | SQLE_INTEGRATED_LOGON_UNSUPPORTED
SQLSTATE | 28W05
Sybase error code | 13694
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

The current database is an older database and does not have a SYS.SYSLOGIN table to map integrated login IDs to database user IDs. You must upgrade your database to use integrated logins.


Integrated logins are required, standard logins are not permitted

Item | Value
SQLCODE | –206
Constant | SQLE_INVALID_INTEGRATED_LOGON
SQLSTATE | 28W03
Sybase error code | 13690
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

The LOGIN_MODE database option is set to INTEGRATED, and you attempted a standard login. Change the option setting or use an integrated login.


Internal database error %1 -- transaction rolled back

Item | Value
SQLCODE | –301
Constant | SQLE_DATABASE_ERROR
SQLSTATE | 40W01
Sybase error code | 13665
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Identification of the error.
Probable cause

An internal database error occurred. If it can be reproduced, it should be reported to iAnywhere Solutions. A ROLLBACK WORK statement has been automatically executed.


Internal rollback log corrupted

Item | Value
SQLCODE | –311
Constant | SQLE_LOG_CORRUPTED
SQLSTATE | WI004
Sybase error code | 932
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

While processing a COMMIT or ROLLBACK, corruption was found in the internal rollback log. This is a fatal internal error.


Invalid absolute or relative offset in FETCH

Item | Value
SQLCODE | –263
Constant | SQLE_INVALID_FETCH_POSITION
SQLSTATE | 42W25
Sybase error code | 6259
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You specified an offset in a FETCH that was invalid or NULL.


Invalid backup operation

Item | Value
SQLCODE | –1021
Constant | SQLE_INVALID_BACKUP_OPERATION
SQLSTATE | WB013
Sybase error code | 3206
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The specified backup operation is not valid because of previous backup operation(s).


Invalid class byte code

Item | Value
SQLCODE | –670
Constant | SQLE_BAD_CLASS_BYTE_CODE
SQLSTATE | WP005
Sybase error code | 13746
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A binary expression passed to the INSTALL JAVA statement was not a valid Java class.


Invalid column number

Item | Value
SQLCODE | –159
Constant | SQLE_INVALID_COLUMN_NUMBER
SQLSTATE | 42W13
Sybase error code | 182
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You gave an invalid column number, or the column you are looking for is in a different table.


Invalid comparison

Item | Value
SQLCODE | –710
Constant | SQLE_INVALID_COMPARISON
SQLSTATE | 52W25
Sybase error code | 13749
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

An attempt was made to compare two arguments that do not support comparison. For example, it is not valid to compare a Java object with another Java object, unless the class of the object supports a valid compareTo() method.


Invalid data conversion

Item | Value
SQLCODE | 103
Constant | SQLE_CANNOT_CONVERT
SQLSTATE | 01W03
Sybase error code | 518
ODBC 2 State | 01S01
ODBC 3 State | 01S01
Probable cause

The database could not convert a value to the required type. The value being converted was either supplied to the database on an insert, update or as a host bind variable, or was a value retrieved from the database into a host variable or SQLDA.


Invalid data conversion: NULL was inserted for column '%1' on row %2.

Item | Value
SQLCODE | 124
Constant | SQLE_CANNOT_CONVERT_LOAD_TABLE
SQLSTATE | 01W01
Sybase error code | 13886
ODBC 2 State | 07006
ODBC 3 State | 07006
Parameter 1 | Name of the column where NULL was inserted.
Parameter 2 | Row number in the data file where the invalid data conversion took place.
Probable cause

The database could not convert a value to the required type. The value being converted was supplied to the database in a data file and inserted using LOAD TABLE. A NULL value has been inserted into the column.


Invalid data type for column in WRITETEXT or READTEXT

Item | Value
SQLCODE | –609
Constant | SQLE_INVALID_TEXT_IMAGE_DATATYPE
SQLSTATE | 53W09
Sybase error code | 7139
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You referenced a column in a WRITETEXT or READTEXT statement that is not defined for storing text or image data.


Invalid database page size

Item | Value
SQLCODE | –644
Constant | SQLE_PAGE_SIZE_INVALID
SQLSTATE | 08W32
Sybase error code | 927
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You attempted to create a database with an invalid page size. The page size for an Adaptive Server Anywhere database must be either 1024, 2048, or 4096 bytes. The page size for an UltraLite database must be either 2048 or 4096 bytes.


Invalid database server command line

Item | Value
SQLCODE | –81
Constant | SQLE_INVALID_COMMAND_LINE
SQLSTATE | 08W08
Sybase error code | 5864
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

It was not possible to start the database server because the command line was invalid.


Invalid day of week or month '%1' for event '%2'

Item | Value
SQLCODE | –791
Constant | SQLE_INVALID_EVENT_DAY
SQLSTATE | WE005
Sybase error code | 13801
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Day-of-week name or day-of-month number.
Parameter 2 | Name of the event being scheduled.
Probable cause

You have attempted to create a schedule with an invalid day-of-week name or day-of-month number.


Invalid descriptor index

Item | Value
SQLCODE | –640
Constant | SQLE_INVALID_DESCRIPTOR_INDEX
SQLSTATE | 07009
Sybase error code | 8201
ODBC 2 State | S1002
ODBC 3 State | 07009
Probable cause

The index number used with respect to a descriptor area is out of range.


Invalid escape character '%1'

Item | Value
SQLCODE | –629
Constant | SQLE_INVALID_ESCAPE_CHAR
SQLSTATE | 22019
Sybase error code | 7707
ODBC 2 State | S1000
ODBC 3 State | 22019
Probable cause

The escape character string length must be exactly one.


Invalid escape sequence '%1'

Item | Value
SQLCODE | –630
Constant | SQLE_INVALID_ESCAPE_SEQ
SQLSTATE | 22025
Sybase error code | 7705
ODBC 2 State | S1000
ODBC 3 State | 22025
Parameter 1 | The escaped character
Probable cause

A LIKE pattern contains an invalid use of the escape character. The escape character may only precede the special characters '%', '_', '[', and the escape character itself.


Invalid expression in WHERE clause of Transact-SQL outer join

Item | Value
SQLCODE | –680
Constant | SQLE_INVALID_TSQL_OJ_EXPRESSION
SQLSTATE | 52W23
Sybase error code | 301
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

An expression in the WHERE clause of a query which uses Transact-SQL syntax contains a comparison of a column from the null-supplying table with a subquery or an expression which references a column from another table.


Invalid expression near '%1'

Item | Value
SQLCODE | –156
Constant | SQLE_EXPRESSION_ERROR
SQLSTATE | 42W08
Sybase error code | 401
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | The invalid expression.
Probable cause

You supplied an expression which the database server cannot understand. For example, you may have tried to add two dates.


Invalid hint specified for table '%1'

Item | Value
SQLCODE | –970
Constant | SQLE_INVALID_HINT
SQLSTATE | 42U07
Sybase error code | 13520
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | The name of the table for which the hint was specified.
Probable cause

A hint was specified for the current statement is not valid in this context. In a single statement, all references to a table must specify the same hint or none at all.


Invalid host variable

Item | Value
SQLCODE | –155
Constant | SQLE_VARIABLE_INVALID
SQLSTATE | 42W07
Sybase error code | 7201
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You supplied an invalid host variable to the database using the C language interface. You may have supplied the variable as a host variable or through a SQLDA.


Invalid IQ database command line option or parameter value: %1

Item | Value
SQLCODE | –744
Constant | SQLE_IQ_INVALID_COMMAND_LINE
SQLSTATE | 08W51
Sybase error code | 13757
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

An invalid command line option was used. The option began with '-iq', but is either invalid or contained a bad parameter.


Invalid jar file

Item | Value
SQLCODE | –730
Constant | SQLE_BAD_JAR_FILE
SQLSTATE | WP010
Sybase error code | 13737
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A file passed to the INSTALL JAVA statement was not a valid jar file.


Invalid JDBC resultset concurrency

Item | Value
SQLCODE | –748
Constant | SQLE_JDBC_INVALID_RESULTSET_CONCURRENCY
SQLSTATE | WJ018
Sybase error code | 13761
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An invalid resultset concurrency was used when creating a JDBC statement.


Invalid JDBC resultset type

Item | Value
SQLCODE | –747
Constant | SQLE_JDBC_INVALID_RESULTSET_TYPE
SQLSTATE | WJ017
Sybase error code | 13760
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An invalid resultset type was used when creating a JDBC statement.


Invalid join type used with Transact-SQL outer join

Item | Value
SQLCODE | –681
Constant | SQLE_INVALID_TSQL_JOIN_TYPE
SQLSTATE | 52W24
Sybase error code | 305
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

An invalid join type was used with a query that contains Transact-SQL outer join comparison operators.


Invalid local database switch

Item | Value
SQLCODE | –79
Constant | SQLE_INVALID_LOCAL_OPTION
SQLSTATE | 08W25
Sybase error code | 5864
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

An invalid database switch was found in the DBS (DatabaseSwitches) connection parameter.


Invalid operation on a closed '%1'

Item | Value
SQLCODE | –696
Constant | SQLE_JDBC_OBJ_CLOSED
SQLSTATE | WJ010
Sybase error code | 13605
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Java class of the closed object
Probable cause

An illegal attempt was made to access a closed JDBC object.


Invalid operation on a closed '%1'

Item | Value
SQLCODE | –714
Constant | SQLE_JNAT_OBJ_CLOSED
SQLSTATE | WJ014
Sybase error code | 13609
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Java class of the closed object
Probable cause

An illegal attempt was made to access a closed native Java object.


Invalid operation on a closed '%1'

Item | Value
SQLCODE | –908
Constant | SQLE_ULTRALITE_OBJ_CLOSED
SQLSTATE | 55W14
Sybase error code | 13575
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Type of the closed object
Probable cause

An illegal attempt was made to access a closed UltraLite object.


Invalid option '%1' -- no PUBLIC setting exists

Item | Value
SQLCODE | –200
Constant | SQLE_INVALID_OPTION
SQLSTATE | 42W16
Sybase error code | 155
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the invalid option.
Probable cause

You may have misspelled the name of an option in the SET OPTION statement. You can only define an option for a user if the database administrator has supplied a PUBLIC value for that option.


Invalid ORDER BY specification

Item | Value
SQLCODE | –152
Constant | SQLE_INVALID_ORDER
SQLSTATE | 53005
Sybase error code | 108
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

Either you used an integer in an ORDER BY list and the integer is larger than the number of columns in the select list, or you specified an ORDER BY expression that is semantically invalid. For example, with UNION queries you can only use integers to specify an ordering of the result.


Invalid parameter

Item | Value
SQLCODE | –735
Constant | SQLE_INVALID_PARAMETER
SQLSTATE | 08W24
Sybase error code | 5864
ODBC 2 State | 08004
ODBC 3 State | 08004
Probable cause

An error occurred while evaluating a parameter.


Invalid preceding or following size in OLAP function

Item | Value
SQLCODE | –957
Constant | SQLE_INVALID_FRAME_BOUNDARY
SQLSTATE | 22X13
Sybase error code | 13531
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The expression for the preceding or following size evaluated to NULL or a negative value.


Invalid prepared statement type

Item | Value
SQLCODE | –133
Constant | SQLE_INVALID_STATEMENT_TYPE
SQLSTATE | 07W03
Sybase error code | 13630
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

This is an internal error. If it can be reproduced, it should be reported to iAnywhere Solutions.


Invalid procedure subtype '%1' for type '%2'

Item | Value
SQLCODE | –987
Constant | SQLE_INVALID_PROCEDURE_SUBTYPE
SQLSTATE | WW056
Sybase error code | 13502
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The procedure subtype
Parameter 2 | The procedure type
Probable cause

A procedure or function was specified with an invalid subtype for the given procedure type.


Invalid procedure type '%1'

Item | Value
SQLCODE | –986
Constant | SQLE_INVALID_PROCEDURE_TYPE
SQLSTATE | WW055
Sybase error code | 13503
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The procedure type
Probable cause

A procedure or function was specified with an invalid type.


Invalid recursive query

Item | Value
SQLCODE | –921
Constant | SQLE_INVALID_RECURSION
SQLSTATE | 42W99
Sybase error code | 13563
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

A recursive query must consist of the UNION ALL of an initial query and an iteration query. The only set operation allowed in the iteration query is UNION ALL. A recursive reference to the name of the common table expression can only appear in the iteration query, and must not be in a SELECT that uses DISTINCT, ORDER BY, or an aggregate function. A recursive reference also cannot appear on the null-supplying side of an outer join, or in a subquery.


Invalid reference to or operation on constraint '%1'

Item | Value
SQLCODE | –937
Constant | SQLE_INVALID_CONSTRAINT_REF
SQLSTATE | 42U06
Sybase error code | 13550
ODBC 2 State | S0002
ODBC 3 State | 42S23
Parameter 1 | Name of the constraint can not be used for the specified purpose.
Probable cause

You specified an invalid operation on a constraint, i.e., tried to ALTER a primary key constraint.


Invalid REFERENCES clause in trigger definition

Item | Value
SQLCODE | –272
Constant | SQLE_INVALID_TRIGGER_COL_REFS
SQLSTATE | 52W12
Sybase error code | 102
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You supplied an invalid REFERENCES clause in a trigger definition. You may have specified an OLD correlation name in a BEFORE INSERT trigger, or a NEW correlation name in an AFTER DELETE trigger. In both cases, the values do not exist and cannot be referenced.


Invalid request log format on line %1

Item | Value
SQLCODE | –999
Constant | SQLE_INVALID_REQUEST_LOG_FORMAT
SQLSTATE | WW020
Sybase error code | 13493
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The line number in the log file.
Probable cause

The request log file format is invalid. The request log may have been created with an older version of the software.


Invalid response from the HTTP server

Item | Value
SQLCODE | –988
Constant | SQLE_INVALID_HTTP_RESPONSE
SQLSTATE | WW057
Sybase error code | 13501
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The response from the remote HTTP server was invalid. It may have been empty, malformed, missing header information, etc.


Invalid scroll position '%1'

Item | Value
SQLCODE | –820
Constant | SQLE_INVALID_POSITION
SQLSTATE | 24504
Sybase error code | 13826
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted to scroll to a position that is not supported. Scroll positions must be between -2147483647 and 2147483646.


Invalid service name '%1'

Item | Value
SQLCODE | –925
Constant | SQLE_INVALID_SERVICE_NAME
SQLSTATE | 42W95
Sybase error code | 13560
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the service.
Probable cause

You have attempted to create a service with an invalid name. The name may contain characters which are not allowed, or it may conflict with the URL PATH setting specified for the service.


Invalid setting for HTTP header '%1'

Item | Value
SQLCODE | –940
Constant | SQLE_INVALID_HTTP_HEADER_SETTING
SQLSTATE | 42W84
Sybase error code | 13547
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the invalid HTTP header.
Probable cause

You supplied an invalid value for an HTTP header.


Invalid setting for HTTP option '%1'

Item | Value
SQLCODE | –939
Constant | SQLE_INVALID_HTTP_OPTION_SETTING
SQLSTATE | 42W83
Sybase error code | 13548
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the invalid HTTP option.
Probable cause

You supplied an invalid value for an HTTP option. Some options only allow numeric values, while other options only allow the values "on" and "off".


Invalid setting for option '%1'

Item | Value
SQLCODE | –201
Constant | SQLE_INVALID_OPTION_SETTING
SQLSTATE | 42W17
Sybase error code | 5849
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the invalid option.
Probable cause

You supplied an invalid value for an option in the SET statement. Some options only allow numeric values, while other options only allow the values "on" and "off".


Invalid SQL descriptor name

Item | Value
SQLCODE | –642
Constant | SQLE_INVALID_DESCRIPTOR_NAME
SQLSTATE | 33000
Sybase error code | 601
ODBC 2 State | 33000
ODBC 3 State | 33000
Probable cause

You attempted to deallocate a descriptor that has not been allocated.


Invalid SQL identifier

Item | Value
SQLCODE | –760
Constant | SQLE_INVALID_SQL_IDENTIFIER
SQLSTATE | 07W06
Sybase error code | 13771
ODBC 2 State | 07001
ODBC 3 State | 07W06
Probable cause

An invalid identifier was supplied through the C language interface. For example, you may have supplied a NULL string for a cursor name.


Invalid sqllen field in SQLDA

Item | Value
SQLCODE | –856
Constant | SQLE_INVALID_SQLLEN
SQLSTATE | 07W08
Sybase error code | 13859
ODBC 2 State | HY090
ODBC 3 State | HY090
Probable cause

An invalid length was specified in a SQLDA sqllen field. All variable length types must have a non-negative length. DT_BINARY and DT_VARCHAR types must have length greater than one.


Invalid start date/time for event '%1'

Item | Value
SQLCODE | –793
Constant | SQLE_INVALID_EVENT_START
SQLSTATE | WE007
Sybase error code | 13803
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the event being scheduled.
Probable cause

You have specified an event starting date or time which has already passed.


Invalid statement

Item | Value
SQLCODE | –130
Constant | SQLE_INVALID_STATEMENT
SQLSTATE | 07W02
Sybase error code | 13628
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The statement identifier generated by a PREPARE passed to the database for a further operation is invalid.


Invalid TEXTPTR value used with WRITETEXT or READTEXT

Item | Value
SQLCODE | –608
Constant | SQLE_INVALID_TEXTPTR_VALUE
SQLSTATE | 22W03
Sybase error code | 7123
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You supplied an invalid value as the TEXTPTR for a WRITETEXT or READTEXT statement.


Invalid time '%1' for event '%2'

Item | Value
SQLCODE | –792
Constant | SQLE_INVALID_EVENT_TIME
SQLSTATE | WE006
Sybase error code | 13802
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Time value.
Parameter 2 | Name of the event being scheduled.
Probable cause

You have attempted to create a schedule with an invalid start or stop time.


Invalid type for field reference

Item | Value
SQLCODE | –94
Constant | SQLE_INVALID_FIELD_REFERENCE
SQLSTATE | WW014
Sybase error code | 13738
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An expression attempted to reference a field or a method of a non-Java value. Field references via '.' and '>>' are only valid when applied to Java objects.


Invalid type on DESCRIBE statement

Item | Value
SQLCODE | –161
Constant | SQLE_INVALID_DESCRIBE_TYPE
SQLSTATE | 07W01
Sybase error code | 13634
ODBC 2 State | OK
ODBC 3 State | OK
Probable cause

A Java type specified on a DESCRIBE statement has no corresponding SQL type.


Invalid use of an aggregate function

Item | Value
SQLCODE | –150
Constant | SQLE_AGGREGATES_NOT_ALLOWED
SQLSTATE | 42W06
Sybase error code | 13204
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to use an aggregate function inappropriately. For example, a SELECT statement cannot contain an aggregate function within a predicate in the WHERE clause unless the aggregate function constitutes an outer reference. Other invalid uses include specifying an aggregate function in the SET clause of an UPDATE statement, or using an aggregate function in a CHECK constraint.


Invalid user ID or password

Item | Value
SQLCODE | –103
Constant | SQLE_INVALID_LOGON
SQLSTATE | 28000
Sybase error code | 4002
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

You supplied an invalid user ID or an incorrect password.


Invalid user ID or password

Item | Value
SQLCODE | –103
Constant | SQLE_INVALID_PASSWORD
SQLSTATE | 28000
Sybase error code | 4002
ODBC 2 State | 28000
ODBC 3 State | 28000


Invalid user ID or password on preprocessed module

Item | Value
SQLCODE | –104
Constant | SQLE_INVALID_MODULE_LOGON
SQLSTATE | 28W01
Sybase error code | 4002
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

You specified an invalid user ID or password when a module was preprocessed.


Invalid value for attribute '%1' in service

Item | Value
SQLCODE | –1022
Constant | SQLE_SERVICE_PARM_INVALID_VALUE
SQLSTATE | 42WAD
Sybase error code | 13488
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the invalid attribute.
Probable cause

The service definition contains a USING, FORMAT or GROUP attribute with an invalid value.


Invalid XQuery constructor

Item | Value
SQLCODE | –905
Constant | SQLE_INVALID_XQUERY_CONSTRUCTOR
SQLSTATE | WX012
Sybase error code | 13578
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The XQuery constructor passed as the first argument to XMLGEN was not valid.


Item '%1' already exists

Item | Value
SQLCODE | –110
Constant | SQLE_NAME_NOT_UNIQUE
SQLSTATE | 52010
Sybase error code | 12006
ODBC 2 State | S0001
ODBC 3 State | 42S01
Parameter 1 | Name of the item that already exists.
Probable cause

You attempted to create a file, table, view, column, constraint, foreign key, or publication with the same name as an existing one.


Jar '%1' not found

Item | Value
SQLCODE | –811
Constant | SQLE_JAR_NOT_FOUND
SQLSTATE | 42W58
Sybase error code | 13821
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the jar.
Probable cause

The jar with this name does not exist in SYS.SYSJAR.


Java class '%1' not found

Item | Value
SQLCODE | –810
Constant | SQLE_JAVA_CLASS_NOT_FOUND
SQLSTATE | 42W57
Sybase error code | 13820
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the Java class.
Probable cause

The Java class with this name does not exist in SYS.SYSJAVACLASS.


Java SecurityManager class not found: %1

Item | Value
SQLCODE | –847
Constant | SQLE_JAVA_SECMGR_NOT_FOUND
SQLSTATE | WJ027
Sybase error code | 13853
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The class name of the Java SecurityManager.
Probable cause

The class specified is either not a SecurityManager subclass or cannot be found.


Java virtual machine could not be started

Item | Value
SQLCODE | –675
Constant | SQLE_JAVA_VM_NOT_STARTED
SQLSTATE | WP006
Sybase error code | 13747
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A problem was encountered starting the Java virtual machine. Possible problems include not enough memory, or incomplete installation of the Java runtime support classes.


Java VM heap exhausted at internal function: %1

Item | Value
SQLCODE | –165
Constant | SQLE_JAVA_VM_HEAP_EXHAUSTED
SQLSTATE | WP008
Sybase error code | 13740
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The internal function is for debugging purposes.
Probable cause

The amount of space allocated for the Java VM is insufficient to continue allocating new objects. Increase the size by using: set option public.java_heap_size = nnnnnnnn


jConnect does not support encryption

Item | Value
SQLCODE | –941
Constant | SQLE_NO_ENCRYPTION_FOR_JCONNECT
SQLSTATE | 08W69
Sybase error code | 13548
ODBC 2 State | 08004
ODBC 3 State | 08004
Probable cause

You supplied an encryption type for a connection using jConnect. jConnect does not support encryption.


JDBC feature '%1' not supported

Item | Value
SQLCODE | –693
Constant | SQLE_UNSUPPORTED_JDBC_FEATURE
SQLSTATE | WJ007
Sybase error code | 13602
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the attempted feature
Probable cause

An attempt was made to use a feature of JDBC that is not supported.


JDBC SAStatement batch execute abandoned

Item | Value
SQLCODE | –742
Constant | SQLE_JDBC_BATCH_EXECUTE_ABANDONED
SQLSTATE | WJ015
Sybase error code | 13755
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An error occurred when executing a statement in the batch. The rest of the statements in the batch will be abandoned.


JDK '%1' is not a supported JDK

Item | Value
SQLCODE | –842
Constant | SQLE_UNSUPPORTED_JDK
SQLSTATE | WJ025
Sybase error code | 13848
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | A JDK version string
Probable cause

Either the JDK version specified in the 'create database' statement is unsupported or the version in the manifest file of the JDK jar file is unsupported.


Key constraint between temporary tables requires a primary key (not unique constraint)

Item | Value
SQLCODE | –865
Constant | SQLE_INVALID_FOREIGN_KEY_INDEX
SQLSTATE | 42R03
Sybase error code | 1709
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

Key constraint between temporary tables requires a primary key (not unique constraint) if the database uses combined indexes. Change the definition of the primary table using ALTER TABLE or rebuild the database.


Label '%1' not found

Item | Value
SQLCODE | –262
Constant | SQLE_LABEL_NOT_FOUND
SQLSTATE | 42W24
Sybase error code | 133
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the label that could not be found.
Probable cause

You reference a label in a LEAVE statement, but the label could not be found.


Language '%1' is not supported, '%2' will be used

Item | Value
SQLCODE | 116
Constant | SQLE_UNSUPPORTED_LANGUAGE
SQLSTATE | 01W14
Sybase error code | 13615
ODBC 2 State | 01000
ODBC 3 State | 01000
Parameter 1 | Name of the language that was requested by the client.
Parameter 2 | Name of the language that the server will use to send message strings.
Probable cause

The language that the application requested is not supported by the server to which the application is connecting. Instead, the server will send message strings in the language stated.


Language extension

Item | Value
SQLCODE | –135
Constant | SQLE_LANGUAGE_EXTENSION
SQLSTATE | 0AW01
Sybase error code | 401
ODBC 2 State | 37000
ODBC 3 State | ERROR
Probable cause

You used a SQL statement that may be valid in some versions of SQL, but not in Adaptive Server Anywhere.


Language extension detected in syntax

Item | Value
SQLCODE | 107
Constant | SQLE_SYNTAX_EXTENSION_WARNING
SQLSTATE | 01W07
Sybase error code | 5703
ODBC 2 State | 01000
ODBC 3 State | 01000
Probable cause

The statement you are executing contains extensions to ANSI 1992 Entry level SQL.


LOAD TABLE not allowed on temporary table with ON COMMIT DELETE ROWS

Item | Value
SQLCODE | –993
Constant | SQLE_INVALID_TEMP_TABLE_COMMIT_ACTION
SQLSTATE | WL007
Sybase error code | 13496
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The LOAD TABLE statement automatically commits at completion. If a temporary table being loaded was declared with ON COMMIT DELETE ROWS, the rows would be discarded at completion.


Memory error -- transaction rolled back

Item | Value
SQLCODE | –309
Constant | SQLE_MEMORY_ERROR
SQLSTATE | 40W08
Sybase error code | 3013
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The UltraLite runtime has received an unexpected error from the system calls being used to store the UltraLite database. For example, a write to persistent memory failed. This is an internal error and indicates faulty or corrupt persistent storage on the device. A ROLLBACK WORK statement has been automatically executed.


Method '%1' cannot be called at this time

Item | Value
SQLCODE | –669
Constant | SQLE_METHOD_CANNOT_BE_CALLED
SQLSTATE | WJ001
Sybase error code | 13711
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the method
Probable cause

The method cannot be called at this time. Check that the method is not being called out of order.


Mismatch between external function platform specifier and current operating system

Item | Value
SQLCODE | –618
Constant | SQLE_EXTERNAL_PLATFORM_FAILURE
SQLSTATE | WW004
Sybase error code | 13675
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A call to an external entry point in a dynamically loaded module was qualified by an operating system which was not the operating system on which the server is currently executing.


Missing value for attribute '%1' in service

Item | Value
SQLCODE | –1023
Constant | SQLE_SERVICE_PARM_MISSING_VALUE
SQLSTATE | 42WAE
Sybase error code | 13487
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the invalid attribute.
Probable cause

The service definition contains a USING, FORMAT or GROUP attribute with a missing value.


Modifications not permitted for read-only database

Item | Value
SQLCODE | –757
Constant | SQLE_READ_ONLY_DATABASE
SQLSTATE | 55W08
Sybase error code | 13768
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You attempted an update operation on a database that was declared as read-only.


More columns are being dropped from table '%1' than are defined

Item | Value
SQLCODE | –124
Constant | SQLE_TOO_MANY_COLUMNS_DELETED
SQLSTATE | 42W44
Sybase error code | 207
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

The number of columns in a table can never fall below one. Your ALTER TABLE has more drop/delete column clauses than the current number of columns in the table.


More information required

Item | Value
SQLCODE | 112
Constant | SQLE_MORE_INFO
SQLSTATE | 01W09
Sybase error code | 13686
ODBC 2 State | 37000
ODBC 3 State | OK
Probable cause

More information is required to complete the request. This is used internally in the database interface library to process a unified login. It should not be returned to an application.


More than one table is identified as '%1'

Item | Value
SQLCODE | –139
Constant | SQLE_CORRELATION_NAME_AMBIGUOUS
SQLSTATE | 52012
Sybase error code | 7364
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Ambiguous correlation name.
Probable cause

You identified two tables in the same FROM clause with the same correlation name.


Multiple consolidated users cannot be defined

Item | Value
SQLCODE | –289
Constant | SQLE_CONSOLIDATED_USER_ALREADY_EXISTS
SQLSTATE | 5RW10
Sybase error code | 13767
ODBC 2 State | S0002
ODBC 3 State | 42S02
Probable cause

You attempted to grant consolidated permissions when your database already has a consolidated user, or attempted to grant consolidated permissions to multiple users in a single statement.


Must include primary key for table '%1' in the synchronization

Item | Value
SQLCODE | –778
Constant | SQLE_PK_NOT_IN_SYNC_ARTICLE
SQLSTATE | 5RW17
Sybase error code | 13788
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | Name of the table
Probable cause

The primary key of the table must be included in the synchronization entry.


NAMESPACE attribute is not valid with procedure type '%1'

Item | Value
SQLCODE | –989
Constant | SQLE_INVALID_NAMESPACE_ATTRIBUTE
SQLSTATE | WW058
Sybase error code | 13500
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The NAMESPACE attribute on the procedure
Probable cause

The NAMESPACE attribute is only applicable to procedures of type SOAP


Namespace heap exhausted at internal function: %1

Item | Value
SQLCODE | –164
Constant | SQLE_NAMESPACE_HEAP_EXHAUSTED
SQLSTATE | WP007
Sybase error code | 13739
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The internal function is for debugging purposes.
Probable cause

The amount of space allocated for the Java Namespace is insufficient to continue loading Java classes etc. Increase the size by using: set option public.java_namespace_size = nnnnnnnn


Need a dynamic library name

Item | Value
SQLCODE | –619
Constant | SQLE_REQUIRE_DLL_NAME
SQLSTATE | WW005
Sybase error code | 13676
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You must provide a library name specifier in the name of the external function to call.


No column list for recursive query

Item | Value
SQLCODE | –922
Constant | SQLE_NO_RECURSIVE_COLUMN_LIST
SQLSTATE | 42W9A
Sybase error code | 13562
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

A common table expression defining a recursive query must have a column list.


No current row of cursor

Item | Value
SQLCODE | –197
Constant | SQLE_NO_CURRENT_ROW
SQLSTATE | 24503
Sybase error code | 560
ODBC 2 State | 24000
ODBC 3 State | 24000
Probable cause

You attempted to perform an operation on the current row of a cursor, but the cursor is not positioned on a row. The cursor is before the first row of the cursor, after the last row, or is on a row that has since been deleted.


No database file specified

Item | Value
SQLCODE | –72
Constant | SQLE_NO_DATABASE_FILE
SQLSTATE | 08W39
Sybase error code | 4001
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

The database server was started but there was no specified database file. The server is stopped.


No indicator variable provided for NULL result

Item | Value
SQLCODE | –181
Constant | SQLE_NO_INDICATOR
SQLSTATE | 22002
Sybase error code | 13635
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You tried to retrieve a value from the database that was NULL, but you did not provide an indicator variable for that value.


No name for argument

Item | Value
SQLCODE | –907
Constant | SQLE_NO_SQLX_ARGUMENT_NAME
SQLSTATE | WX014
Sybase error code | 13576
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Unnamed arguments cannot be used as XML element or attribute names. Name unnamed items in the argument list using AS.


No primary key value for foreign key '%1' in table '%2'

Item | Value
SQLCODE | –194
Constant | SQLE_INVALID_FOREIGN_KEY
SQLSTATE | 23503
Sybase error code | 546
ODBC 2 State | 23000
ODBC 3 State | 23000
Parameter 1 | Name of the foreign key.
Parameter 2 | Name of the table with the foreign key.
Probable cause

You attempted to insert or update a row that has a foreign key for another table. The value for the foreign key is not NULL and there is not a corresponding value in the primary key


No workload capture currently exists

Item | Value
SQLCODE | –943
Constant | SQLE_WORKLOAD_CAPTURE_DOES_NOT_EXIST
SQLSTATE | WW030
Sybase error code | 13545
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You have tried to stop, pause, resume or get the status of a workload capture but no workload captures are currently in existence.


Not allowed while '%1' is using the database

Item | Value
SQLCODE | –211
Constant | SQLE_MUST_BE_ONLY_CONNECTION
SQLSTATE | 42W19
Sybase error code | 13652
ODBC 2 State | 40001
ODBC 3 State | 40001
Probable cause

You attempted a data definition language operation that cannot be completed while another user is connected.


Not connected to a database

Item | Value
SQLCODE | –101
Constant | SQLE_NOT_CONNECTED
SQLSTATE | 08003
Sybase error code | 13622
ODBC 2 State | 08003
ODBC 3 State | 08003
Probable cause

You are not connected to a database, or you executed the DISCONNECT statement and have not connected to a database again.


Not enough fields allocated in SQLDA

Item | Value
SQLCODE | –182
Constant | SQLE_SQLDA_TOO_SMALL
SQLSTATE | 07002
Sybase error code | 13636
ODBC 2 State | 07001
ODBC 3 State | 07002
Probable cause

There are not enough fields in the SQLDA to retrieve all of the values requested.


Not enough memory is allocated to the Java virtual machine for remote access

Item | Value
SQLCODE | –679
Constant | SQLE_OMNI_MEMORY_CONFIG
SQLSTATE | WO009
Sybase error code | 708
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The Java heap size and Java name space configuration values in sysoptions must be increased to allow the loading of the Java classes used for remote access.


Not enough memory to start

Item | Value
SQLCODE | –86
Constant | SQLE_NO_MEMORY
SQLSTATE | 08W13
Sybase error code | 708
ODBC 2 State | S1001
ODBC 3 State | HY001
Probable cause

The database server started, but stopped because there was not enough memory.


Not enough values for host variables

Item | Value
SQLCODE | –188
Constant | SQLE_NOT_ENOUGH_HOST_VARS
SQLSTATE | 07001
Sybase error code | 13638
ODBC 2 State | 07002
ODBC 3 State | 07002
Probable cause

You have not provided enough host variables for either the number of bind variables, or the statement, or the number of select list items.


Null attribute mismatch for column '%1'

Item | Value
SQLCODE | –724
Constant | SQLE_OMNI_NULL_MISMATCH
SQLSTATE | WO018
Sybase error code | 11211
ODBC 2 State | OK
ODBC 3 State | OK
Parameter 1 | The name of the column.
Probable cause

The null attribute of the column specified in the 'CREATE EXISTING' statement differs from the null attribute of the actual column.


Null value eliminated in aggregate function

Item | Value
SQLCODE | 109
Constant | SQLE_NULL_VALUE_ELIMINATED
SQLSTATE | 01003
Sybase error code | 409
ODBC 2 State | 01000
ODBC 3 State | 01003
Probable cause

The expression argument of the aggregate function evaluated to NULL for one or more rows.


Number of columns allowing NULLs exceeds limit

Item | Value
SQLCODE | –733
Constant | SQLE_TOO_MANY_NULL_COLUMNS
SQLSTATE | 23504
Sybase error code | 233
ODBC 2 State | 23000
ODBC 3 State | 23000
Probable cause

You attempted to create or modify a table definition such that the number of columns that allow nulls is now more than the limit on such columns. The limit is a function of database page size and is approximately 8*(page_size - 30).


Number of columns defined for the view does not match SELECT statement

Item | Value
SQLCODE | –114
Constant | SQLE_VIEW_DEFINITION_ERROR
SQLSTATE | 53011
Sybase error code | 4409
ODBC 2 State | 21S02
ODBC 3 State | 21S02
Probable cause

You attempted to create a view, but the column list specified as part of the CREATE VIEW statement does not correspond to the list of items in the view's SELECT statement.


OMNI cannot handle expressions involving remote tables inside stored procedures

Item | Value
SQLCODE | –823
Constant | SQLE_OMNI_EXPRESSION_IN_PROC
SQLSTATE | WO023
Sybase error code | 13829
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

OMNI encountered a complicated expression involving remote tables inside a stored procedure. OMNI cannot always deal with such expressions.


Only PUBLIC settings are allowed for option '%1'

Item | Value
SQLCODE | –202
Constant | SQLE_NOT_PUBLIC_ID
SQLSTATE | 42W43
Sybase error code | 13685
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the option.
Probable cause

The option specified in the SET OPTION statement is PUBLIC only. You cannot define this option for any other user.


Only the DBA can set the option '%1'

Item | Value
SQLCODE | –204
Constant | SQLE_OPTION_REQUIRES_DBA
SQLSTATE | 42W46
Sybase error code | 5878
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

The option specified in the SET OPTION statement can only be set by a user having DBA authority.


Operation would cause a group cycle

Item | Value
SQLCODE | –122
Constant | SQLE_GROUP_CYCLE
SQLSTATE | 42W02
Sybase error code | 314
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to add a member to group that would result in a member belonging to itself. The membership may be direct or indirect.


ORDER BY not allowed in window '%1'

Item | Value
SQLCODE | –949
Constant | SQLE_ORDERBY_NOT_ALLOWED
SQLSTATE | 42WA5
Sybase error code | 13539
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the window.
Probable cause

When an existing window name is referenced from an inline window specification, either the inline window or the referenced window may have an ORDER BY, but not both.


Output file cannot be written

Item | Value
SQLCODE | –979
Constant | SQLE_CANNOT_WRITE_FILE
SQLSTATE | WW048
Sybase error code | 13510
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Unable to create or write an output file. May be locked or readonly.


Output file directory does not exist

Item | Value
SQLCODE | –978
Constant | SQLE_DIRECTORY_INACCESSIBLE
SQLSTATE | WW047
Sybase error code | 13511
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A file is being written to a directory that does not exist.


Owner '%1' used in a qualified column reference does not match correlation name '%2'

Item | Value
SQLCODE | –845
Constant | SQLE_INVALID_COLUMN_QUALIFICATION
SQLSTATE | 42U02
Sybase error code | 13851
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | The owner name specified in the column reference.
Parameter 2 | The correlation name which is incorrectly referenced.
Probable cause

Your query contains a qualified column reference to a table name, but either a correlation name has been used for that table, or the owner of the table does not match the owner name specified in the column reference. Remove the owner qualification, and qualify column references only by correlation name.


Parameter '%1' in procedure or function '%2' does not have a default value

Item | Value
SQLCODE | –1001
Constant | SQLE_NO_DEFAULT_FOR_PARM
SQLSTATE | 08W71
Sybase error code | 13491
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the parameter.
Parameter 2 | The name of the procedure or function.
Probable cause

An attempt was made to use DEFAULT as a procedure or function argument, but the corresponding parameter does not have a default value.


Parameter '%1' not found in procedure '%2'

Item | Value
SQLCODE | –615
Constant | SQLE_INVALID_PARAMETER_NAME
SQLSTATE | 42W47
Sybase error code | 201
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You supplied a procedure parameter name that does not match a parameter for this procedure. Check the spelling of the parameter name.


Parameter name missing in call to procedure '%1'

Item | Value
SQLCODE | –639
Constant | SQLE_PARAMETER_NAME_MISSING
SQLSTATE | 42W42
Sybase error code | 201
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | The name of the procedure
Probable cause

Positional arguments were specified after keyword arguments in a call to this procedure.


Parameter not registered as output parameter

Item | Value
SQLCODE | –671
Constant | SQLE_PARAM_NOT_REGISTERED
SQLSTATE | WJ002
Sybase error code | 13712
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The parameter must be registered as an output parameter before the value of the parameter can be obtained.


Parent not open: '%1'

Item | Value
SQLCODE | –900
Constant | SQLE_EXPLICIT_TAG_NOT_OPEN
SQLSTATE | WX008
Sybase error code | 13581
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The parent tag id that is not among the open tags
Probable cause

FOR XML EXPLICIT requires the parent tag for a row to be opened when that row is read. Check the order of the rows returned by the query with the FOR XML EXPLICIT clause removed.


Parse error: %1

Item | Value
SQLCODE | –95
Constant | SQLE_INVALID_PARSE_PARAMETER
SQLSTATE | 08W49
Sybase error code | 5864
ODBC 2 State | 08004
ODBC 3 State | 08004
Probable cause

An error occurred while parsing a connection string.


Parse error: %1

Item | Value
SQLCODE | –754
Constant | SQLE_INVALID_DSN_NAME
SQLSTATE | 08W54
Sybase error code | 5864
ODBC 2 State | 08004
ODBC 3 State | 08004
Probable cause

An invalid data source name was used in the connection string.


PARTITION BY not allowed in reference to window '%1'

Item | Value
SQLCODE | –948
Constant | SQLE_PARTITIONBY_NOT_ALLOWED
SQLSTATE | 42WA4
Sybase error code | 13540
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the window.
Probable cause

When an existing window name is referenced from an inline window specification, the inline specification may not have a PARTITION BY clause.


Passthrough statement inconsistent with current passthrough

Item | Value
SQLCODE | –287
Constant | SQLE_PASSTHROUGH_INCONSISTENT
SQLSTATE | 5RW08
Sybase error code | 13649
ODBC 2 State | S0002
ODBC 3 State | 42S02
Probable cause

Passthrough is additive, in that subsequent passthrough statements add to the list of users receiving passthrough. The passthrough statements must all be PASSTHROUGH ONLY or none should be PASSTHROUGH ONLY.


Password cannot be longer than %1 characters

Item | Value
SQLCODE | –958
Constant | SQLE_PASSWORD_TOO_LONG
SQLSTATE | 28000
Sybase error code | 13530
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

The password is longer than that allowed by the server. :EN-


Password contains an illegal character

Item | Value
SQLCODE | –963
Constant | SQLE_ILLEGAL_PASSWORD
SQLSTATE | 08005
Sybase error code | 13528
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

The specified password contains an illegal character.


Password must be at least %1 characters

Item | Value
SQLCODE | –738
Constant | SQLE_PASSWORD_TOO_SHORT
SQLSTATE | 28000
Sybase error code | 573
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

The password is shorter than that allowed by the current MIN_PASSWORD_LENGTH option setting. :EN-


Permission denied: %1

Item | Value
SQLCODE | –121
Constant | SQLE_PERMISSION_DENIED
SQLSTATE | 42501
Sybase error code | 262
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Description of the type of permission lacking.
Probable cause

You do not have the required permission to do the specified action. The message specifies the actual permission required and the object being acted upon.


Plan can not be generated for this type of statement

Item | Value
SQLCODE | –894
Constant | SQLE_STMT_NOT_ALLOWED_IN_PLAN
SQLSTATE | 0AW14
Sybase error code | 13589
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You tried to get the execution plan for a statement type that is not supported.


Plan may contain virtual indexes.

Item | Value
SQLCODE | 129
Constant | SQLE_USING_VIRTUAL_INDEXES
SQLSTATE | 01W20
Sybase error code | 13596
ODBC 2 State | 01S01
ODBC 3 State | 01S01
Probable cause

Virtual indexes are currently enabled in this connection. Any plans that are generated may contain virtual indexes.


Previous error lost prior to RESIGNAL

Item | Value
SQLCODE | –825
Constant | SQLE_PREVIOUS_ERROR_LOST
SQLSTATE | WP011
Sybase error code | 13831
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A RESIGNAL statement in an exception handler of a stored procedure was executed but the context of the previous error was unavailable. A possible cause of this error is a SELECT statement which returns a result set in the exception handler.


Primary key column '%1' already defined

Item | Value
SQLCODE | –119
Constant | SQLE_PRIMARY_KEY_COLUMN_DEFINED
SQLSTATE | 52009
Sybase error code | 1909
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the column that is already in the primary key.
Probable cause

You listed the same column name twice in the definition of a primary key.


Primary key for row in table '%1' is referenced by foreign key '%2' in table '%3'

Item | Value
SQLCODE | –198
Constant | SQLE_PRIMARY_KEY_VALUE_REF
SQLSTATE | 23W05
Sybase error code | 547
ODBC 2 State | 23000
ODBC 3 State | 23000
Parameter 1 | The name of the table containing the row being modified.
Parameter 2 | The name of the foreign index (or role) of the referencing table.
Parameter 3 | The name of the foreign table referencing the primary row.
Probable cause

You attempted to delete or modify a row whose primary key value is referenced elsewhere in the database.


Primary key for table '%1' is not unique

Item | Value
SQLCODE | –193
Constant | SQLE_PRIMARY_KEY_NOT_UNIQUE
SQLSTATE | 23W01
Sybase error code | 2601
ODBC 2 State | 23000
ODBC 3 State | 23000
Parameter 1 | Name of the table where the problem was detected.
Probable cause

You attempted to add a new row to a table, but the new row has the same primary key as an existing row. The database has not added the incorrect row to the database. For example, you might have added a student with student number 86004 and there is already a row for a student with that number.


Procedure '%1' is no longer valid

Item | Value
SQLCODE | –836
Constant | SQLE_PROCEDURE_NO_LONGER_VALID
SQLSTATE | 42W63
Sybase error code | 13842
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the procedure.
Probable cause

A procedure definition cannot be loaded from the catalog. Check for tables or columns which have been renamed or which may be reserved words.


Procedure '%1' not found

Item | Value
SQLCODE | –265
Constant | SQLE_PROCEDURE_NOT_FOUND
SQLSTATE | 52W09
Sybase error code | 504
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the procedure that could not be found.
Probable cause

You misspelled the name of a procedure, or you did not qualify a procedure name with a user name.


Procedure '%1' terminated with unhandled exception '%2'

Item | Value
SQLCODE | –91
Constant | SQLE_UNHANDLED_JAVA_EXCEPTION
SQLSTATE | WP001
Sybase error code | 13735
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the procedure which returned the unhandled exception.
Parameter 2 | The fully qualified Java class name of the unhandled exception.
Probable cause

A Java procedure terminated with an active exception, and this exception is reflected in SQL as an error status.


Procedure has completed

Item | Value
SQLCODE | 105
Constant | SQLE_PROCEDURE_COMPLETE
SQLSTATE | 01W05
Sybase error code | 13618
ODBC 2 State | OK
ODBC 3 State | OK
Probable cause

There are no more result sets available for this procedure. An OPEN or a RESUME statement may have caused the procedure to execute to completion. On an OPEN statement, the cursor is not opened. You may have attempted to RESUME a cursor on a SELECT statement.


Procedure in use by '%1'

Item | Value
SQLCODE | –215
Constant | SQLE_PROCEDURE_IN_USE
SQLSTATE | 42W23
Sybase error code | 3702
ODBC 2 State | 40001
ODBC 3 State | 40001
Parameter 1 | Name of user.
Probable cause

You attempted to DROP a procedure that is being used by other active users of the database.


Procedure or trigger calls have nested too deeply

Item | Value
SQLCODE | –274
Constant | SQLE_NESTING_TOO_DEEP
SQLSTATE | 42W29
Sybase error code | 217
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You may have defined a procedure or trigger that causes unlimited recursion.


Publication '%1' not found

Item | Value
SQLCODE | –280
Constant | SQLE_PUBLICATION_NOT_FOUND
SQLSTATE | 5RW01
Sybase error code | 13642
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the publication that could not be found.
Probable cause

You misspelled the name of a publication, or you did not qualify a publication name with a user name.


RAISERROR executed: %1

Item | Value
SQLCODE | –631
Constant | SQLE_RAISERROR_STMT
SQLSTATE | WW012
Sybase error code | 0
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | RAISERROR message string
Probable cause

A RAISERROR statement has been executed.


READTEXT or WRITETEXT statement cannot refer to a view

Item | Value
SQLCODE | –708
Constant | SQLE_TEXT_OPERATION_ON_VIEW
SQLSTATE | 42W50
Sybase error code | 285
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

A Transact-SQL READTEXT or WRITETEXT statement cannot refer to text columns in a view. Replace the view reference with the name of a base table.


Recursion is not allowed without the RECURSIVE keyword

Item | Value
SQLCODE | –938
Constant | SQLE_RECURSIVE_KEYWORD_REQUIRED
SQLSTATE | 42WA0
Sybase error code | 13549
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

The common table expressions for a recursive query must be defined using a WITH RECURSIVE clause.


Recursive column %1: conversion from '%2' to '%3' loses precision

Item | Value
SQLCODE | –945
Constant | SQLE_BAD_RECURSIVE_COLUMN_CONVERSION
SQLSTATE | 42WA2
Sybase error code | 13543
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Column number of the recursive subquery.
Parameter 2 | Type converted from.
Parameter 3 | Type converted to.
Probable cause

Every column in the recursive subquery must be convertible to the type of the corresponding column in the initial subquery without loss of precision. Try casting the column in the initial subquery to an appropriate type.


Referential integrity actions other than RESTRICT not allowed for temporary tables

Item | Value
SQLCODE | –849
Constant | SQLE_INVALID_FOREIGN_KEY_ACTION
SQLSTATE | 42R01
Sybase error code | 1709
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You attempted to specify an unsupported referential integrity action for a temporary table.


Remote message type '%1' not found

Item | Value
SQLCODE | –286
Constant | SQLE_NOT_REMOTE_TYPE
SQLSTATE | 5RW07
Sybase error code | 13648
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of remote message type.
Probable cause

You referred to a remote message type that is not defined in this database. Use CREATE REMOTE TYPE to define remote message types.


Remote server '%1' could not be found; Add the server using CREATE SERVER

Item | Value
SQLCODE | –659
Constant | SQLE_OMNI_SERVER_NOT_FOUND
SQLSTATE | WO004
Sybase error code | 11214
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the remote server.
Probable cause

You attempted to define an object on a server that has not been added. Use CREATE SERVER to add the remote server definition.


Remote server '%1' is currently configured as read only

Item | Value
SQLCODE | –658
Constant | SQLE_OMNI_READONLY
SQLSTATE | WO003
Sybase error code | 11248
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the remote server.
Probable cause

You attempted to perform an update on an object located on a server that is configured as read only. Use ALTER SERVER to reconfigure the remote server to be updatable.


Remote server does not have the ability to support this statement

Item | Value
SQLCODE | –706
Constant | SQLE_OMNI_SERVER_NOT_CAPABLE
SQLSTATE | WO012
Sybase error code | 11227
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted to execute a statement that requires a capability that is not supported by a remote server.


Remote statement failed

Item | Value
SQLCODE | –288
Constant | SQLE_REMOTE_STATEMENT_FAILED
SQLSTATE | 5RW09
Sybase error code | 13650
ODBC 2 State | S0002
ODBC 3 State | 42S02
Probable cause

This SQLSTATE can be signaled within a trigger to prevent DBREMOTE from displaying an error message in the output. This exception will only occur when a trigger or procedure SIGNALS it. This is useful for ignoring replication errors that are permitted by design.


Request denied -- no active databases

Item | Value
SQLCODE | –76
Constant | SQLE_REQUEST_DENIED_NO_DATABASES
SQLSTATE | 08W28
Sybase error code | 950
ODBC 2 State | 08004
ODBC 3 State | 08004
Probable cause

The server has denied your request as there are currently no running databases.


Request to start/stop database denied

Item | Value
SQLCODE | –75
Constant | SQLE_START_STOP_DATABASE_DENIED
SQLSTATE | 08W29
Sybase error code | 6004
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You do not have permission to start or stop a database. The required permission is determined on the server command line.


Required operators excluded

Item | Value
SQLCODE | –969
Constant | SQLE_REQUIRED_OPERATORS_EXCLUDED
SQLSTATE | WI011
Sybase error code | 13521
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The database server was unable to construct a valid access plan for the given request because required data flow operators were excluded by the Exclude_operators option. Re-enable the required operators to execute the statement.


Resource governor for '%1' exceeded

Item | Value
SQLCODE | –685
Constant | SQLE_RESOURCE_GOVERNOR_EXCEEDED
SQLSTATE | WP009
Sybase error code | 13715
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The resource whose limit has been exceeded
Probable cause

The resource governor for the stated resource has determined that the usage of the resource has exceeded its limit.


RESTORE unable to open file '%1'

Item | Value
SQLCODE | –717
Constant | SQLE_RESTORE_UNABLE_TO_OPEN
SQLSTATE | WB008
Sybase error code | 13726
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | File name of database file.
Probable cause

RESTORE was unable to open one of the database files.


RESTORE unable to start database '%1'

Item | Value
SQLCODE | –719
Constant | SQLE_RESTORE_UNABLE_TO_START
SQLSTATE | WB010
Sybase error code | 13728
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | File name of database file.
Probable cause

After a RESTORE, the resulting database could not be started.


RESTORE unable to write to file '%1'

Item | Value
SQLCODE | –718
Constant | SQLE_RESTORE_UNABLE_TO_WRITE
SQLSTATE | WB009
Sybase error code | 13727
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | File name of database file.
Probable cause

RESTORE was unable to write to one of the database files.


Result set not allowed from within an atomic compound statement

Item | Value
SQLCODE | –222
Constant | SQLE_RESULT_NOT_ALLOWED
SQLSTATE | 3BW02
Sybase error code | 13655
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You used a SELECT statement with no INTO clause or a RESULT CURSOR statement within an atomic compound statement.


Result set not permitted in '%1'

Item | Value
SQLCODE | –946
Constant | SQLE_RESULT_SET_NOT_PERMITTED
SQLSTATE | 09W03
Sybase error code | 13542
ODBC 2 State | 07005
ODBC 3 State | 07005
Parameter 1 | Name of object containing the invalid statement.
Probable cause

You attempted to execute a SELECT statement in a context where a result set is not permitted.


Return type of void from procedure '%1' cannot be used in any expression

Item | Value
SQLCODE | –705
Constant | SQLE_PROCEDURE_RETURNS_VOID
SQLSTATE | 53019
Sybase error code | 257
ODBC 2 State | 07006
ODBC 3 State | 07006
Parameter 1 | Name of the procedure.
Probable cause

The Java type void does not map onto any SQL type, hence a procedure returning void cannot be used in any SQL expression.


Return value cannot be set

Item | Value
SQLCODE | –690
Constant | SQLE_RETVAL_CANNOT_BE_SET
SQLSTATE | WJ006
Sybase error code | 13601
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Setting a value for the return parameter of a callable statement is not allowed.


Right truncation of string data

Item | Value
SQLCODE | –638
Constant | SQLE_STRING_RIGHT_TRUNCATION
SQLSTATE | 22001
Sybase error code | 9502
ODBC 2 State | 22001
ODBC 3 State | 22001
Probable cause

Non-space characters were truncated upon the assignment of string data.


Rollback occurred due to deadlock during prefetch

Item | Value
SQLCODE | –684
Constant | SQLE_ROLLBACK_ON_PREFETCH
SQLSTATE | WW019
Sybase error code | 1205
ODBC 2 State | 40001
ODBC 3 State | 40001
Probable cause

One of the cursors that was opened with prefetch enabled was performing fetch operations, and a deadlock occurred during a prefetch. This is a deadlock situation and your transaction has been chosen as the one to rollback. The request which received this error was not executed, unless the request was a CLOSE cursor, in which case the cursor was closed.


ROLLBACK TO SAVEPOINT not allowed

Item | Value
SQLCODE | –221
Constant | SQLE_ROLLBACK_NOT_ALLOWED
SQLSTATE | 3B002
Sybase error code | 13654
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted a ROLLBACK TO SAVEPOINT within an atomic operation to a savepoint established before the atomic operation.


Row has been updated since last time read

Item | Value
SQLCODE | 104
Constant | SQLE_ROW_UPDATED_WARNING
SQLSTATE | 01W04
Sybase error code | 532
ODBC 2 State | OK
ODBC 3 State | OK
Probable cause

You fetched a row from a SCROLL cursor. The row was previously fetched from the same cursor, and one or more columns in the row has been updated since the previous fetch. The column(s) updated may or may not be fetched by the cursor; this warning just indicates that the row from the table has been updated. If the cursor involves more than one table, a row from one or more of the tables has been updated.


Row has changed since last read -- operation canceled

Item | Value
SQLCODE | –208
Constant | SQLE_ROW_UPDATED_SINCE_READ
SQLSTATE | 22W02
Sybase error code | 554
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted an UPDATE (positioned) or DELETE (positioned) operation on a cursor declared as a SCROLL cursor, and the row you are changing has been updated since you read it. This error prevents the 'lost update' problem.


Row in table '%1' was modified or deleted in BEFORE trigger

Item | Value
SQLCODE | –833
Constant | SQLE_ROW_REMODIFIED_OR_DELETED
SQLSTATE | 42W62
Sybase error code | 13839
ODBC 2 State | 37000
ODBC 3 State | ERROR
Parameter 1 | Name of the table.
Probable cause

A BEFORE trigger has updated or deleted the row which caused the trigger to fire, preventing the original operation from completing. The trigger must be re-written so that it does not attempt to change the row via UPDATE or DELETE statements.


Row not found

Item | Value
SQLCODE | 100
Constant | SQLE_NOTFOUND
SQLSTATE | 02000
Sybase error code | 560
ODBC 2 State | OK
ODBC 3 State | OK
Probable cause

You positioned a cursor beyond the beginning or past the end of the query. There is no row at that position.


Row was dropped from table %1 to maintain referential integrity

Item | Value
SQLCODE | 137
Constant | SQLE_ROW_DELETED_TO_MAINTAIN_REFERENTIAL_INTEGRITY
SQLSTATE | 01W24
Sybase error code | 13489
ODBC 2 State | OK
ODBC 3 State | OK
Parameter 1 | The name of the table
Probable cause

A delete of a primary row during download forced its foreign row(s) to be deleted as well to maintain referential integrity


Run time SQL error -- %1

Item | Value
SQLCODE | –300
Constant | SQLE_ERROR
SQLSTATE | 40000
Sybase error code | 13664
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Identification of the error.
Probable cause

An internal database error occurred. If it can be reproduced, it should be reported to iAnywhere Solutions. You may be able to work around this problem by modifying the associated query statement.


Savepoint '%1' not found

Item | Value
SQLCODE | –220
Constant | SQLE_SAVEPOINT_NOTFOUND
SQLSTATE | 3B001
Sybase error code | 6401
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of savepoint.
Probable cause

You attempted to rollback to a savepoint that does not exist.


Savepoints require a rollback log

Item | Value
SQLCODE | –213
Constant | SQLE_SAVEPOINTS_REQUIRE_UNDO
SQLSTATE | 3BW01
Sybase error code | 13656
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You cannot use savepoints when the database server is running in bulk mode without a rollback log.


Schedule '%1' for event '%2' already exists

Item | Value
SQLCODE | –774
Constant | SQLE_SCHEDULE_ALREADY_EXISTS
SQLSTATE | WE004
Sybase error code | 13784
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the schedule that already exists.
Parameter 2 | Name of the event being scheduled.
Probable cause

You have attempted to create a schedule with a name that already exists in SYS.SYSSCHEDULE for the named event.


Schedule '%1' for event '%2' not found

Item | Value
SQLCODE | –773
Constant | SQLE_SCHEDULE_NOT_FOUND
SQLSTATE | WE003
Sybase error code | 13783
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the schedule that could not be found.
Parameter 2 | Name of the event being scheduled.
Probable cause

You have attempted to reference a schedule with a name that does not exist in SYS.SYSSCHEDULE for the named event.


Seek absolute 0 was attempted on a JDBC SAResultSet

Item | Value
SQLCODE | –743
Constant | SQLE_JDBC_RESULTSET_SEEK_ABSOLUTE_ZERO
SQLSTATE | WJ016
Sybase error code | 13756
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

There is no row zero on JDBC resultSets. The valid row numbers are 1, 2, ..., -2, -1.


SELECT lists in UNION, INTERSECT or EXCEPT do not match in length

Item | Value
SQLCODE | –153
Constant | SQLE_INVALID_UNION
SQLSTATE | 53026
Sybase error code | 205
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You specified a UNION, INTERSECT or EXCEPT but the SELECT statements involved in the operation do not have the same number of columns in the select list.


SELECT returns more than one row

Item | Value
SQLCODE | –185
Constant | SQLE_TOO_MANY_RECORDS
SQLSTATE | 21000
Sybase error code | 13637
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You tried to use a SELECT statement without a cursor, but the statement cursor returns more than one row. Only a single row SELECT statement can be used in this context.


Server '%1': %2

Item | Value
SQLCODE | –660
Constant | SQLE_OMNI_REMOTE_ERROR
SQLSTATE | WO005
Sybase error code | 13732
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the remote server.
Parameter 2 | The message from the remote server.
Probable cause

A message was generated by a remote server. The message text is included."


Server capability name '%1' could not be found in the SYS.SYSCAPABILITYNAME table.

Item | Value
SQLCODE | –761
Constant | SQLE_CAPABILITY_NOT_FOUND
SQLSTATE | WO014
Sybase error code | 13723
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of server capability.
Probable cause

An ALTER SERVER statement was attempted on a capability that was not defined.


Server not found and unable to autostart

Item | Value
SQLCODE | –764
Constant | SQLE_UNABLE_TO_CONNECT_OR_START
SQLSTATE | 08W55
Sybase error code | 13774
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

Could not connect to a server, and was unable to autostart a server. Autostart may have failed because no database file was supplied.


Service '%1' already exists

Item | Value
SQLCODE | –919
Constant | SQLE_SERVICE_ALREADY_EXISTS
SQLSTATE | 42W97
Sybase error code | 13565
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the service that already exists.
Probable cause

You have attempted to create a service with a name that already exists in SYS.SYSSERVICE.


Service '%1' in use

Item | Value
SQLCODE | –924
Constant | SQLE_SERVICE_IN_USE
SQLSTATE | 55W15
Sybase error code | 13567
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the service that is in use.
Probable cause

You have attempted to drop a service that is currently in use.


Service '%1' not found

Item | Value
SQLCODE | –920
Constant | SQLE_SERVICE_NOT_FOUND
SQLSTATE | 42W98
Sybase error code | 13564
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the specified service that could not be found.
Probable cause

You have attempted to reference a service with a name that does not exist in SYS.SYSSERVICE.


Service definition requires a statement when authorization is off

Item | Value
SQLCODE | –931
Constant | SQLE_SERVICE_AUTH_REQUIRED
SQLSTATE | 42W9E
Sybase error code | 13554
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The service definition for the specified service type requires a statement to be specified when authorization is set to OFF.


Service statement definition is inconsistent with service type

Item | Value
SQLCODE | –927
Constant | SQLE_SERVICE_STATEMENT_MISMATCH
SQLSTATE | 42W9C
Sybase error code | 13558
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Either no statement was provided for a service whose type requires one, or a statement was provided when the service type does not allow one to be defined.


Service type does not allow '%1' attribute

Item | Value
SQLCODE | –1027
Constant | SQLE_SERVICE_ATTR_NOT_ALLOWED
SQLSTATE | 42WB2
Sybase error code | 13483
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the attribute that is not allowed.
Probable cause

The service definition for the specified service type does not allow the given attribute to be specified


Service type required for CREATE SERVICE

Item | Value
SQLCODE | –915
Constant | SQLE_SERVICE_TYPE_REQUIRED
SQLSTATE | 42W92
Sybase error code | 13569
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The CREATE SERVICE statement requires a service type to be specified.


Set clause for column '%1' used incorrectly

Item | Value
SQLCODE | –846
Constant | SQLE_INVALID_SET_CLAUSE
SQLSTATE | 42U03
Sybase error code | 13852
ODBC 2 State | S0002
ODBC 3 State | 42S03
Probable cause

Your update statement contains an invalid set clause, e.g., there are multiple set clauses for the same column.


SETUSER not allowed in procedures, triggers, events or batches

Item | Value
SQLCODE | –877
Constant | SQLE_SETUSER_NOT_IN_PROCEDURES
SQLSTATE | 42W09
Sybase error code | 13888
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The SETUSER statement is not allowed in stored procedures, triggers, event handlers or batches. It cannot be executed via EXECUTE IMMEDIATE.


Signature '%1' does not match procedure parameters

Item | Value
SQLCODE | –737
Constant | SQLE_SIGNATURE_MISMATCH
SQLSTATE | 42W54
Sybase error code | 201
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | The value of the signature
Probable cause

The number of types in the signature must match the number of procedure parameters. If a 'dynamic result sets' clause was specified, the number of dynamic result sets must match the quantity found in the signature.


Specified database file already in use

Item | Value
SQLCODE | –816
Constant | SQLE_FILE_IN_USE
SQLSTATE | 08W56
Sybase error code | 924
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

The database server could not start the specified database because the file is already in use.


Specified database is invalid

Item | Value
SQLCODE | –84
Constant | SQLE_INVALID_DATABASE
SQLSTATE | 08W11
Sybase error code | 4001
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

The database file you specified is invalid. The database server is stopped.


Specified database not found

Item | Value
SQLCODE | –83
Constant | SQLE_DATABASE_NOT_FOUND
SQLSTATE | 08W10
Sybase error code | 911
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

The database server was unable to find the specified database. The database server may be attempting to start a database file that cannot be opened or that cannot be found on the network. You may be attempting to connect to a database name that is not running.


Specified local connection is not to the current database.

Item | Value
SQLCODE | –997
Constant | SQLE_LOCAL_CONNECTION_NOT_TO_CURRENT_DB
SQLSTATE | WO025
Sybase error code | 710
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The specified connection id is for a connection that is connected to a database other than the current database.


Specified local connection not found.

Item | Value
SQLCODE | –996
Constant | SQLE_LOCAL_CONNECTION_NOT_FOUND
SQLSTATE | WO024
Sybase error code | 709
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

There is no connection with the specified connection id.


SQL statement error

Item | Value
SQLCODE | –132
Constant | SQLE_STATEMENT_ERROR
SQLSTATE | 26501
Sybase error code | 13629
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The statement identifier (generated by PREPARE) passed to the database for a further operation is invalid.


SQLDA data type invalid

Item | Value
SQLCODE | –759
Constant | SQLE_SQLDA_INVALID_DATATYPE
SQLSTATE | 07W05
Sybase error code | 13770
ODBC 2 State | 07001
ODBC 3 State | 07W05
Probable cause

The data type specified for a SQLDA variable is invalid.


SQLDA fields inconsistent for a multi-row SQLDA

Item | Value
SQLCODE | –700
Constant | SQLE_SQLDA_INCONSISTENT
SQLSTATE | 07W04
Sybase error code | 13721
ODBC 2 State | 07001
ODBC 3 State | 07W04
Probable cause

Not all of the rows in a multi-rows SQLDA have been defined identically for an array operation (insert, fetch, or execute). A given column must be defined the same (type and length) in each row.


Sqlpp/dblib version mismatch

Item | Value
SQLCODE | –230
Constant | SQLE_PP_DBLIB_MISMATCH
SQLSTATE | 08W18
Sybase error code | 13657
ODBC 2 State | 08801
ODBC 3 State | 08001
Probable cause

Your executable has source files with Embedded SQL that were preprocessed with a preprocessor that does not match the database interface library.


Statement cannot be executed

Item | Value
SQLCODE | 111
Constant | SQLE_CANNOT_EXECUTE_STMT
SQLSTATE | 01W08
Sybase error code | 590
ODBC 2 State | OK
ODBC 3 State | OK
Probable cause

You specified a statement for the PREPARE..WITH EXECUTE statement that cannot be executed. If you specified an output SQLDA, it may contain a DESCRIBE of the prepared statement.


Statement contains an illegal usage of the non-deterministic function '%1'

Item | Value
SQLCODE | –889
Constant | SQLE_NONDETERMINISTIC_FUNCTION
SQLSTATE | 42W79
Sybase error code | 13594
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | The name of the non-deterministic user-defined function used in error.
Probable cause

Non-deterministic functions cannot appear in a CHECK constraint, or any other type of integrity constraint. They may appear anywhere within a query, view, or derived table. However, if an aliased SELECT list expression contains a non-determinstic function, that alias cannot be referred to elsewhere in the query.


Statement contains an illegal usage of the NUMBER(*) function

Item | Value
SQLCODE | –864
Constant | SQLE_INVALID_NUMBER
SQLSTATE | 42W71
Sybase error code | 13869
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

The NUMBER(*) and IDENTITY() functions can only appear in the SELECT list of the outer-most SELECT block. It cannot be used in any subquery or in a predicate.


Statement interrupted by user

Item | Value
SQLCODE | –299
Constant | SQLE_INTERRUPTED
SQLSTATE | 57014
Sybase error code | 3621
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You canceled a statement during its execution. The database was able to stop the operation without doing a rollback. If the statement is INSERT, UPDATE, or DELETE, any changes made by the statement will be canceled. If the statement is a data definition statement (for example CREATE TABLE), the statement will be canceled, but the COMMIT that was done as a side effect will not be canceled.


Statement is not allowed in passthrough mode

Item | Value
SQLCODE | –707
Constant | SQLE_STMT_NOT_ALLOWED_IN_PASSTHROUGH
SQLSTATE | 0AW05
Sybase error code | 13631
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You tried to execute a statement that cannot be executed while in passthrough mode. For example, you may have executed a batch statement.


Statement size or complexity exceeds server limits

Item | Value
SQLCODE | –890
Constant | SQLE_SYNTACTIC_LIMIT
SQLSTATE | 54W01
Sybase error code | 404
ODBC 2 State | 37000
ODBC 3 State | 54000
Probable cause

The statement contains one or more constructs whose size make it impossible to process. Rewrite the query so that the internal limit is not exceeded. For example, if the query contains a large IN-list, consider inserting the IN-list's values into a temporary table. Then rewrite the query to join this temporary table to the other table(s) in the original statement.


statement's size limit is invalid.

Item | Value
SQLCODE | –674
Constant | SQLE_INVALID_CURSOR_RANGE
SQLSTATE | 09W07
Sybase error code | 13713
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

FIRST or TOP n are used in a SELECT statement to limit the size of a result. The size limit 'n' must be a constant integer greater than 0 and less than 32767.


Strongly-encrypted database files are not supported in the runtime server

Item | Value
SQLCODE | –688
Constant | SQLE_NO_ENCRYPTION_IN_RUNTIME
SQLSTATE | 55W13
Sybase error code | 13879
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You attempted to start a strongly-encrypted database with the runtime server. Use the full server.


Subquery allowed only one select list item

Item | Value
SQLCODE | –151
Constant | SQLE_SUBQUERY_SELECT_LIST
SQLSTATE | 53023
Sybase error code | 102
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You entered a subquery which has more than one column in the select list. Change the select list to have only one column.


Subquery cannot return more than one row

Item | Value
SQLCODE | –186
Constant | SQLE_SUBQUERY_RESULT_NOT_UNIQUE
SQLSTATE | 21W01
Sybase error code | 512
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You used a subquery that returns more than one row, in a context where only a single row can be used. If the subquery is in the WHERE clause, you might be able to use the IN keyword.


Subscription to '%1' for '%2' already exists

Item | Value
SQLCODE | –282
Constant | SQLE_SUBSCRIPTION_NOT_UNIQUE
SQLSTATE | 5RW03
Sybase error code | 13644
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the publication.
Parameter 2 | Name of the user.
Probable cause

You attempted to create a subscription that already exists.


Subscription to '%1' for '%2' not found

Item | Value
SQLCODE | –283
Constant | SQLE_SUBSCRIPTION_NOT_FOUND
SQLSTATE | 5RW04
Sybase error code | 13645
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the publication.
Parameter 2 | Name of the user.
Probable cause

You attempted to drop, start, or synchronize a subscription that does not exist.


Synchronization failed due to an error on the server: %1

Item | Value
SQLCODE | –857
Constant | SQLE_SERVER_SYNCHRONIZATION_ERROR
SQLSTATE | 0AW12
Sybase error code | 13860
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | The error number from the server.
Probable cause

Synchronization failed at the server. More details can be found in the synchronization log file.


Synchronization message type '%1' not found

Item | Value
SQLCODE | –765
Constant | SQLE_NOT_SYNC_TYPE
SQLSTATE | 5RW11
Sybase error code | 13775
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of synchronization message type.
Probable cause

You referred to a synchronization message type that is not defined in this database.


Synchronization option '%1' contains semi-colon, equal sign or curly brace

Item | Value
SQLCODE | –797
Constant | SQLE_BAD_SYNC_OPTION_VALUE
SQLSTATE | 5RW32
Sybase error code | 13807
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | The name of the synchronization option
Probable cause

You attempted to set a synchronization option with an invalid value.


Synchronization option '%1' not found

Item | Value
SQLCODE | –805
Constant | SQLE_SYNC_OPTION_NOT_FOUND
SQLSTATE | 5RW33
Sybase error code | 13815
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | The name of the synchronization option
Probable cause

You attempted to delete a undefined synchronization option.


Synchronization option is too long

Item | Value
SQLCODE | –809
Constant | SQLE_SYNC_OPTION_TOO_LONG
SQLSTATE | 5RW34
Sybase error code | 13819
ODBC 2 State | 42000
ODBC 3 State | 42S02
Probable cause

Synchronization option list cannot be longer than database page size.


Synchronization server failed to commit the upload

Item | Value
SQLCODE | –794
Constant | SQLE_UPLOAD_FAILED_AT_SERVER
SQLSTATE | 0AW09
Sybase error code | 13804
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to synchronize an UltraLite database and during the synchronization session, a complete upload stream was sent that could not be committed to the consolidated database. The reason for the upload failure can be found in the synchronization log file.


Synchronization site '%1' is already defined

Item | Value
SQLCODE | –796
Constant | SQLE_SYNC_SITE_NOT_UNIQUE
SQLSTATE | 5RW31
Sybase error code | 13806
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | The name of the synchronization site
Probable cause

You attempted to create a synchronization site with a non-unique site name.


Syntax error near '%1' %2

Item | Value
SQLCODE | –131
Constant | SQLE_SYNTAX_ERROR
SQLSTATE | 42W04
Sybase error code | 102
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | The word or symbol where the syntax error has been detected.
Parameter 2 | Line number.
Probable cause

The database server cannot understand the statement you are trying to execute. If you used a keyword (such as DATE) for a column name, try enclosing the keyword in quotation marks ("DATE").


Syntax error, cannot specify IQ specific options without specifying IQ PATH

Item | Value
SQLCODE | –687
Constant | SQLE_IQ_PATH_SYNTAX_ERROR
SQLSTATE | 42W48
Sybase error code | 102
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

The database server cannot understand the statement you are trying to execute. If you used a keyword (such as DATE) for a column name, try enclosing the keyword in quotation marks ("DATE").


System command failed with return code %1

Item | Value
SQLCODE | –910
Constant | SQLE_SYSTEM_COMMAND_FAILED
SQLSTATE | 38W01
Sybase error code | 13574
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Return code value
Probable cause

A non-zero return code resulted when executing a system command.


System event type '%1' not found

Item | Value
SQLCODE | –806
Constant | SQLE_EVENT_TYPE_NOT_FOUND
SQLSTATE | WE008
Sybase error code | 13816
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the system event type that could not be found.
Probable cause

You have attempted to create an event with a system event type name that does not exist in SYS.SYSEVENTTYPE.


Table '%1' has a foreign key with a referential action

Item | Value
SQLCODE | –677
Constant | SQLE_TABLE_HAS_REFACTION
SQLSTATE | 56001
Sybase error code | 547
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the table with the referential action
Probable cause

The table could not be renamed as it has a foreign key with a referential action. To rename the table, first drop the foreign key constraints.


Table '%1' has no primary key

Item | Value
SQLCODE | –118
Constant | SQLE_NO_PRIMARY_KEY
SQLSTATE | 55008
Sybase error code | 1719
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the table that does not have a primary key.
Probable cause

You attempted to add a foreign key referring to a table that does not have a primary key. You must add a primary key to the referenced table.


Table '%1' has publications

Item | Value
SQLCODE | –281
Constant | SQLE_TABLE_HAS_PUBLICATIONS
SQLSTATE | 5RW02
Sybase error code | 13643
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the publication that has publications.
Probable cause

You attempted to drop a table that has publications defined.


Table '%1' is already included

Item | Value
SQLCODE | –822
Constant | SQLE_TABLE_ALREADY_INCLUDED
SQLSTATE | 5RW36
Sybase error code | 13828
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | The name of the table
Probable cause

You attempted to add or modify a publication or synchronization definition such that the same table is included twice.


Table '%1' is in an outer join cycle

Item | Value
SQLCODE | –136
Constant | SQLE_OUTER_JOIN_CYCLE
SQLSTATE | 52W14
Sybase error code | 315
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of a table in the cycle.
Probable cause

You specified outer joins that create a cycle of tables.


Table '%1' is part of a synchronization definition

Item | Value
SQLCODE | –819
Constant | SQLE_SYNC_CONTAINS_TABLE
SQLSTATE | 5RW35
Sybase error code | 13825
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | The name of the table
Probable cause

A table belonging to a synchronization definition cannot be dropped or altered except using DBMLSync.


Table '%1' not found

Item | Value
SQLCODE | –141
Constant | SQLE_TABLE_NOT_FOUND
SQLSTATE | 42W33
Sybase error code | 2706
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the table that could not be found.
Probable cause

You misspelled the name of a table, or you did not qualify a table name with a user name. For example, you might have referred to employee instead of "DBA".employee,


Table '%1' requires a unique correlation name

Item | Value
SQLCODE | –137
Constant | SQLE_CORRELATION_NAME_NEEDED
SQLSTATE | 52W15
Sybase error code | 315
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the table that needs a unique correlation name.
Probable cause

You specified a join that joins a table to itself. You need to use unique correlation names in order to have multiple instances of a table.


Table already has a primary key

Item | Value
SQLCODE | –112
Constant | SQLE_EXISTING_PRIMARY_KEY
SQLSTATE | 55013
Sybase error code | 1923
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You attempted to add a primary key on a table that already has a primary key defined. You must delete the current primary key before adding a new one.


Table cannot have two primary keys

Item | Value
SQLCODE | –126
Constant | SQLE_PRIMARY_KEY_TWICE
SQLSTATE | 52W05
Sybase error code | 1923
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You specified the primary key twice in a CREATE TABLE statement.


Table in use

Item | Value
SQLCODE | –214
Constant | SQLE_TABLE_IN_USE
SQLSTATE | 42W21
Sybase error code | 3702
ODBC 2 State | 40001
ODBC 3 State | 40001
Probable cause

You attempted to ALTER or DROP a table that is being used by other active users of the database.


Table must be empty

Item | Value
SQLCODE | –116
Constant | SQLE_TABLE_MUST_BE_EMPTY
SQLSTATE | 55W02
Sybase error code | 4901
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted to modify a table, and the database server can only perform the change if there are no rows in the table.


Table name '%1' is ambiguous

Item | Value
SQLCODE | –852
Constant | SQLE_AMBIGUOUS_TABLE_NAME
SQLSTATE | 52W42
Sybase error code | 13856
ODBC 2 State | S0013
ODBC 3 State | 42S13
Parameter 1 | Name of an ambiguous table.
Probable cause

A statement has referred to a table name which is not unique. Preface the table name by an owner name.


Tables related by key constraint must both be permanent or both be temporary created with ON COMMIT PRESERVE ROWS

Item | Value
SQLCODE | –850
Constant | SQLE_INVALID_FOREIGN_KEY_TABLE
SQLSTATE | 42R02
Sybase error code | 1709
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

Tables involved in a key constraint relationship must both be permanent user tables or both be temporary tables created with ON COMMIT PRESERVE ROWS. Change the definition of one or both tables using ALTER TABLE.


Temporary space limit exceeded

Item | Value
SQLCODE | –1000
Constant | SQLE_TEMP_SPACE_LIMIT
SQLSTATE | 54W05
Sybase error code | 13492
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The connection has exceeded its temporary-space usage limit. This limit is based in part on the amount of free-space remaining on the drive containing the temporary file. Try deleting unused files from the drive, or placing the temporary file on a drive with more space available.


Terminated by user -- transaction rolled back

Item | Value
SQLCODE | –302
Constant | SQLE_TERMINATED_BY_USER
SQLSTATE | 40W02
Sybase error code | 3618
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You canceled a statement while the database was executing. A ROLLBACK WORK statement has been automatically executed.


The %1 attribute '%2' is not valid

Item | Value
SQLCODE | –991
Constant | SQLE_INVALID_PROCEDURE_ATTRIBUTE
SQLSTATE | WW060
Sybase error code | 13498
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The attribute on the procedure
Parameter 2 | The value of the attribute
Probable cause

The attribute value specified on the procedure is not valid.


The aggregate expression '%1' must appear in either the select list or a HAVING clause subquery

Item | Value
SQLCODE | –862
Constant | SQLE_INVALID_AGGREGATE_PLACEMENT
SQLSTATE | 42W69
Sybase error code | 13866
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | The aggregated expression in error.
Probable cause

An aggregated expression containing an outer reference must either appear in a select list expression (a subselect), or in a HAVING clause subquery in the query whose FROM clause contains the table with the column being aggregated.


The column '%1' does not exist in the remote table

Item | Value
SQLCODE | –722
Constant | SQLE_OMNI_NOSUCH_COLUMN
SQLSTATE | WO016
Sybase error code | 11208
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the column.
Probable cause

The column specified in the 'CREATE EXISTING' statement does not exist in the remote table.


The communications environment could not be created

Item | Value
SQLCODE | –740
Constant | SQLE_FAILED_TO_CREATE_STREAMS_ENV
SQLSTATE | WW024
Sybase error code | 13753
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The communications environment could not be created. Either there are insufficient resources to create the environment or the language resource file cannot be found.


The connection parameters file could not be found

Item | Value
SQLCODE | –654
Constant | SQLE_NO_PROFILE_FILE
SQLSTATE | 08W37
Sybase error code | 13706
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

An attempt was made to parse a connection string containing a connection profile but the connection parameters file could not be found.


The cursor name '%1' already exists

Item | Value
SQLCODE | –683
Constant | SQLE_DUPLICATE_CURSOR_NAME
SQLSTATE | WJ004
Sybase error code | 13714
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the cursor
Probable cause

You attempted to declare a cursor with a name that already exists. Cursor names must be unique within a connection.


The data type of column '%1' is not supported

Item | Value
SQLCODE | –736
Constant | SQLE_OMNI_UNSUPPORTED_DATATYPE
SQLSTATE | WO022
Sybase error code | 11205
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the column.
Probable cause

The column is defined with a data type that is not supported for remote tables.


The data type specified for column '%1' is not compatible with the actual data type

Item | Value
SQLCODE | –721
Constant | SQLE_OMNI_DATATYPE_MISMATCH
SQLSTATE | WO015
Sybase error code | 11209
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the column.
Probable cause

The data type of the column specified in the 'CREATE EXISTING' statement is not compatible with the actual data type of the column in the remote table.


The database '%1' was not found

Item | Value
SQLCODE | –954
Constant | SQLE_ULTRALITE_DATABASE_NOT_FOUND
SQLSTATE | WW034
Sybase error code | 13534
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the database specified or the default database name.
Probable cause

The named database was not found. Ensure your connection string properly names the desired database.


The database does not support the Java virtual machine

Item | Value
SQLCODE | –758
Constant | SQLE_NO_JAVA_SUPPORT
SQLSTATE | WJ022
Sybase error code | 13769
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The Java virtual machine could not be started because the database does not have the proper support. It may be that the database was created with an older version of the software, or was created with the Java support disabled. If the database was created with an older version of the software the database should be upgraded to the most recent version. If the database was created with Java support disabled, then the instjava.sql script should be run against the database to enable Java support.


The database needs to be restarted for this Java related command

Item | Value
SQLCODE | –871
Constant | SQLE_JAVA_DB_RESTART_NEEDED
SQLSTATE | WJ029
Sybase error code | 13875
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Java support in the database requires a database restart after some Java related commands are performed, e.g. some Java commands like Alter Database Upgrade Java On require a restart before one performs any Java related commands that load a Java class into the database.


The database was created.

Item | Value
SQLCODE | 136
Constant | SQLE_DATABASE_CREATED
SQLSTATE | WW061
Sybase error code | 13494
ODBC 2 State | OK
ODBC 3 State | OK
Probable cause

The specified UltraLite database was created using the specified schema when the connection was opened.


The external function call is incompatible

Item | Value
SQLCODE | –818
Constant | SQLE_INCOMPATIBLE_EXTERNAL_CALL
SQLSTATE | WW026
Sybase error code | 13824
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted to call an external function. An attempt to load the attempted library failed because of incompatibility with the server. Incompatibility may arise because the dynamic library is using an external function API that is either not supported by the server or is newer than the one supported by the server.


The integrated login ID guest can only be mapped to the guest database user ID

Item | Value
SQLCODE | –247
Constant | SQLE_INTEGRATED_LOGON_GUESTMAP
SQLSTATE | 28W06
Sybase error code | 13695
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

You attempted to map the guest login ID to something other than guest


The JDBC resultset must be positioned on an insert row in order to use the '%1' function

Item | Value
SQLCODE | –753
Constant | SQLE_JDBC_MUST_OPER_ON_INSERT_ROW
SQLSTATE | WJ020
Sybase error code | 13764
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the resultset function being called
Probable cause

Resultset functions such as 'insertRow' can only be called when the resultset is positioned on the insert row.


The JDK version in '%1' does not match '%2'

Item | Value
SQLCODE | –841
Constant | SQLE_JDK_VERSION_MISMATCH
SQLSTATE | WJ026
Sybase error code | 13847
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | A JDK jar file name
Parameter 2 | A JDK version string
Probable cause

The JDK version specified in the 'create database' statement does not match the JDK version in the JDK jar file.


The length specified for column '%1' is different than the actual length

Item | Value
SQLCODE | –723
Constant | SQLE_OMNI_LENGTH_MISMATCH
SQLSTATE | WO017
Sybase error code | 11210
ODBC 2 State | OK
ODBC 3 State | OK
Parameter 1 | The name of the column.
Probable cause

The length of the column specified in the 'CREATE EXISTING' statement is different than the length of the column in the remote table.


The login ID '%1' has not been mapped to any database user ID

Item | Value
SQLCODE | –313
Constant | SQLE_INTEGRATED_LOGON_UNMAPPED
SQLSTATE | 28W09
Sybase error code | 13698
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

You attempted to drop a login ID that had not been mapped yet


The login ID '%1' is already mapped to user ID '%2'

Item | Value
SQLCODE | –249
Constant | SQLE_INTEGRATED_LOGON_MAPPED
SQLSTATE | 28W08
Sybase error code | 13697
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

You attempted to map a login ID twice


The optimizer was unable to construct a valid access plan

Item | Value
SQLCODE | –727
Constant | SQLE_CANNOT_OPTIMIZE_QUERY
SQLSTATE | WI010
Sybase error code | 13730
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The database server was unable to construct a valid access plan for the given request. This is an Adaptive Server Anywhere internal error. If it can be reproduced, it should be reported to iAnywhere Solutions. You may be able to work around this problem by modifying the query statement.


The option '%1' can only be set as a temporary option

Item | Value
SQLCODE | –216
Constant | SQLE_OPTION_IS_TEMP_ONLY
SQLSTATE | 42W52
Sybase error code | 5878
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

The option specified in the SET OPTION statement can only be set as a temporary option.


The option '%1' cannot be set from within a procedure

Item | Value
SQLCODE | –217
Constant | SQLE_OPTION_IN_PROCEDURE
SQLSTATE | 42W53
Sybase error code | 5878
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

The option specified in the SET OPTION statement cannot be set from within a procedure.


The option '%1' is not recognized.

Item | Value
SQLCODE | –1002
Constant | SQLE_UNRECOGNIZED_OPTION
SQLSTATE | WW062
Sybase error code | 13494
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the option.
Probable cause

The specified option was not recognized. The option may have been spelled incorrectly.


The pattern is too long

Item | Value
SQLCODE | –606
Constant | SQLE_PATTERN_TOO_LONG
SQLSTATE | WW001
Sybase error code | 7706
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The pattern for the LIKE operator is too long. All patterns of 126 characters or less are supported. Some patterns as long as 254 characters are supported, depending on their contents. Patterns longer than 254 characters are not supported.


The remote server does not support an auto-incrementing data type

Item | Value
SQLCODE | –698
Constant | SQLE_OMNI_AUTOINC_NOT_SUPPORTED
SQLSTATE | WO011
Sybase error code | 11205
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Auto-incrementing data types can only be supported in a proxy table when the backend server supports this feature.


The remote table '%1' could not be found

Item | Value
SQLCODE | –666
Constant | SQLE_OMNI_RMT_TABLE_NOTFOUND
SQLSTATE | WO007
Sybase error code | 11214
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The complete name of the remote table
Probable cause

The table could not be found on the remote server. Check the remote table name and the user privileges on that table.


The result returned is non-deterministic.

Item | Value
SQLCODE | 122
Constant | SQLE_NONDETERMINISTIC_RESULT
SQLSTATE | 01W18
Sybase error code | 13883
ODBC 2 State | 01000
ODBC 3 State | 01000
Probable cause

FIRST or TOP n are used in a SELECT statement to limit the size of a result. The statement must also have an ORDER BY if the result is to be well-defined. If it does not have an ORDER BY, then the server is free to return any subset of the result that has the requested number of rows.


The secure connection to the remote host failed

Item | Value
SQLCODE | –990
Constant | SQLE_SECURE_CONNECTION_FAILED
SQLSTATE | WW059
Sybase error code | 13499
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The server was unable to initiate a secure connection with the remote host.


The Select list for the derived table '%1' has no expression to match '%2'

Item | Value
SQLCODE | –812
Constant | SQLE_NO_MATCHING_SELECT_ITEM
SQLSTATE | 42W59
Sybase error code | 13822
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the derived table.
Parameter 2 | Name of the alias for which there is no matching expression.
Probable cause

The specified alias from the derived table's AS clause has no matching expression from the Select statement for that derived table. Ensure that each Select list item has a matching alias in the derived table's AS clause, and vice-versa.


The selected database is currently inactive

Item | Value
SQLCODE | –74
Constant | SQLE_DATABASE_NOT_ACTIVE
SQLSTATE | 08W30
Sybase error code | 950
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

The selected database is in an inactive state. The database may be in the process of being started or of being shut down.


The server attempted to access a page beyond the end of the maximum allowable dbspace file size

Item | Value
SQLCODE | –605
Constant | SQLE_ACCESS_BEYOND_END_OF_MAX_DBSPACE
SQLSTATE | 04W08
Sybase error code | 5006
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The database attempted to access a page whose page number is beyond the maximum possible number of disk pages. This is a fatal internal error.


The specified foreign key (%1) can not be enforced

Item | Value
SQLCODE | –729
Constant | SQLE_UNENFORCEABLE_FOREIGN_KEY
SQLSTATE | 23507
Sybase error code | 549
ODBC 2 State | 23000
ODBC 3 State | 23000
Parameter 1 | Name of the foreign key.
Probable cause

You attempted to create a foreign key that can not be enforced. In order to enforceable, the primary and foreign table for the specified key must exist on the same server. You can use the 'unenforced' keyword to create a foreign key specification that is not to be enforced.


The specified listener could not be registered

Item | Value
SQLCODE | –992
Constant | SQLE_CANNOT_REGISTER_LISTENER
SQLSTATE | 54W04
Sybase error code | 13497
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The specified listener could not be registered because the maximum number of listeners has been reached, the class name is already in use, or system resources are not available.


The specified transaction isolation is invalid

Item | Value
SQLCODE | –676
Constant | SQLE_INVALID_TRANSACTION_ISOLATION
SQLSTATE | WJ003
Sybase error code | 7374
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The specified transaction isolation is invalid.


The status of the last synchronization upload is unknown

Item | Value
SQLCODE | –952
Constant | SQLE_SYNC_STATUS_UNKNOWN
SQLSTATE | WW032
Sybase error code | 13536
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The status of the last synchronization upload is unknown. The current operation cannot proceed until a successful upload is synchronized.


The string is too long (%1)

Item | Value
SQLCODE | –973
Constant | SQLE_STRING_PARM_TOO_LONG
SQLSTATE | 28000
Sybase error code | 13515
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

The string is longer than that allowed by the server.


The table specification '%1' identifies more than one remote table

Item | Value
SQLCODE | –726
Constant | SQLE_OMNI_RMT_TABLE_NOTUNIQUE
SQLSTATE | WO020
Sybase error code | 11215
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The complete name of the remote table
Probable cause

More than one table was found on the remote server for the given table specification. Add a database or owner name to the specification.


The URI '%1' is invalid

Item | Value
SQLCODE | –980
Constant | SQLE_INVALID_URI
SQLSTATE | WW049
Sybase error code | 13509
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The invalid URI
Probable cause

The specified URI is not valid.


There are still active database connections

Item | Value
SQLCODE | –109
Constant | SQLE_STILL_ACTIVE_CONNECTIONS
SQLSTATE | 08W06
Sybase error code | 6001
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted to shut down a database which still has active connections.


There is already a variable named '%1'

Item | Value
SQLCODE | –261
Constant | SQLE_VARIABLE_EXISTS
SQLSTATE | 42W15
Sybase error code | 134
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to CREATE a variable with the name of another variable that already exists.


There is more than one way to join '%1' to '%2'

Item | Value
SQLCODE | –147
Constant | SQLE_AMBIGUOUS_JOIN
SQLSTATE | 52W08
Sybase error code | 301
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of first table that cannot be joined.
Parameter 2 | Name of second table that cannot be joined.
Probable cause

You are attempting to KEY JOIN two tables, and there are two or more foreign keys relating the two tables. There may be two foreign keys from the first table to the second table It may be that each table has a foreign key to the other table. You must use a correlation name for the primary key table which is the same as the role name of the desired foreign key relationship.


There is no way to join '%1' to '%2'

Item | Value
SQLCODE | –146
Constant | SQLE_CANNOT_JOIN
SQLSTATE | 53W04
Sybase error code | 301
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of first table that cannot be joined.
Parameter 2 | Name of second table that cannot be joined.
Probable cause

You may have attempted a KEY JOIN between two tables and there is no foreign key on one of the tables that references the primary key of the other table. You may have attempted a NATURAL JOIN between two tables that have no common column names.


There is no way to join to '%1'

Item | Value
SQLCODE | –875
Constant | SQLE_CANNOT_JOIN_TABEXPR
SQLSTATE | 42W73
Sybase error code | 102
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of table or view that cannot be joined.
Probable cause

The server cannot discover a valid join condition involving this table. If the join is an outer join, you may be missing an ON clause. If the join is a KEY JOIN, the server cannot discover a foreign key-primary key relationship with this table that can be used to generate the join condition. If the join is a NATURAL JOIN, the table has no common column names with the table expression it is being joined to.


This connection already exists

Item | Value
SQLCODE | –955
Constant | SQLE_CONNECTION_ALREADY_EXISTS
SQLSTATE | WW035
Sybase error code | 13533
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A connection with the given SQLCA and name (or no name) already exists. Before connecting you must disconnect the existing connection, or specify a different connection name.


TLS handshake failure

Item | Value
SQLCODE | –829
Constant | SQLE_TLS_HANDSHAKE_FAILED
SQLSTATE | 08W59
Sybase error code | 13835
ODBC 2 State | 08S01
ODBC 3 State | 08S01
Probable cause

The connection failed because of a failure in the TLS handshaking process.


TLS initialization on server failed

Item | Value
SQLCODE | –838
Constant | SQLE_TLS_INIT_FAILED_ON_SRV
SQLSTATE | 08W61
Sybase error code | 13844
ODBC 2 State | 08S01
ODBC 3 State | 08S01
Probable cause

The connection failed because the initialization of the TLS library on the server failed.


Too few columns

Item | Value
SQLCODE | –902
Constant | SQLE_FOR_XML_EXPLICIT_TOO_FEW_COLUMNS
SQLSTATE | WX010
Sybase error code | 13581
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

FOR XML EXPLICIT requires at least three columns: the tag column, the parent column, and one or more data columns.


Too many arguments for function or procedure '%1'

Item | Value
SQLCODE | –994
Constant | SQLE_TOO_MANY_ARGUMENTS
SQLSTATE | 42WAC
Sybase error code | 401
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | The name of the function or procedure.
Probable cause

You supplied an argument list which the database server cannot handle. This can happen if the argument list of the function or stored procedure is too long. Rebuilding the database with a larger page size could prevent this error.


Too many columns in table

Item | Value
SQLCODE | –616
Constant | SQLE_TOO_MANY_COLUMNS_IN_TABLE
SQLSTATE | 52W20
Sybase error code | 1702
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You executed a CREATE TABLE or ALTER TABLE statement, which attempted to add a column to a table. The resulting number of columns in the table would exceed the limit for the current database page size.


too many constraints in database

Item | Value
SQLCODE | –936
Constant | SQLE_TOO_MANY_CONSTRAINTS
SQLSTATE | 54W02
Sybase error code | 13551
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An attempt to create a new constraint failed because the SYSCONSTRAINT table is full. If the SYSCONSTRAINT table has a number of unused slots, then reloading the database will reclaim unused space.


Too many distinct group mappings for integrated user

Item | Value
SQLCODE | –1003
Constant | SQLE_INTEGRATED_LOGON_TOO_MANY_MAPPINGS
SQLSTATE | 28W10
Sybase error code | 13490
ODBC 2 State | 28000
ODBC 3 State | 28000
Probable cause

The integrated user does not have an explicit mapping in the database but does have group mappings. There are unfortunately too many distinct group mappings. You must either reduce the number of distinct group mappings or add an explicit mapping for the user.


Too many expressions in GROUP BY list for ROLLUP, CUBE, or GROUPING SETS operation.

Item | Value
SQLCODE | –944
Constant | SQLE_TOO_MANY_GROUPING_EXPRESSIONS
SQLSTATE | 42WA1
Sybase error code | 13544
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You specified too many expressions in the GROUP BY list for the requested ROLLUP, CUBE, or GROUPING SETS operation. The current environment where Adaptive Server Anywhere is executing cannot support this number of expressions in the GROUP BY list for the requested operation.


Too many parameters to this external procedure call

Item | Value
SQLCODE | –625
Constant | SQLE_TOO_MANY_PARAMETERS
SQLSTATE | WW010
Sybase error code | 13680
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

There is a maximum of 256 parameters to an external function call in 32-bit Windows.


Too many recursive iterations

Item | Value
SQLCODE | –923
Constant | SQLE_TOO_MANY_RECURSIVE_ITERATIONS
SQLSTATE | 57015
Sybase error code | 13561
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A recursive query ran for more iterations than allowed by the current MAX_RECURSIVE_ITERATIONS option setting.


too many temporary tables in connection

Item | Value
SQLCODE | –817
Constant | SQLE_TOO_MANY_TEMP_TABLES
SQLSTATE | 52W41
Sybase error code | 13823
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A CREATE TABLE or DECLARE TABLE statement attempted to create a temporary table, but the resulting number of distinct table ids used for temporary tables in the current connection would exceed the limit.


Transaction log backup page only partially full

Item | Value
SQLCODE | 110
Constant | SQLE_BACKUP_PAGE_INCOMPLETE
SQLSTATE | 01W10
Sybase error code | 13683
ODBC 2 State | OK
ODBC 3 State | OK
Probable cause

A DB_LOG_BACKUP_READ_WAIT was issued against the transaction log and the page returned was not full. The application should reissue the request for the same page.


Transaction log was truncated

Item | Value
SQLCODE | –244
Constant | SQLE_LOG_TRUNCATED
SQLSTATE | WB005
Sybase error code | 13661
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

An operation was being performed on the transaction log such as SQL Remote or Replication Agent processing and the transaction log was truncated by an independent backup during that operation.


Transact-SQL feature not supported

Item | Value
SQLCODE | –611
Constant | SQLE_TSQL_FEATURE_NOT_SUPPORTED
SQLSTATE | 0AW02
Sybase error code | 176
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to use a Transact-SQL feature that is not supported in Adaptive Server Anywhere.


Trigger '%1' not found

Item | Value
SQLCODE | –268
Constant | SQLE_TRIGGER_NOT_FOUND
SQLSTATE | 52W10
Sybase error code | 9819
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the trigger that could not be found.
Probable cause

You misspelled the name of a trigger, or you did not qualify a trigger name with a user name.


Trigger definition conflicts with existing triggers

Item | Value
SQLCODE | –271
Constant | SQLE_TRIGGER_DEFN_CONFLICT
SQLSTATE | 52W11
Sybase error code | 102
ODBC 2 State | S0002
ODBC 3 State | 42S01
Probable cause

You attempted to create a trigger, but a trigger with the same name already exists.


Trigger name '%1' is ambiguous

Item | Value
SQLCODE | –855
Constant | SQLE_AMBIGUOUS_TRIGGER_NAME
SQLSTATE | 42W66
Sybase error code | 13858
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the ambiguous trigger.
Probable cause

A statement has referred to a trigger name which is not unique. Preface the trigger name by a table and/or owner name.


Trigger or foreign key for table '%1' is no longer valid

Item | Value
SQLCODE | –837
Constant | SQLE_TRIGGER_NO_LONGER_VALID
SQLSTATE | 42W64
Sybase error code | 13843
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the table.
Probable cause

A trigger definition cannot be loaded from the catalog. Check for tables or columns which have been renamed or which may be reserved words. The trigger may be a system-generated trigger to enforce the referential actions of a foreign key.


Triggers and procedures not supported in runtime server

Item | Value
SQLCODE | –275
Constant | SQLE_PROCEDURES_NOT_IN_DESKTOP
SQLSTATE | 0AW04
Sybase error code | 102
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted to call a stored procedure or have modified a row in a table on which a trigger is defined and you are using the runtime server. Triggers and stored procedures are not supported in the runtime server. You must be running the full server to use these features.


TRUNCATE TABLE statement cannot refer to a view

Item | Value
SQLCODE | –702
Constant | SQLE_CANNOT_TRUNCATE_VIEW
SQLSTATE | 42W49
Sybase error code | 4708
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to use TRUNCATE TABLE on a view. The TRUNCATE TABLE statement deletes every row from a table and cannot be used to delete rows from a view. Replace the view reference with the name of a base table.


UltraLite connection was restored

Item | Value
SQLCODE | 133
Constant | SQLE_CONNECTION_RESTORED
SQLSTATE | WW040
Sybase error code | 13519
ODBC 2 State | OK
ODBC 3 State | OK
Probable cause

The connection attempt completed successfully and the transaction was restored from a suspended state.


UltraLite cursor (or result set or table) was restored

Item | Value
SQLCODE | 134
Constant | SQLE_CURSOR_RESTORED
SQLSTATE | WW041
Sybase error code | 13518
ODBC 2 State | OK
ODBC 3 State | OK
Probable cause

The cursor (or result set or table) was opened successfully and the cursor position was restored from the suspended state.


UltraLite runtime library is incompatible with the database file

Item | Value
SQLCODE | –977
Constant | SQLE_ULTRALITE_RUNTIME_LIBRARY_MISMATCH
SQLSTATE | WW046
Sybase error code | 13512
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The UltraLite runtime library linked with the application is incompatible with the UltraLite database file being opened. Most likely a unicode/ansi mismatch.


Unable to connect to server '%1': %2

Item | Value
SQLCODE | –656
Constant | SQLE_OMNI_CONNECT_ERROR
SQLSTATE | WO001
Sybase error code | 11206
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the server that could not be connected to
Parameter 2 | A more specific reason returned from the server class driver.
Probable cause

You attempted to connect to a remote server. Check that the remote server is running.


Unable to connect to server '%1': server definition is circular

Item | Value
SQLCODE | –657
Constant | SQLE_OMNI_CIRCULAR_CONNECT
SQLSTATE | WO002
Sybase error code | 13593
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The name of the server that could not be connected to
Probable cause

You attempted to connect to a remote server which maps to the local database.


Unable to connect to the remote host specified by '%1'

Item | Value
SQLCODE | –981
Constant | SQLE_UNABLE_TO_CONNECT_TO_HOST
SQLSTATE | WW050
Sybase error code | 13508
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The URI referencing the remote host
Probable cause

A connection could not be initiated to the remote server.


Unable to delete database file

Item | Value
SQLCODE | –243
Constant | SQLE_BACKUP_UNABLE_TO_DELETE_FILE
SQLSTATE | WB004
Sybase error code | 13660
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You attempted to delete a database file, but it could not be deleted. The filename should not be the same as any database file that is currently in use.


Unable to enlist transaction; DTC may be down

Item | Value
SQLCODE | –803
Constant | SQLE_FAILED_TO_ENLIST
SQLSTATE | WL005
Sybase error code | 13813
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You tried to enlist a transaction but DTC does not seem to be available at this time.


Unable to find in index '%1' for table '%2'

Item | Value
SQLCODE | –189
Constant | SQLE_NOT_FOUND_IN_INDEX
SQLSTATE | WI005
Sybase error code | 2727
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of invalid index.
Parameter 2 | Name of table containing the invalid index.
Probable cause

This is an internal error. If it can be reproduced, it should be reported to iAnywhere Solutions. You should be able to work around the error by dropping and recreating the index.


Unable to open backup log '%1'

Item | Value
SQLCODE | 119
Constant | SQLE_UNABLE_TO_OPEN_BACKUP_LOG
SQLSTATE | WB011
Sybase error code | 13776
ODBC 2 State | OK
ODBC 3 State | OK
Parameter 1 | backup log filename
Probable cause

The server was unable to open the backup log to record the execution of a BACKUP or RESTORE statement. Check the settings of the environment variables used to locate the backup log file. The directory to contain the log must already exist.


Unable to reenlist transaction; DTC may be down

Item | Value
SQLCODE | –804
Constant | SQLE_FAILED_TO_REENLIST
SQLSTATE | WL006
Sybase error code | 13814
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You tried to recover a transaction but DTC does not seem to be available at this time.


Unable to start database server

Item | Value
SQLCODE | –80
Constant | SQLE_UNABLE_TO_START_ENGINE
SQLSTATE | 08W07
Sybase error code | 708
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

It was not possible to start the database server. There may not be enough memory to run the database server. It may be that the executable cannot be found.


Unable to start specified database: %1

Item | Value
SQLCODE | –82
Constant | SQLE_UNABLE_TO_START_DATABASE
SQLSTATE | 08W09
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | Reason the database could not be started, if known.
Probable cause

The database server was unable to start the specified database. If you got this error while trying to autostart a server and database, try starting the server and database manually since the server window may provide more details.


Unable to start specified database: '%1' found, but database not found

Item | Value
SQLCODE | –1013
Constant | SQLE_NO_DB_FOR_WRITE
SQLSTATE | 08W77
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the write file.
Probable cause

The database for the specified write file was not found.


Unable to start specified database: '%1' is an invalid transaction log

Item | Value
SQLCODE | –1007
Constant | SQLE_CORRUPT_REDO
SQLSTATE | 08W88
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the transaction log file.
Probable cause

The specified file is not a valid transaction log.


Unable to start specified database: '%1' is an invalid transaction log mirror

Item | Value
SQLCODE | –1008
Constant | SQLE_CORRUPT_REDO_MIRROR
SQLSTATE | 08W72
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the transaction log mirror file.
Probable cause

The specified file is not a valid transaction log mirror.


Unable to start specified database: '%1' is compressed -- use a write file or open in read-only mode

Item | Value
SQLCODE | –1014
Constant | SQLE_FILE_IS_COMPRESSED
SQLSTATE | 08W78
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the database file.
Probable cause

You attempted to start a compressed database file for update. Use a write file or start the database in read-only mode.


Unable to start specified database: '%1' is not a database

Item | Value
SQLCODE | –1004
Constant | SQLE_FILE_NOT_DB
SQLSTATE | 08W85
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the database file.
Probable cause

The specified file is not a valid database file.


Unable to start specified database: '%1' is not a valid database file

Item | Value
SQLCODE | –1006
Constant | SQLE_FILE_BAD_DB
SQLSTATE | 08W87
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the database file.
Probable cause

The specified file is not a valid database.


Unable to start specified database: '%1' must be upgraded to start with this server (capability %2 missing).

Item | Value
SQLCODE | –1012
Constant | SQLE_UPGRADE_DATABASE
SQLSTATE | 08W76
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the database file.
Parameter 2 | The capability that is missing from the database file.
Probable cause

The specified database must be upgraded to start with this server.


Unable to start specified database: '%1' not expecting any operations in transaction log

Item | Value
SQLCODE | –1010
Constant | SQLE_EXPECTING_NO_REDO
SQLSTATE | 08W74
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the transaction log file.
Probable cause

The transaction log contains operations, which is not expected by the database file.


Unable to start specified database: '%1' was created by a different version of the software

Item | Value
SQLCODE | –1005
Constant | SQLE_FILE_WRONG_VERSION
SQLSTATE | 08W86
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the database file.
Probable cause

The specified database file was created by a different version of the software, and it can not be read by this version.


Unable to start specified database: '%1': transaction log file not found

Item | Value
SQLCODE | –1017
Constant | SQLE_LOG_NOT_FOUND
SQLSTATE | 08W81
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the transaction log file.
Probable cause

The transaction log file was not found.


Unable to start specified database: Can't use log file '%1' since it has been used more recently than the database file

Item | Value
SQLCODE | –1016
Constant | SQLE_LOG_NEWER_THAN_DB
SQLSTATE | 08W80
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the transaction log mirror file.
Probable cause

The transaction log file has been used more recently than the database file.


Unable to start specified database: Can't use log file '%1' since it is shorter than expected

Item | Value
SQLCODE | –1020
Constant | SQLE_LOG_TOO_SHORT
SQLSTATE | 08W84
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the transaction log file.
Probable cause

The transaction log file is shorter than expected.


Unable to start specified database: Can't use log file '%1' since the database file has been used more recently

Item | Value
SQLCODE | –1019
Constant | SQLE_LOG_OLDER_THAN_DB
SQLSTATE | 08W83
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the transaction log file.
Probable cause

The database file has been used more recently than the transaction log file.


Unable to start specified database: Can't use log file '%1' since the offsets don't match the offsets in the database file

Item | Value
SQLCODE | –1018
Constant | SQLE_LOG_OFFSETS_DONT_MATCH
SQLSTATE | 08W82
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the transaction log file.
Probable cause

The transaction log file has an offset that does not match the offset expected by the database file.


Unable to start specified database: Log file error

Item | Value
SQLCODE | –935
Constant | SQLE_UNABLE_TO_START_DATABASE_LOG_ERROR
SQLSTATE | 08W68
Sybase error code | 13553
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

The database server was unable to start the database since the log file is missing, for a different database, or some other reason. If you try starting the database manually, the server window may provide more details.


Unable to start specified database: Server must be upgraded to start database %1

Item | Value
SQLCODE | –934
Constant | SQLE_UNABLE_TO_START_DATABASE_VER_NEWER
SQLSTATE | 08W67
Sybase error code | 13552
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | Name of the database which could not be started, if known.
Probable cause

The database server was unable to start the database since the database version is newer than the server version. The server must be upgraded to at least the version of the database to be able to start the database.


Unable to start specified database: The database for write file '%1' has an incorrect modification time

Item | Value
SQLCODE | –1015
Constant | SQLE_OLD_WRITE
SQLSTATE | 08W79
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the write file.
Probable cause

The database for the specified write file has a modification time that does not match the time expected by the write file.


Unable to start specified database: The transaction log '%1' or its mirror '%2' is invalid

Item | Value
SQLCODE | –1009
Constant | SQLE_CORRUPT_REDO_OR_MIRROR
SQLSTATE | 08W73
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Parameter 1 | The name of the transaction log file.
Parameter 2 | The name of the transaction log mirror file.
Probable cause

The transaction log differs from the transaction log mirror. Either the transaction log or its mirror is invalid.


Unable to start specified database: Unknown encryption algorithm.

Item | Value
SQLCODE | –1011
Constant | SQLE_UNKNOWN_ENCRYPTION_ALGORITHM
SQLSTATE | 08W75
Sybase error code | 840
ODBC 2 State | 08001
ODBC 3 State | 08001
Probable cause

The database is encrypted with an algorithm not supported by this server.


Undeclared tag id: '%1'

Item | Value
SQLCODE | –901
Constant | SQLE_UNDECLARED_FOR_XML_EXPLICIT_TAG
SQLSTATE | WX009
Sybase error code | 13580
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The value of the undeclared tag id
Probable cause

Every value appearing in the Tag column of the table must be declared in the TagNumber field of at least one column name.


Undefined synchronization template '%1'

Item | Value
SQLCODE | –795
Constant | SQLE_SYNC_TEMPLATE_NOT_FOUND
SQLSTATE | 5RW30
Sybase error code | 13805
ODBC 2 State | 42000
ODBC 3 State | 42S02
Parameter 1 | The name of the synchronization template
Probable cause

You attempted to define a remote synchronization site using an undefined synchronization template.


Unknown backup operation

Item | Value
SQLCODE | –240
Constant | SQLE_UNKNOWN_BACKUP_OPERATION
SQLSTATE | WB001
Sybase error code | 3206
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

You specified an invalid backup statement operation in a call to db_backup.


Unknown FOR XML EXPLICIT directive: '%1'

Item | Value
SQLCODE | –898
Constant | SQLE_BAD_FOR_XML_EXPLICIT_DIRECTIVE
SQLSTATE | WX006
Sybase error code | 13583
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The unknown directive
Probable cause

Legal FOR XML EXPLICIT directives are: id, idref, idrefs, hide, element, xml, cdata.


Unknown function '%1'

Item | Value
SQLCODE | –148
Constant | SQLE_UNKNOWN_FUNC
SQLSTATE | 42W05
Sybase error code | 176
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Function name that is not a database function.
Probable cause

You misspelled the name of a database function (such as MAXIMUM instead of MAX) in a query definition or in a query column name.


UNLOAD TABLE cannot be used to unload a view

Item | Value
SQLCODE | –643
Constant | SQLE_CANNOT_UNLOAD_A_VIEW
SQLSTATE | WL004
Sybase error code | 13672
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

UNLOAD TABLE was specified with the name of a view. UNLOAD TABLE may only be used to unload tables.


Unsupported character set '%1' and unsupported language '%2'; language used is '%3' instead

Item | Value
SQLCODE | 117
Constant | SQLE_UNSUPPORTED_CHARSET_AND_LANGUAGE
SQLSTATE | 01W15
Sybase error code | 13616
ODBC 2 State | 01000
ODBC 3 State | 01000
Parameter 1 | Name of the character set that could not be supported.
Parameter 2 | Name of the language that could not be supported.
Parameter 3 | Name of the language that the server will use to send language strings.
Probable cause

The character set that the application requested is not supported by the server to which the application is connecting. The language that the application requested is not supported either. Language strings will be sent in the language specified.


Unsupported property '%1' in service USING attribute

Item | Value
SQLCODE | –1024
Constant | SQLE_SERVICE_PARM_UNSUPPORTED_PROPERTY
SQLSTATE | 42WAF
Sybase error code | 13486
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the unsupported property.
Probable cause

The service definition contains a USING attribute with an unsupported property.


Unterminated C string

Item | Value
SQLCODE | –634
Constant | SQLE_UNTERMINATED_C_STR
SQLSTATE | 22024
Sybase error code | 13682
ODBC 2 State | 22024
ODBC 3 State | 22024
Probable cause

The least significant character of a C string host variable must contain the null character.


Update operation attempted on a read-only cursor

Item | Value
SQLCODE | –633
Constant | SQLE_READ_ONLY_CURSOR
SQLSTATE | 42W30
Sybase error code | 7732
ODBC 2 State | S1009
ODBC 3 State | HY092
Probable cause

You attempted an update operation on a cursor that was explicitly declared as read-only.


Update operation attempted on non-updatable query

Item | Value
SQLCODE | –192
Constant | SQLE_NON_UPDATEABLE_VIEW
SQLSTATE | 42W31
Sybase error code | 7301
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You attempted an insert, update, or delete operation on a query that is implicitly read-only. Queries that contain DISTINCT, GROUP BY, HAVING, EXCEPT, INTERSECT or UNION, or that contain aggregate functions, or that involve a join, are implicitly read only. If the query references a view then the view may be non-updatable.


Update operation attempted on non-updatable remote query

Item | Value
SQLCODE | –728
Constant | SQLE_NON_UPDATEABLE_EXT_TAB
SQLSTATE | 42W35
Sybase error code | 7338
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

You attempted an update, or delete operation on a remote table that is currently not implemented. Examples of such operations include positioned updates and updates that require building of work tables.


User '%1' already has EXECUTE permission

Item | Value
SQLCODE | –968
Constant | SQLE_ALREADY_HAS_EXEC_PERMS
SQLSTATE | 42WAB
Sybase error code | 13522
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the user ID that already has EXECUTE permission.
Probable cause

You attempted to give a user EXECUTE permission on a stored procedure and that user already has EXECUTE permission on that procedure.


User '%1' already has GRANT permission

Item | Value
SQLCODE | –120
Constant | SQLE_ALREADY_HAS_GRANT_PERMS
SQLSTATE | 42W01
Sybase error code | 13625
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the user ID that already has GRANT permission.
Probable cause

You attempted to give a user GRANT OPTION and that user already has GRANT OPTION.


User '%1' already has membership in group '%2'

Item | Value
SQLCODE | –312
Constant | SQLE_ALREADY_HAS_GROUP_MEMBERSHIP
SQLSTATE | 42W34
Sybase error code | 13627
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the user ID that already has membership.
Parameter 2 | Name of the group.
Probable cause

You attempted to give a membership in a group to a user that already has such membership.


User '%1' has the row in '%2' locked

Item | Value
SQLCODE | –210
Constant | SQLE_LOCKED
SQLSTATE | 42W18
Sybase error code | 8405
ODBC 2 State | 40001
ODBC 3 State | 40001
Parameter 1 | Name of another user.
Parameter 2 | Table which generates the error.
Probable cause

You attempted to read or write a row and it is locked by another user, while the BLOCKING database option is set to OFF.


User '%1' is already the publisher for this database

Item | Value
SQLCODE | –284
Constant | SQLE_ONLY_ONE_PUBLISHER
SQLSTATE | 5RW05
Sybase error code | 13646
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of the publisher.
Probable cause

You attempted to GRANT PUBLISH to a user ID, when a publisher already exists.


User '%1' is not a remote user for this database

Item | Value
SQLCODE | –285
Constant | SQLE_NOT_REMOTE_USER
SQLSTATE | 5RW06
Sybase error code | 13647
ODBC 2 State | S0002
ODBC 3 State | 42S02
Parameter 1 | Name of user.
Probable cause

You attempted to CREATE a subscription for a user, or PASSTHROUGH for a user that is not a remote user of this database. You must GRANT REMOTE or GRANT CONSOLIDATE.


User '%1' is not a user group

Item | Value
SQLCODE | –123
Constant | SQLE_NOT_A_GROUP
SQLSTATE | 42W03
Sybase error code | 13626
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of user you thought was a group.
Probable cause

You attempted to add a member to group, but the user ID specified as a group has not been granted the GROUP special privilege.


User ID '%1' does not exist

Item | Value
SQLCODE | –140
Constant | SQLE_UNKNOWN_USERID
SQLSTATE | 08004
Sybase error code | 509
ODBC 2 State | 28000
ODBC 3 State | 28000
Parameter 1 | Name of the user ID that could not be found.
Probable cause

You used a user ID that does not exist.


User message %1 already exists

Item | Value
SQLCODE | –610
Constant | SQLE_MESSAGE_ALREADY_EXISTS
SQLSTATE | 52W16
Sybase error code | 13624
ODBC 2 State | 42000
ODBC 3 State | 42000
Probable cause

The message with this error number already exists in the SYSUSERMESSAGES system table.


User message %1 not found

Item | Value
SQLCODE | –612
Constant | SQLE_MESSAGE_NOT_FOUND
SQLSTATE | 52W17
Sybase error code | 2748
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Message number.
Probable cause

The message with this error number does not exist in SYSUSERMESSAGES.


User owns procedures in use

Item | Value
SQLCODE | –750
Constant | SQLE_USER_OWNS_PROCEDURES_IN_USE
SQLSTATE | 42W55
Sybase error code | 3702
ODBC 2 State | 40001
ODBC 3 State | 40001
Probable cause

You attempted to REVOKE CONNECT from a user that owns a procedure being used by other active users of the database.


User owns tables in use

Item | Value
SQLCODE | –751
Constant | SQLE_USER_OWNS_TABLES_IN_USE
SQLSTATE | 42W56
Sybase error code | 3702
ODBC 2 State | 40001
ODBC 3 State | 40001
Probable cause

You attempted to REVOKE CONNECT from a user that owns a table being used by other active users of the database.


User-defined exception signaled

Item | Value
SQLCODE | –297
Constant | SQLE_USER_DEFINED_EXCEPTION
SQLSTATE | 99999
Sybase error code | 13662
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A stored procedure or trigger signaled a user-defined exception. This error state is reserved for use within stored procedures or triggers which contain exception handlers, as a way of signaling an exception which can be guaranteed to not have been caused by the database server. Valid SQLSTATE values range from 99000 to 99999 and are set by the user when executing the signal SQL statement.


User-defined type '%1' not found

Item | Value
SQLCODE | –613
Constant | SQLE_USER_TYPE_NOT_FOUND
SQLSTATE | 52W18
Sybase error code | 2715
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Name of the user-defined type.
Probable cause

The user-defined type with this name does not exist in SYSUSERTYPE.


USING attribute cannot coexist with FORMAT or GROUP attributes

Item | Value
SQLCODE | –1026
Constant | SQLE_SERVICE_ATTR_COEXIST
SQLSTATE | 42WB1
Sybase error code | 13484
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The service definition for the specified service type cannot specify a USING attribute along with a FORMAT or GROUP attribute.


Using temporary table

Item | Value
SQLCODE | 102
Constant | SQLE_TEMPORARY_TABLE
SQLSTATE | 01W02
Sybase error code | 13075
ODBC 2 State | 01000
ODBC 3 State | 01000
Probable cause

A temporary table has been created in order to satisfy the query. This warning can only occur on an OPEN statement.


VALIDATE TABLE statement must refer to a base table

Item | Value
SQLCODE | –720
Constant | SQLE_CANNOT_VALIDATE_OBJECT
SQLSTATE | 42W51
Sybase error code | 13729
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

The VALIDATE TABLE statement must refer to a local base table; it cannot refer to a view, an IQ table, or an object on a remote server.


Value %1 out of range for destination

Item | Value
SQLCODE | –158
Constant | SQLE_OVERFLOW_ERROR
SQLSTATE | 22003
Sybase error code | 220
ODBC 2 State | 22003
ODBC 3 State | 22003
Parameter 1 | The value that caused the overflow.
Probable cause

You supplied to or fetched from the database a value that is out of range for the destination column or host variable. For example, the value 10 may have been supplied for a DECIMAL(3,2) field.


Value for column '%1' in table '%2' has changed

Item | Value
SQLCODE | 106
Constant | SQLE_COLUMN_VALUE_CHANGED
SQLSTATE | 01W06
Sybase error code | 532
ODBC 2 State | OK
ODBC 3 State | OK
Parameter 1 | Name of the column whose value has changed.
Parameter 2 | Name of the table containing the column.
Probable cause

A replicated UPDATE has found a value in an updated column that does not match the value when the original UPDATE was made.


Value truncated

Item | Value
SQLCODE | 101
Constant | SQLE_TRUNCATED
SQLSTATE | 01004
Sybase error code | 7337
ODBC 2 State | 01004
ODBC 3 State | 01004
Probable cause

You may have tried to insert, update, or select a value in the database that is too large to fit in the destination. You may have fetched data into a host variable or SQLDA variable not large enough to receive the value.


Variable '%1' not found

Item | Value
SQLCODE | –260
Constant | SQLE_VARIABLE_NOT_FOUND
SQLSTATE | 42W14
Sybase error code | 137
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to DROP or SET the value of a SQL variable that was not created or was previously dropped.


View references '%1', which is a temporary object. Views can only refer to permanent objects.

Item | Value
SQLCODE | –766
Constant | SQLE_VIEW_OVER_TEMP_OBJECT
SQLSTATE | 42U00
Sybase error code | 4412
ODBC 2 State | 42000
ODBC 3 State | 42000
Parameter 1 | Temporary object name
Probable cause

Views must refer only to permanent objects, not to temporary objects such as local temporary tables.


Virtual index creation with more than %1 columns.

Item | Value
SQLCODE | –887
Constant | SQLE_TOO_MANY_VIRTUAL_INDEX_COLUMNS
SQLSTATE | 54W50
Sybase error code | 13597
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The maximum number of virtual index columns.
Probable cause

Virtual indexes may only contain a limited number of columns. See document on the use of virtual indexes.


Warning detected when optimizing SELECT INTO is treated as an error

Item | Value
SQLCODE | –995
Constant | SQLE_SELECT_INTO_WARNING_TREATED_AS_ERROR
SQLSTATE | WP016
Sybase error code | 13495
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

The SELECT ... INTO #TEMPTABLE statement cannot proceed if a warning is detected while optimizing the query. To fix the problem, test the query by removing the INTO clause, and resolve the reported warning.


Warning: %1

Item | Value
SQLCODE | 200
Constant | SQLE_WARNING
SQLSTATE | 01000
Sybase error code | 13619
ODBC 2 State | OK
ODBC 3 State | OK
Parameter 1 | Warning message.
Probable cause

A warning has occurred. The message indicates the condition that caused the warning.


Window '%1' not found

Item | Value
SQLCODE | –947
Constant | SQLE_WINDOW_NOT_FOUND
SQLSTATE | 42WA3
Sybase error code | 13541
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | Name of the window that could not be found.
Probable cause

You have attempted to reference a window name that is not defined in the window list of the SELECT.


Window function requires ORDER BY

Item | Value
SQLCODE | –965
Constant | SQLE_ORDERBY_REQUIRED
SQLSTATE | 42WA9
Sybase error code | 13525
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

Rank functions and window functions that use the RANGE keyword must specify an ORDER BY.


Window function used in predicate

Item | Value
SQLCODE | –964
Constant | SQLE_ILLEGAL_WINDOW_PREDICATE
SQLSTATE | 42WA8
Sybase error code | 13526
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

A window function was used in the WHERE or HAVING clause of a SELECT statement. Consider making the SELECT into a derived table, putting the window function in the SELECT list of the derived table, and changing the predicate to reference the derived column.


WITH CHECK OPTION violated for insert/update on base table '%1'

Item | Value
SQLCODE | –632
Constant | SQLE_WITH_CHECK_OPTION_VIOLATION
SQLSTATE | 44000
Sybase error code | 550
ODBC 2 State | S1000
ODBC 3 State | 44000
Parameter 1 | Name of the base table being updated.
Probable cause

You attempted an insert or update operation on the indicated base table through a view (possibly nested). However, one or more values in the modified row(s) triggered a WITH CHECK OPTION violation. This violation occurs when a modified value causes one or more rows to fall outside the range of the view by making the view's WHERE clause evaluate to FALSE or UNKNOWN for that row.


Wrong number of parameters to function '%1'

Item | Value
SQLCODE | –154
Constant | SQLE_WRONG_PARAMETER_COUNT
SQLSTATE | 37505
Sybase error code | 174
ODBC 2 State | 37000
ODBC 3 State | 42000
Parameter 1 | Name of the function.
Probable cause

You supplied an incorrect number of parameters to a database function.


Wrong number of values for INSERT

Item | Value
SQLCODE | –207
Constant | SQLE_WRONG_NUM_OF_INSERT_COLS
SQLSTATE | 53002
Sybase error code | 213
ODBC 2 State | 21S01
ODBC 3 State | 21S01
Probable cause

The number of values you are trying to insert does not match the number of columns specified in the INSERT statement, or the number of columns in the table if no columns are specified.


Wrong number of variables in FETCH

Item | Value
SQLCODE | –264
Constant | SQLE_WRONG_NUM_OF_FETCH_VARIABLES
SQLSTATE | 42W26
Sybase error code | 553
ODBC 2 State | S1002
ODBC 3 State | 07009
Probable cause

You specified a number of variables in a FETCH statement that does not match the number of select list items.


XML parser error: %1

Item | Value
SQLCODE | –888
Constant | SQLE_XML_PARSER_ERROR
SQLSTATE | WX002
Sybase error code | 13595
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The error message returned by the XML parser.
Probable cause

An XML instance will only parse correctly if it is well-formed as defined by the XML 1.0 specification.


XMLGEN evaluation failure

Item | Value
SQLCODE | –906
Constant | SQLE_XMLGEN_EVALUATION_FAILURE
SQLSTATE | WX013
Sybase error code | 13577
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Probable cause

One of the variables referenced in the XQuery constructor was not found in the list of arguments.


XPath parser error: %1

Item | Value
SQLCODE | –892
Constant | SQLE_XQUERY_PARSER_ERROR
SQLSTATE | WX003
Sybase error code | 13591
ODBC 2 State | ERROR
ODBC 3 State | ERROR
Parameter 1 | The error message returned by the XPath parser.
Probable cause

The XPath expression is illegal or uses features that are not currently supported.


You cannot synchronize or upgrade with uncommitted transactions

Item | Value
SQLCODE | –755
Constant | SQLE_UNCOMMITTED_TRANSACTIONS
SQLSTATE | 0AW08
Sybase error code | 13765
ODBC 2 State | 37000
ODBC 3 State | 42000
Probable cause

You attempted to synchronize or upgrade the schema of an UltraLite database and there are changes in the UltraLite database that have not been committed.


Internal errors (assertion failed)

Adaptive Server Anywhere has many internal checks that have been designed to detect possible database corruption as soon as possible. If the database server prints an Assertion Failed message, you should not continue to use it before attempting to determine the cause. You should record the assertion number displayed on the screen and report the error to Adaptive Server Anywhere technical support.

The dbvalid utility is useful for determining if your database file is corrupt. You may find it necessary to reconstruct your data from backups and transaction logs. See Backup and Data Recovery.


MobiLink Synchronization Server Error Messages

About this chapter

This chapter lists MobiLink synchronization server communication errors, as well as their probable causes.

The error messages are written to the MobiLink synchronization server message log.

MobiLink synchronization server error messages sorted by code
MobiLink synchronization server error messages sorted message
MobiLink synchronization server error descriptions


MobiLink synchronization server error messages sorted by code

Error code | Error message
–10220 | Unable to load the Java VM shared library.\nMake sure that the shared library path is set correctly and that LD_PRELOAD is set correctly and supported by your version of the dynamic loader.
–10219 | Invalid context for stream parameter %1!s! for stream %2!d!: %3!s!
–10218 | Invalid value %1!s! stream parameter %2!s! for stream %3!d!: %4!s!
–10217 | Invalid stream parameter %1!s! for stream %2!d!: %3!s!
–10216 | A downloaded value for table '%1!s!' (column #%2!ld!) was an invalid unique identifier string.
–10215 | Invalid parameter '%1!s!'.
–10214 | Invalid return value (%2!ld!) from the !1!s! script. Using the default action code (%3!ld!).
–10213 | Unable to convert the string %1!s! to a numeric value
–10212 | Unable to open temporary file '%1!s!'.
–10211 | A downloaded value for table %1!s! (column #%2!ld!) contains character data that cannot be converted.
–10210 | Unable to generate scripts for version '%1!s!', because the client doesn't supply column names of tables
–10209 | Unrecognized data layer command line switch (%1!s!).
–10208 | Unrecognized value (%1!ld!) in ml_user.commit_state. The state information for this user is probably corrupted.
–10207 | Unrecognized event name: %1!s!.
–10206 | '%1!s!'.
–10205 | Failure executing script '%1!s!'.
–10204 | Script '%1!s!' is a member of '%2!s!', but only %3!s! classes are permitted per script version.
–10203 | Attempt to use a connection with an invalid handle.
–10202 | Transactions on this connection cannot be committed or rolled back.
–10201 | Binding of parameter %1!s! requires value to be of type '%2!s!', but a '%3!s!' was supplied.
–10200 | The prepared SQL statement '%1!s!' requires %2!s! parameters, but %3!s! parameters were supplied.
–10199 | Attempt to execute a SQL statement with bound parameters before MLDBCommand.Prepare() was been called.
–10198 | The prepared SQL statement '%1!s!' requires %2!s! parameters, but parameter %3!s! was not supplied.
–10197 | Attempt to execute SQL statement '%1!s!' after MLDBCommand.Close() was called.
–10196 | Attempt to execute null SQL statement. Set value of MLDBCommand.CommandText before calling a MLDBCommand.Execute method.
–10195 | Attempt to prepare null SQL statement. Set value of MLDBCommand.CommandText before calling MLDBCommand.Prepare().
–10194 | Attempt to prepare SQL statement '%1!s!' after MLDBCommand.Close() was called.
–10193 | Unable to load Assembly '%1!s!' into domain '%2!s!'.
–10192 | Could not create domain '%1!s!'.
–10191 | Unable to locate .NET Domain Configuration File '%1!s!'.
–10190 | Script '%1!s!' reported a fatal error.
–10189 | Script '%1!s!' encountered an error.
–10188 | Script '%1!s!' reported a server error.
–10187 | Failed to load .NET start class '%1!s!'.
–10186 | Script '%1!s!' reported a synchronization error.
–10185 | Script '%1!s!' returned an object of type '%2!s!', which is not a subtype of 'System.Void' or 'System.String'.
–10184 | Script '%1!s!' requires %2!s! parameters, but %3!s! parameters were supplied.
–10183 | Only one Domain can be used per script version. Domain '%1!s!' was in use when script '%2!s!' attempted to use Domain '%3!s!'.
–10182 | Invalid format used for script '%1!s!'.
–10181 | Unable to shutdown .NET scripting VM. %1!s! workers still attached.
–10180 | Unable to shutdown .NET scripting VM.
–10179 | No Assembly in domain '%1!s!' contains type '%2!s!'.
–10178 | Domain '%1!s!' was not specified in Domain configuration file.
–10177 | The name '%1!s!' is not a valid name for a .NET start class.
–10176 | .NET Domain Configuration File is corrupt.
–10175 | The .NET scripting VM requires version %1!s! of the MobiLink Script DLL, but was supplied version %2!s! instead.
–10174 | The .NET scripting VM requires version %1!s! of the MobiLink ODBC Bridge DLL, but was supplied version %2!s! instead.
–10173 | Script '%1!s!' returns a '%2!s!' object, but only return types of 'System.Void' and 'System.String' are supported.
–10172 | Assembly '%1!s!' does not contain '%2!s!'.
–10171 | Assembly '%1!s!' was compiled against version %2!s! of '%3!s!'. Please recompile against version %4!s!.
–10170 | Unable to allocate memory needed for script execution.\n
–10169 | Unable to detach worker from VM.\n
–10168 | Unable to attach worker to VM.\n
–10167 | .NET CLR Host encountered unexpected error.\n
–10166 | Unable to find file '%1!s!'.\n
–10165 | Unable to load .NET CLR Host DLL.\n
–10164 | Unable to load .NET Framework CLR Version %1!s!.\n
–10163 | Option '%1!s!' is invalid or was not specified correctly on MobiLink command line.\n
–10162 | Option '%1!s!' was previously defined on MobiLink command line with value '%2!s!'.\n
–10161 | No valid constructor was found for type '%1!s!'.
–10160 | Unable to attach JDBC connection.
–10159 | Unable to create new database connection.
–10158 | Exception thrown in method: '%1!s!'. Error description: '%2!s!'.\nStack trace: '%3!s!'.
–10157 | Could not call method: '%1!s!' with arguments of types '%2!s!'.
–10156 | Internal error: '%1!s!'.
–10155 | System exception thrown in constructor of class: '%1!s!'. Error description: '%2!s!'.
–10154 | Exception thrown in constructor of class: '%1!s!'. Error description: '%2!s!'.\nStack trace: '%3!s!'.
–10153 | No suitable constructor found in class: '%1!s!'.
–10152 | Unable to resolve script. Two methods with name: '%1!s!' found in class: '%2!s!'.
–10151 | No public methods found in script class: '%1!s!'.
–10150 | Linkage error while loading class: '%1!s!' Error description: '%2!s!'.
–10149 | Exception thrown in initializer of class: '%1!s!'. Error description: '%2!s!'.\nStack trace: '%3!s!'.
–10148 | Java exception...
–10147 | There are too many entries in the JVM config file: %1!s!
–10146 | Too many options sent to Java VM.
–10145 | Unable to access the JRE at: %1!s!
–10144 | Shared install directory is incorrect: %1!s!
–10143 | Unable find shared components directory.\nJRE location is not specified in options.\nJRE location is unknown!
–10142 | Unable to find the JAR file: '%1!s!' in install directory or classpath.
–10141 | The classpath '%1!s!' is too long.
–10140 | The option '%1!s!' needs a path.
–10139 | The options '%1!s!' and '%2!s!' must not be used together.
–10138 | There are no entries in the JVM config file: %1!s!
–10137 | Invalid line found in the JVM config file: %1!s!.\nLine is too long.
–10136 | Invalid line found in the JVM config file: %1!s!\nAll lines must begin with either '#' or '-'.
–10135 | Expected an instance of ianywhere.ml.script.RowReader or subclass, but found class '%1!s!' instead.
–10134 | Expected an instance of java.lang.String or subclass, but found class '%1!s!' instead.
–10133 | %1!s!
–10132 | Returned class '%1!s!' not a subclass of ianywhere.ml.script.RowReader or java.lang.String.
–10131 | Expected or an object, but a primitive of type '%1!s!' was returned instead.
–10130 | Not enough arguments to execute script: '%1!s!.%2!s!'.\n %3!d! arguments are needed only %4!d! are available.
–10129 | Two scripts on the same connection have different classes.\nThe connection class is: '%1!s!'\nThe current script has class: '%2!s!' and method: '%3!s!'.
–10128 | Failed to load necessary method: '%1!s!' for Java class: %2!s!
–10127 | Failed to load necessary Java class: %1!s!
–10126 | Error while attaching worker thread to Java VM.
–10125 | Unable to parse class and method name from script: %1!s!
–10124 | The following non-daemon threads were destroyed: %1!s!
–10123 | Unable to load the Java VM due to an unknown error
–10122 | Unable to load the Java VM due to a memory error.
–10121 | Unable to load the Java VM due to a version error.
–10120 | %1!s! is an unknown child of ScriptExecutionException.
–10119 | Unable to dump exception information. Received exception while processing exception.
–10118 | Caught JAVA exception with type: %1!s!.\nException message: %2!s!
–10117 | Stream Error: %1!s!
–10116 | The monitor thread was unable to communicate with the remote monitor.
–10115 | Unable to pass a remote monitoring request to the monitor thread. Only one remote monitor may be connected at a time.
–10114 | Unable to load entry points from dll: '%1!s!'.
–10113 | Unable to create worker thread %1!lu!
–10112 | Unable to create the background thread.
–10111 | Unable to create the monitoring thread.
–10110 | Unable to initialize communications stream %1!lu!: %2!s!
–10109 | One or more invalid parameters
–10108 | Unable to load dll %1!s! for stream %2!lu!: %3!s!
–10107 | Unable to load dll: %1!s!
–10106 | Bad stream type: %1!s!
–10105 | Bad stream specification: %1!s!
–10104 | Unable to load entry points from dll: '%1!s!'.
–10103 | Cannot load dll: '%1!s!' for Data Layer: '%2!s!'.
–10102 | The data layer name '%1!s!' id too long.
–10101 | Table '%1!s!' has no entry in the ml_table table
–10100 | The MobiLink system table '%1!s!' is missing or a table column is missing
–10099 | Unable to load UNILIB collation %1!d!: %2!s!
–10098 | Not enough worker threads are available to handle all streams, specify at least %1!d! more
–10097 | The download stream cannot be restarted for this user
–10096 | The MobiLink system table '%1!s!' is missing column '%2!s!'
–10095 | The MobiLink system table '%1!s!' is missing
–10094 | Expecting %1!ld! authentication parameter(s) from client, but received %2!ld! for script %3!s!
–10093 | There is no download data script defined for table: %1!s!. If you want to be able to synchronize anyway, with the risk of potentially losing download data, use the -fr switch
–10092 | There is no upload data script defined for table: %1!s!. If you want to be able to synchronize anyway, with the risk of potentially losing upload data, use the -fr switch
–10091 | This connection will be abandoned due to previous errors
–10090 | The client cannot find the consolidated progress offset from the client transaction log(s)
–10089 | Client is unable to process truncate table request for table '%1!s!'
–10088 | Unable to load entry points from DLL: '%1!s!'
–10087 | Version mismatch with DLL or shared object: '%1!s!'\nExpected version: %2!d! got version: %3!d!
–10086 | Cannot load DLL or shared object: '%1!s!' for Script Language: '%2!s!'
–10085 | LANG: %1!s! = Failed to allocate database connection
–10084 | LANG: %1!s! - Failed to attach worker thread
–10083 | Unable to delete user name '%1!s!' from the ml_user_table
–10082 | Unable to initialize the resource DLL or shared object '%1!s!'
–10081 | The MobiLink synchronization server DLL or shared object version does not match the data layer DLL or shared object version
–10080 | Unable to execute script '%1!s!'
–10079 | The length of the name of a publication, table, or column cannot be retrieved from the upload stream
–10078 | The publication, table, or column name received from the client is too long: the length is %1!d!
–10077 | The MobiLink synchronization server was unable to modify the error message using the modify_error_message script
–10076 | The MobiLink synchronization server was unable to calculate the timestamp precision on the consolidated database using the ml_scripts_modified table. Timestamp precision related warnings will not be generated
–10075 | Required ODBC function %1!s! is not supported by the driver
–10074 | Unable to update table '%1!s!' using %2!s!
–10073 | Unable to delete from table '%1!s!' using %2!s!
–10072 | Unable to insert into table '%1!s!' using %2!s!
–10071 | Unable to fetch from table '%1!s!' using %2!s!
–10070 | No server connection string specified
–10069 | Unable to initialize consolidated database interface
–10068 | Unable to initialize authentication subsystem
–10067 | Unable to allocate a connection
–10066 | Unable to initialize ODBC
–10065 | Unable to COMMIT Transaction: %1!s! -- Attempting to ROLLBACK
–10064 | Unable to ROLLBACK Transaction: %1!s!
–10063 | An error occurred while uploading an updated row into table '%1!s!'. The updated column values are as follows:
–10062 | An error occurred while uploading a deleted row into table '%1!s!'. The deleted column values are as follows:
–10061 | An error occurred while uploading an insert row into table '%1!s!'. The inserted column values are as follows:
–10060 | Memory allocation failed
–10059 | A protocol error occurred when attempting to retrieve the remote client's synchronization log
–10058 | Unable to open %1!s!
–10057 | Invalid password for user %1!s!
–10056 | User name '%1!s!' not found in the ml_user table
–10055 | Unable to authenticate user %1!s!
–10054 | Unable to insert user name '%1!s!' into the ml_user table
–10053 | The user name '%1!s!' is already synchronizing. Concurrent synchronizations using the same user name are not allowed
–10052 | The %1!s! script returned %2!ld!
–10051 | Internal error: wrong function '%1!s!' called. Please contact technical support
–10050 | Expecting %1!ld! columns in cursor, but found %2!ld!
–10049 | Too many bind parameters in script (expecting %1!ld! but found %2!ld!): %3!s!
–10048 | Expecting at least %1!ld! parameters in script, but only found %2!ld!: %3!s!
–10047 | Expecting %1!ld! parameters in script, but only found %2!ld!: %3!s!
–10046 | Unable to allocate an input/output cursor
–10045 | Cannot directly determine the name of the table referenced by the cursor. The table name is required for inserts, updates, and deletes when using the Microsoft ODBC Cursor Library
–10044 | INTERNAL ERROR: occurred while storing a BLOB -- write
–10043 | INTERNAL ERROR: occurred while retrieving a BLOB -- zero length
–10042 | INTERNAL ERROR: occurred while retrieving a BLOB -- null
–10041 | INTERNAL ERROR: occurred while retrieving a BLOB -- read
–10040 | Extraneous data found in upload stream
–10039 | Scripts cannot be defined as NULL
–10038 | A downloaded value for table %1!s! (column #%2!ld!) was either too big or invalid for the remote schema type
–10037 | Unable to launch the command: (%1!s!). The system error code is %2!d!
–10036 | Download stream encountered error in remote database
–10035 | Download failed with client error %1!d!
–10034 | No download confirmation from remote database
–10033 | The row is too big. The size (%1!ld! bytes) exceeds the maximum allowable size (%2!ld! bytes)
–10032 | Upload failed with client error %1!d!
–10031 | An error occurred when trying to store progress information in the consolidated database
–10030 | A network read failed. Unable to read data from the remote client
–10029 | Attempt to set non-null column to null
–10028 | Unable to connect to the consolidated database. Aborting the synchronization
–10027 | Unable to generate scripts for version '%1!s!'
–10026 | The upload stream is too short: should be at least %1!d! bytes, but received %2!d! bytes
–10025 | The %1!s! cursor is unexpectedly undefined
–10024 | Unrecognized domain id %1!d!
–10023 | The remote database may have been restored from backup, or perhaps user name '%1!s!' is being used by different remote databases. Set ml_user.commit_state to zero to re-enable synchronizations for this user
–10022 | The synchronization sequence number stored in ml_user.commit_state is negative. Set this value to zero (0) to re-enable synchronizations for user '%1!s!'
–10021 | Unable to retry the current transaction after deadlock in the consolidated database. The retry limit has been reached
–10020 | Unable to flush scripts
–10019 | Error fetching table script %1!s!.%2!s!
–10018 | Error fetching connection script %1!s!
–10017 | Protocol error: there is no publication that contains table '%1!s!'
–10016 | Cannot convert '%1!s!' to Unicode
–10015 | Protocol error: client requests an unsupported capability (%1!s!)
–10014 | Protocol error: an invalid timestamp precision of %1!d! was sent from the remote
–10013 | Version '%1!s!' not found in the ml_script_version table. Cannot synchronize
–10012 | There are no registered script versions. Unable to synchronize a client created prior to version 7.0.0
–10011 | Unable to determine the remote version
–10010 | Unable to determine the remote user password
–10009 | Unable to determine the remote user name
–10008 | Unable to load UNILIB collation expansion factor: error %1!d!
–10007 | Unable to load UNILIB collation %1!d!: error %2!d!
–10006 | Collation not supported by this server
–10005 | Old versions of MobiLink clients cannot ping the MobiLink synchronization server
–10004 | Protocol version mismatch
–10003 | Memory allocation failed, attempted to allocate %1!lu! bytes
–10002 | Consolidated database server or ODBC error: %1!s!
–10001 | Protocol error
0 | No error or unknown error


MobiLink synchronization server error messages sorted message

Error code | Error message
–10133 | %1!s!
–10120 | %1!s! is an unknown child of ScriptExecutionException.
–10206 | '%1!s!'.
–10167 | .NET CLR Host encountered unexpected error.\n
–10176 | .NET Domain Configuration File is corrupt.
–10211 | A downloaded value for table %1!s! (column #%2!ld!) contains character data that cannot be converted.
–10038 | A downloaded value for table %1!s! (column #%2!ld!) was either too big or invalid for the remote schema type
–10216 | A downloaded value for table '%1!s!' (column #%2!ld!) was an invalid unique identifier string.
–10030 | A network read failed. Unable to read data from the remote client
–10059 | A protocol error occurred when attempting to retrieve the remote client's synchronization log
–10031 | An error occurred when trying to store progress information in the consolidated database
–10062 | An error occurred while uploading a deleted row into table '%1!s!'. The deleted column values are as follows:
–10061 | An error occurred while uploading an insert row into table '%1!s!'. The inserted column values are as follows:
–10063 | An error occurred while uploading an updated row into table '%1!s!'. The updated column values are as follows:
–10172 | Assembly '%1!s!' does not contain '%2!s!'.
–10171 | Assembly '%1!s!' was compiled against version %2!s! of '%3!s!'. Please recompile against version %4!s!.
–10197 | Attempt to execute SQL statement '%1!s!' after MLDBCommand.Close() was called.
–10199 | Attempt to execute a SQL statement with bound parameters before MLDBCommand.Prepare() was been called.
–10196 | Attempt to execute null SQL statement. Set value of MLDBCommand.CommandText before calling a MLDBCommand.Execute method.
–10194 | Attempt to prepare SQL statement '%1!s!' after MLDBCommand.Close() was called.
–10195 | Attempt to prepare null SQL statement. Set value of MLDBCommand.CommandText before calling MLDBCommand.Prepare().
–10029 | Attempt to set non-null column to null
–10203 | Attempt to use a connection with an invalid handle.
–10105 | Bad stream specification: %1!s!
–10106 | Bad stream type: %1!s!
–10201 | Binding of parameter %1!s! requires value to be of type '%2!s!', but a '%3!s!' was supplied.
–10016 | Cannot convert '%1!s!' to Unicode
–10045 | Cannot directly determine the name of the table referenced by the cursor. The table name is required for inserts, updates, and deletes when using the Microsoft ODBC Cursor Library
–10086 | Cannot load DLL or shared object: '%1!s!' for Script Language: '%2!s!'
–10103 | Cannot load dll: '%1!s!' for Data Layer: '%2!s!'.
–10118 | Caught JAVA exception with type: %1!s!.\nException message: %2!s!
–10089 | Client is unable to process truncate table request for table '%1!s!'
–10006 | Collation not supported by this server
–10002 | Consolidated database server or ODBC error: %1!s!
–10157 | Could not call method: '%1!s!' with arguments of types '%2!s!'.
–10192 | Could not create domain '%1!s!'.
–10178 | Domain '%1!s!' was not specified in Domain configuration file.
–10035 | Download failed with client error %1!d!
–10036 | Download stream encountered error in remote database
–10018 | Error fetching connection script %1!s!
–10019 | Error fetching table script %1!s!.%2!s!
–10126 | Error while attaching worker thread to Java VM.
–10154 | Exception thrown in constructor of class: '%1!s!'. Error description: '%2!s!'.\nStack trace: '%3!s!'.
–10149 | Exception thrown in initializer of class: '%1!s!'. Error description: '%2!s!'.\nStack trace: '%3!s!'.
–10158 | Exception thrown in method: '%1!s!'. Error description: '%2!s!'.\nStack trace: '%3!s!'.
–10131 | Expected or an object, but a primitive of type '%1!s!' was returned instead.
–10135 | Expected an instance of ianywhere.ml.script.RowReader or subclass, but found class '%1!s!' instead.
–10134 | Expected an instance of java.lang.String or subclass, but found class '%1!s!' instead.
–10094 | Expecting %1!ld! authentication parameter(s) from client, but received %2!ld! for script %3!s!
–10050 | Expecting %1!ld! columns in cursor, but found %2!ld!
–10047 | Expecting %1!ld! parameters in script, but only found %2!ld!: %3!s!
–10048 | Expecting at least %1!ld! parameters in script, but only found %2!ld!: %3!s!
–10040 | Extraneous data found in upload stream
–10187 | Failed to load .NET start class '%1!s!'.
–10127 | Failed to load necessary Java class: %1!s!
–10128 | Failed to load necessary method: '%1!s!' for Java class: %2!s!
–10205 | Failure executing script '%1!s!'.
–10042 | INTERNAL ERROR: occurred while retrieving a BLOB -- null
–10041 | INTERNAL ERROR: occurred while retrieving a BLOB -- read
–10043 | INTERNAL ERROR: occurred while retrieving a BLOB -- zero length
–10044 | INTERNAL ERROR: occurred while storing a BLOB -- write
–10051 | Internal error: wrong function '%1!s!' called. Please contact technical support
–10156 | Internal error: '%1!s!'.
–10219 | Invalid context for stream parameter %1!s! for stream %2!d!: %3!s!
–10182 | Invalid format used for script '%1!s!'.
–10137 | Invalid line found in the JVM config file: %1!s!.\nLine is too long.
–10136 | Invalid line found in the JVM config file: %1!s!\nAll lines must begin with either '#' or '-'.
–10215 | Invalid parameter '%1!s!'.
–10057 | Invalid password for user %1!s!
–10214 | Invalid return value (%2!ld!) from the !1!s! script. Using the default action code (%3!ld!).
–10217 | Invalid stream parameter %1!s! for stream %2!d!: %3!s!
–10218 | Invalid value %1!s! stream parameter %2!s! for stream %3!d!: %4!s!
–10148 | Java exception...
–10084 | LANG: %1!s! - Failed to attach worker thread
–10085 | LANG: %1!s! = Failed to allocate database connection
–10150 | Linkage error while loading class: '%1!s!' Error description: '%2!s!'.
–10060 | Memory allocation failed
–10003 | Memory allocation failed, attempted to allocate %1!lu! bytes
–10179 | No Assembly in domain '%1!s!' contains type '%2!s!'.
–10034 | No download confirmation from remote database
0 | No error or unknown error
–10151 | No public methods found in script class: '%1!s!'.
–10070 | No server connection string specified
–10153 | No suitable constructor found in class: '%1!s!'.
–10161 | No valid constructor was found for type '%1!s!'.
–10130 | Not enough arguments to execute script: '%1!s!.%2!s!'.\n %3!d! arguments are needed only %4!d! are available.
–10098 | Not enough worker threads are available to handle all streams, specify at least %1!d! more
–10005 | Old versions of MobiLink clients cannot ping the MobiLink synchronization server
–10109 | One or more invalid parameters
–10183 | Only one Domain can be used per script version. Domain '%1!s!' was in use when script '%2!s!' attempted to use Domain '%3!s!'.
–10163 | Option '%1!s!' is invalid or was not specified correctly on MobiLink command line.\n
–10162 | Option '%1!s!' was previously defined on MobiLink command line with value '%2!s!'.\n
–10001 | Protocol error
–10014 | Protocol error: an invalid timestamp precision of %1!d! was sent from the remote
–10015 | Protocol error: client requests an unsupported capability (%1!s!)
–10017 | Protocol error: there is no publication that contains table '%1!s!'
–10004 | Protocol version mismatch
–10075 | Required ODBC function %1!s! is not supported by the driver
–10132 | Returned class '%1!s!' not a subclass of ianywhere.ml.script.RowReader or java.lang.String.
–10189 | Script '%1!s!' encountered an error.
–10204 | Script '%1!s!' is a member of '%2!s!', but only %3!s! classes are permitted per script version.
–10190 | Script '%1!s!' reported a fatal error.
–10188 | Script '%1!s!' reported a server error.
–10186 | Script '%1!s!' reported a synchronization error.
–10184 | Script '%1!s!' requires %2!s! parameters, but %3!s! parameters were supplied.
–10185 | Script '%1!s!' returned an object of type '%2!s!', which is not a subtype of 'System.Void' or 'System.String'.
–10173 | Script '%1!s!' returns a '%2!s!' object, but only return types of 'System.Void' and 'System.String' are supported.
–10039 | Scripts cannot be defined as NULL
–10144 | Shared install directory is incorrect: %1!s!
–10117 | Stream Error: %1!s!
–10155 | System exception thrown in constructor of class: '%1!s!'. Error description: '%2!s!'.
–10101 | Table '%1!s!' has no entry in the ml_table table
–10025 | The %1!s! cursor is unexpectedly undefined
–10052 | The %1!s! script returned %2!ld!
–10174 | The .NET scripting VM requires version %1!s! of the MobiLink ODBC Bridge DLL, but was supplied version %2!s! instead.
–10175 | The .NET scripting VM requires version %1!s! of the MobiLink Script DLL, but was supplied version %2!s! instead.
–10081 | The MobiLink synchronization server DLL or shared object version does not match the data layer DLL or shared object version
–10076 | The MobiLink synchronization server was unable to calculate the timestamp precision on the consolidated database using the ml_scripts_modified table. Timestamp precision related warnings will not be generated
–10077 | The MobiLink synchronization server was unable to modify the error message using the modify_error_message script
–10095 | The MobiLink system table '%1!s!' is missing
–10096 | The MobiLink system table '%1!s!' is missing column '%2!s!'
–10100 | The MobiLink system table '%1!s!' is missing or a table column is missing
–10141 | The classpath '%1!s!' is too long.
–10090 | The client cannot find the consolidated progress offset from the client transaction log(s)
–10102 | The data layer name '%1!s!' id too long.
–10097 | The download stream cannot be restarted for this user
–10124 | The following non-daemon threads were destroyed: %1!s!
–10079 | The length of the name of a publication, table, or column cannot be retrieved from the upload stream
–10116 | The monitor thread was unable to communicate with the remote monitor.
–10177 | The name '%1!s!' is not a valid name for a .NET start class.
–10140 | The option '%1!s!' needs a path.
–10139 | The options '%1!s!' and '%2!s!' must not be used together.
–10200 | The prepared SQL statement '%1!s!' requires %2!s! parameters, but %3!s! parameters were supplied.
–10198 | The prepared SQL statement '%1!s!' requires %2!s! parameters, but parameter %3!s! was not supplied.
–10078 | The publication, table, or column name received from the client is too long: the length is %1!d!
–10023 | The remote database may have been restored from backup, or perhaps user name '%1!s!' is being used by different remote databases. Set ml_user.commit_state to zero to re-enable synchronizations for this user
–10033 | The row is too big. The size (%1!ld! bytes) exceeds the maximum allowable size (%2!ld! bytes)
–10022 | The synchronization sequence number stored in ml_user.commit_state is negative. Set this value to zero (0) to re-enable synchronizations for user '%1!s!'
–10026 | The upload stream is too short: should be at least %1!d! bytes, but received %2!d! bytes
–10053 | The user name '%1!s!' is already synchronizing. Concurrent synchronizations using the same user name are not allowed
–10138 | There are no entries in the JVM config file: %1!s!
–10012 | There are no registered script versions. Unable to synchronize a client created prior to version 7.0.0
–10147 | There are too many entries in the JVM config file: %1!s!
–10093 | There is no download data script defined for table: %1!s!. If you want to be able to synchronize anyway, with the risk of potentially losing download data, use the -fr switch
–10092 | There is no upload data script defined for table: %1!s!. If you want to be able to synchronize anyway, with the risk of potentially losing upload data, use the -fr switch
–10091 | This connection will be abandoned due to previous errors
–10049 | Too many bind parameters in script (expecting %1!ld! but found %2!ld!): %3!s!
–10146 | Too many options sent to Java VM.
–10202 | Transactions on this connection cannot be committed or rolled back.
–10129 | Two scripts on the same connection have different classes.\nThe connection class is: '%1!s!'\nThe current script has class: '%2!s!' and method: '%3!s!'.
–10143 | Unable find shared components directory.\nJRE location is not specified in options.\nJRE location is unknown!
–10065 | Unable to COMMIT Transaction: %1!s! -- Attempting to ROLLBACK
–10064 | Unable to ROLLBACK Transaction: %1!s!
–10145 | Unable to access the JRE at: %1!s!
–10067 | Unable to allocate a connection
–10046 | Unable to allocate an input/output cursor
–10170 | Unable to allocate memory needed for script execution.\n
–10160 | Unable to attach JDBC connection.
–10168 | Unable to attach worker to VM.\n
–10055 | Unable to authenticate user %1!s!
–10028 | Unable to connect to the consolidated database. Aborting the synchronization
–10213 | Unable to convert the string %1!s! to a numeric value
–10159 | Unable to create new database connection.
–10112 | Unable to create the background thread.
–10111 | Unable to create the monitoring thread.
–10113 | Unable to create worker thread %1!lu!
–10073 | Unable to delete from table '%1!s!' using %2!s!
–10083 | Unable to delete user name '%1!s!' from the ml_user_table
–10169 | Unable to detach worker from VM.\n
–10009 | Unable to determine the remote user name
–10010 | Unable to determine the remote user password
–10011 | Unable to determine the remote version
–10119 | Unable to dump exception information. Received exception while processing exception.
–10080 | Unable to execute script '%1!s!'
–10071 | Unable to fetch from table '%1!s!' using %2!s!
–10166 | Unable to find file '%1!s!'.\n
–10142 | Unable to find the JAR file: '%1!s!' in install directory or classpath.
–10020 | Unable to flush scripts
–10027 | Unable to generate scripts for version '%1!s!'
–10210 | Unable to generate scripts for version '%1!s!', because the client doesn't supply column names of tables
–10066 | Unable to initialize ODBC
–10068 | Unable to initialize authentication subsystem
–10110 | Unable to initialize communications stream %1!lu!: %2!s!
–10069 | Unable to initialize consolidated database interface
–10082 | Unable to initialize the resource DLL or shared object '%1!s!'
–10072 | Unable to insert into table '%1!s!' using %2!s!
–10054 | Unable to insert user name '%1!s!' into the ml_user table
–10037 | Unable to launch the command: (%1!s!). The system error code is %2!d!
–10165 | Unable to load .NET CLR Host DLL.\n
–10164 | Unable to load .NET Framework CLR Version %1!s!.\n
–10193 | Unable to load Assembly '%1!s!' into domain '%2!s!'.
–10099 | Unable to load UNILIB collation %1!d!: %2!s!
–10007 | Unable to load UNILIB collation %1!d!: error %2!d!
–10008 | Unable to load UNILIB collation expansion factor: error %1!d!
–10108 | Unable to load dll %1!s! for stream %2!lu!: %3!s!
–10107 | Unable to load dll: %1!s!
–10088 | Unable to load entry points from DLL: '%1!s!'
–10114 | Unable to load entry points from dll: '%1!s!'.
–10104 | Unable to load entry points from dll: '%1!s!'.
–10122 | Unable to load the Java VM due to a memory error.
–10121 | Unable to load the Java VM due to a version error.
–10123 | Unable to load the Java VM due to an unknown error
–10220 | Unable to load the Java VM shared library.\nMake sure that the shared library path is set correctly and that LD_PRELOAD is set correctly and supported by your version of the dynamic loader.
–10191 | Unable to locate .NET Domain Configuration File '%1!s!'.
–10058 | Unable to open %1!s!
–10212 | Unable to open temporary file '%1!s!'.
–10125 | Unable to parse class and method name from script: %1!s!
–10115 | Unable to pass a remote monitoring request to the monitor thread. Only one remote monitor may be connected at a time.
–10152 | Unable to resolve script. Two methods with name: '%1!s!' found in class: '%2!s!'.
–10021 | Unable to retry the current transaction after deadlock in the consolidated database. The retry limit has been reached
–10180 | Unable to shutdown .NET scripting VM.
–10181 | Unable to shutdown .NET scripting VM. %1!s! workers still attached.
–10074 | Unable to update table '%1!s!' using %2!s!
–10209 | Unrecognized data layer command line switch (%1!s!).
–10024 | Unrecognized domain id %1!d!
–10207 | Unrecognized event name: %1!s!.
–10208 | Unrecognized value (%1!ld!) in ml_user.commit_state. The state information for this user is probably corrupted.
–10032 | Upload failed with client error %1!d!
–10056 | User name '%1!s!' not found in the ml_user table
–10013 | Version '%1!s!' not found in the ml_script_version table. Cannot synchronize
–10087 | Version mismatch with DLL or shared object: '%1!s!'\nExpected version: %2!d! got version: %3!d!


MobiLink synchronization server error descriptions

This section provides a full listing of error messages and descriptions.

Errors with an ODBC state marked "handled by ODBC driver" are not returned to ODBC applications, as the ODBC driver carries out the required actions.

%1!s!
%1!s! is an unknown child of ScriptExecutionException.
'%1!s!'.
.NET CLR Host encountered unexpected error.\n
.NET Domain Configuration File is corrupt.
A downloaded value for table %1!s! (column #%2!ld!) contains character data that cannot be converted.
A downloaded value for table '%1!s!' (column #%2!ld!) was an invalid unique identifier string.
A downloaded value for table %1!s! (column #%2!ld!) was either too big or invalid for the remote schema type
A network read failed. Unable to read data from the remote client
A protocol error occurred when attempting to retrieve the remote client's synchronization log
An error occurred when trying to store progress information in the consolidated database
An error occurred while uploading a deleted row into table '%1!s!'. The deleted column values are as follows:
An error occurred while uploading an insert row into table '%1!s!'. The inserted column values are as follows:
An error occurred while uploading an updated row into table '%1!s!'. The updated column values are as follows:
Assembly '%1!s!' does not contain '%2!s!'.
Assembly '%1!s!' was compiled against version %2!s! of '%3!s!'. Please recompile against version %4!s!.
Attempt to execute a SQL statement with bound parameters before MLDBCommand.Prepare() was been called.
Attempt to execute null SQL statement. Set value of MLDBCommand.CommandText before calling a MLDBCommand.Execute method.
Attempt to execute SQL statement '%1!s!' after MLDBCommand.Close() was called.
Attempt to prepare null SQL statement. Set value of MLDBCommand.CommandText before calling MLDBCommand.Prepare().
Attempt to prepare SQL statement '%1!s!' after MLDBCommand.Close() was called.
Attempt to set non-null column to null
Attempt to use a connection with an invalid handle.
Bad stream specification: %1!s!
Bad stream type: %1!s!
Binding of parameter %1!s! requires value to be of type '%2!s!', but a '%3!s!' was supplied.
Cannot convert '%1!s!' to Unicode
Cannot directly determine the name of the table referenced by the cursor. The table name is required for inserts, updates, and deletes when using the Microsoft ODBC Cursor Library
Cannot load DLL or shared object: '%1!s!' for Script Language: '%2!s!'
Cannot load dll: '%1!s!' for Data Layer: '%2!s!'.
Caught JAVA exception with type: %1!s!.\nException message: %2!s!
Client is unable to process truncate table request for table '%1!s!'
Collation not supported by this server
Consolidated database server or ODBC error: %1!s!
Could not call method: '%1!s!' with arguments of types '%2!s!'.
Could not create domain '%1!s!'.
Domain '%1!s!' was not specified in Domain configuration file.
Download failed with client error %1!d!
Download stream encountered error in remote database
Error fetching connection script %1!s!
Error fetching table script %1!s!.%2!s!
Error while attaching worker thread to Java VM.
Exception thrown in constructor of class: '%1!s!'. Error description: '%2!s!'.\nStack trace: '%3!s!'.
Exception thrown in initializer of class: '%1!s!'. Error description: '%2!s!'.\nStack trace: '%3!s!'.
Exception thrown in method: '%1!s!'. Error description: '%2!s!'.\nStack trace: '%3!s!'.
Expected <void> or an object, but a primitive of type '%1!s!' was returned instead.
Expected an instance of ianywhere.ml.script.RowReader or subclass, but found class '%1!s!' instead.
Expected an instance of java.lang.String or subclass, but found class '%1!s!' instead.
Expecting %1!ld! authentication parameter(s) from client, but received %2!ld! for script %3!s!
Expecting %1!ld! columns in cursor, but found %2!ld!
Expecting %1!ld! parameters in script, but only found %2!ld!: %3!s!
Expecting at least %1!ld! parameters in script, but only found %2!ld!: %3!s!
Extraneous data found in upload stream
Failed to load .NET start class '%1!s!'.
Failed to load necessary Java class: %1!s!
Failed to load necessary method: '%1!s!' for Java class: %2!s!
Failure executing script '%1!s!'.
INTERNAL ERROR: occurred while retrieving a BLOB -- null
INTERNAL ERROR: occurred while retrieving a BLOB -- read
INTERNAL ERROR: occurred while retrieving a BLOB -- zero length
INTERNAL ERROR: occurred while storing a BLOB -- write
Internal error: wrong function '%1!s!' called. Please contact technical support
Internal error: '%1!s!'.
Invalid context for stream parameter %1!s! for stream %2!d!: %3!s!
Invalid format used for script '%1!s!'.
Invalid line found in the JVM config file: %1!s!.\nLine is too long.
Invalid line found in the JVM config file: %1!s!\nAll lines must begin with either '#' or '-'.
Invalid parameter '%1!s!'.
Invalid password for user %1!s!
Invalid return value (%2!ld!) from the !1!s! script. Using the default action code (%3!ld!).
Invalid stream parameter %1!s! for stream %2!d!: %3!s!
Invalid value %1!s! stream parameter %2!s! for stream %3!d!: %4!s!
Java exception...
LANG: %1!s! - Failed to attach worker thread
LANG: %1!s! = Failed to allocate database connection
Linkage error while loading class: '%1!s!' Error description: '%2!s!'.
Memory allocation failed
Memory allocation failed, attempted to allocate %1!lu! bytes
No Assembly in domain '%1!s!' contains type '%2!s!'.
No download confirmation from remote database
No error or unknown error
No public methods found in script class: '%1!s!'.
No server connection string specified
No suitable constructor found in class: '%1!s!'.
No valid constructor was found for type '%1!s!'.
Not enough arguments to execute script: '%1!s!.%2!s!'.\n %3!d! arguments are needed only %4!d! are available.
Not enough worker threads are available to handle all streams, specify at least %1!d! more
Old versions of MobiLink clients cannot ping the MobiLink synchronization server
One or more invalid parameters
Only one Domain can be used per script version. Domain '%1!s!' was in use when script '%2!s!' attempted to use Domain '%3!s!'.
Option '%1!s!' is invalid or was not specified correctly on MobiLink command line.\n
Option '%1!s!' was previously defined on MobiLink command line with value '%2!s!'.\n
Protocol error
Protocol error: an invalid timestamp precision of %1!d! was sent from the remote
Protocol error: client requests an unsupported capability (%1!s!)
Protocol error: there is no publication that contains table '%1!s!'
Protocol version mismatch
Required ODBC function %1!s! is not supported by the driver
Returned class '%1!s!' not a subclass of ianywhere.ml.script.RowReader or java.lang.String.
Script '%1!s!' encountered an error.
Script '%1!s!' is a member of '%2!s!', but only %3!s! classes are permitted per script version.
Script '%1!s!' reported a fatal error.
Script '%1!s!' reported a server error.
Script '%1!s!' reported a synchronization error.
Script '%1!s!' requires %2!s! parameters, but %3!s! parameters were supplied.
Script '%1!s!' returned an object of type '%2!s!', which is not a subtype of 'System.Void' or 'System.String'.
Script '%1!s!' returns a '%2!s!' object, but only return types of 'System.Void' and 'System.String' are supported.
Scripts cannot be defined as NULL
Shared install directory is incorrect: %1!s!
Stream Error: %1!s!
System exception thrown in constructor of class: '%1!s!'. Error description: '%2!s!'.
Table '%1!s!' has no entry in the ml_table table
The %1!s! cursor is unexpectedly undefined
The %1!s! script returned %2!ld!
The .NET scripting VM requires version %1!s! of the MobiLink ODBC Bridge DLL, but was supplied version %2!s! instead.
The .NET scripting VM requires version %1!s! of the MobiLink Script DLL, but was supplied version %2!s! instead.
The classpath '%1!s!' is too long.
The client cannot find the consolidated progress offset from the client transaction log(s)
The data layer name '%1!s!' id too long.
The download stream cannot be restarted for this user
The following non-daemon threads were destroyed: %1!s!
The length of the name of a publication, table, or column cannot be retrieved from the upload stream
The MobiLink synchronization server DLL or shared object version does not match the data layer DLL or shared object version
The MobiLink synchronization server was unable to calculate the timestamp precision on the consolidated database using the ml_scripts_modified table. Timestamp precision related warnings will not be generated
The MobiLink synchronization server was unable to modify the error message using the modify_error_message script
The MobiLink system table '%1!s!' is missing
The MobiLink system table '%1!s!' is missing column '%2!s!'
The MobiLink system table '%1!s!' is missing or a table column is missing
The monitor thread was unable to communicate with the remote monitor.
The name '%1!s!' is not a valid name for a .NET start class.
The option '%1!s!' needs a path.
The options '%1!s!' and '%2!s!' must not be used together.
The prepared SQL statement '%1!s!' requires %2!s! parameters, but %3!s! parameters were supplied.
The prepared SQL statement '%1!s!' requires %2!s! parameters, but parameter %3!s! was not supplied.
The publication, table, or column name received from the client is too long: the length is %1!d!
The remote database may have been restored from backup, or perhaps user name '%1!s!' is being used by different remote databases. Set ml_user.commit_state to zero to re-enable synchronizations for this user
The row is too big. The size (%1!ld! bytes) exceeds the maximum allowable size (%2!ld! bytes)
The synchronization sequence number stored in ml_user.commit_state is negative. Set this value to zero (0) to re-enable synchronizations for user '%1!s!'
The upload stream is too short: should be at least %1!d! bytes, but received %2!d! bytes
The user name '%1!s!' is already synchronizing. Concurrent synchronizations using the same user name are not allowed
There are no entries in the JVM config file: %1!s!
There are no registered script versions. Unable to synchronize a client created prior to version 7.0.0
There are too many entries in the JVM config file: %1!s!
There is no download data script defined for table: %1!s!. If you want to be able to synchronize anyway, with the risk of potentially losing download data, use the -fr switch
There is no upload data script defined for table: %1!s!. If you want to be able to synchronize anyway, with the risk of potentially losing upload data, use the -fr switch
This connection will be abandoned due to previous errors
Too many bind parameters in script (expecting %1!ld! but found %2!ld!): %3!s!
Too many options sent to Java VM.
Transactions on this connection cannot be committed or rolled back.
Two scripts on the same connection have different classes.\nThe connection class is: '%1!s!'\nThe current script has class: '%2!s!' and method: '%3!s!'.
Unable find shared components directory.\nJRE location is not specified in options.\nJRE location is unknown!
Unable to access the JRE at: %1!s!
Unable to allocate a connection
Unable to allocate an input/output cursor
Unable to allocate memory needed for script execution.\n
Unable to attach JDBC connection.
Unable to attach worker to VM.\n
Unable to authenticate user %1!s!
Unable to COMMIT Transaction: %1!s! -- Attempting to ROLLBACK
Unable to connect to the consolidated database. Aborting the synchronization
Unable to convert the string %1!s! to a numeric value
Unable to create new database connection.
Unable to create the background thread.
Unable to create the monitoring thread.
Unable to create worker thread %1!lu!
Unable to delete from table '%1!s!' using %2!s!
Unable to delete user name '%1!s!' from the ml_user_table
Unable to detach worker from VM.\n
Unable to determine the remote user name
Unable to determine the remote user password
Unable to determine the remote version
Unable to dump exception information. Received exception while processing exception.
Unable to execute script '%1!s!'
Unable to fetch from table '%1!s!' using %2!s!
Unable to find file '%1!s!'.\n
Unable to find the JAR file: '%1!s!' in install directory or classpath.
Unable to flush scripts
Unable to generate scripts for version '%1!s!'
Unable to generate scripts for version '%1!s!', because the client doesn't supply column names of tables
Unable to initialize authentication subsystem
Unable to initialize communications stream %1!lu!: %2!s!
Unable to initialize consolidated database interface
Unable to initialize ODBC
Unable to initialize the resource DLL or shared object '%1!s!'
Unable to insert into table '%1!s!' using %2!s!
Unable to insert user name '%1!s!' into the ml_user table
Unable to launch the command: (%1!s!). The system error code is %2!d!
Unable to load .NET CLR Host DLL.\n
Unable to load .NET Framework CLR Version %1!s!.\n
Unable to load Assembly '%1!s!' into domain '%2!s!'.
Unable to load dll %1!s! for stream %2!lu!: %3!s!
Unable to load dll: %1!s!
Unable to load entry points from DLL: '%1!s!'
Unable to load entry points from dll: '%1!s!'.
Unable to load entry points from dll: '%1!s!'.
Unable to load the Java VM due to a memory error.
Unable to load the Java VM due to a version error.
Unable to load the Java VM due to an unknown error
Unable to load the Java VM shared library.\nMake sure that the shared library path is set correctly and that LD_PRELOAD is set correctly and supported by your version of the dynamic loader.
Unable to load UNILIB collation %1!d!: %2!s!
Unable to load UNILIB collation %1!d!: error %2!d!
Unable to load UNILIB collation expansion factor: error %1!d!
Unable to locate .NET Domain Configuration File '%1!s!'.
Unable to open %1!s!
Unable to open temporary file '%1!s!'.
Unable to parse class and method name from script: %1!s!
Unable to pass a remote monitoring request to the monitor thread. Only one remote monitor may be connected at a time.
Unable to resolve script. Two methods with name: '%1!s!' found in class: '%2!s!'.
Unable to retry the current transaction after deadlock in the consolidated database. The retry limit has been reached
Unable to ROLLBACK Transaction: %1!s!
Unable to shutdown .NET scripting VM. %1!s! workers still attached.
Unable to shutdown .NET scripting VM.
Unable to update table '%1!s!' using %2!s!
Unrecognized data layer command line switch (%1!s!).
Unrecognized domain id %1!d!
Unrecognized event name: %1!s!.
Unrecognized value (%1!ld!) in ml_user.commit_state. The state information for this user is probably corrupted.
Upload failed with client error %1!d!
User name '%1!s!' not found in the ml_user table
Version '%1!s!' not found in the ml_script_version table. Cannot synchronize
Version mismatch with DLL or shared object: '%1!s!'\nExpected version: %2!d! got version: %3!d!


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

%1!s!

Item | Value
Error code | –10133
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

%1!s! is an unknown child of ScriptExecutionException.

Item | Value
Error code | –10120
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

'%1!s!'.

Item | Value
Error code | –10206
Parameter 1 | AN error message.
Probable cause

Error messages generated by .Net CLR.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

.NET CLR Host encountered unexpected error.\n

Item | Value
Error code | –10167


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

.NET Domain Configuration File is corrupt.

Item | Value
Error code | –10176


A downloaded value for table %1!s! (column #%2!ld!) contains character data that cannot be converted.

Item | Value
Error code | –10211
Parameter 1 | Table name and column ID.
Probable cause

Character data originating from the consolidated database needs to be translated before being sent to the client. However the MobiLink synchronization server was not able to translate the data.


A downloaded value for table '%1!s!' (column #%2!ld!) was an invalid unique identifier string.

Item | Value
Error code | –10216
Parameter 1 | Table name and column index.
Probable cause

The MobiLink synchronization server cannot convert the string to a unique identifier. Please use a CHAR or VARCHAR data type in the non-ASA consolidated database to map UNIQUEIDENTIFIER in the remote database and make sure the string in the consolidated database is a valid unique identifier.


A downloaded value for table %1!s! (column #%2!ld!) was either too big or invalid for the remote schema type

Item | Value
Error code | –10038
Parameter 1 | Table name and column index.
Probable cause

The column width for the given table may not be defined consistently in the consolidated and remote databases. Please check the table definition.


A network read failed. Unable to read data from the remote client

Item | Value
Error code | –10030
Probable cause

The MobiLink synchronization server was unable to complete a network read. Please check the network.


A protocol error occurred when attempting to retrieve the remote client's synchronization log

Item | Value
Error code | –10059
Probable cause

There was a protocol error when the MobiLink synchronization server was retrieving the client error file. Please make sure that the client is supported by your version of the MobiLink synchronization server.


An error occurred when trying to store progress information in the consolidated database

Item | Value
Error code | –10031
Probable cause

The MobiLink synchronization server is unable to save the synchronization status into the consolidated database. Please make sure that the database server is running and the network is okay.


An error occurred while uploading a deleted row into table '%1!s!'. The deleted column values are as follows:

Item | Value
Error code | –10062
Parameter 1 | The script name.
Probable cause

A failure occurred when the MobiLink synchronization server was uploading a deleted row into the given table in the consolidated database.


An error occurred while uploading an insert row into table '%1!s!'. The inserted column values are as follows:

Item | Value
Error code | –10061
Parameter 1 | The script name.
Probable cause

A failure occurred when the MobiLink synchronization server was uploading an inserted row into the given table in the consolidated database.


An error occurred while uploading an updated row into table '%1!s!'. The updated column values are as follows:

Item | Value
Error code | –10063
Parameter 1 | The script name.
Probable cause

A failure occurred when the MobiLink synchronization server was uploading an updated row into the given table in the consolidated database.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Assembly '%1!s!' does not contain '%2!s!'.

Item | Value
Error code | –10172


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Assembly '%1!s!' was compiled against version %2!s! of '%3!s!'. Please recompile against version %4!s!.

Item | Value
Error code | –10171


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Attempt to execute a SQL statement with bound parameters before MLDBCommand.Prepare() was been called.

Item | Value
Error code | –10199


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Attempt to execute null SQL statement. Set value of MLDBCommand.CommandText before calling a MLDBCommand.Execute method.

Item | Value
Error code | –10196


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Attempt to execute SQL statement '%1!s!' after MLDBCommand.Close() was called.

Item | Value
Error code | –10197


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Attempt to prepare null SQL statement. Set value of MLDBCommand.CommandText before calling MLDBCommand.Prepare().

Item | Value
Error code | –10195


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Attempt to prepare SQL statement '%1!s!' after MLDBCommand.Close() was called.

Item | Value
Error code | –10194


Attempt to set non-null column to null

Item | Value
Error code | –10029
Probable cause

The MobiLink synchronization server attempted to download a null into a non-nullable column.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Attempt to use a connection with an invalid handle.

Item | Value
Error code | –10203


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Bad stream specification: %1!s!

Item | Value
Error code | –10105
Parameter 1 | The stream name.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Bad stream type: %1!s!

Item | Value
Error code | –10106
Parameter 1 | The stream type.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Binding of parameter %1!s! requires value to be of type '%2!s!', but a '%3!s!' was supplied.

Item | Value
Error code | –10201


Cannot convert '%1!s!' to Unicode

Item | Value
Error code | –10016
Parameter 1 | String to be converted.
Probable cause

The MobiLink synchronization server was not able to convert the given string to Unicode using Unilib.


Cannot directly determine the name of the table referenced by the cursor. The table name is required for inserts, updates, and deletes when using the Microsoft ODBC Cursor Library

Item | Value
Error code | –10045
Probable cause

The MobiLink synchronization server cannot directly determine the name of the table referenced by the upload cursor. The table name is required for inserts, updates, and deletes when using the Microsoft ODBC Cursor Library.


Cannot load DLL or shared object: '%1!s!' for Script Language: '%2!s!'

Item | Value
Error code | –10086
Parameter 1 | The DLL or shared object name and the script language name.
Probable cause

Please make sure that the script language is valid. Currently the script languages supported by the MobiLink synchronization server are SQL (sql), Java (java) and .NET (dnet).


Cannot load dll: '%1!s!' for Data Layer: '%2!s!'.

Item | Value
Error code | –10103
Parameter 1 | The DLL name and the data layer name.
Probable cause

Please make sure the data layer is correct. Currently the data layers supported by MobiLink server are 'ODBC' and 'DOTNET'.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Caught JAVA exception with type: %1!s!.\nException message: %2!s!

Item | Value
Error code | –10118
Parameter 1 |
Parameter 2 |


Client is unable to process truncate table request for table '%1!s!'

Item | Value
Error code | –10089
Parameter 1 | The name of a table.
Probable cause

The download_delete_cursor script is requesting that the table be truncated. The client needs to be updated to a newer version in order to process this action.


Collation not supported by this server

Item | Value
Error code | –10006
Probable cause

Old clients were trying to send Unicode-based strings (strings in UTF8). Please upgrade the client.


Consolidated database server or ODBC error: %1!s!

Item | Value
Error code | –10002
Parameter 1 | The actual error message sent by the database server or ODBC driver.
Probable cause

This may be a SQL error such as a syntax error.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Could not call method: '%1!s!' with arguments of types '%2!s!'.

Item | Value
Error code | –10157
Parameter 1 |
Parameter 2 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Could not create domain '%1!s!'.

Item | Value
Error code | –10192


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Domain '%1!s!' was not specified in Domain configuration file.

Item | Value
Error code | –10178


Download failed with client error %1!d!

Item | Value
Error code | –10035
Parameter 1 | An error number sent by the client.
Probable cause

The MobiLink synchronization server aborts the synchronization when the client indicates there is a problem on the remote site during download.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Download stream encountered error in remote database

Item | Value
Error code | –10036
Probable cause

The client indicates that the download failed.


Error fetching connection script %1!s!

Item | Value
Error code | –10018
Parameter 1 | Connection script name.
Probable cause

The MobiLink synchronization server was not able to refresh connection scripts. Please make sure that the database server is running and the network is okay.


Error fetching table script %1!s!.%2!s!

Item | Value
Error code | –10019
Parameter 1 | Table and script name.
Probable cause

The MobiLink synchronization server was not able to refresh table scripts. Please make sure that the database server is running and the network is okay.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Error while attaching worker thread to Java VM.

Item | Value
Error code | –10126


Exception thrown in constructor of class: '%1!s!'. Error description: '%2!s!'.\nStack trace: '%3!s!'.

Item | Value
Error code | –10154
Parameter 1 |
Parameter 2 |
Parameter 3 |


Exception thrown in initializer of class: '%1!s!'. Error description: '%2!s!'.\nStack trace: '%3!s!'.

Item | Value
Error code | –10149
Parameter 1 |
Parameter 2 |
Parameter 3 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Exception thrown in method: '%1!s!'. Error description: '%2!s!'.\nStack trace: '%3!s!'.

Item | Value
Error code | –10158
Parameter 1 |
Parameter 2 |
Parameter 3 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Expected <void> or an object, but a primitive of type '%1!s!' was returned instead.

Item | Value
Error code | –10131
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Expected an instance of ianywhere.ml.script.RowReader or subclass, but found class '%1!s!' instead.

Item | Value
Error code | –10135
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Expected an instance of java.lang.String or subclass, but found class '%1!s!' instead.

Item | Value
Error code | –10134
Parameter 1 |


Expecting %1!ld! authentication parameter(s) from client, but received %2!ld! for script %3!s!

Item | Value
Error code | –10094
Parameter 1 | The number of parameters expected, the number of parameters passed up from the client, and the script that needs the parameters.
Probable cause

The number of authentication parameters received from the client does not match the number expected. The number of client parameters should be two less than the number required by the authenticate_parameters script.


Expecting %1!ld! columns in cursor, but found %2!ld!

Item | Value
Error code | –10050
Parameter 1 | The number of columns expected and the number of columns found.
Probable cause

The number of parameters found in the upload or download script does not match the number of columns or the number of primary key columns for the given table. Please check the number of parameters for the given script.


Expecting %1!ld! parameters in script, but only found %2!ld!: %3!s!

Item | Value
Error code | –10047
Parameter 1 | The number of parameters expected, the number of parameters found, and the script name.
Probable cause

There are too many parameters found in the given script. Please check the number of parameters for the given script.


Expecting at least %1!ld! parameters in script, but only found %2!ld!: %3!s!

Item | Value
Error code | –10048
Parameter 1 | The minimum number of parameters expected, the number of parameters found, and the script name.
Probable cause

There are not enough parameters found in the given script. Please check the number of parameters for the given script.


Extraneous data found in upload stream

Item | Value
Error code | –10040
Probable cause

The client has sent extraneous data to the MobiLink synchronization server. Please check that the client is supported by your MobiLink synchronization server.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Failed to load .NET start class '%1!s!'.

Item | Value
Error code | –10187


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Failed to load necessary Java class: %1!s!

Item | Value
Error code | –10127
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Failed to load necessary method: '%1!s!' for Java class: %2!s!

Item | Value
Error code | –10128
Parameter 1 |
Parameter 2 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Failure executing script '%1!s!'.

Item | Value
Error code | –10205


INTERNAL ERROR: occurred while retrieving a BLOB -- null

Item | Value
Error code | –10042
Probable cause

The MobiLink synchronization server cannot retrieve the upload data from memory or a temporary file. This is an internal error. Please contact technical support.


INTERNAL ERROR: occurred while retrieving a BLOB -- read

Item | Value
Error code | –10041
Probable cause

The MobiLink synchronization server cannot retrieve the upload data from memory or a temporary file. This is an internal error. Please contact technical support.


INTERNAL ERROR: occurred while retrieving a BLOB -- zero length

Item | Value
Error code | –10043
Probable cause

The MobiLink synchronization server cannot retrieve the upload data from memory or a temporary file. This is an internal error. Please contact technical support.


INTERNAL ERROR: occurred while storing a BLOB -- write

Item | Value
Error code | –10044
Probable cause

The MobiLink synchronization server cannot store the upload data to memory or a temporary file. This is an internal error. Please contact technical support.


Internal error: wrong function '%1!s!' called. Please contact technical support

Item | Value
Error code | –10051
Parameter 1 | The function name.
Probable cause

This is an internal error. Please contact technical support.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Internal error: '%1!s!'.

Item | Value
Error code | –10156
Parameter 1 |


Invalid context for stream parameter %1!s! for stream %2!d!: %3!s!

Item | Value
Error code | –10219
Parameter 1 | Parameter name, stream number and stream specification.
Probable cause

The given parameter is not valid for this stream. Some parameters may be specified in a server environment but not for a client.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Invalid format used for script '%1!s!'.

Item | Value
Error code | –10182


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Invalid line found in the JVM config file: %1!s!.\nLine is too long.

Item | Value
Error code | –10137
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Invalid line found in the JVM config file: %1!s!\nAll lines must begin with either '#' or '-'.

Item | Value
Error code | –10136
Parameter 1 |


Invalid parameter '%1!s!'.

Item | Value
Error code | –10215
Parameter 1 | Name of the invalid parameter.
Probable cause

One or more invalid parameters were detected in the communication protocol. Please check the command line switches and make sure all the protocol options valid.


Invalid password for user %1!s!

Item | Value
Error code | –10057
Parameter 1 | The user name.
Probable cause

The password sent up from the remote is invalid for the given user. Please note: passwords are case sensitive.


Invalid return value (%2!ld!) from the !1!s! script. Using the default action code (%3!ld!).

Item | Value
Error code | –10214
Parameter 1 | Name of the script returning the bad value.
Parameter 2 | Action value return from script.
Parameter 3 | Action value to be used.
Probable cause

The error handler script called returned a value outside of the allowable range. The default value will be used.


Invalid stream parameter %1!s! for stream %2!d!: %3!s!

Item | Value
Error code | –10217
Parameter 1 | Parameter name, stream number and stream specification.
Probable cause

The given parameter is not valid for this stream. Check for misspelling.


Invalid value %1!s! stream parameter %2!s! for stream %3!d!: %4!s!

Item | Value
Error code | –10218
Parameter 1 | Parameter value and name, stream number and stream specification.
Probable cause

The value for the given parameter is not valid for this stream.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Java exception...

Item | Value
Error code | –10148


LANG: %1!s! - Failed to attach worker thread

Item | Value
Error code | –10084
Parameter 1 | The name of the script language.
Probable cause

A MobiLink server worker thread could not attach itself to the DLL or shared object used to process the given script language. Please make sure that the MobiLink server installation contains all of the required DLLs or shared objects.


LANG: %1!s! = Failed to allocate database connection

Item | Value
Error code | –10085
Parameter 1 | The name of the script language.
Probable cause

A connection cannot be made to the database server.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Linkage error while loading class: '%1!s!' Error description: '%2!s!'.

Item | Value
Error code | –10150
Parameter 1 |
Parameter 2 |


Memory allocation failed

Item | Value
Error code | –10060
Probable cause

Your system is running out of memory. You may need to close some applications or add more memory to your system.


Memory allocation failed, attempted to allocate %1!lu! bytes

Item | Value
Error code | –10003
Parameter 1 | The number of bytes it was trying to allocate.
Probable cause

Your system is running out of memory. You may need to close some applications or add more memory to your system.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

No Assembly in domain '%1!s!' contains type '%2!s!'.

Item | Value
Error code | –10179


No download confirmation from remote database

Item | Value
Error code | –10034
Probable cause

The client attempted to send a confirmation status to the MobiLink synchronization server after download. The MobiLink synchronization server did not receive this confirmation. This could happen if the synchronization is interrupted or if there is a network problem.


No error or unknown error

Item | Value
Error code | 0
Probable cause

This code indicates there was either no error or an unknown error. The MobiLink synchronization server did not assign an error number.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

No public methods found in script class: '%1!s!'.

Item | Value
Error code | –10151
Parameter 1 |


No server connection string specified

Item | Value
Error code | –10070
Probable cause

There is no server connection string specified in the MobiLink synchronization server command line. Please specify the connection string in the MobiLink synchronization server command line using the -c option.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

No suitable constructor found in class: '%1!s!'.

Item | Value
Error code | –10153
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

No valid constructor was found for type '%1!s!'.

Item | Value
Error code | –10161


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Not enough arguments to execute script: '%1!s!.%2!s!'.\n %3!d! arguments are needed only %4!d! are available.

Item | Value
Error code | –10130
Parameter 1 |


Not enough worker threads are available to handle all streams, specify at least %1!d! more

Item | Value
Error code | –10098
Parameter 1 | The number of extra worker threads required.
Probable cause

Increase the number of worker threads using the -w option.


Old versions of MobiLink clients cannot ping the MobiLink synchronization server

Item | Value
Error code | –10005
Probable cause

Ping is available only from version 8.0.1 and up.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

One or more invalid parameters

Item | Value
Error code | –10109


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Only one Domain can be used per script version. Domain '%1!s!' was in use when script '%2!s!' attempted to use Domain '%3!s!'.

Item | Value
Error code | –10183


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Option '%1!s!' is invalid or was not specified correctly on MobiLink command line.\n

Item | Value
Error code | –10163
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Option '%1!s!' was previously defined on MobiLink command line with value '%2!s!'.\n

Item | Value
Error code | –10162
Parameter 1 |
Parameter 2 |


Protocol error

Item | Value
Error code | –10001
Probable cause

The MobiLink synchronization server does not understand the request sent by the client. This could happen if the client is newer than the MobiLink synchronization server.


Protocol error: an invalid timestamp precision of %1!d! was sent from the remote

Item | Value
Error code | –10014
Parameter 1 | Timestamp precision sent by the client.
Probable cause

The timestamp precision must be greater than 0 and less than 6.


Protocol error: client requests an unsupported capability (%1!s!)

Item | Value
Error code | –10015
Parameter 1 | Capability bit.
Probable cause

The MobiLink synchronization server does not support the capability requested by the client. Please make sure that you are not using a newer client to talk to an older MobiLink synchronization server.


Protocol error: there is no publication that contains table '%1!s!'

Item | Value
Error code | –10017
Parameter 1 | Table name.
Probable cause

A table is requested for synchronization by the client. However the table is not in any publication. Please make sure that the table was not dropped in the remote database.


Protocol version mismatch

Item | Value
Error code | –10004
Probable cause

The MobiLink synchronization server is communicating with the client using different protocol versions. If the client sends a version that is not supported by the MobiLink synchronization server, it will give this error. Please make sure that you are not using a newer client (DBMLSync or an UltraLite application) to talk to an older version of the MobiLink synchronization server.


Required ODBC function %1!s! is not supported by the driver

Item | Value
Error code | –10075
Parameter 1 | The ODBC function name.
Probable cause

The MobiLink synchronization server was not able to find the function from the ODBC driver. Please start the MobiLink synchronization server with the recommended ODBC drivers.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Returned class '%1!s!' not a subclass of ianywhere.ml.script.RowReader or java.lang.String.

Item | Value
Error code | –10132
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Script '%1!s!' encountered an error.

Item | Value
Error code | –10189


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Script '%1!s!' is a member of '%2!s!', but only %3!s! classes are permitted per script version.

Item | Value
Error code | –10204


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Script '%1!s!' reported a fatal error.

Item | Value
Error code | –10190


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Script '%1!s!' reported a server error.

Item | Value
Error code | –10188


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Script '%1!s!' reported a synchronization error.

Item | Value
Error code | –10186


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Script '%1!s!' requires %2!s! parameters, but %3!s! parameters were supplied.

Item | Value
Error code | –10184


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Script '%1!s!' returned an object of type '%2!s!', which is not a subtype of 'System.Void' or 'System.String'.

Item | Value
Error code | –10185


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Script '%1!s!' returns a '%2!s!' object, but only return types of 'System.Void' and 'System.String' are supported.

Item | Value
Error code | –10173


Scripts cannot be defined as NULL

Item | Value
Error code | –10039
Probable cause

Scripts cannot be defined as NULL or empty string. Please check the script definitions to make sure that no script is defined as NULL or empty string.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Shared install directory is incorrect: %1!s!

Item | Value
Error code | –10144
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Stream Error: %1!s!

Item | Value
Error code | –10117


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

System exception thrown in constructor of class: '%1!s!'. Error description: '%2!s!'.

Item | Value
Error code | –10155
Parameter 1 |
Parameter 2 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Table '%1!s!' has no entry in the ml_table table

Item | Value
Error code | –10101
Parameter 1 | Table name.


The %1!s! cursor is unexpectedly undefined

Item | Value
Error code | –10025
Parameter 1 | Cursor script name.
Probable cause

This is an internal error. Please contact technical support.


The %1!s! script returned %2!ld!

Item | Value
Error code | –10052
Parameter 1 | The user authentication script name and the script returning value.
Probable cause

The user authentication script returned a value greater than 3000.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

The .NET scripting VM requires version %1!s! of the MobiLink ODBC Bridge DLL, but was supplied version %2!s! instead.

Item | Value
Error code | –10174


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

The .NET scripting VM requires version %1!s! of the MobiLink Script DLL, but was supplied version %2!s! instead.

Item | Value
Error code | –10175


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

The classpath '%1!s!' is too long.

Item | Value
Error code | –10141
Parameter 1 |


The client cannot find the consolidated progress offset from the client transaction log(s)

Item | Value
Error code | –10090
Probable cause

When the progress offsets in the consolidated and the remote databases are different, the MobiLink synchronization server may ask the client to redo the synchronization again with the progress offset from the consolidated database. However the requested consolidated progress offset cannot be found in the transaction log(s) of the remote database because the old transaction logs have been deleted or the requested offset has not been created yet.

Please find the source that caused this problem, and then rerun dbmlsync using the -ra or -rb option.


The data layer name '%1!s!' id too long.

Item | Value
Error code | –10102
Parameter 1 | The data layer name.
Probable cause

Please make sure the data layer is correct. Currently the data layers supported by MobiLink server are 'ODBC' and 'DOTNET'.


The download stream cannot be restarted for this user

Item | Value
Error code | –10097
Probable cause

The download stream requested cannot be restarted. The server may have download caching disabled, or the cached download may have expired.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

The following non-daemon threads were destroyed: %1!s!

Item | Value
Error code | –10124
Parameter 1 |


The length of the name of a publication, table, or column cannot be retrieved from the upload stream

Item | Value
Error code | –10079
Probable cause

The client sent the MobiLink synchronization server the lengths of the names of publications, tables, and table columns. Please check the network.


The MobiLink synchronization server DLL or shared object version does not match the data layer DLL or shared object version

Item | Value
Error code | –10081
Probable cause

The MobiLink synchronization server DLL or shared object that processes the upload and download data is not consistent with the version of the data layer DLL or shared object (ODBC) that is used to interact with the databases. Please check your MobiLink synchronization server installation.


The MobiLink synchronization server was unable to calculate the timestamp precision on the consolidated database using the ml_scripts_modified table. Timestamp precision related warnings will not be generated

Item | Value
Error code | –10076


The MobiLink synchronization server was unable to modify the error message using the modify_error_message script

Item | Value
Error code | –10077
Probable cause

An error occurred during synchronization, but the MobiLink synchronization server was unable to modify the error message using the given script. Please check your modify_error_message script.


The MobiLink system table '%1!s!' is missing

Item | Value
Error code | –10095
Parameter 1 | The name of the table.
Probable cause

The table cannot be loaded from the consolidated database. The MobiLink tables may not have been installed or an upgrade may be required.


The MobiLink system table '%1!s!' is missing column '%2!s!'

Item | Value
Error code | –10096
Parameter 1 | The name of the table and column.
Probable cause

The table column cannot be loaded from the consolidated database. An upgrade may be required.


The MobiLink system table '%1!s!' is missing or a table column is missing

Item | Value
Error code | –10100
Parameter 1 | The name of the table.
Probable cause

The table or table column cannot be found in the consolidated database. The MobiLink tables may not have been installed or an upgrade may be required.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

The monitor thread was unable to communicate with the remote monitor.

Item | Value
Error code | –10116


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

The name '%1!s!' is not a valid name for a .NET start class.

Item | Value
Error code | –10177


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

The option '%1!s!' needs a path.

Item | Value
Error code | –10140
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

The options '%1!s!' and '%2!s!' must not be used together.

Item | Value
Error code | –10139
Parameter 1 |
Parameter 2 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

The prepared SQL statement '%1!s!' requires %2!s! parameters, but %3!s! parameters were supplied.

Item | Value
Error code | –10200


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

The prepared SQL statement '%1!s!' requires %2!s! parameters, but parameter %3!s! was not supplied.

Item | Value
Error code | –10198


The publication, table, or column name received from the client is too long: the length is %1!d!

Item | Value
Error code | –10078
Parameter 1 | The length of the name.
Probable cause

The client sent the MobiLink synchronization server the lengths of the names of publications, tables, and table columns. These names should be less than 128 bytes long. Please check the names of publications, table, and columns.


The remote database may have been restored from backup, or perhaps user name '%1!s!' is being used by different remote databases. Set ml_user.commit_state to zero to re-enable synchronizations for this user

Item | Value
Error code | –10023
Parameter 1 | User name.
Probable cause

Before doing synchronization, the MobiLink synchronization server compares the sequence number sent by the client with that stored in the consolidated database to see if they match. If a remote database is restored from a backup or the last synchronization was interrupted, the sequence number may be less than that in the consolidated. Please set ml_user.commit_state to zero to re-enable synchronizations for this user.


The row is too big. The size (%1!ld! bytes) exceeds the maximum allowable size (%2!ld! bytes)

Item | Value
Error code | –10033
Parameter 1 | The actual row size to be downloaded and the maximum row size the
Parameter 2 | client is willing to accept.
Probable cause

An UltraLite application may have a row size limit. If the row size in the synchronization table in the consolidated database has exceeded this limit, the table cannot be downloaded. Please redesign your synchronization table.


The synchronization sequence number stored in ml_user.commit_state is negative. Set this value to zero (0) to re-enable synchronizations for user '%1!s!'

Item | Value
Error code | –10022
Parameter 1 | User name.
Probable cause

The sequence number stored in the ml_user table in the consolidated database is negative. This number is maintained by the MobiLink synchronization server. In most cases, please do not directly modify this number.


The upload stream is too short: should be at least %1!d! bytes, but received %2!d! bytes

Item | Value
Error code | –10026
Parameter 1 | The number of bytes that are expected and the number of bytes that are actually received.
Probable cause

The MobiLink server received a connection that did not send enough data. Please check the remote for communication problems. Also check for an agent that is mistakenly connecting to MobiLink server. Also check for an unfriendly agent attempting to disrupt the MobiLink server.


The user name '%1!s!' is already synchronizing. Concurrent synchronizations using the same user name are not allowed

Item | Value
Error code | –10053
Parameter 1 | The user name.
Probable cause

The given user name is already synchronizing. Please try the synchronization later.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

There are no entries in the JVM config file: %1!s!

Item | Value
Error code | –10138
Parameter 1 |


There are no registered script versions. Unable to synchronize a client created prior to version 7.0.0

Item | Value
Error code | –10012
Probable cause

The client-requested script version was not defined in the consolidated database. Please create the scripts for the specified version in the consolidated database or use the -za option in the MobiLink synchronization server command line to allow the MobiLink synchronization server to generate active scripts.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

There are too many entries in the JVM config file: %1!s!

Item | Value
Error code | –10147
Parameter 1 |


There is no download data script defined for table: %1!s!. If you want to be able to synchronize anyway, with the risk of potentially losing download data, use the -fr switch

Item | Value
Error code | –10093
Parameter 1 | The name of a table.
Probable cause

If there is no download data script for a table and synchronization is download only, there is a risk of potentially losing the download data. To prevent this situation, the synchronization is aborted. If you do not care about losing download data, you can use -fr to force the synchronization to continue.


There is no upload data script defined for table: %1!s!. If you want to be able to synchronize anyway, with the risk of potentially losing upload data, use the -fr switch

Item | Value
Error code | –10092
Parameter 1 | The name of a table.
Probable cause

If there is no upload data script for a table, there is a risk of potentially losing the upload data. To prevent this situation, the synchronization is aborted. If you do not care about losing upload data, you can use -fr to force the synchronization to continue.


This connection will be abandoned due to previous errors

Item | Value
Error code | –10091
Probable cause

Due to the severity of error(s) encountered processing the upload stream, further work will be futile. This is probably due to an I/O error or a protocol problem.


Too many bind parameters in script (expecting %1!ld! but found %2!ld!): %3!s!

Item | Value
Error code | –10049
Parameter 1 | The number of parameters expected, the number of parameters found, and the script name.
Probable cause

There are too many parameters found in the given script. Please check the number of parameters for the given script.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Too many options sent to Java VM.

Item | Value
Error code | –10146


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Transactions on this connection cannot be committed or rolled back.

Item | Value
Error code | –10202


Two scripts on the same connection have different classes.\nThe connection class is: '%1!s!'\nThe current script has class: '%2!s!' and method: '%3!s!'.

Item | Value
Error code | –10129
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable find shared components directory.\nJRE location is not specified in options.\nJRE location is unknown!

Item | Value
Error code | –10143


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to access the JRE at: %1!s!

Item | Value
Error code | –10145
Parameter 1 |


Unable to allocate a connection

Item | Value
Error code | –10067
Probable cause

The MobiLink synchronization server was not able to allocate a connection. Please make sure that there is enough memory to start the MobiLink synchronization server. Also, make sure that the database server is running, and that the user ID and password are valid.


Unable to allocate an input/output cursor

Item | Value
Error code | –10046
Probable cause

A failure occurred when the MobiLink synchronization server was trying to allocate memory for upload table scripts. Your system is running out of memory. You may need to close some applications or add more memory to your system.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to allocate memory needed for script execution.\n

Item | Value
Error code | –10170


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to attach JDBC connection.

Item | Value
Error code | –10160


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to attach worker to VM.\n

Item | Value
Error code | –10168


Unable to authenticate user %1!s!

Item | Value
Error code | –10055
Parameter 1 | The user name.
Probable cause

The MobiLink synchronization server was not able to authenticate the given user.


Unable to COMMIT Transaction: %1!s! -- Attempting to ROLLBACK

Item | Value
Error code | –10065
Parameter 1 | The script name.
Probable cause

The MobiLink synchronization server was not able to commit the transaction for the given script. Writing scripts to avoid deadlocks is always a good practice.


Unable to connect to the consolidated database. Aborting the synchronization

Item | Value
Error code | –10028
Probable cause

The MobiLink synchronization server was not able to make a connection to the consolidated database server. Please make sure that the database server is running and the network is okay.


Unable to convert the string %1!s! to a numeric value

Item | Value
Error code | –10213
Parameter 1 | String to be converted.
Probable cause

The MobiLink synchronization server cannot convert the string to a numeric value. This is an internal error. Please contact technical support.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to create new database connection.

Item | Value
Error code | –10159


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to create the background thread.

Item | Value
Error code | –10112


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to create the monitoring thread.

Item | Value
Error code | –10111


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to create worker thread %1!lu!

Item | Value
Error code | –10113


Unable to delete from table '%1!s!' using %2!s!

Item | Value
Error code | –10073
Parameter 1 | The table name and script name.
Probable cause

A failure occurred when the MobiLink synchronization server was deleting row(s) from the given table in the consolidated database.


Unable to delete user name '%1!s!' from the ml_user_table

Item | Value
Error code | –10083
Parameter 1 | The name of the user to be deleted.
Probable cause

Please check if the MobiLink user is valid and is not currently in use by other threads.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to detach worker from VM.\n

Item | Value
Error code | –10169


Unable to determine the remote user name

Item | Value
Error code | –10009
Probable cause

The user name that the client sent to the MobiLink synchronization server is invalid. Please make sure that the name is not longer than 128 bytes.


Unable to determine the remote user password

Item | Value
Error code | –10010
Probable cause

The MobiLink synchronization server was not able to read the remote user password from the stream.


Unable to determine the remote version

Item | Value
Error code | –10011
Probable cause

The MobiLink synchronization server was not able to read the user synchronization version from the stream.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to dump exception information. Received exception while processing exception.

Item | Value
Error code | –10119


Unable to execute script '%1!s!'

Item | Value
Error code | –10080
Parameter 1 | The name of the script.
Probable cause

Please check that the SQL statements in the script are valid.


Unable to fetch from table '%1!s!' using %2!s!

Item | Value
Error code | –10071
Parameter 1 | The table name and script name.
Probable cause

A failure occurred when the MobiLink synchronization server was retrieving row(s) from the given table in the consolidated database.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to find file '%1!s!'.\n

Item | Value
Error code | –10166
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to find the JAR file: '%1!s!' in install directory or classpath.

Item | Value
Error code | –10142
Parameter 1 |


Unable to flush scripts

Item | Value
Error code | –10020
Probable cause

The MobiLink synchronization server always updates its cached scripts at the beginning of each synchronization by connecting to the consolidated database server and querying the ml_scripts_modified table. The MobiLink synchronization server encountered a problem flushing the scripts.


Unable to generate scripts for version '%1!s!'

Item | Value
Error code | –10027
Parameter 1 | User version string.
Probable cause

The MobiLink synchronization server was not able to generate example scripts.


Unable to generate scripts for version '%1!s!', because the client doesn't supply column names of tables

Item | Value
Error code | –10210
Parameter 1 | User version string.
Probable cause

The MobiLink synchronization server was not able to generate example script, because the client doesn't supply the column names of the synchronization tables. If the client is an ASA client, DBMLSync, please use the extended option, scn=on to send column names to the MobiLink synchronization server.


Unable to initialize authentication subsystem

Item | Value
Error code | –10068
Probable cause

The MobiLink synchronization server was not able to initialize the user authentication layer. Your system may be running out of memory. You may need to close some applications or add more memory to your system.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to initialize communications stream %1!lu!: %2!s!

Item | Value
Error code | –10110


Unable to initialize consolidated database interface

Item | Value
Error code | –10069
Probable cause

The MobiLink synchronization server was not able to initialize the consolidated database interface layer. Please make sure that there is enough memory to start the MobiLink synchronization server and then start the MobiLink synchronization server with the recommended ODBC drivers.


Unable to initialize ODBC

Item | Value
Error code | –10066
Probable cause

The MobiLink synchronization server was not able to initialize the ODBC layer. Please make sure that there is enough memory to start the MobiLink synchronization server and then start the MobiLink synchronization server with the recommended ODBC drivers.


Unable to initialize the resource DLL or shared object '%1!s!'

Item | Value
Error code | –10082
Parameter 1 | A string that gives the name of the resource DLL or shared object.
Probable cause

Please check your MobiLink synchronization server installation.


Unable to insert into table '%1!s!' using %2!s!

Item | Value
Error code | –10072
Parameter 1 | The table name and script name.
Probable cause

A failure occurred when the MobiLink synchronization server was inserting row(s) into the given table in the consolidated database.


Unable to insert user name '%1!s!' into the ml_user table

Item | Value
Error code | –10054
Parameter 1 | The user name.
Probable cause

The MobiLink synchronization server was not able to add the given user into the ml_user table. Please verify that the consolidated database server is running and that the MobiLink user has permission to modify the ml_user table.


Unable to launch the command: (%1!s!). The system error code is %2!d!

Item | Value
Error code | –10037
Parameter 1 | Command and system return code.
Probable cause

The MobiLink synchronization server allows users to launch something between upload and download. However, the launch was unsuccessful.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to load .NET CLR Host DLL.\n

Item | Value
Error code | –10165


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to load .NET Framework CLR Version %1!s!.\n

Item | Value
Error code | –10164
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to load Assembly '%1!s!' into domain '%2!s!'.

Item | Value
Error code | –10193


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to load dll %1!s! for stream %2!lu!: %3!s!

Item | Value
Error code | –10108
Parameter 1 | The DLL name, stream type, and stream name.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to load dll: %1!s!

Item | Value
Error code | –10107
Parameter 1 | The DLL name.


Unable to load entry points from DLL: '%1!s!'

Item | Value
Error code | –10088
Parameter 1 | The DLL or shared object name.
Probable cause

Please check your MobiLink synchronization server installation.


Unable to load entry points from dll: '%1!s!'.

Item | Value
Error code | –10104
Parameter 1 | The DLL name.
Probable cause

Please check your MobiLink server installation.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to load entry points from dll: '%1!s!'.

Item | Value
Error code | –10114
Parameter 1 | The DLL name.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to load the Java VM due to a memory error.

Item | Value
Error code | –10122


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to load the Java VM due to a version error.

Item | Value
Error code | –10121


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to load the Java VM due to an unknown error

Item | Value
Error code | –10123


Unable to load the Java VM shared library.\nMake sure that the shared library path is set correctly and that LD_PRELOAD is set correctly and supported by your version of the dynamic loader.

Item | Value
Error code | –10220
Probable cause

The MobiLink synchronization server was not able to load the Java VM shared library. Please make sure that the Java VM shared library is installed, the path is set correctly, and the LD_PRELOAD is set correctly and supported by your version of the dynamic loader."


Unable to load UNILIB collation %1!d!: %2!s!

Item | Value
Error code | –10099
Parameter 1 | Unilib charset ID and Unilib error string.
Probable cause

The MobiLink synchronization server cannot initialize the Unilib converter. The installation may be damaged or the required collation is unavailable.


Unable to load UNILIB collation %1!d!: error %2!d!

Item | Value
Error code | –10007
Parameter 1 | Unilib charset ID and Unilib function return code.
Probable cause

The MobiLink synchronization server cannot initialize the Unilib converter.


Unable to load UNILIB collation expansion factor: error %1!d!

Item | Value
Error code | –10008
Parameter 1 | Unilib function return code.
Probable cause

The MobiLink synchronization server cannot determine the character expansion factor from the Unilib converter.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to locate .NET Domain Configuration File '%1!s!'.

Item | Value
Error code | –10191


Unable to open %1!s!

Item | Value
Error code | –10058
Parameter 1 | The script name.
Probable cause

The MobiLink synchronization server failed to execute the given table script. Please make sure that the script contains valid SQL.


Unable to open temporary file '%1!s!'.

Item | Value
Error code | –10212
Parameter 1 | File name.
Probable cause

The MobiLink synchronization server may use temporary files to store intermediate data. Please make sure the MobiLink synchronization server has permission to create temporary files.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to parse class and method name from script: %1!s!

Item | Value
Error code | –10125
Parameter 1 |


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to pass a remote monitoring request to the monitor thread. Only one remote monitor may be connected at a time.

Item | Value
Error code | –10115


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to resolve script. Two methods with name: '%1!s!' found in class: '%2!s!'.

Item | Value
Error code | –10152
Parameter 1 |
Parameter 2 |


Unable to retry the current transaction after deadlock in the consolidated database. The retry limit has been reached

Item | Value
Error code | –10021
Probable cause

The MobiLink synchronization server has retried the current transaction, but the deadlock problem still occurred. Please redesign your synchronization logic or use the -r MobiLink synchronization server command line option.


Unable to ROLLBACK Transaction: %1!s!

Item | Value
Error code | –10064
Parameter 1 | The script name.
Probable cause

The MobiLink synchronization server was not able to roll back the transaction.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to shutdown .NET scripting VM. %1!s! workers still attached.

Item | Value
Error code | –10181


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unable to shutdown .NET scripting VM.

Item | Value
Error code | –10180


Unable to update table '%1!s!' using %2!s!

Item | Value
Error code | –10074
Parameter 1 | The table name and script name.
Probable cause

A failure occurred when the MobiLink synchronization server was updating row(s) for the given table in the consolidated database.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unrecognized data layer command line switch (%1!s!).

Item | Value
Error code | –10209
Parameter 1 | The string of the command line switch


Unrecognized domain id %1!d!

Item | Value
Error code | –10024
Parameter 1 | Domain ID.
Probable cause

The client-requested domain ID (datatype) is not supported. Please make sure that your MobiLink synchronization server is up-to-date.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Error Messages

MobiLink synchronization server error descriptions

Unrecognized event name: %1!s!.

Item | Value
Error code | –10207
Parameter 1 | The name of the unrecognized event.


Unrecognized value (%1!ld!) in ml_user.commit_state. The state information for this user is probably corrupted.

Item | Value
Error code | –10208
Parameter 1 | The value of the sync status.


Upload failed with client error %1!d!

Item | Value
Error code | –10032
Parameter 1 | An error number sent by the client.
Probable cause

The MobiLink synchronization server aborted the synchronization because the client indicates there is a problem on the remote site during upload.


User name '%1!s!' not found in the ml_user table

Item | Value
Error code | –10056
Parameter 1 | The user name.
Probable cause

The MobiLink synchronization server could not find the user from the ml_user table. Please add this user to the ml_user table using mluser or start the MobiLink synchronization server with the -zu+ option.


Version '%1!s!' not found in the ml_script_version table. Cannot synchronize

Item | Value
Error code | –10013
Parameter 1 | Version string.
Probable cause

The client-specified version does not exist in the consolidated database. Please create a script version.


Version mismatch with DLL or shared object: '%1!s!'\nExpected version: %2!d! got version: %3!d!

Item | Value
Error code | –10087
Parameter 1 | The DLL or shared object name, expected version number and the actual version number.
Probable cause

Please check your MobiLink synchronization server installation.


MobiLink Synchronization Server Warning Messages

About this chapter

This chapter lists MobiLink synchronization server warnings, as well as their probable causes.

The warning messages are written to the MobiLink synchronization server message log.

Levels can be 1–5. The following table explains each level:

Level

Description

1

Server or high level ODBC warnings when a MobiLink synchronization server starts or shuts down

2

Synchronization and user level warnings when a synchronization starts and ends

3

Schema level (including publications and tables) warnings

4

Script and lower level ODBC warnings

5

Table and row level warnings

MobiLink synchronization server warning messages sorted by code
MobiLink synchronization server warning messages sorted by message
MobiLink synchronization server warning descriptions


MobiLink synchronization server warning messages sorted by code

Warning code | Level | Warning message
10001 | 1 | Maximum number of database connections set to %1!lu! (must be at least the number of worker threads plus one)
10002 | 1 | If needed, ODBC cursors will be used, via the Microsoft ODBC Cursor Library, to simulate SQLSETPOS for inserts, updates, and deletes
10003 | 1 | ODBC Isolation level (%1!s!) is not supported
10004 | 1 | ODBC function %1!s! is not supported by the driver
10005 | 1 | ODBC statement option %1!s! has changed from %2!s! (%3!lu!) to %4!s! (%5!lu!)
10006 | 1 | ODBC statement option %1!s! has changed from %2!lu! to %3!lu!
10007 | 2 | Retrying the begin_connection transaction after deadlock in the consolidated database
10008 | 2 | Retry on deadlock is disabled. The MobiLink synchronization server is using an internal workaround which requires this setting
10009 | 2 | MobiLink table '%1!s!' is damaged
10010 | 2 | No handle_error script is defined. The default action code (%1!ld!) will decide the error behavior
10011 | 2 | Unrecognized value (%1!ld!) in ml_user.commit_state. The state information for this user is probably corrupted
10012 | 2 | The consolidated and remote databases disagree on when the last synchronization took place. The remote is being asked to send a new upload that starts at the last known synchronization point
10013 | 4 | Expecting %1!ld! parameter(s) in cursor, but found %2!ld!
10014 | 4 | Expecting at most %1!ld! parameter(s) in cursor, but found %2!ld!
10015 | 3 | Table '%1!s!' has at least one timestamp column. Due to a timestamp precision mismatch, uploaded timestamps can lose precision, defeating download filtering
10016 | 3 | Table '%1!s!' has at least one timestamp column. Due to a timestamp precision mismatch, downloaded timestamps can lose precision, resulting in inconsistent data
10017 | 3 | The consolidated and remote databases have different timestamp precisions. Consolidated database timestamps are precise to %1!d! digit(s) in the fractional second while the remote database timestamps are precise to %2!d! digit(s)
10018 | 3 | The timestamp precision mismatch may be resolved by setting the DEFAULT_TIMESTAMP_INCREMENT option on the remote database to %1!d! and TRUNCATE_TIMESTAMP_VALUES to 'On'
10019 | 3 | The remote database is not capable of matching the timestamp precision of the consolidated database. Your application, schema, and scripts must contain logic that copes with the precision mismatch
10020 | 3 | The timestamp precision mismatch may affect upload conflict detection. Use the -zp option to cause the MobiLink synchronization server to use the lowest timestamp precision for conflict detection purposes
10021 | 3 | The remote and consolidated databases have different timestamp precisions, and a timestamp value with a precision higher than the lower-precision side was used for conflict detection purposes. Consider using the -zp option
10022 | 3 | Publication '%1!s!' is not referenced by any table
10023 | 3 | The upload will be rolled back and the synchronization aborted. The next time this remote synchronizes, it will ask what happened to the previous upload
10024 | 3 | Table '%1!s!' has no entry in the ml_table table
10025 | 5 | Invalid character data encountered in upload -- substituting '?'
10026 | 5 | Invalid character data encountered in upload -- using NULL
10027 | 5 | Invalid character data encountered in upload -- using empty string
10028 | 5 | Multi-byte characters truncated on upload
10029 | 5 | Unable to convert character data for download -- substituting '?'
10030 | 5 | Unable to convert character data for download -- using NULL
10031 | 5 | Unable to convert character data for download -- using empty string
10032 | 2 | Unable to open the file to store the client synchronization logs. The filename is '%1!s!'
10033 | 2 | An error occurred reading the remote client's synchronization log
10034 | 2 | Unable to write to the local file that contains remote synchronization logs
10035 | 2 | The remote client's synchronization log ended prematurely, and was probably truncated
10036 | 2 | Client synchronization logs will be shown in the MobiLink synchronization server output file or the console
10037 | 5 | Ignoring updated row (new values)
10038 | 5 | Ignoring updated row (old values)
10039 | 2 | Error detected during multi-row operation, performing rollback before retrying in single row mode
10040 | 2 | %1!lu! row(s) were ignored in uploading data into table %2!s!
10041 | 2 | The upload will be committed and the synchronization aborted. The next time this remote synchronizes, it will ask what happened to the previous upload
10042 | 1 | NT Performance Monitor data area failed to initialize
10043 | 4 | Unable to determine current timestamp from consolidated database
10044 | 5 | A row in table '%1!s!' could not be updated because it no longer exists in the consolidated database
10045 | 2 | Retrying the upload after deadlock in the consolidated database
10046 | 2 | Retrying the upload. Working around a known ODBC driver problem
10047 | 4 | Cannot directly determine the name of the table referenced by the cursor. The table name is required for inserts, updates, and deletes when using the Microsoft ODBC Cursor Library
10048 | 2 | Retrying the begin_synchronization transaction after deadlock in the consolidated database
10049 | 2 | Retrying the end_synchronization transaction after deadlock in the consolidated database
10050 | 4 | %1!s!
10051 | 1 | Unrecognized ODBC driver '%1!s!'. The functionality and quality of ODBC drivers varies greatly. This driver may lack functionality required for successful synchronizations. Use at your own risk
10052 | 1 | The upload_cursor, new_row_cursor, and old_row_cursor scripts are deprecated. It is strongly recommended that you use the statement-based upload scripts instead
10053 | 1 | The -zac switch is deprecated. It is strongly recommended that you use the -za switch instead
10054 | 1 | The -zec switch is deprecated. It is strongly recommended that you use the -ze switch instead
10055 | 2 | The client has provided %1!d! authentication parameter(s), but no authenticate_parameters script exists
10056 | 4 | There is no download data script defined for table: %1!s!. Synchronization has the risk of potentially losing download data
10057 | 4 | There is no upload data script defined for table: %1!s!. Synchronization has the risk of potentially losing upload data
10058 | 2 | Restart %1!ld!: Unable to seek to position %2!lld! in download cache file '%3!s!' -- %4!s!, restart aborted
10059 | 2 | Restart id %1!ld!: Unable to open download cache file '%2!s!' -- %3!s!, restart aborted
10060 | 2 | Restart id %1!ld!: Bad offset (%2!lld!) requested for restart, restart aborted
10061 | 2 | Restart id %1!ld!: Unable to restart download, cached download (%2!ld!) no longer available
10062 | 2 | Unrecognized table event name: %1!s!
10063 | 2 | Unrecognized connection event name: %1!s!
10064 | 1 | Unknown users will be added automatically (when there is no authenticate_user script)
10065 | 1 | Remote client synchronization logs will not be stored locally
10066 | 1 | mlstop will not be able to stop this server
10067 | 1 | The number of worker threads has been increased to %1!d!, because each communication protocol needs at least one thread
10068 | 5 | '%1!s!'
10069 | 5 | All insert rows for table '%1!s!' will be ignored because there is no upload_insert script for this table
10070 | 5 | All update rows for table '%1!s!' will be ignored because there is no upload_update script for this table
10071 | 5 | All delete rows for table '%1!s!' will be ignored because there is no upload_delete script for this table
10072 | 5 | The update row for table '%1!s!' is a conflict update and this row is ignored
10073 | 1 | Windows XP Firewall is enabled, and the MobiLink synchronization server is not in the exception list. Clients on remote machines may not be able to connect to this server


MobiLink synchronization server warning messages sorted by message

Warning code | Level | Warning message
10040 | 2 | %1!lu! row(s) were ignored in uploading data into table %2!s!
10050 | 4 | %1!s!
10068 | 5 | '%1!s!'
10044 | 5 | A row in table '%1!s!' could not be updated because it no longer exists in the consolidated database
10071 | 5 | All delete rows for table '%1!s!' will be ignored because there is no upload_delete script for this table
10069 | 5 | All insert rows for table '%1!s!' will be ignored because there is no upload_insert script for this table
10070 | 5 | All update rows for table '%1!s!' will be ignored because there is no upload_update script for this table
10033 | 2 | An error occurred reading the remote client's synchronization log
10047 | 4 | Cannot directly determine the name of the table referenced by the cursor. The table name is required for inserts, updates, and deletes when using the Microsoft ODBC Cursor Library
10036 | 2 | Client synchronization logs will be shown in the MobiLink synchronization server output file or the console
10039 | 2 | Error detected during multi-row operation, performing rollback before retrying in single row mode
10013 | 4 | Expecting %1!ld! parameter(s) in cursor, but found %2!ld!
10014 | 4 | Expecting at most %1!ld! parameter(s) in cursor, but found %2!ld!
10002 | 1 | If needed, ODBC cursors will be used, via the Microsoft ODBC Cursor Library, to simulate SQLSETPOS for inserts, updates, and deletes
10037 | 5 | Ignoring updated row (new values)
10038 | 5 | Ignoring updated row (old values)
10025 | 5 | Invalid character data encountered in upload -- substituting '?'
10026 | 5 | Invalid character data encountered in upload -- using NULL
10027 | 5 | Invalid character data encountered in upload -- using empty string
10001 | 1 | Maximum number of database connections set to %1!lu! (must be at least the number of worker threads plus one)
10009 | 2 | MobiLink table '%1!s!' is damaged
10028 | 5 | Multi-byte characters truncated on upload
10042 | 1 | NT Performance Monitor data area failed to initialize
10010 | 2 | No handle_error script is defined. The default action code (%1!ld!) will decide the error behavior
10003 | 1 | ODBC Isolation level (%1!s!) is not supported
10004 | 1 | ODBC function %1!s! is not supported by the driver
10006 | 1 | ODBC statement option %1!s! has changed from %2!lu! to %3!lu!
10005 | 1 | ODBC statement option %1!s! has changed from %2!s! (%3!lu!) to %4!s! (%5!lu!)
10022 | 3 | Publication '%1!s!' is not referenced by any table
10065 | 1 | Remote client synchronization logs will not be stored locally
10058 | 2 | Restart %1!ld!: Unable to seek to position %2!lld! in download cache file '%3!s!' -- %4!s!, restart aborted
10060 | 2 | Restart id %1!ld!: Bad offset (%2!lld!) requested for restart, restart aborted
10059 | 2 | Restart id %1!ld!: Unable to open download cache file '%2!s!' -- %3!s!, restart aborted
10061 | 2 | Restart id %1!ld!: Unable to restart download, cached download (%2!ld!) no longer available
10008 | 2 | Retry on deadlock is disabled. The MobiLink synchronization server is using an internal workaround which requires this setting
10007 | 2 | Retrying the begin_connection transaction after deadlock in the consolidated database
10048 | 2 | Retrying the begin_synchronization transaction after deadlock in the consolidated database
10049 | 2 | Retrying the end_synchronization transaction after deadlock in the consolidated database
10045 | 2 | Retrying the upload after deadlock in the consolidated database
10046 | 2 | Retrying the upload. Working around a known ODBC driver problem
10016 | 3 | Table '%1!s!' has at least one timestamp column. Due to a timestamp precision mismatch, downloaded timestamps can lose precision, resulting in inconsistent data
10015 | 3 | Table '%1!s!' has at least one timestamp column. Due to a timestamp precision mismatch, uploaded timestamps can lose precision, defeating download filtering
10024 | 3 | Table '%1!s!' has no entry in the ml_table table
10053 | 1 | The -zac switch is deprecated. It is strongly recommended that you use the -za switch instead
10054 | 1 | The -zec switch is deprecated. It is strongly recommended that you use the -ze switch instead
10055 | 2 | The client has provided %1!d! authentication parameter(s), but no authenticate_parameters script exists
10012 | 2 | The consolidated and remote databases disagree on when the last synchronization took place. The remote is being asked to send a new upload that starts at the last known synchronization point
10017 | 3 | The consolidated and remote databases have different timestamp precisions. Consolidated database timestamps are precise to %1!d! digit(s) in the fractional second while the remote database timestamps are precise to %2!d! digit(s)
10067 | 1 | The number of worker threads has been increased to %1!d!, because each communication protocol needs at least one thread
10021 | 3 | The remote and consolidated databases have different timestamp precisions, and a timestamp value with a precision higher than the lower-precision side was used for conflict detection purposes. Consider using the -zp option
10035 | 2 | The remote client's synchronization log ended prematurely, and was probably truncated
10019 | 3 | The remote database is not capable of matching the timestamp precision of the consolidated database. Your application, schema, and scripts must contain logic that copes with the precision mismatch
10020 | 3 | The timestamp precision mismatch may affect upload conflict detection. Use the -zp option to cause the MobiLink synchronization server to use the lowest timestamp precision for conflict detection purposes
10018 | 3 | The timestamp precision mismatch may be resolved by setting the DEFAULT_TIMESTAMP_INCREMENT option on the remote database to %1!d! and TRUNCATE_TIMESTAMP_VALUES to 'On'
10072 | 5 | The update row for table '%1!s!' is a conflict update and this row is ignored
10041 | 2 | The upload will be committed and the synchronization aborted. The next time this remote synchronizes, it will ask what happened to the previous upload
10023 | 3 | The upload will be rolled back and the synchronization aborted. The next time this remote synchronizes, it will ask what happened to the previous upload
10052 | 1 | The upload_cursor, new_row_cursor, and old_row_cursor scripts are deprecated. It is strongly recommended that you use the statement-based upload scripts instead
10056 | 4 | There is no download data script defined for table: %1!s!. Synchronization has the risk of potentially losing download data
10057 | 4 | There is no upload data script defined for table: %1!s!. Synchronization has the risk of potentially losing upload data
10029 | 5 | Unable to convert character data for download -- substituting '?'
10030 | 5 | Unable to convert character data for download -- using NULL
10031 | 5 | Unable to convert character data for download -- using empty string
10043 | 4 | Unable to determine current timestamp from consolidated database
10032 | 2 | Unable to open the file to store the client synchronization logs. The filename is '%1!s!'
10034 | 2 | Unable to write to the local file that contains remote synchronization logs
10064 | 1 | Unknown users will be added automatically (when there is no authenticate_user script)
10051 | 1 | Unrecognized ODBC driver '%1!s!'. The functionality and quality of ODBC drivers varies greatly. This driver may lack functionality required for successful synchronizations. Use at your own risk
10063 | 2 | Unrecognized connection event name: %1!s!
10062 | 2 | Unrecognized table event name: %1!s!
10011 | 2 | Unrecognized value (%1!ld!) in ml_user.commit_state. The state information for this user is probably corrupted
10073 | 1 | Windows XP Firewall is enabled, and the MobiLink synchronization server is not in the exception list. Clients on remote machines may not be able to connect to this server
10066 | 1 | mlstop will not be able to stop this server


MobiLink synchronization server warning descriptions

This section provides a full listing of warning messages and descriptions.

Warnings with an ODBC state marked "handled by ODBC driver" are not returned to ODBC applications, as the ODBC driver carries out the required actions.

%1!lu! row(s) were ignored in uploading data into table %2!s!
%1!s!
'%1!s!'
A row in table '%1!s!' could not be updated because it no longer exists in the consolidated database
All delete rows for table '%1!s!' will be ignored because there is no upload_delete script for this table
All insert rows for table '%1!s!' will be ignored because there is no upload_insert script for this table
All update rows for table '%1!s!' will be ignored because there is no upload_update script for this table
An error occurred reading the remote client's synchronization log
Cannot directly determine the name of the table referenced by the cursor. The table name is required for inserts, updates, and deletes when using the Microsoft ODBC Cursor Library
Client synchronization logs will be shown in the MobiLink synchronization server output file or the console
Error detected during multi-row operation, performing rollback before retrying in single row mode
Expecting %1!ld! parameter(s) in cursor, but found %2!ld!
Expecting at most %1!ld! parameter(s) in cursor, but found %2!ld!
If needed, ODBC cursors will be used, via the Microsoft ODBC Cursor Library, to simulate SQLSETPOS for inserts, updates, and deletes
Ignoring updated row (new values)
Ignoring updated row (old values)
Invalid character data encountered in upload -- substituting '?'
Invalid character data encountered in upload -- using empty string
Invalid character data encountered in upload -- using NULL
Maximum number of database connections set to %1!lu! (must be at least the number of worker threads plus one)
mlstop will not be able to stop this server
MobiLink table '%1!s!' is damaged
Multi-byte characters truncated on upload
No handle_error script is defined. The default action code (%1!ld!) will decide the error behavior
NT Performance Monitor data area failed to initialize
ODBC function %1!s! is not supported by the driver
ODBC Isolation level (%1!s!) is not supported
ODBC statement option %1!s! has changed from %2!lu! to %3!lu!
ODBC statement option %1!s! has changed from %2!s! (%3!lu!) to %4!s! (%5!lu!)
Publication '%1!s!' is not referenced by any table
Remote client synchronization logs will not be stored locally
Restart %1!ld!: Unable to seek to position %2!lld! in download cache file '%3!s!' -- %4!s!, restart aborted
Restart id %1!ld!: Bad offset (%2!lld!) requested for restart, restart aborted
Restart id %1!ld!: Unable to open download cache file '%2!s!' -- %3!s!, restart aborted
Restart id %1!ld!: Unable to restart download, cached download (%2!ld!) no longer available
Retry on deadlock is disabled. The MobiLink synchronization server is using an internal workaround which requires this setting
Retrying the begin_connection transaction after deadlock in the consolidated database
Retrying the begin_synchronization transaction after deadlock in the consolidated database
Retrying the end_synchronization transaction after deadlock in the consolidated database
Retrying the upload after deadlock in the consolidated database
Retrying the upload. Working around a known ODBC driver problem
Table '%1!s!' has at least one timestamp column. Due to a timestamp precision mismatch, downloaded timestamps can lose precision, resulting in inconsistent data
Table '%1!s!' has at least one timestamp column. Due to a timestamp precision mismatch, uploaded timestamps can lose precision, defeating download filtering
Table '%1!s!' has no entry in the ml_table table
The client has provided %1!d! authentication parameter(s), but no authenticate_parameters script exists
The consolidated and remote databases disagree on when the last synchronization took place. The remote is being asked to send a new upload that starts at the last known synchronization point
The consolidated and remote databases have different timestamp precisions. Consolidated database timestamps are precise to %1!d! digit(s) in the fractional second while the remote database timestamps are precise to %2!d! digit(s)
The number of worker threads has been increased to %1!d!, because each communication protocol needs at least one thread
The remote and consolidated databases have different timestamp precisions, and a timestamp value with a precision higher than the lower-precision side was used for conflict detection purposes. Consider using the -zp option
The remote client's synchronization log ended prematurely, and was probably truncated
The remote database is not capable of matching the timestamp precision of the consolidated database. Your application, schema, and scripts must contain logic that copes with the precision mismatch
The timestamp precision mismatch may affect upload conflict detection. Use the -zp option to cause the MobiLink synchronization server to use the lowest timestamp precision for conflict detection purposes
The timestamp precision mismatch may be resolved by setting the DEFAULT_TIMESTAMP_INCREMENT option on the remote database to %1!d! and TRUNCATE_TIMESTAMP_VALUES to 'On'
The update row for table '%1!s!' is a conflict update and this row is ignored
The upload will be committed and the synchronization aborted. The next time this remote synchronizes, it will ask what happened to the previous upload
The upload will be rolled back and the synchronization aborted. The next time this remote synchronizes, it will ask what happened to the previous upload
The upload_cursor, new_row_cursor, and old_row_cursor scripts are deprecated. It is strongly recommended that you use the statement-based upload scripts instead
The -zac switch is deprecated. It is strongly recommended that you use the -za switch instead
The -zec switch is deprecated. It is strongly recommended that you use the -ze switch instead
There is no download data script defined for table: %1!s!. Synchronization has the risk of potentially losing download data
There is no upload data script defined for table: %1!s!. Synchronization has the risk of potentially losing upload data
Unable to convert character data for download -- substituting '?'
Unable to convert character data for download -- using empty string
Unable to convert character data for download -- using NULL
Unable to determine current timestamp from consolidated database
Unable to open the file to store the client synchronization logs. The filename is '%1!s!'
Unable to write to the local file that contains remote synchronization logs
Unknown users will be added automatically (when there is no authenticate_user script)
Unrecognized connection event name: %1!s!
Unrecognized ODBC driver '%1!s!'. The functionality and quality of ODBC drivers varies greatly. This driver may lack functionality required for successful synchronizations. Use at your own risk
Unrecognized table event name: %1!s!
Unrecognized value (%1!ld!) in ml_user.commit_state. The state information for this user is probably corrupted
Windows XP Firewall is enabled, and the MobiLink synchronization server is not in the exception list. Clients on remote machines may not be able to connect to this server


%1!lu! row(s) were ignored in uploading data into table %2!s!

Item | Value
Warning code | 10040
Level | 2
Parameter 1 | The total number of ignored rows and the name of the table.
Probable cause

The MobiLink synchronization server counts all the upload rows that were not applied to the consolidated database as ignored rows. This can happen if there are upload inserts/updates/deletes from the client, but there is no upload_insert/upload_update/upload_delete script for the listed table in the consolidated database or errors occurred during uploading data into this table, but the handle_error/handle_odbc_error returned 1000.


%1!s!

Item | Value
Warning code | 10050
Level | 4
Parameter 1 | A message from the ODBC driver.
Probable cause

The MobiLink synchronization server made a successful ODBC call, but the ODBC driver displayed a warning message.

Avoiding this message depends on the specific warning.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Warning Messages

MobiLink synchronization server warning descriptions

'%1!s!'

Item | Value
Warning code | 10068
Level | 5
Parameter 1 | A warning message.
Probable cause

Warning messages generated by .Net CLR.


A row in table '%1!s!' could not be updated because it no longer exists in the consolidated database

Item | Value
Warning code | 10044
Level | 5
Parameter 1 | Table name.
Probable cause

An update statement failed because the table in the consolidated database doesn't contain the original row.


All delete rows for table '%1!s!' will be ignored because there is no upload_delete script for this table

Item | Value
Warning code | 10071
Level | 5
Parameter 1 | The name of the table.
Probable cause

The MobiLink synchronization server will issue this warning message, if the client sends delete rows for the given table, but there is no corresponding upload_delete script defined in the consolidated database.


All insert rows for table '%1!s!' will be ignored because there is no upload_insert script for this table

Item | Value
Warning code | 10069
Level | 5
Parameter 1 | The name of the table.
Probable cause

The MobiLink synchronization server will issue this warning message, if the client sends insert rows for the given table, but there is no corresponding upload_insert script defined in the consolidated database.


All update rows for table '%1!s!' will be ignored because there is no upload_update script for this table

Item | Value
Warning code | 10070
Level | 5
Parameter 1 | The name of the table.
Probable cause

The MobiLink synchronization server will issue this warning message, if the client sends update rows for the given table, but there is no corresponding upload_update script defined in the consolidated database.


An error occurred reading the remote client's synchronization log

Item | Value
Warning code | 10033
Level | 2
Probable cause

The MobiLink synchronization server was unable to get the remote error log from the client. To avoid this warning, please do not kill the client when it is running and also make sure the network connection is okay.


Cannot directly determine the name of the table referenced by the cursor. The table name is required for inserts, updates, and deletes when using the Microsoft ODBC Cursor Library

Item | Value
Warning code | 10047
Level | 4
Probable cause

The MobiLink synchronization server was not able to find the table name referenced by the cursor. To avoid this warning, please use statement-based synchronization.


Client synchronization logs will be shown in the MobiLink synchronization server output file or the console

Item | Value
Warning code | 10036
Level | 2
Probable cause

If an error occurs on the client side during synchronization, the client may send its output file to the server and the server will store this output file to a file specified using the server switch -e or -et. However, if the MobiLink synchronization server could not open this file for writing, it will show this warning message and will write the remote log into its output file or console.

To avoid this warning, please make sure the MobiLink synchronization server has the privilege to write the file.


Error detected during multi-row operation, performing rollback before retrying in single row mode

Item | Value
Warning code | 10039
Level | 2
Probable cause

Errors were detected when the MobiLink synchronization server applied the upload stream using multi-row mode. It will roll back the upload stream and retry the upload transaction in single-row mode.


Expecting %1!ld! parameter(s) in cursor, but found %2!ld!

Item | Value
Warning code | 10013
Level | 4
Parameter 1 | The number of parameter(s) expected and the number of parameter(s) found.
Probable cause

The number of parameters is not as expected. Check the script to ensure it is correct.


Expecting at most %1!ld! parameter(s) in cursor, but found %2!ld!

Item | Value
Warning code | 10014
Level | 4
Parameter 1 | The maximum number of parameter(s) expected and the number of parameter(s) found.
Probable cause

There is a maximum number of parameters for every cursor script in the MobiLink synchronization server. If the number of parameters for the given cursor script is larger than the maximum number of parameters, the server will show this warning.


If needed, ODBC cursors will be used, via the Microsoft ODBC Cursor Library, to simulate SQLSETPOS for inserts, updates, and deletes

Item | Value
Warning code | 10002
Level | 1
Probable cause

The MobiLink synchronization server requires some functionality not provided by your selected ODBC driver. Updating to a newer driver may resolve this problem.


Ignoring updated row (new values)

Item | Value
Warning code | 10037
Level | 5
Probable cause

There is a conflict-update, but there is no upload_new_row_insert or new_row_cursor script defined in the consolidated database for the table.


Ignoring updated row (old values)

Item | Value
Warning code | 10038
Level | 5
Probable cause

There is a conflict-update, but there is no upload_old_row_insert or old_row_cursor script defined in the consolidated database for the table.


Invalid character data encountered in upload -- substituting '?'

Item | Value
Warning code | 10025
Level | 5
Probable cause

Character data originating from the client needs to be translated before being entered into the consolidated database. This was not possible for all characters. A '?' will be substituted for each problematic character.


Invalid character data encountered in upload -- using empty string

Item | Value
Warning code | 10027
Level | 5
Probable cause

Character data originating from the client needs to be translated before being entered into the consolidated database. This was not possible, an empty string will be entered instead.


Invalid character data encountered in upload -- using NULL

Item | Value
Warning code | 10026
Level | 5
Probable cause

Character data originating from the client needs to be translated before being entered into the consolidated database. This was not possible. NULL will be entered instead.


Maximum number of database connections set to %1!lu! (must be at least the number of worker threads plus one)

Item | Value
Warning code | 10001
Level | 1
Parameter 1 | Maximum number of connections.
Probable cause

The MobiLink synchronization server makes one connection for each worker thread and an extra connection for the main thread. Therefore, the maximum number of connections must be at least the number of worker threads plus one.


mlstop will not be able to stop this server

Item | Value
Warning code | 10066
Level | 1
Probable cause

The MobiLink synchronization server cannot be stopped by mlstop because another server with the same name is currently running.


MobiLink table '%1!s!' is damaged

Item | Value
Warning code | 10009
Level | 2
Parameter 1 | The MobiLink system table name.
Probable cause

The MobiLink synchronization server was unable to get information from the listed table. Please make sure the table does exist and the database server is running.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Warning Messages

MobiLink synchronization server warning descriptions

Multi-byte characters truncated on upload

Item | Value
Warning code | 10028
Level | 5
Probable cause

This is an internal error, and should never be reported.


No handle_error script is defined. The default action code (%1!ld!) will decide the error behavior

Item | Value
Warning code | 10010
Level | 2
Parameter 1 | The error action code.
Probable cause

An error occurred in the MobiLink synchronization server during synchronization. However there is no handle_error script defined in the consolidated database. The server will take the default action for the error. To avoid this warning, please define a handle_error script.


NT Performance Monitor data area failed to initialize

Item | Value
Warning code | 10042
Level | 1
Probable cause

The NT Performance Monitor will not be able to monitor this instance of the MobiLink synchronization server. Only one instance of the MobiLink synchronization server may be monitored at a time. The instance that may be monitored is always the one running the instance that was started at the earliest time.

Avoid this warning by making sure the MobiLink synchronization server you want to use with the Performance Monitor is started before any other MobiLink synchronization server on the same machine.


ODBC function %1!s! is not supported by the driver

Item | Value
Warning code | 10004
Level | 1
Parameter 1 | ODBC function name.
Probable cause

This function is required for the MobiLink synchronization server to operate. Update your ODBC driver.


ODBC Isolation level (%1!s!) is not supported

Item | Value
Warning code | 10003
Level | 1
Parameter 1 | The required isolation level.
Probable cause

The required isolation level is not supported by the consolidated database. Determine if another level is suitable.


ODBC statement option %1!s! has changed from %2!lu! to %3!lu!

Item | Value
Warning code | 10006
Level | 1
Probable cause

The option has been changed by the ODBC driver. This may not be desirable.


ODBC statement option %1!s! has changed from %2!s! (%3!lu!) to %4!s! (%5!lu!)

Item | Value
Warning code | 10005
Level | 1
Probable cause

The option has been changed by the ODBC driver. This may not be desirable.


Publication '%1!s!' is not referenced by any table

Item | Value
Warning code | 10022
Level | 3
Parameter 1 | Publication name.
Probable cause

The MobiLink synchronization client sends an upload stream that includes upload data as well as upload tables, publications, etc. All these publications must be referenced by at least one of the upload tables. If there are any publications that are not referenced by any upload table, the server will show this warning. If this happens, please contact technical support.


Web Links Browse Collapse Expand PDF Previous Next

ASA Error Messages

MobiLink Synchronization Server Warning Messages

MobiLink synchronization server warning descriptions

Remote client synchronization logs will not be stored locally

Item | Value
Warning code | 10065
Level | 1


Restart %1!ld!: Unable to seek to position %2!lld! in download cache file '%3!s!' -- %4!s!, restart aborted

Item | Value
Warning code | 10058
Level | 2
Parameter 1 | Restart id
Parameter 2 | Restartable download offset
Parameter 3 | Name of download cache file
Parameter 4 | OS level error
Probable cause

The download cache file previously created cannot be accessed. The current synchronization will not be restarted.


Restart id %1!ld!: Bad offset (%2!lld!) requested for restart, restart aborted

Item | Value
Warning code | 10060
Level | 2
Parameter 1 | Restart id
Parameter 2 | Restartable download offset
Probable cause

The client has requested a download restart beyond the length of the cached download. The current synchronization will not be restarted.


Restart id %1!ld!: Unable to open download cache file '%2!s!' -- %3!s!, restart aborted

Item | Value
Warning code | 10059
Level | 2
Parameter 1 | Restart id
Parameter 2 | Name of download cache file
Parameter 3 | OS level error
Probable cause

The download cache file previously created cannot be accessed. The current synchronization will not be restarted.


Restart id %1!ld!: Unable to restart download, cached download (%2!ld!) no longer available

Item | Value
Warning code | 10061
Level | 2
Probable cause

@EN Restart id

@EN Restart id currently available

The client has requested a cached synchronization that no longer exists.


Retry on deadlock is disabled. The MobiLink synchronization server is using an internal workaround which requires this setting

Item | Value
Warning code | 10008
Level | 2
Probable cause

The MobiLink synchronization server will not retry a synchronization when deadlock occurs. This warning should only occur when using the Oracle 8.0.5.7 ODBC driver (which is not recommended).


Retrying the begin_connection transaction after deadlock in the consolidated database

Item | Value
Warning code | 10007
Level | 2
Probable cause

Deadlock occurred in the transaction of begin_transaction in the consolidated database. To avoid this warning, please rewrite your begin_connection script to avoid deadlocks.


Retrying the begin_synchronization transaction after deadlock in the consolidated database

Item | Value
Warning code | 10048
Level | 2
Probable cause

Deadlock occurred when the MobiLink synchronization server executed the begin_synchronization script. It will roll back the transaction and retry this script.


Retrying the end_synchronization transaction after deadlock in the consolidated database

Item | Value
Warning code | 10049
Level | 2
Probable cause

Deadlock occurred when the MobiLink synchronization server executed the end_synchronization script. It will roll back the transaction and retry this script.


Retrying the upload after deadlock in the consolidated database

Item | Value
Warning code | 10045
Level | 2
Probable cause

Deadlock occurred when the MobiLink synchronization server was applying the upload stream. It will roll back the transaction and retry this script.

Avoid this warning by removing contention between synchronization scripts. There can also be contention between synchronization scripts and other applications.


Retrying the upload. Working around a known ODBC driver problem

Item | Value
Warning code | 10046
Level | 2
Probable cause

A quirk in the ODBC driver requires the MobiLink synchronization server to retry the upload; otherwise it will not be applied successfully. This warning should only occur when using the Oracle 8.0.5.7 ODBC driver, which is not recommended.


Table '%1!s!' has at least one timestamp column. Due to a timestamp precision mismatch, downloaded timestamps can lose precision, resulting in inconsistent data

Item | Value
Warning code | 10016
Level | 3
Parameter 1 | Table name.
Probable cause

A remote database is synchronizing a table with at least one timestamp column while the timestamp precision of the remote database is lower than that of the consolidated database. The downloaded value will lose precision after being stored into the remote database.

This situation creates a virtual difference in the synchronized timestamp data between the consolidated database and the remote database. To avoid this data inconsistency problem, you should align timestamp precision across all databases involved in your synchronization system.


Table '%1!s!' has at least one timestamp column. Due to a timestamp precision mismatch, uploaded timestamps can lose precision, defeating download filtering

Item | Value
Warning code | 10015
Level | 3
Parameter 1 | Table name.
Probable cause

A remote database is synchronizing a table with at least one timestamp column while the timestamp precision on the remote database is higher than that of the consolidated database. The uploaded value will lose precision after being stored in the consolidated database. The MobiLink synchronization server compares upload rows and download rows in order to filter away redundant download rows.

The loss of precision may create a virtual difference that defeats the download filtering. This situation can affect download performance. To avoid this performance penalty, you should align timestamp precision across all databases involved in your synchronization system.


Table '%1!s!' has no entry in the ml_table table

Item | Value
Warning code | 10024
Level | 3
Parameter 1 | Table name.
Probable cause

The tables ml_table, ml_table_script, ml_script contain the scripts for every table that participates in synchronization. The MobiLink synchronization server will show this warning for all the synchronization tables that have no script or that have no entry in the table ml_table.


The client has provided %1!d! authentication parameter(s), but no authenticate_parameters script exists

Item | Value
Warning code | 10055
Level | 2
Parameter 1 | The number of authentication parameter(s).
Probable cause

The MobiLink synchronization client sent the listed number of authentication parameters. However, there is no authentication parameter script defined in the consolidated database.

To avoid this warning, please define the authenticate_parameters script in the consolidated database or do not send authentication parameter(s) from the client.


The consolidated and remote databases disagree on when the last synchronization took place. The remote is being asked to send a new upload that starts at the last known synchronization point

Item | Value
Warning code | 10012
Level | 2
Probable cause

The MobiLink synchronization server stores the remote ending log offsets in its system tables after every synchronization and it compares these ending log offsets with the remote beginning offsets when a new synchronization comes in. If the ending offsets do not match the beginning offsets, the server will show this warning and also inform the client about the mismatching offsets.


The consolidated and remote databases have different timestamp precisions. Consolidated database timestamps are precise to %1!d! digit(s) in the fractional second while the remote database timestamps are precise to %2!d! digit(s)

Item | Value
Warning code | 10017
Level | 3
Parameter 1 | Timestamp precision of the consolidated database in terms of number of decimal digits in the fractional second.
Parameter 2 | Timestamp precision of the remote database in terms of number of decimal digits in the fractional second.
Probable cause

Inconsistent timestamp precisions were found between the remote database and the consolidated database. Align the databases to the same precision to avoid a performance penalty or inconsistent data.


The number of worker threads has been increased to %1!d!, because each communication protocol needs at least one thread

Item | Value
Warning code | 10067
Level | 1
Parameter 1 | Number of communication protocols given in the command line


The remote and consolidated databases have different timestamp precisions, and a timestamp value with a precision higher than the lower-precision side was used for conflict detection purposes. Consider using the -zp option

Item | Value
Warning code | 10021
Level | 3
Probable cause

An upload conflict is detected based on a tolerable timestamp difference while the -zp switch is not used. If you decided not to align precision on the databases involved in your synchronization system, you may use the -zp swith to start the MobiLink synchronization server.

If the switch is used, MobiLink synchronization server will tolerate conflict caused by timestamp differences smaller than the lower precision among the two databases.


The remote client's synchronization log ended prematurely, and was probably truncated

Item | Value
Warning code | 10035
Level | 2
Probable cause

The MobiLink synchronization server was not able to completely get the remote error log from the client, so the remote error log may have been truncated. To avoid this warning, please do not kill the client when it is running and also make sure the network connection is okay.


The remote database is not capable of matching the timestamp precision of the consolidated database. Your application, schema, and scripts must contain logic that copes with the precision mismatch

Item | Value
Warning code | 10019
Level | 3
Probable cause

Timestamp precision of the consolidated database is found to be higher than attainable by the remote database. If possible you may lower the timestamp precision on the consolidated database in order to avoid inconsistent timestamp data between the remote and the consolidated database.

Otherwise, you may need to avoid synchronizing timestamps in your synchronization schema; or you may need to have conflict detection scripts aware of the virtual difference; or you may need to use the -zp switch to tolerate the conflict. Your application should also be able to deal with the inconsistency.


The timestamp precision mismatch may affect upload conflict detection. Use the -zp option to cause the MobiLink synchronization server to use the lowest timestamp precision for conflict detection purposes

Item | Value
Warning code | 10020
Level | 3
Probable cause

Timestamp precision mismatch between the remote database and the consolidated database has been detected. The mismatch can affect upload conflict detection as the MobiLink synchronization server will compare the rows for the two databases. If you decided not to align precision on the databases involved in your synchronization system, you may use the -zp swith to start the MobiLink synchronization server.

If this switch is used, the MobiLink synchronization server will tolerate conflict caused by timestamp differences smaller than the lower precision among the two databases.


The timestamp precision mismatch may be resolved by setting the DEFAULT_TIMESTAMP_INCREMENT option on the remote database to %1!d! and TRUNCATE_TIMESTAMP_VALUES to 'On'

Item | Value
Warning code | 10018
Level | 3
Parameter 1 | Timestamp precision of the consolidated database in terms of number of decimal digits in the fractional second.
Probable cause

This is an advisory on how to align timestamp precision by adjusting timestamp precision on the ASA client database or the ASA reference database for UltraLite clients. UltraLite clients need to be regenerated after the precision is adjusted.


The update row for table '%1!s!' is a conflict update and this row is ignored

Item | Value
Warning code | 10072
Level | 5
Parameter 1 | The name of the table.
Probable cause

A conflict-update has occurred, but there is no conflict resolution script defined for this table.


The upload will be committed and the synchronization aborted. The next time this remote synchronizes, it will ask what happened to the previous upload

Item | Value
Warning code | 10041
Level | 2
Probable cause

This is an internal warning that is primarily used for testing, but may also be seen as part of technical support engagements.


The upload will be rolled back and the synchronization aborted. The next time this remote synchronizes, it will ask what happened to the previous upload

Item | Value
Warning code | 10023
Level | 3
Probable cause

This is an internal warning that is primarily used for testing, but may also be seen as part of technical support engagements.


The upload_cursor, new_row_cursor, and old_row_cursor scripts are deprecated. It is strongly recommended that you use the statement-based upload scripts instead

Item | Value
Warning code | 10052
Level | 1
Probable cause

The cursor-based upload scripts will not be supported in future releases of the MobiLink synchronization server. To avoid this warning, please convert all your cursor-based upload scripts into statement-based upload scripts.


The -zac switch is deprecated. It is strongly recommended that you use the -za switch instead

Item | Value
Warning code | 10053
Level | 1
Probable cause

The cursor-based upload scripts will not be supported in future releases of the MobiLink synchronization server.


The -zec switch is deprecated. It is strongly recommended that you use the -ze switch instead

Item | Value
Warning code | 10054
Level | 1
Probable cause

The cursor-based upload scripts will not be supported in future releases of the MobiLink synchronization server.


There is no download data script defined for table: %1!s!. Synchronization has the risk of potentially losing download data

Item | Value
Warning code | 10056
Level | 4
Parameter 1 | Table name.
Probable cause

The listed table is involved in a download-only synchronization. However, there is no download script for this table in the consolidated database.

To avoid this warning, please define download script(s) for this table in the consolidated database, or always do full synchronization.


There is no upload data script defined for table: %1!s!. Synchronization has the risk of potentially losing upload data

Item | Value
Warning code | 10057
Level | 4
Parameter 1 | Table name.
Probable cause

The listed table is involved in the synchronization and there are some changes to this table in the remote data. However, there is no upload script for this table in the dbmlsync consolidated database.

To avoid this warning, please define upload script(s) for this table in the consolidated database, or do not make any changes in the remote database using any other application except the MobiLink synchronization client.


Unable to convert character data for download -- substituting '?'

Item | Value
Warning code | 10029
Level | 5
Probable cause

Character data originating from the consolidated database needs to be translated before being sent to the client. This was not possible for all characters. A '?' will be substituted for each problem character.


Unable to convert character data for download -- using empty string

Item | Value
Warning code | 10031
Level | 5
Probable cause

Character data originating from the consolidated database needs to be translated before being sent to the client. This was not possible. An empty string will be sent instead.


Unable to convert character data for download -- using NULL

Item | Value
Warning code | 10030
Level | 5
Probable cause

Character data originating from the consolidated database needs to be translated before being sent to the client. This was not possible. NULL will be sent instead.


Unable to determine current timestamp from consolidated database

Item | Value
Warning code | 10043
Level | 4
Probable cause

The MobiLink synchronization server was not able to get the current timestamp from the consolidated database. Please make sure the database server is running and the network connection is okay.


Unable to open the file to store the client synchronization logs. The filename is '%1!s!'

Item | Value
Warning code | 10032
Level | 2
Probable cause

The MobiLink synchronization server was unable to open the local remote log file given by option -e or -et. Please make sure the file name and path are valid and the file is writable.


Unable to write to the local file that contains remote synchronization logs

Item | Value
Warning code | 10034
Level | 2
Probable cause

The MobiLink synchronization server was unable to write the remote error log to a local file. To avoid this warning, please make sure the file name and path given by option -e or -et are valid and the file is writable.


Unknown users will be added automatically (when there is no authenticate_user script)

Item | Value
Warning code | 10064
Level | 1
Probable cause

This is a friendly warning message when the MobiLink server command line switch, -zu+ is used.


Unrecognized connection event name: %1!s!

Item | Value
Warning code | 10063
Level | 2
Parameter 1 | Connection event name.
Probable cause

The connection event name is unrecognized, synchronization will fail, please correct the wrong connection event name.


Unrecognized ODBC driver '%1!s!'. The functionality and quality of ODBC drivers varies greatly. This driver may lack functionality required for successful synchronizations. Use at your own risk

Item | Value
Warning code | 10051
Level | 1
Parameter 1 | The file name of an ODBC driver.
Probable cause

The MobiLink synchronization server is very well tested with a set of ODBC drivers. However, the ODBC driver you are currently using is not on the list. To avoid this warning, please run the MobiLink synchronization server with a recommended ODBC driver.


Unrecognized table event name: %1!s!

Item | Value
Warning code | 10062
Level | 2
Parameter 1 | Table event name.
Probable cause

The table event name is unrecognized, synchronization will fail, please correct the wrong table event name.


Unrecognized value (%1!ld!) in ml_user.commit_state. The state information for this user is probably corrupted

Item | Value
Warning code | 10011
Level | 2
Parameter 1 | The value of a commit state.
Probable cause

The MobiLink synchronization server stores the last synchronization status for an UltraLite application in the commit_state column in the ml_user table. However, the server does not recognize the commit state fetched from the consolidated database. Please do not manually modify the values of the commit_state in ml_table.


Windows XP Firewall is enabled, and the MobiLink synchronization server is not in the exception list. Clients on remote machines may not be able to connect to this server

Item | Value
Warning code | 10073
Level | 1
Probable cause

The Windows XP Firewall is enabled and either the MobiLink synchronization server is not in the expection list or it is in the exception list but disabled. This configuration will prevent remote clients from connecting to the server.


MobiLink Communication Error Messages

About this chapter

This chapter lists MobiLink client/server communication errors, as well as their probable causes.

The error messages are written to the MobiLink synchronization server message log and the MobiLink Adaptive Server Anywhere client message log. The error codes are returned to UltraLite clients in the ss_error_code member of the stream_error parameter.

Communication error messages sorted by code
Communication error messages sorted by message
Communication error messages sorted by constant
Communication error descriptions


Communication error messages sorted by code

Error code | Error message
0 | No error or unknown error.
1 | Invalid parameter '%1!s!'.
2 | Parameter value '%1!s!' is not an unsigned integer.
3 | Parameter value '%1!s!' is not an unsigned integer value or range. A range has the form NNN-NNN.
4 | Parameter value '%1!s!' is not a valid boolean value. The value must be 0 or 1.
5 | Parameter value '%1!s!' is not a valid hexadecimal value.
6 | Unable to allocate %1!s! bytes.
7 | Unable to parse the parameter string '%1!s!'.
8 | Unable to read %1!s! bytes.
9 | Unable to write %1!s! bytes.
10 | An end write failed.
11 | An end read failed.
12 | Feature not implemented.
13 | The operation would cause blocking.
14 | Unable to generate a random number.
15 | Unable to initialize the random number generator.
16 | Unable to seed the random number generator.
17 | Unable to create a random number object.
18 | An error occurred during shutdown.
19 | Unable to dequeue from the connection queue.
20 | Invalid root certificate.
21 | Unrecognized organization '%1!s!'.
22 | Invalid certificate chain length (%1!s!).
23 | Certificate error (4023).
24 | Server certificate not trusted.
25 | Unable to duplicate security context.
26 | Unable to attach the network layer to the security layer.
27 | Internal error 4027.
28 | Internal error 4028.
29 | Internal error 4029.
30 | Internal error 4030.
31 | Internal error 4031.
32 | Internal error 4032.
33 | Unable to open certificate file '%1!s!'.
34 | Unable to read certificates.
35 | Unable to read the private key.
36 | Unable to set the private key.
37 | Unable to fetch a certificate expiry date.
38 | Unable to copy a certificate.
39 | Unable to add a certificate to a certificate chain.
40 | Unable to find the trusted certificate file '%1!s!'.
41 | Error reading from the trusted certificate file '%1!s!'.
42 | No trusted certificates found.
43 | Unable to allocate a certificate.
44 | Unable to import a certificate.
45 | Internal initialization error 4045.
46 | Internal initialization error 4046.
47 | Unable to set the protocol side (%1!s!).
48 | Unable to add a trusted certificate.
49 | Unable to create a private key object.
50 | A certificate has expired.
51 | Unrecognized organization unit '%1!s!'.
52 | Unrecognized common name '%1!s!'.
53 | Handshake error.
54 | Unsupported HTTP version: %1!s!
55 | Internal initialization error 4055.
56 | Internal initialization error 4056.
57 | The host name '%1!s!' could not be found.
58 | Unable to create a TCP/IP socket.
59 | Unable to create a UDP socket.
60 | Unable to bind a socket to port %1!s!.
61 | Unable to clean up the socket layer.
62 | Unable to close a socket.
63 | Unable to connect a socket.
64 | Unable to get a socket's local name.
65 | Unable to get socket option number %1!s!.
66 | Unable to set socket option number %1!s!.
67 | Unable to listen on a socket. The backlog is %1!s!.
68 | Unable to shut down a socket.
69 | Unable to select a socket status.
70 | Unable to initialize the sockets layer.
71 | Unable to determine localhost.
72 | Unable to get host by address.
73 | Unable to load the network interface library.
74 | Invalid port number %1!s!. The value must be between zero and 65535.
75 | ActiveSync synchronization cannot be initiated by an application.
76 | ActiveSync provider has not been installed.
77 | The content type '%1!s!' is unknown.
78 | Client id is not available for use in HTTP header.
79 | The HTTP buffer size specified is out of the valid range.
80 | Extra data found in the HTTP body: %1!s!
81 | Failed to read encoded CR LF.
82 | Failed to read CR LF.
83 | Timed out while waiting for the next HTTP request in this synchronization.
84 | Failed to read encoded chunk length.
85 | An unexpected character was read while parsing the chunk length. %1!s!.
86 | An error status was returned: '%1!s!'.
87 | Unknown transfer encoding: '%1!s!'.
88 | Unable to parse cookie: '%1!s!'.
89 | Expected data from remote but current request is not a POST.
200 | Invalid liveness timeout value %1!s!. The value must be between zero and 65535.
201 | Timed out trying to read %1!s! bytes.
202 | Timed out trying to write %1!s! bytes.
203 | Automatic dialup is not supported on this machine.
204 | Failed dialing to %1!s!.
205 | No server certificate was provided.
206 | No server certificate password was provided.
207 | No trusted root certificates were provided.
208 | Password specified for an unencrypted server key.
209 | A userid and password are required for HTTP authentication.
210 | A userid and password are required for HTTP proxy authentication.
211 | HTTP Authentication failed.
212 | HTTP Proxy Authentication failed.
213 | No userid was supplied.
214 | No password was supplied.
215 | Unsupported http authentication algorithm: %1!s!
216 | Error parsing HTTP header: %1!s!
217 | HTTP server authentication failed


Communication error messages sorted by message

Error code | Error message
50 | A certificate has expired.
209 | A userid and password are required for HTTP authentication.
210 | A userid and password are required for HTTP proxy authentication.
76 | ActiveSync provider has not been installed.
75 | ActiveSync synchronization cannot be initiated by an application.
11 | An end read failed.
10 | An end write failed.
18 | An error occurred during shutdown.
86 | An error status was returned: '%1!s!'.
85 | An unexpected character was read while parsing the chunk length. %1!s!.
203 | Automatic dialup is not supported on this machine.
23 | Certificate error (4023).
78 | Client id is not available for use in HTTP header.
216 | Error parsing HTTP header: %1!s!
41 | Error reading from the trusted certificate file '%1!s!'.
89 | Expected data from remote but current request is not a POST.
80 | Extra data found in the HTTP body: %1!s!
204 | Failed dialing to %1!s!.
82 | Failed to read CR LF.
81 | Failed to read encoded CR LF.
84 | Failed to read encoded chunk length.
12 | Feature not implemented.
211 | HTTP Authentication failed.
212 | HTTP Proxy Authentication failed.
217 | HTTP server authentication failed
53 | Handshake error.
27 | Internal error 4027.
28 | Internal error 4028.
29 | Internal error 4029.
30 | Internal error 4030.
31 | Internal error 4031.
32 | Internal error 4032.
45 | Internal initialization error 4045.
46 | Internal initialization error 4046.
55 | Internal initialization error 4055.
56 | Internal initialization error 4056.
22 | Invalid certificate chain length (%1!s!).
200 | Invalid liveness timeout value %1!s!. The value must be between zero and 65535.
1 | Invalid parameter '%1!s!'.
74 | Invalid port number %1!s!. The value must be between zero and 65535.
20 | Invalid root certificate.
0 | No error or unknown error.
214 | No password was supplied.
206 | No server certificate password was provided.
205 | No server certificate was provided.
42 | No trusted certificates found.
207 | No trusted root certificates were provided.
213 | No userid was supplied.
4 | Parameter value '%1!s!' is not a valid boolean value. The value must be 0 or 1.
5 | Parameter value '%1!s!' is not a valid hexadecimal value.
3 | Parameter value '%1!s!' is not an unsigned integer value or range. A range has the form NNN-NNN.
2 | Parameter value '%1!s!' is not an unsigned integer.
208 | Password specified for an unencrypted server key.
24 | Server certificate not trusted.
79 | The HTTP buffer size specified is out of the valid range.
77 | The content type '%1!s!' is unknown.
57 | The host name '%1!s!' could not be found.
13 | The operation would cause blocking.
201 | Timed out trying to read %1!s! bytes.
202 | Timed out trying to write %1!s! bytes.
83 | Timed out while waiting for the next HTTP request in this synchronization.
39 | Unable to add a certificate to a certificate chain.
48 | Unable to add a trusted certificate.
6 | Unable to allocate %1!s! bytes.
43 | Unable to allocate a certificate.
26 | Unable to attach the network layer to the security layer.
60 | Unable to bind a socket to port %1!s!.
61 | Unable to clean up the socket layer.
62 | Unable to close a socket.
63 | Unable to connect a socket.
38 | Unable to copy a certificate.
58 | Unable to create a TCP/IP socket.
59 | Unable to create a UDP socket.
49 | Unable to create a private key object.
17 | Unable to create a random number object.
19 | Unable to dequeue from the connection queue.
71 | Unable to determine localhost.
25 | Unable to duplicate security context.
37 | Unable to fetch a certificate expiry date.
40 | Unable to find the trusted certificate file '%1!s!'.
14 | Unable to generate a random number.
64 | Unable to get a socket's local name.
72 | Unable to get host by address.
65 | Unable to get socket option number %1!s!.
44 | Unable to import a certificate.
15 | Unable to initialize the random number generator.
70 | Unable to initialize the sockets layer.
67 | Unable to listen on a socket. The backlog is %1!s!.
73 | Unable to load the network interface library.
33 | Unable to open certificate file '%1!s!'.
88 | Unable to parse cookie: '%1!s!'.
7 | Unable to parse the parameter string '%1!s!'.
8 | Unable to read %1!s! bytes.
34 | Unable to read certificates.
35 | Unable to read the private key.
16 | Unable to seed the random number generator.
69 | Unable to select a socket status.
66 | Unable to set socket option number %1!s!.
36 | Unable to set the private key.
47 | Unable to set the protocol side (%1!s!).
68 | Unable to shut down a socket.
9 | Unable to write %1!s! bytes.
87 | Unknown transfer encoding: '%1!s!'.
52 | Unrecognized common name '%1!s!'.
21 | Unrecognized organization '%1!s!'.
51 | Unrecognized organization unit '%1!s!'.
54 | Unsupported HTTP version: %1!s!
215 | Unsupported http authentication algorithm: %1!s!


Communication error messages sorted by constant

Constant | Error message
ACTSYNC NOT INSTALLED | ActiveSync provider has not been installed.
ACTSYNC NO PORT | ActiveSync synchronization cannot be initiated by an application.
CREATE RANDOM OBJECT | Unable to create a random number object.
DEQUEUING CONNECTION | Unable to dequeue from the connection queue.
DUN DIAL FAILED | Failed dialing to %1!s!.
DUN NOT SUPPORTED | Automatic dialup is not supported on this machine.
END READ | An end read failed.
END WRITE | An end write failed.
GENERATE RANDOM | Unable to generate a random number.
HTTP AUTHENTICATION FAILED | HTTP Authentication failed.
HTTP AUTHENTICATION REQUIRED | A userid and password are required for HTTP authentication.
HTTP BAD STATUS CODE | An error status was returned: '%1!s!'.
HTTP BUFFER SIZE OUT OF RANGE | The HTTP buffer size specified is out of the valid range.
HTTP CHUNK LEN BAD CHARACTER | An unexpected character was read while parsing the chunk length. %1!s!.
HTTP CHUNK LEN ENCODED MISSING | Failed to read encoded chunk length.
HTTP CLIENT ID NOT SET | Client id is not available for use in HTTP header.
HTTP CONTENT TYPE NOT SPECIFIED | The content type '%1!s!' is unknown.
HTTP CRLF ENCODED MISSING | Failed to read encoded CR LF.
HTTP CRLF MISSING | Failed to read CR LF.
HTTP EXPECTED POST | Expected data from remote but current request is not a POST.
HTTP EXTRA DATA END READ | Extra data found in the HTTP body: %1!s!
HTTP HEADER PARSE ERROR | Error parsing HTTP header: %1!s!
HTTP NO CONTD CONNECTION | Timed out while waiting for the next HTTP request in this synchronization.
HTTP NO PASSWORD | No password was supplied.
HTTP NO USERID | No userid was supplied.
HTTP PROXY AUTHENTICATION FAILED | HTTP Proxy Authentication failed.
HTTP PROXY AUTHENTICATION REQUIRED | A userid and password are required for HTTP proxy authentication.
HTTP SERVER AUTH FAILED | HTTP server authentication failed
HTTP UNABLE TO PARSE COOKIE | Unable to parse cookie: '%1!s!'.
HTTP UNKNOWN TRANSFER ENCODING | Unknown transfer encoding: '%1!s!'.
HTTP UNSUPPORTED AUTH ALGORITHM | Unsupported http authentication algorithm: %1!s!
HTTP VERSION | Unsupported HTTP version: %1!s!
INIT RANDOM | Unable to initialize the random number generator.
LOAD NETWORK LIBRARY | Unable to load the network interface library.
MEMORY ALLOCATION | Unable to allocate %1!s! bytes.
NONE | No error or unknown error.
NOT IMPLEMENTED | Feature not implemented.
PARAMETER | Invalid parameter '%1!s!'.
PARAMETER NOT BOOLEAN | Parameter value '%1!s!' is not a valid boolean value. The value must be 0 or 1.
PARAMETER NOT HEX | Parameter value '%1!s!' is not a valid hexadecimal value.
PARAMETER NOT UINT32 | Parameter value '%1!s!' is not an unsigned integer.
PARAMETER NOT UINT32 RANGE | Parameter value '%1!s!' is not an unsigned integer value or range. A range has the form NNN-NNN.
PARSE | Unable to parse the parameter string '%1!s!'.
READ | Unable to read %1!s! bytes.
READ TIMEOUT | Timed out trying to read %1!s! bytes.
SECURE ADD CERTIFICATE | Unable to add a certificate to a certificate chain.
SECURE ADD TRUSTED CERTIFICATE | Unable to add a trusted certificate.
SECURE CERTIFICATE CHAIN FUNC | Internal error 4028.
SECURE CERTIFICATE CHAIN LENGTH | Invalid certificate chain length (%1!s!).
SECURE CERTIFICATE CHAIN REF | Internal error 4029.
SECURE CERTIFICATE COMMON NAME | Unrecognized common name '%1!s!'.
SECURE CERTIFICATE COMPANY NAME | Unrecognized organization '%1!s!'.
SECURE CERTIFICATE COMPANY UNIT | Unrecognized organization unit '%1!s!'.
SECURE CERTIFICATE COUNT | No trusted certificates found.
SECURE CERTIFICATE EXPIRED | A certificate has expired.
SECURE CERTIFICATE EXPIRY DATE | Unable to fetch a certificate expiry date.
SECURE CERTIFICATE FILE NOT FOUND | Unable to open certificate file '%1!s!'.
SECURE CERTIFICATE NOT TRUSTED | Server certificate not trusted.
SECURE CERTIFICATE REF | Certificate error (4023).
SECURE CERTIFICATE ROOT | Invalid root certificate.
SECURE CREATE CERTIFICATE | Unable to allocate a certificate.
SECURE CREATE PRIVATE KEY OBJECT | Unable to create a private key object.
SECURE DUPLICATE CONTEXT | Unable to duplicate security context.
SECURE ENABLE NON BLOCKING | Internal error 4030.
SECURE EXPORT CERTIFICATE | Unable to copy a certificate.
SECURE HANDSHAKE | Handshake error.
SECURE IMPORT CERTIFICATE | Unable to import a certificate.
SECURE NO SERVER CERTIFICATE | No server certificate was provided.
SECURE NO SERVER CERTIFICATE PASSWORD | No server certificate password was provided.
SECURE NO TRUSTED ROOTS | No trusted root certificates were provided.
SECURE READ CERTIFICATE | Unable to read certificates.
SECURE READ PRIVATE KEY | Unable to read the private key.
SECURE REDUNDANT SERVER CERTIFICATE PASSWORD | Password specified for an unencrypted server key.
SECURE SET CHAIN NUMBER | Internal error 4032.
SECURE SET CIPHER SUITES | Internal error 4031.
SECURE SET IO | Unable to attach the network layer to the security layer.
SECURE SET IO SEMANTICS | Internal error 4027.
SECURE SET PRIVATE KEY | Unable to set the private key.
SECURE SET PROTOCOL SIDE | Unable to set the protocol side (%1!s!).
SECURE SET RANDOM FUNC | Internal initialization error 4046.
SECURE SET RANDOM REF | Internal initialization error 4045.
SECURE SET READ FUNC | Internal initialization error 4055.
SECURE SET WRITE FUNC | Internal initialization error 4056.
SECURE TRUSTED CERTIFICATE FILE NOT FOUND | Unable to find the trusted certificate file '%1!s!'.
SECURE TRUSTED CERTIFICATE READ | Error reading from the trusted certificate file '%1!s!'.
SEED RANDOM | Unable to seed the random number generator.
SHUTTING DOWN | An error occurred during shutdown.
SOCKET BIND | Unable to bind a socket to port %1!s!.
SOCKET CLEANUP | Unable to clean up the socket layer.
SOCKET CLOSE | Unable to close a socket.
SOCKET CONNECT | Unable to connect a socket.
SOCKET CREATE TCPIP | Unable to create a TCP/IP socket.
SOCKET CREATE UDP | Unable to create a UDP socket.
SOCKET GET HOST BY ADDR | Unable to get host by address.
SOCKET GET NAME | Unable to get a socket's local name.
SOCKET GET OPTION | Unable to get socket option number %1!s!.
SOCKET HOST NAME NOT FOUND | The host name '%1!s!' could not be found.
SOCKET LISTEN | Unable to listen on a socket. The backlog is %1!s!.
SOCKET LIVENESS OUT OF RANGE | Invalid liveness timeout value %1!s!. The value must be between zero and 65535.
SOCKET LOCALHOST NAME NOT FOUND | Unable to determine localhost.
SOCKET PORT OUT OF RANGE | Invalid port number %1!s!. The value must be between zero and 65535.
SOCKET SELECT | Unable to select a socket status.
SOCKET SET OPTION | Unable to set socket option number %1!s!.
SOCKET SHUTDOWN | Unable to shut down a socket.
SOCKET STARTUP | Unable to initialize the sockets layer.
WOULD BLOCK | The operation would cause blocking.
WRITE | Unable to write %1!s! bytes.
WRITE TIMEOUT | Timed out trying to write %1!s! bytes.


Communication error descriptions

This section provides a full listing of error messages and descriptions.

Errors with an ODBC state marked "handled by ODBC driver" are not returned to ODBC applications, as the ODBC driver carries out the required actions.

A certificate has expired.
A userid and password are required for HTTP authentication.
A userid and password are required for HTTP proxy authentication.
ActiveSync provider has not been installed.
ActiveSync synchronization cannot be initiated by an application.
An end read failed.
An end write failed.
An error occurred during shutdown.
An error status was returned: '%1!s!'.
An unexpected character was read while parsing the chunk length. %1!s!.
Automatic dialup is not supported on this machine.
Certificate error (4023).
Client id is not available for use in HTTP header.
Error parsing HTTP header: %1!s!
Error reading from the trusted certificate file '%1!s!'.
Expected data from remote but current request is not a POST.
Extra data found in the HTTP body: %1!s!
Failed dialing to %1!s!.
Failed to read CR LF.
Failed to read encoded chunk length.
Failed to read encoded CR LF.
Feature not implemented.
Handshake error.
HTTP Authentication failed.
HTTP Proxy Authentication failed.
HTTP server authentication failed
Internal error 4027.
Internal error 4028.
Internal error 4029.
Internal error 4030.
Internal error 4031.
Internal error 4032.
Internal initialization error 4045.
Internal initialization error 4046.
Internal initialization error 4055.
Internal initialization error 4056.
Invalid certificate chain length (%1!s!).
Invalid liveness timeout value %1!s!. The value must be between zero and 65535.
Invalid parameter '%1!s!'.
Invalid port number %1!s!. The value must be between zero and 65535.
Invalid root certificate.
No error or unknown error.
No password was supplied.
No server certificate password was provided.
No server certificate was provided.
No trusted certificates found.
No trusted root certificates were provided.
No userid was supplied.
Parameter value '%1!s!' is not a valid boolean value. The value must be 0 or 1.
Parameter value '%1!s!' is not a valid hexadecimal value.
Parameter value '%1!s!' is not an unsigned integer value or range. A range has the form NNN-NNN.
Parameter value '%1!s!' is not an unsigned integer.
Password specified for an unencrypted server key.
Server certificate not trusted.
The content type '%1!s!' is unknown.
The host name '%1!s!' could not be found.
The HTTP buffer size specified is out of the valid range.
The operation would cause blocking.
Timed out trying to read %1!s! bytes.
Timed out trying to write %1!s! bytes.
Timed out while waiting for the next HTTP request in this synchronization.
Unable to add a certificate to a certificate chain.
Unable to add a trusted certificate.
Unable to allocate %1!s! bytes.
Unable to allocate a certificate.
Unable to attach the network layer to the security layer.
Unable to bind a socket to port %1!s!.
Unable to clean up the socket layer.
Unable to close a socket.
Unable to connect a socket.
Unable to copy a certificate.
Unable to create a private key object.
Unable to create a random number object.
Unable to create a TCP/IP socket.
Unable to create a UDP socket.
Unable to dequeue from the connection queue.
Unable to determine localhost.
Unable to duplicate security context.
Unable to fetch a certificate expiry date.
Unable to find the trusted certificate file '%1!s!'.
Unable to generate a random number.
Unable to get a socket's local name.
Unable to get host by address.
Unable to get socket option number %1!s!.
Unable to import a certificate.
Unable to initialize the random number generator.
Unable to initialize the sockets layer.
Unable to listen on a socket. The backlog is %1!s!.
Unable to load the network interface library.
Unable to open certificate file '%1!s!'.
Unable to parse cookie: '%1!s!'.
Unable to parse the parameter string '%1!s!'.
Unable to read %1!s! bytes.
Unable to read certificates.
Unable to read the private key.
Unable to seed the random number generator.
Unable to select a socket status.
Unable to set socket option number %1!s!.
Unable to set the private key.
Unable to set the protocol side (%1!s!).
Unable to shut down a socket.
Unable to write %1!s! bytes.
Unknown transfer encoding: '%1!s!'.
Unrecognized common name '%1!s!'.
Unrecognized organization '%1!s!'.
Unrecognized organization unit '%1!s!'.
Unsupported http authentication algorithm: %1!s!
Unsupported HTTP version: %1!s!


A certificate has expired.

Item | Value
Error code | 50
Constant | SECURE_CERTIFICATE_EXPIRED (Java) STREAM_ERROR_SECURE_CERTIFICATE_EXPIRED (C/C++) ulStreamErrorSecureCertificateExpired (Visual Basic)
Probable cause

A certificate in the certificate chain has expired. Obtain a new certificate with a later expiry date and retry the operation.


A userid and password are required for HTTP authentication.

Item | Value
Error code | 209
Constant | HTTP_AUTHENTICATION_REQUIRED (Java) STREAM_ERROR_HTTP_AUTHENTICATION_REQUIRED (C/C++) ulStreamErrorHttpAuthenticationRequired (Visual Basic)
Probable cause

An HTTP server or gateway requested HTTP authentication. Please supply

a userid and password using the HTTP synchronization parameters

http_userid and http_password.


A userid and password are required for HTTP proxy authentication.

Item | Value
Error code | 210
Constant | HTTP_PROXY_AUTHENTICATION_REQUIRED (Java) STREAM_ERROR_HTTP_PROXY_AUTHENTICATION_REQUIRED (C/C++) ulStreamErrorHttpProxyAuthenticationRequired (Visual Basic)
Probable cause

An HTTP proxy requested HTTP authentication. Please supply a userid

and password using the HTTP synchronization parameters

http_proxy_userid and http_proxy_password.


ActiveSync provider has not been installed.

Item | Value
Error code | 76
Constant | ACTSYNC_NOT_INSTALLED (Java) STREAM_ERROR_ACTSYNC_NOT_INSTALLED (C/C++) ulStreamErrorActsyncNotInstalled (Visual Basic)
Probable cause

The ActiveSync provider has not been installed. Run dbasinst to install it (see documentation for details).


ActiveSync synchronization cannot be initiated by an application.

Item | Value
Error code | 75
Constant | ACTSYNC_NO_PORT (Java) STREAM_ERROR_ACTSYNC_NO_PORT (C/C++) ulStreamErrorActsyncNoPort (Visual Basic)
Probable cause

ActiveSync synchronization can only be initiated by ActiveSync itself, either by placing the device in its cradle or by selecting "Synchronize" from the ActiveSync Manager. To initiate a synchronization from an application, use the TCP/IP socket synchronization stream.


An end read failed.

Item | Value
Error code | 11
Constant | END_READ (Java) STREAM_ERROR_END_READ (C/C++) ulStreamErrorEndRead (Visual Basic)
Probable cause

Unable to finish a sequence of reads from the network.

See also: READ


An end write failed.

Item | Value
Error code | 10
Constant | END_WRITE (Java) STREAM_ERROR_END_WRITE (C/C++) ulStreamErrorEndWrite (Visual Basic)
Probable cause

Unable to finish a sequence of writes to the network.

See also: WRITE


An error occurred during shutdown.

Item | Value
Error code | 18
Constant | SHUTTING_DOWN (Java) STREAM_ERROR_SHUTTING_DOWN (C/C++) ulStreamErrorShuttingDown (Visual Basic)
Probable cause

The MobiLink synchronization server encountered an error in the network layer during shutdown. It is possible that some network operations pending at the time of shutdown were affected.


An error status was returned: '%1!s!'.

Item | Value
Error code | 86
Constant | HTTP_BAD_STATUS_CODE (Java) STREAM_ERROR_HTTP_BAD_STATUS_CODE (C/C++) ulStreamErrorHttpBadStatusCode (Visual Basic)
Parameter 1 | The status line read.
Probable cause

Examine the status line to determine the cause of the failure.


An unexpected character was read while parsing the chunk length. %1!s!.

Item | Value
Error code | 85
Constant | HTTP_CHUNK_LEN_BAD_CHARACTER (Java) STREAM_ERROR_HTTP_CHUNK_LEN_BAD_CHARACTER (C/C++) ulStreamErrorHttpChunkLenBadCharacter (Visual Basic)
Parameter 1 | The unexpected character.
Probable cause

Try using a fixed length HTTP body.


Automatic dialup is not supported on this machine.

Item | Value
Error code | 203
Constant | DUN_NOT_SUPPORTED (Java) STREAM_ERROR_DUN_NOT_SUPPORTED (C/C++) ulStreamErrorDunNotSupported (Visual Basic)
Probable cause

An attempt to dialup has failed due to insufficient system support.

On PocketPC we require cellcore.dll and on Windows we require

wininet.dll from IE 4.0 or above. Dialup is not supported on other

platforms.


Certificate error (4023).

Item | Value
Error code | 23
Constant | SECURE_CERTIFICATE_REF (Java) STREAM_ERROR_SECURE_CERTIFICATE_REF (C/C++) ulStreamErrorSecureCertificateRef (Visual Basic)
Probable cause

This is an internal error in the secure network layer. This is an internal error that should never occur. Please contact technical support.


Client id is not available for use in HTTP header.

Item | Value
Error code | 78
Constant | HTTP_CLIENT_ID_NOT_SET (Java) STREAM_ERROR_HTTP_CLIENT_ID_NOT_SET (C/C++) ulStreamErrorHttpClientIdNotSet (Visual Basic)
Probable cause

The client id was not passed into the HTTP client code. Contact technical support for a fix.


Error parsing HTTP header: %1!s!

Item | Value
Error code | 216
Constant | HTTP_HEADER_PARSE_ERROR (Java) STREAM_ERROR_HTTP_HEADER_PARSE_ERROR (C/C++) ulStreamErrorHttpHeaderParseError (Visual Basic)
Probable cause

An error occurred while trying to parse an HTTP header. The header may

be malformed.


Error reading from the trusted certificate file '%1!s!'.

Item | Value
Error code | 41
Constant | SECURE_TRUSTED_CERTIFICATE_READ (Java) STREAM_ERROR_SECURE_TRUSTED_CERTIFICATE_READ (C/C++) ulStreamErrorSecureTrustedCertificateRead (Visual Basic)
Parameter 1 | The trusted certificate file name.
Probable cause

The secure network layer was unable to read the trusted certificate file. Check the following:

1) The certificate file name was properly specified.

2) The certificate file exists.

3) The certificate file contains one or more certificates.

4) The certificate file contains the correct certificate(s).

5) The program attempting to open the certificate file has sufficient privileges to see the file. This only applies to operating systems having user and/or file permissions.


Expected data from remote but current request is not a POST.

Item | Value
Error code | 89
Constant | HTTP_EXPECTED_POST (Java) STREAM_ERROR_HTTP_EXPECTED_POST (C/C++) ulStreamErrorHttpExpectedPost (Visual Basic)
Probable cause

The proxy you are using may not be compatible with MobiLink. Please check your configuration.


Extra data found in the HTTP body: %1!s!

Item | Value
Error code | 80
Constant | HTTP_EXTRA_DATA_END_READ (Java) STREAM_ERROR_HTTP_EXTRA_DATA_END_READ (C/C++) ulStreamErrorHttpExtraDataEndRead (Visual Basic)
Parameter 1 | First few characters in the extra data.
Probable cause

Extra data has been introduced into the HTTP body. This may have been added by a proxy agent. Try eliminating the proxy.


Failed dialing to %1!s!.

Item | Value
Error code | 204
Constant | DUN_DIAL_FAILED (Java) STREAM_ERROR_DUN_DIAL_FAILED (C/C++) ulStreamErrorDunDialFailed (Visual Basic)
Probable cause

Automatic dialup failed to establish connection to the specified

dial up network.


Failed to read CR LF.

Item | Value
Error code | 82
Constant | HTTP_CRLF_MISSING (Java) STREAM_ERROR_HTTP_CRLF_MISSING (C/C++) ulStreamErrorHttpCrlfMissing (Visual Basic)
Probable cause

The proxy you are using may not be compatible with MobiLink. Please check your configuration.


Failed to read encoded chunk length.

Item | Value
Error code | 84
Constant | HTTP_CHUNK_LEN_ENCODED_MISSING (Java) STREAM_ERROR_HTTP_CHUNK_LEN_ENCODED_MISSING (C/C++) ulStreamErrorHttpChunkLenEncodedMissing (Visual Basic)
Probable cause

Try using a fixed length HTTP body.


Failed to read encoded CR LF.

Item | Value
Error code | 81
Constant | HTTP_CRLF_ENCODED_MISSING (Java) STREAM_ERROR_HTTP_CRLF_ENCODED_MISSING (C/C++) ulStreamErrorHttpCrlfEncodedMissing (Visual Basic)
Probable cause

The proxy you are using may not be compatible with MobiLink. Please check your configuration.


Feature not implemented.

Item | Value
Error code | 12
Constant | NOT_IMPLEMENTED (Java) STREAM_ERROR_NOT_IMPLEMENTED (C/C++) ulStreamErrorNotImplemented (Visual Basic)
Probable cause

An unimplemented internal feature was requested. Please contact technical support.


Handshake error.

Item | Value
Error code | 53
Constant | SECURE_HANDSHAKE (Java) STREAM_ERROR_SECURE_HANDSHAKE (C/C++) ulStreamErrorSecureHandshake (Visual Basic)
Probable cause

The secure handshake failed. Check the following:

1) On the client, the correct host machine and port number were specified.

2) On the server, the correct port number was specified.

3) The correct certificate file was specified, both on the client and on the server.


HTTP Authentication failed.

Item | Value
Error code | 211
Constant | HTTP_AUTHENTICATION_FAILED (Java) STREAM_ERROR_HTTP_AUTHENTICATION_FAILED (C/C++) ulStreamErrorHttpAuthenticationFailed (Visual Basic)
Probable cause

The supplied userid and password were rejected. Check that they were

entered correctly. If so, contact your systems administrator to

ensure you have proper access.


HTTP Proxy Authentication failed.

Item | Value
Error code | 212
Constant | HTTP_PROXY_AUTHENTICATION_FAILED (Java) STREAM_ERROR_HTTP_PROXY_AUTHENTICATION_FAILED (C/C++) ulStreamErrorHttpProxyAuthenticationFailed (Visual Basic)
Probable cause

The supplied userid and password were rejected by the proxy server.

Check that they were entered correctly. If so, contact your systems

administrator to ensure you have proper access.


HTTP server authentication failed

Item | Value
Error code | 217
Constant | HTTP_SERVER_AUTH_FAILED (Java) STREAM_ERROR_HTTP_SERVER_AUTH_FAILED (C/C++) ulStreamErrorHttpServerAuthFailed (Visual Basic)
Probable cause

The Authentication-Info header sent from the server contained an

incorrect value, causing authentication to fail. Make sure that

you are connecting to a legitimate HTTP server.


Internal error 4027.

Item | Value
Error code | 27
Constant | SECURE_SET_IO_SEMANTICS (Java) STREAM_ERROR_SECURE_SET_IO_SEMANTICS (C/C++) ulStreamErrorSecureSetIoSemantics (Visual Basic)
Probable cause

An internal error has occurred in the network layer. Please contact technical support.


Internal error 4028.

Item | Value
Error code | 28
Constant | SECURE_CERTIFICATE_CHAIN_FUNC (Java) STREAM_ERROR_SECURE_CERTIFICATE_CHAIN_FUNC (C/C++) ulStreamErrorSecureCertificateChainFunc (Visual Basic)
Probable cause

An internal error has occurred in the network layer. Please contact technical support.


Internal error 4029.

Item | Value
Error code | 29
Constant | SECURE_CERTIFICATE_CHAIN_REF (Java) STREAM_ERROR_SECURE_CERTIFICATE_CHAIN_REF (C/C++) ulStreamErrorSecureCertificateChainRef (Visual Basic)
Probable cause

An internal error has occurred in the network layer. Please contact technical support.


Internal error 4030.

Item | Value
Error code | 30
Constant | SECURE_ENABLE_NON_BLOCKING (Java) STREAM_ERROR_SECURE_ENABLE_NON_BLOCKING (C/C++) ulStreamErrorSecureEnableNonBlocking (Visual Basic)
Probable cause

An internal error has occurred in the network layer. Please contact technical support.


Internal error 4031.

Item | Value
Error code | 31
Constant | SECURE_SET_CIPHER_SUITES (Java) STREAM_ERROR_SECURE_SET_CIPHER_SUITES (C/C++) ulStreamErrorSecureSetCipherSuites (Visual Basic)
Probable cause

An internal error has occurred in the network layer. Please contact technical support.


Internal error 4032.

Item | Value
Error code | 32
Constant | SECURE_SET_CHAIN_NUMBER (Java) STREAM_ERROR_SECURE_SET_CHAIN_NUMBER (C/C++) ulStreamErrorSecureSetChainNumber (Visual Basic)
Probable cause

An internal error has occurred in the network layer. Please contact technical support.


Internal initialization error 4045.

Item | Value
Error code | 45
Constant | SECURE_SET_RANDOM_REF (Java) STREAM_ERROR_SECURE_SET_RANDOM_REF (C/C++) ulStreamErrorSecureSetRandomRef (Visual Basic)
Probable cause

An internal error has occurred in the network layer. Please contact technical support.


Internal initialization error 4046.

Item | Value
Error code | 46
Constant | SECURE_SET_RANDOM_FUNC (Java) STREAM_ERROR_SECURE_SET_RANDOM_FUNC (C/C++) ulStreamErrorSecureSetRandomFunc (Visual Basic)
Probable cause

An internal error has occurred in the network layer. Please contact technical support.


Internal initialization error 4055.

Item | Value
Error code | 55
Constant | SECURE_SET_READ_FUNC (Java) STREAM_ERROR_SECURE_SET_READ_FUNC (C/C++) ulStreamErrorSecureSetReadFunc (Visual Basic)
Probable cause

This initialization error is most likely due to a lack of system resources. Free up system resources and retry the operation.


Internal initialization error 4056.

Item | Value
Error code | 56
Constant | SECURE_SET_WRITE_FUNC (Java) STREAM_ERROR_SECURE_SET_WRITE_FUNC (C/C++) ulStreamErrorSecureSetWriteFunc (Visual Basic)
Probable cause

This initialization error is most likely due to a lack of system resources. Free up system resources and retry the operation.


Invalid certificate chain length (%1!s!).

Item | Value
Error code | 22
Constant | SECURE_CERTIFICATE_CHAIN_LENGTH (Java) STREAM_ERROR_SECURE_CERTIFICATE_CHAIN_LENGTH (C/C++) ulStreamErrorSecureCertificateChainLength (Visual Basic)
Parameter 1 | The certificate chain length.
Probable cause

The certificate chain has the wrong length. This is an internal error that should never occur. Please contact technical support.


Invalid liveness timeout value %1!s!. The value must be between zero and 65535.

Item | Value
Error code | 200
Constant | SOCKET_LIVENESS_OUT_OF_RANGE (Java) STREAM_ERROR_SOCKET_LIVENESS_OUT_OF_RANGE (C/C++) ulStreamErrorSocketLivenessOutOfRange (Visual Basic)
Parameter 1 | The liveness timeout value.
Probable cause

An invalid liveness timeout value was specified. The liveness timeout value must be an integer between zero and 65535.


Invalid parameter '%1!s!'.

Item | Value
Error code | 1
Constant | PARAMETER (Java) STREAM_ERROR_PARAMETER (C/C++) ulStreamErrorParameter (Visual Basic)
Parameter 1 | The invalid parameter value.
Probable cause

Network parameters are of the form "name=value;[name2=value2[;...]]". This code indicates an invalid parameter value. Consult the documentation for the corresponding parameter name, and correct the parameter value.


Invalid port number %1!s!. The value must be between zero and 65535.

Item | Value
Error code | 74
Constant | SOCKET_PORT_OUT_OF_RANGE (Java) STREAM_ERROR_SOCKET_PORT_OUT_OF_RANGE (C/C++) ulStreamErrorSocketPortOutOfRange (Visual Basic)
Parameter 1 | The port number.
Probable cause

An invalid port number was specified. The port number must be an integer between zero and 65535.


Invalid root certificate.

Item | Value
Error code | 20
Constant | SECURE_CERTIFICATE_ROOT (Java) STREAM_ERROR_SECURE_CERTIFICATE_ROOT (C/C++) ulStreamErrorSecureCertificateRoot (Visual Basic)
Probable cause

The root certificate in the chain is invalid. At the time of publication, this error was defined but not used.


No error or unknown error.

Item | Value
Error code | 0
Constant | NONE (Java) STREAM_ERROR_NONE (C/C++) ulStreamErrorNone (Visual Basic)
Probable cause

This code indicates there was either no network error, or an unknown network error occurred.


No password was supplied.

Item | Value
Error code | 214
Constant | HTTP_NO_PASSWORD (Java) STREAM_ERROR_HTTP_NO_PASSWORD (C/C++) ulStreamErrorHttpNoPassword (Visual Basic)
Probable cause

A userid was supplied for HTTP authentication but no password. Both

are required for authentication.


No server certificate password was provided.

Item | Value
Error code | 206
Constant | SECURE_NO_SERVER_CERTIFICATE_PASSWORD (Java) STREAM_ERROR_SECURE_NO_SERVER_CERTIFICATE_PASSWORD (C/C++) ulStreamErrorSecureNoServerCertificatePassword (Visual Basic)
Probable cause

No server certificate password was provided. This password is required to

decrypt the server's encrypted private key.


No server certificate was provided.

Item | Value
Error code | 205
Constant | SECURE_NO_SERVER_CERTIFICATE (Java) STREAM_ERROR_SECURE_NO_SERVER_CERTIFICATE (C/C++) ulStreamErrorSecureNoServerCertificate (Visual Basic)
Probable cause

No server certificate was provided. A server certificate is required for

secure communications. The file provided must contain the full chain

of certificates for the server as well as its private key.


No trusted certificates found.

Item | Value
Error code | 42
Constant | SECURE_CERTIFICATE_COUNT (Java) STREAM_ERROR_SECURE_CERTIFICATE_COUNT (C/C++) ulStreamErrorSecureCertificateCount (Visual Basic)
Probable cause

The given file does not contain a certificate. Check the following:

1) The certificate file name was properly specified.

2) The certificate file contains one or more certificates.

3) The certificate file contains the correct certificate(s).


No trusted root certificates were provided.

Item | Value
Error code | 207
Constant | SECURE_NO_TRUSTED_ROOTS (Java) STREAM_ERROR_SECURE_NO_TRUSTED_ROOTS (C/C++) ulStreamErrorSecureNoTrustedRoots (Visual Basic)
Probable cause

No trusted root certificates were provided. At least one trusted root

certificate is required for secure communications.


No userid was supplied.

Item | Value
Error code | 213
Constant | HTTP_NO_USERID (Java) STREAM_ERROR_HTTP_NO_USERID (C/C++) ulStreamErrorHttpNoUserid (Visual Basic)
Probable cause

A password was supplied for HTTP authentication but no userid. Both

are required for authentication.


Parameter value '%1!s!' is not a valid boolean value. The value must be 0 or 1.

Item | Value
Error code | 4
Constant | PARAMETER_NOT_BOOLEAN (Java) STREAM_ERROR_PARAMETER_NOT_BOOLEAN (C/C++) ulStreamErrorParameterNotBoolean (Visual Basic)
Parameter 1 | The invalid parameter value.
Probable cause

Network parameters are of the form "name=value;[name2=value2[;...]]". The parameter value is not a boolean value. Locate the offending parameter specification and change the value of the parameter to either 0 (for off or false) or 1 (for on or true).


Parameter value '%1!s!' is not a valid hexadecimal value.

Item | Value
Error code | 5
Constant | PARAMETER_NOT_HEX (Java) STREAM_ERROR_PARAMETER_NOT_HEX (C/C++) ulStreamErrorParameterNotHex (Visual Basic)
Parameter 1 | The invalid parameter value.
Probable cause

Network parameters are of the form "name=value;[name2=value2[;...]]". The parameter value is not a hexadecimal (base 16) value. Locate the offending parameter specification and change the value of the parameter to a hexadecimal value.


Parameter value '%1!s!' is not an unsigned integer value or range. A range has the form NNN-NNN.

Item | Value
Error code | 3
Constant | PARAMETER_NOT_UINT32_RANGE (Java) STREAM_ERROR_PARAMETER_NOT_UINT32_RANGE (C/C++) ulStreamErrorParameterNotUint32Range (Visual Basic)
Parameter 1 | The invalid parameter value.
Probable cause

Network parameters are of the form "name=value;[name2=value2[;...]]". The parameter value is not an unsigned integer value or range. Locate the offending parameter specification and change the value of the parameter to an unsigned integer or an unsigned range. An unsigned range has the form: NNN-NNN.


Parameter value '%1!s!' is not an unsigned integer.

Item | Value
Error code | 2
Constant | PARAMETER_NOT_UINT32 (Java) STREAM_ERROR_PARAMETER_NOT_UINT32 (C/C++) ulStreamErrorParameterNotUint32 (Visual Basic)
Parameter 1 | The invalid parameter value.
Probable cause

Network parameters are of the form "name=value;[name2=value2[;...]]". The parameter value is not an unsigned integer. Locate the offending parameter specification and change the value of the parameter to an unsigned integer.


Password specified for an unencrypted server key.

Item | Value
Error code | 208
Constant | SECURE_REDUNDANT_SERVER_CERTIFICATE_PASSWORD (Java) STREAM_ERROR_SECURE_REDUNDANT_SERVER_CERTIFICATE_PASSWORD (C/C++) ulStreamErrorSecureRedundantServerCertificatePassword (Visual Basic)
Probable cause

A password was specified when the server's private key wasn't encrypted

by any password.


Server certificate not trusted.

Item | Value
Error code | 24
Constant | SECURE_CERTIFICATE_NOT_TRUSTED (Java) STREAM_ERROR_SECURE_CERTIFICATE_NOT_TRUSTED (C/C++) ulStreamErrorSecureCertificateNotTrusted (Visual Basic)
Probable cause

The server's certificate was not signed by a trusted authority. Check the following:

1) The certificate file name was properly specified.

2) The certificate file contains one or more certificates.

3) The certificate file contains the correct certificate(s).

4) The client's list of trusted root certificates includes the server's root certificate.


The content type '%1!s!' is unknown.

Item | Value
Error code | 77
Constant | HTTP_CONTENT_TYPE_NOT_SPECIFIED (Java) STREAM_ERROR_HTTP_CONTENT_TYPE_NOT_SPECIFIED (C/C++) ulStreamErrorHttpContentTypeNotSpecified (Visual Basic)
Parameter 1 | The content type.
Probable cause

An unknown content type was specified. Refer to the documentation and change the content type to one of the supported types.


The host name '%1!s!' could not be found.

Item | Value
Error code | 57
Constant | SOCKET_HOST_NAME_NOT_FOUND (Java) STREAM_ERROR_SOCKET_HOST_NAME_NOT_FOUND (C/C++) ulStreamErrorSocketHostNameNotFound (Visual Basic)
Parameter 1 | The name of the host.
Probable cause

The given host name could not be found. Check the following:

1) The host name was correctly specified.

2) The host is accessible. Many systems include a "ping" utility that can be used to verify access to a named host.

3) The Domain Name Server (DNS), or its equivalent, is available. If the DNS is not available, try specifying the host's IP number (eg. NNN.NNN.NNN.NNN) instead of the host name.

4) The HOSTS file contains an entry that maps the host name to an IP number.


The HTTP buffer size specified is out of the valid range.

Item | Value
Error code | 79
Constant | HTTP_BUFFER_SIZE_OUT_OF_RANGE (Java) STREAM_ERROR_HTTP_BUFFER_SIZE_OUT_OF_RANGE (C/C++) ulStreamErrorHttpBufferSizeOutOfRange (Visual Basic)
Probable cause

Fix the HTTP buffer size. A valid buffer size is positive and not overly large for the host platform.


The operation would cause blocking.

Item | Value
Error code | 13
Constant | WOULD_BLOCK (Java) STREAM_ERROR_WOULD_BLOCK (C/C++) ulStreamErrorWouldBlock (Visual Basic)
Probable cause

A requested operation would block where blocking is undesirable or unexpected.


Timed out trying to read %1!s! bytes.

Item | Value
Error code | 201
Constant | READ_TIMEOUT (Java) STREAM_ERROR_READ_TIMEOUT (C/C++) ulStreamErrorReadTimeout (Visual Basic)
Parameter 1 | The number of bytes that could not be read.
Probable cause

Unable to read the given number of bytes from the network layer in the given time.

Check that the network is functioning correctly, and that the sending application is still running.


Timed out trying to write %1!s! bytes.

Item | Value
Error code | 202
Constant | WRITE_TIMEOUT (Java) STREAM_ERROR_WRITE_TIMEOUT (C/C++) ulStreamErrorWriteTimeout (Visual Basic)
Parameter 1 | The number of bytes that could not be written.
Probable cause

Unable to write the given number of bytes to the network layer in the given time.

Check that the network is functioning correctly, and that the receiving application is still running.


Timed out while waiting for the next HTTP request in this synchronization.

Item | Value
Error code | 83
Constant | HTTP_NO_CONTD_CONNECTION (Java) STREAM_ERROR_HTTP_NO_CONTD_CONNECTION (C/C++) ulStreamErrorHttpNoContdConnection (Visual Basic)
Probable cause

The server timed out while waiting for the next HTTP request from the remote site. Determine why this request failed to reach the server or try a persistent connection.


Unable to add a certificate to a certificate chain.

Item | Value
Error code | 39
Constant | SECURE_ADD_CERTIFICATE (Java) STREAM_ERROR_SECURE_ADD_CERTIFICATE (C/C++) ulStreamErrorSecureAddCertificate (Visual Basic)
Probable cause

The secure network layer was unable to add a certificate to a certificate chain. Free up system resources and retry the operation.


Unable to add a trusted certificate.

Item | Value
Error code | 48
Constant | SECURE_ADD_TRUSTED_CERTIFICATE (Java) STREAM_ERROR_SECURE_ADD_TRUSTED_CERTIFICATE (C/C++) ulStreamErrorSecureAddTrustedCertificate (Visual Basic)
Probable cause

The secure network layer was unable to add a trusted certificate to a certificate chain. The most likely cause is a shortage of system resources. Free up system resources and retry the operation.


Unable to allocate %1!s! bytes.

Item | Value
Error code | 6
Constant | MEMORY_ALLOCATION (Java) STREAM_ERROR_MEMORY_ALLOCATION (C/C++) ulStreamErrorMemoryAllocation (Visual Basic)
Parameter 1 | The number of bytes that was requested.
Probable cause

The network layer was unable to allocate the given number of bytes of storage. Free up system memory and retry the operation. The technique used to free up system memory depends on the operating system and how it is configured. The simplest technique is to reduce the number of active processes. Consult your operating system documentation for details.


Unable to allocate a certificate.

Item | Value
Error code | 43
Constant | SECURE_CREATE_CERTIFICATE (Java) STREAM_ERROR_SECURE_CREATE_CERTIFICATE (C/C++) ulStreamErrorSecureCreateCertificate (Visual Basic)
Probable cause

The secure network layer was unable to allocate storage for a certificate. Free up system resources and retry the operation.


Unable to attach the network layer to the security layer.

Item | Value
Error code | 26
Constant | SECURE_SET_IO (Java) STREAM_ERROR_SECURE_SET_IO (C/C++) ulStreamErrorSecureSetIo (Visual Basic)
Probable cause

The secure network layer was unable to attach to the network layer. Free up system resources and retry the operation.


Unable to bind a socket to port %1!s!.

Item | Value
Error code | 60
Constant | SOCKET_BIND (Java) STREAM_ERROR_SOCKET_BIND (C/C++) ulStreamErrorSocketBind (Visual Basic)
Parameter 1 | The port number.
Probable cause

The network layer was unable to bind a socket to the given port. Check the following.

1) (Server only) Verify that the port isn't already in use. If the port is in use, either shut down the application listening on that port, or specify a different port.

2) (Server only) Verify that there are no firewall restrictions on the use of the port.

3) (Client only) If the client_port option was used, verify that the given port isn't already in use. If only one client port was specified, consider using a range (eg. NNN-NNN). If a range was specified, consider making it a wider range, or a different range.

4) (Client only) If the client_port option was used, verify that there are no firewall restrictions on the use of the port.


Unable to clean up the socket layer.

Item | Value
Error code | 61
Constant | SOCKET_CLEANUP (Java) STREAM_ERROR_SOCKET_CLEANUP (C/C++) ulStreamErrorSocketCleanup (Visual Basic)
Probable cause

The network layer was unable to clean up the socket layer. This error should only occur after all connections are finished, so no current connections should be affected.


Unable to close a socket.

Item | Value
Error code | 62
Constant | SOCKET_CLOSE (Java) STREAM_ERROR_SOCKET_CLOSE (C/C++) ulStreamErrorSocketClose (Visual Basic)
Probable cause

The network layer was unable to close a socket. The network session may or may not have terminated prematurely, due to pending writes that were not flushed. Check the following:

1) The other side of the network connection had any errors.

2) The other side of the connection is running normally.

3) The machine is still connected to the network, and the network is responsive.


Unable to connect a socket.

Item | Value
Error code | 63
Constant | SOCKET_CONNECT (Java) STREAM_ERROR_SOCKET_CONNECT (C/C++) ulStreamErrorSocketConnect (Visual Basic)
Probable cause

The network layer was unable to connect a socket. Check the following:

1) The machine is connected to the network.

2) The socket layer is properly initialized.

3) The correct host machine and port were specified.

4) The host server is running normally and listening on the correct port.

5) The host machine is listening for the proper socket type (TCP/IP vs. UDP).

6) If the client_port option was used, verify that there are no firewall restrictions on the use of the port.

7) If the device has a limit on the number of open sockets, verify that the limit has not been reached.

8) There are enough system resources available. Free up system resources if they are running low.


Unable to copy a certificate.

Item | Value
Error code | 38
Constant | SECURE_EXPORT_CERTIFICATE (Java) STREAM_ERROR_SECURE_EXPORT_CERTIFICATE (C/C++) ulStreamErrorSecureExportCertificate (Visual Basic)
Probable cause

The secure network layer was unable to copy a certificate. Free up system resources and retry the operation.


Unable to create a private key object.

Item | Value
Error code | 49
Constant | SECURE_CREATE_PRIVATE_KEY_OBJECT (Java) STREAM_ERROR_SECURE_CREATE_PRIVATE_KEY_OBJECT (C/C++) ulStreamErrorSecureCreatePrivateKeyObject (Visual Basic)
Probable cause

The secure network layer was unable to create a private key object, prior to loading the private key. The most likely cause is a shortage of system resources. Free up system resources and retry the operation.


Unable to create a random number object.

Item | Value
Error code | 17
Constant | CREATE_RANDOM_OBJECT (Java) STREAM_ERROR_CREATE_RANDOM_OBJECT (C/C++) ulStreamErrorCreateRandomObject (Visual Basic)
Probable cause

The secure network layer could not create a random-number-generating object. Free up system resources, reconnect and retry the operation.


Unable to create a TCP/IP socket.

Item | Value
Error code | 58
Constant | SOCKET_CREATE_TCPIP (Java) STREAM_ERROR_SOCKET_CREATE_TCPIP (C/C++) ulStreamErrorSocketCreateTcpip (Visual Basic)
Probable cause

The network layer was unable to create a TCP/IP socket. Check the following:

1) The machine is connected to the network.

2) The socket layer is properly initialized.

5) If the device has a limit on the number of open sockets, verify that the limit has not been reached.

6) There are enough system resources available. Free up system resources if they are running low.


Unable to create a UDP socket.

Item | Value
Error code | 59
Constant | SOCKET_CREATE_UDP (Java) STREAM_ERROR_SOCKET_CREATE_UDP (C/C++) ulStreamErrorSocketCreateUdp (Visual Basic)
Probable cause

The network layer was unable to create a UDP socket. Check the following:

1) The machine is connected to the network.

2) The socket layer is properly initialized.

3) If the client_port option was used, verify that the given port isn't already in use. If only one client port was specified, consider using a range (eg. NNN-NNN). If a range was specified, consider making it a wider range, or a different range.

4) If the client_port option was used, verify that there are no firewall restrictions on the use of the port.

5) If the device has a limit on the number of open sockets, verify that the limit has not been reached.

6) There are enough system resources available. Free up system resources if they are running low.


Unable to dequeue from the connection queue.

Item | Value
Error code | 19
Constant | DEQUEUING_CONNECTION (Java) STREAM_ERROR_DEQUEUING_CONNECTION (C/C++) ulStreamErrorDequeuingConnection (Visual Basic)
Probable cause

The MobiLink synchronization server encountered an error while attempting to get a queued connection (synchronization) request. Free up system resources. If the problem persists, restart the MobiLink synchronization server.


Unable to determine localhost.

Item | Value
Error code | 71
Constant | SOCKET_LOCALHOST_NAME_NOT_FOUND (Java) STREAM_ERROR_SOCKET_LOCALHOST_NAME_NOT_FOUND (C/C++) ulStreamErrorSocketLocalhostNameNotFound (Visual Basic)
Probable cause

The network layer was unable to determine the IP address of "localhost". Check the following:

1) The Domain Name Server (DNS), or its equivalent, is available. If the DNS is not available, try explicitly specifying the localhost IP number (usually 127.0.0.1) instead.

2) The HOSTS file contains an entry that maps the "localhost" name to an IP number.

3) There are enough system resources available. Free up system resources if they are running low.


Unable to duplicate security context.

Item | Value
Error code | 25
Constant | SECURE_DUPLICATE_CONTEXT (Java) STREAM_ERROR_SECURE_DUPLICATE_CONTEXT (C/C++) ulStreamErrorSecureDuplicateContext (Visual Basic)
Probable cause

The secure network layer was unable to duplicate a security context.

Free up system resources and retry the operation.


Unable to fetch a certificate expiry date.

Item | Value
Error code | 37
Constant | SECURE_CERTIFICATE_EXPIRY_DATE (Java) STREAM_ERROR_SECURE_CERTIFICATE_EXPIRY_DATE (C/C++) ulStreamErrorSecureCertificateExpiryDate (Visual Basic)
Probable cause

A certificate's expiry date could not be read. Check the following:

1) The password was entered correctly.

2) The certificate file contains one or more certificates.

3) The certificate file contains the correct certificate(s).

4) The certificate file is undamaged.


Unable to find the trusted certificate file '%1!s!'.

Item | Value
Error code | 40
Constant | SECURE_TRUSTED_CERTIFICATE_FILE_NOT_FOUND (Java) STREAM_ERROR_SECURE_TRUSTED_CERTIFICATE_FILE_NOT_FOUND (C/C++) ulStreamErrorSecureTrustedCertificateFileNotFound (Visual Basic)
Parameter 1 | The trusted certificate file name.
Probable cause

The certificate file could not be found. Check the following:

1) The certificate file name was properly specified.

2) The certificate file exists.

3) The certificate file contains one or more certificates.

4) The certificate file contains the correct certificate(s).

5) The program attempting to open the certificate file has sufficient privileges to see the file. This only applies to operating systems having user and/or file permissions.


Unable to generate a random number.

Item | Value
Error code | 14
Constant | GENERATE_RANDOM (Java) STREAM_ERROR_GENERATE_RANDOM (C/C++) ulStreamErrorGenerateRandom (Visual Basic)
Probable cause

The secure network layer requires a random number but was unable to generate one. Free up system resources, reconnect and retry the operation.


Unable to get a socket's local name.

Item | Value
Error code | 64
Constant | SOCKET_GET_NAME (Java) STREAM_ERROR_SOCKET_GET_NAME (C/C++) ulStreamErrorSocketGetName (Visual Basic)
Probable cause

The network layer was unable to determine a socket's local name. In a TCP/IP connection, each end of the connection has a socket exclusively attached to a port. A socket's local name includes this port number, which is assigned by the network at connection time. Check the following:

1) The machine is still connected to the network, and the network is responsive.

2) The other side of the connection is running normally.

3) There are enough system resources available. Free up system resources if they are running low.


Unable to get host by address.

Item | Value
Error code | 72
Constant | SOCKET_GET_HOST_BY_ADDR (Java) STREAM_ERROR_SOCKET_GET_HOST_BY_ADDR (C/C++) ulStreamErrorSocketGetHostByAddr (Visual Basic)
Probable cause

The network layer was unable to get the name of a host using its IP address. At the time of publication, this error was defined but not used.


Unable to get socket option number %1!s!.

Item | Value
Error code | 65
Constant | SOCKET_GET_OPTION (Java) STREAM_ERROR_SOCKET_GET_OPTION (C/C++) ulStreamErrorSocketGetOption (Visual Basic)
Parameter 1 | The socket option being retrieved.
Probable cause

The network layer was unable to get a socket option. This error may be the first indication that a connection has been lost. Check the following:

1) The machine is still connected to the network, and the network is responsive.

2) The other side of the connection is running normally.

3) There are enough system resources available. Free up system resources if they are running low.


Unable to import a certificate.

Item | Value
Error code | 44
Constant | SECURE_IMPORT_CERTIFICATE (Java) STREAM_ERROR_SECURE_IMPORT_CERTIFICATE (C/C++) ulStreamErrorSecureImportCertificate (Visual Basic)
Probable cause

The secure network layer was unable to import a certificate. Check the following:

1) The certificate file name was properly specified.

2) The certificate file exists.

3) The certificate file contains one or more certificates.

4) The certificate file contains the correct certificate(s).


Unable to initialize the random number generator.

Item | Value
Error code | 15
Constant | INIT_RANDOM (Java) STREAM_ERROR_INIT_RANDOM (C/C++) ulStreamErrorInitRandom (Visual Basic)
Probable cause

The secure network layer could not initialize its random number generator. Free up system resources, reconnect and retry the operation.


Unable to initialize the sockets layer.

Item | Value
Error code | 70
Constant | SOCKET_STARTUP (Java) STREAM_ERROR_SOCKET_STARTUP (C/C++) ulStreamErrorSocketStartup (Visual Basic)
Probable cause

The network layer was unable to initialize the socket layer. Check the following:

1) The sockets layer is properly installed. The correct network interface library must be present and accessible.

2) The machine is connected to the network, and the network is responsive.

3) There are enough system resources available. Free up system resources if they are running low.


Unable to listen on a socket. The backlog is %1!s!.

Item | Value
Error code | 67
Constant | SOCKET_LISTEN (Java) STREAM_ERROR_SOCKET_LISTEN (C/C++) ulStreamErrorSocketListen (Visual Basic)
Parameter 1 | The requested listener backlog.
Probable cause

The server is unable to listen on a socket. The backlog refers to the maximum number of queued connection requests that may be pending at any given time. Check the following:

1) The machine is still connected to the network, and the network is responsive.

2) There are no firewall or other restrictions preventing a socket listener from running on the current machine.

3) The backlog setting is within the limit, if any, on the machine.

4) There are enough system resources available. Free up system resources if they are running low.


Unable to load the network interface library.

Item | Value
Error code | 73
Constant | LOAD_NETWORK_LIBRARY (Java) STREAM_ERROR_LOAD_NETWORK_LIBRARY (C/C++) ulStreamErrorLoadNetworkLibrary (Visual Basic)
Probable cause

The network interface library could not be found and/or loaded. Please check the following:

1) The sockets layer is properly installed. The correct network interface library (or DLL or shared object) must be present and accessible.

2) There are enough system resources available. Free up system resources if they are running low.


Unable to open certificate file '%1!s!'.

Item | Value
Error code | 33
Constant | SECURE_CERTIFICATE_FILE_NOT_FOUND (Java) STREAM_ERROR_SECURE_CERTIFICATE_FILE_NOT_FOUND (C/C++) ulStreamErrorSecureCertificateFileNotFound (Visual Basic)
Parameter 1 | The certificate file name.
Probable cause

The certificate file could not be opened. Check the following:

1) The certificate file name was properly specified.

2) The certificate file exists.

3) The certificate file contains one or more certificates.

4) The certificate file contains the correct certificate(s).

5) The program attempting to open the certificate file has sufficient privileges to read the file. This only applies to operating systems having user and/or file permissions.


Unable to parse cookie: '%1!s!'.

Item | Value
Error code | 88
Constant | HTTP_UNABLE_TO_PARSE_COOKIE (Java) STREAM_ERROR_HTTP_UNABLE_TO_PARSE_COOKIE (C/C++) ulStreamErrorHttpUnableToParseCookie (Visual Basic)
Parameter 1 | The set cookie header.
Probable cause

Determine where the set cookie header is being corrupted.


Unable to parse the parameter string '%1!s!'.

Item | Value
Error code | 7
Constant | PARSE (Java) STREAM_ERROR_PARSE (C/C++) ulStreamErrorParse (Visual Basic)
Parameter 1 | The parameter string that could not be parsed.
Probable cause

Network parameters are of the form "name=value;[name2=value2[;...]]". Optionally, the entire list of parameters may be enclosed in parentheses. The given string does not follow this convention. Inspect the string, fix any formatting problems, and retry the operation.


Unable to read %1!s! bytes.

Item | Value
Error code | 8
Constant | READ (Java) STREAM_ERROR_READ (C/C++) ulStreamErrorRead (Visual Basic)
Parameter 1 | The number of bytes that could not be read.
Probable cause

Unable to read the given number of bytes from the network layer. Note that reads may occur as part of any larger network operation. For example, some network layers have sub-layers that perform several reads and writes as part of a basic operation in the upper layer.

The cause of a read error is usually one of the following:

1) The network had a problem that caused the read to fail.

Reconnect and retry the operation.

2) The connection timed out.

Reconnect and retry the operation.

3) The other side of the connection cleanly terminated the connection.

Consult the client and/or server logs for errors that indicate why the connection has been dropped.

Consult the output-log errors and fix the cause, then retry the operation.

4) The process at the other side of the connection was aborted.

Consult the client and/or server output logs for errors that indicate why the process was aborted.

If the process was shut down by other than normal means, there may not be any errors in its output log.

Reconnect and retry the operation.

5) The system is low on resources, and cannot perform the read.

Free up system resources, reconnect and retry the operation. If subsequent retry attempts fail, consult your network administrator.


Unable to read certificates.

Item | Value
Error code | 34
Constant | SECURE_READ_CERTIFICATE (Java) STREAM_ERROR_SECURE_READ_CERTIFICATE (C/C++) ulStreamErrorSecureReadCertificate (Visual Basic)
Probable cause

The certificate file could not be read. Check the following:

1) The password was entered correctly.

2) The certificate file contains one or more certificates.

3) The certificate file contains the correct certificate(s).

4) The certificate file is undamaged.


Unable to read the private key.

Item | Value
Error code | 35
Constant | SECURE_READ_PRIVATE_KEY (Java) STREAM_ERROR_SECURE_READ_PRIVATE_KEY (C/C++) ulStreamErrorSecureReadPrivateKey (Visual Basic)
Probable cause

The private key could not be read from the certificate file. Check the following:

1) The password was entered correctly.

2) The certificate file contains one or more certificates.

3) The certificate file contains the correct certificate(s).

4) The certificate file is undamaged.


Unable to seed the random number generator.

Item | Value
Error code | 16
Constant | SEED_RANDOM (Java) STREAM_ERROR_SEED_RANDOM (C/C++) ulStreamErrorSeedRandom (Visual Basic)
Probable cause

The secure network layer could not seed its random number generator. Free up system resources, reconnect and retry the operation.


Unable to select a socket status.

Item | Value
Error code | 69
Constant | SOCKET_SELECT (Java) STREAM_ERROR_SOCKET_SELECT (C/C++) ulStreamErrorSocketSelect (Visual Basic)
Probable cause

The network layer encountered an error attempting to wait for a socket to be ready for reading or writing. Check the following:

1) The machine is connected to the network, and the network is responsive.

2) The other side of the connection is running normally.

3) There are enough system resources available. Free up system resources if they are running low.


Unable to set socket option number %1!s!.

Item | Value
Error code | 66
Constant | SOCKET_SET_OPTION (Java) STREAM_ERROR_SOCKET_SET_OPTION (C/C++) ulStreamErrorSocketSetOption (Visual Basic)
Parameter 1 | The socket option being set.
Probable cause

The network layer was unable to set a socket option. This error may be the first indication that a connection has been lost. Check the following:

1) The machine is still connected to the network, and the network is responsive.

2) The other side of the connection is running normally.

3) There are enough system resources available. Free up system resources if they are running low.


Unable to set the private key.

Item | Value
Error code | 36
Constant | SECURE_SET_PRIVATE_KEY (Java) STREAM_ERROR_SECURE_SET_PRIVATE_KEY (C/C++) ulStreamErrorSecureSetPrivateKey (Visual Basic)
Probable cause

The private key could not be used. Check the following:

1) The password was entered correctly.

2) The certificate file contains one or more certificates.

3) The certificate file contains the correct certificate(s).

4) The certificate file is undamaged.


Unable to set the protocol side (%1!s!).

Item | Value
Error code | 47
Constant | SECURE_SET_PROTOCOL_SIDE (Java) STREAM_ERROR_SECURE_SET_PROTOCOL_SIDE (C/C++) ulStreamErrorSecureSetProtocolSide (Visual Basic)
Parameter 1 | The server side being set. The value is 1 for server side, and 2 for client side.
Probable cause

The secure network layer was unable to establish the given protocol side. This is an internal error that should never occur. Please contact technical support.


Unable to shut down a socket.

Item | Value
Error code | 68
Constant | SOCKET_SHUTDOWN (Java) STREAM_ERROR_SOCKET_SHUTDOWN (C/C++) ulStreamErrorSocketShutdown (Visual Basic)
Probable cause

The network layer was unable to shut down a socket. Check the following:

1) The machine is connected to the network, and the network is responsive.

2) The other side of the connection is running normally.

3) There are enough system resources available. Free up system resources if they are running low.


Unable to write %1!s! bytes.

Item | Value
Error code | 9
Constant | WRITE (Java) STREAM_ERROR_WRITE (C/C++) ulStreamErrorWrite (Visual Basic)
Parameter 1 | The number of bytes that could not be written.
Probable cause

Unable to write the given number of bytes to the network layer. Note that writes may occur as part of any larger network operation. For example, some network layers have sub-layers that perform several reads and writes as part of a basic operation in the upper layer.

The cause of a write error is usually one of the following:

1) The network had a problem that caused the write to fail.

Reconnect and retry the operation.

2) The connection timed out.

Reconnect and retry the operation.

3) The other side of the connection cleanly terminated the connection.

Consult the client and/or server logs for errors that indicate why the connection has been dropped.

Consult the output-log errors and fix the cause, then retry the operation.

4) The process at the other side of the connection was aborted.

Consult the client and/or server output logs for errors that indicate why the process was aborted.

If the process was shut down by other than normal means, there may not be any errors in its output log.

Reconnect and retry the operation.

5) The system is low on resources, and cannot perform the write.

Free up system resources, reconnect and retry the operation. If subsequent retry attempts fail, consult your network administrator.


Unknown transfer encoding: '%1!s!'.

Item | Value
Error code | 87
Constant | HTTP_UNKNOWN_TRANSFER_ENCODING (Java) STREAM_ERROR_HTTP_UNKNOWN_TRANSFER_ENCODING (C/C++) ulStreamErrorHttpUnknownTransferEncoding (Visual Basic)
Parameter 1 | The unknown encoding.
Probable cause

Determine how the unknown transfer encoding is getting generated.


Unrecognized common name '%1!s!'.

Item | Value
Error code | 52
Constant | SECURE_CERTIFICATE_COMMON_NAME (Java) STREAM_ERROR_SECURE_CERTIFICATE_COMMON_NAME (C/C++) ulStreamErrorSecureCertificateCommonName (Visual Basic)
Parameter 1 | The common name.
Probable cause

The given common name is not in the certificate chain. Check the following:

1) The common name was properly entered.

2) The correct certificate file was specified.

3) The common name is in the certificate chain. You can verify this with the readcert utility.


Unrecognized organization '%1!s!'.

Item | Value
Error code | 21
Constant | SECURE_CERTIFICATE_COMPANY_NAME (Java) STREAM_ERROR_SECURE_CERTIFICATE_COMPANY_NAME (C/C++) ulStreamErrorSecureCertificateCompanyName (Visual Basic)
Parameter 1 | The organization name.
Probable cause

The given organization name is not in the certificate chain. Check the following:

1) The organization name was properly entered.

2) The correct certificate file was specified.

3) The organization name is in the certificate chain. You can verify this with the readcert utility.


Unrecognized organization unit '%1!s!'.

Item | Value
Error code | 51
Constant | SECURE_CERTIFICATE_COMPANY_UNIT (Java) STREAM_ERROR_SECURE_CERTIFICATE_COMPANY_UNIT (C/C++) ulStreamErrorSecureCertificateCompanyUnit (Visual Basic)
Parameter 1 | The organization unit name.
Probable cause

The given organization unit is not in the certificate chain. Check the following:

1) The in company name was properly entered.

2) The correct certificate file was specified.

3) The company name is in the certificate chain. You can verify this with the readcert utility.


Unsupported http authentication algorithm: %1!s!

Item | Value
Error code | 215
Constant | HTTP_UNSUPPORTED_AUTH_ALGORITHM (Java) STREAM_ERROR_HTTP_UNSUPPORTED_AUTH_ALGORITHM (C/C++) ulStreamErrorHttpUnsupportedAuthAlgorithm (Visual Basic)
Probable cause

The HTTP Digest authentication algorithm requested by the server is

unsupported. Only "MD5" and "MD5-sess" are supported.


Unsupported HTTP version: %1!s!

Item | Value
Error code | 54
Constant | HTTP_VERSION (Java) STREAM_ERROR_HTTP_VERSION (C/C++) ulStreamErrorHttpVersion (Visual Basic)
Parameter 1 | The requested HTTP version.
Probable cause

The requested HTTP version is unsupported. Consult the documentation and specify a supported HTTP version. At the time of publication the supported HTTP versions are 1.0 and 1.1.


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Security Guide

Version 9.0.2

DC38177-01-0902-01

October 2004

Copyright
About This Manual
Keeping Your Data Secure
Adaptive Server Anywhere Transport-Layer Security
Installation
Auditing
Restrictions and Other Security Concerns
Restricted Syntax
Integrated Logins
Connecting to the Adaptive Server Anywhere Service
The Adaptive Server Anywhere C2 Patch
More Information


Copyright

Copyright © 1989–2004 Sybase, Inc. Portions copyright © 2001–2004 iAnywhere Solutions, Inc. All rights reserved.

No part of this publication may be reproduced, transmitted, or translated in any form or by any means, electronic, mechanical, manual, optical, or otherwise, without the prior written permission of Sybase, Inc.

Sybase, SYBASE (logo), 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-Library, APT-Translator, ASEP, AvantGo, AvantGo Application Alerts, AvantGo Mobile Delivery, AvantGo Mobile Document Viewer, AvantGo Mobile Inspection, AvantGo Mobile Marketing Channel, AvantGo Mobile Pharma, AvantGo Mobile Sales, AvantGo Pylon, AvantGo Pylon Application Server, AvantGo Pylon Conduit, AvantGo Pylon PIM Server, AvantGo Pylon Pro, Backup Server, BayCam, Bit-Wise, BizTracker, Certified PowerBuilder Developer, Certified SYBASE Professional, Certified SYBASE Professional Logo, 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, Dynamic Mobility Model, Dynamo, e-ADK, E-Anywhere, e-Biz Integrator, 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 Portal (logo), Enterprise SQL Server Manager, Enterprise Work Architecture, Enterprise Work Designer, Enterprise Work Modeler, eProcurement Accelerator, eremote, Everything Works Better When Everything Works Together, EWA, E-Whatever, Financial Fusion, Financial Fusion (and design), Financial Fusion Server, Formula One, Fusion Powered e-Finance, Fusion Powered Financial Destinations, Fusion Powered STP, Gateway Manager, GeoPoint, GlobalFIX, iAnywhere, iAnywhere Solutions, ImpactNow, Industry Warehouse Studio, InfoMaker, Information Anywhere, Information Everywhere, InformationConnect, InstaHelp, Intelligent Self-Care, InternetBuilder, iremote, iScript, Jaguar CTS, jConnect for JDBC, KnowledgeBase, Logical Memory Manager, Mail Anywhere Studio, MainframeConnect, Maintenance Express, Manage Anywhere Studio, MAP, M-Business Channel, M-Business Network, M-Business Server, MDI Access Server, MDI Database Gateway, media.splash, Message Anywhere Server, MetaWorks, MethodSet, ML Query, MobiCATS, My AvantGo, My AvantGo Media Channel, My AvantGo Mobile Marketing, MySupport, Net-Gateway, Net-Library, New Era of Networks, Next Generation Learning, Next Generation Learning Studio, O DEVICE, OASiS, OASiS logo, 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++, Orchestration Studio, Partnerships that Work, PB-Gen, PC APT Execute, PC DB-Net, PC Net Library, PhysicalArchitect, Pocket PowerBuilder, PocketBuilder, Power Through Knowledge, power.stop, Power++, 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, QAnywhere, Rapport, Relational Beans, RepConnector, Replication Agent, Replication Driver, Replication Server, Replication Server Manager, Replication Toolkit, Report Workbench, Report-Execute, Resource Manager, RW-DisplayLib, RW-Library, 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 (logo), 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, TotalFix, TradeForce, Transact-SQL, Translation Toolkit, Turning Imagination Into Reality, UltraLite, UltraLite.NET, UNIBOM, Unilib, Uninull, Unisep, Unistring, URK Runtime Kit for UniCode, Versacore, Viewer, 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, and XP Server are trademarks of Sybase, Inc. or its subsidiaries.

All other trademarks are property of their respective owners.


About This Manual

Subject

This book describes security features available in SQL Anywhere Studio. It includes basic security information, as well as instructions on how to operate the current version of SQL Anywhere Studio in a manner that is comparable to the C2-certified environment.

This book does not include all information on security-related features.

Current software is not C2 certified
Adaptive Server Anywhere version 7.0 achieved the C2 security certification of the US federal government. The C2 section of this manual describes how to operate the current version of Adaptive Server Anywhere in a manner comparable to the C2-certified configuration.

This book is not the certified document describing C2 compliance. The certified documentation is available from the Sybase Web site at [external link] http://www.sybase.com/detail?id=1010458. Nothing in this document should be taken to suggest that the current version of the software is C2 compliant. Use of the phrase "equivalent to the C2-certified configuration" and similar phrases does not imply actual C2 compliance. The only way to operate in a C2-certified manner is to use the C2-certified release of the software according to the C2-certified documentation.

Audience

This manual is for users of Adaptive Server Anywhere who wish to make use of the security features in the software, or run the software in a manner equivalent to the C2-certified configuration.


Keeping Your Data Secure

About this chapter

This chapter describes Adaptive Server Anywhere features that help make your database secure. In particular, this chapter describes auditing, database encryption, and securing Windows CE databases. It also presents overviews of other security features, providing pointers to where you can find more detailed information.

Database administrators are responsible for data security. In this chapter, unless otherwise noted, you require DBA authority to carry out the tasks described.

User IDs and permissions are major security-related topics. For information on these topics, see Managing User IDs and Permissions.

For information about encrypting client/server communications, see Adaptive Server Anywhere Transport-Layer Security.

Security features overview
Controlling database access
Auditing database activity
Running the database server in a secure fashion
Encrypting a database
Encrypting portions of a database
Keeping your Windows CE database secure
Security tips


Security features overview

Since databases may contain proprietary, confidential, or private information, ensuring that the database and the data in it are designed for security is very important.

Adaptive Server Anywhere has several features to assist in building a secure environment for your data:

  • User identification and authentication These features control who has access to a database.

    For information on these subjects, see Creating new users.

  • Discretionary access control features These features control the actions a user can carry out while connected to a database.

    For more information, see Database permissions overview.

  • Auditing This feature helps you maintain a record of actions on the database.

    For more information, see Auditing database activity.

  • Database server options These features let you control who can carry out operations (for example, loading databases). These options are set when you start the database server.

    For more information, see Controlling permissions from the command line.

  • Views and stored procedures These features allow you to specify the data a user can access and the operations a user can execute.

    For more information, see Using views and procedures for extra security.

  • Database encryption Database encryption features allow you to choose the level of database encryption. You can choose to secure your database either with simple encryption, or with strong encryption. Simple encryption is equivalent to obfuscation. Strong encryption renders the database completely inaccessible without an encryption key.

    For more information, see -ek database option and DatabaseKey connection parameter [DBKEY].

  • Transport-layer security You can use transport-layer security to authenticate communications between client applications and the database server. Transport-layer security uses elliptic-curve or RSA encryption technology.

    Separately licensable option required
    Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

    To order this component, see Separately-licensable components.

    For more information, see Adaptive Server Anywhere Transport-Layer Security.

  • C2 certification C2 is a set of security guidelines established by the U.S. government to maintain consistency within their organization. If you are running Adaptive Server Anywhere 7.0, and if you have the appropriate hardware, you can set up your machine to run in a C2 certified manner. The C2-certified documentation is available at [external link] http://www.sybase.com/detail?id=1010458.

    For information on running the current version of Adaptive Server Anywhere in a manner equivalent to the C2-certified environment, see Installation.


Controlling database access

By assigning user IDs and passwords, the database administrator controls who has access to a database. By granting permissions to each user ID, the database administrator controls what tasks each user can carry out when connected. This section describes the features available for controlling database access.

Permission scheme is based on user IDs

When you log on to the database, you have access to all database objects that meet any of the following criteria:

  • objects you created.

  • objects to which you received explicit permission.

  • objects to which a group you belong to received explicit permission.

The user cannot access any database object that does not meet these criteria. In short, users can access only the objects they own or objects to which they explicitly received access permissions.

For more information, see the following:

  • Managing User IDs and Permissions
  • CONNECT statement [ESQL] [Interactive SQL]
  • GRANT statement
  • REVOKE statement
Using integrated logins

Integrated logins allow users to use a single login name and password to log onto both your Windows operating system and onto a database. An external login name is associated with a database user ID. When you attempt an integrated login, you log onto the operating system by giving both a login name and password. The operating system then tells the server who you are, and the server logs you in as the associated database user ID. No additional login name or password are required.

There are some security implications of integrated logins to consider. For example, leaving the user profile Guest enabled with a blank password can permit unrestricted access to a database that is hosted by that server. Literally any user can log in to the server using any login ID and any password because they are logged in by default to the Guest user profile.

For more information, see the following:

  • Security concerns: unrestricted database access
  • Using integrated logins
  • LOGIN_MODE option [database]


Increasing password security

Passwords are an important part of any database security system. To be secure, passwords must be difficult to guess, and they must not be easily accessible on users' hard drives or other locations.

Implement minimum password lengths

By default, passwords can be any length. For greater security, you can enforce a minimum length requirement on all new passwords. You do this by setting the MIN_PASSWORD_LENGTH database option to a value greater than zero. The following statement enforces passwords to be at least 8 bytes long.

SET OPTION PUBLIC.MIN_PASSWORD_LENGTH = 8

For more information, see MIN_PASSWORD_LENGTH option [database].

Do not include passwords in ODBC data sources

Passwords are the key to accessing databases. They should not be easily available to unauthorized people in a security-conscious environment.

When you create an ODBC data source or a Sybase Central connection profile, you can optionally include a password. Avoid including passwords for greater security.

For information on creating ODBC data sources, see Creating an ODBC data source.

Encrypt configuration files containing passwords

When you create a configuration file, you can optionally include password information. To protect your passwords, consider hiding the contents of configuration files with simple encryption, using the File Hiding (dbfhide) utility.

For information on the File Hiding (dbfhide) utility to hide configuration files, see Hiding the contents of files using the dbfhide command-line utility.


Controlling the tasks users can perform

Users can access only those objects to which they have been granted access.

You grant permission on an object to another user with the GRANT statement. You can also grant a user permission to pass on the permissions on an object to other users.

The GRANT statement also gives more general permissions to users. Granting CONNECT permissions to a user allows them to connect to the database and change their passwords. Granting RESOURCE authority allows the user to create tables, views, procedures, and so on. Granting DBA authority to a user gives that user the ability to see and do anything in the database. The DBA would also use the GRANT statement to create and administer groups.

The REVOKE statement is the opposite of the GRANT statement—any permission that GRANT has explicitly given, REVOKE can take away. Revoking CONNECT from a user removes the user from the database, including all objects owned by that user.

Negative permissions

Adaptive Server Anywhere does not support negative permissions. This means that you cannot revoke a permission that was not explicitly granted.

For example, suppose user bob is a member of a group called sales. If a user grants DELETE permission on a table, T, to sales, then bob can delete rows from T. If you want to prevent bob from deleting from T, you cannot simply execute a REVOKE DELETE on T from bob, since the DELETE ON T permission was never granted directly to bob. In this case, you would have to revoke bob's membership in the sales group.

For more information, see:

  • GRANT statement
  • REVOKE statement


Designing database objects for security

Views and stored procedures provide alternative ways of tuning the data users can access and the tasks they can perform.

For more information on these features, see:

  • Benefits of procedures and triggers
  • Using views and procedures for extra security


Auditing database activity

Auditing is a way of keeping track of the activity performed on a database. The record of activities stays in the transaction log. By turning on auditing, the DBA increases the amount of data saved in the transaction log to include the following:

  • All login attempts (successful and failed), including the terminal ID.

  • Accurate timestamps of all events (to a resolution of milliseconds).

  • All permissions checks (successful and failed), including the object on which the permission was checked (if applicable).

  • All actions that require DBA authority.

The transaction log

Each database has an associated transaction log file. The transaction log is used for database recovery. It is a record of transactions executed against a database.

For information about the transaction log, see The transaction log.

The transaction log stores all executed data definition statements, and the user ID that executed them. It also stores all updates, deletes, and inserts and which user executed those statements. However, this is insufficient for some auditing purposes. By default, the transaction log does not contain the time of the event, just the order in which events occurred. It also contains neither failed events, nor select statements.


Turning on auditing

The database administrator can turn on auditing to add security-related information to the transaction log.

Auditing is off by default. To enable auditing on a database, the DBA must set the value of the public option AUDITING to ON. Auditing then remains enabled until explicitly disabled, by setting the value of the AUDITING option to OFF. You must have DBA permissions to set this option.

toggle To turn on auditing

  1. Ensure that your database is upgraded to at least version 6.0.2.

  2. If you had to upgrade your database, create a new transaction log.

  3. Execute the following statement:

    SET OPTION PUBLIC.AUDITING = 'ON'

    For more information, see AUDITING option [database].


Retrieving audit information

You can use the Log Translation (dbtran) utility to retrieve audit information. You can access this utility from Sybase Central or from a command prompt. It operates on a transaction log to produce a SQL script containing all of the transactions, along with some information on what user executed each command. By using the -g option, dbtran includes more comments containing the auditing information.

To ensure a complete and readable audit record, the -g option automatically sets the following options:

  • -d Display output in chronological order.

  • -t Include trigger-generated operations in the output.

  • -a Include rolled back transactions in the output.

You can run the Log Translation utility against a running database server or against a database log file.

toggle To retrieve auditing information from a running database server

  1. Make sure your user ID has DBA authority.

  2. With the database server running, execute the following statement at a system command prompt:

    dbtran -g -c "uid=DBA;pwd=SQL;..." -n asademo.SQL

    For information about connection strings, see Connection parameters.

toggle To retrieve auditing information from a transaction log file

  1. Close the database server to ensure the log file is available.

  2. At a system command prompt, execute the following statement to place the information from the file asademo.log and into the file asademo.SQL.

    dbtran -g asademo.log

    The -g option includes auditing information in the output file.

For more information, see The Log Translation utility.


Adding audit comments

You can add comments to the audit trail using the sa_audit_string system stored procedure. It takes a single argument, which is a string of up to 200 bytes. You must have DBA permissions to call this procedure.

For example:

call sa_audit_string( 'Started audit testing here.' )

This comment is stored in the transaction log as an audit statement.


An auditing example

This example shows how the auditing feature records attempts to access unauthorized information.

  1. As database administrator, turn on auditing.

    You can do this from Sybase Central as follows:

    • Connect to the ASA 9.0 Sample data source. This connects you as the DBA user.

    • Select the asademo database icon and from the File menu, choose Options.

    • Select Auditing from the list of options, and enter the value ON in the Public Setting box. Click Set Permanent Now to set the option and Close to exit.

    Alternatively, you can use Interactive SQL. Connect to the sample database from Interactive SQL as user ID DBA with password SQL and execute the following statement:

    SET OPTION PUBLIC.AUDITING = 'ON'

  2. Add a user to the sample database, named BadUser, with password BadUser. You can do this from Sybase Central. Alternatively, you can use Interactive SQL and enter the following statement:

    GRANT CONNECT TO BadUser
IDENTIFIED BY 'BadUser'

  3. Using Interactive SQL, connect to the sample database as BadUser and attempt to access confidential information in the employee table with the following query:

    SELECT emp_lname, salary
FROM DBA.employee

    You receive an error message: do not have permission to select from employee.

  4. From a command prompt, change directory to your Adaptive Server Anywhere installation directory, which holds the sample database, and execute the following command:

    dbtran -g -c "dsn=ASA 9.0 Sample" -n asademo.SQL

    This command produces a file named asademo.SQL, containing the transaction log information and a set of comments holding audit information. The lines indicating the unauthorized BadUser attempt to access the employee table are included in the file as follows:

    --AUDIT-1001-0000287812 -- 2004/02/11 13:59:58.765 Checking Select permission on employee - Failed
--AUDIT-1001-0000287847 -- 2004/02/11 13:59:58.765 Checking Select permission on employee(salary) - Failed

  5. Restore the sample database to its original state so other examples you try in this documentation give the expected results.

    Connect as the DBA user, and carry out the following operations:

    • Revoke Connect privileges from the user ID BadUser.

    • Set the PUBLIC.AUDITING option to OFF.


Auditing actions outside the database server

Some database utilities act on the database file directly. In a secure environment, only trusted users should have access to the database files.

To provide auditing of actions, under Windows NT only, any use of dbtran, dbwrite, or dblog generates a text file in the same directory as the database file, with the extension .alg. For example, for asademo.db, the file is called asademo.alg. Records containing the tool name, Windows user name, and date/time are appended to this file. Records are only added to the .alg file if the AUDITING option is set to ON.


Running the database server in a secure fashion

There are several security features you can set either when starting the database server or during server operation, including:

  • Starting and stopping databases By default, any user can start an extra database on a running server. The –gd option allows you to limit access to this option to users with a certain level of permission in the database to which they are already connected. The permissible values include DBA, all, or none.

    For more information, see -gd server option.

  • Creating and deleting databases By default, any user can use the CREATE DATABASE statement to create a database file. The –gu option allows you to limit access to this option to users with a certain level of permission in the database to which they are connected. The permissible values include DBA, all, none, or utility_db.

    For information, see -gu server option.

  • Stopping the server The dbstop utility stops a database server. It is useful in batch files, or in other cases where stopping the server interactively (by clicking Shutdown on the Server Messages window) is impractical. By default, any user can run dbstop to shut down a server. The –gk option allows you to limit access to this option to users with a certain level of permission in the database. The permissible values include DBA, all, or none.

    For more information, see -gk server option.

  • Loading and unloading data The LOAD TABLE, UNLOAD TABLE, and UNLOAD statements all access the file system on the database server machine. If you are running the personal database server, you already have access to the file system and this is not a security issue. If you are running the network database server, unwarranted file system access may be a security issue. The –gl option allows you to control the database permissions required to carry out loading and unloading of data. The permissible values are DBA, all, or none.

    For more information, see -gl server option.

  • Using transport-layer security to encrypt client/server communications For greater security of network packets, you can use transport-layer security to authenticate communications between client applications and the database server. Transport-layer security uses elliptic-curve or RSA encryption technology.

    For more information, see Adaptive Server Anywhere Transport-Layer Security.


Encrypting a database

As a database administrator, you can use database encryption to make it more difficult for someone to decipher the data in your database. You can choose to secure your database either with simple or with strong encryption.

Caution Compressing an encrypted database removes encryption from the database.
Simple encryption

Simple encryption is equivalent to obfuscation and makes it more difficult for someone using a disk utility to look at the file to decipher the data in your database. Simple encryption does not require a key to encrypt the database. Simple encryption technology is supported in previous versions of SQL Anywhere Studio.

toggle To use simple encryption

  • Create a database using the dbinit -e option.

    The following example create the database test.db using simple encryption:

    dbinit -p 4096 -e test.db

    For more information, see Creating a database using the dbinit command-line utility.

Strong encryption

Strong database encryption technology makes a database inoperable and inaccessible without a key (password). An algorithm scrambles the information contained in your database and transaction log files so they cannot be deciphered.

Caution Protect your key! Be sure to store a copy of your key in a safe location. A lost key will result in a completely inaccessible database, from which there is no recovery.

The algorithm used to implement Adaptive Server Anywhere strong encryption is AES: a block encryption algorithm chosen as the new Advanced Encryption Standard (AES) for block ciphers by the National Institute of Standards and Technology (NIST).

On any supported 32-bit Windows platform, you can also specify a separate FIPS-approved AES algorithm for strong encryption using the AES_FIPS type. When the database server is started with the -fips option, you can run databases encrypted with AES or AES_FIPS strong encryption, but not databases encrypted with simple encryption. Unencrypted databases can also be started on the server when -fips is specified.

For more information see -fips server option.

The SQL Anywhere Studio security option must be installed on any machine used to run a database encrypted with AES_FIPS.

Separately licensable option required
Strong database encryption using AES_FIPS requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

To create a new database with strong encryption, you can use:

  • The Database Initialization utility (dbinit) in combination with various options to enable strong encryption.

    Using the dbinit utility with the -ek option or -ep option creates a database with strong encryption, allowing you to specify the encryption key in a prompt box or on the command line. The dbinit -ea option sets the encryption algorithm to AES or AES_FIPS for the FIPS-approved algorithm.

    For more information, see Initialization utility options and The Initialization utility.

  • The ENCRYPTION clause in the CREATE DATABASE statement. The KEY option sets the encryption key and the ALGORITHM option sets the encryption algorithm to AES or AES_FIPS for the FIPS-approved algorithm.

    You can also use the Sybase Central Create Database wizard to create a strongly encrypted database.

    For more information, see CREATE DATABASE statement.

  • The Unload Database utility (dbunload) with options to create a new database with strong encryption. The -an option creates a new database. To specify strong encryption and the encryption key in a prompt box or on the command line use the -ek or -ep option. The -ea option sets the encryption algorithm to AES or AES_FIPS for the FIPS-approved algorithm.

    You can also use the Sybase Central Unload Database wizard to create a strongly encrypted database.

    For more information, see Unload utility options and The Unload utility.

toggle To create a strongly encrypted database (SQL)

  1. Connect to an existing database from Interactive SQL.

  2. Execute a CREATE DATABASE statement that includes the ENCRYPTION clause and the KEY and ALGORITHM options.

    For example, the following statement creates a database file named myencrypteddb.db in the C:\ directory using FIPS-approved AES encryption.

    CREATE DATABASE 'c:\\myencrypteddb'
TRANSACTION LOG ON
ENCRYPTED ON
  KEY '0kZ2o52AK#'
  ALGORITHM 'AES_FIPS'
toggle To create a strongly encrypted database (command prompt)

  1. At a command prompt, use the dbinit utility to create a database. You must include -ek or -ep to specify the encryption key at the command prompt or a dialog box, respectively.

    The following command creates a strongly encrypted database and specifies the encryption key and algorithm.

    dbinit -ek "0kZ2o56AK#" -ea AES_FIPS "myencrypteddb.db"

  2. Start the database from the command prompt.

    dbeng9 myencrypteddb.db -ek "0kZ2o56AK#"

For more information about the encryption key, see DatabaseKey connection parameter [DBKEY].

As with most passwords, it is best to choose a key value that cannot be easily guessed. It is recommended that you choose a value for your key that includes between 8 and 30 characters, a combination of upper and lower case characters, and numbers, letters, and special characters.

Caution Be sure to store a copy of your key in a safe location. You require the key each time you want to start or modify the database. A lost key will result in a completely inaccessible database, from which there is no recovery.


Controlling strong encryption

In Adaptive Server Anywhere, the database administrator has control over four aspects of strong encryption, including: strong encryption status, the encryption key, protection of the encryption key, and the encryption algorithm.


Strong encryption status

Although you can't simply turn strong encryption on or off in an existing database, you can choose from two options when it comes to implementing strong encryption. You can either create a database from scratch with strong encryption, or you can rebuild an existing database and change the encryption status at that time. Rebuilding the database unloads all of the data and schema of an existing database, creates a new database (at which point you can change a variety of settings including strong encryption status), and reloads the data into the new database. You need to know the key to unload a strongly encrypted database.

For more information on these features, see

  • Reloading a database
  • CREATE DATABASE statement


The encryption key

As with most passwords, it is best to choose a key value that cannot be easily guessed. The key can be of arbitrary length, but generally the longer the key, the better because a shorter key is easier to guess than a longer one. As well, including a combination of numbers, letters, and special characters decreases the chances of someone guessing the key. You must supply this key each time you want to start the database. Lost or forgotten keys result in completely inaccessible databases.


Protection of the encryption key

You can choose whether the encryption key is entered at the command prompt (the default) or into a prompt box. Choosing to enter the key in a prompt box provides an extra measure of security because the key is never visible in plain sight. Clients are required to specify the key each time they start the database. In cases where the database administrator starts the database, clients never need to have access to the key.

For more information, see -ep server option.


The encryption algorithm

When you strongly encrypt a database, your database is encrypted using the AES algorithm.

AES has recently been through a period of international evaluation and has now been chosen as the new Advanced Encryption Standard block cipher algorithm. It has many properties that lend itself well to encryption of Adaptive Server Anywhere databases in terms of performance and size. The AES_FIPS algorithm is also available on any supported 32-bit Windows platform.

For more information about database encryption algorithms, see:

  • Initialization utility options
  • CREATE DATABASE statement


Performance issues

Performance of Adaptive Server Anywhere is somewhat slower when the database is encrypted. The performance impact depends on how often pages are read from or written to disk, and can be minimized by ensuring that the server is using an adequate cache size.

You can increase the starting size of the cache with the -c option when you start the server. For operating systems that support dynamic resizing of the cache, the cache size that is used may be restricted by the amount of memory that is available; to increase the cache size, increase the available memory.

For more information, see:

  • Using the cache to improve performance
  • -c server option


Encrypting portions of a database

If you wish to encrypt only portions of your database, you can do so using the ENCRYPT function. The ENCRYPT function uses the same AES strong encryption algorithm that is used for database encryption to encrypt the values that are passed to it.

The ENCRYPT function uses a key to encrypt the values passed to it. The key is case sensitive, even in case-insensitive databases. As with most passwords, it is best to choose a key value that cannot be easily guessed. It is recommended that you choose a value for your key that is at least 16 characters long, contains a mix of upper and lower case, and includes numbers, letters and special characters. You will require this key each time you want to decrypt the data.

Caution Protect your key. Be sure to store a copy of your key in a safe location. A lost key will result in the encrypted data becoming completely inaccessible, from which there is no recovery.

Encrypted values can be decrypted using the DECRYPT function with the same key that was specified in the ENCRYPT function. Both of these functions return LONG BINARY values. If you require a different data type, you can use the CAST function to convert the value to the required data type. The example below shows how to use the CAST function to convert a decrypted value to the required data type.

For more information about using the CAST function, see CAST function [Data type conversion].

If database users need to access the data in decrypted form, but you do not wish them to have access to the encryption key, you can create a view that uses the DECRYPT function. This allows users to access the decrypted data without knowing the encryption key. If you create a view or stored procedure that uses the table, you can use the SET HIDDEN parameter of the ALTER VIEW and ALTER PROCEDURES to ensure that users cannot access the encryption key.

For more information, see ALTER PROCEDURE statement and ALTER VIEW statement.

Column encryption example

The following example uses triggers to encrypt a column that stores passwords in a table called user_info. The user_info table is defined as follows:

CREATE TABLE user_info (
   emp_id INTEGER NOT NULL PRIMARY KEY,
   user_name CHAR(80),
   user_pwd CHAR(80) )

Two triggers are added to the database to encrypt the value in the user_pwd column when a new user is added or an existing user's password is updated.

  • The encrypt_new_user_pwd trigger fires each time a new row is added to the user_info_table:

    CREATE TRIGGER encrypt_new_user_pwd
BEFORE INSERT
ON user_info
REFERENCING NEW AS new_pwd
FOR EACH ROW
BEGIN
    SET new_pwd.user_pwd=ENCRYPT(new_pwd.user_pwd, '8U3dkA');
END

  • The encrypt_updated_pwd trigger fires each time the user_pwd column is updated in the user_info table:

    CREATE TRIGGER encrypt_updated_pwd
BEFORE UPDATE OF user_pwd
ON user_info
REFERENCING NEW AS new_pwd
FOR EACH ROW
BEGIN
    SET new_pwd.user_pwd=ENCRYPT(new_pwd.user_pwd, '8U3dkA');
END

Add a new user to the database:

INSERT INTO user_info
VALUES ( '1', 'd_williamson', 'abc123')

If you issue a SELECT statement to view the information in the user_info table, the value in the user_pwd column is binary data (the encrypted form of the password) and not the value abc123 that was specified in the INSERT statement.

If this user's password is changed:

UPDATE user_info
SET user_pwd='xyz'
WHERE emp_id='1'

the encrypt_updated_pwd trigger fires and the encrypted form of the new password appears in the user_pwd column.

The original password can be retrieved by issuing the following SQL statement. This statement uses the DECRYPT function and the encryption key to decrypt the data, as well as the CAST function to convert the value from a LONG BINARY to a CHAR value:

SELECT CAST (DECRYPT(user_pwd, '8U3dkA') AS CHAR(100)) FROM user_info
WHERE emp_id = '1'

For more information about the ENCRYPT and functions, see Alphabetical list of functions.


Keeping your Windows CE database secure

This section describes Adaptive Server Anywhere features that help make your Windows CE database secure. In particular, this section describes auditing, database encryption, and presents overviews of other security features, providing links to where you can find more detailed information.

Many of the Adaptive Server Anywhere security features for Windows desktop platforms are supported on Windows CE, such as database file encryption and simple communication encryption, or have modified support, such as the Log Translation utility.

Databases running on Windows CE uses the same user identification and authorization features as databases running on Windows desktop platforms to control who can access the database and what actions those users can carry out.

For more information, see Controlling database access.

Windows CE device security

If you are storing sensitive data on your Windows CE device, you may wish to use the security features provided for your Windows CE device.

For more information on available security features, see the User's Manual provided with your Windows CE device.

Database server options

Server options allow you to control who can carry out certain operations on the server.

These options are set in the Options field of the Server Startup Options dialog when you start the database on your Windows CE device.

For more information, see Controlling permissions from the command line.

For information on setting options on Windows CE, see Server and database options.

Auditing

This feature uses the transaction log to maintain a detailed record of actions on the database.

The Log Translation utility (dbtran) is used to translate the information stored in the transaction log, including auditing information. The dbtran utility is not supported on Windows CE, so you cannot translate a log stored on a Windows CE device. Copy the transaction log file to your PC in order to use this utility.

For more information, see Auditing database activity.

Database encryption on Windows CE

Database encryption features allow you to choose the level of database encryption. You can choose to secure your database either with simple encryption, or with strong encryption. Adaptive Server Anywhere supports both simple and strong encryption on Windows CE.

Simple encryption This level of encryption is equivalent to obfuscation and makes it more difficult for someone using a disk utility to look at the file to decipher the data in your database. Simple encryption does not require a key to encrypt the database.

Simple encryption technology is supported in previous versions of SQL Anywhere Studio.

Strong encryption This level of encryption scrambles the information contained in your database and transaction log files so they cannot be deciphered simply by looking at the files using a disk utility. Strong encryption renders the database completely inaccessible without the key. If you are encrypting a database to use on Windows CE, it must be encrypted with the AES algorithm.

For more information, see Encrypting a database.

Communication encryption and Windows CE

You can encrypt client/server communications for greater security as they pass over the network. Adaptive Server Anywhere provides two types of communication encryption: simple and strong.

Simple communication encryption accepts communication packets that are encrypted with simple encryption. This level of communication encryption is supported on all platforms, including Windows CE and on previous versions of Adaptive Server Anywhere.

Strong communication encryption is only supported over the TCP/IP port on Solaris, Linux, Mac OS X, NetWare, and supported 32-bit Windows operating systems. It is not available on Windows CE.

For more information about encrypting communications, see .


Security tips

As database administrator, there are many actions you can take to improve the security of your data. For example, you can:

  • Change the default user ID and password The default user ID and password for a newly created database is DBA and SQL. You should change this password before deploying the database.

  • Require long passwords You can set the MIN_PASSWORD_LENGTH public option to disallow short (and therefore easily guessed) passwords.

    For information, see MIN_PASSWORD_LENGTH option [database].

  • Restrict DBA authority You should restrict DBA authority only to users who absolutely require it since it is very powerful. Users with DBA authority can see and do anything in the database.

    You may consider giving users with DBA authority two user IDs: one with DBA authority and one without, so they can connect as DBA only when necessary.

  • Drop external system functions The following external functions present possible security risks: xp_cmdshell, xp_startmail, xp_startsmtp, xp_sendmail, xp_stopmail, and xp_stopsmtp.

    The xp_cmdshell procedure allows users to execute operating system commands or programs.

    The e-mail commands allow users to have the server send e-mail composed by the user. Malicious users could use either the e-mail or command shell procedures to perform operating-system tasks with authorities other than those they have been given by the operating system. In a security-conscious environment, you should drop these functions.

    For information on dropping procedures, see DROP statement.

  • Protect your database files You should protect the database file, log files, dbspace files, and write files from unauthorized access. Do not store them within a shared directory or volume.

  • Protect your database software You should similarly protect Adaptive Server Anywhere software. Only give users access to the applications, DLLs, and other resources they require.

  • Run the database server as a service or a daemon To prevent unauthorized users from shutting down or gaining access to the database or log files, run the database server as a Windows service. On UNIX, running the server as a daemon serves a similar purpose.

    For more information, see Running the server outside the current session.

  • Set ASTMP to a unique directory To make the engine secure on UNIX platforms, set ASTMP to a unique directory, and make the directory read, write, and execute protected against all other users. Doing so forces all connections to use TCP/IP, which is more secure than the shared memory connection.

  • Strongly encrypt your database Strongly encrypting your database makes it completely inaccessible without the key. You cannot open the database, or view the database or transaction log files using any other means.

    For more information, see -ep server option and -ek database option.


Adaptive Server Anywhere Transport-Layer Security

About this chapter

This chapter shows you how to secure communications between the Adaptive Server Anywhere database server and client applications using transport-layer security.

For information about MobiLink transport-layer security, see MobiLink Transport-Layer Security.

For information about setting up your Adaptive Server Anywhere web server to use transport-layer security, see Using transport-layer security for web services.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Introduction
Setting up transport-layer security
Creating digital certificates
Starting the database server with transport-layer security
Configuring client applications to use transport-layer security
Using transport-layer security for web services


Introduction

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Transport-layer security, an IETF standard protocol, secures client/server applications using digital certificates and public-key cryptography.

Clients use trusted public certificates to encrypt data and authenticate servers in the initial client/server handshake. Data transmitted by the client can only be decrypted by the matching private key, which is stored in your database server certificate.

For server authentication, the database server sends its public certificate to the client. The client verifies the identity of the server using certificate fields and the digital signature embedded in the certificate.

Efficiency

The transport-layer security standard overcomes the inefficiencies associated with public-key cryptography. Once a secure connection is established, the client and server exchange a common key. They use a highly efficient symmetric cipher for the rest of their communication.

Supported platforms

To use transport-layer security, both the server and the client must be operating on Solaris, Linux, NetWare, Mac OS X, or any supported 32-bit Windows platform except Windows CE, and the connection must be over the TCP/IP port.

FIPS-certified security options are available on Windows only.

FIPS 140-2 certification


FIPS 140-2 certification

Federal Information Processing Standard (FIPS) 140-2 specifies requirements for security algorithms. It does not, however, specify requirements for security protocols such as SSL or transport-layer security. FIPS 140-2 is granted by the American and Canadian governments through the National Institute of Standards and Testing (NIST) and the Canadian Communication Security Establishment (CSE). Certicom has earned FIPS certification for security algorithms implemented on Windows.

SQL Anywhere Studio offers transport-layer security with the option of using the underlying FIPS-certified algorithms in the Certicom software.

To use transport-layer security, you must purchase a separate security option.

For information about how to order transport-layer security, see Separately-licensable components.

You can use FIPS-certified security algorithms to encrypt your database files, or to encrypt communications for database client/server communication, web services, and MobiLink client/server communication.

For more information, see:

  • Encrypting a database
  • Using transport-layer security for web services
  • Starting the database server with transport-layer security
  • Configuring client applications to use transport-layer security


Setting up transport-layer security

To set up Adaptive Server Anywhere transport-layer security, perform the following steps:

  • Create digital certificates Create public certificates and server certificates. Public certificates are distributed to client applications, while server certificates are stored securely with database servers.

    See Creating digital certificates.

  • Start the Adaptive Server Anywhere database server with transport-layer security Use the -ec database server option to specify the type of security, the server certificate, and the password to protect the private key.

    See Starting the database server with transport-layer security.

  • Configure client applications to use transport-layer security Specify the path and file name of trusted public certificates using the Encryption connection parameter [ENC].

    See Configuring client applications to use transport-layer security.


Creating digital certificates

To set up transport-layer security you must generate digital certificates.

You can create self-signed certificates, use enterprise root certificates and certificate chains, or have your certificates signed by a Certificate Authority (CA).

  • Self-signed certificates Self-signed certificates can be used for simple setups involving a single database server. In this case, the private key used to create trusted public certificates is stored with your database server instead of a commercial Certificate Authority or dedicated facility.

    See Self-signed root certificates.

  • Enterprise root certificates Enterprise root certificates increase data integrity and extensibility for multi-server deployments.

    • You can store the private key used to create trusted public certificates in a secure central location.
    • You can add database servers without reconfiguring clients.

    See Certificate chains.

  • Commercial Certificate Authorities You can use a third-party Certificate Authority instead of an enterprise root certificate. Commercial Certificate Authorities have dedicated facilities to store private keys and create high-quality server certificates.

    See Certificate chains and Globally-signed certificates.

Certificate utilities

The SQL Anywhere Studio certificate generation utility, gencert, creates certificates. It prompts you for certificate identification and file information and uses RSA or elliptic-curve encryption technology. You can use the certificate reader utility, readcert, to display certificate values and validate a chain of certificates.


Self-signed root certificates

Self-signed root certificates can be used for simple setups involving a single database server. In this case, the private key used to create trusted public certificates is stored with your database server instead of a commercial Certificate Authority or dedicated facility.

Tip
Use enterprise level certificate chains if you operate multiple database servers or are looking for a higher level of certificate integrity.

For more information about setting up certificate chains, see Certificate chains.

To set up self-signed certificates, you generate the following certificates using the gencert utility:

  • Public certificate The self-signed public certificate is distributed to client applications. It is an electronic document including identity information, the public key of the database server, and a self-signed digital signature used for server authentication.

    For more information, see Starting the database server with transport-layer security.

  • Server certificate The server certificate is stored securely with a database server. It is a combination of the self-signed public certificate (that is distributed to clients) and the corresponding private key. The private key gives the database server the ability to decrypt messages sent by client applications.

The self-signed server certificate, including the server's private key

For information about how to generate self-signed root certificates, see Certificate generation utility.


Certificate chains

You can improve the security and extensibility of a multi-server environment using certificate chains instead of self-signed certificates. Certificate chains require a Certificate Authority or an enterprise root certificate to sign database server certificates.

For more information about self-signed certificates, see Self-signed root certificates.

Benefits of using certificate chains

Certificate chains provide the following advantages:

  • Extensibility You can configure client applications to trust any certificate signed by an enterprise root certificate or Certificate Authority. If you add a new database server, clients do not require a copy of the new public certificate.

  • Security The enterprise root certificate's private key does not reside with database servers. Storing the root certificate's private key in a high-security location, or using a Certificate Authority with dedicated facilities, protects the integrity of server authentication.

The following diagram provides the basic enterprise root certificate architecture.

Enterprise root certificate

To create certificates used in a multi-server environment:

  • Generate a public enterprise root certificate and enterprise private key.

    You distribute the public enterprise root certificate to client applications. You store the enterprise private key in a secure location, preferably a dedicated facility.

  • Generate server certificates for each database server.

    Use the public enterprise root certificate and enterprise private key to sign each server certificate.

You can also use a third-party Certificate Authority to sign your server certificates. Commercial Certificate Authorities have dedicated facilities to store private keys and create high-quality server certificates.

For more information, see Globally-signed certificates.


Enterprise root certificates

Enterprise root certificates increase data integrity and extensibility for multi-server deployments.

  • You can store the private key used to create trusted public certificates in a secure central location.
  • You can add database servers without reconfiguring clients.

To set up enterprise root certificates, you create the enterprise root certificate and the enterprise private key that you use to sign server certificates.

For information about creating server certificates, see Signed server certificates.

For information about how to generate enterprise root certificates, see Certificate generation utility.


Signed server certificates

You generate server certificates for each database server. Since these certificates are signed by an enterprise root certificate, you use the gencert -s option.

For information about generating signed server certificates, see Certificate generation utility.

For information about how to generate signed server certificates fo each database server, see Certificate generation utility.


Globally-signed certificates

A commercial Certificate Authority is an organization that is in the business of creating high-quality certificates and using these certificates to sign your certificate requests.

Globally-signed certificates have the following advantages:

  • In the case of inter-company communication, common trust in an outside, recognized authority may increase confidence in the security of the system. A Certificate Authority must guarantee the accuracy of the identification information in any certificate that it signs.

  • Certificate Authorities provide controlled environments and advanced methods to generate certificates.

  • The private key for the root certificate must remain private. Your organization may not have a suitable place to store this crucial information, whereas a Certificate Authority can afford to design and maintain dedicated facilities.

Setting up globally-signed certificates

To set up globally signed certificates, you:

  • Create a certificate request using Certicom's reqtool utility.

    See Using reqtool to obtain global certificates.

  • Use a Certificate Authority to sign each database server certificate request.

    See Using a global certificate as a server certificate.

    Globally-signing enterprise root certificates
    You might be able to globally-sign an enterprise root certificate. This is only applicable if your Certificate Authority generates certificates that can be used to sign other certificates.

Using reqtool to obtain global certificates
Using a global certificate as a server certificate
Setting up clients to trust the certificate authority's public certificate


Using reqtool to obtain global certificates

Adaptive Server Anywhere transport-layer security is based on Certicom SSL/TLS Plus libraries, which require elliptic-curve or RSA certificates. You can obtain a global certificate from any Certificate Authority that can supply certificates in the correct format.

There are several ways to obtain certificates. One way is to use the reqtool utility, which is installed when you install the security component. This tool creates a server's private key and a global certificate request.

Example

The following example creates an elliptic-curve certificate request:

> reqtool
-- Certicom Corp. Certificate Request Tool 3.0d1 --
Choose certificate request type:
  E - Personal email certificate request.
  S - Server certificate request.
  Q - Quit.
Please enter your request [Q] : S
Choose key type:
  R - RSA key pair.
  D - DSA key pair.
  E - ECC key pair.
  Q - Quit.
Please enter your request [Q] : E
Using curve ec163a02. Generating key pair (please wait)...
Country: CA
State: Ontario
Locality: Waterloo
Organization: Sybase, Inc.
Organizational Unit: IAS
Common Name: IAS_Waterloo
Enter password to protect private key : mypwd123
Enter file path to save request : global.req
Enter file path to save private key : serv1_private_key.pri

The file global.req contains the public certificate and request information. Paste the contents of this file into a form on the certificate-issuing web site. The Certificate Authority will sign the request and create the public certificate global.crt.

The file serv1_private_key.pri contains the corresponding private key. This file is protected by the password you entered, but since the protection provided by the password is weak, you must store this file in a secure location.

For more information about using reqtool, see the document reqtool.pdf, located in the win32 subdirectory of your SQL Anywhere 9 installation.


Using a global certificate as a server certificate

You can use globally-signed certificates directly as database server certificates. The following diagram shows the configuration for a multi-server deployment:

Globally signed server certificates

To create the server identity, you must concatenate the public certificate signed by the Certificate Authority and private key created using the reqtool utility.

For more information about the reqtool utility, see Using reqtool to obtain global certificates.

The following example concatenates the globally-signed public certificate global.crt and the private key serv1_private_key.pri to create the server certificate server1_certificate.crt.

copy global.crt+serv1_private_key.pri server1_certificate.crt

You reference the server certificate server1_certificate.crt and the password for the private key serv1_private_key.pri at the dbsrv9 command line.

For more information, see Starting the database server with transport-layer security.


Setting up clients to trust the certificate authority's public certificate

You must ensure that clients contacting your database server trust the root certificate in the chain. In the case of globally-signed certificates, the root certificate is the Certificate Authority's public certificate.

Certificate field verification
When using a globally-signed certificate, each client application must verify field values to avoid trusting certificates that the same Certificate Authority has signed for other clients.

For more information about configuring client applications to trust server certificates, see Configuring client applications to use transport-layer security.

For more information about using globally-signed certificates to establish trust, see Globally-signed certificates.


Starting the database server with transport-layer security

To start the database server with transport-layer security, supply the server certificate and the password protecting the server's private key. Adaptive Server Anywhere transport-layer security is only available over TCP/IP and on Solaris, Linux, NetWare, Mac OS X, or any supported Windows platform except Windows CE.

For an overview of the steps required to set up transport-layer security, see Setting up transport-layer security.

Use the -ec server option to specify the certificate and certificate_password parameters.

Following is a partial dbsrv9 command line:

-ec cipher (certificate=server-certificate;certificate_password=password)
-x tcpip

  • cipher can be rsa_tls or ecc_tls for RSA and elliptic-curve encryption, respectively. For FIPS-approved RSA encryption, specify rsa_tls_fips. rsa_tls_fips uses a separate approved library, but is compatible with clients specifying rsa_tls with Adaptive Server Anywhere 9.0.2 or later. The rsa_tls_fips cipher can only be used on supported 32-bit Windows platforms.

    The cipher must match the encryption (ECC or RSA) used to create your certificates.

    For information about enforcing the FIPS-approved algorithm, see -fips server option.

  • server-certificate is the path and file name of the server certificate. If you are using FIPS-approved RSA encryption, you must generate your certificates using the RSA cipher.

    For more information about creating the server certificate, which can be self-signed, or signed by a Certificate Authority or enterprise root certificate, see Creating digital certificates.

  • password is the password for the server certificate's private key. You specify this password when you create the server certificate.

You can also start the database server with simple encryption, which does not assure data integrity or provide server authentication. Simple encryption makes it more difficult for someone using a packet sniffer to read the network packets sent between the client and the server. Simple encryption is supported in previous versions of SQL Anywhere Studio.

For more information about the -ec server option, see -ec server option.

You specify the TCP/IP protocol using the -x server option.

For more information, see -x server option.

Examples

The following example uses the -ec server option to specify ecc_tls security, the server certificate, and the password protecting the server's private key:

dbsrv9 -ec ecc_tls(certificate=c:\test\serv1_ecc.crt; certificate_password=mypwd) -x tcpip asademo.db

You can hide the command-line options including passwords using a configuration file and the File Hiding utility, dbfhide. For more information, see @data server option.

The following example uses the -ec server option to specify rsa_tls security, the server certificate, and the password protecting the server's private key:

dbsrv9 -ec rsa_tls(certificate=c:\test\serv1_rsa.crt; certificate_password=test) -x tcpip asademo.db


Configuring client applications to use transport-layer security

You can configure client applications to use transport-layer security. Using a set of encryption connection parameters, you specify trusted public certificates, the type of encryption, and the network protocol.

For an overview of the steps required to set up transport-layer security, see Setting up transport-layer security.


Server authentication

Server authentication allows a remote client to verify the identity of a database server. Digital signatures and certificate field verification work together to achieve server authentication.


Digital signatures

A database server certificate contains one or more digital signatures used to maintain data integrity and protect against tampering. Following are the steps used to create a digital signature:

  • An algorithm performed on a certificate generates a unique value or hash.

  • The hash is encrypted using a signing certificate's or Certificate Authority's private key.

  • The encrypted hash, called a digital signature, is embedded in the certificate.

A digital signature can be self-signed or signed by an enterprise root certificate or Certificate Authority.

When a client application contacts a database server, and each is configured to use transport-layer security, the server sends the client a copy of its public certificate. The client decrypts the certificate's digital signature using the server's public key included in the certificate, calculates a new hash of the certificate, and compares the two values. If the values match, this confirms the integrity of the server's certificate.

If you are using FIPS-approved RSA encryption, you must generate your certificates using RSA.

For more information about self-signed certificates, see Self-signed root certificates.

For more information about enterprise root certificates and Certificate Authorities, see Certificate chains.


Verifying certificate fields

When using a globally signed certificate, each client must verify certificate field values to avoid trusting certificates that the same Certificate Authority has signed for other clients. This is resolved by requiring your clients to test the value of fields in the identity portion of the certificate. A Certificate Authority must guarantee the accuracy of the identification information in any certificate that it signs.

For more information about globally signed certificates, see Globally-signed certificates.

When creating a certificate using the gencert utility, you enter values for the organization, organizational unit, and common name fields. You verify these fields using corresponding client connection parameters.

  • Organization The organization field corresponds to the certificate_company encryption connection parameter.

  • Organizational unit The organizational unit field corresponds to the certificate_unit encryption connection parameter.

  • Common name The common name field corresponds to the certificate_name encryption connection parameter.

For more information about client-side encryption connection parameters, see Encryption connection parameter [ENC].


Client security options

Clients use a set of encryption connection parameters for transport-layer security.

The trusted_certificates option

This is the only required option. Clients use the trusted_certificates encryption option to specify trusted database server certificates. The trusted certificate can be a server's self-signed public certificate, a public enterprise root certificate, or a public certificate belonging to a commercial Certificate Authority.

For more information, see Creating digital certificates.

Verifying certificate fields

The certificate_company, certificate_unit, and certificate_name encryption protocol options are used to verify certificate fields, an important step for server authentication. It is strongly recommended that you verify certificate fields if you are using a third-party Certificate Authority to globally sign certificates.

For more information about verifying certificate fields, see Verifying certificate fields.


Establishing a client connection using transport-layer security

To set up client applications to use transport-layer security, use the Encryption [ENC] connection parameter in your connection string. The connection string takes the following form:

Encryption=cipher(trusted_certificates=public-certificate)

  • cipher can be rsa_tls or ecc_tls for RSA and elliptic-curve encryption, respectively. For FIPS-approved RSA encryption specify rsa_tls_fips. rsa_tls_fips uses a separate approved library, but is compatible with servers specifying rsa_tls with Adaptive Server Anywhere 9.0.2 or later.The rsa_tls_fips cipher can only be used on supported 32-bit Windows platforms.

    The connection fails if the cipher does not match the encryption (RSA or ECC) used to create your certificates.

  • public-certificate is the path and file name of a trusted public certificate. If you are using FIPS-approved RSA encryption, you must generate your certificates using RSA.

For more information about trusted_certificates and other client security parameters, see Client security options.

For more information about creating or obtaining the public certificate, see Creating digital certificates.

For more information about the encryption connection parameter, see Encryption connection parameter [ENC].

Example

The following example uses the trusted_certificates encryption connection parameter to specify the public certificate, public_cert.crt.

"UID=DBA;PWD=SQL;ENG=myeng;LINKS=tcpip;
ENC=ECC_TLS (trusted_certificates=public_cert.crt)"

The following example uses the trusted_certificates encryption connection parameter to specify the public certificate, public_cert.crt, and verifies certificate fields using the certificate_unit, and certificate_name encryption connection parameters.

"UID=DBA;PWD=SQL;ENG=myeng;LINKS=tcpip;
ENC=ECC_TLS (trusted_certificates=public_cert.crt;
certificate_unit=test_unit;certificate_name=my_certificate)"


Using transport-layer security for web services

To set up transport-layer security for web services, perform the following steps:

  • Create digital certificates You must create public certificates and server certificates. Public certificates (which can be Certificate Authority certificates) are distributed to browsers or web clients. Server certificates are stored securely with your Adaptive Server Anywhere web server.

    For general information about creating digital certificates, including information about using Certificate Authorities, see Creating digital certificates.

  • Start the web server with transport-layer security Use the -xs database server option to specify HTTPS, the server certificate, and the password to protect the private key.

    Following is a partial dbsrv9 command line.

    -xs protocol(Certificate=server-certificate;Certificate_Password=password;...) ...

    • protocol can be https, or https_fips for FIPS-approved RSA encryption. https_fips uses a separate approved library, but is compatible with https.

      Note
      The Mozilla Firefox browser can connect when https_fips is used. However, the cipher suite used by https_fips is not supported by the Internet Explorer, Opera, or Safari browsers—if you are using https_fips, these browsers cannot connect.

      For information about enforcing the FIPS-approved algorithm, see -fips server option.

    • server-certificate The path and file name of the server certificate.

      For HTTPS, you must use an RSA certificate.

    • password The password for the server certificate's private key. You specify this password when you create the server certificate.

    For more information about the -xs server option, see -xs server option.

    For more information about the Certificate and Certificate_Password parameters, see:

    • Certificate protocol option

    • Certificate_Password protocol option

  • Configure web clients Configure browsers or other web clients to trust public certificates. The trusted certificate can be self-signed, an enterprise root, or a Certificate Authority certificate.

    For general information about creating digital certificates, including information about using Certificate Authorities, see Creating digital certificates.


Installation

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

About this chapter

This chapter describes the procedures for installing Adaptive Server Anywhere (ASA) in a manner equivalent to the C2 certified configuration.

The instructions contained in this document must be followed exactly to ensure an environment equivalent to the certified environment.


Hardware installation

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Set up the hardware as specified in the Hardware User's Manual with the restrictions listed in the Microsoft Windows C2 NT Administrator's and User's Security Guide, chapter 4.

Additional hardware information is available in the Final Evaluation Report (FER), which is available on Sybase's website.


Operating system installation

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

The first step in creating a C2 certified configuration involves installing and setting up the operating system.

toggle To install and set up the operating system

  1. Install Windows NT 4.0 in the C2 certified configuration (including Service Pack 6a and the C2 security Hotfix), as specified in the Microsoft Windows NT C2 Administrator's and User's Security Guide, Chapter 4.

  2. Log in to Windows NT as Administrator.

  3. From the Start menu, choose Programs > Administrative Tools (Common) > User Manager for Domains.

  4. Using the User Manager, create a user called sybase.

    • Give this user a secure password.

    • Add the user to only the Users group.

    • Clear the User Must Change Password at Next Logon checkbox.

    • Click Add, and then Close.

  5. From the Policies menu, choose User Rights.

  6. Check the Show Advanced User Rights checkbox, and then select Log On As A Service from the Right dropdown list.

  7. Click Add.

    A dialog appears.

  8. In the List Names From dropdown list, select \\machine_name.

  9. In the Add Names field, type sybase, and click OK.

  10. Click OK to close the dialog.

  11. If you wish to audit logons and logoffs of users (which can help in correlating Adaptive Server Anywhere audit records with Windows users) choose Policies > Auditing, and:

    • Select the Audit These Events option.

    • Check the Logon and Logoff checkbox under Success.

    • Select any other events you want audited, and click OK.

  12. Close the User Manager (optional).


Adaptive Server Anywhere software installation

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Next, you have to install Adaptive Server Anywhere in a C2-compliant manner. For C2 compliance you must use Adaptive Server Anywhere version 7.0.0, English only, without any EBFs (express bug fixes), in a standalone environment. Most of this book describes how to operate the current version of the software, but this section refers specifically to the C2-certified release.

toggle To install Adaptive Server Anywhere 7.0.0

  1. Log in to Windows NT as administrator.

  2. Download the Adaptive Server Anywhere C2 patch from [external link] www.sybase.com/developer.

  3. Run ASAC2Patch.exe and save the files into the default directory (C:\ASAC2Patch).

    ASAC2Patch.exe is a self-extracting archive.

    For information on this patch, see The Adaptive Server Anywhere C2 patch.

  4. Open a command prompt window.

    The Adaptive Server Anywhere installation includes MDAC (Microsoft Data Access Components). The MDAC installation replaces some Windows NT system DLLs which are part of the Windows NT TCB (trusted computing base). To avoid this, you must first make copies of these DLLs, and then replace them after the Adaptive Server Anywhere installation. The Adaptive Server Anywhere C2 Patch includes three batch files to facilitate this procedure.

    The first batch file creates a temporary directory and copies fourteen .dll files and one .exe file from the C:\winnt\system32 directory. To run the first batch file, enter the following commands at the command prompt:

    C:
cd \ASAC2Patch
mdac1
exit

  5. Install the Adaptive Server Anywhere 7.0.0 software, using the following guidelines:

    • Clear the Adaptive Server Anywhere for NetWare checkbox.

    • Clear the Adaptive Server Anywhere for Windows CE checkbox.

    • Clear the UltraLite development components checkbox.

    • Clear all options under Synchronization.

    • Clear the PowerDynamo 3.5, PowerDesigner, and Infomaker 7 options.

    • If available, clear the Encryption for MobiLink Synchronization checkbox.

    • Use the default values for installation directories.

  6. Reboot your machine after the installation is complete.

  7. Log in to Windows NT as an administrator.

  8. Install the Adaptive Server Anywhere C2 patch according to the directions in readme.txt (located in C:\ASAC2Patch).

    You do not need to reboot the machine after this step.

  9. Set permissions on the software directory as follows:

    • Double-click My Computer. Right-click the directory containing the Adaptive Server Anywhere software (it should be C:\Program Files\Sybase), and choose Properties.

    • Open the Security tab and then click the Permissions button.

    • Select Everyone, and change the Type of Access to Read.

    • Click Add. On the dialog that appears, select \\machine_name from the List Names From dropdown list. Select Administrators from the Names list and click Add.

    • Click Show Users. Select sybase from the Names list and click Add. Change Type of Access to Full Control, and click OK.

    • Make sure the list contains only the three entries mentioned above.

    • Check the Replace Permissions on Subdirectories checkbox.

    • Click OK, and answer Yes to the prompt.

  10. Create a folder for the database and transaction log files. For example, you may create a folder C:\Databases. In the remainder of this document, this folder is referred to as the C2 database folder. Set the permissions on this folder as follows:

    • Double-click My Computer. Right-click the Databases folder and select Properties.

    • Click the Security tab and click the Permissions button.

    • Remove the Everyone entry.

    • Click Add. On the dialog that appears, select \\machine_name in the List Names From dropdown list, and then type sybase in the Add Names field. Change Type of Access to Full Control, and click OK.

    • Click OK.

  11. Create a folder under C:\ called ASTMP for the engine to use as temporary storage space. Set the same permissions as for the Databases folder in the previous step.

  12. Set the System environment variable ASTMP to the temporary folder just created by right-clicking the My Computer icon, and choosing Properties. Click the Environment tab. In the Upper listbox, click any entry. Change the Variable entry to ASTMP, and change the Value entry to C:\ASTMP. Click Set, and then click OK.

  13. The second batch file contained in the Adaptive Server Anywhere C2 Patch copies the .dll and .exe files from the temporary directory created by mdac1.bat into the C:\winnt\system32 directory. To run the second batch file, from the Start menu, choose Programs > Command Prompt. At the command prompt, enter the following commands:

    C:
cd \ASAC2Patch
mdac2
exit

  14. When putting Windows NT into the certified configuration, several registry keys are deleted. During Adaptive Server Anywhere installation, two of these keys are re-created. For Windows NT to remain in its certified configuration, these keys must be deleted again. Use regedt32.exe to delete the following registry keys:

    Key | HKEY_LOCAL_MACHINE\SOFTWARE
    Subkey | Microsoft\OS/2 Subsystem for Windows NT
    Entry | delete all subkeys
    Key | HKEY_LOCAL_MACHINE\SYSTEM
    Subkey | CurrentControlSet\Control\Session Manager\Environment
    Entry | Os2LibPath
    Value | delete entry

  15. You must also ensure that these files have the correct permissions as shown below:

    Files | C2-Level Permissions
    BOOT.INI, NTDETECT.COM, NTLDR | Administrators: Full Control SYSTEM: Full Control

  16. Close all open windows and reboot your machine.

    You must reboot your machine for the Service Control Manager to read changes to system environment variables.

  17. Log in to Windows NT as administrator.

  18. The third batch file contained in the Adaptive Server Anywhere C2 Patch cleans up the temporary directory created by mdac1.bat. To run the third batch file, open a command prompt window. At the command prompt, enter the following commands:

    C:
cd \ASAC2Patch
mdac3
exit


Creating a database

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

To operate in a C2 compliant configuration, your database must be C2 compliant as well. All connections to the database must use the integrated login mechanism. Standard connections to the database (for example, specifying a user ID and password) are not allowed in the certified configuration.

toggle To create a C2 compliant database

  1. Log in as sybase.

  2. From the Start menu, choose Programs > Command Prompt.

  3. Use the dbinit utility to create a database with the following restrictions:

    • You must use the -I switch to disable jConnect support.

    • You must not use the -k, or -n switches.

    • You must put the database file in your C2 database folder.

    • If you specify a transaction log file using the -t switch, or a transaction log mirror file using the -m switch, the files specified must be in your C2 database folder.

      For information on using the dbinit utility in the certified configuration, see Initialization utility. For information about the database folder, see Adaptive Server Anywhere software installation.

  4. Once the database is created, you need to connect to the database.

    This connection must only be used to set the min_password_length option and the DBA's password.

  5. At a command prompt, type dbisqlc –c UID=DBA;PWD=SQL;DBF=file where file is the full path of the database file created above.

    Interactive SQL appears after a few seconds.

    For information on using the dbisqlc utility in the certified configuration, see Interactive SQL utility and Restrictions.

  6. Type set option public.min_password_length=6 (or higher) and click Execute.

  7. Type grant connect to DBA identified by newpw where newpw is the new password for the DBA account, and click Execute.

    The new password must be at least as long as the number entered in step 5, and should not be easy to guess.

  8. Type grant integrated login to sybase as user DBA, and click Execute.

  9. Type set option public.login_mode='Integrated', and click Execute.

  10. Exit Interactive SQL by clicking the X in the top right corner of the window.


Running the database engine

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

  1. Log in to Windows NT as administrator.

    You require administrator privileges to create, start, and stop services.

  2. Open a command prompt.

  3. Use the dbsvc utility to create a service with the following restrictions:

    • You must use the -a switch to specify the sybase account, and the -p switch to specify its password.

    • You must not use the -as or -I switches.

    • The executable name should be

      C:\Program Files\Sybase\SQL Anywhere 9\win32\dbeng9.exe

      for the personal database server, or

      C:\Program Files\Sybase\SQL Anywhere 9\win32\dbsrv9.exe

      for the database server.

    • You must use the following engine parameters:

      • -n engine name

      • -sc

      • -gd DBA

      • -gk DBA

      • -gl DBA

      • -gu DBA

      • -x namedpipes(TDS=NO)

  4. Enter the full path to any database files you wish to run.

    The path should be in the format database-folder\filename.db, where database-folder is your C2 database folder, and include any other relevant parameters.

    For example, the following command line creates a service called asa_svc that starts manually, and refers to a network server. It runs under the sybase account, whose password is sybase_password. It executes the following command:

    C:\Program Files\Sybase\SQL Anywhere 9\win32\
dbsrv9.exe -n asa_c2 -sc -gd DBA -gk DBA
-gl DBA -gu DBA -x namedpipes(TDS=NO)
database-folder\c2test.db
dbsvc -a sybase -p sybase_password -s manual
-t network -w asa_svc C:\Program Files\Sybase\
SQL Anywhere 9\win32\dbsrv9.exe -n asa_c2 -sc
-gd DBA -gk DBA -gl DBA -gu DBA
-x namedpipes(TDS=NO) database-folder\c2test.db

    For information on using the engine and the server in the certified configuration, see Database engine/server.

  5. To start and stop the service, run the Windows NT service manager from the control panel. From the Start menu, choose Settings > Control Panel, and then double-click Services.

    The service you just created appears under Adaptive Server Anywhere - svc where svc is the service name you specified on the dbsvc command line.

  6. Use the Start and Stop buttons to start and stop the service.


Auditing

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

About this chapter

This chapter contains information on reading auditing output, and correlating Adaptive Server Anywhere auditing output with Windows NT auditing.

Enabling and disabling auditing
Reading auditing output
Audit records
Administration of audit records
Auditing of database utilities
Correlating audit records


Enabling and disabling auditing

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Auditing is OFF when you create a database. However, you can enable and disable auditing using the auditing public option at any time.

toggle To start auditing on a particular database

  • Turn the option ON using the following SQL statement:

    SET OPTION public.auditing='on'

    Only users with DBA authority can set public options. Once this option has been turned on, all permission checks and connection attempts are audited.

toggle To stop (disable) auditing on a particular database

  • Turn the option OFF using the following SQL statement:

    SET OPTION public.auditing = 'off'

    Only a user with DBA authority can issue this statement.

For more information and a complete list of the types of audit records that the engine or server can generate, see Audit records.

Note

Auditing is optional when running in a C2 certified configuration.


Reading auditing output

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

You can use the dbtran utility to retrieve audit records from the transaction log. The transaction log file is usually found in the dbname.log file, located in the same directory as the database file.

The -g switch tells dbtran to include audit records in the output. The output from dbtran is a SQL script with comments interspersed. This SQL script can be used to recover the database if a failure occurs. When using the -g option, the output file is entirely comments, since the -g option implies the -d option (which records transaction log information in the order in which it was contained in the log, not in the default commit order). Do not use output in this format for recovery of a database. Each line is commented to avoid accidental use of this file for recovery.

When a user connects to the database, an audit record is generated:

--CONNECT-1001-0000198970-dba-1998/dec/03 14:54

The data following the CONNECT are interpreted as follows:

  • 1001 is the connection ID assigned to this connection. Any transactions listed below with connection ID 1001 belong to this connection, until another CONNECT-1001 is found.

  • 0000198970 is the byte offset of the record in the transaction log.

  • dba is the user name logged in on this connection.

  • 1998/dec/03 14:54 is the date and time of the connection.

Other records have the connection ID and byte offset, but only the CONNECT record has the user name and date/time. Note that disconnects are not logged. If another CONNECT record is generated with the same connection ID as a previous CONNECT record, you can assume that the first user has disconnected. Although the connection ID is reused, the second connection is entirely unrelated to the first.


Audit records

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

This section identifies the different audit records that may be generated by the engine or server, the information contained in the record, and when the record is generated. Descriptions of the audit records generated by the three database utilities dblog, dbtran, and dbwrite in the .alg file appear in Auditing of database utilities.

Type | Information | Use
Attempting Operation date/time, SQL of attempted operation This record displays the operation being attempted. This is necessary because of the way the transaction log works.

The transaction log contains SQL to replicate changes made to the database data or schema if recovery becomes necessary. Audit records become part of this log so that each permission check is recorded as it happens, and so that the activity on the database can be recreated later.

However, if a permissions check fails, then the operation being attempted doesn't actually happen, and therefore doesn't get logged. In this case, there is no way of knowing what was being attempted. This is especially important when a non-DBA user attempts something that requires DBA authority.

For this reason, all DDL statements (and a few other statements as well) are recorded before they are attempted.
Operation Succeeded / Failed | date/time, success or failure | This record indicates the success or failure of the most recent Operation Attempt, Attempting to set public option, or Attempting SETUSER record for the same connection ID.
Checking permission date/time, type of permission / authority, table name (if applicable), column name (if applicable), procedure / function name (if applicable) This record indicates that a permission or authority check of some kind took place. The permission in question is indicated, and can be one of:

DBA / Resource authority

Insert / Update / Select / Delete / Alter / Resource permission on a table

Update / Select / Resource permission on a table and column

Grant Insert / Update / Select / Delete / Alter / Resource permission on a table

Grant Update / Select / Resource permission on a table and column

Execute permission on a procedure or function

Grant Execute permission on a procedure or function
Checking user | date/time, user name | This record indicates that a user check took place. This can help determine ownership of objects, for example, user bob owns table T. If an insert is attempted on table T, we must check to see if the current user is user bob. The text of the record is Checking to see if user is user name.
Set Public Option | date/time, name of option | This record indicates that a user attempted to set an option owned by the PUBLIC user. Only users with DBA authority are allowed to do this, so this check will always be followed by a DBA authority check. An Operation Succeeded/Failed record indicates success or failure.
Auditing Enabled / Disabled | date/time | This record indicates that the auditing public option has been changed. This record will always follow a Set Public Option record. This record is generated whether auditing is turned on or off. However, this record will not be generated if the user sets the auditing variable to ON when auditing is already on, or if the user sets the variable to OFF when auditing is already off.
Attempting SETUSER | date/time, name of user | This record indicates that a user has attempted a SETUSER command with a parameter. Only users with DBA authority are allowed to do this, so this record will always be followed by a DBA authority check. An Operation Succeeded/Failed record indicates success or failure. Note that the SETUSER command with no arguments is neither audited nor logged, since any user can execute that statement.
Attempting Connection | date/time, user name (if successful), machine address (local if the same machine), port type, success or failure | This record indicates that a connection attempt took place.
Trigger firing / finishing | date/time, name of trigger | This record indicates that a trigger has fired or finished executing. All audit records for the same connection in between these two records are auditing the trigger execution. Note that triggers execute with the permission of the table owner, not the caller, so any permission checks audited in between Trigger firing and Trigger finishing records are done with respect to the table owner. Examining the SQL statement that caused the trigger to fire will reveal the table owner. Look at the SQL statement for the same connection immediately preceding the Trigger firing record. It will be an insert, update, or delete on a table. The table name will be in the format owner.table.
String | date/time, string | Records of this type can be inserted into the audit trail using a system stored procedure called sa_audit_string. This procedure is executable only by users with DBA authority. Any string (up to 128 characters) can be specified.


Table 6.2 - Format of audit records - fixed

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Type | Format
Transaction redo header | 1 byte
Connection identifier | 3 bytes
date / time 11 bytes:

  • 2 bytes year (for example, 1998)

  • 1 byte month (1–12)

  • 1 byte day (1–31)

  • 1 byte hour (0–23)

  • 1 byte minute (0–59)

  • 1 byte second (0–59)

  • 4 bytes microsecond (0–999999)
Audit type | 1 byte


Table 6.3 - Format of audit records - variable by type

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Type Format
AUDIT_ENABLE_AUDITING

  • 1 byte 1 (auditing enabled) or 0 (auditing disabled)
AUDIT_SET_PUB_OPTION

  • 2 bytes length of following string (n)

  • n bytes option name
AUDIT_OP_ATTEMPT

  • 2 bytes length of following string (n)

  • n bytes SQL of attempted operation
AUDIT_OP_SUCCESS

  • 1 byte 1 (operation succeeded) or 0 (operation failed)
AUDIT_PERM_CHECK

  • 1 byte 1 (success) or 0 (failure)

  • 2 bytes length of following string (n)

  • n bytes permission type (for example, select, update, or execute)

  • 2 bytes length of following string (n)

  • n bytes object (table, view, procedure, etc.) name

  • 2 bytes length of following string (n)

  • n bytes column name, if applicable
AUDIT_USER_CHECK

  • 1 byte 1 (success) or 0 (failure)

  • 2 bytes length of following string (n)

  • n bytes user name
AUDIT_CONNECTION

  • 1 byte 1 (success) or 0 (failure)

  • 2 bytes length of following string (n)

  • n bytes user name (if connection succeeded)

  • 2 bytes length of following string (n)

  • n bytes machine ID
AUDIT_SETUSER

  • 2 bytes length of following string (n)

  • n bytes user name
AUDIT_TRIGGER

  • 2 bytes length of following string (n)

  • n bytes name of trigger

  • 3 bytes fired or finished
AUDIT_STRING

  • 2 bytes length of following string (n)

  • n bytes variable text string


Administration of audit records

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

The Log translation [dbtran] utility can retrieve audit records from the transaction log. Using the -u or -x switches when invoking dbtran, records can be filtered depending on the user name. Audit records cannot be deleted. However, the transaction log can be purged or truncated using the dblog or dbbackup utilities.

For more information about purging the transaction log, see Transaction log utility.

If the audit log (in the case of Adaptive Server Anywhere, the transaction log) becomes full, the engine or server will rollback all pending transactions and fail all subsequent requests. At this point, the transaction log must be truncated in order to continue using the database. It is strongly recommended that you back up the transaction log before truncating it. The easiest way to back up the transaction log is to stop the engine, and then copy the file to another disk. You can then delete the old transaction log file and restart the engine or server. A new transaction log file will then be created.


Auditing of database utilities

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Some database utilities perform actions that must be audited, but do not necessarily communicate with a running engine or server. These utilities must be audited separately. The utilities in question are dblog, dbwrite, and dbtran. These utilities check the database or transaction log to see if auditing is enabled. If so, they audit their invocation by writing to a file called dbname.alg, located in the same directory as the database file.

The .alg file is a text file, and can be viewed with any standard editor, such as Notepad. You can also use text-file sort and filter utilities (such as grep) to retrieve audit records for a particular user or utility.

Each audit record consists of a single line, in the following format:

2000/07/07 15:31:17.316 - User NT user name invoking utility name

You can delete records from this file at any time, simply by deleting them in the editor and saving the file. You can also delete the file at any time. Utilities that generate records into this file will fail if they cannot write to this file (for example, if the file system is full). Accesses to the .alg file can be audited using the Windows NT audit mechanism.


Correlating audit records

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

In some cases, it may be useful to know the name of the user who was logged into Windows NT at the time that some audit records were generated. For example, if a DBA notices a lot of failed logon attempts grouped together, he may want to know who was logged into Windows NT at the time that these attempts were made. There are two ways to do this, depending on the type of information that is required.

In the above example, you would simply record the time at which the audit event in question took place – all audit events include the date and time of the event. Then, log into Windows NT as the administrator, and run the Event Viewer application. From the Log menu, choose Security to see the logon and logout audit records. Locate and double click the Logon/Logoff event immediately before the date and time of the audit event in question. It should be a Successful Logon event. The user name and domain of the user that logged on will appear, and tell you who was logged into the Windows NT workstation at the time that the audited event occurred. Note that this is only possible if auditing of Windows NT logons and logouts was enabled during Operating system installation.

If the audit log contains information about a specific connection, and you need to correlate that with a particular Windows user, this second method is easier. Since integrated login is used for all connections, the database user is mapped to a particular Windows user. Since this mapping must be one-to-one, we know that no other Windows user can be mapped to this database user. To find the name of the Windows user given the database login ID, execute the following SQL statement:

SELECT lg.integrated_login_id
FROM syslogin lg
KEY JOIN sysuserperm p
WHERE p.user_name='login ID'


Restrictions and Other Security Concerns

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

About this chapter

This chapter describes C2 certification restrictions and other security concerns.


Restrictions

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

The following restrictions are required for Adaptive Server Anywhere to run in the certified C2 configuration.

  1. Do not delete, modify, or replace any files under the Adaptive Server Anywhere installation directory, with the following exceptions:

    • win32\util_db.ini – this file may be modified as required.

    • win32\asasrv.ini – this file may be modified or deleted as required.

    • win32\rebuild.bat – this file may be modified as required.

    • win32\backup.syb – this file may be modified or deleted as required.

    • win32\procdebug.bat – this file may be modified as required.

    • win32\custom.SQL – this file may be modified as required.

    • win32\tjava.pdf – this file may be deleted as required.

  2. Do not add any new files under the Adaptive Server Anywhere installation directory.

  3. The sybase account password should only be given to one person.

  4. The path for the sybase account should not contain any directories other than %SystemRoot%\system32, %SystemRoot%, and the Adaptive Server Anywhere win32 directory.

  5. Grant only the Login as a Service privilege to the sybase account.

  6. DBA authority is very powerful. Only grant DBA authority to those users who require it. The number of DBA users should be kept to a minimum. However, each person who requires DBA authority should be given a separate account with DBA authority granted to it (for example, do not use shared DBA accounts).

  7. DBAs who will be using the database outside of their DBA capacity should be given two different Adaptive Server Anywhere user accounts—one with DBA authority and one without. DBAs should only use the account with DBA authority when necessary.

  8. The password for the DBA account must be changed upon creation of a new database.

  9. The value for the min_password_length public option must be set to at least 6 upon creation of a new database.

  10. The database engine or server must be run as a Windows NT service. Adaptive Server Anywhere is only certified when running as a service.

  11. The following switches must be specified on the engine or server start line

    -sc -gd DBA -gk DBA -gl DBA -gu DBA
-x namedpipes(TDS=NO)

    The engine or server start line is specified when executing the dbsvc utility, so these switches must be included in the Details part of the dbsvc command.

    For more information, see Service creation utility for details on dbsvc.

  12. Do not use the -x parameter to start up any ports other than Named Pipes. Adaptive Server Anywhere is only certified in a standalone environment.

  13. Do not grant REMOTE_DBA authority to any user.

  14. Do not grant execute permission on the following system procedures to any user or group:

    • xp_cmdshell

    • xp_startmail

    • xp_sendmail

    • xp_stopmail

    • xp_read_file

    • xp_write_file

    • sp_audit_string

    • java_debug_version

    • java_debug_connect

    • java_debug_disconnect

    • java_debug_get_existing_vms

    • java_debug_free_existing_vms

    • java_debug_wait_for_debuggable_vm

    • java_debug_get_vm_name

    • java_debug_release_vm

    • java_debug_attach_to_vm

    • java_debug_detach_from_vm

    • java_debug_detach_request

    • Any system procedures introduced after version 7.

  15. Do not create stored procedures or functions owned by any user with DBA authority.

  16. Do not create triggers on any tables owned by any user with DBA authority.

  17. Upgrade older databases by running the dbupgrad utility before using them.

    For more information about upgrading a database, see Upgrading a database using the dbupgrad command-line utility.

  18. Databases must use a transaction log file. Do not use the -n switch (no transaction log) when creating a database and do not execute dblog -n (do not use a transaction log or mirror) on a database.

  19. All database, transaction log, dbspace, write file, and mirror files should be stored in non-shared, protected directories.

    For guidelines on how to protect a directory, see Adaptive Server Anywhere software installation.

  20. The java.net package is disabled in the engine or server. Java running in the database will not be able to use this package.

  21. The java_input_output public option must always be set to OFF (the default).

  22. Do not create a database user called guest. Such a user would allow any Windows user to connect to the database using integrated login.

  23. Always set the login_mode public option to Integrated during database installation.

    For more information, see Creating a database.

  24. All connections to the database must use the integrated login mechanism. Standard connections to the database (that is, those specifying user ID and password) are not allowed in the certified configuration.

  25. All integrated login mappings must be one-to-one. No two Windows user names may be mapped to the same database user.

  26. Embedded SQL programs must not use the db_delete_file function because the name of the file being deleted is not audited.

  27. Do not grant SELECT access on sys.sysuserperm or sys.syslogin to any non-DBA user.


Security warnings

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Below are some other security issues to be aware of:

  1. Since triggers execute with the permission of the table owner, it is possible for any user with ALTER permission on a table to write a trigger that accesses other tables owned by the same user. Please be aware that by granting ALTER permission on a table to another user, you are effectively granting all permissions on all of your tables to that user.

  2. Audit records are created when a trigger is fired, and when the stored procedure executed by the trigger finishes. The user ID listed in these audit records is that of the owner of the table on which the trigger is defined.

  3. Stored procedures may contain the GRANT command. When such a procedure is executed, the GRANT is done with the permissions of the owner of the stored procedure, not those of the caller. Be aware of this when creating stored procedures containing GRANT statements.

  4. Windows NT has the ability to audit actions taken by users. It is recommended that users configure Windows NT to audit the sybase user. Note that such auditing could produce a large amount of data.

    For more information, see Operating system installation.

  5. Permissions on tables and columns are cumulative, but independent. This means that if executing two different GRANT statements gives overlapping permissions, revoking one of the two does not revoke the other.

    For example, if user fred executes GRANT UPDATE (Street) on the Employee table to sue, Sue can update the Street column of table Employee.

    If user fred subsequently executes GRANT UPDATE on the Employee table to sue, Sue is then able to update any column of the Employee table.

    If user fred then executes REVOKE UPDATE on Employee from sue, the second grant is revoked, but the first grant is still in effect. Sue still has the ability to update the Street column of table Employee.


Changing ownership on nested objects

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Views and procedures can access underlying objects that are owned by different users. For example, if usera, userb, userc, and userd were four different users, userd.viewd could be based on userc.viewc, which could be based on userb.viewb, which could be based on usera.table. Similarly for procedures, userd.procd could call userc.procc, which could call userb.procb, which could insert into usera.tablea.

The following Discretionary Access Control (DAC) rules apply to nested views and tables:

  • To create a view, the user must have SELECT permission on all of the base objects (for example, tables and views) in the view.

  • To access a view, the view owner must have been granted the appropriate permission on the underlying tables or views with the GRANT OPTION and the user must have been granted the appropriate permission on the view.

  • Updating with a WHERE clause requires both SELECT and UPDATE permission.

  • If a user owns the tables in a view definition, the user can access the tables through a view, even if the user is not the owner of the view and has not been granted access on the view.

The following DAC rules apply to nested procedures:

  • A user does not require any permissions on the underlying objects (for example tables, views or procedures) to create a procedure.

  • For a procedure to execute, the owner of the procedure needs the appropriate permissions on the objects that the procedure references.

  • Even if a user owns all the tables referenced by a procedure, the user will not be able to execute the procedure to access the tables unless the user has been granted EXECUTE permission on the procedure.

Following are some examples that describe this behavior.

Example 1: User1 creates table1, and user2 creates view2 on table1
Example 2: User2 creates procedure2 that accesses table1
Example 3: User1 creates table1, user2 creates table2, and user3 creates view3 joining table1 and table2


Example 1: User1 creates table1, and user2 creates view2 on table1

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

  • User1 can always access table1, since user1 is the owner.

  • User1 can always access table1 through view2, since user1 is the owner of the underlying table. This is true even if user2 does not grant permission on view2 to user1.

  • User2 can access table1 directly or through view2 if user1 grants permission on table1 to user2.

  • User3 can access table1 if user1 grants permission on table1 to user3

  • User3 can access table1 through view2 if user1 grants permission on table1 to user2 with grant option and user2 grants permission on view2 to user3.


Example 2: User2 creates procedure2 that accesses table1

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

  • User1 can access table1 through procedure2 if user2 grants EXECUTE permission on procedure2 to user1. Note that this is different from the case of view2, where user1 did not need permission on view2.


Example 3: User1 creates table1, user2 creates table2, and user3 creates view3 joining table1 and table2

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

  • User3 can access table1 and table2 through view3 if user1 grants permission on table1 to user3 AND user2 grants permission on table2 to user3.

  • If user3 has permission on table1 but not on table2, then user3 cannot use view3, even to access the subset of columns belonging to table1.

  • User1 or user2 can use view3 if (a) user1 grants permission with grant option on table1 to user3, (b) user2 grants permission with grant option on table2 to user3, AND ©) user3 grants permission on view3 to that user.


Revoking DBA authority

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Since the engine does not generally allow you to revoke DBA authority from a user while that user is connected to the database, the easiest way to revoke DBA authority is simply to wait until the user has disconnected, and then issue a REVOKE DBA statement.

However, it may be necessary to immediately revoke DBA authority from a user who is currently connected to the database, before the user has a chance to do anything else. Assume for this example you are trying to revoke DBA authority from user fred.

toggle To revoke DBA authority from a connected user

  1. Connect to the same database as a different user with DBA authority.

    For example, use a user ID other than fred.

  2. Disable connections to the server by executing the following statement:

    CALL sa_server_option('ConnsDisabled', 'ON')

    This prevents fred from connecting again once his existing connections have been dropped.

  3. List all the connections to the database by executing the following statement:

    CALL sa_conn_info( )

  4. Write down the value of the Number column for each row containing fred in the Userid column.

  5. For each connection number you wrote down in step 4, execute the following statement:

    DROP CONNECTION number

    This immediately drops each connection, rolling back any uncommitted transactions. Note that any transactions committed by fred, as well as any DDLs executed by fred before the DROP statement was executed, are not rolled back and must be manually undone.

  6. Execute the following SQL statement:

    REVOKE DBA FROM fred

  7. Re-enable connections to the server by executing the following statement:

    CALL sa_server_option('disable_connections', 'OFF')


The TCB subset

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Following are the software modules and files that comprise the TCB (trusted computing base) included in the certified configuration. (Note that all .exe and .dll files are located in the win32 subdirectory of your Adaptive Server Anywhere directory.)

  1. Database engine / server

    • dbeng9.exe

    • dbsrv9.exe

    • dbserv9.dll

    • dbctrs9.dll

    • libsybbr.dll

    • dblgen9.dll

    • dbcis9.dll

    • dbjava9.dll

    • *.sql in the scripts directory

    • *.zip in the java directory

  2. Interactive SQL

    • dbisqlc.exe

    • dbcon9.dll

    • dblgen9.dll

    • dbtool9.dll

    • dblib9.dll

  3. Database utilities

    • dbackup.exe

    • dbcollat.exe

    • dbdsn.exe

    • dberase.exe

    • dbexpand.exe

    • dbinfo.exe

    • dbinit.exe

    • dblog.exe

    • dbping.exe

    • dbshrink.exe

    • dbstop.exe

    • dbsvc.exe

    • dbtran.exe

    • dbunload.exe

    • dbupgrad.exe

    • dbvalid.exe

    • dbwrite.exe

    • sqlpp.exe

    • dblgen9.dll

    • dbtool9.dll

    • dblib9.dll


Restricted Syntax

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

About this chapter

This chapter lists the syntax for the engine and server, as well as several database utilities used in the certified configuration.


Restricted Syntax

Restricted syntax

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

This section lists the syntax for the engine and server, as well as several database utilities used in the certified configuration. These tools are documented in Database Administration Utilities, but appear here for convenience, and also to emphasize the required or restricted switches in the C2 certified configuration. Note that where optional switches are listed, only those switches listed may be used. Any switches that may be documented or listed in the usage screen of the utility but are not listed here are not allowed in the certified configuration.

Please consult the Adaptive Server Anywhere Reference manual for more complete descriptions of each switch.


Database engine/server

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Syntax 1

dbeng9 -sc -gd dba -gk dba -gl dba -gu dba -x namedpipes(TDS=NO)
[ optional-engine-or-server-switches ]
[ db-file [ optional-database-switches ] ] ...

Syntax 2

dbsrv9 -sc -gd dba -gk dba -gl dba -gu dba -x namedpipes(TDS=NO)
[ optional-engine-or-server-switches ]
[ db-file [ optional-database-switches ] ] ...

Required switches:
Switch | Description | Reason
–sc | Set up C2 Certified communication links. | Disallows shared memory connections.
–gd dba | Set starting database permission to DBA. | Non-DBA users could start their own database, connect as DBA, and then execute the UNLOAD or DROP DATABASE statements, or stop the engine or server.
–gk dba | Set stopping database engine or server permission to DBA. | Non-DBA users could stop the database engine or server, causing denial-of-service.
–gl dba | Set LOAD/UNLOAD permission to DBA. | A non-DBA user could use the UNLOAD command to write to the file system with the permissions of the sybase user.
–gu dba | Set utility commands permission to DBA. | Non-DBA users could use the DROP DATABASE statement to delete database files owned by the sybase user.
–x namedpipes(TDS=NO) | Starts the named pipes port and disallows TDS connections. | The named pipes port is the only communications mechanism supported in the certified configuration; the TDS protocol is not included in the certified configuration.
Optional engine or server switches:
Switch | Description | Restrictions
–a logfile | Apply named transaction log file. | Used only in recovery.
–b | Run in bulk operations mode. |
–c size | Make initial cache a maximum of size bytes. |
–ca 0 | Disable automatic cache growth to compensate for memory allocation. |
–ch size | Set maximum cache size of size bytes. |
–cl size | Set minimum cache size of size bytes. |
–cs | Display cache sizing statistics. |
–ct | Perform client-engine or server character translation. |
–d | Disable asynchronous I/O. |
–e | Encrypt communications messages. |
–f | Force database to start without transaction log. | Used only in recovery. Note that auditing is unavailable if the engine or server is started with this switch.
–ga | Automatically shutdown after last database closed. |
–gc num | Set checkpoint timeout period to num minutes. |
–ge size | Set external DLL thread stack size. |
–gf | Disable firing of triggers. |
–gm num | Allow maximum num connections, if possible. |
–gn num | Use num engine or server threads. |
–gp size | Set maximum page size of size bytes. |
–gr num | Set maximum recovery time to num minutes. |
–gt num | Allow num OS threads to run concurrently. |
–gw num | Background process every num milliseconds. Default 500 milliseconds. |
–gx num | Use num OS threads. |
–m | Truncate transaction log after checkpoint. | Note that this also truncates the audit log after checkpoint.
–n name | Name the database engine or server. |
–o file | Filename for copy of message window. |
–os size | Maximum size for the file specified by -o. |
–p size | Set maximum communication packet size. |
–q | Quiet mode—suppress output. |
–r | Read-only mode—database modifications not allowed. |
–ti min | Client idle time before disconnect. Default 240 minutes. |
–tl sec | Client liveness timeout in seconds. | Has no effect in certified configuration.
–tq time | Set quitting time. |
–u | Use buffered disk I/O. |
–v | Display product version information. |
–z | Display debugging information. |
–zo file | Redirect request logging information to file. |
–zr level | Set request logging level. Level may be ALL, SQL, or NONE. |
–zs size | Maximum size for file specified by -zo. |

db-file is a fully-qualified database file or write file name. All files must reside in your C2 database folder.


Initialization utility

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Syntax

dbinit -I [ optional-switches ] c2-database-folder\filename

Required switches:
Switch | Description | Reason
–I | Do not install jConnect support | jConnect uses TCP/IP to communicate, which is not supported in the certified configuration.
Optional switches:
Switch | Description | Restrictions
–b | Blank padding of strings for comparisons |
–c | Case sensitivity on all string comparisons |
–e | Encrypt database |
–m name | Set transaction log mirror name | Full path must be specified; file must reside in your C2 database folder.
–o file | Log output messages to file |
–p size | Set page size |
–q | Quiet: do not print messages |
–t name | Transaction log file name | Full path must be specified; file must reside in your C2 database folder.
–z cs | Specify collation sequence |


Service creation utility

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Syntax 1

dbsvc [ optional-switches ] -d svc name

Syntax 2

dbsvc [ optional-switches ] -a sybase [ creation-switches ] -w svc-name
Details

Syntax 3

dbsvc [ -q ] -d svc name

Syntax 4

dbsvc [ -q ] -l

Required switches:
Switch | Description | Reason
–a sybase | Account name to use | The Adaptive Server Anywhere service must run as the sybase user.
Optional switches:
Switch | Description | Restrictions
–q | Do not print banner |
–y | Delete or overwrite service without confirmation |
Creation switches:
Switch | Description | Restrictions
–p passwd | Specify the password for the sybase account. |
–s startup | Startup option. Startup must be Automatic, Manual, or Disabled. Default is Manual. |
–t type | Type of service. Type must be Network or Standalone. Default is Standalone. |
Notes

For syntax 2, Details must contain the full path to the Adaptive Server Anywhere engine or server executable, as well as the parameters for that engine or server.

For more information about the engine and server parameters, see Database engine/server.


Transaction log utility

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Syntax

dblog [ optional-switches ] c2-database-folder\database-file

Optional switches:
Switch | Description | Restrictions
–g n | Set LTM generation number. |
–il | Ignore LTM truncation point. |
–ir | Ignore SQL Remote truncation point. |
–m name | Set transaction log mirror name. | Full path must be specified; file must reside in your C2 database folder.
–o file | Log output messages to file. |
–q | Quiet: do not print messages. |
–r | Do not use a transaction log mirror. |
–t name | Set transaction log name. | Full path must be specified; file must reside in your C2 database folder.
–x n | Zap transaction log current relative offset to n. |
–z n | Zap transaction log starting offset to n. |


Interactive SQL utility

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Syntax 1

dbisqlc [ optional-switches ] SQL-command

Syntax 2

dbisqlc [ optional switches ] filename

Optional switches:
Switch | Description | Restrictions
–c conn_str | Use connection string conn_str. | conn_str must contain "INT=YES;LINKS=namedpipes" and must not contain "UID=" or "PWD="
–d delimiter | Specify command delimiter. |
–q | Silent mode, no window. |
–x | Syntax check only, no commands executed. |


Integrated Logins

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

About this chapter

This chapter describes how to use the integrated login in a manner equivalent to the C2 certified configuration.

Using integrated logins


Using integrated logins

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Adaptive Server Anywhere uses the integrated login mechanism to map a Windows user to an Adaptive Server Anywhere user. When a Windows user attempts to connect to the database, the operating system provides assurance that the user has been authenticated (usually using a password). If the database server contains a mapping between that Windows user and a valid Adaptive Server Anywhere user, that user can connect.

For use in the C2 certified configuration, Adaptive Server Anywhere requires the use of integrated login exclusively. An integrated login must be created for the DBA account in the database, and it is recommended that the sybase Windows user be used for this purpose. As well, integrated login mappings must be one-to-one. That is, two Windows user accounts may not be mapped to the same Adaptive Server Anywhere account.

For instructions on how to create an integrated login for the sybase user, see Creating a database.

For more information on integrated login, see Connecting to a Database.


Connecting to the Adaptive Server Anywhere Service

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

About this chapter

This chapter describes how to connect to the Adaptive Server Anywhere Service in a manner equivalent to the C2-certified configuration.

Connecting to the Adaptive Server Anywhere service


Connecting to the Adaptive Server Anywhere Service

Connecting to the Adaptive Server Anywhere service

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Once the Adaptive Server Anywhere service has been started, users can use dbisqlc to connect to the engine and execute SQL statements. There are two ways to tell dbisqlc how to connect:

  1. You can use the -c switch and specify a connection string containing a list of parameters that tell dbisqlc which engine and database to connect to, and how to find it. For example, if your engine is named asademo, you can connect to it using:

    dbisqlc -c "ENG=asademo;LINKS=namedpipes;INT=YES

    LINKS=namedpipes tells dbisqlc to use named pipes to connect to the engine, and INT=YES tells dbisqlc to use the integrated login facility.

  2. You can simply start dbisqlc, and fill in the fields on the connection dialog. Note that you must select the Use integrated login option on the Login tab, you must enter an engine name on the Database tab, and you must check the Named pipes checkbox on the Network tab.


The Adaptive Server Anywhere C2 Patch

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

About this chapter

This chapter describes the C2 patch to the Adaptive Server Anywhere 7.0.0 release. This chapter does not apply when running the current software in a manner equivalent to the C2-certified environment.

The Adaptive Server Anywhere C2 patch


The Adaptive Server Anywhere C2 Patch

The Adaptive Server Anywhere C2 patch

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

The Adaptive Server Anywhere C2 Patch contains two DLLs, three batch files, and one text file. This section describes each file in the patch.

This section describes the C2 patch to the Adaptive Server Anywhere 7.0.0 release. It does not apply when running the current software in a manner equivalent to the C2-certified environment.

File | Description
dblgen7.dll | Contains English language strings used by the Adaptive Server Anywhere engine and tools. This file contains the auditing string used by dbbackup to audit the use of the -xo switch.
dbtool7.dll | Used by all of the database utilities, as well as dbisqlc.exe. This file contains a fix to dbbackup to audit the truncation of the transaction log.
mdac1.bat | This batch file creates a temporary directory and copies fourteen .dll files and one .exe from the C:\winnt\system32 directory into the temporary directory. The Adaptive Server Anywhere installation will replace these files, and they must be copied before Adaptive Server Anywhere installation so they can be restored after.
mdac2.bat | This batch file copies the files from the temporary directory created by mdac1.bat into the C:\winnt\system32 directory, overwriting those installed by Adaptive Server Anywhere. One of the files is in use by the operating system, so it is renamed before the file copy.
mdac3.bat | This batch file deletes the file that was renamed by mdac2.bat, as well as the temporary directory created by mdac1.bat.
readme.txt | This file contains instructions for installing the .dll files included in the patch.


More Information

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

About this chapter

This chapter contains a list of additional sources of information that may be helpful while operating Adaptive Server Anywhere in the C2 certified configuration.

Where to look for more information


Where to look for more information

This page describes operation of Adaptive Server Anywhere in a manner equivalent to a C2-security-certified configuration. It does not provide general-purpose information on the topic.

Subject | Source
Auditing | Keeping Your Data Secure
Connection parameters | For a list, run dbdsn -cl or see Client/Server Communications.
Database options | Database Options
dbinit, dblog, dbtran, dbisqlc, dbbackup and other administrative utilities | Database Administration Utilities
dbsvc utility | The Service Creation utility
Engine / server switches | The Database Server
Integrated login | Connecting to a Database
Java in the Database | Introduction to Java in the Database and Using Java in the Database
Procedures, Functions, Triggers | Using Procedures, Triggers, and Batches
Security tips | Keeping Your Data Secure
Tables, Views | Working with Database Objects
The GRANT and REVOKE SQL statements | SQL Statements
The transaction log file | Backup and Data Recovery
User IDs and permissions | Managing User IDs and Permissions


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Administration Guide

Version 9.0.2

DC38132-01-0902-01

October 2004

Copyright
About This Manual
Introducing MobiLink Synchronization
Synchronization Basics
MobiLink Consolidated Databases
Synchronization Techniques
File-Based Downloads
MobiLink Performance
MobiLink Monitor
Synchronizing Through a Web Server With the Redirector
Running MobiLink Outside the Current Session
MobiLink Transport-Layer Security
MobiLink Synchronization Server Options
Writing Synchronization Scripts
Writing Synchronization Scripts in Java
Writing Synchronization Scripts in .NET
Synchronization Events
Stored Procedures
Utilities
MobiLink System Tables
DataType Conversions
Character Set Considerations
iAnywhere Solutions ODBC Drivers
Deploying MobiLink Applications


Copyright

Copyright © 1989–2004 Sybase, Inc. Portions copyright © 2001–2004 iAnywhere Solutions, Inc. All rights reserved.

No part of this publication may be reproduced, transmitted, or translated in any form or by any means, electronic, mechanical, manual, optical, or otherwise, without the prior written permission of iAnywhere Solutions, Inc. iAnywhere Solutions, Inc. is a subsidiary of Sybase, Inc.

Sybase, SYBASE (logo), 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-Library, APT-Translator, ASEP, AvantGo, AvantGo Application Alerts, AvantGo Mobile Delivery, AvantGo Mobile Document Viewer, AvantGo Mobile Inspection, AvantGo Mobile Marketing Channel, AvantGo Mobile Pharma, AvantGo Mobile Sales, AvantGo Pylon, AvantGo Pylon Application Server, AvantGo Pylon Conduit, AvantGo Pylon PIM Server, AvantGo Pylon Pro, Backup Server, BayCam, Bit-Wise, BizTracker, Certified PowerBuilder Developer, Certified SYBASE Professional, Certified SYBASE Professional Logo, 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, Dynamic Mobility Model, Dynamo, e-ADK, E-Anywhere, e-Biz Integrator, 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 Portal (logo), Enterprise SQL Server Manager, Enterprise Work Architecture, Enterprise Work Designer, Enterprise Work Modeler, eProcurement Accelerator, eremote, Everything Works Better When Everything Works Together, EWA, E-Whatever, Financial Fusion, Financial Fusion (and design), Financial Fusion Server, Formula One, Fusion Powered e-Finance, Fusion Powered Financial Destinations, Fusion Powered STP, Gateway Manager, GeoPoint, GlobalFIX, iAnywhere, iAnywhere Solutions, ImpactNow, Industry Warehouse Studio, InfoMaker, Information Anywhere, Information Everywhere, InformationConnect, InstaHelp, Intelligent Self-Care, InternetBuilder, iremote, iScript, Jaguar CTS, jConnect for JDBC, KnowledgeBase, Logical Memory Manager, Mail Anywhere Studio, MainframeConnect, Maintenance Express, Manage Anywhere Studio, MAP, M-Business Channel, M-Business Network, M-Business Server, MDI Access Server, MDI Database Gateway, media.splash, Message Anywhere Server, MetaWorks, MethodSet, ML Query, MobiCATS, My AvantGo, My AvantGo Media Channel, My AvantGo Mobile Marketing, MySupport, Net-Gateway, Net-Library, New Era of Networks, Next Generation Learning, Next Generation Learning Studio, O DEVICE, OASiS, OASiS logo, 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++, Orchestration Studio, Partnerships that Work, PB-Gen, PC APT Execute, PC DB-Net, PC Net Library, PhysicalArchitect, Pocket PowerBuilder, PocketBuilder, Power Through Knowledge, power.stop, Power++, 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, QAnywhere, Rapport, Relational Beans, RepConnector, Replication Agent, Replication Driver, Replication Server, Replication Server Manager, Replication Toolkit, Report Workbench, Report-Execute, Resource Manager, RW-DisplayLib, RW-Library, 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 (logo), 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, TotalFix, TradeForce, Transact-SQL, Translation Toolkit, Turning Imagination Into Reality, UltraLite, UltraLite.NET, UNIBOM, Unilib, Uninull, Unisep, Unistring, URK Runtime Kit for UniCode, Versacore, Viewer, 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, and XP Server are trademarks of Sybase, Inc. or its subsidiaries.

Certicom, MobileTrust, and SSL Plus are trademarks and Security Builder is a registered trademark of Certicom Corp. Copyright © 1997–2001 Certicom Corp. Portions are Copyright © 1997–1998, Consensus Development Corporation, a wholly owned subsidiary of Certicom Corp. All rights reserved. Contains an implementation of NR signatures, licensed under U.S. patent 5,600,725. Protected by U.S. patents 5,787,028; 4,745,568; 5,761,305. Patents pending.

All other trademarks are property of their respective owners.


About This Manual

Subject

This manual describes MobiLink, a session-based relational-database synchronization system. MobiLink technology allows two-way replication and is well suited to mobile computing environments.

Audience

This manual is for users of Adaptive Server Anywhere and other relational database systems who wish to add synchronization or replication to their information systems.

Before you begin

For a comparison of MobiLink with other synchronization and replication technologies, see Introducing Replication Technologies.


Introducing MobiLink Synchronization

About this chapter

This chapter introduces you to MobiLink synchronization technology. It describes the purpose and characteristics of MobiLink.

For information about MobiLink clients, see Introducing MobiLink Clients.

For a more detailed introduction to MobiLink technology, see Synchronization Basics.

The MobiLink synchronization process


The MobiLink synchronization process

MobiLink is a session-based synchronization system that allows two-way synchronization between a main database, called the consolidated database, and many remote databases. The consolidated database, which can be one of several ODBC-compliant databases, holds the master copy of all the data. Remote databases can be either Adaptive Server Anywhere or UltraLite databases.

Synchronization typically begins when a MobiLink remote site opens a connection to a MobiLink synchronization server. During synchronization, the MobiLink client at the remote site uploads database changes that were made to the remote database since the previous synchronization. On receiving this data, the MobiLink synchronization server updates the consolidated database, and then downloads changes on the consolidated database to the remote database.

MobiLink features


MobiLink features

MobiLink synchronization is adaptable and flexible. Following are some of its key features:

  • Data coordination MobiLink allows you to choose selected portions of the data for synchronization. MobiLink synchronization also allows you to resolve conflicts between changes made in different databases. The synchronization process is controlled by synchronization logic, which can be written as a SQL, Java, or .NET application. Each piece of logic is called a script. With scripts, for example, you can specify how uploaded data is applied to the consolidated, specify what gets downloaded, and handle different schema and names between the consolidated and remote databases.

  • Automation MobiLink has a number of automated capabilities. The MobiLink synchronization server can be instructed to generate scripts suitable for snapshot synchronization, or instructed to generate example synchronization scripts. It can also automatically add users for authentication. Server-initiated synchronization allows you to push data updates to remote databases.

  • Monitoring and reporting MobiLink provides two mechanisms for monitoring your synchronizations: the MobiLink Monitor, and statistical scripts. You can monitor scripts, schema contents, row-count values, script names, translated script contents, and row values.

  • Performance tuning There are a number of mechanisms for tuning MobiLink performance. For example, you can adjust the degree of contention, upload cache size, number of database connections, number of worker threads, logging verbosity, or BLOB cache size.

  • Two-way synchronization Changes to a database can be made at any location.

  • Upload-only or download-only synchronization You can choose to perform only an upload or only a download.

  • File-based download Downloads can be distributed as files, enabling offline distribution of synchronization changes. This allows you to create a file once and distribute it widely.

  • Server-initiated synchronization You can initiate MobiLink synchronization from the consolidated database. This means you can push data updates to remote databases, as well as cause remote databases to upload data to the consolidated database.

  • Choice of communication streams Synchronization can be carried out over TCP/IP, HTTP, or HTTPS. Palm devices can synchronize through HotSync. Windows CE devices can synchronize using ActiveSync.

  • Remote-initiated Synchronization between a remote database and a consolidated database can be initiated at the remote database.

  • Session-based All changes can be uploaded in a single transaction and downloaded in a single transaction. At the end of each successful synchronization, the consolidated and remote databases are consistent.

  • Transactional integrity Either a whole transaction is synchronized, or none of it is synchronized. This ensures transactional integrity for each database.

  • Data consistency MobiLink operates using a loose consistency policy. All changes are synchronized with each site over time in a consistent manner, but different sites may have different copies of data at any instant.

  • Wide variety of hardware and software platforms A variety of widely-used database management systems can be used as a MobiLink consolidated database: Adaptive Server Anywhere, Adaptive Server Enterprise, Oracle, Microsoft SQL Server, or IBM DB2. Remote databases can be Adaptive Server Anywhere or UltraLite databases. The MobiLink synchronization server runs on Windows or UNIX platforms. Adaptive Server Anywhere runs on Windows, Windows CE, or UNIX machines. UltraLite runs on Palm, Windows CE, or Java-based devices.

  • Flexibility The MobiLink synchronization server uses SQL, Java, or .NET scripts to control the upload and download of data. The scripts are executed according to an event model during each synchronization. Event-based scripting provides great flexibility in the design of the synchronization process, including such features as conflict resolution, error reporting, and user authentication.

  • Scalability and performance MobiLink synchronization is scalable: a single server can handle thousands of simultaneous synchronizations, and multiple MobiLink servers can be run simultaneously using load balancing. The MobiLink synchronization server is multi-threaded and uses connection pooling with the consolidated database. MobiLink provides extensive monitoring and reporting facilities.

  • Easy to get started Simple MobiLink installations can be constructed quickly. More complex refinements can be added incrementally for full-scale production work.


Synchronization Basics

About this chapter

This chapter introduces the basic components of MobiLink technology and provides information about how to set up your synchronization system.

Parts of the synchronization system
Consolidated database
The MobiLink synchronization server
MobiLink clients
The synchronization process
Upload-only and download-only synchronization
Options for writing synchronization logic
Security


Parts of the synchronization system

The following diagram shows the major parts of the synchronization system.

The MobiLink architecture, showing the consolidated database store, the consolidated server, an ODBC connection, the MobiLink synchronization server, the network, and MobiLink clients.

  • consolidated database This database contains the central copy of all information in the synchronization system.

    For more information, see Consolidated database.

  • consolidated database server The server, or DBMS, that manages the consolidated database. This server can be a Sybase product, such as Adaptive Server Anywhere or Adaptive Server Enterprise, or it may be a supported system made by another company.

    For more information, see MobiLink Consolidated Databases.

  • ODBC connection All communication between the MobiLink synchronization server and the consolidated database occurs through an ODBC connection. ODBC allows the synchronization server to utilize a variety of consolidated database systems.

    For more information, see iAnywhere Solutions ODBC Drivers.

  • MobiLink synchronization server This server manages the synchronization process and provides the interface between all MobiLink clients and the consolidated database server.

    For more information, see The MobiLink synchronization server.

  • Network The connection between the MobiLink synchronization server, dbmlsrv9, and the MobiLink client, dbmlsync or UltraLite, can use a number of protocols.

    For more information about connecting to dbmlsync, see -x option. For information about connecting to UltraLite, see Network protocol options for UltraLite synchronization clients.

  • MobiLink client The client can be installed on a handheld device such as a Palm Pilot or PocketPC, a server or desktop computer, or an embedded device such as a cell phone or vending machine. Two types of clients are supported: UltraLite and Adaptive Server Anywhere databases. Either or both may be used in a single MobiLink installation.

    For more information, see MobiLink clients.


Consolidated database

Applications synchronize with a central, consolidated database. This database is the master repository of information in the synchronization system.

There are many ways to structure the relations between consolidated and remote databases. Following are two examples.

The schema of the remote databases can be a subset of the schema of the consolidated database. For example, a table called emp might be repeated among a number of different remote sites, and the consolidated database might use column data from emp.salary in a table called expense. In this instance, the schemas of the consolidated and remote databases are different, though data is shared.

The schema of the remote database can also be parallel in structure to the schema of the consolidated database. Here, the schema of the consolidated database is a reference for the remote database. In the consolidated database, you may already have tables that correspond to each of the remote tables. In this instance, the schemas in the consolidated and remote databases are virtually the same, and the data in the remote is only a subset of the data on the consolidated.

You write synchronization scripts for each table in the remote database and you save these scripts on the consolidated database. These scripts, from their central location on the consolidated database, direct the synchronization server in moving data between remote and consolidated databases. One script for a particular remote table tells the synchronization server where to store data uploaded from that remote table in the consolidated database. Another script tells the synchronization server which data to download to the same remote table.

For more information about consolidated databases, see MobiLink Consolidated Databases.


The MobiLink synchronization server

All MobiLink clients synchronize through the MobiLink synchronization server. None connect directly to a database server. You must start the MobiLink synchronization server before asking a MobiLink client to synchronize.


Running the MobiLink synchronization server

The MobiLink synchronization server opens connections, via ODBC, with your consolidated database server. It then accepts connections from remote applications and controls the synchronization process.

toggle To start the MobiLink synchronization server

  • Run dbmlsrv9. Use the –c option to specify the ODBC connection parameters for your consolidated database.

For information about connection parameters, see -c option.

You must specify connection parameters. Other options are available, but are optional. These options allow you to specify how the server works. For example, you can specify a maximum number of worker threads, cache size, and logging options.

For more information about dbmlsrv9 options, see MobiLink Synchronization Server Options.

Note: The dbmlsrv9 options allow you to specify how the MobiLink synchronization server works. To control what the server does, you define scripts that are invoked at synchronization events.

For more information, see MobiLink events.

Example

The following command starts the MobiLink synchronization server, identifying the ODBC data source UltraLite 9.0 Sample as the consolidated database. Enter the entire command on one line.

dbmlsrv9
  -c "dsn=UltraLite 9.0 Sample;uid=DBA;pwd=SQL"
  -zs MyServer
  –o mlsrv.log
  -vcr
  -x tcpip

In this example, the -zs option provides a server name. The –o option specifies that the log file should be named mlsrv.log. The contents of mlsrv.log are verbose because of the –vcr option. The –x option specifies that MobiLink clients will be permitted to connect via TCP/IP.

You can also start the MobiLink synchronization server as a Windows service or UNIX daemon. For more information, see Running MobiLink Outside the Current Session.


Stopping the MobiLink synchronization server

The MobiLink synchronization server can be stopped from the computer where the server was started. You can stop the MobiLink server in the following ways:

  • Click Shutdown on the MobiLink server window.

  • Use Exit from the System tray context menu.

  • Use the dbmlstop utility.

    For more information, see MobiLink stop utility.


Logging MobiLink synchronization server actions

Logging the actions that the server takes is particularly useful during the development process, and when troubleshooting. Verbose output is not recommended for normal operation of a production environment because it can slow performance.

Logging output to a file

Logging output is sent to the MobiLink synchronization server window. In addition, you can send the output to a log file using the -o option. The following command sends output to a log file named mlsrv.log.

dbmlsrv9 -o mlsrv.log -c ...

For more information, see -o option.

Controlling the size of log files

You can control the size of log files, and specify what you want done when a file reaches its maximum size.

  • With the -on option, you specify the size at which the log file is renamed with the extension .old, and a new file is started with the original name.

  • With the -os option, you specify the size at which a new log file is started with a new name based on the date and a sequential number.

  • With the -ot option, the contents of the log file are deleted before messages are sent to it.

For more information, see

  • -on option

  • -os option

  • -ot option

Controlling the amount of logging output

You can control the amount of output that is logged using the -v option.

For more information, see -v option.

Controlling which errors are reported

You can also control which warning messages are reported.

For more information, see

  • -zw option

  • -zwd option

  • -zwe option


MobiLink clients

Each remote database, together with its applications, is referred to as a MobiLink client. Two types of MobiLink client are supported:

  • Adaptive Server Anywhere

  • UltraLite

For more information, see Introducing MobiLink Clients.


The synchronization process

A synchronization is the process of bidirectional data exchange between the MobiLink client and synchronization server. During this process, the client must establish and maintain a connection to the synchronization server. If successful, the session leaves the remote and consolidated databases in a mutually consistent state.

The client normally initiates the synchronization process. It begins by establishing a connection to the MobiLink synchronization server.

The upload stream and the download stream

To upload rows, MobiLink clients prepare and send an upload stream that contains a list of all the rows that have been updated, inserted, or deleted on the MobiLink client since the last synchronization. Similarly, to download rows, the MobiLink synchronization server prepares and sends a download stream that contains a list of inserts, updates, and deletes.

  1. Upload stream The MobiLink client automatically keeps track of which rows in the remote database have been inserted, updated, or deleted since the previous successful synchronization. Once the connection is established, the MobiLink client uploads a list of all these changes to the synchronization server.

    The upload stream consists of a set of new and old row values for each row modified in the remote database. If a row has been updated or deleted, the old values are those that were present immediately following the last successful synchronization. If a row has been inserted or updated, the new values are the current row values. No intermediate values are sent, even if the row was modified several times before arriving at its current state.

    The MobiLink synchronization server receives the upload stream and applies the changes to the consolidated database. It normally applies all the changes in a single transaction. When it has finished, the MobiLink synchronization server commits the transaction.

    Note
    MobiLink operates using the ODBC isolation level SQL_TXN_READ_COMMITTED as the default isolation level for the consolidated database. MobiLink does so because repeatable reads are required for conflict detection purposes. If you have no conflict detection scripts or if you want to select an isolation level more suited to your needs, you can set this level in your begin_connection script.

  2. Download stream The MobiLink synchronization server compiles a list of rows to be inserted, updated, or deleted on the MobiLink client, using synchronization logic that you create. It downloads these rows to the MobiLink client. To compile this list, the MobiLink synchronization server opens a new transaction on the consolidated database.

    The MobiLink client receives the download stream. It takes the arrival of this stream as confirmation that the consolidated database has successfully applied all uploaded changes. It will then ensure these changes are not sent to the consolidated database again.

    Next, the MobiLink client automatically processes the download stream, deleting old rows, inserting new rows, and updating rows that have changed. It applies all these changes in a single transaction in the remote database. When finished, it commits the transaction.

  3. Optional download acknowledgement The MobiLink client optionally sends a short confirmation message to the MobiLink synchronization server.

    The MobiLink synchronization server receives the confirmation message. This message tells the synchronization server that the client has received and processed all downloaded changes. In response, it commits the download transaction begun in step 2.

    For more information about the SendDownloadAck extended option, see SendDownloadACK (sa) extended option and Send Download Acknowledgement synchronization parameter.

During MobiLink synchronization, there are few distinct exchanges of information. The client builds and uploads the entire upload stream. In response, the synchronization server builds and downloads the entire download stream. Limiting the chattiness of the protocol is especially important when communication is slower and has higher latency, as is the case when using telephone lines or public wireless networks.

MobiLink events
Stored procedures
Transactions in the synchronization process
How synchronization failure is handled
How the upload stream is processed
Referential integrity and synchronization


MobiLink events

When the MobiLink client initiates a synchronization, a number of synchronization events occur. At the occurrence of an event, MobiLink looks for a script to match the synchronization event. This script contains your instructions outlining what you want done. The basic sequence is:

Event occurs > Script is invoked (if it exists)

For more information about synchronization events and scripts, see:

  • Synchronization Events

  • Writing Synchronization Scripts

MobiLink scripts


MobiLink scripts

Whenever an event occurs, the MobiLink synchronization server executes the associated script if you have created one. If no script exists, the next event in the sequence occurs.

Following are some typical synchronization scripts for tables.

Event Script
upload_insert
INSERT INTO
emp (emp_id,emp_name)
VALUES (?,?)
upload_delete
DELETE FROM emp
WHERE emp_id=?
upload_update
UPDATE emp
SET emp_name=?
WHERE emp_id=?
upload_old_row_insert
INSERT INTO old_emp
(emp_id,emp_name)
VALUES (?,?)
upload_new_row_insert
INSERT INTO new_emp
(emp_id,emp_name)
VALUES (?,?)
upload_fetch
SELECT id, name, size, quantity, unit_price
FROM Product WHERE id=?

The first event, upload_insert, triggers the running of the upload_insert script, which inserts the emp_id and emp_name into the emp table. In like fashion, the upload_delete and upload_update tables will perform similar functions for delete and update actions on the same emp table.

The download script uses a cursor. Following is an example of a download_cursor script:

SELECT emp_id, emp_name
   FROM emp
   WHERE emp_name = ?

The download_cursor acquires data from the emp table for a specified emp_name.

COMMIT or ROLLBACK statements within scripts alter the transactional nature of the synchronization steps. If you use them, you cannot guarantee the integrity of your data in the event of a failure. There should be no implicit or explicit commit or rollback in your synchronization scripts or the procedures or triggers that are called from your synchronization scripts.

Scripts can be written in SQL, Java, or .NET

You can write scripts using the native SQL dialect of your consolidated database, or using Java or .NET synchronization logic. Java and .NET synchronization logic allow you to write code, invoked by the MobiLink synchronization server, to connect to a database, manipulate variables, and create user-defined procedures that can work with MobiLink and any supported relational database. There is a MobiLink Java API and a MobiLink .NET API that have routines to suit the needs of synchronization.

For more information about programming synchronization logic, see Options for writing synchronization logic.

For information about DBMS-dependent scripting, such as scripting for Oracle, MS SQL Server, IBM DB2 or Adaptive Server Enterprise databases, see DBMS-dependent synchronization scripts.

Storing scripts

SQL scripts are stored in system tables in the consolidated database. For Java and .NET, pointers to other locations are stored in the consolidated database. You can add all kinds of scripts to a consolidated database in two ways:

  • By using stored procedures that are installed along with the MobiLink system tables when you create a consolidated database.

  • By using Sybase Central.

For more information, see Adding and deleting scripts in your consolidated database.


Stored procedures

MobiLink stored procedures are used for programmatic conflict resolution, adding scripts, user authentication, and other customization procedures.

For more information about using MobiLink stored procedures for customization, see Stored Procedures.

Other means to gain procedural control are commonly used with databases that don't have a defined procedural language. For example, with databases that do not permit user-defined procedures, such as IBM's DB2, Java procedures may be employed to act as MobiLink stored procedures.

For more information about writing scripts using Java or .NET synchronization logic, see Writing Synchronization Scripts in Java and Writing Synchronization Scripts in .NET.

For Adaptive Server Anywhere clients, you can use stored procedures called client event hook procedures, which are held on the remote database. A variety of event hook procedures are available for you to insert your own logic into the MobiLink synchronization process.

For more information, see Dbmlsync Client Event Hooks.


Transactions in the synchronization process

The MobiLink synchronization server incorporates changes uploaded from each MobiLink client into the consolidated database in one transaction. The MobiLink synchronization server commits these changes once it has completed inserting new rows, deleting old rows, making updates, and resolving any conflicts.

The MobiLink synchronization server prepares the download stream, including all deletes, inserts, and updates, using another transaction. Depending on the SendDownloadAck setting, it does not commit this transaction until it receives a positive confirmation from the MobiLink client. If the client confirms a successful download, the MobiLink synchronization server commits the download transaction. If the application encounters problems or cannot reply, the MobiLink synchronization server instead rolls back the download transaction.

Do not commit or roll back transactions within a script
COMMIT or ROLLBACK statements within scripts alter the transactional nature of the synchronization steps. If you use them, you cannot guarantee the integrity of your data in the event of a failure. There should be no implicit or explicit commit or rollback in your synchronization scripts or the procedures or triggers that are called from your synchronization scripts.
Tracking downloaded information

The primary role of the download transaction is to select rows in the consolidated database. If the download fails being sent to the remote, the remote will upload the same timestamp over again, and no data will be lost.

The MobiLink synchronization server uses two other transactions, one at the beginning of synchronization, and one at the end. These transactions allow you to record information regarding each synchronization and its duration. Thus, you can record statistics about attempted synchronizations, successful synchronizations, and the duration of synchronizations. Since data is committed at various points in the process, these transactions also let you commit data useful when analyzing failed synchronization attempts.

Similarly, the MobiLink client processes information in the download stream in one transaction. Rows are inserted, updated, and deleted to bring the remote database up to date with the consolidated data.


How synchronization failure is handled

MobiLink synchronization is fault tolerant. For example, if a communication link fails during synchronization, both the remote database and the consolidated database are left in a consistent state.

On the client, failure is indicated by a return code. For example, in an embedded SQL UltraLite application, the SQLCode is set to SQLE_COMMUNICATION_ERROR when ULSynchronize returns.

There are three cases that are handled in different ways:

  • Failure during upload If the failure occurs while building or applying the upload stream, the remote database is left in exactly the same state as at the start of synchronization. At the server, any part of the upload stream that has been applied will be rolled back.

  • Failure between upload and download If the failure occurs once the upload stream is complete, but before the MobiLink client receives the download stream, the client cannot be certain whether the uploaded changes were successfully applied to the consolidated database. The upload stream might be fully applied and committed, or the failure may have occurred before the server applied the entire upload stream. The MobiLink synchronization server automatically rolls back incomplete transactions in the consolidated database.

    The MobiLink client maintains a record of all uploaded changes in case they must be sent again. The next time the client synchronizes, it requests the state of the previous upload stream before building the new upload stream. If the previous upload was not committed, the new upload stream contains all changes from the previous upload stream.

  • Failure during download If the failure occurs in the remote device while applying the download stream, any part of the download that has been applied is rolled back and the remote database is left in the same state as before the download. The MobiLink synchronization server automatically rolls back the download transaction in the consolidated database.

In all cases where failure may occur, no data is lost. The MobiLink server and the MobiLink client manage this for you. The developer/user need not worry about maintaining consistent data in their application.


How the upload stream is processed

When the MobiLink synchronization server receives an upload stream from a MobiLink client, the entire upload stream is stored until the synchronization is complete. This is done for three purposes.

  • Deadlock When an upload stream is being applied to the consolidated database, it may encounter deadlock due to concurrency with other transactions. These transactions might be upload transactions from other MobiLink synchronization server database connections, or transactions from other applications using the consolidated database. When an upload transaction is deadlocked, it is rolled back and the MobiLink synchronization server automatically starts applying the upload stream from the beginning again.

    Performance tip
    It is important to write your synchronization scripts to avoid contention as much as possible. Contention has a significant impact on performance when multiple users are synchronizing simultaneously.

  • Filtering download rows The most common technique for determining rows to download is to download rows that have been modified since the previous download. When synchronizing, the upload precedes the download. Any rows inserted or updated during the upload will be rows that have been modified since the previous download.

    It would be difficult to write a download_cursor script that omits from the download stream rows that were sent as part of the upload. For this reason, the MobiLink synchronization server automatically removes these rows from the download stream. When a row is being added to the download stream, the MobiLink synchronization server locates the row in the upload stream and omits the row from the download stream when it is found to be the same.

  • Processing deletes after inserts and updates The upload stream is applied to the consolidated database in an order that avoids referential integrity violations. The upload stream is formatted so all operations (inserts, updates, and deletes) for a single table are grouped together. The tables in the upload stream are ordered based on foreign key relationships. All tables in the remote database that are referenced by another table in the remote database will be in the upload stream before the referencing table.

    For example, if table A and table C both have foreign keys that reference a primary key column in B, then table B rows are uploaded first.

    When the upload stream is applied to the consolidated database, the inserts and updates are applied in the order they appear in the upload stream. When an inserted or updated row references a newly inserted row, this ensures the referenced row will be inserted before the referencing row. Deletes are applied in the opposite order after all inserts and updates have been applied. When a row being deleted references another row that is also being deleted, this order of operations ensures the referencing row is deleted before the referenced row is deleted.


Referential integrity and synchronization

All MobiLink clients enforce referential integrity when they incorporate the download stream into the remote database.

Rather than failing the download transaction, the MobiLink client automatically deletes all rows that violate referential integrity.

This feature affords you these key benefits.

  • Protection from mistakes in your synchronization scripts. Given the flexibility of the scripts, it is possible to accidentally download rows that would break the integrity of the remote database. The MobiLink client automatically maintains referential integrity without requiring intervention.

  • You can use this referential integrity mechanism to delete information from a remote database efficiently. By only sending a delete to a parent record, the MobiLink client will remove all the child records automatically for you. This can greatly reduce the amount of traffic MobiLink must send to the remote database.

MobiLink clients provide notification if they have to explicitly delete rows to maintain referential integrity.

  • For Adaptive Server Anywhere clients, dbmlsync writes an entry in a log.

  • For UltraLite clients, a warning SQLE_ROW_DELETED_TO_MAINTAIN_REFERENTIAL_INTEGRITY is raised. This warning takes a parameter, which is the table name. The warning is raised on every row that is deleted to maintain referential integrity. Your application can ignore the warnings if you wish synchronization to just proceed. If you wish to explicitly handle the warnings, you can use the error callback function to trap them and, for example, count the number of rows deleted.

    If you wish to fail synchronization when the warning is raised, you must implement a synchronization observer and then signal the observer (perhaps through a global variable) from the error callback function to fail the synchronization on the next call to the observer.

Referential integrity checked at the end of the transaction

The MobiLink client incorporates changes from the download stream in a single transaction. To offer more flexibility, referential integrity checking occurs at the end of this transaction. Because checking is delayed, the database may temporarily pass through states where referential integrity is violated as rows are inserted, updated, and deleted, but the rows that violate referential integrity are automatically removed before the download is committed.

Errors are avoided

The MobiLink client resolves referential integrity violations automatically. This feature minimizes administration requirements. It also prevents an error in a synchronization script from disabling an MobiLink client. UltraLite clients raise a warning when a row is deleted to maintian referential integrity, which your application can handle or ignore.

An efficient way to delete rows

You can exploit the automatic referential integrity mechanism of MobiLink clients to delete large quantities of information in a very efficient manner. If your MobiLink client contains a primary row, and other rows that reference it, you can delete all the referencing rows simply by synchronizing a delete of the primary row.

Example

Suppose that an UltraLite sales application contains, among others, the following two tables. One table contains sales orders. Another table contains items that were sold in each order. They have the following relationship.

An entity diagram showing UltraLite tables for sales_order and sales_order_items.

If you use the download_delete_cursor for the sales_order table to delete an order, the automatic referential integrity mechanism automatically deletes all rows in the sales_order_items table that point to the deleted sales order.

This arrangement has the following advantages.

  • You do not require a sales_order_items script because rows from this table will be deleted automatically.

  • The efficiency of synchronization is improved. You need not download rows to delete from the sales_order_item table. If each sales order contains many items, the performance improves because the download stream is now smaller. This technique is particularly valuable when using slow communication methods.


Upload-only and download-only synchronization

For both Adaptive Server Anywhere and UltraLite remote databases, you can choose to do a full synchronization, or you can perform only an upload or download.

Adaptive Server Anywhere remote databases

In Adaptive Server Anywhere remote databases, you perform upload-only synchronization using the dbmlsync option -ds or the extended option DownloadOnly.

For more information, see -ds option and DownloadOnly (ds) extended option.

In Adaptive Server Anywhere remote databases, you perform download-only synchronization using the dbmlsync option -uo or the extended option UploadOnly.

For more information, see -uo option or UploadOnly (uo) extended option.

UltraLite remote databases

In UltraLite remote databases, you perform download-only synchronization using the Download Only synchronization parameter.

For more information, see Download Only synchronization parameter.

In UltraLite remote databases, you perform upload-only synchronization using the Upload Only synchronization parameter.

For more information, see Upload Only synchronization parameter.


Options for writing synchronization logic

MobiLink synchronization scripts can be written in SQL, in Java, or in .NET programming languages. Java or .NET are a good choice whenever your design is restricted by the limitations of the SQL language or by the capabilities of your database-management system, of if you want DBMS-independent synchronization logic.

Program synchronization logic can function just as SQL logic functions, as shown in the figure below. The MobiLink synchronization server can make calls to Java or .NET methods on the occurrence of MobiLink events just as it can access SQL scripts on the occurrence of MobiLink events. However, the upload and download streams are not directly accessible from Java or .NET synchronization logic, where a SQL string must be returned to MobiLink.

Java synchronization logic architecture.

SQL synchronization logic is restricted to the procedural language capabilities of your consolidated database. SQL languages are unlikely to offer all the programming logic given by Java or .NET programming languages. You might want to use Java or .NET synchronization logic when your SQL logic is limited, when you need to perform operations across database platforms, and when you need portability across RDBMSs and operating systems. Following are some scenarios where you might want to consider writing scripts in Java or .NET.

  • A user authentication procedure can be written in Java or .NET that inserts the user ID of a MobiLink user into a table on the consolidated database for audit purposes.

  • If your database lacks the ability to handle variables, you can create a variable in Java or .NET that persists throughout your connection or synchronization.

  • If your database lacks the ability to make user-defined stored procedures, you can make a method in Java or .NET that can perform the needed functionality.

  • If your program calls for contacting an external server midway through a synchronization event, you can use Java or .NET synchronization logic to perform actions triggered by synchronization events. Java and .NET synchronization logic can be shared across multiple connections.

  • With Java and .NET synchronization logic, you can use MobiLink to access data from application servers, Web servers, and files. You can use JDBC or iAnywhere classes in your synchronization logic to access data in relational databases other than the consolidated database. For example, an external server can be used to validate a user ID and password. The figure below shows the links between Java or .NET synchronization logic and both a consolidated database and a second data server.

Using Java synchronization logic to access other data sources.
MobiLink APIs

With Java and .NET synchronization logic, you have access to a MobiLink API. The MobiLink APIs are sets of classes and interfaces for MobiLink synchronization. There are two MobiLink APIs: Java and .NET.

The MobiLink Java API offers you:

  • Access to the existing ODBC connection as a JDBC connection.

  • The ability to create new JDBC connections to perform commits or connects outside the current synchronization connection. For example, you can use this for error logging.

  • The ability to write and debug Java code before it is executed by the MobiLink server. SQL development environments for many database management systems are relatively primitive compared to those available for Java applications.

  • Code that runs inside the Java virtual machine and allows access to all Java libraries and Java Native Interface calls.

For more information, see MobiLink Java API Reference.

The MobiLink .NET API offers you:

  • Access to the existing ODBC connection using iAnywhere classes that call ODBC from .NET.

  • Code that runs inside the .NET Common Language Runtime (CLR) and allows access to all .NET libraries and unmanaged calls.

For more information, see MobiLink .NET API Reference.

Further reading

For more information about your options for writing synchronization scripts, see

  • Writing Synchronization Scripts

  • Synchronization Techniques

  • Writing Synchronization Scripts in Java

  • Writing Synchronization Scripts in .NET


Security

There are several aspects to securing data throughout a widely distributed system such as a MobiLink installation:

  • Protecting data in the consolidated database Data in the consolidated database can be protected using the DBMS user authentication system and other security features.

    For more information, see your DBMS documentation. If you are using an Adaptive Server Anywhere consolidated database, see Keeping Your Data Secure.

  • Protecting data in the remote databases If you are using Adaptive Server Anywhere remote databases, the data can be protected using Adaptive Server Anywhere security features. By default, these are designed to prevent unauthorized access through client/server communications, but not to be proof against a serious attempt to extract information directly from the database file.

    Files on the client are protected by the security features of the client operating system.

    If you are using an Adaptive Server Anywhere remote database, see Keeping Your Data Secure.

  • Protecting data during synchronization Communication from MobiLink clients to MobiLink synchronization servers can be protected by the MobiLink transport layer security features.

    For more information, see MobiLink Transport-Layer Security.

  • Protecting the synchronization system from unauthorized users MobiLink synchronization can be secured by a password-based user authentication system. This mechanism prevents unauthorized users from synchronizing data.

    For more information, see Authenticating MobiLink Users.


MobiLink Consolidated Databases

About this chapter

This chapter describes how to set up and use your consolidated database.

Introduction
Setting up a consolidated database
DBMS-dependent synchronization scripts
Adaptive Server Anywhere consolidated database
Sybase Adaptive Server Enterprise consolidated database
Oracle consolidated database
IBM DB2 consolidated database
Microsoft SQL Server consolidated database


Introduction

Your consolidated database can be one of the following ODBC-compliant databases: Adaptive Server Anywhere, Adaptive Server Enterprise, Oracle, IBM DB2, and Microsoft SQL Server. You can use synchronization scripts to exploit the features of your particular consolidated server.

Synchronization scripts are associated with the consolidated database. SQL scripts are stored in the consolidated database, and Java and .NET scripts are referenced.

For information about setting up each type of database as a consolidated database, see Setting up a consolidated database.

For information about writing synchronization scripts for particular consolidated databases, see DBMS-dependent synchronization scripts.

How remote tables relate to consolidated tables


How remote tables relate to consolidated tables

Synchronization designs can specify mappings between tables and rows in the remote database with tables and rows in the consolidated database.

Arbitrary relationships permitted

Tables in a remote database need not be identical to those in the consolidated database. Synchronized data in one remote application table can be distributed between columns in different tables, and even between tables in different consolidated databases. You specify these relationships using synchronization scripts.

Direct relationships are simple

You can often simplify your design using a table structure in the remote database that is a subset of that in the consolidated database. Using this method, every table in the remote database exists in the consolidated database. Corresponding tables have the same structure and foreign key relationships as those in the consolidated database.

Tables in the consolidated database will frequently contain extra columns that are not synchronized. Indeed, extra columns can aid synchronization. For example, a timestamp column can identify new or updated rows in the consolidated database. In other cases, extra columns or tables in the consolidated database may hold information that is not required at remote sites.


Setting up a consolidated database

Setup scripts

To set up a database so that it can be used as a MobiLink consolidated database, you must run a setup script that installs MobiLink system tables and stored procedures. The exception is Adaptive Server Anywhere databases, which are preconfigured with the appropriate system tables and stored procedures. For instructions on how to run the setup scripts, see the sections below for each supported RDBMS.

For more information about MobiLink system tables, see MobiLink System Tables.

For more information about stored procedures, see Stored Procedures.

ODBC connection

In addition, the MobiLink synchronization server needs an ODBC connection to your consolidated database. You must configure the appropriate ODBC driver for your server and create an ODBC data source for the database on the computer where your MobiLink synchronization server is running.

For a summary of supported ODBC drivers, see iAnywhere Solutions ODBC Drivers.

For updated information and complete functional specifications, see [external link] http://www.ianywhere.com/developer/technotes/odbc_mobilink.html.

For information about configuring ODBC drivers for MobiLink consolidated databases, see Introduction to iAnywhere Solutions ODBC Drivers.

For specific information about each type of consolidated database, see the appropriate section:

  • Adaptive Server Anywhere consolidated database
  • Sybase Adaptive Server Enterprise consolidated database
  • Oracle consolidated database
  • IBM DB2 consolidated database
  • Microsoft SQL Server consolidated database


DBMS-dependent synchronization scripts

MobiLink uses synchronization scripts to provide flexibility in the rules you use to synchronize data. The scripts define:

  • How data uploaded from the remote database is to be applied to the consolidated database.

  • What data should be downloaded from the consolidated database.

For more information about writing synchronization scripts, see Writing Synchronization Scripts.

For a complete list of events you can write scripts for, see Synchronization Events.

Some aspects of scripts depend on the DBMS you are using. A number of factors determine the kind of scripting needed for your synchronization with your ODBC compliant database, and these factors include, but are not limited to:

  • User defined procedures

  • Session-wide connection variables

    Session-wide variables provide a useful means to store values persisting through a synchronization. For example, in the begin_synchronization script store the user name into a session-wide variable variable called UserName. In subsequent scripts, refer to UserName as many times as you want.

  • Autoincrement methods

    If supported, you can use autoincrement to maintain unique primary key values in a MobiLink environment. For more information, see Maintaining unique primary keys.

For specific information about each type of consolidated database, see the appropriate section:

  • Adaptive Server Anywhere consolidated database

  • Sybase Adaptive Server Enterprise consolidated database

  • Oracle consolidated database

  • IBM DB2 consolidated database

  • Microsoft SQL Server consolidated database

.NET and Java synchronization scripts

One strategy for using MobiLink with supported databases is to write your table scripts and synchronization logic in the DBMS version of the SQL language. Another strategy for using MobiLink with any supported consolidated database uses Java or .NET synchronization logic. When you use Java or .NET synchronization logic you can hold session-wide variables and create user-defined procedures.

For information about Java synchronization logic, see Writing Java synchronization logic.

For information about .NET synchronization logic, see Writing Synchronization Scripts in .NET.

Invoking procedures from scripts

Some databases, such as Microsoft SQL Server, require that procedure calls with parameters be written using the ODBC syntax.

{ CALL procedure_name( ?, ?, ... ) }

You can pass return values by defining the parameters as OUT or INOUT in the procedure definition.

CHAR columns

In many other DBMSs, CHAR data types are fixed length and blank-padded to the full length of the string. In MobiLink remote databases (Adaptive Server Anywhere or UltraLite) CHAR is the same as VARCHAR: values are not blank-padded to a fixed width. The dbmlsrv9 -b command line option can be used to remove trailing blanks from strings during synchronization. This option is important for string comparisons used to detect conflicts.

For more information, see -b option.

Data conversion

For information about the conversion of data that must take place when a MobiLink synchronization server communicates with a consolidated database that was not made with Adaptive Server Anywhere, see DataType Conversions.


Adaptive Server Anywhere consolidated database

Adaptive Server Anywhere databases are automatically configured so that they can be used as a MobiLink consolidated database without running a setup script.

A setup script is provided for Adaptive Server Anywhere databases in case you want to examine source code. For example, it includes source code for the ml_add_connection_script stored procedure. This setup script is called syncasa.sql and it is located in the scripts subdirectory of your SQL Anywhere installation.

Setting up the ODBC driver

You must set up an ODBC DSN for your Adaptive Server Anywhere consolidated database. The ODBC driver for Adaptive Server Anywhere is installed with SQL Anywhere Studio.

For information about the Adaptive Server Anywhere ODBC driver, see Working with ODBC data sources.


Sybase Adaptive Server Enterprise consolidated database

To set up Adaptive Server Enterprise version 12.5 or later to work as a MobiLink consolidated database, run the syncase125.sql setup script, located in the MobiLink\setup subdirectory of your SQL Anywhere installation. For versions prior to 12.5, run syncase.sql from the same location.

To ensure that the MobiLink administrator has adequate permissions to change the MobiLink system tables (required for adding scripts and other things), the user who will need access to those tables should run the setup script.

ODBC driver

You must set up an ODBC DSN for your Adaptive Server Enterprise consolidated database. SQL Anywhere Studio includes an iAnywhere Solutions ODBC driver for Adaptive Server Enterprise. You must configure this driver to work with MobiLink.

For more information, see iAnywhere Solutions ODBC Driver for Sybase Adaptive Server Enterprise.

Adaptive Server Enterprise issues

  • Column sizes To download BLOB data from an Adaptive Server Enterprise consolidated database, you need to set an ODBC driver connection option to allow column sizes greater than 4096 bytes. To do this, use the ODBC driver connection option called StaticCursorLongColBuffLen. For example,

    dbmlsrv9 -c "...;StaticCursorLongColBuffLen=number"

    where number is in bytes, and is larger than the largest expected BLOB.

    Note that using this option consumes significantly more disk space on the computer that runs the MobiLink synchronization server.

  • Numeric primary key values In addition, the MobiLink synchronization server requires that primary key values of type numeric or decimal be explicitly converted to their types under Adaptive Server Enterprise.

    You must add an explicit conversion to the numeric parameters in the script as displayed in the following examples.

    SELECT ...
WHERE numeric_col = CONVERT( NUMERIC, ? )
...

    The above statement explicitly converts the first parameter to type NUMERIC.

    SELECT ...
WHERE decimal_col = CONVERT( DECIMAL(10,8), ? )
...

    The above statement explicitly converts the first parameter to type DECIMAL (10,8).

  • CHAR columns In Adaptive Server Enterprise, CHAR data types are fixed length and blank-padded to the full length of the string. In MobiLink remote databases (Adaptive Server Anywhere or UltraLite) CHAR is the same as VARCHAR: values are not blank-padded to a fixed width. The dbmlsrv9 -b command line option can be used to remove trailing blanks from strings during synchronization. This option is important for string comparisons used to detect conflicts.

    For more information, see -b option.

  • Data type mapping For details of how Adaptive Server Anywhere data types are mapped to Adaptive Server Enterprise data types, see Adaptive Server Enterprise data mapping.


Oracle consolidated database

To set up Oracle to work as a MobiLink consolidated database, run the syncora.sql setup script, located in the MobiLink\setup subdirectory of your SQL Anywhere installation.

To ensure that the MobiLink administrator has adequate permissions to change the MobiLink system tables (required for adding scripts and other things), the user who will need access to those tables should run the setup script.

ODBC driver

You must set up an ODBC DSN for your Oracle consolidated database. SQL Anywhere Studio includes an iAnywhere Solutions ODBC driver for Oracle. You must configure this driver to work with MobiLink.

For more information, see iAnywhere Solutions ODBC Driver for Oracle.

Oracle issues

  • Session-wide variables Oracle does not provide session-wide variables. You can store session-wide information in variables within Oracle packages. Oracle packages allow variables to be created, modified and destroyed and these variables may last as long as the Oracle package is current.

  • Autoincrement methods To maintain primary key uniqueness, you can use an Oracle sequence to generate a list of keys similar to that of an autoincrement field. The CustDB sample database provides coding examples, which can be found in Samples\MobiLink\CustDB\custora.sql. Unlike autoincrement, however, you must explicitly reference the sequence. Autoincrement inserts a column value automatically if the column is not referenced in an INSERT statement.

    For an example of using an Oracle sequence, see Tutorial: Using MobiLink with an Oracle 8i Consolidated Database.

  • CHAR columns In Oracle, CHAR data types are fixed length and blank-padded to the full length of the string. In MobiLink remote databases (Adaptive Server Anywhere or UltraLite) CHAR is the same as VARCHAR: values are not blank-padded to a fixed width. The dbmlsrv9 -b command line option can be used to remove trailing blanks from strings during synchronization. This option is important for string comparisons used to detect conflicts.

    For more information, see -b option.

  • Data type mapping For details of how Adaptive Server Anywhere data types are mapped to Oracle data types, see Oracle data mapping.


IBM DB2 consolidated database

To set up IBM DB2 UDB to work as a MobiLink consolidated database, run the syncdb2long.sql setup script, located in the MobiLink\setup subdirectory of your SQL Anywhere installation. However, prior to running the script you must complete the following steps.

To install MobiLink system tables using the setup script, an IBM DB2 tablespace must use a minimum of 8 Kb pages. If a tablespace does not use 8 Kb pages, complete the following steps.

  • Verify that at least one of your buffer pools has 8 Kb pages. If not, create a buffer pool with 8 Kb pages.

  • Create a new tablespace and temporary tablespace that use the buffer pool with 8 Kb pages. For more information, consult your DB2 documentation.

To ensure that the MobiLink administrator has adequate permissions to change the MobiLink system tables (required for adding scripts and other things), the user who will need access to those tables should run the setup script.

The syncdb2long.sql script contains a default connection statement, connect to DB2Database. You should make a copy of the script and alter this line to be appropriate for your installation. The syntax of the line must be:

connect to DB2Database user userid using password ~

where DB2Database, userid, and password are names you provide.

The syncdb2long.sql script uses the tilde character (~) as a command delimiter. You can run the scripts as follows:

db2 -c -ec -td~ +s -v -f syncdb2long.sql

In order for DB2 to use the stored procedures defined in syncdb2long.sql, you must copy the syncdb2long_version Java and class files located in the MobiLink\setup subdirectory of your SQL Anywhere installation to the FUNCTION subdirectory of your DB2 installation.

ODBC driver

To set up an ODBC DSN for your DB2 consolidated database, use the iAnywhere Solutions DB2 Wire Protocol driver.

For more information, see iAnywhere Solutions ODBC Driver for DB2.

DB2 issues

  • Tablespace capacity A tablespace and temporary tablespace of any DB2 database that you wish to use as a consolidated database must use 8 Kb pages.

    In addition, there are columns that require a LONG tablespace. If there is no default LONG tablespace, the creation statements for the tables containing these columns must be qualified appropriately, as in the following example.

    CREATE TABLE ... ( ... )
IN tablespace
LONG IN long-tablespace

    For an example using the sample application, see The CustDB Sample Application.

  • Session-wide variables Earlier versions of DB2 (prior to version 8) do not support session-wide variables. A convenient solution is to use a base table with columns for the MobiLink user name and other session data. The base table will have rows representing concurrent synchronizations.

  • User-defined procedures. DB2 requires a C compiler to compile SQL procedures into an executable library (such as a DLL). The resulting DLL/shared library must be copied to a special directory on the server. Note that you can write stored procedures using several different languages, including C/C++ and Java, among others.

    For an example of Java as a procedural language for DB2, see the CustDB scripts in the files Samples\MobiLink\CustDB\custdbq.sql and Samples\MobiLink\CustDB\custdbq.java.

    For more information about Java and .NET synchronization scripts, see

    • Options for writing synchronization logic

    • Writing Synchronization Scripts in Java

    • Writing Synchronization Scripts in .NET

  • CHAR columns In IBM DB2, CHAR data types are fixed length and blank-padded to the full length of the string. In MobiLink remote databases (Adaptive Server Anywhere or UltraLite) CHAR is the same as VARCHAR: values are not blank-padded to a fixed width. The dbmlsrv9 -b command line option can be used to remove trailing blanks from strings during synchronization. This option is important for string comparisons used to detect conflicts.

    For more information, see -b option.

  • Data type mapping For details of how Adaptive Server Anywhere data types are mapped to DB2 data types, see IBM DB2 data mapping.


Microsoft SQL Server consolidated database

To set up Microsoft SQL Server to work as a MobiLink consolidated database, run the syncmss.sql setup script, located in the MobiLink\setup subdirectory of your SQL Anywhere installation.

To ensure that the MobiLink administrator has adequate permissions to change the MobiLink system tables (required for adding scripts and other things), the user who will need access to those tables should run the setup script.

ODBC driver

You must set up an ODBC DSN for your Microsoft SQL Server consolidated database. Unlike the other consolidated databases, iAnywhere Solutions does not provide an ODBC driver for Microsoft SQL Server. This is because the Microsoft SQL Server driver is freely available for download.

For updated details, see [external link] http://www.ianywhere.com/developer/technotes/odbc_mobilink.html.

SQL Server issues

  • Procedure calls Microsoft SQL Server requires that procedure calls with parameters be written using the ODBC syntax:

    { CALL procedure_name( ?, ?, ... ) }

  • CHAR columns In Microsoft SQL Server, CHAR data types are fixed length and blank-padded to the full length of the string. In MobiLink remote databases (Adaptive Server Anywhere or UltraLite) CHAR is the same as VARCHAR: values are not blank-padded to a fixed width. The dbmlsrv9 -b command line option can be used to remove trailing blanks from strings during synchronization. This option is important for string comparisons used to detect conflicts.

    For more information, see -b option.

  • Data type mapping For details of how Adaptive Server Anywhere data types are mapped to SQL Server data types, see Microsoft SQL Server data mapping.


Synchronization Techniques

About this chapter

This chapter describes a variety of techniques that you can use to tackle common synchronization tasks encountered in MobiLink installations.

There are sample applications that provide examples of the techniques that are described in this chapter. For more information, see The Contact Sample Application, and The CustDB Sample Application.

The techniques in this chapter are illustrated using SQL scripts. Many of the same techniques can be implemented in Java or .NET synchronization logic. For more information, see

  • Writing Synchronization Scripts in Java

  • Writing Synchronization Scripts in .NET

Introduction
Development tips
Timestamp-based synchronization
Snapshot synchronization
Partitioning rows among remote databases
Maintaining unique primary keys
Handling conflicts
Data entry
Handling deletes
Handling failed downloads
Downloading a result set from a stored procedure call
Schema changes in remote databases


Introduction

The chapter Writing Synchronization Scripts describes how to write simple synchronization scripts, store them in your database, and test that they are free of syntax errors.

Many useful synchronization features require not just one script, but a set of scripts working together. This chapter describes how to implement some common synchronization techniques. The examples describe SQL synchronization scripts. You can also use Java or .NET synchronization logic, although the upload and download events still require a knowledge of the SQL scripts.

Example

The timestamp-based synchronization of the Customer table used in the Contact sample application requires the following scripts:

  • An upload_insert script to handle new rows added at remote databases at the consolidated database.

  • An upload_update script to handle modifications made at remote databases at the consolidated database.

  • An upload_delete script to handle rows deleted from remote databases at the consolidated database.

  • A download_cursor script to download new and updated rows to remote databases.

  • A download_delete_cursor script to download rows to be deleted from remote databases.


Development tips

Adding synchronization functionality to an application adds an added level of complexity to your application. The following tips may be useful.

  • Wait If you try to add synchronization to a prototype application, it can be difficult to see which components are causing problems. This is particularly the case with UltraLite applications, where database and application are compiled together. When developing a prototype, temporarily hard code INSERT statements in your application to provide data for testing and demonstration purposes. Once your prototype is working correctly, enable synchronization and discard the temporary INSERT statements.

  • Go step-by-step Start with straightforward synchronization techniques. Operations such as a simple upload or download require only one or two scripts. Once those are working correctly, you can introduce more advanced techniques, such as timestamps, primary key pools, and conflict resolution.

Following are some fundamental rules of MobiLink synchronization applications.

  • Every table that is to be synchronized must have a primary key.

  • Don't update the values of primary keys.

  • Primary keys must be unique across all synchronized databases.

  • The MobiLink user name that identifies each remote database must be unique.


Timestamp-based synchronization

The timestamp method is the most useful general technique for efficient synchronization. The technique involves tracking the last time that each user synchronized, and using this information to control the rows downloaded to each remote database.

MobiLink maintains a timestamp value indicating when each MobiLink user last downloaded data. This value is called the last download timestamp. The last download timestamp is provided as a parameter to many events, and can be used in synchronization scripts.

If you are using an Adaptive Server Anywhere consolidated database and the column holding last modified information is of type DEFAULT TIMESTAMP, then the column should not be synchronized. If your remote databases require such a column, a different column name should be used. Otherwise, the default timestamp value may be overridden by the uploaded value, and will not contain the time that the row was last modified on the consolidated.

toggle To implement timestamp-based synchronization for a table

  1. At the consolidated database, add a column that holds the most recent time the row was modified. The column is typically declared as follows:

    DBMS | last modified column
    Adaptive Server Anywhere | timestamp DEFAULT timestamp
    Adaptive Server Enterprise | datetime
    Microsoft SQL Server | datetime
    Oracle | date
    IBM DB2 | timestamp

  2. In scripts for the download_cursor and download_delete_cursor events, compare the first parameter to the value in the timestamp column.

Example

The following table declaration and scripts implement timestamp-based synchronization on the Customer table in the Contact sample:

  • Table definition:

    CREATE TABLE "DBA"."Customer"(
   "cust_id"  integer NOT NULL
                     DEFAULT GLOBAL AUTOINCREMENT,
   "name"  char(40) NOT NULL,
   "rep_id"  integer NOT NULL,
   "last_modified" timestamp NULL DEFAULT timestamp,
   "active"  bit NOT NULL,
   PRIMARY KEY ("cust_id") )

  • download_delete_cursor script:

    SELECT cust_id
FROM Customer JOIN SalesRep
ON Customer.rep_id = SalesRep.rep_id
WHERE Customer.last_modified >= ?
    AND ( SalesRep.ml_username != ?
          OR Customer.active = 0 )

  • download_cursor script:

    SELECT cust_id, Customer.name, Customer.rep_id
FROM Customer KEY JOIN SalesRep
WHERE Customer.last_modified >= ?
AND SalesRep.ml_username = ?
AND Customer.active = 1

For more information, see Synchronization logic source code, and Synchronizing contacts in the Contact sample.


Snapshot synchronization

Timestamp-based synchronization is appropriate for most synchronizations. However, occasionally you may want to update a snapshot of your data.

Snapshot synchronization of a table is a complete download of all relevant rows in the table, even if they have been downloaded before. This is the simplest synchronization method, but can involve unnecessarily large data sets being exchanged, which can limit performance.

You can use snapshot synchronization for downloading all the rows of the table, or in conjunction with a partitioning of the rows as described in Partitioning rows among remote databases.

When to use snapshot synchronization

The snapshot method is typically most useful for tables that have both the following characteristics.

  • Relatively few rows When there are few rows, the overhead associated with downloading all of them is small.

  • Rows that change frequently When most rows in a table change frequently, there is little to be gained by explicitly excluding those that have not changed since the last synchronization.

A table that holds a list of exchange rates could be suited to this approach because there are relatively few currencies, but the rates of most change frequently. Depending on the nature of the business, a table that holds prices, a list of interest rates, or current news items could all be candidates.

toggle To implement snapshot-based synchronization

  1. Leave the upload scripts undefined unless remote users update the values.

  2. If the table may have rows deleted, write a download_delete_cursor script that deletes all the rows from the remote table, or at least all rows no longer required. Do not delete the rows from the consolidated database; rather, mark them for deletion. You must know the row values to delete them from the remote database.

    For more information, see Writing download_delete_cursor scripts.

  3. Write a download_cursor script that selects all the rows you want to include in the remote table.

Deleting rows

Rather than deleting rows from the consolidated database, mark them for deletion. You must know the row values to delete them from the remote database. Select only unmarked rows in the download_cursor script and only marked rows in the download_delete_cursor script.

The download_delete_cursor script is executed before the download_cursor script. If a row is to be included in the download stream, you need not include a row with the same primary key in the delete list. When a downloaded row is received at the remote location, it replaces a preexisting row with the same primary key.

For more information, see Writing scripts to download rows.

An alternative deletion technique

Rather than delete rows from the remote database using a download_cursor script, you can allow the remote application to delete the rows. For example, immediately following synchronization, you could allow the application to execute SQL statements that delete the unneeded rows.

Rows deleted by the application are ordinarily uploaded to the MobiLink synchronization server upon the next synchronization, but you can prevent this upload using the STOP SYNCHRONIZATION DELETE statement. For example,

STOP SYNCHRONIZATION DELETE;
DELETE FROM table-name
   WHERE expiry_date < CURRENT TIMESTAMP;
COMMIT;
START SYNCHRONIZATION DELETE;

For more information about deleting rows, see Writing download_delete_cursor scripts.

Snapshot example

The ULProduct table in the sample application is maintained by snapshot synchronization. The table contains relatively few rows, and for this reason, there is little overhead in using snapshot synchronization.

  1. There is no upload script. This reflects a business decision that products cannot be added at remote databases.

  2. There is no download_delete_cursor, reflecting an assumption that products are not removed from the list.

  3. The download_cursor script selects the product identifier, price, and name of every current product. If the product is pre-existing, the price in the remote table will be updated. If the product is new, a row will be inserted in the remote table.

    SELECT prod_id, price, prod_name
FROM ULProduct

For another example of snapshot synchronization in a table with very few rows, see Synchronizing sales representatives in the Contact sample.


Partitioning rows among remote databases

Each MobiLink remote database can contain a different subset of the data in the consolidated database. Stated another way, you can write your scripts so that data is partitioned among remote databases.

The partitioning may be disjoint, or it may contain overlaps. For example, if each employee has their own set of customers, with no shared customers, the partitioning would be disjoint. If there are shared customers, who appear in more than one remote database, the partitioning contains overlaps.

Partitioning is implemented in the download_cursor and download_delete_cursor scripts for the table, which define the rows to be downloaded to the remote database. Each of these scripts takes a MobiLink user name as a parameter parameter. By defining your scripts using this parameter in the WHERE clause, each user gets the appropriate rows.


Disjoint partitioning

Partitioning is controlled by the download_cursor and download_delete_cursor scripts for each table involved in synchronization. These scripts take two parameters, a last download timestamp and the MobiLink user name supplied in the call to synchronize.

toggle To partition a table among remote databases

  1. Include in the table definition a column containing the synchronization user name in the consolidated database. You need not download this column to remote databases.

  2. Include a condition in the WHERE clause of the download_cursor and download_delete_cursor scripts requiring this column to match the script parameter.

    The script parameter is represented by a question mark in the script. The user name is the second parameter in the download_cursor script. For example, the following download_cursor script partitions the Contact table by employee ID.

    SELECT id, contact_name
FROM Contact
WHERE last_modified >= ?
AND emp_id = ?

    For more information, see download_cursor table event, and download_delete_cursor table event.

Example

The primary key pool tables in the CustDB sample application are used to supply each remote database with its own set of primary key values. This technique is used to avoid duplicate primary keys, and is discussed in Maintaining unique primary keys using key pools.

A necessary feature of the method is that primary key-pool tables must be partitioned among remote databases in a disjoint fashion.

One key-pool table is ULCustomerIDPool, which holds primary key values for each user to use when they add customers. The table has three columns:

  • pool_cust_id A primary key value for use in the ULCustomer table. This is the only column downloaded to the remote database.

  • pool_emp_id The employee who owns this primary key.

  • last_modified This table is maintained using the timestamp technique, based on the last_modified column.

    For information on timestamp synchronization, see Timestamp-based synchronization.

The download_cursor script for this table is as follows.

SELECT pool_cust_id
FROM ULCustomerIDPool
WHERE last_modified >= ?
   AND pool_emp_id = ?

When not using a variable, you should use a join or sub-selection that includes the ? placeholder.

For more information, see Synchronizing customers in the Contact sample, and Synchronizing contacts in the Contact sample.


Partitioning with overlaps

Some tables in your consolidated database may have rows that belong to many remote databases. Each remote database has a subset of the rows in the consolidated database and the subset overlaps with other remote databases. This is frequently the case with a customer table. In this case, there is a many-to-many relationship between the table and the remote databases and there will usually be a table to represent the relationship. The scripts for the download_cursor and download_delete_cursor events need to join the table being downloaded to the relationship table.

Example

The CustDB sample application uses this technique for the ULOrder table. The ULEmpCust table holds the many-to-many relationship information between ULCustomer and ULEmployee.

Each remote database receives only those rows from the ULOrder table for which the value of the emp_id column matches the MobiLink user name.

The Adaptive Server Anywhere version of the download_cursor script for ULOrder in the CustDB application is as follows:

SELECT o.order_id, o.cust_id, o.prod_id,
   o.emp_id, o.disc, o.quant, o.notes, o.status
FROM ULOrder o , ULEmpCust ec
WHERE o.cust_id = ec.cust_id
   AND ec.emp_id = ?
   AND ( o.last_modified >= ?
      OR ec.last_modified >= ?)
   AND    ( o.status IS NULL
      OR o.status != 'Approved' )
   AND ( ec.action IS NULL )

This script is fairly complex. It illustrates that the query defining a table in the remote database can include more than one table in the consolidated database. The script downloads all rows in ULOrder for which all of the following are true:

  • the cust_id column in ULOrder matches the cust_id column in ULEmpCust

  • the emp_id column in ULEmpCust matches the synchronization user name

  • the last modification of either the order or the employee-customer relationship was later than the most recent synchronization time for this user

  • the status is anything other than Approved

The action column on ULEmpCust is used to mark columns for delete. Its purpose is not relevant to the current topic.

The download_delete_cursor script is as follows.

SELECT o.order_id
FROM ULOrder o, ULEmpCust ec
WHERE o.cust_id = ec.cust_id
  AND ec.emp_id = ?
  AND ( o.last_modified >= ? OR
        c.last_modified >= ? )
  AND ( o.status IS NULL OR
        o.status != 'Approved' )
  AND ( ec.action IS NULL )

This script deletes all approved rows from the remote database.


Partitioning child tables

The example in Partitioning with overlaps illustrates how to partition tables based on a criterion in some other table.

Some tables in your remote database may have disjoint subsets or overlapping subsets, but do not contain a column that determines the subset. These are child tables that usually have a foreign key (or a series of foreign keys) referencing another table. The referenced table has a column that determines the correct subset.

In this case, the download_cursor script and the download_delete_cursor script need to join the referenced tables and have a WHERE clause that restricts the rows to the correct subset.

For an example, see Synchronizing contacts in the Contact sample.


Maintaining unique primary keys

Every table that is to be synchronized must have a primary key, and the primary key must be unique across all synchronized databases. The values of primary keys should not be updated.

It is often convenient to use a single column as the primary key for tables. For example, each customer should be assigned a unique identification value. If all the sales representatives work in an environment where they can maintain a direct connection to the database, assigning these numbers is easily accomplished. Whenever a new customer is inserted into the customer table, automatically add a new primary key value that is greater than the last value.

In a disconnected environment, assigning unique values for primary keys when new rows are inserted is not as easy. When a sales representative adds a new customer, she is doing so to a remote copy of the Customer table. You must prevent other sales representatives, working on other copies of the Customer table, from using the same customer identification value.

This section describes the following ways to solve the problem of how to generate unique primary keys:

  • Using Universally Unique IDs (UUIDs)

  • Using global autoincrement values.

  • Using primary key pools.


Maintaining unique primary keys using UUIDs

You can ensure that primary keys in Adaptive Server Anywhere databases are unique by using the newid( ) function to create universally unique values for your primary key. The resulting UUIDs can be converted to a string using the uuidtostr( ) function, and converted back to binary using the strtouuid( ) function.

UUIDs are unique across all computers. However, the values are completely random and so cannot be used to determine when a value was added, or the order of values. UUID values are also considerably larger than the values required by other methods (including global autoincrement), and require more table space in both the primary and foreign key tables. Indexes on tables using UUIDs are also less efficient.

For more information, see

  • The NEWID default

  • NEWID function [Miscellaneous]

  • UNIQUEIDENTIFIER data type [Binary]

Example

The following CREATE TABLE statement creates a primary key that is universally unique:

CREATE TABLE customer (
   cust_key UNIQUEIDENTIFIER NOT NULL
            DEFAULT NEWID( ),
   rep_key VARCHAR(5),
   PRIMARY KEY(cust_key))


Maintaining unique primary keys using global autoincrement

In Adaptive Server Anywhere and UltraLite databases, you can set the default column value to be GLOBAL AUTOINCREMENT. You can use this default for any column in which you want to maintain unique values, but it is particularly useful for primary keys.

toggle To use global autoincrement columns

  1. Declare the column as a global autoincrement column.

    When you specify default global autoincrement, the domain of values for that column is partitioned. Each partition contains the same number of values. For example, if you set the partition size for an integer column in a database to 1000, one partition extends from 1001 to 2000, the next from 2001 to 3000, and so on.

    See Declaring default global autoincrement.

  2. Set the GLOBAL_DATABASE_ID value.

    Adaptive Server Anywhere supplies default values in a database only from the partition uniquely identified by that database's number. For example, if you assigned the database in the above example the identity number 10, the default values in that database would be chosen in the range 10001–11000. Another copy of the database, assigned the identification number 11, would supply default value for the same column in the range 11001–12000.

    See Setting the GLOBAL_DATABASE_ID value.

For more information

This section describes how to use global autoincrement columns in Adaptive Server Anywhere remote databases. For information on using global autoincrement columns in UltraLite databases, see Declaring default global autoincrement columns.

For information on how global autoincrement columns work in Adaptive Server Anywhere databases, see How default values are chosen.


Declaring default global autoincrement

You can set default values in your database by selecting the column properties in Sybase Central, or by including the DEFAULT GLOBAL AUTOINCREMENT phrase in a CREATE TABLE or ALTER TABLE statement.

Optionally, the partition size can be specified in parentheses immediately following the AUTOINCREMENT keyword. The partition size may be any positive integer, although the partition size is generally chosen so that the supply of numbers within any one partition will rarely, if ever, be exhausted.

For columns of type INT or UNSIGNED INT, the default partition size is 216 = 65536; for columns of other types the default partition size is 232 = 4294967296. Since these defaults may be inappropriate, especially if our column is not of type INT or BIGINT, it is best to specify the partition size explicitly.

For example, the following statement creates a simple table with two columns: an integer that holds a customer identification number and a character string that holds the customer's name.

CREATE TABLE customer (
   id   INT          DEFAULT GLOBAL AUTOINCREMENT (5000),
   name VARCHAR(128) NOT NULL,
   PRIMARY KEY (id)
)

In the above example, the chosen partition size is 5000.

For more information on GLOBAL AUTOINCREMENT, see CREATE TABLE statement.


Setting the GLOBAL_DATABASE_ID value

When deploying an application, you must assign a different identification number to each database. You can accomplish the task of creating and distributing the identification numbers by a variety of means. One method is to place the values in a table and download the correct row to each database based on some other unique property, such as user name.

toggle To set the global database identification number

  • You set the identification number of a database by setting the value of the public option GLOBAL_DATABASE_ID. The identification number must be a non-negative integer.

Example

For example, the following statement sets the database identification number to 20.

SET OPTION PUBLIC.GLOBAL_DATABASE_ID = 20

If the partition size for a particular column is 5000, default values for this database are selected from the range 100001–105000.


How default values are chosen

The public option GLOBAL_DATABASE_ID in each database must be set to a unique, non-negative integer. The range of default values for a particular database is pn + 1 to p(n + 1), where p is the partition size and n is the value of the public option GLOBAL_DATABASE_ID. For example, if the partition size is 1000 and GLOBAL_DATABASE_ID is set to 3, then the range is from 3001 to 4000.

If GLOBAL_DATABASE_ID is set to a non-negative integer, Adaptive Server Anywhere chooses default values by applying the following rules:

  • If the column contains no values in the current partition, the first default value is pn + 1.

  • If the column contains values in the current partition, but all are less than p(n + 1), the next default value will be one greater than the previous maximum value in this range.

  • Default column values are not affect by values in the column outside of the current partition; that is, by numbers less than pn + 1 or greater than p(n + 1). Such values may be present if they have been replicated from another database via MobiLink synchronization.

If the public option GLOBAL_DATABASE_ID is set to the default value of 2147483647, a null value is inserted into the column. Should null values not be permitted, the attempt to insert the row causes an error. This situation arises, for example, if the column is contained in the table's primary key.

Because the public option GLOBAL_DATABASE_ID cannot be set to negative values, the values chosen are always positive. The maximum identification number is restricted only by the column data type and the partition size.

Null default values are also generated when the supply of values within the partition has been exhausted. In this case, a new value of GLOBAL_DATABASE_ID should be assigned to the database to allow default values to be chosen from another partition. Attempting to insert the null value causes an error if the column does not permit nulls. To detect that the supply of unused values is low and handle this condition, create an event of type GlobalAutoincrement.

Should the values in a particular partition become exhausted, you can assign a new database id to that database. You can assign new database id numbers in any convenient manner. However, one possible technique is to maintain a pool of unused database id values. This pool is maintained in the same manner as a pool of primary keys.

You can set an event handler to automatically notify the database administrator (or carry out some other action) when the partition is nearly exhausted. For more information, see Defining trigger conditions for events.

For more information, see Setting the GLOBAL_DATABASE_ID value, and GLOBAL_DATABASE_ID option [database].


Maintaining unique primary keys using key pools

One efficient means of solving this problem is to assign each user of the database a pool of primary key values to assign as the need arises. For example, you can assign each sales representative 100 new identification values. Each sales representative can freely assign values to new customers from his own pool.

toggle To implement a primary key pool

  1. Add a new table to the consolidated database and to each remote database to hold the new primary key pool. Apart from a column for the unique value, these tables should contain a column for a user name, to identify who has been given the right to assign the value.

  2. Write a stored procedure to ensure that each user is assigned enough new identification values. Assign more new values to remote users who insert many new entries or who synchronize infrequently.

  3. Write a download_cursor script to select the new values assigned to each user and download them to the remote database.

  4. Modify the application that uses the remote database so that when a user inserts a new row, the application uses one of the values from the pool. The application must then delete that value from the pool so it is not used a second time.

  5. Write an upload scripts. The MobiLink synchronization server will then delete rows from the consolidated pool of values that a user has deleted from his personal value pool in the remote database.

  6. Write an end_upload script to call the stored procedure that maintains the pool of values. Doing so has the effect of adding more values to the user's pool to replace those deleted during upload.

Example

The sample application allows remote users to add customers. It is essential that each new row has a unique primary key value, and yet each remote database is disconnected when data entry is occurring.

The ULCustomerIDPool holds a list of primary key values that can be used by each remote database. In addition, the ULCustomerIDPool_maintain stored procedure tops up the pool as values are used up. The maintenance procedures are called by a table-level end_upload script, and the pools at each remote database are maintained by upload_cursor and download_cursor scripts.

  1. The ULCustomerIDPool table in the consolidated database holds the pool of new customer identification numbers. It has no direct link to the ULCustomer table.

    The ULCustomerIDPool, ULEmployee, and ULCustomer tables.

  2. The ULCustomerIDPool_maintain procedure updates the ULCustomerIDPool table in the consolidated database. The following sample code is for an Adaptive Server Anywhere consolidated database.

    CREATE PROCEDURE ULCustomerIDPool_maintain ( IN syncuser_id INTEGER )
BEGIN
    DECLARE pool_count INTEGER;

    -- Determine how may ids to add to the pool
    SELECT COUNT(*) INTO pool_count
    FROM ULCustomerIDPool
    WHERE pool_emp_id = syncuser_id;

    -- Top up the pool with new ids
    WHILE pool_count < 20 LOOP
      INSERT INTO ULCustomerIDPool ( pool_emp_id )
      VALUES ( syncuser_id );
      SET pool_count = pool_count + 1;
    END LOOP;
END

    This procedure counts the numbers presently assigned to the current user, and inserts new rows so that this user has a sufficient supply of customer identification numbers.

    This procedure is called at the end of the upload stream, by the end_upload table script for the ULCustomerIDPool table. The script is as follows:

    CALL ULCustomerIDPool_maintain( ? )

  3. The download_cursor script for the ULCustomerIDPool table downloads new numbers to the remote database.

    SELECT pool_cust_id
FROM ULCustomerIDPool
WHERE pool_emp_id = ?
AND last_modified >= ?

  4. To insert a new customer, the application using the remote database must select an unused identification number from the pool, delete this number from the pool, and insert the new customer information using this identification number. The following embedded SQL function for an UltraLite application retrieves a new customer number from the pool.

    bool CDemoDB::GetNextCustomerID( void )
/*************************************/
{
    short   ind;

    EXEC SQL SELECT min( pool_cust_id )
    INTO :m_CustID:ind FROM ULCustomerIDPool;
    if( ind < 0 ) {
        return false;
    }
    EXEC SQL DELETE FROM ULCustomerIDPool
    WHERE pool_cust_id = :m_CustID;
    return true;
}


Handling conflicts

Caution Don't update primary keys in a MobiLink environment. A primary key uniquely identifies a row for conflict detection purposes.

Conflicts arise during the upload of rows to the consolidated database. If two users modify the same row on different remote databases, a conflict is detected when the second of the rows arrives at the MobiLink synchronization server. When conflicts can occur, you should define a process to compute the correct values, or at least to log the conflict.

During the download stage of a synchronization, no conflicts arise in the remote database. If a downloaded row contains a new primary key, the values are inserted into a new row. If the primary key matches that of a pre-existing row, the values in the row are updated.

Conflicts are not the same as errors. Conflict handling is an integral part of a well-designed application.

Default behavior

Conflicts are detected only during updates of a row. An attempt to update a row that has been updated or deleted since that last synchronization is a conflict. By default:

  • If an attempt to insert a row finds that the row has already been inserted, an error is generated.

  • If an attempt to delete a row finds that the row has already been deleted, the attempt to delete is ignored.

These are the built-in behaviors that have been defined for convenience. If you need different behavior, you may implement it yourself using one or more of the upload events.

For a description of how to handle syncrhonization conflicts, see Tutorial: Writing MobiLink Scripts and Monitoring Synchronizations.


Detecting conflicts

When a MobiLink client sends an updated row to the MobiLink synchronization server, it includes not only the new values (the post-image), but also a copy of the old row values (the pre-image). When the pre-image does not match the current values in the consolidated database, a conflict is detected.

There are two ways to detect conflicts:

  • Define an upload_fetch script.

  • Define an upload_update script that includes all non-primary key columns in the WHERE clause.

If you define both of these scripts for the same table, only the upload_fetch script is used.

The MobiLink synchronization server detects conflicts only if an upload_fetch or appropriate upload_update script is applied. If an upload_fetch script is supplied, the MobiLink synchronization server compares the pre-image of an update to the values of the row returned by the upload_fetch script with the same primary key values. If values in the pre-image do not match the current consolidated values, the MobiLink synchronization server detects a conflict.

upload_fetch

The upload_fetch script typically selects a single row of data from a consolidated database table corresponding to the row being updated. A typical upload_fetch script has the following syntax:

SELECT col1, col2, ...
FROM table-name
WHERE pk1 = ? AND pk2 = ? ...

For more information, see upload_fetch table event.

upload_update

The upload_update script provides a parameter for each column in the row.

The parameters for an upload_update event are arranged so that statements with the following syntax update rows correctly:

UPDATE table-name
SET col1 = ?, col2 = ?, ...
WHERE pk1 = ? AND pk2 = ? ...

In this statement, col1, col2 and so on are the non-primary key columns, while pk1, pk2 and so on are primary key columns.

For a conflict to be detected, the syntax must be as follows:

UPDATE table-name
SET col1 = ?, col2 = ?, ...
WHERE pk1 = ? AND pk2 = ? ...
AND col1 = ? AND col2 = ? ...

The WHERE clause compares old values uploaded from the remote to current values in the consolidated database. If the values do not match, the update is ignored, thus preserving the values already on the consolidated database.

For more information, see upload_update table event.


Resolving conflicts

You have several options for resolving conflicts:

  • Resolve conflicts as they occur using temporary or permanent tables and a resolve_conflict script.

    See Resolving conflicts with resolve_conflict scripts.

  • Resolve conflicts as they occur using an upload_update script.

    See Resolving conflicts with upload_update scripts.

  • Resolve all conflicts at once using a table's end_upload event.

    See end_upload table event.

For an example of conflict resolution using statement-based uploads, see Synchronizing products in the Contact sample.

Example

For example, User1 starts with an inventory of ten items, and then sells three and updates the Remote1 inventory value to seven items. User2 sells four items and updates the Remote2 inventory to six. When Remote1 synchronizes, the consolidated database is updated to seven. When Remote2 synchronizes, a conflict is detected because the value of the inventory is no longer ten. To resolve this conflict programmatically, you need three row values:

  1. The current value in the consolidated database.

  2. The new row value that Remote2 uploaded.

  3. The old row value that Remote2 obtained during the last synchronization.

In this case, the business logic would use the following to calculate the new inventory value and resolve the conflict:

current consolidated - (old remote - new remote)
-> 7 - (10-6) = 3


Resolving conflicts with resolve_conflict scripts

When the MobiLink synchronization server detects a conflict using an upload_fetch script, the following events take place.

  • The MobiLink synchronization server inserts old row values uploaded from the remote database as defined by the upload_old_row_insert script. Typically, the old values are inserted into a temporary table.

    For more information, see upload_old_row_insert table event.

  • The MobiLink synchronization server inserts the new row values uploaded from the remote database as defined by the upload_new_row_insert script. Typically, the new values are inserted into a temporary table.

    For more information, see upload_new_row_insert table event.

  • The MobiLink synchronization server executes the resolve_conflict script. In this script you can either call a stored procedure, or define a sequence of steps to resolve the conflict using the new and old row values.

For more information, see resolve_conflict table event.

Example

In the following example, you create scripts for six events and then you create a stored procedure.

  • In the begin_synchronization script, you create two temporary tables called contact_new and contact_old. This is done in begin_synchronization instead of begin_connection so that the corresponding "end_" script will run even if the synchronization fails, ensuring that the temporary tables are deleted.

  • In the upload_old_row_insert and upload_new_row_insert scripts, you populate the two temporary tables with the new and old data uploaded from the remote database.

  • The upload_fetch script detects the conflict.

  • The resolve_conflict script calls the stored procedure MLResolveConflict to resolve the conflict.

Event Script
begin_synchronization
CREATE TABLE #contact_new(
   id  INTEGER,
   location CHAR(36),
   contact_date DATE);
CREATE TABLE #contact_old(
   id  INTEGER,
   location CHAR(36),
   contact_date DATE)
upload_fetch
SELECT id, location, contact_date
   FROM contact
   WHERE id = ?
upload_old_row_insert
INSERT INTO #contact_new( id, location, contact_date )
  VALUES ( ?, ?, ? )
upload_new_row_insert
INSERT INTO #contact_old( id, location, contact_date )
  VALUES ( ?, ?, ? )
resolve_conflict
CALL MLResolveConflict( )
end_synchronization
DROP TABLE #contact_new;
DROP TABLE #contact_old

The stored procedure MLResolveConflict is as follows:

CREATE PROCEDURE MLResolveConflict( )
BEGIN
  --update the consolidated database only if the new contact date
  --is later than the existing contact date
  UPDATE contact c
    SET c.contact_date = cn.contact_date
      FROM #contact_new cn
      WHERE c.id = cn.id
        AND cn.contact_date > c.contact_date;
  --cleanup
  DELETE FROM #contact_new;
  DELETE FROM #contact_old;
END


Resolving conflicts with upload_update scripts

Instead of using the resolve_conflict script for conflict resolution, you can call a stored procedure in the upload_update script. With this technique, you must both detect and resolve conflicts programmatically.

For example, the following stored procedure, sp_update_customer, contains logic for conflict detection and resolution. It accepts new column values, primary keys, and old column values for parameters.

call ml_add_table_script( 'version_1', 'customer', 'upload_update', '
CALL sp_update_customer (?,?,?,?,?,?)
)
CREATE PROCEDURE sp_update_customer(
     IN @new_first_name    varchar(30)
    ,IN @new_last_name     varchar(30)
    ,IN @new_nullable_col  varchar(30)
    ,IN @new_last_modified timestamp
    ,IN @cust_1st_pk       integer
    ,IN @cust_2nd_pk       integer
    ,IN @old_first_name    varchar(30)
    ,IN @old_last_name     varchar(30)
    ,IN @old_nullable_col  varchar(30)
    ,IN @old_last_modified timestamp
)

To detect a conflict you can check the number of rows affected by the following update operation. The WHERE clause compares old values uploaded from the remote to current values in the consolidated database. If the values match, the update succeeds and no conflict has occurred.

UPDATE customer
SET first_name                  = @new_first_name,
 last_name                        = @new_last_name,
 nullable_col                   = @new_nullable_col,
 last_modified                  = @new_last_modified

WHERE cust_1st_pk               = @cust_1st_pk
 AND cust_2nd_pk                = @cust_2nd_pk
 AND first_name                 = @old_first_name
 AND last_name                  = @old_last_name
 AND COALESCE(nullable_col, '') = COALESCE(@old_nullable_col, '')
 AND last_modified              = @old_last_modified;
...
Note:
The COALESCE function returns the first non-NULL expression from a list, and is used in this case to compare values for a nullable column.

For more information, see COALESCE function [Miscellaneous].

You can use a mechanism in your consolidated database to determine the outcome of the update statement shown above. Using Adaptive Server Anywhere, for example, you can check the @@rowcount global variable to determine the number of rows affected by the update. If @@rowcount = 0 then a conflict has occurred, and you can programmatically resolve the conflict, as follows. In this example, the database with the most recent update wins the conflict. If the consolidated database wins the conflict, it retains its current values and no action is taken.

IF( @@rowcount = 0 ) THEN
-- A conflict has been detected. To resolve, you:
-- b) Use business logic to determine which values to use
-- c) Update the consolidated database with the final values

 IF( @new_last_modified > @current_last_modified ) THEN
 -- The remote has won the conflict
 -- use the values it uploaded.

  UPDATE customer
   SET first_name    = @new_first_name,
       last_name     = @new_last_name,
       nullable_col  = @new_nullable_col,
       last_modified = @new_last_modified
       WHERE cust_1st_pk  = @cust_1st_pk
        AND cust_2nd_pk   = @cust_2nd_pk;

 END IF;
END IF;


Forced conflicts

Forced conflict resolution is a special technique that forces every uploaded row to be treated as if it were a conflict.

The MobiLink synchronization server uses forced conflict resolution when the upload_insert, upload_update, and upload_delete script are all undefined. In this mode of operation, the MobiLink synchronization server attempts to insert all uploaded rows from that table using the statements defined by the upload_old_row_insert and upload_new_row_insert scripts. In essence, all uploaded rows are then treated as conflicts. You can write stored procedures or scripts to process the uploaded values in any way you want.

Without any of the upload_insert, upload_update, or upload_delete scripts, the normal conflict-resolution procedure is bypassed. This technique has two principal uses.

  • Arbitrary conflict detection and resolution The automatic mechanism only detects errors when updating a row, and only then when the old values do not match the present values in the consolidated database.

    You can capture the raw uploaded data using the upload_old_row_insert and upload_new_row_insert scripts, then process the rows as you see fit.

  • Performance When the upload_insert, upload_update, and upload_delete are not defined, the MobiLink synchronization server is relieved of its normal conflict-detection tasks, which involve querying the consolidated database one row at a time. Instead, it needs only to insert the raw uploaded information using the statements defined by the upload_old_row_insert and upload_new_row_insert scripts. Since only inserts are involved, the MobiLink synchronization server performs more efficiently.

Storing the user name


Storing the user name

When you write upload_old_row_insert or upload_new_row_insert scripts, you can include an extra parameter in your INSERT statement. If you do so, the MobiLink synchronization server automatically inserts the user name into the first parameter, and then uses the rest of the parameters as usual. This mechanism is available because some database-management systems provide no convenient mechanism to store the identity of the current user.

You can use this feature to conveniently identify which user inserted each row. It is also useful when one or two tables are used to hold the new and old uploaded values from many different users at the same time. This information allows you to include user-specific logic in the resolve_conflict script.

For example, an ordinary upload_old_row_insert script is of the following form. The items in the select list correspond to the columns of the remote table.

INSERT INTO MyTable (c1, c2, . . . , cN) VALUES (?,?,...,?)

However, the following syntax is also permitted.

INSERT INTO MyTableWithUser (user_name, c1, c2, . . . , cN) VALUES (?,?,...,?)

Normally, the selected columns must match the columns of the remote table in both number and type. This case is an exception. The single extra parameter in the values list must be of a type suitable to hold the user name; for example, VARCHAR(128). The subsequent parameters in the list must match the columns of the remote table in order and type, as usual. If you include more than one extra parameter, an error results.

For more information, see upload_old_row_insert table event and upload_new_row_insert table event.


Data entry

In some databases, there are tables that are only used for data entry. One way of processing these tables is to upload all inserted rows at each synchronization, and remove them from the remote database on the download stream. After synchronization, the remote table is empty again, ready for another batch of data.

To achieve this model, you can upload rows into a temporary table and then insert them into a base table using an end_upload table script. The temporary table can be used in the download_delete_cursor to remove rows from the remote database following a successful synchronization.

Alternatively, you can allow the client application to the delete the rows, using the STOP SYNCHRONIZATION DELETE statement to stop the deletes being uploaded during the next synchronization.

For more information, see STOP SYNCHRONIZATION DELETE statement [MobiLink].


Handling deletes

When rows are deleted from the consolidated database, there needs to be a record of the row so it can be removed from any remote databases that have the row.

One technique is to not delete the row. Data that is no longer required can be marked as inactive by changing a status column in the row. In this case, called a logical delete, the download_cursor and download_delete_cursor can refer to the status of the row in the WHERE clause. This technique is used in the ULEmpCust table in the CustDB sample application, in which the action column holds a D for Delete. The scripts use this value to delete the record from the remote database, and delete the record from the consolidated database at the end of the synchronization. CustDB also uses this technique for the ULOrder table, and the Contact sample uses the technique on the Customer, Contact, and Product tables.

A second technique is to have a shadow table that stores the primary key values of deleted rows. When a row is deleted, a trigger can populate the shadow table. The download_delete_cursor can use the shadow table to remove rows from remote databases. The shadow table only needs to have the primary key columns from the real table.

For more information, see Writing download_delete_cursor scripts.


Handling failed downloads

Bookkeeping information about what is downloaded must be maintained in the download transaction. This information is updated atomically with the download being applied to the remote database.

If a failure occurs before the entire download stream is applied to the remote database, and if you change SendDownloadAck to ON, then the MobiLink synchronization server does not get confirmation for the download and rolls back the download transaction. Since the bookkeeping information is part of the download transaction, it is also rolled back. Next time the download stream is built, it will use the original bookkeeping information.

For more information, see SendDownloadACK (sa) extended option or Send Download Acknowledgement synchronization parameter.

When testing your synchronization scripts, you should add logic to your end_download script that causes occasional failures. This will ensure that your scripts can handle a failed download.

Resuming failed downloads


Resuming failed downloads

Download failure is caused by a communication error during download or a user aborting the download. MobiLink has functionality that helps you recover from download failure, and may help you avoid having to retransmit the entire download. This functionality has separate implementations for Adaptive Server Anywhere and UltraLite remote databases.

Adaptive Server Anywhere remote databases

When synchronization fails during a download, none of the download is applied to the remote database. However, the part of the download that was successfully transmitted is stored in a temporary file on the remote device. You cannot access this file directly, but dbmlsync provides functionality that makes use of the file. When you use this functionality, you may be able to avoid lengthy retransmission of data. You may also be able to recover from download failure automatically.

Note
The download cannot be resumed when the SendDownloadACK extended option is set to ON (the default is OFF) or when the DownloadBufferSize extended option is set to 0 (which is also not the default).

There are three ways to implement this functionality. In all cases, the resumed download will fail if there is any new data to be uploaded, and dbmlsync will abort.

  • -dc After a download fails, use -dc the next time you start dbmlsync to resume the download. If part of the failed download was transmitted, the MobiLink synchronization server will only transmit the remainder of the download.

    For more information, see -dc option.

  • ContinueDownload (cd) extended option When used on the dbmlsync command line, the cd extended option works just like the -dc option. You can also store this option in the database, or use sp_hook_dbmlsync_set_extended_options to set this option in a single synchronization.

    For more information, see ContinueDownload (cd) extended option and sp_hook_dbmlsync_set_extended_options.

  • sp_hook_dbmlsync_end hook You can use the restart parameter to cause a download to resume. You know a download is resumable if the restartable download parameter is set to true. You can also create logic in the hook to resume a download if a download file exists and is a certain size.

    For more information, see sp_hook_dbmlsync_end.

UltraLite remote databases

You can control the behavior of UltraLite applications following a failed download as follows:

  • If you set the Keep Partial Download synchronization parameter to true when you synchronize, and the download fails before completion, then UltraLite applies that portion of the changes that were downloaded. UltraLite also sets the Partial Download Retained synchronization parameter to true.

    The UltraLite database may be in an inconsistent state at this point. Depending on your application, you may wish to ensure that synchronization completes successfully or is rolled back before you allow changes to the data.

    For more information, see Keep Partial Download synchronization parameter, and Partial Download Retained synchronization parameter.

  • To resume the download, set the Resume Partial Download synchronization parameter to true and synchronize again.

    For more information, see Resume Partial Download synchronization parameter.

    The restarted synchronization does not carry out an upload, and downloads only those changes that would have been downloaded by the failed download. That is, it completes the failed download, but does not synchronize changes made since the previous attempt. To get those changes, you would need to synchronize again once the failed download has completed, or and call Rollback Partial Download and synchronize with Resume Partial Download set to false.

    When you restart the download, many of the synchronization parameters from the failed synchronization are used again automatically. For example, the publications parameter is ignored: the synchronization downloads those publications requested on the initial download. The only parameters that must be set are the Resume Partial Download parameter (which must be set to true) and the User Name parameter. In addition, settings for the following parameters are obeyed, if set:

    • Keep Partial Download (in case of further interruption)
    • DisableConcurrency
    • Observr
    • User Data

  • To roll back the changes from the failed download without resuming synchronization, call the function to roll back the changes. This function is ULRollbackPartialDownload function for embedded SQL. For UltraLite components, it is a method on the Connection object.

    • MobileVB RollbackPartialDownload method.

    • UltraLite.NET See RollbackPartialDownload method (iAnywhere.Data.UltraLite namespace) and RollbackPartialDownload method (iAnywhere.UltraLite namespace)..

    • Native UltraLite for Java ianywhere.native_ultralite.Connection.rollbackPartialDownload method in the API Reference.

    • UltraLite C++ Component RollbackPartialDownload method

    • UltraLite ActiveX RollbackPartialDownload method.

    • Embedded SQL ULRollbackPartialDownload function.

    • Static C++ API RollbackPartialDownload method.

    • Static Java API This feature is not available in the Static Java API.

    You may wish to roll back the changes from a failed download if synchronization cannot be completed (perhaps the server or network is unavailable) and if you want to maintain a consistent set of data while letting the end user carry on working on the application.

For more information about communications errors, see ASA Error Messages.

Note
If the send_download_ack synchronization parameter is set to true (which is not the default), the setting will be ignored for the resumed download.

Previous Next


Downloading a result set from a stored procedure call

You can download a result set from a stored procedure call. For example, you might currently have a download_cursor for the following table:

CREATE TABLE MyTable (
    pk INTEGER PRIMARY KEY NOT NULL,
    col1 VARCHAR(100) NOT NULL,
    col2 VARCHAR(20) NOT NULL
)

The download_cursor table script might look as follows:

SELECT pk, col1, col2
   FROM MyTable
      WHERE last_modified >= ?
      AND employee = ?

If you want your downloads to MyTable to use more sophisticated business logic, you can now create your script as follows, where DownloadMyTable is a stored procedure taking two parameters (last-download timestamp and MobiLink user name) and returning a result set. (This example uses an ODBC calling convention for portability):

{call DownloadMyTable( ?, ? )}

Following are some simple examples for each supported consolidated database. Consult the documentation for your consolidated database for full details.

The following example works with Adaptive Server Anywhere, Adaptive Server Enterprise, and Microsoft SQL Server.

CREATE PROCEDURE SPDownload
    @last_dl_ts DATETIME,
    @u_name VARCHAR( 128 )
AS
BEGIN
     SELECT pk, col1, col2
       FROM MyTable
          WHERE last_modified >= @last_dl_ts
          AND employee = @u_name
END

The following example works with Oracle. Oracle requires that a package be defined. This package must contain a record type for the result set, and a cursor type that returns the record type.

Note
This example requires that Oracle return a result set. In the ODBC Oracle Driver Setup dialog, you must select the Procedure Returns Results option; or in the connection string, set ProcedureRetResults=1. For more information about setting up the Oracle ODBC driver, see iAnywhere Solutions ODBC Driver for Oracle.
Create or replace package SPInfo as
Type SPRec is record (
    pk     integer,
    col1   varchar(100),
    col2   varchar(20)
);
Type SPCursor is ref cursor return SPRec;
End SPInfo;

Next, Oracle requires a stored procedure with the cursor type as the first parameter. Note that the download_cursor script only passes in two parameters, not three. For stored procedures returning result sets in Oracle, cursor types declared as parameters in the stored procedure definition define the structure of the result set, but do not define a true parameter as such.

Create or replace procedure
    DownloadMyTable( spcursor IN OUT SPInfo.SPCursor,
                     last_dl_ts IN DATE,
                     user_name IN VARCHAR ) As
Begin
    Open spcursor For
       select pk, col1, col2
         from MyTable
           where last_modified >= last_dl_ts
           and employee = user_name;
End;

The following example works with IBM DB2 UDB.

CREATE PROCEDURE DownloadMyTable(
   IN last_dl_ts TIMESTAMP,
   IN u_name VARCHAR( 128 ) )
        EXTERNAL NAME 'DLMyTable!DownloadMyTable'
        RESULT SETS 1
        FENCED
        LANGUAGE JAVA PARAMETER STYLE DB2GENERAL

The following example is a Java implementation of the stored procedure, in DLMyTable.java. To return a result set, you must leave the result set open when the method returns:

import COM.ibm.db2.app.*;
import java.sql.*;

public class DLMyTable extends StoredProc
{
  public void DownloadMyTable(
      Date last_dl_ts,
      String u_name ) throws Exception
  {
      Connection  conn = getConnection();
      conn.setAutoCommit( false );
      Statement   s    = conn.createStatement();
      // Execute the select and leave it open.
      ResultSet   r    = s.executeQuery(
            "select pk, col1, col2 from MyTable"
                  + " where last_modified >= '"
                  + last_dl_ts
                  + "' and employee = '"
                  + u_name + "'" );
    }
}


Schema changes in remote databases

As your needs evolve, deployed remote databases may require schema changes. The most common schema changes are adding a new column to an existing table or adding a new table to the database.


Adaptive Server Anywhere remote databases

You can change the schema of remote Adaptive Server Anywhere databases after they are deployed.

toggle To add tables to Adaptive Server Anywhere remote databases

  1. Add the associated table scripts in the consolidated database.

    The same script version may be used for the remote database without the new table and the remote database with the new table. However, if the presence of the new table changes how existing tables are synchronized, then you must create a new script version, and create new scripts for all tables being synchronized with the new script version.

  2. Perform a normal synchronization.

    This step is optional, but recommended, before changing schema.

  3. Use the ALTER PUBLICATION statement to add the table. For example,

    ALTER PUBLICATION your_pub
   ADD TABLE table_name

    For more information, see ALTER PUBLICATION statement.

  4. Synchronize. Use the new script version, if required.

Changing table definitions in remote databases

Changing the number or type of columns in an existing table must be done carefully. When a MobiLink client synchronizes with a new schema, it expects scripts, such as upload_update or download_cursor, which have parameters for all columns in the remote table. An older remote database expects scripts that have only the original columns.

toggle To alter a published table in a deployed Adaptive Server Anywhere remote database

  1. At the consolidated database, create a new script version.

    For more information, see Script versions.

  2. For your new script version, create scripts for all tables in the publication(s) that contain the table that you want to alter and that are synchronized with the old script version.

  3. At the remote database, perform a normal synchronization using the old script version.

  4. At the remote database, use the ALTER PUBLICATION statement to temporarily drop the table from the publication. For example,

    ALTER PUBLICATION your_pub
  DROP TABLE table_name

    For more information, see ALTER PUBLICATION statement.

  5. At the remote database, use the ALTER TABLE statement to alter the table.

    For more information, see ALTER TABLE statement.

  6. At the remote database, use the ALTER PUBLICATION statement to add the table back into the publication.

    For more information, see ALTER PUBLICATION statement.

  7. Synchronize with the new script version.

Note: Steps 4 through 6 may also be performed by the sp_hook_dbmlsync_schema_upgrade stored procedure. For more information, see sp_hook_dbmlsync_schema_upgrade.

For more information about changing schemas for Adaptive Server Anywhere remote databases, see sp_hook_dbmlsync_schema_upgrade.


UltraLite remote databases

You can change the schema of a remote UltraLite database by deploying a new application or through a schema upgrade.

  • If you deploy a new application without a schema upgrade, you need to repopulate the UltraLite database by synchronizing with the MobiLink synchronization server.

  • In the schema upgrade case, your data will be preserved. It is usually impractical to have all users upgrade to the new version of the application at the same time.

You need to be able to have both versions co-existing in the field and synchronizing with a single consolidated database. You can create two or more versions of the synchronization scripts that are stored in the consolidated database and control the actions of the MobiLink synchronization server. Each version of your application can then select the appropriate set of synchronization scripts by specifying the correct version name when it initiates synchronization.

For more information about schemas in UltraLite, see Creating UltraLite databases and schemas.


File-Based Downloads

About this chapter

This chapter describes an alternative way to download data to Adaptive Server Anywhere remote databases: downloads can be distributed as files, enabling offline distribution of synchronization changes. This allows you to create a file once and distribute it to many remote databases.

This chapter provides a complete description of how to use file-based downloads and then provides two in-depth examples that demonstrate how to set it up.


Introduction

With file-based downloads, you can put download synchronization changes in a file and transfer it to Adaptive Server Anywhere remote databases in any way a file can be transferred. For example,

  • broadcast the data by satellite multicast

  • apply the update using Sybase Manage Anywhere

  • e-mail or ftp the file to users

You choose the users you want to receive the file. Full synchronization integrity is preserved in file-based downloads, including conflict detection and resolution. You can ensure that the file is secure by applying third-party encryption on the file.

When to use

File-based downloads are useful when a large amount of data changes on the consolidated database, but the remote database does not update the data frequently or does not do any updates at all. For example, price lists, product lists, and code tables.

File-based downloads are not useful when the downloaded data is updated frequently on the remote database or when you are running frequent upload-only synchronizations. In these situations, the remote sites may be unable to apply download files because of integrity checks that are performed when download files are applied.

File-based downloads cannot be used as the sole means of updating remote databases. You still need to regularly perform full synchronizations or upload-only synchronizations. Full or upload-only synchronizations are required to advance log offsets and to maintain the log file, which otherwise will grow large and slow down synchronization. A full synchronization may also be required to recover from errors.

File-based downloads currently can be used only with Adaptive Server Anywhere remote databases.


Setting up file-based downloads

To set up file-based download, you:

  1. Create a file-definition database.

  2. At the consolidated database, create scripts with a new script version.

  3. Create a download file.

  4. Apply the download file.

Complete instructions follow.


Create the file-definition database

To set up file-based downloads, you create a file-definition database. This is an Adaptive Server Anywhere database that has the same synchronization tables and publications as your remote databases. It can be located anywhere. This database contains no data or state information. It does not have to be backed up or maintained; in fact, you can delete it and recreate it as needed.

The file-definition database must include the following:

  • the same publications as the remote databases, as well as the tables and columns used in the publication, the foreign key relationships and constraints of those tables and columns, and the tables required by those foreign key relationships.

  • a MobiLink user name that identifies the group of remote databases that are to apply the download file. You will use this group MobiLink user name in your synchronization scripts to identify the group of remote databases.


Changes at the consolidated database

On the consolidated database, create a new script version for your file-based downloads, and implement any scripts required by your existing synchronization system into it. Upload scripts are not required. This script version will be used only for file-based downloads. For this script version, all scripts that take MobiLink user names as parameters will instead take a MobiLink user name that refers to a group of remote databases. This is the user name that is defined in the file-definition database.

For each script version that you have defined, implement a begin_publication script.

For timestamp-based downloads, implement a modify_last_download_timestamp script for each script version. How you implement this script depends on how much data you intend to send in each download file. For example, one approach is to use the earliest time that any user from the group last downloaded successfully. Remember that the ml_username parameter passed to this script is actually the group name.

For more information, see modify_last_download_timestamp connection event.


Creating the download file

The download file contains the data to be synchronized. To create the download file, set up your file-definition database and consolidated database as described above. Run dbmlsync with the -bc option and supply a file name with the extension .df. For example,

dbmlsync -c "uid=dba;pwd=sql;eng=fbdl_eng;dbf=fdef.db" -v+
   -e "sv=filebased" -bc file1.df

Optionally, you can specify options when you create the download file:

  • -be option Use -be to add a string to the download file that can be accessed at the remote database using the sp_hook_dbmlsync_validate_download_file stored procedure.

    For more information, see -be option sp_hook_dbmlsync_validate_download_fileand .

  • -bg option Use the -bg option to create a download file that can be used by remotes that have never synchronized.

    Use the -bg option to create a download file that can be used by remotes that have never synchronized.


Synchronizing new remotes

If you want to apply a download file to a remote database that has never synchronized using MobiLink, then before you apply the download file you need to either perform a normal synchronization on the remote database or use the dbmlsync -bg option when creating the download file.

For timestamp-based synchronization, doing either of these two things causes the download of an initial snapshot of the data. For both timestamp and snapshot based synchronization, this step sets the generation number to the value that is generated by the begin_publication script on the consolidated database.

Perform a normal synchronization

You can prepare a remote database to receive download files by performing a synchronization that does not use a download file.

Use the -bg option

Alternatively, you can create a download file with the -bg option to use with remotes that haven't yet synchronized. You apply this initial download file to prepare the remote database for file-based synchronization.

  • Snapshot downloads If you are performing snapshot downloads, then the initial download file just needs to set the generation number. You may choose to include an initial snapshot of the data in this file, but since each snapshot download contains all the data and does not depend on previous downloads, this is not required.

    For snapshot downloads, using the -bg option is straightforward. Just specify -bg in the dbmlsync command line when you create the download file. You can use the same script version to create the initial download file as you use for subsequent download files.

  • Timestamp-based downloads If you are performing timestamp-based downloads, then the initial download must set the generation number on the remote database and include a snapshot of the data. With timestamp-based downloads, each download builds on previous ones. Each download file contains a last download timestamp. All rows changed on the consolidated after the file's last download timestamp are included in the file. To apply a file, a remote database must already have received all the changes that occurred before the file's last download timestamp. This is confirmed by checking that the file's last download timestamp is greater than or equal to the remote database's last download timestamp (the time up to which the remote database has received all changes from the consolidated database).

    Before a remote can apply its first normal download file, it must receive all data changed before that file's last download timestamp and after January 1, 1900. The initial download file created with the -bg option must contain this data. The easiest way to select this data is to create a separate script version that uses the same download_cursor's as your normal file-based synchronization script version but does not have a modify_last_download_timestamp script. If no modify_last_download_timestamp script is defined, then the last download timestamp for a file-based download will default to January 1, 1900.

If you apply download files built with the -bg option to remote databases that have already synchronized, the -bg option causes the generation numbers on the remote database to be updated with the value on the consolidated database at the time the download file was created. This defeats the purpose of generation numbers, which is to prevent you from applying further file-based downloads until an upload has been performed in situations such as when recovering a consolidated database that is lost or corrupted.

For more information about generation numbers, see MobiLink generation numbers.


Validation checks

Before applying a download file to a remote database, dbmlsync does a number of things to ensure that the synchronization is valid.

  • dbmlsync checks the download file to ensure that the file-definition database that was used to create it has:

    • the same publication as the remote database

    • the same tables and columns used in the publication

    • the same foreign key relationships and constraints as those tables and columns

  • dbmlsync checks to see if there is any data in the publication that has not been uploaded from the remote. If there is, the download file is not applied, because applying the download file could cause pending upload data to be lost.

  • dbmlsync checks the last download timestamp, next last download timestamp, and creation time of the download file to ensure that:

    • newer data on the remote database will not be overwritten by older data contained in the download file.

    • a download file will not be applied if applying it means that the remote database would miss some changes that have occurred on the consolidated database. This situation might occur if the remote did not apply previous file-based downloads.

      For more information, see Automatic validation.

  • Optionally, dbmlsync checks the generation number in the remote database to ensure it matches the generation number in the download file.

    For more information, see MobiLink generation numbers.

  • Optionally, you can create custom validation logic with the sp_hook_dbmlsync_validate_download_file stored procedure.

    For more information, see Custom validation.


Automatic validation

Before applying a download file, dbmlsync performs special checks on the last download timestamp, next last download timestamp, download file creation time, and transaction log.

Last download timestamp and next last download timestamp

Each download file contains all changes to be downloaded that occurred on the consolidated database between the file's last download timestamp, and its next last download timestamp. Both times are expressed in terms of the time at the consolidated database. By default the file's last download time is Jan 1, 1900 12:00 AM and the file's next last download timestamp is the time the download file was created. These defaults can be overridden by implementing the modify_last_download_timestamp and modify_next_last_download_timestamp scripts on the consolidated database.

A remote site can apply a download file only if the file's last download timestamp is less than or equal to the remote's last download timestamp. This ensures that a remote never misses operations that occur on the consolidated database. Usually when a file-based download fails based on this check, the remote has missed one or more download files. The situation can be corrected by applying the missing download files or by performing a full or download-only synchronization.

In addition, a remote site can apply a download file only if the file's next last download timestamp is greater than the remote's last download timestamp. The remote's last download timestamp is the time (at the consolidated database) up to which the remote has received all changes that are to be downloaded. The remote database's last download time is updated each time the remote successfully applies a download (normal or file-based). This check ensures that a download file will not be applied if more recent data has already been downloaded. A common case where this could happen occurs when download files are applied out of order. For example, suppose a download file F1.df is created, and another file F2.df is created later. This check ensures that F1.df cannot be applied after F2.df, because that could allow newer data in F2.df to be overwritten with older data in F1.df.

When a file-based download fails based on the next last download timestamp, no additional action is required other than to delete the file. Synchronization will succeed once a new file is received.

Creation time

The download file's creation time indicates the time at the consolidated database when creation of the file began. A download file can only be applied if the file's creation time is greater than the remote database's last upload time. The remote's last upload time is the time at the consolidated database when the remote's last successful upload was committed. This check ensures that data that has been uploaded after the creation of the download (and hence is newer than the download) will not be overwritten by older data in the download file.

When a download file is rejected based on this check, no action is required. The remote site should be able to apply the next download file.

When an upload fails because dbmlsync sent an upload to the MobiLink synchronization server but got no acknowledgement, the remote database's last upload time may be incorrect. In this case, the creation time check cannot be performed and the remote is unable to apply download files until it completes a normal synchronization.

Transaction log

Before applying a download file, dbmlsync scans the remote database's transaction log and builds up a list of all changes that must be uploaded. Dbmlsync will only apply a download file if it does not contain any operations that affect rows with changes that must be uploaded.


MobiLink generation numbers

Generation numbers provide a mechanism for forcing remote databases to upload data before applying any more download files. This is especially useful when a problem on the consolidated database has resulted in data loss and you must recover lost data from the remote databases.

On the remote database, a separate generation number is automatically maintained for each subscription. On the consolidated database, the generation number for each subscription is determined by the begin_publication script. Each time a remote performs a successful upload, it updates the remote generation number with the value set by the begin_publication script in the consolidated database.

Each time a download file is created, the generation number set by the begin_publication script is stored in the download file. A remote site will only apply a download file if the generation number in the file is equal to the generation number stored in the remote database.

Note
Whenever the generation number generated by the begin_publication script for a file-based download changes, the remote databases must perform a successful upload before they can apply any new download files.

The sp_hook_dbmlsync_validate_download_file stored procedure can be used to override the default checking of the generation number.

For more information about managing MobiLink generation numbers, see:

  • begin_publication connection event

  • end_publication connection event

  • sp_hook_dbmlsync_validate_download_file


Custom validation

You can create custom validation logic to determine if a download file should be applied to a remote database. You do this with the sp_hook_dbmlsync_validate_download_file stored procedure. With this stored procedure, you can both reject a download file and override the default checking of the generation number.

You can use the dbmlsync -be option to embed a string in the file. You use the -be option against the file-definition database when you create the download file This string is passed to the sp_hook_dbmlsync_validate_download_file through the #hook_dict table, and can be used in your validation logic.

For more information, see sp_hook_dbmlsync_validate_download_file.


Examples

This section contains two very simple examples. Each sets up a file-based download synchronization using a consolidated database with only one table. The first is a snapshot example and the second is a timestamp-based example.


Snapshot example

This example implements file-based download for snapshot synchronization. It set up the three databases that are required by the file-based download, and then demonstrates how to download data. This example is presented in such a way that you can either just read through it, or you can cut and paste the text to run the sample.

Create databases for the sample

The following commands create the three databases used in the example: a consolidated database, a remote database, and a file-definition database.

dbinit scons.db
dbinit sremote.db
dbinit sfdef.db

The following commands start the three databases, create a data source name for MobiLink to use to connect to the consolidated database, and start the MobiLink synchronization server.

dbeng9 -n sfdef_eng sfdef.db
dbeng9 -n scons_eng scons.db
dbeng9 -n sremote_eng sremote.db
dbdsn -y -w fbd_demo -c "eng=scons_eng;dbf=scons.db;uid=dba;
   pwd=sql;astart=off;astop=off"
start dbmlsrv9 -v+ -c "dsn=fbd_demo"
   -zu+ -ot scons.txt
Set up the snapshot example consolidated database

In this example, the consolidated database has one table, called T1. After connecting to the consolidated database, you can run the following SQL to create table T1:

CREATE TABLE T1 (
   pk   INTEGER PRIMARY KEY,
   c1   INTEGER
);

The following code creates a script version called filebased and creates a download script for that script version.

CALL ml_add_table_script( 'filebased',
  'T1', 'download_cursor',
    'SELECT pk, c1 FROM T1' );

The following code creates a script version called normal and creates upload and download scripts for that script version.

CALL ml_add_table_script ( 'normal', 'T1',
  'upload_insert',
  'INSERT INTO T1 VALUES (?,?)');
CALL ml_add_table_script( 'normal', 'T1',
  'upload_update',
  'UPDATE T1 SET c1 = ? WHERE pk = ? ' );

CALL ml_add_table_script( 'normal', 'T1',
 'upload_delete',
   'DELETE FROM T1 WHERE pk = ?' );

CALL ml_add_table_script( 'normal', 'T1',
  'download_cursor',
    'SELECT pk, c1 FROM T1' );

COMMIT;

The following command creates the stored procedure begin_pub and specifies that begin_pub is the begin_publication script for both the "normal" and "filebased" script versions:

CREATE PROCEDURE begin_pub (
       INOUT generation_num integer,
           IN    username       varchar(128),
           IN    pubname        varchar(128) )
BEGIN
   SET gnum=1;
END;

CALL ml_add_connection_script(
  'filebased',
  'begin_publication',
      '{ call begin_pub( ?, ?, ? ) }' );

CALL ml_add_connection_script( 'normal',
  'begin_publication',
      '{ call begin_pub( ?, ?, ? ) }' );
Create the snapshot example remote database

In this example, the remote database also contains one table, called T1. Connect to the remote database and run the following SQL to create the table T1, a publication called P1, and a user called U1. The SQL also creates a subscription for U1 to P1.

CREATE TABLE T1 (
   pk   INTEGER PRIMARY KEY,
   c1   INTEGER
);

CREATE PUBLICATION P1 (
    TABLE T1
);
CREATE SYNCHRONIZATION USER U1;

CREATE SYNCHRONIZATION SUBSCRIPTION
TO P1
FOR U1;

The following code creates an sp_hook_dbmlsync_validate_download_file hook to implement user-defined validation logic in the remote database:

CREATE PROCEDURE sp_hook_dbmlsync_validate_download_file()
BEGIN
    DECLARE udata   varchar(256);
SELECT value
    INTO udata
    FROM #hook_dict
    WHERE name = 'user data';
    IF udata <> 'ok' THEN
    UPDATE #hook_dict
      SET value = 'FALSE'
      WHERE name = 'apply file';
    END IF;
END
Create the snapshot example file-definition database

A file-definition database is required in MobiLink systems that use file-based downloads. This database has the same schema as the remote databases being updated by file-based download, and it contains no data or state information. The file-definition database is used solely to define the structure of the data that is to be included in the download file. One file-definition database can be used for many groups of remote databases, each defined by its own MobiLink group user name.

The following code defines the file-definition database for this sample. It creates a schema that is identical to the remote database, and also creates:

  • a publication called P1 that publishes all rows of the T1 table. The same publication name must be used in the file-definition database and the remote databases.

  • a MobiLink user called G1. This user represents all the remotes that are to be updated in the file-based download.

  • a subscription to the publication

You must connect to sfdef.db before running this code.

CREATE TABLE T1 (
   pk   INTEGER PRIMARY KEY,
   c1   INTEGER
);
CREATE PUBLICATION P1 (
    TABLE T1
);

CREATE SYNCHRONIZATION USER G1;
CREATE SYNCHRONIZATION SUBSCRIPTION
TO P1
FOR G1;
Prepare for initial synchronization

To prepare your new remote database so that you can apply a download file, you need to either perform a normal synchronization or create the download file with the dbmlsync -bg option. This example shows you how to initialize your new remote database by performing a normal synchronization.

You can perform an initial synchronization of the remote database with the script version called normal that was created earlier:

dbmlsync -c "uid=dba;pwd=sql;eng=sremote_eng;
  dbf=sremote.db" -v+ -e "sv=normal"
Demonstrate the snapshot example file-based download

Connect to the consolidated database and insert some data that will be synchronized by file-based download, such as the following:

INSERT INTO T1 VALUES( 1, 1 );
INSERT INTO T1 VALUES( 2, 4 );
INSERT INTO T1 VALUES( 3, 9 );
COMMIT;

The following command must be run on the computer that holds the file-definition database. It does the following:

  • the dbmlsync -bc option creates the download file, and names it file1.df.

  • the -be option includes the string "OK" in the download file that will be accessible to the sp_dbmlsync_validate_download_file hook.

dbmlsync -c
   "uid=dba;pwd=sql;eng=sfdef_eng;dbf=sfdef.db"
   -v+ -e "sv=filebased" -bc file1.df -be ok -ot fdef.txt

To apply the download file, run dbmlsync with the -ba option on the remote database, supplying the name of the download file you want to apply:

dbmlsync -c "uid=dba;pwd=sql;eng=sremote_eng;
   dbf=sremote.db" -v+ -ba file1.df -ot remote.txt

The changes are now applied to the remote database. Open Interactive SQL, connect to the remote database, and run the following SQL command to verify that the remote has the data:

SELECT * FROM T1
Clean up the snapshot example

The following commands stop all three database engines and erase the files.

del file1.df
dbmlstop -h -w
dbstop -y -c eng=sfdef_eng
dbstop -y -c eng=scons_eng
dbstop -y -c eng=sremote_eng
dberase -y sfdef.db
dberase -y scons.db
dberase -y sremote.db


Timestamp-based example

This example implements file-based download for timestamp-based synchronization. It set up the three databases that are required by the file-based download, and then demonstrates how to download data with this functionality. This example is presented in such a way that you can either just read through it, or you can cut and paste the text to run the sample.

Create databases for the sample

The following commands create the three databases used in the example: a consolidated database, a remote database, and a file-definition database.

dbinit tcons.db
dbinit tremote.db
dbinit tfdef.db

The following commands start the three databases, create a data source name for MobiLink to use to connect to the consolidated database, and start the MobiLink synchronization server.

dbeng9 -n tfdef_eng tfdef.db
dbeng9 -n tcons_eng tcons.db
dbeng9 -n tremote_eng tremote.db
dbdsn -y -w tfbd_demo -c "eng=tcons_eng;dbf=tcons.db;uid=dba;
   pwd=sql;astart=off;astop=off"
start dbmlsrv9 -v+ -c "dsn=tfbd_demo" -zu+ -ot tcons.txt
Set up the timestamp example consolidated database

In this example, the consolidated database has one table, called T1. After connecting to the consolidated database, you can run the following code to create T1:

CREATE TABLE T1 (
   pk      INTEGER PRIMARY KEY,
   c1      INTEGER,
   last_modified   TIMESTAMP DEFAULT TIMESTAMP
);

The following code defines a script version called normal with a minimal number of scripts. This script version is used for synchronizations that do not use file-based download.

CALL ml_add_table_script( 'normal', 'T1',
   'upload_insert',
     'INSERT INTO T1( pk, c1) VALUES( ?, ? )' );

CALL ml_add_table_script( 'normal', 'T1',
   'upload_update',
   'UPDATE T1 SET c1 = ? WHERE pk = ? ' );

CALL ml_add_table_script( 'normal', 'T1',
   'upload_delete',
     'DELETE FROM T1 WHERE pk = ?' );

CALL ml_add_table_script( 'normal', 'T1',
   'download_cursor',
     'SELECT pk, c1 FROM T1 WHERE last_modified >= ?' );

The following code sets the generation number for all subscriptions to 1. It is good practice to use generation numbers in case your consolidated database ever becomes lost or corrupted and you need to force an upload.

CREATE PROCEDURE begin_pub (
       INOUT generation_num integer,
           IN    username       varchar(128),
           IN    pubname        varchar(128) )
BEGIN
   SET generation_num = 1;
END;

CALL ml_add_connection_script( 'normal',
    'begin_publication',
            '{ call begin_pub( ?, ?, ? ) }' );

COMMIT;

The following code defines the script version called filebased. This script version is used to create file-based downloads.

CALL ml_add_connection_script( 'filebased',
    'begin_publication',
            '{ call begin_pub( ?, ?, ? ) }' );

CALL ml_add_table_script( 'filebased', 'T1',
    'download_cursor',
      'SELECT pk, c1 FROM T1 WHERE last_modified >= ?' );

The following code sets the last download time so that all changes that occurred within the last five days will be included in download files. Any remote that has missed all the download files created in the last five days will have to perform a normal synchronization before being able to apply any more file-based downloads.

CREATE PROCEDURE ModifyLastDownloadTimestamp(
             INOUT last_download_timestamp TIMESTAMP,
             IN    ml_username             VARCHAR(128) )
BEGIN
    SELECT dateadd( day, -5, CURRENT TIMESTAMP )
    INTO last_download_timestamp;
END;

CALL ml_add_connection_script( 'filebased',
   'modify_last_download_timestamp',
         'CALL ModifyLastDownloadTimestamp( ?, ? )' );

COMMIT;
Create the timestamp example remote database

In this example, the remote database also contains one table, called T1. After connecting to the remote database, run the following code to create table T1, a publication called P1, and a user called U1. The code also creates a subscription for U1 to P1.

CREATE TABLE T1 (
   pk   INTEGER PRIMARY KEY,
   c1   INTEGER
);

CREATE PUBLICATION P1 (
    TABLE T1
);

CREATE SYNCHRONIZATION USER U1;

CREATE SYNCHRONIZATION SUBSCRIPTION
TO P1
FOR U1;

The following code defines a sp_hook_dbmlsync_validate_download_file stored procedure. This stored procedure prevents the application of download files that do not have the string "ok" embedded in them.

CREATE PROCEDURE sp_hook_dbmlsync_validate_download_file()
BEGIN
    DECLARE udata   varchar(256);

    SELECT value
    INTO udata
    FROM #hook_dict
    WHERE name = 'user data';

    IF udata <> 'ok' THEN
      UPDATE #hook_dict
        SET value = 'FALSE'
        WHERE name = 'apply file';
    END IF;
END
Create the timestamp example file-definition database

The following code defines the file-definition database for the timestamp example. It creates a table, a publication, a user, and a subscription for the user to the publication.

CREATE TABLE T1 (
   pk   INTEGER PRIMARY KEY,
   c1   INTEGER
);

CREATE PUBLICATION P1 (
    TABLE T1
);

CREATE SYNCHRONIZATION USER G1;

CREATE SYNCHRONIZATION SUBSCRIPTION
TO P1
FOR G1;
Prepare for initial synchronization

To prepare your new remote database so that you can apply a download file, you need to either perform a normal synchronization or create the download file with the dbmlsync -bg option. This example shows you how to use -bg.

The following code defines a script version called filebased_init for the consolidated database. This script version has a single begin_publication script.

CALL ml_add_table_script(
  'filebased_init', 'T1', 'download_cursor',
    'SELECT pk, c1 FROM T1' );

CALL ml_add_connection_script(
  'filebased_init',
  'begin_publication',
      '{ call begin_pub( ?, ?, ? ) }' );

COMMIT;

The following two command lines create and apply an initial download file using the script version called filebased_init and the -bg option.

dbmlsync -c "uid=dba;pwd=sql;eng=tfdef_eng;dbf=tfdef.db"
  -v+ -e "sv=filebased_init" -bc tfile1.df -be ok -bg
  -ot tfdef1.txt

dbmlsync -c "uid=dba;pwd=sql;eng=tremote_eng;dbf=tremote.db"
  -v+ -ba tfile1.df -ot tremote.txt
Demonstrate the timestamp example file-based download

Connect to the consolidated database and insert some data that will be synchronized by file-based download, such as the following:

INSERT INTO T1(pk, c1) VALUES( 1, 1 );
INSERT INTO T1(pk, c1) VALUES( 2, 4 );
INSERT INTO T1(pk, c1) VALUES( 3, 9 );
commit;

The following command line creates a download file containing the new data.

dbmlsync -c
   "uid=dba;pwd=sql;eng=tfdef_eng;dbf=tfdef.db"
   -v+ -e "sv=filebased" -bc tfile2.df -be ok -ot tfdef2.txt

The following command line applies the download file to the remote database.

dbmlsync -c "uid=dba;pwd=sql;eng=tremote_eng;dbf=tremote.db"
   -v+ -ba tfile2.df -ot tfdef3.txt

The changes are now applied to the remote database. Open Interactive SQL, connect to the remote database, and run the following SQL command to verify that the remote has the data:

SELECT * FROM T1
Clean up the timestamp example

The following commands stop all three database engines and then erase the files.

del file1.df
dbmlstop -h -w
dbstop -y -c eng=tfdef_eng
dbstop -y -c eng=tcons_eng
dbstop -y -c eng=tremote_eng
dberase -y tfdef.db
dberase -y tcons.db
dberase -y tremote.db


MobiLink Performance

About this chapter

This chapter provides information that can help you improve the performance of your MobiLink synchronization.

For more information about MobiLink performance, see the MobiLink Performance whitepaper at [external link] http://my.sybase.com/detail?id=1009664.

For a hands-on description of how to monitor performance, see Tutorial: Writing MobiLink Scripts and Monitoring Synchronizations.


Performance tips

Following are some suggestions to help you get the best performance out of MobiLink.

  • Test Before deploying, perform volume testing using the same hardware and network that you plan to use for production. Use this time to experiment with the following performance tips.

  • Avoid contention Avoid contention in your synchronization scripts. Another way of putting this is that you should maximize concurrency.

    For example, suppose a begin_download script increments a column in a table to count the total number of downloads. If multiple users synchronize at the same time, this script would effectively serialize their downloads. The same counter would be better in the begin_synchronization or end_synchronization script because these scripts are called just before a commit.

    For more information about contention, see Contention.

    For information on the transaction structure of synchronization, see Transactions in the synchronization process.

  • Use an optimal number of worker threads Use the MobiLink –w option to set the number of MobiLink worker threads to the smallest number that gives you optimum throughput. You will need to experiment to find the best number for your situation.

    A larger number of worker threads can improve throughput by allowing more synchronizations to occur at the same time.

    Keeping the number of worker threads small reduces the chance of contention in the consolidated database, the number of connections to the consolidated database, and the memory required for optimal caching.

    For example, in tests with fast clients, it was discovered that approximately five worker threads gave optimum throughput. For slower clients, more worker threads were needed to maximize download throughput, and the best upload throughput was obtained by limiting the number that can simultaneously upload, via the -wu option. In tests with extremely slow clients, the best throughput for both uploads and downloads was obtained with hundreds of worker threads with only five allowed to upload simultaneously. Note that these numbers are from a specific set of tests. Every deployment has different characteristics, and you must test to determine the optimal values for -w and -wu.

    For more information about worker threads, see Number of worker threads.

    For more information, see -w option and -wu option.

  • Enable the client-side download buffer for ASA clients

    For Adaptive Server Anywhere clients, a download buffer allows a MobiLink worker thread to transmit the download without waiting for the client to apply the download. The download buffer is enabled by default. However, the download buffer cannot be used if download acknowledgement is enabled (see next bullet).

    For more information about setting the download buffer size, see the DownloadBufferSize (dbs) extended option.

  • Do not enable download acknowledgement for ASA clients By default, download acknowledgement is not enabled. This frees up MobiLink worker threads that otherwise would be waiting for confirmation of successful download from the client, which also frees up the connection that the worker thread is using. It also makes it possible for the MobiLink synchronization server to buffer the downloads.

    UltraLite clients do not buffer downloads, so the benefit of not acknowledging downloads is not as great.

    For more information about download acknowledgements, see the SendDownloadACK (sa) extended option.

  • Set the upload cache size To avoid the situation where the upload cache overflows to disk, set the upload cache size to be larger than the size of your largest upload stream times the number of worker threads. You set the upload cache size with the dbmlsrv9 –u option.

    For more information, see -u option.

  • Set the download cache size To avoid the situation where the download buffer overflows to disk, set the download cache size to be larger than the size of your largest download times the number of worker threads. You set the download cache size with the dbmlsrv9 -d option.

    For more information about setting the memory allocated to the download buffer, see -d option.

  • Set the BLOB cache size If your rows have data of type LONG VARCHAR or LONG BINARY, you can avoid having the BLOB cache access disk if you set the BLOB cache size to be larger than twice the largest BLOB data in a row times the number of worker threads. You set the BLOB cache size with the dbmlsrv9 -bc option.

    For more information, see -bc option.

  • Set maximum number of database connections

    Set the maximum number of MobiLink database connections to be your typical number of synchronization script versions times the number of MobiLink worker threads, plus one. This reduces the need for MobiLink to close and create database connections. You set the maximum number of connections with the dbmlsrv9 -cn option.

    For more information, see MobiLink database connections and -cn option.

  • Have sufficient physical memory Ensure that the computer running MobiLink has enough physical memory to accommodate the upload, download and BLOB caches in addition to its other memory requirements.

  • Use sufficient processing power Dedicate enough processing power to MobiLink so that the MobiLink server processing is not a bottleneck. In tests with an Adaptive Server Anywhere consolidated database, MobiLink required a third to a half of the processing required by Adaptive Server Anywhere when both were stressed and executing on the same computer.

  • Use minimum logging verbosity Use the minimum logging verbosity that is compatible with your business needs. By default, verbose logging is off, and MobiLink does not write its log to disk. You can control logging verbosity with the -v option, and enable logging to a file with the -o or -ot options.

    As an alternative to verbose log files, you can monitor your synchronizations with the MobiLink Monitor. The Monitor does not need to be on the same computer as the MobiLink synchronization server, and a Monitor connection has negligible effect on MobiLink server performance. For more information, see MobiLink Monitor.

  • Java or .NET vs. SQL synchronization logic No significant throughput difference has been found between using Java or .NET synchronization logic vs. SQL synchronization logic. However, Java and .NET synchronization logic have some extra overhead per synchronization and require more memory.

    In addition, SQL synchronization logic is executed on the computer that runs the consolidated database, while Java or .NET synchronization logic is executed on the computer that runs the MobiLink server. Thus, Java or .NET synchronization logic may be desirable if your consolidated database is heavily loaded.

  • Priority synchronization If you have some tables that you need to synchronize more frequently than others, create a separate publication and subscription for them. You can synchronize this priority publication more frequently than other publications, and synchronize other publications at off-peak times.

  • Download only the rows you need Take care to download only the rows that are required. It is easier to write synchronization scripts that download all rows upon each synchronization, but downloading unneeded rows affects synchronization performance.

  • Optimize script execution The performance of your scripts in the consolidated database is an important factor. It may help to create indexes on your tables so that the upload and download cursor scripts can efficiently locate the required rows. However, too many indexes may slow uploads.

  • For large uploads from ASA clients, estimate the number of rows You can significantly improve the speed of uploading a large number of rows by providing dbmlsync with an estimate of the number of rows that will be uploaded. You do this with the dbmlsync -urc option.

    For more information, see -urc option.


Key factors influencing MobiLink performance

The overall performance of any system, including throughput for MobiLink synchronization, is usually limited by a bottleneck at one point in the system. For MobiLink synchronization, the following might be the bottlenecks limiting synchronization throughput:

  • The performance of the consolidated database Of particular importance for MobiLink is the speed at which it can execute the MobiLink scripts. Multiple worker threads might execute scripts simultaneously, so for best throughput you need to avoid database contention in your synchronization scripts.

  • The bandwidth for MobiLink to consolidated communication This is unlikely to be a bottleneck if both MobiLink and the consolidated database are running on the same computer, or if they are on separate computers connected by a high-speed network.

  • The speed of the computer running MobiLink If the processing power of the computer running MobiLink is slow, or if it does not have sufficient memory for the MobiLink worker threads and buffers, then MobiLink execution speed could be a synchronization bottleneck. The MobiLink server's performance depends little on disk speed as long as the buffers and worker threads fit in physical memory.

  • The number of MobiLink worker threads A smaller number of threads will involve fewer database connections, less chance of contention in the consolidated database and less operating system overhead. However, too small a number may leave clients waiting for a free worker thread, or have fewer connections to the consolidated database than it can overlap efficiently.

  • The bandwidth for client-to-MobiLink communications For slow connections, such as those over dial-up or wide-area wireless networks, the network may cause clients and MobiLink worker threads to wait for data to be transferred.

  • The client processing speed Slow client processing speed is more likely to be a bottleneck in downloads than uploads, since downloads involve more client processing as rows and indexes are written.

Tuning MobiLink for performance


Tuning MobiLink for performance

The key to achieving optimal MobiLink synchronization throughput is to have multiple synchronizations occurring simultaneously and executing efficiently. To enable multiple simultaneous synchronizations, MobiLink assigns a worker thread to each synchronization. A worker thread receives the changes uploaded from the client and applies them to the consolidated database. It then fetches the changes from the consolidated database, and downloads them to the client. Each worker thread uses a single connection to the consolidated database for applying and fetching changes, using your synchronization scripts.

Contention

The most important factor is to avoid database contention in your synchronization scripts. Just as with any other multi-client use of a database, you want to minimize database contention when clients are simultaneously accessing a database. Database rows that must be modified by each synchronization can increase contention. For example, if your scripts increment a counter, then updating that counter can be a bottleneck.

The figure below shows the following:

  • a pool of connections to the consolidated database, shown as C1 to Cn

  • a number of synchronization requests, shown as S1 to Sn

  • MobiLink worker threads, shown as W1 to Wn

MobiLink database connections, worker threads, and synchronizations.

If there are more synchronization requests than worker threads, the excess requests are queued until a worker thread becomes available after completing a synchronization. You can control the number of worker threads and connections, but MobiLink will always ensure that there is at least one connection per worker thread. If there are more connections than worker threads, the excess connections will be idle. Excess connections may be useful with multiple script versions, as discussed below.

Number of worker threads

Other than contention in your synchronization scripts, the most important factor for synchronization throughput is the number of worker threads. The number of worker threads controls how many synchronizations can proceed simultaneously.

Testing is vital to determine the optimum number of worker threads.

Increasing the number of worker threads allows more overlapping synchronizations, and increased throughput, but it will also increase resource and database contention between the overlapping synchronizations, and increase the time for individual synchronizations. As the number of worker threads is increased, the benefit of more simultaneous synchronizations becomes outweighed by the cost of longer individual synchronizations, and adding more worker threads decreases throughput. Experimentation is required to determine the optimal number of worker threads for your situation, but the following may help to guide you.

For uploads, performance testing shows that the best throughput happens with a relatively small number of worker threads: in most cases, three to ten worker threads. Variation depends on factors like the type of consolidated database, data volume, database schema, the complexity of the synchronization scripts, and the hardware used. The bottleneck is usually due to contention between worker threads executing the SQL of your upload scripts at the same time in the consolidated database.

For downloads, the optimum number of worker threads depends on the client to MobiLink bandwidth and the processing speed of clients. For slower clients, more worker threads are needed to get optimal download performance. This is because downloads involve more client processing and less consolidated database processing than uploads.

For Adaptive Server Anywhere clients, leaving download acknowledgement off (and not disabling the optional download buffering) can reduce the optimal number of worker threads for download, because worker threads do not have to wait for clients to apply downloads. There is little effect for UltraLite clients since UltraLite clients apply the download as it is received, without buffering.

For more information on disabling the download acknowledgement, see the SendDownloadACK (sa) extended option.

To get both the best download throughput and the best upload throughput, MobiLink provides two options. You can specify a total number of worker threads to optimize downloads. You can also limit the number that can simultaneously apply uploads to optimize upload throughput.

The -w option controls the total number of worker threads. The default is five.

The -wu option limits the number of worker threads that can simultaneously apply uploads to the consolidated database. By default, all worker threads can apply uploads simultaneously, but that can cause severe contention in the consolidated database. The -wu option lets you reduce that contention while still having a larger number of worker threads to optimize downloads and receive uploads. The -wu option only has an effect if the number is less than the total number of worker threads.

For more information, see -w option and -wu option.

MobiLink database connections

MobiLink creates a database connection for each worker thread. You can use the -cn option to specify that MobiLink create a larger pool of database connections, but any excess connections will be idle unless MobiLink needs to close a connection or use a different script version.

There are two cases where MobiLink will close a database connection and open a new one. The first case is if an error occurs. The second case is if the client requests a synchronization script version, and none of the available connections have already used that synchronization version.

Note
Each database connection is associated with a script version. To change the version, the connection must be closed and reopened.

If you have more than one synchronization version, you may want to set the maximum number of pooled connections to be larger than the number of worker threads, which is the default number. Then MobiLink will not need to close and open a new database connection each time a different synchronization version is requested.

If you routinely use more than one script version, you can reduce the need for MobiLink to close and open connections by increasing the number of connections. You can eliminate the need completely if the number of connections is the number of worker threads times the number of versions.

An example of tuning MobiLink for two script versions is given in the command line below:

dbmlsrv9 -c "dsn=ASA 9.0 Sample" -w 5 -cn 10

Since the maximum usable number of database connections is the number of script versions times the number of worker threads plus one, you can set -cn to 10 to ensure that database connections are not closed and opened to accommodate synchronization versions.

An example of tuning MobiLink for three script versions is:

dbmlsrv9 -c "dsn=ASA 9.0 Sample" -w 7 -cn 21

For more information on setting the number of connections for any number of script versions, see -cn option.


Monitoring MobiLink performance

There are a variety of tools available to help you monitor the performance of your synchronizations.

The MobiLink Monitor is a graphical tool for monitoring synchronizations. It allows you to see the time taken by every aspect of the synchronization, sorted by MobiLink user or by worker thread.

For more information, see MobiLink Monitor.

In addition, there are a number of MobiLink scripts that are available for monitoring synchronizations. These scripts allow you to use performance statistics in your business logic. You may, for example, want to store the performance information for future analysis, or alert a DBA if a synchronization takes too long. For more information, see

  • download_statistics connection event

  • download_statistics table event

  • synchronization_statistics connection event

  • synchronization_statistics table event

  • time_statistics connection event

  • time_statistics table event

  • upload_statistics connection event

  • upload_statistics table event


MobiLink Monitor

About this chapter

The MobiLink Monitor is a tool for monitoring MobiLink synchronizations. This chapter describes how to use the MobiLink Monitor.

For a hands-on description of how to use the Monitor, see Tutorial: Writing MobiLink Scripts and Monitoring Synchronizations.


Introduction

The MobiLink Monitor is a MobiLink administration tool that provides you with detailed information about the performance of your synchronizations.

When you start the Monitor and connect it to a MobiLink synchronization server, the Monitor begins to collect statistical information about all synchronizations that occur in that monitoring session. The Monitor continues to collect data until you disconnect it or shut down the MobiLink server.

You can view the data in tabular or graphical form in the Monitor interface. You can also save the data in binary format for viewing with the Monitor later, or in .csv format to open in another tool, such as Microsoft Excel; or you can export it to an ODBC data source such as a MobiLink-supported relational database.

Monitor output allows you to see a wide variety of information about your synchronizations. For example, you can quickly identify synchronizations that result in errors, or that meet other criteria that you specify. You can identify possible contention in synchronization scripts by checking to see if synchronizations of differing durations have phases that end around the same time (because synchronizations are waiting for a previous phase to finish before they can continue).

The MobiLink Monitor can be used routinely in development and production, because monitoring does not degrade performance, particularly when the Monitor is run on a different computer from the MobiLink synchronization server.


Starting the MobiLink Monitor

If synchronization is already occurring when the MobiLink Monitor is started, the Monitor must wait until a worker thread is free before it can start monitoring. Therefore, you may want to start the Monitor before starting synchronizations. Once the Monitor is running it does not use a MobiLink worker thread.

You can have one instance of the Monitor running for each MobiLink synchronization server.

toggle To start monitoring data

  1. From the Start menu, choose Programs > SQL Anywhere 9 > MobiLink > MobiLink Monitor.

    Alternatively, you can type dbmlmon at a command prompt. For details, see below.

  2. Start your consolidated database and MobiLink synchronization server, if they are not already running.

  3. In the MobiLink Monitor, choose Monitor > Connect to MobiLink Server.

    The Connect to MobiLink Server dialog appears.

    A Monitor connection starts like a synchronization connection to the MobiLink synchronization server. For example, if you started the MobiLink server with -zu+ then it doesn't matter what user ID you use here. For all MobiLink Monitor sessions, the script version is set to for_ML_Monitor_only.

    The Connect to MobiLink Server dialog should be completed as follows:

    • Host is the computer where the MobiLink synchronization server is running. By default, it is the computer where the Monitor is running.

    • Network Protocol should be set to the same protocol and port as the MobiLink synchronization server is using for synchronization requests.

    • Additional Network Parameters allows you to set optional parameters. You can set the following parameters, separated by semi-colon if you need to specify multiple parameters:

      • buffer_size=number (HTTP and HTTPS only)

      • client_port=nnnn

      • client_port=nnnn-mmmmm

      • persistent={0|1}

      • proxy_host=proxy_hostname (HTTP and HTTPS only)

      • proxy_port=proxy_portnumber (HTTP and HTTPS only)

      • url_suffix=suffix (HTTP and HTTPS only)

      • version=versionnumber (HTTP and HTTPS only)

      For more information about these network parameters, see Network protocol options for UltraLite synchronization clients.

  4. Start synchronizing.

    The data appears in the Monitor as it is collected.

Starting dbmlmon on the command line

Command line options allow you to have the Monitor open a file or connect to a MobiLink synchronization server on startup. Following is the syntax:

dbmlmon [ connect-options | inputfile.{ mlm | csv } | -? ]

where:

connect-options can be one or more of the following:

-u ml_username

-p password

-x { tcpip | http | https } [ ( keyword=value;... ) ]

The keyword=value pairs can be the host, protocol, and Additional Network Parameters as described above.

-o outputfile.{ mlm | csv }

The -o option closes the Monitor at the end of the connection and saves the session in the specified file.

-? You can type dbmlmon -? to view the dbmlmon syntax.

Note: The options -u and -x are required to connect.

toggle To stop the MobiLink Monitor

  1. In the Monitor, choose Monitor > Disconnect from MobiLink Server. This stops the collection of data.

    You can also stop collecting data by shutting down the MobiLink synchronization server or closing the Monitor.

    Before closing the Monitor, you can save the data for the session. For more information, see Saving Monitor data.

  2. When you are ready to close the Monitor, choose File > Close.


Using the MobiLink Monitor

The Monitor has three panes:

  • Details Table is the top pane. It is a spreadsheet that shows the total time taken by each synchronization, with a breakdown showing the amount of time taken by each part of the synchronization.

    For more information, see Details Table pane.

  • Chart is the middle pane. It provides a graphical representation of the data. The scale at the bottom of this pane represents time. You can select the data that is displayed in the Chart by drawing a box around data in the Overview pane; or by choosing View > Go To.

    For more information, see Chart pane.

  • Overview is the bottom pane. It shows an overview of all the data. To choose data to see in the Chart, click in the Overview and draw a box. The Chart will show everything that is located in the box.

    For more information, see Overview pane.

In addition, there is an Options dialog that you can use to customize the data, and properties dialogs for viewing more detailed information. For more information, see

  • Options dialog

  • Session properties

  • Synchronization properties


Details Table pane

The Details Table provides information about the duration of each part of the synchronization. All times are measured by the MobiLink synchronization server. Some times may be non-zero even when you do not have the corresponding script defined.

You can choose the columns that appear in the Details Table pane by opening Tools > Options and then opening the Table tab. For a description of the statistics that are available, see MobiLink statistical properties.

The following columns appear by default:

  • Sync Identifies each synchronization.

  • Worker Identifies the MobiLink worker thread that carried out the synchronization. The worker is identified as n.m, where n is the stream number and m is the thread number.

  • User Identifies the synchronization user.

  • Version The version of the synchronization script.

    For information about script versions, see Script versions .

  • Start_Time The date and time when the MobiLink synchronization server started the synchronization. (This may be later than when the synchronization was requested by the client.)

  • Duration The total duration of the synchronization, in seconds.

  • Verify_Upload The time in seconds for MobiLink to validate the synchronization request, validate the user name, and validate the password (if your synchronization setup requires authentication).

  • Preload_Upload The time in seconds for MobiLink to receive the uploaded data from the client.

  • Begin_Sync The time in seconds to run your begin_synchronization script, if one was run.

  • Upload The time in seconds to apply the upload to the consolidated database. This is the time between the begin_upload script and the end_upload script.

  • Prepare_for_Download The time in seconds to run your prepare_for_download script, if one was run.

  • Download The time in seconds to download the data. This is the time between the begin_download script and the end_download script. If download acknowledgement is enabled, this includes the time to apply the download on the remote database and return acknowledgement.

  • End_Sync The time in seconds to run the end_synchronization script, if one was run.

To sort the table by a specific column, click on the column heading. If new data is appearing in the Monitor, it will be sorted as it is added.

You can close the Details Table pane by clearing View > Details Table.


Chart pane

The Chart pane presents the same information as the Details Table, but in graphical format. The bars in the Chart represent the length of time taken by each synchronization, with subsections of the bars representing the phases of the synchronization.

Viewing data

Click a synchronization to select that synchronization in the Details Table.

Double-click a synchronization to open the Synchronization Session Properties for the synchronization. For more information, see Synchronization properties.

Grouping data by thread or user

You can group the data by worker thread or by user. Choose View > By User or View > By Worker Thread.

Zooming in on data

There are several ways to select the data that is visible:

  • Zoom options There are zoom options in the View menu and zoom buttons on the toolbar that allow you to zoom in and out. To have a synchronization fill the available space, use Zoom to Selection.

  • Scrollbar Click the scrollbar at the bottom of the Chart pane and slide it.

  • Go To dialog Open this dialog by choosing View > Go To. The Go To dialog appears.

    Start Date & Time lets you specify the start time for the data that appears in the Chart pane. If you change this setting, you must specify at least the year, month, and date of the date-time.

    Chart Range lets you specify the duration of time that is displayed. The chart range can be specified in milliseconds, seconds, minutes, hours, or days. The chart range determines the granularity of the data: a smaller length of time means that more detail is visible.

  • Overview Pane The box in the Overview pane indicates the area being displayed in the Chart. It allows you to quickly select a portion of data to view. You can easily resize or move the box to see different data, or see data at different granularity. If you make the box smaller you shorten the interval of the visible data in the Chart, which makes more detail visible. Click to move the current box without changing the zoom. Drag in the Overview to redraw the box and select a different zoom and position.

Time axis

At the bottom of the Chart pane there is a scale showing time periods. The format of the time is readjusted automatically depending on the span of time that is displayed. You can always see the complete date-time by hovering your cursor over the scale.

Default color scheme

You can view or set the colors in the Chart pane by opening the Options dialog (available from the Tools menu). The default color scheme for the Chart pane uses green for uploads, red for downloads, and blue for begin and end phases, with a darker shade for earlier parts of a phase.

For information about setting colors, see Options dialog.


Overview pane

The Overview pane shows you an overview of the entire Monitor session. The area that is currently displayed in the Chart pane is represented as a box in the Overview. Click in the Overview pane to move the box (and thus move the start time of the data shown in the Chart) or drag in the Overview to redraw the box to change the box's location and size (and thus change the start time and the range of data)

You can separate the Overview pane from the rest of the Monitor window. In the Options dialog, open the Overview tab and clear the Keep Overview Window Attached to Main Window checkbox.

For more information, see Options dialog.

You can close the Overview pane by clearing View > Overview Pane.


Options dialog

Options allow you to specify a number of settings, including colors and patterns for the graphical display in the Chart pane (the middle pane of the MobiLink Monitor) and the Overview pane (the bottom pane).

To open the Options dialog, open the Monitor and choose Tools > Options.

Restoring defaults

To restore default settings, delete the file .mlMonitorSettings. This file is stored in your user profiles directory.


Session properties

The Session Properties dialog provides basic information about the monitoring session.

To open the Session Properties dialog, open the Monitor and choose File > Properties.


Synchronization properties

Double-click a synchronization in either the Details Table or the Chart to see properties for that synchronization.

You can choose to see statistics for all tables (which is the sum for all tables in the synchronization), or for individual tables. The dropdown list provides a list of the tables that were involved in the synchronization.

For an explanation of the statistics in Synchronization Properties, see MobiLink statistical properties.


Saving Monitor data

You can save the data from a Monitor session as a binary file (.mlm), as a text file with comma-separated values (.csv), as tables in a relational database, or as a Microsoft Excel file.

Saving to file

To save the data as a file, choose File > Save As.

  • Save the data as a binary (.mlm) file if you want to view the saved data in the MobiLink Monitor. To reopen, choose File > Open.

  • Save the data as a comma separated file (.csv) if you want to view it in another tool, such as Microsoft Excel. This will save all the information in the session and synchronization property sheets, except per table information and the session begin and end time. You can also open a .csv file in the Monitor.

    In the .csv file format, time durations are stored in milliseconds.

You can specify that you want data to be saved automatically to a file. To do this, choose Tools > Options, and enter an output file name on the General tab. The output file is overwritten by new data.

Exporting to a relational database or Excel

You can also export Monitor data using an ODBC or JConnect connection. With JConnect, you can only export to Adaptive Server Anywhere or Adaptive Server Enterprise databases. With ODBC, you can export to any relational database that is supported by MobiLink, as well as to Excel.

When you export data, all the columns in your Monitor session are exported, as well as a column called export_time that identifies the time the export was performed.

The data source must have quoted identifiers enabled, because some of the columns are reserved words. The Monitor enables quoted identifiers automatically for Adaptive Server Anywhere, Adaptive Server Enterprise, and Microsoft SQL Server databases. If quoted identifiers is not enabled, the export will fail.

toggle To export the data to a database or Excel

  1. After collecting Monitor information, disconnect from the MobiLink synchronization server.

  2. In the MobiLink Monitor, choose File > Export to Database.

    The Export to Database dialog appears.

  3. Select options for the output.

    • You can name the two tables that will be created to hold the data, or use the defaults (mlm_by_sync and mlm_by_table). If the tables do not exist, they will be created by the Monitor. For Excel output, the two table names identify the two worksheets that are created.

    • Choose whether you want to overwrite data in existing tables. If you do not choose to overwrite the data, new data is appended to existing data.

  4. Click OK.

    A Connect dialog appears that allows you to connect to the database or Excel spreadsheet using ODBC or JConnect.


Customizing your statistics

The Watch Manager allows you to visibly distinguish synchronizations that meet criteria that you specify. For example, you might want to highlight big synchronizations, long synchronizations, small synchronizations that take a long time, or synchronizations that receive warnings.

To open the Watch Manager, open the Monitor and then click Tools > Watch Manager.

The left pane of the Watch Manager contains a list of all available watches. The right pane contains a list of active watches. To add or remove a watch from the active list, select a watch in the left pane and click the appropriate button.

There are three predefined watches (Active, Completed, and Failed). You can edit predefined watches to change the way they are displayed, and you can deactivate them by removing them from the right pane.

No synchronizations are displayed in the Chart unless they meet the conditions of a watch. If you disable all watches (by removing them from the Current Watches list), then no synchronizations are shown in the Chart or Overview.

The order of watches in the right pane is important. Watches that are closer to the top of the list are processed first. Use the Move Up and Move Down buttons to organize the order of watches in the right pane.

You can use the predefined watches, and create other watches. To edit a watch condition, remove it and then add the new watch condition.

toggle To create a new watch

  1. In the Watch Manager, click New.

    The New Watch dialog appears.

  2. Give the watch a name in the Name box.

  3. Select a property, comparison operator, and value.

    For a complete list of properties, see MobiLink statistical properties.

  4. Click Add. (You must click Add to save the settings.)

  5. If desired, select another property, operator, and value, and click Add.

  6. Select a pattern for the watch in the Chart pane. (The Chart pane is the middle pane in MobiLink Monitor.)

  7. Select a color for the watch in the Overview pane. (The Overview pane is the bottom pane in the MobiLink Monitor.)


MobiLink statistical properties

Following is a list of the properties that are available in the MobiLink Monitor. These statistics can be viewed in the New Watch dialog, the Details Table pane, or the Synchronization Properties. In Synchronization Properties, the property names do not contain underscores.

For more information about the New Watch dialog, see Customizing your statistics.

For more information about the Details Table, see Details Table pane.

For more information about the Synchronization Properties dialog, see Synchronization properties.

Property | Notes
active | True if the synchronization is in progress.
begin_sync | Time for the begin_synchronization event.
completed | True if the synchronization completed successfully.
conflicted_deletes | Number of uploaded deletes for which conflicts were detected.
conflicted_inserts | Number of uploaded inserts for which conflicts were detected.
conflicted_updates | Number of uploaded updates for which conflicts were detected.
connection_retries | Number of times the MobiLink synchronization server retried the connection to the consolidated database.
download | Time for the download.
download_bytes | Bytes downloaded to the synchronization client.
download_deleted_rows | Number of row deletions fetched from the consolidated database by the MobiLink synchronization server (using download_delete_cursor scripts).
download_errors | Number of errors that occurred during the download.
download_fetched_rows | Number of rows fetched from the consolidated database by the MobiLink synchronization server (using download_cursor scripts).
download_filtered_rows | Number of fetched rows that were not downloaded to the MobiLink client because they matched rows that the client uploaded.
download_warnings | Number of warnings that occurred during the download.
duration | Total time for the synchronization, as measured by the MobiLink synchronization server. This does not include time when the synchronization request is queued waiting for an available worker thread.
end_sync | Time for the end_synchronization event.
ignored_deletes | Number of uploaded deletes that were ignored.
ignored_inserts | Number of uploaded inserts that were ignored.
ignored_updates | Number of uploaded updates that were ignored.
preload_upload | Time for the transfer of the upload data from the client to the MobiLink synchronization server.
prepare_for_download | Time for the prepare_for_download event.
start_time | Date-time (in ISO-8601 extended format) for the start of the synchronization. All fields of the format must be specified: YYYY-MM-DD hh:mm:ss.sss or YYYY-MM-DD hh:mm:ss,sss, depending on your locale setting.
sync | A number uniquely identifying the synchronization within the Monitor session.
sync_deadlocks | Total number of deadlocks in the consolidated database that were detected for the synchronization.
sync_errors | Total number of errors that occurred for the synchronization.
sync_tables | Number of client tables that were involved in the synchronization.
sync_warnings | Total number of warnings that occurred for the synchronization.
upload | Time for data to be uploaded to the consolidated database.
upload_bytes | Number of bytes uploaded from the synchronization client.
upload_deadlocks | Number of deadlocks in the consolidated database that were detected during the upload.
upload_deleted_rows | Number of row deletions that were uploaded from the synchronization client.
upload_errors | Number of errors that occurred during the upload.
upload_inserted_rows | Number of row insertions that were uploaded from the synchronization client.
upload_updated_rows | Number of row updates that were uploaded from the synchronization client.
upload_warnings | Number of warnings that occurred during the upload.
user | Name of the MobiLink client.
verify_upload | Time for verifying the synchronization protocol and authenticating the synchronization client.
version | Name of the synchronization version.
worker | Identifier for the MobiLink worker thread used for the synchronization in the form n.m, where n is the stream number and m is the thread number.


Synchronizing Through a Web Server With the Redirector

About this chapter

This chapter describes how to route MobiLink synchronization through a web server, focusing on the Redirector.

Introduction
Setting up the Redirector
Configuring MobiLink clients and servers for the Redirector
Configuring Redirector properties (all versions)
NSAPI Redirector for Netscape/Sun web servers
ISAPI Redirector for Microsoft web servers
Servlet Redirector
Apache Redirector
M-Business Anywhere Redirector


Introduction

MobiLink includes a web server extension called the Redirector that routes requests and responses between a client and the MobiLink synchronization server. A plug-in such as this is also commonly called a reverse proxy.

The main reason for routing requests through a web server is to use existing web server and firewall configurations for HTTP or HTTPS synchronization. However, a web server can operate as a proxy without the Redirector. The Redirector is most useful when you have more than one MobiLink synchronization server.

For more information, see Options when using a web server.

Using the Redirector, you can configure your web server to route specific URL requests to one or more computers running the MobiLink synchronization server.

Web servers can be configured to pass requests with specific URLs or ranges of URLs to extension programs commonly written in the form of perl CGI scripts, DLLs, or other extension mechanisms. These extension programs may access external data sources and provide responses for the web server to deliver to its clients.

Load balancing and failover

The Redirector implements load balancing and failover using a simple round robin algorithm (servers are chosen in a fixed cyclic order). Each MobiLink synchronization server is tested at set intervals and requests are no longer sent to a server that is not responding. The Redirector detects when a MobiLink synchronization server is running again and resumes sending requests at that time.

HTTPS synchronization

In HTTPS synchronization, HTTP headers are encrypted over SSL/TLS using RSA encryption before being sent to or from the server. HTTPS is only used for the connection between the MobiLink client and the web server. The web server decrypts the HTTPS and sends HTTP to MobiLink via the Redirector.

The HTTPS protocol is slower than other secure protocols, so it is recommended that it be used only if the HTTPS protocol is required.

Supported web servers

Plug-ins are provided for the following web servers:

Redirector plug-in | ...supports
ISAPI Redirector | Microsoft web servers
NSAPI Redirector | Sun One (previously Netscape) web servers on Windows
Servlet Redirector | Web servers that support the Java Servlet API 2.3, including Apache Tomcat and Sun One web servers on UNIX
Native Apache Redirector | Apache web server
M-Business Anywhere Redirector | M-Business Anywhere web server

Options when using a web server


Options when using a web server

The Redirector is one way to route MobiLink synchronization through a web server. The Redirector is particularly useful for synchronizing across a firewall or with multiple MobiLink synchronization servers.

The main reason for routing requests through a web server is to use existing web server and firewall configurations for HTTP or HTTPS synchronization. The Redirector is most useful when you have more than one MobiLink synchronization server.

You can also route synchronizations through a web server without using the Redirector. In this case, you might configure your web server as a proxy to route synchronizations to a MobiLink server. For more information on how to do this with your web server, see your web server documentation.

The following table contains recommendations to help you decide how best to route your MobiLink synchronizations.

 | Direct connection possible | Direct connection not possible
One MobiLink synchronization server | Use TCP/IP instead of HTTP | Use an HTTP or HTTPS proxy to pass messages through the web server to the MobiLink synchronization server
Multiple MobiLink synchronization servers | Use the Redirector with HTTP or HTTPS | Use the Redirector with HTTP or HTTPS

See Synchronizing Through a Web Server With the Redirector.


Setting up the Redirector

The following sections describe how to configure your web server to manage synchronization requests.

toggle Overview of the configuration process

  1. Configure MobiLink clients and the MobiLink synchronization server.

    See Configuring MobiLink clients and servers for the Redirector.

  2. Ensure that the Redirector configuration file is on the same computer as the web server.

    See Configuring Redirector properties (all versions).

  3. Modify the Redirector configuration file.

    See Configuring Redirector properties (all versions).

  4. Perform web server-specific configuration.

    See one of the following:

    • NSAPI Redirector for Netscape/Sun web servers

    • ISAPI Redirector for Microsoft web servers

    • Servlet Redirector

    • Apache Redirector

    • M-Business Anywhere Redirector


Configuring MobiLink clients and servers for the Redirector

This section describes how to configure MobiLink clients and the MobiLink synchronization server for synchronization through a web server. The following procedures set the parameters required for requests directed through web servers.

MobiLink clients
toggle To configure MobiLink clients (Adaptive Server Anywhere and UltraLite)

  1. Specify the communication type for MobiLink clients to HTTP or HTTPS.

    For more information about setting the communication type for Adaptive Server Anywhere clients, see CommunicationType (ctp) extended option.

    For more information about setting the communication type for UltraLite clients, see HTTP protocol options or HTTPS protocol options.

  2. Specify the following HTTP/HTTPS synchronization protocol options for MobiLink clients:

    • host the name or IP address of the web server.

    • port the web server port accepting HTTP or HTTPS requests.

    • url_suffix This setting depends on the type of web server you are using:

      • For ISAPI web servers:

        exe_dir/iaredirect.dll/ml/

        where exe_dir is the location of iaredirect.dll.

      • For NSAPI web servers:

        mlredirect/ml/

        where mlredirect is a name mapped in your obj.conf file.

      • For servers that support the Java Servlet API 2.2, including Apache with Tomcat using the servlet Redirector:

        iaredirect/ml/

      • For the native Redirector for Apache, set this to whatever you chose in the Redirector's <location> tag in the httpd.conf file. For example:

        iaredirect/ml/

For more information about setting protocol options for UltraLite clients, see HTTP protocol options or HTTPS protocol options.

For more information about setting protocol options for Adaptive Server Anywhere clients, see CommunicationAddress (adr) extended option.

MobiLink synchronization server
toggle To configure MobiLink servers

  1. The MobiLink synchronization server must be started with the HTTP protocol to use HTTP or HTTPS for communication between the client and the proxy. The Redirector cannot use HTTPS directly.

    For example, the HTTP protocol may be specified on the dbmlsrv9 command line as follows:

    dbmlsrv9 -x http

    For more information, see -x option.

  2. In addition, you may want to set the following parameters for the MobiLink synchronization server:

    • port for the HTTP protocol, MobiLink defaults to port 80. For the HTTPS protocol, MobiLink defaults to port 443. If the MobiLink synchronization server is running on the same machine as the web server, port 80 is normally in use by the web server. If this is the case you must specify a different port. For example, you could use port 2439, which is the Internet Assigned Numbers Authority (IANA)-registered port number for the MobiLink synchronization server.

    • contd_timeout This is the number of seconds to wait to receive the next part of a partially completed synchronization before the synchronization is abandoned. This setting is optional and has a default value of 30 seconds.

      You may wish to increase the timeout parameters if your applications involve large synchronizations over slow networks.

    For more information about port and contd_timeout, see -x option.


Configuring Redirector properties (all versions)

This section describes generic web server configuration steps to configure Redirector properties.

toggle To configure Redirector properties

  1. Complete the steps in Configuring MobiLink clients and servers for the Redirector.

  2. Copy redirector.config to the web server.

    The file redirector.config is provided with the MobiLink synchronization server installation, in the MobiLink\redirector subdirectory of your SQL Anywhere installation.

    If the MobiLink synchronization server is not installed on the same computer as the web server, copy redirector.config to the computer that holds the web server.

    For Microsoft web servers, copy redirector.config to the directory Inetpub/scripts. For other web servers, you can copy redirector.config to any directory.

  3. Configure the Redirector configuration file.

    To configure communications between the web server and MobiLink synchronization server, you must edit the file redirector.config on the computer that holds the web server.

    You can set the following directives in this file:

    • LOG_LEVEL used to control the amount of output written to the log file. Values are 0, 1, and 2, with 1 being the default and 2 generating the most output. For the Apache Redirector, this setting has no effect; set the log level in the LogLevel section of the Apache configuration file, httpd.conf.

    • ML used to list the computers running MobiLink synchronization server, in the form ML=host:port. ML is case sensitive.

    • ML_CLIENT_TIMEOUT used to ensure that each step of a single synchronization is directed to the same MobiLink synchronization server. The default value is 600 seconds (ten minutes).

      Information is maintained by the MobiLink synchronization server for the duration of a synchronization, so each step of a synchronization should be handled by the same server. The Redirector maintains an association between client and server for the duration of ML_CLIENT_TIMEOUT. The value of this parameter should be greater than the longest step in any user's synchronization.

    • SLEEP used to set the interval in seconds at which the Redirector checks that the servers are functioning. The default is 1800 (30 minutes). For example, SLEEP=3600. SLEEP is case sensitive.

      The following rules apply to redirector.config:

      • The maximum line length is 300 characters.

      • Comments start with the hash character (#).

      • You cannot include spaces or tabs in the directive definitions.

  4. Complete web server-specific configuration in one of the following sections:

    • ISAPI Redirector for Microsoft web servers

    • NSAPI Redirector for Netscape/Sun web servers

    • Servlet Redirector

    • Apache Redirector

Example

Following is a sample redirector.config file. This file specifies the following:

  • The Redirector should check every 1800 seconds that the servers are functioning.

  • The three computers running MobiLink synchronization servers that are able to process requests. When you specify multiple servers, load balancing is automatically enabled.

SLEEP=1800
ML=myServ-pc:80
ML=209.123.123.1:8080
ML=myCompany.com:8081


NSAPI Redirector for Netscape/Sun web servers

The NSAPI Redirector is provided for the Sun One web server, which was previously the Netscape iPlanet Enterprise Edition web server. Following are setup instructions for Sun One, service pack 1.

This Redirector works only on Windows. To use the Redirector with Netscape/Sun web servers on UNIX, you can use the servlet Redirector. See Servlet Redirector.

toggle To configure the NSAPI Redirector for Sun One

  1. Complete the steps in Configuring Redirector properties (all versions).

  2. If necessary, copy the file iaredirect.dll to the computer that holds the web server. This file is installed with the MobiLink synchronization server, in the MobiLink\redirector\nsapi subdirectory of your SQL Anywhere installation.

  3. Update the Sun One web server configuration file obj.conf as follows.

    Sample file provided
    A complete sample copy of obj.conf, preconfigured for the MobiLink synchronization server, is provided in MobiLink\redirector\nsapi, and is called obj.conf.example. You can use this sample file to confirm where the following sections fit in to the file.

    Update the following sections of the files magnus.conf and obj.conf.

    • In magnus.conf, specify where iaredirect.dll and redirector.config are located.

      At the end of the Init section, add the following text, where location is the actual location of the files. (iaredirect.dll and redirector.config can be in different locations, although both must be on the same computer as the web server.)

      Init fn="load-modules" shlib="location/iaredirect.dll"
funcs="redirector,initialize_redirector"
Init fn="initialize_redirector" configFile="location/redirector.config"

    • In obj.conf, specify the name of the Redirector to be used in URLs.

      At the beginning of the "default object" section, add the following text. This section should appear exactly as provided below, except that you can change mlredirect to whatever you wish. All requests of the form http://host:port/mlredirect/ml/* will be sent to one of the MobiLink synchronization servers running with the Redirector.

      <Object name=default>
NameTrans fn="assign-name" from="/mlredirect/ml/*" name="redirectToML"

    • In obj.conf, specify the objects that are called by the Redirector. After the "default object" section, add the following section:

      <Object name="redirectToML">
Service fn="redirector" serverType="ml"
</Object>

  4. Set the buffer size for the MobiLink upload streams.

    Add a directive to your web server's magnus.conf file to set the buffer size (in bytes) for the upload and download stream. For example:

    ChunkedRequestBufferSize 2000000

    This directive increases the buffer to 2 Mb. The value must be sufficient to accommodate the size of the uploaded data.

    If you are using any network protocol other than HTTPS, your configuration is complete.

  5. If you are using HTTPS synchronization, configure your server as follows:

    • Start the Sun One web server Administration Server.

      Choose Start > Programs > iPlanet Web Server > Start iWS Administration Server.

    • Log in to the Administration Server.

      Choose Start > Programs > iPlanet Web Server > Administer Web Server.

      When prompted, enter your user ID and password.

    • On the Servers tab, select your server from the list and click Manage.

    • On the Security tab, click Request a Certificate.

    • Generate a certificate request and have it signed by a certificate authority or using gencert, which requires a separate license.

      • To have the certificate request signed by a certificate authority, fill out the form.

      • To use the gencert utility, fill out the form, supplying your own e-mail address instead of the e-mail address of a certificate authority. Save the text of the certificate request to a file, then run the gencert utility. For more information, see Certificate generation utility.

    • On the Security tab, click Install Certificate. Fill out the form and specify the location of your signed certificate.

    • Click Manage Certificates to verify that your certificate has been installed correctly.

    • On the Preferences tab, click Add Listen Socket. Specify the required parameters. The default port for HTTPS is 443. Select On from the Security dropdown list to activate HTTPS synchronization.

      For more information about using HTTPS, see MobiLink Transport-Layer Security.

Example

Following is an example of the section of magnus.conf that you need to customize.

Init fn="load-modules" shlib="D:/iaredirect.dll"
funcs="redirector,initialize_redirector"
Init fn=" initialize_redirector " configFile="D:/redirector.config"

Following is an example of the sections of obj.conf that you need to customize.

<Object name=default>
NameTrans fn="assign-name" from="/mlredirect/ml/*" name="redirectToML"
...
<Object name="redirectToML">
Service fn="redirector" serverType="ml"
</Object>
toggle To test your configuration

  1. Call the Redirector using the following syntax:

    http://host:port/mlredirect/ml/

  2. Check the log file to see if the Redirector logged a request.

    Note: This test does not make a connection to the MobiLink synchronization server.


ISAPI Redirector for Microsoft web servers

If you are using a Microsoft web server, you can use the ISAPI version of the Redirector. Following are setup instructions for IIS 5.0.

toggle To configure ISAPI Redirector for Microsoft web servers

  1. Complete the steps in Configuring Redirector properties (all versions).

  2. Copy the file iaredirect.dll to Inetpub/scripts on the computer that holds the web server.

    The file iaredirect.dll is installed with the MobiLink synchronization server, in MobiLink\redirector\isapi under your SQL Anywhere directory.

    The directory Inetpub/scripts is in the Microsoft web server installation directory.

  3. Copy the file redirector.config to Inetpub/scripts on the computer that holds the web server.

    If you are using any network protocol other than HTTPS, your configuration is complete. If your configuration is not successful, see the Note, below.

  4. If you are using HTTPS synchronization, configure your server as follows:

    • Right-click My Computer and select Manage from the popup menu.

    • In the left pane, open the Services and Applications folder. Select Internet Information Services.

    • In the right pane, right-click the default web site and select Configure from the popup menu.

    • Click the Directory Security tab.

    • Click Server Certificate.

      The Web Server Certificate wizard appears.

    • Select Create a New Certificate to generate a certificate request. Follow the remaining prompts, choosing to output the certificate request to a file.

    • Sign your certificate.

      You can sign the certificate using a third-party certificate authority or using the gencert utility, which requires a separate license. For more information, see Certificate generation utility.

    • Click Server Certificate.

      The Web Server Certificate wizard appears with different prompts to allow you to install the signed certificate. Follow the prompts.

    • Click View Certificate to verify that your certificate has been correctly installed.

      For more information about using HTTPS, see MobiLink Transport-Layer Security.

Note

The directory Inetpub/scripts should be created during the web server installation with execute permissions. You can put redirector.config and iaredirect.dll in a different directory only if you use Internet Information Services to give execute permissions to the directory.

If you are unable to connect to the MobiLink synchronization server, the problem may be that you do not have a virtual directory that points to the Inetpub/scripts directory. If this is the case, you must open Internet Information Services and manually create a virtual directory. This virtual directory should point to Inetpub/scripts and have Execute Permissions set to Scripts and Executables. See the IIS online help for instructions.

toggle To test your configuration

  1. Call the ISAPI Redirector using the following syntax:

    protocol://host[:port]/exec_dir/iaredirect.dll/ml/

    where:

    • protocol is http or https.

    • host is the host name of the web server.

    • port is the port on which the web server is listening, if it is not the default port.

    • exec_dir is the directory where you installed the Redirector dll, iaredirect.dll. The default directory is scripts.

      For example,

      http://server:8080/scripts/iaredirect.dll/ml/

  2. Check the log file to see if the Redirector logged a request.

    Note: This test does not make a connection to the MobiLink synchronization server.


Servlet Redirector

The servlet Redirector is supported for web servers that support the Java servlet specification version 2.3. The following procedure is an example for how to set up the servlet Redirector for Apache Tomcat 4.0.6.

There is also a native Redirector for Apache web servers. For more information, see Apache Redirector.

To configure the servlet Redirector for Apache Tomcat

This section describes how to install the servlet version of the Redirector to work on an Apache web server in conjunction with the Tomcat servlet container. Testing of the Redirector software has been carried out using Tomcat version 4.0.6 and Apache 2.0.47.

Installation requires the following steps:

  1. Complete the steps in Configuring Redirector properties (all versions).

  2. Install the servlet version of the Redirector in Tomcat.

  3. Configure the Apache web server to run as a proxy.

This section uses %CATALINA_HOME% and %APACHE_HOME% as the root directory of your Tomcat and Apache installation respectively.

toggle To install the servlet Redirector in Tomcat

  1. Install Tomcat as a standalone server.

    You can download Tomcat binaries from the Jakarta project on the Apache web site at [external link] http://archive.apache.org/dist/jakarta/tomcat-4/archive/v4.0.6/bin/.

  2. Optionally, set the required Tomcat HTTP port.

    Tomcat binds to port 8080 by default. If there is a conflict, perhaps because another web server is using this port,

    • open the file: %CATALINA_HOME%/conf/server.xml

    • search for 8080 (which is in a <Connector> tag)

    • change it to a port that is not in use

  3. Install the servlet Redirector as a web application.

    • Copy iaredirect.war file to %CATALINA_HOME%/webapps

    • Shut down and restart Tomcat.

      Tomcat expands the war file and creates the directory iaredirect for the Redirector web application.

    • Edit the file %CATALINA_HOME%/webapps/iaredirect/WEB-INF/web.xml. Search for redirector.config (in an <init-param> tag), and correct the path for the redirector.config file.

      Change the entry redirector.config to read drive:/path/redirector.config. Even on Windows operating systems, use a forward slash as a path separator, as in d:/redirector.config.

    • Shut down and restart Tomcat for the changes to take effect.

      Once the changes have taken effect, you no longer need the war file in the deployed location.

    • The Redirector can now be invoked through the following URL:

      [external link] http://tc-host:tc-port/iaredirect/ml/

      where tc-host is the machine and tc-port the port on which Tomcat is listening.

toggle To configure the Apache web server as a proxy

  1. Install the Apache web server.

    You can download binaries from the Apache web site at [external link] http://www.apache.org.

  2. Optionally, change the Apache web server port.

    Edit the file %APACHE_HOME%/conf/httpd.conf and change the Port setting to the desired port.

  3. Configure Apache to run as a proxy.

    In %APACHE_HOME%/conf/httpd.conf, add the following two directives:

    LoadModule proxy_module {module-path}/mod_proxy.so
LoadModule proxy_connect_module {module-path}/mod_proxy_connect.so
LoadModule proxy_http_module {module-path}/mod_proxy_http.so

    For example, the path may be modules/mod_proxy.so (the default).

  4. Configure Apache to forward Redirector URLs to Tomcat.

    In %APACHE_HOME%/conf/httpd.conf, add the following two directives so that Apache forwards URLs of the form http://localhost/iaredirect/* to the Tomcat 4 Connector listening on port 8080:

    ProxyPass /iaredirect http://localhost:8080/iaredirect

    The port number must match the port number used for Tomcat. If Tomcat and Apache are not running on the same machine, provide the machine name where Tomcat is running instead of localhost.

    If you are using any network protocol other than HTTPS, your configuration is complete.

  5. If you are using HTTPS synchronization, configure your server as follows. (Note that this HTTPS configuration is identical to the HTTPS instructions for the native Redirector for Apache and M-Business Anywhere.)

    • Download and install binaries for mod_ssl and OpenSSL. You can find them using the Apache Module Registry at [external link] http://modules.apache.org/. mod_ssl.so must be copied to %APACHE_HOME%\modules. libeay32.dll and ssleay32.dll must be copied to %APACHE_HOME%\bin.

    • Generate a server certificate and private key either by generating a request with reqtool.exe and sending it to a third party certificate authority to sign it, or by generating a certificate directly using gencert.exe. The private key can either be in the same file as the server certificate or in its own file.

    • Add the following lines to %APACHE_HOME%\conf\httpd.conf:

      LoadModule ssl_module modules/mod_ssl.so
   SSLEngine on
   SSLCertificateFile certificate_file

      where certificate_file is the path and file name of the server's certificate file.

      If the server's private key is in a separate file from the server's certificate, add the additional line

      SSLCertificateKeyFile private_key_file

      where private_key_file is the path and file name of the server's private key.

      If the private key is encrypted using a pass phrase and you are running under win32, add the additional line

      SSLPassPhraseDialog exec:exe_name

      where exe_name is the path and file name of an executable that will return the pass phrase on stdout.

      Alternatively, the pass phrase can be removed from the private key using openssl:

      openssl rsa -in src_file -out dst_file

      where src_file is the path and file name of the private key protected by a pass phrase, and dst_file is the path and file name of the output file that will contain the unprotected private key. Note that this may reduce server security.

      For more information about using HTTPS, see MobiLink Transport-Layer Security.

Example of HTTPS Configuration

Following is an example of how to configure Apache for HTTPS. This example uses Apache's virtual host feature to read HTTPS from port 443 (the default HTTPS port) and HTTP from port 80 at the same time.

LoadModule ssl_module modules/mod_ssl.so

        Listen 80
        Listen 443

        NameVirtualHost *:443
        <VirtualHost _default_:443>
            ServerName server_name:443
            ErrorLog logs/https_error
            CustomLog logs/https_access common

            SSLEngine on
            SSLCertificateFile rsaserver.crt
            SSLCertificateKeyFile rsaserver.key
        </VirtualHost>
Verifying your setup
toggle To check your configuration

  1. Call the Redirector using the following syntax:

    http://host:port/iaredirect/ml/

  2. Check the log file to see if the Redirector logged a request.

    Note: This test does not make a connection to the MobiLink synchronization server.


Apache Redirector

The Apache Redirector is a native Redirector for Apache web servers version 2.0.x. It has been tested with version 2.0.47. The Apache Redirector is supported for Windows, Solaris and Linux.

If you are using Tomcat, you can also use the servlet Redirector. For more information, see Servlet Redirector.

toggle To configure the Apache Redirector

  1. Complete the steps in Configuring Redirector properties (all versions).

  2. Copy the file mod_iaredirect.dll or mod_iaredirect.so to the appropriate directory in your web server, as follows:

    • For Apache on Windows, the file mod_iaredirect.dll is located in the MobiLink\redirector\apache\v20\ subdirectory of your SQL Anywhere installation. Copy this file to the %apache-home%\modules directory on the computer that holds the web server.

    • For Apache for Solaris or Linux, the file mod_iaredirect.so is located in the MobiLink/redirector/apache/v20/OS subdirectory of your SQL Anywhere installation, where OS is linux or solaris. Copy it to the %apache-home%/modules directory on the computer that holds the web server.

  3. Update the Apache web server configuration file httpd.conf as follows.

    • In the LoadModule section, add the following line:

      (Windows) LoadModule iaredirect_module pathmodules/mod_iaredirect.dll
      (Solaris and Linux) LoadModule iaredirect_module pathmodules/mod_iaredirect.so

      where path is the location of the Apache modules directory.

    • Add the following section to the file:

      <Location /iaredirect/ml>
   SetHandler iaredirect-handler
   iaredirectorConfigFile location/redirector.config
</Location>

      where /iaredirect/ml is the path that you will use to invoke the Redirector, and location is the directory where redirector.config is located.

    • If you are using Apache on Solaris or Linux, you may also want to add the following optional directives to the <Location> section you just created:

      • MaxSyncUsers number The maximum number of MobiLink users synchronizing through the Redirector. This number is used to allocate necessary resources to the Redirector. This number cannot be less than 60. The default is 1000. Only change this setting if the default number of users is less than the actual number.

      • ShmemDiagnosis on|off If set to on, allows debugging of the memory resource. The default is off.

  4. To help with debugging, you may want to increase the amount of logging information that the Redirector outputs. To do this, modify the LogLevel directive in httpd.conf and set it to LogLevel info. The log level can be (from most to least verbose): debug, info, notice, warn, error, crit, alert, and emerg.

    If you are using any network protocol other than HTTPS, your configuration is complete.

  5. If you are using HTTPS synchronization, configure your server as follows. (Note that this HTTPS configuration is identical to the HTTPS instructions for the servlet Redirector on Apache Tomcat and the native Redirector for M-Business Anywhere.)

    • Download and install binaries for mod_ssl and OpenSSL. You can find them using the Apache Module Registry at [external link] http://modules.apache.org/. The file mod_ssl.so must be copied to %APACHE_HOME%\modules. The files libeay32.dll and ssleay32.dll must be copied to %APACHE_HOME%\bin.

    • Generate a server certificate and private key either by generating a request with reqtool.exe and sending it to a third party certificate authority to sign it, or by generating a certificate directly using gencert.exe. The private key can either be in the same file as the server certificate or in its own file.

    • Add the following lines to httpd.conf:

      LoadModule ssl_module modules/mod_ssl.so
   SSLEngine on
   SSLCertificateFile certificate_file

      where certificate_file is the path and file name of the server's certificate file.

      If the server's private key is in a separate file from the server's certificate, add the additional line

      SSLCertificateKeyFile private_key_file

      where private_key_file is the path and file name of the server's private key.

      If the private key is encrypted using a pass phrase and you are running under win32, add the additional line

      SSLPassPhraseDialog exec:exe_name

      where exe_name is the path and file name of an executable that will return the pass phrase on stdout.

      Alternatively, the pass phrase can be removed from the private key using openssl:

      openssl rsa -in src_file -out dst_file

      where src_file is the path and file name of the private key protected by a pass phrase, and dst_file is the path and file name of the output file that will contain the unprotected private key. Note that this may reduce server security.

      For more information about using HTTPS, see MobiLink Transport-Layer Security.

Example

Following are examples of the sections of httpd.conf that configure the Apache web server to route requests to the MobiLink synchronization server. The line starting with AddModule applies only to version 1.3.x. This example works for Windows. For UNIX and Linux, change mod_iaredirect.dll to mod_iaredirect.so.

LoadModule iaredirect_module modules/mod_iaredirect.dll
...
AddModule mod_iaredirect.c
...
<Location /iaredirect/ml>
    SetHandler iaredirect-handler
    iaredirectorConfigFile c:/redirector.config
</Location>
toggle To test your configuration

  1. Call the Redirector using the following syntax:

    http://host:port/iaredirect/ml/

    where iaredirect/ml is the path you specified in the <Location> tag of httpd.conf.

  2. Check the log file to see if the Redirector logged a request.

    Note: This test does not make a connection to the MobiLink synchronization server.


M-Business Anywhere Redirector

The M-Business Anywhere Redirector is supported on Windows, Solaris, and Linux. It has been tested for M-Business Anywhere version 5.5.

toggle To configure the M-Business Anywhere Redirector

  1. Complete the steps in Configuring Redirector properties (all versions).

  2. Copy the file mod_iaredirect.dll or mod_iaredirect.so to the %avantgo-home%\bin directory on the computer that holds the web server. This file is located in the MobiLink\redirector\avantgo\OS subdirectory of your SQL Anywhere installation, where OS is linux or solaris. (For Windows, there is no OS sub-directory.)

  3. For Windows, update the M-Business Anywhere web server configuration file sync.conf as follows:

    • In the LoadModule section, add the following line:

      LoadModule iaredirect_module path/bin/mod_iaredirect.dll

      where path is the location of the M-Business Anywhere bin directory.

    • Add the following section to the file:

      <Location /iaredirect/ml>
   SetHandler iaredirect-handler
   iaredirectorConfigFile location/redirector.config
</Location>

      where /iaredirect/ml is the path that you will use to invoke the Redirector, and location is the directory where redirector.config is located.

    • In the SyncLoadFile section, add the following line:

      SyncLoadFile path/bin/mod_iaredirect.dll

      where path is the location of the M-Business Anywhere bin directory.

  4. For Solaris and Linux, update the M-Business Anywhere web server configuration file sync.conf as follows:

    • In the LoadModule section, add the following line:

      LoadModule iaredirect_module pathbin/mod_iaredirect.so

      where path is the location of the M-Business Anywhere bin directory.

    • Add the following section to the file:

      <Location /iaredirect/ml>
   SetHandler iaredirect-handler
   iaredirectorConfigFile location/redirector.config
</Location>

      where /iaredirect/ml is the path that you will use to invoke the Redirector, and location is the directory where redirector.config is located.

    • You may also want to add the following optional directives to the <Location> section you just created:

      • MaxSyncUsers number The maximum number of MobiLink users synchronizing through the Redirector. This number is used to allocate necessary resources to the Redirector. This number cannot be less than 60. The default is 1000. Only change this setting if the default number of users is less than the actual number.

      • ShmemDiagnosis on|off If set to on, allows debugging of the memory resource. The default is off.

  5. To help with debugging, you may want to increase the amount of logging information that the Redirector outputs. To do this, modify the LogLevel directive in sync.conf and set it to LogLevel info. The log level can be (from most to least verbose): debug, info, notice, warn, error, crit, alert, and emerg.

    If you are using any network protocol other than HTTPS, your configuration is complete.

  6. If you are using HTTPS synchronization, you must implement both ECC and RSA security.

    For more information, see the chapters "Security on Windows" or "Security on UNIX" in the Administrator Guide for M-Business Server.

Example

Following are examples of the sections of sync.conf that configure the M-Business Anywhere web server to route requests to the MobiLink synchronization server.

This example works on Windows:

LoadModule iaredirect_module "c:\program files\M-Business Anywhere\bin\mod_iaredirect.dll"
...
SyncLoadFile "c:\program files\M-Business Anywhere\bin\mod_iaredirect.dll"
...
<Location \iaredirect\ml>
    SetHandler iaredirect-handler
    iaredirectorConfigFile "c:\AvantGoServer\conf\redirector.config"
</Location>

The following example works on UNIX and Linux:

LoadModule iaredirect_module modules/mod_iaredirect.so
...
<Location /iaredirect/ml>
    SetHandler iaredirect-handler
    iaredirectorConfigFile "/redirector.config"
</Location>
toggle To test your configuration

  1. Call the Redirector using the following syntax:

    http://host:port/iaredirect/ml/

    where iaredirect is the path you specified in the <Location> tag of sync.conf.

  2. Check the log file to see if the Redirector logged a request.

    Note: This test does not make a connection to the MobiLink synchronization server.


Running MobiLink Outside the Current Session

About this chapter

This chapter describes how to run the MobiLink synchronization server as a daemon or service.

You can set up MobiLink synchronization server to be available all the time. To make this easier, you can run the MobiLink synchronization server for Windows and for UNIX in such a way that, when you log off the computer it remains running. The way you do this depends on your operating system.

  • UNIX daemon You can run the MobiLink synchronization server as a daemon using the -ud command line option, enabling the MobiLink server to run in the background, and to continue running after you log off.

  • Windows service You can run the Windows MobiLink server as a service.


Running the UNIX MobiLink server as a daemon

To run the UNIX MobiLink server in the background, and to enable it to run independently of the current session, you run it as a daemon.

toggle To run the UNIX MobiLink server as a daemon

  • Use the -ud option when starting the MobiLink server. For example:

    dbmlsrv9 -c "dsn=ASA 9.0 Sample;uid=DBA;pwd=SQL" -ud

For more information, see -ud option.


Running the Windows MobiLink server as a service

To run the Windows MobiLink server in the background, and to enable it to run independently of the current session, you run it as a service.

You can carry out the following service management tasks from the command line, or on the Services tab in Sybase Central:

  • Add, edit, and remove services.

  • Start, stop, and pause services.

  • Modify the parameters governing a service.

  • Add databases to a service, so you can run several databases at one time.


Adding, modifying, and removing services

The service icons in Sybase Central display the current state of each service using a traffic light icon that displays running, paused, or stopped.

toggle To add a new service (Sybase Central)

  1. In Sybase Central, click the server in the left pane, and then open the Services tab in the right pane.

  2. Double-click Add Service.

  3. Follow the instructions in the wizard.

You can also use the dbsvc utility to create the service. For more information, see Managing services using the dbsvc command-line utility.

toggle To remove a service (Sybase Central)

  1. In Sybase Central, click the server in the left pane, and then open the Services tab in the right pane.

  2. In the right pane, right-click the icon of the service you want to remove and choose Delete from the popup menu.

toggle To change the parameters for a service

  1. In Sybase Central, click the server in the left pane, and then open the Services tab in the right pane.

  2. In the right pane, right-click the service you want to change and choose Properties from the popup menu.

  3. Alter the parameters as needed on the tabs of the Service property sheet.

  4. Click OK when finished.

Changes to a service configuration take effect the next time the service is started.

Setting the startup option

The following options govern startup behavior for MobiLink services. You can set them on the General tab of the service property sheet.

  • Automatic If you choose Automatic, the service starts whenever the Windows operating system starts. This setting is appropriate for database servers and other applications running all the time.

  • Manual If you choose Manual, the service starts only when a user with Administrator permissions starts it. For information about Administrator permissions, see your Windows documentation.

  • Disabled If you choose Disabled, the service will not start.

The startup option is applied the next time Windows is started.

Specifying command line options

The Configuration tab of the service property sheet provides a text box for typing command line options for a service. Do not type the name of the program executable in this box.

For example, to start a MobiLink synchronization service with verbose logging and three worker threads, type the following in the Parameters box:

-c "dsn=ASA 9.0 Sample;uid=DBA;pwd=SQL"
-vc
-w 3

The command line options for a service are the same as those for the executable. For a full description of the command line options for MobiLink, see MobiLink Synchronization Server Options.

Setting account options

You can choose which account the service runs under. Most services run under the special LocalSystem account, which is the default option for services. You can set the service to log on under another account by opening the Account tab on the Service property sheet, and typing the account information.

If you choose to run the service under an account other than LocalSystem, that account must have the "log on as a service" privilege. This can be granted from the Windows User Manager application, under Advanced Privileges.

Whether or not an icon for the service appears on the taskbar or desktop depends on the account you select, and whether Allow Service to Interact with Desktop is checked, as follows:

  • If a service runs under LocalSystem, and Allow Service to Interact with Desktop is checked in the service property sheet, an icon appears on the desktop of every user logged in to Windows NT/2000/XP on the computer running the service. Consequently, any user can open the application window and stop the program running as a service.

  • If a service runs under LocalSystem, and Allow Service to Interact with Desktop is unchecked in the service property sheet, no icon appears on the desktop for any user. Only users with permissions to change the state of services can stop the service.

  • If a service runs under another account, no icon appears on the desktop. Only users with permissions to change the state of services can stop the service.

Changing the executable file

To change the program executable file associated with a service in Sybase Central, click the Configuration tab on the Service property sheet and type the new path and file name in the File Name box.

If you move an executable file to a new directory, you must modify this entry.

Starting, stopping, and pausing services
toggle To start, stop, or pause a service

  1. In Sybase Central, click the server in the left pane, and then open the Services tab in the right pane.

  2. Right-click the service and choose Start, Stop, or Pause from the popup menu.

    To resume a paused service, right-click the service and select Continue from the popup menu.

If you start a service, it keeps running until you stop it. Closing Sybase Central or logging off does not stop the service.

Stopping a service closes all connections to the database and stops the database server. For other applications, the program closes down.

Pausing a service prevents any further action being taken by the application. It does not shut the application down or (in the case of server services) close any client connections to the database. Most users do not need to pause their services.


Running more than one service at a time

Although you can use the Windows Service Manager in the Control Panel for some tasks, you cannot install or configure a MobiLink service from the Windows Service Manager. You can use Sybase Central to carry out all the service management for MobiLink.

When you open the Windows Service Manager from the Windows Control Panel, a list of services appears. The names of the Adaptive Server Anywhere services are formed from the Service Name you provided when installing the service, prefixed by Adaptive Server Anywhere. All the installed services appear together in the list.

This section describes topics specific to running more than one service at a time.

Service dependencies

In some circumstances you may wish to run more than one executable as a service, and these executables may depend on each other. For example, you must run the MobiLink synchronization server and the database server in order to synchronize.

In cases such as these, the services must start in the proper order. If a MobiLink synchronization service starts up before the consolidated database server has started, it fails because it cannot find the consolidated database server. The sequence must be such that the database server is running when you start the MobiLink server. (This does not apply if the consolidated database server is on another computer.)

You can prevent these problems using service groups, which you manage from Sybase Central.

Service groups

You can assign each service on your system to be a member of a service group. By default, each service belongs to a group. The default group for the MobiLink synchronization server is ASANYMobiLink.

Before you can configure your services to ensure they start in the correct order, you must check that your service is a member of an appropriate group. You can check which group a service belongs to, and change this group, from Sybase Central.

toggle To check and change which group a service belongs to

  1. In Sybase Central, click the server in the left pane, and then open the Services tab in the right pane.

  2. Right-click the service and choose Properties from the popup menu.

  3. Click the Dependencies tab. The top text box displays the name of the group the service belongs to.

  4. Click Change to display a list of available groups on your system.

  5. Select one of the groups, or type a name for a new group.

  6. Click OK to assign the service to that group.

Managing service dependencies

With Sybase Central, you can specify dependencies for a service. For example:

  • You can ensure that at least one group has started before the current service.

  • You can ensure that any service starts before the current service.

toggle To add a service or group to a list of dependencies

  1. In Sybase Central, click the server in the left pane, and then open the Services tab in the right pane

  2. Right-click the service and choose Properties from the popup menu.

  3. Click the Dependencies tab.

  4. Click Add Services or Add Service Groups to add a service or group to the list of dependencies.

  5. Select one of the services or groups from the list.

  6. Click OK to add the service or group to the list of dependencies.


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Administration Guide

Running MobiLink Outside the Current Session

Troubleshooting MobiLink server startup

This section describes some common problems when starting the MobiLink server.


Ensure that network communication software is running

Appropriate network communication software must be installed and running before you run the MobiLink server. If you are running reliable network software with just one network installed, this should be straightforward. You should confirm that other software requiring network communications is working properly before running the MobiLink server.

If you are running under the TCP/IP protocol, you may want to confirm that ping and telnet are working properly. The ping and telnet applications are provided with many TCP/IP protocol stacks.


Debugging network communications startup problems

If you are having problems establishing a connection across a network, you can use debugging options at both client and server to diagnose problems. The startup information appears on the server window: you can use the -o option to log the results to an output file.


MobiLink Transport-Layer Security

About this chapter

This chapter shows you how to secure communications between the MobiLink synchronization server and MobiLink clients using MobiLink transport-layer security.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Introduction
Setting up transport-layer security
Creating digital certificates
Starting the MobiLink synchronization server with transport-layer security
Configuring MobiLink clients to use transport-layer security


Introduction

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Transport-layer security, an IETF standard protocol, secures client/server applications using digital certificates and public-key cryptography.

Clients use trusted public certificates to encrypt data and authenticate servers in the initial client/server handshake. Data transmitted by the client can only be decrypted by the matching private key, which is stored in your MobiLink synchronization server certificate.

For server authentication, the MobiLink synchronization server sends its public certificate to the client. The client verifies the identity of the server using certificate fields and the digital signature embedded in the certificate.

Efficiency

The transport-layer security standard overcomes the inefficiencies associated with public-key cryptography. Once a secure connection is established, the client and server exchange a common key. They use a highly efficient symmetric cipher for the rest of their communication.

Supported platforms

FIPS-certified security options are available on Windows only, and do not work on UltraLite.

FIPS 140-2 certification


FIPS 140-2 certification

Federal Information Processing Standard (FIPS) 140-2 specifies requirements for security algorithms. It does not, however, specify requirements for security protocols such as SSL or transport-layer security. FIPS 140-2 is granted by the American and Canadian governments through the National Institute of Standards and Testing (NIST) and the Canadian Communication Security Establishment (CSE). Certicom has earned FIPS certification for security algorithms implemented on Windows.

SQL Anywhere Studio offers transport-layer security with the option of using the underlying FIPS-certified algorithms in the Certicom software.

To use transport-layer security, you must purchase a separate security option.

For information about how to order transport-layer security, see Separately-licensable components.

You can use FIPS-certified security algorithms to encrypt your database files, or to encrypt communications for database client/server communication, web services, and MobiLink client/server communication.

For more information, see:

  • Encrypting a database
  • Using transport-layer security for web services
  • Starting the MobiLink synchronization server with transport-layer security
  • Configuring MobiLink clients to use transport-layer security


Setting up transport-layer security

To set up MobiLink transport-layer security, perform the following steps:

  • Create digital certificates Create public certificates and server certificates. Public certificates are distributed to MobiLink clients, while server certificates are stored securely with MobiLink synchronization servers.

    See Creating digital certificates.

  • Start the MobiLink synchronization server with transport-layer security Use dbmlsrv9 command-line options to specify the type of security, the server certificate, and the password to protect the private key.

    See Starting the MobiLink synchronization server with transport-layer security.

  • Configure MobiLink clients to use transport-layer security Specify the path and file name of trusted public certificates.

    Supply the appropriate security or network protocol options with the MobiLink synchronization client utility (dbmlsync) or UltraLite application.

    See Configuring MobiLink clients to use transport-layer security.


Creating digital certificates

To set up transport-layer security you must generate digital certificates.

You can create self-signed certificates, use enterprise root certificates and certificate chains, or have your certificates signed by a Certificate Authority (CA).

  • Self-signed certificates Self-signed certificates can be used for simple setups involving a single MobiLink synchronization server. In this case, the private key used to create trusted public certificates is stored with your MobiLink synchronization server instead of a commercial Certificate Authority or dedicated facility.

    See Self-signed root certificates.

  • Enterprise root certificates Enterprise root certificates increase data integrity and extensibility for multi-server deployments.

    • You can store the private key used to create trusted public certificates in a secure central location.
    • You can add MobiLink synchronization servers without reconfiguring clients.

    See Certificate chains.

  • Commercial Certificate Authorities You can use a third-party Certificate Authority instead of an enterprise root certificate. Commercial Certificate Authorities have dedicated facilities to store private keys and create high-quality server certificates.

    See Certificate chains and Globally-signed certificates.

Certificate utilities

The SQL Anywhere Studio certificate generation utility, gencert, creates certificates. It prompts you for certificate identification and file information and uses RSA or elliptic-curve encryption technology. You can use the certificate reader utility, readcert, to display certificate values and validate a chain of certificates.


Self-signed root certificates

Self-signed root certificates can be used for simple setups involving a single MobiLink synchronization server. In this case, the private key used to create trusted public certificates is stored with your MobiLink synchronization server instead of a commercial Certificate Authority or dedicated facility.

Tip
Use enterprise level certificate chains if you operate multiple MobiLink synchronization servers or are looking for a higher level of certificate integrity.

For more information about setting up certificate chains, see Certificate chains.

To set up self-signed certificates, you generate the following certificates using the gencert utility:

  • Public certificate The self-signed public certificate is distributed to MobiLink clients. It is an electronic document including identity information, the public key of the MobiLink synchronization server, and a self-signed digital signature used for server authentication.

    For more information about digital signatures and server authentication, see Server authentication.

  • Server certificate The server certificate is stored securely with a MobiLink synchronization server. It is a combination of the self-signed public certificate (that is distributed to MobiLink clients) and the corresponding private key. The private key gives the MobiLink synchronization server the ability to decrypt messages sent by Adaptive Server Anywhere or UltraLite clients.

The self-signed server certificate, including the server's private key

For information about how to generate self-signed root certificates, see Certificate generation utility.


Certificate chains

You can improve the security and extensibility of a multi-server environment using certificate chains instead of self-signed certificates. Certificate chains require a Certificate Authority or an enterprise root certificate to sign MobiLink synchronization server certificates.

For more information about self-signed certificates, see Self-signed root certificates.

Benefits of using certificate chains

Certificate chains provide the following advantages:

  • Extensibility You can configure MobiLink synchronization clients to trust any certificate signed by an enterprise root certificate or Certificate Authority. If you add a new MobiLink synchronization server, clients do not require a copy of the new public certificate.

  • Security The enterprise root certificate's private key does not reside with MobiLink synchronization servers. Storing the root certificate's private key in a high-security location, or using a Certificate Authority with dedicated facilities, protects the integrity of server authentication.

The following diagram provides the basic enterprise root certificate architecture.

Enterprise root certificate

To create certificates used in a multi-server environment:

  • Generate a public enterprise root certificate and enterprise private key.

    You distribute the public enterprise root certificate to MobiLink clients. You store the enterprise private key in a secure location, preferably a dedicated facility.

  • Generate server certificates for each MobiLink synchronization server.

    Use the public enterprise root certificate and enterprise private key to sign each server certificate.

You can also use a third-party Certificate Authority to sign your server certificates. Commercial Certificate Authorities have dedicated facilities to store private keys and create high-quality server certificates.

For more information, see Globally-signed certificates.


Enterprise root certificates

Enterprise root certificates increase data integrity and extensibility for multi-server deployments.

  • You can store the private key used to create trusted public certificates in a secure central location.
  • You can add MobiLink synchronization servers without reconfiguring clients.

To set up enterprise root certificates, you create the enterprise root certificate and the enterprise private key that you use to sign server certificates.

For information about creating server certificates, see Signed server certificates.

For information about how to generate enterprise root certificates, see Certificate generation utility.


Signed server certificates

You generate server certificates for each MobiLink synchronization server. Since these certificates are signed by an enterprise root certificate, you use the gencert -s option.

For information about generating signed server certificates, see Certificate generation utility.

For information about how to generate signed server certificates fo each MobiLink synchronization server, see Certificate generation utility.


Globally-signed certificates

A commercial Certificate Authority is an organization that is in the business of creating high-quality certificates and using these certificates to sign your certificate requests.

Globally-signed certificates have the following advantages:

  • In the case of inter-company communication, common trust in an outside, recognized authority may increase confidence in the security of the system. A Certificate Authority must guarantee the accuracy of the identification information in any certificate that it signs.

  • Certificate Authorities provide controlled environments and advanced methods to generate certificates.

  • The private key for the root certificate must remain private. Your organization may not have a suitable place to store this crucial information, whereas a Certificate Authority can afford to design and maintain dedicated facilities.

Setting up globally-signed certificates

To set up globally signed certificates, you:

  • Create a certificate request using Certicom's reqtool utility.

    See Using reqtool to obtain global certificates.

  • Use a Certificate Authority to sign each MobiLink synchronization server certificate request.

    See Using a global certificate as a server certificate.

    Globally-signing enterprise root certificates
    You might be able to globally-sign an enterprise root certificate. This is only applicable if your Certificate Authority generates certificates that can be used to sign other certificates.

Using reqtool to obtain global certificates
Using a global certificate as a server certificate
Setting up clients to trust the certificate authority's public certificate


Using reqtool to obtain global certificates

MobiLink transport-layer security is based on Certicom SSL/TLS Plus libraries, which require elliptic-curve or RSA certificates. You can obtain a global certificate from any Certificate Authority that can supply certificates in the correct format.

There are several ways to obtain certificates. One way is to use the reqtool utility, which is installed when you install the security component. This tool creates a server's private key and a global certificate request.

Example

The following example creates an elliptic-curve certificate request:

> reqtool
-- Certicom Corp. Certificate Request Tool 3.0d1 --
Choose certificate request type:
  E - Personal email certificate request.
  S - Server certificate request.
  Q - Quit.
Please enter your request [Q] : S
Choose key type:
  R - RSA key pair.
  D - DSA key pair.
  E - ECC key pair.
  Q - Quit.
Please enter your request [Q] : E
Using curve ec163a02. Generating key pair (please wait)...
Country: CA
State: Ontario
Locality: Waterloo
Organization: Sybase, Inc.
Organizational Unit: IAS
Common Name: IAS_Waterloo
Enter password to protect private key : mypwd123
Enter file path to save request : global.req
Enter file path to save private key : serv1_private_key.pri

The file global.req contains the public certificate and request information. Paste the contents of this file into a form on the certificate-issuing web site. The Certificate Authority will sign the request and create the public certificate global.crt.

The file serv1_private_key.pri contains the corresponding private key. This file is protected by the password you entered, but since the protection provided by the password is weak, you must store this file in a secure location.

For more information about using reqtool, see the document reqtool.pdf, located in the win32 subdirectory of your SQL Anywhere 9 installation.


Using a global certificate as a server certificate

You can use globally-signed certificates directly as MobiLink synchronization server certificates. The following diagram shows the configuration for a multi-server deployment:

Globally signed server certificates

You can use globally-signed certificates directly as database server certificates. The following diagram shows the configuration for a multi-server deployment:

To create the server identity, you must concatenate the public certificate signed by the Certificate Authority and private key created using the reqtool utility.

For more information about the reqtool utility, see Using reqtool to obtain global certificates.

The following example concatenates the globally-signed public certificate global.crt and the private key serv1_private_key.pri to create the server certificate server1_certificate.crt.

copy global.crt+serv1_private_key.pri server1_certificate.crt

You reference the server certificate server1_certificate.crt and the password for the private key serv1_private_key.pri at the dbmlsrv9 command line.

For more information, see Starting the MobiLink synchronization server with transport-layer security.


Setting up clients to trust the certificate authority's public certificate

You must ensure that clients contacting your MobiLink synchronization server trust the root certificate in the chain. In the case of globally-signed certificates, the root certificate is the Certificate Authority's public certificate.

Certificate field verification
When using a globally-signed certificate, each MobiLink client must verify field values to avoid trusting certificates that the same Certificate Authority has signed for other clients.

For more information about verifying certificate fields for globally-signed certificates, see Verifying certificate fields.

For more information about configuring MobiLink clients to trust server certificates, see Configuring MobiLink clients to use transport-layer security.

For more information about using globally-signed certificates to establish trust, see Globally-signed certificates.


Starting the MobiLink synchronization server with transport-layer security

To start the MobiLink synchronization server with transport-layer security, supply the server certificate and the password protecting the server's private key.

For an overview of the steps required to set up transport-layer security, see Setting up transport-layer security.

Securing the server over TCP/IP

If you are using TCP/IP, use the dbmlsrv9 -x server option to specify certificate and certificate_password parameters. Following is a partial dbmlsrv9 command line:

-x tcpip(security=cipher(certificate=server-certificate;certificate_password=password;...))

  • cipher can be rsa_tls or ecc_tls for RSA and elliptic-curve encryption, respectively. For FIPS-approved RSA encryption, specify rsa_tls_fips. rsa_tls_fips uses separate FIPS 140-2 certified software from Certicom. It is compatible with clients using rsa_tls (with version 9.0.2 or later), and clients using rsa_tls_fips are also compatible with servers using rsa_tls. rsa_tls_fips can only be used with Adaptive Server Anywhere databases on Windows.

    The cipher must match the encryption used to create your certificates.

  • server-certificate is the path and file name of the server certificate.

    For more information about creating the server certificate, which can be self-signed, or signed by a Certificate Authority or enterprise root certificate, see Creating digital certificates.

  • password is the password for the server certificate's private key. You specify this password when you create the server certificate.

For more information about the dbmlsrv9 -x option, see -x option.

Securing the server over HTTPS

If you are using HTTPS, use the dbmlsrv9 -x option to specify certificate and certificate_password parameters directly. Following is a partial dbmlsrv9 command line:

-x protocol(certificate=server-certificate;certificate_password=password;...))

  • protocol can be https; or https_fips for FIPS-approved RSA encryption. https_fips uses separate uses separate FIPS 140-2 certified software from Certicom but is compatible with clients using https (and version 9.0.2 or later). https_fips can only be used with Adaptive Server Anywhere databases on Windows.

  • server-certificate is the path and file name of the server certificate.

    For HTTPS, you must use an RSA certificate.

    For more information about creating the server certificate, see Creating digital certificates.

  • password is the password for the server certificate's private key. You specify this password when you create the server certificate.

For more information about the dbmlsrv9 -x option, see -x option.

Static Java UltraLite applications

Static Java UltraLite uses a separate protocol for transport-layer security.

For more information about using transport-layer security for static Java UltraLite, see Using transport-layer security.

Examples

The following example specifies the type of security (RSA), the server certificate, and the password protecting the server's private key:

dbmlsrv9 -c "dsn=my_cons"
 -x tcpip(security=rsa_tls(certificate=c:\test\serv_rsa1.crt;certificate_password=pwd))

For elliptic-curve certificates, enter:

dbmlsrv9 -c "dsn=my_cons"
 -x tcpip(security=ecc_tls(certificate=c:\test\serv_ecc1.crt;certificate_password=pwd))

For more information about the dbmlsrv9 -x option, see -x option.

For more information about creating the server certificate, in this case serv1.crt, see Creating digital certificates.

You can hide the command-line options using a configuration file and the File Hiding utility, dbfhide. For more information, see @data option.


Configuring MobiLink clients to use transport-layer security

You can configure Adaptive Server Anywhere or UltraLite clients for MobiLink transport-layer security. For each client, you specify trusted public certificates, the type of encryption, and the network protocol.

For an overview of the steps required to set up transport-layer security, see Setting up transport-layer security.

Server authentication
Client security options
Configuring Adaptive Server Anywhere clients to use transport-layer security
Configuring UltraLite clients to use transport-layer security


Server authentication

Server authentication allows a remote client to verify the identity of a MobiLink synchronization server. Digital signatures and certificate field verification work together to achieve server authentication.


Digital signatures

A MobiLink synchronization server certificate contains one or more digital signatures used to maintain data integrity and protect against tampering. Following are the steps used to create a digital signature:

  • An algorithm performed on a certificate generates a unique value or hash.

  • The hash is encrypted using a signing certificate's or Certificate Authority's private key.

  • The encrypted hash, called a digital signature, is embedded in the certificate.

A digital signature can be self-signed or signed by an enterprise root certificate or Certificate Authority.

When a MobiLink client contacts a MobiLink synchronization server, and each is configured to use transport-layer security, the server sends the client a copy of its public certificate. The client decrypts the certificate's digital signature using the server's public key included in the certificate, calculates a new hash of the certificate, and compares the two values. If the values match, this confirms the integrity of the server's certificate.

For more information about self-signed certificates, see Self-signed root certificates.

For more information about enterprise root certificates and Certificate Authorities, see Certificate chains.


Verifying certificate fields

When using a globally signed certificate, each client must verify certificate field values to avoid trusting certificates that the same Certificate Authority has signed for other clients. This is resolved by requiring your clients to test the value of fields in the identity portion of the certificate. A Certificate Authority must guarantee the accuracy of the identification information in any certificate that it signs.

For more information about globally signed certificates, see Globally-signed certificates.

When creating a certificate using the gencert utility, you enter values for the organization, organizational unit, and common name fields. You verify these fields using corresponding MobiLink client connection parameters.

  • Organization The organization field corresponds to the certificate_company MobiLink client connection parameter.

    See certificate_company.

  • Organizational unit The organizational unit field corresponds to the certificate_unit MobiLink client connection parameter.

    See certificate_unit.

  • Common name The common name field corresponds to the certificate_name MobiLink client connection parameter.

    See certificate_name.

    The common name field corresponds to the certificate_name encryption connection parameter.

For more information about setting up MobiLink synchronization clients, see:

  • Configuring UltraLite clients to use transport-layer security.
  • Client security options.

For more information about creating digital certificates, see Creating digital certificates.


Client security options

Adaptive Server Anywhere and UltraLite use a common set of connection parameters to configure transport-layer security.

trusted_certificates parameter

MobiLink clients use the trusted_certificates connection parameter to specify trusted MobiLink synchronization server certificates. The trusted certificate can be a server's self-signed public certificate, a public enterprise root certificate, or the public certificate belonging to a commercial Certificate Authority.

For more information, see:

  • trusted_certificates

  • Creating digital certificates

Verifying certificate fields

The certificate_company, certificate_unit, and certificate_name connection parameters are used to verify certificate fields, an important step for server authentication. It is strongly recommended that you verify certificate fields if you are using a third-party Certificate Authority to globally-sign certificates.

For more information about verifying certificate fields, see:

  • Verifying certificate fields

  • Globally-signed certificates

  • Server authentication


Configuring Adaptive Server Anywhere clients to use transport-layer security

This section shows you how to configure Adaptive Server Anywhere clients to use transport-layer security over HTTPS or TCP/IP.


Transport-layer security over HTTPS

MobiLink transport-layer security is an inherent feature of the MobiLink HTTPS protocol. To use transport-layer security over HTTPS, specify the trusted_certificates connection parameter using the ADR extended option. Following is a partial dbmlsync command line.

-e "ctp=protocol;adr=trusted_certificates=public-certificate..."

  • protocol can be https, or https_fips for FIPS-approved RSA encryption. https_fips uses separate FIPS 140-2 certified software from Certicom but is compatible with MobiLink synchronization servers using https and version 9.0.2 or later.

  • public-certificate is the path and file name of a trusted public certificate.

    For HTTPS or HTTPS_FIPS, you must use certificates created using RSA encryption.

For more information about trusted_certificates and other client security parameters, see Client security options.

For more information about creating or obtaining the public certificate, see Creating digital certificates.

For more information about HTTPS parameters, see the HTTPS section in CommunicationAddress (adr) extended option.

Examples

The following example specifies RSA security over HTTPS at the dbmlsync command line.

dbmlsync -c "eng=rem1;uid=dba;pwd=mypwd"
  -e "ctp=https;adr=trusted_certificates=c:\temp\public_cert.crt;certificate_company=Sybase, Inc.;certificate_unit=IAS;certificate_name=MobiLink)"

Alternatively, you can specify the CommunicationAddress extended option using the CREATE SYNCHRONIZATION SUBSCRIPTION or ALTER SYNCHRONIZATION SUBSCRIPTION statement. This method provides the same information but stores it in the database.

CREATE SYNCHRONIZATION SUBSCRIPTION
 TO pub1
 FOR user1
 ADDRESS 'trusted_certificates=c:\temp\public_cert.crt;
    certificate_company=Sybase, Inc.;
    certificate_unit=IAS;
  certificate_name=MobiLink'
 OPTION scriptversion='ver1';


Transport-layer security over TCP/IP

To configure Adaptive Server Anywhere clients to use transport-layer security over TCP/IP, use the CommunicationAddress (adr) extended option to specify trusted certificates.

Unlike HTTPS, where you can specify trusted_certificates and certificate fields directly, you must use the security option and the following syntax for TCP/IP:

adr=security=cipher(trusted_certificates=public-certificate; ...)

  • cipher can be rsa_tls or ecc_tls for RSA and elliptic-curve encryption, respectively.

    For FIPS-approved RSA encryption, specify rsa_tls_fips. rsa_tls_fips uses a separate approved library but is compatible with servers using rsa_tls. Clients using rsa_tls are also compatible with servers using rsa_tls_fips. rsa_tls_fips can be used on SQL Anywhere Studio databases on Windows.

    The cipher must match the encryption used to create your certificates.

  • public-certificate is the path and file name of a trusted public certificate.

For more information about trusted_certificates and other client security parameters, see Client security options.

For more information about creating or obtaining the public certificate, see Creating digital certificates.

For more information about the CommunicationAddress (adr) extended option, including a list of security parameters, see CommunicationAddress (adr) extended option.

Examples

The following example specifies RSA security and TCP/IP at the dbmlsync command line:

dbmlsync -c "eng=rem1;uid=myuid;pwd=mypwd"
  -e "ctp=tcpip;adr=port=3333;security=rsa_tls(trusted_certificates=c:\test\public_cert.crt;certificate_company=Sybase, Inc.;certificate_unit=IAS;certificate_name=MobiLink)"

Another option is to specify the CommunicationAddress extended option using the CREATE SYNCHRONIZATION SUBSCRIPTION or ALTER SYNCHRONIZATION SUBSCRIPTION statement:

CREATE SYNCHRONIZATION SUBSCRIPTION
 TO pub1
 FOR user1
 ADDRESS 'port=3333;security=rsa_tls(trusted_certificates=public_cert.crt;
    certificate_company=Sybase, Inc.;
    certificate_unit=IAS;
  certificate_name=MobiLink )'
 OPTION scriptversion='ver1';

For more information see CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink] and ALTER SYNCHRONIZATION SUBSCRIPTION statement [MobiLink].


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Administration Guide

MobiLink Transport-Layer Security

Configuring MobiLink clients to use transport-layer security

Configuring UltraLite clients to use transport-layer security

This section shows you how to configure UltraLite clients to use transport-layer security over HTTPS or TCP/IP.


Transport-layer security over HTTPS

MobiLink transport-layer security is an inherent feature of the MobiLink HTTPS protocol. If you use HTTPS and UltraLite clients, you can specify trusted certificates and certificate fields directly as network protocol options.

For HTTPS, you must use RSA certificates.

For more information about specifying the HTTPS protocol for your UltraLite interface, see HTTPS protocol options.

The ul_synch_info security_stream and security_parms security synchronization parameters are only used for TCP/IP and have no effect when you use HTTPS.

For more information about the security synchronization parameter, see Security synchronization parameter and Transport-layer security over TCP/IP.

toggle To configure your UltraLite client to use transport-layer security over HTTPS

  1. Specify trusted root certificates in the UltraLite schema.

    • Static UltraLite interfaces For static UltraLite interfaces, including UltraLite for static C/C++, Embedded SQL, and static Java, use the ulgen -r option. The following example specifies the trusted root certificate ent_root.crt for static C/C++ UltraLite:

      ulgen -a -c "dsn=myCons" -j Product -s ISampleSQL
  -f SampleDB -r ent_root.crt

      For more information about the ulgen -r option, see The UltraLite Generator.

    • UltraLite component interfaces For UltraLite component interfaces, specify trusted certificates using the Schema Painter. The Schema Painter's Database Schema Properties dialog includes a Certification tab.

      For more information, see Database Schema property sheet: Certification tab.

  2. Specify the HTTPS protocol for synchronization.

    The following example uses the ULHTTPSStream() function for C/C++ UltraLite:

    auto ul_synch_info synch_info;
conn.InitSynchInfo( &synch_info );
synch_info.user_name = UL_TEXT( "50" );
synch_info.version = UL_TEXT( "ul_default" );
...
synch_info.stream = ULHTTPSStream();
...

    For more information about ULHTTPSStream(), see ULHTTPSStream function.

  3. Specify HTTPS protocol options.

    The following example uses the stream_parms field of ul_synch_info to specify standard HTTPS parameters and verify certificate fields for C/C++ UltraLite.

    auto ul_synch_info synch_info;
...
synch_info.stream = ULHTTPSStream();
synch_info.stream_parms = TEXT(
      "port=9999;
       certificate_company=Sybase, Inc.;
       certificate_unit=IAS;
       certificate_name=MobiLink");
    synch_info.security_stream = NULL;
    synch_info.security_parms = NULL;

    The certificate_company, certificate_unit, and certificate_name parameters are used to verify certificate fields.

    For more information about verifying certificate fields, see Verifying certificate fields.

    You can also specify the trusted_certificates HTTPS protocol option, which overrides any trusted certificate information embedded in the UltraLite schema (step 1 of this procedure). You can only use this parameter for Windows NT/2000/XP or Windows CE.

    auto ul_synch_info synch_info;
...
synch_info.stream = ULHTTPSStream();
synch_info.stream_parms = TEXT(
      "port=9999;
       trusted_certificates=\rsaroot.crt;
       certificate_company=Sybase, Inc.;
       certificate_unit=IAS;
       certificate_name=MobiLink");
    synch_info.security_stream = NULL;
    synch_info.security_parms = NULL;

    For more information about HTTPS options, see HTTPS protocol options


Transport-layer security over TCP/IP

To configure UltraLite clients to use transport-layer security over TCP/IP, specify trusted root certificates and the appropriate security stream.

toggle To configure your UltraLite client to use transport-layer security over TCP/IP

  1. Specify trusted root certificates in the UltraLite schema.

    • Static UltraLite interfaces For static UltraLite interfaces, including UltraLite for static C/C++, Embedded SQL, and static Java, use the ulgen -r option. The following example specifies trusted root certificates for static C/C++ UltraLite:

      ulgen -a -c "dsn=myCons" -j Product -s ISampleSQL
  -f SampleDB -r ent_root.crt

      For more information about the ulgen -r option, see The UltraLite Generator.

    • UltraLite component interfaces For UltraLite component interfaces, specify trusted certificates using the Schema Painter. The Schema Painter's Database Schema Properties dialog includes a Certification tab.

      For more information, see Database Schema property sheet: Certification tab.

  2. Supply the appropriate security or protocol options in the programming interface.

    • Static Java UltraLite Static Java UltraLite requires a separate stream for transport-layer security and does not provide a separate security parameter. The following example use the UlSecureSocketStream as the protocol for elliptic-curve security:

      UlSynchOptions opts = new UlSynchOptions();
opts.setStream(new UlSecureSocketStream() );
opts.setStreamParms( "host=myserver;"
   + "port=2439;"
   + "certificate_company=Sybase Inc.;"
   + "certificate_unit="IAS;"
   + "certificate_name=Mobilink");
// set other options here
conn.synchronize( opts );

      For more information about using Transport-Layer Security for static Java UltraLite, see Using transport-layer security.

    • UltraLite Interfaces using the security synchronization parameter Set the security synchronization parameter for applicable UltraLite interfaces including UltraLite for static C++, Embedded SQL, and the C++ UltraLite component. For other component interfaces, you must use HTTPS for transport-layer security.

      You can use ULSecureRSATLSStream() or ULSecureCerticomTLSStream() to specify RSA and elliptic-curve security, respectively.

      For more information, see Security synchronization parameter.

      The following example specifies RSA security and TCP/IP for C/C++ UltraLite.

      ul_synch_info synch_info;
...
synch_info.stream = ULSocketStream();
synch_info.security = ULSecureRSATLSStream();
synch_info.security_parms = TEXT(
      "port=9999;
       certificate_company=Sybase, Inc.;
       certificate_unit=IAS;
       certificate_name=MobiLink");

      The certificate_company, certificate_unit, and certificate_name parameters are used to verify certificate fields.

      For more information about verifying certificate fields, see Verifying certificate fields.

      You can also specify the trusted_certificates security parameter, which overrides any trusted certificate information embedded in the UltraLite schema (step 1 of this procedure). You can only use this parameter for Windows NT/2000/XP or Windows CE.

      ul_synch_info synch_info;
...
synch_info.stream = ULSocketStream();
synch_info.security = ULSecureRSATLSStream();
synch_info.security_parms = TEXT(
      "port=9999;
       trusted_certificates=\rsaroot.crt;
       certificate_company=Sybase, Inc.;
       certificate_unit=IAS;
       certificate_name=MobiLink");

      For more information about the ul_synch_info security_parms field, see security_parms synchronization parameter.

    • UltraLite interfaces using ActiveSync For information about using Transport-Layer Security and ActiveSync, see ActiveSync protocol options.

    • UltraLite interfaces using HotSync For information about using Transport-Layer Security and HotSync, see HotSync protocol options.


MobiLink Synchronization Server Options

About this chapter

This chapter describes the options that can be set when starting the MobiLink synchronization server, dbmlsrv9.

MobiLink synchronization server


MobiLink synchronization server

The MobiLink synchronization server lets you synchronize remote databases or applications with an ODBC-compliant consolidated database.

Function

Start a MobiLink synchronization server.

Syntax

dbmlsrv9 –c "connection-string" [ options ]

Option | Description
@data | Read in options from the specified environment variable or configuration file. See @data option.
–a | Disable automatic reconnection upon synchronization error. See -a option.
-b | Trim blank padding of strings. See -b option.
–bc size | Specify the amount of memory to reserve for BLOB caching. See -bc option.
–bn size | Specify the maximum number of bytes to consider when comparing BLOBs for conflict detection. See -bn option.
–c "keyword=value; ..." | Supply ODBC database connection parameters for your consolidated database. See -c option.
–cn connections | Set the maximum number of simultaneous connections with the consolidated database server. See -cn option.
–cr count | Set the maximum number of database connection retries. See -cr option.
–ct connection-timeout | Set the length of time a connection may be unused before it is timed out. See -ct option.
–d number | Specify the size of the download cache. See -d option.
-dd directory | Specify where download streams are stored. See -dd option.
–dl | Display all log messages on the console. See -dl option.
-ds size | Specify the amount of disk storage that can be used to store restartable download streams. See -ds option.
–e filename | Store remote error logs sent into the named file. See -e option.
–et filename | Truncate the file and append remote synchronization logs to the new file. See -et option.
–f | Assume synchronization scripts do not change. See -f option.
–fr | If table data scripts are missing, synchronization will not abort, but just issue a warning. See -fr option.
-m [filename] | Enables QAnywhere messaging. See -m option.
-notifier | Starts a Notifier for server-initiated synchronization. See -notifier option.
–o logfile | Log messages to a file. See -o option.
-on size | Set maximum size for log file. See -on option.
–oq | Prevent the popup dialog on startup error. See -oq option.
–os size | Maximum size of output file. See -os option.
–ot logfile | Log messages to a file, but truncate it first. See -ot option.
–ps num | Set maximum number of prepared statements to cache per connection. See -ps option.
–q | Minimize the synchronization server window. See -q option.
–r retries | Retry deadlocked uploads at most this many times. See -r option.
–rd delay | Set maximum delay, in seconds, before retrying a deadlocked transaction. See -rd option.
–s count | Specify the maximum number of rows to be fetched or sent at once. See -s option.
–sl dnet script-options | Set the .NET CLR options and force loading of the virtual machine on startup. See -sl dnet option.
–sl java script-options | Set the Java virtual machine options and force loading of the virtual machine on startup. See -sl java option.
–t ODBC-output-file | Log ODBC calls issued by MobiLink to this file. See -t option.
–tt ODBC-output-file | Log ODBC calls issued by MobiLink to this file, but first delete the file if it exists. See -tt option.
–u size | Specify the amount of memory to reserve for caching upload streams. See -u option.
–ud | On UNIX platforms, run as a daemon. See -ud option.
-us | Prevents MobiLink from invoking upload scripts for tables for which there is no upload. See -us option.
–v [ levels ] | Controls the type of messages written to the log file. See -v option.
–w count | Set the number of worker threads. See -w option.
–wu count | Set the maximum number of worker threads permitted to process uploads concurrently. See -wu option.
–x protocol[ (network-parameters) ] | Specify the communications protocol. Optionally, specify network parameters in form parameter=value, with multiple parameters separated by semicolons. See -x option.
–za | Allow generation of active scripts. See -za option.
–ze | Allow generation of sample scripts. See -ze option.
–zp | In the event of a timestamp conflict between the consolidated and remote database, this option allows timestamp values with a precision higher than the lowest-precision to be used for conflict detection purposes. See -zp option.
–zs name | Specify a server name. See -zs option.
–zt number | Specify the maximum number of processors used to run the MobiLink synchronization server. See -zt option.
–zu { + | – } | Controls the automatic addition of users when the authenticate_user script is undefined. See -zu option.
-zw 1,...5 | Controls which levels of warning message to display. See -zw option.
-zwd code | Disables specific warning codes. See -zwd option.
-zwe code | Enables specific warning codes. See -zwe option.
Description

The MobiLink synchronization server opens connections, via ODBC, with your consolidated database server. It then accepts connections from client applications and controls the synchronization process.

The MobiLink synchronization server is compatible with a variety of database-management systems, including Adaptive Server Anywhere, Adaptive Server Enterprise, Oracle, Microsoft SQL Server, and IBM DB2.

You must supply connection parameters for the consolidated database using the –c option. The command line options may be presented in any order. The –c option is shown here as the first item in a command string as a convention only. It can be anywhere in a list of options, but must precede a connection string.

Unless your ODBC data source is configured to automatically start the consolidated database, the database must be running before you start the MobiLink server.

dbmlsrv9 options


dbmlsrv9 options

This section lists all MobiLink synchronization server command line options.

@data option
-a option
-b option
-bc option
-bn option
-c option
-cn option
-cr option
-ct option
-d option
-dd option
-dl option
-ds option
-e option
-et option
-f option
-fr option
-m option
-notifier option
-o option
-on option
-oq option
-os option
-ot option
-ps option
-q option
-r option
-rd option
-s option
-sl dnet option
-sl java option
-t option
-tt option
-u option
-ud option
-us option
-v option
-w option
-wu option
-x option
-za option
-ze option
-zp option
-zs option
-zt option
-zu option
-zw option
-zwd option
-zwe option


@data option
Function

Reads in options from the specified environment variable or configuration file.

Syntax

dbmlsrv9 –c "connection-string" @data ...

Description

Use this option to read in dbmlsrv9 command line options from the specified environment variable or configuration file. If both exist with the same name that is specified, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

See Hiding the contents of files using the dbfhide command-line utility.


-a option
Function

Instructs the MobiLink synchronization server to not reconnect on synchronization error.

Syntax

dbmlsrv9 –c "connection-string" –a ...

Description

Should an error occur during synchronization, the MobiLink synchronization server automatically disconnects from the consolidated database, and then re-establishes the connection. Reconnecting ensures that the following synchronization starts from a known state. When this behavior is not required, you can use this option to disable it. The maintenance of state information depends on programmer requirements and may vary depending on the ways in which the programmer configures MobiLink scripting to work with the DBMS. This applies even if that database is an Oracle, Adaptive Server Anywhere database, or other supported product. Some status information may need to be re-initialized depending on the client application.


-b option
Function

For columns of type VARCHAR, CHAR, LONG VARCHAR, or LONG CHAR, removes trailing blanks from strings during synchronization.

Syntax

dbmlsrv9 –c "connection-string" –b ...

Description

This option is intended to help resolve differences between the Adaptive Server Anywhere CHAR data type and the CHAR or VARCHAR data type used by the consolidated database. The Adaptive Server Anywhere CHAR data type is equivalent to VARCHAR. However, in most consolidated databases that are not Adaptive Server Anywhere, the CHAR(n) data type is blank-padded to n characters.

When -b is specified, the MobiLink synchronization server removes trailing blanks from strings for columns of type CHAR, VARCHAR, LONG CHAR, or LONG VARCHAR if the column on the remote is a string. It does this before filtering rows that were uploaded in the current synchronization. The trimmed data is then downloaded to the remote databases.

This option can also be used to detect conflict updates. For each upload update row, the MobiLink synchronization server fetches the row from the consolidated database for the given primary key, compares the row with the pre-image of the update, and then determines whether the update is a conflict update. When -b is used, MobiLink trims trailing blanks from columns of type CHAR, VARCHAR, LONG CHAR, or LONG VARCHAR before doing the comparison.

Example

If the -b option is not used, a primary-key value of 'abc' uploaded from an Adaptive Server Anywhere or UltraLite remote to a CHAR(10) column in the consolidated database will become 'abc' followed by seven blank spaces. If the same row is downloaded, then it will appear on the remote as 'abc' followed by seven spaces. If the remote database is not blank-padded, then the remote will now have two rows: both 'abc' and 'abc' followed by seven spaces. There is now a duplicate row on the remote.

If the -b option is used, a primary-key value of 'abc' uploaded from an Adaptive Server Anywhere or UltraLite remote to a CHAR(10) column in the consolidated database will become 'abc' followed by seven spaces. Seven spaces still pad the value to ten characters, but if the same row is downloaded, then MobiLink server will strip the trailing spaces, and the value will appear on the remote as 'abc'. The -b option thus fixes the duplicate row problem.


-bc option
Function

Sets the BLOB cache size.

Syntax

dbmlsrv9 –c "connection-string" –bc size [ k | m | g ] ...

Description

The amount of memory to use for caching BLOBs. If more memory is required, the MobiLink synchronization server uses disk space, instead. For this reason, too small a value can degrade performance. To calculate the minimum recommended size, multiply the maximum size of all BLOB data in any one row by the number of worker threads, then multiply the result by 4, which provides for a large reserve of memory.

The size is the amount of memory to reserve in bytes. Use the suffix k, m, or g to specify units of kilobytes, megabytes, or gigabytes, respectively. The default is 524 288 bytes.


-bn option
Function

Sets the maximum number of BLOB bytes to compare during conflict detection.

Syntax

dbmlsrv9 –c "connection-string" –bn size...

Description

When two BLOBs contain similar or identical values, the operation of comparing them for filtering or conflict detection can be expensive due to the amount of data involved. This option tells the MobiLink synchronization server to consider only the first size bytes of two BLOBs when making the comparison. The default is to compare the two BLOBs in their entirety.

Under some situations, limiting the maximum amount of data compared can speed synchronization substantially; however, it can also cause errors. For example, if two large BLOBs differ only in the last few bytes, the MobiLink synchronization server may consider them identical when in fact they are not.


-c option
Function

Specifies connection parameters for the consolidated database.

Syntax

dbmlsrv9 –c "connection-string"...

Description

The connection string must give the MobiLink synchronization server information sufficient to connect to the consolidated database. The connection string is required.

The connection string must specify connection parameters in the form keyword=value, separated by semicolons, with no spaces between parameters.

Connection parameters must be included in the ODBC data source specification if not given in the command line. Check your RDBMS and ODBC data source to determine required connection data.

For a complete list of SQL Anywhere connection parameters, see Connection parameters.

For information about how to hide the password, see The File Hiding utility.

Example
dbmlsrv9 -c "dsn=odbcname;uid=DBA;pwd=sql"


-cn option
Function

Sets the maximum number of simultaneous consolidated database connections.

Syntax

dbmlsrv9 –c "connection-string" –cn value...

Description

Specifies the maximum number of simultaneous connections that the MobiLink synchronization server should make to the consolidated database. The minimum and the default value are one greater than the number of worker threads. A warning is issued if the supplied value is too small.

A value larger than the number of worker threads may speed performance, particularly if connecting to the consolidated database is slow or if multiple script versions are in use. The optimum maximum number of database connections is the number of script versions times the number of worker threads, plus one. Connections above this optimum value will not necessarily speed synchronization, and will needlessly consume resources in both the MobiLink synchronization server and the consolidated database server.


-cr option
Function

Sets the maximum number of database connection retries.

Syntax

dbmlsrv9 -c "connection-string" -cr value...

Description

Set the maximum number of times that the MobiLink synchronization server will attempt to connect to the database, before quitting, when a connection goes bad. The default value is three connection retries.


-ct option
Function

Sets the length of time, in minutes, that a connection may be unused before it is timed out and disconnected by the MobiLink synchronization server.

Syntax

dbmlsrv9 –c "connection-string" –ct connection-timeout...

Description

MobiLink database connections that go unused for a specified amount of time are freed by the server. The timeout can be set using the -ct option. A default timeout period of 60 minutes is used.


-d option
Function

Sets the size of the download cache.

Syntax

dbmlsrv9 –c "connection-string" –d number [ k | m | g ]...

Description

When no download acknowledgement is required, MobiLink buffers the download stream in a download cache. Since no acknowledgement is required from the client to commit the download transaction, the buffered download stream is sent to the client after the commit.

Use the suffix k, m, or g to specify units of kilobytes, megabytes, or gigabytes, respectively. The default size for the download cache is 0.5 megabytes.


-dd option
Function

For use with restartable downloads. Specifies where download streams are stored.

Syntax

dbmlsrv9 –c "connection-string" –dd directory ...

Description

When the MobiLink synchronization server is shut down, the download directory is cleaned. This means that a download cannot be restarted across a server restart.

The default directory is your TEMP directory.

See also

Resuming failed downloads

-dc option

-ds option


-dl option
Function

Displays all log messages on screen.

Syntax

dbmlsrv9 –c "connection-string" -v -dl ...

Description

Display all log messages in the MobiLink synchronization server window. By default, only a subset of all messages is shown in the window when a log file is being output (using -o). In circumstances with many messages, this option can degrade performance.


-ds option
Function

For use with restartable downloads. Specifies the amount of disk space that can be used to store the restartable download stream.

Syntax

dbmlsrv9 –c "connection-string" –ds size [ k | m | g ]...

Description

Use the suffix k, m, or g to specify units of kilobytes, megabytes, or gigabytes, respectively. The default is 10 Mb.

See also

Resuming failed downloads

-dc option

-dd option


-e option
Function

Stores error logs sent from Adaptive Server Anywhere MobiLink clients.

Syntax

dbmlsrv9 –c "connection-string" –e filename...

Description

With no -e option, error logs from Adaptive Server Anywhere MobiLink clients are stored in a file named dblmsrv.mle. The -e option instructs the MobiLink synchronization server to store the error logs in the named file. By default, dbmlsync sends, on the occurrence of an error on the remote site, up to 32 kilobytes of remote log messages to a MobiLink synchronization server.

This option provides centralized access to remote error logs to help diagnose synchronization issues.

The amount of information delivered from a remote site can be controlled by the dbmlsync extended option ErrorLogSendLimit.

See also
  • -et option
  • ErrorLogSendLimit (el) extended option


-et option
Function

Stores error logs sent from Adaptive Server Anywhere MobiLink clients in the named file after truncating the existing file.

Syntax

dbmlsrv9 –c "connection-string" –et filename...

Description

The -et option is the same as the -e option, except that the error log file is truncated before any new errors are added to it.

The amount of information delivered from a remote site can be controlled by the dbmlsync extended option ErrorLogSendLimit.

See also
  • ErrorLogSendLimit (el) extended option
  • -e option


-f option
Function

Loads synchronization scripts only once, for better performance.

Syntax

dbmlsrv9 –c "connection-string" –f...

Description

Without the -f option, the MobiLink synchronization server checks to see if synchronization scripts have changed during regular operation. This checking is helpful during development, but can have an unnecessary performance impact in a production environment. With the -f option, the MobiLink synchronization server loads the synchronization scripts only once per MobiLink session..


-fr option
Function

If table data scripts are missing, synchronization will not abort, but just issue a warning.

Syntax

dbmlsrv9 –c "connection-string" –fr...

Description

Without the -fr option, the MobiLink synchronization server aborts if a synchronization does not include at least one script that uploads or downloads data. This option causes MobiLink to issue a warning instead of aborting.

For bi-directional or upload-only synchronization, -fr will cause an error to occur if data is uploaded and there is no corresponding upload script:

  • if you attempt to upload an INSERT with no upload_insert, upload_new_row_insert, upload_cursor, or new_row_cursor script defined

  • if you attempt to upload a DELETE with no upload_delete, upload_old_row_insert, upload_cursor, or old_row_cursor script defined

    if you attempt to upload an UPDATE with no upload_update, upload_new_row_insert, upload_cursor, or new_row_cursor script defined

For download-only synchronization, -fr will cause an error if any tables in the synchronization are missing a download script (download_cursor or download_delete_cursor).


-m option
Function

Enables QAnywhere messaging.

Syntax

dbmlsrv9 –c "connection-string" –m [ message-properties-file ] ...

Description

The optional message-properties-file specifies property settings for QAnywhere messaging, including the name of files that specify property settings for connectors and transmission rules.

In the message-properties-file, each property must appear on its own line and consist of a property name, the = character, and then a property value.

Following are the properties you can set in the QAnywhere properties file:

  • ianywhere.qa.server.logLevel The logging level of the messaging. The property value may be one of 1, 2, 3, or 4. 1 indicates that only message errors are logged. 2 additionally causes warnings to be logged. 3 additionally causes informational messages to be logged. 4 additionally causes more verbose informational messages to be logged, including details about each QAnywhere message that is transmitted with the MobiLink synchronization server. The default is 2.

    These logging messages are output to the MobiLink synchronization server console. If the dbmlsrv9 -o or -ot option was specified, the messages are output to the MobiLink synchronization server log file.

  • ianywhere.qa.compressionLevel The default amount of compression applied to each message received by a QAnywhere connector. The compression is an integer between 0 and 9, with 0 being no compression and 9 being the most compression. The default is 0.

    If you also set the compression level for a connector in the connector properties file, this setting is overridden for that connector. For more information, see Configuring the JMS connector properties file.

  • ianywhere.qa.server.connectorPropertiesFiles A list of one or more files that specify the configuration of QAnywhere connectors to an external message system such as JMS. The default is no connectors.

    For more information, see Using JMS Connectors.

  • ianywhere.qa.server.transmissionRulesFile A file used to specify rules for governing the transmission and persistence of messages. By default, there are no filters for messages, and messages are deleted when the final status of the message has been transmitted to the message originator.

  • ianywhere.qa.server.autoRulesEvaluationPeriod The time in milliseconds between evaluations of rules, including message transmission and persistence rules. Since, typically, rules are evaluated on the fly as messages are transmitted to the server store, the rule evaluation period is only for rules that are timing-sensitive. The default value is 60000 (one minute).

See also
  • Introduction to QAnywhere
  • QAnywhere Transmission Rules
  • Configuring the JMS connector properties file
  • Starting the MobiLink synchronization server for QAnywhere messaging
  • Starting the MobiLink server for JMS integration
Example

For example, the following lines could be contained in a QAnywhere message properties file called qanymsgprop.ini; it tells QAnywhere to:

  • read connector properties from a file called connector.ini
  • read server transmission rules from a file called rules.ini
  • set the logging level to 4 (verbose)
ianywhere.qa.server.connectorPropertiesFiles=connector.ini
ianywhere.qa.server.transmissionRulesFiles=rules.ini
ianywhere.qa.server.logLevel=4

To run these settings, start the MobiLink synchronization server with the -m option and the message properties filename. Following is a partial command line:

dbmlsrv9 -m qanymsgprop.ini ...


-notifier option
Function

Starts the Notifier for server-initiated synchronization.

Syntax

dbmlsrv9 –c "connection-string" –notifier [ notifier-properties-file ] ...

Description

If you specify a Notifier configuration file name, or if you do not specify a file name but you have a default Notifier properties file called config.notifier, the Notifier is configured using that file. This overrides any configuration information that is stored in the ml_properties table in the consolidated database.

Otherwise, MobiLink uses the configuration information that is stored in the ml_properties table in the consolidated database.

When you use the -notifier option, you start every Notifier that you have enabled.

For more information about enabling Notifiers, see enable property.

The -notifier option cannot be used on AIX 4.3.3. For more information, see [external link] http://www-106.ibm.com/developerworks/eserver/articles/JavaPart1.html.

See also
  • Setting properties in more than one place
  • Notifier properties file
  • Notifiers
  • MobiLink Notification Properties


-o option
Function

Logs output messages to a MobiLink synchronization server message log file, and limits the data logged to the console window.

Syntax

dbmlsrv9 –c "connection-string" –o logfile...

Description

Write all log messages to the specified file. Note that the MobiLink synchronization server window, if present, usually shows a subset of all messages logged.

The MobiLink synchronization server gives the full error context in its output file if errors occur during synchronization. The error context may include the following information:

  • User Name This is the actual user name that is provided by MobiLink Adaptive Server Anywhere applications during synchronization.

  • Modified User Name This is the user name as modified by the modify_user script.

  • Transaction This lists the transaction the error occurs in. The transaction could be authenticate_user, begin_synchronization, upload, prepare_for_download, download, or end_synchronization.

  • Table Name This shows the table name if it is available or NULL.

  • Row Operation The operation could be INSERT, UPDATE, DELETE or FETCH.

  • Row Data This shows all the column values of the row that caused the error.

  • Script Version This is the script version currently used for synchronization.

  • Script This is the script that caused the error.

Error context information appears in the log regardless of your chosen level of verbosity.

See also
  • -os option
  • -dl option
  • -ot option
  • -on option
  • -v option


-on option
Function

Specifies a maximum size for the MobiLink synchronization server message log file, after which the file is renamed with the extension .old and a new file is started.

Syntax

dbmlsrv9 –c "connection-string" –on size [ k | m ]...

Description

The size is the maximum file size for the output log, in bytes. Use the suffix k or m to specify units of kilobytes or megabytes, respectively. The minimum size limit is 10 Kb.

When the log file reaches the specified size, the MobiLink synchronization server renames the output file with the extension .old, and starts a new one with the original name.

Note
If the .old file already exists, it is overwritten. To avoid losing old log files, use the -os option instead.

This option cannot be used with the -os option.

See also
  • -o option
  • -ot option
  • -on option
  • -os option
  • -v option


-oq option
Function

On Windows, prevents the appearance of the error dialog when a startup error occurs.

Syntax

dbmlsrv9 –c "connection-string" –oq ...

Description

By default, the MobiLink synchronization server displays a message box dialog if a startup error occurs. The -oq option prevents this dialog from being displayed.


-os option
Function

Sets the maximum size of the MobiLink synchronization server message log file, after which a new log file with a new name is created and used.

Syntax

dbmlsrv9 –c "connection-string" –os size [ k | m ]...

Description

The size is the maximum file size for logging output messages. The default unit is bytes. Use the suffix k or m to specify units of kilobytes or megabytes, respectively. The minimum size limit is 10 kb.

Before the MobiLink synchronization server logs output messages to a file, it checks the current file size. If the log message will make the file size exceed the specified size, the MobiLink synchronization server renames the message log file to yymmddxx.mls, where xx is a number from 00 to 99, and yymmdd represents the current year, month, and day.

You can use this option to prune old message log files to free up disk space. The latest output is always appended to the file specified by -o or -ot.

You cannot use this option with the -on option.

Note
This option will make an unlimited number of log files. To avoid this situation, use -o or -on.
See also
  • -o option
  • -on option
  • -ot option
  • -v option


-ot option
Function

Logs output messages to the MobiLink synchronization server message log file, but truncates it first.

Syntax

dbmlsrv9 –c "connection-string" –ot logfilename ...

Description

Truncate the message log file and then append output messages to it. The default is to send output to the screen.

See also
  • -on option
  • -os option
  • -v option
  • -o option


-ps option
Function

Sets the maximum number of prepared statements to cache per connection.

Syntax

dbmlsrv9 –c "connection-string" –ps num ...

Description

Controls the maximum number of ODBC prepared statements kept in the prepared statement cache.

Caching prepared statements improves performance, but consumes resources. Some consolidated database types have configurable limits on the number of prepared statements, so this option may be set accordingly.


-q option
Function

Instructs MobiLink to run in a minimized window on startup.

Syntax

dbmlsrv9 –c "connection-string" –q ...

Description

Minimize the MobiLink synchronization server window.


-r option
Function

Sets the maximum number of deadlock retries.

Syntax

dbmlsrv9 –c "connection-string" –r retries ...

Description

By default, MobiLink synchronization server retries uploads that are deadlocked, for a maximum of 10 attempts. If the deadlock is not broken, synchronization fails, since there is no guarantee that the deadlock can be overcome. This option allows an arbitrary retry limit to be set. To stop the server from retrying deadlocked transactions, specify –r 0. The upper bound on this setting is 2 to the power 32, minus one.


-rd option
Function

Sets the maximum delay time between deadlock retries.

Syntax

dbmlsrv9 –c "connection-string" –rd delay ...

Description

When upload transactions are deadlocked, the MobiLink synchronization server waits a random length of time before retrying the transaction. The random nature of the delay increases the likelihood that future attempts will succeed. This option allows you to specify the maximum delay in units of seconds. The value 0 (zero) makes retries instantaneous, but larger values are recommended because they yield more successful retries. The default and maximum delay value is 30.


-s option
Function

Sets the maximum number of rows fetched, inserted, updated, or deleted at once.

Syntax

dbmlsrv9 –c "connection-string" –s count ...

Description

Set the maximum number of rows transferred between the MobiLink synchronization server and the consolidated database to count.

Set this option to no less than the number of rows specified in the ODBC prefetch option, if this option is set. The default value is 10.

The number of rows fetched at once can be viewed in the log file as rowset size.

Note: The actual maximum number of rows transferred is influenced by settings in your ODBC data source, and/or database client software.


-sl dnet option
Function

Sets the .NET Common Language Runtime (CLR) options and forces the CLR to load on startup.

Syntax

dbmlsrv9 –c "connection-string" –sl dnet options ...

Description

Sets options to pass directly to the .NET CLR. The options are:

Option | Description
-D name=value Set an environment variable. For example,
-Dsynchtype=far -Dextra_rows=yes
For more information, see the .NET framework class System.Environment.
-MLAutoLoadPath=path | Set the location of base assemblies. Only works with private assemblies. To tell MobiLink where assemblies are located, use this option or -MLDomConfigFile, but not both. When you use -MLAutoLoadPath, you cannot specify a domain in the event script. The default is the current directory.
-MLDomConfigFile=file | Set the location of base assemblies. Use when you have shared assemblies, or you don't want to load all assemblies in the directory, or you can't use MLAutoLoadPath for some other reason. To tell MobiLink where assemblies are located, use -MLDomConfigFile or -MLAutoLoadPath, but not both.
-MLStartClasses=

classnames

 At server startup, load and instantiate user-defined start classes in the order listed.
-clrConGC | Enable concurrent garbage collection in the CLR.
-clrFlavor=( wks | svr ) | Flavor of the .NET CLR to load. The flavor is svr for server and wks for workstation. By default, wks is loaded.
-clrVersion=version | Version of the .NET CLR to load. This must be prefixed with v. For example, v1.0.3705 loads the directory \WINNT\Microsoft.NET\Framework\v1.0.3705.

To display this list of options, use the following command:

dbmlsrv9 -sl dnet (?)
See also
  • Writing Synchronization Scripts in .NET


-sl java option
Function

Sets the Java virtual machine options and forces the virtual machine to load on startup.

Syntax

dbmlsrv9 –c "connection-string" –sl java ( options ) ...

Description

Sets -jrepath and other options to pass directly to the Java virtual machine. The options are:

Option | Description
{ -hotspot | -server | -classic } | Override the default choice for the Java VM to use.
{ –cp | –classpath } location;... | Specify a set of directories or jar files in which to search for classes. You must enclose -cp or -classpath in either curly braces or round brackets.
–D name=value Set a system property. For example,
-Dsynchtype=far -Dextra_rows=yes
–DMLStartClasses=class, ... | At server startup, load and instantiate user-defined start classes in the order listed.
–jrepath path | Override the default JRE path, which is the sun\jre142 directory under the Sybase\shared directory.
–verbose [ :class |:gc | :jni ] | Enable verbose output.
–X vm-option | Set a VM-specific option as described in the file Xusage.txt, which by default is installed to Sybase\Shared\Sun\jre142\bin\hotspot.

Options must be enclosed in brackets. These can be round brackets, as shown in the syntax above, or curly braces { }.

To display this list of options, use the following command:

dbmlsrv9 -sl java (?)

To display a list of Java options you can use, type:

java
Description

The -jrepath option is only available on Windows. On UNIX, if you want to load a specific JRE, you should set the LD_LIBRARY_PATH (LIBPATH on AIX, SHLIB_PATH on HP-UX) to include the directory containing the JRE. The directory must be listed before any of the Adaptive Server Anywhere install directories.

See also
  • Writing Synchronization Scripts in Java
Examples

For example, the following partial dbmlsrv9 command line sets the Java virtual machine option that enables system asserts:

dbmlsrv9 -sl java {-cp ;\myclasses; -esa} ...

The following partial dbmlsrv9 command line defines the LDAP_SERVER system property:

dbmlsrv9 -sl java { -cp ;\myclasses; -DLDAP_SERVER=huron-ldap } ...


-t option
Function

Creates a file containing all the ODBC calls issued by MobiLink.

Syntax

dbmlsrv9 –c "connection-string" –t ODBC-output-file ...

Description

This option can be used to create a file containing all of the ODBC calls issued by MobiLink. If used on UNIX, with the Adaptive Server Anywhere driver used as a driver manager, this feature is ignored. The feature is useful for tracing what was called, passed, and retrieved. It has a severe impact on performance, so should not be used in production.

To prevent the file from becoming large, use the -tt option.

See also
  • -tt option


-tt option
Function

Logs ODBC calls issued by MobiLink to a file. If the file already exists, it first deletes it.

Syntax

dbmlsrv9 –c "connection-string" –tt ODBC-output-file ...

Description

This option is used to create a file containing all of the ODBC calls issued by MobiLink. If used on UNIX with the Adaptive Server Anywhere driver used as a driver manager, this feature is ignored. The feature is useful for tracing what was called, passed, and retrieved. It has a severe impact on performance, so should not be used in production.

See also
  • -t option


-u option
Function

Sets the upload cache size.

Syntax

dbmlsrv9 –c "connection-string" –u size[ k | m | g ] ...

Description

The amount of space, in bytes, to reserve for caching upload streams that are being processed. Use the suffix k, m, or g to specify units of kilobytes, megabytes, or gigabytes respectively. You should consider enlarging this value if your clients upload large streams, or many clients synchronize at once, or both. The suggested size is the maximum expected size of an upload stream multiplied by the number of worker threads. The default value is 500 Kb.

See also
  • -bc option


-ud option
Function

Instructs MobiLink to run as a daemon.

Syntax

dbmlsrv9 –c "connection-string" –ud ...

Description

UNIX platforms only.

See also
  • Running MobiLink Outside the Current Session


-us option
Function

Prevents the MobiLink synchronization server from invoking upload scripts for a table when no rows are uploaded for the table.

Syntax

dbmlsrv9 –c "connection-string" –us ...

Description

This option is particularly useful when dbmlsync transaction-level uploads are used.

See also

-tu option


-v option
Function

Allows you to specify what information is logged to the message log file and displayed in the synchronization window.

Syntax

dbmlsrv9 –c "connection-string" –v[ levels ] ...

Description

This option is particularly useful when dbmlsync transaction-level uploads are used.

This option controls the type of messages written to the message log file.

If you specify –v alone, the MobiLink synchronization server writes a minimal amount of information about each synchronization.

The values of levels are as follows. You can use one or more of these options at once; for example, -vnrsu.

  • + Turn on all logging options that increase verbosity.

  • c Show the content of each synchronization script when it is invoked. This level implies s.

  • f Show first-read errors. This will log errors caused when load-balancing devices check for server liveness by making connections that don't send any data, and thus result in failed synchronizations.

    For TCP/IP connections, you might be better off using the TCP/IP option ignore. For more information, see -x option.

  • h Show the remote schema as uploaded during synchronization.

  • n Show row-count summaries.

  • p Show progress offsets.

  • r Display the column values of each row uploaded or downloaded.

  • s Show the name of each synchronization script as it is invoked.

  • t Show the translated SQL that results from scripts that are written in ODBC canonical format. This level implies c. The following example shows the automatic translation of a statement for Adaptive Server Anywhere.

    I. 02/11 11:02:14. [102]: begin_upload synch2
{ call SynchLogLine( ?, ?, 'begin_upload' ) }
I. 02/11 11:02:14. [102]: Translated SQL:
call SynchLogLine( ?, ?, 'begin_upload' )

    The following example shows the translation of the same statement for Microsoft SQL Server.

    I. 02/11 11:03:21. [102]: begin_upload synch2
{ call SynchLogLine( ?, ?, 'begin_upload' ) }
I. 02/11 11:03:21. [102]: Translated SQL:
EXEC SynchLogLine ?, ?, 'begin_upload'

  • u Show undefined table scripts. This may help new users understand the synchronization process.


-w option
Function

Sets the number of worker threads.

Syntax

dbmlsrv9 –c "connection-string" –w count ...

Description

Each worker thread accepts synchronization requests one at a time. Each worker thread is associated with a network protocol. If you have more than one protocol defined, the worker threads are divided evenly among the protocols.

Each worker thread uses one connection to the consolidated database. The MobiLink synchronization server opens one additional connection for administrative purposes. Hence, the minimum number of connections from the MobiLink synchronization server to the consolidated database is count + 1.

The number of worker threads has a strong influence on MobiLink synchronization throughput, and you need to run tests to determine the optimum number for your particular synchronization setup. The number of worker threads determines how many synchronizations can be active simultaneously; the rest will be queued waiting for worker threads to become available. Thus adding worker threads should increase throughput, but it will also increase the possibility of contention between the active synchronizations. At some point adding more worker threads will decrease throughput, because the increased contention outweighs the benefit of overlapping synchronizations.

For more information, see the MobiLink Performance whitepaper at [external link] http://my.sybase.com/detail?id=1009664, and MobiLink Performance.

The value set for this option is also the default setting for the -wu option, which can be used to limit the number of threads that can simultaneously upload. This is useful if the optimum number of worker threads for downloading is larger than the optimum number for uploading, as is typically the case with remote databases on slow computers or with slow connections to the MobiLink server. Tests have shown that for slow synchronization clients (such as Palm devices or computers connected by dialup), the best throughput is achieved with a large number of worker threads (via -w) with a small number allowed to apply uploads simultaneously (via -wu). In general, the optimum number for -wu depends on the consolidated database, and is relatively independent of the processing or network speeds for the remote databases. Therefore, when you increase the number of threads with -w, you may want to use -wu to restrict the number that can upload simultaneously. For more information, see -wu option.

The default number of worker threads is 5.


-wu option
Function

Sets the maximum number of worker threads that can apply uploads simultaneously.

Syntax

dbmlsrv9 –c "connection-string" –wu count ...

Description

Use the -wu option to limit the number of worker threads that can simultaneously apply uploads. When the limit is reached, a worker thread that is ready to apply its upload must wait until another finishes its upload. The excess worker threads are still free to receive uploads or to download.

The most common cause of contention in the consolidated database is having too many worker threads applying uploads simultaneously. This can be an issue when the network connection is slow, or when the client device has low processing speed. For example, when working over a wide-area wireless network or using a Palm device you may want to increase the total number of threads (-w) but limit the number that can apply uploads simultaneously.

Consider the following example. In a pilot setup using a LAN and remote databases on PCs, you find that the optimum number of worker threads is approximately 10 for both upload-only and download-only synchronizations, and that corresponds to 100% CPU utilization on the consolidated database. With fewer worker threads you find that throughput is less and the CPU utilization for the consolidated database is lower. With more worker threads, throughput does not increase because the consolidated database is already processing as fast as it can with 10 workers. When you switch to using a dialup network with 10 MobiLink worker threads, you will probably find that throughput is lower and the consolidated CPU utilization has dropped. You may find that you can get throughput (and consolidated CPU utilization) to approach the values obtained with the LAN by increasing the number of worker threads (via -w) while keeping the number that apply uploads simultaneously limited to 10 (via -wu).

By default, all worker threads can apply uploads simultaneously. The number of worker threads that are used is set by the -w option. The default is 5.


-x option
Function

Sets network protocol and protocol options for MobiLink clients. These are used by the MobiLink synchronization server to listen for synchronization requests.

Syntax

dbmlsrv9 –c "connection-string"
–x protocol[ protocol-options ]...

protocol-options : ( keyword=value;... )

Description

Specify communications protocol through which to communicate with client applications. The default is TCPIP with port 2439.

Note for UltraLite users
If you are using an UltraLite Java application and you are using TLS security, the syntax of -x is slightly different. For details, see Using transport-layer security.

The allowed values of protocol are as follows:

  • tcpip Accept connections from applications via TCP/IP.

  • http Accept connections via the standard Web protocol. Client applications can pick their HTTP version and the MobiLink synchronization server adjusts on a per-connection basis.

  • https Accept connections via a variant of HTTP that handles secure transactions. The HTTPS stream implements HTTP over SSL/TLS using RSA encryption, and is compatible with any other HTTPS server.

  • https_fips Accept connections using the HTTPS protocol and FIPS-approved algorithms for encryption. HTTPS_FIPS uses separate FIPS 140-2 certified software. Servers using rsa_tls are compatible with clients using rsa_tls_fips, and servers using rsa_tls_fips are compatible with clients using rsa_tls. rsa_tls_fips can only be used with Adaptive Server Anywhere databases on Windows.

Optionally, you can also specify network protocol options, in the form option=value. You should separate multiple options with semicolons. Which options you specify depends on the protocol you choose.

  • TCP/IP options If you specify the tcpip protocol, you can optionally specify the following protocol options:

    • backlog=number-of-connections

      The maximum number of remote connections before MobiLink should reject new synchronization requests, causing synchronization to fail on the client side. By specifying a backlog size, you can prevent clients from waiting to synchronize when the server is busy. If you do not specify a backlog size, clients will attempt to synchronize regardless of the size of the backlog.

    • host=hostname

      The host name or IP number on which the MobiLink synchronization server should listen. The default value is localhost.

    • ignore=hostname A host name or IP number that will be ignored by the MobiLink synchronization server if it makes a connection. This option allows you to ignore requests from load balancers at the lowest possible level, preventing excessive output in the MobiLink server log and MobiLink Monitor output files. You can specify multiple hosts to ignore; for example -x tcpip(ignore=lb1;ignore=123.45.67.89).

    • liveness_timeout=n The amount of time, in seconds, after the last communication with a client before MobiLink aborts the synchronization. A value of 0 means that there is no timeout. This option is only effective if download acknowledgement on the client is set to off (the default). The default is 120 seconds.

    • port=portnumber The socket port number on which the MobiLink synchronization server should listen. The default port is 2439, which is the IANA registered port number for the MobiLink synchronization server.

    • security=cipher(keyword=value;...) All communication through this connection is to be encrypted and authenticated using transport-layer security. The cipher can be one of ecc_tls, rsa_tls, or rsa_tls_fips, for elliptic-curve encryption, RSA encryption, or RSA encryption that is FIPS-approved, respectively. rsa_tls_fips uses separate FIPS 140-2 certified software from Certicom but is compatible with clients using https (and version 9.0.2 or later). rsa_tls_fips can only be used with Adaptive Server Anywhere clients on Windows.

      For backwards compatibility, ecc_tls can also be specified as certicom_tls.

      The security parameters are certificate (the path and file name of the certificate that is to be used for server authentication), and certificate_password. You must use a certificate that matches the cipher suite you choose.

      For more information, see Starting the MobiLink synchronization server with transport-layer security.

      Separately licensable option required
      Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

      To order this component, see Separately-licensable components.

  • HTTP options If you specify the http protocol, you can optionally specify the following protocol options:

    • backlog=number-of-connections

      The maximum number of remote connections before MobiLink should reject new synchronization requests, causing synchronization to fail on the client side. By specifying a backlog size, you can prevent clients from waiting to synchronize when the server is busy. If you do not specify a backlog size, clients will attempt to synchronize regardless of the size of the backlog.

    • buffer_size=number

      The maximum body size for an HTTP message sent from MobiLink server, in bytes. Changing the option will decrease or increase the amount of memory allocated for sending HTTP messages. The default is 65 535 bytes.

    • contd_timeout=seconds

      The number of seconds the MobiLink synchronization server waits to receive the next part of a partially completed synchronization before the synchronization is abandoned. You can tune this option to free MobiLink worker threads when the wait time indicates that the client will never continue the connection. The default value is 30 seconds.

    • host=hostname The host name or IP number on which the MobiLink synchronization server should listen. The default value is localhost.

    • port=portnumber The socket port number on which the MobiLink synchronization server should listen. The port number must be a decimal number that matches the port the MobiLink synchronization server is setup to monitor. The default port is 80.

    • unknown_timeout=seconds The number of seconds the MobiLink synchronization server waits to receive HTTP headers on a new connection before the synchronization is abandoned. You can tune this option to free MobiLink worker threads when the wait time indicates that a network failure has occurred. The default value is 30 seconds.

    • url_suffix=suffix The suffix to add to the URL on the first line of each HTTP request. This parameter can be used to help ensure that a particular client connects to the intended server. Values must match or synchronization will not be successful.

    • version=http-version The MobiLink synchronization server automatically detects the HTTP version used by a client. This parameter is a string specifying the default version of HTTP to use in case the server cannot detect the method used by the client. You have a choice of 1.0 or 1.1. The default value is 1.1.

  • HTTPS or HTTPS_FIPS options The https communication stream uses RSA digital certificates for transport-layer security. The https_fips stream uses separate FIPS 140-2 certified software but is compatible with https.

    For more information, see Starting the MobiLink synchronization server with transport-layer security.

    Separately licensable option required
    Transport-layer security requires that you obtain a separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

    To order this component, see Separately-licensable components.

    If you specify the https protocol, you can optionally specify the following protocol options:

    • backlog=number-of-connections

      The maximum number of remote connections before MobiLink should reject new synchronization requests, causing synchronization to fail on the client side. By specifying a backlog size, you can prevent clients from waiting to synchronize when the server is busy. If you do not specify a backlog size, clients will attempt to synchronize regardless of the size of the backlog.

    • buffer_size=number The maximum body size for an HTTPS message sent from MobiLink server, in bytes. Changing the option will decrease or increase the amount of memory allocated for sending HTTPS messages. The default is 65 535 bytes.

    • contd_timeout=seconds

      The number of seconds the MobiLink synchronization server waits to receive the next part of a partially completed synchronization before the synchronization is abandoned. You can tune this option to free MobiLink worker threads when the wait time indicates that the client will never continue the connection. The default value is 30 seconds.

    • host=hostname The host name or IP number on which the MobiLink synchronization server should listen. The default value is localhost.

    • port=portnumber

      The socket port number on which the MobiLink synchronization server should listen. The port number must be a decimal number that matches the port the MobiLink synchronization server is setup to monitor. The default port is 443.

    • certificate The path and file name of the certificate that is to be used for server authentication. This must be an RSA certificate.

    • certificate_password An optional parameter that specifies a password for the certificate.

      For more information about security, see MobiLink Transport-Layer Security.

    • unknown_timeout=seconds The number of seconds the MobiLink synchronization server waits to receive HTTP headers on a new connection before the synchronization is abandoned. You can tune this option to free MobiLink worker threads when the wait time indicates that a network failure has occurred. The default value is 30 seconds.

    • url_suffix=suffix The suffix to add to the URL on the first line of each HTTP request. This parameter can be used to help ensure that a particular client connects to the intended server. Values must match or synchronization will not be successful.

    • version=http-version The MobiLink synchronization server automatically detects the HTTP version used by a client. This parameter is a string specifying the default version of HTTP to use in case the server cannot detect the method used by the client. You have a choice of 1.0 or 1.1. The default value is 1.1.

Examples

The following command line sets the backlog size to 10 connections.

dbmlsrv9 -c dsn=asa90sample;uid=DBA;pwd=SQL -x http(backlog=10)


-za option
Function

Generates statement-based scripts that perform a simple snapshot synchronization.

Syntax

dbmlsrv9 –c "connection-string" –za

Description

The following scripts are generated:

  • upload_insert

  • upload_update

  • upload_delete

  • download_cursor

This option generates active scripts; that is, they are used for the current synchronization. The scripts are also saved and will work for subsequent synchronizations using the same script version. The -za option is typically used for quick demos. To generate scripts as a starting point for writing your own scripts, the dbmlsrv9 -ze option might be more useful.

To generate scripts, you must also specify that the client sends column names. You do this when you initiate synchronization. For Adaptive Server Anywhere remotes, see SendColumnNames (scn) extended option. For UltraLite remotes, see Send Column Names synchronization parameter.

The generated scripts perform one-to-one snapshot synchronization using the table and column names sent from the client. If the consolidated database has different table or column names than the remote, activating these scripts will cause an error during the synchronization.

Note:
Scripts are generated the first time that a remote synchronizes with a script version that doesn't exist. If the given script version already exists, -za has no effect. This means that you cannot use -za to generate scripts one table at a time for the same script version. Using -za, you must generate scripts for all tables and publications at once.
See also
  • -ze option
Example

The following dbmlsrv9 command enables automatic script generation. The dbmlsync command sets the necessary SendColumnNames option.

dbmlsrv9 -c "dsn=YourDBDSN" -za
dbmlsync -c dsn=dsn_remote -e "SendColumnNames=ON"


-ze option
Function

Generates sample scripts that, if activated, perform a simple snapshot synchronization.

Syntax

dbmlsrv9 –c "connection-string" –ze

Description

The following scripts are generated:

  • example_upload_insert

  • example_upload_update

  • example_upload_delete

  • example_download_cursor

You can use these scripts as starting points for creating your own scripts.

To generate scripts, you must also specify that the client sends column names. You do this when you initiate synchronization. For Adaptive Server Anywhere remotes, see SendColumnNames (scn) extended option. For UltraLite remotes, see Send Column Names synchronization parameter.

The generated scripts perform one-to-one snapshot synchronization using the table and column names sent from the client. If the consolidated database has different table or column names than the remote, activating these scripts will cause an error during the synchronization.

Note:
Scripts are generated only the first time that a remote synchronizes, and only when the given script version does not exist. Otherwise, -ze has no effect.
See also
  • -za option


-zp option
Function

Adjusts which timestamp values will be used for conflict detection purposes.

Syntax

dbmlsrv9 –c "connection-string" –zp

Description

In the event of a timestamp conflict between the consolidated and remote database, this option allows timestamp values with a precision higher than the lowest precision to be used for conflict detection purposes. The option is useful when timestamps in the consolidated database are more precise than in the remote, as updated timestamps on the remote can cause conflicts in the next synchronization. The option allows MobiLink to ignore these conflicts. When there is a precision mismatch and -zp is not used, a per synchronization and a schema sensitive per table warning are written to the log to advertise the -zp option. Another per synchronization warning is also added to advise users to adjust the timestamp precision on the remote database where possible.


-zs option
Function

Specifies a MobiLink server name for dbmlstop.

Syntax

dbmlsrv9 –c "connection-string" –zs name

Description

The name that is specified may include letters and numbers, but no other characters.

When dbmlstop is used to shut down a MobiLink synchronization server started with the -zs option, you must specify the server name on the dbmlstop command line. For example, dbmlstop myMLserver. Shutdown may only be initiated from the computer where the MobiLink synchronization server is installed.

See also
  • MobiLink stop utility


-zt option
Function

Specifies the maximum number of processors used to run the MobiLink synchronization server.

Syntax

dbmlsrv9 –c "connection-string" –zt number

Description

This option may be required for some ODBC drivers. It also gives you fine control of processor resources.

This option can only be used on Windows operating systems. The default is the number of processors on the computer.


-zu option
Function

Controls the automatic addition of users when the authenticate_user script is undefined.

Syntax

dbmlsrv9 –c "connection-string" –zu{ + | - } ...

Description

If this is supplied as -zu+, then unrecognized MobiLink user names are added to the ml_user table on first synchronizing. If the argument is supplied as -zu-, or not supplied, unrecognized user names are prevented from synchronizing.

See also
  • Authenticating MobiLink Users
  • MobiLink user authentication utility
  • authenticate_user connection event


-zw option
Function

Controls which levels of warning message to display.

Syntax

dbmlsrv9 –c "connection-string" –zw levels

Description

MobiLink has five levels of warning messages:

Level | Description
0 | Suppress all warning messages
1 | Server and high ODBC level: warning messages when the MobiLink synchronization server starts
2 | Synchronization and user level: warning messages when a synchronization starts
3 | Schema level: warning messages when a MobiLink synchronization server is processing a client schema
4 | Script and lower ODBC level: warning messages when a MobiLink synchronization server fetches, prepares, or executes scripts
5 | Table or row level: warning messages when a MobiLink synchronization server performs table operations in an upload or download

To specify the level of warning messages you want reported, you can separate levels with a comma, or separate a range with two dots. For example, -zw 1..3,5 is the same as -zw 1,2,3,5.

The reporting of messages has a slight impact on performance. Levels with a higher number tend to produce more messages.

If -zw is used more than once in the same command line, MobiLink recognizes only the last instance. If settings of -zw, -zwd, and -zwe conflict, MobiLink gives priority to -zwe, then -zwd, then -zw.

The default is 1,2,3,4,5, which indicates that all levels of warning message should be displayed.


-zwd option
Function

Disables specific warning codes.

Syntax

dbmlsrv9 –c "connection-string" –zwd code,...

Description

You can disable specific warning codes so that they will not be reported, even though other codes of the same level are reported.

For a complete list of warning message codes, see MobiLink Synchronization Server Warning Messages.

If -zwd is used more than once in the same command line, MobiLink accumulates the settings. If settings of -zw, -zwd, and -zwe conflict, MobiLink gives priority to -zwe, then -zwd, then -zw.


-zwe option
Function

Enables specific warning codes.

Syntax

dbmlsrv9 –c "connection-string" –zwe code,...

Description

You can enable specific warning codes so that they will be reported even though you have disabled other codes of the same level using -zw.

For a complete list of warning message codes, see MobiLink Synchronization Server Warning Messages.

If -zwe is used more than once on the same command line, MobiLink accumulates the settings. If settings of -zw, -zwd, and -zwe conflict, MobiLink gives priority to -zwe, then -zwd, then -zw.


Writing Synchronization Scripts

About this chapter

You control the synchronization process by writing synchronization scripts and storing them in the consolidated database.

You can write scripts in SQL, Java, or .NET. This chapter applies to all kinds of scripts, but focuses on how to write synchronization scripts in SQL.

For more information about writing scripts, see

  • Synchronization Events

  • Synchronization Techniques

  • Writing Synchronization Scripts in Java

  • Writing Synchronization Scripts in .NET

Introduction to synchronization scripts
Scripts and the synchronization process
Script types
Script parameters
Script versions
Adding and deleting scripts in your consolidated database
Writing scripts to upload rows
Writing scripts to download rows
Writing scripts to handle errors
Testing script syntax


Introduction to synchronization scripts

MobiLink Synchronization logic consists of scripts, which may be individual statements or stored procedure calls, stored in your consolidated database. During synchronization, the MobiLink synchronization server reads the scripts and executes them against the consolidated database. Scripts provide you with opportunities to perform tasks at various points of time during the synchronization process. You can use Sybase Central to add scripts to the consolidated database or you can use stored procedures.

Synchronization scripts held in the consolidated database.

The synchronization process is composed of multiple steps. A unique event name identifies each step. You control the synchronization process by writing scripts associated with some of these events. You write a script only when some particular action must occur at a particular event. The MobiLink synchronization server executes each script when its associated event occurs. If you do not define a script for a particular event, the MobiLink synchronization server simply proceeds to the next step.

For example, one event is begin_upload_rows. You can write a script and associate it with this event. The MobiLink synchronization server reads this script when it is first needed, and executes it during the upload phase of synchronization. If you write no script, the MobiLink synchronization server proceeds immediately to the next step, which is processing the uploaded rows.

Some scripts, called table scripts, are associated not only with an event, but also with a particular table in the remote database. The MobiLink synchronization server performs some tasks on a table-by-table basis; for example, downloading rows. You can have many scripts associated with the same event, but each with different application tables. Alternatively, you can define many scripts for some application tables, but none for others.

For an overview of events, see The synchronization process.

For a description of every script you can write, see Synchronization Events.

You can write scripts in SQL, Java, or .NET. This chapter applies to all kinds of scripts, but focuses on how to write synchronization scripts in SQL.

For a description and comparison of SQL, Java, and .NET, see Options for writing synchronization logic.

For information about writing scripts in .NET, see Writing Synchronization Scripts in .NET.

For information about writing scripts in Java, see Writing Synchronization Scripts in Java.

For information about how to implement synchronization scripts, see Synchronization Techniques.


A simple synchronization script

MobiLink provides many events that you can exploit, but it is not mandatory to provide scripts for each event. In a simple synchronization model, you may need only a few scripts.

Downloading all the rows from the table to each remote database synchronizes the ULProduct table in the CustDB sample application. In this case, no additions are permitted at the remote databases. You can implement this simple form of synchronization with a single script; in this case only one event has a script associated with it.

The MobiLink event that controls the rows to be downloaded during each synchronization is named the download_cursor event. Cursor scripts must contain SELECT statements. The MobiLink synchronization server uses these queries to define a cursor. In the case of a download_cursor script, the cursor selects the rows to be downloaded to one particular table in the remote database.

In the CustDB sample application, there is a single download_cursor script for the ULProduct table in the sample application, which consists of the following query.

SELECT prod_id, price, prod_name
FROM ULProduct

This query generates a result set. The rows that make up this result set are downloaded to the client. In this case, all the rows of the table are downloaded.

The MobiLink synchronization server knows to send the rows to the ULProduct application table because this script is associated with both the download_cursor event and ULProduct table by the way it is stored in the consolidated database. Sybase Central allows you to make these associations.

Note
In this example, the query selects data from a consolidated table also named ULProduct. The names need not match. You could, instead, download data to the ULProduct application table from any table, or any combination of tables, in the consolidated database by rewriting the query.

You can write more complicated synchronization scripts. For example, you could write a script that downloads only recently modified rows, or one that provides different information to each remote database.


Generating scripts automatically

You can use the dbmlsrv9 -za option to generate default synchronization scripts. The synchronization scripts perform a snapshot synchronization of your consolidated database with your remote database using table and column names that are sent from the client.

To use this feature with Adaptive Server Anywhere clients, set the SendColumnNames extended option to ON to cause dbmlsync to send the column names with the upload header. To use this feature with UltraLite clients, set the send_column_names parameter to ul_true.

When you use -za, scripts are generated the first time that a remote synchronizes with a script version that doesn't exist. If the given script version already exists, -za has no effect. This means that you cannot use -za to generate scripts one table at a time for the same script version. Using -za, you must generate scripts for all tables and publications at once.

For more information, see -za option.

Example

Start the MobiLink synchronization server using the -za switch. For example, type:

dbmlsrv9 -c "dsn=YourDBDSN" -za

Run dbmlsync and set the SendColumnNames extended option to ON. For example, type:

dbmlsync -c dsn=dsn_remote -e "SendColumnNames=ON"

Scripts are generated for all tables specified in the publication. On synchronization, these automatically-generated scripts control the upload and download of data to and from your client and consolidated databases. The following table describes these scripts for the emp table.

Script name Script contents
upload_insert
INSERT INTO emp (emp_id, emp_name)
VALUES (?,?)
upload_update
UPDATE emp SET emp_name=?
WHERE emp_id=?
upload_delete
DELETE FROM emp
WHERE emp_id=?
download_cursor
SELECT emp_id, emp_name FROM emp


Generating example scripts

You can use the dbmlrv9 -ze option to generate example synchronization scripts. The example synchronization scripts are capable of performing a snapshot synchronization of your consolidated database with your remote database using the table and column names sent from the client, but they are not enabled. If the consolidated database has different table or column names, then activating these scripts causes an error during the synchronization.

To use this feature with Adaptive Server Anywhere clients, set the SendColumnNames extended option to ON to cause dbmlsync to send the column names with the upload header. To use this feature with UltraLite clients, set the send_column_names parameter to ul_true.

The -ze option generates the example scripts example_upload_insert, example_upload_update, example_upload_delete, and example_download_cursor.

For more information, see -ze option.

Example

The following example generates scripts for an Adaptive Server Anywhere remote database.

At a command prompt, type:

dbmlsrv9 -c "dsn=YourDBDSN" -ze

At a command prompt, type:

dbmlsync -c dsn=dsn_remote -e "SendColumnNames=ON"

In the example above, example scripts are generated for all tables specified in the synchronization definition. The scripts exist for each table specified in the synchronization definition. The following table lists these scripts for the emp table.

Script name Script
example_upload_insert
INSERT INTO emp (emp_id,emp_name) VALUES (?,?)
example_upload_update
UPDATE emp SET emp_name=?
WHERE emp_id=?
example_upload_delete
DELETE FROM emp
WHERE emp_id=?
example_download_cursor
SELECT emp_id, emp_name FROM emp

The example scripts select and upload all records from any table in the synchronization subscription that meet the conditions specified in the statement. So, for example, the upload_insert script for emp inserts all records from emp. The example scripts are generated for each table in the remote database specified in the synchronization subscription. The MobiLink synchronization server generates complete scripts needed for a snapshot synchronization. The scripts are added right after the synchronization description is processed. The synchronization is aborted after scripts are generated.


Example scripts for UltraLite

When you build an UltraLite application, the UltraLite generator automatically inserts an example_download_cursor script into the UltraLite reference database. The action of the example download script is to download all rows of a corresponding table that exists in the remote database. The script specifies the select list in the correct order.

The example script is inserted into the ml_scripts table, but they are not used unless you insert an entry in the ml_table_script table that associates them with the download_cursor event.

Minimally, the example scripts for download cursors provide the order of columns expected by the remote database.


Scripts and the synchronization process

Each script corresponds to a particular event in the synchronization process. You write a script only when some action must occur. All unnecessary events can be left undefined.

The two principal parts of the process are the processing of uploaded information and the preparation of rows for downloading.

The MobiLink synchronization server reads and prepares each script once, when it is first needed. The script is then executed whenever the event is invoked.

The sequence of events

For information about the full sequence of MobiLink events, see Overview of MobiLink events.

For the details of upload stream processing, see Writing scripts to upload rows.

For the details of download stream processing, see Writing scripts to download rows.

Notes

  • MobiLink technology allows multiple clients to synchronize concurrently. In this case, each client uses a separate connection to the consolidated database.

  • The begin_connection and end_connection events are independent of any one synchronization as one connection can handle many synchronization requests. These scripts have no parameters. These are examples of connection-level scripts.

  • Some events are invoked only once for each synchronization and have a single parameter. This parameter is the user name, which uniquely identifies the MobiLink client that is synchronizing. These are also examples of connection-level scripts.

  • Some events are invoked once for each table being synchronized. Scripts associated with these events are called table-level scripts. They provide two parameters. The first is the user name supplied in the call to the synchronization function, and the second is the name of the table in the remote database being synchronized.

    While each table can have its own table scripts, you can also write table-level scripts that are shared by several tables.

  • Some events, such as begin_synchronization, occur at both the connection level and the table level. You can supply both connection and table scripts for these events.

  • The COMMIT statements illustrate how the synchronization process is broken up into distinct transactions.

  • Errors are a separate event that can occur at any point within the synchronization process. Errors are handled using the following script.

    handle_error( error_code, error_message, user_name, table_name )

For reference material, including detailed information about each script and its parameters, see Synchronization Events.


Script types

Synchronization scripts can apply to the entire connection or to specific tables.

  • connection scripts These scripts perform actions that are connection-specific or synchronization-specific and that are independent of any one remote table. These scripts are used in conjunction with other scripts when implementing more complex synchronization schemes.

  • table scripts These scripts perform actions specific to one synchronization and one particular remote table. These scripts are used in conjunction with other scripts when implementing more complex synchronization schemes.


Connection scripts

Connection-level scripts control high level events that are not associated with a particular table. Use these events to perform global tasks that are required during every synchronization.

Connection scripts control actions centered on connecting and disconnecting, as well as actions at synchronization-level events such as beginning and ending the upload or download process. Some connection scripts have related table scripts. These connection scripts are always invoked regardless of the tables being synchronized.

You only need to write a connection-level script when some action must occur at a particular event. You may need to create scripts for only a few events. The default action at any event is for the MobiLink synchronization server to carry out no actions. Some simple synchronization schemes need no connection scripts.


Table scripts

Table scripts allow actions at specific events relating to the synchronization of a specific table, such as the start or end of uploading rows, resolving conflicts, or selecting rows to download.

The synchronization scripts for a given table can refer to any table, or combination of tables, in the consolidated database. You can use this feature to fill a particular remote table with data stored in one or more consolidated tables, or to store data uploaded from a single remote table into multiple tables in the consolidated database.

Table names need not match

The names of tables in the remote databases need not match the names of the tables in the consolidated database. The MobiLink synchronization server determines which scripts are associated with a table by looking up the remote table name in the ml_table system table.


Script parameters

Most synchronization scripts receive parameters from the MobiLink synchronization server. You can use these parameters in your scripts by placing question marks in the script.

The following are some common parameters used in scripts.

  • last_download_timestamp The last download timestamp is the value obtained from the consolidated database during the last successful synchronization immediately prior to the download phase. If the current MobiLink user has never synchronized, or has never synchronized successfully, this value is set to 1900-01-01.

    For more information, see Timestamp-based synchronization.

  • ml_username The value of this parameter is the string that uniquely identifies a MobiLink client. Each client must identify itself by this name when initiating synchronization with a MobiLink synchronization server. This parameter is available within most connection-level scripts, all table-level scripts, and some cursor scripts.

    The user name can be used to partition tables among remote databases.

  • table This parameter identifies a table in the remote database. The consolidated database may or may not contain a table with the same name. Only table scripts use this parameter.

To use parameters, place a single question mark in your SQL script for each parameter. Some parameters are optional. The MobiLink synchronization server replaces each question mark with the value of a parameter. It substitutes values in the order the parameters appear in the script definition.

For reference material, including detailed information about each script and its parameters, see Synchronization Events.


Script versions

Scripts are organized into groups called script versions. By specifying a particular version, MobiLink clients can select which set of synchronization scripts will be used to process the upload stream and prepare the download stream.

For information about how to add a script version to the consolidated database, see Adding a script version.

Application of script versions

Script versions allow you to organize your scripts into sets, which are run under different circumstances. This ability provides flexibility and is especially useful in the following circumstances.

  • customization Using a different set of scripts to process information from different types of remote users. For example, you could write a different set of scripts for use when managers synchronize their databases than would be used for other people in the organization. Although you could achieve the same functionality with one set of scripts, these scripts would be more complicated.

  • upgrading applications When you wish to upgrade a database application, new scripts may be needed because the new version of your application may handle data differently. New scripts are almost always necessary when the remote database changes. It is usually impossible to upgrade all users simultaneously. MobiLink clients can request that a new set of scripts be used during synchronization. Since both old and new scripts can coexist on the server, all users can synchronize no matter which version of your application they are using.

  • multiple applications A single MobiLink synchronization server may need to synchronize two entirely different applications. For example, some employees may use a sales application, whereas others require an application designed for inventory control. When two applications require different sets of data, you can create two versions of the synchronization scripts, one version for each application.

  • set properties for the script version You can set properties for your script version that can be referenced from classes in .NET or Java synchronization logic. For more information, see ml_add_property.

Assigning version names

A script version name is a string. You specify this name when you add a script to the consolidated database. For example, if you add your scripts with the ml_add_connection_script and the ml_add_table_script stored procedures, the script version name is the first parameter. Alternatively, if you add your scripts using Sybase Central, you are prompted for the version name.

You cannot use the following names for script versions: ml_sis_1 or ml_qa_1. These names are used internally by MobiLink. In addition, it is recommended that your script versions do not start with ml_.

The default script version

Whenever a remote site fails to supply a script version, the MobiLink synchronization server uses the first version defined in the ml_script_version table. If no script version has been defined, the synchronization fails.

Adding a script version


Adding a script version

All scripts are associated with a script version. You must add a version name to your consolidated database before you can add any connection scripts.

For more information, see Script versions.

toggle To add a script version to a database (Sybase Central)

  1. From Sybase Central, right-click MobiLink Synchronization and connect to the consolidated database.

  2. Open the Versions folder.

  3. Double-click Add Version and follow the instructions in the wizard.

toggle To remove a script version from a database (Sybase Central)

  1. From Sybase Central, right-click MobiLink Synchronization and connect to the consolidated database.

  2. Open the Versions folder.

  3. Right-click the version name and select Delete.

  4. The Confirm Delete dialog appears. Click Yes.

toggle To add a script version to a database (stored procedures)

  • You can add a script version in the same operation as adding a connection script or table script.

For more information, see Stored procedures to add or delete scripts.


Adding and deleting scripts in your consolidated database

When you have created scripts, you must add them to MobiLink system tables in the consolidated database. To do this, you can use stored procedures or Sybase Central wizards.

For information about the MobiLink system tables, see MobiLink System Tables.

Note: SQL scripts are stored in the consolidated database. In the case of Java and .NET scripts, the location of the script is stored in the consolidated database. However, the method for adding/deleting a script or script location is similar.


Adding or deleting scripts

You can add synchronization scripts using Sybase Central wizards. The procedure is different for connection scripts and table scripts. Table scripts correspond to tables in the remote database, so before you can add a table script, you must add the name of the remote database table to the consolidated database.

If you are using Sybase Central, you must add a synchronization version to the database before you can add individual scripts. For more information, see Adding a script version.

toggle To add or delete a connection script (Sybase Central)

  1. From Sybase Central, right-click MobiLink Synchronization and connect to the consolidated database.

  2. Open Connection Scripts.

  3. To add a connection script, double-click Add Connection Script and follow the instructions in the wizard.

    or

    To delete a connection script, right-click the script name and select Delete. The Confirm Delete dialog appears. Click Yes.

toggle To add or delete a remote table in the list of synchronized tables (Sybase Central)

  1. From Sybase Central, right-click MobiLink Synchronization and connect to the consolidated database.

  2. Open Synchronized Tables.

  3. To add a remote table to the list of synchronized tables, double-click Add Synchronized Table. Enter the name of a table at the remote database for which you are going to write synchronization scripts. The wizard provides a shortcut if the consolidated database has a table with a matching name.

    or

    To delete a remote table from the list of synchronized tables, right-click the table name and select Delete. The Confirm Delete dialog appears. Click Yes.

toggle To add or delete a table script in a database (Sybase Central)

  1. From Sybase Central, right-click MobiLink Synchronization and connect to the consolidated database.

  2. Open Synchronized Tables.

  3. Select the table for which you wish to add a script.

  4. To add a table script, double-click Add Table Script and follow the instructions in the wizard.

    or

    To delete a table script, right-click the script name and select Delete. The Confirm Delete dialog appears. Click Yes.

toggle To add or delete all types of scripts (stored procedures)

  • You can add scripts to a consolidated database or delete scripts from a consolidated database using stored procedures that are installed along with the MobiLink system tables when you create your consolidated database.

    For a description of the stored procedures that you can use to add or delete scripts, see Stored procedures to add or delete scripts.


Direct inserts of scripts

In most cases, it is recommended that you use stored procedures or Sybase Central to insert scripts into the system tables. However, in some rare cases you may need to use an INSERT statement to directly insert the scripts. For example, older versions of some DBMSs may have length limitations that make it difficult to use stored procedures.

For a complete description of the MobiLink system tables, see MobiLink System Tables.

The format of the INSERT statements that are required to directly insert scripts can be found in the source code for the ml_add_connection_script and ml_add_table_script stored procedures. The source code for these stored procedures is located in the MobiLink setup scripts. There is a different setup script for each supported RDBMS. The setup scripts are:

Consolidated database | Setup file
Adaptive Server Anywhere | scripts\syncasa.sql
Oracle | MobiLink\setup\syncora.sql
IBM DB2 UDB | MobiLink\setup\syncdb2long.sql
Microsoft SQL Server | MobiLink\setup\syncmss.sql
Adaptive Server Enterprise version 12.5 and later | MobiLink\setup\syncase125.sql
Adaptive Server Enterprise prior to version 12.5 | MobiLink\setup\syncase.sql


Writing scripts to upload rows

To upload information contained in your remote database to your consolidated database, you define upload scripts. You write separate scripts to handle rows that are updated, inserted, or deleted at the remote database. A simple implementation would carry out corresponding actions (update, insert, delete) at the consolidated database.

The MobiLink synchronization server uploads data in a single transaction. For a description of the upload process, see Events during upload.

For techniques for uploading rows in .NET synchronization logic, see Uploading rows.

Notes

  • The begin_upload and end_upload scripts for each remote table hold logic that is independent of the individual rows being updated.

  • The upload stream consists of single row inserts, updates, and deletes. These actions are typically performed using upload_insert, upload_update and upload_delete scripts.

  • To prepare the upload for Adaptive Server Anywhere clients, the dbmlsync utility requires access to all transaction logs written since the last successful synchronization. For more information, see Transaction log files.


Writing upload_insert scripts

The MobiLink synchronization server uses this event during processing of the upload stream to handle rows inserted into the remote database. The following INSERT statement shows how you use the upload_insert statement.

INSERT INTO emp (emp_id,emp_name)
VALUES (?,?)

For more information, see upload_insert table event.


Writing upload_update scripts

The MobiLink synchronization server uses this event during processing of the upload stream to handle rows updated at the remote database. The following UPDATE statement illustrates use of the upload_update statement.

UPDATE emp
SET emp_name=?
WHERE emp_id=?

For more information, see upload_update table event.


Writing upload_delete scripts

The MobiLink synchronization server uses this event during processing of the upload stream to handle rows deleted from the remote database. The following statement shows how to use the upload_delete statement.

DELETE FROM emp
WHERE emp_id=?

For more information, see upload_delete table event.


Writing upload_fetch scripts

The upload_fetch script is a SELECT statement that defines a cursor in the consolidated database table. This cursor is used to compare the old values of updated rows, as received from the remote database, against the value in the consolidated database. In this way, the upload_fetch script identifies conflicts when updates are being processed.

Given a synchronized table defined as:

CREATE TABLE uf_example (
   pk1 integer NOT NULL,
   pk2    integer NOT NULL,
   val    varchar(200),
   PRIMARY KEY( pk1, pk2 ))

Then one possible upload_fetch script for this table is:

SELECT pk1, pk2, val
FROM uf_example
WHERE pk1 = ? and pk2 = ?

For more information, see upload_fetch table event.

The MobiLink synchronization server requires the WHERE clause of the query in the upload_fetch script to identify exactly one row in the consolidated database to be checked for conflicts.


Writing scripts to download rows

There are two scripts that can be used for processing each table during the download transaction. These are the download_cursor script, which carries out inserts and updates, and the download_delete_cursor script, which carries out deletes.

These scripts are either SELECT statements or calls to procedures that return result sets. The MobiLink synchronization server downloads the result set of the script to the remote database. The MobiLink client automatically inserts or updates rows based on the download_cursor script result set, and deletes rows based on the download_delete_cursor event.

For more information about using stored procedures, see Downloading a result set from a stored procedure call.

The MobiLink synchronization server downloads data in a single transaction. For a description of the download process, see Events during download.

Notes

  • Like the upload stream, the download stream starts and ends with connection events. Other events are table-level events.

  • If you change the SendDownloadAck setting to ON, if no confirmation of the download is received from the client, the entire download transaction is rolled back in the consolidated database. (By default, SendDownloadAck is set to OFF.)

    For more information, see SendDownloadACK (sa) extended option or Send Download Acknowledgement synchronization parameter.

  • The begin_download and end_download scripts for each remote table hold logic that is independent of the individual rows being updated.

  • The download stream does not distinguish between inserts and updates. The script associated with the download_cursor event is a SELECT statement that defines the rows to be downloaded. The client detects whether the row exists or not and carries out the appropriate insert or update operation.

  • At the end of the download processing, the client automatically deletes rows if necessary to avoid referential integrity violations.

    For more information, see Referential integrity and synchronization.


Writing download_cursor scripts

You write download_cursor scripts to download information from the consolidated database to your remote database. You must write one of these scripts for each table in the remote database for which you want to download changes. You can use other scripts to customize the download process, but no others are necessary.

  • Each download_cursor script must contain a SELECT statement or a call to a procedure that contains a SELECT statement. The MobiLink synchronization server uses this statement to define a cursor in the consolidated database.

  • The script must select all columns that correspond to the columns in the corresponding table in the remote database. The columns in the consolidated database can have different names than the corresponding columns in the remote database, but they must be of compatible types.

  • The columns must be selected in the order that the corresponding columns are defined in the remote database. This order is identical to the order of the columns in the reference database.

Example

The following script could serve as a download_cursor script for a remote table that holds employee information. The MobiLink synchronization server would use this SQL statement to define the download cursor. This script downloads information about all the employees.

SELECT emp_id, emp_fname, emp_lname
FROM employee

The MobiLink synchronization server passes specific parameters to some scripts. To use these parameters, you include a question mark in your SQL statement. The MobiLink synchronization server substitutes the value of the parameter before executing the statement against the consolidated database. The following script shows how you can use these parameters:

call ml_add_table_script( 'Lab', 'ULOrder', 'download_cursor',
'SELECT o.order_id, o.cust_id, o.prod_id, o.emp_id, o.disc,
  o.quant, o.notes, o.status
FROM ULOrder o
WHERE o.last_modified >= ?
AND o.emp_name = ?' )

In this example, the MobiLink synchronization server replaces the question mark with the value of the parameter to the download_cursor script.

Notes

  • Row values can be selected from a single table or from a join of multiple tables.

  • The script itself need not include the name of the remote table. The remote table need not have the same name as the table in the consolidated database. The name of the remote table is identified by an entry in the ml_table table. In Sybase Central, the remote tables are listed together with their scripts.

  • The rows in the remote table must contain the values of emp_id, emp_fname, and emp_lname. The remote columns must be in that order, although they can have different names. The columns in the remote database are in the same order as those in the reference database.

    UltraLite tip
    The example scripts list the columns in the order that they are defined in the reference database. Inspect the example_download_cursor and example_upload_cursor scripts to see the column order.

  • All cursor scripts must select the columns in the same order as the columns are defined in the remote database. Where column names or table structure is different in the consolidated database, columns should be selected in the correct order for the remote database, or equivalently, the reference database. Columns are assigned to columns in the remote database based on their order in the SELECT statement.

  • When you build an UltraLite application, the UltraLite generator creates a sample download script for each table in your UltraLite application. It inserts these sample scripts into your reference database. The example scripts assume that the consolidated database contains the same tables as your application. You must modify the sample scripts if your consolidated database differs in design, but these scripts provide a starting point.

See also
  • download_cursor table event
  • Partitioning rows among remote databases
  • Writing download_delete_cursor scripts


Writing download_delete_cursor scripts

You write download_delete_cursor scripts to delete rows from your remote database. You must write one of these scripts for each table in the remote database from which you want to delete rows during synchronization.

You cannot just delete rows from the consolidated database and have them disappear from remote databases. You need to keep track of the primary keys for deleted rows, so that you can select those primary keys with your download_delete_cursor. There are two common techniques for achieving this:

  • Logical deletes Do not physically delete the row in the consolidated database. Instead, have a status column that keeps track of whether rows are valid. This simplifies the download_delete_cursor. However, the download_cursor and other applications may need to be modified to recognize and use the status column. If you have a last modified column that holds the time of deletion, and if you also keep track of the last download time for each remote, then you can physically delete the row once all remote download times are newer than the time of deletion.

  • Shadow table For each table for which you want to track deletes, create a shadow table with two columns, one holding the primary key for the table, and the other holding a timestamp. Create a trigger that inserts the primary key and timestamp into the shadow table whenever a row is deleted. Your download_delete_cursor can then select from this shadow table. As with logical deletes, you can delete the row from the shadow table once all remote databases have downloaded it.

The MobiLink synchronization server deletes rows in the remote database by selecting primary key values from the consolidated database and passing those values to the remote database. If the values match those of a primary key in the remote database, then that row is deleted.

  • Each download_delete_cursor script must contain a SELECT statement or a call to a stored procedure that returns a result set. The MobiLink synchronization server uses this statement to define a cursor in the consolidated database.

  • This statement must select all the columns that correspond to the primary key columns in the table in the remote database. The columns in the consolidated database can have different names than the corresponding columns in the remote database, but they must be of compatible types.

  • The values must be selected in the same order as the corresponding columns are defined in the remote database. That order is the order of the columns in the CREATE TABLE statement used to make the table, not the order they appear in the statement that defines the primary key.

While each download_delete_cursor script must select all the column values present in the primary key of the corresponding remote table, it may also select all the other columns. This feature is present only for compatibility with older clients. Selecting the additional columns is less efficient, as the database engine must retrieve more data. Unless the client is of an old design, the MobiLink synchronization server discards the extra values immediately. The extra values are downloaded only to older clients.

Deleting all the rows in a table

When MobiLink detects a download_delete_cursor with a row that contains all NULLs, it deletes all the data in the remote table. The number of NULLs in the download_delete_cursor can be the number of primary key columns or the total number of columns in the table.

For example, the following download_delete_cursor SQL script deletes every row in a table in which there are two primary key columns. This example works for Adaptive Server Anywhere, Adaptive Server Enterprise, and Microsoft SQL Server databases.

SELECT NULL, NULL

In IBM DB2 and Oracle consolidated databases, you must specify a dummy table to select NULL. For IBM DB2 7.1, you can use the following syntax:

SELECT NULL FROM SYSIBM.SYSDUMMY1

For Oracle consolidated databases, you can use the following syntax:

SELECT NULL FROM DUAL
Examples

The following example is a download_delete_cursor script for a remote table that holds employee information. The MobiLink synchronization server uses this SQL statement to define the delete cursor. This script deletes information about all employees who are both in the consolidated and remote databases at the time the script is executed.

SELECT emp_id
FROM employee

The download_delete_cursor accepts the parameters last_download and ml_username. The following script shows how you can use each parameter to narrow your selection.

SELECT order_id
FROM ULOrder
WHERE last_modified >= ?
   AND status = 'Approved'
   AND user_name = ?

Note that these examples could prove inefficient in an organization with many employees. You can make the delete process more efficient by selecting only rows that could be present in the remote database. For example, you could limit the number of rows by selecting only those people who have recently been assigned a new manager. Another strategy is to allow the client application to delete the rows itself. This method is possible only when a rule identifies the unneeded rows. For example, rows might contain a timestamp that indicates an expiry date. Before you delete the rows, use the STOP SYNCHRONIZATION DELETE statement to stop these deletes being uploaded during the next synchronization. Be sure to execute START SYNCHRONIZATION DELETE immediately afterwards if you want other deletes to be synchronized in the normal fashion.

See also

You can use the referential integrity checking built into all MobiLink clients to delete rows in a particularly efficient manner. For details, see Referential integrity and synchronization.

For more information about using download_delete_cursor scripts, see

  • download_delete_cursor table event
  • Temporarily stopping synchronization of deletes
  • STOP SYNCHRONIZATION DELETE statement [MobiLink]
  • Handling deletes
  • download_cursor table event
  • Partitioning rows among remote databases
  • Snapshot synchronization


Writing scripts to handle errors

An error in a synchronization script occurs when an operation in the script fails while the MobiLink synchronization server is executing it. The DBMS returns a SQLCODE to the MobiLink synchronization server indicating the nature of the error. Each consolidated database DBMS has its own set of SQLCODE values.

When an error occurs, the MobiLink synchronization server invokes the handle_error event. You should provide a connection script associated with this event to handle errors. The MobiLink synchronization server passes several parameters to this script to provide information about the nature and context of the error, and requires an output value to tell it how to respond to the error.

Error handling actions

Some actions you may wish to take in an error-handling script are:

  • Log the error in a separate table.

  • Instruct the MobiLink synchronization server whether to ignore the error and continue, or rollback the synchronization, or rollback the synchronization and shut down the MobiLink synchronization server.

  • Send an e-mail message.

For more information, see handle_error connection event.


Reporting errors

Since errors can disrupt the natural progression of the synchronization process, it can be difficult to create a log of errors and their resolutions. The report_error script provides a means of accomplishing this task. The MobiLink synchronization server executes this script whenever an error occurs. If the handle_error script is defined, it is executed immediately prior to the reporting script.

The parameters to the report_error script are identical to those of the handle_error script, except that the report_error script can not modify the action code. Since the value of the action code is that returned by the handle_error script, this script can be used to debug error-handling problems.

This script typically consists of an insert statement, which records the values, perhaps with other data, such as the time or date, in a table for later reference. To ensure that this data is not lost, the MobiLink synchronization server always runs this script in a separate transaction and automatically commits the changes as soon as this script completes.

For more information, see report_error connection event.

Example

The following report_error script, which consists of a single insert statement, adds the script parameters into a table, along with the current date and time. The script does not commit this change because the MobiLink synchronization server always does so automatically.

INSERT INTO errors
VALUES( CURRENT DATE, ?, ? ,?, ?, ? );


Handling multiple errors on a single SQL statement

ODBC allows multiple errors per SQL statement, and some DBMSs make use of this feature. Microsoft SQL Server, for example, can have two errors for a single statement. The first is the actual error, and the second is usually an informational message telling you why the current statement has been terminated.

When a single SQL statement causes multiple errors, the handle_error script is invoked once per error. The MobiLink synchronization server uses the most severe action code (that is, the numerically greatest) to determine the action to take. The same applies to the handle_error script.

If the handle_error script itself causes a SQL error, then the default action code (3000) is assumed.


Testing script syntax

As you develop your synchronization scripts, you can use Sybase Central to test for syntax errors in your scripts.

Testing the scripts is done without any remote site in place. No data is added to the database or downloaded from the database during testing. The validity of the synchronized data itself is not tested.

toggle To test your synchronization scripts

  1. Start Sybase Central and connect to a database from MobiLink Synchronization.

  2. In the left pane, click the database name.

  3. Right-click the Synchronized Tables folder or the Connection scripts folder and select Test Scripts from the popup menu.

    The Test Scripts window appears:

    The Test Scripts window.

  4. Click Test. If prompted, enter parameters. The results of the test are displayed in the window.

    The test results include a listing of which scripts are executed, in which order. They also include a listing of any syntax errors or data type errors found during the test.


Writing Synchronization Scripts in Java

About this chapter

You control the actions of the MobiLink synchronization server by writing synchronization scripts. You can implement these scripts in SQL, .NET or Java. This chapter describes how to implement synchronization scripts in Java.

For a tutorial using Java synchronization scripts, see Tutorial: Java Synchronization Logic With Adaptive Server Anywhere .

For a description and comparison of SQL, Java, and .NET, see Options for writing synchronization logic.

For information about writing scripts, see Writing Synchronization Scripts.

For information about writing scripts in .NET, see Writing Synchronization Scripts in .NET.


Introduction

MobiLink synchronization scripts can be written in Java. Java synchronization logic can function just as SQL logic functions: the MobiLink synchronization server can make calls to Java methods on the occurrence of MobiLink events just as it accesses SQL scripts on the occurrence of MobiLink events. A SQL string may be returned as a Java method to MobiLink.

This section tells you how to set up, develop, and run Java synchronization logic. It includes a sample application and the MobiLink Java API.

For a tutorial using Java synchronization scripts, see Tutorial: Java Synchronization Logic With Adaptive Server Anywhere .


Setting up Java synchronization logic

When you install SQL Anywhere Studio, the installer automatically sets the location of the MobiLink Java API classes. When you start the MobiLink synchronization server, it automatically includes these classes in your classpath. The MobiLink Java API classes are installed to java\mlscript.jar in your SQL Anywhere Studio installation directory. MobiLink uses the ASANYSH9 environment variable to determine the shared component path.

For more information, see ASANYSH9 environment variable.

toggle To implement synchronization scripts in Java

  1. Create your own class or classes. Write a method for each required synchronization script. These methods must be public. The class must be public in the package.

    For more information about methods, see Methods.

    Each class with non-static methods should have a public constructor. The MobiLink synchronization server automatically instantiates each class the first time a method in that class is called.

    For more information about constructors, see Constructors.

  2. When compiling the class, you must include the JAR file java\mlscript.jar.

    For example,

    javac MyClass.java -classpath %ASANY9%\java\mlscript.jar

  3. In your consolidated database, specify the name of the package, class, and method to call for each synchronization script. One class is permitted per script version.

    The easiest way to add this information to the MobiLink system tables is to use the ml_add_java_connection_script stored procedure or the ml_add_java_table_script stored procedure.

    For example, the following SQL statement, when run in an Adaptive Server Anywhere database, specifies that for the script version ver1, myPackage.myClass.myMethod should be run whenever the authenticate_user connection-level event occurs. The method that is specified must be the fully qualified name of a public Java method, and the name is case sensitive.

    call ml_add_java_connection_script( 'ver1',
'authenicate_user', 'myPackage.myClass.myMethod' )

    For more information about adding scripts, see:

    • Stored procedures to add or delete scripts
    • ml_add_java_connection_script
    • ml_add_java_table_script

  4. Instruct the MobiLink server to load classes. A vital part of setting up Java synchronization logic is to tell the virtual machine where to look for Java classes. There are two ways to do this:

    • Use the dbmlsrv9 -sl java -cp option to specify a set of directories or jar files in which to search for classes. For example, at the command line, enter:

      dbmlsrv9 -c "dsn=consolidated1" -sl java (-cp %classpath%;c:\local\Java\myclasses.jar)

      The MobiLink synchronization server automatically appends the location of the MobiLink Java API classes (java\mlscript.jar) to the set of directories or jar files. The -sl java option also forces the Java VM to load on server startup.

      For more information about the available Java options, see -sl java option.

    • Explicitly set the classpath. To set the classpath for user-defined classes, use a statement such as the following:

      SET classpath=%classpath%;c:\local\Java\myclasses.jar

      If your system classpath includes your Java synchronization logic classes, you do not need to make changes to your MobiLink synchronization server command line.

      You can use the -sl java option to force the Java virtual machine to load at server startup. Otherwise, the Java virtual machine is started when the first Java method is executed.

      For more information about the available Java options, see -sl java option.

  5. On UNIX, if you want to load a specific JRE, you should set the LD_LIBRARY_PATH (LIBPATH on AIX, SHLIB_PATH on HP-UX) to include the directory containing the JRE. The directory must be listed before any of the Adaptive Server Anywhere install directories.


Writing Java synchronization logic

Writing Java synchronization logic is no different in complexity from writing any other Java code. What is required from you is knowledge of MobiLink events, some knowledge of Java, and knowledge of the MobiLink Java API. The following sections help you write useful synchronization logic.

Java synchronization logic can be used to maintain state information, and implement logic around the upload and download events. For example, a begin_synchronization script written in Java could store the MobiLink user name in a variable. Scripts called later in the synchronization process can access this variable. Also, you can use Java to access rows in the consolidated database, before or after they are committed.

Using Java reduces dependence on the consolidated database. Behavior is affected less by upgrading the consolidated database to a new version or switching to a different database-management system.

For a complete description of the API, see MobiLink Java API Reference.

Class instances
Transactions
SQL-Java data types
Constructors
Methods
Debugging Java classes
Handling MobiLink server errors in Java
User-defined start classes


Class instances

The MobiLink synchronization server instantiates your classes at the connection level. When an event is reached for which you have written a non-static Java method, the MobiLink synchronization server automatically constructs the class, if it has not already done so on the present connection.

For more information, see Constructors.

All methods directly associated with a connection-level or table-level event for one script version must belong to the same class.

For each database connection, once a class has been instantiated, the class persists until that connection is closed. Thus, the same instance may well be used for multiple consecutive synchronization sessions. Information present in public or private variables will thus persist across synchronizations that occur on the same connection unless explicitly cleared.

You can also use static classes or variables. In this case, the values are available across all connections.

The MobiLink synchronization server automatically deletes your class instances only when the connection to the consolidated database is closed.


Transactions

The normal rules regarding transactions apply to Java methods. The start and duration of database transactions is critical to the synchronization process. Transactions must be started and ended only by the MobiLink synchronization server. Explicitly committing or rolling back transactions on the synchronization connection within a Java method violates the integrity of the synchronization process and can cause errors.

These rules apply only to the database connections created by the MobiLink synchronization server and, in particular, to SQL statements returned by methods. If your classes create other database connections, you are free to manage them as you please.


SQL-Java data types

The following table shows SQL data types and the corresponding Java data types.

SQL data type | Corresponding Java data type
VARCHAR | java.lang.String
CHAR | java.lang.String
INTEGER | Int or Integer
BINARY | byte[ ]
TIMESTAMP | java.sql.Timestamp
INOUT INTEGER | ianywhere.ml.script.InOutInteger
INOUT VARCHAR | ianywhere.ml.script.InOutString
INOUT CHAR | ianywhere.ml.script.InOutString
INOUT BYTEARRAY | ianywhere.ml.script.InOutByteArray

The MobiLink synchronization server automatically adds this package to your classpath if it is not already present.

However, when you compile your class you need to add the path of java\mlscript.jar, from your SQL Anywhere Studio installation directory.


Constructors

The constructor of your class may have one of two possible signatures.

public MyScriptClass (
ianywhere.ml.script.DBConnectionContext sc )

or

public MyScriptClass ( )

The synchronization context passed to you is for the connection through which the MobiLink synchronization server is synchronizing the current user.

The getConnection method of the DBConnectionContext class returns the same database connection that MobiLink is using to synchronize the present user. You can execute statements on this connection, but you must not commit or roll back the transaction. The MobiLink synchronization server manages the transactions.

The MobiLink synchronization server prefers to use constructors with the first signature. It only uses the non-argument constructor if a constructor with the first signature is not present.

For more information, see DBConnectionContext interface.


Methods

In general, you implement one method for each synchronization event. These methods must be public. If they are private, the MobiLink synchronization server cannot use them and will fail to recognize that they exist.

The names of the methods are not important, as long as the names match the names specified in the ml_script table in the consolidated database. In the examples included in the documentation, however, the method names are the same as those of the MobiLink events because this naming convention makes the Java code easier to read.

The signature of your method should match the signature of the script for that event, except that you can truncate the parameter list if you do not need the values of parameters at the end of the list. Indeed, you should accept only the parameters you need, because overhead is associated with passing the parameters.

You cannot, however, overload the methods. Only one method prototype per class may appear in the ml_script system table.

Return values

Methods called for a MobiLink upload or download must return a valid SQL language statement. The return type of these methods must be java.lang.String. No other return types are allowed.

The return type of all other scripts must either be java.lang.String or void. No other types are allowed. If the return type is a string and not null, the MobiLink synchronization server assumes that the string contains a valid SQL statement and executes this statement in the consolidated database as it would an ordinary SQL-language synchronization script. If a method ordinarily returns a string but does not wish to execute a SQL statement against the database upon its return, it can return null.


Debugging Java classes

MobiLink provides various information and facilities that you may find helpful when debugging your Java code. This section describes where you can find this information and exploit these capabilities.

Information in the MobiLink synchronization server's log file

The MobiLink synchronization server writes various related information to its output log file. The synchronization server log file contains the following information:

  • The Java Runtime Environment. You can use the -jrepath option to request a particular JRE when you start the MobiLink synchronization server. The default is the path installed with Adaptive Server Anywhere 9.

  • The path of the standard Java classes loaded. If you did not specify these explicitly, the MobiLink synchronization server automatically adds them to your classpath before invoking the Java virtual machine.

  • The fully specified names of the specific methods invoked. You can use this information to verify that the MobiLink synchronization server is invoking the correct methods.

  • Any output written in a Java method to java.lang.System.out or java.lang.System.err is redirected to the MobiLink synchronization server log file.

  • The dbmlsrv9 command line option -verbose can be used.

    For more information, see -sl java option.

Using a Java debugger

You can debug your Java classes using a standard Java debugger. Specify the necessary parameters using the -sl java option on the dbmlsrv9 command line.

For more information, see -sl java option.

Specifying a debugger causes the Java virtual machine to pause and wait for a connection from a Java debugger.

Printing information from Java

Alternatively, you may choose to add statements to your Java methods that print information to the MobiLink output log, using java.lang.System.err or java.lang.System.out. Doing so can help you track the progress and behavior of your classes.

Performance tip
Printing information in this manner is a useful monitoring tool, but is not recommended in a production scenario.

The same technique can be exploited to log arbitrary synchronization information or collect statistical information on how your scripts are used.

Writing your own test driver

You may wish to write your own driver to exercise your Java classes. This approach can be helpful because it isolates the actions of your Java methods from the rest of the MobiLink system.


Handling MobiLink server errors in Java

When scanning the log is not sufficient, you can monitor your applications programmatically. For example, you can send messages of a certain type in an email.

You can write methods that are passed a class representing every error or warning message that is printed to the log. This may help you monitor and audit a MobiLink synchronization server.

The following code installs a LogListener for all warning messages, and writes the information to a file.

class TestLogListener implements LogListener {
        FileOutputStream    _out_file;

        public TestLogListener(   FileOutputStream    out_file )
        {
            _out_file       = out_file;
        }
        public void messageLogged(  ServerContext   sc,
                                    LogMessage      msg )
        {
            String  type;
            String  user;
            try {
                 if(msg.getType() == LogMessage.ERROR) {
                    type = "ERROR";
                } else if(msg.getType() == LogMessage.WARNING) {
                    type = "WARNING";
                } else {
                    type = "UNKNOWN!!!";
                }
                user = msg.getUser();
                if( user == null ) {
                    user = "NULL";
                }
                _out_file.write(
                        ("Caught msg type=" + type +
                                " user=" + user +
                                " text=" +msg.getText() +
                                "\n").getBytes() );
                _out_file.flush();
            } catch( Exception e ) {
              // print some error output to the MobiLink log
                e.printStackTrace();
            }
        }
    }
// This line of code will register TestLogListener to receive
// warning messages.  Call this code from anywhere that has
// access to the ServerContext such as a class constructor or
// synchronization script.  ServerContext serv_context;
serv_context.addWarningListener(
      new MyLogListener( ll_out_file ));
See also

addErrorListener, removeErrorListener, addWarningListener, removeWarningListener in ServerContext interface

LogListener interface

LogMessage class


User-defined start classes

You can define start classes that are loaded automatically when the server is started. The purpose of this feature is to allow you to write Java code that executes at the time the MobiLink server starts the JVM—before the first synchronization. This means you can create connections or cache data before a user synchronization request.

You do this with the DMLStartClasses option of the dbmlsrv9 -sl java option. For example, the following is part of a dbmlsrv9 command line. It causes mycl1 and mycl2 to be loaded as start classes.

-sl java(-DMLStartClasses=com.test.mycl1,com.test.mycl2)

Classes are loaded in the order in which they are listed. If the same class is listed more than once, more than one instance is created.

All start classes must be public and must have a public constructor that either accepts no arguments or accepts one argument of type ianywhere.ml.script.ServerContext.

The names of loaded start classes are output to the MobiLink log with the message "Loaded JAVA start class: classname".

For more information about Java virtual machine options, see -sl java option.

To see the start classes that are constructed at server start time, see getStartClassInstances.

Example

Following is a template start class. It starts a daemon thread that processes events and creates a database connection. (Not all start classes will need to create a thread but if a thread is spawned it should be a daemon thread.)

import ianywhere.ml.script.*;
import java.sql.*;

public class StartTemplate extends
   Thread implements ShutdownListener {
//=================================================
  ServerContext   _sc;
  Connection      _conn;
  boolean         _exit_loop;

  public StartTemplate( ServerContext sc )
  //=============================================
                        throws SQLException
  {
    // perform setup first so that an exception will
    // cause MobiLink startup to fail
 _sc       = sc;
    // create a connection for use later
    _conn      = _sc.makeConnection();
    _exit_loop = false;
    setDaemon( true );
    start();
  }
  public void run()
  //===============
  {
    _sc.addShutdownListener( this );
    // we can't throw any exceptions through run()
    try {
       handlerLoop();
       _conn.close();
       _conn = null;
    } catch( Exception e ) {
       // print some error output to the MobiLink log
       e.printStackTrace();
       // we will die so we don't need to be notified
       // of shutdown
       _sc.removeShutdownListener( this );
       // ask server to shutdown so that this fatal
       // error will be fixed
       _sc.shutdown();
    }
    // shortly after return this thread will no longer
    // exist
    return;
  }

 public void shutdownPerformed( ServerContext sc )
  //===============================================
  // stop our event handler loop
  {
    try {
       // wait max 10 seconds for thread to die
  join( 10*1000);
    } catch( Exception e ) {
       // print some error output to the MobiLink log
       e.printStackTrace();
   }
  }
  private void handlerLoop()
  //================throws InterruptedException
  {
      while( !_exit_loop ) {
        // Handle events in this loop. Sleep not
        // needed, we should block on event queue.
        sleep( 1*1000 );
    }
  }
}


Java synchronization example

Java synchronization logic works with MobiLink and common Java classes to provide you with flexibility in deploying applications using MobiLink synchronization server. The following section introduces you to this extended range of functionality using a simple example.

Note:
This section provides a simple example to illustrate basic Java synchronization logic. Typically, reasons for using a custom user authentication mechanism include integration with existing DBMS user authentication schemes, or supplying custom features, such as minimum password length or password expiry. MobiLink also has a built-in mechanism.

For more information about MobiLink authentication, see Choosing a user authentication mechanism.


Introduction

This section describes a working example of Java synchronization logic. Before you try to use this class or write your own class, use the following checklist to ensure you have all the pieces in place before compiling the class.

  • Plan your desired functionality using, for example, pseudocode.

  • Create a map of database tables and columns.

  • Set up the consolidated database by ensuring you have specified in the MobiLink system tables the language type and location of the Java synchronization methods.

    For more information see Setting up Java synchronization logic.

  • Create a list of associated Java classes that are called during the running of your Java class.

  • Have a location for your Java classes that is in the classpath for MobiLink synchronization server.

Plan

The Java synchronization logic for this example points to the associated Java files and classes that contain functionality needed for the example to work. It will show you how to create a class CustEmpScripts. It shows you how to set up a synchronization context for the connection. Finally, the example provides Java methods to

  • Authenticate a MobiLink user

  • Perform download and upload operations using cursors for each database table.

Schema

The tables to be synchronized are emp and cust. The emp table has three columns called emp_id, emp_name and manager. The cust table has three columns called cust_id, cust_name and emp_id. All columns in each table are synchronized. The mapping from consolidated to remote database is such that the table names and column names are identical in both databases. One additional table, an audit table, is added to the consolidated database.

Java class files

The files used in the example are included in the Samples\MobiLink\JavaAuthentication directory.


Create your Java synchronization script

Setup

The following sets up the Java synchronization logic. The import statements tell the Java virtual machine the location of needed files. The public class statement declares the class.

// use a package when you create your own script
import   ianywhere.ml.script.InOutInteger;
import   ianywhere.ml.script.DBConnectionContext;
import   ianywhere.ml.script.ServerContext;
import   java.sql.*;
public class CustEmpScripts {
/* Context for this synchronization connection.
*/
    DBConnectionContext _conn_context;
/* Same connection MobiLink uses for sync we can't commit or
 * close this.
*/
    Connection       _sync_connection;
    Connection       _audit_connection;
/* Get a user id given the user name. On audit connection.
*/
    PreparedStatement      _get_user_id_pstmt;
/* Add record of user logins added. On audit connection.
*/
    PreparedStatement      _insert_login_pstmt;
/* Prepared statement to add a record to the audit table.
 * On audit connection.
*/
    PreparedStatement      _insert_audit_pstmt;

The CustEmpScripts constructor sets up all the prepared statements for the authenticateUser method. It sets up member data.

public CustEmpScripts( DBConnectionContext cc )
    throws SQLException
{
try
    {
    _conn_context = cc;
    _sync_connection = _conn_context.getConnection();

    ServerContext serv_context =
    _conn_context.getServerContext();
    _audit_connection = serv_context.makeConnection();

    // get the prep statements ready
    _get_user_id_pstmt =
    _audit_connection.prepareStatement(
        "select user_id from ml_user where name = ?"
        );
    _insert_login_pstmt =

   _audit_connection.prepareStatement(
        "insert into login_added( ml_user, add_time )
        " + " values( ?, { fn CONVERT( { fn NOW() },
        SQL_VARCHAR ) })"
        );
    _insert_audit_pstmt =
        _audit_connection.prepareStatement(
        "insert into login_audit( ml_user_id,
        audit_time, audit_action ) " +
        " values( ?, { fn CONVERT( { fn NOW() },
        SQL_VARCHAR ) }, ? ) "
        );
    } catch ( SQLException e ) {
        freeJDBCResources();
        throw e;
    } catch ( Error e ) {
        freeJDBCResources();
        throw e;
    }
}

The finalize method cleans up JDBC resources if end_connection is not called.

protected void finalize()
    throws SQLException, Throwable
{
    super.finalize();
    freeJDBCResources();
}

The freeJDBCResources method frees allocated memory and we close the audit connection. It is a housekeeping procedure.

private void freeJDBCResources()
        throws SQLException
    {
   if( _get_user_id_pstmt != null ) {
       _get_user_id_pstmt.close();
   }
   if( _insert_login_pstmt != null ) {
       _insert_login_pstmt.close();
   }
   if( _insert_audit_pstmt != null ) {
       _insert_audit_pstmt.close();
   }
   if( _audit_connection != null ) {
       _audit_connection.close();
   }
   _conn_context        = null;
   _sync_connection    = null;
   _audit_connection   = null;
   _get_user_id_pstmt  = null;
   _insert_login_pstmt = null;
   _insert_audit_pstmt = null;
    }

The endConnection method cleans up resources once the resources are not needed. This is also a housekeeping procedure.

public void endConnection()
    throws SQLException
{
    freeJDBCResources();
 }

The authenticateUser method below approves all user logins and logs user information to database tables. If the user is not in the ml_user table they are logged to login_added. If the user id is found in ml_user then they are logged to login_audit. In a real system we would not ignore the user_password but in order to keep this sample simple we approve all users. The procedure throws SQLException if any of the database operations we perform fail with an exception

public void authenticateUser( InOutInteger auth_status,
        String user_name )
    throws SQLException
{
        boolean new_user;
        int user_id;

   // get ml_user id
    _get_user_id_pstmt.setString( 1, user_name );
    ResultSet user_id_rs =
    _get_user_id_pstmt.executeQuery();
    new_user = !user_id_rs.next();
    if( !new_user ) {
        user_id = user_id_rs.getInt(1);
    } else {
        user_id = 0;
    }

   user_id_rs.close();
    user_id_rs = null;
    // in this tutorial always allow the login
    auth_status.setValue( 1000 );
    if( new_user ) {
        _insert_login_pstmt.setString( 1, user_name );
        _insert_login_pstmt.executeUpdate();
        java.lang.System.out.println( "user: " +
            user_name + " added. " );
    } else {
        _insert_audit_pstmt.setInt( 1, user_id );
        _insert_audit_pstmt.setString( 2, "LOGIN ALLOWED" );
        _insert_audit_pstmt.executeUpdate();
    }
    _audit_connection.commit();
    return;
}

The following methods use SQL code to act as cursors on the database tables. Since these are cursor scripts, they must return a SQL string.

public static String empUploadInsertStmt()
{
    return( "INSERT INTO emp(
       emp_id, emp_name) VALUES( ?, ?) " );
}
public static String empUploadDeleteStmt()
{
    return( "DELETE FROM emp WHERE emp_id = ?" );
}
public static String empUploadUpdateStmt()
{
    return( "UPDATE emp SET emp_name = ?
             WHERE emp_id = ? " );
}
public static String empDownloadCursor()
{
    return( "SELECT emp_id, emp_name FROM emp" );
}
public static String custUploadInsertStmt()
{
    return( "INSERT INTO cust(
        cust_id, emp_id, cust_name)
        VALUES ( ?, ?, ? ) " );
}
public static String custUploadDeleteStmt()
{
    return( "DELETE FROM cust WHERE cust_id = ? " );
}
public static String custUploadUpdateStmt()
{
    return( "UPDATE cust
            SET emp_id = ?, cust_name = ?
            WHERE cust_id = ? " );
}
public static String custDownloadCursor()
{
    return( "SELECT cust_id, emp_id, cust_name
             FROM cust" );
    }
}

This code would be compiled using the command

javac -cp %asany9%\java\mlscript.jar CustEmpScripts.jar

and we could run the MobiLink synchronization server with the location of CustEmpScripts.class in the classpath. Following is a partial command line:

dbmlsrv9 ... -sl java (-cp <class_location>)


MobiLink Java API Reference

This section explains the MobiLink Java interfaces and classes, and their associated methods and constructors.

DBConnectionContext interface
InOutByteArray interface
InOutInteger interface
InOutString interface
LogListener interface
LogMessage class
ServerContext interface
ServerException class
ShutdownListener interface
SynchronizationException class


DBConnectionContext interface

Interface for obtaining and accessing information about the current database connection. This is passed to the constructor of classes containing scripts. If context is required for a background thread or beyond the lifetime of a connection, use a ServerContext.

Caution
A DBConnectionContext instance should not be used outside the thread that calls into your Java code.
getConnection method

public java.sql.Connection getConnection( )
throws java.sql.SQLException

Returns the existing connection java.sql.Connection as a JDBC connection. The connection is the same connection that MobiLink uses to execute SQL scripts.

This connection must not be committed, closed or altered in any way that would affect the MobiLink server use of this connection. The connection returned is only valid for the lifetime of the underlying MobiLink connection. Do not use the connection after the end_connection event has been called for that connection.

If an error occurs binding the existing connection as a JDBC connection then it throws java.sql.SQLException

If a server connection with full access is required, use ServerContext.makeConnection().

getProperties method

public java.util.Properties getProperties( )

Returns the properties for this connection, based on this connection's script version. Properties are stored in the ml_property table.

For more information, see ml_property and ml_add_property.

getServerContext method

public ServerContext getServerContext( )

Returns the ServerContext for this MobiLink server.

getVersion method

public java.util.Properties getVersion( )

Returns the name of the script version.

For more information, see ml_property and ml_add_property.


InOutByteArray interface

Passed into methods to enable the functionality of an in/out parameter passed to a SQL script.

getValue method

public byte[ ] getValue( )

Returns the value of this byte array parameter.

setValue method

public void setValue( byte[ ] new_value )

Sets the value of this byte array parameter. There is one parameter, new_value, which is the value this byte array should take.


InOutInteger interface

Passed into methods to enable the functionality of an in/out parameter passed to a SQL script.

getValue method

public int getValue( )

Returns the value of this integer parameter.

setValue method

public void setValue( int new_value )

Sets the value of this integer parameter. There is one parameter, new_value, which is the value this integer should take.


InOutString interface

Passed into methods to enable the functionality of an in/out parameter passed to a SQL script.

getValue method

public java.lang.String getValue( )

Returns the value of this string parameter.

setValue method

public void setValue( int new_value )

Sets the value of this integer parameter. There is one parameter, new_value, which is the value this string should take.


LogListener interface

The listener interface for catching messages that are printed to the log.

messageLogged method

public void messageLogged(
ServerContext sc
LogMessage message )

Invoked when a message is printed to the log. There are two parameters: sc, which is the context for the server that is printing the message; and message, which is the LogMessage that has been sent to the MobiLink log.


LogMessage class

Holds the data associated with a log message.

Extends java.lang.Object

Constants

int ERROR

int WARNING

getType method

public int getType( )

Accessor for this message type.

Returns the type of this message, which can be either ERROR or WARNING.

getUser method

public java.lang.String getUser( )

Accessor for this message user. If the message has no user, then the user is NULL.

Returns the user associated with this message.

getText method

public java.lang.String getText( )

Accessor for the message text.

Returns the main text of this message.


ServerContext interface

An instantiation of all the context that is present for the duration of the MobiLink server. This context can be held as static data and used in a background thread. It is valid for the duration of the Java virtual machine invoked by MobiLink.

To access a ServerContext instance, use the DBConnectionContext.getServerContext method.

addShutdownListener

public void addShutdownListener( ShutdownListener sl )

Adds the specified ShutdownListener that is to receive notification before the server context is destroyed. On shutdown, the method ShutdownListener.shutdownPerformed (ianywhere.ml.script.ServerContext) is called. There is one parameter, sl, which specifies that the ShutdownListener is to be notified on shutdown.

removeShutdownListener

public void removeShutdownListener( ShutdownListener sl )

Removes the specified ShutdownListener from the list of listeners that are to receive notification before the server context is destroyed. There is one parameter, sl, which specifies the listener that will no longer be notified on shutdown.

shutdown

public void shutdown( )

Forces the server to shut down.

getStartClassInstances

public java.lang.Object[ ] getStartClassInstances( )

Gets an array of the start classes that were constructed at server start time. The array length is zero if there are no start classes.

For more information about user-defined start classes, see User-defined start classes.

Following is an example of getStartClassInstances( ):

Object objs[] = sc.getStartClassInstances();
int I;
for( I=0; i<objs.length; I+=1 ) {
   if( objs[i] instanceof MyClass ) {
       //use class
   }
}
getProperties

public java.util.Properties getProperties(
java.lang.String component_name
java.lang.String prop_set_name )

Returns the set of properties associated with the script version. These are stored in the MobiLink system table ml_property.

For more information, see ml_property and ml_add_property.

getPropertiesByVersion

public java.util.Properties getPropertiesByVersion( java.lang.String script_version )

Returns the set of properties associated with the script version. These are stored in the MobiLink system table ml_property. The script version is stored in the prop_set_name column when the component_name is ScriptVersion.

For more information, see ml_property and ml_add_property.

getPropertySetNames

public java.util.Properties getPropertySetNames(
java.lang.String component_name )

Returns the list of property set names for a given component. These are stored in the MobiLink system table ml_property.

For more information, see ml_property and ml_add_property.

makeConnection method

public java.sql.Connection makeConnection( )
throws java.sql.SQLException

Creates a new server connection. If an error occurs when opening a new connection, the method throws java.sql.SQLException.

addErrorListener method

public void addErrorListener( LogListener ll )

Adds the specified LogListener to receive a notification when an error is printed.

ll is the LogListener that is to be notified.

The following method will be called: LogListener.messageLogged(ianywhere.ml.script.ServerContext, ianywhere.ml.script.LogMessage).

removeError Listener method

public void removeErrorListener( LogListener ll )

Removes the specified LogListener from the list of listeners that are to receive a notification when an error is printed.

ll is the LogListener that is no longer to be notified.

addWarningListener method

public void addWarningListener( LogListener ll )

Adds the specified LogListener to receive a notification when a warning is printed.

ll is the LogListener that is to be notified.

The following method will be called: LogListener.messageLogged(ianywhere.ml.script.ServerContext, ianywhere.ml.script.LogMessage).

removeWarningListener method

public void removeWarningListener( LogListener ll )

Removes the specified LogListener from the list of listeners that are to receive a notification when a warning is printed.

ll is the LogListener that is no longer to be notified.


ServerException class

Thrown to indicate that there is an error condition that makes any further synchronization on the server impossible. Throwing this exception causes the MobiLink server to shut down.

ServerException constructors

public ServerException( )

Constructs a ServerException with no detail message.

public ServerException( java.lang.String s )

Constructs a ServerException with a specified detail message. There is one parameter, s, which specifies the detailed message.


ShutdownListener interface

The listener interface for catching server shutdowns. Use this interface to ensure that all resources, threads, connections, and so on are cleaned up before the server exits.

shutdownPerformed method

public void shutdownPerformed( ServerContext sc)

Invoked before the ServerContext is destroyed due to server shutdown. There is one parameter, sc, which is the context for the server that is being shut down.


SynchronizationException class

Thrown to indicate that there is an error condition that makes the completion of the current synchronization impossible. Throwing this exception will force the MobiLink server to rollback.

SynchronizationException constructors

public SynchronizationException( )

Constructs a SynchronizationException with no detail message.

public SynchronizationException( java.lang.String s )

Constructs a SynchronizationException with the specified detail message. There is one parameter, s, which specifies a detail message.


Writing Synchronization Scripts in .NET

About this chapter

You control the actions of the MobiLink synchronization server by writing synchronization scripts. You can implement these scripts in SQL, Java, or .NET. This chapter describes how to implement synchronization scripts in .NET.

For a tutorial using .NET synchronization scripts, see Tutorial: .NET Synchronization Logic With Adaptive Server Anywhere.

For information about writing scripts, see Writing Synchronization Scripts.

For a description and comparison of SQL, Java, and .NET, see Options for writing synchronization logic.

For information about writing scripts in Java, see Writing Synchronization Scripts in Java.

Introduction
Setting up .NET synchronization logic
Writing .NET synchronization logic
.NET synchronization techniques
Loading Shared Assemblies
.NET synchronization example
MobiLink .NET API Reference


Introduction

Microsoft .NET is a platform for building, deploying, and running Web services and applications.

MobiLink supports Visual Studio .NET programming languages for writing synchronization scripts. To write MobiLink scripts in .NET, you can use any language that lets you create valid .NET assemblies. In particular, the following languages are tested and documented:

  • C#

  • Visual Basic .NET

  • C++

.NET synchronization logic can function just as Java logic functions: the MobiLink synchronization server can make calls to .NET methods on the occurrence of MobiLink events. A SQL string may be returned to MobiLink.

This section tells you how to set up, develop, and run .NET synchronization logic for C#, Visual Basic .NET, and C++. It includes a sample application and the MobiLink .NET API Reference.

For a tutorial using .NET synchronization scripts, see Tutorial: .NET Synchronization Logic With Adaptive Server Anywhere.


Setting up .NET synchronization logic

The most important part of implementing synchronization scripts in .NET is telling MobiLink where to find the packages, classes, and methods that are contained in your assemblies.

toggle To implement synchronization scripts in .NET

  1. Create your own class or classes. Write a method for each required synchronization event. These methods must be public.

    For more information about methods, see Methods.

    Each class with non-static methods should have a public constructor. The MobiLink synchronization server automatically instantiates each class the first time a method in that class is called for a connection.

    For more information about constructors, see Constructors.

  2. Create one or more assemblies. While compiling, reference iAnywhere.MobiLink.Script.dll which contains a repository of MobiLink API classes to utilize in your own .NET methods. iAnywhere.MobiLink.Script.dll is located in win32 subdirectory of your SQL Anywhere installation.

    For more information about the MobiLink .NET API, see MobiLink .NET API Reference.

    You can compile your class on the command line, or using Visual Studio .NET or another .NET development environment.

    • To Compile from Visual Studio .NET:

      1. From the VS.NET Project menu, choose Add Existing Item...

      2. Locate iAnywhere.MobiLink.Script.dll; from the Open dropdown list choose Link File:

        Adding a reference to the MobiLink API library from VS.NET
        Caution:
        For Visual Studio .NET, always use the Link File method shown above. Do not use the Add Reference option to reference iAnywhere.MobiLink.Script.dll. The Add Reference option duplicates iAnywhere.MobiLink.Script.dll in the same physical directory as your class assembly, creating problems for the MobiLink synchronization server.

      3. Use the Build menu to build your assembly.

    • To compile from the command line:

    You can reference iAnywhere.MobiLink.Script.dll from the command line as follows:

    csc /out:c:\out.dll /target:library /reference:c:\iAnywhere.MobiLink.Script.dll sync_v1.cs

    The above example assumes iAnywhere.MobiLink.Script.dll has been copied to c:\.

    For a complete description of the API, see MobiLink .NET API Reference.

  3. In the MobiLink system tables in your consolidated database, specify the name of the package, class, and method to call for each synchronization script. One class is permitted per script version.

    The easiest way to add this information to the MobiLink system tables is to use the ml_add_dnet_connection_script stored procedure or the ml_add_dnet_table_script stored procedure.

    For example, the following statement, when run in an Adaptive Server Anywhere database, specifies that myNamespace.myClass.myMethod should be run whenever the authenticate_user connection-level event occurs.

    call ml_add_dnet_connection_script( 'version1',
'authenicate_user', 'myNamespace.myClass.myMethod' )
    Note:
    The fully qualified method name is case sensitive.

    As a result of this procedure call, the script_language column of the ml_script system table must contain the word dnet. The string in the script column, which contains a statement for scripts implemented in SQL, must instead contain the qualified name of a public .NET method.

    For more information, see ml_add_dnet_connection_script and ml_add_dnet_table_script.

    You can also add this information using Sybase Central.

  4. Instruct the MobiLink server to load assemblies and start the CLR. You tell MobiLink where to locate these assemblies using options on the dbmlsrv9 command line. There are two options to choose from:

    • Use -sl dnet ( -MLAutoLoadPath ) This sets the given path to the application base directory and loads all the private assemblies within it. You should use this option in most cases. For example, to load all assemblies located in c:\, enter:

      dbmlsrv9 -c "dsn=consolidated1" -sl dnet(-MLAutoLoadPath=c:\)

      When you use the -MLAutoLoadPath option you cannot specify a domain when entering the fully qualified method name for the event script.

      For more information about loading assemblies, see Loading assemblies. For more information about the dbmlsrv9 option -sl dnet, see -sl dnet option.

    • Use -sl dnet ( -MLDomConfigFile ) This option requires a configuration file that contains domain and assembly settings. You should use this option when you have shared assemblies, when you don't want to load all the assemblies in a directory, or when for some other reason you need to use a configuration file.

      For more information about loading shared assemblies, see Loading assemblies. For more information about the dbmlsrv9 option -sl dnet, see -sl dnet option.

      Note:
      You can use the -MLAutoLoadPath option or the -MLDomConfigFile option, but not both.

Previous Next


Writing .NET synchronization logic

Writing .NET synchronization logic is no different in complexity from writing any other .NET code. What is required from you is knowledge of MobiLink events and familiarity with the MobiLink .NET API. The following sections help you write useful synchronization logic.

For a complete description of the API, see MobiLink .NET API Reference.

.NET synchronization logic can be used to maintain state information, and implement logic around the upload and download events. For example, a begin_synchronization script written in .NET could store the MobiLink user name in a variable. Scripts called later in the synchronization process can access this variable. Also, you can use .NET to access rows in the consolidated database, before or after they are committed.

Using .NET also reduces dependence on the consolidated database. Behavior is affected less by upgrading the consolidated database to a new version or switching to a different database-management system.

Class instances
Transactions
SQL-.NET data types
Constructors
Methods
User-defined start classes
Printing information from .NET
Handling MobiLink server errors with .NET
Debugging .NET synchronization logic


Class instances

The MobiLink synchronization server instantiates your classes at the connection level. When an event is reached for which you have written a non-static .NET method, the MobiLink synchronization server automatically constructs the class, if it has not already done so on the present database connection.

For more information, see Constructors.

All methods directly associated with a connection-level or table-level event for one script version must belong to the same class.

For each database connection, once a class has been instantiated, the class persists until that connection is closed. Thus, the same instance may well be used for multiple consecutive synchronization sessions. Information present in public or private variables will thus persist across synchronizations that occur on the same connection unless explicitly cleared.

You can also use static classes or variables. In this case, the values are available across all connections in the same domain.

The MobiLink synchronization server automatically deletes your class instances only when the connection to the consolidated database is closed.


Transactions

The normal rules regarding transactions apply to .NET methods. The start and duration of database transactions is critical to the synchronization process. Transactions must be started and ended only by the MobiLink synchronization server. Explicitly committing or rolling back transactions on the synchronization connection within a .NET method violates the integrity of the synchronization process and can cause errors.

These rules apply only to the database connections created by the MobiLink synchronization server and, in particular, to SQL statements returned by methods. If your classes create other database connections, you are free to manage them as you please.


SQL-.NET data types

The following table shows SQL data types and the corresponding .NET data types for MobiLink script parameters.

SQL data type | Corresponding .NET data type
VARCHAR | string
CHAR | string
INTEGER | int
BINARY | byte [ ]
TIMESTAMP | DateTime
INOUT INTEGER | ref int
INOUT VARCHAR | ref string
INOUT CHAR | ref string
INOUT BYTEARRAY | ref byte [ ]


Constructors

The constructor of your class can have one of two possible signatures.

public ExampleClass( iAnywhere.MobiLink.Script.DBConnectionContext cc )

or

public ExampleClass()

The synchronization context passed to you is for the connection through which the MobiLink synchronization server is synchronizing the current user.

The getConnection method of the DBConnectionContext class returns the same database connection that MobiLink is using to synchronize the present user. You can execute statements on this connection, but you must not commit or roll back the transaction. The MobiLink synchronization server manages the transactions.

The MobiLink synchronization server prefers to use constructors with the first signature. It only uses the void constructor if a constructor with the first signature is not present.

For more information about the DBConnectionContext class, see DBConnectionContext interface.


Methods

In general, you implement one method for each synchronization event. These methods must be public. If they are private, the MobiLink synchronization server cannot use them and will fail to recognize that they exist.

The names of the methods are not important, as long as the names match the names specified in the ml_script table in the consolidated database. In the examples included in the documentation, however, the method names are the same as those of the MobiLink events as this naming convention makes the .NET code easier to read.

The signature of your method should match the signature of the script for that event, except that you can truncate the parameter list if you do not need the values of parameters at the end of the list. Indeed, you should accept only the parameters you need, because overhead is associated with passing the parameters.

You cannot, however, overload the methods. Only one method prototype per class may appear in the ml_script system table.

Return values

Methods called for a MobiLink upload or download must return a valid SQL language statement. The return type of these methods must be String. No other return types are allowed.

The return type of all other scripts must either be string or void. No other types are allowed. If the return type is a string and not null, the MobiLink synchronization server assumes that the string contains a valid SQL statement and executes this statement in the consolidated database as it would an ordinary SQL-language synchronization script. If a method ordinarily returns a string but does not wish to execute a SQL statement against the database upon its return, it can return null.


User-defined start classes

You can define start classes that are loaded automatically when the server is started. The purpose of this feature is to allow you to write .NET code that executes at the time the MobiLink server starts the CLR—before the first synchronization. This means you can create connections or cache data before a user synchronization request.

You do this with the MLStartClasses option of the dbmlsrv9 -sl dnet option. For example, the following is part of a dbmlsrv9 command line. It causes mycl1 and mycl2 to be loaded as start classes.

-sl dnet(-MLStartClasses=com.test.mycl1,com.test.mycl2)

Classes are loaded in the order in which they are listed. If the same class is listed more than once, more than one instance is created.

All start classes must be public and must have a public constructor that either accepts no arguments or accepts one argument of type MobiLink.Script.ServerContext.

The names of loaded start classes are output to the MobiLink log with the message "Loaded .NET start class: classname".

For more information about .NET CLR, see -sl dnet option.

To see the start classes that are constructed at server start time, see GetStartClassInstances method.

Example

Following is a template start class. It starts a daemon thread that processes events and creates a database connection. (Not all start classes will need to create a thread but if a thread is spawned it should be a daemon thread.)

using System;
using System.IO;
using System.Threading;
using iAnywhere.MobiLink.Script;
namespace TestScripts
{
    public class MyStartClass {
   ServerContext    _sc;
   bool             _exit_loop;
   Thread           _thread;
   OdbcConnection   _conn;
   public MyStartClass( ServerContext sc )
   //=====================================
   {
       // perform setup first so that an exception will
       // cause MobiLink startup to fail
       _sc          = sc;
       // create connection for use later
       _conn        = _sc.makeConnection();
       _exit_loop   = false;
       _thread      = new Thread( new ThreadStart( run ) ) ;
       _thread.IsBackground = true;
       _thread.Start();
   }
   public void run()
   //===============
   {
       ShutdownCallback callback = new ShutdownCallback( shutdownPerformed );
       _sc.ShutdownListener += callback;
       // we can't throw any exceptions through run()
       try {
      handlerLoop();
      _conn.close();
      _conn = null;
       } catch( Exception e ) {
      // print some error output to the MobiLink log
      Console.Error.Write( e.ToString() );
      // we will die so we don't need to be notified of
      // shutdown
      _sc.ShutdownListener -= callback;
      // ask server to shutdown so that this fatal error will
      // be fixed
      _sc.Shutdown();
       }
       // shortly after return this thread will no longer
       // exist
       return;
   }
   public void shutdownPerformed( ServerContext sc )
   //===============================================
   // stop our event handler loop
   {
       try {
          _exit_loop = true;
          // wait max 10 seconds for thread to die
          _thread.Join( 10*1000 );
       } catch( Exception e ) {
          // print some error output to the MobiLink log
          Console.Error.Write( e.ToString() );
       }
   }
   private void handlerLoop()
   //========================
   {
       while( !_exit_loop ) {
         // handle events in this loop
         Thread.Sleep( 1*1000 );
       }
   }
    }
}


Printing information from .NET

You may choose to add statements to your .NET methods that print information to the MobiLink log using System.Console. Doing so can help you track the progress and behavior of your classes.

Performance tip
Printing information in this manner is a useful monitoring tool, but is not recommended in a production scenario.

The same technique can be exploited to log arbitrary synchronization information or collect statistical information on how your scripts are used.


Handling MobiLink server errors with .NET

When scanning the log is not sufficient, you can monitor your applications programmatically. For example, you can send messages of a certain type in an email.

You can write methods that are passed a class representing every error or warning message that is printed to the log. This may help you monitor and audit a MobiLink synchronization server.

The following code installs a Listener for all error messages and prints the information to a StreamWriter.

class TestLogListener {
    public TestLogListener( StreamWriter output_file  )
    {
        _output_file    = output_file;
    }
    public void errCallback( ServerContext sc, LogMessage lm )
    {
        string type;
        string user;
        if( lm.Type==LogMessage.MessageType.ERROR ) {
            type = "ERROR";
        } else if( lm.Type==LogMessage.MessageType.WARNING ) {
            type = "WARNING";
        } else {
            type = "INVALID TYPE!!";
        }
        if( lm.User == null ) {
            user = "null";
        } else {
            user = lm.User;
        }
        _output_file.WriteLine( "Caught msg type=" + type +
                                        " user=" + user +
                                        " text=" + lm.Text );
        _output_file.Flush();
    }
    StreamWriter    _output_file;
}
// Two lines that registers the TestLogListener Call this code
// from anywhere that has access to the ServerContext such as
// a class constructor or synchronization script.
// ServerContext serv_context;
TestLogListener etll = new TestLogListener(log_listener_file);
serv_context.ErrorListener += new LogCallback(etll.errCallback);
See also

LogCallback delegate

ErrorListener and WarningListener in ServerContext interface

LogMessage class

MessageType enumeration


Debugging .NET synchronization logic

The following procedure describes one way you can debug your .NET scripts using Microsoft Visual Studio .NET.

toggle To debug .NET scripts

  1. Compile your code with debugging information turned on:

    • On the csc command line, set the flag /debug+

      or

    • Use Microsoft Visual Studio .NET settings to set debug output

      • From the File menu choose Build > Configuration Manager. From the Active Solution Configuration drop down list, select Debug.

      • Build your assembly.

  2. Close running instances of Visual Studio .NET that contain your source files.

    In the next step, you start a new Visual Studio .NET instance to debug the MobiLink synchronization server and your .NET synchronization scripts.

  3. Start Visual Studio .NET using a command line option to debug the MobiLink synchronization server.

    • At a command prompt, navigate to the Common7\IDE subdirectory of your Visual Studio .NET installation.

    • Start devenv (the Visual Studio .NET IDE) using the /debugexe option.

      For example, type the following command line to debug the MobiLink synchronization server. Remember to specify dbmlsrv9 options, including the connection string and the option to load .NET assemblies.

      devenv /debugexe %asany9%\win32\dbmlsrv9.exe -c ...

      This causes Visual Studio .NET to start and dbmlsrv9.exe to appear in the Solution Explorer window.

  4. Set up Microsoft Visual Studio for debugging .NET code:

    • In the Visual Studio Solution Explorer window, right-click dbmlsrv9.exe and choose Properties.

    • Change Debugger Type from Auto to Mixed or Managed Only.

      This ensures Visual Studio .NET will only debug your .NET synchronization scripts.

  5. Open the associated .NET source files and set break points.

    Note: Open the source files individually in the dbmlsrv9 solution. Do not open the original solution or project file.

  6. Start MobiLink from the Debug menu or using F5.

    If prompted, save dbmlsrv9.sln in an appropriate location.

    If the dialog No Symbolic Information appears, click OK to debug anyway. You are debugging the managed .NET synchronization scripts that MobiLink calls, not the MobiLink synchronization server itself.

  7. Perform a synchronization that causes the code with a breakpoint to be executed by MobiLink.


.NET synchronization techniques

This section describes techniques you can use to tackle common .NET synchronization tasks.

Uploading rows


Uploading rows

You can use the upload_insert, upload_update, and upload_delete events to handle rows uploaded to the consolidated database.

For more information about these events, see:

  • upload_insert table event

  • upload_update table event

  • upload_delete table event

The variable number of rows passed to these events are not passed as parameters to the corresponding .NET functions. For special processing on these rows you can insert them into a temporary table and handle the result set using a subsequent event.

toggle To handle rows uploaded to the consolidated database

  1. Insert the uploaded values into a temporary table.

    For example, use the following function for the upload_insert event:

    public static string UploadInsert(/* no parameters */)
 {
   return("INSERT INTO tempULCustomer(cust_id, cust_name) values (?,?)");
 }

  2. Use a subsequent script to obtain the values from the temporary table and process the rows.

    Register the following function for the end_upload event:

    public void EndUpload(string user, string table)
{
   // declare variables to store your row values
   string _custid;
   string _custname;

   // create the command
   DBCommand stmt = currConn.CreateCommand();
   stmt.CommandText = "select * from tempULCustomer";

  // store the result set in a DBRowReader instance
   DBRowReader rset = stmt.ExecuteReader();

   // traverse the result set
   object[] rvalues = rset.NextRow();

   while( rvalues != null )
   {
      _custid = (string)rvalues[0];
      _custname = (string)rvalues[1];

     //... your logic to process the rows

      rvalues = rset.NextRow();
   }

   rset.Close();
   stmt.Close();
}


Loading Shared Assemblies

This section details options to load .NET assemblies and details the process to load shared assemblies.

Loading assemblies


Loading assemblies

A .NET assembly is a package of types, metadata, and executable code. In .NET applications, all code must be in an assembly. Assembly files have the extension .dll or .exe.

There are two types of assemblies:

  • Private assemblies A private assembly is a file in the file system.

  • Shared assemblies A shared assembly is an assembly that is installed in the global assembly cache.

Before MobiLink can load a class and call a method of that class, it must locate the assembly that contains the class. MobiLink only needs to locate the assembly that it calls directly. The assembly can then call any other assemblies it needs.

For example, MobiLink calls MyAssembly, and MyAssembly calls UtilityAssembly and NetworkingUtilsAssembly. In this situation, MobiLink only needs to be configured to find MyAssembly.

MobiLink provides two ways to load assemblies:

  • Use -sl dnet ( -MLAutoLoadPath ) This option only works with private assemblies. It sets the path to the application base directory and loads all the assemblies within it. This option is simpler to use and it is expected that it will be sufficient in most cases.

    When you use the -MLAutoLoadPath option you cannot specify a domain when entering the fully qualified method name for the event script.

    When you specify a path and directory with -MLAutoLoadPath, MobiLink does the following:

    • sets this path as the application base path

    • loads all classes in all files ending with .dll or .exe in the directory that you specified

    • creates one application domain and loads into that domain all user classes that do not have a domain specified

    Assemblies in the global assembly cache cannot be called directly with this option. To call these shared assemblies, use -MLDomConfigFile.

  • Use -sl dnet ( -MLDomConfigFile ) This option works with both private and shared assemblies. It requires a configuration file that contains domain and assembly settings. You should use this option when you have shared assemblies, when you don't want to load all the assemblies in the application base path, or when for some other reason you need to use a configuration file.

    With this option, MobiLink reads the settings in the specified domain configuration file. A domain configuration file contains configuration settings for one or more .NET domains. If there is more than one domain represented in the file, the first one that is specified is used as the default domain. (The default domain is used when scripts do not have a domain specified.)

    When loading assemblies, MobiLink tries to load the assembly first as private, and then attempts to load the assembly from the global assembly cache. Private assemblies must be located in the application base directory. Shared assemblies are loaded from the global assembly cache.

With the -MLDomConfigFile option, only assemblies that are specified in the domain configuration file can be called directly from event scripts.

Sample domain configuration file

A sample domain configuration file called mlDomConfig.xml is installed with MobiLink. You can write your own file from scratch, or edit the sample to suit your needs. The sample file is located in the SQL Anywhere Studio path, in

MobiLink\setup\dnet\mlDomConfig.xml

Following is the content of the sample domain configuration file mlDomConfig.xml:

<?xml version="1.0" encoding="utf-8"?>
<config xmlns="iAnywhere.MobiLink.mlDomConfig" xsi:schemaLocation='iAnywhere.MobiLink.mlDomConfig mlDomConfig.xsd' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' >
   <domain>
      <name>SampleDomain1</name>
      <appBase>C:\scriptsDir</appBase>
      <configFile></configFile>
      <assembly name="Assembly1" />
      <assembly name="Assembly2" />
   </domain>
   <domain>
      <name>SampleDomain2</name>
      <appBase>\Dom2assembly</appBase>
      <configFile>\Dom2assembly\AssemblyRedirects.config</configFile>
      <assembly name="Assembly3" />
      <assembly name="Assembly4" />
   </domain>
</config>

Following is an explanation of the contents of mlDomConfig.xml:

  • name is the domain name, used when specifying the domain in an event script. An event script with the format "DomainName:Namespace.Class.Method" would require a domain called DomainName be in the domain configuration file.

    You must specify at least one domain name.

  • appBase is the directory that the domain should use as its application base directory. All private assemblies are loaded by the .NET CLR based on this directory. You must specify appBase.

  • configFile is the .NET application configuration file that should be used for the domain. This can be left blank. It is usually used to modify the default assembly binding and loading behavior. Refer to your .NET documentation for more information about application configuration files.

  • assembly is the name of an assembly that MobiLink should load and search when resolving type references in event scripts. You must specify at least one assembly. If an assembly is used in more than one domain, it must be specified as an assembly in each domain. If the assembly is private, it must be in the application base directory for the domain.

For more information about the dbmlsrv9 option -sl dnet, see -sl dnet option.


.NET synchronization example

This example modifies an existing application to describe how to use .NET synchronization logic to handle the authenticate_user event. It creates a C# script for authenticate_user called AuthUser.cs. This script looks up the user's password in a table called user_pwd_table and authenticates the user based on that password.

Note:
This section provides a simple example to illustrate basic .NET synchronization logic. Typically, reasons for using a custom user authentication mechanism include integration with existing DBMS user authentication schemes, or supplying custom features, such as minimum password length or password expiry. MobiLink also has a built-in default mechanism.

For more information about MobiLink authentication, see Choosing a user authentication mechanism.

First, add the table user_pwd_table to the database. Execute the following in Interactive SQL:

CREATE TABLE user_pwd_table (
  user_name  varchar(128) PRIMARY KEY NOT NULL,
  pwd        varchar(128)
)

Next, add a user and password to the table:

INSERT INTO user_pwd_table VALUES( 'user1', 'myPwd' )

Create a directory for your .NET assembly. For example:

mkdir c:\mlexample

Create a file called AuthUser.cs with the following contents:

For more information, see authenticate_user connection event.

using System;
using iAnywhere.MobiLink.Script;
namespace MLExample
{

  public class AuthClass
  {
     private DBConnection  _conn;
    /// AuthClass constructor.

  public AuthClass( DBConnectionContext cc )
  {
     _conn   = cc.GetConnection();
  }
  /// The DoAuthenticate method handles the 'authenticate_user'
  /// event.
  /// Note: This method does not handle password changes for
  /// advanced authorization status codes.

  public void DoAuthenticate(
            ref int authStatus,
            string user,
            string pwd,
            string newPwd )
  {
      DBCommand   pwd_command = _conn.CreateCommand();
      pwd_command.CommandText = "select pwd from user_pwd_table"
                             + " where user_name = ? ";
      pwd_command.Prepare();
        // add a parameter for the user name
      DBParameter user_param = new DBParameter();
      user_param.DbType = SQLType.SQL_CHAR;
      // we need to set the size for SQL_VARCHAR
      user_param.Size   = (uint)user.Length;
      user_param.Value  = user;
      pwd_command.Parameters.Add( user_param );
     // fetch the password for this user.
      DBRowReader   rr  = pwd_command.ExecuteReader();
      object[]   pwd_row  = rr.NextRow();
      if( pwd_row == null ) {
      // user is unknown
      authStatus  = 4000;
      } else {
      if( ((string)pwd_row[0]) == pwd ) {
           // password matched
           authStatus = 1000;
      } else {
           // password did not match
           authStatus = 4000;
      }
      }
      pwd_command.Close();
      rr.Close();
      return;
  }
  }
}

The MLExample.AuthClass.DoAuthenticate method handles the authenticate_user event. It accepts the user name and password and returns an authorization status code indicating the success or failure of the validation.

Compile the file AuthUser.cs. You can do this on the command line or in Visual Studio .NET.

For example, the following command line will compile AuthUser.cs and generate an Assembly named example.dll in c:\mlexample. Substitute your install directory for asany9.

csc /out:c:\mlexample\example.dll /target:library /reference:\asany9\win32\iAnywhere.MobiLink.Script.dll AuthUser.cs

Register .NET code for the authenticate_user event. The method you need to execute (DoAuthenticate) is in the namespace MLExample and class AuthClass. Execute the following SQL:

call ml_add_dnet_connection_script( 'ex_version', 'authenticate_user', 'MLExample.AuthClass.DoAuthenticate' )
COMMIT

Next, run the MobiLink synchronization server with the following option. This option causes MobiLink to load all assemblies in c:\myexample:

-sl dnet ( -MLAutoLoadPath=c:\mlexample )

Now, when a user synchronizes with the version ex_version, they are authenticated with the password from the table user_pwd_table.


MobiLink .NET API Reference

This section explains the MobiLink .NET interfaces and classes, and their associated methods, properties, and constructors. To use these classes, reference the assembly \win32\iAnywhere.MobiLink.Script.dll in your SQL Anywhere Studio installation directory.

This section focuses on C#, but there are equivalents in VB.NET and C++.

DBCommand interface
DBConnection interface
DBConnectionContext interface
DBParameter class
DBParameterCollection class
DBRowReader interface
LogCallback delegate
LogMessage class
MessageType enumeration
ServerContext interface
ServerException class
ShutdownCallback delegate
SQLType enumeration
SynchronizationException class


DBCommand interface

public interface DBCommand
Member of iAnywhere.MobiLink.Script

Represents a SQL statement or database command. DBCommand can represent an update or query.

For example, the following C# code uses the DBCommand interface to execute two queries:

DBCommand stmt = conn.CreateCommand();
stmt.CommandText = "select t1a1, t1a2 from table1 ";
DBRowReader rs = stmt.ExecuteReader();
printResultSet( rs );
rs.Close();
stmt.CommandText = "select t2a1 from table2 ";
rs = stmt.ExecuteReader();
printResultSet( rs );
rs.Close();
stmt.Close();

The following C# example uses DBCommand to execute an update with parameters:

DBCommand cstmt = conn.CreateCommand();
cstmt.CommandText = "call myProc( ?,?,? )";
cstmt.Prepare();
DBParameter param = new DBParameter();
param.DbType          = SQLType.SQL_CHAR;
param.Value           = "10000";
cstmt.Parameters.Add( param );
param                 = new DBParameter();
param.DbType          = SQLType.SQL_INTEGER;
param.Value           = 20000;
cstmt.Parameters.Add( param );
param                 = new DBParameter();
param.DbType          = SQLType.SQL_DECIMAL;
param.Precision       = 5;
param.Value           = new Decimal( 30000 );
cstmt.Parameters.Add( param );
// Execute update
DBRowReader rset = cstmt.ExecuteNonQuery();
cstmt.Close();
Prepare method

public void Prepare( )

Prepare the SQL statement stored in CommandText for execution.

ExecuteNonQuery() method

public int ExecuteNonQuery( )

Execute a non-query statement. Returns the number of rows in the database affected by the SQL statement.

ExecuteReader() method

public DBRowReader ExecuteReader( )

Execute a query statement returning the result set. Returns a DBRowReader for retrieving results returned by the SQL statement.

Close() method

public void Close( )

Close the current SQL statement or command.

CommandText property

public string CommandText

The value is the SQL statement to be executed.

DBParameterCollection Parameters property

public DBParameterCollection Parameters

Gets the iAnywhere.MobiLink.Script.DBParameterCollection for this DBCommand.


DBConnection interface

public interface DBConnection
Member of iAnywhere.MobiLink.Script

Represents a MobiLink ODBC connection.

This interface allows user-written synchronization logic to access an ODBC connection created by MobiLink.

Commit() method

public void Commit( )

Commit the current transaction.

Rollback() method

public void Rollback( )

Roll back the current transaction.

Close() method

public void Close( )

Close the current connection.

CreateCommand() method

public DBCommand CreateCommand( )

Create a SQL statement or command on this connection. Returns the newly generated DBCommand.


DBConnectionContext interface

public interface DBConnectionContext
Member of iAnywhere.MobiLink.Script

Interface for obtaining and accessing information about the current database connection. This is passed to the constructor of classes containing scripts. If context is required for a background thread or beyond the lifetime of a connection, use a ServerContext.

Caution:
A DBConnectionContext instance should not be used outside the thread that calls into your .NET code.

Interface for obtaining information about the current database connection. This is passed to the constructor of classes containing scripts.

GetConnection method

public iAnywhere.MobiLink.Script.DBConnection GetConnection( )
Member of iAnywhere.MobiLink.Script.DBConnectionContext

Returns the existing connection. The connection is the same connection that MobiLink uses to execute SQL scripts.

This connection must not be committed, closed or altered in any way that would affect the MobiLink server use of the connection. The connection returned is only valid for the lifetime of the underlying MobiLink connection. Do not use the connection after the end_connection event has been called for the connection.

If a server connection with full access is required, use ServerContext.makeConnection().

GetServerContext method

public iAnywhere.MobiLink.Script.ServerContext.GetServerContext( )
Member of iAnywhere.MobiLink.Script.DBConnectionContext

Returns the ServerContext for this MobiLink server.

getProperties method

NameValueCollection getProperties( )

Returns the properties for this connection, based on this connection's script version. Properties are stored in the ml_property table.

For more information, see ml_property and ml_add_property.

getVersion method

string getVersion( )

Returns the name of the script version.

For more information, see ml_property and ml_add_property.


DBParameter class

public class DBParameter
Member of iAnywhere.MobiLink.Script

Represents a bound ODBC parameter.

DBParameter is required to execute commands with parameters. All parameters must be in place before the command is executed.

For example, the following C# code uses DBCommand to execute an update with parameters:

DBCommand cstmt = conn.CreateCommand();
  cstmt.CommandText = "call myProc( ?,?,? )";
  cstmt.Prepare();
  DBParameter param = new DBParameter();
  param.DbType          = SQLType.SQL_CHAR;
  param.Value           = "10000";
  cstmt.Parameters.Add( param );
  param                 = new DBParameter();
  param.DbType          = SQLType.SQL_INTEGER;
  param.Value           = 20000;
  cstmt.Parameters.Add( param );
  param                 = new DBParameter();
  param.DbType          = SQLType.SQL_DECIMAL;
  param.Precision       = 5;
  param.Value           = new Decimal( 30000 );
  cstmt.Parameters.Add( param );
  // Execute update
  DBRowReader rset = cstmt.ExecuteNonQuery();
  cstmt.Close();
dbType property

public SQLTYPE dbType

The value is the SQLType of this parameter.

Default: SQLType.SQL_TYPE_NULL.

Direction property

public System.Data.ParameterDirection Direction

The value is the Input/Output direction of this parameter.

Default: ParameterDirection.Input.

IsNullable property

public bool IsNullable

The value Indicates whether this parameter can be NULL.

Default: false.

ParameterName property

public string ParameterName

The value is the name of this parameter.

Default: null.

Precision property

public uint Precision

The value is the decimal precision of this parameter. Only used for SQLType.SQL_NUMERIC and SQLType.SQL_DECIMAL parameters.

Default: 0.

Scale property

public short Scale

The value is the resolvable digits of this parameter. Only used for SQLType.SQL_NUMERIC and SQLType.SQL_DECIMAL parameters.

Default: 0.

Size property

public uint Size

The value is the size in bytes of this parameter.

Default: Inferred from DbType.

Value property

public object Value

The value is the value of this parameter.

Default: null.


DBParameterCollection class

public class DBParameterCollection
inherits from IDataParameterCollection, IList, ICollection, IEnumerable
Member of iAnywhere.MobiLink.Script

Collection of DBParameters. When DBCommand creates a DBParamterCollection it is empty and must be filled with appropriate parameters before the DBCommand executes.

DBParameterCollection( ) method

public DBParameterCollection( )

Creates an empty list of DBParameters.

Contains( string parameterName ) method

public bool Contains( string parameterName )

Returns true if the collection contains a parameter with the specified name. Takes one parameter, parameterName, which is the name of the parameter.

IndexOf( string parameterName ) method

public int IndexOf( string parameterName )

Returns index of the parameter, or -1 if there is no parameter with the given name. Takes one parameter, parameterName, which is the name of the parameter.

RemoveAt( string parameterName ) method

public void RemoveAt( string parameterName )

Removes the parameter with the given name from the collection. Takes one parameter, parameterName, which is the name of the parameter.

Add( object value ) method

public int Add( object value )

Adds the given parameter to the collection. Takes one parameter, value, which is the iAnywhere.MobiLink.Script.DBParameter to add to the collection. Returns the index of the added parameter in the collection.

Clear() method

public void Clear( )

Removes all parameters from the collection.

Contains( object value ) method

public bool Contains( object value )

Returns true if this collection contains the given iAnywhere.MobiLink.Script.DBParameter. Takes one parameter, value, which is the iAnywhere.MobiLink.Script.DBParameter.

IndexOf( object value ) method

public int IndexOf( object value )

Returns the index of the given iAnywhere.MobiLink.Script.DBParameter in the collection. Takes one parameter, value, which is the iAnywhere.MobiLink.Script.DBParameter.

Insert( int index, object value ) method

public void Insert( int index, object value )

Inserts the given iAnywhere.MobiLink.Script.DBParameter into the collection at the specified index. Takes two parameters: value, which is the iAnywhere.MobiLink.Script.DBParameter; and index, which is the index to insert at.

Remove( object value ) method

public void Remove( object value )

Removes the given iAnywhere.MobiLink.Script.DBParameter from the collection. Takes one parameter, value, which is the iAnywhere.MobiLink.Script.DBParameter.

RemoveAt( int index) method

public int RemoveAt( int index )

Removes the iAnywhere.MobiLink.Script.DBParameter at the given index in the collection. Takes one parameter, index, which is the index of the iAnywhere.MobiLink.Script.DBParameter.

CopyTo(Array array, int index) method

public void CopyTo( Array array, int index )

Copies the contents of the collection into the given array starting at the specified index. Takes two parameters: array, which is the array to copy the contents of the collection into; and index, which is the index in the array to begin copying the contents of the collection into.

GetEnumerator() method

public IEnumerator GetEnumerator( )

Returns an enumerator for the collection.

IsFixedSize property

public bool IsFixedSize

Returns false.

IsReadOnly property

public bool IsReadOnly

Returns false.

Count property

public int Count

The number of parameters in the collection.

IsSynchronized property

public bool IsSynchronized

Returns false.

SyncRoot property

public object SyncRoot

Object that can be used to synchronize the collection.

this[ string parameterName ] property

public object this[ string parameterName ]

Gets or sets the iAnywhere.MobiLink.Script.DBParameter with the given name in the collection. Takes one parameter, parameterName, which is the name of the iAnywhere.MobiLink.Script.DBParameter to get or set.

this[ int index ] property

public object this[ int index ]

Gets or sets the iAnywhere.MobiLink.Script.DBParameter at the given index in the collection. Takes one parameter, index, which is the index of the iAnywhere.MobiLink.Script.DBParameter to get or set.


DBRowReader interface

public interface DBRowReader
Member of iAnywhere.MobiLink.Script

Represents a set of rows being read from a database. Executing the method DBCommand.executeReader( ) creates a DBRowReader.

The following example is a C# code fragment. It calls a function with the rows in the result set represented by the given DBRowReader.

DBCommand stmt = conn.CreateCommand();
stmt.CommandText = "select intCol, strCol from table1 ";
DBRowReader rs = stmt.ExecuteReader();
object[] values = rset.NextRow();
while( values != null ) {
handleRow( (int)values[0], (String)values[1] );
 values = rset.NextRow();
}
rset.Close();
stmt.Close();
NextRow( ) method

public object[ ] NextRow( )

Retrieves and returns the next row of values in the result set. If there are no more rows in the result set, it returns NULL.

See SQLType enumeration.

Close( ) method

public void Close( )

Cleans up resources used by this MLDBRowReader. After Close( ) is called, this MLDBRowReader cannot be used again.

ColumnNames property

public string[ ] ColumnNames

Gets the names of all columns in the result set. The value is an array of strings corresponding to the column names in the result set.

ColumnTypes property

public SQLType[ ] ColumnTypes

Gets the types of all columns in the result set. The value is an array of SQLTypes corresponding to the column types in the result set.


LogCallback delegate

public delegate void LogCallback(
ServerContext sc
LogMessage message
)
Member of iAnywhere.MobiLink.Script

Called when the MobiLink synchronization server prints a message.


LogMessage class

public class LogMessage : iAnywhere.MobiLink.Script.LogMessage
Member of iAnywhere.MobiLink.Script

Contains information about a message printed to the log.

Type property

public LogMessage.MessageType Type

The type of the log message that this instance represents.

User property

public string User

The user for which this message is being logged. It may be null.

Text property

public string Text

The main text of the message.


MessageType enumeration

public enum MessageType
Member of iAnywhere.MobiLink.Script.LogMessage

Enumeration of the possible types of LogMessage.

ERROR field

public ERROR

A log error message.

WARNING field

public WARNING

A log warning message.


ServerContext interface

public interface ServerContext
Member of iAnywhere.MobiLink.Script

An instantiation of all the context that is present for the duration of the MobiLink server. This context can be held as static data and used in a background thread. It is valid for the duration of the .NET CLR invoked by MobiLink.

To access a ServerContext instance, use the DBConnectionContext.getServerContext method.

GetStartClassInstances method

public object[ ] GetStartClassInstances( )
Member of iAnywhere.MobiLink.Script.ServerContext

Gets an array of the start classes that were constructed at server start time. The array length is zero if there are no start classes.

For more information about user-defined start classes, see User-defined start classes.

Following is an example of getStartClassInstances():

void FindStartClass( ServerContext sc, string name )
 {
   object[] startClasses = sc.GetStartClassInstances();
   foreach( object obj in startClasses ) {
     if( obj is MyClass ) {
         // Execute some code.....
     }
   }
 }
LogCallback ErrorListener event

This event is triggered when the MobiLink synchronization server prints an error.

LogCallback WarningListener event

This event is triggered when the MobiLink synchronization server prints a warning.

MakeConnection method

public iAnywhere.MobiLink.Script.DBConnection makeConnection( )
Member of iAnywhere.MobiLink.Script.ServerContext

Creates a new server connection.

ShutDown method

public void Shutdown( )
Member of iAnywhere.MobiLink.Script.ServerContext

Forces the server to shut down.

ShutdownListener method

public event iAnywhere.MobiLink.Script.ShutdownCallback
ShutdownListener(
iAnwyhere.MobiLink.Script.ServerContext sc)
Member of iAnywhere.MobiLink.Script.ServerContext

This event is triggered on shutdown. The following code is an example of how to use this event:

ShutdownCallback callback = new ShutdownCallback( shutdownHandler );
_sc.ShutdownListener += callback;
public void shutdownHandler( ServerContext sc )
//===============================================
{
_test_out_file.WriteLine( "shutdownPerformed" );
}
getProperties method

NameValueCollection getProperties(
 string component_name
string prop_set_name )

Returns the set of properties associated with the script version. These are stored in the MobiLink system table ml_property.

For more information, see ml_property and ml_add_property.

getPropertiesByVersion method

NameValueCollection getPropertiesByVersion( string script_version )

Returns the set of properties associated with the script version. These are stored in the MobiLink system table ml_property. The script version is stored in the prop_set_name column when the component_name is ScriptVersion.

For more information, see ml_property and ml_add_property.

getPropertySetNames method

StringCollection getPropertySetNames( string component_name )

Returns the list of property set names for a given component. These are stored in the MobiLink system table ml_property.

For more information, see ml_property and ml_add_property.


ServerException class

public class ServerException
Member of iAnywhere.MobiLink.Script

Used to signal MobiLink that an error has occurred with the server and it should shut down immediately.

ServerException constructors

public ServerException( )
Member of iAnywhere.MobiLink.Script.ServerException

Constructs a ServerException with no detail message.

public ServerException( string message )
Member of iAnywhere.MobiLink.Script.ServerException

Creates a new ServerException with the given message. The parameter message is the message for this ServerException.

public ServerException( string message, SystemException ie )
Member of iAnywhere.MobiLink.Script.ServerException

Creates a new ServerException with the given message and containing the given inner exception that caused this one. There are two parameters: message, which is the message for this ServerException, and ie, which is the exception that caused this ServerException.


ShutdownCallback delegate

public sealed delegate ShutdownCallback : System.MulticastDelegate
Member of iAnywhere.MobiLink.Script

Called when the MobiLink synchronization server is shutting down. Implementations of this delegate can be registered with the ServerContext.ShutdownListener event to be called when the MobiLink server shuts down.


SQLType enumeration

public enum SQLType
Member of iAnywhere.MobiLink.Script

Enumeration of all possible ODBC data types.

SQL_TYPE_NULL field

public SQL_TYPE_NULL

Null data type.

SQL_UNKNOWN_TYPE field

public SQL_UNKNOWN_TYPE

Unknown data type.

SQL_CHAR field

public SQL_CHAR

UTF-8 character array of a set size. Has .NET type String.

SQL_NUMERIC field

public SQL_NUMERIC

Numeric value of set size and precision. Has .NET type Decimal.

SQL_DECIMAL field

public SQL_DECIMAL

Decimal number of set size and precision. Has .NET type Decimal.

SQL_INTEGER field

public SQL_INTEGER

32-bit integer. Has .NET type Int32.

SQL_SMALLINT field

public SQL_SMALLINT

16-bit integer. Has .NET type Int16.

SQL_FLOAT field

public SQL_FLOAT

Floating point number with ODBC driver defined precision. Has .NET type Double.

SQL_REAL field

public SQL_REAL

Single precision floating-point number. Has .NET type Single.

SQL_DOUBLE field

public SQL_DOUBLE

Double precision floating point number. Has .NET type Double.

SQL_DATE field

public SQL_DATE

A date. Has .NET type DateTime.

SQL_DATETIME field

public SQL_DATETIME

A date and time. Has .NET type DateTime.

SQL_TIME field

public SQL_TIME

A time. Has .NET type DateTime.

SQL_INTERVAL field

public SQL_INTERVAL

An interval of time. Has .NET type TimeSpan.

SQL_TIMESTAMP field

public SQL_TIMESTAMP

A time stamp. Has .NET type DateTime.

SQL_VARCHAR field

public SQL_VARCHAR

A null terminated UTF-8 string with a user set maximum length. Has .NET type String.

SQL_TYPE_DATE field

public SQL_TYPE_DATE

A date. Has .NET type DateTime.

SQL_TYPE_TIME field

public SQL_TYPE_TIME

A time. Has .NET type DateTime.

SQL_TYPE_TIMESTAMP field

public SQL_TYPE_TIMESTAMP

A timestamp. Has .NET type DateTime.

SQL_DEFAULT field

public SQL_DEFAULT

A default type. Has no type.

SQL_ARD_TYPE field

public SQL_ARD_TYPE

An ARD object. Has no type.

SQL_BIT field

public SQL_BIT

A single bit. Has .NET type Boolean.

SQL_TINYINT field

public SQL_TINYINT

An 8-bit integer. Has .NET type SByte.

SQL_BIGINT field

public SQL_BIGINT

A 64-bit integer. Has .NET type Int64.

SQL_LONGVARBINARY field

public SQL_LONGVARBINARY

Variable length binary data with a driver dependent maximum length. Has .NET type byte[ ].

SQL_VARBINARY field

public SQL_VARBINARY

Variable length binary data with a user specified maximum length. Has .NET type byte[ ].

SQL_BINARY field

public SQL_BINARY

Fixed length binary data. Has .NET type byte[ ].

SQL_LONGVARCHAR field

public SQL_LONGVARCHAR

A null-terminated UTF-8 string with a driver-dependent maximum length. Has .NET type String.

SQL_GUID field

public SQL_GUID

A Global Unique ID (also called a UUID). Has .NET type Guid.

SQL_WCHAR field

public SQL_WCHAR

Unicode character array of fixed size. Has .NET type String.

SQL_WVARCHAR field

public SQL_WVARCHAR

Null-terminated Unicode string of user-defined maximum length. Has .NET type String.

SQL_WLONGVARCHAR field

public SQL_WLONGVARCHAR

Null-terminated Unicode string of driver-dependent maximum length. Has .NET type String.


SynchronizationException class

public class SynchronizationException
Member of iAnywhere.MobiLink.Script

Used to signal that a synchronization exception has occurred and that the current synchronization should be rolled back and restarted.

SynchronizationException constructors

public SynchronizationException( )
Member of iAnywhere.MobiLink.Script.SynchronizationException

Constructs a SynchronizationException with no details.

public SynchronizationException( string message )
Member of iAnywhere.MobiLink.Script.SynchronizationException

Creates a new SynchronizationException with the given message. The parameter message is the message for this ServerException.

public SynchronizationException( string message, SystemException ie )
Member of iAnywhere.MobiLink.Script.SynchronizationException

Creates a new SynchronizationException with the given message and containing the given inner exception that caused this one. There are two parameters: message, which is the message for this ServerException, and ie, which is the exception that caused this ServerException.


Synchronization Events

About this chapter

This chapter provides information about the MobiLink synchronization events and the SQL scripts, Java methods, or .NET methods that handle these events. You implement scripts to handle one or more of these events to control the actions of the MobiLink synchronization server.

For information about storing scripts, see Adding and deleting scripts in your consolidated database.

Overview of MobiLink events
authenticate_parameters connection event
authenticate_user connection event
authenticate_user_hashed connection event
begin_connection connection event
begin_connection_autocommit connection event
begin_download connection event
begin_download table event
begin_download_deletes table event
begin_download_rows table event
begin_publication connection event
begin_synchronization connection event
begin_synchronization table event
begin_upload connection event
begin_upload table event
begin_upload_deletes table event
begin_upload_rows table event
download_cursor table event
download_delete_cursor table event
download_statistics connection event
download_statistics table event
end_connection connection event
end_download connection event
end_download table event
end_download_deletes table event
end_download_rows table event
end_publication connection event
end_synchronization connection event
end_synchronization table event
end_upload connection event
end_upload table event
end_upload_deletes table event
end_upload_rows table event
example_upload_cursor table event
example_upload_delete table event
example_upload_insert table event
example_upload_update table event
handle_error connection event
handle_odbc_error connection event
modify_error_message connection event
modify_last_download_timestamp connection event
modify_next_last_download_timestamp connection event
modify_user connection event
new_row_cursor table event (deprecated)
old_row_cursor table event (deprecated)
prepare_for_download connection event
report_error connection event
report_odbc_error connection event
resolve_conflict table event
synchronization_statistics connection event
synchronization_statistics table event
time_statistics connection event
time_statistics table event
upload_cursor table event (deprecated)
upload_delete table event
upload_fetch table event
upload_insert table event
upload_new_row_insert table event
upload_old_row_insert table event
upload_statistics connection event
upload_statistics table event
upload_update table event


Overview of MobiLink events

When a synchronization request occurs and MobiLink server decides that a new connection must be created, the begin_connection event is fired and synchronization starts.

Flowchart of the MobiLink event model, showing the begin_connection event, a pre-defined process called do synchronizations, and an end_connection event.

Following the synchronization, the connection is placed in a connection pool, and MobiLink again waits for a synchronization request for the current script version. Before a connection is eventually dropped from the connection pool, the end_connection event is fired. But if another synchronization request for the same version is received, then MobiLink handles the next synchronization request on the same connection. There are a number of events that affect the current synchronization.

The primary phases of a synchronization are the upload and download transactions. The events contained in the upload and download transactions are outlined below.

The upload transaction

The upload transaction applies changes uploaded from a remote database.

The begin_upload event marks the beginning of the upload transaction. The upload transaction is a two-part process. First, inserts and updates are uploaded for all remote tables, and second, deletes are uploaded for all remote tables.

Flowchart of the MobiLink upload transaction process.

The end_upload event marks the end of the upload transaction.

For more information about the events that happen during upload, see Writing scripts to upload rows.

The download transaction

The download transaction fetches rows from the consolidated database. It begins with the begin_download event.

The download transaction is a two-part process. For each table, first deletes are downloaded, and then update/insert rows (upserts) are downloaded. The end_download event ends the download transaction.

Flowchart of the MobiLink download transaction process.

For more information about the events that happen during download, see Writing scripts to download rows.

The following pseudocode provides an overview of the sequence in which events, and hence the script of the same name, are invoked.

Event overview in pseudocode

The following pseudocode shows the complete MobiLink synchronization event model. This model assumes a full synchronization (not upload-only or download-only) with no errors.

Notes

  • In most cases, if you have not defined a script for a given event, the default action is to do nothing.

  • The begin_connection and end_connection events are connection-level events. They are independent of any single synchronization and have no parameters.

  • Some events are invoked once per synchronization for each table being synchronized. Scripts associated with these events are called table-level scripts.

    While each table can have its own table scripts, you can also write table-level scripts that are shared by several tables.

  • Some events, such as begin_synchronization, occur at both the connection level and the table level. You can supply both connection and table scripts for these events.

  • The COMMIT statements illustrate how the synchronization process is broken up into distinct transactions.

  • A database error can occur at any point within the synchronization process. Database errors are handled using the handle_error or handle_odbc_error scripts.

Warning
There should be no implicit or explicit commit or rollback in your synchronization scripts or the procedures or triggers that are called from your synchronization scripts. COMMIT or ROLLBACK statements within scripts alter the transactional nature of the synchronization steps. If you use them, you cannot guarantee the integrity of your data in the event of a failure.
------------------------------------------------------
Synchronization events in pseudocode.

Legend:
- // This is a comment
- <name>
    The pseudo code for <name> is listed separately
    in a later section, under a banner:
        ------------------------
        name
        ------------------------
- VariableName <- value
    Assign the given value to the given variable name.
    Variable names are in mixed case.
- event_name
    If you have defined a script for the given event name,
    it will be invoked.
------------------------------------------------------

CONNECT to consolidated database
begin_connection_autocommit
begin_connection
COMMIT
for each synchronization request with
     the same script version {
  <synchronize>
}
end_connection
COMMIT
DISCONNECT from consolidated database

------------------------------------------------------
synchronize
------------------------------------------------------

<authenticate>
<begin_synchronization>
<upload>
<prepare_for_download>
<download>
<end_synchronization>

------------------------------------------------------
authenticate
------------------------------------------------------

Status <- 1000
UseDefaultAuthentication <- TRUE
if( authenticate_user script is defined ) {
  UseDefaultAuthentication <- FALSE
  TempStatus <- authenticate_user
  if( TempStatus > Status ) {
    Status <- TempStatus
  }
}
if( authenticate_user_hashed script is defined ) {
  UseDefaultAuthentication <- FALSE
  TempStatus <- authenticate_user_hashed
  if( TempStatus > Status ) {
    Status <- TempStatus
  }
}
if( UseDefaultAuthentication ) {
  if( the user exists in the ml_user table ) {
    if( ml_user.hashed_password column is not NULL ) {
      if( password matches ml_user.hashed_password ) {
        Status <- 1000
      } else {
        Status <- 4000
      }
    } else {
      Status <- 1000
    }
  } else if( -zu+ was on the command line ) {
    Status <- 1000
  } else {
    Status <- 4000
  }
}
if( Status <= 2000 ) {
  if( authenticate_parameters script is defined )
 {
    TempStatus <- authenticate_parameters
    if( TempStatus > Status ) {
      Status <- TempStatus
  }
}
if( Status >= 3000 ) {
  ROLLBACK
  // Abort the synchronization.
} else {
  // UserName defaults to MobiLink user name
  // sent from the remote.
  if( modify_user script is defined ) {
  UserName <- modify_user
  // The new value of UserName is later passed to
  // all scripts that expect the MobiLink user name.
  }
  COMMIT
}

------------------------------------------------------
begin_synchronization
------------------------------------------------------

begin_synchronization   // conection event
for each table being synchronized {
    begin_synchronization    // call the table level script
}
for each publication being synchronized {
  begin_publication
}
COMMIT

------------------------------------------------------
end_synchronization
------------------------------------------------------

for each publication being synchronized {
  if( begin_publication script was called ) {
    end_publication
  }
}
for each table being synchronized {
  if( begin_synchronization table script was called ) {
    end_synchronization // table event
  }
}
end_synchronization     // connection event

for each table being synchronized {
synchronization_statistics // table event
}
synchronization_statistics // connection event
for each table being synchronized {
time_statistics // table event
}
time_statistics // connection event

COMMIT

For the details of upload stream processing, see Events during upload.

For the details of download stream processing, see Events during download.


Events during upload

The following pseudocode illustrates how upload events and upload scripts are invoked.

These events take place at the upload location in the complete event model. For more information, see Overview of MobiLink events.

------------------------------------------------------
upload
------------------------------------------------------

begin_upload
  for each table being synchronized {
    begin_upload_rows
    for each uploaded INSERT or UPDATE for this table {
      if( INSERT ) {
        <upload_inserted_row>
      }
      if( UPDATE ) {
        <upload_updated_row>
      }
    }
    end_upload_rows
  }
  for each table being synchronized IN REVERSE ORDER {
    begin_upload_deletes
    for each uploaded DELETE for this table {
      <upload_deleted_row>
    }
    end_upload_deletes
  }
  end_upload

  for each table being synchronized {
    upload_statistics  // table event
  }
    upload_statistics  // connection event

  COMMIT

------------------------------------------------------
<upload_inserted_row>
------------------------------------------------------
// NOTES:
// - Only table scripts for the current table are involved.
// - Cursor-based upload scripts, like upload_cursor,
//   are deprecated, and so are not shown.

UploadUsingStatements <- (
       upload_insert script is defined
    or upload_update script is defined
    or upload_delete script is defined
    or upload_fetch script is defined
    or upload_new_row_insert script is defined
    or upload_old_row_insert script is defined )
if( UploadUsingStatements ) {
  ConflictsAreExpected <- (
       upload_new_row_insert script is defined
    or upload_old_row_insert script is defined
    or resolve_conflict script is defined )
  if( upload_insert script is defined ) {
    upload_insert
  } else if( ConflictsAreExpected
      and upload_update script is not defined
      and upload_insert script is not defined
      and upload_delete script is not defined ) {
      // Forced conflict.
      upload_new_row_insert
      resolve_conflict
  } else {
      // ignore the insert
  }
} else {
  // ignore the insert
}

------------------------------------------------------
upload_updated_row
------------------------------------------------------
// NOTES:
// - Only table scripts for the current table are involved.
// - Both the old (original) and new rows are uploaded for
//   each update.
// - Cursor-based upload scripts, like upload_cursor,
//   are deprecated, and so are not shown.

UploadUsingStatements <- (
       upload_insert script is defined
    or upload_update script is defined
    or upload_delete script is defined
    or upload_fetch script is defined
    or upload_new_row_insert script is defined
    or upload_old_row_insert script is defined )
if( UploadUsingStatements ) {
  ConflictsAreExpected <- (
       upload_new_row_insert script is defined
    or upload_old_row_insert script is defined
    or resolve_conflict script is defined )
  Conflicted <- FALSE
  if( upload_update script is defined ) {
    if( ConflictsAreExpected
      and upload_fetch script is defined ) {
      FETCH using upload_fetch INTO current_row
      if( current_row <> old row ) {
        Conflicted <- TRUE
      }
    }
    if( not Conflicted ) {
      upload_update
    }
  } else if( upload_update script is not defined
      and upload_insert script is not defined
      and upload_delete script is not defined ) {
      // Forced conflict.
      Conflicted <- TRUE
  }
  if( ConflictsAreExpected and Conflicted ) {
    upload_old_row_insert
    upload_new_row_insert
    resolve_conflict
  }
} else {
  // ignore the update
}

------------------------------------------------------
upload_deleted_row
------------------------------------------------------
// NOTES:
// - Only table scripts for the current table are involved.
// - Cursor-based upload scripts, like upload_cursor,
//   are deprecated, and so are not shown.

UploadUsingStatements <- (
       upload_insert script is defined
    or upload_update script is defined
    or upload_delete script is defined
    or upload_fetch script is defined
    or upload_new_row_insert script is defined
    or upload_old_row_insert script is defined )
if( UploadUsingStatements ) {
  ConflictsAreExpected <- (
       upload_new_row_insert script is defined
    or upload_old_row_insert script is defined
    or resolve_conflict script is defined )
  if( upload_delete is defined ) {
    upload_delete
  } else if( ConflictsAreExpected
    and upload_update script is not defined
    and upload_insert script is not defined
    and upload_delete script is not defined ) {
    // Forced conflict.
    upload_old_row_insert
    resolve_conflict
  } else {
    // ignore this delete
  }
} else {
    // ignore this delete
}


Events during download

The following pseudocode provides an overview of the sequence in which download events, and hence the script of the same name, are invoked.

These events take place at the download location in the complete event model provided in Overview of MobiLink events.

------------------------------------------------------
prepare_for_download
------------------------------------------------------

prepare_for_download
modify_last_download_timestamp
if( prepare_for_download script is defined
    or modify_last_download_timestamp script is defined ) {
    COMMIT
}

------------------------------------------------------
download
------------------------------------------------------

begin_download
for each table being synchronized {
  begin_download_deletes
  for each row in download_delete_cursor {
    if( all primary key columns are NULL ) {
      send TRUNCATE to remote
    } else {
      send DELETE to remote
    }
  }
  end_download_deletes
  begin_download_rows
  for each row in download_cursor {
    send INSERT ON EXISTING UPDATE to remote
  }
  end_download_rows
}
modify_next_download_timestamp
end_download
for each table being synchronized {
  download_statistics   // table event
}
  download_statistics   // connection event

COMMIT
Notes

  • If an acknowledgement is expected, and if no confirmation of the downloads is received from the client, the entire download transaction is rolled back in the consolidated database.

    For more information, see SendDownloadACK (sa) extended option for Adaptive Server Anywhere remotes or Send Download Acknowledgement synchronization parameter for UltraLite remotes.

  • The download stream does not distinguish between inserts and updates. The script associated with the download_cursor event is a SELECT statement that defines the rows to be downloaded. The client detects whether the row exists or not and carries out the appropriate insert or update operation.

  • At the end of the download processing, the client automatically deletes rows that violate referential integrity.

    For more information, see Referential integrity and synchronization.


authenticate_parameters connection event

Function

Receives non-table data from the remote that can be used to authenticate beyond a user ID or password. The non-table data can also be used to arbitrarily customize each synchronization.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Item | Parameter | Description
1 | auth_status | INTEGER. This is an INOUT parameter.
2 | ml_username | VARCHAR(128).
3... | remote_parameters (one or more) | VARCHAR(128).
Description

You can send strings or parameters in the form of strings from both Adaptive Server Anywhere and UltraLite remotes. This allows you to have authentication beyond a user ID and password. It also means that you can customize your synchronization based on the value of parameters, and do this in a pre-synchronization phase, during authentication.

For UltraLite remote databases, pass the parameters using the num_auth_parms and auth_parms fields in the ul_synch_info struct. num_auth_parms is a count of the number of parameters, from 0 to 255. auth_parms is a pointer to a list of strings. To prevent the strings being viewed as plain text, the strings are sent in the same way as passwords. If num_auth_parms is 0, set auth_parms to NULL.

Following is an example of passing parameters in UltraLite:

ul_char * Params[ 3 ] = { UL_TEXT( "parm1" ), UL_TEXT( "parm2" ), UL_TEXT( "parm3" ) };

...
info.num_auth_parms = 3;
info.auth_parms = Params;

For Adaptive Server Anywhere remote databases, you pass parameters using the dbmlsync -ap option, in a comma-separated list. For example,

dbmlsync -ap "parm1,parm2,parm3"

The MobiLink synchronization server executes this event upon starting each synchronization. It is executed before, and in the same transaction as, the begin_synchronization event.

You can use this event to replace the built-in MobiLink authentication mechanism with a custom mechanism. You may want to call into the authentication mechanism of your DBMS, or you may wish to implement features not present in the MobiLink built-in mechanism.

The number of remote parameters must match the number expected or an error will result. For example, if three parameters are sent, the event must expect five, because there is auth_status and ml_username plus the three parameters. An error will also occur if parameters are sent from the client and there is no event.

If the authenticate_user or authenticate_user_hashed scripts are invoked and return an error, this event is not called.

SQL scripts for the authenticate_parameters event must be implemented as stored procedures.

See also
  • Authenticating MobiLink Users
  • Custom user authentication
  • authenticate_user connection event
  • authenticate_user_hashed connection event
  • begin_synchronization connection event
  • -ap option
  • Authentication Parameters synchronization parameter


authenticate_user connection event

Function

Implements custom user authentication.

Parameters

In the following table, the description indicates the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | auth_status | INTEGER. This is an INOUT parameter.
2 | ml_username | VARCHAR(128).
3 | user_password | VARCHAR(128).
4 | user_new_password | VARCHAR(128).
Default action

Use MobiLink built-in user authentication mechanism.

Description

The MobiLink synchronization server executes this event upon starting each synchronization. It is executed in a transaction before the begin_synchronization transaction.

You can use this event to replace the built-in MobiLink authentication mechanism with a custom mechanism. You may want to call into the authentication mechanism of your DBMS, or you may wish to implement features not present in the MobiLink built-in mechanism, such as password expiry or a minimum password length.

The parameters used in an authenticate_user event are as follows:

  1. auth_status This required parameter is an INOUT parameter: a parameter that provides a value to the script, and could be given a new value by the script. The auth_status parameter indicates the overall success of the authentication, and can be set to one of the following values:

    Returned Value | Auth_status | Description
    V <= 1999 | 1000 | Authentication succeeded.
    1999 < V <= 2999 | 2000 | Authentication succeeded: password expiring soon.
    2999 < V <= 3999 | 3000 | Authentication failed: password expired.
    3999 < V <= 4999 | 4000 | Authentication failed.
    4999 < V <= 5999 | 5000 | Authentication failed as user is already synchronizing.
    5999 < V | 4000 | If the returned value is greater than 5999, MobiLink interprets it as a returned value of 4000.

  2. ml_username This optional parameter is the MobiLink user name.

  3. user_password This optional parameter indicates the password for authentication purposes. If the user does not supply a password, this is NULL.

  4. user_new_password This optional parameter indicates a new password. If the user does not change their password, this is NULL.

SQL scripts for the authenticate_user event must be implemented as stored procedures.

When the two authentication scripts are both defined, and both scripts return different auth_status codes, the higher value is used.

The authenticate_user script is executed in a transaction along with all authentication scripts. This transaction always commits.

There are predefined scripts that you can use for the authenticate_user event to simplify authentication using LDAP, IMAP and POP3 servers.

For more information, see Authenticating to external servers.

See also
  • Authenticating MobiLink Users
  • Custom user authentication
  • Authenticating to external servers
  • authenticate_user_hashed connection event
  • authenticate_parameters connection event
  • modify_user connection event
  • begin_synchronization connection event
SQL example

A typical authenticate_user script is a call to a stored procedure. The order of the parameters in the call must match the order above. The following example uses ml_add_connection_script to assign the event to a stored procedure called my_auth.

call ml_add_connection_script(
   'ver1', 'authenticate_user', 'call my_auth ( ?, ?, ?, ? )'
)

The following Adaptive Server Anywhere stored procedure uses only the user name to authenticate—it has no password check. The procedure ensures only that the supplied user name is one of the employee IDs listed in the ULEmployee table.

CREATE PROCEDURE my_auth(in @user_name varchar(128))
begin
  if exists
  ( select * from ulemployee
    where emp_id = @user_name )
  then
    message 'OK' type info to client;
      return 1000;
    else
    message 'Not OK' type info to client;
      return 4000;
  end if
end
Java example

The following stored procedure call registers a Java method called authenticateUser as the script for the authenticate_user event when synchronizing the script version ver1. This syntax is for Adaptive Server Anywhere consolidated databases.

call ml_add_java_connection_script(
   'ver1', 'authenticate_user',
   'ExamplePackage.ExampleClass.authenticateUser'
)

Following is the sample Java method authenticateUser. It calls Java functions that check and, if needed, change the user's password.

public String authenticateUser
( ianywhere.ml.script.InOutInteger authStatus,
  String user, String pwd, String newPwd )
  throws java.sql.SQLException
{  // in a real authenticate_user handler, we would
   // handle more auth code states
   _curUser = user;
   if( checkPwd( user, pwd ) )
   {  // auth successful
      if( newPwd != null )
      {  // pwd is being changed
         if( changePwd( user, pwd, newPwd ) )
         {  // auth ok and pwd change ok. Use custom code
            authStatus.setValue( 1001 );
         }
         else {  // authorization ok but password
                 // change failed. Use custom code.
                 java.lang.System.err.println( "user: "
                 + user + " pwd change failed!" );
                 authStatus.setValue( 1002 ); } }
        else {  authStatus.setValue( 1000 ); } }
        else {  // auth failed
           authStatus.setValue( 4000 ); }
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called AuthUser as the script for the authenticate_user connection event when synchronizing the script version ver1. This syntax is for Adaptive Server Anywhere consolidated databases.

call ml_add_dnet_connection_script(
   'ver1', 'authenticate_user',
   'TestScripts.Test.AuthUser'
)

Following is the C# signature for the method AuthUser.

public void AuthUser( ref int authStatus, string user, string pwd, string newPwd )

For a more detailed example of an authenticate_user script written in C# in .NET, see .NET synchronization example.


authenticate_user_hashed connection event

Function

Implements a custom user authentication mechanism.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | auth_status | INTEGER. This is an INOUT parameter.
2 | ml_username | VARCHAR(128).
3 | hashed_user_password | BINARY(20). If the user does not supply a password, this is NULL.
4 | hashed_new_password | BINARY(20). If the user does not change their password, this is NULL.
Default action

Use MobiLink built-in user authentication mechanism.

Description

This event is identical to authenticate_user except for the passwords, which are in the same hashed form as those stored in the ml_user.hashed_password column. Passing the passwords in hashed form provides increased security.

A one-way hash is used. A one-way hash takes a password and converts it to a byte sequence that is (essentially) unique to each possible password. The one-way hash lets password authentication take place without having to store the actual password in the consolidated database.

When authenticate_user and authenticate_user_hashed are both defined, and both scripts return different auth_status codes, the higher value is used.

See also
  • Authenticating MobiLink Users
  • Custom user authentication
  • authenticate_user connection event
  • authenticate_parameters connection event
SQL example

A typical authenticate_user_hashed script is a call to a stored procedure. The order of the parameters in the call must match the order above. The following example calls ml_add_connection_script to assign the event to a stored procedure called my_auth.

call ml_add_connection_script(
   'ver1', 'authenticate_user_hashed', 'call my_auth ( ?, ?, ?)'
)

The following Adaptive Server Anywhere stored procedure uses both the user name and password to authenticate. The procedure ensures only that the supplied user name is one of the employee IDs listed in the ULEmployee table. The procedure assumes that the Employee table has a binary(20) column called hashed_pwd.

CREATE PROCEDURE my_auth(
  inout @auth_status integer,
  in @user_name varchar(128),
  in @hpwd binary(20) )
begin
  if exists
  ( select * from ulemployee
    where emp_id = @user_name
      and hashed_pwd = @hpwd )
  then
    message 'OK' type info to client;
    return 1000;
  else
    message 'Not OK' type info to client;
    return 4000;
  end if
end

Java example

The following stored procedure call registers a Java method called authUserHashed as the script for the authenticate_user_hashed event when synchronizing the script version ver1.

call ml_add_java_connection_script(
   'ver1', 'authenticate_user_hashed',
   'ExamplePackage.ExampleClass.authUserHashed')

Following is the sample Java method authUserHashed. It calls Java functions that check and, if needed, change the user's password.

public String authUserHashed(
   ianywhere.ml.script.InOutInteger authStatus,
   String user, byte pwd[], byte newPwd[] )
  throws java.sql.SQLException
{  // in a real authenticate_user_hashed handler, we
   // would handle more auth code states
   _curUser = user;
   if( checkPwdHashed( user, pwd ) ) {
   // auth successful
     if( newPwd != null )
     {  // pwd is being changed
        if( changePwdHashed( user, pwd, newPwd ) )
        {  // auth ok and pwd change ok use custom code
           authStatus.setValue( 1001 ); }
        else
        { // auth ok but pwd change failed.
          // Use custom code
          java.lang.System.err.println( "user: " + user
            + " pwd change failed!" );
          authStatus.setValue( 1002 ); } }
   else {  authStatus.setValue( 1000 ); } }
   else {  // auth failed
        authStatus.setValue( 4000 ); }
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called AuthUserHashed as the script for the authenticate_user_hashed connection event when synchronizing the script version ver1. This syntax is for Adaptive Server Anywhere consolidated databases.

call ml_add_dnet_connection_script(
   'ver1',
   'authenticate_user_hashed',
   'TestScripts.Test.AuthUserHashed'
)

Following is the C# signature for the call AuthUserHashed.

public void AuthUserHashed(
   ref int authStatus,
   string user,
   byte[] pwd,
   byte[] newPwd )


begin_connection connection event

Function

Invoked at the time the MobiLink synchronization server connects to the consolidated database server.

Parameters

None.

Default action

None.

Description

The MobiLink synchronization server executes this event upon opening each worker-thread connection to the consolidated database server. The MobiLink synchronization opens connections on demand as synchronization requests come in. When an application forms or reforms a connection with the MobiLink synchronization server, the MobiLink synchronization server temporarily allocates one connection with the database server for the duration of that synchronization.

See also
  • end_connection connection event.
SQL example

The following SQL script works with an Adaptive Server Anywhere consolidated database. Two variables are created, one for the last_download timestamp, and one for employee ID.

call ml_add_connection_script(
    'custdb',
    'begin_connection',
    'create variable @LastDownload timestamp;
    create variable @EmployeeID integer;')
Java example

Note: This script is not generally used in Java, because instead of database variables you would use member variables in this class instance, and prepare the members in the constructor.

The following stored procedure call registers a Java method called beginConnection as the script for the begin_connection event when synchronizing the script version ver1. This syntax is for Adaptive Server Anywhere consolidated databases.

call ml_add_java_connection_script(
    'ver1',
    'begin_connection',
    'ExamplePackage.ExampleClass.beginConnection' )

Following is the sample Java method beginConnection. This returns SQL that will create a connection level variable.

public String beginConnection()
{ return("create variable @LastDownload timestamp;" ); }
.NET example

The following stored procedure call registers a .NET method called BeginConnection as the script for the begin_connection connection event when synchronizing the script version ver1. This syntax is for Adaptive Server Anywhere consolidated databases.

call ml_add_dnet_connection_script(
   'ver1',
   'begin_connection',
   'TestScripts.Test.BeginConnection'
)

Following is the signature for the call BeginConnection.

public string BeginConnection()
{ return("create variable @LastDownload timestamp;" ); }


begin_connection_autocommit connection event

Function

Turns on autocommit.

Parameters

None.

Default action

Autocommit is off.

Description

When the MobiLink synchronization server connects to the consolidated database, it turns off autocommit so that it can roll back the upload and download streams if an error occurs.

However, if you are using an Adaptive Server Enterprise consolidated database, you cannot perform DDL functions such as creating temporary tables unless autocommit is on. If you are using an Adaptive Server Enterprise consolidated database, run your DDL commands in the begin_connection_autocommit event. When the event is finished, autocommit is turned off.

Begin_connection_autocommit scripts must be written so that they are repeatable. This is because if an error or deadlock occurs, the MobiLink synchronization server needs to be able to retry the script (since it can't roll it back).


begin_download connection event

Function

Processes any statements just before the MobiLink synchronization server commences preparing the download data stream.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | last_download | TIMESTAMP
2 | ml_username | VARCHAR(128)
Default action

None.

Description

The MobiLink synchronization server executes this event as the first step in the processing of downloaded information. Download information is processed in a single transaction. The execution of this event is the first action in this transaction.

The last_download timestamp is the value obtained from the consolidated database during the last successful synchronization immediately prior to the download phase. If the current user has never synchronized successfully, this value is set to 1900-01-01.

See also
  • end_download connection event
SQL example

The following example calls ml_add_connection_script to assign the event to a stored procedure called SetDownloadParameters.

call ml_add_connection_script (
   'Lab',
   'begin_download',
   'CALL SetDownloadParameters( ?, ? )' )
Java example

The following stored procedure call registers a Java method called beginDownloadConnection as the script for the begin_download connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
   'example_ver',
   'begin_download',
   'ExamplePackage.ExampleClass.beginDownloadConnection' )

Following is the sample Java method beginDownloadConnection. It calls a Java function (prepDeleteTables) that will prepare the delete tables using a JDBC synchronization that was set earlier.

public String beginDownloadConnection(
    Timestamp ts, String user )
  throws java.sql.SQLException
{  prepDeleteTables ( _syncConn, ts, user );
   return ( null ); }
.NET example

The following stored procedure call registers a .NET method called BeginDownload as the script for the begin_download connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script(
  'ver1',
  'begin_download',
  'TestScripts.Test.BeginDownload'
)

Following is the sample .NET method BeginDownload. It calls a .NET function (prepDeleteTables) that will prepare the delete tables using a JDBC synchronization that was set earlier.

public void BeginDownload(
  DateTime timestamp,
  string user )
{  prepDeleteTables ( _syncConn, ts, user );
   return ( null ); }


begin_download table event

Function

Processes statements related to a specific table just before preparing the download stream of inserts, updates, and deletions.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | last_download | TIMESTAMP
2 | ml_username | VARCHAR(128)
3 | table | VARCHAR (128)
Default action

None.

Description

The MobiLink synchronization server executes this event as the first step in preparing download information for a specific table. The download information is prepared in its own transaction. The execution of this event is the first table-specific action in the transaction.

You can have one begin_download script for each table in the remote database. The script is only invoked when that table is synchronized.

The last_download timestamp is the value obtained from the consolidated database during the last successful synchronization immediately prior to the download phase. If the current user has never synchronized successfully, this value is set to 1900-01-01.

See also
  • end_download table event
SQL example

The following example can be used on an Adaptive Server Anywhere 9 database. The first piece of code calls the ml_add_table_script, and the second creates a BeginTableDownload procedure.

call ml_add_table_script(
   'version1',
   'Leads',
   'begin_download',
   'call BeginTableDownLoad( ?, ?, ? ) );

create procedure BeginTableDownload(
   LastDownload timestamp,
   MLUser varchar(128),
   TableName varchar(128) )
begin
  execute immediate 'update ' || TableName ||
' set last_download_check = CURRENT TIMESTAMP
  where Owner = ' ||MLUser;
end
Java example

The following stored procedure call registers a Java method called beginDownloadTable as the script for the begin_download table event when synchronizing the script version ver1.

call ml_add_java_table_script(
   'ver1',
   'table1',
   'begin_download',
   'ExamplePackage.ExampleClass.beginDownloadTable' )

Following is the sample Java method beginDownloadTable. It saves the name of the current table for use in a later member function call.

public String beginDownloadTable(
   Timestamp ts,
   String user,
   String table )
{  _curTable = table;
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called BeginTableDownload as the script for the begin_download table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1', 'table1', 'begin_download',
  'TestScripts.Test.BeginTableDownload'
)

Following is the sample .NET method BeginTableDownload. It saves the name of the current table for use in a later member function call.

public void BeginTableDownload(
  DateTime timestamp,
  string user,
  string table )
{  _curTable = table;
   return( null ); }


begin_download_deletes table event

Function

Processes statements related to a specific table just before fetching a list of rows to be deleted from the specified table in the remote database.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | last_download | TIMESTAMP
2 | ml_username | VARCHAR (128)
3 | table | VARCHAR (128)
Default action

None.

Description

This event is executed immediately before fetching a list of rows to be deleted from the named table in the remote database.

You can have one begin_download_deletes script for each table in the remote database.

The last_download timestamp is the value obtained from the consolidated database during the last successful synchronization immediately prior to the download phase. If the current user has never synchronized successfully, this value is set to 1900-01-01.

See also
  • begin_download_rows table event
  • end_download_rows table event
SQL example

To minimize the amount of data on remotes, you can use this event to flag data that will be deleted when the download_delete_cursor is executed. The following example flags for deletion sales leads from the remote device that are over 10 weeks old. The example can be used on an Adaptive Server Anywhere 9 database. The code calls the ml_add_table_script, and then creates a beginDownloadDeletes procedure.

call ml_add_table_script (
  'version1',
  'Leads',
  'begin_download_deletes',
  'call BeginDownloadDeletes (?, ?, ?)' );

create procedure BeginDownloadDeletes(
  LastDownload timestamp,
  MLUser varchar(128),
  TableName varchar(128) )
begin
  execute immediate 'update ' || TableName ||
  ' set delete_flag = 1 where
  days(creation_time, CURRENT DATE) > 70 and Owner = '
  || MLUser;
end;
Java example

The following stored procedure call registers a Java method called beginDownloadDeletes as the script for the begin_download_deletes table event when synchronizing the script version ver1.

call ml_add_java_table_script(
   'ver1',
   'table1',
   'begin_download_deletes',
   'ExamplePackage.ExampleClass.beginDownloadDeletes' )

Following is the sample Java method beginDownloadDeletes. It saves the name of the current table for use in a later member function call.

public String beginDownloadDeletes( Timestamp ts,
String user, String table )
{  _curTable = table;
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called BeginDownloadDeletes as the script for the begin_download_deletes table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1', 'table1', 'begin_download_deletes',
  'TestScripts.Test.BeginDownloadDeletes'
)

Following is the sample .NET method BeginDownloadDeletes. It saves the name of the current table for use in a later member function call.

public void BeginDownloadDeletes(
  DateTime timestamp,
  string user,
  string table )
{  _curTable = table;
   return( null ); }


begin_download_rows table event

Function

Processes statements related to a specific table just before fetching a list of rows to be inserted or updated in the specified table in the remote database.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | last_download | TIMESTAMP
2 | ml_username | VARCHAR (128)
3 | table | VARCHAR (128)
Default action

None.

Description

This event is executed immediately before fetching the stream of rows to be inserted or updated in the named table in the remote database.

You can have one begin_download_rows script for each table in the remote database.

The last_download timestamp is the value obtained from the consolidated database during the last successful synchronization immediately prior to the download phase. If the current user has never synchronized successfully, this value is set to 1900-01-01.

See also
  • begin_download_deletes table event
  • end_download_deletes table event
SQL example

You can use the begin_download_rows table event to flag rows that you no longer want to download for this table. The following example archives sales leads that are over seven days old.

call ml_add_table_script( 'version1', 'Leads',
  'begin_download_rows',
  'call BeginDownloadRows (?, ?, ?)' );

create procedure BeginDownloadRows (
  LastDownload timestamp, MLUser varchar(128),
  TableName varchar(128) )
begin
  execute immediate 'update ' || TableName ||
  ' set download_flag = 0 where
  days(creation_time, CURRENT DATE) > 7 and Owner = '
  || MLUser;
end;
Java example

The following stored procedure call registers a Java method called beginDownloadRows as the script for the begin_download_rows table event when synchronizing the script version ver1. This syntax is for Adaptive Server Anywhere consolidated databases.

call ml_add_java_table_script(
   'ver1',
   'table1',
   'begin_download_rows',
   'ExamplePackage.ExampleClass.beginDownloadRows' )

Following is the sample Java method beginDownloadRows. It generates an UPDATE statement using the table and user. MobiLink will execute this SQL statement.

public String beginDownloadRows( Timestamp ts,
String user, String table )
{  return( "update " + table + " set download_flag = 0 "
   + " where days(creation_time, CURRENT DATE) > 7 " +
   " and Owner = '" + user + "'" ); }
.NET example

The following stored procedure call registers a .NET method called BeginDownloadRows as the script for the begin_download_rows table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1', 'table1', 'begin_download_rows',
  'TestScripts.Test.BeginDownloadRows'
)

Following is the sample .NET method BeginDownloadRows. It generates an UPDATE statement using the table and user. MobiLink will execute this SQL statement.

public void BeginDownloadRows(
  DateTime timestamp,
  string user,
  string table )
{  return( "update " + table + " set download_flag = 0 "
   + " where days(creation_time, CURRENT DATE) > 7 " +
   " and Owner = '" + user + "'" ); }


begin_publication connection event

Function

Provides useful information about the publication(s) being synchronized. This script may also be used to manage generation numbers for file-based downloads.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Item | Parameter | Description
1 | generation_number | INTEGER. This is an INOUT parameter. If your deployment does not use file-based downloads, this parameter can be ignored. The default is 1.
2 | ml_username | VARCHAR(128). If an UltraLite remote is synchronizing with UL_SYNC_ALL, this event is invoked once with the name 'unknown'.
3 | publication_name | VARCHAR(128)
4 | last_upload | TIMESTAMP. Last successful upload.
5 | last_download | TIMESTAMP. Last successful download.
Default action

The default generation number is 1. If no script is defined for this event, the generation number sent to the remote will always be 1.

Description

This event lets you design synchronization logic based on the publications currently being synchronized. This event is invoked in the same transaction as the begin_synchronization event, and is invoked after the begin_synchronization event. It is invoked once per publication being synchronized.

One potential use for this event is to affect what is downloaded based on the publication used. For example, consider a table that is part of both a priority publication (PriorityPub) and a publication for all tables (AllTablesPub). A script for the begin_publication event could store the publication names in a Java class or a SQL variable or package. Download scripts could then behave differently based on whether the publication being synchronized is PriorityPub or AllTablesPub.

Generation number

The generation_number parameter is specifically for file-based downloads. The output value of the generation number is passed from the begin_synchronization script to the end_synchronization script. The meaning of the generation_number depends on whether the current synchronization is being used to create a download file, or whether the current synchronization has an upload.

The output value of the generation number is passed from the begin_publication script to the end_publication script. The meaning of the generation_number depends on whether the current synchronization is being used to create a download file, or whether the current synchronization has an upload.

In file-based downloads, generation numbers are used to force an upload before the download. The number is stored in the download file. During a synchronization that has an upload, one generation number is output for every subscription to a publication. They are sent to the remote database in the upload acknowledgement, and stored in SYSSYNC.generation_number.

See also
  • end_publication connection event.
  • File-Based Downloads.
  • MobiLink generation numbers.
SQL example

You may want to record the information for each publication being synchronized. The following example calls ml_add_connection_script to assign the event to a stored procedure called RecordPubSync.

call ml_add_connection_script(
'version1',
'begin_publication',
'{call RecordPubSync( ?, ?, ?, ?, ? )}' );
Java example

The following stored procedure call registers a Java method called beginPublication as the script for the begin_publication connection event when synchronizing the script version ver1.

call ml_add_java_connection_script( 'ver1',
   'begin_publication',
   'ExamplePackage.ExampleClass.beginPublication' )

Following is the sample Java method beginPublication. It saves the name of each publication for later use.

public String beginPublication(
    ianywhere.ml.script.InOutInteger generation_number,
    String user,
    String pub_name,
    Timestamp last_upload,
    Timestamp last_download )
{  _publicationNames[ _numPublications++ ] = pub_name;
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called BeginPub as the script for the begin_publication connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script( 'ver1',
  'begin_publication',
  'TestScripts.Test.BeginPub'
)

Following is the sample .NET method BeginPub. It saves the name of each publication for later use.

public void BeginPub(
    ref int generation_number,
    string user,
    string pub_name,
    DateTime last_upload,
    DateTime last_download )
{
    _publicationNames[ _numPublications++ ] = pub_name;
}


begin_synchronization connection event

Function

Processes any statements at the time an application connects to the MobiLink synchronization server in preparation for the synchronization process.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
Default action

None.

Description

The MobiLink synchronization server executes this event immediately after an application preparing to synchronize has formed a connection with the MobiLink synchronization server.

This event is executed within a separate transaction before the upload transaction. It is useful for maintaining statistics.

See also
  • end_synchronization connection event
  • begin_synchronization table event
SQL example

You may want to store the ml_username value in a temporary table or variable if you will be referencing that value many times in subsequent scripts.

Call ml_add_connection_script (
  'version1',
  'begin_synchronization',
  'set @EmployeeID = ?' );
Java example

The following stored procedure call registers a Java method called beginSynchronizationConnection as the script for the begin_synchronization connection event when synchronizing the script version ver1.

call ml_add_java_connection_script( 'ver1',
  'begin_synchronization',
  'ExamplePackage.ExampleClass.beginSynchronizationConnection'
 )

Following is the sample Java method beginSynchronizationConnection. It saves the name of the synchronizing user for later use.

public String beginSynchronizationConnection(
  String user )
{  _curUser = user;
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called BeginSync as the script for the begin_synchronization connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script( 'ver1',
  'begin_synchronization',
  'TestScripts.Test.BeginSync'
)

Following is the sample Java method BeginSync. It saves the name of the synchronizing user for later use.

public void BeginSync( string user )
{  _curUser = user;
   return( null ); }


begin_synchronization table event

Function

Processes statements related to a specific table at the time an application connects to the MobiLink synchronization server in preparation for the synchronization process.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR (128)
2 | table | VARCHAR (128)
Default action

None.

Description

The MobiLink synchronization server executes this event after an application that is preparing to synchronize has formed a connection with the MobiLink synchronization server, and after the begin_synchronization connection-level event.

You can have one begin_synchronization script for each table in the remote database. The event is only invoked when the table is synchronized.

See also
  • end_synchronization table event
  • begin_synchronization connection event
SQL example

The begin_synchronization table event is used to set up the synchronization of a particular table. The following Adaptive Server Anywhere SQL procedure call registers a script that creates a temporary table for storing rows during synchronization.

call ml_add_table_script(
 'ver1',
 'sales_order',
 'begin_synchronization',
 'CREATE TABLE #sales_order
(
   id         integer NOT NULL default autoincrement,
   cust_id      integer NOT NULL,
   order_date      date NOT NULL,
   fin_code_id   char(2) NULL,
   region      char(7) NULL,
   sales_rep      integer NOT NULL,
   PRIMARY KEY (id),
)' )
Java example

The following stored procedure call registers a Java method called beginSynchronizationTable as the script for the begin_synchronization table event when synchronizing the script version ver1.

call ml_add_java_table_script(
 'ver1',
 'table1',
 'begin_synchronization',
 'ExamplePackage.ExampleClass.beginSynchronizationTable' )

Following is the sample Java method beginSynchronizationTable. It adds the current table name to a list of table names contained in this instance.

public String beginSynchronizationTable(String user,
String table )
{  _tableList.add( table );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called BeginTableSync as the script for the begin_synchronization table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
 'ver1', 'table1',
  'begin_synchronization',
  'TestScripts.Test.BeginTableSync'
             )

Following is the sample NET method BeginTableSync. It adds the current table name to a list of table names contained in this instance.

public void BeginTableSync( string user, string table )
{  _tableList.Add( table );
   return( null ); }


begin_upload connection event

Function

Processes any statements just before the MobiLink synchronization server commences processing the stream of uploaded inserts, updates, and deletes.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Item | Parameter | Description
1 | ml_username | VARCHAR (128)
Default action

None.

Description

The MobiLink synchronization server executes this event as the first step in the processing of uploaded information. Upload information is processed in a single transaction. The execution of this event is the first action in this transaction.

See also
  • end_upload connection event
  • begin_upload table event
SQL example

The begin_upload connection event is used to perform whatever steps you need performed prior to uploading rows. The following Adaptive Server Anywhere SQL script creates a temporary table for storing old and new row values for conflict processing of the sales_order table.

call ml_add_connection_script(
 'version1',
 'begin_upload',
 'CREATE TABLE #sales_order_conflicts
(
   id         integer NOT NULL default autoincrement,
   cust_id      integer NOT NULL,
   order_date      date NOT NULL,
   fin_code_id   char(2) NULL,
   region      char(7) NULL,
   sales_rep      integer NOT NULL,
   new_value      char(1) NOT NULL,
   PRIMARY KEY (id),
)' )
Java example

The following stored procedure call registers a Java method called beginUploadConnection as the script for the begin_upload connection event when synchronizing the script version ver1.

call ml_add_java_connection_script( 'ver1', 'begin_upload',
'ExamplePackage.ExampleClass.beginUploadConnection ' )

Following is the sample Java method beginUploadConnection. It prints a message to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public String beginUploadConnection( String user )
{  java.lang.System.out.println(
     "Starting upload for user: " + user );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called BeginUpload as the script for the begin_upload connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script(
  'ver1',
  'begin_upload',
  'TestScripts.Test.BeginUpload'
)

Following is the C# signature for the call BeginUpload.

public void BeginUpload( string user )

The following C# example saves the current user name for use in a later event.

public void BeginUpload( string curUser )
{
    user = curUser;
}


begin_upload table event

Function

Processes statements related to a specific table just before the MobiLink synchronization server commences processing the stream of uploaded inserts, updates, and deletes.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | table | VARCHAR(128)
Default action

None.

Description

The MobiLink synchronization server executes this event as the first step in the processing of uploaded information. Upload information is processed in a separate transaction. The execution of this event is the first table-specific action in this transaction.

You can have one begin_upload script for each table in the remote database. The script is only invoked when the table is actually synchronized.

See also
  • end_upload table event
  • begin_upload connection event
SQL example

When uploading rows from a remote you may want to place the changes in an intermediate table and manually process changes yourself. You can populate a global temporary table in this event.

call ml_add_table_script(
  'version1',
  'Leads',
  'begin_upload',
  'insert into T_Leads SELECT *
FROM Leads WHERE Owner = @EmployeeID')
Java example

The following stored procedure call registers a Java method called beginUploadTable as the script for the begin_upload table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'begin_upload',
  'ExamplePackage.ExampleClass.beginUploadTable'
 )

Following is the sample Java method beginUploadTable. It prints a message to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public String beginUploadTable( String user,
String table )
{  java.lang.System.out.println("Beginning to process upload for: " + table);
return( null ); }
.NET example

The following stored procedure call registers a .NET method called BeginTableUpload as the script for the begin_upload table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1', 'table1', 'begin_upload',
  'TestScripts.Test.BeginTableUpload'
)

Following is the sample .NET method BeginTableUpload. It prints a message to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public void BeginTableUpload(
  string user,
  string table )
{  System.Console.WriteLine("Beginning to process upload for: " + table);
return( null ); }


begin_upload_deletes table event

Function

Processes statements related to a specific table just before uploading deleted rows from the specified table in the remote database.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | table | VARCHAR(128)
Default action

None.

Description

This event runs immediately before applying the changes that result from rows deleted in the client table named in the second parameter.

You can have one begin_upload_deletes script for each table in the remote database. The script is only invoked when the table is actually synchronized.

See also
  • end_upload_deletes table event
SQL example

The begin_upload_deletes connection event is used to perform whatever steps you need performed after uploading inserts and updates for a particular table, but before deletes are uploaded for that table. The following Adaptive Server Anywhere SQL script creates a temporary table for storing deletes temporarily during upload:

call ml_add_table_script(
 'ver1',
 'sales_order',
 'begin_upload_deletes',
 'CREATE TABLE #sales_order_deletes
(
   id         integer NOT NULL default autoincrement,
   cust_id      integer NOT NULL,
   order_date      date NOT NULL,
   fin_code_id   char(2) NULL,
   region      char(7) NULL,
   sales_rep      integer NOT NULL,
   PRIMARY KEY (id),
)' )
Java example

The following stored procedure call registers a Java method called beginUploadDeletes as the script for the begin_upload_deletes table event when synchronizing the script version ver1.

call ml_add_java_table_script( 'ver1', 'table1',
'begin_upload_deletes',
'ExamplePackage.ExampleClass. beginUploadDeletes' )

Following is the sample Java method beginUploadDeletes. It prints a message to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public String beginUploadDeletes(
   String user,
   String table )
 throws java.sql.SQLException
{  java.lang.System.out.println( "Starting upload
   deletes for table: " + table );
    return( null ); }
.NET example

The following stored procedure call registers a .NET method called BeginUploadDeletes as the script for the begin_upload_deletes table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script( 'ver1', 'table1',
  'begin_upload_deletes',
  'TestScripts.Test.BeginUploadDeletes'
)

Following is the sample .NET method BeginUploadDeletes. It prints a message to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public void BeginUploadDeletes( string user,
  string table )
{  System.Console.WriteLine( "Starting upload
   deletes for table: " + table );
    return( null ); }


begin_upload_rows table event

Function

Processes statements related to a specific table just before uploading inserts and updates from the specified table in the remote database.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | table | VARCHAR(128)
Default action

None.

Description

This event is run immediately prior to applying the changes that result from inserts and deletes to the client table named in the second parameter.

You can have one begin_upload_rows script for each table in the remote database. The script is only invoked when the table is actually synchronized.

See also
  • end_upload_rows table event
SQL example

The begin_upload_rows connection event is used to perform whatever steps you need performed before uploading inserts and updates for a particular table. The following script calls a stored procedure that prepares the consolidated database for inserts and updates into the Inventory table:

call ml_add_table_script(
 'MyCorp 1.0',
 'Inventory',
 'begin_upload_rows',
 'call PrepareForUpserts()' )
Java example

The following stored procedure call registers a Java method called beginUploadRows as the script for the begin_upload_rows table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'begin_upload_rows',
  'ExamplePackage.ExampleClass.beginUploadRows' )

Following is the sample Java method beginUploadRows. It prints a message to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public String beginUploadRows( String user,
String table )
  throws java.sql.SQLException
{  java.lang.System.out.println( "Starting upload rows
   for table: " + table + " and user: " + user );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called BeginUploadRows as the script for the begin_upload_rows table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1', 'table1', 'begin_upload_rows',
  'TestScripts.Test.BeginUploadRows'
)

Following is the sample .NET method BeginUploadRows. It prints a message to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public void BeginUploadRows(
  string user,
  string table )
{  System.Console.WriteLine( "Starting upload rows
   for table: " + table + " and user: " + user );
   return( null ); }


download_cursor table event

Function

Defines a cursor to select rows that are to be downloaded and inserted or updated in the remote database.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | last_download | TIMESTAMP
2 | ml_username | VARCHAR(128)
Default action

None.

A default download_cursor SQL script can be generated using the MobiLink synchronization server -za option. Also, the UltraLite analyzer generates a SELECT statement based on your reference database that you can use to get started.

Description

The MobiLink synchronization server opens a read-only cursor with which to fetch a list of rows to download to the remote database. This script should contain a suitable SELECT statement.

The parameters are the last_download timestamp and the user name. You can use these values if you choose by placing question marks in your SQL statement.

You can have one download_cursor script for each table in the remote database.

The last_download timestamp is the value obtained from the consolidated database during the last successful synchronization immediately prior to the download phase. If the current user has never synchronized successfully, this value is set to 1900-01-01.

To optimize performance of the download stage of synchronization to UltraLite clients, when the range of primary key values is outside the current rows on the device, you should order the rows in the download cursor by primary key. Downloads of large reference tables, for example, can benefit from this optimization.

Each download_cursor script must contain a SELECT statement or a call to a procedure that contains a SELECT statement. The MobiLink synchronization server uses this statement to define a cursor in the consolidated database.

The script must select all columns that correspond to the columns in the corresponding table in the remote database. The columns in the consolidated database can have different names than the corresponding columns in the remote database, but they must be of compatible types.

The columns must be selected in the order that the corresponding columns are defined in the remote database. This order is identical to the order of the columns in the reference database.

Note that download_cursor allows for cascading deletes. Thus, you can delete records from a database.

For Java and .NET applications, this script must return valid SQL.

See also
  • Writing scripts to download rows
  • Writing download_cursor scripts
  • Partitioning rows among remote databases
  • download_delete_cursor table event
SQL example

The following example comes from an Oracle installation, although the statement is valid against all supported databases. The example downloads all rows that have been changed since the last time the user downloaded data, and which match the user name in the emp_name column.

call ml_add_table_script(
  'Lab',
  'ULOrder',
  'download_cursor',
  'SELECT order_id, cust_id, prod_id, emp_id,
      disc, quant, notes, status
       FROM ULOrder
       WHERE last_modified >= ? AND emp_name = ?' )

To write a download_cursor SQL script that does not use the first parameter (the last_download timestamp), but does use the second parameter (the MobiLink user name), add a dummy clause that affects no rows. For example:

call ml_add_table_script(
   'Lab',
   'ULOrder',
   'download_cursor',
   'SELECT order_id, cust_id, prod_id, emp_id, disc,
       quant, notes, status
        FROM ULOrder WHERE ? IS NOT NULL AND emp_name = ?' )

You must still use both parameters, but the first ? is a place holder that does nothing.

Java example

The following stored procedure call registers a Java method called downloadCursor as the script for the download_cursor table event when synchronizing the script version ver1.

call ml_add_java_table_script(
   'ver1',
   'ULCustomer',
   'download_cursor',
   'ExamplePackage.ExampleClass.downloadCursor ' )

Following is the sample Java method downloadCursor. It returns an SQL statement to download rows where the last_modified column is greater than or equal to the last download time.

public String downloadCursor(java.sql.Timestamp ts,String user )
 {
  return("SELECT cust_id, cust_name FROM ULCustomer where last_modified >= ' " + ts + " ' ");
 }
.NET example

The following stored procedure call registers a .NET method called DownloadCursor as the script for the download_cursor table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1', 'table1', 'download_cursor',
  'TestScripts.Test.DownloadCursor'
)

Following is the sample .NET method DownloadCursor. It populates a temporary table with the contents of a file called rows.txt. It then returns a cursor that causes MobiLink to send the rows in the temporary table to the remote database. This syntax is for Adaptive Server Anywhere consolidated databases.

public string DownloadCursor(
   DateTime ts,
   string user )
{
  DBCommand   stmt   = curConn.CreateCommand();
  StreamReader  input  = new StreamReader( "rows.txt" );
  string        sql    = input.ReadLine();

  stmt.CommandText = "DELETE FROM dnet_dl_temp";
  stmt.ExecuteNonQuery();

  while( sql != null ){
   stmt.CommandText = "INSERT INTO dnet_dl_temp VALUES " + sql;
   stmt.ExecuteNonQuery();
   sql = input.ReadLine();
  }
  return( "SELECT * FROM dnet_dl_temp" );
}


download_delete_cursor table event

Function

Defines a cursor to select rows that are to be deleted in the remote database.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | last_download | TIMESTAMP
2 | ml_username | VARCHAR(128)
Default action

None.

Description

The MobiLink synchronization server opens a read-only cursor with which to fetch a list of rows to download, and then insert or update in the remote database. This script must contain a SELECT statement that returns the primary key values of the rows to be deleted from the table in the remote database.

The parameters are the last_download timestamp and the user name. You can use these values by placing a question mark in your SQL statement.

You can have one download_delete_cursor script for each table in the remote database.

If the download_delete_cursor has NULLs for the primary key columns for one or more rows in a table, then MobiLink tells the remote to delete all the data in the table. For a complete description of this behavior, see Deleting all the rows in a table.

The last_download timestamp is the value obtained from the consolidated database during the last successful synchronization immediately prior to the download phase. If the current user has never synchronized successfully, this value is set to 1900-01-01.

Note that rows deleted from the consolidated database will not appear in a result set defined by a download_delete_cursor event, and so are not automatically deleted from the remote database. One technique for identifying rows to be deleted from remote databases is to add a column to the consolidated database table identifying a row as inactive.

For Java and .NET applications, this script must return valid SQL.

See also
  • download_cursor table event
  • Writing scripts to download rows
  • Partitioning rows among remote databases
  • Writing download_delete_cursor scripts
SQL example

This example is taken from the Contact sample and can be found in Samples\MobiLink\Contact\build_consol.sql. It deletes from the remote database any customers who have been changed since the last time this user downloaded data (Customer.last_modified >= ?), and either

  • do not belong to the synchronizing user (SalesRep.ml_username != ?), or

  • are marked as inactive in the consolidated database (Customer.active = 0).

    call ml_add_table_script(
   'ver1',
   'table1',
   'download_delete_cursor',
'SELECT cust_id FROM Customer key join SalesRep
WHERE Customer.last_modified >= ? AND
( SalesRep.ml_username != ? OR Customer.active = 0 )')
Java example

The following stored procedure call registers a Java method called downloadDeleteCursor as the script for the download_delete_cursor event when synchronizing the script version ver1.

call ml_add_java_table_script(
   'ver1',
   'table1',
   'download_delete_cursor',
   'ExamplePackage.ExampleClass.downloadDeleteCursor' )

Following is the sample Java method downloadDeleteCursor. It calls a Java method that generates the SQL for the download delete cursor.

public String downloadDeleteCursor( Timestamp ts,
String user )
{  return( getDownloadCursor( _curUser, _curTable ) ); }
.NET example

The following stored procedure call registers a .NET method called DownloadDeleteCursor as the script for the download_delete_cursor table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1',
  'table1',
  'download_delete_cursor',
  'TestScripts.Test.DownloadDeleteCursor'
)

Following is the sample .NET method DownloadDeleteCursor. It calls a .NET method that generates the SQL for the download delete cursor.

public string DownloadDeleteCursor(
  DateTime timestamp,
  string user )
{  return( getDownloadCursor( _curUser, _curTable ) ); }


download_statistics connection event

Function

Tracks synchronization statistics for download operations.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128). The MobiLink user name as specified in your SYNCHRONIZATION USER definition.
2 | warnings | INTEGER. The number of warnings issued.
3 | errors | INTEGER. The number of errors, including handled errors, that occurred.
4 | fetched_rows | INTEGER. The number of rows fetched by the download_cursor script.
5 | deleted_rows | INTEGER. The number of rows fetched by the download_deletes script.
6 | filtered_rows | INTEGER. The number of rows from (5) actually sent to the remote. This reflects download filtering of uploaded values.
7 | bytes | INTEGER. The number of bytes sent to the remote as the download.
Default action

None.

Description

The download_statistics event allows you to gather, for any user, statistics on downloads. The download_statistics connection script is called just prior to the commit at the end of the download transaction.

Note:
Depending on the command line, not all warnings or errors are logged, so the warnings and errors counts may be more than the number of warnings or errors logged.
See also
  • download_statistics table event
  • upload_statistics connection event
  • upload_statistics table event
  • synchronization_statistics connection event
  • synchronization_statistics table event
  • time_statistics connection event
  • time_statistics table event
  • MobiLink Monitor
SQL example

The following example inserts synchronization statistics into a table called download_audit.

call ml_add_connection_script(
  'ver1', 'download_statistics',
'INSERT INTO download_audit(
  user_name, warnings, errors, deleted_rows,
  fetched_rows, download_rows, bytes )
VALUES (?,?,?,?,?,?,?)')

Once vital statistics are inserted into the audit table, you may use these statistics to monitor your synchronizations and make optimizations where applicable.

Java example

The following stored procedure call registers a Java method called downloadStatisticsConnection as the script for the download_statistics event when synchronizing the script version ver1.

call ml_add_java_connection_script(
  'ver1',
  'download_statistics',
  'ExamplePackage.ExampleClass.downloadStatisticsConnection' )

Following is the sample Java method downloadStatisticsConnection. It prints the number of fetched rows to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public String downloadStatisticsConnection(
  String user,
  int warnings,
  int errors,
  int fetchedRows,
  int deletedRows,
  int bytes )
{  java.lang.System.out.println( "download connection
   stats fetchedRows: " + fetchedRows );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called DownloadStats as the script for the download_statistics connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script(
  'ver1',
  'download_statistics',
  'TestScripts.Test.DownloadStats'
)

Following is the sample .NET method DownloadStats. It prints the number of fetched rows to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public void DownloadStats(
  string user,
  int warnings,
  int errors,
  int deletedRows,
  int fetchedRows,
  int downloadRows,
  int bytes )
{  System.Console.WriteLine( "download connection
   stats fetchedRows: " + fetchedRows );
   return( null ); }


download_statistics table event

Function

Tracks synchronization statistics for download operations by table.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128). This is the MobiLink user name as specified in your SYNCHRONIZATION USER definition.
2 | table | VARCHAR(128). The table name.
3 | warnings | INTEGER. The number of warnings issued.
4 | errors | INTEGER. The number of errors, including handled errors, that occurred.
5 | fetched_rows | INTEGER. The number of rows fetched by the download_cursor script.
6 | deleted_rows | INTEGER. The number of rows fetched by the download_deletes script.
7 | filtered_rows | INTEGER. The number of rows from (6) actually sent to the remote. This reflects download filtering of uploaded values.
8 | bytes | INTEGER. The number of bytes sent to the remote as the download.
Default action

None.

Description

The download_statistics event allows you to gather, for any user and table, statistics on downloads as they apply to that table. The download_statistics table script is called just prior to the commit at the end of the download transaction.

See also
  • download_statistics connection event
  • upload_statistics connection event
  • upload_statistics table event
  • synchronization_statistics connection event
  • synchronization_statistics table event
  • time_statistics connection event
  • time_statistics table event
  • MobiLink Monitor
SQL example

The following example inserts synchronization statistics into a table called download_audit. Once vital statistics are inserted into the audit table, you may use these statistics to monitor your synchronizations and make optimizations where applicable.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'download_statistics',
'INSERT INTO download_audit (
  user_name, table, warnings, errors,
  deleted_rows, fetched_rows, download_rows, bytes)
VALUES (?,?,?,?,?,?,?,?)')
Java example

The following stored procedure call registers a Java method called downloadStatisticsTable as the script for the download_statistics table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'download_statistics',
  'ExamplePackage.ExampleClass.downloadStatisticsTable' )

Following is the sample Java method downloadStatisticsTable. It prints some statistics for this table to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public String downloadStatisticsTable(
  String user,
  String table,
  int warnings,
  int errors,
  int fetchedRows,
  int deletedRows,
  int bytes )
{  java.lang.System.out.println( "download table stats "
   + "table: " + table + "bytes: " + bytes );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called DownloadTableStats as the script for the download_statistics table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1',
  'table1',
  'download_statistics',
  'TestScripts.Test.DownloadTableStats'
)

Following is the sample .NET method DownloadTableStats. It prints some statistics for this table to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public void DownloadTableStats(
  string user,
  string table,
  int warnings,
  int errors,
  int deletedRows,
  int fetchedRows,
  int downloadRows,
  int bytes )
{  System.Console.WriteLine( "download table stats "
   + "table: " + table + "bytes: " + bytes );
   return( null ); }


end_connection connection event

Function

Processes any statements just before the MobiLink synchronization server closes a connection with the consolidated database server, either in preparation to shut down or when a connection is removed from the connection pool.

This script is normally used to complete any actions started by the begin_connection script and free any resources acquired by it.

Parameters

None.

Default action

None.

Description

You can use the end_connection script to perform an action of your choice just prior to closing of a connection between the MobiLink synchronization server and the consolidated database server.

See also
  • begin_connection connection event
SQL example

The following Adaptive Server Anywhere SQL script drops a temporary table that was created by the begin_connection script. Strictly speaking, this table doesn't need to be dropped explicitly, since ASA will do this automatically when the connection is destroyed. Whether or not a temporary table needs to be dropped explicitly depends on your consolidated database type.

call ml_add_connection_script(
 'version 1.0',
 'end_connection',
 'drop table #sync_info' )
Java example

The following stored procedure call registers a Java method called endConnection as the script for the end_connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
   'ver1',
   'end_connection',
   'ExamplePackage.ExampleClass.endConnection' )

Following is the sample Java method endConnection. It prints a message to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public String endConnection()
{  java.lang.System.out.println( "ending connection" );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called EndConnection as the script for the end_connection connection event when synchronizing the script version ver1. This syntax is for Adaptive Server Anywhere consolidated databases.

call ml_add_dnet_connection_script(
  'ver1',
  'end_connection',
  'TestScripts.Test.EndConnection'
)

Following is the sample .NET method EndConnection. It prints a message to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public void EndConnection()
{  System.Console.WriteLine( "ending connection" );
   return( null ); }


end_download connection event

Function

Processes any statements just after the MobiLink synchronization server concludes preparation of the download data.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | last_download | TIMESTAMP
2 | ml_username | VARCHAR(128)
Default action

None.

Description

The MobiLink synchronization server executes this script after all rows have been downloaded and, if expecting a download acknowledgement, confirmation of receipt has been received. Download information is processed in a single transaction. The execution of this script is the last non statistical action in this transaction.

The last_download timestamp is the value obtained from the consolidated database during the last successful synchronization immediately prior to the download phase. If the current user has never synchronized successfully, this value is set to 1900-01-01.

See also
  • begin_download connection event
SQL example

The following example shows one possible use of an end_download connection script. Each row in the ULEmpCust table has an action column. The following script uses the value in this column to delete records from the remote database.

all ml_add_java_connection_script(
  'ver1',
  'end_download',
'DELETE FROM ULEmpCust ec
  WHERE ? IS NOT NULL
    AND ec.emp_id = ? AND action = ''D''')
Java example

The following stored procedure call registers a Java method called endDownloadConnection as the script for the end_download connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
  'ver1',
  'end_download',
  'ExamplePackage.ExampleClass.endDownloadConnection' )

Following is the sample Java method endDownloadConnection. Each row in the ULEmpCust table has an action column. The following script uses the value in this column to delete records from the remote database. It also uses the current MobiLink connection (saved earlier) to perform an update before the download ends. This syntax is for Adaptive Server Anywhere consolidated databases.

public String endDownloadConnection(
    Timestamp ts,
    String user )
  throws java.sql.SQLException
{  String del_sql =    "DELETE FROM ULEmpCust ec " +
   "WHERE ec.emp_id = '" + user + "' " +
   "AND action = 'D' ";
   execUpdate( _syncConn, del_sql );
   return( null );
}
.NET example

The following stored procedure call registers a .NET method called EndDownload as the script for the end_download connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script(
  'ver1',
  'end_download',
  'TestScripts.Test.EndDownload' )

Following is the sample .NET method EndDownload. Each row in the ULEmpCust table has an action column. The following script uses uses the value in this column to delete records from the remote database. It also uses the current MobiLink connection (saved earlier) to perform an update before the download ends. This syntax is for Adaptive Server Anywhere consolidated databases.

public void EndDownload(
  DateTime timestamp,
  string user )
{  string del_sql =    "DELETE FROM ULEmpCust ec " +
   "WHERE ec.emp_id = '" + user + "' " +
   "AND action = 'D' ";
   execUpdate( _syncConn, del_sql );
   return( null );
}


end_download table event

Function

Processes statements related to a specific table just after the MobiLink synchronization server concludes preparing the stream of downloaded inserts, updates, and deletes.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | last_download | TIMESTAMP
2 | ml_username | VARCHAR(128)
3 | table | VARCHAR(128)
Default action

None.

Description

The MobiLink synchronization server executes this script after all rows have been downloaded and confirmation of receipt has been received. The download information is prepared in a separate transaction. The execution of this script is the last table-specific, non-statistical action in this transaction.

You can have one end_download script for each table in the remote database.

The last_download timestamp is the value obtained from the consolidated database during the last successful synchronization immediately prior to the download phase. If the current user has never synchronized successfully, this value is set to 1900-01-01.

See also
  • begin_download table event
  • end_download connection event
SQL example

The end_download table event is used to perform whatever steps you need performed after downloading a particular table. The following Adaptive Server Anywhere SQL script drops a temporary table created by a prepare_for_download script to hold download rows for the sales_summary table.

call ml_add_table_script(
 'MyCorp 1.0',
 'sales_summary',
 'end_download',
 'drop table #sales_summary_download' )
Java example

The following stored procedure call registers a Java method called endDownloadTable as the script for the end_download table event when synchronizing the script version ver1..

call ml_add_java_table_script (
  'ver1',
  'table1',
  'end_download',
  'ExamplePackage.ExampleClass.endDownloadTable' )

Following is the sample Java method endDownloadTable. It resets the current table member variable.

public String endDownloadTable( Timestamp ts,
String user, String table )
{  _curTable = null;
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called EndTableDownload as the script for the end_download table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1',
  'table1',
  'end_download',
  'TestScripts.Test.EndTableDownload'
)

Following is the sample .NET method EndTableDownload. It resets the current table member variable.

public void EndTableDownload
  DateTime timestamp,
  string user,
  string table )
{  _curTable = null;
   return( null ); }


end_download_deletes table event

Function

Processes statements related to a specific table just after preparing a list of rows to be deleted from the specified table in the remote database.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | last_download | TIMESTAMP
2 | ml_username | VARCHAR(128)
3 | table | VARCHAR(128)
Default action

None.

Description

This script is executed immediately after preparing a list of rows to be deleted from the named table in the remote database.

You can have one end_download_deletes script for each table in the remote database.

The last_download timestamp is the value obtained from the consolidated database during the last successful synchronization immediately prior to the download phase. If the current user has never synchronized successfully, this value is set to 1900-01-01.

See also
  • begin_download_deletes table event
  • end_download connection event
  • begin_download_rows table event
  • end_download_rows table event
  • download_delete_cursor table event
SQL example

You may want to mark a row as deleted on the remote database. The following script updates a column in the consolidated database called OnRemote. Note: The WHERE clause on the UPDATE matches the WHERE clause used for your download_delete_cursor event script.

Call ml_add_table_script(
  'version1',
  'Leads',
  'end_download_deletes',
  'UPDATE Leads SET OnRemote = 0
      WHERE LastModified >= ?
        AND Owner = ? AND DeleteFlag=1');
Java example

The following stored procedure call registers a Java method called endDownloadDeletes as the script for the end_download_deletes table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'end_download_deletes',
  'ExamplePackage.ExampleClass.endDownloadDeletes' )

You may want to mark a row as deleted on the remote database. Following is the sample Java method endDownloadDeletes. It updates a column in the consolidated database called OnRemote to indicate the record no longer resides on the remote database. Note: The WHERE clause on the UPDATE matches the WHERE clause used for your download_delete_cursor event script.

public String endDownloadDeletes(
  Timestamp ts,
  String user,
  String table )
{ return( "UPDATE Leads SET OnRemote = 0
     WHERE LastModified >= ?
     AND Owner = ? AND DeleteFlag=1" ); }
.NET example

The following stored procedure call registers a .NET method called EndDownloadDeletes as the script for the end_download_deletes table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1',
  'table1',
  'end_download_deletes',
  'TestScripts.Test.EndDownloadDeletes'
)

You may want to mark a row as deleted on the remote database. Following is the sample .NET method EndDownloadDeletes. It updates a consolidated database column called OnRemote to indicate that the record no longer resides on the remote database. The WHERE clause on the UPDATE matches the WHERE clause used for your download_delete_cursor event script.

public void EndDownloadDeletes(
  DateTime timestamp, string user, string table)
{ return( "UPDATE Leads SET OnRemote = 0
     WHERE LastModified >= ?
     AND Owner = ? AND DeleteFlag=1" ); }


end_download_rows table event

Function

Processes statements related to a specific table just after preparing a list of rows to be inserted or updated in the specified table in the remote database.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | last_download | TIMESTAMP
2 | ml_username | VARCHAR(128)
3 | table | VARCHAR(128)
Default action

None.

Description

This script is executed immediately after preparing the stream of rows to be inserted or updated in the named table in the remote database.

You can have one end_download_rows script for each table in the remote database.

The last_download timestamp is the value obtained from the consolidated database during the last successful synchronization immediately prior to the download phase. If the current user has never synchronized successfully, this value is set to 1900-01-01.

See also
  • begin_download_rows table event
  • end_download connection event
  • end_download_deletes table event
  • begin_download_deletes table event
SQL example

You may want to mark a row as successfully downloaded to the remote database. The following script updates a column in the consolidated database called OnRemote. Note: The WHERE clause on the UPDATE matches the WHERE clause used for your download_delete_cursor event script.

call ml_add_table_script(
   'version1',
   'Leads',
   'end_download_rows',
   'UPDATE Leads SET OnRemote = 1 WHERE LastModified >= ?
      AND Owner = ? AND DownloadFlag=1');
Java example

The following stored procedure call registers a Java method called endDownloadRows as the script for the end_download_rows table event when synchronizing the script version ver1.

call ml_add_java_table_script(
   'ver1',
   'table1',
   'end_download_rows',
   'ExamplePackage.ExampleClass.endDownloadRows' )

Following is the sample Java method endDownloadRows. It prints a message to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public String endDownloadRows(
  Timestamp ts,
  String user,
  String table )
{  java.lang.System.out.println( "Done downloading
   inserts and updates for table " + table );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called EndDownloadRows as the script for the end_download_rows table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
 'ver1', 'table1', 'end_download_rows',
  'TestScripts.Test.EndDownloadRows'
)

Following is the sample Java method endDownloadRows. It prints a message to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public void EndDownloadRows(
  DateTime timestamp,
  string user,
  string table )
{  System.Console.WriteLine( "Done downloading
   inserts and updates for table " + table );
   return( null ); }


end_publication connection event

Function

Provides useful information about the publication(s) being synchronized.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Item | Parameter | Description
1 | generation_number | INTEGER. If your deployment does not use file-based downloads, this parameter can be ignored. The default is 1.
2 | ml_username | VARCHAR(128). If an UltraLite remote is synchronizing with UL_SYNC_ALL, this event is invoked once with the name 'unknown'.
3 | publication_name | VARCHAR(128)
4 | last_upload | TIMESTAMP. Last successful upload.
5 | last_download | TIMESTAMP. Last successful download.
Default action

None.

Description

This event lets you design synchronization logic based on the publications currently being synchronized. This event is invoked in the same transaction as the end_synchronization event, and is invoked before the end_synchronization event. It is invoked once per publication being synchronized.

If the current synchronization successfully applied an upload, the last_upload parameter will contain the time this latest upload was applied. If the current synchronization has a successful download acknowledgement, the last_download time will contain the time this latest download was generated. This is the same value that was passed to the download scripts as the last download timestamp.

Generation number

The generation_number parameter is specifically for file-based downloads.

The output value of the generation number is passed from the begin_publication script to the end_publication script. The meaning of the generation_number depends on whether the current synchronization is being used to create a download file, or whether the current synchronization has an upload.

In file-based downloads, generation numbers are used to force an upload before the download. The number is stored in the download file.

See also
  • begin_publication connection event
  • File-Based Downloads
SQL example

You may want to record the information for each publication being synchronized. The following example calls ml_add_connection_script to assign the event to a stored procedure called RecordPubEndSync.

call ml_add_connection_script(
   'version1',
   'end_publication',
   'call RecordPubEndSync( ?, ?, ?, ?, ? )' );
Java example

The following stored procedure call registers a Java method called endPublication as the script for the begin_publication connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
   'ver1',
   'end_publication',
   'ExamplePackage.ExampleClass.endPublication' )

Following is the sample Java method endPublication. It outputs a message to the MobiLink log. (This might be useful at development time but would slow down a production server.)

public String endPublication(
    ianywhere.ml.script.InOutInteger generation_number,
    String user,
    String pub_name,
    Timestamp last_upload,
    Timestamp last_download )
{  System.out.println(
     "Finished synchronizing publication " + pub_name );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called EndPub as the script for the end_publication connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script( 'ver1',
  'end_publication',
  'TestScripts.Test.EndPub'
)

Following is the sample Java method endPublication. It outputs a message to the MobiLink log. (This might be useful at development time but would slow down a production server.)

public void EndPub(
    ref int generation_number,
    string user,
    string pub_name,
    DateTime last_upload,
    DateTime last_download )
{
    Console.Write(
      "Finished synchronizing publication " + pub_name );
}


end_synchronization connection event

Function

Processes any statements at the time an application disconnects from the MobiLink synchronization server upon completion of the synchronization process.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | sync_ok | INTEGER. This value is 1 for a successful synchronization and 0 for an unsuccessful synchronization.
Default action

None.

Description

The MobiLink synchronization server executes this script after synchronization is complete and, if expecting a download acknowledgement, the MobiLink client has returned confirmation of receipt of the download stream.

This script is executed within a separate transaction after the download transaction. It is useful for maintaining statistics.

See also
  • begin_synchronization connection event
  • begin_synchronization table event
  • end_synchronization table event
SQL example

The following Adaptive Server Anywhere SQL script calls a stored procedure that records the end time of the synchronization attempt along with its success or failure status.

call ml_add_connection_script(
 'ver1',
 'end_synchronization',
 'call RecordEndOfSyncAttempt(?,?)' )
Java example

The following stored procedure call registers a Java method called endSynchronizationConnection as the script for the end_synchronization event when synchronizing the script version ver1.

call ml_add_java_connection_script(
  'ver1',
  'end_synchronization',
  'ExamplePackage.ExampleClass.endSynchronizationConnection'
)

Following is the sample Java method endSynchronizationConnection. It uses a JDBC connection to execute an update. This syntax is for Adaptive Server Anywhere consolidated databases.

public String endSynchronizationConnection(
 String user )
  throws java.sql.SQLException
{  execUpdate( _syncConn, "UPDATE sync_count set cnt =
   count + 1 where user_id = '" + user + "' " );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called EndSync as the script for the end_synchronization connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script(
  'ver1',
  'end_synchronization',
  'TestScripts.Test.EndSync'
)

Following is the sample .NET method EndSync. It updates the table sync_count. This syntax is for Adaptive Server Anywhere consolidated databases.

public void EndSync( string user )
{
  return("UPDATE sync_count set cnt =
   count + 1 where user_id = '" + user + "' ");
}


end_synchronization table event

Function

Processes statements related to a specific table at the time an application disconnects from the MobiLink synchronization server upon completion of the synchronization process.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | table | VARCHAR(128)
3 | sync_ok | INTEGER. This value is 1 for a successful synchronization and 0 for an unsuccessful synchronization.
Default action

None.

Description

The MobiLink synchronization server executes this script after an application has synchronized and is about to disconnect from the MobiLink synchronization server, and before the connection level script of the same name.

You can have one end_synchronization script for each table in the remote database.

See also
  • begin_synchronization table event
  • end_synchronization connection event
  • end_synchronization table event
SQL example

The following Adaptive Server Anywhere SQL script drops a temporary table created by the begin_synchronization script.

call ml_add_table_script(
 'ver1',
 'sales_order',
 'end_synchronization',
 'drop table #sales_order' )
Java example

The following stored procedure call registers a Java method called endSynchronizationTable as the script for the end_synchronization table event when synchronizing the script version ver1.

call ml_add_java_table_script(
   'ver1',
   'table1',
   'end_synchronization',
   'ExamplePackage.ExampleClass.endSynchronizationTable' )

Following is the sample Java method endSynchronizationTable. It returns SQL to drop a temporary table created by the begin_synchronization script.

public String endSynchronizationTable(  String user,
String table )
{  return( "drop table #sales_order" ); }
.NET example

The following stored procedure call registers a .NET method called EndTableSync as the script for the end_synchronization table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1', 'table1', 'end_synchronization',
  'TestScripts.Test.EndTableSync'
)

Following is the sample Java method EndTableSync. It returns SQL to drop a temporary table created by the begin_synchronization script.

public void EndTableSync( string user, string table )
{  return( "drop table #sales_order" ); }


end_upload connection event

Function

Processes any statements just after the MobiLink synchronization server concludes processing uploaded inserts, updates, and deletes.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
Default action

None.

Description

The MobiLink synchronization server executes this script as the last step in the processing of uploaded information. Upload information is processed in a single transaction. The execution of this script is the last action in this transaction before statistical scripts.

See also
  • begin_upload connection event
  • end_upload table event
Java example

The following stored procedure call registers a Java method called endUploadConnection as the script for the end_upload connection event when synchronizing the script version ver1. This syntax is for Adaptive Server Anywhere consolidated databases.

call ml_add_java_connection_script(
   'ver1',
   'end_upload',
   'ExamplePackage.ExampleClass.endUploadConnection' )

Following is the sample Java method endUploadConnection. It calls a method to perform operations on the database.

public String endUploadConnection( String user )
{  // clean up new and old tables
   Iterator    two_iter = _tables_with_ops.iterator();
   while( two_iter.hasNext() )
   {  TableInfo cur_table = (TableInfo)two_iter.next();
      dumpTableOps( _sync_conn, cur_table ); }
    _tables_with_ops.clear(); }
.NET example

The following stored procedure call registers a .NET method called EndUpload as the script for the end_upload connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script(
  'ver1',
  'end_upload',
  'TestScripts.Test.EndUpload'
)

Following is the C# signature for the call EndUpload.

public void EndUpload( string user )


end_upload table event

Function

Processes statements related to a specific table just after the MobiLink synchronization server concludes processing the stream of uploaded inserts, updates, and deletions.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | table | VARCHAR(128)
Default action

None.

Description

The MobiLink synchronization server executes this script as the last step in the processing of uploaded information. Upload information is processed in a separate transaction. The execution of this script is the last table-specific action in this transaction.

You can have one end_upload script for each table in the remote database.

See also
  • begin_upload table event
  • end_upload connection event
SQL example

The following statements define a stored procedure and an end_upload script. The first piece of code calls the ml_add_table_script, and the second creates the ULCustomerIDPool_maintain procedure.

 ml_add_table_script(
   'custdb',
   'ULCustomerIDPool',
   'end_upload',
ULCustomerIDPool_maintain( ? );)

CREATE OR REPLACE PROCEDURE ULCustomerIDPool_maintain(
  SyncUserID IN integer )
AS
  pool_count INTEGER;
  pool_max   INTEGER;
BEGIN
  -- Determine how many ids to add to the pool

SELECT COUNT(*)
    INTO pool_count
    FROM ULCustomerIDPool
    WHERE pool_emp_id = SyncUserID;
  -- Determine the current Customer id max

SELECT MAX(pool_cust_id)
    INTO pool_max
    FROM ULCustomerIDPool;
  -- Top up the pool with new ids

 WHILE pool_count < 20 LOOP
    pool_max := pool_max + 1;
      INSERT INTO ULCustomerIDPool(
          pool_cust_id, pool_emp_id )
            VALUES ( pool_max, SyncUserID );
      pool_count := pool_count + 1;
  END LOOP;
END;
Java example

The following stored procedure call registers a Java method called endUploadTable as the script for the end_upload table event when synchronizing the script version ver1.

call ml_add_java_table_script(
   'ver1',
   'table1'
   'end_upload',
   'ExamplePackage.ExampleClass.endUploadTable' )

Following is the sample Java method endUploadTable. It generates a delete for a table with a name related to the passing-in table name. This syntax is for Adaptive Server Anywhere consolidated databases.

public String endUploadTable(   String user,
String table)
{  return( "DELETE from '" + table + "_temp'" ); }
.NET example

The following stored procedure call registers a .NET method called EndTableUpload as the script for the end_upload table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
   'ver1',
   'table1',
   'end_upload',
   'TestScripts.Test.EndTableUpload'
)

Following is the C# signature for the call EndTableUpload.

public void EndTableUpload(
   string user, string table )

The following C# example moves rows inserted into a temporary table into the table passed into the script.

public void EndUpload( string user, string table )
{
  DBCommand stmt = curConn.CreateCommand();

  // move the uploaded rows to the destination table
  stmt.CommandText = "INSERT INTO "
    + table
    + " SELECT * FROM dnet_ul_temp";
  stmt.ExecuteNonQuery();
  stmt.Close();
}


end_upload_deletes table event

Function

Processes statements related to a specific table just after applying deletes uploaded from the specified table in the remote database.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | table | VARCHAR(128)
Default action

None.

Description

This script is run immediately after applying the changes that result from rows deleted in the remote table named in the second parameter.

You can have one end_upload_deletes script for each table in the remote database.

See also
  • begin_upload_deletes table event
SQL example

You can use this event to process rows deleted during the upload stream on an intermediate table. You can compare the rows in the base table with rows in the intermediate table and decide what to do with the deleted row.

Call ml_add_table_script(
  'version1',
  'Leads',
  'end_uploads_deletes',
  'call EndUploadDeletesLeads()');
Create procedure EndUploadDeletesLeads ( )
Begin
  FOR names AS curs CURSOR FOR
  SELECT LeadID
    FROM Leads
    WHERE LeadID NOT IN (SELECT LeadID FROM T_Leads);
  DO
   CALL decide_what_to_do( LeadID );
  END FOR;
end
Java example

The following stored procedure call registers a Java method called endUploadDeletes as the script for the end_upload_deletes table event when synchronizing the script version ver1.

call ml_add_java_table_script(
   'ver1',
   'table1',
   'end_upload_deletes',
   'ExamplePackage.ExampleClass.endUploadDeletes' )

Following is the sample Java method a endUploadDeletes. It calls a Java method that manipulates the database.

public String endUploadDeletes( String user,
String table )
  throws java.sql.SQLException
{  processUploadedDeletes( _syncConn, table );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called EndUploadDeletes as the script for the end_upload_deletes table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
   'ver1',
   'table1',
   'end_upload_deletes',
   'TestScripts.Test.EndUploadDeletes'
)

Following is the sample .NET method a EndUploadDeletes. It calls a .NET method that manipulates the database.

public void EndUploadDeletes( string user, string table )
{  processUploadedDeletes( _syncConn, table );
   return( null ); }


end_upload_rows table event

Function

Processes statements related to a specific table just after applying uploaded inserts and updates from the specified table in the remote database.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | table | VARCHAR(128)
Default action

None.

Description

Uploaded information can require inserting or updating rows in the consolidated database. This script is run immediately after applying the changes that result from modifications to the remote table named in the second parameter.

You can have one end_upload_rows script for each table in the remote database.

See also
  • begin_upload_rows table event
SQL example

You use this event to process rows deleted during the upload stream on an intermediate table. You can compare the rows in the base table with the rows in the intermediate table and decide what to do with the deleted row as the following example illustrates.

Call ml_add_table_script(
   'version1',
   'Leads',
   'end_uploads_deletes',
   'call EndUploadDeletesLeads()');
Create procedure EndUploadDeletesLeads ( )
Begin
  FOR names AS curs CURSOR FOR
  SELECT LeadID FROM Leads
    WHERE LeadID NOT IN (select LeadID from T_Leads);
  DO
   CALL decide_what_to_do( LeadID );
  END FOR;
end
Java example

The following stored procedure call registers a Java method called endUploadRows as the script for the end_upload_rows table event when synchronizing the script version ver1.

call ml_add_java_table_script(
   'ver1',
   'table1',
   'end_upload_rows',
   'ExamplePackage.ExampleClass.endUploadRows' )

Following is the sample Java method endUploadRows. It calls a Java method that manipulates the database.

public String endUploadRows(String user,
String table )
  throws java.sql.SQLException
{  processUploadedRows( _syncConn, table );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called EndUploadRows as the script for the end_upload_rows table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1',
  'table1',
  'end_upload_rows',
  'TestScripts.Test.EndUploadRows'
)

Following is the sample .NET method endUploadRows. It calls a .NET method that manipulates the database.

public void EndUploadRows(
  string user,
  string table )
{  processUploadedRows( _syncConn, table );
   return( null ); }


example_upload_cursor table event

Function

Provides an event that the MobiLink synchronization server does not use during processing of the upload stream to handle rows inserted into the remote database. The event is not called.

Parameters
Item | Parameter
1 | column 1
2 | column 2
... | ...
Description

The statement based example_upload_cursor script performs direct inserts of column values identical to those specified in the example_upload_cursor statement. The example_upload_cursor event is not called by MobiLink.

SQL example

The script is not called. If it were called, it would insert the values into a table named Customer in the consolidated database. The final column of the table identifies the Customer as active. The final column does not appear in the remote database.

SELECT cust_id, name, rep_id
FROM customer
WHERE cust_id=?


example_upload_delete table event

Function

Processes the upload stream to handle rows deleted from the remote database. The script is not called by MobiLink.

Parameters
Item | Parameter
1 | column 1
2 | column 2
... | ...
Description

The statement based example_upload_delete script handles rows that are deleted in the remote database. The action taken at the consolidated database can be a DELETE statement, but need not be.

See also
  • upload_delete table event
SQL example

This example marks customers who are deleted from the remote database as inactive.

UPDATE Customer
SET active = 0
WHERE cust_id=?


example_upload_insert table event

Function

Provides an event that the MobiLink synchronization server uses during processing of the upload stream to handle rows inserted into the remote database.

Parameters
Item | Parameter
1 | column 1
2 | column 2
... | ...
Description

The statement-based example_upload_insert script performs direct inserts of column values identical to those specified in the upload_insert statement.

The example_upload_insert event is not called.

See also
  • upload_insert table event
SQL example

The script is not called. If it were called, it would insert the values into a table named Customer in the consolidated database. The final column of the table identifies the Customer as active. The final column does not appear in the remote database.

INSERT INTO Customer( cust_id, name, rep_id )
VALUES ( ?, ?, ? )


example_upload_update table event

Function

An example event for the upload stream to handle rows updated at the remote database. The example script is not called by MobiLink but is identical in form to the upload_update event.

Parameters
Clause | Parameters
SET | column 1 column 2 ...
WHERE | primary key 1 primary key 2 ...
Description

You create an example_upload_update event script by using the option -za in the dbmlsync command line.

See also
  • upload_update table event
SQL example

This example handles updates made to the Customer table in the remote database. The script updates the values in a table named Customer in the consolidated database. Note: The script is never called and is only an example script.

UPDATE Customer
SET name=?, rep_id=?
WHERE cust_id=?


handle_error connection event

Function

Executed whenever the MobiLink synchronization server encounters a SQL error.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | action_code | INTEGER. This is an INOUT parameter.
2 | error_code | INTEGER
3 | error_message | TEXT
4 | ml_username | VARCHAR(128)
5 | table | VARCHAR(128). If the script is not a table script, the table name is NULL.
Default action

When no handle_error script is defined or this script causes an error, the default action code is 3000: rollback the current transaction and cancel the current synchronization.

Description

The MobiLink synchronization server sends in the current action_code. Initially, this is set to 3000 for each set of errors caused by a single SQL operation. Usually, there is only one error per SQL operation, but there may be more. This handle_error script is called once per error in the set. The action code passed into the first error is 3000. Subsequent calls are passed in the action code returned by the previous call. MobiLink will use the numerically highest value returned from multiple calls.

You can modify the action code in the script, and return a value instructing MobiLink how to proceed. The action code parameter takes one of the following values:

  • 1000 Skip the current row and continue processing.

  • 3000 Rollback the current transaction and cancel the current synchronization. This is the default action code, and is used when no handle_error script is defined or this script causes an error.

  • 4000 Rollback the current transaction, cancel the synchronization, and shut down the MobiLink synchronization server.

SQL scripts for the handle_error event must be implemented as stored procedures.

The MobiLink synchronization server executes this script whenever it encounters an error during the synchronization process. The error codes and message allow you to identify the nature of the error. If the error happened as part of synchronization, the user name is supplied. Otherwise, this value is NULL.

If the error happened while manipulating a particular table, the table name is supplied. Otherwise, this value is NULL. The table name is the name of a table in the client application. This name may or may not have a direct counterpart in the consolidated database, depending upon the design of the synchronization system.

The action code tells the MobiLink synchronization server what to do next. Before it calls this script, the MobiLink synchronization server sets the action code to a default value, which depends upon the severity of the error. Your script may modify this value. Your script must return or set an action code.

You can return a value from the handle_error script in two ways.

  • Pass the action parameter to an OUTPUT parameter of a procedure:

    CALL my_handle_error( ?, ?, ?, ?, ? )

  • Set the action code via a procedure or function return value:

    ? = CALL my_handle_error( ?, ?, ?, ? )

    Most DBMSs use the RETURN statement to set the return value from a procedure or function.

The CustDB sample application contains error handlers for various database-management systems.

See also
  • report_error connection event
  • report_odbc_error connection event
  • handle_odbc_error connection event
SQL example

The following example works with an Adaptive Server Anywhere consolidated database. It allows your application to ignore redundant inserts.

call ml_add_connection_script(
    'ver1',
    'handle_error',
   'call ULHandleError(?,?,?,?,?)' )
CREATE PROCEDURE ULHandleError(
   INOUT action integer,
   IN error_code integer,
   IN error_message varchar(1000),
   IN user_name varchar(128),
   IN table_name varchar(128) )
BEGIN
  -- -196 is SQLE_INDEX_NOT_UNIQUE
  -- -194 is SQLE_INVALID_FOREIGN_KEY
  if error_code = -196 or error_code = -194 then
      -- ignore the error and keep going
      SET action = 1000;
  else
      -- abort the synchronization
      SET action = 3000;
  end if;
END
Java example

The following stored procedure call registers a Java method called handleError as the script for the handle_error connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
    'ver1',
    'handle_error',
    'ExamplePackage.ExampleClass.handleError' )

Following is the sample Java method handleError. It processes an error based on the data that is passed in. It also determines the resulting error code.

public String handleError(
  ianywhere.ml.script.InOutInteger actionCode,
  int errorCode,
  String errorMessage,
  String    user,
  String  table )
{  int new_ac;
   if( user == null )
   {  new_ac = handleNonSyncError( errorCode,
      errorMessage ); }
   else if( table == null )
   {  new_ac = handleConnectionError( errorCode,
      errorMessage, user ); }
   else
   {  new_ac = handleTableError( errorCode,
      errorMessage, user, table ); }
   // keep the most serious action code
   if( actionCode.getValue() < new_ac )
   {  actionCode.setValue( new_ac ); }
   return( null ); }


handle_odbc_error connection event

Function

Executed whenever the MobiLink synchronization server encounters an error triggered by the ODBC Driver Manager.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | action_code | INTEGER. This is an INOUT parameter.
2 | ODBC_state | VARCHAR(5)
3 | error_message | TEXT
4 | ml_username | VARCHAR(128)
5 | table | VARCHAR(128)
Default action

The MobiLink synchronization server selects a default action code. You can modify the action code in the script, and return a value instructing MobiLink how to proceed. The action code parameter takes one of the following values:

  • 1000 Skip the current row and continue processing.

  • 3000 Rollback the current transaction and cancel the current synchronization. This is the default action code, and is used when no handle_error script is defined or this script causes an error.

  • 4000 Rollback the current transaction, cancel the synchronization, and shut down the MobiLink synchronization server.

Description

The MobiLink synchronization server executes this script whenever it encounters an error flagged by the ODBC Driver Manager during the synchronization process. The error codes allow you to identify the nature of the error.

The action code tells the MobiLink synchronization server what to do next. Before it calls this script, the MobiLink synchronization server sets the action code to a default value, which depends upon the severity of the error. Your script may modify this value. Your script must return or set an action code.

The handle_odbc_error script is called after the handle_error and report_error scripts, and before the report_odbc_error script.

When only one, but not both, error-handling script is defined, the return value from that script decides error behavior. When both error-handling scripts are defined, the MobiLink synchronization server uses the numerically highest action code. If both handle_error and handle_ODBC_error are defined, MobiLink uses the numerically highest action code returned from all calls.

See also
  • handle_error connection event
  • report_error connection event
  • report_odbc_error connection event
SQL example

The following example works with an Adaptive Server Anywhere consolidated database. It allows your application to ignore ODBC integrity constraint violations.

call ml_add_connection_script(
 'ver1',
 'handle_odbc_error',
 'call HandleODBCError( ?, ?, ?, ?, ? )'  )
CREATE PROCEDURE HandleODBCError( INOUT action integer,
IN odbc_state varchar(5), IN error_message varchar(1000),
IN user_name varchar(128), IN table_name varchar(128) )
BEGIN
  if odbc_state = '23000' then
      -- ignore the error and keep going
      SET action = 1000;
  else
      -- abort the synchronization
      SET action = 3000;
  end if;
END
Java example

The following stored procedure call registers a Java method called handleODBCError as the script for the handle_odbc_error event when synchronizing the script version ver1.

call ml_add_java_connection_script(
'ver1', 'handle_odbc_error', 'ExamplePackage.ExampleClass.handleODBCError'
)

Following is the sample Java method handleODBCError. It processes an error based on the data that is passed in. It also determines the resulting error code.

public String handleODBCError(
  ianywhere.ml.script.InOutInteger actionCode,
  String ODBCState,
  String errorMessage,
  String user,
  String table )
{  int new_ac;
   if( user == null )
   {  new_ac = handleNonSyncError( ODBCState,
      errorMessage ); }
   else if( table == null )
   {  new_ac = handleConnectionError( ODBCState,
      errorMessage, user ); }
   else {  new_ac = handleTableError( ODBCState,
           errorMessage, user, table ); }
   // keep the most serious action code
   if( actionCode.getValue() < new_ac )
   {  actionCode.setValue( new_ac ); }
   return( null ); }


modify_error_message connection event

Function

The script can be used to customize the message text (error, warning, and information) that is sent to remote databases.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | error_message | VARBINARY(1024). This is an INOUT parameter.
2 | ml_username | VARCHAR(128)
3 | error_code | INT
Default action

None.

Description

SQL scripts for the modify_error_message event must be implemented as stored procedures.

SQL example

The following example downloads everything from one day ago, regardless of whether the databases were synchronized since then.

First, create a procedure for your Adaptive Server Anywhere consolidated database:

CREATE PROCEDURE ModifyLastDownloadTimestamp(
  inout last_download_time TIMESTAMP,
  in user_name VARCHAR(128) )
BEGIN
  SELECT dateadd(day, -1, last_download_time )
  INTO last_download_time
END

Second, install the script into your Adaptive Server Anywhere consolidated database:

call ml_add_connection_script(
  'modify_ts_test',
  'modify_last_download_timestamp',
  'call  ModifyLastDownloadTimestamp ( ?, ? )' )
Java example

The following stored procedure call registers a Java method called modifyLastDownloadTimestamp as the script for the modify_last_download_timestamp connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
  'ver1',
  'modify_last_download_timestamp',
  'ExamplePackage.ExampleClass.modifyLastDownloadTimestamp' )

Following is the sample Java method modifyLastDownloadTimestamp. It prints the current and new timestamp and modifies the timestamp that is passed in.

public String modifyLastDownloadTimestamp(
     Timestamp last_download_time,
     String user_name )
{  java.lang.System.out.println( "old date: " +
   last_download_time.toString() );
   last_download_time.setDate(
   last_download_time.getDate() -1 );
   java.lang.System.out.println( "new date: " +
   last_download_time.toString() );
   return( null ); }


modify_last_download_timestamp connection event

Function

The script can be used to modify the last_download timestamp for the current synchronization.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | last_download_timestamp | TIMESTAMP. This is an INOUT parameter.
2 | ml_username | VARCHAR(128)
Default action

None.

Description

Use this script when you want to modify the last download timestamp for the current synchronization. If this script is defined, the MobiLink synchronization server calls this script and uses the modified last_download timestamp as the last_download timestamp passed to the download scripts.

SQL scripts for the modify_last_download_timestamp event must be implemented as stored procedures. The MobiLink synchronization server passes in the last_download_timestamp as the first parameter to the stored procedure, and replaces the timestamp by the first value passed out by the stored procedure.

For example, if you defined the following download_cursor script, the MobiLink synchronization server would replace the ? with the value of the modified last download timestamp before executing the SELECT statement:

SELECT pk, c2, c3 FROM test WHERE last_modified >= ?

This script is executed just before the prepare_for_download script, in the same transaction.

SQL example

First, create a procedure for your Adaptive Server Anywhere consolidated database. In Oracle:

CREATE PROCEDURE modify_nldts(
      nldts      OUT DATE,
      ldts      IN DATE,
      user_name    IN VARCHAR )
       AS
       BEGIN
       -- N is max replication latency in consolidated cluster
      nldts := nldts - N;
       END;

In Adaptive Server Anywhere, Adaptive Server Enterprise, or Microsoft SQL Server:

CREATE PROCEDURE modify_nldts
      @nldts     DATETIME OUTPUT,
      @ldts      DATETIME,
      @t_name    VARCHAR( 128 )
       AS
       BEGIN
       -- N is max replication latency in consolidated cluster
      SELECT @nldts = @nldts - N
       END

Next, install the script into your consolidated database. For an Adaptive Server Anywhere consolidated database:

ml_add_connection_script(
  'my_version',
  'modify_last_download_timestamp',
  '{call modify_nldts(?,?,?)}' )
Java example

The following stored procedure call registers a Java method called modifyLastDownloadTimestamp as the script for the modify_last_download_timestamp connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
  'ver1',
  'modify_last_download_timestamp',
  'ExamplePackage.ExampleClass.modifyLastDownloadTimestamp' )

Following is the sample Java method modifyLastDownloadTimestamp. It prints the current and new timestamp and modifies the timestamp that is passed in.

public String modifyLastDownloadTimestamp(
     Timestamp last_download_time,
     String user_name )
{  java.lang.System.out.println( "old date: " +
   last_download_time.toString() );
   last_download_time.setDate(
   last_download_time.getDate() -1 );
   java.lang.System.out.println( "new date: " +
   last_download_time.toString() );
   return( null ); }


modify_next_last_download_timestamp connection event

Function

The script can be used to modify the last_download timestamp for the next synchronization.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | download_timestamp | TIMESTAMP. This is an INOUT parameter.
2 | last_download_timestamp | TIMESTAMP
3 | ml_username | VARCHAR(128)
Default action

None.

Description

Use this script when you want to modify the last download timestamp for the next synchronization. If this script is defined, the MobiLink synchronization server calls this script and sends the next last download timestamp down to the remote, which will send it as part of the next synchronization.

SQL scripts for the modify_next_last_download_timestamp event must be implemented as stored procedures. The MobiLink synchronization server passes in the download_timestamp as the first parameter to the stored procedure, and replaces the timestamp by the first value passed out by the stored procedure.

You can use this script to modify the download timestamp that the MobiLink synchronization server sends to the MobiLink client. If the client is dbmlsync, the timestamp is stored in the SYSSYNC system table.

This script is executed in the download transaction, after downloading user tables.

SQL example

The following example shows one application of this script. First, create a procedure for your Adaptive Server Anywhere consolidated database:

CREATE PROCEDURE ModifyNextDownloadTimestamp(
  inout download_timestamp TIMESTAMP ,
  in last_download TIMESTAMP ,
  in user_name VARCHAR(128) )
  BEGIN
    SELECT dateadd(hour, -1, download_timestamp )
    INTO download_timestamp
END

Second, install the script into your Adaptive Server Anywhere consolidated database:

call ml_add_connection_script(
  'modify_ts_test',
  'modify_next_last_download_timestamp',
  'call  ModifyNextDownloadTimestamp ( ?, ?, ? )' )
Java example

The following stored procedure call registers a Java method called modifyNextDownloadTimestamp as the script for the modify_next_last_download_timestamp connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
   'ver1',
   'modify_next_last_download_timestamp',
   'ExamplePackage.ExampleClass.modifyNextDownloadTimestamp' )

Following is the sample Java method modifyNextDownloadTimestamp. It sets the download timestamp back an hour.

public String modifyNextDownloadTimestamp(
  Timestamp download_timestamp,
  Timestamp last_download,
  String user_name )
{  download_timestamp.setHours(
   download_timestamp.getHours() -1 );
   return( null ); }


modify_user connection event

Function

Provide the MobiLink user name.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Item | Parameter | Description
1 | ml_username | VARCHAR(128). This is an INOUT parameter.
Default action

None.

Description

The MobiLink server provides the user name as a parameter when it calls scripts; the user name is sent by the MobiLink client. In some cases, you may want to have an alternate user name. This script allows you to modify the user name used in calling MobiLink scripts.

The ml_username parameter must be long enough to hold the user name.

SQL scripts for the modify_user event must be implemented as stored procedures.

See also
  • authenticate_user connection event
  • authenticate_user_hashed connection event
SQL example

The following example works with an Adaptive Server Anywhere consolidated database. It maps a remote database user name to the id of the user using the device, by using a mapping table called user_device. This technique can be used when the same person has multiple remotes (such as a PDA and a laptop) requiring the same synchronization logic (based on the user's name or id).

call ml_add_connection_script(
 'ver1',
 'modify_user',
 'call ModifyUser( ? )'  )
CREATE PROCEDURE ModifyUser( INOUT u_name varchar(128) )
BEGIN
 select user_name
    into u_name
    from user_device
    where device_name = u_name
END
Java example

The following stored procedure call registers a Java method called modifyUser as the script for the modify_user connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
   'ver1',
   'modify_user',
   'ExamplePackage.ExampleClass.modifyUser' )

Following is the sample Java method modifyUser. It gets the user ID from the database and then uses it to set the user name.

public void ModifyUser( InOutString io_user_name )
  throws SQLException
{  Statement uid_select = curConn.createStatement();
   ResultSet uid_result = uid_select.executeQuery(
   "select rep_id from SalesRep where name = '" +
   io_user_name.getValue() + "' " );
   uid_result.next();
   io_user_name.setValue(
   java.lang.Integer.toString(uid_result.getInt( 1 ))
   uid_result.close();
   uid_select.close();
   return; }
.NET example

The following stored procedure call registers a .NET method called ModUser as the script for the modify_user connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script(
  'ver1',
  'modify_user',
  'TestScripts.Test.ModUser'
)

Following is the C# signature for the call ModUser.

public void ModUser( string user )


new_row_cursor table event (deprecated)

Function

Defines the insert cursor that the MobiLink synchronization server uses to insert the new values of rows that were updated in the remote database, but conflict with values presently in the consolidated database.

Use statement-based events for uploads
This script has been deprecated. Use the statement-based event upload_new_row_insert instead. Support for the new_row_cursor event is likely to be removed from future releases.
Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
Default action

None.

Description

When a row is updated on a remote database, the MobiLink client saves a copy of the original values. The client sends both old and new values to the MobiLink synchronization server. Also used to input an INSERT operation in forced conflict mode.

When the MobiLink synchronization server receives an updated row, it compares the original values with the present values in the consolidated database, using the upload_cursor. If the old uploaded values do not match the current value in the consolidated database, the row conflicts. Instead of updating the row, the MobiLink synchronization server inserts both old and new values into the consolidated database using the old_row_cursor and the new_row_cursor, respectively.

The MobiLink synchronization server uses a cursor to insert the new uploaded values from conflicting rows into the consolidated database. This script contains the SELECT statement used to define this cursor.

It is common practice to use temporary tables to store the old and new versions of conflicting rows. You can create these temporary tables in an earlier script.

You can have one new_row_cursor script for each table in the remote database.

Normally, the columns in the select list must match those in the client table in both order and type. However, the MobiLink synchronization server permits you to add one extra column. If you do so, the MobiLink synchronization server automatically inserts the user name into the first column, then proceeds to insert the new row values using the remaining columns, as usual.

Note
The script is ignored if any of the following scripts are defined for the same table: upload_insert, upload_update, upload_delete, upload_fetch, upload_new_row_insert, upload_old_row_insert.
See also
  • upload_new_row_insert table event
  • Handling conflicts
  • resolve_conflict table event
SQL example

The following SELECT statement defines a new_row_cursor script suited to the CustDB sample application.

call ml_add_table_script(
  'ver1',
  'table1',
  'new_row_cursor',
'SELECT order_id, cust_id, prod_id, emp_id,
    disc, quant, notes, status
  FROM ULNewOrder FOR update')

The primary key of the ULOrder table is order_id.

The following SELECT statement could instead be used for the same client table. This variation includes the permitted one extra row. The MobiLink synchronization server automatically stores the user name in the first column.

SELECT user_name, order_id, cust_id, prod_id,
    emp_id, disc, quant, notes, status
  FROM ULNewOrder FOR update
Java example

This script must return valid SQL.

The following stored procedure call registers a Java method called newRowCursor as the script for the new_row_cursor event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'new_row_cursor',
  'ExamplePackage.ExampleClass.newRowCursor' )

Following is the sample Java method newRowCursor. It dynamically generates a new row cursor statement by calling a Java method.

public String newRowCursor()
{  return( getRowCursor ( _curTable ) ); }


old_row_cursor table event (deprecated)

Function

Defines the cursor that the MobiLink synchronization server uses to insert the old values of rows that were updated in the remote database, but that conflict with values presently in the consolidated database. The event is also used to insert the values of deleted rows when in forced conflict mode.

Use statement-based events for uploads
This script has been deprecated. Use the statement-based event upload_old_row_insert instead. Support for the old_row_cursor event is likely to be removed from future releases.
Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
Default action

None.

Description

When a row is updated on a remote database, the MobiLink client saves a copy of the original values. The client sends both old and new values to the MobiLink synchronization server.

When the MobiLink synchronization server receives an updated row, it compares the original values with the present values in the consolidated database, using the upload_cursor event. If the old uploaded values do not match the current values in the consolidated database, the row conflicts. Instead of updating the row, the MobiLink synchronization server inserts both old and new values into the consolidated database using the old_row_cursor event and the new_row_cursor event.

It is common practice to use temporary tables to store the old and new versions of conflicting rows. In Adaptive Server Anywhere, you can create these tables in an earlier script. Some non-ASA consolidated databases support temporary tables, but they usually differ significantly from the temporary tables offered by ASA. Consult your DBMS documentation for details. An alternative to a temporary table is a base table with an extra column for the MobiLink user name. This effectively partitions the rows of the base table between concurrent synchronizations.

The MobiLink synchronization server uses a cursor to insert the old uploaded values from conflicting rows into the consolidated database. This script contains the SELECT statement used to define this cursor.

You can have one old_row_cursor script for each table in the remote database.

Normally, the columns in the SELECT list must match those in the client table in both order and type. However, the MobiLink synchronization server permits you to add one extra column. If you do so, the MobiLink synchronization server automatically inserts the user name into the first column, then proceeds to insert the old row values using the remaining columns, as usual.

See also
  • upload_old_row_insert table event
  • Handling conflicts
  • resolve_conflict table event
SQL example

The following SELECT statement defines an old_row_cursor script suited to the CustDB sample application for an Oracle installation. The primary key of the ULOrder table is order_id.

call ml_add_table_script(
  'ver1',
  'table1',
  'old_row_cursor',
'SELECT order_id, cust_id, prod_id, emp_id,
    disc, quant, notes, status
 FROM ULOldOrder')

The following SELECT statement could instead be used for the same client table. This variation includes the permitted one extra row. The MobiLink synchronization server automatically stores the user name in the first column.

SELECT user_name, order_id, cust_id, prod_id,
    emp_id, disc, quant, notes, status
 FROM ULOldOrder
Java example

This script must return valid SQL.

The following stored procedure call registers a Java method called oldRowCursor as the script for the old_row_cursor event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'old_row_cursor',
  'ExamplePackage.ExampleClass.oldRowCursor' )

Following is the sample Java method oldRowCursor. It dynamically generates an old row cursor statement by calling a Java method.

public String oldRowCursor()
{  return( getRowCursor( _curTable ) ); }


prepare_for_download connection event

Function

Processes any required operations between the upload and download transactions.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | last_download | TIMESTAMP
2 | ml_username | VARCHAR(128)
Default action

None.

Description

The MobiLink synchronization server executes this script as a separate transaction, between the upload transaction and the start of the download transaction.

The last_download timestamp is the value obtained from the consolidated database during the last successful synchronization immediately prior to the download phase. If the current user has never synchronized successfully, this value is set to 1900-01-01.

See also
  • end_upload connection event
  • begin_download connection event
Java example

The following stored procedure call registers a Java method called prepareForDownload as the script for the prepare_for_download event when synchronizing the script version ver1.

call ml_add_java_connection_script(
   'ver1',
   'prepare_for_download',
   'ExamplePackage.ExampleClass.prepareForDownload' )

Following is the sample Java method prepareForDownload. It calls a Java method to modify some rows in the database.

public String prepareForDownload( Timestamp ts,
String user )
{  adjustUploadedRows( _syncConn, user );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called PrepareForDownload as the script for the prepare_for_download connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script( 'ver1',
  'prepare_for_download',
  'TestScripts.Test.PrepareForDownload'
)

Following is the C# signature for the call PrepareForDownload.

public void PrepareForDownload(
  DateTime timestamp,
  string user )


report_error connection event

Function

Allows you to log errors and to record the actions selected by the handle_error script.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | action_code | INTEGER. This parameter is mandatory.
2 | error_code | INTEGER. This parameter is optional if none of the following parameters are specified.
3 | error_message | TEXT. This parameter is optional if none of the following parameters are specified.
4 | ml_username | VARCHAR(128). This parameter is optional if none of the following parameters are specified.
5 | table | VARCHAR(128). This parameter is optional.
Default action

None.

Description

This script allows you to log errors and to record the actions selected by the handle_error script. This script is executed after the handle_error event, whether or not a handle_error script is defined. It is always executed in its own transaction, on a different database connection than the synchronization connection (the administrative/information connection).

The error code and error message allow you to identify the nature of the error. The action code value is returned by the last call to an error handling script for the SQL operation that caused the current error.

If the error happened as part of synchronization, the user name is supplied. Otherwise, this value is NULL.

If the error happened while manipulating a particular table, the table name is supplied. Otherwise, this value is NULL. The table name is the name of a table in the remote database. This name may or may not have a direct counterpart in the consolidated database, depending on the design of the synchronization system.

See also
  • handle_error connection event
  • handle_odbc_error connection event
  • report_odbc_error connection event
SQL example

The following example works with an Adaptive Server Anywhere consolidated database. It inserts a row into a table used to record synchronization errors.

call ml_add_connection_script(
 'ver1',
 'report_error',
 'insert into sync_error(
   action_code,
   error_code,
   error_message,
   user_name,
   table_name )
    values( ?, ?, ?, ?, ? )'  )
Java example

The following stored procedure call registers a Java method called reportError as the script for the report_error connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
   'ver1',
   'report_error,
   'ExamplePackage.ExampleClass.reportError' )

Following is the sample Java method reportError. It logs the error to a table using the JDBC connection provided by MobiLink. It also sets the action code.

public String reportError(
ianywhere.ml.script.InOutInteger actionCode,
int errorCode, String errorMessage, String user,
String table )
  throws java.sql.SQLException
{  // insert error information in a table
   JDBCLogError( _syncConn, errorCode, errorMessage,
   user, table );
   actionCode.setValue( getActionCode( errorCode ) );
   return( null ); }


report_odbc_error connection event

Function

Allows you to log errors and to record the actions selected by the handle_odbc_error script.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | action_code | INTEGER. This parameter is mandatory.
2 | ODBC_state | VARCHAR(5). This parameter is optional if none of the following parameters are specified.
3 | error_message | TEXT. This parameter is optional if none of the following parameters are specified.
4 | ml_username | VARCHAR(128). This parameter is optional if none of the following parameters are specified.
5 | table | VARCHAR(128). This parameter is optional.
Default action

None.

Description

This script allows you to log errors and to record the actions selected by the handle_odbc_error script. This script is executed after the handle_odbc_error event, whether or not a handle_odbc_error script is defined. It is always executed in its own transaction, on a different database connection than the synchronization connection (the administrative/information connection).

The error code and error message allow you to identify the nature of the error. The action code value is returned by the last call to an error handling script for the SQL operation that caused the current error.

If the error happened as part of synchronization, the user name is supplied. Otherwise, this value is NULL.

If the error happened while manipulating a particular table, the table name is supplied. Otherwise, this value is NULL. The table name is the name of a table in the remote database. This name may or may not have a direct counterpart in the consolidated database, depending on the design of the synchronization system.

See also
  • handle_error connection event
  • handle_odbc_error connection event
  • report_error connection event
SQL example

The following example works with an Adaptive Server Anywhere consolidated database. It inserts a row into a table used to record synchronization errors.

call ml_add_connection_script(
 'ver1',
 'report_odbc_error',
 'insert into sync_error(
    action_code,
    odbc_state,
    error_message,
    user_name,
    table_name )
  values( ?, ?, ?, ?, ? )'  )
Java example

The following stored procedure call registers a Java method called reportODBCError as the script for the report_odbc_error event when synchronizing the script version ver1.

call ml_add_java_connection_script(
   'ver1',
   'report_odbc_error',
   'ExamplePackage.ExampleClass.reportODBCError' )

Following is the sample Java method reportODBCError. It logs the error to a table using the JDBC connection provided by MobiLink. It also sets the action code.

public String reportODBCError(
   ianywhere.ml.script.InOutInteger actionCode,
   String ODBCState,
   String errorMessage,
   String user,
   String table )
  throws java.sql.SQLException
{  JDBCLogError( _syncConn, ODBCState, errorMessage,
   user, table );
   actionCode.setValue( getActionCode( ODBCState ) );
   return( null ); }


resolve_conflict table event

Function

Defines a process for resolving a conflict in a specific table.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. You must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | table | VARCHAR(128)
Default action

None.

Description

When a row is updated on a remote database, the MobiLink client saves a copy of the original values. The client sends both old and new values to the MobiLink synchronization server.

When the MobiLink synchronization server receives an updated row, it compares the original values with the present values in the consolidated database. The comparison is carried out using the upload_fetch script.

If the old uploaded values do not match the current values in the consolidated database, the row conflicts. Instead of updating the row, the MobiLink synchronization server inserts both old and new values into the consolidated database. The old and new rows are handled using the upload_old_row_insert and upload_new_row_insert scripts, respectively. If you are using cursor-based uploads the rows are handled using old_row_cursor and new_row_cursor, respectively.

Once the values have been inserted, the MobiLink synchronization server executes the resolve_conflict script. It provides the opportunity to resolve the conflict. You can implement any scheme of your choosing.

This script is executed once per conflict.

Alternatively, instead of defining the resolve_conflict script, you can resolve conflicts in a set-oriented fashion by putting conflict-resolution logic either in your end_upload_rows script or in your end_upload table script.

You can have one resolve_conflict script for each table in the remote database.

See also
  • upload_old_row_insert table event
  • upload_new_row_insert table event
  • upload_update table event
  • old_row_cursor table event (deprecated)
  • new_row_cursor table event (deprecated)
  • end_upload_rows table event
SQL example

The following statement defines a resolve_conflict script suited to the CustDB sample application for an Oracle installation. It calls a stored procedure ULResolveOrderConflict .

exec ml_add_table_script(
   'custdb', 'ULOrder', 'resolve_conflict',
   'begin ULResolveOrderConflict();
end; ')

CREATE OR REPLACE PROCEDURE ULResolveOrderConflict()
AS
  new_order_id integer;
  new_status   varchar(20);
  new_notes   varchar(50);
BEGIN
  -- approval overrides denial
  SELECT order_id, status, notes
    INTO new_order_id, new_status, new_notes
    FROM ULNewOrder
   WHERE syncuser_id = SyncUserID;
  IF new_status = 'Approved' THEN
    UPDATE ULOrder o
       SET o.status = new_status, o.notes =
new_notes
     WHERE o.order_id = new_order_id;
  END IF;
  DELETE FROM ULOldOrder;
  DELETE FROM ULNewOrder;
END;
Java example

The following stored procedure call registers a Java method called resolveConflict as the script for the resolve_conflict table event when synchronizing the script version ver1.

call ml_add_java_table_script(
   'ver1',
   'table1',
   'resolve_conflict',
   'ExamplePackage.ExampleClass.resolveConflict' )

Following is the sample Java method resolveConflict. It calls a Java method that will use the JDBC connection provided by MobiLink. It also sets the action code.

public String resolveConflict( String user,
 String table)
{  resolveRows(_syncConn, user ); }


synchronization_statistics connection event

Function

Tracks synchronization statistics.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | warnings | INTEGER
3 | errors | INTEGER
4 | deadlocks | INTEGER
5 | synchronized_tables | INTEGER
6 | connection_retries | INTEGER
Default action

None.

Description

The synchronization_statistics event allows you to gather, for any user and connection, various statistics about the current synchronization. The synchronization_statistics connection script is called just prior to the commit at the end of the end synchronization transaction.

See also
  • download_statistics connection event
  • download_statistics table event
  • upload_statistics connection event
  • upload_statistics table event
  • synchronization_statistics table event
  • time_statistics connection event
  • time_statistics table event
  • MobiLink Monitor
SQL example

The following example inserts synchronization statistics into the sync_con_audit table.

call ml_add_connection_script(
  'ver1',
  'synchronization_statistics',
'INSERT INTO sync_con_audit(
  ml_user, warnings, errors,
  deadlocks, synchronized_tables,
  connection_retries)
VALUES (?,?,?,?,?,?)')

Once statistics are inserted into the audit table, you may use these statistics to monitor your synchronizations and make optimizations where applicable.

Java example

The following stored procedure call registers a Java method called synchronizationStatisticsConnection as the script for the synchronization_statistics connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
  'ver1',
  'synchronization_statistics',
  'ExamplePackage.ExampleClass.synchronizationStatisticsConnection'
)

Following is the sample Java method synchronizationStatisticsConnection. It logs some of the statistics to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public String synchronizationStatisticsConnection(
  String user, int warnings, int errors, int deadlocks,
  int synchronizedTables, int connectionRetries )
{  java.lang.System.out.println( "synch statistics
   number of deadlocks: " + deadlocks ;
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called SyncStats as the script for the synchronization_statistics connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script(
  'ver1',
  'synchronization_statistics',
  'TestScripts.Test.SyncStats'
)

Following is the sample .NET method SyncStats. It logs some of the statistics to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public void SyncStats(
  string user,
  int warnings,
  int errors,
  int deadLocks,
  int syncedTables,
  int connRetries )
{  System.Console.WriteLine( "synch statistics
   number of deadlocks: " + deadlocks ;
   return( null ); }


synchronization_statistics table event

Function

Tracks synchronization statistics.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | table | VARCHAR(128)
3 | warnings | INTEGER
4 | errors | INTEGER
Default action

None.

Description

The synchronization_statistics event allows you to gather, for any user and table, the number of warnings and errors that occurred during synchronization. The synchronization_statistics table script is called just prior to the commit at the end of the end synchronization transaction.

See also
  • download_statistics connection event
  • download_statistics table event
  • upload_statistics connection event
  • upload_statistics table event
  • synchronization_statistics connection event
  • time_statistics connection event
  • time_statistics table event
  • MobiLink Monitor
SQL example

The following example inserts synchronization statistics into the sync_tab_audit table.

call ml_add_java_table_script(
  'ver1',
  'table1',
'INSERT INTO sync_tab_audit ( ml_user, table,
warnings, errors) VALUES (?,?,?,?)')

Once synchronization statistics are inserted into the audit table, you may use these statistics to monitor your synchronizations and make optimizations where applicable.

Java example

The following stored procedure call registers a Java method called synchronizationStatisticsTable as the script for the synchronization_statistics table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'synchronization_statistics',
  'ExamplePackage.ExampleClass.synchronizationStatisticsTable'
)

Following is the sample Java method synchronizationStatisticsTable. It logs some of the statistics to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public String synchronizationStatisticsTable(
String user, String table, int warnings, int errors )
{  java.lang.System.out.println( "synch statistics for
   table: " + table + " errors: " + errors );
   return( null ); }
.NET example

The following stored procedure call registers a .NET method called SyncTableStats as the script for the synchronization_statistics table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1',
  'table1',
  'synchronization_statistics',
  'TestScripts.Test.SyncTableStats'
)

Following is the sample .NET method SyncTableStats. It logs some of the statistics to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public void SyncTableStats(
  string user,
  string table,
  int warnings,
  int errors )
{  System.Console.WriteLine( "synch statistics for
   table: " + table + " errors: " + errors );
   return( null ); }


time_statistics connection event

Function

Tracks time statistics by user and event.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | event_name | VARCHAR(128)
3 | num_calls | INTEGER
4 | min_time | INTEGER. Milliseconds.
5 | max_time | INTEGER. Milliseconds.
6 | total_time | INTEGER. Milliseconds.
Default action

None.

Description

The time_statistics event allows you to gather time statistics for any user during synchronization. The statistics are gathered only for those events for which there is a corresponding script. The script gathers aggregate data for occasions where a single event occurs multiple times. The script can be especially useful for time comparisons across users, events and tables.

See also
  • time_statistics table event
  • download_statistics connection event
  • download_statistics table event
  • upload_statistics connection event
  • upload_statistics table event
  • synchronization_statistics connection event
  • synchronization_statistics table event
  • MobiLink Monitor
SQL example

The following example inserts statistical information into the time_statistics table.

call ml_add_connection_script(
  'ver1',
  'time_statistics',
'INSERT INTO time_statistics (id, ml_user, table,
     event_name, num_calls, min_time, max_time, total_time)
   VALUES (ts_id.nextval,?,?,?,?,?,?)')
Java example

The following stored procedure call registers a Java method called timeStatisticsConnection as the script for the time_statistics connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
  'ver1',
  'time_statistics',
  'ExamplePackage.ExampleClass.timeStatisticsConnection' )

Following is the sample Java method timeStatisticsConnection. It prints statistics for the prepare_for_download event. (This might be useful at development time but would slow down a production server.)

public void timeStatisticsConnection(
  String ml_username,
  String table_name,
  String event_name,
int num_calls, int min_time, int max_time,
int total_time )
{  if( event_name.equals( "prepare_for_download")
   {  java.lang.System.out.println(
      "prepare_for_download num_calls: " + num_calls +
      "total_time: " + total_time ); } }
.NET example

The following stored procedure call registers a .NET method called TimeStats as the script for the time_statistics connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script(
  'ver1',
  'time_statistics',
  'TestScripts.Test.TimeStats'
)

Following is the sample Java method TimeStats. It prints statistics for the prepare_for_download event. (This might be useful at development time but would slow down a production server.)

public void TimeStats(
  string user,
  string eventName,
  int numCalls,
  int minTime,
  int maxTime,
  int totTime )
{  if( event_name=="prepare_for_download")
   {  System.Console.WriteLine(
      "prepare_for_download num_calls: " + num_calls +
      "total_time: " + total_time ); } }


time_statistics table event

Function

Tracks time statistics.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | table | VARCHAR(128)
3 | event_name | VARCHAR(128)
4 | num_calls | INTEGER
5 | min_time | INTEGER. Milliseconds.
6 | max_time | INTEGER. Milliseconds.
7 | total_time | INTEGER. Milliseconds.
Default action

None.

Description

The time_statistics table event allows you to gather time statistics for any user and table during synchronization. The statistics are gathered only for those events for which there is a corresponding script. The script gathers aggregate data for occasions where a single event occurs multiple times. The script can be especially useful for time comparisons across users, events and tables.

See also
  • time_statistics connection event
  • download_statistics connection event
  • download_statistics table event
  • upload_statistics connection event
  • upload_statistics table event
  • synchronization_statistics connection event
  • synchronization_statistics table event
  • MobiLink Monitor
SQL example

The following example inserts statistical information into the time_statistics table.

INSERT INTO time_statistics(
 ml_user, table, event_name, num_calls,
 min_time, max_time, total_time)
VALUES (?,?,?,?,?,?,?)
Java example

The following stored procedure call registers a Java method called timeStatisticsTable as the script for the time_statistics table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'time_statistics',
  'ExamplePackage.ExampleClass.timeStatisticsTable' )

Following is the sample Java method timeStatisticsTable. It prints statistics for the upload_old_row_insert event.

public void timeStatisticsConnection(
   String ml_username,
   String table_name,
   String event_name,
int num_calls, int min_time, int max_time,
int total_time )
{  if( event_name.equals( "upload_old_row_insert")
   {  java.lang.System.out.println(
      "upload_old_row_insert num_calls: " + num_calls +
      "total_time: " + total_time ); } }
.NET example

The following stored procedure call registers a .NET method called TimeTableStats as the script for the time_statistics table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1',
  'table1',
  'time_statistics',
  'TestScripts.Test.TimeTableStats'
)

Following is the sample .NET method TimeTableStats. It prints statistics for the upload_old_row_insert event.

public void TimeTableStats(
  string user,
  string table,
  string eventName,
  int numCalls,
  int minTime,
  int maxTime,
  int totTime )
{  if( event_name == "upload_old_row_insert")
   {  System.Console.WriteLine(
      "upload_old_row_insert num_calls: " + num_calls +
      "total_time: " + total_time ); } }


upload_cursor table event (deprecated)

Function

Defines a cursor that the MobiLink synchronization server uses to insert, update, or delete rows during processing of the upload stream.

Use statement-based events for uploads
This script has been deprecated. Use the statement-based events upload_delete, upload_insert, and upload_update instead of the upload_cursor event to process the upload stream. Support for the upload_cursor event is likely to be removed from future releases.
Parameters
Item | Parameter
1 | primary key 1
2 | primary key 2
... | ...
Default action

None.

Description

The MobiLink synchronization server opens a cursor with which to insert, update, or delete rows in the consolidated database based on rows uploaded from a client application. This script should contain a suitable SELECT statement or call a stored procedure that contains a suitable SELECT statement.

The parameters are the values of each column included in the primary key of the corresponding client table. You must use these in a WHERE clause, so that the synchronization can identify a unique row based on these values. The type and order of the parameters is as defined in the example_upload_cursor script. This order is the same as that in the corresponding table definition in the remote database, which in turn may have been copied from your reference database.

You can have one upload_cursor script for each table in the remote database.

For Java and .NET applications, this script must return valid SQL.

See also
  • Writing scripts to upload rows
  • upload_delete table event
  • upload_insert table event
  • upload_update table event
SQL example

The following SELECT statement defines the upload cursor in the CustDB sample application.

call ml_add_table_script(
  'ver1',
  'table1',
  'upload_cursor',
'SELECT cust_id, cust_name
FROM ULCustomer
WHERE cust_id = ?')

The primary key of the ULCustomer table in the CustDB sample application is the column cust_id. If the corresponding table in the consolidated database is, instead, named Customer, then change the above statement as follows.

SELECT cust_id, cust_name
FROM Customer
WHERE cust_id = ?
Java example

The following stored procedure call registers a Java method called uploadCursor as the script for the upload_cursor event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'upload_cursor',
  'ExamplePackage.ExampleClass.uploadCursor' )

Following is the sample Java method uploadCursor. It calls getUploadCursor to dynamically generate an upload cursor.

public String uploadCursor()
{ return( getUploadCursor( _curTable ) ); }
.NET example

The following stored procedure call registers a .NET method called UploadCursor as the script for the upload_cursor event when synchronizing the script version ver1.

call ml_add_dnet_table_script(
  'ver1',
  'table1',
  'upload_cursor',
  'TestScripts.Test.UploadCursor' )

The following C# example deletes the contents of a temporary table. It then returns SQL that causes rows to be uploaded into the temporary table.

public string UploadCursor()
{
    DBCommand stmt = curConn.CreateCommand();
    stmt.CommandText = "DELETE FROM dnet_ul_temp";
    stmt.ExecuteNonQuery();
    stmt.Close();

    return( "SELECT * FROM dnet_ul_temp WHERE pk = ?" );
}


upload_delete table event

Function

Provides an event that the MobiLink synchronization server uses during processing of the upload stream to handle rows deleted from the remote database.

Parameters
Item | Parameter
1 | primary key 1
2 | primary key 2
... | ...
Default action

None.

Description

The statement-based upload_delete script handles rows that are deleted on the remote database. The action taken at the consolidated database can be a DELETE statement, but need not be.

You can have one upload_delete script for each table in the remote database.

For Java and .NET applications, this script must return valid SQL.

See also
  • upload_insert table event
  • upload_update table event
SQL example

This example is taken from the Contact sample and can be found in Samples\MobiLink\Contact\build_consol.sql. It marks customers that are deleted from the remote database as inactive.

call ml_add_table_script(
  'ver1',
  'table1',
  'upload_delete',
'UPDATE Customer SET active = 0 WHERE cust_id=?')
Java example

The following stored procedure call registers a Java method called uploadDeleteTable as the script for the upload_delete table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'upload_delete',
  'ExamplePackage.ExampleClass.uploadDeleteTable' )

Following is the sample Java method uploadDeleteTable. It calls genUD which dynamically generates an UPLOAD statement.

public string uploadDeleteTable()
{  return( genUD(_curTable) ); }
.NET example

The following stored procedure call registers a .NET method called UploadDelete as the script for the upload_delete table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1',
  'table1',
  'upload_delete',
  'TestScripts.Test.UploadDelete'
)

Following is the sample .NET method UploadDelete. It calls genUD which dynamically generates an UPLOAD statement.

public string UploadDelete( object pk1 )
{  return( genUD(_curTable) ); }


upload_fetch table event

Function

Provides an event that the MobiLink synchronization server uses to identify update conflicts during statement-based processing of the upload stream.

Parameters
Item | Parameter
1 | primary key 1
2 | primary key 2
... | ...
Default action

None.

Description

The statement-based upload_fetch script fetches rows from a synchronized table for the purposes of conflict detection. It is a companion to the upload_update event.

The columns of the result set must match the number of columns being uploaded from the remote database for this table. If the values returned do not match the pre-image in the uploaded row, a conflict is identified.

You can have one upload_fetch script for each table in the remote database.

This script may be ignored if none of the following scripts are defined: upload_new_row_insert, upload_old_row_insert, and resolve_conflict.

See also
  • resolve_conflict table event
  • upload_delete table event
  • upload_insert table event
  • upload_update table event
SQL example

The following SQL script is taken from the Contact sample and can be found in Samples\MobiLink\Contact\build_consol.sql in the SQL Anywhere installation. It is used to identify conflicts that occur when rows updated in the remote database Product table are uploaded. This script selects rows from a table also named Product, but depending on your consolidated and remote database schema, the two table names may not match.

call ml_add_table_script(
  'ver1',
  'table1',
  'upload_fetch',
'SELECT id, name, size, quantity, unit_price
FROM Product WHERE id=?')
Java example

This script must return valid SQL.

The following stored procedure call registers a Java method called uploadFetchTable as the script for the upload_fetch table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'upload_fetch',
  'ExamplePackage.ExampleClass.uploadFetchTable' )

Following is the sample Java method uploadFetchTable. It calls genUF to dynamically generate an UPLOAD statement.

public string uploadFetchTable()
{  return( genUF(_curTable) ); }


upload_insert table event

Function

Provides an event that the MobiLink synchronization server uses during processing of the upload stream to handle rows inserted into the remote database.

Parameters
Item | Parameter
1 | column 1
2 | column 2
... | ...
Default action

None.

Description

The statement based upload_insert script performs direct inserts of column values.

You can have one upload_insert script for each table in the remote database.

For Java and .NET applications, this script must return valid SQL.

See also
  • upload_delete table event
  • upload_update table event
  • upload_fetch table event
SQL example

This example handles inserts that were made on the Customer table in the remote database. The script inserts the values into a table named Customer in the consolidated database. The final column of the table identifies the Customer as active. The final column does not appear in the remote database.

call ml_add_table_script(
  'ver1',
  'Customer',
  'upload_insert',
'INSERT INTO Customer( cust_id, name, rep_id, active )
VALUES ( ?, ?, ?, 1 )')
Java example

The following stored procedure call registers a Java method called uploadInsertTable as the script for the upload_insert table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'upload_insert',
  'ExamplePackage.ExampleClass.uploadInsertTable' )

Following is the sample Java method uploadInsertTable. It dynamically generates an UPLOAD statement. This syntax is for Adaptive Server Anywhere consolidated databases.

public string uploadInsertTable()
{  return("insert into" + _curTable + getCols(_curTable)
   + "values" + getQM(_curTable)); }
.NET example

The following stored procedure call registers a .NET method called UploadInsert as the script for the upload_insert table event when synchronizing the script version ver1 and the table table1. This syntax is for Adaptive Server Anywhere consolidated databases.

call ml_add_dnet_table_script(
  'ver1',
  'table1',
  'upload_insert',
  'TestScripts.Test.UploadInsert'
)

Following is the sample .NET method UploadInsert. It returns an UPLOAD statement for the ULCustomer table.

public static string UploadInsert()
 {
   return("INSERT INTO ULCustomer(cust_id,cust_name) values (?,?)");
 }


upload_new_row_insert table event

Function

Conflict resolution scripts for statement-based uploads commonly require access to the old and new values of rows uploaded from the remote database. This event allows you to handle the new, updated values of rows uploaded from the remote database.

Parameters
Item | Parameter
ml_username | VARCHAR(128). This parameter is optional.
1 | column 1
2 | column 2
... | ...
Default action

None.

Description

When a MobiLink client sends an updated row to the MobiLink synchronization server, it includes not only the new values (the post-image), but also a copy of the old row values (the pre-image). When the pre-image does not match the current values in the consolidated database, a conflict is detected.

This event allows you to save post-image values to a table. You can use this event to assist in developing conflict resolution procedures for statement-based updates. The parameters for this event hold new row values from the remote database before the update is carried out on the corresponding consolidated database table. This event is also used to insert rows in statement-based, forced-conflict mode.

The script for this event is usually an insert statement that inserts the new row into a temporary table for use by a resolve_conflict script.

You can have one upload_new_row_insert script for each table in the remote database.

For Java and .NET applications, this script must return valid SQL.

See also
  • Handling conflicts
  • resolve_conflict table event
  • upload_old_row_insert table event
  • upload_update table event
  • Storing the user name
SQL example

This example handles updates made on the product table in the remote database. The script inserts the new value of the row into a global temporary table named product_conflict. The final column of the table identifies the row as a new row.

call ml_add_table_script(
  'ver1',
  'table1',
  'upload_new_row_insert',
'INSERT INTO DBA.product_conflict(
  id, name, size, quantity, unit_price, row_type )
VALUES( ?, ?, ?, ?, ?, 'N' )')
Java example

The following stored procedure call registers a Java method called uploadNewRowInsertTable as the script for the upload_new_row_insert table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'upload_new_row_insert',
  'ExamplePackage.ExampleClass.uploadNewRowInsertTable'
)

Following is the sample Java method uploadNewRowInsertTable. It dynamically generates an UPLOAD statement. This syntax is for Adaptive Server Anywhere consolidated databases.

public string uploadNewRowInsertTable()
{  return("insert into" + _curTable + "_new" +
   getCols(_curTable) + "values" + getQM(_curTable)); }


upload_old_row_insert table event

Function

Conflict resolution scripts for statement-based uploads commonly require access to the old and new values of rows uploaded from the remote database. This event allows you to handle the old values of rows uploaded from the remote database.

Parameters
Item | Parameter
ml_username | VARCHAR(128). This parameter is optional.
1 | column 1
2 | column 2
... | ...
Default action

None.

Description

When a MobiLink client sends an updated row to the MobiLink synchronization server, it includes not only the new values (the post-image), but also a copy of the old row values (the pre-image). When the pre-image does not match the current values in the consolidated database, a conflict is detected.

This event allows you to save pre-image values to a table. You can use this event to assist in developing conflict resolution procedures for statement-based updates. The parameters for this event hold old row values from the remote database before the update is carried out on the corresponding consolidated database table. This event is also used to insert rows in statement-based, forced-conflict mode.

The script for this event is usually an insert statement that inserts the old row into a temporary table for use by a resolve_conflict script.

You can have one upload_old_row_insert script for each table in the remote database.

For Java and .NET applications, this script must return valid SQL.

See also
  • Handling conflicts
  • resolve_conflict table event
  • upload_new_row_insert table event
  • upload_update table event
  • Storing the user name
SQL example

This example handles updates made on the product table in the remote database. The script inserts the old value of the row into a global temporary table named product_conflict. The final column of the table identifies the row as an old row.

call ml_add_table_script(
  'ver1',
  'table1',
  'upload_old_row_insert',
'insert into DBA.product_conflict(
id, name, size, quantity, unit_price, row_type )
values( ?, ?, ?, ?, ?, 'O' )')
Java example

The following stored procedure call registers a Java method called uploadOldRowInsertTable as the script for the upload_old_row_insert table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'upload_old_row_insert',
  'ExamplePackage.ExampleClass.uploadNewRowInsertTable'
)

Following is the sample Java method uploadOldRowInsertTable. It dynamically generates an UPLOAD statement.

public string uploadOldRowInsertTable()
{  old" + getCols(_curTable) +
   "values" + getQM(_curTable)); }


upload_statistics connection event

Function

Tracks synchronization statistics for upload operations.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | warnings | INTEGER
3 | errors | INTEGER
4 | inserted_rows | INTEGER
5 | deleted_rows | INTEGER
6 | updated_rows | INTEGER
7 | conflicted_inserts | INTEGER
8 | conflicted_deletes | INTEGER
9 | conflicted_updates | INTEGER
10 | ignored_inserts | INTEGER
11 | ignored_deletes | INTEGER
12 | ignored_updates | INTEGER
13 | bytes | INTEGER
14 | deadlocks | INTEGER
Default action

None.

Description

The upload_statistics event allows you to gather, for any user, statistics on uploads. The upload_statistics connection script is called just prior to the commit at the end of the upload transaction.

See also
  • download_statistics connection event
  • download_statistics table event
  • upload_statistics table event
  • synchronization_statistics connection event
  • synchronization_statistics table event
  • time_statistics connection event
  • time_statistics table event
  • MobiLink Monitor
SQL example

The following example inserts synchronization statistics for upload operations into the table upload_summary_audit.

call ml_add_connection_script(
   'ver1',
   'upload_statistics',
'INSERT INTO upload_summary_audit (
 ml_user, warnings, errors, inserted_rows,
 deleted_rows, updated_rows, conflicted_inserts,
 conflicted_deletes, conflicted_updates,
 bytes, ignored_inserts, ignored deletes,
 ignored_updates, bytes, deadlocks)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)'

Once statistics are inserted into the audit table, you may use these statistics to monitor your synchronizations and make optimizations where applicable.

Java example

The following stored procedure call registers a Java method called uploadStatisticsConnection as the script for the upload_statistics connection event when synchronizing the script version ver1.

call ml_add_java_connection_script(
   'ver1',
   'upload_statistics',
   'ExamplePackage.ExampleClass.uploadStatisticsConnection' )

Following is the sample Java method uploadStatisticsConnection. It logs some statistics to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public String uploadStatisticsConnection(
  String user,
  int warnings,
  int errors,
  int insertedRows,
  int deletedRows,
  int updatedRows,
  int conflictedInserts,
  int conflictedDeletes,
  int conflictedUpdates,
  int ignoredInserts,
  int ignoredDeletes,
  int ignoredUpdates,
  int bytes,
  int deadlocks
)
{  java.lang.System.out.println( "updated rows: " +
   updatedRows ); }
.NET example

The following stored procedure call registers a .NET method called UploadStats as the script for the upload_statistics connection event when synchronizing the script version ver1.

call ml_add_dnet_connection_script(
  'ver1',
  'upload_statistics',
  'TestScripts.Test.UploadStats'
)

Following is the sample .NET method UploadStats. It logs some statistics to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public void UploadStats(
  string user,
  int warnings,
  int errors,
  int insertedRows,
  int deletedRows,
  int updatedRows,
  int conflictInserts,
  int conflictDeletes,
  int conflictUpdates,
  int ignoredInserts,
  int ignoredDeletes,
  int ignoredUpdates,
  int bytes,
  int deadlocks)
{  System.Console.WriteLine( "updated rows: " +
   updatedRows ); }


upload_statistics table event

Function

Tracks synchronization statistics for upload operations for a specific table.

Parameters

In the following table, the description provides the SQL data type. If you are writing your script in Java or .NET, you should use the appropriate corresponding data type. See SQL-Java data types and SQL-.NET data types.

Event parameters are optional only if no subsequent parameters are specified. For example, you must use parameter 1 if you want to use parameter 2.

Item | Parameter | Description
1 | ml_username | VARCHAR(128)
2 | table | VARCHAR(128)
3 | warnings | INTEGER
4 | errors | INTEGER
5 | inserted_rows | INTEGER
6 | deleted_rows | INTEGER
7 | updated_rows | INTEGER
8 | conflicted_inserts | INTEGER
9 | conflicted_deletes | INTEGER
10 | conflicted_updates | INTEGER
11 | ignored_inserts | INTEGER
12 | ignored_deletes | INTEGER
13 | ignored_updates | INTEGER
14 | bytes | INTEGER
15 | deadlocks | INTEGER
Default action

None.

Description

The upload_statistics event allows you to gather, for any user, vital statistics on synchronization happenings as they apply to any table. The upload_statistics table script is called just prior to the commit at the end of the upload transaction.

See also
  • download_statistics connection event
  • upload_statistics connection event
  • upload_statistics table event
  • synchronization_statistics connection event
  • synchronization_statistics table event
  • time_statistics connection event
  • time_statistics table event
  • MobiLink Monitor
SQL Example

The following example inserts a row into a table used to track upload statistics.

call ml_add_connection_script(
 'ver1',
 'upload_statistics',
 'INSERT INTO my_upload_statistics
    ( user_name, table_name, num_warnings, num_errors,
      inserted_rows, deleted_rows, updated_rows,
      conflicted_inserts, conflicted_deletes,
      conflicted_updates, ignored_inserts,
      ignored_deletes, ignored_updates, bytes,
      deadlocks )
    VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )'  )

The following example works with an Oracle consolidated database.

INSERT INTO upload_tables_audit (
id, user_name, table, warnings, errors,
inserted_rows, deleted_rows, updated_rows,
conflicted_inserts, conflicted_deletes,
conflicted_updates, ignored_inserts, ignored_deletes,
ignored_updates, bytes, deadlocks)
VALUES ( ut_audit.nextval,
?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)

Once statistics are inserted into the audit table, you may use these statistics to monitor your synchronizations and make optimizations where applicable.

Java example

The following stored procedure call registers a Java method called uploadStatisticsTable as the script for the upload_statistics table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'upload_statistics',
  'ExamplePackage.ExampleClass.uploadStatisticsTable' )

Following is the sample Java method uploadStatisticsTable. It logs some statistics to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public String uploadStatisticsTable(
  String user,
  int warnings,
  int errors,
  int insertedRows,
  int deletedRows,
  int updatedRows,
  int conflictedInserts,
  int conflictedDeletes,
  int conflictedUpdates,
  int ignoredInserts,
  int ignoredDeletes,
  int ignoredUpdates,
  int bytes,
 int deadlocks
)
{  java.lang.System.out.println( "updated rows: " +
   updatedRows ); }
.NET example

The following stored procedure call registers a .NET method called UploadTableStats as the script for the upload_statistics table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1',
  'table1',
  'upload_statistics',
  'TestScripts.Test.UploadTableStats'
)

Following is the sample .NET method uploadStatisticsTable. It logs some statistics to the MobiLink output log. (This might be useful at development time but would slow down a production server.)

public void UploadTableStats(
  string user,
  string table,
  int warnings,
  int errors,
  int insertedRows,
  int deletedRows,
  int updatedRows,
  int conflictInserts,
  int conflictDeletes,
  int conflictUpdates,
  int ignoredInserts,
  int ignoredDeletes,
  int ignoredUpdates,
  int bytes,
  int deadlocks )
{  System.Console.WriteLine( "updated rows: " +
   updatedRows ); }


upload_update table event

Function

Provides an event that the MobiLink synchronization server uses during processing of the upload stream to handle rows updated at the remote database.

Parameters
Clause | Parameters
SET | non-primary key column 1 non-primary key column 2 ...
WHERE | primary key 1 primary key 2 ...
Default action

None.

Description

The statement-based upload_update script may perform direct updates of column values as specified in the UPLOAD statement.

The WHERE clause must include all of the primary key columns that are being synchronized. The SET clause must contain all of the non-primary key columns that are being synchronized.

You use as many non-primary key columns in your SET clause as exist in the table, and MobiLink will send the correct number of column values. Similarly, in the WHERE clause, you can have any number of primary keys, but all must be specified here, and MobiLink will send the correct values. MobiLink sends these column values and primary key values in the order the columns or primary keys appear in a MobiLink report of your schema. You can use the -vh option to determine the column ordering for this table schema.

You can have one upload_update script for each table in the remote database.

For Java and .NET applications, this script must return valid SQL.

See also
  • upload_delete table event
  • upload_fetch table event
  • upload_insert table event
SQL example

This example handles updates made to the Customer table in the remote database. The script updates the values in a table named Customer in the consolidated database.

call ml_add_table_script(
  'ver1',
  'table1',
  'upload_update',
'UPDATE Customer SET name=?, rep_id=? WHERE cust_id=?')
Java example

The following stored procedure call registers a Java method called uploadUpdateTable as the script for the upload_update table event when synchronizing the script version ver1.

call ml_add_java_table_script(
  'ver1',
  'table1',
  'upload_update',
  'ExamplePackage.ExampleClass.uploadUpdateTable' )

Following is the sample Java method uploadUpdateTable. It calls a method called genUU to dynamically generate an UPLOAD statement.

public string uploadUpdateTable()
{  return( genUU(_curTable) ); }
.NET example

The following stored procedure call registers a .NET method called UploadUpdate as the script for the upload_update table event when synchronizing the script version ver1 and the table table1.

call ml_add_dnet_table_script(
  'ver1',
  'table1',
  'upload_update',
  'TestScripts.Test.UploadUpdate'
)

Following is the C# signature for the call UploadUpdate.

public string UploadUpdate()


Stored Procedures

About this chapter

This chapter provides information about the MobiLink predefined stored procedures.


Stored procedures to add or delete scripts

You must add synchronization scripts to system tables in the consolidated database before you can use them. The following stored procedures add synchronization scripts to the consolidated database. They can also be used to delete scripts.

Notes

  • When you add a script using a stored procedure, the script is a string. Any strings within the script need to be escaped. For Adaptive Server Anywhere, each quotation mark (') needs to be doubled so as not to terminate the string.

  • You cannot use stored procedures to add scripts longer than 255 bytes to Adaptive Server Enterprise 11.5 or earlier. Instead, use Sybase Central or direct insertion to define longer scripts.

  • IBM DB2 prior to version 6 only supports column names and other identifiers of 18 characters or less, and so the names are truncated. For example, ml_add_connection_script is shortened to ml_add_connection_.

ml_add_connection_script
ml_add_table_script
ml_add_dnet_connection_script
ml_add_dnet_table_script
ml_add_java_connection_script
ml_add_java_table_script


ml_add_connection_script

Function

Use this stored procedure to add or delete SQL connection scripts in the consolidated database.

Parameters
Item | Description | Remarks
1 | version name | VARCHAR(128)
2 | event name | VARCHAR(128)
3 | script contents | For Adaptive Server Anywhere and MS SQL Server, this is TEXT. For ASE, this is VARCHAR(16384). For ASE prior to 12.5, this is VARCHAR(255). For DB2, this is VARCHAR(4000). For Oracle, this is VARCHAR.
Description

To delete a connection script, set the script contents parameter to NULL.

When you add a script, the script is inserted into the ml_script table and the appropriate references are defined to associate the script with the event and script version that you specify. If the version name is new, it is automatically inserted into the ml_version table.

See also
  • Adding and deleting scripts in your consolidated database
  • ml_add_table_script
  • ml_add_dnet_connection_script
  • ml_add_dnet_table_script
  • ml_add_java_connection_script
  • ml_add_java_table_script
Example

The following statement adds a connection script associated with the begin_synchronization event to the script version custdb in an Adaptive Server Anywhere consolidated database. The script itself is the single statement that sets the @EmployeeID variable.

call ml_add_connection_script( 'custdb',
   'begin_synchronization',
   'set @EmployeeID = ?' )


ml_add_table_script

Function

Use this stored procedure to add or delete SQL table scripts in the consolidated database.

Parameters
Item | Description | Remarks
1 | version name | VARCHAR(128)
2 | table name | VARCHAR(128)
3 | event name | VARCHAR(128)
4 | script contents | For Adaptive Server Anywhere and MS SQL Server, this is TEXT. For ASE, this is VARCHAR(16384). For ASE prior to 12.5, this is VARCHAR(255). For DB2, this is VARCHAR(4000). For Oracle, this is VARCHAR.
Description

To delete a table script, set the script contents parameter to NULL.

When you add a script, the script is inserted into the ml_script table and the appropriate references are defined to associate the script with the table, event and script version that you specify. If the version name is new, it is automatically inserted into the ml_version table.

See also
  • Adding and deleting scripts in your consolidated database
  • ml_add_connection_script
  • ml_add_dnet_connection_script
  • ml_add_dnet_table_script
  • ml_add_java_connection_script
  • ml_add_java_table_script
Example

The following command adds a table script associated with the upload_insert event on the Customer table.

call ml_add_table_script( 'default', 'Customer', 'upload_insert',
   'INSERT INTO Customer( cust_id, name, rep_id, active )
      VALUES ( ?, ?, ?, 1 )' )


ml_add_dnet_connection_script

Function

Use this stored procedure to add or delete .NET connection scripts in the consolidated database.

Parameters
Item | Description | Remarks
1 | version name | VARCHAR(128)
2 | event name | VARCHAR(128)
3 | script contents | For Adaptive Server Anywhere and MS SQL Server, this is TEXT. For ASE, this is VARCHAR(16384). For ASE prior to 12.5, this is VARCHAR(255). For DB2, this is VARCHAR(4000). For Oracle, this is VARCHAR.
Description

To delete a connection script, set the script contents parameter to NULL.

The script value is a public method in a class in the MobiLink synchronization server classpath (for example, MyClass.MyMethod).

When you add a script, the method is associated with the event and script version that you specify. If the version name is new, it is automatically inserted into the ml_version table.

See also
  • Adding and deleting scripts in your consolidated database
  • ml_add_dnet_table_script
  • ml_add_connection_script
  • ml_add_table_script
  • ml_add_java_table_script
  • Methods
Example

The following example assigns the beginDownloadConnection method of the ExampleClass class to the begin_download event.

call ml_add_dnet_connection_script( 'ver1',
'begin_download',
'ExamplePackage.ExampleClass.beginDownloadConnection')


ml_add_dnet_table_script

Function

Use this stored procedure to add or delete .NET table scripts in the consolidated database.

Parameters
Item | Description | Remarks
1 | version name | VARCHAR(128)
2 | table name | VARCHAR(128)
3 | event name | VARCHAR(128)
4 | script contents | For Adaptive Server Anywhere and MS SQL Server, this is TEXT. For ASE, this is VARCHAR(16384). For ASE prior to 12.5, this is VARCHAR(255). For DB2, this is VARCHAR(4000). For Oracle, this is VARCHAR.
Description

To delete a connection script, set the script contents parameter to NULL.

The script value is a public method in a class in the MobiLink synchronization server classpath (for example, MyClass.MyMethod).

When you add a script, the method is associated with the table, event, and script version that you specify. If the version name is new, it is automatically inserted into the ml_version table.

See also
  • Adding and deleting scripts in your consolidated database
  • ml_add_dnet_connection_script
  • ml_add_connection_script
  • ml_add_table_script
  • ml_add_java_connection_script
  • Methods
Example

The following example assigns the empDownloadCursor method of the EgClass class to the download_cursor event for the table emp.

call ml_add_dnet_table_script( 'ver1', 'emp',
'download_cursor',EgPackage.EgClass.empDownloadCursor')


ml_add_java_connection_script

Function

Use this stored procedure to add or delete Java connection scripts in the consolidated database.

Parameters
Item | Description | Remarks
1 | version name | VARCHAR(128)
2 | event name | VARCHAR(128)
3 | script contents | For Adaptive Server Anywhere and MS SQL Server, this is TEXT. For ASE, this is VARCHAR(16384). For ASE prior to 12.5, this is VARCHAR(255). For DB2, this is VARCHAR(4000). For Oracle, this is VARCHAR.
Description

To delete a connection script, set the script contents parameter to NULL.

The script value is a public method in a class in the MobiLink synchronization server classpath (for example, MyClass.MyMethod).

When you add a script, the method is associated with the event and script version that you specify. If the version name is new, it is automatically inserted into the ml_version table.

See also
  • Adding and deleting scripts in your consolidated database
  • ml_add_connection_script
  • ml_add_table_script
  • ml_add_dnet_connection_script
  • ml_add_dnet_table_script
  • ml_add_java_table_script
  • Methods
Example

The following example is taken from the Samples\MobiLink\JavaAuthentication sample. It assigns the endConnection method of the CustEmpScripts class to the end_connection event.

call ml_add_java_connection_script( 'ver1',
'end_connection',
'CustEmpScripts.endConnection')


ml_add_java_table_script

Function

Use this stored procedure to add or delete Java table scripts in the consolidated database.

Parameters
Item | Description | Remarks
1 | version name | VARCHAR(128)
2 | table name | VARCHAR(128)
3 | event name | VARCHAR(128)
4 | script | For Adaptive Server Anywhere and MS SQL Server, this is TEXT. For ASE, this is VARCHAR(16384). For ASE prior to 12.5, this is VARCHAR(255). For DB2, this is VARCHAR(4000). For Oracle, this is VARCHAR.
Description

To delete a connection script, set the script parameter to NULL.

The script value is a public method in a class in the MobiLink synchronization server classpath (for example, MyClass.MyMethod).

When you add a script, the method is associated with the table, event, and script version that you specify. If the version name is new, it is automatically inserted into the ml_version table.

See also
  • Adding and deleting scripts in your consolidated database
  • ml_add_connection_script
  • ml_add_table_script
  • ml_add_dnet_connection_script
  • ml_add_dnet_table_script
  • ml_add_java_connection_script
  • Methods
Example

The following example is taken from the Samples\MobiLink\JavaAuthentication sample. It assigns the empDownloadCursor method of the CustEmpScripts class to the download_cursor event for the table emp.

call ml_add_java_table_script( 'ver1', 'emp',
'download_cursor','CustEmpScripts.empDownloadCursor')


Stored procedures to add or delete properties

The following stored procedure adds properties to the consolidated database. It can also be used to delete properties.

ml_add_property


ml_add_property

Function

Use this stored procedure to add or delete MobiLink properties. This stored procedure changes rows in the ml_property MobiLink system table.

Parameters
Item | Description | Remarks
1 | component_name | VARCHAR(128)
2 | prop_set_name | VARCHAR(128)
3 | prop_name | VARCHAR(128)
4 | prop_value | LONG VARCHAR
Description

  • component_name You can create records for which this parameter is ScriptVersion or SIS.

    To save properties by script version, set this to ScriptVersion.

    For server-initiated synchronization properties, set this to SIS. For more information, see Setting properties.

  • prop_set_name If the component_name is ScriptVersion, then this is the name of the script version.

    If the component_name is SIS, then this is the name of the Notifier, gateway, or carrier that you are setting a property for.

  • prop_name This is the name of the property.

    If the component_name is ScriptVersion, then this is a property that you define. You reference these properties using the following methods:

    • from DBConnectionContext: getVersion and getProperties

    • from ServerContext: getPropertiesByVersion, getProperties, and getPropertySetNames

    For more information, see MobiLink Java API Reference and MobiLink .NET API Reference.

    If the component_name is SIS, then this is a property of the Notifier, gateway, or carrier. For a list of properties, see MobiLink Notification Properties.

  • prop_value This is the value of the property.

    To delete a property, set the prop_value parameter to NULL.

Server-initiated synchronization

For server-initiated synchronization, the ml_add_property stored procedure allows you to set properties for Notifiers, gateways, and carriers.

For example, to add the property server=mailserver1 for an SMTP gateway called x:

ml_add_property( 'SIS','SMTP(x)','server','mailserver1');

The verbosity property applies to all Notifiers and gateways, and so you cannot specify a particular prop_set_name. To change the verbosity setting, leave the prop_set_name blank:

ml_add_property( 'SIS','','verbosity',2);

For more information about setting properties, see Setting properties. For a complete list of server-initiated synchronization properties, see MobiLink Notification Properties.

Script Version

For regular MobiLink synchronization, you can use this stored procedure to associate properties with a script version. In this case, set the component_name to ScriptVersion. You can specify whatever properties you like, and use Java and .NET classes to access them.

For example, to associate an LDAP server with a script version called MyVersion:

ml_add_property( 'ScriptVersion','MyVersion','ldap-server','MyServer' )

For more information, see the following methods in the MobiLink Java API Reference and MobiLink .NET API Reference:

  • from DBConnectionContext: getVersion and getProperties

  • from ServerContext: getPropertiesByVersion, getProperties, and getPropertySetNames

See also

ml_property


Utilities

About this chapter

This chapter describes MobiLink synchronization server utilities.

For information about MobiLink client utilities, see Utilities.

For information about other Adaptive Server Anywhere utilities, see Database Administration Utilities.


MobiLink stop utility

Stops the MobiLink synchronization server on the local machine.

Syntax

dbmlstop [ options ] [ server-name ]

Option | Description
@data | Reads options from the specified environment variable or configuration file.
-f | Forced shutdown. Use if a hard shutdown does not work.
-h | Hard shutdown. MobiLink stops all synchronizations and exits. Some remotes may report an error.
-q | Quiet mode. Suppresses the banner.
-t time | Soft shutdown, with a hard shutdown done after the specified time. time is a number followed by D, H, M, or S (for days, hours, minutes and seconds). For example, -t 10m specifies that the server should be shut down in 10 minutes or when current synchronizations complete, whichever is sooner. D, H, M, and S are not case sensitive.
-w | Waits for the MobiLink synchronization server to shut down before returning from the command.
Parameters

@data Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

See Hiding the contents of files using the dbfhide command-line utility.

Server-name If the MobiLink synchronization server is started using the -zs option, it must be shut down by specifying the same server name.

For more information, see -zs option.

Description

By default (if none of -f, -h or -t are specified), dbmlstop does a soft shutdown.

  • Soft shutdown means that the MobiLink synchronization server stops accepting new connections and exits when the current synchronizations are complete.

  • Hard shutdown means that the MobiLink synchronization server stops all synchronizations and exits. Some remotes may report an error.


MobiLink user authentication utility

Registers MobiLink users at the consolidated database. For Adaptive Server Anywhere remotes, the users must have previously been created at the remote databases with the CREATE SYNCHRONIZATION USER statement.

Syntax

dbmluser [ options ] -c "connection-string"
{ -f file | -u user [ -p password ] }

Option | Description
@data | Reads options from the specified environment variable or configuration file.
-c "keyword=value;..." | Supply database connection parameters. The connection string must give the utility permission to connect to the consolidated database using an ODBC data source. This parameter is required.
-d | Deletes the user name(s) specified by -f or -u.
-dl | Display messages in the window or on the command line and also in the log file, if specified.
-f filename | Read the user names and passwords from the specified file. The file should be a text file containing one user name and password pair on each line, separated by white space. You must specify either -f or -u.
-o filename | Log output messages to the specified file.
-os size | Limit the size of the output file. The size is the maximum file size for logging output messages, specified in bytes. Use the suffix k or m to specify units of kilobytes or megabytes, respectively. By default, there is no size limit. The minimum size limit is 10 kb.
-ot filename | Truncate the log file and then append output messages to it. The default is to send output to the screen.
-p password | Password to associate with the user. This option can only be used with -u.
-pc collation-id | Supply a database collation ID for character set translation of the user name and password. This should be one of the Adaptive Server Anywhere collation labels such as those listed in Initialization utility options. This option is required when user names and passwords are read from a file that is encoded in a different character set than the default character set determined by locale.
-u ml_username | Specify the user name to add (or delete, if used with -d). Only one user can be specified on a single command line. This option is used with -p if passwords are being used. You must specify either -f or -u.
Options

@data Use this option to read in options from the specified environment variable or configuration file. If both exist with the specified name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

See Hiding the contents of files using the dbfhide command-line utility.

Description

Given a user/password pair, the dbmluser utility first attempts to add the user. If the user has already been added to the consolidated database, it attempts to update the password for that user.

There are alternative ways to register user names in the consolidated database:

  • Use Sybase Central.

  • Specify the -zu+ command line option with dbmlsrv9. In this case, any existing MobiLink users that have not been added to the consolidated database are added when they first synchronize.

The MobiLink user must already exist in a remote database. To add users at the remote, you have the following options:

  • For Adaptive Server Anywhere remotes, set the name with CREATE SYNCHRONIZATION USER and synchronize with that user name.

  • For UltraLite remotes, you can either use the user_name field of the ul_synch_info structure; or in Java, use the SetUserName() method of the ULSynchInfo class before synchronizing.

See also
  • Authenticating MobiLink Users


Certificate reader utility

Use the readcert utility to display values within a certificate and validate the chain of certificates.

Syntax

readcert certificate-name

Description

The certificate you specify can be elliptic-curve or RSA.

When synchronization occurs through an ECC_TLS or RSA_TLS synchronization stream, the MobiLink synchronization server sends its certificate to the client, as well as the certificate of the entity that signed it, and so on up to a self-signed root. The client checks that the chain is valid and that it trusts the root certificate in the chain.

This utility scans an X509 authentication certificate and displays the field values. It then checks that the chain of certificates is valid. A validation error is reported if any of the certificates in the chain have expired, are in the wrong order, or are missing.

See also

  • Certificate generation utility


Certificate generation utility

Use the gencert utility to create new elliptic-curve or RSA certificates, or to sign pre-generated certificate requests.

Syntax

gencert [ -c | -s ] [ -r | -q ]

Option | Description
-c | Specifies a certificate you can use to sign other certificates. If used with -r, generates an enterprise root certificate.
-s | Specifies a server identity certificate. The server identity is a combination of a server's private key and public certificate. You reference the server identity certificate when you start the MobiLink synchronization server (for MobiLink transport-layer security) or database server (for Adaptive Server Anywhere client-server transport-layer security). If used with -r, generates a self-signed server certificate.
-r | Specifies a self-signed root certificate. If used with -s, gencert creates a self-signed server certificate. If used with -c, gencert creates an enterprise root certificate you can use to sign other certificates. If you specify gencert -r with no additional options, gencert creates a certificate you can use as a server certificate or an enterprise root. This option is not compatible with -q.
-q request-file | Sign a pre-generated certificate request. If used with -s, gencert creates a server certificate. If used with -c, gencert creates an enterprise root certificate you can use to sign other certificates. If you specify gencert -q with no additional options, gencert creates a certificate you can use as a server certificate or an enterprise root. The -q option is not compatible with -r.

If you do not specify -s or -c , the certificate contains the functionality provided by both options, so it can be used to sign other certificates or you can use it directly as a server certificate.

Description

You can use the gencert utility to generate trusted public certificates, private keys, and server certificates used to secure MobiLink synchronizations or Adaptive Server Anywhere client-server communication. This utility creates X509 certificates (a standard certificate format) for various security configurations.

Gencert prompts you for the following information:

  • Cipher Gencert prompts you to choose an elliptic-curve or RSA cipher. If you are generating an elliptic-curve certificate, gencert generates an elliptic-curve key pair. If you are generating an RSA certificate, it prompts for a key size between 512 and 2048, and then creates a certificate using RSA. (In general, longer keys provide stronger encryption but take longer to process.)

    Whichever cipher you choose, you must specify that cipher when you start the server and client. For ECC certificates, specify ecc_tls, and for RSA certificates, you can specify rsa_tls or rsa_tls_fips.

  • Country, State/Province, and Locality These values provide general certificate identification. The locality fields are also required by third-party Certificate Authorities if you plan to use globally-signed certificates.

    For more information about using Certificate Authorities, see Globally-signed certificates.

  • Organization, Organizational Unit, and Common Name These fields provide additional security that the client is authenticating the correct certificate. On the client side, they correspond to the certificate_company, certificate_unit, and certificate_name protocol options, respectively.

    See Verifying certificate fields.

  • Serial number You are prompted to choose a serial number for the certificate. The serial number must use alphanumeric characters.

  • Certificate valid for how many years You are prompted for the period (in years) that the enterprise root certificate remains valid. If the enterprise root certificate expires, all signed server certificates will also be invalid. Following the specified period, you will need to regenerate the enterprise root, each server certificate, and the public certificates distributed to clients.

  • Enter password to protect private key This is the password you will specify in the certificate_password protocol option.

  • Enter file path to save certificate Choose a file name and location for the certificate.

  • Enter file path to save private key Choose a file name and location for the private key.

  • Enter file path to save server identity You will only be prompted for this information if you are creating a self-signed root certificate. Choose a file name and location for the server certificate.

See also

For more information about using certificates to secure MobiLink synchronizations, see MobiLink Transport-Layer Security.

For more information about using certificates to secure Adaptive Server Anywhere RDBMSs, see Adaptive Server Anywhere Transport-Layer Security.

  • Certificate reader utility
  • -ec server option
  • Encryption connection parameter [ENC]
  • FIPS 140-2 certification
Examples

  • The following example uses the gencert -r option to generate an RSA self-signed server certificate.

    > gencert -r
Certificate Generation Tool
Choose certificate type ((R)SA or (E)CC): R
Enter key length (512-2048): 1024
Generating key pair...
Country: CA
State/Province: ON
Locality: Waterloo
Organization: Sybase, Inc.
Organizational Unit: IAS
Common Name: MobiLink
Serial Number: 123
Certificate valid for how many years: 12
Enter password to protect private key: mypwd123
Enter file path to save certificate: public_cert.crt
Enter file path to save private key: server_key.pri
Enter file path to save server identity: server_cert.crt

    You distribute the self-signed public certificate public_cert.crt to clients. The server certificate server_cert.crt includes the server certificate and private key and is stored with the MobiLink synchronization server (for MobiLink transport-layer security) or the database server (for Adaptive Server Anywhere client-server transport-layer security).

  • The following example uses the gencert -r and -c options to generate an enterprise root certificate.

    > gencert -r -c
Certificate Generation Tool
Choose certificate type ((R)SA or (E)CC): E
Generating key pair...
Country: CA
State/Province: ON
Locality: Waterloo
Organization: Sybase, Inc.
Organizational Unit: IAS
Common Name: MobiLink
Serial Number: 123
Certificate valid for how many years: 15
Enter password to protect private key: mypwd123
Enter file path to save certificate: public_root_cert.crt
Enter file path to save private key: root_key.pri

    The public enterprise root certificate public_root_cert.crt is distributed to clients. Store the enterprise private key root_key.pri in a secure location. You can use the generated files to sign server certificates.

  • The following example uses the gencert -s option to create a signed server certificate.

    > gencert -s
Certificate Generation Tool
Choose certificate type ((R)SA or (E)CC): E
Generating key pair...
Country: CA
State/Province: ON
Locality: Waterloo
Organization: Sybase, Inc.
Organizational Unit: IAS
Common Name: MobiLink
Serial Number: 123
Certificate valid for how many years: 7
Enter file path of signer's certificate: public_root_cert.crt
Enter file path of signer's private key: root_key.pri
Enter password for signer's private key: mypwd123
Enter password to protect private key: SERV1privatekeypwd
Enter file path to save server identity: serv1_cert.crt

    The enterprise root certificate created in the previous example is used as the signing certificate. You reference the server identity serv1_cert.crt and the password SERV1privatekeypwd when you start the MobiLink synchronization server or your database server.

  • The following example uses the gencert option -q to sign a certificate request called certreq.txt.

    >gencert -s -q certreq.txt
Certificate Generation Tool
Serial Number: 01
Certificate valid for how many years: 10
Enter file path of signer's certificate: rsaroot.crt
Enter file path of signer's private key: rsaroot.key
Enter password for signer's private key: test
Enter file path to save certificate: testcert.crt
Save entire chain (y/n): y

    The certificate request is created using reqtool. For more information, see

    • Globally-signed certificates for MobiLink transport-layer security.

    • Globally-signed certificates for Adaptive Server Anywhere transport-layer security.


MobiLink System Tables

About this chapter

This chapter describes the MobiLink administration tables.

Introduction
ml_connection_script
ml_device
ml_device_address
ml_listening
ml_property
ml_qa_delivery
ml_qa_delivery_client
ml_qa_global_props
ml_qa_global_props_client
ml_qa_notifications
ml_qa_repository
ml_qa_repository_client
ml_qa_repository_content_client
ml_qa_repository_props
ml_qa_repository_props_client
ml_qa_repository_staging
ml_qa_status_staging
ml_script
ml_script_version
ml_scripts_modified
ml_subscription
ml_table
ml_table_script
ml_user


Introduction

The MobiLink system tables store information about MobiLink users, subscriptions, tables, scripts, and script versions. They are created when you run the MobiLink setup scripts for your consolidated database, and are updated as you use MobiLink. They are not like RDBMS system tables in that you can alter them directly.

For more information about how to create these tables, see Setting up a consolidated database.

The MobiLink system tables are stored in the consolidated database. Unlike most system tables, you can modify them. However, except in rare circumstances you should not alter them directly. You should never alter MobiLink system tables starting with ml_qa.

Adaptive Server Anywhere remote databases also have system tables. For more information, see System Tables. UltraLite databases do not have system tables.

Notes

  • This chapter provides data types for the MobiLink system tables in Adaptive Server Anywhere consolidated databases. In some RDBMSs, the data types are slightly different.

  • IBM DB2 UDB version 5.2 only supports column names and other identifiers of 18 characters or less. In a DB2 5.2 consolidated database, MobiLink system tables are truncated where necessary.


ml_connection_script

For a given script version, associates a script with a given event.

Column | Description
version_id | INTEGER. Primary key. The version of the connection script. The version_id column references the version_id column of the ml_script_version table.
event | VARCHAR(128). Primary key. The event column stores the name of the event that triggers the connection script.
script_id | INTEGER. Foreign key. The script_id column references the script_id column of the ml_script system table. The text of the connection script is stored in the ml_script system table.
Remarks

There is a view, ml_connection_scripts, that makes it easier to view the contents of the ml_connection_script MobiLink system table.


ml_device

This table is used only for server-initiated synchronization. It stores device names that are required by device tracking.

Column | Description
device_name | VARCHAR(255). Primary key.
listener_version | VARCHAR(128). Not null.
listener_protocol | INTEGER. Not null.
info | VARCHAR(255). Not null.
ignore_tracking | CHAR(1). Not null.
source | VARCHAR(255). Not null.
Description

  • device_name A name given to the device. This name is extracted from the operating system unless you specify a name using the dblsn -e option.

  • listener_version This field contains the SQL Anywhere Studio version number for the installed software on the device. Changing this value does not affect the operation of the software, but may be useful for diagnostic purposes.

  • listener_protocol This value is 0 for Listeners from versions of SQL Anywhere Studio prior to 9.0.1, and Listeners started with the -s option; 1 for post-9.0.0 Palm Listeners; and 2 for post-9.0.0 Windows Listeners started without -s.

  • info Information about the device. This field is populated if you provide information using the dblsn -f option.

  • ignore_tracking If this is y, tracking information is not written to the row. If it is n, tracking information is written to the row.

  • source This is tracking if the row was created by automatic device tracking. Otherwise, it is blank unless you change it using stored procedures to add information about where the data in this row came from. Unless it is set to tracking, the value in this column does not affect the operation of the software.

Remarks

The MobiLink system tables ml_device, ml_device_address, and ml_listening contain information about devices for server-initiated synchronization. DeviceTracker gateways use this information to address target devices by MobiLink user name.

In most cases, you should not need to alter these tables. However, if your device does not support device tracking or if you want to override device tracking for troubleshooting purposes, you can add or delete rows to this system table using pre-defined stored procedures. For more information, see Using device tracking with Listeners that don't support it.

If you want to stop automatic tracking, set override_tracking to y. In this case, it is also recommended that you use a source name other than tracking. For more information, see ml_set_device.

See also
  • ml_set_device
  • ml_delete_device


ml_device_address

This table is used only for server-initiated synchronization. It stores addressing information that is required by device tracking.

Column | Description
device_name | VARCHAR(255). Primary key. Foreign key references dbo.ml_device. Not null.
medium | VARCHAR(255). Primary key. Not null.
address | VARCHAR(255). Not null.
active | CHAR(1). Not null.
last_modified | Timestamp. Not null. Default timestamp.
ignore_tracking | CHAR(1). Not null.
source | VARCHAR(255). Not null.
Description

  • device_name A name given to the device. This name is extracted from the operating system unless you specify a name using the dblsn -e option.

  • medium For UDP, this is _UDP_. Otherwise, it is the network provider ID.

  • address For UDP, this is ip:port-number, where ip is an IP address or host name. For SMTP, this is the phone number.

  • active This is y for active, and n otherwise. A DeviceTracker gateway may deactivate a UDP channel if it is unresponsive and there is a fallback SMTP delivery path.

  • last_modified This tells when this row was last modified.

  • ignore_tracking If this is y, tracking information is not written to the row. If it is n, tracking information is written to the row.

  • source This is tracking if the row was created by automatic device tracking. Otherwise, it is blank unless you change it using stored procedures to add information about where the data in this row came from. Unless it is set to tracking, the value in this column does not affect the operation of the software.

Remarks

The MobiLink system tables ml_device, ml_device_address, and ml_listening contain information about devices for server-initiated synchronization. DeviceTracker gateways use this information to address target devices by MobiLink user name.

In most cases, you should not need to alter these tables. However, if your device does not support device tracking or if you want to override device tracking for troubleshooting purposes, you can add or delete rows to this system table using pre-defined stored procedures. For more information, see Using device tracking with Listeners that don't support it.

If you want to stop automatic tracking, set override_tracking to y. In this case, it is also recommended that you use a source name other than tracking. For more information, see ml_set_device_address.

See also
  • ml_set_device_address
  • ml_delete_device_address


ml_listening

This table is used only for server-initiated synchronization. It maps a MobiLink user name to a device name for use by device tracking.

Column | Description
ml_user | VARCHAR(128). Primary key. Not null.
device_name | VARCHAR(255). Foreign key references dbo.ml_device. Not null.
listening | CHAR(1). Not null.
ignore_tracking | CHAR(1). Not null.
source | VARCHAR(255). Not null.
Description

  • ml_user This is the MobiLink user name, which uniquely identifies a remote database.

    If you use the dblsn -t+ option, this is the alias that you have defined for the ml_user. For more information, see Listener options for device tracking.

  • device_name A name given to the device. This name is extracted from the operating system unless you specify a name using the dblsn -e option.

  • listening This is y for an active Listener; otherwise it is n. This field is set when you use the dblsn option -t, or you can manually set it with stored procedures.

  • ignore_tracking If this is y, tracking information is not written to the row. If it is n, tracking information is written to the row.

  • source This is tracking if the row was created by automatic device tracking. Otherwise, it is blank unless you change it using stored procedures to add information about where the data in this row came from. The value in this column does not affect the operation of the software.

Remarks

The MobiLink system tables ml_device, ml_device_address, and ml_listening contain tracked information about devices for server-initiated synchronization. DeviceTracker gateways use this information to address target devices by MobiLink user name.

In most cases, you should not need to alter these tables. However, if your device does not support device tracking or if you want to override device tracking for troubleshooting purposes, you can add or delete rows in this table using pre-defined stored procedures. For more information, see Using device tracking with Listeners that don't support it.

If you want to stop automatic tracking, set override_tracking to Yes. In this case, it is also recommended that you use a source name other than tracking.

See also
  • ml_set_listening
  • ml_delete_listening


ml_property

Stores some MobiLink properties.

Column | Description
component_name | VARCHAR(128). First part of the composite primary key.
property_set_name | VARCHAR(128). Second part of the composite primary key.
property_name | VARCHAR(128). Third part of the composite primary key.
property_value | LONG VARCHAR.
Description

  • component_name For user-defined properties, this can be ScriptVersion or SIS.

  • prop_set_name If the component_name is ScriptVersion, then this is the name of the script version.

    If the component_name is SIS, then this is the name of the Notifier, gateway, or carrier that you are setting a property for.

  • prop_name This is the name of the property.

    If the component_name is ScriptVersion, then this is a user-defined property.

    If the component_name is SIS, then this is a property of the Notifier, gateway, or carrier. For a list of properties, see MobiLink Notification Properties.

  • prop_value This is the value of the property.

Remarks

This table stores name-value pairs. Some of the properties in this table are used internally by MobiLink. In addition, you can use the stored procedure ml_add_property to add or delete rows in this table.

You can use the component_name ScriptVersion to store information on per script version basis that can be accessed by Java or .NET scripting logic.

This table has a composite primary key made up of component_name, property_set_name, and property_name.

See also
  • ml_add_property


ml_qa_delivery

This table is used only for QAnywhere applications.

Column | Description
msgid | VARCHAR(255). Globally unique message identifier.
address | VARCHAR(255). Address of the target recipient.
client | VARCHAR(255).Client of the target recipient.
status | INTEGER. The status of the message. Can be 1 (pending), 10 (receiving), 30 (expired), 50 (receivable), or 60 (received).
statustime | TIMESTAMP. The time this status was achieved.
verbiage | VARCHAR (32767). Localized description of the status (if any).
syncstatus | INTEGER. Indicates the state of the synchronization between the client and server with respect to this message Can be 0 (not in sync), 1 (in sync), or 2 (message should not be synchronized).
receiverid | VARCHAR(128). An identifier set by the receiver that identifies the receiver of the message, if any.
last_modified | TIMESTAMP. Indicates the last time the status was changed.
Remarks

The owner of this table is ml_qa_user_group.


ml_qa_delivery_client

Column | Description
msgid | VARCHAR(255). Globally unique message identifier.
address | VARCHAR(255). Address of the target recipient.
client | VARCHAR(255).Client of the target recipient.
status | INTEGER. The status of the message. Can be 1 (pending), 10 (receiving), 30 (expired), 50 (receivable), or 60 (received).
statustime | TIMESTAMP. The time this status was achieved.
verbiage | VARCHAR (32767). Localized description of the status (if any).
syncstatus | INTEGER. Indicates the state of the synchronization between the client and server with respect to this message Can be 0 (not in sync), 1 (in sync), or 2 (message should not be synchronized).
receiverid | VARCHAR(128). An identifier set by the receiver that identifies the receiver of the message, if any.
Remarks

The owner of this table is ml_qa_user_group.


ml_qa_global_props

This table is used only for QAnywhere applications. It contains global name-value pairs that are used in transmission rules.

Column | Description
client | VARCHAR(255). Primary key. The client associated with the property. A client value of ' ' indicates a property that is global to all clients.
name | VARCHAR(255). Primary key. The name of the property.
modifiers | INTEGER. Bitfields used to further describe the property. Currently, only the first bit is used to indicate a property that should not be synchronized. All other bit fields are reserved for future use.
value | VARCHAR(32767). The value of the property.
last_modified | TIMESTAMP. Indicates the last time the value was changed. This is necessary to indicate when a property needs to be synchronized with the client.
Remarks

This table has a composite primary key made up of client and name.

The owner of this table is ml_qa_user_group.

Do not modify the contents of this table.


ml_qa_global_props_client

This table is used only for QAnywhere applications. It is identical to ml_qa_global_props. This table is created on the remote database by the QAnywhere Agent as needed.

Do not modify the contents of this table.

Column | Description
name | VARCHAR(255). Primary key. The name of the property.
modifiers | INTEGER. Bitfields used to further describe the property. Currently, only the first bit is used to indicate a property that should not be synchronized. All other bit fields are reserved for future use.
value | VARCHAR(32767). The value of the property.
Remarks

The owner of this table is ml_qa_user_group.

Do not modify the contents of this table.

See also
  • ml_qa_global_props


ml_qa_notifications

This table is used only for QAnywhere applications. It is used by the Notifier to determine which QAnywhere users to notify to initiate synchronization.

Column | Description
user_id | INTEGER. Primary key.
name | VARCHAR(128). The MobiLink user name that uniquely identifies a remote database.
Remarks

The owner of this table is ml_qa_user_group.

Do not modify the contents of this table.


ml_qa_repository

This table is used only for QAnywhere applications. It stores messages and their properties.

Column | Description
seqno | BIGINT. Used to give a total ordering to the messages, this is necessary for true queuing.
msgid | VARCHAR(255). Primary key. Globally unique message identifier.
originator | VARCHAR(255). The name of the originating MobiLink user.
priority | INTEGER. A number from 0 to 9. Messages with a higher priority number are delivered before messages with a lower priority. The default is 4.
expires | TIMESTAMP . Expiry time after which the message might not be delivered.
kind | INTEGER. Indicates whether the message is binary (1) or text (2).
contentsize | BIGINT. The size of the message. For binary messages, this is the number of bytes. For text messages, this is the number of characters.
props | LONG BINARY. An encoding of the message properties. For information about the properties, see ml_qa_repository_props.
content | LONG BINARY. The content of the message. Text messages are encoded as UTF-8.
Remarks

The owner of this table is ml_qa_user_group.

Do not modify the contents of this table.


ml_qa_repository_client

This table is used only for QAnywhere applications. It is identical to ml_qa_repository. This table is created on the remote database by the QAnywhere Agent as needed.

Column | Description
seqno | BIGINT. Used to give a total ordering to the messages, this is necessary for true queuing.
msgid | VARCHAR(255). Primary key. Globally unique message identifier.
syncstatus | INTEGER. Indicates the state of the synchronization between the client and server with respect to this message. 0 means that they are not in sync; 1 means that they are in sync; 2 means that a message should not be synchronized.
originator | VARCHAR(255). The name of the originating MobiLink user.
priority | INTEGER. A number from 0 to 9. Messages with a higher priority number are delivered before messages with a lower priority. The default is 4.
expires | TIMESTAMP . Expiry time after which the message might not be delivered.
kind | INTEGER. Indicates whether the message is binary (1) or text (2).
contentsize | BIGINT. The size of the message. For binary messages, this is the number of bytes. For text messages, this is the number of characters.
props | LONG BINARY. An encoding of the message properties. For information about the properties, see ml_qa_repository_props.
content | LONG BINARY. The content of the message. Text messages are encoded as UTF-8.
Remarks

The owner of this table is ml_qa_user_group.

Do not modify the contents of this table.

See also
  • ml_qa_repository


ml_qa_repository_content_client

This table is used only for QAnywhere applications. It is identical to ml_qa_repository_content. This table is created on the remote database by the QAnywhere Agent as needed.

The owner of this table is ml_qa_user_group.

Do not modify the contents of this table.


ml_qa_repository_props

This table is used only for QAnywhere applications. This is an expansion of the props column in the ml_qa_repository table. Properties are only expanded as needed by the transmission rules engine. If there are no associated rules, a property is not expanded.

Column | Description
msgid | VARCHAR(255). Primary key. Globally unique message identifier.
name | VARCHAR(255). Primary key. The name of the property. If the property name was provided in Unicode, it is translated to the native character set of the database.
value | VARCHAR(32767). The value of the property.
Remarks

The owner of this table is ml_qa_user_group.

Do not modify the contents of this table.

This table has a composite primary key made up of msgid and name.


ml_qa_repository_props_client

This table is used only for QAnywhere applications. It is identical to ml_qa_repository_props. This table is created on the remote database by the QAnywhere Agent as needed.

Do not modify the contents of this table.

Column | Description
msgid | VARCHAR(255). Primary key. Globally unique message identifier.
name | VARCHAR(255). Primary key. The name of the property. If the property name was provided in Unicode, it is translated to the native character set of the database.
value | VARCHAR(32767). The value of the property.
Remarks

The owner of this table is ml_qa_user_group.

See also
  • ml_qa_repository_props


ml_qa_repository_staging

This table is used only for QAnywhere applications. It contains messages that are to be sent to a QAnywhere client.

Column | Description
seqno | BIGINT. Used to give a total ordering to the messages, this is necessary for true queuing.
msgid | VARCHAR(255). Primary key. Globally unique message identifier.
destination | VARCHAR(255). The address of the message.
originator | VARCHAR(255). The name of the originating MobiLink user.
status | VARCHAR(255). The status of the message. Can be pending, receiving, received, unreceivable, expired, or cancelled. The default is pending.
statustime | TIMESTAMP. The last time the status was changed.
uploaded | BIT. Indicates whether the sender and recipient are in sync on the status of the message. 0 means that they are not in sync and 1 indicates that they are in sync. The default is 0.
expires | TIMESTAMP. Expiry time after which the message will not be delivered.
priority | INTEGER. A number from 0 to 9. Messages with a higher priority number will always be delivered before messages with a lower priority. The default is 4.
props | LONG BINARY. An encoding of the message properties.
kind | INTEGER. Indicates whether the message is binary (1) or text (2).
content | LONG BINARY. The content of the message. Text messages are encoded as UTF-8.
contentsize | BIGINT. The size of the message. For binary messages, this is the number of bytes. For text messages, this is the number of characters.
mluser | VARCHAR(128). The MobiLink user name that uniquely identifies a remote database.
Remarks

The owner of this table is ml_qa_user_group.

Do not modify the contents of this table.


ml_qa_status_staging

This table is used only for QAnywhere applications. It is a staging table that is used when synchronizing status changes with the originating client.

Column | Description
msgid | VARCHAR(255). Primary key. Globally unique message identifier.
status | VARCHAR(255). The status of the message. Can be pending, receiving, received, unreceivable, expired, or cancelled. The default is pending.
statustime | TIMESTAMP. The last time the status was changed.
mluser | VARCHAR(128). The MobiLink user name that uniquely identifies a remote database.
Remarks

The owner of this table is ml_qa_user_group.

Do not modify the contents of this table.


ml_script

Stores the text of all scripts.

Column | Description
script_id | INTEGER. Primary key. The script_id column stores a unique integer that identifies the script.
script | TEXT. The script column stores the text of the script.
script_language | VARCHAR(128). The script_language column stores the scripting language used for the script. The scripting language can be sql, java, or dnet.


ml_script_version

Stores the name, ID and comment of script associated with each script version.

Column | Description
version_id | INTEGER. Primary key. The version_id column stores a unique integer that identifies the version.
name | VARCHAR(128). The name column stores the arbitrary name given to the version.
description | TEXT. The description column stores the arbitrary description given to the version. The description is not used by MobiLink, but is useful for application-specific comments. For example, you could describe the purpose of a given script version.


ml_scripts_modified

Stores the last time script tables were changed. MobiLink server checks this table to determine if it must load new scripts.

Column | Description
last_modified | DATETIME. Primary key. The last_modified column stores the last time when the ml_script_version, ml_script or ml_connection_script system table was altered.


ml_subscription

Keeps track of the log offsets (or progress) per subscription for Adaptive Server Anywhere remote databases.

Column | Description
user_id | INTEGER. Primary key. The user_id column references the user_id column of the ml_user table. This is the ID of a user who has subscribed to the publication.
subscription_id | VARCHAR(128). Primary key. The subscription_id is a number that is generated by Adaptive Server Anywhere on the remote.
publication_name | VARCHAR(128). Primary key. The publication_name stores the user-defined name for the publication.
progress | NUMERIC(20,0). The progress, also called the offset or state, refers to the point in the remote transaction log up to which all operations for the subscription have been uploaded. This column is used for version 8.0 and up databases. For version 7 databases, the progress is stored in the ml_user table.
last_download_time | TIMESTAMP. Indicates the last time a download was applied to the consolidated for a given user or subscription. The default is January 1, 1900, 00:00:00.
last_upload_time | TIMESTAMP. Indicates the last time an upload was applied to the consolidated for a given user or subscription. The default is January 1, 1900, 00:00:00.
Remarks

The progress, also called the offset or state, refers to a position in the transaction log of the remote database. It indicates the point to which all operations for the subscription have been uploaded and acknowledged. Dbmlsync uses the offset to decide what data to upload.

On the remote database, the offset is stored in the progress column of the SYS.SYSSYNC system table.

On the consolidated database, the offset is stored in the progress column of the ml_user table for version 7.x databases, and in the progress column of the ml_subscription table for version 8.0 and up databases.


ml_table

Stores names of remote tables. This list includes any table marked as a synchronized table in Sybase Central.

Column | Description
table_id | INTEGER. Primary key. The table_id column stores a unique integer identifying the table.
name | VARCHAR(128). The name column stores the arbitrary name given to the table.


ml_table_script

For a given script version, associates a table script with a given table and event.

Column | Description
version_id | INTEGER. Primary key. The version_id column references the version_id column of the ml_script_version table.
table_id | INTEGER. Primary key. The table_id column references the table_id column of the ml_table system table.
event | VARCHAR(128). Primary key. The event column stores the name of the event.
script_id | INTEGER. The script_id column references the script_id column of the ml_script table. The script is stored in the ml_script table.
Remarks

There is a view, ml_table_scripts, that makes it easier to view the contents of the ml_table_script MobiLink system table.


ml_user

Stores all registered MobiLink users, including their password and their synchronization state. The progress in this table is used only for UltraLite remotes or version 7 Adaptive Server Anywhere remotes.

Column | Description
user_id | INTEGER. Primary key. The user_id column stores a unique integer identifying the user. This value is only used internally by MobiLink.
name | VARCHAR(128). The name column stores the arbitrary name given to the user.
commit_state | INTEGER. The commit_state column stores the state.
progress | NUMERIC(20,0). The progress, also called the log offset or state, refers to the point in the transaction log up to which all operations for subscriptions have been uploaded and acknowledged. This column is used for version 7 databases. For version 8.0 and up databases, the progress is stored in the ml_subscription table.
hashed_password | BINARY(20). The hashed_password column stores the MobiLink user's password in obfuscated form. If there is no password, this value is NULL. (This is not recommended.)
last_download_time | TIMESTAMP. Indicates the last time a download was applied to the consolidated for a given user or subscription. The default is January 1, 1900, 00:00:00.
last_upload_time | TIMESTAMP. Indicates the last time an upload was applied to the consolidated for a given user or subscription. The default is January 1, 1900, 00:00:00.
Remarks

The progess, also called the log offset or state, refers to a position in the transaction log of the remote database. It indicates the point to which all operations for the subscription have been uploaded and acknowledged. dbmlsync uses the offset to decide what data to upload.

On the remote database, the offset is stored in the progress column of the SYS.SYSSYNC system table.

On the consolidated database, the offset is stored in the progress column of the ml_user table for version 7.x databases, and in the progress column of the ml_subscription table for version 8.0 and up databases.


DataType Conversions

About this chapter

This chapter provides information about the conversion of data types that must take place when a MobiLink synchronization server communicates with a consolidated database that is not Adaptive Server Anywhere. The following tables identify these conversions.

If you are writing synchronization scripts in .NET languages or in Java, you may need to know how to map SQL data types to Java and .NET data types. For more information, see SQL-.NET data types and SQL-Java data types.

Note
Only supported data types are presented in this chapter.

Adaptive Server Enterprise data mapping
IBM DB2 data mapping
Oracle data mapping
Microsoft SQL Server data mapping

Previous Next


Adaptive Server Enterprise data mapping

The following table identifies how Adaptive Server Anywhere or UltraLite data types are mapped to Adaptive Server Enterprise data types.

Adaptive Server Anywhere or UltraLite data type | Adaptive Server Enterprise data type
bit | bit
tinyint | tinyint
smallint | smallint
int | int
integer | integer
decimal [defaults p=30, s=6] | numeric(30,6)
numeric [defaults p=30 s=6] | numeric(30,6)
float | real
real | real
double | float
smallmoney | numeric(10,4)
money | numeric(19,4)
date | datetime
time | datetime
timestamp | datetime
smalldatetime | datetime
datetime | datetime
char(n) | varchar(n)
character(n) | varchar(n)
varchar(n) | varchar(n)
character varying(n) | varchar(n)
long varchar | text
text | text
binary(n) | binary(n)
long binary | image
image | image
bigint | numeric(20,0)
uniqueidentifier | varchar(n) 1

1 n must be greater than 36.


IBM DB2 data mapping

The following table identifies how Adaptive Server Anywhere or UltraLite data types are mapped to IBM DB2 data types.

Adaptive Server Anywhere or UltraLite data type | IBM DB2 data type
bit | smallint
tinyint | smallint
smallint | smallint
int | int
integer | int
bigint | decimal(20,0)
char(1–4000) | varchar(n)
char(4001–32767) | long varchar
character(1–4000) | varchar(n)
character(4001–32767) | long varchar
varchar(1–4000) | varchar(n)
varchar(4001–32767) | long varchar
character varying(1–4000) | varchar(n)
character varying(4001–32767) | long varchar or CLOB(n)
long varchar | long varchar or CLOB(n)
text | long varchar
binary(1–4000) | varchar for bit data or BLOB(n)
binary(4001–32767) | long varchar for bit data or BLOB(n)
long binary | long varchar for bit data or BLOB(n)
image | long varchar for bit data or BLOB(n)
decimal [defaults p=30, s=6] | decimal(30,6)
numeric [defaults p=30 s=6] | decimal(30,6)
real | real
float | float
double | float
smallmoney | decimal(10,4)
money | decimal(19,4)
date | date
time | time
smalldatetime | timestamp
datetime | timestamp
timestamp | timestamp
uniqueidentifier | varchar(n) 1

1 n must be greater than 36.


Oracle data mapping

The following table identifies how Adaptive Server Anywhere or UltraLite data types are mapped to Oracle data types.

Adaptive Server Anywhere or UltraLite data type | Oracle data type
bit | number(1,0)
tinyint | number(3,0)
smallint | number(5,0)
int | number(11,0)
integer | number(11,0)
bigint | number(20,0)
decimal(prec, scale) | number(prec, scale)
numeric(prec, scale) | number(prec, scale)
float | float
real | real
smallmoney | numeric(10,4)
money | number(19,4)
date | date
time | date
timestamp | date
smalldatetime | date
datetime | date
char(n) | varchar(n) or CLOB(n)
varchar(n) | varchar(n) or CLOB(n)
long varchar | CLOB
binary(n) | raw(n) or BLOB(n)
varbinary(n) | raw(n) or BLOB(n)
long binary | BLOB
uniqueidentifier | varchar2(n) 1

1 n must be greater than 36.

The LONG data types are deprecated in Oracle 8, 8i and 9i.

For Oracle LONG data types to synchronize properly, you must check the Oracle Force Retrieval of Long Columns ODBC option in the ODBC data source configuration dialog.


Microsoft SQL Server data mapping

The following table identifies how Adaptive Server Anywhere or UltraLite data types are mapped to Microsoft SQL Server data types.

Adaptive Server Anywhere or UltraLite data type | Microsoft SQL Server data type
bit | bit
tinyint | tinyint
smallint | smallint
int | int
integer | int
bigint | numeric(20,0) or bigint (SQL Server 2000 only)
decimal [defaults p=30, s=6] | decimal(30, 6)
numeric [defaults p=30 s=6] | numeric(30, 6)
float | float
real | real
smallmoney | smallmoney
money | money
date | datetime
time | datetime
timestamp | datetime
smalldatetime | datetime
datetime | datetime
char(n) | varchar(n) or text
character(n) | varchar(n)
varchar(n) | varchar(n) or text
long varchar | text
binary(n) | binary(n) or image
long binary | image
double | float
uniqueidentifier | uniqueidentifier


Character Set Considerations

About this chapter

This chapter describes how to handle international language issues in MobiLink applications.

Character set considerations


Character Set Considerations

Character set considerations

Each character of text is represented in one or more bytes. The mapping from characters to binary codes is called the character set encoding. Some character sets used for languages with small alphabets, such as European languages, use a single-byte representation. Others, such as Unicode, use a double-byte representation. Because they use twice the storage space for each character, double-byte character sets can represent a much larger number of characters.

Conversion errors can occur or data can be lost when text using one character set must be translated to another character set. Not all characters can be represented in all character sets. In particular, single-byte character sets can represent a much smaller number of characters than multi-byte systems because of the limited number of codes available.

When the character set of your MobiLink remote database is the same as your consolidated database, character translation issues are avoided.

Text often needs to be sorted to build indexes and to prepare ordered result sets, such as directory listings. The sort order identifies the order of the characters. For example, a sort order typically states that the letter "a" comes before the letter "b" , which comes before the letter "c" .

Each database has a collation sequence. You set the collation sequence when you create the database, although how you do so can differ between database systems. The collation sequence defines both the character set and the sort order for that database.

Tip
Whenever possible, define the collation sequence of your remote database to be the same as that of your consolidated database. This arrangement reduces the chance of erroneous translations.

For more information, see Character sets in UltraLite and International Languages and Character Sets.


Character set translation during synchronization: Windows

During synchronization, characters may need to be translated from one character set to another. The following translations occur as characters are passed between the remote application and the consolidated database.

Character set translation during upload

The MobiLink client sends data to the MobiLink synchronization server using the character set of the remote database.

  1. The MobiLink synchronization server communicates with the consolidated database using the Unicode ODBC API. To do so, the MobiLink synchronization server translates all characters received from the remote database into Unicode.

  2. If necessary, the ODBC driver for the consolidated database server translates the characters from Unicode into the character set of your consolidated database. This translation is controlled solely by the ODBC driver for your consolidated database system. Hence, behavior can differ between two different database systems, particularly systems made by different manufacturers. MobiLink synchronization works with a number of database systems. Check the documentation of your particular consolidated server and ODBC driver for details.

Character set translation during download

  1. The ODBC driver for the consolidated database system receives characters in the coding of the consolidated database. It translates these characters into Unicode to pass them through the Unicode API to the MobiLink synchronization server. This translation is controlled solely by the ODBC driver for your consolidated database system. Check the documentation of your particular consolidated server and ODBC driver for details.

  2. The MobiLink synchronization server receives characters through the Unicode ODBC API. If the remote database uses a different character set, the MobiLink synchronization server translates the characters before downloading them.

Examples

  • UltraLite applications on Windows CE devices use the Unicode character set.

    When you synchronize a Windows CE application, no character translation occurs within the MobiLink synchronization server. The server finds that data arriving from the application is already in Unicode and passes it directly to the ODBC driver. Similarly, no character set translation is necessary when downloading data.

  • All Adaptive Server Anywhere databases and all UltraLite applications on platforms other than Windows CE use the character set determined by the collating sequence of the remote database.

    When you synchronize a remote database, the MobiLink synchronization server performs character set translations between the character set of the remote database and Unicode.

Controlling ODBC driver character set translation


Controlling ODBC driver character set translation

Because most consolidated databases are unlikely to use Unicode, it is important to understand how the ODBC driver for your consolidated database system converts data to and from Unicode. Some ODBC drivers use the language settings of the machine running MobiLink to determine what character set to use. In these cases, it is best if the language and code-page settings of the machine running the MobiLink synchronization server match those of the consolidated database.

Other ODBC drivers, such as the driver for Sybase Adaptive Server Enterprise, allow each connection to use a specific character set. To avoid translation errors, the character set used by MobiLink should be set to match that of the consolidated database.

For a detailed description of how character set translations take place in your consolidated database server's ODBC driver, consult that product's ODBC driver documentation.


Character set translation during synchronization: non-Windows

The ODBC drivers that iAnywhere Solutions provides on non-Windows platforms do not have a Unicode ODBC API. The MobiLink synchronization server exchanges data with the ODBC driver using the character set determined by the collating sequence of the remote database.

When the remote database is an UltraLite application running under Windows CE, the MobiLink synchronization server performs character set translation between Unicode and the character set being used with ODBC.


iAnywhere Solutions ODBC Drivers

About this appendix

This appendix describes the ODBC drivers available for use with MobiLink.

ODBC drivers supported by MobiLink


ODBC drivers supported by MobiLink

The MobiLink synchronization server can work with a variety of consolidated databases and ODBC drivers, as shown in the table below. Some drivers, though compatible for use with MobiLink, may have functional restrictions associated with their use.

For updated information and complete functional specifications, see [external link] http://www.ianywhere.com/developer/technotes/odbc_mobilink.html.

For information about configuring ODBC drivers, see Introduction to iAnywhere Solutions ODBC Drivers. On UNIX, a standalone version of this book is installed in the drivers subdirectory of your SQL Anywhere Studio install directory.

Database | ODBC Drivers
Oracle 8i | iAnywhere Solutions 8 - Oracle 8, 8i & 9i ODBC Driver Merant DataDirect Connect ODBC Driver for Oracle
Oracle 9i | iAnywhere Solutions 8 - Oracle 8, 8i & 9i ODBC Driver Oracle 9i ODBC Driver
Microsoft SQL Server 7, Microsoft SQL Server 2000 | Microsoft SQL Server ODBC Driver Merant DataDirect SQL Server Wire Protocol ODBC Driver
Sybase Adaptive Server Enterprise 11.5 or later | iAnywhere Solutions 8 - Sybase ASE ODBC Driver Sybase ASE ODBC Driver Merant DataDirect Sybase Wire Protocol ODBC Driver Merant DataDirect Connect ODBC Driver for Sybase ASE Merant Connect ODBC Driver for Sybase ASE
IBM DB2 UDB 7.1, 7.2 | IBM DB2 UDB 7.1 ODBC driver IBM DB2 UDB 7.2 ODBC driver Merant DataDirect DB2 Wire Protocol ODBC Driver
Sybase Adaptive Server Anywhere 9 | Adaptive Server Anywhere 9.0 ODBC Driver


Deploying MobiLink Applications

About this appendix

This appendix describes how to deploy the MobiLink server and MobiLink clients in a production environment. It identifies the files required for deployment.

Check your license agreement
Redistribution of files is subject to your license agreement. No statements in this document override anything in your license agreement. Please check your license agreement before considering deployment.

Deployment overview
Deploying the MobiLink server
Deploying Adaptive Server Anywhere MobiLink clients
Deploying UltraLite MobiLink clients
Deploying QAnywhere applications


Deployment overview

Deploying MobiLink applications involves the following activities:

  • Deploy the MobiLink server into a production setting.

  • Deploy any Adaptive Server Anywhere MobiLink clients.

  • Deploy any UltraLite MobiLink clients.

This chapter describes the files you need to include in your application's install program for each of these items.


Deploying the MobiLink server

The simplest way to deploy a MobiLink synchronization server into a production environment is to install a licensed copy of SQL Anywhere Studio onto the production machine.

However, if you are redistributing a MobiLink synchronization server in a separate install program (subject to your license agreement), you may want to include only a subset of the files. In this case, you need to include the following files in your installation.

Notes

  • Test on a clean machine before redistributing.

  • Files must be installed within the SQL Anywhere Studio install directory.

  • The files should be in the same directory, unless otherwise mentioned.

  • When a location is given, the files must be copied into a directory of the same name.

  • On UNIX, environment variables must be set for the system to be able to locate SQL Anywhere applications and libraries. It is recommended that you use the appropriate file for your shell, either asa_config.sh or asa_config.csh (located in the directory /opt/sybase/SYBSsa9/bin) as a template for setting the required environment variables. Some of the environment variables set by the asa_config files include PATH, LD_LIBRARY_PATH, ASANY9, and ASANYSH9.

  • To use Java synchronization logic, and to use the graphical administration tools (Sybase Central and the MobiLink Monitor), you must have JRE 1.4.2 installed.

Windows applications
Description Windows files
MobiLink synchronization server
  • charsets\unicode
  • win32\dbmlsv9.dll
  • win32\dbmlsrv9.exe
  • win32\dbmsql9.dll
  • win32\dbunic9.dll
Language library
  • win32\dblgen9.dll1
Windows Performance Monitor support
  • win32\dbmlctr9.dll2
  • win32\dbmlctr9.h
  • win32\dbmlctr9.ini
Synchronization stream libraries (deploy the ones you use)
  • win32\dbmlhttp9.dll
  • win32\dbmlsock9.dll
Java synchronization logic
  • java\activation.jar3
  • java\imap.jar3
  • java\jodbc.jar
  • java\log4j.jar3
  • java\mailapi.jar3
  • java\mlscript.jar
  • java\mlsupport.jar
  • java\pop3.jar3
  • java\smtp.jar3
  • win32\dbmjava9.dll
  • win32\mljodbc9.dll
.NET synchronization logic
  • MobiLink\setup\dnet\mlDomConfig.xml
  • win32\dbmdnet9.dll
  • win32\dnetodbc9.dll
  • win32\iAnywhere.MobiLink.dll
  • win32\iAnywhere.MobiLink.Script.dll
  • win32\iAnywhere.MobiLink.Script.xml
  • win32\mlDomConfig.xsd
Security option4
  • win32\dbmlhttps.dll
  • win32\dbmlhttpsfips9.dll
  • win32\dbmlrsafips9.dll
  • win32\dbmljrsa9.dll
  • win32\dbmljtls9.dll
  • win32\dbmlrsa9.dll
  • win32\dbmltls9.dll
Script files (deploy the ones for your consolidated database)
  • MobiLink\setup
  • MobiLink\upgrade
iAnywhere Solutions ODBC drivers
  • drivers
dbmluser utility
  • win32\dbmluser.exe
dbmlstop utility
  • win32\dbmlstop.exe
Error names
  • h\sserror.h
MobiLink Monitor
  • java\mlmon.jar
  • shared\java\HelpManager11.jar
  • shared\java\JComponents142.jar
  • shared\java\jsyblib142.jar
  • shared\win32\jsyblib142.dll
  • ultralite\java\lib\ulrt.jar
  • win32\dbmlmon.exe
Online help for the MobiLink plug-in and Monitor
  • java\dbmaen9.jar1
MobiLink Redirector
  • MobiLink\redirector
Sybase Central
  • shared\Sybase Central 4.3
Sybase Central plug-in
  • win32\dbmlput9.dll
Notifier
  • java\activation.jar3
  • java\jodbc.jar
  • java\log4j.jar
  • java\mailapi.jar3
  • java\mlnotif.jar
  • java\mlscript.jar
  • java\smtp.jar3
QAnywhere
  • java\log4j.jar
  • java\qaconnector.jar

Note: Files may be located in the win32 or ia64 directory, depending on your version of the software.

1 For French, German, Japanese, and Chinese editions, substitute en with fr, de, ja, and zh, respectively.

2 Your setup program must self-register this file.

3 If you are redistributing an application, you must obtain these files directly from Sun.

4 Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations. To order this component, see Separately-licensable components.

UNIX, Linux, and Macintosh applications
Description UNIX files
MobiLink synchronization server
  • bin/dbmlsrv9
  • charsets/unicode
  • lib/libdbodm9_r.so3
  • lib/libdbmsql9_r.so3
  • lib/libdbtasks9_r.so3
  • lib/libdbunic9_r.so3
Language library
  • res/dblgen9.res1
Synchronization stream libraries (deploy the ones you use)
  • lib/libdbmlhttp9_r.so3
  • lib/libdbmlsock9_r.so3
Java synchronization logic
  • java/activation.jar2
  • java/imap.jar2
  • java/jodbc.jar
  • java/log4j.jar2
  • java/mailapi.jar2
  • java/mlscript.jar
  • java/mlsupport.jar
  • java/pop3.jar2
  • java/smtp.jar2
  • lib/libdbmjava9_r.so3
  • lib/libmljodbc9.so3
.NET synchronization logic
  • N/A
Security option4
  • lib/libdbmlhttps9_r.so3
  • lib/libdbmlrsa9_r.so3
  • lib/libdbmltls9_r.so3
Script files (deploy the ones for your consolidated database)
  • MobiLink/setup
  • MobiLink/upgrade
iAnywhere Solutions ODBC drivers
  • drivers
dbmluser utility
  • bin/dbmluser
dbmlstop utility
  • bin/dbmlstop
Error names
  • h/sserror.h
MobiLink Monitor
  • bin/dbmlmon
  • java/mlmon.jar
  • shared/java/HelpManager11.jar
  • shared/java/JComponents142.jar
  • shared/java/jsyblib142.jar
  • ultralite/java/lib/ulrt.jar
MobiLink Redirector
  • Mobilink/redirector/redirector.config
  • MobiLink/redirector/java
Online help for the MobiLink plug-in and MobiLink Monitor
  • java/dbmaen9.jar
Sybase Central
  • shared/sybcentral43
Sybase Central plug-in
  • lib/libdbmlput9_r.so3
Notifier
  • java/activation.jar2
  • java/jodbc.jar
  • java/log4j.jar
  • java/mailapi.jar2
  • java/mlnotif.jar
  • java/mlscript.jar
  • java/smtp.jar2
QAnywhere
  • java/log4j.jar
  • java/qaconnector.jar

1 For French, German, Japanese, and Chinese editions, substitute en with fr, de, ja, and zh, respectively.

2 If you are redistributing an application, you must obtain these files directly from Sun.

3For Solaris and Linux, the file extension is .so. For AIX, the file extension is .a. For HP, the file extension is .sl. For the Macintosh, the file extension is .dylib.

4 Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations. To order this component, see Separately-licensable components.


Deploying Adaptive Server Anywhere MobiLink clients

For Adaptive Server Anywhere clients, you need to deploy an Adaptive Server Anywhere database server and the MobiLink client.

For information about deploying Adaptive Server Anywhere databases, see Deploying Databases and Applications.

If you are redistributing MobiLink synchronization clients (subject to your license agreement) you need to include the following files in your installation in addition to those required for the Adaptive Server Anywhere database:

The files should be in the same directory, unless otherwise mentioned.

Windows applications
Description Windows files
MobiLink synchronization client
  • win32\dblgen9.dll1
  • win32\dbmlsync.exe
  • win32\dbtool9.dll
Note: dbtool9.dll is not required on Windows CE unless you are using the dbtools interface.
Dbmlsync integration component
  • MobiLink synchronization client files
  • dbmlsynccomg.dll for the visual component or dbmlsynccom.dll for the non-visual component
Synchronization stream libraries (deploy the ones you use)
  • win32\dbmlhttp9.dll
  • win32\dbmlsock9.dll
Security option2
  • dbmlhttps9.dll
  • dbmlhttpsfips9.dll3
  • dbmlrsafips9.dll3
  • dbmlrsa9.dll
  • dbmltls9.dll
ActiveSync and HotSync utilities
  • win32\dbasinst.exe
  • win32\dbcon9.exe
Listener
  • win32\dblgen9.dll1
  • win32\dblsn.exe
  • win32\lsn_udp.dll
  • win32\lsn_swi510.dll
  • win32\maac555.dll
  • win32\maac750.dll
  • win32\maac750r3.dll
  • win32\mabridge.dll

1 For French, German, Japanese, and Chinese editions, substitute en with fr, de, ja, and zh, respectively.

2 Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations. To order this component, see Separately-licensable components.

3 FIPS security does not apply to Windows CE.

UNIX, Linux, and Macintosh applications
Description UNIX files
MobiLink synchronization client
  • bin/dbmlsync
  • res/dblgen9.res
  • lib/libdbtool9.so1
  • lib/libdbtool9_r.so1
Synchronization stream libraries (deploy the ones you use)
  • lib/libdbmlhttp9_r.so1
  • lib/libdbmlsock9_r.so1
Security option2
  • lib/libdbmlhttps9_r.so1
  • lib/libdbmlrsa9_r.so1
  • lib/libdbmltls9_r.so1

1For Solaris and Linux, the file extension is .so. For AIX, the file extension is .a. For HP, the file extension is .sl. For the Macintosh, the file extension is .dylib.

2 Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations. To order this component, see Separately-licensable components.


Deploying UltraLite MobiLink clients

For UltraLite clients, the UltraLite runtime library or the UltraLite component includes the required synchronization stream functions. The UltraLite runtime library is compiled into your application. Deployment is subject to your license agreement.

For more information, see the documentation for the UltraLite component or development model you are using.

Palm applications
Description Palm files
Windows Listener configuration utility
  • dblsncfg.exe
Listener for Treo 180
  • palm\Treo180\lsnT180.prc
Listener for Kyocera 6035
  • palm\Kyocera6035\lsnK6035.prc


Deploying QAnywhere applications

QAnywhere applications require client and server files.

The QAnywhere client requires all files used by dbmlsync, in addition to the files listed below.

For more information about dbmlsync, see Deploying Adaptive Server Anywhere MobiLink clients.

Windows applications
Description Windows files
QAnywhere client
  • qanywhere.db
  • win32\iAnywhere.QAnywhere.Client.dll or ce\iAnywhere.QAnywhere.Client.dll (required for the C# interface only)
  • win32\qaagent.exe or ce\arm.30\qaagent.exe or ce\x86.30\qaagent.exe
  • win32\qany9.dll or ce\arm.30\qany9.dll or ce\x86.30\qany9.dll
Server side
  • java\log4j.jar
  • java\qaconnector.jar
UNIX, Linux, and Macintosh applications
Description UNIX files
Server side
  • java/log4j.jar
  • java/qaconnector.jar
Registering the QAnywhere .NET API dll

The QAnywhere .NET API dll (win32\iAnywhere.QAnywhere.Client.dll) needs to be registered in the Global Assembly Cache on Windows (except Windows CE). The Global Assembly Cache lists all the registered programs on your machine. When you install SQL Anywhere Studio, the installation program registers it. On Windows CE you do not need to register the DLL.

If you are deploying QAnywhere, you must register the QAnywhere .NET API dll (win32\iAnywhere.QAnywhere.Client.dll) using the gacutil utility that is included with the .NET Framework.


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Clients

Version 9.0.2

DC00193-01-0902-01

October 2004

Copyright
About This Manual
Introducing MobiLink Clients
Authenticating MobiLink Users
Utilities
MobiLink Client Network Protocol Options
Adaptive Server Anywhere Clients
Adaptive Server Anywhere Client Synchronization Parameters
MobiLink SQL Statements
Dbmlsync Client Event Hooks
Dbmlsync Integration Component
DBTools Interface for dbmlsync
UltraLite Clients
UltraLite Synchronization Parameters


SQL Anywhere Studio documentation

This book is part of the SQL Anywhere documentation set. This section describes the books in the documentation set and how you can use them.

The SQL Anywhere Studio documentation

The SQL Anywhere Studio documentation is available in a variety of forms: in an online form that combines all books in one large help file; as separate PDF files for each book; and as printed books that you can purchase. The documentation consists of the following books:

  • Introducing SQL Anywhere Studio This book provides an overview of the SQL Anywhere Studio database management and synchronization technologies. It includes tutorials to introduce you to each of the pieces that make up SQL Anywhere Studio.

  • What's New in SQL Anywhere Studio This book is for users of previous versions of the software. It lists new features in this and previous releases of the product and describes upgrade procedures.

  • Adaptive Server Anywhere Database Administration Guide This book covers material related to running, managing, and configuring databases and database servers.

  • Adaptive Server Anywhere SQL User's Guide This book describes how to design and create databases; how to import, export, and modify data; how to retrieve data; and how to build stored procedures and triggers.

  • Adaptive Server Anywhere SQL Reference Manual This book provides a complete reference for the SQL language used by Adaptive Server Anywhere. It also describes the Adaptive Server Anywhere system tables and procedures.

  • Adaptive Server Anywhere Programming Guide This book describes how to build and deploy database applications using the C, C++, and Java programming languages. Users of tools such as Visual Basic and PowerBuilder can use the programming interfaces provided by those tools. It also describes the Adaptive Server Anywhere ADO.NET data provider.

  • Adaptive Server Anywhere SNMP Extension Agent User's Guide This book describes how to configure the Adaptive Server Anywhere SNMP Extension Agent for use with SNMP management applications to manage Adaptive Server Anywhere databases.

  • Adaptive Server Anywhere Error Messages This book provides a complete listing of Adaptive Server Anywhere error messages together with diagnostic information.

  • SQL Anywhere Studio Security Guide This book provides information about security features in Adaptive Server Anywhere databases. Adaptive Server Anywhere 7.0 was awarded a TCSEC (Trusted Computer System Evaluation Criteria) C2 security rating from the U.S. Government. This book may be of interest to those who wish to run the current version of Adaptive Server Anywhere in a manner equivalent to the C2-certified environment.

  • MobiLink Synchronization User's Guide This book describes how to use the MobiLink data synchronization system for mobile computing, which enables sharing of data between a single Oracle, Sybase, Microsoft or IBM database and many Adaptive Server Anywhere or UltraLite databases.

  • MobiLink Administration Guide This book describes how to use the MobiLink data synchronization system for mobile computing, which enables sharing of data between a single Oracle, Sybase, Microsoft or IBM database and many Adaptive Server Anywhere or UltraLite databases.

  • MobiLink Clients This book describes how to set up and synchronize Adaptive Server Anywhere and UltraLite remote databases.

  • MobiLink Tutorials This book provides several tutorials that walk you through how to set up and run MobiLink applications.

  • QAnywhere User's Guide This manual describes MobiLink QAnywhere, a messaging platform that enables the development and deployment of messaging applications for mobile and wireless clients, as well as traditional desktop and laptop clients.

  • iAnywhere Solutions ODBC Drivers This book describes how to set up ODBC drivers to access consolidated databases other than Adaptive Server Anywhere from the MobiLink synchronization server and from Adaptive Server Anywhere remote data access.

  • SQL Remote User's Guide This book describes all aspects of the SQL Remote data replication system for mobile computing, which enables sharing of data between a single Adaptive Server Anywhere or Adaptive Server Enterprise database and many Adaptive Server Anywhere databases using an indirect link such as e-mail or file transfer.

  • SQL Anywhere Studio Help This book includes the context-sensitive help for Sybase Central, Interactive SQL, and other graphical tools. It is not included in the printed documentation set.

  • UltraLite Database User's Guide This book is intended for all UltraLite developers. It introduces the UltraLite database system and provides information common to all UltraLite programming interfaces.

  • UltraLite Interface Guides A separate book is provided for each UltraLite programming interface. Some of these interfaces are provided as UltraLite components for rapid application development, and others are provided as static interfaces for C, C++, and Java development.

In addition to this documentation set, PowerDesigner and InfoMaker include their own online documentation.

Documentation formats

SQL Anywhere Studio provides documentation in the following formats:

  • Online documentation The online documentation contains the complete SQL Anywhere Studio documentation, including both the books and the context-sensitive help for SQL Anywhere tools. The online documentation is updated with each maintenance release of the product, and is the most complete and up-to-date source of documentation.

    To access the online documentation on Windows operating systems, choose Start > Programs > SQL Anywhere 9 > Online Books. You can navigate the online documentation using the HTML Help table of contents, index, and search facility in the left pane, as well as using the links and menus in the right pane.

    To access the online documentation on UNIX operating systems, see the HTML documentation under your SQL Anywhere installation.

  • PDF books The SQL Anywhere books are provided as a set of PDF files, viewable with Adobe Acrobat Reader.

    The PDF books are accessible from the online books, or from the Windows Start menu.

  • Printed books The complete set of books is available from Sybase sales or from eShop, the Sybase online store, at [external link] http://eshop.sybase.com/eshop/documentation.


Introducing MobiLink Clients

About this chapter

This chapter introduces you to MobiLink remote databases.

MobiLink supports two types of remote database: Adaptive Server Anywhere and UltraLite.


Adaptive Server Anywhere clients

Synchronization is initiated by running a command line utility called dbmlsync. This utility connects to the remote database and prepares the upload stream using information contained in the transaction log of the remote database. It then uses information stored in a synchronization publication and synchronization subscription to connect to the MobiLink synchronization server and exchange data.

For more information about Adaptive Server Anywhere clients, see Adaptive Server Anywhere Clients.

For details of dbmlsync command line options, see Adaptive Server Anywhere Client Synchronization Parameters.


UltraLite clients

Applications built with the UltraLite technology available in SQL Anywhere Studio are automatically MobiLink-enabled whenever the application includes a call to the appropriate MobiLink synchronization function. The UltraLite development tools included in SQL Anywhere Studio automatically include synchronization logic when you build your UltraLite application.

The UltraLite application and libraries handle the synchronization actions at the application end. You can write your UltraLite application with little regard to synchronization. The UltraLite runtime keeps track of changes made since the previous synchronization.

Synchronization is initiated from your application by a single call to a synchronization function when using TCP/IP, HTTP, HTTPS, or ActiveSync.

The interface for HotSync is slightly different. Once synchronization is initiated from the application or from HotSync, the MobiLink synchronization server and the UltraLite runtime control the actions that occur during synchronization.

For more information about UltraLite clients, see UltraLite Clients.

For more information about initiating synchronization, see UltraLite Synchronization Parameters.


Specifying the communications protocol for clients

The MobiLink synchronization server uses the -x command line option to specify the network protocol or protocols for the synchronization client to connect to the MobiLink server. The network protocol you choose must match the synchronization protocol used by the client. The syntax for this command line option is:

dbmlsrv9 -c "connection-string" -x protocol( options )

In the following example, the TCP/IP protocol is selected with no additional protocol options.

dbmlsrv9 -c "dsn=ASA 9.0 Sample" -x tcpip

You can configure your protocol using options of the form:

(keyword=value;...)

For example:

dbmlsrv9 -c "dsn=ASA 9.0 Sample" -x tcpip(
   host=localhost;port=2439)

For more information about network protocols and protocol options, see -x option.


MobiLink users

You need to provide one unique MobiLink user name for each remote database in the MobiLink system. This name uniquely identifies each MobiLink remote database.

The ml_user MobiLink system table, located in the consolidated database, holds a list of MobiLink user names. The synchronization state of each user is recorded in the commit_state column or the progress column. This information ensures proper recovery if synchronization is interrupted.

For more information about MobiLink users, see

  • About MobiLink users

  • Creating MobiLink users

  • ml_user


Authenticating MobiLink Users

About this chapter

A MobiLink user is a name that uniquely identifies a remote database for synchronization.

This chapter describes how to manage MobiLink users, including the mechanisms provided to manage and authenticate their passwords.

For more information about security options, see MobiLink Transport-Layer Security.

About MobiLink users
Choosing a user authentication mechanism
User authentication architecture
Providing initial passwords for users
Synchronizations from new users
Prompting end users to enter passwords
Changing passwords
Custom user authentication


About MobiLink users

A MobiLink user, also called a synchronization user, is a name assigned to a remote database. Each MobiLink user name must be unique within the synchronization system.

MobiLink user names and passwords are not the same as database user names and passwords. MobiLink user names and passwords are used to uniquely identify remote databases, and optionally to authenticate the connection from the remote database to the MobiLink synchronization server.

You can also use user names to control the behavior of the synchronization server. You do so using the user name in synchronization scripts. For example, you can send remote databases different rows based on their user name.

The MobiLink user name is stored in the ml_user MobiLink system table in the consolidated database.

Naming conventions

In large-scale deployments, you might find it useful to adopt a naming convention for your MobiLink user names. For example, you could adopt a naming convention whereby MobiLink names were created as user:application, where user identifies a person and application identifies a specific application, such as EmpA01:HRApp. Or your convention could be user:application:device, where device identifies a remote device.

UltraLite user authentication

Although UltraLite and MobiLink user authentication schemes are separate, you may wish to share the values of UltraLite user IDs with MobiLink user names for simplicity. This will only work when the UltraLite application is used by a single user.

For more information about UltraLite user authentication, see User authentication in UltraLite.

Creating MobiLink users


Creating MobiLink users

Warning
A MobiLink user name uniquely identifies a remote database. Therefore, two different remote databases must have different MobiLink user names.
Create users in the remote database

To add users to the remote database, you have the following options:

  • For Adaptive Server Anywhere remotes, use Sybase Central or the CREATE SYNCHRONIZATION USER statement.

    For more information, see Adding MobiLink users to a remote database.

  • For UltraLite remotes, you can use the user_name field of the ul_synch_info structure. In Java, use the SetUserName() method of the ULSynchInfo class before synchronizing.

    For more information, see User Name synchronization parameter and Password synchronization parameter.

Add MobiLink user names to the consolidated database

Once user names are created on the remote database, you can use any of the following methods to register the user names in the consolidated database:

  • Use the dbmluser utility.

    For more information, see MobiLink user authentication utility.

  • Use Sybase Central.

  • Implement a script for the authenticate_user or authenticate_user_hashed events. When either of these scripts are invoked, the MobiLink synchronization server automatically adds users that successfully authenticate.

  • Specify the -zu+ command line option with dbmlsrv9. In this case, any existing MobiLink users that have not been added to the consolidated database are added when they first synchronize.

    For more information, see -zu option.

Sharing MobiLink user names


Sharing MobiLink user names

MobiLink user names must be unique within a synchronization system. If you want two or more remote databases (UltraLite or Adaptive Server Anywhere) to share the same MobiLink user name, you can create a MobiLink user name that is a base name with a unique suffix.

A typical use of this technique is for a person who wants to have several remote databases. Each remote database must have a unique MobiLink user name, but they can share the same base name.

Example

The following example creates MobiLink user names that are 102 followed by a colon and a universally unique ID.

BEGIN
EXECUTE IMMEDIATE 'CREATE SYNCHRONIZATION USER "102' + ':' +
NEWID() + '"';
END;

This creates a MobiLink user name such as 102:b23fdbed-bead-418a-9d53-917e774c2f4f.

You still need MobiLink to provide the user name to each of the MobiLink scripts. To do this, you can use a MobiLink event called modify_user. It takes the MobiLink user as input and allows you to modify it. The modified value is what is passed to all the download events. For example,

CALL sp_ML_modify_user( ? )

The result is that the following download_cursor is based on the value of 102, not 102:b23fdbed-bead-418a-9d53-917e774c2f4f.

Select emp_id, emp_name
From ULEmployee
Where last_modified >= ?
 And emp_id = ?

Here is the procedure written using Adaptive Server Anywhere syntax. This can easily be converted for other RDBMSs.

CREATE PROCEDURE sp_ML_modify_user( INOUT @ml_user_name VARCHAR(255) )
BEGIN
    DECLARE @colon_at INT;
    SET @colon_at = LOCATE( @ml_user_name, ':' );
    IF( @colon_at > 0 ) THEN
        -- Message statements are displayed in the minimized engine
        -- window, this is useful for debugging
        MESSAGE 'UUID: ' +
                RIGHT( @ml_user_name,
                    (LENGTH(@ml_user_name)-@colon_at) );
        SET @ml_user_name = LEFT( @ml_user_name, (@colon_at-1) );
        MESSAGE 'New MobiLink User: ' + @ml_user_name;
    ELSE
        MESSAGE 'No change to MobiLink User: ' + @ml_user_name;
    END IF;
END;


Choosing a user authentication mechanism

User authentication is one part of a security system for protecting your data.

MobiLink provides you with a choice of user authentication mechanisms. You do not have to use a single installation-wide mechanism; MobiLink lets you use different authentication mechanisms for different script versions within the installation for flexibility.

  • No MobiLink user authentication If your data is such that you do not need password protection, you can choose not to use any user authentication in your installation. In this case, the MobiLink user name must still be included in the ml_user table, but the hashed_password column is NULL.

  • Built-in MobiLink user authentication MobiLink uses the user names and passwords stored in the ml_user MobiLink system table to perform authentication.

    The built-in mechanism is described in the following sections.

  • Custom authentication You can use the MobiLink script authenticate_user to replace the built-in MobiLink user authentication system with one of your own. For example, depending on your consolidated database-management system, you may be able to use the database user authentication instead of the MobiLink system.

    For more information about custom user authentication mechanisms, see Custom user authentication.

For information about other security-related features of MobiLink and its related products, see

  • MobiLink Transport-Layer Security

  • Encrypting UltraLite databases

  • Keeping Your Data Secure


User authentication architecture

The MobiLink user authentication system relies on user names and passwords. You can choose either to let the MobiLink synchronization server validate the user name and password using a built-in mechanism, or you can implement your own custom user authentication mechanism.

In the built-in authentication system, both the user name and the password are stored in the ml_user MobiLink system table in the consolidated database. The password is stored in hashed form so that applications other than the MobiLink synchronization server cannot read the ml_user table and reconstruct the original form of the password. You add user names and passwords to the consolidated database using Sybase Central, using the dbmluser utility, or by specifying -zu+ when you start the MobiLink synchronization server.

For more information, see Creating MobiLink users.

When a MobiLink client connects to a MobiLink synchronization server, it provides the following values.

  • user name The MobiLink user name. Mandatory. To synchronize, the user name must be stored in the ml_user system table, or you must start the MobiLink synchronization server with the -zu+ option to add new users to the ml_user table.

  • password The MobiLink password. Optional only if the user is unknown or if the corresponding password in the ml_user MobiLink system table is NULL.

  • new password A new MobiLink password. Optional. MobiLink users can change their password by setting this value.

Custom authentication

Optionally, you can substitute your own user authentication mechanism.

For more information, see Custom user authentication.

The authentication process


The authentication process

Following is an explanation of the order of events that occur during authentication.

  1. You initiate a synchronization request using a MobiLink user name, and optionally a password and new password. The MobiLink synchronization server starts a new transaction and triggers the begin_connection event.

  2. MobiLink verifies that the MobiLink user name you provided is not currently synchronizing.

  3. If you have defined an authenticate_user script, then the following occurs:

    1. The authenticate_user script is called and sets the auth_status field with the MobiLink user name you provided and optionally the password and new password.

    2. If the authenticate_user script throws an exception, the synchronization process stops.

    3. If the authenticate_user script returns a SQL statement, the statement is executed. The SQL statement must be a call to a stored procedure taking 2 to 4 arguments. The auth_status value that was set in step 3.a is passed as the first parameter and may be updated by the stored procedure.

  4. If an error occurred, authentication stops with a failure.

  5. Otherwise, if an authenticate_user_hashed script exists, then the following occurs:

    1. If a password was provided, a hashed value is calculated for it. If a new password was provided, a hashed value is calculated for it.

    2. The authenticate_user_hashed script is called with the current value of auth_status and the hashed passwords. The behavior is identical to steps 3.b and 3.c, except that the authenticate_user_hashed script can overwrite the value of auth_status with a larger (more severe) value if it was set by step 3.a. If the authenticate_user script was not defined, then the auth_status value that is set by authenticate_user_hashed is used no matter what.

  6. The MobiLink synchronization server searches the ml_user table for the MobiLink user name you provided.

    1. If either of the custom scripts authenticate_user or authenticate_user_hashed was called but the MobiLink user name you provided is not in the ml_user table and the auth_status is valid (1000 or 2000), the MobiLink user name is added to the MobiLink system table ml_user. If auth_status is not valid, ml_user is not updated and an error occurs.

    2. If the custom scripts were not called and the MobiLink user name you provided is not in the ml_user table, the MobiLink user name you provided is added to ml_user if you started the MobiLink synchronization server with the -zu option. Otherwise, an error occurs and auth_status is set accordingly.

    3. If the custom scripts were called and the MobiLink user name you provided is in the ml_user table, nothing happens.

    4. If the custom scripts were not called and the MobiLink user name you provided is in the ml_user table, the password is checked against the value in the ml_user table and auth_status is set accordingly.

  7. The MobiLink synchronization server attempts to authenticate the MobiLink user name you provided using the password you provided.

  8. If neither of the scripts authenticate_user or authenticate_user_hashed was called and you provided a new password, the password is changed to the one you provided.

  9. If you have defined an authenticate_parameters script and the auth_status is valid (1000 or 2000), then the following occurs:

    1. The parameters are passed to the authenticate_parameters script.

    2. If the authenticate_parameters script returns an auth_status value greater than the current auth_status, the new auth_status overwrites the old value.

  10. If auth_status is not valid, the synchronization is aborted.

  11. If you have defined the modify_user script, it is called to replace the MobiLink user name you provided with a new MobiLink user name.

  12. The MobiLink synchronization server commits or rolls back the synchronization as appropriate, and continues with the synchronization.


Providing initial passwords for users

The password for each user is stored along with the user name in the ml_user table. You can provide initial passwords from Sybase Central, or using the dbmluser command line utility.

Sybase Central is a convenient way of adding individual users and passwords. The dbmluser utility is useful for batch additions.

If you create a user with no password, then MobiLink performs no user authentication for that user: they can connect and synchronize without supplying a password.

toggle To provide an initial MobiLink password for a user (Sybase Central)

  1. Connect to the consolidated database from Sybase Central using the MobiLink plug-in.

  2. Open the Users folder.

  3. Double-click Add User. The Add User wizard appears.

  4. Supply a user name and an optional password.

  5. Click Finish to complete the task.

toggle To provide initial MobiLink passwords (command line)

  1. Create a file with a single user name and password on each line, separated by white space.

  2. Open a command prompt, and execute the dbmluser command line utility. For example:

    dbmluser -c "dsn=my_dsn" -f password-file

    In this command line, the -c option specifies an ODBC connection to the consolidated database. The -f option specifies the file containing the user names and passwords.

    For information about dbmluser, see MobiLink user authentication utility.


Synchronizations from new users

Ordinarily, each MobiLink client must provide a valid MobiLink user name and password to connect to a MobiLink synchronization server.

Setting the -zu+ option when you start the MobiLink synchronization server allows the MobiLink synchronization server to automatically add new user names to the ml_user table according to the following rules.

In effect, this option permits new users to create their own MobiLink accounts, easing administration of new users. This arrangement can be convenient when the server and clients all operate within a firewall.

If a MobiLink client synchronizes with a user name that is not in the current ml_user table, MobiLink, by default, takes the following actions:

  • New user, no password If the user supplied no password, then by default the user name is added to the ml_user table with a NULL password. This behavior provides compatibility with earlier releases of MobiLink that did not allow user authentication.

    For more information, see -zu option.

  • New user, password If the user supplies a password, then the user name and password are both added to the ml_user table and the new user name becomes a recognized name in your MobiLink system.

  • New user, new password A new user may provide information in the new password field, instead of or as well as in the password field. In either case, the new password setting overrides the password setting, and the new user is added to the MobiLink system using the new password.

Preventing synchronization by unknown users

You can change the default behavior by starting the MobiLink synchronization server using the -zu option. In this case, the MobiLink synchronization server rejects any attempt to synchronize from a user name that is not present in the ml_user table.

This setting provides two benefits. First, it reduces the risk of unauthorized access to the MobiLink synchronization server. Second, it prevents authorized users from accidentally connecting using an incorrect or misspelled user name. Such accidents should be avoided because they can cause the MobiLink system to behave in unpredictable ways.


Prompting end users to enter passwords

Each end user must supply a MobiLink user name and password each time they synchronize from a MobiLink client, unless you choose to disable user authentication on your MobiLink synchronization server.

toggle To prompt your end users to enter their MobiLink passwords

  • The mechanism for supplying the user name and password is different for UltraLite and Adaptive Server Anywhere clients.

    • UltraLite When synchronizing, the UltraLite client must supply a valid value in the password field of the synchronization structure (C/C++) or object (Java). For built-in MobiLink synchronization, a valid password is one that matches the value in the ml_user MobiLink system table.

      Your application should prompt the end user to enter their MobiLink user name and password before synchronizing.

      For more information, see UltraLite Synchronization Parameters.

    • Adaptive Server Anywhere You can supply a valid password on the dbmlsync command line. However, if you do not do so, you are prompted for one in the dbmlsync connection dialog. The latter method is more secure because command lines are visible to other processes running on the same computer.

      If authentication fails, you are prompted to re-enter the user name and password.

      For more information, see -c option.


Changing passwords

MobiLink provides a mechanism for end users to change their password. The interface differs between UltraLite and Adaptive Server Anywhere clients.

toggle To prompt your end users to enter MobiLink passwords

  • The mechanism for supplying the user name and password is different for UltraLite and Adaptive Server Anywhere clients.

    • UltraLite When synchronizing, the application must supply the existing password in the password field of the synchronization structure and the new password in the new_password field.

      For more information, see Password synchronization parameter and New Password synchronization parameter.

    • Adaptive Server Anywhere Supply a valid existing password together with the new password on the dbmlsync command line, or in the dbmlsync connection dialog if you do not supply command line parameters.

      For more information, see -mp option and -mn option.

The new password is not verified until the next synchronization attempt. For the dbmlsync utility, or if you prompt at synchronization time in an UltraLite application, this attempt is almost immediate.

An initial password can be set in the consolidated server or on the first synchronization attempt. For more information, see Providing initial passwords for users and Synchronizations from new users.

Once a password is assigned, you cannot reset the password to NULL from the client side.


Custom user authentication

You can choose to use a user authentication mechanism other than the built-in MobiLink mechanism. Reasons for using a custom user authentication mechanism include integration with existing DBMS user authentication schemes or external authentication mechanisms; or supplying custom features, such as minimum password length or password expiry, that do not exist in the built-in MobiLink mechanism.

There are three custom authentication tools:

  • dbmlsrv9 -zu option

  • authenticate_user script

  • authenticate_parameters script

The dbmlsrv9 -zu option allows you to control the automatic addition of users. For example, specify -zu+ to have all unrecognized MobiLink user names added to the ml_user table when they first synchronize. The -zu option is only needed for built-in MobiLink authentication.

The authenticate_user script and authenticate_parameters script both override the default MobiLink user authentication mechanism. Any user that successfully authenticates is automatically added to the ml_user table

There are several predefined scripts for the authenticate_user event that are installed with MobiLink. These make it easier for you to authenticate using LDAP, POP3, and IMAP servers. For more information, see Authenticating to external servers.

Use authenticate_user to create custom authentication of user IDs and passwords. If this script exists, it is executed instead of the built-in password comparison. The script must return error codes to indicate the success or failure of the authentication.

Use authenticate_parameters to create custom authentication that depends on values other than user IDs and passwords.

For more information, see:

  • -zu option

  • authenticate_user connection event

  • authenticate_parameters connection event


Java and .NET user authentication

User authentication is a natural use of Java and .NET synchronization logic, as Java and .NET classes allow you to reach out to other sources of user names and passwords used in your computing environment, such as application servers.

A simple sample is included in the directory Samples\MobiLink\JavaAuthentication. The sample code in Samples\MobiLink\JavaAuthentication\CustEmpScripts.java implements a simple user authentication system. On the first synchronization, a MobiLink user name is added to the login_added table. On subsequent synchronizations, a row is added to the login_audit table. In this sample, there is no test before adding a user ID to the login_added table.

For a .NET sample that explains user authentication, see .NET synchronization example.


SQL user authentication

A typical authenticate_user SQL script is a call to a stored procedure that uses the parameters auth_status, ml_username, user_password, and user_new_password. The order of the parameters in the call must match this. For example, in an Adaptive Server Anywhere consolidated database, the format is:

call my_authentication( ?, ?, ?, ? )

where the first argument is the authentication code, and so on. The authentication code is an integer type, and the other parameters are VARCHAR(128).

A Transact-SQL format is:

execute ? = my_authentication( ?, ?, ? )

where the authentication code is the parameter on the left hand side.

For more information, see authenticate_user connection event.


Authenticating to external servers

Predefined Java synchronization scripts are included with MobiLink that make it simpler for you to authenticate to external servers using the authenticate_user event. Currently, predefined scripts are available for the following authentication servers:

  • POP3 or IMAP servers using the JavaMail 1.2 API

  • LDAP servers using the Java Naming and Directory Interface (JNDI)

How you use these scripts is determined by whether your MobiLink user names map directly to the user IDs in your external authentication system.

If your MobiLink user names map directly to your user IDs

In the simple case where the MobiLink user name maps directly to a valid user ID in your authentication system, the predefined scripts can be used directly in response to the authenticate_user connection event. The authentication code will initialize itself based on properties stored in the ml_property table.

toggle To use predefined scripts directly in authenticate_user

  1. Add the predefined Java synchronization script to the ml_scripts MobiLink system table. You can do this using a stored procedure or in Sybase Central.

    • To use the ml_add_java_connection_script stored procedure, type the following at a command prompt:

      call ml_add_java_connection_script(
  'MyVersion'
  'authenticate_user'
  'ianywhere.ml.authentication.ServerType.authenticate' )

      where MyVersion is the name of a script version, and ServerType is LDAP, POP3, or IMAP.

    • To use the Add Connection Script wizard in Sybase Central, choose authenticate_user as the script type, and enter the following in the Code Editor:

      ianywhere.ml.authentication.ServerType.authenticate

      where ServerType is LDAP, POP3, or IMAP.

  2. Add properties for this authentication server.

    Use the ml_add_property stored procedure for each property you need to set:

    call ml_add_property(
  'ScriptVersion'
  'MyVersion'
  'property_name'
  'property_value' )

    where MyVersion is the name of a script version, property_name is determined by your authentication server, and property_value is a value appropriate to your application. Repeat this call for every property you want to set.

    For more information, see External authenticator properties.

If your MobiLink user names do not map directly to your user IDs

If your MobiLink user names are not equivalent to your user IDs, the code must be called indirectly and you must extract or map the user ID from the ml_user value. You do this by writing a Java class.

For more information about writing Java classes, see Writing Synchronization Scripts in Java.

Following is a simple example. In this example, the code in the extractUserID method has been left out because it depends on how the ml_user value maps to a userid. All the work is done in the "authenticate" method of the authentication class.

package com.mycompany.mycode;

import ianywhere.ml.authentication.*;
import ianywhere.ml.script.*;

public class MLEvents
{
    private DBConnectionContext _context;
    private POP3 _pop3;

    public MLEvents( DBConnectionContext context )
    {
        _context = context;
        _pop3 = new POP3( context );
    }
    public void authenticateUser(
      InOutInteger status,
      String userID,
      String password,
      String newPassword )
    {
        String realUserID = extractUserID( userID );
        _pop3.authenticate( status, realUserID, password, newPassword );
    }

    private String extractUserID( String userID )
    {
        // code here to map ml_user to a "real" POP3 user
    }
}

In this example, The POP3 object needs to be initialized with the DBConnectContext object so that it can find its initialization properties. If you do not initialize it this way, you must set the properties in code. For example,

POP3 pop3 = new POP3();
pop3.setServerName( "smtp.sybase.com" );
pop3.setServerPort( 25 );

This applies to any of the authentication classes, although the properties vary by class.

External authenticator properties


External authenticator properties

MobiLink provides reasonable defaults wherever possible, especially in the LDAP case. The properties that can be set vary, but following are the basic ones.

POP3 authenticator
mail.pop3.host | the hostname of the server
mail.pop3.port | the port number (can be omitted if default 110 is used)

For more information, see [external link] http://java.sun.com/products/javamail/javadocs/com/sun/mail/pop3/package-summary.html

IMAP authenticator
mail.imap.host | the hostname of the server
mail.imap.port | the port number (can be omitted if default 143 is used)

For more information, see [external link] http://java.sun.com/products/javamail/javadocs/com/sun/mail/imap/package-summary.html.

LDAP authenticator
java.naming.provider.url the URL of the LDAP server, such as ldap://ops-yourLocation/dn=sybase,dn=com

For more information, see the JNDI documentation.


Utilities

About this chapter

This chapter describes MobiLink client utilities.

For information about MobiLink synchronization server utilities, see Utilities.

For information about other Adaptive Server Anywhere utilities, see Database Administration Utilities.


ActiveSync provider installation utility

Installs a MobiLink provider for ActiveSync, or registers and installs UltraLite applications on Windows CE devices.

Syntax

dbasinst [options ] [ [ src ] dst name class [ args ] ]

Options | Description
-d | Disable the application on creation.
-k path | Specify the location of the desktop provider dbasdesk.dll.
-l filename | Write the activity log to the specified file. If no path or a relative path is given for the filename, the log file will be in or relative to the ActiveSync install directory.
-n | Register the application but do not copy it to the device.
-u | Uninstall the MobiLink ActiveSync provider.
-v path | Specify the location of the device provider dbasdev.dll.
Args | Description
src | The source filename and path for an application.
dst | The destination filename and path for an application.
name | The name of the application.
class | The registered Windows class name of the application.
args | Command line arguments to use when ActiveSync starts the application.
Description

This utility installs a MobiLink provider for ActiveSync. The provider includes both a component that runs on the desktop (dbasdesk.dll) and a component that is deployed to the Windows CE device (dbasdev.dll). The dbasinst utility makes a registry entry pointing to the current location of the desktop provider; and copies the device provider to the device.

If additional arguments are supplied, the dbasinst utility can also be used to register and install UltraLite applications onto a Windows CE device. Alternatively, you can register and install UltraLite applications using the ActiveSync software.

Subject to licensing requirements, you may supply this application, together with the desktop and device components to end users, so that they can prepare their copies of your application for use with ActiveSync.

You must be connected to a remote device to install the ActiveSync provider.

For complete instructions on using the ActiveSync provider installation utility, see:

  • Adaptive Server Anywhere: Installing the MobiLink provider for ActiveSync
  • UltraLite: Installing the MobiLink provider for ActiveSync
Options

-d By default, an application registered by dbasinst is enabled, meaning that it is automatically synchronized when ActiveSync begins a synchronization. With the -d option, the application is still registered, but it is unchecked in the ActiveSync MobiLink settings dialog.

-l The ActiveSync provider logs its activities to the specified file. If no path or a relative path is given for the filename, the log file is in or relative to the ActiveSync install directory.

-k The path to the desktop provider dbasdesk.dll. By default the file is looked for in the win32 subdirectory of your SQL Anywhere directory. End users (who generally do not have the full SQL Anywhere install) may need to specify -k when installing the MobiLink ActiveSync provider.

-n In addition to installing the MobiLink ActiveSync provider, register an application but do not copy it to the device. This is appropriate if the application includes more than one file (for example, if it is compiled to use the UltraLite runtime library DLL rather than a static library) or if you have an alternative method of copying the application to the device.

-u Unregister all applications that have been registered for use with the MobiLink ActiveSync provider and uninstall the MobiLink ActiveSync provider. No files are deleted from the desktop machine or the device by this operation. If the device is not connected to the desktop, an error is reported.

-v The path to the device provider dbasdev.dll. By default the file is looked for in a platform-specific directory under the CE subdirectory of your SQL Anywhere directory. End users (who generally do not have the full SQL Anywhere install) may need to specify -v when installing the MobiLink ActiveSync provider.

Arguments

src The source filename and path for copying an application to the device. Supply this parameter only if you are registering an application and copying it to the device: do not supply the parameter if you use the -n option.

dst The destination filename and path on the device for an application.

name The application name. This is the name by which ActiveSync refers to the application.

class The registered Windows class name for the application.

args Any command line arguments to be used when ActiveSync starts the application.

Examples

The following command installs the MobiLink provider for ActiveSync using default arguments. It does not register an application. The device must be connected to your desktop for the installation to succeed.

dbasinst

The following command uninstalls the MobiLink provider for ActiveSync. The device must be connected to your desktop for the uninstall to succeed:

dbasinst -u

The following command installs the MobiLink provider for ActiveSync, if it is not already installed, and registers the application myapp.exe. It also copies the c:\My Files\myapp.exe file to \Program Files\myapp.exe on the device. The -p -x arguments are command line options for myapp.exe when started by ActiveSync. The command must be entered on a single line:

dbasinst "C:\My Files\myapp.exe" "\Program Files\myapp.exe"
   "My Application" MYAPP -p -x
See also
  • Using ActiveSync synchronization
  • UltraLite Synchronization Parameters


MobiLink client database extraction utility (deprecated)

Creates an Adaptive Server Anywhere client database using another Adaptive Server Anywhere database as a template. This utility is deprecated. For an alternative way to create client databases, see Creating a remote database.

Syntax

mlxtract [ additional-options ] directory site-name

Option | Description
-ac "keyword=value; ..." | Connect to the database specified in the connect string to do the reload.
-al filename | Log file name for this new database.
-an filename | Creates a database file with the same settings as the database being unloaded and automatically reloads it.
-c "keyword=value; ..." | Supply database connection parameters.
-id | Extract schema definition and data.
-it | Extract triggers.
-j count | Iteration count for view-creation statements.
-l level | Perform all extraction operations at specified isolation level.
-o file | Output messages to file.
-p character | Escape character.
-q | Operate quietly: do not print messages or show windows.
-r file | Specify name of generated reload Interactive SQL command file (default "reload.sql").
-s7 | Use Adaptive Server Anywhere version 7 syntax for creating synchronization definitions.
-u | Unordered data.
-v | Verbose messages.
-x | Use external table loads.
-xh | Exclude procedure hooks.
-xf | Exclude foreign keys.
-xp | Exclude stored procedures.
-xv | Exclude views.
-y | Overwrite command file without confirmation.
directory | The directory to which the files are written. This option is not needed if you use -an or -ac.
site-name | Specify which client database to generate.
Description

mlxtract is the MobiLink extraction utility for Adaptive Server Anywhere client databases. It is run against an Adaptive Server Anywhere reference database and creates a new client database or a command file for an Adaptive Server Anywhere client database, depending on the chosen options.

The command line extraction utility creates a command file and a set of associated data files. The command file can be run against a newly initialized Adaptive Server Anywhere database to create the database objects and load the data for the client database.

By default, the command file is named reload.sql.

Options

Reload the data to an existing database (-ac) You can combine the operation of extracting a database and reloading the results into an existing database using this option.

For example, the following command (which should be entered all on one line) loads a copy of the data for the field_user subscriber into an existing database file named newdemo.db:

mlxtract -c "uid=DBA;pwd=SQL;dbf=asademo.db" -ac "uid=DBA;pwd=SQL;dbf=newdemo.db" field_user

If you use this option, no copy of the data is created on disk, so you do not specify an unload directory on the command line. This provides greater security for your data, but at some cost for performance.

Reload the data to a new database (-an) You can combine the operations of extracting a database, creating a new database, and loading the data using this option.

For example, the following command (which should be entered all on one line) creates a new database file named asacopy.db and copies the schema and data for the field_user subscriber of asademo.db into it:

mlxtract -c "uid=DBA;pwd=SQL;dbf=asademo.db" -an asacopy.db field_user

If you use this option, no copy of the data is created on disk, so you do not specify an unload directory on the command line. This provides greater security for your data, but at some cost for performance.

Connection parameters (-c) A set of connection parameters, in a string.

  • mlxtract connection parameters The user ID should have DBA authority to ensure that the user has permissions on all the tables in the database.

    For example, the following statement (which should be typed on one line) extracts a database for MobiLink user name joe_remote from the ASADemo database running on the sample_server server, connecting as user ID DBA with password SQL. The data is unloaded into the c:\extract directory.

    mlxtract -c "eng=sample_server;dbn=sademo;
uid=DBA;pwd=SQL" c:\extract joe_remote

Extract both schema definition and data (-id) By default, only the schema is extracted. Such a database can be initialized with data upon the first connection to a MobiLink synchronization server. This option provides the option of extracting the initial set of data from the reference database.

Extract triggers (-it) By default, triggers are not extracted. This option provides causes triggers present in the reference database to be extracted.

Iteration count for views (-j) If there are nested views in the consolidated database, this option specifies the maximum number of iterations to use when extracting the views.

Perform extraction at a specified isolation level (-l) The default setting is an isolation level of zero. If you are extracting a database from an active server, you should run it at isolation level 3 to ensure that data in the extracted database is consistent with data on the server. Increasing the isolation level may result in large numbers of locks being used by the extraction utility, and may restrict database use by other users.

Output messages to file (-o) Outputs the messages from the extraction process to a file for later review.

Escape character (-p) The default escape character (\) can be replaced by another character using this option.

Operate quietly (-q) Display no messages except errors.

Reload filename (-r) The default name for the reload command file is reload.sql in the current directory You can specify a different file name with this option.

Use ASA v7 syntax (-s7) This option is useful when you are using an Adaptive Server Anywhere version 8 or higher consolidated database along with Adaptive Server Anywhere version 7 remote databases. For example, create a version 9 consolidated database, extract the remote databases using the -s7 option, and deploy the reload.sql files to the remote.

Output the data unordered (-u) By default the data in each table is ordered by primary key. Unloads are quicker with the -u option, but loading the data into the client database is slower.

Verbose mode (-v) The name of the table being unloaded and the number of rows unloaded are displayed. The SELECT statement used is also displayed.

Use external loads (-x) In the reload script, the default is to use the LOAD TABLE statement to load the data into the database. If you choose to use external loads, the Interactive SQL INPUT statement is used instead. The LOAD TABLE statement is faster than INPUT.

INPUT takes the path of the data files relative to the client, while LOAD TABLE takes the path relative to the server.

Exclude foreign key definitions (-xf) You can use this if the client database contains a subset of the consolidated database schema, and some foreign key references are not present in the client database.

Exclude stored procedure (-xp) Do not extract stored procedures from the database.

Exclude views (-xv) Do not extract views from the database.

Operate without confirming actions (-y) Without this option, you are prompted to confirm the replacement of an existing reloadcommand file.


MobiLink Client Network Protocol Options

About this chapter

This chapter describes the network protocol options that you use to connect to the MobiLink synchronization server from a remote database.

Protocol options


Protocol options

This chapter describes the network protocol options you can use when connecting a MobiLink client to the MobiLink synchronization server.

For information about how to use these options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to use these options with UltraLite, see:

  • TCP/IP protocol options
  • HTTP protocol options
  • HTTPS protocol options
  • UlSecureRSASocketStream synchronization parameters
  • UlSecureSocketStream synchronization parameters

For information about how to set connection options for the MobiLink synchronization server, see -x option.

buffer_size
certificate_company
certificate_name
certificate_unit
client_port
custom_header
host
http_password
http_proxy_password
http_proxy_userid
http_userid
liveness_timeout
network_connect_timeout
network_leave_open
network_name
persistent
port
proxy_host
proxy_port
security
set_cookie
trusted_certificates
url_suffix
version


buffer_size

Function

Specify the maximum HTTP body size for a fixed content length message, in bytes.

Syntax

buffer_size=number

Protocols
  • dbmlsync - HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - HTTP, HTTPS
Default
  • UltraLite - 1024
  • dbmlsync on PocketPC - 1024
  • dbmlsync on other devices - 64 000
Remarks

In general, the larger the HTTP body size, the fewer the number of HTTP request-response cycles, but the more memory required for buffering the body.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.


certificate_company

Function

If specified, the application only accepts server certificates when the Organization field on the certificate matches this value.

Separately licensable option required
Transport-layer security requires that you obtain a separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Syntax

certificate_company=organization

Protocols
  • dbmlsync - TCP/IP (via the security option), HTTPS, HTTPS_FIPS
  • UltraLite - TCP/IP (via security parms), HTTPS, UlSecureRSASocketStream, UlSecureSocketStream
Default

None

Remarks

MobiLink clients trust all certificates signed by the certificate authority, so they may also trust certificates that the same certificate authority has issued to other companies. Without a means to discriminate, your clients might mistake a competitor's MobiLink synchronization server for your own and accidentally send it sensitive information. This option specifies a further level of verification, that the Organization field in the identity portion of the certificate also matches a value you specify.

For TCP/IP, set this option as part of the security option. For more information, see security.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

See also
  • MobiLink Transport-Layer Security
  • Verifying certificate fields
  • -x option
  • security
  • trusted_certificates
  • certificate_name
  • certificate_unit
Example

The following examples tell an Adaptive Server Anywhere client to check all three identity fields and to accept only the named values. This example verifies all three fields. You can instead choose to verify only one or two fields.

For example, if you have Adaptive Server Anywhere clients you can set up certificate verification in the subscription as follows:

CREATE SYNCHRONIZATION SUBSCRIPTION
FOR 'user01'
TO test_pub
ADDRESS 'port=3333;security=ecc_tls(
 trusted_certificates=certicom.crt;
   certificate_company=Sybase, Inc.;
   certificate_unit=iAnywhere;certificate_name=sample )'

With UltraLite clients, the precise syntax depends upon the interface used to build the application. The following fragment of C code accomplishes the same task when developing the UltraLite application using embedded SQL in C or C++:

ul_synch_info info;
info.stream = ULSocketStream();
info.stream_parms = TEXT("port=9999");
info.security_stream = ULSecureRSATLSStream();
info.security_parms =
   UL_TEXT ( "certificate_company=Sybase, Inc." )
   UL_TEXT ( ";" )
   UL_TEXT ( "certificate_unit=iAnywhere" )
   UL_TEXT ( ";" )
   UL_TEXT ( "certificate_name=sample" );
. . .
ULSynchronize( &info );


certificate_name

Function

If specified, the application only accepts server certificates when the Common Name field on the certificate matches this value.

Separately licensable option required
Transport-layer security requires that you obtain a separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Syntax

certificate_name=common-name

Protocols
  • dbmlsync - TCP/IP (via the security option), HTTPS, HTTPS_FIPS
  • UltraLite - TCP/IP (via the security parameters), HTTPS, UlSecureRSASocketStream, UlSecureSocketStream
Default

None

Remarks

For TCP/IP, set this option as part of the security parameter. For more information, see security.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

See also
  • MobiLink Transport-Layer Security
  • Verifying certificate fields
  • -x option
  • security
  • trusted_certificates
  • certificate_company
  • certificate_unit
Example

The following example sets up RSA encryption for an HTTPS Protocol. This requires setup on the server and client. Each command must be written on one line.

dbmlsrv9
   -c "dsn=asa90sample;uid=DBA;pwd=SQL"
   -x https(
     port=9999;
     certificate=c:\asa90\win32\rsaserver.crt;
     certificate_password=test)

On an Adaptive Server Anywhere client, the implementation is:

dbmlsync
   -c "dsn=mydb;uid=DBA;pwd=SQL"
   -e "ctp=https;
       adr='port=9999;
         trusted_certificates=c:\asa90\win32\rsaroot.crt;
         certificate_name=RSA Server'"

On an UltraLite client, the equivalent implementation is:

    info.stream = ULHTTPSStream();
    info.stream_parms = TEXT(
      "port=9999;
       trusted_certificates=\rsaroot.crt;
       certificate_name=RSA Server");
    info.security_stream = NULL;
    info.security_parms = NULL;


certificate_unit

Function

If specified, the application only accepts server certificates when the Organization Unit field on the certificate matches this value.

Separately licensable option required
Transport-layer security requires that you obtain a separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Syntax

certificate_unit=organization-unit

Protocols
  • dbmlsync - TCP/IP (via the security option), HTTPS, HTTPS_FIPS
  • UltraLite - TCP/IP (via security parms), HTTPS, UlSecureRSASocketStream, UlSecureSocketStream
Default

None

Remarks

For TCP/IP, set this option as part of the security option. For more information, see security.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

See also
  • MobiLink Transport-Layer Security
  • Verifying certificate fields
  • -x option
  • security
  • trusted_certificates
  • certificate_company
  • certificate_name
Example

For examples of https security, see certificate_name and trusted_certificates.


client_port

Function

Specify a range of client ports for communication.

Syntax

client_port=nnnnn[-mmmmm]

Protocols
  • dbmlsync - TCP/IP, HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - TCP/IP, HTTP, HTTPS, UlSecureRSASocketStream, UlSecureSocketStream
Default

None

Remarks

Specify a low value and a high value to create a range of possible port numbers. To restrict the client to a specific port number, specify the same number for nnnnn and mmmmm. If you specify only one value, the end of the range is 100 greater than the initial value, for a total of 101 ports.

The option can be useful for clients inside a firewall communicating with a MobiLink synchronization server outside the firewall.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.


custom_header

Function

Specify a custom HTTP header.

Syntax

custom_header=header

HTTP headers are of the form header_name: header_value.

Protocols
  • dbmlsync - HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - HTTP and HTTPS, but not supported for Java UltraLite
Default

None

Remarks

When you specify custom HTTP headers, the client includes the headers with every HTTP request it sends. To specify more than one custom header, use custom_header multiple times.

Custom headers are useful when your synchronization client interacts with a third-party tool that requires custom headers.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

Example

Some HTTP proxies require all requests to contain special headers. The following example sets a custom HTTP header called MyProxyHdr to the value ProxyUser in an Embedded SQL or C++ UltraLite application.

info.stream = ULHTTPStream();
info.stream_parms = TEXT(
  "host=www.myhost.com;proxy_host=www.myproxy.com;
  custom_header=MyProxyHdr:ProxyUser");


host

Function

Specify the host name or IP number for the machine on which the MobiLink synchronization server is running, or, if you are synchronizing through a web server, the computer where the web server is running.

Syntax

host=hostname-or-ip

Protocols
  • dbmlsync - TCP/IP, HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - TCP/IP, HTTP, HTTPS, UlSecureRSASocketStream, UlSecureSocketStream
Default
  • Windows CE - the default value is taken from the desktop machine where the CE device cradle is connected, which is stored as the ipaddr entry in the registry folder Comm\Tcpip\Hosts\ppp_peer.
  • All other devices - the default is localhost.
Remarks

On Windows CE, do not use localhost, which refers to the remote device itself. The default value allows a Windows CE device to connect to a MobiLink synchronization server on the desktop machine where the Windows CE device's cradle is connected.

For the Palm Computing Platform, the default value of localhost refers to the device. You should supply an explicit host name or IP address to connect to a desktop machine.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.


http_password

Function

Authenticate to third-party HTTP servers and gateways using RFC 2617 Basic or Digest authentication.

Syntax

http_password=password

Protocols
  • dbmlsync - HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - HTTP, HTTPS
Default

None

Remarks

This feature supports Basic and Digest authentication as described in RFC 2617.

With Basic authentication, passwords are included in HTTP headers in clear text; however, you can use HTTPS to encrypt the headers and protect this password. With Digest authentication, headers are not sent in clear text but are hashed.

You must use http_userid with this option.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

See also
  • http_userid
  • http_proxy_password
  • http_proxy_userid
Example

The following example of an Embedded SQL or C++ UltraLite application provides a user ID and password for basic authentication to a web server.

synch_info.stream = ULHTTPSStream();
    synch_info.stream_parms = TEXT("http_userid=user;http_password=pwd");


http_proxy_password

Function

Authenticate to third-party HTTP proxies using RFC 2617 Basic or Digest authentication.

Syntax

http_proxy_password=password

Protocols
  • dbmlsync - HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - HTTP, HTTPS
Default

None

Remarks

This feature supports Basic and Digest authentication as described in RFC 2617.

With Basic authentication, passwords are included in HTTP headers in clear text; you can use HTTPS, but the initial connection to the proxy is through HTTP, so this password is clear text. With Digest authentication, headers are not sent in clear text but are hashed.

You must use http_proxy_userid with this option.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

See also
  • http_password
  • http_userid
  • http_proxy_userid
Example

The following example of an Embedded SQL or C++ UltraLite application provides a user ID and password for basic authentication to a web proxy.

synch_info.stream = ULHTTPSStream();
    synch_info.stream_parms = TEXT("http_proxy_userid=user;http_proxy_password=pwd");


http_proxy_userid

Function

Authenticate to third-party HTTP proxies using RFC 2617 Basic or Digest authentication.

Syntax

http_proxy_userid=userid

Protocols
  • dbmlsync - HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - HTTP, HTTPS
Default

None

Remarks

This feature supports Basic and Digest authentication as described in RFC 2617.

With Basic authentication, passwords are included in HTTP headers in clear text; you can use HTTPS, but the initial connection to the proxy is through HTTP, so the password is clear text. With Digest authentication, headers are not sent in clear text but are hashed.

You must use http_proxy_password with this option.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

See also
  • http_password
  • http_userid
  • http_proxy_password
Example

The following example of an Embedded SQL or C++ UltraLite application provides a user ID and password for basic authentication to a web proxy.

synch_info.stream = ULHTTPSStream();
    synch_info.stream_parms = TEXT("http_proxy_userid=user;http_proxy_password=pwd");


http_userid

Function

Authenticate to third-party HTTP servers and gateways using RFC 2617 Basic or Digest authentication.

Syntax

http_userid=userid

Protocols
  • dbmlsync - HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - HTTP, HTTPS
Default

None

Remarks

This feature supports Basic and Digest authentication as described in RFC 2617.

With Basic authentication, passwords are included in HTTP headers in clear text; however, you can use HTTPS to encrypt the headers and protect the password. With Digest authentication, headers are not sent in clear text but are hashed.

You must use http_password with this option.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

See also
  • http_password
  • http_proxy_password
  • http_proxy_userid
Example

The following example of an Embedded SQL or C++ UltraLite application provides a user ID and password for basic authentication to a web server.

synch_info.stream = ULHTTPSStream();
    synch_info.stream_parms = TEXT("http_userid=user;http_password=pwd");


liveness_timeout

Function

Specify the amount of time, in seconds, after the last communication with the client before MobiLink assumes that the connection to the client has been lost and aborts the synchronization.

Syntax

liveness_timeout=n

Protocols
  • dbmlsync - TCP/IP
  • UltraLite - TCP/IP, UlSecureRSASocketStream, UlSecureSocketStream
Default

120 seconds

Remarks

A value of 0 means that there is no timeout.

This option can be useful if download acknowledgement on the client is set to off (the default). This option is not normally used when download acknowledgement is on because if the download takes longer than n seconds to apply, the MobiLink synchronization server aborts the synchronization. Using a larger liveness_timeout value in this case usually defeats the purpose of the timeout.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.


network_connect_timeout

Function

Specify the number of seconds before the synchronization client should give up trying to connect.

Syntax

network_connect_timeout=seconds

Protocols
  • dbmlsync - TCP/IP, HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - TCP/IP, HTTP, HTTPS
Default

120 seconds

Remarks

You must specify network_name to use this option.

This feature applies to Pocket PC 2002 only. On Windows, you control this feature by configuring the connection profile for a given network_name.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.


network_leave_open

Function

When you specify network_name, you can optionally specify that the network connectivity should be left open after the synchronization finishes (1).

Syntax

network_leave_open={ 0 | 1 }

Protocols
  • dbmlsync - TCP/IP, HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - TCP/IP, HTTP, HTTPS
Default

Network connectivity is closed after synchronization ( 0 )

Remarks

You must specify network_name to use this option.

When this option is set to 1, network connectivity is left open after the synchronization finishes.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

See also

network_name


network_name

Function

Specify the network name to start when not already connected to the network.

Syntax

network_name=name

Protocols
  • dbmlsync - TCP/IP, HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - TCP/IP, HTTP, HTTPS
Default

None

Remarks

Specify the network name so that you can use MobiLink's auto-dial feature. This allows you to connect from a Pocket PC 2002 or Windows desktop computer without manually dialing.

Used with scheduling, your remote can synchronize unattended. Used without scheduling, this allows you to run dbmlsync without manually dialing a connection. The name should be the network name that you have specified in the dropdown list in Settings > Connections > Connections (Pocket PC) or Network & Dialup Connections (Windows).

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

See also
  • Scheduling synchronization
  • network_connect_timeout
  • network_leave_open


persistent

Function

Use a single TCP/IP connection for all HTTP requests in a synchronization.

Syntax

persistent={ 0 | 1 }

Protocols
  • dbmlsync - HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - HTTP, HTTPS

HTTP, HTTPS

Default
  • Palm - 0
  • All other devices - 1
Remarks

1 means that the client will attempt to use the same TCP/IP connection for all HTTP requests in a synchronization. A setting of 0 is usually more compatible with intermediate agents.

Except on Palm devices, you should only set persistent to 1 if you are connecting directly to MobiLink. If you are connecting through an intermediate agent such as a proxy or redirector, a persistent connection may cause problems.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.


port

Function

Specify the socket port number.

Syntax

port=port-number

Protocols
  • dbmlsync - TCP/IP, HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - TCP/IP, HTTP, HTTPS, UlSecureRSASocketStream, UlSecureSocketStream
Default

For TCP/IP, the default is 2439, which is the IANA-registered port number for the MobiLink synchronization server.

For HTTP, the default is 80.

For HTTPS and HTTPS_FIPS, the default is 443.

Remarks

The port number must be a decimal number that matches the port the MobiLink synchronization server is set up to listen on.

If you are synchronizing through a web server, specify the web server port accepting HTTP or HTTPS requests.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.


proxy_host

Function

Specify the host name or IP address of the proxy server.

Syntax

proxy_host=proxy_hostname_or_ip

Protocols
  • dbmlsync - HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - HTTP, HTTPS

HTTP, HTTPS

Default

None

Remarks

Use only if going through a proxy.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.


proxy_port

Function

Specify the port number of the proxy server.

Syntax

proxy_port=proxy_port_number

Protocols
  • dbmlsync - HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - HTTP, HTTPS
Default

None

Remarks

Use only if going through a proxy.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.


security

Function

Specify an encryption cipher and encryption options for synchronization.

Separately licensable option required
Transport-layer security requires that you obtain a separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Syntax

security=cipher( keyword=value;... )

Protocols

dbmlsync - TCP/IP

Default

None

Remarks

All communication for this synchronization is to be encrypted using the specified cipher. The cipher can be one of:

  • ecc_tls for elliptic-curve encryption. For backwards compatibility, ecc_tls can also be specified as certicom_tls.

  • rsa_tls for RSA encryption.

  • rsa_tls_fips for RSA encryption that is FIPS-approved. The rsa_tls_fips cipher uses separate FIPS 140-2 certified software from Certicom. Clients using rsa_tls are compatible with servers using rsa_tls_fips, and clients using rsa_tls_fips are compatible with servers using rsa_tls. rsa_tls_fips can only be used with Adaptive Server Anywhere databases on Windows.

For more information, see Configuring MobiLink clients to use transport-layer security.

The following security keywords are supported.

  • certificate_company=organization

  • certificate_name=common_name

  • certificate_unit=organization_unit

  • trusted_certificates=filename

When using dbmlsync with HTTPS, you do not set the security option, but set these four security keywords directly. For details of how to set the security options, see each security keyword.

For UltraLite, see Security synchronization parameter.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

See also
  • MobiLink Transport-Layer Security
  • -x option
  • certificate_company
  • certificate_name
  • certificate_unit
  • trusted_certificates
Example

The following example sets up RSA encryption for a dbmlsync TCP/IP protocol. This requires setup on the server and client. Each command must be written on one line.

dbmlsrv9
  -c "dsn=asa90sample;uid=DBA;pwd=SQL"
  -x tcpip(
    port=9999;
    security=rsa_tls(
      certificate=c:\asa90\win32\rsaserver.crt;
      certificate_password=test))
dbmlsync
  -c "dsn=mydb;uid=DBA;pwd=SQL"
  -e "ctp=tcpip;
      adr='port=9999;
         security=rsa_tls(
           trusted_certificates=c:\asa90\win32\rsaroot.crt;
           certificate_name=RSA Server)'"

For UltraLite clients, you implement the client side slightly differently. The equivalent client implementation in an Embedded SQL or C++ UltraLite application is:

    info.stream = ULSocketStream();
    info.stream_parms = TEXT("port=9999");
    info.security_stream = ULSecureRSATLSStream();
    info.security_parms = TEXT("trusted_certificates=\rsaroot.crt;certificate_name=RSA Server");


set_cookie

Function

Specify custom HTTP cookies to set in the HTTP requests used during synchronization.

Syntax

set_cookie=cookie_name=cookie_value [ ,cookie_name=cookie_value, ... ]

Protocols
  • dbmlsync - HTTP, HTTPS, and HTTPS_FIPS
  • UltraLite - HTTP and HTTPS, but not supported for Java UltraLite
Default

None

Remarks

Custom HTTP cookies are useful when your synchronization client interacts with a third-party tool, such as an authentication tool, that uses cookies to identify sessions. For example, you have a system where a user agent connects to a web server, proxy, or gateway and authenticates itself. If successful, the agent receives one or more cookies from the server. The agent then starts a synchronization and hands over its session cookies through the set_cookie option.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

Example

The following example sets a custom HTTP cookie in an Embedded SQL or C++ UltraLite application.

info.stream = ULHTTPStream();
info.stream_parms = TEXT(
  "host=www.myhost.com;
  set_cookie=MySessionID=12345, enabled=yes;");


trusted_certificates

Function

Specify a file containing a list of trusted root certificates used for secure synchronization.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Syntax

trusted_certificates=filename

Protocols
  • dbmlsync - TCP/IP (via the security option), HTTPS, HTTP_FIPS
  • UltraLite - TCP/IP (via security parms), HTTPS. Not supported on Palm OS.
Default

None

Remarks

When synchronization occurs through a Certicom TLS synchronization stream, the MobiLink synchronization server sends its certificate to the client, as well as the certificate of the entity that signed it, and so on up to a self-signed root.

The client checks that the chain is valid and that it trusts the root certificate in the chain. This feature allows you to specify which root certificates to trust.

This option is required when using encryption for dbmlsync.

This option is not available on the Palm platform or with UltraLite Static Java.

For TCP/IP, set this option as part of the security option. For more information, see security.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.

See also
  • MobiLink Transport-Layer Security
  • -x option
  • security
  • certificate_company
  • certificate_name
  • certificate_unit
Example

The following example sets up RSA encryption for an HTTPS protocol. This requires setup on the server and client. Each command must be written on one line.

dbmlsrv9
   -c "dsn=asa90sample;uid=DBA;pwd=SQL"
   -x https(
     port=9999;
     certificate=c:\asa90\win32\rsaserver.crt;
     certificate_password=test)

On an Adaptive Server Anywhere client, the implementation is:

dbmlsync
   -c "dsn=mydb;uid=DBA;pwd=SQL"
   -e "ctp=https;
       adr='port=9999;
         trusted_certificates=c:\asa90\win32\rsaroot.crt;
         certificate_name=RSA Server'"

On an UltraLite client, the equivalent implementation is:

    info.stream = ULHTTPSStream();
    info.stream_parms = TEXT(
      "port=9999;
       trusted_certificates=\rsaroot.crt;
       certificate_name=RSA Server");
    info.security_stream = NULL;
    info.security_parms = NULL;

For UltraLite clients addressing the Palm OS, the following command embeds the trusted root certificate in the generated code with the UltraLite Generator:

ulgen.exe -c "dsn=asa90sample;uid=DBA;pwd=SQL"  -r c:\asa90\win32\rsaroot.crt test test.c

Alternatively, you can use the UltraLite initialization utility:

ulinit.exe -c "dsn=asa90sample;uid=DBA;pwd=SQL" -t c:\asa90\win32\rsaroot.crt -f test.usm -n test_pub


url_suffix

Function

Specify the suffix to add to the URL on the first line of each HTTP request sent during synchronization.

Syntax

url_suffix=suffix

Protocols
  • dbmlsync - HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - HTTP, HTTPS

HTTP, HTTPS

Default

The default value is MobiLink\.

Remarks

When synchronizing through a proxy or web server, the url_suffix may be necessary in order to find the MobiLink synchronization server.

For information about how to set this option when using the Redirector, see Configuring MobiLink clients and servers for the Redirector.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.


version

Function

Specify the version of HTTP to use for synchronization.

Syntax

version=HTTP_version_number

Protocols
  • dbmlsync - HTTP, HTTPS, HTTPS_FIPS
  • UltraLite - HTTP, HTTPS
Default

The default value is 1.1.

Remarks

This option is useful if your HTTP infrastructure requires a specific version of HTTP. Values can be 1.0 or 1.1.

HTTPS_FIPS is available on Windows only.

For information about how to set network protocol options with dbmlsync, see CommunicationAddress (adr) extended option.

For information about how to set network protocol options with UltraLite, see Network protocol options for UltraLite synchronization clients.


Adaptive Server Anywhere Clients

About this chapter

This chapter describes how to use Adaptive Server Anywhere databases as MobiLink clients.

For a tutorial to walk you through some of the concepts in this chapter, see Tutorial: Introduction to MobiLink.

For information about UltraLite databases as MobiLink clients, seeUltraLite Clients.

Creating a remote database
Publishing data
Creating MobiLink users
Subscribing MobiLink synchronization users
Initiating synchronization
Using ActiveSync synchronization
Temporarily stopping synchronization of deletes
Scheduling synchronization
Adaptive Server Anywhere version 7 MobiLink clients


Creating a remote database

Any Adaptive Server Anywhere database can be converted for use as a remote database in a MobiLink installation. All you need to do is create a publication, create a MobiLink user, and subscribe the MobiLink user to the publication.

toggle To create an Adaptive Server Anywhere remote database

  1. Start with an existing Adaptive Server Anywhere database, or create a new one and add your tables.

  2. Create one or more publications in the new database.

    See Publishing data.

  3. Create a MobiLink user.

    See Creating MobiLink users.

  4. Subscribe a MobiLink user to one or more of the publications.

    See Subscribing MobiLink synchronization users.


Deploying remote databases

To deploy Adaptive Server Anywhere remote databases, you need to create the databases and add the appropriate publications and subscriptions. To do this, you customize a prototype remote database.

toggle To deploy MobiLink remote databases by customizing a prototype

  1. Create a prototype remote database.

    The prototype database should have all the tables and publications needed, but not the information that is specific to each database. This individual information typically includes the following:

    • The MobiLink user name.

    • Synchronization subscriptions.

    • The GLOBAL_DATABASE_ID option that provides the starting point for global autoincrement key values.

  2. For each remote database, carry out the following operations:

    • Create a directory to hold the remote database.

    • Copy the prototype remote database into the directory.

      If the transaction log is held in the same directory as the remote database, the log filename does not need to be changed.

    • Run a SQL script that adds the individual information to the database.

      The SQL script can be a parameterized script. For information on parameterized scripts, see PARAMETERS statement [Interactive SQL], and Using SQL command files.

Example

The following SQL script is taken from the Contact sample. It can be found in Samples\MobiLink\Contact\customize.sql.

PARAMETERS ml_userid, db_id;
go
SET OPTION PUBLIC.GLOBAL_DATABASE_ID = {db_id}
go

CREATE SYNCHRONIZATION USER {ml_userid}
        TYPE 'TCPIP'
        ADDRESS 'host=localhost;port=2439'
        OPTION MEM=''
go
CREATE SYNCHRONIZATION SUBSCRIPTION TO "DBA"."Product"
        FOR {ml_userid}
go
CREATE SYNCHRONIZATION SUBSCRIPTION TO "DBA"."Contact"
        FOR {ml_userid}
go
commit work
go

The following command line executes the script for a remote database with data source dsn_remote_1.

dbisql -c "dsn=dsn_remote_1" read customize.sql [SSinger] [2]


Partitioning data between remote databases

It is common for remote databases to fall into separate categories, each with their own requirements. Consider a sales application. All the sales personnel in one region may require access to a particular set of data, but not require access to information about regions other than their own. Employees in other departments may require data of an entirely different nature. Managers may require data that should not be accessible to their subordinates.

Publications are typically used to specify fundamentally different sets of data. For example, you can create one publication for the sales staff and another publication for those employees who do technical support.

You can further fine-tune the data any given remote database will receive by using a WHERE clause within the publication. This feature is useful when remote databases require similar types of information. For example, it can be used to provide sales representatives with only the information relevant to their region.

For more information, see Partitioning rows among remote databases.


Upgrading remote databases

If you install a new Adaptive Server Anywhere remote database over an older version, the synchronization progress information in the consolidated database is incorrect.

You can correct this problem by setting the progress column of the ml_user table to 0 (zero) for this user. This is an exceptional case when direct modification of the MobiLink system tables is required. In other cases, you should not directly access the MobiLink system tables.

For more information, see Upgrading Adaptive Server Anywhere MobiLink clients.


Progress offsets

The offset, also called the progress or state, refers to a position in the transaction log of the remote database. It indicates the point to which all operations for the subscription have been uploaded and acknowledged. Dbmlsync uses the offset to decide what data to upload. On the remote database, the offset is stored in the progress column of the SYS.SYSSYNC system table. On the consolidated database, the offset is stored in the progress column of the ml_user table for version 7.x databases, and in the progress column of the ml_subscription table for version 8.0 and up databases.

For each remote, the remote and consolidated databases maintain an offset for every subscription. When a user synchronizes, the offsets are confirmed for all subscriptions that are associated with the user, even if they are not being synchronized at the time. This is required because publications can synchronize the same data. The only exception is that dbmlsync does not check the progress offset of a subscription until it has attempted an upload.

If there is any disagreement between the remote and consolidated database offsets, the default behavior is to update the offsets on the remote with values from the consolidated and then send a new upload based on those offsets. In most cases, this default is appropriate. For example, it is generally appropriate when the consolidated database is restored from backup and the remote transaction log is intact, or when an upload is successful but communication failure prevented an upload acknowledgement from being sent.

Most progress offset mismatches are resolved automatically using the consolidated progress values. In the rare case that you must intervene to fix a problem with progress offsets, you can use the dbmlsync -r option.

For more information, see -r option.

First synchronization always works

When you delete and recreate a remote database and then synchronize for the first time, you don't get a progress offset mismatch even though there may be a mismatch with the progress value on the consolidated database. This is because dbmlsync detects that this is a first synchronization and so does not check the offset of the consolidated database, but instead uses the progress offset on the remote database.

Dbmlsync detects a first synchronization when the columns in the remote database system table SYS.SYSSYNC are as follows: the value for the progress column is the same as the value for the created column, and the value for the log_sent column is NULL.

However, if your first synchronization synchronizes two or more subscriptions in the same upload stream, and one of the subscriptions is not synchronizing for the first time, then progress offsets are checked for all subscriptions being synchronized, including the ones that are being synchronized for the first time. For example, you specify the dbmlsync -n option with two publications (-n pub1,pub2), and pub1 has synchronized before but pub2 has not. In this case, if you have deleted and recreated a remote database, there may be a progress offset mismatch with the consolidated database.

For more information, see:

  • SYSSYNC system table
  • ml_user
  • ml_subscription


Publishing data

A publication is a database object that identifies the data that is to be synchronized. A publication consists of articles, which are subsets of a table's columns, rows, or both. Each publication can contain one or more entire tables, or partial tables consisting of selected rows and columns. In a single publication, no table can be included in more than one article.

You create publications using Sybase Central or with the CREATE PUBLICATION statement.

In Sybase Central, all publications and articles appear in the Publications folder.

Notes about publications

  • DBA authority is required to create and drop publications.

  • In order to be able to synchronize when you subscribe to multiple publications, the publications must contain the same column subsets of the same table.

  • The publication determines which columns are selected, but it does not determine the order in which they are sent. Columns are always sent in the order in which they were defined in the CREATE TABLE statement.

  • Publications must include all the columns in the primary key of the table that they reference.

  • A single publication can publish a subset of columns from a set of tables and use a WHERE clause to select a set of rows to be replicated.

  • Views and stored procedures cannot be included in publications.

  • Publications and subscriptions are also used by the Sybase message-based replication technology, SQL Remote. SQL Remote requires publications and subscriptions in both the consolidated and remote databases. In contrast, MobiLink publications appear only in Adaptive Server Anywhere remote databases. MobiLink consolidated databases are configured using synchronization scripts.

Publishing whole tables
Publishing only some columns in a table
Publishing only some rows in a table
Altering existing publications
Dropping publications


Publishing whole tables

The simplest publication you can make consists of a single article, which consists of all rows and columns of one or more tables. These tables must already exist.

toggle To publish one or more entire tables (Sybase Central)

  1. Connect to the remote database as a user with DBA authority, using the Adaptive Server Anywhere plug-in.

  2. Open the Publications folder.

  3. From the File menu, choose New > Publication. The Create a New Publication wizard appears.

  4. Type a name for the new publication. Click Next.

  5. On the Tables tab, select a table from the list of Available Tables. Click Add. The table appears in the list of Selected Tables on the right.

  6. Optionally, you may add additional tables. The order of the tables is not important.

  7. Click Finish.

toggle To publish one or more entire tables (SQL)

  1. Connect to the remote database as a user with DBA authority.

  2. Execute a CREATE PUBLICATION statement that specifies the name of the new publication and the table you want to publish.

Example

The following statement creates a publication that publishes the whole customer table:

CREATE PUBLICATION pub_customer (
   TABLE customer
)

The following statement creates a publication including all columns and rows in each of a set of tables from the Adaptive Server Anywhere sample database:

CREATE PUBLICATION sales (
   TABLE customer,
   TABLE sales_order,
   TABLE sales_order_items,
   TABLE product
)

For more information, see the CREATE PUBLICATION statement.


Publishing only some columns in a table

You can create a publication that contains all the rows but only some of the columns of a table from Sybase Central or by listing the columns in the CREATE PUBLICATION statement.

Note

If you create two publications that include the same table with different column subsets, then any user who subscribes to both publications will be unable to synchronize.

toggle To publish only some columns in a table (Sybase Central)

  1. Connect to the remote database as a user with DBA authority using the Adaptive Server Anywhere plug-in.

  2. Open the Publications folder.

  3. From the File menu, choose New > Publication. The Create a New Publication wizard appears.

  4. Type a name for the new publication. Click Next.

  5. On the Tables tab, select a table from the list of Available Tables. Click Add. The table is added to the list of Selected Tables on the right.

  6. On the Columns tab, double-click the table's icon to expand the list of Available Columns. Select each column you want to publish and click Add. The selected columns appear on the right.

  7. Click Finish.

toggle To publish only some columns in a table (SQL)

  1. Connect to the remote database as a user with DBA authority.

  2. Execute a CREATE PUBLICATION statement that specifies the publication name and the table name. List the published columns in parenthesis following the table name.

Example

The following statement creates a publication that publishes all rows of the id, company_name, and city columns of the customer table:

CREATE PUBLICATION pub_customer (
   TABLE customer (id, company_name,
      city )
)

For more information, see the CREATE PUBLICATION statement.


Publishing only some rows in a table

You can create a publication that contains some or all the columns in a table, but only some of the rows. You do so by writing a search condition that matches only the rows you want to publish.

Sybase Central and the SQL language each provide two ways of publishing only some of the rows in a table; however, only one way is compatible with MobiLink.

  • WHERE clause Compatible with MobiLink. You can use a WHERE clause to include a subset of rows in an article.

  • Subscription expression Ignored by MobiLink.

In MobiLink, you can use the WHERE clause to exclude the same set of rows from all subscriptions to a publication. All subscribers to the publication upload any changes to the rows that satisfy the search condition.

toggle To create a publication using a WHERE clause (Sybase Central)

  1. Connect to the remote database as a user with DBA authority using the Adaptive Server Anywhere plug-in.

  2. Open the Publications folder.

  3. From the File menu, choose New > Publication. The Create a New Publication wizard appears.

  4. Type a name for the new publication. Click Next.

  5. On the Tables tab, select a table from the list of Available Tables. Click Add. The table is added to the list of Selected Tables on the right.

  6. On the WHERE Clauses tab, select the table and type the search condition in the lower box. Optionally, you can use the Insert dialog to assist you in formatting the search condition.

  7. Click Finish.

toggle To create a publication using a WHERE clause (SQL)

  1. Connect to the remote database as a user with DBA authority.

  2. Execute a CREATE PUBLICATION statement that includes the tables you wish to include in the publication and a WHERE condition.

Examples

The following statement creates a publication that publishes the id, company_name, city, and state columns of the customer table, for the customers marked as active in the status column.

CREATE PUBLICATION pub_customer (
   TABLE customer (
      id,
      company_name,
      city,
      state )
   WHERE status = 'active'
)

In this case, the status column itself is not published. All unpublished rows must have a default value. Otherwise, an error occurs when rows are downloaded for insert from the consolidated database.

The following example creates a single-article publication that includes order information for sales rep number 856.

CREATE PUBLICATION pub_orders_samuel_singer (
   TABLE sales_order WHERE sales_rep = 856
)

For more information, see the CREATE PUBLICATION statement. Note that the CREATE PUBLICATION statement includes a SUBSCRIBE BY clause. This clause can be used to selectively publish rows in SQL Remote. However, it is ignored during MobiLink synchronization.


Altering existing publications

After you have created a publication, you can alter it by adding, modifying, or deleting articles, or by renaming the publication. If an article is modified, the entire specification of the modified article must be entered.

You can perform these tasks using Sybase Central or with the ALTER PUBLICATION statement.

Notes

  • Publications can be altered only by the DBA or the publication's owner.

  • Be careful. In a running MobiLink setup, altering publications may cause errors and can lead to loss of data.

toggle To modify the properties of existing publications or articles (Sybase Central)

  1. Connect to the remote database as a user who owns the publication or as a user with DBA authority.

  2. In the left pane, click the publication or article. The properties will appear in the right pane.

  3. Configure the desired properties.

toggle To add articles (Sybase Central)

  1. Connect to the remote database as a user who owns the publication or as a user with DBA authority using the Adaptive Server Anywhere plug-in.

  2. Open the Publications folder.

  3. Select a publication.

  4. From the File menu, choose New > Article. The Create a New Article wizard appears.

  5. In the Article Creation wizard, do the following:

    • On the first page, select a table.

    • On the next page, select the number of columns.

    • On the final page, enter a WHERE clause (if desired).

  6. Click Finish to create the article.

toggle To remove articles (Sybase Central)

  1. Connect to the database as a user who owns the publication or as a user with DBA authority using the Adaptive Server Anywhere plug-in.

  2. Open the Publications folder.

  3. Click the publication.

  4. In the right pane, right-click the article you want to delete and choose Delete from the popup menu.

toggle To modify an existing publication (SQL)

  1. Connect to the remote database as a user who owns the publication or as a user with DBA authority.

  2. Connect to a database with DBA authority.

  3. Execute an ALTER PUBLICATION statement.

Example

  • The following statement adds the customer table to the pub_contact publication.

    ALTER PUBLICATION pub_contact (
   ADD TABLE customer
)

See also the ALTER PUBLICATION statement.


Dropping publications

You can drop a publication using either Sybase Central or the DROP PUBLICATION statement. Before dropping the publication, you must drop all subscriptions connected to it.

You must have DBA authority to drop a publication.

toggle To delete a publication (Sybase Central)

  1. Connect to the remote database as a user with DBA authority using the Adaptive Server Anywhere plug-in.

  2. Open the Publications folder.

  3. Right-click the desired publications and choose Delete from the popup menu.

toggle To delete a publication (SQL)

  1. Connect to the remote database as a user with DBA authority.

  2. Execute a DROP PUBLICATION statement.

Example

The following statement drops the publication named pub_orders.

DROP PUBLICATION pub_orders

See also the DROP PUBLICATION statement.


Creating MobiLink users

A MobiLink user name uniquely identifies a remote database. It is used to identify, and optionally authenticate, clients attempting to connect to the MobiLink synchronization server.

MobiLink users are not the same as database users. You can create a MobiLink user name that matches the name of a database user, but neither MobiLink nor Adaptive Server Anywhere is affected by this coincidence.

For information about adding MobiLink users to the consolidated database, see About MobiLink users.


Adding MobiLink users to a remote database

This section describes how to add a MobiLink user name to a remote database. For information on supplying MobiLink user properties, including the password, see Configuring MobiLink user properties.

toggle To add a MobiLink user to a remote database (Sybase Central)

  1. Connect to the database from the Adaptive Server Anywhere plug-in as a user with DBA authority.

  2. Click the MobiLink Users folder.

  3. From the File menu, choose New > MobiLink User. The Create a New MobiLink User wizard appears.

  4. Enter a name for the MobiLink user. This name is supplied to the MobiLink synchronization server during synchronization.

    The MobiLink user name uniquely identifies a remote database and so must be unique within your synchronization system.

  5. Click Finish.

toggle To add a MobiLink user to a remote database (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute a CREATE SYNCHRONIZATION USER statement. The MobiLink user name uniquely identifies a remote database and so must be unique within your synchronization system.

    The following example adds a MobiLink user named SSinger:

    CREATE SYNCHRONIZATION USER SSinger

    You can specify properties for the MobiLink user as part of the CREATE SYNCHRONIZATION USER statement, or you can specify them separately with an ALTER SYNCHRONIZATION USER statement.

    For more information, see CREATE SYNCHRONIZATION USER statement [MobiLink].


Configuring MobiLink user properties

You can specify properties for each MobiLink user in a remote database.

There are two types of property:

  • Options Options can be specified on the dbmlsync command line. For a complete list of dbmlsync command line options, see Adaptive Server Anywhere Client Synchronization Parameters.

  • Extended options Extended options can be specified on the command line, stored in the database, or specified with the sp_hook_dbmlsync_set_extended_options event hook.

    For a list of extended options, see dbmlsync extended options.

toggle To store MobiLink extended options in the database (Sybase Central)

  1. Connect to the database from the Adaptive Server Anywhere plug-in as a user with DBA authority.

  2. Open the MobiLink Users folder.

  3. Right-click the MobiLink user name and choose Properties from the pop-up menu.

  4. Change the properties as needed.

toggle To store MobiLink extended options in the database (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute an ALTER SYNCHRONIZATION USER statement.

    The following example changes the extended options for MobiLink user named SSinger to their default values:

    ALTER SYNCHRONIZATION USER SSinger
DELETE ALL OPTION

    For more information, see ALTER SYNCHRONIZATION USER statement [MobiLink].

    You can also specify properties when you create the MobiLink user name.

    For more information, see CREATE SYNCHRONIZATION USER statement [MobiLink].

toggle To configure MobiLink user properties on the command line

  • You can specify dbmlsync options when you start dbmlsync.

    For more information, see Adaptive Server Anywhere Client Synchronization Parameters.

toggle To specify MobiLink user properties with a client event hook

  • You can programmatically customize the behavior of an upcoming synchronization.

    For more information, see sp_hook_dbmlsync_set_extended_options.


Priority order for extended options and connection parameters

The CREATE/ALTER SYNCHRONIZATION USER and CREATE/ALTER SYNCHRONIZATION SUBSCRIPTION statements allow you to store extended options and connection parameters in the database and associate them with subscriptions, users or publications. The dbmlsync utility reads this information from the database.

Note: You specify options for a publication by using the CREATE SYNCHRONIZATION SUBSCRIPTION statement and omitting the FOR clause.

If extended options are specified in both the database and the command line, the option strings are combined. If conflicting options are specified, dbmlsync resolves them as follows, where options specified by earlier in the list take precedence over those occurring later in the list.

  1. options specified in the sp_hook_dbmlsync_set_extended_options event hook.

  2. options specified on the command line that aren't extended options. (For example, -ds overrides -e "ds=off".)

  3. options specified on the command line with the dbmlsync -eu option.

  4. options specified on the command line with the dbmlsync -e option.

  5. options saved with the subscription definition (whether using SQL statements or Sybase Central).

  6. options saved with the user definition (whether using SQL statements or Sybase Central).

  7. options saved with the publication definition (whether using SQL statements or Sybase Central).

If the connection TYPE or ADDRESS is specified in more than one place, the one specified with the highest priority according to the list above overrides any other specification.


Dbmlsync connection parameters

Dbmlsync connection information includes the protocol to use for communications with the server, the address for the MobiLink synchronization server, and other connection parameters.

For more information, see:

  • CommunicationType (ctp) extended option
  • CommunicationAddress (adr) extended option
  • -c option


Dropping MobiLink users

You must drop all subscriptions for a MobiLink user before you drop the user from a remote database.

toggle To drop a MobiLink user from a remote database (Sybase Central)

  1. Connect to the database from the Adaptive Server Anywhere plug-in as a user with DBA authority.

  2. Locate the MobiLink user in the MobiLink Users folder.

  3. Right click the MobiLink user and choose Delete from the popup menu.

toggle To drop a MobiLink user from a remote database (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute a DROP SYNCHRONIZATION USER statement.

    The following example removes the MobiLink user named SSinger from the database:

    DROP SYNCHRONIZATION USER SSinger

    For more information, see DROP SYNCHRONIZATION USER statement [MobiLink].


Subscribing MobiLink synchronization users

To complete the setup, you must subscribe at least one MobiLink user to one or more pre-existing publications.

For information about creating publications, see Publishing data. For information about creating MobiLink users, see Creating MobiLink users.

Subscriptions versus synchronization subscriptions
Do not confuse subscriptions (CREATE SUBSCRIPTION statement) with synchronization subscriptions (CREATE SYNCHRONIZATION SUBSCRIPTION statement). Subscriptions work only with SQL Remote. They create relationships between publications and database users who have been granted remote privileges. Synchronization subscriptions, used with MobiLink, create relationships between publications and MobiLink users .

A synchronization subscription links a particular MobiLink user with a publication. It can also carry other information needed for synchronization. For example, you can specify the address of the MobiLink server and any desired options for a synchronization subscription. Values for a specific synchronization subscription override those set for MobiLink users.

Synchronization subscriptions are required only in MobiLink Adaptive Server Anywhere remote databases. Server logic is implemented through synchronization scripts, stored in the MobiLink system tables in the consolidated database.

A single Adaptive Server Anywhere database can synchronize with more than one MobiLink synchronization server. To allow synchronization with multiple servers, create different MobiLink users for each server.

Example

To synchronize the customer and sales_order tables in the Adaptive Server Anywhere sample database, you could use the following statements.

  1. First, publish the customer and sales_order tables. Give the publication the name testpub.

    CREATE PUBLICATION testpub
   (TABLE customer, TABLE sales_order)

  2. Next, create a MobiLink user. In this case, the MobiLink user is demo_ml_user.

    CREATE SYNCHRONIZATION USER demo_ml_user

  3. To complete the process, subscribe the user to the publication.

    CREATE SYNCHRONIZATION SUBSCRIPTION TO testpub
   FOR demo_ml_user
   TYPE tcpip
   ADDRESS 'host=localhost;port=2439;'
   OPTION sv='version1'


Altering MobiLink subscriptions

Synchronization subscriptions can be altered using Sybase Central or the ALTER SYNCHRONIZATION SUBSCRIPTION statement. The syntax is similar to that of the CREATE SYNCHRONIZATION SUBSCRIPTION statement, but provides an extension to more conveniently add, modify, and delete options.

toggle To alter a synchronization subscription (Sybase Central)

  1. Connect to the database as a user with DBA authority.

  2. Open the MobiLink Users folder.

  3. Click the desired user. The properties appear in the right pane.

  4. In the right pane, click the Synchronization Subscriptions tab. Right-click the subscription you wish to change and select Properties from the popup menu.

  5. Change the properties as needed

toggle To alter a synchronization subscription (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute an ALTER SYNCHRONIZATION SUBSCRIPTION statement.

For more information, see ALTER SYNCHRONIZATION USER statement [MobiLink].


Dropping MobiLink subscriptions

You can delete a synchronization subscription using either Sybase Central or the DROP SYNCHRONIZATION SUBSCRIPTION statement.

You must have DBA authority to drop a synchronization subscription.

toggle To delete a synchronization subscription (Sybase Central)

  1. Connect to the database as a user with DBA authority.

  2. Open the MobiLink Users folder.

  3. Select a MobiLink user.

  4. Right-click the desired subscription and choose Delete from the popup menu.

toggle To delete a synchronization subscription (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute a DROP SYNCHRONIZATION SUBSCRIPTION statement.

Example

The following statement drops the synchronization subscription of MobiLink user jsmith to a publication named pub_orders.

DROP SYNCHRONIZATION SUBSCRIPTION
FOR jsmith TO pub_orders

See also the DROP SYNCHRONIZATION SUBSCRIPTION statement [MobiLink].


Initiating synchronization

The client always initiates MobiLink synchronization. In the case of an Adaptive Server Anywhere client, synchronization is initiated by running the dbmlsync utility. This utility connects to and synchronizes an Adaptive Server Anywhere remote database.

You can specify connection parameters on the dbmlsync command line using the -c option. These parameters are for the remote database. If you do not specify connection parameters, a connection dialog appears, asking you to supply the missing connection parameters and startup options.

Connection parameters set in the synchronization subscriptions within the remote database are used to locate the appropriate MobiLink synchronization server.

Permissions for dbmlsync

When dbmlsync connects to a database, it must have permissions to apply all the changes being made. The dbmlsync command line contains the password for this connection. This could present a security issue.

To avoid security problems, grant a user (other than DBA) REMOTE DBA authority, and use this user ID in the dbmlsync connection string. A user ID with REMOTE DBA authority has DBA authority only when the connection is made from the dbmlsync utility. Any other connection using the same user ID is granted no special authority.

Multiple MobiLink synchronization users
Customizing synchronization
Transaction log files
Concurrency during synchronization
Initiating synchronization from an application


Multiple MobiLink synchronization users

Each remote database typically contains exactly one MobiLink synchronization user. In this case, you do not need to specify a MobiLink user name on the dbmlsync command line. However, if the remote database contains more than one, you must specify which MobiLink synchronization user to synchronize using the -u command line option.

dbmlsync –c "dsn=remote;uid=syncuser" -u mluser

Similarly, you can specify the user's password using the -mp option, or change the password by specifying the new password with the -mn option. These are the user ID and password used to the MobiLink synchronization server and may be different from the user ID and password used to connect to the remote database.


Customizing synchronization

MobiLink provides a number of extended options to customize the synchronization process. Extended options can be set for publications, users, and subscriptions. In addition, extended option values can be overridden using options on the dbmlsync command line.

For a complete list of extended options, see dbmlsync extended options.

toggle To override an extended option on the dbmlsync command line

  • Supply the extended option values in the -e or -eu dbmlsync options for dbmlsync, in the form option-name=value. For example:

    dbmlsync -e "v=on;sc=low"
toggle To set an extended option for a subscription, publication or user

  • Add the option to the CREATE SYNCHRONIZATION SUBSCRIPTION statement or CREATE SYNCHRONIZATION USER statement in the Adaptive Server Anywhere remote database.

    Adding an extended option for a publication is a little different. To add an extended option for a publication, use the ALTER/CREATE SYNCHRONIZATION SUBSCRIPTION statement and omit the FOR clause.

Example

The following statement creates a synchronization subscription that uses extended options to set the cache size for preparing the upload stream to 3 Mb and the upload increment size to 3 kb.

CREATE SYNCHRONIZATION SUBSCRIPTION TO my_pub
FOR ml_user
ADDRESS 'host=test.internal;port=2439;'
OPTION memory='3m',increment='3k'

Note that the option values can be enclosed in single quotes, but the option names must remain unquoted.


Transaction log files

To prepare the upload stream, the dbmlsync utility requires access to all transaction logs written since the last successful synchronization. However, log files are typically truncated and renamed as part of regular database maintenance. In such a case, old log files must be renamed and saved in a separate directory until all changes they describe have been synchronized successfully.

You can specify the directory that contains the renamed log files on the dbmlsync command line. You may omit this parameter if the working log file has not been truncated and renamed since you last synchronized, or if you run dbmlsync from the directory that contains the renamed log files.

For more information, see Backup and Data Recovery.

Example

Suppose that the old log files are stored in the directory c:\oldlogs. You could use the following command to synchronize the remote database.

dbmlsync –c "dbn=remote;uid=syncuser" c:\oldlogs

The path to the old logs directory must be the final argument on the command line.


Concurrency during synchronization

To ensure the integrity of synchronizations, dbmlsync must ensure that no rows in the download stream are modified between the time the upload stream is built and the time the download is applied.

On all platforms except Windows CE, by default, dbmlsync obtains a shared lock on all tables mentioned in any publication being synchronized. On Windows CE, by default, dbmlsync obtains an exclusive lock. Dbmlsync obtains the lock before it begins building the upload stream, and it maintains the lock until the download is applied.

For more information about locks, see Types of locks.

The following options let you customize this locking behavior:

  • -d option
  • LockTables option
-d option

When using the locking mechanism, if other connections to the database exist and if these connections have any locks on the synchronization tables, then synchronization will fail. If you want to ensure that synchronization proceeds immediately even if other locks exist, use the dbmlsync -d option. When this option is specified, any connection with locks that would interfere with synchronization are dropped by the database so that synchronization can proceed. Uncommitted changes on the dropped connections are rolled back.

For more information, see -d option.

LockTables option

An alternative way to protect data integrity is to set the extended option LockTables to OFF, which prevents an article's tables from being locked. This causes dbmlsync to track all rows that are modified after the upload stream has been built. When the download is received, it is not applied if any rows in the download have been modified. Dbmlsync will then retry the synchronization. The retry will succeed unless a new download conflict is detected.

For more information, see LockTables (lt) extended option.

If a conflict is detected, the download phase is cancelled and the download operations rolled back to avoid overwriting the new change. The dbmlsync utility then retries the synchronization, including the upload step. This time, because the row is present at the beginning of the synchronization process, it is included in the upload stream and therefore not lost.

By default, dbmlsync will retry synchronization until success is achieved. You can limit the number of retries using the extended option ConflictRetries. Setting ConflictRetries to -1 causes dbmlsync to retry until success is achieved. Setting it to a non-negative integer causes dbmlsync to retry for not more than the specified number of times.

For more information, see ConflictRetries (cr) extended option.


Initiating synchronization from an application

You may wish to include the features of dbmlsync in your application, rather than provide a separate executable to your remote users.

There are two ways to do this:

  • Use the Dbmlsync Integration Component.

    For more information, see Dbmlsync Integration Component.

  • If you are developing in any language that can call a DLL, and are programming in C or C#, you can include the dbtools.h header file, located in the h subdirectory of your SQL Anywhere directory. This file contains a description of the a_sync_db structure and the DBSynchronizeLog function, which you use to add this functionality to your application. This solution works on all supported platforms, including Windows, UNIX, Linux, and Macintosh.

    For more information, see:

    • DBTools Interface for dbmlsync
    • DBSynchronizeLog function
    • a_sync_db structure


Using ActiveSync synchronization

ActiveSync is synchronization software for Microsoft Windows CE handheld devices. Adaptive Server Anywhere MobiLink clients can use ActiveSync version 3.1 or 3.5.

ActiveSync governs synchronization between a Windows CE device and a desktop computer. A MobiLink provider for ActiveSync governs synchronization to the MobiLink synchronization server, as shown in the following diagram.

ActiveSync architecture, showing components on the Windows CE device, the desktop computer, and the computer where MobiLink synchronization server is running.

Setting up ActiveSync synchronization for Adaptive Server Anywhere clients involves the following steps:

  • Configure the Adaptive Server Anywhere remote database for ActiveSync synchronization.

    See Configuring Adaptive Server Anywhere remote databases for ActiveSync.

  • Install the MobiLink provider for ActiveSync.

    See Installing the MobiLink provider for ActiveSync.

  • Register the Adaptive Server Anywhere client for use with ActiveSync.

    See Registering Adaptive Server Anywhere clients for ActiveSync.

If you use ActiveSync synchronization, synchronization must be initiated from the ActiveSync software. The MobiLink provider for ActiveSync can start dbmlsync or it can wake a dbmlsync that is sleeping as scheduled by a schedule string.

You can also put dbmlsync into a sleep mode using a delay hook in the remote database, but the MobiLink provider for ActiveSync cannot invoke synchronization from this state.

For information about scheduling synchronization, see Scheduling synchronization.

Configuring Adaptive Server Anywhere remote databases for ActiveSync
Installing the MobiLink provider for ActiveSync
Registering Adaptive Server Anywhere clients for ActiveSync


Configuring Adaptive Server Anywhere remote databases for ActiveSync

toggle To configure your Adaptive Server Anywhere remote database for ActiveSync

  1. Select ActiveSync as the synchronization type.

    The synchronization type can be set for a synchronization publication, for a synchronization user or for a synchronization subscription. It is set in a similar manner for each. Here is part of a typical CREATE SYNCHRONIZATION USER statement:

    CREATE SYNCHRONIZATION USER SSinger
TYPE ActiveSync
...

  2. Supply an address clause to specify communication between the MobiLink provider for ActiveSync and the MobiLink synchronization server.

    For HTTP or TCP/IP synchronization the ADDRESS clause of the CREATE SYNCHRONIZATION USER or CREATE SYNCHRONIZATION SUBSCRIPTION statement specifies communication between the MobiLink client and server. For ActiveSync, the communication takes place in two stages: from the dbmlsync utility on the device to the MobiLink provider for ActiveSync on the desktop machine, and from desktop machine to the MobiLink synchronization server. The ADDRESS clause specifies the communication between MobiLink provider for ActiveSync and the MobiLink synchronization server.

    The following statement specifies TCP/IP communication to a MobiLink synchronization server on a machine named kangaroo:

    CREATE SYNCHRONIZATION USER SSinger
TYPE ActiveSync
ADDRESS 'stream=tcpip;host=kangaroo;port=2439'

    For more information, see CREATE SYNCHRONIZATION USER statement [MobiLink].


Installing the MobiLink provider for ActiveSync

Before you register your Adaptive Server Anywhere MobiLink client for use with ActiveSync, you must install the MobiLink provider for ActiveSync using the installation utility (dbasinst.exe).

The Adaptive Server Anywhere for Windows CE setup program installs the MobiLink provider for ActiveSync. If you install Adaptive Server Anywhere for Windows CE you do not need to carry out the steps in this section.

When you have installed the MobiLink provider for ActiveSync you must register each application separately. For instructions, see Registering Adaptive Server Anywhere clients for ActiveSync.

toggle To install the MobiLink provider for ActiveSync

  1. Ensure that you have the ActiveSync software on your machine, and that the Windows CE device is connected.

  2. Enter the following command to install the MobiLink provider:

    dbasinst -k desk-path -v dev-path

    where desk-path is the location of the desktop component of the provider (dbasdesk.dll) and dev-path is the location of the device component (dbasdev.dll).

    If you have SQL Anywhere installed on your computer, dbasdesk.dll is in the win32 or win64 subdirectory of your SQL Anywhere directory and dbasdev.dll is in a platform-specific directory in the CE subdirectory. If you omit -v or -k, these directories are searched by default.

    If you receive a message telling you that the remote provider failed to open, perform a soft reset of the device and repeat the command:

    For more information, see ActiveSync provider installation utility.

  3. Restart your machine.

    ActiveSync does not recognize new providers until the machine is restarted.

  4. Enable the MobiLink provider.

    • From the ActiveSync window, click Options.

    • Check the MobiLink item in the list and click OK to activate the provider.

    • To see a list of registered applications, click Options again, choose the MobiLink provider, and click Settings.

      For more information about registering applications, see Registering Adaptive Server Anywhere clients for ActiveSync.


Registering Adaptive Server Anywhere clients for ActiveSync

You can register your application for use with ActiveSync either by using the ActiveSync provider install utility or using the ActiveSync software itself. This section describes how to use the ActiveSync software.

For information on the alternative approach, see ActiveSync provider installation utility.

toggle To register the Adaptive Server Anywhere client for use with ActiveSync

  1. Ensure that the MobiLink provider for ActiveSync is installed.

    For information, see Installing the MobiLink provider for ActiveSync.

  2. Start the ActiveSync software on your desktop machine.

  3. From the ActiveSync window, choose Options.

  4. From the list of information types, choose MobiLink and click Settings.

  5. In the MobiLink Synchronization dialog, click New. The Properties dialog appears.

  6. Enter the following information for your application:

    • Application name A name identifying the application to be displayed in the ActiveSync user interface.

    • Class name The class name for the dbmlsync client, as set using the -wc option.

      For more information, see -wc option.

    • Path The location of the dbmlsync application on the device.

    • Arguments Any command line arguments to be used when ActiveSync starts dbmlsync.

      You start dbmlsync in one of two modes:

      • If you specify scheduling options, dbmlsync enters hover mode. In this case, use the dbmlsync -wc option with a matching value in the class name setting.

        For more information, see -wc option and Scheduling synchronization.

      • Otherwise, dbmlsync is not in hovering mode. In this case, use -k to shut down dbmlsync.

        For more information, see -k option.

  7. Click OK to register the application.


Temporarily stopping synchronization of deletes

Ordinarily, Adaptive Server Anywhere automatically logs any changes to tables or columns that are part of a publication with a synchronization subscription. These changes are uploaded to the consolidated database during the next synchronization.

You may, however, wish to delete rows from synchronized data and not have those changes uploaded. This feature can be used to make unusual corrections, but should be used with caution as it effectively disables part of the automatic synchronization functionality. This technique is a practical alternative to deleting the necessary rows using a download_delete_cursor script

When a STOP SYNCHRONIZATION DELETE statement is executed, none of the delete operations subsequently executed on that connection are synchronized. The effect continues until a START SYNCHRONIZATION DELETE statement is executed. The effects do not nest; that is, subsequent executions of stop synchronization delete after the first will have no additional effect.

toggle To temporarily disable upload of deletes made through a connection

  1. Issue the following statement to stop automatic logging of deletes.

    STOP SYNCHRONIZATION DELETE

  2. Delete rows from the synchronized data, as required, using the DELETE statement. Commit these changes.

  3. Restart logging of deletes using the following statement.

    START SYNCHRONIZATION DELETE

The deleted rows will not be sent up to the MobiLink synchronization server and hence will not be deleted from the consolidated database.


Scheduling synchronization

Instead of running dbmlsync in a batch fashion, where it synchronizes and then shuts down, you can set up an Adaptive Server Anywhere client so that dbmlsync runs continuously, synchronizing at predetermined times.

You specify the synchronization schedule as an extended option. It can be specified either on the dbmlsync command line or it can be stored in the database for the synchronization user, subscription, or publication.

For information about extended options, see dbmlsync extended options or -eu option. For more information about how to set scheduling, see Schedule (sch) extended option.

toggle To add scheduling to the synchronization subscription

  • Set the Schedule extended option in the synchronization subscription. For example,

    CREATE SYNCHRONIZATION SUBSCRIPTION TO mypub
FOR mluser
ADDRESS 'host=localhost'
OPTION schedule='weekday@11:30am-12:30pm'

    For more information about scheduling syntax, see Schedule (sch) extended option.

    You can override scheduling instructions and synchronize immediately using the dbmlsync -is option. The -is option instructs dbmlsync to ignore all scheduling information. For more information, see -is option.

toggle To add scheduling from the dbmlsync command line

  • Set the schedule extended option. Extended options are set with -e or -eu. For example,

    dbmlsync -e sch=weekday@11:30am-12:30pm ...

If scheduled synchronization is specified in either place, dbmlsync does not shut down after synchronizing, but runs continuously.

Hovering

When scheduling options are specified, dbmlsync goes into hovering mode. Hovering is a feature that reduces the amount of time spent scanning the log. You can improve the performance benefits of hovering by setting the dbmlsync extended option HoverRescanThreshold or by using the dbmlsync stored procedure sp_hook_dbmlsync_log_rescan.

For more information, see HoverRescanThreshold (hrt) extended option and sp_hook_dbmlsync_log_rescan.


Adaptive Server Anywhere version 7 MobiLink clients

Adaptive Server Anywhere 7.0 MobiLink clients were configured using SQL statements that are now deprecated. In particular, synchronization definitions were used instead of publications and subscriptions. The older statements are no longer supported. They have some disadvantages:

  1. A synchronization definition is equivalent to a single publication and a single subscription to it. There is no support for subscriptions to multiple publications. In contrast, a single MobiLink user can now subscribe to multiple publications. This allows you to synchronize some portions of your data without synchronizing all of it.

  2. Some people found the old terminology confusing. For example, a MobiLink user name was formerly called a site in the context of an Adaptive Server Anywhere client. A MobiLink user is now called a MobiLink user or a synchronization user.

  3. The new statements are analogous to those used in SQL Remote, the Sybase message-based replication technology.

Synchronization definitions identify data to upload in version 7 remote databases

You can choose to synchronize all or any portion of the data in a client Adaptive Server Anywhere database. You can choose to synchronize entire tables, or you can choose to synchronize only particular columns and rows.

The synchronization definition, located in the client Adaptive Server Anywhere database, describes the data that is to be replicated and the location of the appropriate MobiLink synchronization server.

Synchronization scripts, stored in the consolidated database, control how the uploaded rows are processed and which rows are downloaded to the remote database. These scripts do not depend on the type of remote database.

A synchronization definition may include data from several database tables. Each table's contribution to a synchronization definition is called an article . Each article may consist of a whole table, or a subset of the rows and columns in a table.

The figure shows a two-table synchronization definition, featuring one article using all rows and columns from Table A, and another article with some rows and columns from Table B.
Synchronizing a remote database

Once a remote database is set up, the two databases must be periodically brought to a state where they both have the same set of information. This process of synchronization is carried out using the dbmlsync command line utility.

Altering a synchronized table

A table, once added to a synchronization definition, should not be altered. Altering the table interferes with the synchronization process. Should it be necessary to make such an alteration, this step should be performed immediately following synchronization.

The only way to ensure that the ALTER STATEMENT is executed immediately following synchronization is to place this statement in a script, then execute that script using the -I option of the dbmlsync command line utility.

Comparison to UltraLite clients

If you have developed UltraLite applications for use as MobiLink clients, the following information may be helpful. Many of the elements of a synchronization definition have an UltraLite counterpart.

Adaptive Server Anywhere 9.0 client | Adaptive Server Anywhere 7.0 client | UltraLite clients | MobiLink synchronization server
MobiLink synchronization user | site | user name | MobiLink user
type | type | stream | connection type
address | address | connection parameters | the server's address
script version | script version | version | script version
publication | part of a definition in a remote database, or part of a template in a reference database | none —all tables are synchronized | publication
subscription | part of a definition in a remote database, or a part of a site in a reference database | none | none
Writing synchronization definitions

The synchronization definition is a version 7.0 database object describing data in an Adaptive Server Anywhere remote database that is to be synchronized with a particular MobiLink synchronization server. When using Adaptive Server Anywhere 9.0 or later, publications and synchronization subscriptions should be used instead.

For details, see Creating a remote database.

A synchronization definition should appear only in an Adaptive Server Anywhere 7.0 remote database. MobiLink consolidated servers are configured using scripts.

A synchronization definition specifies the following pieces of information

  • name The name of the synchronization definition, known only within the remote database.

  • site A name that uniquely identifies this particular MobiLink client.

  • type The type of stream to be used to communicate with the MobiLink synchronization server.

  • address The parameters necessary to connect to the MobiLink synchronization server.

  • script version The version of the synchronization scripts the MobiLink synchronization server is to use when synchronizing this client.

  • articles A description of the data to be synchronized. You can synchronize entire tables, or only particular rows and columns.

The following statement creates a synchronization definition named testpub that defines what data is to be synchronized with site demo_sync_site.

CREATE SYNCHRONIZATION DEFINITION testpub
   SITE 'demo_sync_site'
   TYPE 'tcpip'
   ADDRESS 'host=localhost;port=2439;'
   OPTION sv='version1'
   (table People( person_id, fname, lname ),table Pets);

In this statement,

  • The name of this synchronization definition is testpub. This name is only known within the remote database.

  • The name demo_sync_site uniquely identifies this client to the MobiLink synchronization server. This name should appear in the ml_user MobiLink system table, located in the consolidated database.

  • The synchronization is to occur over a TCP/IP connection. The connection parameters appear in a string in the ADDRESS clause.

    The TCP/IP connection parameters show that the MobiLink synchronization server is listening on port 2439 of the current machine. Only the listed columns of the People table are synchronized. The option clause is included to indicate that the MobiLink synchronization server should use version1 of the synchronization scripts when processing data from this client. The default value of this parameter is default . Notice that the list of columns is also enclosed in parentheses.

  • The MobiLink synchronization server is to use the set of synchronization scripts identified by the name version1 when synchronizing this client. This script version name should appear in the ml_script_version MobiLink system table, located in the consolidated database.

  • All columns and rows of the Pets table and the listed columns of the People table are to be synchronized.

Synchronizing with multiple servers

To synchronize a remote database with multiple MobiLink synchronization servers, create multiple synchronization definitions within the remote database. Each synchronization definition must have a unique site name because, from the point of view of the MobiLink synchronization server, each is a separate logical client.

Synchronizing the same data in one remote database with multiple MobiLink synchronization servers is not presently supported.

Rewriting synchronization definitions for version 8 and up

To use an Adaptive Server Anywhere 7 database as a MobiLink client, you use a synchronization definition to identify which data to upload. In version 8.0 and later, these are better rewritten as publications and synchronization subscriptions.

Example

Suppose you wanted to synchronize the Customer and Sales_Order tables of the sample database. You could have created the following synchronization definition.

CREATE SYNCHRONIZATION DEFINITION testpub
   SITE 'demo_ml_user'
   TYPE 'tcpip'
   ADDRESS 'host=localhost;port=2439;'
   OPTION sv='version1'
   (TABLE Customer, TABLE Sales_Order);

Instead, you should now do the following.

  1. First, publish the Customer and Sales_Order tables.

    CREATE PUBLICATION testpub
   (TABLE Customer, TABLE Sales_Order);

  2. Next, create a subscription to this publication for the MobiLink user. In this case, the MobiLink user is demo_ml_user. It is unnecessary that a database user of the same name to exist. MobiLink users and database users are independent.

    CREATE SYNCHRONIZATION SUBSCRIPTION TO testpub
   FOR demo_ml_user
   TYPE 'tcpip'
   ADDRESS 'host=localhost;port=2439;'
   OPTION sv='version1'

The information is the same, but is broken into two smaller statements instead of one large one.

The SITE clause in the synchronization definition specifies that this particular MobiLink client will synchronizing using the MobiLink user name demo_sync_site. Synchronization is to occur over a TCP/IP connection. The synchronization server is to use the version1 version of the synchronization scripts when interacting with this client.

In the second case, the synchronized tables are published, and then a subscription is created for the demo_sync_site MobiLink user. The TYPE, ADDRESS, and OPTION clauses have the same syntax.


Adaptive Server Anywhere Client Synchronization Parameters

About this chapter

This chapter details all the options you can set for the MobiLink synchronization client, dbmlsync. You can use dbmlsync to synchronize Adaptive Server Anywhere remote databases with a consolidated database.

The dbmlsync utility only works with Adaptive Server Anywhere remote databases. To synchronize UltraLite remote databases, see UltraLite Synchronization Parameters.


MobiLink synchronization client

Use the dbmlsync utility to synchronize Adaptive Server Anywhere remote databases with a consolidated database.

Syntax

dbmlsync [ options ] [ transaction-logs-directory ]

Option | Description
@data | Read in options from the specified environment variable or configuration file. See @data option.
-a | Do not prompt for input again on error. See -a option
-ap | Specify authentication parameters. See -ap option.
-ba filename | Apply a download file. See -ba option.
-bc filename | Create a download file. See -bc option.
-be string | When creating a download file, add a string. See -be option.
-bg | When creating a download file, make it suitable for new remotes. See -bg option.
-c connection-string | Supply database connection parameters in the form parm1=value1; parm2=value2,... If you do not supply this option, a dialog will appear and you must supply connection information. See -c option.
-d | Drop any other connections to the database whose locks conflict with the articles to be synchronized. See -d option.
-dc | Enable restartable downloads. See -dc option.
-dl | Display log messages on the console. See -dl option.
-ds | Specify download-only synchronization. See -ds option.
-e "option=value"... | Specify extended options. See dbmlsync extended options.
-eh | Ignore errors that occur in hook functions.
-ek key | Specify encryption key. See -ek option.
-ep | Prompt for encryption key. See -ep option.
-eu | Specify extended options for upload defined by most recent -n option. See -eu option.
-is | Ignore schedule. See -is option.
-k | Close window on completion. See -k option.
-l | List available extended options. See -l option.
-mn password | Specify new MobiLink password. See -mn option.
-mp password | Specify MobiLink password. See -mp option.
-n name | Specify synchronization publication name(s). See -n option.
-o logfile | Log output messages to this file. See -o option.
-os size | Specifies a maximum size for the output log, at which point the log is renamed. See -os option.
-ot logfile | Truncate file and log output messages to file. See -ot option.
-p | Disable logscan polling. See -p option.
-pd dllname;... | Preload specified dlls for Windows CE. See -pd option.
-pi | Test that you can connect to MobiLink. See -pi option.
-pp number | Set logscan polling period. See -pp option.
-q | Run in minimized window. See -q option.
-r[ a | b ] | Upload retry on client progress. See -r option.
-sc | Reload schema information before each synchronization. See -sc option.
-tu | Remote transactions are preserved on upload. See -tu option.
-u ml_username | Allows you to specify the MobiLink user to synchronize. See -u option.
-uo | Synchronization will be upload-only (no download). See -uo option.
-urc row-estimate | Allows you to specify an estimate of the rows that will be uploaded. See -urc option.
-v[ levels ] | Verbose operation. See -v option.
-wc classname | Specify a window class name. See -wc option.
-x | Rename and restart the transaction log. See -x option.
transaction-logs-directory | Specify the location of the transaction log. See Transaction Log File, below.
Description

Run dbmlsync on the command line to synchronize an Adaptive Server Anywhere remote database with a consolidated database.

To locate and connect to the MobiLink synchronization server, dbmlsync uses the information on the publication, synchronization user, synchronization subscription, or command line.

Transaction log file The transaction-logs-directory is the directory that contains the transaction log for the Adaptive Server Anywhere remote database. There is an active transaction log and transaction log archive files, both of which may be required by dbmlsync to determine what to upload. You must specify this parameter if the following are true:

  • the working log file has been truncated and renamed since you last synchronized

  • you run the dbmlsync utility from a directory other than the one where the renamed log files are stored

For more information, see Transaction log files.

dbmlsync event hooks There are also dbmlsync client stored procedures that can help you customize the synchronization process. For more information, see Customizing the client synchronization process and Dbmlsync Client Event Hooks.

Using dbmlsync For more information about using dbmlsync, see Initiating synchronization.


dbmlsync options

This section lists MobiLink synchronization client command line options.

@data option
-a option
-ap option
-ba option
-bc option
-be option
-bg option
-c option
-d option
-dc option
-dl option
-ds option
dbmlsync extended options
-eh option
-ek option
-ep option
-eu option
-is option
-k option
-l option
-mn option
-mp option
-n option
-o option
-os option
-ot option
-p option
-pd option
-pi option
-pp option
-q option
-r option
-sc option
-tu option
-u option
-uo option
-urc option
-v option
-wc option
-x option


@data option

Function

Reads in options from the specified environment variable or configuration file.

Syntax

dbmlsync @data ...

Description

With this option, you can put command line options in an environment variable or configuration file. If both exist with the name you specify, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

See Hiding the contents of files using the dbfhide command-line utility.


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Clients

Adaptive Server Anywhere Client Synchronization Parameters

dbmlsync options

-a option

Function

Specifies that dbmlsync should not prompt for input again on error.

Syntax

dbmlsync -a ...


-ap option

Function

Specifies parameters for authentication.

Syntax

dbmlsync -ap "parameters,..." ...

Description

Use when you use the authenticate_parameters connection script. For example,

dbmlsync -ap "parm1,parm2,parm3"

For more information, see authenticate_parameters connection event.


-ba option

Function

Applies a download file.

Syntax

dbmlsync -ba "filename" ...

Description

Specify the name of an existing download file. You can optionally specify a path. If you do not specify a path, the default location is dbmlsync's current working directory (the directory where dbmlsync was started).

For more information, see File-Based Downloads.


-bc option

Function

Creates a download file.

Syntax

dbmlsync -bc "filename" ...

Description

Create a download file with the specified name. You should use the file extension .df for download files.

You can optionally specify a path. If you do not specify a path, the default location is dbmlsync's current working directory, which is the directory where dbmlsync was started.

Optionally, in the same dbmlsync command line as you create the download file, you can use the -be option to specify a string that can be validated at the remote database, and the -bg option to create a download file for new remote databases.

See also

File-Based Downloads

-be option

-bg option


-be option

Function

When creating a download file, this option specifies an extra string to be included in the file.

Syntax

dbmlsync -bc "filename" -be "string" ...

Description

The string can be used for authentication or other purposes. It is verified at the remote database using the sp_hook_dbmlsync_validate_download_file stored procedure.

See also

sp_hook_dbmlsync_validate_download_file

File-Based Downloads

-bc option


-bg option

Function

When creating a download file, this option creates a file that can be used with remote databases that have not yet synchronized.

Syntax

dbmlsync -bc "filename" -bg ...

Description

The -bg option causes the download file to update the generation numbers on the remote database.

This option allows you to build a download file that can be applied to remote databases that have never synchronized. Otherwise, you must perform a synchronization before you apply a download file.

Download files built with the -bg option should be snapshot downloads. Timestamp-based downloads will not work with remote databases that have not synchronized because the last download timestamp on a new remote is by default January 1, 1900, which will be earlier than the last download timestamp in the download file. For timestamp-based file-based downloads to work, the last download timestamp in the download file must be the same or earlier than on the remote.

You should not apply download files built with the -bg option to remote databases that have already synchronized. The -bg option causes the generation numbers on the remote database to be updated with the value on the consolidated database at the time the download file was created. For remotes that have already synchronized, this means that the remote database is not forced to upload data before applying a download, and so data could be lost.

See also

-bc option

File-Based Downloads

MobiLink generation numbers

Synchronizing new remotes


-c option

Function

Specifies connection parameters for the remote database.

Syntax

dbmlsync -c "connection-string" ...

Description

The connection string must give dbmlsync permission to connect to the Adaptive Server Anywhere remote database. Commonly, a user ID with REMOTE DBA authority is used.

Specify the connection string in the form keyword=value, with multiple parameters separated by semicolons. If any of the parameter names contain spaces, you need to enclose the connection string in double quotes.

If you do not specify -c, a dbmlsync Setup dialog appears. You can specify the remaining command line options in the fields of the connection dialog.

For a complete list of connection parameters for connecting to Adaptive Server Anywhere databases, see Connection parameters.


-d option

Function

Drops conflicting locks to the remote database.

Syntax

dbmlsync -d ...

Description

During synchronization, unless the LockTables extended option is set to OFF, all tables involved in the publications being synchronized are locked to prevent any other processes from making changes. If another connection has a lock on one of these tables, the synchronization fails. Specifying this option forces Adaptive Server Anywhere to drop any other connections to the remote database that hold conflicting locks.

See also

Concurrency during synchronization


-dc option

Function

Specifies restartable downloads.

Syntax

dbmlsync -dc ...

Description

By default, if MobiLink fails during a download it doesn't apply any of the download data to the remote database. However, it stores the part of the download it did receive in a temporary file on the remote device, so that if you specify -dc the next time you start dbmlsync, it can more quickly complete the download. When you specify -dc, dbmlsync restarts the download and attempts to download the part of the previous download that it did not receive. If it is able to download the remaining data, it applies the complete download to your remote database.

If there is any new data to be uploaded when you use -dc, the restartable download will fail.

You can also specify restartable downloads for Adaptive Server Anywhere remote databases with the ContinueDownload extended option or with the sp_hook_dbmlsync_end hook.

See also

Resuming failed downloads

ContinueDownload (cd) extended option

sp_hook_dbmlsync_end

DownloadReadSize (drs) extended option


-dl option

Function

Displays messages in the log file.

Syntax

dbmlsync -dl ...

Description

Normally when output is logged to a file, more messages are written to the log file than to the dbmlsync window. This option forces dbmlsync to write information normally only written to the file to the window as well. Using this option may have an effect on the speed of synchronization.


-ds option

Function

Specifies download-only synchronization.

Syntax

dbmlsync -ds ...

Description

When download-only synchronization occurs, dbmlsync does not upload any row operations or data. However, it does upload information about the schema and progress offset.

In addition, dbmlsync ensures that changes on the remote are not overwritten during download-only synchronization. It does this by scanning the log to detect rows with operations waiting to be uploaded. If any of these rows is modified by the download stream, the download stream is rolled back and the synchronization fails. If the synchronization fails for this reason, you must do a full synchronization to correct the problem.

When you have remotes that are synchronized by download-only synchronization, you should regularly do a full synchronization to reduce the amount of log that is scanned by the download-only synchronization. Otherwise, the download-only synchronizations will take an increasingly long time to complete.

When -ds is used, the ConflictRetries setting is ignored. dbmlsync never retries a download-only synchronization. If a download-only synchronization fails, it will continue to fail until a normal synchronization is performed.

See also

Upload-only and download-only synchronization

DownloadOnly (ds) extended option

UploadOnly (uo) extended option or -uo option


dbmlsync extended options

Function

Specifies extended options.

Syntax

dbmlsync -e extended-option=value; ...

extended-option:
adr cd cr ctp dbs dir drs ds eh el ft hrt inc isc lt mem mn mp p pp sa sc sch scn st sv tor uo v vn vm vo vr vs vu

Parameters

Extended options can be specified by their long form or short form. See each option, below, for details.

Description

Options specified on the command line with the -e option apply to all synchronizations requested on the command line. For example, in the following command line, the extended option sv=test applies to the synchronization of both pub1 and pub2.

dbmlsync -e "sv=test" -n pub1 -n pub2

To specify extended options for a single upload, use the -eu option.

Extended options can be specified on the dbmlsync command line using the -e or -eu options, or they can be stored in the database. You store extended options in the database using Sybase Central, by using the sp_hook_dbmlsync_set_extended_options event hook, or by using the OPTIONS clause in any of the following statements:

  • CREATE SYNCHRONIZATION SUBSCRIPTION

  • ALTER SYNCHRONIZATION SUBSCRIPTION

  • CREATE SYNCHRONIZATION USER

  • ALTER SYNCHRONIZATION USER

  • CREATE SYNCHRONIZATION SUBSCRIPTION without specifying a synchronization user (which associates extended options with a publication)

Dbmlsync combines options stored in the database with those specified on the command line. If conflicting options are specified, dbmlsync resolves them as follows. In the following list, options specified by methods occurring earlier in the list take precedence over those occurring later in the list.

  • options specified in the sp_hook_dbmlsync_set_extended_options event hook

  • options specified on the command line with the -eu option

  • options specified on the command line with the -e option

  • options specified for the subscription (whether by a SQL statement or in Sybase Central)

  • options specified for the user (whether by a SQL statement or in Sybase Central)

  • options specified for the publication (whether by a SQL statement or in Sybase Central)

You can review extended options in the log and the SYSSYNC system table.

For information on how extended options can be used to tune synchronization, see Customizing synchronization.

For a detailed explanation of each option, see below.

See also

-eu option

SYSSYNC system table

sp_hook_dbmlsync_set_extended_options

Example

The following dbmlsync command line illustrates how you can set extended options when you start dbmlsync:

dbmlsync -e "adr=host=localhost;dir=c:\db\logs"...

The following SQL statement illustrates how you can store extended options in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION TO mypub
   FOR mluser
   ADDRESS 'host=localhost'
   OPTION schedule='weekday@11:30am-12:30pm', dir='c:\db\logs'

The following dbmlsync command line opens the usage screen that lists options and their syntax:

dbmlsync -l

CommunicationAddress (adr) extended option
CommunicationType (ctp) extended option
ConflictRetries (cr) extended option
ContinueDownload (cd) extended option
DisablePolling (p) extended option
DownloadBufferSize (dbs) extended option
DownloadOnly (ds) extended option
DownloadReadSize (drs) extended option
ErrorLogSendLimit (el) extended option
FireTriggers (ft) extended option
HoverRescanThreshold (hrt) extended option
IgnoreHookErrors (eh) extended option
IgnoreScheduling (isc) extended option
Increment (inc) extended option
LockTables (lt) extended option
Memory (mem) extended option
MirrorLogDirectory (mld) extended option
MobiLinkPwd (mp) extended option
NewMobiLinkPwd (mn) extended option
OfflineDirectory (dir) extended option
PollingPeriod (pp) extended option
Schedule (sch) extended option
ScriptVersion (sv) extended option
SendColumnNames (scn) extended option
SendDownloadACK (sa) extended option
SendTriggers (st) extended option
TableOrder (tor) extended option
UploadOnly (uo) extended option
Verbose (v) extended option
VerboseHooks (vs) extended option
VerboseMin (vm) extended option
VerboseOptions (vo) extended option
VerboseRowCounts (vn) extended option
VerboseRowValues (vr) extended option
VerboseUpload (vu) extended option


CommunicationAddress (adr) extended option
Function

Specifies network protocol options for connecting to the MobiLink server.

Syntax

dbmlsync -e adr=protocol-option; ...

Parameters

  • TCP/IP protocol options If you specify the tcpip protocol, you can optionally specify the following protocol options:

    TCP/IP protocol option | For more information, see...
    client_port=nnnnn[-mmmmm] | client_port
    host=hostname | host
    liveness_timeout=n | liveness_timeout
    network_connect_timeout=seconds | network_connect_timeout
    network_leave_open={0|1} | network_leave_open
    network_name=name | network_name
    port=portnumber | port
    security=cipher(keyword=value;...) | security

  • HTTP protocol If you specify the http protocol, you can optionally specify the following protocol options:

    HTTP protocol option | For more information, see...
    buffer_size=number | buffer_size
    client_port=nnnnn[-mmmmm] | client_port
    custom_header=header | custom_header
    host=hostname | host
    network_connect_timeout=seconds | network_connect_timeout
    network_leave_open={0|1} | network_leave_open
    network_name=name | network_name
    persistent={0|1} | persistent
    port=portnumber | port
    proxy_host=proxy_hostname | proxy_host
    proxy_port=proxy_portnumber | proxy_port
    set_cookie=cookie_name =cookie_value | set_cookie
    url_suffix=suffix | url_suffix
    version=versionnumber | version

  • HTTPS or HTTPS_FIPS protocols The HTTPS protocol uses Certicom RSA security. The HTTPS_FIPS protocol uses separate FIPS 140-2 certified RSA encryption software from Certicom.

    Separately licensable option required
    Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

    To order this component, see Separately-licensable components.

    If you specify the HTTPS protocol, you can optionally specify the following protocol options:

    HTTPS/HTTPS_FIPS protocol option | For more information, see...
    buffer_size=number | buffer_size
    certificate_company=company_name | certificate_company
    certificate_name=name | certificate_name
    certificate_unit=company_unit | certificate_unit
    client_port=nnnnn[-mmmmm] | client_port
    custom_header=header | custom_header
    host=hostname | host
    network_connect_timeout=seconds | network_connect_timeout
    network_leave_open={0|1} | network_leave_open
    network_name=name | network_name
    persistent={0|1} | persistent
    port=portnumber | port
    proxy_host=proxy_hostname | proxy_host
    proxy_port=proxy_portnumber | proxy_port
    set_cookie=cookie_name =cookie_value | set_cookie
    trusted_certificates=filename | trusted_certificates
    url_suffix=suffix | url_suffix
    version=versionnumber | version

  • ActiveSync protocol During ActiveSync synchronization, ActiveSync is used to exchange data with the MobiLink provider for ActiveSync, which resides on the desktop machine. The ActiveSync protocol options describe the communications between the MobiLink provider for ActiveSync and the MobiLink synchronization server.

    The address string for ActiveSync takes the following form:

    stream=desktop-protocol;[desktop-protocol-options]

    where:

    • desktop-protocol is the network protocol to use between the MobiLink provider for ActiveSync and the MobiLink synchronization server. It can be http, https, https_fips or tcpip. The default is tcpip.

    • desktop-protocol-options are TCP/IP, HTTP, HTTPS, or HTTPS_FIPS options, as described in the lists above.

      Separately licensable option required
      Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

      To order this component, see Separately-licensable components.

      For more information, see ActiveSync provider installation utility.

Description

You must ensure that all subscriptions for a MobiLink user are synchronized to only one consolidated database. Otherwise, you may experience data loss and unpredictable behavior.

If you are using the Redirector, see Configuring MobiLink clients and servers for the Redirector.

This option has a short form and long form: you can use adr or CommunicationAddress.

This option can also be stored in the database using the SQL statement that creates or alters a publication, subscription, or user. For more information, see:

  • CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • CREATE SYNCHRONIZATION USER statement [MobiLink]

To specify the TCP/IP, HTTP, HTTPS, or HTTPS_FIPS protocol, use the CommunicationType extended option.

For more information, see CommunicationType (ctp) extended option.

See also

Configuring MobiLink clients and servers for the Redirector

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "adr=host=localhost"

To specify multiple network protocol options on the command line, enclose them in single quotes. For example,

dbmlsync -e "adr='host=somehost;port=5001'"

To store the Address or CommunicationType in the database, you can use an extended option or you can use the ADDRESS or TYPE clause. For example,

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   TYPE 'https'
   ADDRESS host='localhost;port=2439'


CommunicationType (ctp) extended option
Function

Specifies the type of network protocol to use for connecting to the MobiLink server.

Syntax

dbmlsync -e ctp=sync-type; ...

Description

sync-type can be one of tcpip, http, https, https_fips or ActiveSync. The default is tcpip.

You must ensure that all subscriptions for a MobiLink user are synchronized to only one consolidated database. Otherwise, you may experience data loss and unpredictable behavior.

This option has a short form and long form: you can use ctp or CommunicationType.

This option can also be stored in the database using the SQL statement that creates or alters a publication, subscription, or user. For more information, see:

  • CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • CREATE SYNCHRONIZATION USER statement [MobiLink]
See also
  • MobiLink Transport-Layer Security
  • CommunicationAddress (adr) extended option
Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "ctp=https"

To store the Address or CommunicationType in the database, you can use an extended option or you can use the ADDRESS or TYPE clause. For example,

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   TYPE 'tcpip'
   ADDRESS host='localhost'


ConflictRetries (cr) extended option
Function

Specifies the number of retries if the download fails because of conflicts.

Syntax

dbmlsync -e cr=number; ...

Description

-1 specifies that retries should continue indefinitely. The default is -1.

This option is useful only if the LockTables option is OFF, which is not the default.

This option has a short form and long form: you can use cr or ConflictRetries.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

Handling conflicts

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "cr=5"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION cr='5';


ContinueDownload (cd) extended option
Function

Specifies restartable downloads.

Syntax

dbmlsync -e cd={ ON | OFF }; ...

Description

By default, if MobiLink fails during a download it doesn't apply any of the download data to the remote database. However, it stores the part of the download it did receive in a temporary file on the remote device, so that if you specify -e cd the next time you start dbmlsync, it can more quickly complete the download. When you specify -e cd, dbmlsync restarts the download and attempts to download the part of the previous download that it did not receive. If it is able to download the remaining data, it applies the complete download to your remote database.

If there is any new data to be uploaded when you use -dc, the restartable download will fail.

You can also specify restartable downloads for Adaptive Server Anywhere remote databases with the -dc option or with the sp_hook_dbmlsync_end hook.

This option has a short form and long form: you can use cd or ContinueDownload.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

Resuming failed downloads

sp_hook_dbmlsync_set_extended_options

-dc option

sp_hook_dbmlsync_end

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "cd=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION cd='on';


DisablePolling (p) extended option
Function

Disables automatic logscan polling.

Syntax

dbmlsync -e p= { ON | OFF }; ...

Description

In order to build an upload stream, dbmlsync must scan the transaction log. Usually it does this just before synchronization. However, when synchronizations are scheduled, dbmlsync by default scans the log in the time between scheduled synchronizations; and when the sp_hook_dbmlsync_delay hook is used, dbmlsync by default scans the log in the pause that occurs just before synchronization. This behavior is more efficient because the log is already at least partially scanned when synchronization begins. This default behavior is called logscan polling.

Logscan polling is on by default but only has an effect when synchronizations are scheduled or when sp_hook_dbmlsync_delay hook is used. When in effect, polling occurs at set intervals: dbmlsync scans to the end of the log, waits for the polling period, and then scans any new transactions in the log. By default, the polling period is 1 minute, but it can be changed with the dbmlsync -pp option or the PollingPeriod extended option.

The default is to not disable logscan polling (OFF).

This option is identical to dbmlsync -p.

This option has a short form and long form: you can use p orDisablePolling.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

PollingPeriod (pp) extended option

-p option

-pp option

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "p=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION p='on';


DownloadBufferSize (dbs) extended option
Function

Specifies the size of the download buffer.

Syntax

dbmlsync -e dbs= number[ K | M ]; ...

Description

The buffer size is specified in units of bytes. Use the suffix k or m to specify units of kilobytes or megabytes, respectively.

If you set this option to 0, dbmlsync does not buffer the download stream. If the setting is greater than 0 but less than 4k, dbmlsync uses a 4k buffer size and issues a warning. The default is 32K on Windows CE, and 1M on all other operating systems.

Download buffering increases the benefit of eliminating the download acknowledgement because it allows the worker thread to send the download faster.

This option has a short form and long form: you can use dbs or DownloadBufferSize.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "dbs=32k"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION dbs='32k';


DownloadOnly (ds) extended option
Function

Specifies that synchronization should be download-only.

Syntax

dbmlsync -e ds={ ON | OFF }; ...

Description

When download-only synchronization occurs, dbmlsync does not upload any row operations or data. However, it does upload information about the schema and progress offset.

In addition, dbmlsync ensures that changes on the remote are not overwritten during download-only synchronization. It does this by scanning the log to detect rows with operations waiting to be uploaded. If any of these rows is modified by the download stream, the download stream is rolled back and the synchronization fails. If the synchronization fails for this reason, you must do a full synchronization to correct the problem.

When you have remotes that are synchronized by download-only synchronization, you should regularly do a full synchronization to reduce the amount of log that is scanned by the download-only synchronization. Otherwise, the download-only synchronizations will take an increasingly long time to complete.

The default is OFF (full synchronization of both upload and download).

This option has a short form and long form: you can use ds or DownloadOnly.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

-ds option

Upload-only and download-only synchronization

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "ds=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION ds='ON';


DownloadReadSize (drs) extended option
Function

For restartable downloads, specifies the maximum amount of data that may need to be resent after a communications failure.

Syntax

dbmlsync -e drs= number[ K | M ]; ...

Description

The DownloadReadSize option is only useful when doing restartable downloads.

The download read size is specified in units of bytes. Use the suffix k or m to specify units of kilobytes or megabytes, respectively.

Dbmlsync reads the download stream in chunks. The DownloadReadSize defines the size of these chunks. When a communication error occurs, dbmlsync loses the entire chunk that was being processed. Depending on when the error occurs, the number of bytes lost will be between 0 and the DownloadReadSize -1. So for example, if the DownloadReadSize is 100 bytes and an error occurs after reading 497 bytes, the last 97 bytes read will be lost. Bytes that are lost in this way will be resent when the download is restarted.

In general, larger DownloadReadSize values result in better performance on successful synchronizations but result in more data being resent when an error occurs.

The typical use of this option is to reduce the default size when communication is unreliable.

The default is 32k.

This option has a short form and long form: you can use drs or DownloadReadSize.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also
  • Resuming failed downloads
  • ContinueDownload (cd) extended option
  • sp_hook_dbmlsync_end
  • -dc option
Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "drs=100"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION drs='100';


ErrorLogSendLimit (el) extended option
Function

Specifies how much of the remote log file dbmlsync should send to the server when synchronization error occurs.

Syntax

dbmlsync -e el=number[ K | M ]; ...

Description

This option is specified in units of bytes. Use the suffix k or m to specify units of kilobytes or megabytes, respectively.

This option specifies the number of bytes of the output log that dbmlsync sends to the MobiLink synchronization server when errors occur during synchronization. Set this option to 0 if you don't want any dbmlsync output log to be sent.

If ErrorLogSendLimit is set to be large enough, dbmlsync sends the entire output log messages from the current session to the MobiLink synchronization server. For example, if the output log messages were appended to an old output log file, dbmlsync only sends the new messages generated in the current session. If the total length of new messages is greater than ErrorLogSendLimit, dbmlsync only logs the last part of the newly generated error and log messages up to the specified size.

Note: The size of the output log is influenced by your verbosity settings. You can adjust these using the dbmlsync -v option, or by using dbmlsync extended options starting with "verbose". For more information, see -v option and -e verbose options, below.

The default is 32K.

This option has a short form and long form: you can use el or ErrorLogSendLimit.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "el=32k"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION el='32k';


FireTriggers (ft) extended option
Function

Specifies that triggers should be fired on the remote database when the download is applied.

Syntax

dbmlsync -e ft= { ON | OFF }; ...

Description

The default is ON.

This option has a short form and long form: you can use ft or FireTriggers.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "ft=off"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION ft='off';


HoverRescanThreshold (hrt) extended option
Function

When you are using scheduling, this limits the amount of discarded memory that is allowed to accumulate before a rescan is performed.

Syntax

dbmlsync -e hrt= number[ K | M ]; ...

Description

Specifies memory in units of bytes. Use the suffix k or m to specify units of kilobytes or megabytes, respectively. The default is 1M.

When scheduling options are specified or when more than one dbmlsync -n option is specified, dbmlsync goes into hovering mode. Hovering is a feature that reduces the amount of time spent scanning the log when dbmlsync is started and asked to perform more than one synchronization before shutting down. Hovering can occur only when all the subscriptions to be synchronized involve the same MobiLink user.

While hovering, dbmlsync keeps track of operations read from the log using a system than maintains information first in memory, and then spills it on to disk. As hovering continues, dbmlsync discards memory that has become fragmented. The amount of memory discarded is proportional to the number of operations processed while hovering and the size of the rows involved (not counting BLOBs). Memory is not discarded if the remote database has only one publication for the user being synchronized.

Discarded memory can be recovered after a complete rescan is performed. There are two ways that you can control when memory is recovered: the HoverRescanThreshold extended option and the sp_hook_dbmlsync_log_rescan stored procedure.

This option has a short form and long form: you can use hrt or HoverRescanThreshold.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

sp_hook_dbmlsync_log_rescan

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "hrt=2m"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION hrt='2m';


IgnoreHookErrors (eh) extended option
Function

Specifies that errors that occur in hook functions should be ignored.

Syntax

dbmlsync -e eh= { ON | OFF }; ...

Description

The default is OFF.

This option has a short form and long form: you can use eh or IgnoreHookErrors.

This option is equivalent to the dbmlsync -eh option.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "eh=off"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION eh='off';


IgnoreScheduling (isc) extended option
Function

Specifies that scheduling settings should be ignored.

Syntax

dbmlsync -e isc= { ON | OFF }; ...

Description

If set to ON, dbmlsync ignores any scheduling information that is specified in extended options and synchronizes immediately. The default is OFF.

This option is equivalent to the dbmlsync -is option.

This option has a short form and long form: you can use isc or IgnoreScheduling.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

Scheduling synchronization

Schedule (sch) extended option

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "isc=off"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION isc='off';


Increment (inc) extended option
Function

Controls the size of incremental uploads.

Syntax

dbmlsync -e inc= number [ K | M ]; ...

Description

This option specifies a minimum incremental scan volume in units of bytes. Use the suffix k or m to specify units of kilobytes or megabytes, respectively.

When this option is specified, uploads are sent to MobiLink in one or more parts. This could be useful if a site has difficulty maintaining a connection for long enough to complete the full upload. When the option is not set, uploads are sent as a single unit.

The value of this option specifies, very approximately, the size of each upload part. The value of the option controls the size of each upload part as follows. Dbmlsync builds the upload stream by scanning the database transaction log. When this option is set, dbmlsync scans the number of bytes that are set in the option, and then continues scanning to the first point at which there are no outstanding partial transactions—the next point at which all transactions have either been committed or rolled back. It then sends what it has scanned as an upload part and resumes scanning the log from where it left off.

You cannot use the Increment extended option with -tu.

This option has a short form and long form: you can use inc or Increment.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "inc=32000"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION inc='32k';


LockTables (lt) extended option
Function

Specifies that articles (table or parts of tables in the publications being synchronized) should be locked before synchronizing.

Syntax

dbmlsync -e lt= { ON | OFF | SHARE | EXCLUSIVE }; ...

Description

SHARE means that dbmlsync locks all synchronization tables in shared mode. EXCLUSIVE means that dbmlsync locks all synchronization tables in exclusive mode. For all platforms except Windows CE, ON is the same as SHARE. For Windows CE devices, ON is the same as EXCLUSIVE. The default is ON.

Set to OFF to allow modifications during synchronization.

For more information about shared and exclusive locks, see How locking works and LOCK TABLE statement.

For more information about locking tables in MobiLink applications, see Concurrency during synchronization.

When synchronization tables are locked in exclusive mode (the default for Windows CE devices), no other connections can access the tables, and so dbmlsync stored procedures that require a separate connection will not be able to execute if they require access to any of the synchronization tables. The stored procedures that require a separate connection are

  • sp_hook_dbmlsync_download_com_error

  • sp_hook_dbmlsync_download_fatal_sql_error

  • sp_hook_dbmlsync_download_log_ri_violation

This option has a short form and long form: you can use lt or LockTables.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "lt=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION lt='on';


Memory (mem) extended option
Function

Specifies a cache size.

Syntax

dbmlsync -e mem= number[ K | M ]; ...

Description

Specifies the cache used for building the upload stream, in units of bytes. A larger cache means that dbmlsync can keep more pages of data in memory, thus reducing the number of disk reads/writes and improving performance.

Use the suffix k or m to specify units of kilobytes or megabytes, respectively. The default is 1M.

This option has a short form and long form: you can use mem or Memory.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

-urc option

Performance tips

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "mem=2M"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION mem='2m';


MirrorLogDirectory (mld) extended option
Function

Specifies the location of old mirror log files so that they can be deleted.

Syntax

dbmlsync -e mld= filename ...

Description

This option makes it possible for dbmlsync to delete old mirror log files when either of the following two circumstances occur:

  • the offline mirror log is located in a different directory from the mirror transaction log

    or

  • dbmlsync is run on a different machine from the remote database engine

In a normal setup, the active mirror log and renamed mirror transaction logs are located in the same directory, and dbmlsync is run on the same machine as the remote database, so this option is not required and old mirror log files are automatically deleted.

Transaction logs in this directory will only be affected if the DELETE_OLD_LOGS database option is set to ON or DELAY.

This option has a short form and long form: you can use mld or MirrorLogDirectory.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

DELETE_OLD_LOGS option [replication]

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "mld=c:\tmp\file"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION mld='c:\tmp\file';


MobiLinkPwd (mp) extended option
Function

Specifies the MobiLink password.

Syntax

dbmlsync -e mp=password; ...

Description

Specifies the password used to connect. This password should be the correct password for the MobiLink user whose subscriptions are being synchronized. This user may be specified with the dbmlsync -u option. The default is NULL.

If the MobiLink user already has a password, use the extended option -e mn to change it.

This option has a short form and long form: you can use mp or MobiLinkPwd.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

NewMobiLinkPwd (mn) extended option

-mn option

-mp option

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "mp=SQL"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION mp='SQL';


NewMobiLinkPwd (mn) extended option
Function

Specifies a new password.

Syntax

dbmlsync -e mn=new-password; ...

Description

Specifies a password for the MobiLink user whose subscriptions are being synchronized. Use this option when you want to change an existing password. The default is NULL.

This option has a short form and long form: you can use mn or NewMobiLinkPwd.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

MobiLinkPwd (mp) extended option

-mn option

-mp option

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "mp=oldpassword; mn=newpassword"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION mn='SQL';


OfflineDirectory (dir) extended option
Function

Specifies the path containing offline transaction logs.

Syntax

dbmlsync -e dir=path; ...

Description

This option has a short form and long form: you can use dir or OfflineDirectory.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "dir=c:\db\logs"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION dir='c:\db\logs';


PollingPeriod (pp) extended option
Function

Specifies the logscan polling period.

Syntax

dbmlsync -e pp=number [S | M | H | D ]; ...

Description

This option specifies the interval between log scans. Use the suffix s, m, h, or d to specify seconds, minutes, hours or days, respectively. The default is 1 minute. If you do not specify a suffix, the default unit of time is minutes.

Logscan polling occurs only when you are scheduling synchronizations or using the sp_hook_dbmlsync_delay hook.

For an explanation of logscan polling, see DisablePolling (p) extended option.

This option is identical to dbmlsync -pp.

This option has a short form and long form: you can use pp or PollingPeriod.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

DisablePolling (p) extended option

-pp option

-p option

sp_hook_dbmlsync_delay

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "pp=5"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION pp='5';


Schedule (sch) extended option
Function

Specifies a schedule for synchronization.

Syntax

dbmlsync -e sch=schedule; ...

schedule= { EVERY:hhhh:mm | singleSchedule | INFINITE,... }

hhhh : 00... 9999

mm : 00... 59

singleSchedule : day @hh:mm[ AM | PM ] [ –hh:mm[ AM | PM ] ]

hh : 00... 24

mm : 00... 59

day :
EVERYDAY | WEEKDAY | MON | TUE | WED | THU | FRI | SAT | SUN | dayOfMonth

dayOfMonth : 0... 31

Parameters

EVERY The EVERY keyword causes synchronization to occur immediately, and then repeat indefinitely after the specified time period. If the synchronization process takes longer than the specified period, synchronization starts again immediately.

singleSchedule Given one or more single schedules, synchronization occurs only at the specified days and times.

An interval is specified as @hh:mm–hh:mm (with optional specification of AM or PM). If AM or PM is not specified, a 24-hour clock is assumed. 24:00 is interpreted as 00:00 on the next day. When an interval is specified, synchronization occurs, starting at a random time within the interval. The interval provides a window of time for synchronization so that multiple remote databases with the same schedule do not cause congestion at the synchronization server by synchronizing at exactly the same time.

The interval end time is always interpreted as following the start time. When the time interval includes midnight, it ends on the next day. If dbmlsync is started midway through the interval, synchronization occurs at a random time before the end time.

EVERYDAY EVERYDAY is all seven days of the week.

WEEKDAY WEEKDAY is Monday through Friday.

Days of the week are Mon, Tue, and so on. You may also use the full forms of the day, such as Monday. You must use the full forms of the day names if the language you are using is not English, is not the language requested by the client in the connection string, and is not the language which appears in the server window.

dayOfMonth To specify the last day of the month regardless of the length of the month, set the dayOfMonth to 0.

INFINITE The INFINITE keyword causes dbmlsync to run and to scan the log periodically, but not to synchronize, even if synchronizations are scheduled. A synchronization can happen only when initiated by another program. You can use this option in conjunction with the dbmlsync -wc option to wake up dbmlsync and perform a synchronization.

For more information, see -wc option.

Description

If a previous synchronization is still incomplete at a scheduled time, the scheduled synchronization commences when the previous synchronization completes.

The default is no schedule.

This option has a short form and long form: you can use sch or Schedule.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

The schedule option syntax is the same when used in the synchronization SQL statements and in the dbmlsync command line.

The IgnoreScheduling extended option and the -is option instruct dbmlsync to ignore scheduling, so that synchronization is immediate. For more information, see IgnoreScheduling (isc) extended option.

For more information about scheduling, see Scheduling synchronization.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "sch=WEEKDAY@8:00am,SUN@9:00pm"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION sch='WEEKDAY@8:00am,SUN@9:00pm';


ScriptVersion (sv) extended option
Function

Specifies a script version.

Syntax

dbmlsync -e sv=version-name; ...

Description

The script version determines which scripts are run by MobiLink on the consolidated database during synchronization. The default script version name is default.

This option has a short form and long form: you can use sv or ScriptVersion.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "sv=SyaAd001"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION sv='SysAd001';


SendColumnNames (scn) extended option
Function

Specifies that column names should be sent in the upload.

Syntax

dbmlsync -e scn= { ON | OFF }; ...

Description

Set this option to ON to tell dbmlsync to send column names from the remote database to the server. This option is required when you generate scripts automatically using the dbmlsrv9 -za or -ze options. This option increases the size of your upload, so you probably won't want to use it if you are not using -za or -ze.

The default is OFF.

This option has a short form and long form: you can use scn or SendColumnNames.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

-za option

-ze option

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "scn=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION scn='on';


SendDownloadACK (sa) extended option
Function

Specifies that a download acknowledgement should be sent from the client to the server.

Syntax

dbmlsync -e sa= { ON | OFF }; ...

Description

Turning the acknowledgement off (the default) can lead to less contention in the consolidated database and also increased throughput due to shorter download transactions. Download transactions are shorter because they are committed or rolled back as soon as possible, since MobiLink doesn't need to keep these transactions open for as long as it takes the remote client to apply the download. Enable client side download buffering to get the most performance out of eliminating the download acknowledgement. It is recommended that SendDownloadAck be set to OFF.

For more information about improving performance by turning off the download acknowledgement, see Performance tips.

Note: When SendDownloadAck is set to ON and you are in verbose mode, an acknowledgement line is written to the client log.

The default is OFF.

This option has a short form and long form: you can use sa or SendDownloadACK.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "sa=off"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION sa='off';


SendTriggers (st) extended option
Function

Specifies that trigger actions should be sent on upload.

Syntax

dbmlsync -e st= { ON | OFF }; ...

Description

Cascaded deletes are also considered trigger actions.

The default is OFF.

This option has a short form and long form: you can use st or SendTriggers.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "st=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION st='on';


TableOrder (tor) extended option
Function

Specifies the order of tables in the upload stream.

Syntax

dbmlsync -e tor= tables ; ...

Description

This option allows you to specify the order of tables that are to be uploaded. Specify tables as a comma-separated list. You must specify all tables that are to be uploaded. If you list tables that are not included in the synchronization, they are ignored.

Specify table order to ensure referential integrity. For example, if Table1 refers to Table2, then Table2 must be uploaded before Table1.

In the specified table order, no table may have a foreign key that refers to a table that comes after it in the table order, unless your tables have a cyclical foreign key relationship. By default, dbmlsync selects a table order that satisfies this condition.

There are no cases where this option must be used. It is provided for users who for some reason (usually because it makes their scripts simpler on the consolidated database) would like to ensure that tables are uploaded in a specific order.

This option has a short form and long form: you can use tor or TableOrder.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

Referential integrity and synchronization

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "tor=admin,parent,child"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION tor='admin,parent,child';


UploadOnly (uo) extended option
Function

Specifies that synchronization should only include an upload.

Syntax

dbmlsync -e uo={ ON | OFF } ; ...

Description

During an upload only synchronization, dbmlsync prepares and sends an upload to the MobiLink synchronization server exactly as in a normal full synchronization. However, instead of sending a download stream back down, MobiLink sends only an acknowledgement indicating if the upload was successfully committed.

The default is OFF.

This option has a short form and long form: you can use uo or UploadOnly.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

Upload-only and download-only synchronization

DownloadOnly (ds) extended option

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "uo=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION uo='on';


Verbose (v) extended option
Function

Specifies full verbosity.

Syntax

dbmlsync -e v= { ON | OFF } ; ...

Description

This option specifies a high level of verbosity, which may affect performance and should normally be used in the development phase only.

This option is identical to dbmlsync -v+. If you specify both -v and the extended options and there are conflicts, the -v option overrides the extended option. If there is no conflict, the verbosity logging options are additive—all options that you specify are used. When logging verbosity is set by extended option, the logging does not take effect immediately, so startup information is not logged. By the time of the first synchronization, the logging behavior is identical between the -v options and the extended options.

For more information, see -v option.

The default is OFF.

This option has a short form and long form: you can use v or Verbose.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "v=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION v='on';


VerboseHooks (vs) extended option
Function

Specifies that messages related to hook scripts should be logged.

Syntax

dbmlsync -e vs= { ON | OFF } ; ...

Description

This option is identical to dbmlsync -vs. If you specify both -v and the extended options and there are conflicts, the -v option overrides the extended option. If there is no conflict, the verbosity logging options are additive—all options that you specify are used. When logging verbosity is set by extended option, the logging does not take effect immediately, so startup information is not logged. By the time of the first synchronization, the logging behavior is identical between the -v options and the extended options.

For more information, see -v option.

The default is OFF.

This option has a short form and long form: you can use vs or VerboseHooks.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

See also

Dbmlsync Client Event Hooks

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "vs=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION vs='on';


VerboseMin (vm) extended option
Function

Specifies that a small amount of information should be logged.

Syntax

dbmlsync -e vm= { ON | OFF } ; ...

Description

This option is identical to dbmlsync -v. If you specify both -v and the extended options and there are conflicts, the -v option overrides the extended option. If there is no conflict, the verbosity logging options are additive—all options that you specify are used. When logging verbosity is set by extended option, the logging does not take effect immediately, so startup information is not logged. By the time of the first synchronization, the logging behavior is identical between the -v options and the extended options.

For more information, see -v option.

The default is OFF.

This option has a short form and long form: you can use vm or VerboseMin.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "vm=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION vm='on';


VerboseOptions (vo) extended option
Function

Specifies that information should be logged about the command line options (including extended options) that you have specified.

Syntax

dbmlsync -e vo= { ON | OFF } ; ...

Description

This option is identical to dbmlsync -vo. If you specify both -v and the extended options and there are conflicts, the -v option overrides the extended option. If there is no conflict, the verbosity logging options are additive—all options that you specify are used. When logging verbosity is set by extended option, the logging does not take effect immediately, so startup information is not logged. By the time of the first synchronization, the logging behavior is identical between the -v options and the extended options.

For more information, see -v option.

The default is OFF.

This option has a short form and long form: you can use vo or VerboseOptions.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "vo=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION vo='on';


VerboseRowCounts (vn) extended option
Function

Specifies that the number of rows that are uploaded and downloaded should be logged.

Syntax

dbmlsync -e vn= { ON | OFF } ; ...

Description

This option is identical to dbmlsync -vn. If you specify both -v and the extended options and there are conflicts, the -v option overrides the extended option. If there is no conflict, the verbosity logging options are additive—all options that you specify are used. When logging verbosity is set by extended option, the logging does not take effect immediately, so startup information is not logged. By the time of the first synchronization, the logging behavior is identical between the -v options and the extended options.

For more information, see -v option.

The default is OFF.

This option has a short form and long form: you can use vn or VerboseRowCounts.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "vn=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION vn='on';


VerboseRowValues (vr) extended option
Function

Specifies that the values of rows that are uploaded and downloaded should be logged.

Syntax

dbmlsync -e vr= { ON | OFF } ; ...

Description

This option is identical to dbmlsync -vr. If you specify both -v and the extended options and there are conflicts, the -v option overrides the extended option. If there is no conflict, the verbosity logging options are additive—all options that you specify are used. When logging verbosity is set by extended option, the logging does not take effect immediately, so startup information is not logged. By the time of the first synchronization, the logging behavior is identical between the -v options and the extended options.

For more information, see -v option.

The default is OFF.

This option has a short form and long form: you can use vr or VerboseRowValues.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "vr=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION vr='on';


VerboseUpload (vu) extended option
Function

Specifies that information about the upload steam should be logged.

Syntax

dbmlsync -e vu= { ON | OFF } ; ...

Description

This option is identical to dbmlsync -vu. If you specify both -v and the extended options and there are conflicts, the -v option overrides the extended option. If there is no conflict, the verbosity logging options are additive—all options that you specify are used. When logging verbosity is set by extended option, the logging does not take effect immediately, so startup information is not logged. By the time of the first synchronization, the logging behavior is identical between the -v options and the extended options.

For more information, see -v option.

The default is OFF.

This option has a short form and long form: you can use vu or VerboseUpload.

You can also store extended options in the database. For more information about dbmlsync extended options, see dbmlsync extended options.

Example

The following dbmlsync command line illustrates how you can set this option when you start dbmlsync:

dbmlsync -e "vu=on"

The following SQL statement illustrates how you can store this option in the database:

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION vu='on';


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Clients

Adaptive Server Anywhere Client Synchronization Parameters

dbmlsync options

-eh option

Function

Ignores errors that occur in hook functions.

Syntax

dbmlsync -eh ...


-ek option

Function

Allows you to specify the encryption key for strongly encrypted databases directly on the command line.

Syntax

dbmlsync -ek key ...

Description

If you have a strongly encrypted database, you must provide the encryption key to use the database or transaction log in any way, including offline transactions. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify a key for a strongly encrypted database.


-ep option

Function

Prompt for the encryption key.

Syntax

dbmlsync -ep ...

Description

This option causes a dialog box to appear, in which you enter the encryption key. It provides an extra measure of security by never allowing the encryption key to be seen in clear text. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify a key for a strongly encrypted database.


-eu option

Function

Specifies extended upload options.

Syntax

dbmlsync -n publication-name -eu keyword=value;...

Description

Extended options that are specified on the command line with the -eu option apply only to the synchronization specified by the -n option they follow. For example, on the following command line, the extended option sv=test applies only to the synchronization of pub2.

dbmlsync -n pub1 -n pub2 -eu sv=test

For an explanation of how extended options are processed when they are set in more than one place, see dbmlsync extended options.

For a complete list of extended options, see dbmlsync extended options.


-is option

Function

Ignores scheduling instructions so that synchronization is immediate.

Syntax

dbmlsync -is ...

Description

Ignore extended options that schedule synchronization.

For information about scheduling, see Scheduling synchronization.


-k option

Function

Shuts down dbmlsync when synchronization is finished.

Syntax

dbmlsync -k ...

Description

When -k is used, dbmlsync exits after synchronization is completed if the synchronization was successful or if an output log file was specified using the -o or -ot options.

See also

-o option

-ot option


-l option

Function

Lists available extended options.

Syntax

dbmlsync -l ...

Description

When used with the dbmlsync command line it shows you available extended options.


-mn option

Function

Supplies a new password for the user being synchronized.

Syntax

dbmlsync -mn password ...

Description

Changes the MobiLink user's password.

For more information, see Authenticating MobiLink Users.

See also

MobiLinkPwd (mp) extended option

NewMobiLinkPwd (mn) extended option

-mp option


-mp option

Function

Supplies the password of the user being synchronized.

Syntax

dbmlsync -mp password ...

Description

Supplies the password for MobiLink user authentication.

For more information, see Authenticating MobiLink Users.

See also

MobiLinkPwd (mp) extended option

NewMobiLinkPwd (mn) extended option

-mn option


-n option

Function

Names the synchronization publication.

Syntax

dbmlsync -n pubname ...

Description

Name of synchronization publication. You can supply more than one -n option to synchronize more than one synchronization publication.

There are two ways to use -n to synchronize multiple publications:

  • Specify -n pub1,pub2,pub3 to upload pub1, pub2, and pub3 in one upload stream.

    In this case, if you have set extended options on the publications, only the options set on the first publication in the list are used. Extended options set on subsequent publications are ignored.

  • Specify -n pub1 -n pub2 -n pub3 to upload pub1 in one upload stream, pub2 in another, and pub3 in a third upload stream.

    When successive synchronizations occur very quickly, such as when you specify -n pub1 -n pub2, it is possible that dbmlsync may start processing a synchronization when the server is still processing the previous synchronization. In this case, the second synchronization will fail with an error indicating that concurrent synchronizations are not allowed. If you run into this situation, you can define an sp_hook_dbmlsync_delay stored procedure to create a delay before each synchronization. Usually a few seconds to a minute is a sufficient delay.

    For more information, see sp_hook_dbmlsync_delay.


-o option

Function

Sends output to a log file.

Syntax

dbmlsync -o filename ...

Description

Append output to a log file. Default is to send output to the screen.

See also

-os option

-ot option


-os option

Function

Specifies a maximum size for the output log, at which point the log is renamed.

Syntax

dbmlsync -os size [ K | M | G ]...

Description

The size is the maximum file size for logging output messages, specified in units of bytes. Use the suffix k, m or g to specify units of kilobytes, megabytes or gigabytes, respectively. By default, there is no size limit. The minimum size limit is 10 kb.

Before the dbmlsync utility logs output messages to a file, it checks the current file size. If the log message will make the file size exceed the specified size, the dbmlsync utility renames the output file to yymmddxx.dbr, where yymmdd represents the year, month, and day, and xx are sequential characters ranging from AA to ZZ.

This option allows you to manually delete old log files and free up disk space.

See also

-o option

-ot option


-ot option

Function

Truncates the log file and appends output messages to it.

Syntax

dbmlsync -ot logfile ...

Description

The functionality is the same as the -o option except the log file is truncated before any messages are written to it.

See also

-o option

-os option


-p option

Function

Disables logscan polling.

Syntax

dbmlsync -p ...

Description

In order to build an upload stream, dbmlsync must scan the transaction log. Usually it does this just before synchronization. However, when synchronizations are scheduled or when the sp_hook_dbmlsync_delay hook is used, dbmlsync by default scans the log in the pause that occurs just before synchronization. This behavior is more efficient because when synchronization begins the log is already at least partially scanned. This default behavior is called logscan polling.

Logscan polling is on by default but only has an effect when synchronizations are scheduled using scheduling options or when sp_hook_dbmlsync_delay hook is used. When in effect, polling occurs at set intervals; by default this is 1 minute, but it can be changed with the dbmlsync -pp option.

The default is to not disable logscan polling ( OFF).

This option is identical to dbmlsync -e p.

See also

DisablePolling (p) extended option

PollingPeriod (pp) extended option

-pp option


-pd option

Function

Preload specified dlls for Windows CE.

Syntax

dbmlsync -pd dllname;...

Description

When running dbmlsync on Windows CE, you should use the -pd option to specify dlls that need to be loaded. Otherwise, the correct dlls may not be loaded and an error may be generated.

Following are the dlls that need to be loaded for each communication protocol:

Protocol | DLL
TCP/IP | dbmlsock9.dll
HTTP | dbmlhttp9.dll
HTTPS | dbmlhttps9.dll

You should specify multiple dlls as a semicolon-separated list. For example,

-pd dbmlsock9.dll;dbmlhttp9.dll


-pi option

Function

Pings a MobiLink synchronization server.

Syntax

dbmlsync -pi -c connection_string -e sv=script_version
[-n pubname ] [ -u ml_username ]

Description

The ping option allows you to test that your connection information is correct. When you use -pi, dbmlsync does not initiate synchronization.

In order to be able to ping, dbmlsync must have a unique address for the MobiLink synchronization server. This means that you must include connection parameters and a script version, as well as the publication name, MobiLink user name, or both. The publication or user hold connection information for the remote. You need to specify both when the user is subscribed to multiple publications or the publication has multiple users. For example, if there is only one subscription to the publication, you can specify the publication without the user.

When the MobiLink synchronization server receives a ping request, it connects to the consolidated database, authenticates the user, and then sends the authenticating user status and value back to the client (dbmlsync or UltraLite).

If the ping succeeds, the MobiLink server issues an information message. If the ping does not succeed, it issues an error message.

If the MobiLink user name cannot be found in the ml_user system table and the MobiLink server is running with the command line option -zu+, the MobiLink server adds the user to ml_user.

The MobiLink synchronization server may execute the following scripts, if they exist:

  • begin_connection

  • authenticate_user

  • authenticate_user_hashed

  • end_connection

The client cannot synchronize while it is pinging the server.


-pp option

Function

Specifies the frequency of log scans.

Syntax

dbmlsync -pp number [ h | m | s ]...

Description

This option specifies the interval between log scans. Use the suffix s, m, h, or d to specify seconds, minutes, hours or days, respectively. The default is 1 minute. If you do not specify a suffix, the default unit of time is minutes.

Logscan polling occurs only when you are scheduling synchronizations or using the sp_hook_dbmlsync_delay hook.

For an explanation of logscan polling, see -p option.

See also

PollingPeriod (pp) extended option

DisablePolling (p) extended option

-p option


-q option

Function

Starts the MobiLink synchronization client in a minimized window.

Syntax

dbmlsync -q ...

Description

For Windows operating systems only.


-r option

Function

Specifies that the remote offset should be used when there is disagreement between the offsets in the remote and consolidated databases.

The -rb option can be used when the remote offset is less than the consolidated offset (such as when the remote database has been restored from backup). The -r option is provided for backward compatibility and is identical to -rb. The -ra option, used when the remote offset is greater than the consolidated offset, is provided only for very rare circumstances and may cause data loss.

Syntax

dbmlsync { -r | -ra | -rb } ...

Description

For information about progress offsets, see Progress offsets.

-rb If the remote database is restored from backup, the default behavior may cause data to be lost. In this case, the first time you run dbmlsync after the remote database is restored, you should specify -rb. When you use -rb, the upload continues from the offset recorded in the remote database if the offset recorded in the remote is less than that obtained from the consolidated database. If you use -rb and the offset in the remote is not less than the offset from the consolidated database, an error is reported and the synchronization is aborted.

The -rb option may result in some data being uploaded that has already been uploaded. This can result in conflicts in the consolidated database and should be handled with appropriate conflict resolution scripts.

-ra The -ra option should be used only in very rare cases. If you use -ra, the upload is retried starting from the offset obtained from the remote database if the remote offset is greater than the offset obtained from the consolidated database. If you use -ra and the offset in the remote is not greater than the offset from the consolidated database, an error is reported and the synchronization is aborted.

The -ra option should be used with care. If the offset mismatch is the result of a restore of the consolidated database, changes that happened in the remote database in the gap between the two offsets are lost. The -ra option may be useful when the consolidated database has been restored from backup and the remote database transaction log has been truncated at the same point as the remote offset. In this case, all data that was uploaded from the remote database is lost from the point of the consolidated offset to the point of the remote offset.


-sc option

Function

Specifies that dbmlsync should reload schema information before each synchronization.

Syntax

dbmlsync -sc...

Description

Prior to version 9.0, dbmlsync reloaded schema information from the database before each synchronization. The information that was reloaded includes foreign key relationships, publication definitions, extended options stored in the database, and information about database settings. On slower handheld devices, loading this information typically took 20 seconds. In most cases this information does not change between synchronizations.

Starting with version 9.0, by default dbmlsync loads schema information only at startup. Specify -sc if you want the information to be loaded before every synchronization.


-tu option

Function

Specifies that each transaction on the remote database should be uploaded as a separate transaction within one synchronization.

Syntax

dbmlsync -tu ...

Description

When you use -tu, you create a transaction-level upload: dbmlsync uploads each transaction on the remote database as a distinct transaction. If you change the same row three times on the remote database and commit the change each time, each of the three transactions is applied in the next upload stream. The transactions are uploaded in a single synchronization, on a single connection, but each transaction is committed as soon as it is successfully uploaded.

When you use -tu, the order of transactions on the remote database is always preserved on the consolidated database. However, the order of operations in a transaction may not be preserved, for two reasons:

  • MobiLink always applies updates based on foreign key relationships. For example, when data is changed in child and parent tables, MobiLink inserts data into the parent table before the child table, but deletes data from the child before the parent. If your remote operations do not follow this order, the order of operations will be different on the consolidated database.

  • Operations within a transaction are coalesced. This means that if you change the same row three times in one transaction, only the final form of the row is uploaded.

Usage

When you do not use -tu, MobiLink coalesces all changes on the remote database into one transaction in the upload stream. This means that if you change the same row three times between synchronizations, regardless of the number of remote transactions, only the final form of the row is uploaded. This default behavior is efficient and is optimal in many situations.

However, in certain situations you may wish to preserve remote transactions on the consolidated database. For example, you may wish to define triggers on the consolidated database that act on transactions as they occur in the remote database. Or you may want the consolidated database to reflect all changes on the remote database, regardless of when synchronization occurs.

In addition, there are advantages to breaking up the upload stream into smaller transactions. Many consolidated databases are optimized for small transactions, so sending a very large transaction is not efficient or may cause too much contention. Also, when you use -tu each transaction is applied as it is successfully uploaded, so you may not lose the entire upload if there are communications errors during the upload. When you use -tu and there is an upload error, all successfully uploaded transactions are applied.

When you use -tu, performance will be improved if you start the MobiLink synchronization server with the -us option, which prevents MobiLink from invoking scripts for tables which have no data to upload.

The -tu option makes MobiLink behave in a manner that is very close to SQL Remote. The main difference is that SQL Remote replicates all changes to the remote database in the order they occur, without coalescing. To mimic this behavior, you must commit every change, because -tu causes MobiLink to replicate all transactions.

You cannot use -tu with the Increment extended option.


-u option

Function

Specifies the MobiLink user name.

Syntax

dbmlsync -u ml_username ...

Description

You can specify one user in the dbmlsync command line, where ml_username is the name used in the FOR clause of the CREATE SYNCHRONIZATION SUBSCRIPTION statement corresponding to the subscription to be processed.

This option should be used in conjunction with -n publication to identify the subscription on which dbmlsync should operate. Each subscription is uniquely identified by an ml_username, publication pair.

You can only specify one user name on the command line. All subscriptions to be synchronized in a single run must involve the same user. The -u option can be omitted if each publication that is specified on the command line with the -n option has only one subscription.


-uo option

Function

Specifies that synchronization will only include an upload, and no download will occur.

Syntax

dbmlsync -uo...

Description

During an upload only synchronization, dbmlsync prepares and sends an upload to MobiLink exactly as it would in a normal full synchronization. However, instead of sending a download stream back down, MobiLink sends only an acknowledgement indicating if the upload was successfully committed.

Upload-only and download-only synchronization

DownloadOnly (ds) extended option

UploadOnly (uo) extended option


-urc option

Function

Specifies an estimate of the number of rows to be uploaded in a synchronization.

Syntax

dbmlsync -urc row-estimate ...

Description

To improve performance, you can specify an estimate of the number of rows that will be uploaded in a synchronization. In general, a higher estimate results in faster uploads but more memory usage.

Synchronization will proceed correctly regardless of the estimate that is specified.

See also

Memory (mem) extended option

Performance tips


-v option

Function

Allows you to specify what information is logged to the message log file and displayed in the synchronization window. A high level of verbosity may affect performance and should normally be used in the development phase only.

Syntax

dbmlsync -v [ levels ] ...

Description

The -v options affect the message log file and synchronization window. You only have a message log if you specify -o or -ot on the dbmlsync command line.

If you specify –v alone, a small amount of information is logged.

The values of levels are as follows. You can use one or more of these options at once; for example, -vnrsu or -v+cp.

  • + Turn on all logging options except for c and p.

  • c Expose the connect string in the log.

  • p Expose the password in the log.

  • n Log the number of rows that were uploaded and downloaded.

  • o Log information about the command line options and extended options that you have specified.

  • r Log the values of rows that were uploaded and downloaded.

  • s Log messages related to hook scripts.

  • u Log information about the upload stream.

There are extended options that have similar functionality to the -v options. If you specify both -v and the extended options and there are conflicts, the -v option overrides the extended option. If there is no conflict, the verbosity logging options are additive—all options that you specify are used. When logging verbosity is set by extended option, the logging does not take effect immediately, so startup information is not logged. By the time of the first synchronization, the logging behavior is identical between the -v options and the extended options.

See also

Verbose (v) extended option

VerboseHooks (vs) extended option

VerboseMin (vm) extended option

VerboseOptions (vo) extended option

VerboseRowCounts (vn) extended option

VerboseRowValues (vr) extended option


-wc option

Function

Specifies a window class name.

Syntax

dbmlsync -wc class-name ...

Description

This option specifies a class name that can be used to poke dbmlsync and wake it up whenever it is in hover mode, such as when scheduling is enabled or when you are using server-initiated synchronization.

In addition, the window class name identifies the application for ActiveSync synchronization. The class name must be given when registering the application for use with ActiveSync synchronization.

See also
  • Registering Adaptive Server Anywhere clients for ActiveSync
  • Using ActiveSync synchronization
  • INFINITE keyword in Schedule (sch) extended option
  • Scheduling synchronization
Example
dbmlsync -wc dbmlsync_$message_end...


-x option

Function

Renames and restarts the transaction log after it has been scanned for outgoing messages.

Syntax

dbmlsync -x [ size [ K | M | G ]...

Description

The optional size means that the transaction log is renamed only if it is larger than the specified size. Use the suffix k, m or g to specify units of kilobytes, megabytes or gigabytes, respectively. The default size is 0.

In some circumstances, synchronizing data to a consolidated database can take the place of backing up remote databases, or renaming the transaction log when the database server is shut down.

If backups are not routinely performed at the remote database, the transaction log continues to grow. As an alternative to using the -x option to control transaction log size, you can use an Adaptive Server Anywhere event handler to control the size of the transaction log. For example, the following event handler renames the transaction log at the remote database when its size exceeds 5 Mb. You can use such an event handler together with the DELETE_OLD_LOGS database option to control the space taken up by transaction logs.

CREATE EVENT RenameLogLimit
TYPE GrowLog
WHERE event_condition( 'LogSize' ) > 5
AT REMOTE
HANDLER
BEGIN
 If event_parameter( 'NumActive' ) <= 1 then
  BACKUP DATABASE DIRECTORY backupdir
  TRANSACTION LOG ONLY
  TRANSACTION LOG RENAME
 end if;
END

In this example, NumActive ensures that only one of the stacked handlers is executed.

See also
  • Automating Tasks Using Schedules and Events
  • DELETE_OLD_LOGS option [replication]
  • CREATE EVENT statement


MobiLink SQL Statements

About this chapter

This chapter presents detailed descriptions of SQL statements in alphabetical order.

ALTER PUBLICATION statement
ALTER SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
ALTER SYNCHRONIZATION USER statement [MobiLink]
CREATE PUBLICATION statement
CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
CREATE SYNCHRONIZATION USER statement [MobiLink]
DROP PUBLICATION statement
DROP SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
DROP SYNCHRONIZATION USER statement [MobiLink]
START SYNCHRONIZATION DELETE statement [MobiLink]
STOP SYNCHRONIZATION DELETE statement [MobiLink]


ALTER PUBLICATION statement

Description

Use this statement to alter a publication. In MobiLink, a publication identifies synchronized data in a Adaptive Server Anywhere remote database. In SQL Remote, publications identify replicated data in both consolidated and remote databases.

Syntax

ALTER PUBLICATION [ owner.]publication-name alterpub-clause, ...

alterpub-clause:
ADD TABLE article-description
| MODIFY TABLE article-description
| { DELETE | DROP } TABLE [ owner.]table-name
| RENAME publication-name

owner, publication-name, table-name : identifier

article-description :
table-name [ ( column-name, ... ) ]
[ WHERE search-condition ]
[ SUBSCRIBE BY expression ]

Usage

This statement is applicable only to MobiLink and SQL Remote.

The ALTER PUBLICATION statement alters a publication in the database. The contribution to a publication from one table is called an article. Changes can be made to a publication by adding, modifying, or deleting articles, or by renaming the publication. If an article is modified, the entire specification of the modified article must be entered.

You set options for a MobiLink publication with the ADD OPTION clause in the ALTER SYNCHRONIZATION SUBSCRIPTION statement or CREATE SYNCHRONIZATION SUBSCRIPTION statement.

Permissions

Must have DBA authority, or be the owner of the publication. Requires exclusive access to all tables referred to in the statement.

Side effects

Automatic commit.

See also
  • CREATE PUBLICATION statement
  • DROP PUBLICATION statement
  • ALTER SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • sp_add_article procedure
  • sp_add_article_col procedure
Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

Example

The following statement adds the customer table to the pub_contact publication.

ALTER PUBLICATION pub_contact
   ADD TABLE customer


ALTER SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]

Description

Use this statement in an Adaptive Server Anywhere remote database to alter the properties of a subscription of a MobiLink user to a publication.

Syntax

ALTER SYNCHRONIZATION SUBSCRIPTION
TO publication-name
[ FOR ml_username, ... ]
[ TYPE protocol ]
[ ADDRESS protocol-options ]
[ ADD OPTION option=value, ... ]
[ MODIFY OPTION option=value, ... ]
[ DELETE { ALL OPTION | OPTION option, ... } ]

ml_username: identifier

protocol-type: http | https | https_fips |tcpip | ActiveSync

protocol-options: string

value: string | integer

Parameters

TO clause Specify the name of a publication.

FOR clause Specify one or more MobiLink user names.

Omit the FOR clause to set the protocol type, protocol options, and extended options for a publication.

For information about how dbmlsync processes options that are specified in different locations, see Priority order for extended options and connection parameters.

TYPE clause This clause specifies the network protocol to use for synchronization. The default protocol is tcpip.

For more information about communication protocols, see CommunicationType (ctp) extended option.

ADDRESS clause This clause specifies network protocol options, including the location of the MobiLink synchronization server.

For a complete list of protocol options, see CommunicationAddress (adr) extended option.

ADD OPTION, MODIFY OPTION, DELETE OPTION, AND DELETE ALL OPTION clauses These clauses allow you to add, modify, delete, or delete all extended options. You may specify only one option in each clause.

The values for each option cannot contain the characters "=" or "," or ";".

For a complete list of options, see dbmlsync extended options.

Usage

Use this statement to alter a synchronization subscription within a MobiLink remote or reference database.

Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the publication.

Side effects

Automatic commit.

See also
  • CREATE PUBLICATION statement
  • CREATE SYNCHRONIZATION USER statement [MobiLink]
Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

Examples

Create a default subscription, which contains default subscription values, for the sales publication (by omitting the FOR clause). Indicate the address of the MobiLink synchronization server and specify that only the Certicom root certificate is to be trusted.

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   ADDRESS 'host=test.internal;port=2439;
      security=ecc_tls'
   OPTION memory='2m';

Subscribe MobiLink user ml_user1 to the sales publication. Set the memory option to 3 Mb, rather than the value specified in the default publication.

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR 'ml_user1'
   OPTION memory='3m';


ALTER SYNCHRONIZATION USER statement [MobiLink]

Description

Use this statement in an Adaptive Server Anywhere remote database to alter the properties of a MobiLink user.

Syntax

ALTER SYNCHRONIZATION USER ml_username
[ TYPE protocol-type ]
[ ADDRESS protocol-options ]
[ ADD OPTION option=value, ... ]
[ MODIFY OPTION option=value, ... ]
[ DELETE { ALL OPTION | OPTION option } ]

ml_username: identifier

protocol-type: http | https | https_fips | tcpip | ActiveSync

protocol-options: string

value: string | integer

Parameters

TYPE clause This clause specifies the network protocol to use for synchronization.

For more information about communication protocols, see CommunicationType (ctp) extended option.

ADDRESS clause This clause specifies network protocol options, including the location of the MobiLink synchronization server.

For a complete list of protocol options, see CommunicationAddress (adr) extended option.

ADD OPTION, MODIFY OPTION, DELETE OPTION, AND DELETE ALL OPTION clauses These clauses allow you to add, modify, delete, or delete all extended options. You may specify only one option in each clause.

For a complete list of options, see dbmlsync extended options.

Usage

Use this statement to alter the properties of a synchronization user within a MobiLink remote database.

Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the publication.

Side effects

Automatic commit.

See also
  • ALTER SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • CREATE SYNCHRONIZATION USER statement [MobiLink]
  • CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.


CREATE PUBLICATION statement

Description

Use this statement to create a publication. In MobiLink, a publication identifies synchronized data in UltraLite or Adaptive Server Anywhere remote databases.

Syntax

CREATE PUBLICATION [ owner.]publication-name
( TABLE article-description, ... )

owner, publication-name : identifier

article-description :
table-name [ ( column-name, ... ) ]
[ WHERE search-condition ]
[ SUBSCRIBE BY expression ]

Parameters

article-description Publications are built from articles. Each article is a table or part of a table. An article may be a vertical partition of a table (a subset of the table's columns), a horizontal partition (a subset of the table's rows) or a vertical and horizontal partition.

WHERE clause The WHERE clause is a way of defining the subset of rows of a table to be included in an article. It is useful if the same subset is to be received by all subscribers to the publication.

SUBSCRIBE BY clause

You can combine WHERE and SUBSCRIBE BY clauses in an article definition, but the SUBSCRIBE BY clause is used only by SQL Remote.

Usage

This statement is applicable only to MobiLink and SQL Remote.

The CREATE PUBLICATION statement creates a publication in the database. A publication can be created for another user by specifying an owner name.

In MobiLink, publications are required in Adaptive Server Anywhere remote databases, and are optional in UltraLite databases. These publications and the subscriptions to them determine which data will be uploaded to the MobiLink synchronization server. You can construct a remote database by creating publications and subscriptions directly. Alternatively, you can create publications and subscriptions in an Adaptive Server Anywhere reference database, which acts as a template for the remote databases, and then construct the remote databases using the MobiLink extraction utility.

You set options for a MobiLink publication with the ADD OPTION clause in the ALTER SYNCHRONIZATION SUBSCRIPTION statement or CREATE SYNCHRONIZATION SUBSCRIPTION statement.

Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the statement.

Side effects

Automatic commit.

See also
  • ALTER PUBLICATION statement
  • DROP PUBLICATION statement
  • ALTER SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • sp_create_publication procedure
  • Adaptive Server Anywhere MobiLink clients: Publishing data
  • UltraLite MobiLink clients: Choosing data to synchronize
Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

Example

The following statement publishes all columns and rows of two tables.

CREATE PUBLICATION pub_contact (
   TABLE contact,
   TABLE company
)

The following statement publishes only some columns of one table.

CREATE PUBLICATION pub_customer (
   TABLE customer ( id, company_name, city )
)

The following statement publishes only the active customer rows by including a WHERE clause that tests the status column of the customer table.

CREATE PUBLICATION pub_customer (
   TABLE customer ( id, company_name, city, state )
   WHERE status = 'active'
)


CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]

Description

Use this statement in an Adaptive Server Anywhere remote database to subscribe a MobiLink user to a publication.

Syntax

CREATE SYNCHRONIZATION SUBSCRIPTION
TO publication-name
[ FOR ml_username, ... ]
[ TYPE protocol-type ]
[ ADDRESS protocol-options]
[ OPTION option=value, ... ]

ml_username: identifier

protocol-type: http | https | https_fips | tcpip | ActiveSync

protocol-options: string

value: string | integer

Parameters

TO clause Specify the name of a publication.

FOR clause Specify one or more MobiLink user names.

ml_username is a name identifying a remote database. This name must be unique.

For more information about synchronization user names, see About MobiLink users.

Omit the FOR clause to set the protcol type, protocol options, and extended options for a publication.

For information about how dbmlsync processes options that are specified in different locations, see Priority order for extended options and connection parameters.

TYPE clause This clause specifies the network protocol to use for synchronization. The default protocol is tcpip.

For more information about network protocols, see CommunicationType (ctp) extended option.

ADDRESS clause This clause specifies network protocol options such as the location of the MobiLink synchronization server. Multiple options must be separated with semi-colons.

For a complete list of protocol options, see CommunicationAddress (adr) extended option.

OPTION clause This clause allows you to set extended options for the subscription. If no FOR clause is provided, the extended options act as default settings for the publication, and are overridden by any extended options set for a synchronization user.

For information about how dbmlsync processes options that are specified in different locations, see Priority order for extended options and connection parameters.

For a complete list of options, see dbmlsync extended options.

Usage

Use this statement to create a synchronization subscription within a MobiLink remote or reference database.

Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the publication.

Side effects

Automatic commit.

See also
  • CREATE PUBLICATION statement
  • CREATE SYNCHRONIZATION USER statement [MobiLink]
Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

Examples

Create a default subscription, which contains default subscription values, for the sales publication (by omitting the FOR clause). Indicate the address of the MobiLink synchronization server and specify that only the Certicom root certificate is to be trusted.

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   ADDRESS 'host=test.internal;port=2439;
      security=ecc_tls'
   OPTION memory='2m';

Subscribe MobiLink user ml_user1 to the sales publication. Set the memory option to 3 Mb, rather than the value specified in the default publication.

CREATE SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR ml_user1
   OPTION memory='3m';


CREATE SYNCHRONIZATION USER statement [MobiLink]

Description

Use this statement in an Adaptive Server Anywhere remote database to create a synchronization user.

Syntax

CREATE SYNCHRONIZATION USER ml_username
[ TYPE protocol-type ]
[ ADDRESS protocol-options ]
[ OPTION option=value, ... ]

ml_username: identifier

protocol-type: tcpip | http | https | https_fips | ActiveSync

protocol-options: string

value: string | integer

Parameters

ml_username A name identifying a remote database. This name must be unique.

For more information about synchronization user names, see About MobiLink users.

TYPE clause This clause specifies the communication protocol to use for synchronization. The options are tcpip, http, https, https_fips, and ActiveSync. The default protocol is tcpip.

For more information about communication protocols, see CommunicationType (ctp) extended option.

ADDRESS clause This clause specifies protocol-options in the form keyword=value, separated by semi-colons. Which settings you supply depends on the communication protocol you are using (TCPIP, HTTP, HTTPS, or ActiveSync).

For a complete list of protocol options, see CommunicationAddress (adr) extended option.

OPTION clause The OPTION clause allows you to set extended options using option=value in a comma-separated list.

The values for each option cannot contain equal signs or semicolons. The database server accepts any option that you enter without checking for its validity. Therefore, if you misspell an option or enter an invalid value, no error message appears until you run the dbmlsync command to perform synchronization.

Options set for a synchronization user can be overridden in individual subscriptions or on the dbmlsync command line.

For information about extended options, see dbmlsync extended options.

Description

The protocol-type, protocol-options, and options can be set in several places.

For information about how dbmlsync processes options that are specified in different locations, see Priority order for extended options and connection parameters.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also
  • ALTER SYNCHRONIZATION USER statement [MobiLink]
  • CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • CREATE PUBLICATION statement
  • MobiLink Transport-Layer Security
Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Supported by Open Client/Open Server.

Examples

The following example creates a user named SSinger, who synchronizes over TCP/IP with a server machine named mlserver.mycompany.com using the password Sam. The use of a password in the user definition is not secure.

CREATE SYNCHRONIZATION USER SSinger
TYPE http
ADDRESS 'host=mlserver.mycompany.com'
OPTION MobiLinkPwd='Sam'

The following creates a synchronization user called factory014 that will cause dbmlsync to hover and synchronize via Certicom-encrypted TCP/IP at a random time in every 8-hour interval. The randomness helps prevent performance degradation at the MobiLink server due to multiple simultaneous synchronizations:

CREATE SYNCHRONIZATION USER factory014
TYPE tcpip
ADDRESS 'host=mycompany.manufacturing.mobilink1;security=certicom_tls(certificate=mycompany_mobilink.crt;certificate_password=thepassword)'
OPTION Schedule='EVERY:08:00'

The following creates a synchronization user called sales5322 that will be used to synchronize with HTTP. In this example, the MobiLink synchronization server runs behind the corporate firewall, and synchronization requests are redirected to it using the Redirector (a reverse proxy to an NSAPI Web server).

CREATE SYNCHRONIZATION USER sales5322
TYPE https
ADDRESS 'host=www.mycompany.com;port=80;url_suffix=mlredirect/ml/'


DROP PUBLICATION statement

Description

Use this statement to drop a publication. In MobiLink a publication identifies synchronized data in a Adaptive Server Anywhere remote database. In SQL Remote, publications identify replicated data in both consolidated and remote databases.

Syntax

DROP PUBLICATION [ owner.]publication-name

owner, publication-name : identifier

Usage

This statement is applicable only to MobiLink and SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit. All subscriptions to the publication are dropped.

See also
  • ALTER PUBLICATION statement
  • CREATE PUBLICATION statement
  • sp_drop_publication procedure
Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

Example

The following statement drops the pub_contact publication.

DROP PUBLICATION pub_contact


DROP SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]

Description

Use this statement to drop a synchronization subscription within a MobiLink remote database or a MobiLink reference database. You can also use it to drop a default subscription, which contains default subscription values, for the specified publication.

Syntax

DROP SYNCHRONIZATION SUBSCRIPTION
TO publication-name
[ FOR ml_username, ... ]

Parameters

TO clause Specify the name of a publication.

FOR clause Specify one more MobiLink users.

Omitting this clause drops the default subscription for the publication. MobiLink users subscribed to a publication inherit as defaults the values in a default publication.

Usage

Drop a synchronization subscription in a MobiLink remote or reference database.

Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the publication.

Side Effects

Automatic commit.

Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

Examples

Unsubscribe MobiLink user ml_user1 to the sales publication.

DROP SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication
   FOR "ml_user1"

Drop the default subscription, which contains default subscription values, for the sales publication (by omitting the FOR clause).

DROP SYNCHRONIZATION SUBSCRIPTION
   TO sales_publication


DROP SYNCHRONIZATION USER statement [MobiLink]

Description

Use this statement to drop a synchronization user from a MobiLink remote database.

Syntax

DROP SYNCHRONIZATION USER ml_username, ...

ml_username: identifier

Usage

Drop one or more synchronization users from a MobiLink remote database.

Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the publication.

Side Effects

All subscriptions associated with the user are also deleted.

Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

Example

Remove MobiLink user ml_user1 from the database.

DROP SYNCHRONIZATION USER ml_user1


START SYNCHRONIZATION DELETE statement [MobiLink]

Description

Use this statement to restart logging of deletes for MobiLink synchronization.

Syntax

START SYNCHRONIZATION DELETE

Usage

Ordinarily, Adaptive Server Anywhere and UltraLite automatically log any changes made to tables or columns that are part of a synchronization, and upload these changes to the consolidated database during the next synchronization. You can temporarily suspend automatic logging of delete operations using the STOP SYNCHRONIZATION DELETE statement. The START SYNCHRONIZATION DELETE statement allows you to restart the automatic logging.

When a STOP SYNCHRONIZATION DELETE statement is executed, none of the delete operations executed on that connection will be synchronized. The effect continues until a START SYNCHRONIZATION DELETE statement is executed. Repeating STOP SYNCHRONIZATION DELETE has no additional effect.

A single START SYNCHRONIZATION DELETE statement restarts the logging, regardless of the number of STOP SYNCHRONIZATION DELETE statements preceding it.

Do not use START SYNCHRONIZATION DELETE if your application does not synchronize data.

Permissions

Must have DBA authority.

Side effects

None.

See also
  • STOP SYNCHRONIZATION DELETE statement [MobiLink]
  • StartSynchronizationDelete method
Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

Example

The following sequence of SQL statements illustrates how to use START SYNCHRONIZATION DELETE and STOP SYNCHRONIZATION DELETE.

-- Prevent deletes from being sent
-- to the consolidated database
STOP SYNCHRONIZATION DELETE;

-- Remove all records older than 1 month
-- from the remote database,
-- NOT the consolidated database
DELETE FROM PROPOSAL
WHERE last_modified < months( CURRENT TIMESTAMP, -1 )

-- Re-enable all deletes to be sent
-- to the consolidated database
-- DO NOT FORGET to start this
START SYNCHRONIZATION DELETE;

-- Commit the entire operation,
-- otherwise rollback everything
-- including the stopping of the deletes
commit;


STOP SYNCHRONIZATION DELETE statement [MobiLink]

Description

Use this statement to temporarily stop logging of deletes for MobiLink synchronization.

Syntax

STOP SYNCHRONIZATION DELETE

Usage

Ordinarily, Adaptive Server Anywhere and UltraLite remote databases automatically log any changes made to tables or columns that are included in a synchronization, and then upload these changes to the consolidated database during the next synchronization. This statement allows you to temporarily suspend logging of changes to an Adaptive Server Anywhere or UltraLite remote database.

When a STOP SYNCHRONIZATION DELETE statement is executed, none of the subsequent delete operations executed on that connection will be synchronized. The effect continues until a START SYNCHRONIZATION DELETE statement is executed.

Repeating STOP SYNCHRONIZATION DELETE has no additional effect. A single START SYNCHRONIZATION DELETE statement restarts the logging, regardless of the number of STOP SYNCHRONIZATION DELETE statements preceding it.

This command can be useful to make corrections to a remote database, but should be used with caution as it effectively disables MobiLink synchronization.

Do not use STOP SYNCHRONIZATION DELETE if your application does not synchronize data.

Permissions

Must have DBA authority.

Side Effects

None.

See also
  • StartSynchronizationDelete method
  • StopSynchronizationDelete method
  • START SYNCHRONIZATION DELETE statement [MobiLink]
Standards and compatibility

  • SQL/92 Vendor extension.

  • SQL/99 Vendor extension.

  • Sybase Not applicable.

Example

For an example, see START SYNCHRONIZATION DELETE statement [MobiLink].


Dbmlsync Client Event Hooks

About this chapter

Customizing the client synchronization process
sp_hook_dbmlsync_abort
sp_hook_dbmlsync_begin
sp_hook_dbmlsync_connect_failed
sp_hook_dbmlsync_delay
sp_hook_dbmlsync_download_begin
sp_hook_dbmlsync_download_com_error
sp_hook_dbmlsync_download_end
sp_hook_dbmlsync_download_fatal_sql_error
sp_hook_dbmlsync_download_log_ri_violation
sp_hook_dbmlsync_download_ri_violation
sp_hook_dbmlsync_download_sql_error
sp_hook_dbmlsync_download_table_begin
sp_hook_dbmlsync_download_table_end
sp_hook_dbmlsync_end
sp_hook_dbmlsync_log_rescan
sp_hook_dbmlsync_logscan_begin
sp_hook_dbmlsync_logscan_end
sp_hook_dbmlsync_process_return_code
sp_hook_dbmlsync_schema_upgrade
sp_hook_dbmlsync_set_extended_options
sp_hook_dbmlsync_upload_begin
sp_hook_dbmlsync_upload_end
sp_hook_dbmlsync_validate_download_file


Customizing the client synchronization process

The Adaptive Server Anywhere synchronization client, dbmlsync, provides a set of event hooks that you can use to customize the synchronization process. When a hook is implemented, it is called at a specific point in the synchronization process.

You implement an event hook by creating a stored procedure with a specific name. Most event-hook stored procedures are executed on the same connection as the synchronization itself.

You can use event hooks to log synchronization events, schedule synchronizations based on logical events or time and customize synchronization behavior.

In addition, you can use event hooks to synchronize subsets of data that cannot be easily defined in a publication. For example, you can synchronize data in a temporary table by writing one event hook procedure to copy data from the temporary table to a permanent table prior to the synchronization and another to copy the data back afterwards.

Caution The integrity of the synchronization process relies on a sequence of built-in transactions. Thus, you must not perform an implicit or explicit commit or rollback within your event-hook procedures.


Synchronization event hook sequence

The following pseudo-code shows the available events and the point at which each is called during the synchronization process. For example, sp_hook_dbmlsync_abort is the first event hook to be invoked.

Each event makes particular parameter values available, which you can use when you implement the procedure. In some cases, you can modify the value to return a new value; others are read-only. These parameters are not stored procedure arguments. No arguments are passed to any of the event-hook stored procedures. Instead, arguments are exchanged by reading and modifying rows in the #hook_dict table.

For example, the sp_hook_dbmlsync_begin procedure has a parameter, which is the user name that the application supplied in the synchronization call. You can retrieve this value from the #hook_dict table.

Although the sequence has similarities to the event sequence at the MobiLink synchronization server, there is little overlap in the kind of logic you would want to add to the consolidated and remote databases. The two interfaces are therefore separate and distinct.

Any *_end hook will be called if the corresponding *_begin hook is called and completed successfully. A *_begin hook is considered to have run successfully if it was not implemented when it would have been called.

For more information about upload options, see -tu option and Increment (inc) extended option.

sp_hook_dbmlsync_abort
sp_hook_dbmlsync_set_extended_options
loop until return codes direct otherwise (
   sp_hook_dbmlsync_abort
   sp_hook_dbmlsync_delay
)
sp_hook_dbmlsync_abort
// start synchronization
sp_hook_dbmlsync_begin
// upload events
for each upload segment
// a normal synchronization has one upload segment
// a transaction-level upload has one segment per transaction
// an incremental upload has one segment per upload piece
 sp_hook_dbmlsync_logscan_begin
 sp_hook_dbmlsync_logscan_end
 sp_hook_dbmlsync_upload_begin
 sp_hook_dbmlsync_upload_end
next upload event
// download events
sp_hook_dbmlsync_validate_download_file (only called
   when -ba option is used)
sp_hook_dbmlsync_download_begin
for each table
   sp_hook_dbmlsync_download_table_begin
   sp_hook_dbmlsync_download_table_end
next table
sp_hook_dbmlsync_download_end
sp_hook_dbmlsync_schema_upgrade
// end synchronization
sp_hook_dbmlsync_end
sp_hook_dbmlsync_process_return_code
sp_hook_dbmlsync_log_rescan
Error handling

In addition, the following event-hook procedures are available for error handling.

sp_hook_dbmlsync_all_error
sp_hook_dbmlsync_communication_error
sp_hook_dbmlsync_connect_failed
sp_hook_dbmlsync_download_com_error
sp_hook_dbmlsync_download_SQL_error
sp_hook_dbmlsync_download_fatal_SQL_error
sp_hook_dbmlsync_download_ri_violation
sp_hook_dbmlsync_download_log_ri_violation
sp_hook_dbmlsync_misc_error
sp_hook_dbmlsync_sql_error

Once implemented, each procedure is automatically executed whenever an error of the named type occurs.


Using event-hook procedures

This section describes some considerations for designing and using event-hook procedures.

Notes

  • Do not perform any COMMIT or ROLLBACK operations in event-hook procedures. The procedures are executed on the same connection as the synchronization, and a COMMIT or ROLLBACK may interfere with synchronization.

  • Do not define more than one hook with the same name. If more than one hook with the same name is created (say by different users), then which hook is called is undefined.

  • Hook procedures must be created by a user with DBA authority.

  • If a *_begin hook executes successfully, the corresponding *_end hook is called regardless of any error that occurs afterwards. If the *_begin hook is not defined, but you have defined an *_end hook, then the *_end hook is called unless an error occurs prior the point in time where the *_begin hook would normally be called.


#hook_dict table

Immediately before a hook is called, dbmlsync creates the #hook_dict table in the remote database, using the following CREATE statement. The # before the table name means that the table is temporary.

CREATE TABLE #hook_dict(
name VARCHAR(128) NOT NULL UNIQUE,
value VARCHAR(255) NOT NULL)

dbmlsync uses the #hook_dict table to pass values to hook functions, and hook functions use the #hook_dict table to pass values back to dbmlsync.

For example, for the following dbmlsync command line,

dbmlsync -c 'dsn=MyDsn' -n pub1,pub2 -u MyUser

when the sp_hook_dbmlsync_abort hook is called, the #hook_dict table will contain the following rows:

Name Value
publication_0
pub1
publication_1
pub2
MobiLink user
MyUser
Abort synchronization
false

Your abort hook can retrieve values from the #hook_dict table and use them to customize behavior. For example, to retrieve the MobiLink user you would use a SELECT statement like this:

SELECT value
FROM #hook_dict
WHERE name = 'MobiLink user'

In/out parameters can be updated by your hook to modify the behavior of dbmlsync. For example, your hook could instruct dbmlsync to abort synchronization by updating the abort synchronization row of the table using a statement like this:

UPDATE #hook_dict
SET value='true'
WHERE name='abort synchronization'

The description of each hook lists the rows in the #hook_dict table.


Event-hook procedure owner

The event-hook connection calls the stored procedures without qualifying them by owner. The stored procedures must therefore be owned by one of the following:

  • The user name employed on the dbmlsync connection (typically a user with REMOTE DBA authority).

  • A group ID of which the dbmlsync user is a member.


Connections for event-hook procedures

Each event-hook procedure is executed on the same connection as the synchronization itself. The following are exceptions:

  • sp_hook_dbmlsync_all_error

  • sp_hook_dbmlsync_communication_error

  • sp_hook_dbmlsync_download_com_error

  • sp_hook_dbmlsync_download_fatal_sql_error

  • sp_hook_dbmlsync_download_log_ri_violation

  • sp_hook_dbmlsync_misc_error

  • sp_hook_dbmlsync_sql_error

These procedures are called before a synchronization fails. On failure, synchronization actions are rolled back. By operating on a separate connection, you can use these procedures to log information about the failure, without the logging actions being rolled back along with the synchronization actions.


Event arguments

Each hook receives parameter values. In some cases, you can modify the value to return a new value; others are read-only.

These parameters are exchanged by reading and modifying rows in the #hook_dict table, which is defined as follows.

CREATE TABLE #hook_dict (
   name   VARCHAR( 128 ) NOT NULL UNIQUE,
   value   VARCHAR( 255 ) NOT NULL
)

Each row in the table contains the value for one parameter.

Before calling any of the stored procedures, dbmlsync creates the #hook_dict table, and adds the parameters for that event. Procedures can read the values by selecting from this table.

Some parameters can be used to pass values back to dbmlsync from the hook. The hook passes values back by updating the #hook_dict table.

For a list of the parameter values supplied at each event, see Dbmlsync Client Event Hooks.

Examples

The following examples illustrate how to retrieve and set values in the #hook_dict table.

The following sample sp_hook_dbmlsync_delay procedure illustrates the use of the #hook_dict table to pass arguments. The procedure allows synchronization only outside a scheduled down time of the MobiLink system between 18:00 and 19:00.

CREATE PROCEDURE sp_hook_dbmlsync_delay()
BEGIN
   DECLARE delay_val integer;
 SET delay_val=DATEDIFF(
   second, CURRENT TIME, '19:00');
 IF (delay_val>0 AND
     delay_val<3600)
 THEN
 UPDATE #hook_dict SET value=delay_val
   WHERE name='delay duration';
 END IF;
END

The following procedure is executed in the remote database at the beginning of synchronization. It retrieves the current MobiLink user name, one of the parameters available for the sp_hook_dbmlsync_begin event, and displays it on the console.

CREATE PROCEDURE sp_hook_dbmlsync_begin()
BEGIN
   DECLARE syncdef VARCHAR(150);
   SELECT '>>>syncdef = ' || value INTO syncdef
      FROM #hook_dict
      WHERE name ='MobiLink user name';
   MESSAGE syncdef TYPE INFO TO CONSOLE;
END


Ignoring errors in event-hook procedures

By default, synchronization stops when an error is encountered in an event-hook procedure. You can instruct the dbmlsync utility to ignore errors that occur in event-hook procedures by supplying the -eh option.

For more information, see IgnoreHookErrors (eh) extended option.


sp_hook_dbmlsync_abort

Function

Use this stored procedure to cancel the synchronization process.

Rows in #hook_dict table
Name | Values | Description
abort synchronization (in|out) | true | false | If you set the abort synchronization row of the #hook_dict table to true, then dbmlsync terminates immediately after the event.
publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
exit code (in|out) | number | When abort synchronization is set to TRUE, you can use this value to set the return code for the aborted synchronization. 0 indicates a successful synchronization. Any other number indicates that the synchronization failed.
script version (in|out) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is called at dbmlsync startup, and then again after each synchronization delay that is caused by the sp_hook_dbmlsync_delay hook.

If the hook requests an abort by setting the abort synchronization value to true, the exit code is passed to the sp_hook_dbmlsync_process_exit_code hook. If no sp_hook_dbmlsync_process_exit_code hook is defined, the exit code is used as the exit code for the program.

Actions of this procedure are committed immediately after execution.

See also
  • Synchronization event hook sequence
  • sp_hook_dbmlsync_process_return_code
Examples

The following procedure prevents synchronization during a scheduled maintenance hour between 19:00 and 20:00 each day.

create procedure sp_hook_dbmlsync_abort()
begin
  declare down_time_start time;
  declare is_down_time varchar(128);
  set down_time_start='19:00';
  if abs( datediff( hour,down_time_start,now(*) ) ) < 1
  then
    set is_down_time='true';
  else
    set is_down_time='false';
  end if;
  UPDATE #hook_dict
  SET value = is_down_time
  WHERE name = 'abort synchronization'
end

Suppose you have an abort hook that may abort synchronization for one of two reasons. One of the reasons indicates normal completion of synchronization, so you want dbmlsync to have an exit code of 0. The other reason indicates an error condition, so you want dbmlsync to have a non-zero exit code. You could achieve this with an sp_hook_dbmlsync_abort hook defined as follows.

BEGIN
   IF [condition that defines the normal abort case] THEN
      UPDATE #hook_dict SET value =  '0'
   WHERE name = 'exit code';
      UPDATE #hook_dict SET value =  'TRUE'
   WHERE name = 'abort synchronization';
   ELSEIF [condition that defines the error abort case] THEN
      UPDATE #hook_dict SET value =  '1'
   WHERE name = 'exit code';
      UPDATE #hook_dict SET value =  'TRUE'
   WHERE name = 'abort synchronization';
   END IF;
END;


sp_hook_dbmlsync_begin

Function

Use this stored procedure to add custom actions at the beginning of the synchronization process.

Rows in #hook_dict table
Name | Values | Description
publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is called at the beginning of the synchronization process.

Actions of this procedure are committed immediately after execution.

See also
  • Synchronization event hook sequence
Examples

Assume you use the following table to log synchronization events on the remote database.

CREATE TABLE SyncLog
(
 "event_id"            integer NOT NULL DEFAULT autoincrement ,
   "event_name"        varchar(128) NOT NULL ,
   "ml_user"             varchar(128) NULL ,
   "event_time"          timestamp NULL,
   "table_name"          varchar(128) NULL ,
   "upsert_count"        varchar(128) NULL ,
   "delete_count"        varchar(128) NULL ,
   "exit_code"           integer NULL ,
   "status_retval"       varchar(128) NULL ,
   "pubs"                  varchar(128) NULL ,
   "sync_descr "         varchar(128) NULL ,
    PRIMARY KEY ("event_id"),
)

The following example compiles a list of publications. It logs the list of publications and other synchronization information at the beginning of the synchronization process.

CREATE PROCEDURE sp_hook_dbmlsync_begin ()
BEGIN

    DECLARE pubs_list varchar(1024);
    DECLARE temp_str varchar(128);
    DECLARE qry varchar(128);
-- insert publication list into pubs_list
    SELECT list(value) INTO pubs_list
     FROM #hook_dict
     WHERE name LIKE 'publication_%';
-- log publication and synchronization information
    INSERT INTO SyncLog(event_name,ml_user,pubs,event_time)
     SELECT 'dbmlsync_begin',#hook_dict.value,pubs_list,current timestamp
     FROM #hook_dict
     WHERE name='MobiLink user';
END


sp_hook_dbmlsync_connect_failed

Function

Use this stored procedure to retry failed attempts to connect to the MobiLink synchronization server using a different communication type or address.

Rows in #hook_dict table
Name | Values | Description
publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
script version (in) | script version name | The MobiLink script version to be used for the synchronization.
connection address (in|out) | connection address | When the hook is invoked, this is the address used in the most recent failed communication attempt. You can set this value to a new connection address that you want to try. If retry is set to true, this value is used for the next communication attempt.
connection type (in|out) | tcpip | http | https | ActiveSync | ecc_tls | rsa_tls | When the hook is invoked, this is the communication type that was used in the most recent failed communication attempt. You can set this value to a new connection type that you want to try. If retry is set to true, this value is used for the next communication attempt.
user data (in|out) | user-defined data | State information to be used if the next connection attempt fails. For example, you might find it useful to store the number of retries that have occurred. The default is an empty string.
allow remote ahead (in|out) | true | false | This is true only if dbmlsync was started with the -ra option. You can use this row to read or change the -ra option for the current synchronization only. For more information, see -r option.
allow remote behind (in|out) | true | false | This is true only if dbmlsync was started with the -rb option. You can use this row to read or change the -rb option for the current synchronization only. For more information, see -r option.
retry (in|out) | true | false | Set this value to true if you want to retry a failed connection attempt. The default is FALSE.
Description

If a procedure of this name exists, it is called if dbmlsync fails while attempting to connect to the MobiLink synchronization server.

This hook only applies to connection attempts to the MobiLink synchronization server, not the database.

When a progress offset mismatch occurs, dbmlsync disconnects from the MobiLink synchronization server and reconnects later. In this kind of reconnection, this hook is not called, and failure to reconnect causes the synchronization to fail.

Actions of this procedure are committed immediately after execution.

Examples

This example uses the sp_hook_dbmlsync_connect_failed hook to retry the connection up to five times.

CREATE PROCEDURE sp_hook_dbmlsync_ml_connect_failed ()
BEGIN
    DECLARE idx integer;
    DECLARE buf varchar( 128 );

    SELECT value
      INTO buf
      FROM #hook_dict
      WHERE name = 'user data';

    IF buf = '' THEN
      SELECT 1 INTO idx;
    ELSE
      SELECT CONVERT( integer, value ) + 1
        INTO idx
        FROM #hook_dict
        WHERE name = 'user data';
    END IF;

  IF idx <= 5 THEN
        UPDATE #hook_dict
        SET value = CONVERT( varchar(128), idx )
        WHERE name = 'user data';

        UPDATE #hook_dict
        SET value = 'TRUE'
        WHERE name = 'retry';
  END IF
END

The next example uses a table containing connection information. When an attempt to connect fails, the hook tries the next server in the list.

CREATE TABLE conn_list (
    label   integer primary key,
    addr  varchar( 128 ),
    type  varchar( 64 )
);
INSERT INTO conn_list
 VALUES ( 1, 'host=server1;port=91', 'tcpip' );
INSERT INTO conn_list
 VALUES ( 2, 'host=server2;port=92', 'http' );
INSERT INTO conn_list
 VALUES ( 3, 'host=server3;port=93', 'tcpip' );
COMMIT;

CREATE PROCEDURE sp_hook_dbmlsync_ml_connect_failed ()
BEGIN
 DECLARE idx integer;
 DECLARE cnt integer;
 DECLARE buf varchar( 128 );

 SELECT value
  INTO buf
  FROM #hook_dict
  WHERE name = 'user data';

 IF buf = '' THEN
   SELECT 1 INTO idx;
 ELSE
   SELECT CONVERT( integer, value ) + 1
   INTO idx
     FROM #hook_dict
   WHERE name = 'user data';
   END IF;

 SELECT count( label ) INTO cnt FROM conn_list;

 IF idx <= cnt THEN
   UPDATE #hook_dict
        SET value = ( SELECT addr FROM conn_list WHERE label = idx )
        WHERE name = 'connection address';

   UPDATE #hook_dict
    SET value = (SELECT type FROM conn_list WHERE label=idx)
    WHERE name = 'connection type';

   UPDATE #hook_dict
    SET value = CONVERT( varchar(128), idx )
        WHERE name = 'user data';

       UPDATE #hook_dict
        SET value = 'TRUE'
        WHERE name = 'retry';
 END IF
END


sp_hook_dbmlsync_delay

Function

Use this stored procedure to control when synchronization takes place.

Rows in #hook_dict table
Name | Values | Description
delay duration (in|out) | number of seconds | If the procedure sets the delay duration value to zero, then dbmlsync synchronization proceeds. A non-zero delay_duration value specifies the number of seconds before the delay hook is called again.
maximum accumulated delay (in|out) | number of seconds | The maximum accumulated delay specifies the maximum number of seconds delay before each synchronization. Dbmlsync keeps track of the total delay created by all calls to the delay hook since the last synchronization. If no synchronization has occurred since dbmlsync started running, the total delay is calculated from the time dbmlsync started up. When the total delay exceeds the value of maximum accumulated delay, synchronization begins without any further calls to the delay hook.
publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user ( in ) | MobiLink user name | The MobiLink user for which you are synchronizing.
script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is called before sp_hook_dbmlsync_begin at the beginning of the synchronization process.

Actions of this procedure are committed immediately after execution.

See also
  • Synchronization event hook sequence
Example

Assume you have the following table to log orders on the remote database.

CREATE TABLE OrdersTable(
  "id" integer primary key default autoincrement,
  "priority" varchar(128)
)

The following example delays synchronization for a maximum accumulated delay of one hour. Every ten seconds the hook is called again and checks for a high priority row in the OrdersTable. If a high priority row exists the delay duration is set to zero to start the synchronization process.

CREATE PROCEDURE sp_hook_dbmlsync_delay()
BEGIN
      -- Set the maximum delay between synchronizations
    -- or before the first synchronization starts to 1 hour
    UPDATE #hook_dict SET value = '3600'  // 3600 seconds
     WHERE name = 'maximum accumulated delay';

    -- check if a high priority order exists in OrdersTable
    IF EXISTS (SELECT * FROM OrdersTable where priority='high') THEN
     -- start the synchronization to process the high priority row
     UPDATE #hook_dict
      SET value = '0'
      WHERE name='delay duration';
    ELSE
     -- set the delay duration to call this procedure again
     -- following a 10 second delay
     UPDATE #hook_dict
      SET value = '10'
      WHERE name='delay duration';
    END IF;
END

In the sp_hook_dbmlsync_end hook you can mark the high priority row as processed.

-- change status of high priority row
 UPDATE OrdersTable
  SET priority = 'high-processed'
  WHERE priority = 'high';

For more information about sp_hook_dbmlsync_end, see sp_hook_dbmlsync_end.


sp_hook_dbmlsync_download_begin

Function

Use this stored procedure to add custom actions at the beginning of the download stage of the synchronization process.

Rows in #hook_dict table
Name | Values | Description
publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is called at the beginning of the download stage of the synchronization process.

Actions of this procedure are committed or rolled back when the download stream is committed or rolled back.

See also
  • Synchronization event hook sequence
Example

Assume you use the following table to log synchronization events on the remote database.

CREATE TABLE SyncLog
(
 "event_id"            integer NOT NULL DEFAULT autoincrement ,
   "event_name"        varchar(128) NOT NULL ,
   "ml_user"             varchar(128) NULL ,
   "event_time"          timestamp NULL,
   "table_name"          varchar(128) NULL ,
   "upsert_count"        varchar(128) NULL ,
   "delete_count"        varchar(128) NULL ,
   "exit_code"           integer NULL ,
   "status_retval"       varchar(128) NULL ,
   "pubs"                  varchar(128) NULL ,
   "sync_descr "         varchar(128) NULL ,
    PRIMARY KEY ("event_id"),
)

The following example compiles a list of publications. It logs the list of publications and other synchronization information at the beginning of the download stage of the synchronization.

CREATE PROCEDURE sp_hook_dbmlsync_begin ()
BEGIN

    DECLARE pubs_list varchar(1024);
    DECLARE temp_str varchar(128);
    DECLARE qry varchar(128);
-- insert publication list into pubs_list
    SELECT list(value) INTO pubs_list
     FROM #hook_dict
     WHERE name LIKE 'publication_%';
-- log publication and synchronization information
    INSERT INTO SyncLog(event_name,ml_user,pubs,event_time)
     SELECT 'dbmlsync_download_begin',#hook_dict.value,
      pubs_list,current timestamp
     FROM #hook_dict
     WHERE name='MobiLink user';
END


sp_hook_dbmlsync_download_com_error

Function

Use this stored procedure to add custom actions when communications errors occur while reading the download stream sent by the MobiLink synchronization server.

Rows in #hook_dict table
Name | Values | Description
table name (in) | table name | The table to which operations were being applied when the error occurred. The value is an empty string if dbmlsync is unable to identify the table.
publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is invoked when a communication error is detected during the download phase of synchronization. The download is then terminated.

This procedure executes on a separate connection, so that failures can be logged. Otherwise, the action of logging would be rolled back along with the synchronization actions. If dbmlsync cannot establish a separate connection, the procedure is not called.

By default on Windows CE devices, synchronization tables are locked in exclusive mode, which means that this hook cannot successfully execute if it requires access to any of the synchronization tables. It also cannot execute if it needs to access synchronization tables and you set the dbmlsync extended option LockTables to EXCLUSIVE. For more information, see LockTables (lt) extended option.

Actions of this procedure are committed immediately after execution.

See also
  • Synchronization event hook sequence
Examples

Assume you use the following table to log communication errors.

CREATE TABLE SyncLogComErrorTable
(
   " user_name "    varchar(255) NOT NULL ,
   " event_time "   timestamp NOT NULL ,
)

The following example logs the MobiLink user and current time stamp when communications errors occur while reading the download stream sent by the MobiLink synchronization server. The information is stored on the SyncLogComErrorTable table on the remote database.

CREATE PROCEDURE sp_hook_dbmlsync_download_com_error ()
BEGIN
 INSERT INTO SyncLogComErrorTable (user_name, event_time)
  SELECT #hook_dict.value, current timestamp
  FROM #hook_dict
  WHERE name = 'MobiLink user';
END;


sp_hook_dbmlsync_download_end

Function

Use this stored procedure to add custom actions at the end of the download stage of the synchronization process.

Rows in #hook_dict table
Name | Values | Description
publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is called at the end of the download stage of the synchronization process.

Actions of this procedure are committed or rolled back when the download stream is committed or rolled back.

See also
  • Synchronization event hook sequence
Examples

Assume you use the following table to log synchronization events on the remote database.

CREATE TABLE SyncLog
(
 "event_id"            integer NOT NULL DEFAULT autoincrement ,
   "event_name"        varchar(128) NOT NULL ,
   "ml_user"             varchar(128) NULL ,
   "event_time"          timestamp NULL,
   "table_name"          varchar(128) NULL ,
   "upsert_count"        varchar(128) NULL ,
   "delete_count"        varchar(128) NULL ,
   "exit_code"           integer NULL ,
   "status_retval"       varchar(128) NULL ,
   "pubs"                  varchar(128) NULL ,
   "sync_descr "         varchar(128) NULL ,
    PRIMARY KEY ("event_id"),
)

The following example compiles a list of publications. It logs the list of publications and other synchronization information at the end of the download stage of a synchronization.

CREATE PROCEDURE sp_hook_dbmlsync_begin ()
BEGIN

    DECLARE pubs_list varchar(1024);
    DECLARE temp_str varchar(128);
    DECLARE qry varchar(128);
-- insert publication list into pubs_list
    SELECT list(value) INTO pubs_list
     FROM #hook_dict
     WHERE name LIKE 'publication_%';
-- log publication and synchronization information
    INSERT INTO SyncLog(event_name,ml_user,pubs,event_time)
     SELECT 'dbmlsync_download_begin',#hook_dict.value,
      pubs_list,current timestamp
     FROM #hook_dict
     WHERE name='MobiLink user';
END


sp_hook_dbmlsync_download_fatal_sql_error

Function

Take action when a synchronization download is about to be rolled back because of a database error.

Rows in #hook_dict table
Name | Values | Description
table name (in) | table name | The table to which operations were being applied when the error occurred. The value is an empty string if dbmlsync is unable to identify the table.
SQL error code (in) | SQL error code | Identifies the SQL error code returned by the database when the operation failed.
publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is called immediately before a synchronization download is rolled back because of a database error. This occurs whenever an SQL error is encountered that cannot be ignored, or when the sp_hook_dbmlsync_download_SQL_error hook has already been called and has chosen not to ignore the error.

This procedure executes on a separate connection, so that failures can be logged. Otherwise, the action of logging would be rolled back along with the synchronization actions. If dbmlsync cannot establish a separate connection, the procedure is not called.

By default on Windows CE devices, synchronization tables are locked in exclusive mode, which means that this hook cannot successfully execute if it requires access to any of the synchronization tables. It also cannot execute if it needs to access synchronization tables and you set the dbmlsync extended option LockTables to EXCLUSIVE. For more information, see LockTables (lt) extended option.

Actions of this procedure are committed immediately after execution.

See also
  • Synchronization event hook sequence
  • sp_hook_dbmlsync_download_sql_error
Examples

Assume you use the following table to log SQL errors.

CREATE TABLE "DBA"."SyncLogComErrorTable"
(
   " error_code "       varchar(255) NOT NULL ,
   " event_time "       timestamp NOT NULL ,
)

The following example logs the SQL error code and current time stamp when SQL errors occur while reading the download stream. The information is stored in SyncLogSQLErrorTable on the remote database.

CREATE PROCEDURE sp_hook_dbmlsync_download_fatal_sql_error ()
BEGIN
 INSERT INTO SyncLogSQLErrorTable (error_code, event_time)
  SELECT #hook_dict.value, current timestamp
  FROM #hook_dict
  WHERE name = 'SQL error code';
END;


sp_hook_dbmlsync_download_log_ri_violation

Function

Logs referential integrity violations in the download process.

Rows in #hook_dict table
Name | Values | Description
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Foreign key table (in) | table name | The table containing the foreign key column for which the hook is being called.
Primary key table (in) | table name | The table referenced by the foreign key for which the hook is being called.
Role name (in) | role name | The role name of the foreign key for which the hook is being called.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

A download RI violation occurs when rows in the download stream violate foreign key relationships on the remote database. This hook allows you to log RI violations as they occur so that you can investigate their cause later.

After the download is complete, but before it is committed, dbmlsync checks for RI violations. If it finds any, it identifies a foreign key that has an RI violation and calls sp_hook_dbmlsync_download_log_ri_violation (if it is implemented). It then calls sp_hook_dbmlsync_download_ri_conflict (if it is implemented). If there is still a conflict, dbmlsync deletes the rows that violate the foreign key constraint. This process is repeated for remaining foreign keys that have RI violations.

This hook is called only when there are RI violations involving tables that are currently being synchronized. If there are RI violations involving tables that are not being synchronized, this hook is not called and the synchronization fails.

This hook is called on a separate connection from the one that dbmlsync uses for the download. The connection used by the hook has an isolation level of 0 so that the hook can see the rows that have been applied from the download stream that are not yet committed. The actions of the hook are committed immediately after it completes so that changes made by this hook will be preserved regardless of whether the download stream is committed or rolled back.

By default on Windows CE devices, synchronization tables are locked in exclusive mode, which means that this hook cannot successfully execute if it requires access to any of the synchronization tables. It also cannot execute if it needs to access synchronization tables and you set the dbmlsync extended option LockTables to EXCLUSIVE. For more information, see LockTables (lt) extended option.

Do not attempt to use this hook to correct RI violation problems. It should be used for logging only. Use sp_hook_dbmlsync_download_ri_violation to resolve RI violations.

See also
  • sp_hook_dbmlsync_download_ri_violation
  • Synchronization event hook sequence
Examples

Assume you use the following table to log referential integrity violations.

CREATE TABLE "DBA"." LogRIErrorTable "
(
 "id"     int PRIMARY KEY NOT NULL,
 "name"     varchar(255) NOT NULL,
 "value"  timestamp NOT NULL
)

The following example logs the foreign key table name, primary key table name, and other synchronization information when a referential integrity violation is detected on the remote database. The information is stored in LogRIErrorTable on the remote database.

CREATE PROCEDURE sp_hook_dbmlsync_download_log_ri_violation()
BEGIN
 --
 -- get the next id for the LogRIErrorTable
 --
   DECLARE nextid int;

 SELECT max(id)
  INTO nextid
  FROM LogRIErrorTable;

 IF nextid is NULL THEN
  SET nextid = 0
 ELSE
  SET nextid = nextid +1
 END IF;

 INSERT INTO LogRIErrorTable(id,name, value )
  SELECT nextid,#hook_dict.name, #hook_dict.value
  FROM #hook_dict;
END;


sp_hook_dbmlsync_download_ri_violation

Function

Allows you to resolve referential integrity violations in the download process.

Rows in #hook_dict table
Name | Values | Description
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Foreign key table (in) | table name | The table containing the foreign key column for which the hook is being called.
Primary key table (in) | table name | The table referenced by the foreign key for which the hook is being called.
Role name (in) | role name | The role name of the foreign key for which the hook is being called.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

A download RI violation occurs when rows in the download stream violate foreign key relationships on the remote database. This hook allows you to attempt to resolve RI violations before dbmlsync deletes the rows that are causing the conflict.

After the download is complete, but before it is committed, dbmlsync checks for RI violations. If it finds any, it identifies a foreign key that has an RI violation and calls sp_hook_dbmlsync_download_log_ri_violation (if it is implemented). It then calls sp_hook_dbmlsync_download_ri_conflict (if it is implemented). If there is still a conflict, dbmlsync deletes the rows. This process is repeated for remaining foreign keys that have RI violations.

This hook is called only when there are RI violations involving tables that are currently being synchronized. If there are RI violations involving tables that are not being synchronized, this hook is not called and the synchronization fails.

This hook is called on the same connection that dbmlsync uses for the download. This hook should not contain any explicit or implicit commits, because they may lead to inconsistent data in the database. The actions of this hook are committed or rolled back when the download stream is committed or rolled back.

Unlike other hook actions, the operations performed during this hook are not uploaded during the next synchronization.

See also
  • sp_hook_dbmlsync_download_log_ri_violation
Example

This example uses the Department and Employee tables shown below:

CREATE TABLE Department(
 "department_id"   integer primary key
);

CREATE TABLE Employee(
  "employee_id"      integer primary key,
  "department_id"   integer,
  foreign key EMPLOYEE_FK1 (department_id) references Department
)

The following sp_hook_dbmlsync_download_ri_violation definition cleans up referential integrity violations between the Department and Employee tables. It verifies the role name for the foreign key and inserts missing department_id values into the Department table.

CREATE PROCEDURE sp_hook_dbmlsync_download_ri_violation()
BEGIN

IF EXISTS (SELECT * FROM #hook_dict WHERE name = 'role name'
 AND value = 'EMPLOYEE_FK1') THEN

 -- update the Department table with missing department_id values
 INSERT INTO Department
  SELECT distinct department_id FROM Employee
  WHERE department_id NOT IN (SELECT department_id FROM Department)

END IF;


sp_hook_dbmlsync_download_sql_error

Function

Handle database errors that occur while applying the download stream sent by the MobiLink synchronization server.

Rows in #hook_dict table
Name | Values | Description
Table name (in) | table name | The table to which operations were being applied when the error occurred. The value is an empty string if dbmlsync is unable to identify the table.
Continue (in|out) | true | false | Indicates whether the error should be ignored and synchronization should continue. This parameter should be set to false to call the sp_hook_dbmlsync_download_fatal_sql_error hook and stop synchronization. If you set this parameter to true, dbmlsync ignores the error and continues with synchronization, which may result in data loss.
SQL error code (in) | SQL error code | Identifies the SQL error code returned by the database when the operation failed.
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is invoked when a database error is detected during the download phase of synchronization. The procedure is only invoked for errors where it is possible to ignore the error and continue with synchronization. For fatal errors, the sp_hook_dbmlsync_download_fatal_SQL_error procedure is called.

Caution When continue is set to TRUE, dbmlsync simply ignores the database error and continues with synchronization. There is no attempt to retry the operation that failed. As a result part or all of the download may be lost. The amount of data lost depends on the type of error encountered, when it occurred, and what steps the hook took to recover. It is very difficult to predict which data will be lost and so this feature must be used with extreme caution. Most users would be best advised to not attempt to continue after an SQL error.

Actions of this procedure are committed or rolled back when the download stream is committed or rolled back.

See also
  • Synchronization event hook sequence
  • sp_hook_dbmlsync_download_fatal_sql_error
Examples

Assume you use the following table to log SQL errors.

CREATE TABLE "DBA"." LogSQLErrorTable "
(
 "id"     int PRIMARY KEY NOT NULL,
 "name"     varchar(255) NOT NULL,
 "value"  timestamp NOT NULL
)

The following example logs the SQL error code, table name, and other synchronization information when a database error occurs during the download phase of synchronization.

CREATE PROCEDURE sp_hook_dbmlsync_download_sql_error()
BEGIN
 --
 -- get the next LogSQLErrorTable id
 --
   DECLARE nextid int;

 SELECT max(id)
  INTO nextid
  FROM LogSQLErrorTable;

 IF nextid is NULL THEN
  SET nextid = 0
 ELSE
  SET nextid = nextid +1
 END IF;

 INSERT INTO LogSQLErrorTable(id,name, value )
  SELECT nextid,#hook_dict.name, #hook_dict.value
  FROM #hook_dict;
END;


sp_hook_dbmlsync_download_table_begin

Function

Use this stored procedure to add custom actions immediately before each table is downloaded.

Rows in #hook_dict table
Name | Values | Description
Table name (in) | table name | The table to which operations are about to be applied.
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is called for each table immediately before downloaded operations are applied to that table. Actions of this procedure are committed or rolled back when the download stream is committed or rolled back.

See also
  • Synchronization event hook sequence
Examples

Assume you use the following table to log synchronization events on the remote database.

CREATE TABLE SyncLog
(
 "event_id"            integer NOT NULL DEFAULT autoincrement ,
   "event_name"        varchar(128) NOT NULL ,
   "ml_user"             varchar(128) NULL ,
   "event_time"          timestamp NULL,
   "table_name"          varchar(128) NULL ,
   "upsert_count"        varchar(128) NULL ,
   "delete_count"        varchar(128) NULL ,
   "exit_code"           integer NULL ,
   "status_retval"       varchar(128) NULL ,
   "pubs"                  varchar(128) NULL ,
   "sync_descr "         varchar(128) NULL ,
    PRIMARY KEY ("event_id"),
)

The following example logs the MobiLink user, table name, and current timestamp immediately before a table is downloaded.

CREATE PROCEDURE sp_hook_dbmlsync_download_table_begin()
BEGIN
    declare tbl varchar(255);

    -- load the table name from #hook_dict
  SELECT #hook_dict.value
   INTO tbl
   FROM #hook_dict
   WHERE #hook_dict.name = 'table name';

  INSERT INTO SyncLog (event_name, ml_user, table_name
    ,event_time)
   SELECT 'download_table_begin', #hook_dict.value, tbl
    ,current timestamp
   FROM #hook_dict
   WHERE name = 'MobiLink user' ;
END


sp_hook_dbmlsync_download_table_end

Function

Use this stored procedure to add custom actions immediately after each table is downloaded.

Rows in #hook_dict table
Name | Values | Description
Table name (in) | table name | The table to which operations have just been applied.
Delete count (in) | number of rows | The number of rows in this table deleted by the download stream.
Upsert count (in) | number of rows | The number of rows in this table updated or inserted by the download stream.
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is called immediately after all operations in the download stream for a table have been applied.

Actions of this procedure are committed or rolled back when the download stream is committed or rolled back.

See also
  • Synchronization event hook sequence
Examples

Assume you use the following table to log synchronization events on the remote database.

CREATE TABLE SyncLog
(
 "event_id"            integer NOT NULL DEFAULT autoincrement ,
   "event_name"        varchar(128) NOT NULL ,
   "ml_user"             varchar(128) NULL ,
   "event_time"          timestamp NULL,
   "table_name"          varchar(128) NULL ,
   "upsert_count"        varchar(128) NULL ,
   "delete_count"        varchar(128) NULL ,
   "exit_code"           integer NULL ,
   "status_retval"       varchar(128) NULL ,
   "pubs"                  varchar(128) NULL ,
   "sync_descr "         varchar(128) NULL ,
    PRIMARY KEY ("event_id"),
)

The following example logs the MobiLink user, the table name and the number of inserted or updated rows immediately after a table is downloaded.

CREATE PROCEDURE sp_hook_dbmlsync_download_table_end()
BEGIN
    -- declare variables
    declare tbl varchar(255);
    declare upsertCnt varchar(255);
    declare deleteCnt varchar(255);

    -- load the table name from #hook_dict
    SELECT #hook_dict.value
     INTO tbl
     FROM #hook_dict
     WHERE #hook_dict.name = 'table name';

    -- load the upsert count from #hook_dict
    SELECT #hook_dict.value
     INTO upsertCnt
     FROM #hook_dict
     WHERE #hook_dict.name = 'upsert count';

    -- load the delete count from #hook_dict
    SELECT #hook_dict.value
     INTO deleteCnt
     FROM #hook_dict
     WHERE #hook_dict.name = 'delete count';

    INSERT INTO SyncLog (event_name, ml_user, table_name,
      upsert_count, delete_count, event_time)
     SELECT 'download_table_end', #hook_dict.value, tbl,
      upsertCnt, deleteCnt, current timestamp
     FROM #hook_dict
     WHERE name = 'MobiLink user' ;
END


sp_hook_dbmlsync_end

Function

Use this stored procedure to add custom actions immediately before synchronization is complete.

Rows in #hook_dict table
Name | Values | Description
Restart (out) sync | download | none If set to sync, then dbmlsync retries the synchronization it just completed. The value sync replaces true, which is identical but is deprecated.

If set to none (the default), then dbmlsync shuts down or restarts according to its command line arguments. The value none replaces false, which is identical but is deprecated.

If set to download and the restartable download parameter is true, then dbmlsync attempts to restart the download that just failed.
Exit code (in) | number | If set to anything other than zero (the default), this represents a synchronization error.
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Upload status (in) committed | failed Specifies the status returned by the MobiLink synchronization server when dbmlsync attempted to verify receipt of the upload stream.

committed The upload stream was received by the MobiLink synchronization server, and committed.

failed The MobiLink synchronization server did not commit the upload stream.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Restartable download (in) | true|false | If true, the download for the current synchronization failed and can be restarted. If false, the download was successful or it cannot be restarted.
Restartable download size (in) | integer | When the restartable download parameter is true, this parameter indicates the number of bytes that were received before the download failed. When restartable download is false, this value is meaningless.
error hook user state (in) | integer | This value contains information about errors and can be sent from the hooks sp_hook_dbmlsync_all_error, sp_hook_dbmlsync_communication_error, sp_hook_dbmlsync_misc_error, or sp_hook_dbmlsync_sql_error.
Description

If a procedure of this name exists, it is called as the last event during synchronization.

Actions of this procedure are committed immediately after execution.

If an sp_hook_dbmlsync_end hook is defined so that the hook always sets the restart parameter to sync, and you specify multiple publications on the dbmlsync command line in the form -n pub1, -n pub2, etc., then dbmlsync repeatedly synchronizes the first publication and never synchronizes the second.

See also
  • Customizing the client synchronization process
  • Synchronization event hook sequence
  • Resuming failed downloads
Examples

In the following example the download is manually restarted if the download for the current synchronization failed and can be restarted.

CREATE PROCEDURE sp_hook_dbmlsync_end()
BEGIN
  -- Restart the download if the download for the current sync
  --  failed and can be restarted
  IF exists(SELECT * FROM #hook_dict
    WHERE name = 'restartable download' AND value='true')
      THEN
   UPDATE #hook_dict SET value ='download' WHERE name='restart';
  END IF;
END


sp_hook_dbmlsync_log_rescan

Function

Use this stored procedure to programmatically decide when a rescan is required.

Rows in #hook_dict table
Name | Values | Description
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Discarded storage (in) | number | The number of bytes of discarded memory after the last synchronization.
Rescan (in|out) | true | false | If set to True by the hook, dbmlsync performs a complete rescan before the next synchronization. On entry, this value is set to False.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

When more than one -n option is specified at the command line, dbmlsync may experience fragmentation which results in discarded memory. This hook allows you to decide if dbmlsync should rescan the database transaction log to recover memory.

When no other condition has been met that would force a rescan, this hook is called immediately after the sp_hook_dbmlsync_end hook.

See also
  • HoverRescanThreshold (hrt) extended option
Examples

The following example sets the rescan field in the #hook_dict table to TRUE if the discarded storage is greater than 1000 bytes.

CREATE PROCEDURE sp_hook_dbmlsync_log_rescan ()
BEGIN

 IF exists(SELECT * FROM #hook_dict
  WHERE name = 'Discarded storage' AND value>1000)
 THEN
  UPDATE #hook_dict SET value ='true' WHERE name='Rescan';
 END IF;

END


sp_hook_dbmlsync_logscan_begin

Function

Use this stored procedure to add custom actions immediately before the transaction log is scanned for upload.

Rows in #hook_dict table
Name | Values | Description
Starting log offset_n (in) | number | The log offset value where scanning is to begin. There is one value for each publication being uploaded. The numbering of n starts at zero.
Log scan retry (in) | true | false | If this is the first time the transaction log has been scanned for this synchronization, the value is false; otherwise it is true. The log is scanned twice when the MobiLink synchronization server and dbmlsync have different information about where the scanning should begin.
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is called immediately before dbmlsync scans the transaction log to assemble the upload stream.

Actions of this procedure are committed immediately after execution.

See also
  • Synchronization event hook sequence
Examples

Assume you use the following table to log synchronization events on the remote database.

CREATE TABLE SyncLog
(
 "event_id"            integer NOT NULL DEFAULT autoincrement ,
   "event_name"        varchar(128) NOT NULL ,
   "ml_user"             varchar(128) NULL ,
   "event_time"          timestamp NULL,
   "table_name"          varchar(128) NULL ,
   "upsert_count"        varchar(128) NULL ,
   "delete_count"        varchar(128) NULL ,
   "exit_code"           integer NULL ,
   "status_retval"       varchar(128) NULL ,
   "pubs"                  varchar(128) NULL ,
   "sync_descr "         varchar(128) NULL ,
    PRIMARY KEY ("event_id"),
)

The following example logs the MobiLink user and current timestamp immediately before the transaction log is scanned for upload.

CREATE PROCEDURE sp_hook_dbmlsync_logscan_begin ()
BEGIN
 -- log the synchronization event
 INSERT INTO SyncLog (event_nam
e, ml_user,event_time)
  SELECT 'logscan_begin', #hook_dict.value, current timestamp
  FROM #hook_dict
  WHERE name = 'MobiLink user' ;
END


sp_hook_dbmlsync_logscan_end

Function

Use this stored procedure to add custom actions immediately after the transaction log is scanned for upload.

Rows in #hook_dict table
Name | Values | Description
Ending log offset (in) | number | The log offset value where scanning ended.
Starting log offset_n (in) | number | The initial progress value for each subscription you synchronize. The n values correspond to those in Publication_n. For example, Starting log offset_1 is the offset for Publication_1.
Log scan retry (in) | true | false | If this is the first time the transaction log has been scanned for this synchronization, the value is false; otherwise it is true. The log is scanned twice when the MobiLink synchronization server and dbmlsync have different information about where the scanning should begin.
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is called immediately after dbmlsync has scanned the transaction log to assemble the upload stream.

Actions of this procedure are committed immediately after execution.

See also
  • Synchronization event hook sequence
Examples

Assume you use the following table to log synchronization events on the remote database.

CREATE TABLE SyncLog
(
 "event_id"            integer NOT NULL DEFAULT autoincrement ,
   "event_name"        varchar(128) NOT NULL ,
   "ml_user"             varchar(128) NULL ,
   "event_time"          timestamp NULL,
   "table_name"          varchar(128) NULL ,
   "upsert_count"        varchar(128) NULL ,
   "delete_count"        varchar(128) NULL ,
   "exit_code"           integer NULL ,
   "status_retval"       varchar(128) NULL ,
   "pubs"                  varchar(128) NULL ,
   "sync_descr "         varchar(128) NULL ,
    PRIMARY KEY ("event_id"),
)

The following example logs the MobiLink user and current timestamp immediately after the transaction log is scanned for upload. The #hook_dict log scan retry parameter indicates if the transaction log is scanned more than one time.

CREATE PROCEDURE sp_hook_dbmlsync_logscan_end ()
BEGIN

 declare scan_retry varchar(128);

 -- load the scan retry parameter from #hook_dict
 SELECT #hook_dict.value
  INTO scan_retry
  FROM #hook_dict
  WHERE #hook_dict.name = 'log scan retry';

 -- Determine if the log is being rescanned
 -- and log the synchronization event

 IF scan_retry='true' then
   INSERT INTO SyncLog (event_name, ml_user,event_time,sync_descr)
    SELECT 'logscan_end', #hook_dict.value, current timestamp,
     'Transaction log rescanned'
    FROM #hook_dict
    WHERE name = 'MobiLink user' ;
 ELSE
   INSERT INTO SyncLog (event_name, ml_user,event_time,sync_descr)
    SELECT 'logscan_end', #hook_dict.value, current timestamp,
     'Transaction log scanned normally'
    FROM #hook_dict
    WHERE name = 'MobiLink user' ;
 END IF;
END


sp_hook_dbmlsync_process_return_code

Function

Use this stored procedure to manage return codes.

Rows in #hook_dict table
Name | Values | Description
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Fatal error (in) | true | false | True when the hook is called because of an error that will cause dbmlsync to terminate.
Aborted synchronization (in) | true | false | True when the hook is called because of an abort request from the sp_hook_dbmlsync_abort hook.
Return code (in) | number | The return code from the most recent synchronization attempt. 0 indicates a successful synchronization. Any other value indicates that the synchronization failed. This value can be set by sp_hook_dbmlsync_abort when that hook is used to abort synchronization.
Last return code (in) | number | The value stored in the new return code row of the #hook_dict table the last time this hook was called, or 0 if this is the first call to the hook.
New return code (in|out) | number | The desired return code for the process. When dbmlsync exits, dblmsync's return code is the value stored in this row by the last call to the hook. The value must be -32768 to 32767.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

A dbmlsync session can run multiple synchronizations when you specify the -n option more than once on the command line, when you use scheduling, or when you use the restart parameter in sp_hook_dbmlsync_end. In these cases, if one or more of the synchronizations fail, the default return code does not indicate which failed. Use this hook to define the return code for the dbmlsync process based on the return codes from the synchronizations. This hook can also be used to log return codes.

Example

Suppose that you run dbmlsync to perform five synchronizations and you want the return code to indicate how many of the synchronizations failed, with a return code of 0 indicating that there were no failures, a return code of 1 indicating that one synchronization failed, and so on. You can achieve this by defining the sp_hook_dbmlsync_process_return_code hook as follows. In this case, if three synchronizations fail, the new return code is 3.

CREATE PROCEDURE sp_hook_dbmlsync_process_return_code()
BEGIN
   DECLARE   rc   integer;

   SELECT value INTO rc FROM #hook_dict WHERE name = 'return code';
   IF rc <> 0 THEN
      SELECT value INTO rc FROM #hook_dict WHERE name = 'last return code';
      UPDATE #hook_dict SET value = rc + 1 WHERE name = 'new return code';
   END IF;
END;
See also
  • Synchronization event hook sequence
  • sp_hook_dbmlsync_abort


sp_hook_dbmlsync_schema_upgrade

Function

Use this stored procedure to run a SQL script that revises your schema.

Rows in #hook_dict table
Name | Values | Description
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Script version | name of script version | The script version that you are synchronizing.
Drop hook (out) never | always | on success The values can be:

never - (the default) Do not drop the sp_hook_dbmlsync_schema_upgrade hook from the database.

always - After attempting to run the hook, ,drop the sp_hook_dbmlsync_schema_upgrade hook from the database.

on success - If the hook runs successfully, drop the sp_hook_dbmlsync_schema_upgrade hook from the database. On success is identical to always if the dbmlsync -eh option is used, or the dbmlsync extended option IgnoreHookErrors is set to true.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

This stored procedure is intended for making schema changes to deployed remote databases. Using this hook for schema upgrades ensures that all changes on the remote database are synchronized before the schema is upgraded, which is required to ensure that the database will continue to be able to synchronize. When this hook is being used you should not set the dbmlsync extended option LockTables to off (LockTables is on by default).

During any synchronization where the upload was applied successfully and acknowledged by MobiLink, this hook is called after the sp_hook_dbmlsync_download_end hook and before the sp_hook_dbmlsync_end hook. This hook is not called during download-only synchronization or when a file-based download is being created or applied.

Actions performed in this hook are committed immediately after the hook completes.

See also
  • Schema changes in remote databases
Examples

The following example uses the sp_hook_dbmlsync_schema_upgrade procedure to add a column to the Dealer table on the remote database. If the upgrade is successful the sp_hook_dbmlsync_schema_upgrade hook is dropped.

CREATE PROCEDURE sp_hook_dbmlsync_schema_upgrade()
BEGIN
 -- Upgrade the schema of the Dealer table
 -- here we add a column
 ALTER TABLE Dealer
  ADD dealer_description varchar(128);

 -- if the schema upgrade is successful, drop this hook
 UPDATE #hook_dict
  SET value = 'on success'
  WHERE name = 'drop hook';
END


sp_hook_dbmlsync_set_extended_options

Function

Use this stored procedure to programmatically customize the behavior of an upcoming synchronization by specifying extended options to be applied to that synchronization.

Rows in #hook_dict table
Name | Values | Description
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Extended options (out) | opt=val;... | Extended options to add for the next synchronization.
Description

If a procedure of this name exists, it is called immediately before the sp_hook_dbmlsync_delay hook.

Extended options specified by this hook apply only to the synchronization identified by the publication and MobiLink user entries, and they apply only until the next time the hook is called for the same synchronization.

Scheduling options may not be specified using this hook.

Actions of this procedure are committed immediately after execution.

See also
  • Synchronization event hook sequence
  • dbmlsync extended options
  • Priority order for extended options and connection parameters
Examples

The following example uses sp_hook_dbmlsync_set_extended_options to specify the SendColumnNames extended option. The extended option is only applied if pub1 is synchronizing.

CREATE PROCEDURE sp_hook_dbmlsync_set_extended_options ()
BEGIN
 IF exists(SELECT * FROM #hook_dict
  WHERE name LIKE 'publication_%' AND value='pub1')
 THEN
   -- specify the sendcolumnnames=on extended option
   UPDATE #hook_dict
          SET value = 'SendColumnNames=on'
    WHERE name = 'extended options';
 END IF;
END


sp_hook_dbmlsync_upload_begin

Function

Use this stored procedure to add custom actions immediately before the transmission of the upload.

Rows in #hook_dict table
Name | Values | Description
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Description

If a procedure of this name exists, it is called immediately before dbmlsync sends the upload stream.

Actions of this procedure are committed immediately after execution.

See also
  • Synchronization event hook sequence
Examples

Assume you use the following table to log synchronization events on the remote database.

CREATE TABLE SyncLog
(
 "event_id"            integer NOT NULL DEFAULT autoincrement ,
   "event_name"        varchar(128) NOT NULL ,
   "ml_user"             varchar(128) NULL ,
   "event_time"          timestamp NULL,
   "table_name"          varchar(128) NULL ,
   "upsert_count"        varchar(128) NULL ,
   "delete_count"        varchar(128) NULL ,
   "exit_code"           integer NULL ,
   "status_retval"       varchar(128) NULL ,
   "pubs"                  varchar(128) NULL ,
   "sync_descr "         varchar(128) NULL ,
    PRIMARY KEY ("event_id"),
)

The following example logs the MobiLink user and current timestamp immediately before the transmission of the upload.

CREATE PROCEDURE sp_hook_dbmlsync_upload_begin ()
BEGIN
 INSERT INTO SyncLog (event_name, ml_user,event_time)
  SELECT 'upload_begin', #hook_dict.value, current timestamp
  FROM #hook_dict
  WHERE name = 'MobiLink user';
END


sp_hook_dbmlsync_upload_end

Function

Use this stored procedure to add custom actions after dbmlsync has verified receipt of the upload stream by the MobiLink synchronization server.

Rows in #hook_dict table
Name | Values | Description
Failure cause (in) | See range of values in Description, below | The cause of failure of an upload. For more information, see Description.
Upload status (in) retry | committed | failed | unknown Specifies the status returned by the MobiLink synchronization server when dbmlsync attempted to verify receipt of the upload stream.

retry The MobiLink synchronization server and dbmlsync had different values for the log offset from which the upload stream should start. The upload stream was not committed by the MobiLink synchronization server. The dbmlsync utility will attempt to send another upload stream starting from a new log offset.

committed The upload stream was received by the MobiLink synchronization server and committed.

failed The MobiLink synchronization server did not commit the upload stream.

unknown The MobiLink synchronization server was started with the -tu option, causing transaction-level uploads. For each transaction that is uploaded, the sp_hook_dbmlsync_upload_begin and sp_hook_dbmlsync_upload_end hooks are called and the upload status value is unknown each time except the last one.
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
Script version (in) | script version name | The MobiLink script version to be used for the synchronization.
Authentication value (in) | value | This value is generated by the authenticate_user, authenticate_user_hashed, or authenticate_parameters script on the server. The value is an empty string when the upload status is unknown or when the upload_end hook is called after an upload is resent because of a conflict between the log offsets stored in the remote and consolidated databases.
Description

If a procedure of this name exists, it is called immediately after dbmlsync has sent the upload stream and received confirmation of it from the MobiLink synchronization server.

Actions of this procedure are committed immediately after execution.

The range of possible parameter values for the failure cause row in the #hook_dict table includes:

  • UPLD_ERR_COMMUNICATIONS_FAILURE A communication error occurred.

  • UPLD_ERR_LOG_OFFSET_MISMATCH The upload failed because of conflict between log offset stored on the remote and consolidated databases.

  • UPLD_ERR_GENERAL_FAILURE The upload failed for an unknown reason.

  • UPLD_ERR_INVALID_USERID_OR_PASSWORD The user ID or password was incorrect.

  • UPLD_ERR_USERID_OR_PASSWORD_EXPIRED The user ID or password expired.

  • UPLD_ERR_USERID_ALREADY_IN_USE The user ID was already in use.

  • UPLD_ERR_DOWNLOAD_NOT_AVAILABLE The upload was committed on the consolidated but an error occurred that prevented MobiLink from generating a download stream.

  • UPLD_ERR_PROTOCOL_MISMATCH Dbmlsync received unexpected data from the MobiLink synchronization server.

  • UPLD_ERR_SQLCODE_n Here, n is an integer. A SQL error occurred in the consolidated database. The integer specified is the SQLCODE for the error encountered.

See also
  • Synchronization event hook sequence
Examples

Assume you use the following table to log synchronization events on the remote database.

CREATE TABLE SyncLog
(
 "event_id"            integer NOT NULL DEFAULT autoincrement ,
   "event_name"        varchar(128) NOT NULL ,
   "ml_user"             varchar(128) NULL ,
   "event_time"          timestamp NULL,
   "table_name"          varchar(128) NULL ,
   "upsert_count"        varchar(128) NULL ,
   "delete_count"        varchar(128) NULL ,
   "exit_code"           integer NULL ,
   "status_retval"       varchar(128) NULL ,
   "pubs"                  varchar(128) NULL ,
   "sync_descr "         varchar(128) NULL ,
    PRIMARY KEY ("event_id"),
)

The following example logs the MobiLink user and current timestamp after dbmlsync verifies that the MobiLink Synchronization server has received the upload stream.

CREATE PROCEDURE sp_hook_dbmlsync_upload_end ()
BEGIN

 declare status_return_value varchar(255);

 -- store status_return_value
 SELECT #hook_dict.value
  INTO status_return_value
  FROM #hook_dict
  WHERE #hook_dict.name = 'upload status';

   INSERT INTO SyncLog (event_name, ml_user,
   status_retval, event_time)
  SELECT 'upload_end', #hook_dict.value,
   status_return_value, current timestamp
  FROM #hook_dict
  WHERE name = 'MobiLink user';
END


sp_hook_dbmlsync_validate_download_file

Function

Use this hook to implement custom logic to decide if a download file can be applied to the remote database.

Rows in #hook_dict table
Name | Values | Description
Publication_n (in) | publication name | The publications being synchronized, where n is an integer. There is one publication_n entry for each publication being uploaded. The n in publication_n and generation number_n match. The numbering of n starts at zero.
MobiLink user (in) | MobiLink user name | The MobiLink user for which you are synchronizing.
File last download time (in) |  | The download file's last download time. (The download file contains all rows that were changed between its last download time and its next last download time.)
File next last download time (in) |  | The download file's next last download time. (The download file contains all rows that were changed between its last download time and its next last download time.)
File creation time (in) |  | The time when the download file was created.
File generation number_n (in) | number | The generation numbers from the download file. There is one file generation number_n for each publication_n entry. The n in publication_n and generation number_n match. The numbering of n starts at zero.
User data (in) | string | The string specified with the dbmlsync -be option when the download file was created.
Apply file (in|out) | True|False | If true (the default), the download file will be applied only if it passes dbmlsync's other validation checks. If false, the download file will not be applied to the remote database.
Check generation number (in|out) | True|False | If true (the default), dbmlsync validates generation numbers. If the generation numbers in the download file do not match those in the remote database, dbmlsync does not apply the download file. If false, dbmlsync does not check generation numbers.
Setting generation number (in) | true | false | True if the -bg switch was used when the download file was created. If -bg was used, the generation numbers on the remote database are updated from the download file and normal generation number checks are not performed.
Description

Use this stored procedure to implement custom checks to decide if a download file can be applied.

If you want to compare the generation numbers or timestamps contained in the file with those stored in the remote database, they can be queried from the SYSSYNC and SYSPUBLICATION tables.

This hook is called when the -ba option is specified. It is called after the sp_hook_dbmlsync_upload_end hook and before the sp_hook_dbmlsync_download_begin hook.

The actions of this hook are committed immediately after it completes.

See also
  • -be option
  • -bg option
  • File-Based Downloads
Examples

The following example prevents application of download files that don't contain the user string 'sales manager data'.

CREATE PROCEDURE sp_hook_dbmlsync_validate_download_file ()
BEGIN
  IF NOT exists(SELECT * FROM #hook_dict
   WHERE name = 'User data' AND value='sales manager data')
  THEN
    UPDATE #hook_dict
            SET value = 'false' WHERE name = 'Apply file';
  END IF;
END


Dbmlsync Integration Component

About this chapter

This chapter describes how to use the Dbmlsync Integration Component. The Dbmlsync Integration Component helps you customize your Adaptive Server Anywhere client applications.

Introduction
Setting up the Dbmlsync Integration Component
Dbmlsync Integration Component methods
Dbmlsync Integration Component properties
Dbmlsync Integration Component events
IRowTransferData interface


Introduction

The Dbmlsync Integration Component is useful for adding synchronization to your applications. It provides a set of properties, events, and methods to regulate the behavior of Adaptive Server Anywhere clients.

The Dbmlsync Integration Component is available in two forms, both of which expose the same properties, events and methods:

  • A visual component that provides an easy way to integrate the standard dbmlsync user interface into your applications.

  • A non-visual component that allows you to access the component's functionality with no user interface or with a custom user interface that you create yourself.

Using the Dbmlsync Integration Component, your application can initiate synchronization, receive information about the progress of a synchronization, and implement special processing based on synchronization events.

As an alternative to the Dbmlsync Integration Component, you can use the a_sync_db structure in the database tools library provided with Adaptive Server Anywhere.

For more information about a_sync_db, see a_sync_db structure.

For more information about Adaptive Server Anywhere clients, see MobiLink synchronization client.

Supported platforms


Supported platforms

You can use the Dbmlsync Integration Component on all MobiLink supported Windows operating systems, including Windows CE versions supporting ActiveX.

Supported development environments include Microsoft Visual Basic 6.0, eMbedded Visual Basic, and Visual Studio .NET.


Setting up the Dbmlsync Integration Component

The Dbmlsync Integration Component can be used in a wide variety of programming environments. You should consult the documentation in your programming environment for information about how to set it up. Following are the procedures for setting up the integration component in Windows form applications and console applications.

Windows form applications
toggle To set up the Dbmlsync Integration Component in a Windows application

  1. Add a reference to the component.

    • For the visual component, use dbmlsynccomg.dll, which is located in the win32 subdirectory of your SQL Anywhere installation. Add it to the development environment toolbox.

    • For the non-visual component, use dbmlsynccom.dll, which is located in the win32 subdirectory of your SQL Anywhere installation.

  2. Create a component instance.

    • For the visual component, use the toolbox to drag and drop an instance on the form.

    • For the non-visual component, declare a global variable and create an instance in your initialization code.

      • For example, if you are using Visual Basic .NET, enter the following as a global variable declaration:

        Dim WithEvents dbmlsync1 As DbmlsyncCOM.Dbmlsync

        To create an instance, enter:

        dbmlsync1 = New DbmlsyncCOM.Dbmlsync

      • For example, if you are using C#, enter the following as a global variable declaration:

        private DbmlsyncCOM.Dbmlsync dbmlsync1;

        To create an instance, enter:

        dbmlsync1 = new DbmlsyncCOM.Dbmlsync();

        Note: for C# you must create the instance prior to assigning delegates for dbmlsync events (step 3 of this procedure).

  3. Add functions to handle synchronization events.

    • For example, if you are using Visual Basic .NET, use the Handles keyword in your function prototype.

      Private Sub dbmlsync1_ProgressMessage(ByVal msg As String)
Handles dbmlsync1.ProgressMessage
    lblProgressMessage.Text = msg
End Sub

    • If you are using C#, write an event handler function.

      private void dbmlsync1_ProgressMessage(string msg)
{
    lblProgressMessage.Text = msg;
}

      In your C# initialization code, use delegates to specify the event handler function for a dbmlsync event. The following example assigns dbmlsync1_ProgressMessage, to handle the dbmlsync ProgressMessage event.

      dbmlsync1.ProgressMessage +=
new DbmlsyncCOM._IDbmlsyncEvents_ProgressMessageEventHandler(dbmlsync1_ProgressMessage);

    For more information about events, see Dbmlsync Integration Component events.

  4. Set properties.

    The following example sets the UploadEventsEnabled property to true. This enables the UploadRow event:

    dbmlsync1.UploadEventsEnabled = True

    For more information about the UploadRow event, see UploadRow event.

    For more information about properties, see Dbmlsync Integration Component properties.

  5. Use the Run method to begin one or more synchronizations. For example,

    dbmlsync1.Run("-c eng=rem1;uid=dba;pwd=sql")

    For more information about the Run method, see Run method.

Console applications

Console applications can use the non-visual component only.

The fully qualified name of the Dbmlsync Integration Component is DbmlsyncCOM.Dbmlsync.

A console application that uses the non-visual Dbmlsync Integration Component must pump the Windows message queue. For example, with .NET applications you must use the following methods in the System.Windows.Application namespace:

System.Windows.Application.Run() Starts a standard application message loop on the current thread.

System.Windows.Application.Exit() Requests all message pumps to terminate and then closes all application windows.

toggle To set up the Dbmlsync Integration Component in a console application (Visual Basic.NET)

  1. Add a reference to System.Windows.Forms.dll.

  2. Add a reference to the non-visual component, dbmlsynccom.dll, located in the win32 subdirectory of your SQL Anywhere installation.

  3. Create an instance of the Dbmlsync Integration Component.

    • Enter the following as a global variable declaration:

      Dim WithEvents dbmlsync1 As DbmlsyncCOM.Dbmlsync

    • To create a component instance, enter:

      dbmlsync1 = New DbmlsyncCOM.Dbmlsync

  4. Set properties.

    The following example sets the UploadEventsEnabled property to true. This enables the UploadRow event:

    dbmlsync1.UploadEventsEnabled = True

    For more information about properties, see Dbmlsync Integration Component properties.

    For more information about the UploadRow event, see UploadRow event.

  5. Use the Run method to begin one or more synchronizations. For example,

    dbmlsync1.Run("-c eng=rem1;uid=dba;pwd=sql")

    For more information about the Run method, see Run method.

  6. Use System.Windows.Application Run method to enable pumping of the Windows message queue:

    System.Windows.Forms.Application.Run()

  7. Add logic to handle synchronization events.

    For more information about events, see Dbmlsync Integration Component events.

  8. Use the System.Windows.Application Exit method to request all message pumps to terminate:

    System.Windows.Application.Exit()


Dbmlsync Integration Component methods

The following are methods implemented by the DbmlsyncCOM.Dbmlsync class.


Run method

Function

Begins one or more synchronizations using dbmlsync command line options.

Syntax

Run( ByVal cmdLine As String )
Member of DbmlsyncCOM.Dbmlsync

Parameters

cmdLine A string specifying dbmlsync options.

Description

For a list of options, see dbmlsync options.

The cmdLine parameter should contain the same options you would use if you were performing a synchronization with the dbmlsync command line utility. For example, running dbmlsync with the command line

dbmlsync -c uid=dba;pwd=sql

is equivalent to the following Run method invocation

dbmlsync1.Run "-c uid=dba;pwd=sql"
Example

The following example initiates a synchronization for a remote database called remote1.

dbmlsync1.Run "-c eng=remote1;uid=dba;pwd=sql"


Stop method

Function

Requests active synchronizations to terminate.

Syntax

Stop( )
Member of DbmlsyncCOM.Dbmlsync

Description

The Stop method issues a request to terminate any active synchronizations. It returns immediately.

The stop button built in to the visual Dbmlsync Integration Component automatically invokes this method.

Example

The following example stops synchronizations being run by the Dbmlsync Integration Component instance dbmlsync1.

dbmlsync1.Stop


Dbmlsync Integration Component properties

Dbmlsync Integration Component properties let you customize the behavior of the component and examine the state of a running synchronization.

Path property
UploadEventsEnabled property
DownloadEventsEnabled property
ErrorMessageEnabled property
WarningMessageEnabled property
InfoMessageEnabled property
DetailedInfoMessageEnabled property
UseVB6Types property
ExitCode property
EventChannelSize property
DispatchChannelSize property


Path property

Function

Specifies the location of dbmlsync.exe.

Syntax

Public Property Path( ) As String
Member of DbmlsyncCOM.Dbmlsync

Description

You do not need to set this property if dbmlsync.exe is located in a directory specified by the Windows PATH environment variable.

Example

The following example sets the path of a Dbmlsync Integration Component instance.

dbmlsync1.Path = "c:\program files\sybase\sql anywhere 9\win32"


UploadEventsEnabled property

Function

Enables the UploadRow event.

Syntax

Public Property UploadEventsEnabled() As Boolean
Member of DbmlsyncCOM.Dbmlsync

Description

If you handle the UploadRow event, you should set this property to true. The default is false, which disables the UploadRow event.

For more information about the UploadRow event, see UploadRow event.

Example

The following example sets UploadEventsEnabled to true:

dbmlsync1.UploadEventsEnabled = True


DownloadEventsEnabled property

Function

Enables the DownloadRow event.

Syntax

Public Property DownloadEventsEnabled( ) As Boolean
Member of DbmlsyncCOM.Dbmlsync

Description

If you handle the DownloadRow event, you should set this property to true. The default is false, which disables the DownloadRow event.

For more information about the DownloadRow event, see DownloadRow event.

Example

The following example sets DownloadEventsEnabled to true:

dbmlsync1.DownloadEventsEnabled = True


ErrorMessageEnabled property

Function

Prevents the Message event from being called for messages of type MsgError.

Syntax

Public Property ErrorMessageEnabled( ) As Boolean
Member of DbmlsyncCOM.Dbmlsync

Description

If you do not handle error information in the Message event, you should set this property to false to improve performance. The default true, which enables messages of type MsgError to trigger the Message event.

For more information about the Message event, see Message event.

Example

The following example sets ErrorMessageEnabled to false:

dbmlsync1.ErrorMessageEnabled = False


WarningMessageEnabled property

Function

Prevents the Message event from being called for messages of type MsgWarning.

Syntax

Public Property WarningMessageEnabled( ) As Boolean
Member of DbmlsyncCOM.Dbmlsync

Description

If you do not handle warning information in the Message event, you should set this property to false to improve performance. The default is true, which enables messages of type MsgWarning to trigger the Message event.

For more information about the Message event, see Message event.

Example

The following example sets WarningMessageEnabled to false:

dbmlsync1.WarningMessageEnabled = False


InfoMessageEnabled property

Function

Prevents the Message event from being called for messages of type MsgInfo.

Syntax

Public Property InfoMessageEnabled( ) As Boolean
Member of DbmlsyncCOM.Dbmlsync

Description

If you do not handle general progress information in the Message event, you should set this property to false to improve performance. The default is true, which enables messages of type MsgInfo to trigger the Message event.

For more information about the Message event, see Message event.

Example

The following example sets InfoMessageEnabled to false:

dbmlsync1.InfoMessageEnabled = False


DetailedInfoMessageEnabled property

Function

Prevents the Message event from being called for messages of type MsgDetailedInfo.

Syntax

Public Property DetailedInfoMessageEnabled( ) As Boolean
Member of DbmlsyncCOM.Dbmlsync

Description

If you do not handle detailed progress information in the Message event, you should set this property to false to improve performance. The default is true, which enables messages of type MsgDetailedInfo to trigger the Message event.

For more information about the Message event, see Message event.

Example

The following example sets DetailedInfoMessageEnabled to false:

dbmlsync1.DetailedInfoMessageEnabled = False


UseVB6Types property

Function

If you are using Visual Basic 6, set this property to true to simplify handling of row data returned by the UploadRow and DownloadRow events.

Syntax

Public Property DetailedInfoMessageEnabled( ) As Boolean
Member of DbmlsyncCOM.Dbmlsync

Description

Visual Basic 6 does not support unsigned 32 bit values and any 64 bit values. Data of these types may be returned by the ColumnValue property of an IRowTransferData object. When UseVB6Types is set to true, data of these types is converted to other types supported by Visual Basic 6 for easier processing. Uint32 values are converted to double; 64 bit values are converted to strings.

For more information about the IRowTransferData interface, see IRowTransferData interface.

For more information about the UploadRow event, see UploadRow event.

For more information about the DownloadRow event, see DownloadRow event.

Example

The following example enables data type coercion for a Dbmlsync Integration Component instance used in Visual Basic 6.0:

dbmlsync1.UseVB6Types = True


ExitCode property

Function

Returns the exit code from synchronizations started by the most recent Run method invocation.

Syntax

Public Property ExitCode( ) As Integer
Member of DbmlsyncCOM.Dbmlsync

Description

The ExitCode property returns the exit code for the synchronizations started by the last Run method invocation. 0 indicates successful synchronizations. Any other value indicates that a synchronization failed.

Note:
Retrieving the value of this property before the DoneExecution event is triggered may result in a meaningless exit code value.
Example

The following example displays the exit code from the most recent synchronization attempt when the DoneExecution event is triggered.

Private Sub dbmlsync1_DoneExecution() Handles dbmlsync1.DoneExecution
        MsgBox(dbmlsync1.ExitCode)
    End Sub


EventChannelSize property

Function

Specifies the size of an internal buffer used for processing method calls.

Syntax

Public Property EventChannelSize( ) As Integer
Member of DbmlsyncCOM.Dbmlsync

Description

Most users will never have to change this property.


DispatchChannelSize property

Function

Specifies the size of an internal buffer used for processing event information.

Syntax

Public Property DispatchChannelSize( ) As Integer
Member of DbmlsyncCOM.Dbmlsync

Description

Most users will never have to change this property.


Dbmlsync Integration Component events

Events provide a mechanism for client applications to receive and act on information about the progress of a synchronization.

BeginDownload event
BeginLogScan event
BeginSynchronization event
BeginUpload event
ConnectMobilink event
DisconnectMobilink event
DoneExecution event
DownloadRow event
EndDownload event
EndLogScan event
EndSynchronization event
EndUpload event
Message event
ProgressIndex event
ProgressMessage event
SetTitle event
UploadAck event
UploadRow event
WaitingForUploadAck event


BeginDownload event

The BeginDownload event is triggered at the beginning of the download stage of a synchronization.

Syntax

Public Event BeginDownload( )
Member of DbmlsyncCOM.Dbmlsync

Description

Use this event to add custom actions at the beginning of the download stage of a synchronization.

Example

The following Visual Basic .NET example outputs a message when the BeginDownload event is triggered.

Private Sub dbmlsync1_BeginDownload()
Handles dbmlsync1.BeginDownload

        MsgBox("Beginning Download")

End Sub


BeginLogScan event

The BeginLogScan event is triggered immediately before dbmlsync scans the transaction log to assemble the upload stream.

Syntax

Public Event BeginLogScan( ByVal rescanLog As Boolean )
Member of DbmlsyncCOM.Dbmlsync

Parameters

rescanLog If this is the first time the transaction log has been scanned for this synchronization, the value is false; otherwise it is true. The log is scanned twice when the MobiLink synchronization server and dbmlsync have different information about where scanning should begin.

Description

Use this event to add custom actions immediately before the transaction log is scanned for upload.

Example

The following Visual Basic .NET example outputs a message when the BeginLogScan event is triggered.

Private Sub dbmlsync1_BeginLogScan(
 ByVal rescanLog As Boolean
)
Handles dbmlsync1.BeginLogScan

        MsgBox("Begin Log Scan")

End Sub


BeginSynchronization event

The BeginSynchronization event is triggered at the beginning of each synchronization.

Syntax

Public Event BeginSynchronization( _
ByVal userName As String, _
ByVal pubNames As String _
)
Member of DbmlsyncCOM.Dbmlsync

Parameters

userName The MobiLink user for which you are synchronizing.

pubNames The publication being synchronized. If there is more than one publication this is a comma-separated list.

Description

Use this event to add custom actions at the beginning of a synchronization.

Example

The following Visual Basic .NET example outputs a message when the BeginSynchronization event is triggered. The message outputs the user and publication names.

Private Sub dbmlsync1_BeginSynchronization(
 ByVal userName As String,
 ByVal pubNames As String
)
Handles dbmlsync1.BeginSynchronization

       MsgBox("Beginning synchronization for: " + userName _
     + " publication: " + pubNames)

End Sub


BeginUpload event

The BeginUpload event is triggered immediately before the transmission of the upload.

Syntax

Public Event BeginUpload( )
Member of DbmlsyncCOM.Dbmlsync

Description

Use this event to add custom actions immediately before the transmission of the upload to the MobiLink synchronization server.

Example

The following Visual Basic .NET example outputs a message when the BeginUpload event is triggered.

Private Sub dbmlsync1_BeginUpload()
Handles dbmlsync1.BeginUpload

        MsgBox("Begin Upload")

End Sub


ConnectMobilink event

The ConnectMobilink event is triggered immediately before the component connects to the MobiLink synchronization server.

Syntax

Public Event ConnectMobilink( )
Member of DbmlsyncCOM.Dbmlsync

Description

Use this event to add custom actions immediately before the remote database connects to the MobiLink synchronization server. At this stage, dbmlsync has generated the upload stream.

The ConnectMobiLink event occurs after the BeginSynchronization event.

Example

The following Visual Basic .NET example outputs a message when the ConnectMobilink event is triggered.

Private Sub dbmlsync1_ConnectMobilink()
Handles dbmlsync1.ConnectMobilink

        MsgBox("Connecting to the MobiLink synchronization server")

End Sub


DisconnectMobilink event

The DisconnectMobilink event is triggered immediately after the component disconnects from the MobiLink synchronization server.

Syntax

Public Event DisconnectMobilink( )
Member of DbmlsyncCOM.Dbmlsync

Description

Use this event to add custom actions immediately after the remote database disconnects from the MobiLink synchronization server.

Example

The following Visual Basic .NET example outputs a message when the DisconnectMobilink event is triggered.

Private Sub dbmlsync1_DisconnectMobilink()
Handles dbmlsync1.DisconnectMobilink

        MsgBox("Disconnected from the MobiLink synchronization server")

End Sub


DoneExecution event

The DoneExecution event is triggered when all synchronizations started by a Run method invocation have completed.

Syntax

Public Event DoneExecution( )
Member of DbmlsyncCOM.Dbmlsync

Description

Use this event to add custom actions when all synchronizations started by a Run method invocation have completed.

Example

Using the ExitCode property, the following Visual Basic .NET example outputs the exit code from the synchronizations started by the last Run method invocation:

Private Sub dbmlsync1_DoneExecution()
Handles dbmlsync1.DoneExecution

        MsgBox(dbmlsync1.ExitCode)

End Sub


DownloadRow event

The DownloadRow event is triggered when a row is downloaded from the MobiLink synchronization server.

Syntax

Public Event DownloadRow(
ByVal rowData As DbmlsyncCOM.IRowTransferData
)
Member of DbmlsyncCOM.Dbmlsync

Parameters

rowData An IRowTransferData object containing detailed information about the downloaded row.

For more information about the IRowTransferData interface, see IRowTransferData interface.

Description

Use this event to examine rows being downloaded from the MobiLink synchronization server.

To enable the DownloadRow event, use the DownloadEventsEnabled property.

For more information, see DownloadEventsEnabled property.

When a delete operation is encountered in the download row event, only primary key column values are available.

Example

The following Visual Basic .NET example iterates through all the columns for a row in the DownloadRow event. It determines if a column value is null, and outputs column names and values.

Private Sub dbmlsync1_DownloadRow(
 ByVal rowData As DbmlsyncCOM.IRowTransferData
)
Handles dbmlsync1.DownloadRow

Dim liX As Integer
For liX = 0 To rowData.ColumnCount - 1
    If VarType(rowData.ColumnValue(liX)) <> VariantType.Null Then
        ' output the non-null column value
        MsgBox("Column " + CStr(liX) + ": " + rowData.ColumnName(liX) + _
        ", " + CStr(rowData.ColumnValue(liX)))
    Else
        ' output 'NULL' for the column value
        MsgBox("Column " + CStr(liX) + ": " + rowData.ColumnName(liX) + _
        ", " + "NULL")
    End If
Next liX

End Sub


EndDownload event

The EndDownload event is triggered at the end of the download stage of the synchronization process.

Syntax

Public Event EndDownload(
long upsertRows,
long deleteRows
)
Member of DbmlsyncCOM.Dbmlsync

Parameters

upsertRows Indicates the number of rows updated or inserted by the download.

deleteRows Indicates the number of rows deleted by the download.

Description

Use this event to add custom actions at the end of the download stage of synchronization.

Example

The following Visual Basic .NET example outputs a message and the number of inserted, updated, and deleted rows when the EndDownload event is triggered.

Private Sub dbmlsync1_EndDownload(
 ByVal upsertRows As Integer,
 ByVal deleteRows As Integer
)
Handles dbmlsync1.EndDownload

    MsgBox("Download complete." + _
     CStr(upsertRows) + "Rows updated or inserted" + _
     CStr(deleteRows) + "Rows deleted")

End Sub


EndLogScan event

The EndLogScan event is triggered immediately after the transaction log is scanned for upload.

Syntax

Public Event EndLogScan( )
Member of DbmlsyncCOM.Dbmlsync

Description

Use this event to add custom actions immediately after the transaction log is scanned for upload.

Example

The following Visual Basic .NET example outputs a message when the EndLogScan event is triggered.

Private Sub dbmlsync1_EndLogScan()
Handles dbmlsync1.EndLogScan

        MsgBox("Scan of transaction log complete...")

End Sub


EndSynchronization event

The EndSynchronization event is triggered when a synchronization is complete.

Syntax

Public Event EndSynchronization(
ByVal exitCode As Integer,
ByRef restart As Boolean
)
Member of DbmlsyncCOM.Dbmlsync

Parameters

exitCode If set to anything other than zero, this indicates that a synchronization error occurred.

restart This value is set to false when the event is called. If the event changes its value to true, dbmlsync will restart the synchronization.

Description

Use this event to add custom actions when a synchronization is complete.

Example

The following Visual Basic .NET example uses the EndSynchronization event to restart up to five failed synchronization attempts. If all restart attempts failed, the message "All restart attempts failed" is output, along with the exit code. If a synchronization is successful, the message "Synchronization succeeded " is output, along with the exit code.

' Global variable for the number of restarts
Dim numberOfRestarts As Integer

Private Sub dbmlsync1_EndSynchronization(
 ByVal ExitCode As Integer,
 ByRef restart As Boolean
)
Handles dbmlsync1.EndSynchronization

    If numberOfRestarts < 5 Then
        MsgBox("Restart Number: " + CStr(numberOfRestarts + 1))
        If ExitCode <> 0 Then
            ' restart the failed synchronization
            restart = True
            numberOfRestarts = numberOfRestarts + 1
        Else
            ' the last synchronization succeeded
            MsgBox("Synchronization succeeded. " + _
              "Exit code: " + CStr(ExitCode))
        End If
    Else
        MsgBox("All restart attempts failed. " + _
             "Exit code: " + CStr(ExitCode))
    End If

End Sub


EndUpload event

The EndUpload event is triggered immediately after transmission of the upload stream to the MobiLink synchronization server.

Syntax

Public Event EndUpload( )
Member of DbmlsyncCOM.Dbmlsync

Description

Use this event to add custom actions immediately after transmission of the upload stream from dbmlsync to the MobiLink synchronization server.

Example

The following Visual Basic .NET example outputs a message when the EndUpload event is triggered.

Private Sub dbmlsync1_EndUpload()
Handles dbmlsync1.EndUpload

    MsgBox("End Upload")

End Sub


Message event

The Message event is triggered when dbmlsync logs information.

Syntax

Public Event Message(_
ByVal msgClass As DbmlsyncCOM.MessageClass, _
ByVal msgID As Integer, ByVal msg As String_
)
Member of DbmlsyncCOM.Dbmlsync

Parameters

msgClass indicates the severity of the message. Values can be:

  • MsgInfo A message containing progress information about the synchronization.

  • MsgDetailedInfo Like MsgInfo, but containing more detailed information.

  • MsgWarning A message indicating a potential problem but one that will not prevent successful synchronization.

  • MsgError A message indicating a problem that will prevent successful synchronization.

msgID A unique identifier for the message. If msgID is zero, the message does not have a unique identifier.

msg The text of the message.

Description

Use this event to receive information logged by dbmlsync.

Example

The following Visual Basic .NET example adds messages logged by dbmlsync to a listbox control.

Private Sub dbmlsync1_Message(
 ByVal msgClass As DbmlsyncCOM.MessageClass,
 ByVal msgId As Integer, ByVal msg As String
)
Handles dbmlsync1.Message

    Select Case msgClass
        Case DbmlsyncCOM.MessageClass.MsgError
            lstMessages.Items.Add("Error: " + msg)
        Case DbmlsyncCOM.MessageClass.MsgWarning
            lstMessages.Items.Add("Warning: " + msg)
        Case DbmlsyncCOM.MessageClass.MsgInfo
            lstMessages.Items.Add("Info: " + msg)
    End Select

End Sub


ProgressIndex event

The ProgressIndex event is triggered when dbmlsync updates its progress bar.

Syntax

Public Event ProgressIndex(_
ByVal index As Integer, _
ByVal max As Integer _
)
Member of DbmlsyncCOM.Dbmlsync

Parameters

index An integer representing the progress of the synchronization.

max The maximum progress value. If this value is zero, the maximum value has not changed since the last time the event was fired.

Description

Use this event to update a progress indicator such as a progress bar.

Example

The following Visual Basic .NET example updates a progress bar control based on the Index value. The maximum index value is set at the beginning of the synchronization.

Private Sub dbmlsync1_ProgressIndex(
 ByVal index As Integer,
 ByVal max As Integer
)
Handles dbmlsync1.ProgressIndex

    If max <> 0 Then
        ProgressBar1.Maximum = max
    End If
    ProgressBar1.Value = index

End Sub


ProgressMessage event

The ProgressMessage event is triggered when synchronization progress information changes.

Syntax

Public Event ProgressMessage( ByVal msg As String )
Member of DbmlsyncCOM.Dbmlsync

Parameters

msg The new progress string.

Description

Use this event to receive the string normally displayed above the dbmlsync progress bar.

Example

The following Visual Basic .NET example sets the value of a progress label when the ProgressMessage event is triggered.

Private Sub dbmlsync1_ProgressMessage(
 ByVal msg As String
)
Handles dbmlsync1.ProgressMessage

    lblProgressMessage.Text = msg

End Sub


SetTitle event

The SetTitle event is triggered when status information changes. In the dbmlsync utility, this information is displayed in the title bar.

Syntax

Public Event SetTitle( ByVal title ) As String
)
Member of DbmlsyncCOM.Dbmlsync

Parameters

title The title in the dbmlsync window title bar.

Description

Use this event to receive the title normally seen on the dbmlsync window when its value changes.

Example

The following Visual Basic .NET example sets the title of a Windows form when the SetTitle event is triggered.

Private Sub dbmlsync1_SetTitle(
 ByVal title As String
)
Handles dbmlsync1.SetTitle

        Me.Text = title

End Sub


UploadAck event

The UploadAck event is triggered after the component has received acknowledgement of the upload stream from the MobiLink synchronization server.

Syntax

Public Event UploadAck( _
ByVal status As DbmlsyncCOM.UploadAckStatus _
)
Member of DbmlsyncCOM.Dbmlsync

Parameters

status Indicates the status returned by MobiLink to the remote after the upload stream is processed. Its value is one of:

  • StatCommitted Indicates that the upload stream was received by the MobiLink synchronization server and committed.

  • StatRetry Indicates that the MobiLink synchronization server and the remote database had different values for the log offset from which the upload stream should start. The upload stream was not committed by the MobiLink synchronization server. The component will attempt to send another upload stream starting from the MobiLink synchronization server's log offset.

  • StatFailed Indicates that the MobiLink synchronization server did not commit the upload stream.

Description

Use this event to add custom actions after dbmlsync has received acknowledgement of the upload stream from the MobiLink synchronization server.

Example

The following Visual Basic .NET example outputs a message if the upload has failed when the UploadAck event is triggered.

Private Sub dbmlsync1_UploadAck(ByVal status As DbmlsyncCOM.UploadAckStatus) Handles dbmlsync1.UploadAck

    If status = DbmlsyncCOM.UploadAckStatus.StatFailed Then
         MsgBox("Upload Failed")
    End If

End Sub


UploadRow event

The UploadRow event is triggered when a row is uploaded to the MobiLink synchronization server.

Syntax

Public Event UploadRow(
ByVal rowData As DbmlsyncCOM.IRowTransferData
)
Member of DbmlsyncCOM.Dbmlsync

Parameters

rowData An IRowTransferData object containing detailed information about the uploaded row.

For more information about the IRowTransferData interface, see IRowTransferData interface.

Description

Use this event to examine rows being uploaded to the MobiLink synchronization server.

To enable the UploadRow event, use the UploadEventsEnabled property.

For more information, see UploadEventsEnabled property.

Example

The following Visual Basic .NET example iterates through all the columns for a row in the UploadRow event. It determines if a column value is null and outputs column names and values.

Private Sub dbmlsync1_UploadRow(
 ByVal rowData As DbmlsyncCOM.IRowTransferData
)
Handles dbmlsync1.UploadRow

Dim liX As Integer
For liX = 0 To rowData.ColumnCount - 1
    If VarType(rowData.ColumnValue(liX)) <> VariantType.Null Then
        ' output the non-null column value
        MsgBox("Column " + CStr(liX) + ": " + rowData.ColumnName(liX) + _
        ", " + CStr(rowData.ColumnValue(liX)))
    Else
        ' output 'NULL' for the column value
        MsgBox("Column " + CStr(liX) + ": " + rowData.ColumnName(liX) + _
        ", " + "NULL")
    End If
Next liX

End Sub


WaitingForUploadAck event

The WaitingForUploadAck event is triggered when the component begins waiting for upload acknowledgement from the MobiLink synchronization server.

Syntax

Public Event WaitingForUploadAck( )
Member of DbmlsyncCOM.Dbmlsync

Description

Use this event to add custom actions when the component is waiting for upload acknowledgement from the MobiLink synchronization server.

Example

The following Visual Basic .NET example outputs a message when the WaitingForUploadAck event is triggered.

Private Sub dbmlsync1_WaitingForUploadAck()
Handles dbmlsync1.WaitingForUploadAck

    MsgBox("Waiting for Upload Acknowledgement")

End Sub


IRowTransferData interface

Public Interface IRowTransferData
Member of DbmlsyncCOM

The UploadRow and DownloadRow events accept DbmlsyncCOM.IRowTransferData objects as parameters to examine uploaded and downloaded rows. This interface defines detailed row information including the table name, row operation, and column names.


RowOperation property

Function

Specifies the operation performed on the row.

Syntax

Public Property RowOperation( ) As DbmlsyncCOM.RowEventOp
Member of DbmlsyncCOM.IRowTransferData

Description

This property has one of the following values:

OpInsert The row was inserted.

OpUpdate The row was updated.

OpDelete The row was deleted.

OpTruncate The table was truncated (all the rows in the table were deleted). When the RowOperation property has this value, the ColumnName and ColumnValue properties return invalid information.

Note: For the DownloadRow event, upsert (update or insert) operations are given the OpInsert value.


TableName property

Function

The name of the table on which an upload or download operation occurred.

Syntax

Public Property TableName( ) As String
Member of DbmlsyncCOM.IRowTransferData

Description

The TableName property specifies the name of the table on which an upload or download operation occurred. The following example illustrates the use of the TableName property in the UploadRow event.

For more information about the UploadRow event, see UploadRow event.

Example

Following is a Visual Basic .NET example.

Private Sub dbmlsync1_UploadRow(
 ByVal rowData As DbmlsyncCOM.IRowTransferData
)
Handles dbmlsync1.UploadRow

    MsgBox ("Table name:" + rowData.TableName)

End Sub


ColumnName property

Function

Retrieves the column names for a row on which an upload or download operation occurred.

Syntax

Public Property ColumnName(ByVal index As String) As Object
Member of DbmlsyncCOM.IRowTransferData

Parameters

index A zero based integer specifying the column name to be retrieved. Index values range from zero to one less than the ColumnCount property value.

For more information about the ColumnCount property, see ColumnCount property.

Description

Associated column values can be retrieved using the ColumnValue property with the same index.

Example

The following Visual Basic .NET example iterates through all the columns for a row in the UploadRow event. It determines if a column value is null and outputs column names and values.

For more information about the UploadRow event, see UploadRow event.

Private Sub dbmlsync1_UploadRow(
 ByVal rowData As DbmlsyncCOM.IRowTransferData
)
Handles dbmlsync1.UploadRow

Dim liX As Integer
For liX = 0 To rowData.ColumnCount - 1
    If VarType(rowData.ColumnValue(liX)) <> VariantType.Null Then
        ' output the non-null column value
        MsgBox("Column " + CStr(liX) + ": " + rowData.ColumnName(liX) + _
        ", " + CStr(rowData.ColumnValue(liX)))
    Else
        ' output 'NULL' for the column value
        MsgBox("Column " + CStr(liX) + ": " + rowData.ColumnName(liX) + _
        ", " + "NULL")
    End If
Next liX

End Sub


ColumnValue property

Function

Retrieves the value of columns on which an upload or download operation occurred.

Syntax

Public Property ColumnValue( ByVal index As Integer ) As Object
Member of DbmlsyncCOM.IRowTransferData

Parameters

index The zero based integer specifying the column value to be retrieved. Index values range from zero to one less than the ColumnCount property value.

For more information about the ColumnCount property, see ColumnCount property.

Description

When an update operation is encountered, the column values given by this property are the values after the update is applied.

Associated column names can be retrieved using the ColumnName property with the same index.

Blob column values are not available through this property. When a blob column is encountered, the ColumnValue is the string "(blob)".

Example

The following Visual Basic .NET example iterates through all the columns for a row in the UploadRow event. It determines if a column value is null and outputs column names and values.

For more information about the UploadRow event, see UploadRow event.

Private Sub dbmlsync1_UploadRow(
 ByVal rowData As DbmlsyncCOM.IRowTransferData
)
Handles dbmlsync1.UploadRow

Dim liX As Integer
For liX = 0 To rowData.ColumnCount - 1
    If VarType(rowData.ColumnValue(liX)) <> VariantType.Null Then
        ' output the non-null column value
        MsgBox("Column " + CStr(liX) + ": " + rowData.ColumnName(liX) + _
        ", " + CStr(rowData.ColumnValue(liX)))
    Else
        ' output 'NULL' for the column value
        MsgBox("Column " + CStr(liX) + ": " + rowData.ColumnName(liX) + _
        ", " + "NULL")
    End If
Next liX

End Sub


ColumnCount property

Function

The number of columns contained in a row on which an upload or download operation occurred.

Syntax

Public Property ColumnCount( ) As Integer
Member of DbmlsyncCOM.IRowTransferData

Description

The ColumnCount property specifies the number of columns for a row on which an upload or download operation occurred. The following example illustrates the use of the ColumnCount property in the UploadRow event.

For more information about the UploadRow event, see UploadRow event.

Example

Following is a Visual Basic .NET example.

Private Sub dbmlsync1_UploadRow(
 ByVal rowData As DbmlsyncCOM.IRowTransferData
)
Handles dbmlsync1.UploadRow

    MsgBox "Number of Columns:" + CStr(rowData.ColumnCount)

End Sub


DBTools Interface for dbmlsync

About this chapter

This chapter describes how to configure and use the DBTools interface for dbmlsync, allowing you to customize your Adaptive Server Anywhere client applications.


Introduction

Database tools (DBTools) is a library you can use to integrate database management, including synchronization, into your applications. All the database management utilities are built on DBTools.

For more information about the DBTools library, see The Database Tools Interface.

You can use the DBTools interface for dbmlsync to integrate synchronization functionality into your MobiLink synchronization client applications. For example, you can use the interface to display dbmlsync output messages in a custom user interface.

As an alternative to the DBTools interface for dbmlsync, you can use the Dbmlsync Integration Component.

For more information about the Dbmlsync Integration Component, see About this chapter.

The DBTools interface for dbmlsync consists of the following elements that let you configure and run the MobiLink synchronization client:

  • a_sync_db structure This structure holds settings, corresponding to dbmlsync command line options, that allow you to customize synchronization. This structure also contains pointers to callback functions receiving synchronization and progress information.

    For more information about a_sync_db, see a_sync_db structure.

  • a_syncpub structure This structure holds publication information. You can specify a linked list of publications for synchronization.

    For more information about a_syncpub, see a_syncpub structure.

  • DBSynchronizeLog function This function starts the synchronization process. Its only parameter is a pointer to an a_sync_db instance.

    For more information about DBSynchronizeLog, see DBSynchronizeLog function.


Setting up the DBTools interface for dbmlsync

This section guides you through the basic steps for using the DBTools interface for dbmlsync.

For more information about the DBTools library, see Introduction to the database tools interface.

For more information about using import libraries for your development environment, see Using the database tools interface.

toggle To configure and start dbmlsync using the DBTools interface

  1. Include the DBTools header file.

    The DBTools header file, dbtools.h, lists the entry points to the DBTools library and defines required data types.

    #include "dbtools.h"

  2. Start the DBTools interface.

    • Declare and initialize the a_dbtools_info structure.

      a_dbtools_info   info;
short ret;
...
// clear a_dbtools_info fields
memset( &info, 0, sizeof( info ) );
info.errorrtn = dbsyncErrorCallBack;

      The dbsyncErrorCallBack function handles error messages and is defined in step 4 of this procedure.

    • Use the DBToolsInit function to start DBTools.

      ret = DBToolsInit( &info );
if( ret != 0 ) {
 printf("dbtools initialization failure \n");
}

      For more information about DBTools initialization, see:

      • Using the database tools interface.

      • a_dbtools_info structure.

      • DBToolsInit function.

  3. Initialize the a_sync_db instance.

    • Declare an a_sync_db instance. For example, declare an instance called dbsync_info:

      a_sync_db dbsync_info;

    • Clear a_sync_db structure fields.

      memset( &dbsync_info, 0, sizeof( dbsync_info ) );

    • Set required a_sync_db fields.

      dbsync_info.version = DB_TOOLS_VERSION_NUMBER;
dbsync_info.output_to_mobile_link = 1;
dbsync_info.default_window_title
  = "dbmlsync dbtools sample";

    • Set the database connection string.

      dbsync_info.connectparms = "uid=dba;pwd=sql";

      For more information about database connection parameters, see -c option.

    • Set other a_sync_db fields to customize synchronization.

      Most fields correspond to dbmlsync command line options. For more information about this correspondence, see dbtools.h.

      In the example below, verbose operation is enabled.

      dbsync_info.verbose_upload = 1;
dbsync_info.verbose_option_info = 1;
dbsync_info.verbose_row_data = 1;
dbsync_info.verbose_row_cnts = 1;

    • Initialize other a_sync_db fields.

    For more information about a_sync_db fields, see a_sync_db structure.

  4. Create callback functions to receive feedback during synchronization and assign these functions to the appropriate a_sync_db fields.

    The following functions use the standard output stream to display dbmlsync error, log, and progress information.

    For more information about DBTools callback functions, see Using callback functions.

    • For example, create a function called dbsyncErrorCallBack to handle generated error messages:

      extern short _callback dbsyncErrorCallBack( char *str )
{
    if( str != NULL ) {
        printf( "Error Msg    %s\n", str );
    }
    return 0;
}

    • For example, create a function called dbsyncWarningCallBack to handle generated warning messages:

      extern short _callback dbsyncWarningCallBack( char *str )
{
    if( str != NULL ) {
        printf( "Warning Msg  %s\n", str );
    }
    return 0;
}

    • For example, create a function called dbsyncLogCallBack to receive verbose informational messages that you might choose to log to a file instead of displaying in a window:

      extern short _callback dbsyncLogCallBack( char *str )
{
    if( str != NULL ) {
        printf( "Log Msg      %s\n", str );
    }
    return 0;
}

    • For example, create a function called dbsyncMsgCallBack to receive informational messages generated during synchronization.

      extern short _callback dbsyncMsgCallBack( char *str )
{
    if( str != NULL ) {
        printf( "Display Msg  %s\n", str );
    }
    return 0;
}

    • For example, create a function called dbsyncProgressMessageCallBack to receive the progress text. In the dbmlsync utility, this text is displayed directly above the progress bar.

      extern short _callback dbsyncProgressMessageCallBack(
 char *str )
{
    if( str != NULL ) {
        printf( "ProgressText %s\n", str );
    }
    return 0;
}

    • For example, create a function called dbsyncProgressIndexCallBack to receive information for updating a progress indicator or progress bar. This function receives two parameters:

      • index An integer representing the current progress of a synchronization.

      • max The maximum progress value. If this value is zero, the maximum value has not changed since the last time the event was fired.

      extern short _callback dbsyncProgressIndexCallBack
(a_sql_uint32 index, a_sql_uint32 max )
{
    printf( "ProgressIndex    Index %d Max: %d\n",
           index, max );
    return 0;
}

      A typical sequence of calls to this callback is shown below

      // example calling sequence
// dbsyncProgressIndexCallBack( 0, 100 );
//   dbsyncProgressIndexCallBack( 25, 0 );
//   dbsyncProgressIndexCallBack( 50, 0 );
//   dbsyncProgressIndexCallBack( 75, 0 );
//   dbsyncProgressIndexCallBack( 100, 0 );

      This sequence should result in the progress bar being set to 0% done, 25% done, 50% done, 75% done, and 100% done.

    • For example, create a function called dbsyncWindowTitleCallBack to receive status information. In the dbmlsync utility, this information is displayed in the title bar.

      extern short _callback dbsyncWindowTitleCallBack(
 char *title )
{
    printf( "Window Title     %s\n", title );
    return 0;
}

    • The dbsyncMsgQueueCallBack function is called when a delay or sleep is required. It must return one of the following values, which are defined in dllapi.h.

      • MSGQ_SLEEP_THROUGH indicates that the routine slept for the requested number of milliseconds. In most cases this is the value you should return.

      • MSGQ_SHUTDOWN_REQUESTED indicates that you would like the synchronization to terminate as soon as possible.

      • MSGQ_SYNC_REQUESTED indicates that the routine slept for less than the requested number of milliseconds and that the next synchronization should begin immediately if a synchronization is not currently in progress.

      extern short _callback dbsyncMsgQueueCallBack(
         a_sql_uint32 sleep_period_in_milliseconds )
{

 printf( "Sleep %d ms\n", sleep_period_in_milliseconds );
 Sleep( sleep_period_in_milliseconds );
 return MSGQ_SLEEP_THROUGH;
}

    • Assign callback function pointers to the appropriate a_sync_db synchronization structure fields.

      // set call back functions
dbsync_info.errorrtn    = dbsyncErrorCallBack;
dbsync_info.warningrtn  = dbsyncWarningCallBack;
dbsync_info.logrtn      = dbsyncLogCallBack;
dbsync_info.msgrtn      = dbsyncMsgCallBack;
dbsync_info.msgqueuertn = dbsyncMsgQueueCallBack;
dbsync_info.progress_index_rtn
     = dbsyncProgressIndexCallBack;
dbsync_info.progress_msg_rtn
     = dbsyncProgressMessageCallBack;
dbsync_info.set_window_title_rtn
     = dbsyncWindowTitleCallBack;

  5. Create a linked list of a_syncpub structures to specify which publications should be synchronized.

    Each node in the linked list corresponds to one instance of the -n option on the dbmlsync command line.

    • Declare an a_syncpub instance. For example, call it publication_info:

      a_syncpub publication_info;

    • Initialize a_syncpub fields, specifying publications you want to synchronize.

      For example, to identify the template_p1 and template_p2 publications together in a single synchronization session:

      publication_info.next = NULL; // linked list terminates
publication_info.pub_name = "template_p1,template_p2";
publication_info.ext_opt  = "sv=template_ver1";
publication_info.alloced_by_dbsync = 0;

      This is equivalent to specifying -n template_p1,template_p2 on the dbmlsync command line.

      The associated script version specified using the ext_opt field, provides the same functionality as the dbmlsync -eu option.

      For more information, see -eu option.

    • Assign the publication structure to the upload_defs field of your a_sync_db instance.

      dbsync_info.upload_defs   = &publication_info;

    You can create a linked list of a_syncpub structures. Each a_syncpub instance in the linked list corresponds to using the dbmlsync -n option.

    For more information about the dbmlsync -n option, see -n option.

    For more information about the a_syncpub structure, see a_syncpub structure.

  6. Run dbmlsync using the DBSynchronizeLog function.

    In the following code listing, sync_ret_val is a return value as listed in Software component return codes.

    printf("Running dbmlsync using dbtools interface...\n");
sync_ret_val = DBSynchronizeLog(&dbsync_info);
printf("\n Done... synchronization return value is: %I \n", sync_ret_val);

    You can repeat step 6 multiple times with the same or different parameter values.

  7. Shutdown the DBTools interface.

    The DBToolsFini function frees DBTools resources.

    DBToolsFini( &info );

    For more information about the DBToolsFini function, see DBToolsFini function.


UltraLite Clients

About this chapter

This chapter describes how to use an UltraLite database as a MobiLink client. It provides information on designing UltraLite databases to make the most of synchronization. It also introduces network protocols and provides material on how to set up Palm OS devices and Windows CE devices for synchronization.

For more information about UltraLite, see UltraLite Database User's Guide.

For information about how to use Adaptive Server Anywhere databases as MobiLink clients, see Adaptive Server Anywhere Clients.

Introduction
Adding synchronization to your UltraLite application
Choosing data to synchronize
Foreign key cycles
UltraLite network protocols
Maintaining primary key uniqueness
Synchronizing UltraLite databases on the Palm Computing Platform
Synchronizing UltraLite databases on Windows CE


Introduction

UltraLite developers can synchronize the data in UltraLite databases with a central consolidated database. This database may be a desktop database for personal applications, or a multi-user database for shared enterprise data.


Adding synchronization to your UltraLite application

Mobile and embedded databases generally cannot contain all the data that exists in the consolidated database. In practice, however, the only data you need locally is that used by the particular application you wish to make mobile. UltraLite provides the ability to take such a piece of a database, and keep it synchronized with the consolidated database.

The tables in each UltraLite database can have a subset of the rows and columns in the central database. For example, a customer table might contain over 100 columns and 100 000 rows in the consolidated database, but the UltraLite database may only require 4 columns and 1000 rows. MobiLink allows you to define the exact subset to be downloaded to each remote database.

toggle To add synchronization to an UltraLite application

  1. Prepare the synchronization stream.

    Select a network protocol and set protocol options as required for that protocol.

    For more information, see Selecting a network protocol.

  2. Call the synchronization function.

    The synchronization function depends on the development model you are using and the network protocol the application is using.

    For more information, see Calling the synchronization function.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.


Choosing data to synchronize

By default, when you add synchronization to your database, all data is synchronized. You can customize what data is synchronized using publications, as well as a variety of other techniques.

Designing sets of data to synchronize separately
Creating publications
Synchronizing high-priority changes
Including non-synchronizing tables in UltraLite databases
Using client-specific data to control synchronization
Including read-only tables in an UltraLite database


Designing sets of data to synchronize separately

The schema of an UltraLite database is defined by the queries included in the application. You can add publications to the reference database to define sets of data that can be synchronized separately. If you do not use publications to define which changes are to be synchronized, all changes are synchronized.

Publications are used for several purposes in SQL Anywhere. A publication consists of a set of articles. In general, each article can be a whole table, or can define a subset of the data in a table.

Articles defined for UltraLite applications can use row subsets by supplying a WHERE clause, but cannot use column subsets or the SUBSCRIBE BY clause. Articles in UltraLite publications governing HotSync synchronization cannot use a WHERE clause.

toggle To synchronize subsets of data from an UltraLite database

  1. Create publications representing the data you wish to synchronize.

    For more information, see Creating publications.

  2. Run the UltraLite generator, specifying the publications on the -v command-line option.

    For more information, see The UltraLite Generator.

  3. When calling the synchronization function, specify the publication.

    If you specify no publication, all changes to the database are synchronized. If you specify one or more publications, only changes that fall within one or more of the listed publications are synchronized.

    For more information, see the following:

    • MobileVB See ULSyncParms class.

    • ActiveX See ULSyncParms class.

    • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

    • Embedded SQL and Static C++ API See publication synchronization parameter.

    • Static Java API See publication synchronization parameter.

    • UltraLite for M-Business Anywhere See Class SyncParms.


Creating publications

Components

Publications can be added to the UltraLite database using the schema painter, the ULXML utility, or from a reference database.

toggle To publish data from an UltraLite database (Schema Painter)

  1. Connect to the UltraLite database.

  2. In the left pane, open the Synchronization folder.

  3. Double-click Add Publication.

  4. Specify a set of tables to include in the publication.

  5. Click OK to save the changes.

Reference database

For UltraLite synchronization, each article in a publication may include either a complete table or may include a WHERE clause.

toggle To publish data from an UltraLite reference database (Sybase Central)

  1. Connect to the database as a user with DBA authority.

  2. Open the Publications folder and double-click Add Publication.

  3. Type a name for the new publication. Click Next.

  4. On the Tables tab, select a table from the list of Matching Tables. Click Add. The table appears in the list of Selected Tables on the right.

  5. Add additional tables as required. The order of the tables is not important.

  6. If necessary, click the Where tab to specify the rows to be included in the publication. You cannot specify column subsets. If you are using HotSync synchronization, do not specify a WHERE clause.

  7. Click Finish.

toggle To publish data from an UltraLite reference database (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute a CREATE PUBLICATION statement that specifies the name of the new publication and the table you want to publish.

    For more information, see CREATE PUBLICATION statement.


Synchronizing high-priority changes

Publications permit the synchronization of specific portions of your UltraLite database. You can combine publications with upload-only or download-only synchronization to synchronize high-priority changes efficiently. Both upload-only and download-only synchronization are less time-consuming than two-way synchronization.

For more information, see Choosing data to synchronize, and the following:

  • MobileVB See ULSyncParms class.

  • ActiveX See ULSyncParms class.

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • Embedded SQL and Static C++ API See upload_only synchronization parameter.

  • Static Java API See upload_only synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Including non-synchronizing tables in UltraLite databases

By default, all tables in an UltraLite database are synchronized to the consolidated database. You can include tables in your UltraLite database that are excluded from synchronization, but you must explicitly identify these tables when you create your reference database.

Tables with names ending in nosync are excluded from synchronization. You can use these tables for persistent data that is not related to the consolidated database. Other than being excluded from synchronization, you can use these tables in exactly the same way as other tables in the UltraLite database.

You can alternatively use publications to achieve the same effect. For more information, see Designing sets of data to synchronize separately.


Using client-specific data to control synchronization

Some UltraLite applications require client-specific data that control synchronization, but which are not needed on the consolidated database. For example, you may wish your UltraLite applications to indicate which of a number of channels or topics they are interested in, and use this information to download the appropriate rows.

If you create a table in your UltraLite database with a name ending in allsync, all rows of that table are synchronized at each synchronization, whether or not they have been changed since the last synchronization.

You can store user-specific or client-specific data in allsync tables. If you upload the data in the table to a temporary table in the consolidated database on synchronization, you can use the data to control synchronization by your other scripts without having to be maintained in the consolidated database.


Including read-only tables in an UltraLite database

Some applications include tables in the UltraLite database that are not updated locally. Price lists and company policies are two examples. You can synchronize these tables efficiently by including them in a publication, and synchronizing the publication using download-only synchronization. Download-only synchronization is less time-consuming than a two-way synchronization, as no data is uploaded.

To use download-only synchronization, you must ensure that the data is not changed locally. If any data is changed locally, synchronization fails with a SQLE_DOWNLOAD_CONFLICT error.

Unlike two-way synchronization, you do not have to commit all changes to the UltraLite database before download-only synchronization. Uncommitted changes to tables not involved in synchronization are not uploaded, and so there incomplete transactions do not cause problems.

For information about download-only synchronization, see the following:

  • MobileVB See ULSyncParms class.

  • ActiveX See ULSyncParms class.

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • Embedded SQL and Static C++ API See download_only synchronization parameter.

  • Static Java API See download_only synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Foreign key cycles

This section describes a specific limitation in UltraLite synchronization that results from a series of tables linked together by foreign keys so that a cycle is formed.

MobiLink synchronization from an UltraLite remote database requires that all changes be committed to the consolidated database in one transaction. To facilitate this single transaction for multiple tables, the inserts, updates, and deletes for each table must be ordered so that operations for a primary table come before the associated foreign table. This ensures that the insert in the foreign table will have its foreign key referential integrity constraint satisfied (likewise for other operations like delete).

The UltraLite analyzer automatically orders all the tables in the remote database so those primary tables are uploaded before foreign tables based on the schema in the reference database. The ordering is always possible as long as there are no foreign key cycles in the schema.

The figure illustrates a simple foreign key cycle between two tables.

A foreign key cycle between two tables.

If a foreign key cycle is detected by the UltraLite analyzer, the cycle must be broken for the analyzer to successfully complete without any errors. The foreign key cycle must be broken on both the reference database and the consolidated database in order for synchronization transactions to be successfully applied.

For an Adaptive Server Anywhere consolidated and reference database, one of the foreign keys can be made to check on commit so that foreign key referential integrity is checked during the commit phase rather than when the operation is initiated. Other database vendors may have similar methods but if not, the schema must be redesigned to eliminate the foreign key cycle.

Example
create table c (
    id integer not null primary key,
    c_pk integer not null
);
create table p (
    pk integer not null primary key,
    c_id integer not null,
    foreign key p_to_c (c_id) references c(id)
);
alter table c
add foreign key c_to_p (c_pk)
references p(pk)
check on commit;


UltraLite network protocols

Each UltraLite database that synchronizes with a MobiLink synchronization server does so over a network protocol. The network protocol is specified in the UltraLite application. Available network protocols include TCP/IP, HTTP, and HTTPS for TCP/IP-based networks. Support is also provided for HotSync synchronization on the Palm Computing Platform and for ActiveSync synchronization on Windows CE.

For more information, see Selecting a network protocol.


Supported network protocols

UltraLite databases can synchronize with a MobiLink synchronization server over one of a set of network protocols, including TCP/IP, HTTP, and HTTPS. ActiveSync synchronization is available for Windows CE applications under some development models. HotSync is available for Palm OS applications.

Each network protocol has a set of appropriate protocol options. These options set required values for the protocol, such as the location of the MobiLink synchronization server, as well as network-specific control parameters.

The following network protocols are supported for synchronizing UltraLite clients:

Component | TCP/IP | HTTP | HTTPS | ActiveSync (Windows CE only) | HotSync (Palm OS only)
UltraLite ActiveX | Y | Y | Y |  |
UltraLite for MobileVB | Y | Y | Y 1 |  | Y
Native UltraLite for Java | Y | Y | Y | Y |
UltraLite.NET | Y | Y | Y | Y |
UltraLite C++ | Y | Y | Y | Y | Y
Embedded SQL | Y | Y | Y | Y | Y
Static C++ API | Y | Y | Y | Y | Y
Static Java API | Y 2 | Y | Y |  |
Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

1 Must be separately ordered

2 Use separate protocols for secure synchronization


Selecting a network protocol

Each network protocol has a set of options that govern its behavior. You should set these synchronization protocol options when you select a network protocol.

The way to select a network protocol and its associated synchronization protocol options depends on the particular UltraLite development model you are using.

  • For UltraLite for MobileVB and UltraLite ActiveX, the network protocol is one of the synchronization parameters set in the Stream property of the ULSyncParms object. The protocol options are provided as a set of keyword-value pairs in the StreamParms property.

    For more information, see ULSyncParms class, and ULSyncParms class.

  • For Native UltraLite for Java applications, the network protocol is set by the setStream method of the SyncParms object.

    For more information, see ianywhere.native_ultralite.SyncParms in the API Reference.

  • For embedded SQL and static C++ API applications, the network protocol is set in the stream member of the ul_synch_info structure. The protocol options are supplied in the stream_parms member of the ul_synch_info structure, as a string. The following code is an example for TCP/IP synchronization:

    ul_synch_info info;
...
info.stream = ULSocketStream();
info.stream_parms = UL_TEXT( "host=myserver" );

    For more information, see the following:

    • stream synchronization parameter

    • stream_parms synchronization parameter

  • For static Java applications, the protocol options are supplied using the setStreamParms method. The following example illustrates how to call the method:

    UlSynchOptions synch_options = new UlSynchOptions();
synch_opts.setStream( new UlSocketStream() );
synch_opts.setStreamParms( "host=myserver;port=2439" );

    For more information, see stream synchronization parameter and stream_parms synchronization parameter.


Calling the synchronization function

In order to synchronize data with a MobiLink synchronization server, UltraLite applications call a synchronization function. The particular function depends on the development model you are using and on the network protocol you have selected.

It is helpful to distinguish the following kinds of netowrk protocol:

  • Externally-initiated synchronization streams ActiveSync and HotSync synchronization are initiated by an external application.

    For information about calling HotSync synchronization, see the following:

    • MobileVB See Synchronizing data.

    • Embedded SQL and Static C++ API See Adding HotSync synchronization to Palm applications.

  • Direct network protocols TCP/IP, HTTP, and HTTPS network protocols are initiated directly from UltraLite.

    For information about calling the synchronization function for these protocols, see the following:

    • UltraLite for MobileVB See Synchronize method.

    • UltraLite ActiveX See Synchronize method.

    • Native UltraLite for Java See ianywhere.native_ultralite.Connection.synchronize in the API Reference.

    • UltraLite.NET See Synchronize in the UltraLite.NET API Reference.

    • Embedded SQL See ULSynchronize function.

    • Static C++ API See Synchronize method.

    • Static Java API See synchronize method.


Maintaining primary key uniqueness

You can declare the default value of a column in a reference database to be of type GLOBAL AUTOINCREMENT. You can use this default for any column in which you want to maintain unique values, but it is particularly useful for primary keys. This feature simplifies the task of generating unique values in setups where data is being replicated among multiple databases, typically by MobiLink synchronization.

When you specify default global autoincrement, the domain of values for that column is partitioned. Each partition contains the same number of values. For example, if you set the partition size for an integer column in a database to 1000, one partition extends from 1001 to 2000, the next from 2001 to 3000, and so on.

For information about declaring columns as global autoincrement in your reference database, see Declaring default global autoincrement columns.

To use global autoincrement columns in your UltraLite database, you must first assign each copy of the database a unique global database identification number. UltraLite then supplies default values for the column only from the partition uniquely identified by that database's number. For example, if you assigned a database in the above example the identity number 1, the default values in that database would be chosen in the range 1001–2000. Another copy of the database, assigned the identification number 2, would supply default value for the same column in the range 2001–3000.

For information about assigning global database identification numbers, see Setting the global database identifier.

For more information about using global autoincrement values in MobiLink remote databases, see Maintaining unique primary keys using global autoincrement.

Declaring default global autoincrement columns
Setting the global database identifier
How default values are chosen
Determining the most recently assigned value
Detecting the number of available default values


Declaring default global autoincrement columns

You declare default column values in the Adaptive Server Anywhere reference database. When you build your UltraLite application, your UltraLite database inherits the default column value. You can set default values in your reference database by selecting the column properties in Sybase Central, or by including the DEFAULT GLOBAL AUTOINCREMENT phrase in a TABLE or ALTER TABLE statement.

Optionally, the partition size can be specified in parentheses immediately following the AUTOINCREMENT keyword. The partition size may be any positive integer, although the partition size is generally chosen so that the supply of numbers within any one partition will rarely, if ever, be exhausted.

For columns of type INT or UNSIGNED INT, the default partition size is 216 = 65536; for columns of other types the default partition size is 232 = 4294967296. Since these defaults may be inappropriate it is best to specify the partition size explicitly.

For example, the following statement creates a simple reference table with two columns: an integer that holds a customer identification number and a character string that holds the customer's name.

CREATE TABLE customer (
   id   INT          DEFAULT GLOBAL AUTOINCREMENT (5000),
   name VARCHAR(128) NOT NULL,
   PRIMARY KEY (id)
)

In the above example, the chosen partition size is 5000.

Default partition sizes for some data types are different in UltraLite applications than in Adaptive Server Anywhere databases. Declare the partition size explicitly if you wish the reference database to behave in the same manner as your UltraLite application.

For more information on GLOBAL AUTOINCREMENT, see CREATE TABLE statement.


Setting the global database identifier

When deploying an application, you must assign a different identification number to each database. You can accomplish the task of creating and distributing the identification numbers by a variety of means. One method is to place the values in a table and download the correct row to each database based on some other unique property, such as user name.

The method of setting this identification number varies according to the programming interface you are using.

  • UltraLite for MobileVB See Properties.

  • UltraLite ActiveX See Properties.

  • Native UltraLite for Java See ianywhere.native_ultralite.Connection.databaseID in the API Reference.

  • UltraLite.NET See Connection in the UltraLite.NET API Reference.

  • Embedded SQL See ULSetDatabaseID function.

  • Static C++ API See SetDatabaseID method.

  • Static Java API See setDatabaseID method.

  • UltraLite for M-Business Anywhere See Method setDatabaseID.


How default values are chosen

The global database identifier in each deployed UltraLite application must be set to a unique, non-negative integer before default values can be assigned. These identification numbers uniquely identify the databases.

For information, see Setting the global database identifier.

The range of default values for a particular database is pn + 1 to p(n + 1), where p is the partition size and n is the global database identification number. For example, if the partition size is 1000 and the global database identification number is set to 3, then the range is from 3001 to 4000.

UltraLite applications choose default values by applying the following rules:

  • If the column contains no values in the current partition, the first default value is pn + 1.

  • If the column contains values in the current partition, but all are less than p(n + 1), the next default value will be one greater than the previous maximum value in this range.

  • Default column values are not affect by values in the column outside of the current partition; that is, by numbers less than pn + 1 or greater than p(n + 1). Such values may be present if they have been replicated from another database via MobiLink synchronization.

Caution Column values downloaded via MobiLink synchronization do not update the default value counter. Thus, an error can occur should one MobiLink client insert a value into another client's partition. To avoid this problem, ensure that each copy of your UltraLite application inserts values only in its own partition.

If the global database identification number is set to the default value of 2147483647, a NULL value is inserted into the column. Should NULL values not be permitted, the attempt to insert the row causes an error. This situation arises, for example, if the column is contained in the table's primary key.

Because the global database identification number cannot be set to negative values, the values chosen are always positive. The maximum identification number is restricted only by the column data type and the partition size.

Null default values are also generated when the supply of values within the partition has been exhausted. In this case, a new global database identification number should be assigned to the database to allow default values to be chosen from another partition. Attempting to insert the NULL value causes an error if the column does not permit nulls.

Should the values in a particular partition become exhausted, you can assign a new database identification number to that database. You can assign new database id numbers in any convenient manner. However, one possible technique is to maintain a pool of unused database id values. This pool is maintained in the same manner as a pool of primary keys.

For information about determining whether the range of default values is becoming exhausted, see Detecting the number of available default values.

For information about maintaining primary key uniqueness using explicit primary key pools, see Maintaining unique primary keys.


Determining the most recently assigned value

You can retrieve the value that was chosen during the most recently insert operation. Since these values are often used for primary keys, knowing the generated value may let you more easily insert rows that reference the primary key of the first row.

From embedded SQL, you can obtain the most recently assigned global autoincrement default value using the following statement.

select @@identity

From the C++ API, the value is available using the GetLastIdentity() method on the ULConnection object

The returned value is an unsigned 64-bit integer, database data type UNSIGNED BIGINT. Since this statement only allows you to determine the most recently assigned default value, you should retrieve this value soon after executing the insert statement to avoid spurious results.

Occasionally, a single insert statement may include more than one column of type global autoincrement. In this case, the return value is one of the generated default values, but there is no reliable means to determine which one. For this reason, you should design your database and write your insert statements so as to avoid this situation.


Detecting the number of available default values

Default values are chosen from the partition identified by the global database identification number until the maximum value is reached. When this state has been reached or is imminent, you must assign the database a new identification number.

The programming interfaces provide means of obtaining the proportion of numbers that have been used. The return value is a short in the range 0–100 that represents the percent of values used thus far. For example, a value of 99 indicates that very few unused values remain and the database should be assigned a new identification number.

The method of setting this identification number varies according to the programming interface you are using.

  • UltraLite for MobileVB See Properties.

  • UltraLite ActiveX See Properties.

  • Native UltraLite for Java See ianywhere.native_ultralite.Connection.databaseID in the API Reference.

  • UltraLite.NET See Connection in the UltraLite.NET API Reference.

  • Embedded SQL See ULGlobalAutoincUsage function.

  • Static C++ API See GlobalAutoincUsage method.

  • Static Java API See globalAutoincUsage method.

  • UltraLite for M-Business Anywhere See Method getGlobalAutoIncrementUsage.


Synchronizing UltraLite databases on the Palm Computing Platform

This section describes the details of synchronization that are specific to the Palm Computing Platform.

For more information about UltraLite on the Palm Computing Platform, see Developing UltraLite Applications for the Palm Computing Platform.

Choosing a synchronization method
Understanding HotSync synchronization
HotSync configuration overview
Registering the MobiLink HotSync conduit to HotSync Manager
Checking that MobiLink HotSync conduit installation is correct
Configuring the MobiLink HotSync conduit
Deploying the MobiLink HotSync conduit
Configuring TCP/IP, HTTP, or HTTPS synchronization
Configuring Remote Access Service


Choosing a synchronization method

Synchronization on the Palm Computing Platform can be carried out using HotSync or over standard network protocols using TCP/IP or HTTP. Each synchronization method has its advantages and disadvantages.

  • Multiple applications If you have more than one UltraLite application installed on a Palm device, they all synchronize when you invoke HotSync. To synchronize multiple applications through a TCP/IP or HTTP connection, you must activate and synchronize each application in turn.

  • Universal Serial Bus support HotSync synchronization has automatic support for USB.

  • Publications Synchronization using HotSync cannot include WHERE clauses.

    For more information, see Designing sets of data to synchronize separately.


Understanding HotSync synchronization

UltraLite applications on Palm devices can synchronize over a TCP/IP or HTTP protocol, in much the same manner as UltraLite applications on other platforms. They can also synchronize using the Palm-specific HotSync protocols, which operate in a different manner. This section describes the architecture of the HotSync synchronization.

The sequence of events that occur during HotSync synchronization is as follows:

  1. When your UltraLite application is closed, it saves the state of your UltraLite application. The state information is stored in the Palm database, separately from the UltraLite database.

    For more information, see Saving state in UltraLite Palm applications.

  2. When you synchronize your Palm device, HotSync calls the MobiLink conduit to synchronize with the MobiLink synchronization server. The MobiLink conduit reads the pages from the UltraLite database and sends the upload to the MobiLink synchronization server.

  3. The MobiLink synchronization server integrates updates into the consolidated database and sends a download stream to the conduit.

  4. The conduit integrates the download stream into the UltraLite database on the Palm device.

  5. When your application is launched, it loads the previously saved state of your UltraLite application.

    For more information, see Restoring state in UltraLite Palm applications.

HotSync architecture

The following diagram depicts the HotSync architecture. A separate HotSync conduit is required for each application. You can have multiple HotSync conduits on a single PC.

HotSync architecture, showing UltraLite databases on Palm devices, MobiLink HotSync conduits on the desktop computer, and a MobiLink synchronization server on a server.

For a description of how to set up your MobiLink HotSync conduit, see Configuring the MobiLink HotSync conduit.


HotSync configuration overview

During HotSync synchronization, the HotSync Manager starts the MobiLink HotSync conduit, dbhsync9.dll, which reads from the device and then sends the upload stream to a MobiLink synchronization server. It then receives the download stream from the MobiLink synchronization server and writes the download to the device.

The MobiLink HotSync conduit synchronizes with the MobiLink synchronization server using one of TCP/IP, HTTP, or HTTPS protocols.

In most applications, only the MobiLink HotSync conduit is deployed onto the desktop machines of users.

For information about HotSync architecture, see Understanding HotSync synchronization.

toggle To install and configure the MobiLink HotSync conduit

  1. Place the MobiLink conduit files on the user's machine.

    For instructions, see Conduit files.

  2. Register the MobiLink conduit to the HotSync Manager. The HotSync Manager is then able to use the MobiLink conduit.

    For instructions, see Registering the MobiLink HotSync conduit to HotSync Manager.

  3. If you did not include a stream_parms parameter in your UltraLite ul_synch_info structure, enter these parameters from the HotSync Manager.

    For instructions, see Configuring the MobiLink HotSync conduit.

    For information about including stream_parms parameter in your UltraLite synchronization call, see Adding HotSync synchronization to Palm applications.

  4. If you are using an encrypted database, enter the encryption key in the conduit configuration dialog. If you do not enter this key, you will have to enter it on every synchronization.

    For instructions, see Configuring the MobiLink HotSync conduit.

Conduit files

The HotSync conduit consists of the following files:

  • dbhsync9.dll The DLL that is called by the HotSync Manager.

  • dblgen9.dll The language resource library. For languages other than English, the letters en in the file name are replaced by a two-letter abbreviation for the language, such as dblgde9.dll or dblgja9.dll.

  • Stream DLL You need a DLL for the communication between the conduit and the MobiLink synchronization server. A separate DLL is provided for each network protocol:

    • For TCP/IP, use dbmlsock9.dll.

    • For HTTP, use dbmlsock9.dll and dbmlhttp9.dll.

    • For HTTPS, use dbmlhttps9.dll

    • If you use encryption for this communication, you also need to supply the encryption DLL dbmltls9.dll.

These files should be in the same directory, in your system path. When you install SQL Anywhere Studio, they are installed into the operating system subdirectory of your installation directory, which is already in the system path. However, you do not have to install SQL Anywhere Studio to use these files.


Registering the MobiLink HotSync conduit to HotSync Manager

UltraLite includes a command line conduit installation utility named dbcond9 to make a set of registry entries for the HotSync Manager to be able to use the MobiLink conduit. This utility requires the following files:

  • dbcond9.exe

  • condmgr.dll

toggle To deploy the conduit installation utility

  1. Choose a top-level deployment directory.

    For example, you may choose a directory named c:\deploy.

  2. Add a registry entry with the full path of the deployment directory as its value.

    The registry entry must be as follows:

    HKEY_CURRENT_USER\Software\Sybase\Adaptive Server Anywhere\version-string\Location

    where version-string is a number representing your version of the SQL Anywhere Studio (such as 9.0). If the entry is not found in HKEY_CURRENT_USER, the software looks in HKEY_LOCAL_MACHINE.

  3. Add the dbcond9.exe file to the win32 subdirectory of the deployment directory.

  4. Add the condmgr.dll file.

    The condmgr.dll file must go in the win32\condmgr subdirectory of the deployment directory.

The SQL Anywhere Studio installation creates the required registry entries and places files in the appropriate locations.

toggle To register the MobiLink HotSync conduit to HotSync Manager

  1. Ensure that the HotSync conduit files and the files for the conduit installation utility are in place.

  2. Run the conduit installation utility. On the command line, you must specify the creator ID of the Palm application and a name that HotSync will use to identify the conduit.

    For example, the following command installs a conduit for the application with creator ID Syb2, named CustDB. These are the settings for the CustDB sample application:

    dbcond9 "Syb2" –n CustDB

    For more information about the conduit installation utility, see The HotSync Conduit Installer.

    Note

    A secondary location for HotSync synchronization depends on the version of the Palm Computing Platform software you are using. This secondary location may be under the HKEY_CURRENT_USER\Software\U.S. Robotics or HKEY_CURRENT_USER\Software\Palm Computing folders.


Checking that MobiLink HotSync conduit installation is correct

Following are instructions for verifying that your conduit is installed and is working.

toggle To check that the HotSync conduit is properly installed

  1. Check that a conduit is installed:

    • In your PC's system tray, right-click HotSync Manager.

    • From the pop-up menu, choose Custom.

      A list of conduits is displayed for each user. Verify that your conduit is listed.

  2. Set the system environment variable UL_DEBUG_CONDUIT to any value.

  3. Shut down and restart the HotSync Manager.

  4. If the MobiLink conduit is properly installed, two dialog boxes appear. If no dialog appears, the conduit was not properly installed.

  5. Unset the environment variable.

  6. Shut down and restart the HotSync Manager.

MobiLink must be started before using HotSync
Before using HotSync, the MobiLink synchronization server must be started and be ready to accept connections from the MobiLink HotSync conduit. The MobiLink synchronization server does not have to be on the same computer, but it must be reachable across the network.

Previous Next


Configuring the MobiLink HotSync conduit

The MobiLink HotSync conduit needs to communicate with a MobiLink synchronization server to synchronize the UltraLite application and the consolidated database. You can provide the information needed by the conduit to locate the MobiLink synchronization server in a stream_parms member of the UltraLite ul_synch_info structure supplied to the ULSetSynchInfo function. If you did not specify a stream_parms value, or if you specified the value as null, you can enter the required parameters from the HotSync Manager.

In addition, if you are using a strongly encrypted UltraLite database, you can save the encryption key so that you do not have to enter it on each synchronization.

If you have Palm Desktop software installed, the Adaptive Server Anywhere installation creates registry entries for the CustDB sample application. You can use these entries as a starting point for your own application.

For information about stream_parms, see Adding HotSync synchronization to Palm applications.

toggle To configure the MobiLink HotSync conduit for synchronization

  1. Right-click the HotSync Manager icon in the system tray, and choose Custom from the popup menu.

  2. Select your MobiLink HotSync conduit from the list of conduit names, and click Change.

  3. Enter a set of network protocol options in the Synchronization Parameters text box. These options are the same as those in a stream_parms parameter, except that a "stream" entry is used to specify the network protocol type (TCPIP, HTTP, or HTTPS). For example:

    stream=tcpip;host=localhost

    For more information, see HotSync protocol options.

  4. If the database is strongly encrypted, you can enter the encryption key in the Encryption Key text box. If no key is entered, you will be prompted for the encryption key on each synchronization.

  5. Click OK to complete the entry. The HotSync conduit is now ready to use.

Registry locations

The protocol options and encryption key are stored in the registry in HKEY_CURRENT_USER\Software\Sybase\Adaptive Server Anywhere\9.0\Conduit\ Creator-ID, where Creator-ID is application-dependent.

A secondary location for HotSync synchronization depends on the version of the Palm Computing Platform software you are using. They are made under the HKEY_CURRENT_USER\Software\U.S. Robotics or the HKEY_CURRENT_USER\Software\Palm Computing folder.

HotSync log files

HotSync records when each synchronization took place and whether each installed conduit worked as expected. The HotSync log file is in the subdirectory User\HotSync.log of your Pilot or Palm directory.

You can obtain additional debugging information in your HotSync log file by setting the UL_DEBUG_CONDUIT_LOG environment variable. This variable is useful during development if you have problems with the HotSync conduit. By default, the environment variable is not set.

UL_DEBUG_CONDUIT_LOG = 1 When set to 1, basic information is written to the HotSync log file, such as synchronization parameters, registry locations, and attempts to load libraries.

UL_DEBUG_CONDUIT_LOG = 2 When set to 2, more detailed information is written to the HotSync log file.

You must restart HotSync before the new setting takes effect.

For information about how to set environment variables, see Setting environment variables.


Deploying the MobiLink HotSync conduit

For applications using HotSync synchronization, each end user must have the MobiLink HotSync conduit installed on their desktop. This installation requires the following:

  • Deploy the conduit files The files for the conduit must be installed into a location in the end user's system path.

    For a list of conduit files, see Conduit files.

  • Install the conduit You can deploy the conduit installation utility to your end users and provide instructions for them to run it, or you can use the HotSync Manager to install the conduit.

    For instructions, see Registering the MobiLink HotSync conduit to HotSync Manager.

  • Configure the conduit If you did not include a stream_parms parameter in your UltraLite ul_synch_info structure, enter these parameters from the HotSync Manager. Also, if you are using an encrypted database, you may want to enter the encryption key.

    For instructions, see Configuring the MobiLink HotSync conduit.


Configuring TCP/IP, HTTP, or HTTPS synchronization

This section describes how to configure the synchronization setup for UltraLite Palm applications using TCP/IP or HTTP synchronization.

For information about synchronization architecture for HTTP or TCP/IP communications, see Parts of the synchronization system.


Configuring TCP/IP synchronization for the Palm Computing Platform

There are two ways of using TCP/IP networking in a Palm device. In either case, you must connect to a Remote Access Service (RAS). The difference lies in how you make the connection to the RAS.

  • Use a modem to dial into an ISP The Internet Service Provider (ISP) must provide access to a Remote Access Service (RAS). The components of the connection are as follows:

    Application
<--> Palm Net Library
<--> Palm modem
<--> NT RAS
<--> TCP/IP network

  • Connect via the serial port to a Windows NT machine The components of the connection are as follows:

    Application
<--> Palm Net Library
<--> serial cable
<--> NT RAS
<--> TCP/IP network

When using TCP/IP, the MobiLink synchronization server can be any machine on the network that is accessible via TCP/IP.

Before synchronization, the following conditions must be satisfied:

  1. The device must be in its cradle.

  2. If you are using the serial port to connect to a Windows NT machine running RAS, the HotSync Manager and other applications that use the serial port must be shut down. Windows NT only allows one application to use a serial port at a time.

  3. The MobiLink synchronization server must be started. By default, the MobiLink synchronization server listens for TCP/IP communications over port 2439.

  4. The Palm device must have Network settings in place so that it can connect to the network. Modem settings are also required if using a modem to dial into an ISP.


Configuring HTTP or HTTPS synchronization for the Palm Computing platform

To use HTTP or HTTPS synchronization, you must first configure RAS TCP/IP synchronization. For information about configuring RAS, see Configuring TCP/IP synchronization for the Palm Computing Platform.

When using HTTP or HTTPS, the MobiLink synchronization server can be any machine on the network that is accessible via the protocol.

toggle To synchronize using HTTP or HTTPS

  1. Place the Palm device in its cradle.

  2. If you are using the serial port to connect to a desktop machine running RAS, shut down the HotSync Manager and other applications that use the serial port. Windows only allows one application to use a serial port at a time.

  3. Start the MobiLink synchronization server.

  4. Ensure that the network settings on the Palm device are configured so that it can connect to the network. Modem settings are also required if using a modem to dial into an ISP.

    For more information, see Configuring TCP/IP synchronization for the Palm Computing Platform.


Configuring Remote Access Service

Synchronizing Palm applications over TCP/IP, HTTP, or HTTPS requires a Remote Access Service on your desktop machine. Remote Access Service software is not part of UltraLite or MobiLink. Configuring Remote Access Service software is tricky, however, and so this section provides some instructions to assist with the task.


Configuring RAS for synchronization via modem

To use this method, you must have access to a Remote Access Service when you dial in.

toggle To configure a Palm device for RAS TCP/IP via a modem

  1. Install the modem by plugging the Palm device into the modem module.

  2. Go to the Preferences (Prefs) panel and choose Network from the dropdown list at the top right of screen.

  3. Choose the Windows RAS service.

  4. Set the dial-in username and password.

  5. Set the phone number to the number at which the Remote Access Service can be reached. Obtain this number from your ISP.

  6. Tap Details.

  7. Set the connection type (usually PPP).

  8. Set the DNS and IP addresses as recommended by your network administrator.

  9. Tap Script and enter the script recommended by your ISP. This script will be similar to the following sample.

    Wait For: Username:
Delay: 1
Send UserID:
Send CR:
Wait For: Password:
Delay: 1
Send Password:
Send CR:
Wait For: >
Delay: 1
Send: ppp
Send CR:
End:

    Tap OK until you are back to the Network Preferences.

At this point, you are ready to test your TCP/IP connection.


Configuring RAS for serial port connection

This procedure involves actions both on Windows NT and on the Palm Computing device.

toggle To configure Windows NT for RAS TCP/IP via serial port

  1. From the Control Panel, open Modems. Make sure that a modem is defined for Dial-Up Networking Serial Cable between 2 PCs on the COM port to which the cradle is connected.

  2. Set the speed for this modem to the baud rate you are using. The default is 19200.

  3. Make sure TCP/IP protocol is installed. Select Start > Settings > Control Panel and double-click the Network icon. Click on the Protocols tab. If there is no TCP/IP entry, choose Add to install it.

  4. Enable IP Forwarding (in the Routing tab of TCP/IP properties)

  5. Under the Services tab, make sure that Remote Access Service is installed. If there is no entry for Remote Access Service, choose Add to install it.

    In Remote Access Service Properties, add Dial Up Network serial cable between 2 pc's for that COM port if the cradle's COM port is not in the list of ports.

  6. Configure this entry to receive calls. In the RAS Network properties set encryption settings to Allow any authentication including clear text. In the RAS Network properties allow only TCP/IP client.

  7. Configure TCP/IP. Allow clients to access the entire network. Assigning the TCP/IP addresses depends on your network. Contact your network administrator for details.

  8. Add a user for dial-in access. Select Start > Programs > Administrative Tools > User Manager. Uncheck User Must Change Password at Next Logon. Choose the Dialin button, and grant dialin permission to user with No Call Back.

  9. If the RAS COM port is the same one that HotSync Manager uses, shut down the HotSync Manager or any other applications that use the COM port.

  10. Start the Remote Access Administrator. Select Start > Programs > Administrative Tools > Remote Access Admin.

  11. Start the RAS service. Select Server > Start Remote Access Service. Choose to start the service on the local machine.

HotSync Manager or any other applications that use the serial port and the RAS service will not run at the same time. One must be shut down first for the other to run, as Windows NT prevents two different applications from accessing the same serial port. You have to stop the RAS service (Server > Stop Remote Access Service from the Remote Access Admin) before you can restart the HotSync Manager. Alternatively, you can use separate serial ports.

Once the RAS service is running, it is ready to receive connection requests via the serial port.

toggle To configure a Palm device for RAS TCP/IP via serial port

  1. Go to the Preferences (Prefs) panel and choose Network from the dropdown list at the top right of screen.

  2. Choose the Windows RAS service.

  3. Set the dial-in username and password.

  4. Set the Palm to use the serial port.

    • For Palm OS 3.3 and above, select Direct serial.

    • For earlier versions of the Palm OS, set the phone number to 00 (zero zero). This is a special phone number that tells the Palm to use the serial port directly, instead of a modem.

  5. Tap Details.

  6. Set the connection type (usually PPP).

  7. Set the DNS and IP addresses as recommended by your network administrator.

  8. Tap Script and enter the following script:

    Send: CLIENT
Send CR:
Delay: 1
Send: CLIENT
END

    Tap OK until you are back to the Network Preferences

At this point, you are ready to test your TCP/IP connection.


Testing and troubleshooting
toggle To test the connection

  1. via modem Connect the Palm device to the modem and follow the instructions provided by your ISP for connecting to their network. Once connected, tap the Connect button in Prefs > Network on the Palm device.

  2. via serial port Ensure RAS is running on the Windows NT machine. Place the Palm device in the cradle and connect the cradle to the correct COM port on the Windows NT machine. Tap the Connect button in Prefs > Network on the Palm device.

With TCP/IP, there are two levels of service. At the minimum level, you can connect to another TCP/IP host using an IP number of the following form.

NNN.NNN.NNN.NNN

At the next level, when a DNS server is properly configured, you are able to connect to another host by name.

some_host_machine.any_company.com

Having a DNS service is more convenient, since most people are better at remembering a name than a number. As long as you have the minimum TCP/IP service, and an IP number, you can synchronize an UltraLite application using TCP/IP.

There are a number of steps you can take to troubleshoot TCP/IP connections on the Palm device.

  • Hitting the scroll down button on the Palm device during the connection phase displays the progress of the connection.

  • The connection log is accessible from the Network Preferences panel. Choose View Log from the Options menu to see information about the network connection. The log is an interactive utility for controlling and viewing your connection information. Enter ? for help.

  • There are several tools for testing a TCP/IP connection from the Palm. You can find most of them at the following locations:

    http://www.roadcoders.com
http://www.palmcentral.com

There are also steps you can take for troubleshooting on Windows NT:

  • In the Remote Access Admin, double-click on the running server.

  • Select the appropriate port and choose Port Status. The Port Status dialog shows you the Line condition (connected or waiting for a call) and lets you watch the byte counts for both directions.


Synchronizing UltraLite databases on Windows CE

UltraLite applications on Windows CE can synchronize using standard network protocols (TCP/IP, HTTP, or HTTPS). UltraLite applications built using embedded SQL, the static C++ API, or Native UltraLite for Java can also use ActiveSync.

This section describes ActiveSync synchronization.


Installing the MobiLink provider for ActiveSync

Before you register your application for use with ActiveSync, you must install the MobiLink provider for ActiveSync using the installation utility (dbasinst.exe).

The MobiLink provider for ActiveSync includes a desktop component and a device component. You must configure the provider for each device that synchronizes through your desktop machine.

When you have installed the MobiLink provider for ActiveSync you must register each application separately. For instructions, see Registering applications for use with ActiveSync.

toggle To install the MobiLink provider for ActiveSync

  1. Ensure that you have the ActiveSync software on your machine, and that the Windows CE device is connected.

  2. Enter the following command to install the MobiLink provider:

    dbasinst -k desk-path -v dev-path

    where desk-path is the location of the desktop component of the provider (dbasdesk.dll) and dev-path is the location of the device component (dbasdev.dll).

    If you have SQL Anywhere installed on your machine, dbasdesk.dll is in the win32 subdirectory of your SQL Anywhere directory and dbasdev.dll is in a platform-specific directory in the CE subdirectory. These directories are default search locations, and you can omit both the -k and -v options.

    For more information, see ActiveSync provider installation utility.

  3. Restart your machine.

    ActiveSync does not recognize new providers until the machine is restarted.

  4. Enable the MobiLink provider.

    • From the ActiveSync window, click Options.

    • Check the MobiLink item in the list and click OK to activate the provider.

    • To see a list of registered applications, click Options again, choose the MobiLink provider, and click Settings.

      For more information about registering applications, see Registering applications for use with ActiveSync.


Registering applications for use with ActiveSync

You can register your application for use with ActiveSync either by using the ActiveSync provider install utility or using the ActiveSync software itself. This section describes how to use the ActiveSync software.

For information about the alternative approach, see ActiveSync provider installation utility.

toggle To register an application for use with ActiveSync

  1. Ensure that the MobiLink provider for ActiveSync is installed.

    For information, see Installing the MobiLink provider for ActiveSync.

  2. Start the ActiveSync software on your desktop machine.

  3. From the ActiveSync window, choose Options.

  4. From the list of information types, choose MobiLink and click Settings.

  5. In the MobiLink Synchronization dialog, click New. The Properties dialog appears.

  6. Enter the following information for your application:

    • Application name A name identifying the application to be displayed in the ActiveSync user interface.

    • Class name The registered class name for the application.

      See Assigning class names for applications.

    • Path The location of the application on the device.

    • Arguments Any command line arguments to be used when ActiveSync starts the application.

  7. Click OK to register the application.


Deploying applications that use ActiveSync

Applications that use ActiveSync synchronization must be registered with ActiveSync as well as copied onto the device. Also, each desktop machine must have the MobiLink provider for ActiveSync installed. The architecture for ActiveSync is illustrated in the following diagram.

ActiveSync architecture, showing components on the Windows CE device, the desktop computer, and the computer where MobiLink synchronization server is running.
toggle To deploy ActiveSync applications

  1. Install the MobiLink provider for ActiveSync on each end user's computer.

    An ActiveSync provider install utility is provided with SQL Anywhere. This is the dbasinst.exe command line utility.

    For information about the dbasinst.exe command line utility, see Installing the MobiLink provider for ActiveSync and ActiveSync provider installation utility.

  2. Register the application for use with ActiveSync.

    You can register the application either by using ActiveSync, or by using the ActiveSync provider installation utility dbasinst.exe.

    For information about registering the application, see Registering applications for use with ActiveSync.

  3. Copy the application onto the device.

    If your application is a single executable, statically linked with the runtime library, you can use the ActiveSync provider installation utility dbasinst.exe to copy the application to the device.

    If the application includes multiple files (for example, if you use the UltraLite runtime DLL rather than the static runtime library), you must copy the files onto the device in some other way.


UltraLite Synchronization Parameters

About this chapter

This chapter details all the parameters that you can set to synchronize your UltraLite applications using MobiLink.

The parameters described in this chapter only apply to UltraLite remote databases. To synchronize Adaptive Server Anywhere remote databases, see Adaptive Server Anywhere Client Synchronization Parameters.


Synchronization parameters

Synchronization parameters control the synchronization between an UltraLite database and the MobiLink synchronization server. The way you set the parameters depends on the specific UltraLite interface you are using. This section describes the effects of the parameters, and provides links to other locations for information on how to set them.

The Stream Type and Version parameters are required. If they are not set, the synchronization function throws an exception (SQLCode.SQLE_SYNC_INFO_INVALID or its equivalent).

Some synchronization parameters can conflict. Only one of Download Only, Ping, Resume Partial Download, or Upload Only may be specified at a time. If more than one of these parameters is set to true, the synchronization function throws an exception (SQLCode.SQLE_SYNC_INFO_INVALID or its equivalent).

Authentication Parameters synchronization parameter
Authentication Status synchronization parameter
Authentication Value synchronization parameter
Checkpoint Store synchronization parameter
Disable Concurrency synchronization parameter
Download Only synchronization parameter
Ignored Rows synchronization parameter
Keep Partial Download synchronization parameter
New Password synchronization parameter
Number of Authentication Parameters parameter
Observer synchronization parameter
Partial Download Retained synchronization parameter
Password synchronization parameter
Ping synchronization parameter
Publication synchronization parameter
Resume Partial Download synchronization parameter
Security synchronization parameter
Security Parameters synchronization parameter
Send Column Names synchronization parameter
Send Download Acknowledgement synchronization parameter
Stream Error synchronization parameter
Stream Type synchronization parameter
Stream Parameters synchronization parameter
Sync Result synchronization parameter
Upload OK synchronization parameter
Upload Only synchronization parameter
User Data synchronization parameter
User Name synchronization parameter
Version synchronization parameter


Authentication Parameters synchronization parameter

Function

Supplies parameters to the authentication_parameters script.

Usage

Use this parameter to supply any values required by your authentication_parameters script. These may be a user name and password, for example.

If you use this parameter, you must also supply the number of parameters. See Number of Authentication Parameters parameter.

Allowed values

An array of strings. Null is not allowed as a value for any of the strings, but you can supply an empty string.

See also

Number of Authentication Parameters parameter

authenticate_parameters connection event

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See AuthenticationParms property (iAnywhere.Data.UltraLite namespace) and AuthenticationParms property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See auth_parms parameter.

  • Static Java API See auth_parms parameter.


Authentication Status synchronization parameter

Function

Reports the status of MobiLink user authentication. The MobiLink synchronization server provides this information to the client.

Usage

If you are implementing a custom authentication scheme, the authenticate_user or authenticate_user_hashed synchronization script must return one of the allowed values of this parameter.

The parameter is set by the MobiLink synchronization server, and so is read-only.

Allowed values

The allowed values are held in an interface-specific enumeration.

If a custom authenticate_user synchronization script at the consolidated database returns a different value, the value is interpreted according to the rules given in authenticate_user connection event.

See also

Authenticating MobiLink Users.

Interfaces

  • MobileVB ULSyncResult class

  • ActiveX ULSyncResult class

  • UltraLite.NET See AuthStatus property (iAnywhere.Data.UltraLite namespace) and AuthStatus property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncResult in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See auth_status parameter.

  • Static Java API See auth_status parameter.

  • UltraLite for M-Business Anywhere See Class SyncResult.


Authentication Value synchronization parameter

Function

Reports results of a custom MobiLink user authentication script. The MobiLink synchronization server provides this information to the client.

Default

The values set by the default MobiLink user authentication mechanism are described in Authentication Status synchronization parameter.

Usage

The parameter is set by the MobiLink synchronization server, and so is read-only.

See also

authenticate_user connection event

authenticate_user_hashed connection event

Authentication Status synchronization parameter

Interfaces

  • MobileVB ULSyncResult class

  • ActiveX ULSyncResult class

  • UltraLite.NET See AuthValue property (iAnywhere.Data.UltraLite namespace) and AuthValue property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See auth_value synchronization parameter.

  • Static Java API See auth_value synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncResult.


Checkpoint Store synchronization parameter

Function

Adds additional checkpoints of the database during synchronization to limit database growth during the synchronization process.

The checkpoint operation adds I/O operations for the application and for the Palm conduit and so slows synchronization. The option is most useful for large downloads with many updates. Devices with slow flash memory may not want to pay the performance penalty.

Default

By default, only required checkpointing is done.

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See CheckpointStore property (iAnywhere.Data.UltraLite namespace) and CheckpointStore property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See checkpoint_store synchronization parameter.

  • Static Java API Not available.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Disable Concurrency synchronization parameter

Function

Disallow database access from other threads during synchronization.

Default

The parameter is a Boolean value, and by default is false (allowing concurrent database access). Data access is read-write during the download phase, and read-only otherwise.

See also

Understanding concurrency in UltraLite

Interfaces

  • MobileVB Not available

  • ActiveX Not available

  • UltraLite.NET See DisableConcurrency property (iAnywhere.Data.UltraLite namespace) and DisableConcurrency property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See disable_concurrency synchronization parameter.

  • Static Java API Not available.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Download Only synchronization parameter

Function

Do not upload any changes from the UltraLite database during this synchronization.

Default

The parameter is a Boolean value, and by default is false.

See also

Including read-only tables in an UltraLite database.

Upload Only synchronization parameter

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See DownloadOnly property (iAnywhere.Data.UltraLite namespace) and DownloadOnly property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See download_only synchronization parameter.

  • Static Java API See download_only synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Ignored Rows synchronization parameter

Function

This boolean parameter is set to true if any rows were ignored by the MobiLink synchronization server during synchronization because of absent scripts.

The parameter is read-only.

Interfaces

  • MobileVB ULSyncResult class

  • ActiveX ULSyncResult class

  • UltraLite.NET See IgnoredRows property (iAnywhere.Data.UltraLite namespace) and IgnoredRows property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncResult in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See ignored_rows synchronization parameter.

  • Static Java API See ignored_rows synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncResult.


Keep Partial Download synchronization parameter

Function

When a download fails because of a communications error during synchronization, this parameter controls whether UltraLite holds on to the download rather than rolling back the changes.

Default

The default setting is false, indicating that UltraLite rolls back all changes after a failed download.

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See KeepPartialDownload property (iAnywhere.Data.UltraLite namespace) and KeepPartialDownload property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See keep_partial_download synchronization parameter.

  • Static Java API Not available.

  • UltraLite for M-Business Anywhere See Class SyncParms.

See also
  • Resuming failed downloads
  • Resume Partial Download synchronization parameter


New Password synchronization parameter

Function

Sets a new MobiLink password associated with the user name.

Default

The parameter is optional, and is a string.

See also

Authenticating MobiLink Users.

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See NewPassword property (iAnywhere.Data.UltraLite namespace) and NewPassword property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See new_password synchronization parameter.

  • Static Java API See new_password synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Number of Authentication Parameters parameter

Function

Supply the number of authentication parameters being passed to the authentication_parameters script.

Default

No parameters supplied.

See also

Authentication Parameters synchronization parameter

authenticate_parameters connection event

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See AuthenticationParms property (iAnywhere.Data.UltraLite namespace) or AuthenticationParms property (iAnywhere.UltraLite namespace)

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See num_auth_parms parameter.

  • Static Java API See num_auth_parms parameter.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Observer synchronization parameter

Function

A pointer to a callback function or event handler that monitors synchronization.

See also

User Data synchronization parameter

Interfaces

  • MobileVB Declare the connection object With Events. See ULConnection class

  • ActiveX Use CreateObjectWithEvents when opening the DatabaseManager object. See ULDatabaseManager class

  • UltraLite.NET See ULSyncProgressListener members (iAnywhere.Data.UltraLite namespace) and SyncProgressListener interface (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncProgressListener in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See observer synchronization parameter.

  • Static Java API See observer synchronization parameter.


Partial Download Retained synchronization parameter

Function

When a download fails because of a communications error during synchronization, this parameter controls whether UltraLite applied those changes that were downloaded rather than rolling back the changes.

Default

The parameter is set by UltraLite. If there is no partial download retained, the value is false.

Partial downloads are retained only if Keep Partial Download is set to true.

Interfaces

  • MobileVB ULSyncResult class

  • ActiveX ULSyncResult class

  • UltraLite.NET See PartialDownloadRetained property (iAnywhere.Data.UltraLite namespace) and PartialDownloadRetained property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncResult in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See partial_download_retained synchronization parameter.

  • Static Java API Not available.

  • UltraLite for M-Business Anywhere See Class SyncResult.

See also
  • Resuming failed downloads
  • Keep Partial Download synchronization parameter
  • Resume Partial Download synchronization parameter


Password synchronization parameter

Function

A string specifying the MobiLink password associated with the user name. This user name and password are separate from any database user ID and password, and serves to identify and authenticate the application to the MobiLink synchronization server.

Default

The parameter is optional, and is a string.

See also

Authenticating MobiLink Users.

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See Password property (iAnywhere.Data.UltraLite namespace) and Password property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See password synchronization parameter.

  • Static Java API See password synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Ping synchronization parameter

Function

Confirm communications between the UltraLite client and the MobiLink synchronization server. When this parameter is set to true, no synchronization takes place.

When the MobiLink synchronization server receives a ping request, it connects to the consolidated database, authenticates the user, and then sends the authenticating user status and value back to the client.

If the ping succeeds, the MobiLink server issues an information message. If the ping does not succeed, it issues an error message.

If the MobiLink user name cannot be found in the ml_user system table and the MobiLink server is running with the command line option -zu+, the MobiLink server adds the user to ml_user.

The MobiLink synchronization server may execute the following scripts, if they exist, for a ping request:

  • begin_connection

  • authenticate_user

  • authenticate_user_hashed

  • end_connection

Default

The parameter is optional, and is a boolean.

See also

-pi option

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See PingOnly property (iAnywhere.Data.UltraLite namespace) and PingOnly property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See ping synchronization parameter.

  • Static Java API See ping synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Publication synchronization parameter

Function

Specifies the publications to be synchronized.

Default

If you do not specify a publication, all data is synchronized.

Usage

When synchronizing, set the publication parameter to a publication mask: an OR'd list of publication constants.

See also

The UltraLite Generator

Designing sets of data to synchronize separately

Interfaces

  • MobileVB ULPublicationSchema class

  • ActiveX ULPublicationSchema class

  • UltraLite.NET See ULPublicationSchema class (iAnywhere.Data.UltraLite namespace) and PublicationSchema class (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.PublicationSchema in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See publication synchronization parameter.

  • Static Java API See publication synchronization parameter.

  • UltraLite for M-Business Anywhere See Class PublicationSchema.


Resume Partial Download synchronization parameter

Function

Resume a failed download. The synchronization does not upload changes, and downloads only those changes that were to be downloaded in the failed download.

Default

False.

See also
  • Resuming failed downloads
  • Keep Partial Download synchronization parameter
  • Partial Download Retained synchronization parameter
Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See ResumePartialDownload property (iAnywhere.Data.UltraLite namespace) and ResumePartialDownload property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See resume_partial_download synchronization parameter.

  • Static Java API Not available.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Security synchronization parameter

Function

Set the UltraLite client to use Certicom encryption technology when exchanging messages with the MobiLink synchronization server.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

This parameter is not used in the static Java API. To use secure synchronization from the static Java API, choose a separate stream. For more information, see UlSecureRSASocketStream synchronization parameters and UlSecureSocketStream synchronization parameters.

Default

The parameter is null by default, corresponding to no transport-layer security.

Usage

The security stream is specified in addition to the synchronization stream. Allowed values are as follows:

  • ULSecureCerticomTLSStream() Elliptic-curve transport-layer security provided by Certicom. If you use this stream, you must link your application against ulecc.llib or supply ulecc9.dll with your application (ulecc9w.dll for Unicode applications).

  • ULSecureRSATLSStream() RSA transport-layer security provided by Certicom. If you use this stream, you must link your application against ulrsa.lib or supply ulrsa9.dll with your application (ulrsa9w.dll for Unicode applications).

Example

The following C++ code sets synchronization to use RSA transport-layer security over TCP/IP:

//C++
ul_synch_info info;
...
info.stream = ULSocketStream();
info.security = ULSecureRSATLSStream();
See also
  • MobiLink Transport-Layer Security
  • Security Parameters synchronization parameter
  • certificate_company
  • certificate_name
  • certificate_unit
  • trusted_certificates certificate_company
Interfaces

  • C++ Component, embedded SQL, and Static C++ API See security synchronization parameter.

  • Static Java API Use a separate synchronization stream. See UlSecureRSASocketStream synchronization parameters, and UlSecureSocketStream synchronization parameters.


Security Parameters synchronization parameter

Function

Sets the options required when using transport-layer security. This parameter must be used together with the security parameter.

For more information, see Security synchronization parameter.

This parameter is not applicable to static Java applications. To use secure synchronization from UltraLite static Java applications, choose a separate stream. For more information, see UlSecureRSASocketStream synchronization parameters and UlSecureSocketStream synchronization parameters.

Default

The default setting is an empty string.

Usage

The ULSecureCerticomTLSStream() and ULSecureRSATLSStream() security parameters take a string composed of the following options, supplied in an semicolon-separated string.

  • certificate_company The UltraLite application only accepts server certificates when the organization field on the certificate matches this value. By default, this field is not checked.

  • certificate_unit The UltraLite application only accepts server certificates when the organization unit field on the certificate matches this value. By default, this field is not checked.

  • certificate_name The UltraLite application only accepts server certificates when the common name field on the certificate matches this value. By default, this field is not checked.

  • trusted_certificates If this value is supplied, the UltraLite application retrieves the certificat from permanent storage rather than from the database schema itself. The option cannot be used on Palm OS.

For example:

ul_synch_info info;
...
info.stream = ULSocketStream();
info.security = ULSecureCerticomTLSStream();
info.security_parms =
     UL_TEXT( "certificate_company=Sybase" )
     UL_TEXT( ";" )
     UL_TEXT( "certificate_unit=Sales" );

If you use secure synchronization on the Palm OS, trusted_certificates is not available. You must use the –r command-line option on the UltraLite generator to embed the certificate in the application itself. For more information, see The UltraLite Generator.

See also
  • Security synchronization parameter
  • certificate_company
  • certificate_name
  • certificate_unit
  • trusted_certificates certificate_company
Interfaces

  • C++ Component, embedded SQL, and Static C++ API See security_parms synchronization parameter.

  • Static Java API Use a separate synchronization stream.


Send Column Names synchronization parameter

Function

When set to true, UltraLite sends each column name to the MobiLink synchronization server.

This parameter is typically used together with the -za or -ze switch on the MobiLink synchronization server for automatically generating synchronization scripts.

This parameter is not available for UltraLite static Java applications.

Default

False.

See also

-za option

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See SendColumnNames property (iAnywhere.Data.UltraLite namespace) and SendColumnNames property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See send_column_names synchronization parameter.

  • Static Java API This feature is not available in the static Java API.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Send Download Acknowledgement synchronization parameter

Function

Set this boolean parameter to true to instruct the MobiLink synchronization server that the client will provide a download acknowledgement.

If the client does send a download acknowledgement, the MobiLink synchronization server worker thread must wait for the client to apply the download. If the client does not sent a download acknowledgement, the MobiLink synchronization server is freed up sooner for its next synchronization.

Default

False.

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See SendDownloadAck property (iAnywhere.Data.UltraLite namespace) and SendDownloadAck property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See send_download_ack synchronization parameter.

  • Static Java API This parameter is not available for static Java applications.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Stream Error synchronization parameter

Function

Set a structure to hold communications error reporting information.

Applies To

This parameter applies only to C/C++ interfaces.

UltraLite components other than the UltraLite C++ Component receive communications error information as part of the Sync Result parameter. See Sync Result synchronization parameter.

This feature is not available for UltraLite static Java applications.

Default

The parameter is set by the MobiLink synchronization server, and so is read-only. It is set only if a communication error occurs during synchronization.

Interfaces

  • MobileVB ULSyncResult class

  • ActiveX ULSyncResult class

  • UltraLite.NET See ianywhere.UltraLite.SyncResult.

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See stream_error synchronization parameter.

  • Static Java API This feature is not available in static Java.

  • UltraLite for M-Business Anywhere See Class SyncResult.


Stream Type synchronization parameter

Function

Set the MobiLink network protocol to use for synchronization.

Most network protocols require protocol options to identify the MobiLink synchronization server address and other behavior. These options are supplied in the stream_parms parameter.

For more information, see Stream Parameters synchronization parameter.

Default

This parameter is required. It has no default value.

Usage

When the network protocol requires an option, pass that option using the Stream Parameters parameter; otherwise, set the Stream Parameters parameter to null.

The following stream functions are available, but not all are available on all target platforms:

Network protocol Description
ActiveSync ActiveSync synchronization (Windows CE only).

For a list of protocol options, see ActiveSync protocol options.
HTTP Synchronize via HTTP.

The HTTP protocol uses TCP/IP as its underlying transport. UltraLite applications act as Web browsers and the MobiLink synchronization server acts as a Web server. UltraLite applications send POST requests to send data to the server and GET requests to read data from the server.

For a list of protocol options, see HTTP protocol options.
HTTPS and HTTPS_FIPS Synchronize via the HTTPS protocol.

The HTTPS protocol uses SSL or TLS as its underlying protocol. It operates over Internet protocols (HTTP and TCP/IP).

The HTTPS protocol requires the use of technology supplied by Certicom. Use of Certicom technology requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations. For more information, see Separately-licensable components.

For a list of protocol options, see HTTPS protocol options.
TCP/IP Synchronize via TCP/IP.

For a list of protocol options, see TCP/IP protocol options.
UlSecureSocketStream() TCP/IP or HTTP synchronization with transport-layer security using elliptic curve encryption. This stream is available for static Java applications only.

For a list of protocol options, see UlSecureSocketStream synchronization parameters.
UlSecureRSASocketStream() TCP/IP or HTTP synchronization with transport-layer security using RSA encryption. This stream is available for static Java applications only.

For a list of protocol options, see UlSecureSocketStream synchronization parameters.
Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See Stream property (iAnywhere.Data.UltraLite namespace) and Stream property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See stream synchronization parameter.

  • Static Java API See stream synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Stream Parameters synchronization parameter

Function

Sets options to configure the network protocol.

A semi-colon separated list of network protocol options. Each option is of the form keyword=value, where the allowed sets of keywords depends on the network protocol.

For a list of available options for each protocol, see the following sections:

  • ActiveSync protocol options

  • HotSync protocol options

  • HTTP protocol options

  • HTTPS protocol options

  • TCP/IP protocol options

  • UlSecureRSASocketStream synchronization parameters

  • UlSecureSocketStream synchronization parameters

Default

The parameter is optional, is a string, and by default is null.

See also

Network protocol options for UltraLite synchronization clients.

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See StreamParms property (iAnywhere.Data.UltraLite namespace) and StreamParms property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See stream_parms synchronization parameter.

  • Static Java API See stream_parms synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Sync Result synchronization parameter

Function

Reports the status of a synchronization.

Applies To

This parameter applies only to the UltraLite components.

The C/C++ interfaces receive this information in separate parameters.

Communications error information is not available for UltraLite static Java applications.

Default

The parameter is set by the MobiLink synchronization server, and so is read-only. It is set only if a communication error occurs during synchronization.

Remarks

Sync Result is a compound parameter containing a variety of information in separate fields:

  • Authentication Status Reports success or failure of authentication. See Authentication Status synchronization parameter.

  • Ignored Rows Reports the number of ignored rows. See Ignored Rows synchronization parameter.

  • Stream Error information The Stream Error information includes a Stream Error Code, Stream Error Context, Stream Error ID, and Stream Error System.

  • Upload OK Reports the success or failure of the upload phase. See Upload OK synchronization parameter.

Interfaces

  • MobileVB ULSyncResult class

  • ActiveX ULSyncResult class

  • UltraLite.NET See ULSyncResult class (iAnywhere.Data.UltraLite namespace) and SyncResult class (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL,, Static C++ API See stream_error synchronization parameter.

  • Static Java API This feature is not available in static Java.

  • UltraLite for M-Business Anywhere See Class SyncResult.


Upload OK synchronization parameter

Function

Reports the status of data uploaded to the MobiLink synchronization server.

Usage

The MobiLink synchronization server sets this parameter, and so it is read-only.

After synchronization, the parameter holds true if the upload was successful, and false otherwise. You can check this parameter if there was a synchronization error, to know whether data was successfully uploaded before the error occurred.

Interfaces

  • MobileVB ULSyncResult class

  • ActiveX ULSyncResult class

  • UltraLite.NET See UploadOK property (iAnywhere.Data.UltraLite namespace) and UploadOK property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See upload_ok synchronization parameter.

  • Static Java API See upload_ok synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncResult.


Upload Only synchronization parameter

Function

Indicates that there should be no downloads in the current synchronization, which can save communication time, especially over slow communication links. When set to true, the client waits for the upload acknowledgement from the MobiLink synchronization server, after which it terminates the synchronization session successfully.

Default

The parameter is an optional Boolean value, and by default is false.

See also

Synchronizing high-priority changes

Download Only synchronization parameter

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See UploadOnly property (iAnywhere.Data.UltraLite namespace) and UploadOnly property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See upload_only synchronization parameter.

  • Static Java API See upload_only synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncParms.


User Data synchronization parameter

Function

Make application-specific information available to the synchronization observer.

Usage

When implementing the synchronization observer callback function or event handler, you can make application-specific information available by providing information using the User Data parameter.

Some components, such as UltraLite.NET, do not require a separate parameter to handle user data and so have no User Data parameter.

See also

Observer synchronization parameter

Interfaces

  • MobileVB ULConnection class

  • ActiveX ULDatabaseManager class

  • Native UltraLite for Java See ianywhere.native_ultralite.Connection in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See user_data synchronization parameter.

  • Static Java API See user_data synchronization parameter.


User Name synchronization parameter

Function

A string specifying the user name that uniquely identifies the MobiLink client to the MobiLink synchronization server. MobiLink uses this value to determine the download content, to record the synchronization state, and to recover from interruptions during synchronization.

Default

The parameter has no default value, and must be explicitly set.

Usage

The user name is required unless the MobiLink synchronization server is being run with user authentication turned off. For more information, see -zu option.

See also

Authenticating MobiLink Users.

MobiLink users.

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See UserName property (iAnywhere.Data.UltraLite namespace) and UserName property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See user_name synchronization parameter.

  • Static Java API See user_name synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Version synchronization parameter

Function

Each synchronization script in the consolidated database is marked with a version string. For example, there may be two different download_cursor scripts, identified by different version strings. The version string allows an UltraLite application to choose from a set of synchronization scripts.

Default

This parameter is required and is a string.

See also

Script versions.

Interfaces

  • MobileVB ULSyncParms class

  • ActiveX ULSyncParms class

  • UltraLite.NET See Version property (iAnywhere.Data.UltraLite namespace) and Version property (iAnywhere.UltraLite namespace).

  • Native UltraLite for Java See ianywhere.native_ultralite.SyncParms in the API Reference.

  • C++ Component, embedded SQL, and Static C++ API See version synchronization parameter.

  • Static Java API See version synchronization parameter.

  • UltraLite for M-Business Anywhere See Class SyncParms.


Network protocol options for UltraLite synchronization clients

This section lists the options you can use with each network protocol. The network protocol options provide information such as addressing information (host and port) and protocol-specific information to ensure that the client can locate and properly communicate with the MobiLink synchronization server.

ActiveSync protocol options
HotSync protocol options
TCP/IP protocol options
HTTP protocol options
HTTPS protocol options
UlSecureRSASocketStream synchronization parameters
UlSecureSocketStream synchronization parameters


ActiveSync protocol options

The ActiveSync synchronization stream is accessible only from Native UltraLite for Java, embedded SQL, and static C++ API applications running on Windows CE.

To choose ActiveSync synchronization:

  • In Native UltraLite for Java, supply StreamType.ACTIVE_SYNC as the argument to the syncParms.setStream method. For example:

    _conn.syncParms.setStream( StreamType.ACTIVE_SYNC );

    For more information, see ianywhere.native_ultralite.StreamType and ianywhere.native_ultralite.SyncParms in the Native UltraLite for Java API Reference.

  • In embedded SQL and the static C++ API, supply ULActiveSyncStream() as the network protocol. For example:

    ul_synch_info info;
...
info.stream = ULActiveSyncStream();

    For more information, see ULActiveSyncStream function.

Meaning of protocol options

The protocol options control the connection from the MobiLink ActiveSync provider, running on the desktop machine, to the MobiLink synchronization server.

The protocol options take the following form:

stream=stream_name;provider_stream_parameters

where stream_name indicates the protocol for the conduit to use when communicating from the conduit to the MobiLink synchronization server. It must be one of the following:

  • tcpip

  • http

  • https

and where provider_stream_parameters is a set of protocol options for use by the ActiveSync provider, and has the same form as the protocol options for the protocol in use. For the given protocol, the provider_stream_parameters adopts the same defaults as the protocol options for the protocol. The default value for the stream_name is tcpip.

For example, the following static C++ code uses an HTTP protocol:

ULInitSynchInfo( &info );
info.stream = ULActiveSyncStream();
info.stream_parms = "stream=http";
ULSynchronize( &sqlca, &info );

For more information on provider_stream_parameters, see TCP/IP protocol options, HTTP protocol options, and HTTPS protocol options.

Adding encryption to ActiveSync synchronization

To add Certicom encryption to the stream, the root certificates must be in a file on the desktop machine. This is different from other UltraLite applications, where the encryption information is embedded in the security synchronization parameter.

The protocol options need to be specified in much the same way as for Adaptive Server Anywhere MobiLink clients . The format is:

security=cipher{ keyword=value;... }

where cipher must be certicom_tls and the keywords are taken from the following list:

  • certificate_company The organization field on the certificate.

  • certificate_unit The organization unit field on the certificate.

  • certificate_name The common name field on the certificate.

  • trusted_certificates The location of the trusted certificates.

For example, a static C++ application may use a line such as the following:

info.stream_parms = "stream=tcpip;security=ecc_tls(trusted_certificates=trusted.crt)";

For more information, see:

  • certificate_company
  • certificate_name
  • certificate_unit
  • trusted_certificates


HotSync protocol options

The HotSync synchronization stream is accessible only from UltraLite for MobileVB applications, embedded SQL applications, and static C++ API applications running on the Palm Computing Platform. Unlike HTTP or TCP/IP synchronization, HotSync synchronization is initiated externally by the HotSync Manager, rather than by a synchronization function within the UltraLite application.

To choose HotSync synchronization:

  • In UltraLite for MobileVB, choose ulPalmConduit from the ULStreamType enumeration as the ULSyncParms.Stream.

    For more information, see ULSyncParms class.

  • In embedded SQL or the static C++ API, supply the ul_synch_info structure to the ULSetSynchInfo method of your application. The stream parameter is ignored and may be set to UL_NULL.

    For more information, see ULSetSynchInfo function.

Meaning of protocol options

For HotSync synchronization, the protocol options do not control the connection from the device to the HotSync Manager or HotSync Server. Instead, they specify the connection from the MobiLink conduit, running at the HotSync manager or server, to the MobiLink synchronization server.

The argument has the following form:

stream=stream_name;conduit_stream_parameters

where stream_name indicates the protocol for the conduit to use when communicating from the conduit to the MobiLink synchronization server. It must be one of the following:

  • tcpip

  • http

  • https

and where conduit_stream_parameters is a set of protocol options for use by the conduit, and has the same form as the stream_parms argument for the protocol in use. For the given stream, the conduit_stream_parameters adopts the same defaults as the stream_parms argument for the protocol. The default value for the stream_name is tcpip.

For example, the following embedded SQL code uses an HTTP synchronization stream:

ULInitSynchInfo( &info );
info.stream_parms = "stream=http";

For more information on conduit_stream_parameters, see TCP/IP protocol options, HTTP protocol options, and HTTPS protocol options.

Null value and default settings

If you use HotSync synchronization, and do not supply protocol options, the conduit searches in the registry for the protocol name and protocol options. If it finds no valid network protocol, the default protocol and protocol options are used. This default stream parameter setting is:

stream=tcpip;host=localhost
Adding encryption to HotSync synchronization

To add Certicom encryption to the stream, the root certificates must be in a file on the desktop machine. This is different from other UltraLite applications, where the encryption information is embedded in the security synchronization parameter.

The protocol options need to be specified in much the same way as for Adaptive Server Anywhere MobiLink clients . The format is:

security=cipher{ keyword=value;... }

where cipher must be certicom_tls and the keywords are taken from the following list:

  • certificate_company The organization field on the certificate.

  • certificate_unit The organization unit field on the certificate.

  • certificate_name The common name field on the certificate.

  • trusted_certificates The location of the trusted certificates.

For example, in a static C++ application:

info.stream_parms = "stream=tcpip;security=ecc_tls(trusted_certificates=trusted.crt)";

For more information, see:

  • certificate_company
  • certificate_name
  • certificate_unit
  • trusted_certificates


TCP/IP protocol options

The TCP/IP synchronization stream is accessible from all UltraLite interfaces.

Selecting the TCP/IP synchronization stream

To select TCP/IP as the synchronization stream:

  • In UltraLite for MobileVB and UltraLite ActiveX, choose ulTCPIP from the ULStreamType enumeration as the ULSyncParms.Stream.

    For more information, see ULSyncParms class and ULSyncParms class.

  • In Native UltraLite for Java, supply StreamType.TCPIP as the argument for SyncParms.setStream().

    For more information, see ianywhere.native_ultralite.StreamType and ianywhere.native_ultralite.SyncParms in the Native UltraLite for Java API Reference.

  • In embedded SQL or the static C++ API, supply ULSocketStream() as the stream synchronization parameter.

    For more information, see ULSocketStream function.

  • In the static Java API, supply UlSocketStream as the argument for UlSynchOptions.setStream(). For example:

    UlSynchOptions opts = new UlSynchOptions;
opts.setStream(new UlSocketStream() );

    For more information, see stream synchronization parameter.

Protocol options

When you use the TCP/IP protocol, you can choose from the following protocol options:

Parameter | For more information, see...
client_port= nnnnn[-mmmmm] | client_port
host=hostname | host
liveness_timeout=n | liveness_timeout
network_connect_timeout=seconds | network_connect_timeout
network_leave_open={0|1} | network_leave_open
network_name=name | network_name
port=portnumber | port


HTTP protocol options

The HTTP synchronization stream is accessible from all UltraLite components.

Selecting the HTTP synchronization stream

To select HTTP as the synchronization stream:

  • In UltraLite for MobileVB and UltraLite for ActiveX, choose ulHTTP from the ULStreamType enumeration as the ULSyncParms.Stream.

    For more information, see ULSyncParms class.

  • In Native UltraLite for Java, supply StreamType.HTTP as the argument for SyncParms.setStream().

    For more information, see ianywhere.native_ultralite.StreamType and ianywhere.native_ultralite.SyncParms in the Native UltraLite for Java API Reference.

  • In embedded SQL or the static C++ API, supply ULHTTPStream() as the stream synchronization parameter.

    For more information, see ULHTTPStream function.

Protocol options

When you use the HTTP stream, you can choose from the following protocol options:

Parameter | For more information, see...
buffer_size=nnnn | buffer_size
client_port= nnnnn[-mmmmm] | client_port
custom_header=header | custom_header
host=hostname | host
network_connect_timeout=seconds | network_connect_timeout
network_leave_open={0|1} | network_leave_open
network_name=name | network_name
persistent={0|1} | persistent
port=portnumber | port
proxy_host=proxy_hostname | proxy_host
proxy_port= proxy_portnumber | proxy_port
set_cookie=cookie_name=cookie_value | set_cookie
url_suffix=suffix | url_suffix
version=versionnumber | version
See also

Configuring MobiLink clients and servers for the Redirector


HTTPS protocol options

The HTTPS synchronization stream is accessible from all UltraLite components.

Selecting the HTTPS synchronization stream

To select HTTPS as the synchronization stream:

  • In UltraLite for MobileVB and UltraLite for eMbedded Visual Basic, choose ulHTTPS from the ULStreamType enumeration as the ULSyncParms.Stream.

    For more information, see ULSyncParms class.

  • In Native UltraLite for Java, supply StreamType.HTTPS as the argument for SyncParms.setStream().

    For more information, see ianywhere.native_ultralite.StreamType and ianywhere.native_ultralite.SyncParms in the Native UltraLite for Java API Reference.

  • In embedded SQL or the static C++ API, supply ULHTTPSStream() as the stream synchronization parameter.

    For more information, see ULHTTPSStream function.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Protocol options

When you use the HTTPS stream, you can choose from the following protocol options:

Parameter | For more information, see...
buffer_size=nnnn | buffer_size
certificate_company=company_name | certificate_company
certificate_name=name | certificate_name
certificate_unit=company_unit | certificate_unit
client_port= nnnnn[-mmmmm] | client_port
custom_header=header | custom_header
host=hostname | host
network_connect_timeout=seconds | network_connect_timeout
network_leave_open={0|1} | network_leave_open
network_name=name | network_name
persistent={0|1} | persistent
port=portnumber | port
proxy_host=proxy_hostname | proxy_host
proxy_port=proxy_portnumber | proxy_port
set_cookie=cookie_name=cookie_value | set_cookie
trusted_certificates=filename | trusted_certificates
url_suffix=suffix | url_suffix
version=versionnumber | version
See also
  • Configuring UltraLite clients to use transport-layer security
  • Configuring MobiLink clients and servers for the Redirector


UlSecureRSASocketStream synchronization parameters

Transport-layer security using Certicom RSA encryption is accessed from static Java applications as a separate stream, accessed using the UlSecureRSASocketStream object. This is different behavior from other UltraLite applications, where a separate parameter is supplied to the synchronization structure.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Protocol options

The parameters for the UlSecureSocketStream are supplied in a semicolon-separated string. When you use UlSecureRSASocketStream, you can choose from the following protocol options:

Parameter | Description
certificate_company=company_name | certificate_company
certificate_name=name | certificate_name
certificate_unit=company_unit | certificate_unit
client_port= nnnnn[-mmmmm] | client_port
host=hostname | host
liveness_timeout=n | liveness_timeout
port=portnumber | port


UlSecureSocketStream synchronization parameters

Transport-layer security using Certicom elliptic-curve encryption is accessed from static Java applications as a separate stream, accessed using the UlSecureSocketStream object.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

For more information, see stream synchronization parameter, and Using transport-layer security.

Protocol options

The parameters for the UlSecureSocketStream are supplied in a semicolon-separated string. When you use UlSecureRSASocketStream, you can choose from the following protocol options:

Parameter | Description
certificate_company=company_name | certificate_company
certificate_name=name | certificate_name
certificate_unit=company_unit | certificate_unit
client_port= nnnnn[-mmmmm] | client_port
host=hostname | host
liveness_timeout=n | liveness_timeout
port=portnumber | port


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Server-Initiated Synchronization User's Guide

Version 9.0.2

DC20056-01-0902-01

October 2004

Copyright
About This Manual
Introducing Server-Initiated Synchronization
Setting Up Server-Initiated Synchronization
The Listener
Listeners for Palm Devices
MobiLink Notification Properties
Server-Initiated Synchronization Stored Procedures
MobiLink Listener SDKs
Tutorial: Server-Initiated Synchronization


About This Manual

Subject

This manual describes MobiLink server-initiated synchronization, a feature of MobiLink that allows you to initiate synchronization or other remote actions from the consolidated database.

Audience

This manual is for MobiLink users who wish to use this advanced feature.

Before you begin

For more information about MobiLink, see Introducing MobiLink Synchronization.


Finding out more and providing feedback

Finding out more

Additional information and resources, including a code exchange, are available at the iAnywhere Developer Network at [external link] http://www.ianywhere.com/developer/.

If you have questions or need help, you can post messages to the iAnywhere Solutions newsgroups listed below.

When you write to one of these newsgroups, always provide detailed information about your problem, including the build number of your version of SQL Anywhere Studio. You can find this information by typing dbeng9 -v at a command prompt.

The newsgroups are located on the forums.sybase.com news server. The newsgroups include the following:

  • [external link] sybase.public.sqlanywhere.general

  • [external link] sybase.public.sqlanywhere.linux

  • [external link] sybase.public.sqlanywhere.mobilink

  • [external link] sybase.public.sqlanywhere.product_futures_discussion

  • [external link] sybase.public.sqlanywhere.replication

  • [external link] sybase.public.sqlanywhere.ultralite

  • [external link] sybase.public.sqlanywhere.qanywhere

  • [external link] ianywhere.public.sqlanywhere.qanywhere

Newsgroup disclaimer
iAnywhere Solutions has no obligation to provide solutions, information or ideas on its newsgroups, nor is iAnywhere Solutions obliged to provide anything other than a systems operator to monitor the service and ensure its operation and availability.

iAnywhere Solutions Technical Advisors as well as other staff assist on the newsgroup service when they have time available. They offer their help on a volunteer basis and may not be available on a regular basis to provide solutions and information. Their ability to help is based on their workload.

Feedback

We would like to receive your opinions, suggestions, and feedback on this documentation.

You can e-mail comments and suggestions to the SQL Anywhere documentation team at [external link] iasdoc@ianywhere.com. Although we do not reply to e-mails sent to that address, we read all suggestions with interest.

In addition, you can provide feedback on the documentation and the software through the newsgroups listed above.


Introducing Server-Initiated Synchronization

About this chapter

This chapter provides an overview of server-initiated synchronization.

Introduction to server-initiated synchronization
Components of server-initiated synchronization
Supported platforms
Deployment considerations
Quick start


Introduction to server-initiated synchronization

Server-initiated synchronization allows you to initiate MobiLink synchronization from the consolidated database. This means you can push data updates to remote databases, as well as cause remote databases to upload data to the consolidated database. This MobiLink component provides programmable options for determining what changes in the consolidated database initiate synchronization, how remotes are chosen to receive push messages, and how the remotes respond.

Example

For example, a fleet of truck drivers uses mobile databases to determine routes and delivery points. A driver synchronizes a report of a traffic disruption. A component called the Notifier detects the change in the consolidated database and automatically sends a message to the remote device of every driver whose route is affected, which causes the drivers' remote databases to synchronize so that the drivers will use an alternate route.

The notification process

In the following illustration, the Notifier polls a consolidated database and detects a change that it has been configured to look for. In this scenario, the Notifier sends a message to a single remote device, resulting in the remote database being updated via synchronization.

The process of server-initiated synchronization.

Following are the steps that occur in this example:

  1. Using a query based on business logic, the Notifier polls the consolidated database to detect any change that needs to be synchronized to the remote.

  2. When a change is detected, the Notifier prepares a message to send to the remote device.

  3. The Notifier sends a message using UDP or SMTP.

  4. The Listener checks the subject, content, and sender of the message against a filter.

  5. If the message matches the filter, the Listener runs a program that has been associated with the filter. For example, the Listener runs dbmlsync or it launches an UltraLite application.

Connection-initiated synchronization

In addition to initiating synchronization on the server, you can also initiate synchronization using internal messages that are generated by the Listener on the remote device. These internal messages indicate a change in connectivity, such as when a device enters Wi-Fi coverage, the user makes a RAS connection, or the user puts the device in the cradle.

For more information, see Connection-initiated synchronization.


Components of server-initiated synchronization

MobiLink server-initiated synchronization uses the following components:

  • Push requests cause synchronization to occur. A push request takes the form of some data that you insert into a table on the MobiLink consolidated database, or in some cases data inserted into a temporary table or even just a SQL result set. You can create push requests in any way that you cause data to be inserted into a table. For example, a push request could be created by a database trigger that is activated when a price changes. Any database application can create push requests, including the Notifier.

    For more information, see Push requests.

  • The Notifier is a Java program running on the same computer as the MobiLink synchronization server. It polls the consolidated database on a regular basis, looking for push requests. You control how often the Notifier polls the database. You specify business logic that the Notifier uses to gather push requests, including which remote devices should be notified. When the Notifier detects a request, it sends the message associated with the request via SMTP or UDP to a Listener on one or more remote devices. You have the option to send repeatable messages with an expiry time.

    For more information about Notifiers, see Notifiers.

  • The Listener is a program that is installed on each remote device. It receives messages from the Notifier and initiates action. The action is usually synchronization, but can be other things. You can configure the Listener to act only on messages from selected sources, or with specific content.

    On Windows or Windows CE, the Listener is an executable program configured by command line options. In order to receive a message, the remote device must be on and the Listener must be started.

    For more information, see The Listener.

    On the Palm OS, you first create a configuration file by running the Palm Listener Configuration utility on a Windows desktop. You then copy the configuration file to your Palm device and run the Palm Listener.

    For more information, see Listeners for Palm Devices.

  • Gateways provide an interface to send messages from the Notifier to the Listener. You can send messages using an SMTP gateway or a UDP gateway. When you use an SMTP gateway, you send an e-mail message that your carrier converts into SMS before the Listener receives it. Most carriers provide an e-mail-to-SMS service.

    Device tracking gateways provide a way to automatically track remote devices. Using device tracking functionality, you don't have to know the addresses of remote devices. You supply the gateway name of your device tracker gateway (by default, Default-DeviceTracker) and the MobiLink user name, and MobiLink routes the message through the appropriate gateway to the appropriate device.

    For more information, see Gateways and carriers.


Supported platforms

In addition to MobiLink requirements, the computer must have JRE 1.4.1 or higher to use the Notifier.

For more information about MobiLink requirements, see SQL Anywhere Studio Supported Platforms.

The Listener is not supported on Windows 95 or Windows NT 4.

If you are targeting Palm remotes, you must use the Palm Listener Configuration utility on a Windows desktop device to create a configuration file.

  • SMS messages can be transmitted through an SMTP gateway and go through an e-mail-to-SMS conversion that is provided by wireless carriers. This has been tested on the following platforms:

    • Pocket PC 2002 with Sierra Wireless AirCard 510, 555, 710, or 750

    • Windows 2000 and XP with the Sierra Wireless AirCard 510, 555, 710, or 750

    • Palm 4.1 on the Kyocera 7135 and Palm 5.2 on the Treo 600

  • UDP messages have been tested on the following platforms:

    • Pocket PC 2002

    • Windows 2000 and XP

The supported AirCards are supported for the following firmware and drivers. (710 is compatible with 750.)

AirCard | Firmware version | Driver version
510 | R1-3-4 | Not applicable
555 | R1_1_2_10AC_GEN | R1_0_0_9ac_1xRTT
750 | R1_1_2_10AC_GEN | R1_0_7_ac_gprs
750 | R3_1_17ACAP | R1_0_9_ac_gprs


Deployment considerations

Following are some issues that you should consider before deploying server-initiated synchronization applications.

Limitations of Listeners when using UDP gateways

  • On UDP gateways, the Listener keeps a socket open for listening, and so must be connected to an IP network to be able to listen.

  • The IP address on the remote device needs to be reachable from the MobiLink synchronization server.

Limitations of Listeners on CE or PCs

  • The current set of supported wireless modems require that the operating system is running, which could result in battery drain. Make sure that you have enough power for your usage pattern.

Palm Listeners can't automatically use device tracking

  • On the Palm, device tracking does not work automatically. However, there is a way to enable it.

    For more information, see Using device tracking with Listeners that don't support it.


Quick start

To set up server-initiated synchronization, you should perform the following steps. This assumes that MobiLink synchronization is already set up.

toggle Overview of setting up server-initiated synchronization

  1. Create a table to store push requests on the consolidated database.

    See Push requests.

  2. Set up the Notifier to create and manage push requests.

    See Notifiers.

  3. Set up the Listener to filter and act on Notifier push requests.

    See Listeners.

  4. If you are sending SMS notifications, configure gateways and carriers to identify the interface you are using to send messages. (If you are using UDP, you may be able to skip this step and send messages via the default settings.) To send SMS notifications, you must also specify SMTP listening libraries when you start the Listener.

    See Gateways and carriers and Listening libraries.

Other resources for getting started
  • Tutorial: Server-Initiated Synchronization
  • Sample applications are installed to Samples\MobiLink\SIS_* in your SQL Anywhere Studio installation directory.


Setting Up Server-Initiated Synchronization

About this chapter

This chapter describes how to set up and use server-initiated synchronization.


Push requests

A push request takes the form of some data that you insert into a table on the MobiLink consolidated database, or in some cases data inserted into a temporary table or even just a SQL result set. You can create push requests in any way that you cause data to be inserted into a table.

The Notifier sends a message to a remote database when it detects a push request. The push request specifies the content of the message, along with when, how, and to whom the message should be sent.


Creating the push request table

A push request is a row in a SQL result set on the consolidated database that contains the following columns in the following order. The first five columns are required and the last two columns are optional. The Notifier uses the request_cursor property to fetch push requests.

In a typical implementation, you add a table to your consolidated database with the following columns. However, push requests can also be stored in temporary tables and across multiple tables.

Column | Description
request id | INTEGER. A unique ID for a push request.
gateway | VARCHAR. The gateway on which to send the message. This can be a predefined or user-defined gateway. Predefined gateways are Default-DeviceTracker, Default-SMTP, and Default-UDP.
subject | VARCHAR. The subject line of the message.
content | VARCHAR. The content of the message.
address | VARCHAR. The destination address. The format of the address is gateway-specific. For a DeviceTracker gateway (which might use either SMTP or UDP), it is the MobiLink user name of the Listener database, or other MobiLink user names that you register using dblsn -t+. For an SMTP gateway, it is an email address. For a UDP gateway, it is an IP address or host name, optionally followed by a colon and port number.
resend interval | VARCHAR. Optional. How often the message should be resent. The default unit is minutes. You can specify S, M, and H for units of seconds, minutes, and hours. You can also combine units, as in 1H 30M 10S. The resend interval is especially useful when the remote device is listening for UDP and the network is unreliable. The Notifier assumes that all attributes associated with a resendable notification request do not change: subsequent updates are ignored after the first poll of the request. The Notifier automatically adjusts the next polling interval if a resendable notification must be sent before the next polling time. You can stop a resendable notification using the request_cursor query or by deleting the request from the request table. The default is to send exactly once, with no resend. Delivery confirmation from the intended Listener may stop a subsequent resend.
time to live | VARCHAR. Optional. The time until the resend expires. The default unit is minutes. You can specify S, M, and H for units of seconds, minutes, and hours. You can also combine units, as in 1H 30M 10S. If this value is 0, NULL, or not specified, the default is to send exactly once, with no resend.

For more information about addressing notifications when you are using device tracking, see Listener options for device tracking.

Example

Following is an Adaptive Server Anywhere CREATE TABLE statement that creates a push request table.

create table PushRequest (
    req_id   integer default autoincrement primary key,
    gateway   varchar(128),
    subject   varchar(128),
    content   varchar(128),
    address   varchar(128),
    resend_minute varchar(30),
    minute_to_live varchar(30)
)

The following code uses the ml_add_property stored procedure to create a request_cursor property that creates the push request.

call ml_add_property( 'SIS', 'Notifier(Simple)', 'request_cursor',
  'select req_id,
          gateway,
            subject,
            content,
            address,
            resend_minute,
          minute_to_live
   from PushRequest' );


Creating push requests

You can create push requests in any way that you cause data to be inserted into a table. Following is a list of common ways to create push requests:

  • Specify SQL synchronization logic in Notifier properties. The most obvious property for creating push requests is the begin_poll property.

    A benefit of creating push requests inside the Notifier is that contention is minimized because only one database connection is used for push requests.

    For more information, see begin_poll property.

  • Define a database trigger. For example, create a trigger that detects when a price changes and then inserts push request data into a table of push requests.

    For information about triggers, see Introduction to triggers.

  • Use MobiLink synchronization logic to create push requests that notify other MobiLink users. For example, create an end_upload script that detects that a specific change has been uploaded and then creates a push request to update other users who should have the same data.

    For more information, see end_upload table event.

  • Use a database client application that inserts data into a push request table directly.

  • Manually insert push request data using an Interactive SQL utility.


Sending push requests

The Notifier sends a set of push requests to remote devices by executing a SQL query that you provide in the request_cursor property.

For more information about querying the consolidated database, see request_cursor property.


Deleting push requests

You delete push requests to prevent resending old messages. Deleting requests in a timely manner can help minimize the number of messages sent and increase the efficiency of the application.

The most straightforward way to delete push requests is to use the Notifier property request_delete. This property is a SQL statement with a request ID as a parameter. Using this statement, the Notifier deletes requests that have been confirmed as delivered or that have expired.

For more information, see request_delete property.

Built-in delivery confirmation is not available on Palm devices; on all devices, it can be disabled. You can optionally implement your own delivery-confirmation mechanism. For example, your synchronization logic can delete push requests from a request table when a specific synchronization occurs.


Notifying the Listener with sa_send_udp

Adaptive Server Anywhere databases include a system stored procedure called sa_send_udp that can be used to send UDP notifications to the Listener.

If you use sa_send_udp as a way to notify the Listener, you should append a 1 to your UDP packet. This number is a server-initiated synchronization protocol number. In future versions of MobiLink, new protocol versions may cause the Listener to behave differently.

For more information, see sa_send_udp system procedure.

Example

On a device, start the Listener as follows, where path is the location of your Internet Explorer program:

dblsn -v -l "message=TheMessage;action=start 'path\iexplore.exe' http://www.yahoo.com"

On a different device, start an Adaptive Server Anywhere database. Start Interactive SQL, and connect to the database. Execute the following SQL. (Note that the UDP packet has a 1 appended to it.)

call sa_send_udp('machine#1_ip_name',5001,'TheMessage1')

Internet Explorer will open, showing the Yahoo home page.

To make this example work with one device, use localhost as the first paramter to sa_send_udp.


Setting properties

Notifiers, gateways, and carriers are configured via properties. These properties can be stored in the ml_property MobiLink system table or in a Notifier properties file.

Storing properties in the database

You have two options to configure properties in the MobiLink system table:

  • Use the Notification folder in the MobiLink plug-in in Sybase Central. This stores property settings in the ml_property table on the consolidated database. You can also right-click the Notification folder in Sybase Central and choose to export settings to a Notifier properties file, or import settings from a Notifier properties file.

    For more information, click Help on the Sybase Central Notifier dialogs.

  • Use the ml_add_property stored procedure. This also stores configuration information in the ml_property table on the consolidated database.

    For more information, see ml_add_property.

Storing properties in a properties file

Alternatively, you can store options in a Notifier properties file. This is a text file that you can edit with a text editor.

For more information, see Notifier properties file.

Properties

For a detailed list of the properties you can set, see

  • MobiLink Notification Properties

  • Device tracker gateway properties

  • SMTP gateway properties

  • UDP gateway properties

  • Carrier properties

Setting properties in more than one place

If you specify properties in both the ml_properties table and the Notifier properties file, the settings are determined as follows:

  1. Server-initiated synchronization properties in the ml_property table in the consolidated database are loaded.

  2. If a Notifier properties file is specified with the -notifier option, the settings in this file are loaded on top of the settings from the database.

    If a Notifier properties file is not specified, and if the default configuration file is found (config.notifier), the settings in the default file are loaded on top of the settings from the database.

Changing properties

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

Notifier properties file


Notifier properties file

Properties for Notifiers, gateways, and carriers can be stored in the ml_property MobiLink system table or in the Notifier properties file. For more information, see Setting properties.

The Notifier properties file is a text file. It can have any name. The easiest way to create this file is to alter the template, %asany9%\samples\MobiLink\template.notifier.

You can export the properties from the ml_property table into your Notifier properties file. To do this, connect to the MobiLink plug-in in Sybase Central, right-click the Notification folder, and choose Export Settings. The exported file may be copied to a different location and used to easily configure a Notifier there.

You can have several Notifier property files. To identify the properties file you want to use, specify the name and location when you start dbmlsrv9 with the -notifier option. Following is a partial dbmlsrv9 command line:

dbmlsrv9 ... -notifier "c:\samples\CarDealer.notifier"

For information about how properties are read if you do specify a properties file at the command line, see Setting properties in more than one place.

A Notifier properties file can configure and start multiple Notifiers and multiple gateways. You provide a name for each Notifier and gateway that you want to define.

Notifier properties are normally entered on one line, but you can use the backslash ( \ ) as a line continuation character.

The backslash is also an escape character. You can use the following escape sequences in your property settings:

Escape sequence | Description
\b | \u0008: backspace, BS
\t | \u0009: horizontal tab, HT
\n | \u000a: linefeed, LF
\f | \u000c: form feed, FF
\r | \u000d: carriage return, CR
\" | \u0022: double quote, "
\' | \u0027: single quote, '
\\ | \u005c: backslash, \
\uhhhh | Unicode character (hexadecimal)
\xhh | \xhh: ASCII character (hexadecimal)
\e | \u001b: Escape, ESC


Notifiers

The Notifier runs on the same computer as the MobiLink synchronization server. The Notifier polls the consolidated database on a regular basis, looking for push requests. When it detects a push request, it sends a message to a remote device. It also contains functionality for executing custom SQL scripts, handling delivery confirmation, deleting push requests, and reconnecting after lost database connections. You may use the custom SQL scripts to monitor your data and create push requests.

You can have more than one Notifier running within a single instance of the MobiLink synchronization server. Each Notifier keeps one database connection open all the time.

For an example of multiple Notifiers, see the sample located in the Samples\MobiLink\SIS_MultipleNotifier subdirectory of your SQL Anywhere Studio installation.


Starting the Notifier

You start Notifiers on the dbmlsrv9 command line. To start the Notifier, use the dbmlsrv9 option -notifier. Optionally, you can also specify the name of your Notifier properties file, if you have one.

Following is a partial dbmlsrv9 command line:

dbmlsrv9 ... -notifier c:\myfirst.notifier

For information about how properties are read if you specify a properties file in the command line, see Setting properties in more than one place.

For information about how properties are applied, see Setting properties.

For more information about the -notifier option, see -notifier option.

When you use the -notifier option, you start every Notifier that you have enabled. For more information about enabling Notifiers, see enable property.


Configuring Notifiers

The Notifier allows you to create custom SQL to program the server-initiated synchronization process. You do this by setting properties. For example, you would configure properties in order to perform tasks such as the following:

  • Set a polling interval using the poll_every property.

  • Create push requests in response to changes in the consolidated database. The begin_poll property is often used in this way.

  • Use the request_cursor property to determine what information is sent in a message, to whom, where, and when.

    Note: The request_cursor property is the only required property. For more information, see request_cursor property.

  • Delete push requests with the request_delete property.

For a complete list of Notifier properties, see MobiLink Notification Properties.

For information about how to set Notifier properties, see Setting properties.

Notifier property sequence

The following pseudo-code shows the sequence in which server-initiated synchronization properties are used. Note that except for request_cursor, all of these properties are optional.

connect_string
isolation
begin_connection
poll_every
For each poll (
  begin_poll
  shutdown_query
  request_cursor
  request_delete
  end_poll
)
end_connection


Gateways and carriers

Gateways are the mechanisms for sending messages. You can define UDP gateways and SMTP gateways. In addition, you can use a device tracker gateway that automatically decides which UDP or SMTP gateway to use.

Use of the device tracker gateway is recommended. If you do not use device tracking, your request_cursor must include a UDP or SMTP gateway name and address, and for each push request, only that gateway will be tried. But if you use device tracking, you only need to supply a MobiLink user name, and there is a possibility of failover if a gateway fails.

For more information, see Device tracking.

If you are using UDP, you may not need to make any changes to the default gateway settings. For SMTP, you need to configure an SMTP gateway and carrier.

You configure carriers to store information about the public wireless carriers that you want to use. Carrier information is used to create SMS e-mail addresses from device tracking information that is sent up from Listeners.

Configuring gateways and carriers


Configuring gateways and carriers

For information about how to set properties for gateways and carriers, see Setting properties.

For a detailed list of gateway and carrier properties, see

  • Device tracker gateway properties

  • UDP gateway properties

  • SMTP gateway properties

  • Carrier properties

Gateways

There are three default gateways. They are installed when you run the MobiLink setup scripts for your consolidated database. The default gateways are called:

  • Default-DeviceTracker gateway

  • Default-UDP gateway

  • Default-SMTP gateway

A device tracker gateway can have up to two subordinate gateways: one SMTP and one UDP. The device tracker gateway automatically routes each message to one of its subordinate gateways based on device tracking information sent up from Listeners. For more information, see Device tracking.

Default-UDP and Default-SMTP are preconfigured with some settings that may work out of the box, especially UDP. In most cases, you should use the default gateways. You can customize their configuration, if required.

You should not delete the default gateways or change their names. You can create additional gateways and assign names to them.

Carriers

You only need to configure a carrier if you are using device tracking with an SMTP gateway. Carrier configuration allows you to specify information such as the name of a network provider, their email prefix, network provider id, and so on. This information is necessary for the Notifier to construct e-mail addresses for each public wireless carrier's e-mail-to-SMS service.

To configure a carrier, you can run the Listener on a device that has a modem and service provider working, and inspect the Listener console or log. If your Listener uses the -x option to connect to a running MobiLink synchronization server, you can also find carrier device tracking information in the ml_device_address MobiLink system table.

Once a carrier is configured, it requires no further attention. The carrier can be used to send SMS messages via SMTP to all devices using that public wireless carrier.

For a list of carrier properties, see Carrier properties.


Device tracking

Device tracking allows you to address a remote database by supplying only its MobiLink user name in a push request. When device tracking is enabled, MobiLink keeps track of how to reach users. For example, when a device's IP address changes, the Listener synchronizes with the consolidated database to update the device tracking information in the MobiLink system table ml_device_address. The device tracker gateway first attempts to use a UDP gateway (if one is assigned to it), and if the delivery fails it then attempts using an SMTP gateway (if one is assigned to it).

Device tracking is especially useful for UDP addresses that may change frequently; the Listener automatically sends the most recent address to the consolidated database when it changes.

In most cases, you should be able to use device tracking. It is recommended that you use it because it simplifies deployment.

Most 9.0.1 or later Listeners support device tracking. If you are using Listeners that don't support device tracking, you can still use a device tracker gateway by providing tracking information yourself.

For more information, see Using device tracking with Listeners that don't support it.

If you do not use device tracking, your request_cursor must include a UDP or SMTP gateway name and address. For each push request, only that gateway will be used, and no other gateway will be attempted.


Setting up device tracking

toggle To set up device tracking

  1. Set up a UDP gateway and/or SMTP gateway, if necessary. Note: Typically, the UDP gateway is usable without further configuration, and you can skip this step. However, if you want to use e-mail-to-SMS notification, the default SMTP gateway requires configuration.

    See Configuring gateways and carriers.

  2. Your request_cursor script should have the following settings:

    • The gateway name must be the name of a device tracker gateway. The default instance is called Default-DeviceTracker.

    • The address must be a MobiLink user name. By default, it can be the Listener user name. However, you can use the dblsn option -t+ to add the MobiLink user name of the remote database that you are synchronizing, and then directly address that database.

    See request_cursor property.

  3. Add the Listener name to the MobiLink ml_user system table.

    The default Listener name is device_name-dblsn, where device_name is the name of your device. You can find the device name in your Listener console. Optionally, you can set the device name using the dblsn -e option. You can specify a different Listener name using the dblsn -u option.

    Whether or not you use the default name, you may need to add the Listener_name to the ml_user MobiLink system table on your consolidated database. This is because the Listener_name is a MobiLink user name. Like other MobiLink user names, it must be unique and it must be added to the ml_user MobiLink system table on your consolidated database.

    See Creating MobiLink users.

  4. Start the Listener with the required options.

    See Listener options for device tracking.


Listener options for device tracking

The following dblsn options are used for device tracking.

Use -x, -u, and -w to specify how to connect to the MobiLink server. This is required if you are using device tracking so that the remote device can update the consolidated database if the address changes. These are also required if you wish to send delivery confirmations to the consolidated database.

The -t+ option is recommended. With it, you can register the MobiLink user name of your remote database and use it when you address notifications instead of addressing the MobiLink user name of the Listener database. You only need to do this once.

  • -t+ ml_user Use this option to register the MobiLink user name of your remote database so that you can directly address that user name, instead of addressing the Listener database.

    This mapping is retained on the server (in the ml_listening table) once tracking information is uploaded successfully, so you only need to register a MobiLink user name once unless you change the MobiLink user name or location. However, using -t+ multiple times is not harmful.

  • -t- ml_user_alias To disable a MobiLink user name created with -t+, use -t-.

  • -u Listener_name Use -u to create a MobiLink user name for the Listener. The -u option is optional because there is a default Listener_name, which is device_name-dblsn, where device_name is the name of your device. You can find the device name in your Listener console. Optionally, you can set the device name using the -e option.

    Whether or not you use the default name, you may need to add the Listener_name to the ml_user MobiLink system table on your consolidated database. This is because the Listener_name is a MobiLink user name. Like other MobiLink user names, it must be unique and it must be in the ml_user MobiLink system table on your consolidated database.

    See Creating MobiLink users.

  • -w password This option sets the password for the Listener name.

  • -x connection-parameters Use -x to specify how to connect to the MobiLink synchronization server. This is required if you are using device tracking because it lets the remote device update the consolidated database if the address changes. This option is also required if you wish to send delivery confirmations to the consolidated database.

  • -y This option updates the password for the Listener name.

For more information about Listener options, see The Listener utility.

Example

The following command starts the Listener with device tracking.

dblsn -x tcpip(host=MLSERVER_MACHINE) -t+ user1 -u remoteuser1

Stopping device tracking


Stopping device tracking

It might be useful to stop device tracking in situations such as the following:

  • Your device listens only on UDP on a static IP address.

  • Your device listens only on UDP and has dynamic IP with low latency DNS update, so you can use a static IP name to address your device directly.

To stop device tracking when you want to continue using delivery confirmation, use the dblsn option -g.

For more information about dblsn options, see The Listener utility.


Using device tracking with Listeners that don't support it

You cannot use the completely automatic form of device tracking if any of your Listeners have the following characteristics:

  • are prior to Adaptive Server Anywhere 9.0.1 or are Palm Listeners

    For information about how to set up device tracking in these situations, see Manually setting up device tracking.

  • are listening on UDP, and remote IP addresses are unreachable from the MobiLink server machine

    For information about how to deal with this situation, see Unreachable addresses.

Manually setting up device tracking

Several stored procedures are provided to help you manually set up device tracking for 9.0.0 Listeners or Palm Listeners. These stored procedures manipulate the MobiLink system tables ml_device, ml_device_address, and ml_listening on the consolidated database. With manual device tracking, you can address recipients by MobiLink user name—without providing network address information—but the information cannot be automatically updated by MobiLink if it changes: you must change it yourself.

This method is especially useful for SMTP gateways because e-mail addresses don't tend to change. For UDP gateways, it is more difficult to rely on static entries if your IP address changes every time you reconnect. You may get around this problem by addressing by host name instead of IP address, but in that case slow updates to DNS server tables can cause misdirected messages. You can also deal with changing IP addresses by setting up the following stored procedures to update the MobiLink system tables programmatically.

toggle To manually set up device tracking

  1. For each remote device, add a device record to the ml_device MobiLink system table. For example,

    call ml_set_device(
   'myFirstTreo180',
   'MobiLink Listeners for Treo 180 - 9.0.1',
   '1',
   'not used',
   'y',
   'manually entered by administrator' );

    The first parameter, myFirstTreo180, is a user-defined unique device name. The second parameter contains optional remarks about the Listener version. The third parameter, set here to 1, specifies a Listener version; use 0 for Listeners from SQL Anywhere Studio 9.0.0, 1 for post-9.0.0 Palm Listeners, and 2 for post-9.0.0 Windows Listeners. The fourth parameter specifies optional device information. The fifth parameter is set to y here, which specifies that device tracking should be ignored; if this were set to n, device tracking would overwrite this record. The final parameter contains optional remarks on the source of this record.

    For more information about using ml_set_device, see ml_set_device.

  2. For each device that you just added, add an address record to the ml_device_address MobiLink system table. For example,

    call ml_set_device_address(
   'myFirstTreo180',
   'ROGERS AT&T',
   '3211234567',
   'y',
   'y',
   'manually entered by administrator' );

    The first parameter, myFristTreo180, is a user-defined unique device name. The second parameter is a network provider ID, and must match a carrier's network_provider_id property (for more information, see network_provider_id property). The third parameter is the phone number of your SMS-capable device. The fourth parameter, set here to y, activates this record for sending notifications. The fifth parameter, set here to y, specifies that device tracking should be ignored; if this were set to n, device tracking could overwrite this record. The final parameter contains optional remarks on the source of this record.

    For information about how to locate carrier information, see Device tracking.

    For more information about using ml_set_device_address, see ml_set_device_address.

  3. For each remote database, add a recipient record to the ml_listening MobiLink system table for the device that was just added. This maps the device to the MobiLink user name. For example,

    call ml_set_listening(
   'myULDB',
   'myFirstTreo180',
   'y',
   'y',
   'manually entered by administrator' );

    The first parameter is a MobiLink user name. The second parameter is a user-defined unique device name. The third parameter, set here to y, activates this record for device tracking addressing. The fourth parameter, set here to y, specifies that device tracking should be ignored; if this were set to n, device tracking could overwrite this record. The final parameter contains optional remarks on the source of this record.

    For more information, see ml_set_listening.


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Server-Initiated Synchronization User's Guide

Setting Up Server-Initiated Synchronization

Device tracking

Troubleshooting gateways

This section describes some known problems and solutions connected with communication between remote devices and servers.


Unreachable addresses
Symptom

The Notifier cannot reach the device with the tracked IP address.

Cause

Some or all devices cannot be addressed directly because they are private relative to the MobiLink server. For example, a remote device is on a private sub-network and its address is internal to that network.

Remedy

Try one of the following:

  • If the IP address is assigned by a public wireless carrier or ISP, you may be able to upgrade your carrier plan so that you can obtain public IP addresses instead of private ones.

  • If you are using Wi-Fi, the IP security policy in your organization may stop your device from being reachable. Contact your IT department for assistance.

  • Use an SMS gateway.

    If the device's IP address is never reachable, you may want to stop device tracking on the Listener with the -g option. If you are using delivery confirmation, the first attempt to connect will be via UDP, and the lack of confirmation will prevent further UDP attempts.


Tracked address is not correct
Symptom

Device tracking is not picking the best IP address for a device.

Cause

There may be a problem with the routing table on the device.

Remedy

Try one of the following:

  • Fix the routing table.

  • Use the ml_set_device_address stored procedure to ignore tracking for the device and set the address parameter to the correct address. Be sure to set the fourth parameter to y. In addition, use -g for the problematic Listener.

    For more information, see ml_set_device_address.


Listeners

The Listener runs on remote devices. It receives messages from the Notifier and processes them into actions based on message handlers that you create. A typical message handler contains filters, actions, and options.

For example, for the following Listener command line, the Listener will only start dbmlsync if it receives a message with the subject FullSync:

dblsn -l "subject='FullSync';action='run dbmlsync.exe ...'"

Following are some of the actions that you can invoke. Typically, the desired action is synchronization initiated via either dbmlsync or an UltraLite application.

  • Start a process.

  • Run a process until it completes.

  • Post a window message to a process that is already running.

  • Perform text-based communication with local or remote applications via TCP/IP with optional confirmation.

Actions can be parameterized with variables derived from the message. This provides extra flexibility in implementing dynamic options.

Normally, you only need to start up one Listener on a device. One Listener can listen on multiple channels and it can serve multiple MobiLink users on the same device. A running Listener always listens on UDP (except for Palm Listeners).

Listeners can also synchronize device tracking information back to the consolidated database. For more information, see Device tracking.

See also

For Listener syntax and options, see The Listener utility.

For information about Palm devices, see Listeners for Palm Devices.

For dbmlsync options, see Adaptive Server Anywhere Client Synchronization Parameters.

For more information about message handlers, see Message handlers

Instead of typing dblsn options at a command prompt, it is often convenient to store them in a text file. For more information, see Storing Listener options.

Example

The following command starts the Listener utility. It must be typed on one line.

dblsn -v2 -m -ot dblsn.log -x "host=localhost"
 -l "subject=sync;action='start dbmlsync.exe
    -c eng=rem1;uid=dba;pwd=sql -ot dbmlsyncOut.txt -k';"

The options used in this example are:

Option | Description
-v2 | Set verbosity to level 2 (log Listener DLL messages and action tracing).
-m | Log notification messages.
-ot | Truncate the log file and send output to it. In this case, the output file is dblsn.log.
-x | Specify a way to connect to the MobiLink synchronization server. This is required for device tracking and delivery confirmation. In this simple example, the only protocol options that are specified are "host=localhost". For a complete list of protocol options, see -x option.
-l | Specify a message handler. In this case the filter is that a message must contain the subject sync, and the action is to start dbmlsync. Three dbmlsync command line options are also provided: -c specifies a connection string to the MobiLink synchronization server for the synchronization; -ot names an output log file; and -k shuts down dbmlsync when the synchronization is complete.


Message handlers

Using the dblsn command line, you create message handlers to tell the Listener which messages to filter and what actions should result from each accepted message.

For more information about dblsn, see The Listener.

Message interpretation
Using subject and content filters
Using the filters message, message_start, and sender
Connection-initiated synchronization
Multi-channel listening


Message interpretation

Messages arrive as a single piece of text with the following structure:

message control_information

The control_information is for internal use only and is removed prior to message handling. The Listener substitutes non-printable characters with tildes, and then interprets the message portion with the following pattern:

message = sender subj-open subject subj-close content
subj-open = ( | [ | { | < | ' | "

The subj-open character is determined by the first possible character found by scanning from left to right. The value of subj-open determines the value of subj-close. The possible values of subj-close are ), ], }, >, ' and ".

The location of the first subj-close character marks the end of the subject and the beginning of the content.

The sender is empty when the message begins with a subj-open. In that case, the sender of the message is determined in a delivery path-dependent way. For example, messages going through UDP gateways arrive as [subject]content, and the sender is the IP address. SMTP gateways send an e-mail message that is converted by an e-mail to SMS service into a format that varies between different public wireless carriers.

For more information about the Listener, see The Listener.


Using subject and content filters

Use the filters subject and/or content to filter messages by subject and/or content as specified in your push requests. When you use these filters, the Listener automatically adjusts the filter to match the format received by the carrier. For example, you may want to filter a message with the subject Sync and the content Orders. You do not have to worry that in UDP, this would appear as [Sync]Orders, and on one e-mail to SMS conversion service, it would be Bob@mail.com[Sync]Orders.

Your subject cannot contain the closing character that is used to enclose the subject. In the previous example, UDP encloses the subject Sync in square brackets. This means that you cannot use a closing square bracket in subjects that might be received over UDP. For SMTP messages, your carrier determines the character used to enclose the subject. This might be one of ), ], }, >, ' or ".

Note:
For best results, only use alphanumeric characters in your subject when creating push requests.

The Listener trims leading and trailing spaces, as well as leading and trailing tilde (~) characters, from the sender name, subject, and content. Non-printable characters such as the new line character are converted to tildes by the Listener before filtering.

For more information about the Listener, see The Listener.


Using the filters message, message_start, and sender

The recommended filters are called subject and content. However, there are three other types of filter that you may also want to use.

The Listener translates non-printable characters in a message to a tilde (~) so if there are non-printable characters, the filter must also use tildes.

  • message

    compares the entire message to text you specify. To match, this filter must also be the exact same length as the message. You can specify only one message per message handler.

    The format of messages is carrier-dependent, and you must account for this if you use the message, message_start, or sender filters. For example, you may want to match a message from a sender named Bob@mail.com with the subject Help and the message Me. In UDP, this would appear as [Help]Me. On Bell Mobility's e-mail to SMS conversion service, it would be Bob@mail.com[Help]Me. On Fido's e-mail to SMS conversion service, it would arrive as Bob@mail.com\n(Help)\nMe, but would be translated by the Listener to Bob@mail.com~(Help)~Me. You must test with your carrier to determine the appropriate format, using the dblsn options -v and -m.

  • message_start

    compares a portion of the message (from the beginning) to text that you specify. When you specify message_start, the Listener creates the action variables $message_start and $message_end. For more information, see Action variables. There is a maximum of one message_start per message handler.

  • sender

    is the sender of the message. You can only specify one sender per message handler. For UDP gateways, the sender is the IP address of the host of the gateway. For SMS e-mail, the sender is the e-mail address embedded in the beginning of the message if the SMS format is compatible with server-initiated synchronization. Otherwise, the sender information is not available.

Multiple message handlers may be required

Subject and content are the recommended filters when messages arrive in a compatible format. However, if your message format is incompatible, you need to use the message, message_start, and/or sender filters. In that case, if the delivery path can vary (sometimes through UDP and sometimes through SMTP), then you need multiple handlers with different filters.

For example, if you sent a message of the form sub, content through a UDP gateway, it would arrive as [sub]content. But if you sent it through an SMTP gateway, it might be rendered as mySender@mySite.com \n sub \n content. To catch a message that has the subject sub, you would need two message handlers, with the following filters:

-l "subject='sub';action=..."
-l "message_start='mySender@mySite.com ~ sub ~ ';action=..."

For more information about the Listener, see The Listener.


Connection-initiated synchronization

In addition to initiating synchronization from the server, on Windows devices you can also initiate synchronization when connectivity changes. This is possible because the Windows Listener generates an internal message with the content _IP_CHANGED_ whenever there is a change in connectivity, and it generates an internal message with the content _BEST_IP_CHANGED_ whenever there is a new "best" IP connection.

The internal messages _IP_CHANGED_ and _BEST_IP_CHANGED_ are generated only on Windows devices, including Windows CE.

Identifying a change in the optimum path to a MobiLink server

An IP connection is considered to be "best" if it is the best connection to use when connecting to the MobiLink synchronization server that is specified with the dblsn -x option. Although the "best" designation is defined by the path to the MobiLink synchronization server, in practice it tends to indicate the best IP connection to use in general.

To make use of a change in the best IP connection, use the keyword _BEST_IP_CHANGED_ in your message filter. A MobiLink server is required as a destination for the network to determine which route is optimal, so you must also specify connection parameters for a MobiLink server using the -x option. The message filter should be of the form:

-l "message='_BEST_IP_CHANGED_';action=..."

The $best_ip action variable is very useful with the _BEST_IP_CHANGED_ filter. The value of $best_ip is the local IP address that represents the best IP connection. If there is no IP connection, $best_ip has the value 0.0.0.0.

You can only use _BEST_IP_CHANGED_ when the Listener is run on a separate machine from the MobiLink synchronization server.

In the following example, the _BEST_IP_CHANGED_ filter is used to initiate a synchronization when the best IP connection changes. If the connection is lost, an error is generated.

dblsn -x http(host=mlserver.company.com)
   -v2 -m -i 3 -ot dblsn.log
   -l "message=_BEST_IP_CHANGED_;
       action='start dbmlsync.exe -ra -c eng=remote;uid=dba;pwd=sql
               -n test_pub'"
Identifying any change in connectivity

To make use of a change in IP connectivity on your remote device, use the keyword _IP_CHANGED_ in your message filter. _IP_CHANGED_ only indicates that there has been a change in IP connectivity. The message filter should be of the form:

-l "message='_IP_CHANGED_';action=..."

The following example shows a message handler that can be used in the dblsn command line. The filter captures messages that contain the content _IP_CHANGED_. The action makes use of the action variables $adapters and $network_names. If the connection is lost, an error is generated.

-l "message=_IP_CHANGED_;
    action='socket port=12345;
           sendText=IP changed: $adapters|$network_names;
       recvText=beeperAck;
       timeout=5';
    continue=yes;"
See also
  • The Listener
  • Action variables


Multi-channel listening

To listen on multiple media, you can start the Listener with the -d option. A library for UDP listening is always loaded by default, but there are several others that you can load. For more information, see The Listener utility and Listening libraries.

For more information about the Listener, see The Listener.


Storing Listener options

A convenient way to configure the Listener is to store the command line options in a text file and access it with the @ symbol. For example, store the settings in mydblsn.txt and start the Listener by typing

dblsn @mydblsn.txt

The path to the parameters file must be fully qualified.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

See Hiding the contents of files using the dbfhide command-line utility.

You can also store command line options in an environment variable, and call it in the dblsn command line by typing @ and the environment variable name; for example, dblsn @dblsnoptions. If you have both a filename and an environment variable with the same name, the environment variable is used.

Default parameters file dblsn.txt

If you type dblsn without any parameters, dblsn will use dblsn.txt as the default argument file. This feature is particularly useful for CE devices.

Following is a sample parameters file.

#---- SIS_SimpleListener\dblsn.txt --------------------------------------------
#
# This is the default argument file for dblsn.exe
#

#------------------------------------------------------------------------------
# Device name
#
-e device1

#------------------------------------------------------------------------------
# MobiLink connection parameters
#
-x host=localhost

#------------------------------------------------------------------------------
# Verbosity level 2
#
-v2

#------------------------------------------------------------------------------
# Show notification messages in console and log
#
-m

#------------------------------------------------------------------------------
# Polling interval of 1 seconds
#
-i 1

#------------------------------------------------------------------------------
# Truncate, then write output to dblsn.log
#
-ot dblsn.log

#------------------------------------------------------------------------------
# First message handler
#   - No filter, so it applies to all messages
#   - Try to send the message to the beeper utility
#   - If that fails, start the beeper utility with the message
#   - Message handling continues with the next handler
#
-l "action='socket port=12345;
            sendText=$sender:$message;
            recvText=beeperAck;
            timeout=5';
    altaction='start java.exe Beeper 12345 $sender:$message';
    continue=yes;"

#------------------------------------------------------------------------------
# Second message handler
#   - Only applies to messages with subject equals 'shutdown'
#   - The action is to send "shutdown" to the beeper utility
#   - Message handling continues with the next handler
#
-l "subject='shutdown';
    action='socket port=12345;
            sendText=shutdown;
            recvText=beeperAck;
            timeout=5';
    continue=yes;"

#------------------------------------------------------------------------------
# Third handler
#   - Only applies to messages with subject equals 'shutdown'
#   - The action is to shut down the MobiLink Listener
#
-l "subject='shutdown';
    action='DBLSN FULL SHUTDOWN';"


The Listener

About this chapter

This chapter is a detailed reference of the Listener utility. The Listener utility runs on Windows devices, including Windows CE.

For usage information, see Listeners.

For information about Palm devices, see Listeners for Palm Devices.

The Listener utility


The Listener utility

The Listener utility, dblsn, configures and starts the Listener on Windows devices, including Windows CE.

This section is a detailed reference of the Listener utility. For usage information, see Listeners.

For information about Palm devices, see Listeners for Palm Devices.

Syntax

dblsn [ options ] -l message-handler [ -l message-handler... ]

message-handler :
[ filter;... ]action
[ ;continue = yes ]
[ ;maydial = no ]
[ ;confirm_delivery = no ]

filter :
[ subject = string ]
[ content = string ]
[ message = string | message_start = string ]
[ sender = string ]

action :
action = command[;altaction = command ]

command :
start program [ program-arguments ]
| run program [ program-arguments ]
| post window-message to { window-class-name | window-title }
| tcpip-socket-action
| DBLSN FULL SHUTDOWN

tcpip-socket-action :
socket port=app-port
[ ;host=app-host ]
[ ;sendText=text1 ]
[ ;recvText= text2 [ ;timeout=num-sec ] ]

window-message : string | message-id

Parameters

Options The following options can be used to configure the Listener. They are all optional.

dblsn options | Description
@data | Reads options from the specified environment variable or configuration file. If both exist, the environment variable is used. See Storing Listener options.
-a option Specifies a Listener DLL option. If you specify multiple -d options, each -a is for the -d option it follows.

To specify multiple options, repeat -a. For example, -a port=2439 -a ShowSenderPort.

To see options for your dll, type dblsn -d filename.dll -a ? or see Listening libraries.
-d filename Specifies the Listener dll that you want to use. The default dll is lsn_udp.dll.

For SMTP gateways, there are several dll's that you can specify. For a list, see Listening libraries.

You can also create a custom Listener library. See MobiLink Listener SDKs.

To enable multi-channel listening, specify multiple dlls by repeating -d. After each -d option, specify the -a and -i options that relate to the dll. For example,

dblsn.exe -d lsn_udp.dll -i 10 -d maac750.dll -i 60
-e device-name | Specifies the device name. By default, the device name is automatically extracted from the system. If you do not use -e, you must ensure that all devices have unique names.
-f string | Specifies extra information about the device. By default, this information is the operating system version. Using this option will override the default value.
-g | Stop tracking UDP addresses when -x is used. This is useful when you do not want device tracking but you do want delivery confirmation.
-i seconds | Sets the polling interval in seconds for SMTP connections. This is the frequency at which the Listener checks for messages. If you use multiple -d options, each -i setting is for the -d it follows. The default for SMTP is 30 seconds. For UDP connections, the Listener attempts to connect immediately.
-m | Turns on message logging. The default is off.
-o filename | Logs output to a file. If -o is not used, output is logged to the console window.
-os bytes | Specifies a maximum size for the log file in bytes. The minimum size is 10 000. By default, there is no limit.
-ot filename | Logs output to file, but first truncates the file.
-p | Allows automatic idle power-off. This option has an effect only on CE devices. Use it to allow the device to shut down when idle. By default, the Listener prevents the device from shutting itself down so that Listening may continue.
-q | Runs in a minimized window.
-t {+|-} ml_user_alias Register remote databases for notification so that you can address the remote database by name when using device tracking.

See Listener options for device tracking.
-u Listener_name Specifies a unique name for this Listener. This name is used for uploading tracking information and delivery confirmation, and can also be used as a notification address for the DeviceTracker gateway.

The Listener_name is a MobiLink user name. Like other MobiLink user names, it must be unique and you must add it to the ml_user MobiLink system table on your consolidated database. For more information, see Creating MobiLink users.

The default Listener name is device-name-dblsn.

See Listener options for device tracking.
-v [ level ] Sets the verbosity level for the dblsn log and console. The level can be 0, 1, 2, or 3:

  • 0 - show no informational messages (the default).

  • 1 - show Listener dll messages and basic action tracing steps.

  • 2 - show level 1 plus detailed action tracing steps.

  • 3 - show level 2 plus polling and listening states.

To output notification messages, you must also use -m (see above).
-w password Specifies a password for the Listener_name.

See Listener options for device tracking.
-x {http|tcpip} [(keyword=value;...)] Specifies the network protocol and protocol options for the MobiLink synchronization server. For a list of protocol options, see -x option. This information is required for the Listener to send device tracking information and delivery confirmation to the consolidated database.

See Listener options for device tracking.
-y new_password Specifies a new MobiLink password for the Listener name. If your authentication system allows remote devices to change their passwords, this option lets them send up the new password.

See Listener options for device tracking.

Message-handlers The -l option allows you to specify a message handler, which is a filter-action pair. The filter determines which messages should be handled, and the action is invoked when the filter matches a message.

You can specify multiple instances of -l. Each instance of -l specifies a different message handler for each incoming message. Message handlers are processed in the order they are specified.

You can also specify the following options for message handlers:

  • continue=yes

    specifies that the Listener should continue after finding the first match. This is useful when you specify multiple -l clauses to cause one message to initiate multiple actions. The default is no.

  • maydial=no

    specifies that the action cannot dial the modem. This provides information to the Listener to decide whether to release the modem or not before the action. This option is useful when the action or altaction need exclusive access to the modem used by the Listener. The default is yes.

  • confirm_delivery=no

    specifies that this handler should not confirm delivery. A message requires confirmation if the gateway used to send it has its confirm_delivery property set to yes. Delivery can only be confirmed if the message requires confirmation and if the handler accepts the message. The default is yes.

    Normally, you do not need to specify this option. By default the first handler that accepts the message will send delivery confirmation, if required. This option can be used when multiple handlers might accept the same message to give you finer control over which handler should confirm the delivery.

Filters You specify a filter to compare to an incoming message. If the filter matches, the action you specify is invoked.

The filter is optional. If you do not specify a filter, the action is performed when any message is received. This is useful when debugging or when you want a catch-all message handler as the last message handler.

For information about using the subject or content filters, see Using subject and content filters.

For information about using the message, message_start, or sender filters, see Using the filters message, message_start, and sender.

Action and altaction

Each filter is associated with an action and, optionally, an alternative action called the altaction. If a message meets the conditions of the filter, the action is invoked. You must specify an action. If you specify an altaction, the altaction is invoked only if the action fails.

For each action and altaction, there can be one command, and it can be one of start, run, post, socket, or DBLSN FULL SHUTDOWN.

  • start

    spawns a process. When you start a program, the Listener continues listening for more messages.

    When you start a program, the Listener doesn't wait for a return code, so it can only tell that the action has failed if it cannot find or start the program.

    The following example starts dbmlsync with some command line options, parts of which are obtained from the message.

    "action='start dbmlsync.exe @dbmlsync.txt -n
  $content -wc dbmlsync_$content -e sch=INFINITE';"

  • run

    runs the program and waits for it to finish. The Listener resumes listening after the process is complete.

    When you run a program, the Listener determines that the program has failed if the Listener cannot find or start the program or if it returns a non-zero return code.

    The following example runs dbmlsync with some command line options, parts of which are obtained from the message.

    "action='run dbmlsync.exe @dbmlsync.txt -n $content';"

  • post

    posts a window message to a window class. This is required by dbmlsync when scheduling is on. Post is also used when signaling applications that use Windows messages.

    You can identify the window message by message contents or by the ID of the window message, if one exists.

    You can identify the window class by its name or by the title of the window. If you identify the window class by name, you can use the dbmlsync -wc option to specify the window class name. If you identify the window class by its title, only the title of the top level window can be used to identify the window class.

    If there are non-alphanumeric characters such as spaces or punctuation marks in your window message or window class name, you can put the message or name in single quotes. In that case, to use a single quote in the string, use two single quotes in a row. For example, to post my'message to my'class, use the following syntax:

    ... -l "action='post my''''message to my''''class':"

    or

    ... -l "action='post ''my''''message'' to ''my''''class''':"

    The following example posts a Windows message registered as dbas_synchronize to a dbmlsync instance registered with the class name dbmlsync_FullSync.

    "action='post dbas_synchronize to dmblsync_FullSync';"

    For more information, see -wc option.

  • socket

    notifies an application by making a TCP/IP connection. This is especially useful for passing dynamic information to a running application. It is also useful for integrating with Java and Visual Basic applications, because Java and VB don't support custom window messaging, and eVB doesn't support command line parameters. You can connect to a local socket by specifying just a port, or you can connect to a remote socket by specifying the host along with the port. Using sendText, you can send a string. You can optionally verify that the response is as expected with recvText. When you use recvText, you can also specify a timeout to avoid hanging if the case of application or network problems.

    When you perform a socket action, the Listener determines that the action has failed if it failed to connect, send, or receive expected acknowledgement before timeout.

    The following example forwards the string in $sender=$message to a local application that is listening on port 12345, and expects the application to send back "beeperAck" as an acknowledgement within 5 seconds.

    -l "action='socket port=12345;
   sendText=$sender=$message;
   recvText=beeperAck;
   timeout=5'"

  • DBLSN FULL SHUTDOWN

    causes the Listener utility to shut down. After shutdown, the Listener stops handling inbound messages and stops synchronizing device tracking information. The remote user must restart the Listener in order to continue with server-initiated synchronization. This feature is mostly useful during testing.

    For example, action='DBLSN FULL SHUTDOWN'

You can only specify one action and one altaction in each instance of -l. If you want an action to perform multiple tasks, you can write a cover program or batch file that contains multiple actions, and run it as a single action.

Following is an example of altaction. In this example, $content is the protocol option for connecting to MobiLink. The primary action is to post the dbas_synchronize Windows message to the dbmlsync_FullSync window. The example uses altaction to start (not run) dbmlsync with the window class name dbmlsync_FullSync if the primary action fails. This is the standard way to make the Listener work with dbmlsync scheduling.

-l "subject=sync;
    action='post dbas_synchronize to dbmlsync_FullSync';
    altaction='start dbmlsync.exe
                        @dbmlsync.txt
                 -wc dbmlsync_FullSync
                 -e adr=$content;sch=INFINITE'"
See also

Listeners


Action variables

The following Listener action variables can be used anywhere in the action or altaction.

An action variable is substituted just before the action or altaction is performed.

Listener action variables start with a dollar sign ($). The escape character is also a dollar sign, so to specify a single dollar sign as plain text, type $$. For example, type $$message_start when you don't want $message_start to be substituted.

Action variable | Description
$subject | The subject of the message.
$content | The content of the message.
$message | The entire message, including subject, content, and formatting that is specific to the delivery path.
$message_start | A portion of the text of the message from the beginning, as specified in -l message_start. This variable is only available if you have specified -l message_start.
$message_end | The part of the message that is left over after the part specified in -l message_start is removed. This variable is only available if you have specified -l message_start.
$sender | The sender of the message.
$type | The meaning of this variable is carrier library dependent.
$priority | The meaning of this variable is carrier library dependent.
$request_id | The request ID that was specified for the push request. For more information, see Push requests.
$year | The meaning of this variable is carrier library dependent.
$month | The meaning of this variable is carrier library dependent. Values can be from 1-12.
$day | The meaning of this variable is carrier library dependent. Values can be from 1-31.
$hour | The meaning of this variable is carrier library dependent. Values can be from 0-23.
$minute | The meaning of this variable is carrier library dependent. Values can be from 0-59.
$second | The meaning of this variable is carrier library dependent. Values can be from 0-59.
$best_adapter_mac | The MAC address of the best NIC for reaching the MobiLink server that is specified in the dblsn command line with the -x option. If the best route does not go through a NIC, the value is an empty string.
$best_adapter_name | The adapter name of the best NIC for reaching the MobiLink server that is specified in the dblsn command line with the -x option. If the best route does not go through a NIC, the value is an empty string.
$best_ip | The IP address of the best IP interface for reaching the MobiLink server that is specified in the dblsn command line with the -x option. If that server is unreachable, the value is 0.0.0.0.
$best_network_name | The RAS or dialup profile name of the best profile for reaching the MobiLink server that is specified in the dblsn command line with the -x option. If the best route does not go through a RAS/dialup connection, the value is an empty string.
$adapters | A list of active network adapter names, each separated by a vertical bar ( | ).
$network_names | A list of connected RAS entry names, each separated by a vertical bar ( | ). RAS entry names are sometimes referred to as dial-up entry names or Dial-Up Network (DUN).
Example

For example, if a message arrives in the form message_start pub-name, you can use the following $message_end action variable to determine which publication to synchronize:

-l "message_start=message_start;action='dbmlsync.exe -c ... -n $message_end'"


Listening libraries

When you run the Listener, by default the listening library lsn_udp.dll is used. If you are using SMTP, you need to specify an SMTP listening library.

You specify the listening library with the dblsn -d option, and specify options for the listening library with the -a option. To enable multi-channel listening, specify multiple dlls by repeating -d. After each -d option, specify the -a and -i options that relate to the dll. For example,

dblsn.exe -d lsn_udp.dll -i 10 -d maac750.dll -i 60

To specify multiple options, repeat -a. For example,

-d maac750.dll -a port=2439 -a ShowSenderPort

To see options for your dll, type dblsn -d filename.dll -a ?.

You can also create a custom Listener library. For more information, see MobiLink Listener SDKs.

Following is a list of supported listening libraries and their options.

UDP (lsn_udp.dll)
Option | Description
Port=port_number | The default is 5001.
Timeout=seconds | This value must be smaller than the polling interval of the UDP listening thread. The default is 0.
ShowSenderPort | Appends :port to the sender.
HideWSAErrorBox | Suppresses the error box showing errors on socket operations.
CodePage=number | On CE, translates multi-byte characters into Unicode based on this code page number.
SMS for AirCard510 (lsn_swi510.dll)
Option | Description
MessageStoreSize=number | This size affects how the library collapses redundant messages. If the message store is filled, the library stops collapsing identical messages until a message is consumed. The default is 20.
NetworkProviderId=name | The matching Carrier(name).network_provider_id. This information is sent up during a device tracking synchronization. This option is needed for device tracking.
PhoneNumber=number | A 10-digit telephone number. This information is sent up during a device tracking synchronization. This option is needed for device tracking.
SMS for AirCard555 (maac555.dll)
Option | Description
MessageStoreSize=number | This size affects how the library collapses redundant messages. If the message store is filled, the library stops collapsing identical messages until a message is consumed. The default is 20.
PreserveMessage | Specifies that messages should be left in the queue for other SMS applications. The default is for the Listener to consume messages as they are processed.
SMS for AirCard710 and AirCard750 using firmware R2 (maac750.dll)
Option | Description
MessageStoreSize=number | This size affects how the library collapses redundant messages. If the message store is filled, the library stops collapsing identical messages until a message is consumed. The default is 20.
PreserveMessage | Specifies that messages should be left in the queue for other SMS applications. The default is for the Listener to consume messages as they are processed.
SMS for AirCard710 and AirCard750 using firmware R3 (maac750r3.dll)
Option | Description
MessageStoreSize=number | This size affects how the library collapses redundant messages. If the message store is filled, the library stops collapsing identical messages until a message is consumed. The default is 20.
PreserveMessage | Specifies that messages should be left in the queue for other SMS applications. The default is for the Listener to consume messages as they are processed.


Listeners for Palm Devices

About this chapter

This chapter describes how to set up and run server-initiated synchronization on Palm devices. Palm Listeners do not support UDP.

Palm Listener utilities


Palm Listener utilities

To run server-initiated synchronization on Palm devices, you use two utilities:

  • Palm Listener Configuration utility (dblsncfg)

  • Palm Listener (lsnK7135.prc or lsnT600.prc)

First, run the Palm Listener Configuration utility on a Windows desktop to create a configuration file for the Palm. The configuration file must later be transferred to the Palm device via HotSync.

For an overview of Listeners and message handlers, see Listeners.


Palm Listener Configuration utility

The Palm Listener Configuration utility, running on a Windows desktop, creates a configuration file for the Palm Listener. For information about the Palm Listener, see Palm Listener utility.

Syntax

dblsncfg -n [ filename ] -l message-handler [ -l message-handler... ]

message-handler : [ filter;...] action

filter :
[ subject = string ]
[ content = string ]
[ message = string | message_start = string ]
[ sender = string ]

action : action=run application-name [ arguments ]

Options and parameters

@data Reads options from the specified environment variable or configuration file. If both exist, the environment variable is used. See Storing Listener options.

-n [filename] The -n option is used to create a configuration file for the Palm Listener. The filename should be lsncfg.pdb.

-l message-handler -l allows you to specify a message handler, which is a filter-action pair. The filter determines which message should be handled, and the action is invoked when the filter matches a message. You can specify multiple instances of -l. Each instance of -l specifies a different message handler.

Filters You specify a filter to compare to an incoming message. If the filter matches, the action you specify is invoked.

For information about using the subject or content filters, see Using subject and content filters.

For information about using the message, message_start, or sender filters, see Using the filters message, message_start, and sender.

The filter is optional. If you do not specify a filter, the action is performed when any message is received.

Action

The action fully launches the specified application. The syntax is run application-name [ arguments ]. arguments is an application-dependent string; it may contain action variables. The PilotMain routine of the target application should take a string as the command block. For more information, see Action variables.

Note: When running the Palm Listener Configuration utility on a Windows desktop to generate a configuration file for the Palm, you must specify the run action. However, on the Palm device you can delete the run action using the Handler Editor in the Palm Listener. This way you can consume the message without causing an action.

Action variables


Action variables

The following action variables can be used in the arguments in the run clause.

An action variable is substituted just before the action is performed.

Listener action variables start with a dollar sign ($). The escape character is also a dollar sign, so to specify a dollar sign as plain text, type $$. For example, type $$message_start when you don't want $message_start to be substituted.

Action variable | Description
$subject | The subject of the message.
$object | The object of the message.
$message | The full message string.
$message_start | A portion of the text of the message from the beginning, as specified in -l message_start. This variable is only available if you have specified -l message_start.
$message_end | The part of the message that is left over after the part specified in -l message_start is removed. This variable is only available if you have specified -l message_start.
$sender | The sender of the message.
$time | This is the current time in seconds since 12:00 AM, January 1, 1904.


Palm Listener utility

For Palm applications using server-initiated synchronization, each client must have a Palm Listener installed. The two supported Palm Listeners are for Kyocera 7135 and Treo 600. The Listener files are:

  • lsnK7135.prc the Listener on Kyocera 7135

  • lsnT600.prc the Listener on Treo 600

Currently, the two Palm Listeners only read from configuration file lsncfg.pdb.

The Palm Listener also allows you to set three options. These options remain until they are explicitly changed or until you perform a reset.

  • Listening A way to stop the Listener from consuming messages.

  • Enable Actions This is applicable only when Listening is on. When disabled, no action is invoked.

  • Prompt Before Actions This is applicable only when actions are enabled. When this option is set, a confirmation dialog pops up before an action is invoked.

The device need not always be on if it turns on automatically when an SMS message is received. Kyocera and Treo devices do not need to be on for the Listener to work.

A Listener SDK is provided that you can use to create support for other Palm devices. For more information, see Listener SDK for Palm.


MobiLink Notification Properties

About this chapter

This chapter describes the properties that you use to customize Notifiers, gateways, and carriers.

For information about how to set properties, see Setting properties.


Common properties

There is one common property, verbosity.

For more information about setting properties, see Setting properties.

verbosity property


verbosity property

The verbosity setting applies to all Notifiers, gateways, and carriers. You can set the verbosity to the following levels:

Level | Description
0 | No trace (the default)
1 | Startup, shutdown, and property trace
2 | Display notification messages
3 | Poll-level trace
See also

Setting properties.

Examples

Following are the ways you can set verbosity to level 2.

If you are using the MobiLink plug-in in Sybase Central to change the verbosity property, right-click the Notification folder and choose Properties.

If you are configuring properties using the Notifier properties file, include the line:

verbosity=2

If you are using the stored procedure ml_add_property to change the verbosity level, enter the following:

ml_add_property( 'SIS','global','verbosity','2' );


Notifier properties

The following properties can be set in the Notifier properties file. The enable and request_cursor properties are required. All other Notifier properties are optional.

You can have multiple Notifiers running with one MobiLink server. To set up additional Notifiers, copy the properties for one Notifier and provide a different Notifier name and property values.

For more information about the Notifier, see Notifiers.

For more information about setting properties, see Setting properties.

begin_connection property
begin_poll property
connect_string property
gui property
enable property
end_connection property
end_poll property
isolation property
poll_every property
request_cursor property
request_delete property
shutdown_query property


begin_connection property

This is a SQL statement that runs in a separate transaction after the Notifier connects to the database and before the first poll. For example, this property can be used to create temporary tables or variables.

If the Notifier loses its connection to the consolidated database, it will re-execute this transaction immediately after reconnecting.

You should not use this property to change isolation levels. To control isolation levels, use the isolation property.

See also
  • Setting properties
  • isolation property
Examples

If you are using the MobiLink plug-in in Sybase Central, right-click the Notifier and choose Properties. Open the Logic tab and select begin_connection from the dropdown list. Paste the following code into the box called Execute this SQL Statement.

set temporary option blocking = 'off'

If you are configuring properties using the Notifier properties file, begin_connection is defined for a Notifier called Car Dealer with the following line. The backslash is a line continuation character.

Notifier(Car Dealer).begin_connection = \
   set temporary option blocking = 'off'

If you are using the stored procedure ml_add_property to change the begin_connection property, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property(
  'SIS',
  'Notifier(Car Dealer)',
  'begin_connection',
  'set temporary option blocking = ''off'''
);


begin_poll property

This is a SQL statement that is executed before each Notifier poll. Typical uses are to detect data change in the database and create push requests that are later fetched with the request_cursor.

The statement is executed in a standalone transaction.

This property is optional. The default is NULL.

See also

Setting properties.

Examples

For example, the following SQL statement inserts rows into a table called PushRequest. Each row in this table represents a message to send to an address. The WHERE clause determines what push requests are inserted into the PushRequest table.

INSERT INTO PushRequest
( gateway, mluser, subject, content )
      SELECT 'MyGateway', DISTINCT mluser,
       'sync', stream_param
      FROM MLUserExtra, Dealer
      WHERE
    MLUserExtra.mluser.push_sync_status = "waiting for request"
      AND Dealer.last_modified > MLUserExtra.last_sync_time

If you are using the MobiLink plug-in in Sybase Central, right-click the Notifier and choose Properties. Open the Logic tab and select begin_poll from the dropdown list. Paste the code above into the box called Execute this SQL Statement.

If you are configuring properties using the Notifier properties file, include the following line for a Notifier called NotifierA. The backslash is a line continuation character.

Notifier(NotifierA).begin_poll = \
INSERT INTO PushRequest \
( gateway, mluser, subject, content ) \
      SELECT 'MyGateway', DISTINCT mluser, \
       'sync', stream_param \
      FROM MLUserExtra, Dealer \
      WHERE \
   MLUserExtra.mluser.push_sync_status = "waiting for request" \
      AND Dealer.last_modified > MLUserExtra.last_sync_time \
);

If you are using the stored procedure ml_add_property to change the begin_connection property, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS',
  'Notifier(Car Dealer)',
  'begin_connection',
  'INSERT INTO PushRequest
     ( gateway, mluser, subject, content )
            SELECT ''MyGateway'', DISTINCT mluser,
         ''sync'', stream_param
            FROM MLUserExtra, mluser_union, Dealer
            WHERE
        MLUserExtra.mluser = mluser_union.name
          AND( push_sync_status = ''waiting for request''
               OR datediff( hour, last_status_change, now() ) > 12 )
            AND ( mluser_union.publication_name is NULL
               OR mluser_union.publication_name =''FullSync'' )
            AND
               Dealer.last_modified > mluser_union.last_sync_time'
);


connect_string property

By default, the Notifier uses ianywhere.ml.script.ServerContext to connect to the consolidated database. This means that it uses the connection string that was specified in the current dbmlsrv9 session's command line.

This is an optional property that can be used to override the default connection behavior. You can use it to connect to any database, including the consolidated database. It may be useful to connect to another database when you want notification logic and data to be separate from your synchronization data. Most deployments will not set this property.

For more information, see ServerContext interface.

See also

Setting properties.

Examples

If you are using the MobiLink plug-in in Sybase Central, right-click the Notifier and choose Properties. The connect string is set on the Connection tab.

If you are configuring properties using the Notifier properties file, configure a Notifier called Simple to use a DSN with the following line. The backslash is a line continuation character.

Notifier(Simple).connect_string = dsn=SIS_DB \
   ;uid=user;pwd=myPwd

If you are using the stored procedure ml_add_property to change the connect string, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS',
  'Notifier(Simple)',
  'connect_string',
  'dsn=SIS_DB;uid=user;pwd=myPwd' );


gui property

This controls whether the Notifier dialog is displayed on the computer where the Notifier is running. This user interface allows users to temporarily change the polling interval, or poll immediately. It can also be used to shut down the Notifier without shutting down the MobiLink synchronization server. (Once stopped, the Notifier can only be restarted by shutting down and restarting the MobiLink synchronization server.)

This property is optional. The default is ON.

See also

Setting properties.

Examples

If you are using the MobiLink plug-in in Sybase Central, right-click the Notifier and choose Properties. Open the General tab and change Display Control Window When Running.

If you are configuring properties using the Notifier properties file, disable the dialog for a Notifier called Simple with the following line:

Notifier(Simple).gui=off

If you are using the stored procedure ml_add_property to change this property, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS','Notifier(Simple)','gui','off' );


enable property

You can enable or disable existing Notifiers. If you have enabled multiple Notifiers, all are started when you start the MobiLink synchronization server with the -notifier option.

See also

Setting properties.

Examples

If you are using the MobiLink plug-in in Sybase Central, open the Notifiers folder and double-click Add Notifier to add a new Notifier. New Notifiers are automatically enabled. To disable an existing Notifier, right-click the Notifier and choose Properties; open the General tab and clear Enable This Notifier.

If you are configuring properties using the Notifier properties file, a Notifier called NotifierA is enabled with the following line:

Notifier(NotifierA).enable=yes

If you are using the stored procedure ml_add_property to enable NotifierA, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS','Notifier(NotifierA)','enable','yes' );


end_connection property

This is a SQL statement that runs as a separate transaction just before a Notifier database connection is closed. For example, this property can be used to delete temporary storage such as SQL variables and temporary tables.

The statement is executed in a standalone transaction.

Examples

If you are using the MobiLink plug-in in Sybase Central, right-click the Notifier called Simple and choose Properties. Open the Logic tab and select end_connection from the dropdown list. Paste the following code into the box called Execute this SQL Statement.

DELETE FROM NotifierShutdown WHERE name = 'Simple'

If you are configuring properties using the Notifier properties file, end_connection is defined for a Notifier called Simple with the following line. The backslash is a line continuation character.

Notifier(Simple).end_connection =   \
   DELETE FROM NotifierShutdown WHERE name = 'Simple'

If you are using the stored procedure ml_add_property, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS',
  'Notifier(Simple)',
  'end_connection',
  'DELETE FROM NotifierShutdown WHERE name = ''Simple''');


end_poll property

This is a SQL statement that is executed after each poll. Typical uses are to perform customized cleanup or track polling.

The statement is executed in a standalone transaction.

This property is optional. The default is NULL.

Examples

If you are using the MobiLink plug-in in Sybase Central, right-click the Notifier called Simple and choose Properties. Open the Logic tab and select end_poll from the dropdown list. Paste the following code into the box called Execute this SQL Statement.

call reportAliveRequests( )

If you are configuring properties using the Notifier properties file, end_poll is defined for a Notifier called Simple with the following line.

Notifier(Simple).end_poll = call reportAliveRequests( )

If you are using the stored procedure ml_add_property, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS',
  'Notifier(Simple)',
  'end_poll',
  'call reportAliveRequests( )');


isolation property

Isolation is an optional property that controls the isolation level of the Notifier's database connection. The default value is 1. You can use the following values:

Value | Isolation level
0 | Read uncommitted
1 | Read committed (the default)
2 | Repeatable read
3 | Serializable
Description

Be aware of the consequences of setting the isolation level. Higher levels increase contention, and may adversely affect performance. Isolation level 0 allows reads of uncommitted data—data which may eventually be rolled back.

See also

Setting properties.

Examples

If you are using the MobiLink plug-in in Sybase Central, right-click the Notifier and choose Properties. Isolation levels are set on the Connection tab.

If you are configuring properties using the Notifier properties file, the isolation level for a Notifier called NotifierA is set with the following line:

Notifier(NotifierA).isolation=2

If you are using the stored procedure ml_add_property to change the isolation level, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS','Notifier(NotifierA)','isolation','2' );


poll_every property

This property specifies the Notifier polling interval. You can specify S, M, and H for units of seconds, minutes. and hours. You can also combine units, as in 1H 30M 10S. If no unit is specified, the interval is in seconds.

If the Notifier loses the database connection, it will recover automatically at the first polling interval after the database becomes available again.

This property is optional. The default is 30 seconds.

Examples

If you are using the MobiLink plug-in in Sybase Central, right-click the Notifier and choose Properties. Open the Polling tab and choose a polling interval.

If you are configuring properties using the Notifier properties file, a Notifier called Simple is configured to poll every three hours with the following line:

Notifier(Simple).poll_every = 3H

If you are using the stored procedure ml_add_property to change the polling interval, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS','Notifier(Simple)','poll_every','3H' );


request_cursor property

This property contains SQL used by the Notifier to fetch push requests. Each row is a push request that determines what information is sent in the message, who receives the information, when, and where. You must set this property.

The result set of this statement must contain at least five columns, and can optionally contain two other columns. These columns can have any name, but must be in the following order in the result set:

  • request id

  • gateway

  • subject

  • content

  • address

  • resend interval (optional)

  • time to live (optional)

For more information about these columns, see Push requests.

You might want to include a WHERE clause in your request_cursor to filter out requests that have been satisfied. For example, you can add a column to your push request table to track the time you inserted a request, and then use a WHERE clause to filter out requests that were inserted prior to the last time the user synchronized.

The statement is executed in a standalone transaction.

Examples

If you are using the MobiLink plug-in in Sybase Central, right-click the Notifier and choose Properties. Open the Logic tab and select request_cursor from the dropdown list. Paste the following code into the box called Execute this SQL Statement.

SELECT req_id, gateway, subject, content, address
  FROM PushRequest

If you are configuring properties using the Notifier properties file, a request_cursor is defined for a Notifier called Simple with the following line. The backslash is a line continuation character.

Notifier(Simple).request_cursor = \
SELECT req_id, gateway, subject, content, address \
  FROM PushRequest

If you are using the stored procedure ml_add_property, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property(
  'SIS',
  'Notifier(Simple)',
  'request_cursor',
  'SELECT req_id, gateway, subject, content, address
     FROM PushRequest'
);


request_delete property

This is a SQL statement that specifies cleanup operations. The statement takes the request id as its only parameter. The placeholder for a parameter is a question mark (?).

Using the DELETE statement, the Notifier can automatically remove these forms of old request:

  • implicitly dropped requests requests that appeared previously, but did not appear in the current set of requests obtained from the request_cursor.

  • confirmed requests messages confirmed as delivered.

  • expired requests requests that have expired based on their resend attributes and the current time. Requests without resend attributes are considered expired even if they appear in the next request.

The request_delete statement is executed per request ID in a standalone transaction when the need for deletion is detected. It is optional if you have provided another process to do the cleanup.

You can write the request_delete script in such a way to avoid eliminating expired or implicitly dropped requests. For example, the CarDealer sample uses request_delete to set the status field of the PushRequest table to 'processed'.

update PushRequest set status='processed' where req_id = ?

The sample's begin_poll script uses the last synchronization time to check that a remote device is up-to-date prior to eliminating processed requests.

For more information, see the Car Dealer sample located in the Samples\MobiLink\SIS_CarDealer subdirectory of your SQL Anywhere Studio installation.

Examples

In the following examples, a Notifier called Simple is configured to substitute a req_id previously obtained from request_cursor for the question mark (?).

If you are using the MobiLink plug-in in Sybase Central, right-click the Notifier called Simple and choose Properties. Open the Logic tab and select request_delete from the dropdown list. Paste the following code into the box called Execute this SQL Statement.

DELETE FROM PushRequest WHERE req_id = ?

If you are configuring properties using the Notifier properties file, request_delete is defined for a Notifier called Simple with the following line. The backslash is a line continuation character.

Notifier(Simple).request_delete = \
   DELETE FROM PushRequest WHERE req_id = ?

If you are using the stored procedure ml_add_property, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS',
  'Notifier(Simple)',
  'request_delete',
  'delete = DELETE FROM PushRequest WHERE req_id = ?');


shutdown_query property

This is a SQL statement that is executed right after begin_poll. The result should contain only the value yes (or 1) or no (or 0). To shut down the Notifier, specify yes or 1. This statement is executed as a standalone transaction.

If you are storing the shutdown state in a table, then you can use the end_connection property to reset the state before the Notifier disconnects.

Examples

If you are using the MobiLink plug-in in Sybase Central, right-click the Notifier and choose Properties. Open the Logic tab and select shutdown_query from the dropdown list. Paste the following code into the box called Execute this SQL Statement.

SELECT COUNT(*) FROM NotifierShutdown
  WHERE name='Simple'

If you are configuring properties using the Notifier properties file, shutdown_query is defined for a Notifier called Simple with the following line. The backslash is a line continuation character.

Notifier(Simple).shutdown_query = \
  SELECT COUNT(*) FROM NotifierShutdown \
  WHERE name='Simple'

If you are using the stored procedure ml_add_property, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS','Notifier(Simple)','shutdown_query',
 'SELECT COUNT(*) FROM NotifierShutdown
  WHERE name=''Simple'''

);


Device tracker gateway properties

To use the default device tracker gateway, include the name Default-DeviceTracker in the second column of the result set of the request_cursor.

A device tracker gateway utilizes automatically-tracked IP addresses, phone numbers, and public wireless network provider IDs to deliver messages through either a UDP or SMTP gateway. Your configuration defines which UDP gateway and which SMTP gateway are to be used by your device tracker gateway. You can also control tracking requirements for messages sent through this gateway.

For more information about device tracking, see Device tracking.

For more information about setting properties, see Setting properties.


confirm_delivery property

Specifies whether the Listener should confirm with the consolidated database that the message was received. To be able to do this, you must start the Listener with the -x option. The default setting for confirm_delivery is yes.

For example,

DeviceTracker(Default-DeviceTracker).confirm_delivery = yes
Examples

If you are using the MobiLink plug-in in Sybase Central, open the Gateways folder, right-click Default-DeviceTracker, and choose Properties. Open the Delivery tab and select Confirm Delivery.

If you are configuring properties using the Notifier properties file, a DeviceTracker gateway called Default-DeviceTracker has delivery confirmation set with the following line:

DeviceTracker(Default-DeviceTracker).confirm_deivery=yes

If you are using the stored procedure ml_add_property to set confirm_delivery for Default-DeviceTracker, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS',
  'DeviceTracker(Default-DeviceTracker)',
  'confirm_delivery',
  'yes' );


enable property

Specify enable=yes to use a device tracker gateway. Specify enable=no to disable a device tracker gateway. You can define and use multiple device tracker gateways.

Examples

If you are using the MobiLink plug-in in Sybase Central, open the Carriers folder and double-click Add Gateway. New gateways are automatically enabled.

If you are configuring properties using the Notifier properties file, a DeviceTracker gateway called Default-DeviceTracker is enabled with the following line:

DeviceTracker(Default-DeviceTracker).enable=yes

If you are using the stored procedure ml_add_property to enable Default-DeviceTracker, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS',
  'DeviceTracker(Default-DeviceTracker)',
  'enable',
  'yes' );


smtp_gateway property

This names an SMTP gateway that the device tracker can use. The gateway must be enabled. A device tracker gateway can only use one SMTP gateway. The default is Default-SMTP.


udp_gateway property

This identifies a UDP gateway that the device tracker can use. The gateway must be enabled. A device tracker gateway can only use one UDP gateway. The default is Default-UDP.


SMTP gateway properties

SMTP gateway configuration is required only if you need to send SMS messages via SMTP.

SMTP gateways can be used to send e-mail messages. In particular, they can send SMS messages to SMS listeners via a wireless carrier's e-mail-to-SMS service.

In the following list of properties, the enable and server properties are required. The server and sender properties are often required. The user and password properties may be required, depending on your SMTP server setup. All other SMTP gateway properties are optional.

You can have multiple SMTP gateways. To set up additional SMTP gateways, copy the properties for one gateway and provide a different gateway name and property values.

For more information about gateways, see Gateways and carriers.

For more information about setting properties, see Setting properties.

confirm_delivery property
confirm_timeout property
enable property
listeners_are_900 property
password property
sender property
server property
user property


confirm_delivery property

Specify yes to confirm delivery. The default is no. This property has an effect only when sending directly through this gateway (not indirectly via a device tracking gateway).


confirm_timeout property

Specify the amount of time before a confirmation should time out. Specify s, m, or h for seconds, minutes, or hours. If you do not specify s, m, or h, the default is seconds. The default confirmation timeout is 10m.


enable property

Specify enable=yes to use an SMTP gateway. You can define and use multiple SMTP gateways.

Examples

If you are using the MobiLink plug-in in Sybase Central, open the Gateways folder and double-click Add Gateway. New gateways are automatically enabled.

If you are configuring properties using the Notifier properties file, an SMTP gateway called Gate3 is enabled with the following line:

SMTP(Gate3).enable=yes

If you are using the stored procedure ml_add_property to enable the gateway Gate3, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS','SMTP(Gate3)','enable','yes' );


listeners_are_900 property

Specify yes if all Listeners are Adaptive Server Anywhere version 9.0.0 clients. Specify no if they are version 9.0.1 or later. The default is no.


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Server-Initiated Synchronization User's Guide

MobiLink Notification Properties

SMTP gateway properties

password property

This is the password for your SMTP service. Your SMTP service may not require a password.


sender property

This is the sender address of the e-mails (SMTP requests). The default is anonymous.

The sender may not be available as an action variable to the Listener if the arriving message format is not compatible with MobiLink's message interpretation.


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Server-Initiated Synchronization User's Guide

MobiLink Notification Properties

SMTP gateway properties

server property

This is the IP address or host name of the SMTP server used to send the message to the Listener. The default is mail.


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Server-Initiated Synchronization User's Guide

MobiLink Notification Properties

SMTP gateway properties

user property

This is the user name for your SMTP service. Your SMTP service may not require a user name.


UDP gateway properties

UDP gateway configuration is required only if you need to send UDP messages.

The format of the UDP message is [ subject ] content where subject and content come from the subject and content columns of the request_cursor Notifier property.

In the following list of properties, only the enable property is required. All other UDP gateway properties are optional.

You can have multiple UDP gateways. To set up additional UDP gateways, copy the properties for one gateway and provide a different gateway name and property values.

For more information about gateways, see Gateways and carriers.

For more information about setting properties, see Setting properties.

confirm_delivery property
confirm_timeout property
enable property
listeners_are_900 property
listener_port property
sender property
sender_port property


confirm_delivery property

Specify yes to confirm delivery. The default is yes. This property has an effect only when sending directly through this gateway (not indirectly via a device tracking gateway).


confirm_timeout property

Specify the amount of time before a confirmation should time out. Specify s, m, or h for seconds, minutes, or hours. If you do not specify s, m, or h, the default is seconds. The default confirmation timeout is 1m.


enable property

Specify enable=yes to use a UDP gateway. You can define and use multiple UDP gateways.

Examples

If you are using the MobiLink plug-in in Sybase Central, open the Gateways folder and double-click Add Gateway. New gateways are automatically enabled.

If you are configuring properties using the Notifier properties file, a UDP gateway called Gate3 is enabled with the following line:

UDP(Gate3).enable=yes

If you are using the stored procedure ml_add_property to enable the gateway Gate3, type the following:

ml_add_property( 'SIS','UDP(Gate3)','enable','yes' );


listener_port property

This is the port on the remote device where the gateway sends the UDP packet. This property is optional. The default is the default listening port of the UDP Listener (5001).


sender property

This is the IP address or host name of the sender. This property is optional, and is only useful for multi-homed hosts. The default is localhost.


sender_port property

This is the port to use for sending the UDP packet. This property is optional; you may need to set it if your firewall restricts outgoing traffic. If not set, your operating system will assign a free port.


Carrier properties

Carrier properties set up public wireless carrier configuration, which provides carrier-specific information such as how to map automatically-tracked phone numbers and network providers to SMS e-mail addresses.

Carrier information is used when the device tracker gateway needs an SMS e-mail address to be generated from an automatically-tracked device address. Addresses are generated in the following form:

email-address =
  sms_email_user_prefixphone-number@sms_email_domain

where:

  • sms_email_user_prefix is the value of the sms_email_user_prefix property

  • the phone number comes from the ml_device_address.address column

  • sms_email_domain is the value of the sms_email_domain property

See also
  • sms_email_domain property
  • sms_email_user_prefix property
  • ml_device_address

For more information about carriers, see Gateways and carriers.

For more information about setting properties, see Setting properties.


enable property

Specify enable=yes to use a Carrier mapping. You can define and use multiple Carrier mappings in one file.

Examples

If you are using the MobiLink plug-in in Sybase Central, open the Carriers folder and double-click Add Carrier Mapping. New carrier mappings are automatically enabled.

If you are configuring properties using the Notifier properties file, a carrier mapping called Bell Mobility 1x is enabled with the following line:

Carrier(Bell Mobility 1x).enable=yes

If you are using the stored procedure ml_add_property to enable the carrier Bell Mobility 1x, type the following (this assumes an Adaptive Server Anywhere consolidated database):

ml_add_property( 'SIS',
  'Carrier(Bell Mobility 1x)',
  'enable',
  'yes' );


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Server-Initiated Synchronization User's Guide

MobiLink Notification Properties

Carrier properties

network_provider_id property

Specifies the network provider ID.


sms_email_domain property

Specifies the domain name of the carrier.

Carrier information is used when the device tracker gateway needs an SMS e-mail address to be generated from an automatically-tracked device address. Addresses are generated in the following form:

email-address =
  sms_email_user_prefixphone-number@sms_email_domain

where:

  • sms_email_user_prefix is the value of the sms_email_user_prefix property

  • the phone number comes from the ml_device_address.address column

  • sms_email_domain is the value of the sms_email_domain property

See also
  • sms_email_user_prefix property
  • ml_device_address


sms_email_user_prefix property

Specifies the prefix used in e-mail addresses.

Carrier information is used when the device tracker gateway needs an SMS e-mail address to be generated from an automatically-tracked device address. Addresses are generated in the following form:

email-address =
  sms_email_user_prefixphone-number@sms_email_domain

where:

  • sms_email_user_prefix is the value of the sms_email_user_prefix property

  • the phone number comes from the ml_device_address.address column

  • sms_email_domain is the value of the sms_email_domain property

See also
  • sms_email_domain property
  • ml_device_address


Server-Initiated Synchronization Stored Procedures

About this chapter

This chapter describes the stored procedures that are provided for server-initiated synchronization. These stored procedures add and delete rows in MobiLink system tables.

Note: These stored procedures are used for device tracking. If you use remote devices that support automatic device tracking, you do not need to use these stored procedures. If you use remote devices that do not support automatic device tracking, you can configure manual device tracking using these stored procedures.

For more information, see Device tracking and Using device tracking with Listeners that don't support it.

For more information about MobiLink system tables, see MobiLink System Tables.

For information about other MobiLink stored procedures, see Stored Procedures.


ml_delete_device

Function

Use this stored procedure to delete all information about a remote device when you are manually setting up device tracking.

Parameters
Item | Parameter | Description
1 | device | VARCHAR(255). Device name.
Description

Example

Delete a device record and all associated records that reference this device record:

call ml_delete_device( 'myOldDevice' );


ml_delete_device_address

Function

Use this stored procedure to delete a device address when you are manually setting up device tracking.

Parameters
Item | Parameter | Description
1 | device | VARCHAR(255)
2 | medium | VARCHAR(255)
Description

For more information, see Using device tracking with Listeners that don't support it.

Example

Delete an address record:

call ml_delete_device_address( 'myFirstTreo180', 'ROGERS AT&T' );


ml_delete_listening

Function

Use this stored procedure to delete mappings between a MobiLink user and remote devices when you are manually setting up device tracking.

Parameters
Item | Parameter | Description
1 | ml_user | VARCHAR(128)
Description

For more information, see Using device tracking with Listeners that don't support it.

Example

Delete a recipient record:

call ml_delete_listening( 'myULDB' );


ml_set_device

Function

Use this stored procedure to add or alter information about remote devices when you are manually setting up device tracking. It adds or updates a row in the ml_device table.

Parameters
Item | Parameter | Description
1 | device | VARCHAR(255). User-defined unique device name.
2 | listener_version | VARCHAR(128). Optional remarks on listener version.
3 | listener_protocol | INTEGER. Use 0 for version 9.0.0, 1 for post-9.0.0 Palm Listeners, 2 for post-9.0.0 Windows Listeners.
4 | info | VARCHAR(255). Optional device information.
5 | ignore_tracking | CHAR(1). Set to y to ignore tracking and stop it from overwriting manually entered data.
6 | source | VARCHAR(255). Optional remarks on the source of this record.
Description

The stored procedures ml_set_device, ml_set_device_address, and ml_set_listening are used to override automatic device tracking by changing information in the MobiLink system tables ml_device, ml_device_address, and ml_listening. For example, if some of your remote devices are Palm devices you may want to use automatic device tracking but manually insert data for the Palm devices.

For more information, see Using device tracking with Listeners that don't support it.

See also
  • ml_set_device_address
  • ml_set_listening
  • ml_device
  • ml_device_address
  • ml_listening
Example

For each device, add a device record:

call ml_set_device(
   'myFirstTreo180',
   'MobiLink Listeners for Treo 180 - 9.0.1',
   '1',
   'not used',
   'y',
   'manually entered by administrator' );


ml_set_device_address

Function

Use this stored procedure to add or alter information about remote device addresses when you are manually setting up device tracking. It adds or updates a row in the ml_device_address table.

Parameters
Item | Parameter | Description
1 | device | VARCHAR(255). Existing device name.
2 | medium | VARCHAR(255). Network provider ID (must match a carrier's network_provider_id property).
3 | address | VARCHAR(255). Phone number of an SMS-capable device.
4 | active | CHAR(1).Set to y to activate this record to be used for sending notification.
5 | ignore_tracking | CHAR(1). Set to y to ignore tracking and stop it from overwriting manually entered data.
6 | source | VARCHAR(255). Optional remarks on the source of this record.
Description

The stored procedures ml_set_device, ml_set_device_address, and ml_set_listening are used to override automatic device tracking by changing information in the MobiLink system tables ml_device, ml_device_address, and ml_listening. For example, if some of your remote devices are Palms you may want to use automatic device tracking but manually insert data for the Palm devices.

For more information, see Using device tracking with Listeners that don't support it.

See also
  • ml_set_device
  • ml_set_listening
  • ml_device
  • ml_device_address
  • ml_listening
Example

For each device, add an address record for a device:

call ml_set_device_address(
      'myFirstTreo180',
      'ROGERS AT&T',
      '3211234567',
      'y',
  'y',
      'manually entered by administrator' );


ml_set_listening

Function

Use this stored procedure to add or alter mappings between MobiLink users and remote devices when you are manually setting up device tracking. It adds or updates a row in the ml_listening table.

Parameters
Item | Parameter | Description
1 | ml_user | VARCHAR(128). MobiLink user name.
2 | device | VARCHAR(255). Existing device name.
3 | listening | CHAR(1). Set to y to activate this record to be used for DeviceTracker addressing.
5 | ignore_tracking | CHAR(1). Set to y to ignore tracking and stop it from overwriting manually entered data.
6 | source | VARCHAR(255). Optional remarks on the source of this record.
Description

The stored procedures ml_set_device, ml_set_device_address, and ml_set_listening are used to override automatic device tracking by changing information in the MobiLink system tables ml_device, ml_device_address, and ml_listening. For example, if some of your remote devices are Palms you may want to use automatic device tracking but manually insert data for the Palm devices.

For more information, see Using device tracking with Listeners that don't support it.

See also
  • ml_set_device
  • ml_set_device_address
  • ml_device
  • ml_device_address
  • ml_listening
Example

For each remote database, add a recipient record for a device. This maps the device to the MobiLink user name.

call ml_set_listening(
      'myULDB',
      'myFirstTreo180',
      'y',
      'y',
      'manually entered by administrator' );


MobiLink Listener SDKs

About this chapter

This chapter describes the Listener Software Development Kit, which is provided to help you create support for remote devices that are not supported.


Introduction

If you want to use remote devices that are not currently supported by MobiLink server-initiated synchronization, you can use the Listener Software Development Kit to create Listeners for those devices. The Listener SDK is a simple program API that is provided to help you extend the Listener utility.

For example, you can use the Listener SDK to create Listeners for new Palm devices or new wireless network adapters. The SDK provides development material for both Windows (32-bit and CE) and Palm operating systems.

For more information about the Listener SDK for Palm, see Listener SDK for Palm.

For more information about the Listener SDK for Windows and Windows CE, see Listener SDK for Windows.

The MobiLink Listener SDK and sample implementations are located in the following files. All are located in the MobiLink\ListenerSDK subdirectory of your SQL Anywhere Studio installation.

Windows Listener SDK files
Windows Files | Description
\Win32andCE\Win32_VC\lsn.def | Visual C++ module definition for the Listener library.
\Win32andCE\CE_EVC\lsn.def | Embedded Visual C module definition for the Listener library.
\Win32andCE\src\lsn.h | Win32 and CE Listener library API.
\Win32andCE\src\swi510.c | Sierra Wireless AirCard 510 implementation.
Win32andCE\src\udp.c | UDP implementation.
Palm Listener SDK files
Palm Files | Description
\Palm\68k\cw\lib\PalmLsn.lib | Runtime library for Palm Listeners. This provides a message handling routine, Listener controls, and a handler editor.
\Palm\68k\cw\rsc\ | Contains UI resources for the Palm Listener.
\Palm\src\PalmLsn.h | Runtime library header and Palm Listener API.
\Palm\src\Kyocera7135.c | Kyocera 7135 implementation.
\Palm\src\Treo600.c | Treo 600 implementation.


Listener SDK for Windows

You can use the Listener SDK for Windows (32-bit and CE) to create shared Listener libraries for new wireless network adapters or communication protocols.

The library, conforming to a common interface used for retrieving server initiated synchronization messages, includes:

  • A class representing Listener message data.

  • Enumerations defining return values and version numbers for the Listener SDK.

  • Structures storing Listener state.

  • Functions controlling Listener message or state information.

For more information about Listener libraries, see Listening libraries.

The Listener utility (dblsn.exe) loads your library using the -d command line option.

For more information about dblsn options, see The Listener utility.

Data types
Message class
LSN_RET enumeration
LSN_VERSION enumeration
lsn_info structure
lsn_state structure
LsnInit function
LsnFini function
LsnIsListening
LsnSuspendListening function
LsnResumeListening function
LsnReceiveAll function
LsnReadNext function
LsnGetAddress
LsnGetMedium function


Data types

The following data types are defined in the Listener SDK for Windows. They map common value types to Listener types used in the SDK interface.

Name | Description
lsn_bool | unsigned char
lsn_ulong | unsigned long
lsn_long | long


Message class

The message class (a_msg) provides an interface to manage Listener messages, including:

  • Public fields to store message data.

  • Functions for message allocation, comparison, and basic manipulation.


a_msg public fields
Function

The message class contains fields you can use to represent the sender, the message contents, and optionally the time, type, and priority of a message.

Prototype
class a_msg {

// message class functions...
...

// message class fields

   public:
    lsn_long year;
    lsn_long month;    // 1 to 12
    lsn_long day;   // 1 to 31
    lsn_long hour;   // 0 to 23
    lsn_long minute;   // 0 to 59
    lsn_long second;   // 0 to 59
    lsn_long type;
    lsn_long priority;
    TCHAR * sender;
    TCHAR * message;
...

};
Parameters
Name | Description
sender | A string used for the sender of a message.
message | A string used for the message contents.
year | An integer used for the year field of a message.
month | An integer used for the month field of a message.
day | An integer used for the day field of a message.
hour | An integer used for the hour field of a message.
minute | An integer used for the minute field of a message.
second | An integer used for the second field of a message.
type | An integer used for the type of a message.
priority | An integer used for the priority of a message.
Remarks

In your implementation, you give meaning to each field listed above.

Use the lsn_info structure to specify if the time, type, and priority fields are applicable. For example, you can set the lsn_info isMsgPriorityApplicable field to FALSE to disable the a_msg priority field.

For more information about the lsn_info structure, see lsn_info structure.

Example

The following example declares an a_msg class instance and determines if the priority field is set to 1.

a_msg * msgA;

//...

if( msgA -> priority == 1)
{
      MessageBox( NULL,
     TEXT("Message Priority is 1."),
       TEXT( "Message from lsn_udp.dll" ), MB_ICONEXCLAMATION );
}


a_msg allocateSize function
Function

Returns a new a_msg instance with the specified size for sender and message fields.

Prototype

static a_msg * allocateSize (
long senderTChars,
long messageTChars
)

Parameters

  • senderTChars The number of characters used for the sender field.

  • messageTChars The number of characters used for the message field.

Return value

A new message class instance instance with all fields initialized to zero.

See also
  • Message class
Example

The following example uses the allocateSize function to create a new a_msg instance. In this implementation the sender field is 16 characters long and the message field is 200 characters long.

#define MAX_SENDER_TCHARS      16
#define MAX_MESSAGE_TCHARS      200

//...

a_msg* msgA;
msgA = a_msg::allocateSize( MAX_SENDER_TCHARS, MAX_MESSAGE_TCHARS );


a_msg copy function
Function

Overwrites the fields of the calling instance using an a_msg parameter.

Prototype

void copy ( a_msg * source-msg )

Parameters

  • source-msg An a_msg instance used to replace the information contained in the calling instance.

See also
  • Message class
Example

The following example uses the copy function to initialize msgA. In this case, the source is the copyOfLastReceivedMsg field of stateB, an lsn_state instance.

For more information about the lsn_state structure, see lsn_state structure.

a_msg* msgA;
msgA -> copy( stateB -> copyOfLastReceivedMsg );


a_msg equals function
Function

Determines if the public fields of the calling instance equal all fields in the a_msg parameter.

Prototype

bool equals ( a_msg * source-msg )

Parameters

  • source-msg An a_msg instance used to compare to the calling instance.

Return value

TRUE if the public fields of the calling instance equal all fields in the a_msg parameter. FALSE otherwise.

See also
  • Message class
Example

The following example uses the equals function to determine if msgA equals the copyOfLastReceivedMsg field of stateB, an lsn_state instance.

For more information about the lsn_state structure, see lsn_state structure.

a_msg* msgA;

//...

if(msgA -> equals( stateB -> copyOfLastReceivedMsg ))
{
      MessageBox( NULL,
     TEXT("msgA equals stateB->copyOfLastReceivedMsg."),
       TEXT( "Message from lsn_sw786.dll" ), MB_ICONEXCLAMATION );
}


a_msg makeEmpty function
Function

Clears (zeros) the fields of an a_msg instance.

Prototype

void makeEmpty ( )

See also
  • Message class
Example

The following example uses the makeEmpty function to clear the contents of an a_msg instance.

a_msg* msgA;
msgA -> makeEmpty();


a_msg reallocBuffers function
Function

Increases the size of the sender and message buffers for an a_msg instance.

Prototype

unsigned char reallocBuffers (
long senderTChars,
long messageTChars
)

Parameters

  • senderTChars The number of characters used for the sender field.

  • messageTChars The number of characters used for the message field.

Return value

TRUE if the sender and message fields are valid or non-NULL. FALSE otherwise.

Remarks

If the values specified at the input are less than the current length of the sender or message fields, the field size does not change.

See also
  • Message class
Example

The following example uses the reallocBuffers function to increase the sender and message fields of an a_msg instance. The LSN_RET_OUT_OF_MEMORY return code is used if the reallocation fails.

For more information about LSN_RET_OUT_OF_MEMORY, see LSN_RET enumeration.

#define MAX_SENDER_TCHARS      16
#define MAX_MESSAGE_TCHARS      200
//...

a_msg* msgA;
//...

if( msgA.reallocBuffers(MAX_SENDER_TCHARS, MAX_MESSAGE_TCHARS))
{
   ret = LSN_RET_OUT_OF_MEMORY;
   goto failed;
}


LSN_RET enumeration

Function

Defines the set of return values for Windows Listener SDK functions.

Prototype

typedef enum {
LSN_RET_OK = 0,
LSN_RET_NOT_SUP = 1,
LSN_RET_NO_RESP = 2,
LSN_RET_FAILED = 3,
LSN_RET_MSG_NOT_READ = 4,
LSN_RET_NO_MORE_MSG = 5,
LSN_RET_OUT_OF_MEMORY = 6,
LSN_RET_BAD_ARG = 7,
LSN_RET_NOT_ENOUGH_ARG = 8,
LSN_RET_TOO_MANY_ARGS = 9,
LSN_RET_SERVICE_NOT_ACTIVATED = 10
} LSN_RET;

Parameters
Value | Description
LSN_RET_OK | The function call is successful.
LSN_RET_NOT_SUP | The function call is invalid or not applicable. For example, the LsnSuspendListening function is not supported in the UDP Listener implementation. For more information, see LsnSuspendListening function.
LSN_RET_NO_RESP | The request timed out.
LSN_RET_FAILED | General failure.
LSN_RET_MSG_NOT_READ | Indicates unread messages in the Listener storage. The request to receive new messages has been ignored.
LSN_RET_NO_MORE_MSG | No unread messages remain. An attempt to read a message failed.
LSN_RET_OUT_OF_MEMORY | The function could not continue due to insufficient memory resources.
LSN_RET_BAD_ARG | A problem occurred with one or more input parameters.
LSN_RET_NOT_ENOUGH_ARG | More input arguments are required. This return value indicates an insufficient number of string arguments contained in the input array.
LSN_RET_TOO_MANY_ARGS | Fewer input arguments are required. This return value indicates an excess number of string arguments contained in the input array.


LSN_VERSION enumeration

Function

Defines the Listener SDK version number.

Prototype

typedef enum {
LSN_VERSION_1 = 1,
LSN_VERSION_2 = 2,
LSN_CURRENT_VERSION = LSN_VERSION_2
} LSN_VERSION;

Parameters
Value | Description
LSN_VERSION_1 | Specifies Listener SDK version 1.
LSN_VERSION_2 | Specifies Listener SDK version 2.
LSN_CURRENT_VERSION | Specifies the current Listener version.
Remarks

You should use this enumeration to specify the Listener SDK version that your application was developed against. To specify the current version, use LSN_CURRENT_VERSION.


lsn_info structure

Function

Stores Listener static information.

Prototype

typedef struct lsn_info {
lsn_ulong version;
lsn_ulong maxSenderTChars;
lsn_ulong maxMessageTChars;
lsn_bool isExtDialNeedSuspendListening;
lsn_bool isMsgTimeApplicable;
lsn_bool isMsgTypeApplicable;
lsn_bool isMsgPriorityApplicable;
lsn_bool isMsgTimeInUTC;

// LSN_VERSION_1 fields ends here

} lsn_info;

Parameters
Value | Description
version | Version of the Listener interface or SDK.
maxSenderTChars | Maximum number of characters in the sender name field.
maxMessageTChars | Maximum number of characters in the message field.
isExtDialNeedSuspendListening | If a Listener library needs to be suspended from receiving messages before another application can dial using a modem set this field to TRUE.
isMsgTimeApplicable | If the message class time fields (year, month, day, hour, minute, and second) are applicable set this field to TRUE. For more information, see a_msg public fields.
isMsgTypeApplicable | If the message class type field is applicable set this field to TRUE. For more information, see a_msg public fields.
isMsgPriorityApplicable | If the message class priority field is applicable set this field to TRUE. For more information, see a_msg public fields.
isMsgTimeInUTC | If the message class time fields are in coordinated universal time (UTC) set this field to TRUE. For more information, see a_msg public fields.
See Also
  • Message class
Example

The following example initializes lsn_info fields for a UDP Listener.

lsn_info * info;

info->version = LSN_VERSION_2;
info->maxSenderTChars = MAX_SENDER_TCHARS;
info->maxMessageTChars = MAX_MESSAGE_TCHARS;
info->isExtDialNeedSuspendListening = false;
info->isMsgTimeApplicable = false;
info->isMsgTypeApplicable = false;
info->isMsgPriorityApplicable = false;
info->isMsgTimeInUTC = false;


lsn_state structure

Function

The Listener state structure used for dynamic information.

Prototype
struct lsn_state;
// Add your Listener state fields here
Remarks

You add fields to this structure to store dynamic Listener information such as a message field, receive buffer, or a flag to specify unread messages.

Example

The following example shows the lsn_state structure used for the UDP Listener implementation.

typedef struct lsn_state {
    WSADATA wsaData;
    SOCKET socket;
    bool hideWSAErrorBox;
    bool unread;
    bool showSenderPort;
    a_msg * msg;
    struct timeval timeout;
    char * recvBuff;
    UINT codePage;
    TCHAR port[6];
} lsn_state;

The following example shows the lsn_state structure used for the Sierra Wireless AirCard 510 Listener implementation.

typedef struct lsn_state {
    bool apiOpened;
    int nextMsg;
    int numReceivedMsg;
    int messageStoreSize;
    a_msg copyOfLastReceivedMsg;
    a_msg ** messages;
    TCHAR * phone;
    TCHAR * carrier;
} lsn_state;


LsnInit function

Function

Allocates and initializes a Listener state structure.

Prototype

LSN_RET LsnInit (
lsn_info* info,
lsn_state** state,
lsn_long argc,
char* argv[],
lsn_long* badArg
)

Parameters

  • info This is an output parameter containing an lsn_info structure with static Listener information.

    For more information, see lsn_info structure.

  • state This is an output parameter pointing to the allocated lsn_state structure.

    For more information, see lsn_state structure.

  • argc The number of string arguments contained in the argv[] array.

  • argv[] An array of string arguments used to initialize the Listener state structure.

    You specify the arguments passed to argv[] using the dblsn.exe -a command line option. For example,

    dblsn -d my_lsn.dll -a prop1=v1 -a prop2=v2 ...

    results in the following string arguments:

    argv[] = { "prop1=v1", "prop2=v2", ... }

    For more information about the -a option, see The Listener utility.

  • badArg This is an output parameter providing argument error information. The meaning of this parameter depends on the LsnInit return value:

    • If the return value is LSN_RET_BAD_ARG, badArg is the index of the problematic argument in argv.

    • If the return is LSN_RET_NOT_ENOUGH_ARG, badArg is the minimum number of arguments required.

    • If the return value is LSN_TOO_MANY_ARGS, badArg is the maximum number of allowed arguments.

Return value

Use the following return values defined in the LSN_RET enumeration for this function.

Value | Description
LSN_RET_OK | The function call is successful.
LSN_RET_FAILED | General failure.
LSN_RET_OUT_OF_MEMORY | The function could not continue due to insufficient memory resources.
LSN_RET_BAD_ARG | A problem occurred with one or more input parameters.
LSN_RET_NOT_ENOUGH_ARG | More input arguments are required. This return value indicates an insufficient number of string arguments contained in the input array. [Am I right on this?]
LSN_RET_TOO_MANY_ARGS | Fewer input arguments are required. This return value indicates an excess number of string arguments contained in the input array.

For more information about the LSN_RET enumeration, see LSN_RET enumeration.

Remarks

Use this function to initialize your Listener and acquire necessary resources for the Listener to operate. If the function call is successful, your LsnInit implementation returns the filled lsn_info and allocated lsn_state structures.

The number and type of input parameters in the argv[] array depend on your implementation.

See also
  • LSN_RET enumeration
  • lsn_state structure
  • lsn_info structure
  • Message class
Example

The following example shows the LsnInit function used for the UDP Listener implementation.

LsnExport LSN_RET LsnExportFunc LsnInit(
    lsn_info * info, lsn_state** state, lsn_long argc,
    char* argv[], lsn_long* badArg )
/*****************************************************/
{
    // Argument names
    #define ARGN_RECEIVER_PORT "Port"
    #define ARGN_HIDE_WSA_ERROR_BOX "HideWSAErrorBox"
    #define ARGN_TIMEOUT_SEC "Timeout"
    #define ARGN_SHOW_SENDER_PORT "ShowSenderPort"
    #define ARGN_CODEPAGE "CodePage"

  // Helper macros
    #define IS_ARG( argn, x ) _strnicmp( argn "=", x, sizeof(argn) ) == 0
    #define ARG_VAL( argn, x ) &(x)[sizeof(argn)]

   LSN_RET ret = LSN_RET_FAILED;
    lsn_state * s;
    struct sockaddr_in receiverAddr;
    unsigned short port;
    int i;
    bool showUsageBox = true;
    *state = NULL;

      // Fill static info structure
    info->version = LSN_VERSION_2;
    info->maxSenderTChars = MAX_SENDER_TCHARS;
    info->maxMessageTChars = MAX_MESSAGE_TCHARS;
    info->isExtDialNeedSuspendListening = false;
    info->isMsgTimeApplicable = false;
    info->isMsgTypeApplicable = false;
    info->isMsgPriorityApplicable = false;
    info->isMsgTimeInUTC = false;

 // Check argc
    if( argc < 0 ) {
   *badArg = 0;
   ret = LSN_RET_NOT_ENOUGH_ARG;
   goto failed;
    }
    if( argc > 4 ) {
   *badArg = 4;
   ret = LSN_RET_TOO_MANY_ARGS;
   goto failed;
    }

 // Allocate state structure
    s = (lsn_state*)calloc( 1, sizeof(lsn_state) );
    if( s == NULL ) {
   showUsageBox = false;
   ret = LSN_RET_OUT_OF_MEMORY;
   goto failed;
    }

 // Initialize state structure
    memset( s, 0, sizeof(lsn_state) );
    s->socket = INVALID_SOCKET;
    s->hideWSAErrorBox = false;
    s->unread = false;
    s->showSenderPort = false;
    s->timeout.tv_sec = 0;
    s->timeout.tv_usec = 0;

// Allocate message in state structure
    s->msg = a_msg::allocateSize( MAX_SENDER_TCHARS, MAX_MESSAGE_TCHARS );
    if( s->msg == NULL ) {
   showUsageBox = false;
   ret = LSN_RET_OUT_OF_MEMORY;
   goto failed;
    }
#if defined( UNICODE )
    // Allocate recvBuff
    s->recvBuff = (char*)malloc( MAX_MESSAGE_BYTES + 1 );
    if( s->recvBuff == NULL ) {
   ret = LSN_RET_OUT_OF_MEMORY;
   goto failed;
    }
#endif
port = 5001;

 // Read args
    for( i = 0; i < argc; i++ ) {
   *badArg = i;
   if( IS_ARG( ARGN_RECEIVER_PORT, argv[i] ) ) {
       port = atoi( ARG_VAL( ARGN_RECEIVER_PORT, argv[i] ) );
   } else if( _stricmp( ARGN_HIDE_WSA_ERROR_BOX, argv[i] ) == 0 ) {
       s->hideWSAErrorBox = true;
   } else if( _stricmp( ARGN_SHOW_SENDER_PORT, argv[i] ) == 0 ) {
       s->showSenderPort = true;
   } else if( IS_ARG( ARGN_TIMEOUT_SEC, argv[i] ) ) {
       s->timeout.tv_sec = atol( ARG_VAL( ARGN_TIMEOUT_SEC, argv[i] ) );
   } else if( IS_ARG( ARGN_CODEPAGE, argv[i] ) ) {
       s->codePage = atol( ARG_VAL( ARGN_CODEPAGE, argv[i] ) );
   } else {
       ret = LSN_RET_BAD_ARG;
       goto failed;
   }
    }

 // Fill the port buffer
    _stprintf( s->port, TEXT("%d"), port );
    // At this point, all args are valid
    showUsageBox = false;
    *badArg = -1;
    // WSAStartup
    if( WSAStartup( 0x202, &s->wsaData ) != 0 ) {
   foundWSAError( s );
   goto failed;
    }

// Setup receiver address
    memset( &receiverAddr, 0, sizeof(receiverAddr) );
    receiverAddr.sin_family = AF_INET;
    receiverAddr.sin_addr.s_addr = INADDR_ANY;
    receiverAddr.sin_port = htons( port );
    // Open socket
    s->socket = socket( AF_INET, SOCK_DGRAM, 0 );
    if( s->socket == INVALID_SOCKET ) {
   foundWSAError( s );
   goto failed;
    }

 // Bind the socket to the receiver address
    if( bind( s->socket, (struct sockaddr*)&receiverAddr, sizeof( receiverAddr ) )
        == SOCKET_ERROR ) {
   foundWSAError( s );
   goto failed;
    }
    *state = s;
    return( LSN_RET_OK );
  failed:
    if( showUsageBox ) {
   MessageBox( NULL, USAGE, USAGE_TITLE, MB_ICONINFORMATION );
    }
    LsnFini( s );
    return( ret );
}


LsnFini function

Function

Shuts down the Listener and frees resources.

Prototype

void LsnFini ( lsn_state* state )

Parameters

  • state Points to an lsn_state structure instance.

    For more information, see lsn_state structure.

Remarks

Use this function to shutdown your Listener and free allocated resources, including the Listener state structure.

See also
  • lsn_state structure
  • Message class
Example

The following example shows the LsnFini function for the UDP Listener implementation.

LsnExport void LsnExportFunc LsnFini( lsn_state* state )
/*******************************************************/
{

 if( state != NULL ) {
    if( state->msg != NULL ) {
        delete( state->msg );
    }
    if( state->recvBuff != NULL ) {
        free( state->recvBuff );
    }
    if( state->socket != INVALID_SOCKET ) {
             closesocket( state->socket );
    }
    WSACleanup();
    free( state );
 }
}


LsnIsListening

Function

Determines if the Listener is ready to receive messages.

Prototype

bool LsnIsListening ( const lsn_state* state )

Parameters

  • state Points to an lsn_state structure instance.

    For more information about lsn_state, see lsn_state structure.

Return value

Returns TRUE if the Listener is ready to receive messages and FALSE otherwise.

Remarks

Use this function to define when your Listener is ready to receive messages.

See also
  • lsn_state structure
  • Message class
Example

The following example shows the LsnIsListening implementation for UDP Listeners.

LsnExport bool LsnExportFunc LsnIsListening(
    const lsn_state* state)
/**********************************************/
{
    return( state->socket != INVALID_SOCKET );
}


LsnSuspendListening function

Function

Suspends the Listener.

Prototype

LSN_RET LsnSuspendListening ( lsn_state* state )

Parameters

  • state Points to a Listener state structure instance.

    For more information about lsn_state, see lsn_state structure.

Return value

Use the following return values defined in the LSN_RET enumeration for this function.

Value | Description
LSN_RET_OK | The function call is successful.
LSN_RET_NOT_SUP | The function call is invalid or not applicable. For example, the LsnSuspendListening function is not supported in the UDP Listener implementation. For more information, see LsnSuspendListening function.
LSN_RET_NO_RESP | The request timed out.
LSN_RET_FAILED | General failure.

For more information about the LSN_RET enumeration, see LSN_RET enumeration.

Remarks

Use this function to prevent your Listener from receiving messages.

See also
  • LSN_RET enumeration
  • lsn_state structure
  • Message class
Example

The following example shows the LsnSuspendListening function for the Sierra Wireless AirCard 510 implementation. The SwiApiClose() function call suspends the modem from listening on SMS.

LsnExport LSN_RET LsnExportFunc LsnSuspendListening(
    lsn_state* state )
/******************************************************/
{
    if( !state->apiOpened ) {
        return( LSN_RET_OK );
    }
    state->apiOpened = FALSE;
    return( transformRcode( SwiApiClose() ) );
}

The following example shows the LsnSuspendListening implementation for UDP Listeners. Since UDP Listeners do not support this function, it uses the return value LSN_RET_NOT_SUP.

For more information about LSN_RET_NOT_SUP, see LSN_RET enumeration.

[ what is _unused ?]

LsnExport LSN_RET LsnExportFunc LsnSuspendListening(
    lsn_state* state )
/****************************************************/
{
    _unused( state );
    return( LSN_RET_NOT_SUP );
}


LsnResumeListening function

Function

Resumes a suspended listener.

Prototype

LSN_RET LsnResumeListening ( lsn_state* state )

Parameters

  • state Points to a Listener state structure instance.

    For more information about lsn_state, see lsn_state structure.

Return value

Use the following return values defined in the LSN_RET enumeration for this function.

Value | Description
LSN_RET_OK | The function call is successful.
LSN_RET_NOT_SUP | The function call is invalid or not applicable. For example, the LsnSuspendListening function is not supported in the UDP Listener implementation. For more information, see LsnSuspendListening function.
LSN_RET_NO_RESP | The request timed out.
LSN_RET_FAILED | General failure.

For more information about the LSN_RET enumeration, see LSN_RET enumeration.

Remarks

Use this function to resume a suspended Listener.

See also
  • LSN_RET enumeration
  • lsn_state structure
  • Message class
Example

The following example shows the LsnSuspendListening function for the Sierra Wireless AirCard 510 implementation. The SwiApiOpen( SESSION_NAME ) function call triggers the modem to resume listening on SMS.

[Can we provide a few words to describe this?]

LsnExport LSN_RET LsnExportFunc LsnResumeListening(
    lsn_state* state )
/****************************************************/
{
    LSN_RET ret;
    if( state->apiOpened ) {
        return( LSN_RET_OK );
    }
    ret = transformRcode( SwiApiOpen( SESSION_NAME ) );
    state->apiOpened = ( ret == LSN_RET_OK );
    return( ret );
}

The following example shows the LsnSuspendListening implementation for UDP Listeners. Since UDP Listeners do not support this function, it uses the return value LSN_RET_NOT_SUP.

For more information about LSN_RET_NOT_SUP, see LSN_RET enumeration.

LsnExport LSN_RET LsnExportFunc LsnResumeListening(
    lsn_state* state
)
/******************************************************/
{
    _unused( state );
    return( LSN_RET_NOT_SUP );
}


LsnReceiveAll function

Function

Receives pending messages.

Prototype

LSN_RET LsnReceiveAll (
lsn_state* state,
lsn_long* nMsg
)

Parameters

  • state Points to a lsn_state structure instance.

    For more information about lsn_state, see lsn_state structure.

  • nMsg Points to the number of received messages.

Return value

Use the following return values defined in the LSN_RET enumeration for this function.

Value | Description
LSN_RET_OK | The function call is successful.
LSN_RET_NO_RESP | The request timed out.
LSN_RET_FAILED | General failure.
LSN_RET_MSG_NOT_READ | Indicates unread messages in the Listener storage. The request to receive new messages has been ignored.

For more information about the LSN_RET enumeration, see LSN_RET enumeration.

Remarks

Use this function to receive pending messages into your Listener storage. This function should terminate when all pending messages are received or the store is full.

The nMsg parameter points to the number of messages that can be read using the LsnReadNext function.

For more information about the LsnReadNext function, see LsnReadNext function.

See also
  • LsnReadNext function
  • LSN_RET enumeration
  • lsn_state structure
  • Message class
Example

The following example shows the LsnReceiveAll function for the UDP Listener implementation.

LsnExport LSN_RET LsnExportFunc LsnReceiveAll(
    lsn_state* state, lsn_long* nMsg )
/************************************************/
{
    LSN_RET ret = LSN_RET_FAILED;
    int wsaRet;
    struct sockaddr_in from;
    int fromLen = sizeof(from);
    fd_set readableSockets;
    char* senderIpA;
#if defined( UNICODE )
    int mbwcRet;
    WCHAR senderIpW[ MAX_SENDER_TCHARS + 1 ];
    #define RECVBUFF   (state->recvBuff)
    #define SENDERIP   senderIpW
#else
    #define RECVBUFF (state->msg->message)
    #define SENDERIP   senderIpA
#endif

    if( state->unread ) {
   return( LSN_RET_MSG_NOT_READ );
    }
    if( nMsg != NULL ) {
   *nMsg = 0;
    }
    state->unread = false;

 // Select readable socket
    FD_ZERO( &readableSockets );
    FD_SET( state->socket, &readableSockets );
    switch( select( 0, &readableSockets, NULL, NULL, &state->timeout ) ) {
    case 0:
        // Nothing to read
        ret = LSN_RET_OK;
   break;
    case 1:
        // Receive the message
   wsaRet = recvfrom( state->socket, RECVBUFF,
          MAX_MESSAGE_BYTES, 0,
          (struct sockaddr *)&from, &fromLen );
   if( wsaRet == SOCKET_ERROR ) {
       foundWSAError( state );
       break;
   }
   // Null terminate the message
   RECVBUFF[ wsaRet ] = '\0';

#if defined( UNICODE )
   mbwcRet = MultiByteToWideChar( state->codePage, 0, state->recvBuff,
          -1, state->msg->message, MAX_MESSAGE_TCHARS );
   if( mbwcRet == 0 ) {
       MessageBox( NULL,
          TEXT("Failed to translate an incoming message"),
      TEXT( "Message from lsn_udp.dll" ), MB_ICONEXCLAMATION );
       break;
   }
#endif

   // Retrieve the sender name and port
   senderIpA = inet_ntoa( from.sin_addr );
   if( senderIpA == NULL ) {
       break;
   }
#if defined( UNICODE )
   size_t i;
   for( i = 0; i <= strlen( senderIpA ); i++ ) {
       senderIpW[i] = senderIpA[i];
   }
#endif

if( state->showSenderPort ) {
       _stprintf( state->msg->sender, TEXT("%s:%d"),
          SENDERIP, ntohs( from.sin_port ) );
   } else {
       _tcscpy( state->msg->sender, SENDERIP );
   }
        if( nMsg != NULL ) {
       *nMsg = 1;
   }

   state->unread = true;
   ret = LSN_RET_OK;
   break;
    case SOCKET_ERROR:
   foundWSAError( state );
   break;
    }
    return( ret );
}


LsnReadNext function

Function

Used to read the next message into a message buffer.

Prototype

LSN_RET LsnReadNext (
lsn_state* state,
a_msg* msg
)

Parameters

  • state Points to a Listener state structure instance.

    For more information about lsn_state, see lsn_state structure.

  • msg Points to the destination message buffer.

Return value

Use the following return values defined in the LSN_RET enumeration for this function.

Value | Description
LSN_RET_OK | The function call is successful.
LSN_RET_NO_MORE_MSG | No unread messages remain. An attempt to read a message failed.

For more information about the LSN_RET enumeration, see LSN_RET enumeration.

Remarks

Use this function to read the next message from your Listener storage.

See also
  • LSN_RET enumeration
  • lsn_state structure
  • Message class
Example

The following example shows the LsnReadNext function for the UDP Listener implementation.

LsnExport LSN_RET LsnExportFunc LsnReadNext(
lsn_state* state, a_msg* msg )
/**********************************************/
{
    if( !state->unread ) {
   return( LSN_RET_NO_MORE_MSG );
    }
    msg->copy( state->msg );
    state->unread = false;
    return( LSN_RET_OK );
}


LsnGetAddress

Function

Returns the Listener address.

Prototype

const TCHAR * LsnGetAddress ( lsn_state* state )

Parameters

  • state Points to a Listener state structure instance.

    For more information about lsn_state, see lsn_state structure.

Return value

A character array containing the Listener address.

Remarks

Use this function to return the address used for your Listener.

The address, for example, can be specified as a phone number.

See also
  • lsn_state structure
  • Message class
Example

The following example shows the LsnGetAddress function for the Sierra Wireless AirCard 510 implementation.

LsnExport const TCHAR * LsnExportFunc LsnGetAddress(
  lsn_state* state )
/***************************************************/
{
    if( state->phone == NULL ) {
   return( TEXT("Unspecified") );
    }
    return( state->phone );
}


LsnGetMedium function

Function

Returns the carrier or medium used for Listener communication.

Prototype

TCHAR * LsnGetMedium ( lsn_state* state );

Parameters

  • state Points to a Listener state structure instance.

    For more information about lsn_state, see lsn_state structure.

Return value

A character array storing the medium or carrier name.

Remarks

Use this function to return the carrier or medium used for your Listener.

See also
  • lsn_state structure
  • Message class
Example

The following example shows the LsnGetMedium function for the Sierra Wireless AirCard 510 implementation.

LsnExport const TCHAR * LsnExportFunc LsnGetMedium(
  lsn_state* state )
/**************************************************/
{
   if( state->carrier == NULL ) {
 return( TEXT("Unspecified") );
    }
   return( state->carrier );
}


Listener SDK for Palm

You can use the Listener SDK for Palm to create Listeners for new Palm devices. The programming interface includes a message processing interface and device dependent functions.


Message processing interface

The message processing interface is contained in PalmLsn.lib, the Palm Listener Library.

For more information about PalmLsn.lib, see Palm Listener SDK files.

a_palm_msg structure

The Palm Listener SDK uses the a_palm_msg structure to represent Palm Listener messages. The SDK's message processing interface includes functions to allocate and process a_palm_msg instances.

Overview
PalmLsnAllocate function
PalmLsnFree function
PalmLsnDupMessage function
PalmLsnDupSender function
PalmLsnDupTime function
PalmLsnProcess function
PalmLsnCheckConfigDB function
palm_lsn_ret enumeration


Overview

The following functions can be used for a_palm_msg allocation, message field initialization, and message processing.

  • Message allocation You can use the following functions for message allocation and deallocation:

    Overview

    PalmLsnFree function

  • Message field initialization You can use the following functions to assign values to the message, sender, and time fields of an a_palm_msg instance.

    PalmLsnDupMessage function

    PalmLsnDupSender function

    PalmLsnDupTime function

  • Message processing You can use the PalmLsnProcess function to process a message's fields and launch an application.

    For more information, see PalmLsnProcess function.


PalmLsnAllocate function
Function

Returns a new a_palm_msg instance.

Prototype

struct a_palm_msg * PalmLsnAllocate( )

Return value

A new a_palm_msg instance with all fields initialized to zero.

See Also
  • PalmLsnFree function
Example

The following example uses PalmLsnAllocate to allocate an a_palm_msg instance.

a_palm_msg *   ulMsg;

// Allocate a message structure
ulMsg = PalmLsnAllocate();


PalmLsnFree function
Function

Frees message memory resources.

Prototype

void PalmLsnFree( struct a_palm_msg * const msg )

Parameters

  • msg The a_palm_msg instance to be freed.

See Also
  • Overview
Example

The following example shows a partial listing for allocating the message structure, processing the message, and using PalmLsnFree to free resources.

a_palm_msg *   ulMsg;
...

// Allocate the message structure
ulMsg = PalmLsnAllocate();
...

// Fill the message fields
ret = PalmLsnDupMessage( ulMsg, msgBody );
...

// Process the message
ret = PalmLsnProcess( ulMsg, configDb, NULL, handled );
...

// Free the message
PalmLsnFree( ulMsg );


PalmLsnDupMessage function
Function

Initializes the message field values of an a_palm_msg instance.

Prototype

Err PalmLsnDupMessage(
struct a_palm_msg * const msg,
Char const * message
)

Parameters

  • msg A pointer to an a_palm_msg instance.

  • message An input parameter containing the source message text.

Return Value

A Palm OS error code. errNone indicates success.

Remarks

The PalmLsnDupMessage function duplicates a text message, extracts the subject, content, and sender fields, and assigns these values to an a_palm_msg instance.

The sender field is not extracted if it does not appear in the message. If you use PalmLsnDupSender it overrides the sender field extracted from PalmLsnDupMessage (if any).

See Also
  • PalmLsnDupSender function
  • PalmLsnDupTime function
  • a_palm_msg structure
Example

The following example, used for the Treo 600 smartphone implementation, retrieves a text message and calls PalmLsnDupMessage to initialize the appropriate fields in an a_palm_msg instance.

//
// Retrieve the entire message body
//
ret = PhnLibGetText( libRef, id, &msgBodyH );
if( ret != errNone ) {
    // handle error
    goto done;
}
msgBody = (Char *)MemHandleLock( msgBodyH );
ret = PalmLsnDupMessage( ulMsg, msgBody );
//
// msgBodyH must be disposed of by the caller
//
MemHandleUnlock( msgBodyH );
MemHandleFree( msgBodyH );
if( ret != errNone ) {
  // handle error
  goto done;
}


PalmLsnDupSender function
Function

Initializes the sender field of an a_palm_msg instance.

Prototype

Err PalmLsnDupSender(
struct a_palm_msg * const msg,
Char const * sender
)

Parameters

  • msg A pointer to an a_palm_msg instance.

  • sender An input parameter containing the source sender field.

Return Value

A Palm OS error code. errNone indicates success.

Remarks

The PalmLsnDupSender function duplicates the sender input parameter and assigns the value to an a_palm_msg instance.

See Also
  • PalmLsnDupMessage function
  • PalmLsnDupTime function
  • a_palm_msg structure


PalmLsnDupTime function
Function

Initializes the time field of an a_palm_msg instance.

Prototype

Err PalmLsnDupTime(
struct a_palm_msg * const msg,
UInt32 const time
)

Parameters

  • msg A pointer to an a_palm_msg instance.

  • time An input parameter containing the source time field.

Return Value

A Palm OS error code. errNone indicates success.

Remarks

The PalmLsnDupTime function duplicates the time input parameter and assigns the value to an a_palm_msg instance.

See Also
  • PalmLsnDupMessage function
  • PalmLsnDupSender function
  • a_palm_msg structure


PalmLsnProcess function
Function

Processes a message according to the records in a configuration database.

Prototype

palm_lsn_ret PalmLsnProcess(
struct a_palm_msg * msg,
Char const * configPDBName,
UInt16 * const problematicRecNum,
Boolean * handled
)

Parameters

  • msg A pointer to an a_palm_msg instance.

  • configPDBName A character array containing the name of the configuration database. You can obtain the configuration database name using the PalmLsnGetConfigFileName function.

    See PalmLsnGetConfigFileName.

  • problematicRecNum An output parameter identifying the index of a problematic or malformed record in the configuration database.

  • handled An output parameter indicating if PalmLsnProcess successfully processed the message.

Return Value

Return codes defined in the palm_lsn_ret enumeration.

See palm_lsn_ret enumeration.

Remarks

PalmLsnProcess determines the appropriate action to take in response to an incoming message. It compares the message's fields to filters stored in a configuration database.

For more information about creating the Palm Listener configuration database, see Palm Listener Configuration utility.

The records contained in the configuration database store information about message filters and what actions should result from an accepted message.

A configuration record has the following format:

[subject=<string>;] [content=<string>;]
[message|message_start=<string>;] [sender=<string>;]
action=run <app name> [arguments]

arguments is an application dependent string which may contain action variables.

For more information about action variables, see Action variables.

See Also
  • Palm Listener Configuration utility
  • Message handlers
  • Action variables
  • PalmLsnCheckConfigDB function
  • a_palm_msg structure
Example

The following is a partial listing used to handle a message. The example allocates the message structure, initializes fields, and processes the message using PalmLsnProcess.

a_palm_msg * ulMsg;
Boolean * handled
Char configDb[ dmDBNameLength ];
...

// Allocate the message structure
ulMsg = PalmLsnAllocate();
...

// Fill the message fields
ret = PalmLsnDupMessage( ulMsg, msgBody );
...

// Get the configuration database name
PalmLsnGetConfigFileName( configDb );

// Process the message
ret = PalmLsnProcess( ulMsg, configDb, NULL, handled );
...

// Free the message
PalmLsnFree( ulMsg );


PalmLsnCheckConfigDB function
Function

Reports errors in a Palm Listener configuration database.

Prototype

palm_lsn_ret PalmLsnCheckConfigDB(
Char const * cfg,
UInt16 * const rec
)

Parameters

  • cfg A character array containing the name of the configuration database. You can obtain the configuration database name using the PalmLsnGetConfigFileName function.

    See PalmLsnGetConfigFileName.

  • rec An output parameter identifying the index of a problematic or malformed record in the configuration database.

Return Value

Return codes defined in the palm_lsn_ret enumeration.

See palm_lsn_ret enumeration.

Remarks

You can use this function to detect errors opening a configuration database or reading its records.

See Also
  • PalmLsnProcess function
Example

The following example uses PalmLsnCheckConfigDB to detect problematic or malformed records in a configuration database.

Err ret;
UInt16 badRec;
Char configDb[ dmDBNameLength ];

// Get configuration database name
PalmLsnGetConfigFileName( configDb );

// check for errors in the configuration database
ret = PalmLsnCheckConfigDB(configDb, &badRec);
if(ret!=errNone)
{
  // handle error
}


palm_lsn_ret enumeration
Function

The palm_lsn_ret enumeration specifies the possible message processing return codes.

Prototype

typedef enum {
PalmLsnOk = errNone,
PalmLsnMissingConfig = appErrorClass,
PalmLsnProblemReadingConfig,
PalmLsnProblemParsingCmd,
PalmLsnOutOfMemory,
PalmLsnUnrecognizedAction,
PalmLsnRunMissingApp
} palm_lsn_ret;

Parameters
Value | Description
PalmLsnOk | The function call is successful. This value contains the same value as errNone, a Palm error code indicating no error.
PalmLsnMissingConfig | Indicates a missing Palm Listener configuration database. This field contains the same value as the Palm error code appErrorClass, indicating an application-defined error.
PalmLsnProblemReadingConfig | Indicates an error reading the Palm Listener configuration database.
PalmLsnProblemParsingCmd | Indicates an inability to process the command stored in the Palm Listener configuration database.
PalmLsnOutOfMemory | The function does not run to completion due to an error while allocating memory for message processing.
PalmLsnUnrecognizedAction | The Listener does not support an action specified in the Palm Listener configuration database.
PalmLsnRunMissingApp | The Listener cannot launch the application specified in the run action.
See Also
  • PalmLsnProcess function


LsnMain function

Function

Provides the main entry point to PalmLsn.lib, the Palm Listener library.

Prototype

UInt32 LsnMain(
UInt16 cmd,
MemPtr cmdPBP,
UInt16 launchFlags
)

Parameters

  • cmd A Palm OS application launch code.

  • cmdPBP A pointer to a structure containing launch code parameters. If your application does not have any launch-command-specific parameters, this value is NULL.

  • launchFlags Flags that provide extra information about the launch.

Return Value

A Palm OS error code. If the Palm listener library successfully processed the launch code, the function returns errNone.

Remarks

The values passed to LsnMain are analogous to the launch code parameters passed to PilotMain, the main entry point of a Palm OS application.

For more information about these parameters, consult your Palm OS Reference.

See Also
  • PalmLsnProcess function
  • Palm Listener SDK files
Example

The following example, used in theTreo 600 smartphone implementation, passes launch code parameters to LsnMain in the main entry point of the Listener application.

UInt32 PilotMain(
/***************/
    UInt16 cmd,
    MemPtr cmdPBP,
    UInt16 launchFlags )
{
    return( LsnMain( cmd, cmdPBP, launchFlags ) );
}


Device dependent functions

You specify device dependent features using a group of functions defined in the Palm Listener SDK. These functions provide:

  • Identification You can use the following functions to provide identification information for the Listener and the configuration database:

    PalmLsnTargetCompanyID

    PalmLsnTargetDeviceID

    PalmLsnGetConfigFileName

  • Registration or initialization You can use the following functions to register or unregister the Listener.

    PalmLsnNormalStart

    PalmLsnNormalStop

  • Event handling You can use the following function to handle application events:

    PalmLsnNormalHandleEvent

    You can use the following function to respond to launch codes which may be device dependent.

    PalmLsnSpecialLaunch

PalmLsnTargetCompanyID
PalmLsnTargetDeviceID
PalmLsnGetConfigFileName
PalmLsnNormalStart
PalmLsnNormalStop
PalmLsnNormalHandleEvent
PalmLsnSpecialLaunch


PalmLsnTargetCompanyID
Function

Returns a device's company ID.

Prototype

UInt32 PalmLsnTargetCompanyID( )

Return Value

A value containing the ID of the device's company or manufacturer.

Remarks

You can use PalmLsnTargetCompanyID and PalmLsnTargetDeviceID to check for device compatibility.

See Also
  • PalmLsnTargetDeviceID
Example

The following example, used in the Treo 600 smartphone implementation, returns 'hspr', a company ID for Handspring.

UInt32 PalmLsnTargetCompanyID( void )
/***********************************/
{
    return( 'hspr' );
}


PalmLsnTargetDeviceID
Function

Returns the target device ID.

Prototype

UInt32 PalmLsnTargetDeviceID( )

Return Value

A positive integer containing the device ID.

Remarks

You can use PalmLsnTargetCompanyID and PalmLsnTargetDeviceID to check for device compatibility.

See Also
  • PalmLsnTargetCompanyID
Example

The following example returns the device ID for the Treo 600 simulator.

UInt32 PalmLsnTargetDeviceID( void )
/**********************************/
{
    // Simulator device ID is hsDeviceIDOs5Device1Sim
    return( hsDeviceIDOs5Device1 );
}


PalmLsnGetConfigFileName
Function

Returns a string containing the name of your Palm Listener configuration database.

Prototype

void PalmLsnGetConfigFileName( Char * configPDBName )

Parameters

  • configPDBName An output parameter containing the name of your Palm Listener configuration database.

Remarks

You can use this function to obtain the configuration database file name to pass into PalmLsnProcess.

To use the default configuration database file name lsncfg copy PalmLsnDefaultConfigDB (defined in PalmLsn.h) into the output parameter.

See Also
  • PalmLsnProcess function
  • Palm Listener SDK files
Example

The following example, used for the Treo 600 smartphone implementation, returns the default configuration database name in the output parameter.

void PalmLsnGetConfigFileName( Char * configPDBName )
{
    StrCopy( configPDBName, PalmLsnDefaultConfigDB );
}


PalmLsnNormalStart
Function

Provides custom actions when your Listener application starts.

Prototype

Err PalmLsnNormalStart( )

Return Value

A Palm OS error code. errNone indicates success.

Remarks

PalmLsnNormalStart provides a means to register your Listener device.

See Also
  • PalmLsnNormalStop
  • PalmLsnSpecialLaunch


PalmLsnNormalStop
Function

Provides custom actions when your Listener application exits from the event loop.

Prototype

void PalmLsnNormalStop( )

Remarks

If you want to continue listening, do not unregister your device in PalmLsnNormalStop. You can also use this function to get and set the current application preferences.

See Also
  • PalmLsnNormalStart


PalmLsnNormalHandleEvent
Function

Handles application events.

Prototype

Boolean PalmLsnNormalHandleEvent( EventPtr eventP )

Parameters

  • eventP A pointer to an application event.

Return Value

Returns true if the event was handled.

Remarks

You can use this function to handle application events.


PalmLsnSpecialLaunch
Function

Responds to launch codes which may be device dependent.

Prototype

Err PalmLsnSpecialLaunch(
UInt16 cmd,
MemPtr cmdPBP,
UInt16 launchFlags
)

Parameters

  • cmd The Palm OS application launch code.

  • cmdPBP A pointer to a structure containing launch code parameters. If your application does not have any launch-command-specific parameters, this value is NULL.

  • launchFlags Flags that indicate status information about your application.

Return Value

A Palm OS error code. errNone indicates success.

Remarks

This function responds to device dependent or standard launch codes not defined as sysAppLaunchCmdNormalLaunch.

Example

The following example, used for the Treo 600 smartphone implementation, uses PalmLsnSpecialLaunch to handle Listener events.

Err PalmLsnSpecialLaunch(
/***********************/
    UInt16 cmd,
    MemPtr cmdPBP,
    UInt16 /*launchFlags*/ )
{
switch( cmd ) {

  case sysAppLaunchCmdSystemReset:
    // Fall through

  case phnLibLaunchCmdRegister:
   break;

case phnLibLaunchCmdEvent: {
   if( !IsFeatureOn( PalmLsnGetFeature(), Listening ) ) {
      return( errNone );
   }

 PhnEventPtr phoneEventP = (PhnEventPtr)cmdPBP;

 if( phoneEventP->eventType == phnEvtMessageInd ) {
      // handle the message
      return( handleMessage( phoneEventP->data.params.id, &phoneEventP->acknowledge ) );
    }
  }
 default:
   break;
}
return( errNone );
}

If a message is detected, handleMessage is used to process the message into the appropriate action.

static Err handleMessage( PhnDatabaseID id, Boolean * handled )
/*************************************************************/
// This routine will construct a_palm_msg and then call
// PalmLsnProcess to process it.
{

  a_palm_msg *     ulMsg;
  Err              ret;
  Boolean          newlyLoaded;
  PhnAddressList   addrList;
  PhnAddressHandle addrH;
  MemHandle        msgBodyH;
  Char *           msgSender;
  Char *           msgBody;
  UInt32           msgTime;
  Char             configDb[ dmDBNameLength ];
  UInt16           libRef   = 0;
  // CDMA workaround recommended by Handspring
  DmOpenRef        openRef   = 0;
  *handled = false;

  // Allocate a message structure for passing over
  // to PalmLsnProcess later

  ulMsg = PalmLsnAllocate();
  if( ulMsg == NULL ) {
    return( sysErrNoFreeRAM );
   }
  // Load the phone library

  ret = findOrLoadPhoneLibrary( &libRef, &newlyLoaded );
  if( ret != errNone ) {
   goto done;
  }
  openRef = PhnLibGetDBRef( libRef );
  // Retrieve sender of the message

  ret = PhnLibGetAddresses( libRef, id, &addrList );
  if( ret != errNone ) {
      goto done;
  }
  ret = PhnLibGetNth( libRef, addrList, 1, &addrH );
 if( ret != errNone ) {
    PhnLibDisposeAddressList( libRef, addrList );
    goto done;
  }

  msgSender = PhnLibGetField( libRef, addrH, phnAddrFldPhone );
  if( msgSender != NULL ) {
    ret = PalmLsnDupSender( ulMsg, msgSender );
    MemPtrFree( msgSender );
  }
  PhnLibDisposeAddressList( libRef, addrList );
  if( ret != errNone ) {
    goto done;
  }

  // Retrieve message time

  ret = PhnLibGetDate( libRef, id, &msgTime );
  if( ret != errNone ) {
   goto done;
  }
  ret = PalmLsnDupTime( ulMsg, msgTime );
  if( ret != errNone ) {
    goto done;
  }
  // Retrieve the entire message body

  ret = PhnLibGetText( libRef, id, &msgBodyH );
  if( ret != errNone ) {
      goto done;
  }
  msgBody = (Char *)MemHandleLock( msgBodyH );
  ret = PalmLsnDupMessage( ulMsg, msgBody );

  // msgBodyH must be disposed of by the caller

  MemHandleUnlock( msgBodyH );
  MemHandleFree( msgBodyH );
  if( ret != errNone ) {
    goto done;
  }

  // Get the configuration database name

  PalmLsnGetConfigFileName( configDb );

  // Call PalmLsnProcess to process the message

  ret = PalmLsnProcess( ulMsg, configDb, NULL, handled );
done:
  if( ulMsg != NULL ) {
    PalmLsnFree( ulMsg );
  }
  PhnLibReleaseDBRef( libRef, openRef );

  // Unload the phone library before any possible application switch

  if( newlyLoaded ) {
    unloadPhoneLibrary( libRef );
    newlyLoaded = false;
  }
  return( ret );
}


Tutorial: Server-Initiated Synchronization

About this chapter

This chapter demonstrates how to configure a consolidated and remote database for server-initiated synchronization. It shows how to set up a simple synchronization from scratch using an Adaptive Server Anywhere consolidated database.

Several sample implementations of server-initiated synchronization are included in the SQL Anywhere Studio installation. They are fully documented in readmes and code comments. To locate the sample applications, navigate to the Samples\MobiLink directory in your SQL Anywhere Studio install path. All server-initiated synchronization sample directories start with the prefix SIS_.

Server-initiated synchronization using the car dealer sample
Lesson 1: Set up the consolidated database
Lesson 2: Create a push request table
Lesson 3: Configure the Notifier
Lesson 4: Configure gateways and carriers
Lesson 5: Define an ODBC data source
Lesson 6: Start the MobiLink server
Lesson 7: Set up a remote database
Lesson 8: Configure the Listener
Lesson 9: Issue push requests


Server-initiated synchronization using the car dealer sample

Car dealer sample

This tutorial is based on the sample located in the Samples\MobiLink\SIS_CarDealer subdirectory in your SQL Anywhere installation. This tutorial uses a single client located on a desktop computer. However, server initiated synchronization Listeners can be installed on other platforms, such as Windows CE and Palm OS. For more information, consult the SIS_CarDealer sample and MobiLink server-initiated synchronization documentation.

Tutorial overview


Tutorial overview

Following is an overview of the steps required to set up MobiLink server-initiated synchronization using the Car Dealer sample. The purpose of this lesson is to provide an overview of what's to come; later steps will describe how to do each of these steps.

toggle Set up the consolidated database and Notifier utility

  1. Create an Adaptive Server Anywhere database with the following schema:

    • A table used for synchronization.

      For this tutorial, the table is called Dealer and stores the name and rating of automobile manufacturers.

    • Synchronization logic for download-only synchronization.

      For this tutorial, you will implement the download_cursor synchronization script.

    • A table to store push requests.

      Populating this table triggers remote notification.

  2. Configure the Notifier utility.

    Provide logic to handle the begin_poll, request_cursor, and request_delete events.

  3. Configure gateways and carriers.

    This tutorial uses the default gateway settings for a UDP Listener.

  4. Start the MobiLink synchronization server with the -notifier option.

toggle Set up the remote database and Listener utility

  1. Create an Adaptive Server Anywhere database with a table used for synchronization.

    This table will be synchronized with the consolidated database Dealer table.

  2. Create a remote synchronization publication, synchronization user, and synchronization subscription.

  3. Create dblsn.txt, the command-line file for the MobiLink Listener.

  4. Start a local UDP Listener.

toggle Issue push requests

  • To issue push requests, you can insert data directly into the push request table or make other changes that will cause the Notifier begin_poll event to populate the push request table. Each request will cause the Notifier to send a message using the request_cursor event.

    If the message of a push request matches a message defined in the Listener command file, for example 'sync', the remote database will synchronize (or take the corresponding action).


Lesson 1: Set up the consolidated database

In this lesson, you create a consolidated database with the scripts required for synchronization.

One way to create an Adaptive Server Anywhere database is to use the dbinit command-line utility. In this tutorial, the consolidated database is called cons.

toggle To create and start a new Adaptive Server Anywhere consolidated database

  1. At a command prompt, navigate to the directory where you would like to create the database.

  2. Type the following command to create the database:

    dbinit cons.db

  3. Now, to start the database, type:

    dbeng9 cons.db
Generate the consolidated database schema

The consolidated database schema includes a Dealer table, a download_cursor synchronization script, and a table and stored procedure to generate server-initiated synchronization push requests.

toggle To add the Dealer table and download_cursor synchronization script

  1. Connect to the consolidated database:

    • In Sybase Central, select the Adaptive Server Anywhere 9 plug-in. From the File menu, choose Connect.

      The Connect dialog appears.

    • On the Identification tab, type DBA as the User ID and SQL as the Password. On the Database tab, type cons as the Server Name.

    • Click OK to connect.

  2. Start Interactive SQL:

    • In Sybase Central, select the cons database. From the File menu, choose Open Interactive SQL.

  3. Install the Dealer table and download_cursor synchronization script.

    • Execute the following commands in Interactive SQL:

      /* the dealer table */
create table Dealer (
    name      varchar(10) not null primary key,
    rating      varchar(5),
    last_modified   timestamp default timestamp
)
go
insert into Dealer(name, rating) values ( 'Audi', 'a');
insert into Dealer(name, rating) values ( 'Buick', 'b');
insert into Dealer(name, rating) values ( 'Chrysler', 'c' );
insert into Dealer(name, rating) values ( 'Dodge', 'd');
insert into Dealer(name, rating) values ( 'Eagle', 'e');
insert into Dealer(name, rating) values ( 'Ford', 'f');
insert into Dealer(name, rating) values ( 'Geo', 'g');
insert into Dealer(name, rating) values ( 'Honda', 'h');
insert into Dealer(name, rating) values ( 'Isuzu', 'i');
go

/* the download_cursor synchronization script */
call ml_add_table_script( 'sis_ver1', 'Dealer', 'download_cursor',
'SELECT * FROM Dealer WHERE last_modified >= ?' )
go
Further reading

For more information about the topics in this lesson, see:

  • The Initialization utility
  • The database server
  • Using Interactive SQL
  • CREATE TABLE statement
  • Writing Synchronization Scripts
  • download_cursor table event


Lesson 2: Create a push request table

The Notifier sends a message to a remote database when it detects a push request. In a typical implementation, you add a push request table to your consolidated database.

toggle To create a table for push requests

  1. Execute the following command in Interactive SQL:

    CREATE TABLE PushRequest (
    req_id   INTEGER DEFAULT AUTOINCREMENT PRIMARY KEY,
    mluser   VARCHAR(128),
    subject   VARCHAR(128),
    content VARCHAR(128),
    resend_interval VARCHAR(30) DEFAULT '20s',
    time_to_live VARCHAR(30) DEFAULT '1m',
    status   VARCHAR(128) DEFAULT 'created'
)
go

  2. Close Interactive SQL.

Further reading

For more information about the topics in this lesson, see:

  • Push requests
  • Introducing Server-Initiated Synchronization
  • Components of server-initiated synchronization


Lesson 3: Configure the Notifier

In this lesson you configure three Notifier properties to influence how the Notifier creates push requests, transmits the requests to remote Listeners, and cleans up expired requests.

toggle To configure the Notifier utility

  1. Connect to the consolidated database using the MobiLink Synchronization plug-in:

    • Open Sybase Central.

    • In the left pane, select the MobiLink Synchronization 9 plug-in. From the File menu, choose Connect.

      The Connect dialog appears.

    • On the Identification tab, type DBA as the User ID and SQL as the Password. On the Database tab, type cons as the Server Name.

    • Click OK to connect.

  2. Add a new Notifier.

    In the left-pane, open the Notification folder and select the Notifiers folder. In the right-pane double-click Add Notifier.

    The Add a New Notifier dialog appears.

  3. Name the Notifier CarDealerNotifier. Click Finish.

  4. Enter the begin_poll event script.

    The Notifier detects changes in the consolidated database and creates push requests using the begin_poll event. In this case, the begin_poll script will populate the PushRequest table if changes occur in the Dealer table and when a remote database is not up-to-date.

    • In the right pane, select the CarDealerNotifier. From the File menu, choose Properties.

      The CarDealerNotifier Notifier Properties dialog appears.

    • Click the Logic tab. From the dropdown menu, choose begin_poll.

    • Enter the following for the begin_poll script:

      --
-- Insert the last consolidated database
-- modification date into @last_modified
--
declare @last_modified timestamp;
select max( last_modified ) into @last_modified from Dealer;
      --
-- Delete processed requests if the mluser is up-to-date
--
delete from PushRequest
  from PushRequest as p, ml_user as u, ml_subscription as s
where
      p.status = 'processed'
and
  u.name = p.mluser
and
  u.user_id = s.user_id
and
  @last_modified <= greater( s.last_upload_time, s.last_download_time );
      --
-- Insert new requests when a device is not up-to-date
--
insert into PushRequest( mluser, subject, content )
select u.name, 'sync', 'ignored'
 from ml_user as u, ml_subscription as s
where
 u.name in ( select ml_user from ml_listening where listening = 'y' )
and
 u.user_id = s.user_id
and
 @last_modified > greater( s.last_upload_time, s.last_download_time )
and
 u.name not like '%-dblsn'
and
 not exists( select * from PushRequest
  where PushRequest.mluser = u.name
    and PushRequest.subject = 'sync')

    In the first major section of the begin_poll script, processed requests from the PushRequest table are eliminated if a device is up to date:

    @last_modified <= greater( s.last_upload_time, s.last_download_time)

    @last_modified is the maximum modification date in the consolidated database Dealer table. The expression greater( s.last_upload_time, s.last_download_time) represents the last synchronization time for a remote database.

    You can also delete push requests directly using the request_delete event. However, the begin_poll event, in this case, ensures that expired or implicitly dropped requests are not eliminated before a remote database synchronizes.

    The next section of code checks for changes in the last_modified column of the Dealer table and issues push requests for all active listeners (listed in the ml_listening table) that are not up to date:

    @last_modified > greater( s.last_upload_time, s.last_download_time)

    When populating the PushRequest table, the begin_poll script sets the subject to 'sync'.

  5. Enter the request_cursor script.

    The request_cursor script fetches push requests. Each push request determines what information is sent in the message, and which remote databases receive the information.

    • From the dropdown menu, choose request_cursor.

    • Enter the following code for the request_cursor script:

      select
   p.req_id,
   'Default-DeviceTracker',
   p.subject,
   p.content,
   p.mluser,
   p.resend_interval,
   p.time_to_live
from PushRequest as p

    The PushRequest table supplies rows to the request_cursor script.

    The order and values in the request_cursor result set is significant. The second parameter, for example, defines the default gateway Default-DeviceTracker. A device tracker gateway keeps track of how to reach users and automatically selects UDP or SMTP to connect to remote devices.

  6. Enter the request_delete script.

    The request_delete notifier event specifies cleanup operations. Using this script, the Notifier can automatically remove implicitly dropped and expired requests.

    • From the dropdown menu, choose request_delete.

    • Enter the following for the request_delete script:

      update PushRequest set status='processed' where req_id = ?

    Instead of deleting the row, this request_delete script updates the status of a row in the PushRequest table to 'processed'.

  7. Click OK to save the Notifier properties.

Further reading

For more information about the topics in this lesson, see:

  • Managing Databases with Sybase Central
  • request_delete property
  • begin_poll property
  • ml_listening
  • Device tracking
  • Listener options for device tracking
  • request_cursor property
  • request_delete property


Lesson 4: Configure gateways and carriers

Gateways are the mechanisms for sending messages. You can define UDP gateways and SMTP gateways. Alternatively, you can use a device tracker gateway. With device tracking, MobiLink keeps track of how to reach users, and automatically decides to use a UDP or SMTP gateway.

In this tutorial you use a default device tracker gateway, so no confirguration is necessary.

Further reading

For more information about the topics in this lesson, see:

  • Device tracker gateway properties
  • Gateways and carriers


Lesson 5: Define an ODBC data source

Use the Adaptive Server Anywhere 9.0 driver to define an ODBC data source for the database.

toggle To define an ODBC data source for the consolidated database

  1. Start the ODBC Administrator:

    From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > ODBC Administrator.

    The ODBC Data Source Administrator appears.

  2. On the User DSN tab, click Add.

    The Create New Data Source dialog appears.

  3. Select Adaptive Server Anywhere 9.0 and click Finish.

    The ODBC Configuration for Adaptive Server Anywhere 9 dialog appears.

  4. On the ODBC tab, type the Data source name sis_cons. On the Logic tab, type DBA for the User ID and SQL for the Password. On the Database tab, type cons for the Server Name.

  5. Click OK.

Further reading

For more information about the topics in this lesson, see:

  • Working with ODBC data sources

If you are using a consolidated database other than Adaptive Server Anywhere, see Introduction to iAnywhere Solutions ODBC Drivers.


Lesson 6: Start the MobiLink server

toggle To run the MobiLink synchronization server (dbmlsrv9)

  • At a command prompt, navigate to the directory of your consolidated database. Type the following on a single line:

    dbmlsrv9
   –notifier
   –c "dsn=sis_cons"
   –o ml.log
   –fr
   –v+
   -zu+
   -x tcpip

    The following table describes each option used with the dbmlsrv9 utility. The options -o and -v provide debugging and troubleshooting information. Using these logging options is appropriate in a development environment. For performance reasons, -v is typically not used in production.

    Option Description
    -notifier Starts the Notifier for server-initiated synchronization.

    See -notifier option.
    -c Specifies a connection string.

    See -c option.
    -o Specifies the message log file ml.log.

    See -o option.
    -fr Prevents the MobiLink synchronization server from aborting if a synchronization does not include at least one script that uploads and one script that downloads data. This option is required for this tutorial which uses download-only synchronization.

    See -fr option.
    -v+ The -v option specifies what information is logged. Using -v+ sets maximum verbose logging.

    See -v option.
    -zu+ Adds new users automatically.

    See -zu option.
    -x Sets the communications protocol and protocol options for MobiLink clients.

    See -x option.

    A dialog appears to indicate the MobiLink synchronization server is ready to handle requests. The Notifier utility also appears.

Further reading

For more information about the topics in this lesson, see:

  • Running the MobiLink synchronization server
  • MobiLink Synchronization Server Options


Lesson 7: Set up a remote database

MobiLink server-initiated synchronization is designed for synchronization involving a consolidated database server and a large number of mobile databases. In this lesson, you create an Adaptive Server Anywhere remote database, create a synchronization publication, user, and subscription. Then, you create the command file for the Listener utility and start the Listener.

toggle To create and start a new Adaptive Server Anywhere remote database

  1. At a command prompt, navigate to the directory where you would like to create the database.

  2. Type the following command to create the database:

    dbinit rem1.db

  3. Now, to start the database, type:

    dbeng9 rem1.db
toggle To generate the remote database schema

  1. Connect to the database:

    • In Sybase Central, select the Adaptive Server Anywhere 9 plug-in. From the File menu, choose Connect.

      The Connect dialog appears.

    • On the Identification tab, type DBA as the User ID and SQL as the Password. On the Database tab, type rem1 as the Server Name.

    • Click OK to connect.

  2. Start Interactive SQL:

    • In Sybase Central, select the rem1 database. From the File menu, choose Open Interactive SQL.

  3. Create the Dealer table.

    • Execute the following command in Interactive SQL:

      create table Dealer (
    name      varchar(10) not null primary key,
    rating      varchar(5),
    last_modified   timestamp default timestamp
)
go

  4. Create a synchronization publication, user, and subscription.

    • Execute the following commands in Interactive SQL:

      CREATE PUBLICATION car_dealer_pub (table Dealer);
CREATE SYNCHRONIZATION USER sis_user1;
CREATE SYNCHRONIZATION SUBSCRIPTION
   TO car_dealer_pub
     FOR sis_user1
     OPTION scriptversion='sis_ver1';
Further reading

For more information about the topics in this lesson, see:

  • Introducing MobiLink Clients
  • The Initialization utility
  • CREATE TABLE statement
  • Publishing data
  • CREATE PUBLICATION statement
  • CREATE SYNCHRONIZATION USER statement [MobiLink]
  • CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]
  • Script versions


Lesson 8: Configure the Listener

The Listener runs on remote devices. It receives messages from the Notifier and processes them into actions. For example, the Listener will start dbmlsync if it receives the message "sync" when the following dblsn option is specified:

-l "subject=sync;action='run dbmlsync.exe...'

A convenient way to configure the Listener is to store command line options in a text file. For example, if you store the settings in mydblsn.txt, you can start the Listener by typing:

dblsn @mydblsn.txt

Alternatively, if you type dblsn without any parameters, dblsn will use dblsn.txt as the default argument file.

toggle To create and start the MobiLink Listener

  1. Create a text file mydblsn.txt with the following contents.

    #----------------------------------
# Verbosity level
-v2

# Show notification messages in console and log
-m

# Polling interval, in seconds
-i 3

# Truncate, then write output to dblsn.log
-ot dblsn.log
    # Mobilink address and connect parameter for dblsn
-x "host=localhost"

# Enable device tracking and specify the MobiLink user name.
-t+ sis_user1

# Message handlers
# Synchronize using dbmlsync
-l "subject=sync;
action='start dbmlsync.exe
 -c eng=rem1;uid=dba;pwd=sql
 -ot dbmlsyncOut.txt -k';"

    • Save the file as mydblsn.txt.

  2. Start the Listener.

    At a command prompt, navigate to the directory of your Listener command file.

    Start the listener by typing:

    dblsn @mydblsn.txt

A dialog appears indicating the Listener is running and has uploaded device tracking information to the MobiLink synchronization server.

When tracking information is uploaded to the consolidated database, you should notice a new entry in the MobiLink synchronization server window. This information relays the successful initial communication between the Listener and the MobiLink synchronization server.

Further reading

For more information about the topics in this lesson, see:

  • Listeners
  • The Listener utility
  • Storing Listener options


Lesson 9: Issue push requests

For server-initiated synchronization, you can issue push requests by populating the PushRequest table directly, or making a change in the Dealer table. In the latter case, the Notifier begin_poll script will detect the change in the Dealer table and populate the PushRequest table.

In either case, the PushRequest table supplies rows to the Notifier request_cursor script, which determines how remote devices receive messages.

toggle To insert a push request directly into the PushRequest table prompting server-initiated synchronization

  1. From Interactive SQL, connect to the cons.db database and enter the following:

    INSERT INTO pushrequest(mluser,subject,content)
  VALUES ('sis_user1','sync','not used');
  COMMIT;

  2. Wait a few seconds for the synchronization to occur.

When populated, the PushRequest table supplies rows to the Notifier's request_cursor script. The request_cursor script determines what information is sent in the message, and which remote devices receive the information.

toggle To make a change in the consolidated database Dealer prompting server-initiated synchronization

  1. From Interactive SQL, enter the following:

    UPDATE Dealer SET RATING = 'B'
   WHERE name = 'Geo'; commit;

  2. Wait a few seconds for the synchronization to occur.

In this case, the Notifier begin_poll script detects changes in the dealer table and will populate the push request table appropriately. As before, once the PushRequest table is populated, the Notifier request_cursor script determines what information is sent in the message, and which remote devices receive the information.

Further reading

For more information about the topics in this lesson, see:

  • Creating push requests
  • INSERT statement
  • UPDATE statement


Web Links Browse Collapse Expand PDF Previous Next

MobiLink Tutorials

Version 9.0.2

DC00194-01-0902-01

October 2004

Copyright
About This Manual
Tutorial: Introduction to MobiLink
Tutorial: Writing MobiLink Scripts and Monitoring Synchronizations
Tutorial: Using MobiLink with an Oracle 8i Consolidated Database
Tutorial: Java Synchronization Logic With Adaptive Server Anywhere
Tutorial: .NET Synchronization Logic With Adaptive Server Anywhere
The Contact Sample Application
The CustDB Sample Application


About This Manual

Subject

This manual contains tutorials that help you learn how to use MobiLink synchronization technology.

Before you begin

For more information about MobiLink, see Introducing MobiLink Synchronization.


SQL Anywhere Studio documentation

This book is part of the SQL Anywhere documentation set. This section describes the books in the documentation set and how you can use them.

The SQL Anywhere Studio documentation

The SQL Anywhere Studio documentation is available in a variety of forms: in an online form that combines all books in one large help file; as separate PDF files for each book; and as printed books that you can purchase. The documentation consists of the following books:

  • Introducing SQL Anywhere Studio This book provides an overview of the SQL Anywhere Studio database management and synchronization technologies. It includes tutorials to introduce you to each of the pieces that make up SQL Anywhere Studio.

  • What's New in SQL Anywhere Studio This book is for users of previous versions of the software. It lists new features in this and previous releases of the product and describes upgrade procedures.

  • Adaptive Server Anywhere Database Administration Guide This book covers material related to running, managing, and configuring databases and database servers.

  • Adaptive Server Anywhere SQL User's Guide This book describes how to design and create databases; how to import, export, and modify data; how to retrieve data; and how to build stored procedures and triggers.

  • Adaptive Server Anywhere SQL Reference Manual This book provides a complete reference for the SQL language used by Adaptive Server Anywhere. It also describes the Adaptive Server Anywhere system tables and procedures.

  • Adaptive Server Anywhere Programming Guide This book describes how to build and deploy database applications using the C, C++, and Java programming languages. Users of tools such as Visual Basic and PowerBuilder can use the programming interfaces provided by those tools. It also describes the Adaptive Server Anywhere ADO.NET data provider.

  • Adaptive Server Anywhere Error Messages This book provides a complete listing of Adaptive Server Anywhere error messages together with diagnostic information.

  • SQL Anywhere Studio Security Guide This book provides information about security features in Adaptive Server Anywhere databases. Adaptive Server Anywhere 7.0 was awarded a TCSEC (Trusted Computer System Evaluation Criteria) C2 security rating from the U.S. Government. This book may be of interest to those who wish to run the current version of Adaptive Server Anywhere in a manner equivalent to the C2-certified environment.

  • MobiLink Administration Guide This book describes how to use the MobiLink data synchronization system for mobile computing, which enables sharing of data between a single Oracle, Sybase, Microsoft or IBM database and many Adaptive Server Anywhere or UltraLite databases.

  • MobiLink Clients This book describes how to set up and synchronize Adaptive Server Anywhere and UltraLite remote databases.

  • MobiLink Server-Initiated Synchronization User's Guide This book describes MobiLink server-initiated synchronization, a feature of MobiLink that allows you to initiate synchronization from the consolidated database.

  • QAnywhere User's Guide This manual describes MobiLink QAnywhere, a messaging platform that enables the development and deployment of messaging applications for mobile and wireless clients, as well as traditional desktop and laptop clients.

  • iAnywhere Solutions ODBC Drivers This book describes how to set up ODBC drivers to access consolidated databases other than Adaptive Server Anywhere from the MobiLink synchronization server and from Adaptive Server Anywhere remote data access.

  • SQL Remote User's Guide This book describes all aspects of the SQL Remote data replication system for mobile computing, which enables sharing of data between a single Adaptive Server Anywhere or Adaptive Server Enterprise database and many Adaptive Server Anywhere databases using an indirect link such as e-mail or file transfer.

  • SQL Anywhere Studio Help This book includes the context-sensitive help for Sybase Central, Interactive SQL, and other graphical tools. It is not included in the printed documentation set.

  • UltraLite Database User's Guide This book is intended for all UltraLite developers. It introduces the UltraLite database system and provides information common to all UltraLite programming interfaces.

  • UltraLite Interface Guides A separate book is provided for each UltraLite programming interface. Some of these interfaces are provided as UltraLite components for rapid application development, and others are provided as static interfaces for C, C++, and Java development.

In addition to this documentation set, PowerDesigner and InfoMaker include their own online documentation.

Documentation formats

SQL Anywhere Studio provides documentation in the following formats:

  • Online documentation The online documentation contains the complete SQL Anywhere Studio documentation, including both the books and the context-sensitive help for SQL Anywhere tools. The online documentation is updated with each maintenance release of the product, and is the most complete and up-to-date source of documentation.

    To access the online documentation on Windows operating systems, choose Start > Programs > SQL Anywhere 9 > Online Books. You can navigate the online documentation using the HTML Help table of contents, index, and search facility in the left pane, as well as using the links and menus in the right pane.

    To access the online documentation on UNIX operating systems, see the HTML documentation under your SQL Anywhere installation.

  • PDF books The SQL Anywhere books are provided as a set of PDF files, viewable with Adobe Acrobat Reader.

    The PDF books are accessible from the online books, or from the Windows Start menu.

  • Printed books The complete set of books is available from Sybase sales or from eShop, the Sybase online store at [external link] http://eshop.sybase.com/eshop/documentation.


Finding out more and providing feedback

Finding out more

Additional information and resources, including a code exchange, are available at the iAnywhere Developer Network at [external link] http://www.ianywhere.com/developer/.

If you have questions or need help, you can post messages to the iAnywhere Solutions newsgroups listed below.

When you write to one of these newsgroups, always provide detailed information about your problem, including the build number of your version of SQL Anywhere Studio. You can find this information by typing dbeng9 -v at a command prompt.

The newsgroups are located on the forums.sybase.com news server. The newsgroups include the following:

  • [external link] sybase.public.sqlanywhere.general

  • [external link] sybase.public.sqlanywhere.linux

  • [external link] sybase.public.sqlanywhere.mobilink

  • [external link] sybase.public.sqlanywhere.product_futures_discussion

  • [external link] sybase.public.sqlanywhere.replication

  • [external link] ianywhere.public.sqlanywhere.ultralite

Newsgroup disclaimer
iAnywhere Solutions has no obligation to provide solutions, information or ideas on its newsgroups, nor is iAnywhere Solutions obliged to provide anything other than a systems operator to monitor the service and ensure its operation and availability.

iAnywhere Solutions Technical Advisors as well as other staff assist on the newsgroup service when they have time available. They offer their help on a volunteer basis and may not be available on a regular basis to provide solutions and information. Their ability to help is based on their workload.

Feedback

We would like to receive your opinions, suggestions, and feedback on this documentation.

You can e-mail comments and suggestions to the SQL Anywhere documentation team at [external link] iasdoc@ianywhere.com. Although we do not reply to e-mails sent to that address, we read all suggestions with interest.

In addition, you can provide feedback on the documentation and the software through the newsgroups listed above.


Tutorial: Introduction to MobiLink

About this chapter

This chapter provides a very introductory tutorial to guide you through the process of setting up a synchronization system that uses Adaptive Server Anywhere databases.

Introduction
Lesson 1: Creating and populating your databases
Lesson 2: Running the MobiLink synchronization server
Lesson 3: Running the MobiLink synchronization client
Cleanup
Summary
Further reading


Introduction

In this tutorial, you use Adaptive Server Anywhere to create a consolidated database and a remote database. You then synchronize these databases using MobiLink synchronization technology.

Timing

The tutorial takes about 30 minutes.

Goals

You will gain competence and familiarity with:

  • The MobiLink synchronization server and client as an integrated system.

  • The MobiLink synchronization server and client command lines and options.

  • How to create an ODBC connection and set the properties of an ODBC connection for Adaptive Server Anywhere.

  • How to initialize a database.

Key concepts

The MobiLink synchronization server connects to the consolidated database using ODBC. The MobiLink synchronization client connects to your remote database. The MobiLink synchronization server and client function as a group, managing the upload and download of data from one database to another.

Suggested background reading

For more information about the architecture of MobiLink, see Synchronization Basics.

For more information about the Adaptive Server Anywhere utility for running SQL commands, see Using Interactive SQL.


Lesson 1: Creating and populating your databases

MobiLink synchronization requires that you have a consolidated database, at least one remote database, and an ODBC data source for each database.

Create your database files

The first step is to create each of the databases. In this procedure, you build a consolidated database and a remote database using the dbinit utility from a command line.

The dbinit utility creates a database file with no user tables or procedures. You create your database schema when you define, within the newly-initialized file, user-defined tables and procedures.

toggle To create your database files

  1. Open a command prompt and navigate to the Samples\MobiLink\AutoScripting subdirectory of your SQL Anywhere 9 installation.

  2. Create a consolidated database for this tutorial. Run the following command line:

    dbinit consol.db

    If this tutorial has been previously run on your computer, consol.db and consol.log may already exist. This will cause dbinit to fail. Delete these files before running dbinit.

  3. Create the remote database for this tutorial. Run the following command line:

    dbinit remote.db

    If this tutorial has been previously run on your computer, remote.db and remote.log may already exist. This will cause dbinit to fail. Delete these files before running dbinit.

  4. Verify the successful creation of these database files by listing the contents of the directory. You should see consol.db and remote.db in the listing.

Create ODBC data sources

You are now ready to build ODBC data sources through which you can connect to your Adaptive Server Anywhere databases.

toggle To create ODBC data sources

  1. Open a command prompt and navigate to the Samples\MobiLink\AutoScripting subdirectory of your SQL Anywhere 9 installation.

  2. Create an ODBC data source for your consolidated database by running the following command line:

    dbdsn -w test_consol -y -c "uid=DBA;pwd=SQL;dbf=consol.db;eng=Consol"

    This command line specifies the following dbdsn options:

    • -w Creates a data source definition.

    • -y Delete or overwrite data source without confirmation.

    • -c Specifies the connection parameters as a connection string.

    For more information, see Data Source utility options.

  3. Create an ODBC data source for a remote database by running the following command line:

    dbdsn -w test_remote -y -c "uid=DBA;pwd=SQL;dbf=remote.db;eng=Remote"
Create your schema

The following procedure executes SQL statements using the Interactive SQL utility to create and populate tables in the consolidated database. It also creates tables and inserts synchronization subscriptions and publications into the remote database.

It does this using two predefined SQL files, build_consol.sql and build_remote.sql. You may want to open these files in a text editor to examine them in detail.

toggle To create your schema

  1. Open a command prompt and navigate to the Samples\MobiLink\AutoScripting subdirectory of your SQL Anywhere 9 installation.

  2. Run the following command line:

    dbisql -c "dsn=test_consol;astop=no" build_consol.sql

    The SQL statements in build_consol.sql create and populate the emp and cust tables in the consolidated database.

    This step includes astop=no to instruct the server not to shut down when the dbisql utility shuts down.

  3. Run the following command line:

    dbisql -c "dsn=test_remote;astop=no" build_remote.sql

    The SQL statements in build_remote.sql create the remote tables emp and cust, and insert synchronization subscriptions and publications.

  4. Verify the creation of the emp and cust tables in the remote and consolidated databases using Interactive SQL:

    • Open Interactive SQL by typing dbisql at a command prompt. Connect using the test_consol DSN as DBA, using SQL as the password.

    • Execute the following SQL statement by typing it into the SQL Statements pane and pressing F9.

         SELECT * FROM emp, cust

      The tables in the consolidated database are populated with data.

    • Connect using the test_remote DSN and execute the following SQL statement:

         SELECT * FROM emp, cust

      The tables in the remote database are empty.

  5. Leave the consolidated and remote databases running for the next lesson.

Further reading

For more information about creating databases, see The Initialization utility and Creating a database using the dbinit command-line utility.

For more information about running Interactive SQL, see The Interactive SQL utility and Using Interactive SQL.

For more information about SELECT statements, see SELECT statement.

For more information about creating ODBC data sources, see The Data Source utility.

For more information about creating remote databases, see Creating a remote database.

For more information about creating subscriptions and publications, see Publishing data.


Lesson 2: Running the MobiLink synchronization server

Your consolidated database must be running prior to starting the MobiLink synchronization server. If you shut down your consolidated database following Lesson 1, you should restart the database.

toggle To start the MobiLink synchronization server

  1. Open a command prompt and navigate to the Samples\MobiLink\AutoScripting subdirectory of your SQL Anywhere 9 installation.

  2. Run the following command line:

    dbmlsrv9 -c "dsn=test_consol" -o mlserver.mls -v+ -dl -za -zu+

This command line specifies the following dbmlsrv9 options:

  • -c The connection string for the MobiLink synchronization server uses the DSN for the consolidated database. For more information, see -c option.

  • -o The -o option is used to specify the message log file. For more information, see -o option.

  • -v+ The -v+ option sets verbose logging on. For more information, see -v option.

  • -dl The -dl option sets the display log feature ON. For more information, see -dl option.

  • -za The -za option turns automated scripting ON. For more information, see -za option.

  • -zu+ The -zu+ option automates the user authentication process. For more information, see -zu option.

    The options -o, -v, and -dl are chosen to provide debugging and troubleshooting information. These options are typically not used in a production environment.

Once you have executed the MobiLink synchronization server command, the output below appears.

A MobiLink output screen, with a display screen showing Ready to Handle Requests.

If the MobiLink synchronization server is already running when you attempt to run dbmlsrv9, you will receive an error message. Shut down the current instance of MobiLink and run the command again.

Further reading

For more information about the MobiLink synchronization server, see The MobiLink synchronization server.

For a complete list of dbmlsrv9 options, see MobiLink Synchronization Server Options.


Lesson 3: Running the MobiLink synchronization client

Adaptive Server Anywhere clients initiate MobiLink synchronization by using the dbmlsync utility.

toggle To start the MobiLink synchronization client

  1. Open a command prompt and navigate to the Samples\MobiLink\AutoScripting subdirectory of your SQL Anywhere 9 installation.

  2. Run the following command line:

    dbmlsync -c "dsn=test_remote" -o dbmlsync.out -v -e "SendColumnNames=ON"

    This command line specifies the following options:

    • -c Supply database connection parameters. For more information, see -c option.

    • -o Specify the message log file. For more information, see -o option.

    • -v Verbose operation. For more information, see -v option.

    • -e Extended options. Specifying "SendColumnNames=ON" sends column names to MobiLink. This is required when you use -za in the dbmlsrv9 command line. For more information, see SendColumnNames (scn) extended option.

Once you have executed the MobiLink synchronization client command, the output below appears to indicate that synchronization has succeeded. After synchronization, the remote database is populated with the data from the consolidated database.

A MobiLink output screen, with a bar-type display showing a successful synchronization.
Further reading

For more information about dbmlsync options, see MobiLink synchronization client.

For more information about remote clients, see MobiLink clients.

For more information about dbmlsync, see Initiating synchronization.


Cleanup

You should delete the databases and ODBC data sources that you created in this tutorial.

toggle To remove tutorial materials from your computer

  1. Open a command prompt and navigate to the Samples\MobiLink\AutoScripting subdirectory of your SQL Anywhere 9 installation.

  2. Run the file clean.bat.


Summary

During this tutorial, you:

  • Created and populated Adaptive Server Anywhere consolidated and remote databases.

  • Started a MobiLink synchronization server.

  • Started the MobiLink synchronization client and synchronized the remote database with the consolidated database.

Learning accomplishments

During this tutorial, you gained:

  • Familiarity with the MobiLink synchronization server and client as an integrated system.

  • Competence in executing MobiLink synchronization server and client commands.

  • Familiarity with the MobiLink synchronization server and client command lines and options.


Further reading

The following documentation sections are good starting points for further reading.

For more information about Adaptive Server Anywhere remote databases, see Adaptive Server Anywhere Clients.

For more information about running the MobiLink synchronization server, see Synchronization Basics.

For more information about synchronization scripting, see Writing Synchronization Scripts.

For a more advanced tutorial that describes how to write and add scripts, see Tutorial: Writing MobiLink Scripts and Monitoring Synchronizations.


Tutorial: Writing MobiLink Scripts and Monitoring Synchronizations

About this chapter

This chapter provides a tutorial to guide you through the process of writing synchronization scripts, including conflict detection and resolution scripts. It also shows you how to monitor synchronizations.

Introduction
Lesson 1: Set up the Adaptive Server Anywhere consolidated database
Lesson 2: Set up the remote Adaptive Server Anywhere databases
Lesson 3: Creating scripts for your synchronization
Lesson 4: Run MobiLink synchronization
Lesson 5: Monitoring your MobiLink synchronization using log files
Lesson 6: Creating scripts for conflict detection and resolution
Lesson 7: Use the MobiLink Monitor to detect update conflicts
Tutorial cleanup
Further reading


Introduction

Timing

The tutorial takes about 120 minutes.

Goals

The goals for the tutorial are to gain competence and familiarity with the following tasks:

  • Migrating the consolidated database schema to remote databases.

  • Writing the basic scripts needed for synchronization and storing them in the consolidated database using Sybase Central or Interactive SQL.

  • Writing scripts for conflict detection and resolution.

  • Monitoring synchronization using log files and the MobiLink Monitor.

Suggested background reading

For more information about the architecture of MobiLink, see Synchronization Basics.

For more information about synchronization scripts, see Introduction to synchronization scripts.

For more information about Interactive SQL, see Using Interactive SQL.

For more information about Sybase Central, see Managing Databases with Sybase Central.

For an introduction to synchronization, see Tutorial: Introduction to MobiLink.

For more information about MobiLink Conflict resolution, see Handling conflicts.

For more information about the MobiLink Monitor, see MobiLink Monitor.


Lesson 1: Set up the Adaptive Server Anywhere consolidated database

This lesson guides you through the following steps to set up your Adaptive Server Anywhere consolidated database:

  1. Create the consolidated database and schema.

  2. Define an ODBC data source for the consolidated database.

Create the consolidated database

In this procedure, you create the consolidated database using the Sybase Central Create a Database wizard.

toggle To create your Adaptive Server Anywhere RDBMS

  1. Start Sybase Central.

    Choose Start > Programs > Sybase SQL Anywhere 9 > Sybase Central.

    Sybase Central appears.

  2. In Sybase Central, choose Tools > Adaptive Server Anywhere 9 > Create Database.

    The Create a Database wizard appears. Click Next.

  3. Leave the default of Create a Database on this Computer. Click Next.

  4. Enter the filename and path for the database. For example, enter:

    C:\temp\cons.db

  5. Follow the remaining instructions in the wizard, accepting the default values, except as follows.

    • Choose a 4096 byte page size.

      A 4K page size increases performance for many environments.

  6. Click Finish to connect to the new database in Sybase Central.

Generate the consolidated database schema

The consolidated database schema includes the Product table, storing the name and quantity of hardware products.

toggle To add the Product table to the consolidated schema

  1. Start Interactive SQL.

    • In the left pane of Sybase Central, select the cons - DBA database. From the File menu choose Open Interactive SQL.

      Interactive SQL appears.

  2. Install the Product table.

    • Execute the following commands in Interactive SQL.

      /* the Product table */
create table Product (
    name      varchar(128) not null primary key,
    quantity      integer,
    last_modified   timestamp default timestamp
)
go
      insert into Product(name, quantity)
  values ( 'Screwmaster Drill', 10);

insert into Product(name, quantity)
  values ( 'Drywall Screws 10lb', 30);

insert into Product(name, quantity)
  values ( 'Putty Knife x25', 12);

go

  3. Install temporary tables used for conflict resolution.

    In Lesson 6: Creating scripts for conflict detection and resolution you write scripts inserting values into these tables when a conflict occurs.

    /* the Product_old table */
create table Product_old (
    name      varchar(128) not null primary key,
    quantity      integer,
    last_modified   timestamp default timestamp
)
go
    /* the Product_new table */
create table Product_new (
    name      varchar(128) not null primary key,
    quantity      integer,
    last_modified   timestamp default timestamp
)
go

  4. Verify the successful creation of each table.

    • For example, execute the following command in Interactive SQL to verify the contents of the Product table.

      select * from Product
Define an ODBC data source for the consolidated database.

Use the Adaptive Server Anywhere 9.0 driver to define an ODBC data source for the cons database.

toggle To define an ODBC data source for the consolidated database

  1. Start the ODBC Administrator:

    From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > ODBC Administrator.

    The ODBC Data Source Administrator appears.

  2. On the User DSN tab, click Add.

    The Create New Data Source dialog appears.

  3. Select Adaptive Server Anywhere 9.0 and click Finish.

    The ODBC Configuration for Adaptive Server Anywhere 9 dialog appears.

  4. On the ODBC tab, type the Data source name asa_cons. On the Login tab, type DBA for the User ID and SQL for the Password. On the Database tab, type cons for the Server Name.

  5. Click OK to add the data source.

  6. Click OK to close the ODBC Administrator.

Further reading

You can also use the dbinit command line utility to create your consolidated database. For more information, see Creating a database using the dbinit command-line utility or Lesson 2: Set up the remote Adaptive Server Anywhere databases.

For more information about consolidated databases, including non-ASA RDBMSs, see Consolidated database.

For more information about Interactive SQL, see The Interactive SQL utility.

For more information about creating ODBC data sources, see The Data Source utility.


Lesson 2: Set up the remote Adaptive Server Anywhere databases

MobiLink is designed for synchronization involving a consolidated database server and a large number of mobile databases. In this section, you create two remote databases. For each database you:

  • Migrate a selected portion of the consolidated schema.

  • Create a synchronization publication, user, and subscription.

Create Adaptive Server Anywhere databases

In Lesson 1, you used Sybase Central to create databases. In this tutorial, you use a command line utility. The two tools produce identical results.

toggle To create and start Adaptive Server Anywhere remote databases

  1. At a command prompt, navigate to the directory where you would like to create the remote databases.

  2. Type the following commands to create the database:

    dbinit -p 4096 remote1.db

    For remote2, type:

    dbinit -p 4096 remote2.db

    The -p option defines a 4K page size shown to increase performance for many environments.

    For more information about dbinit options, see Creating a database using the dbinit command-line utility.

  3. Now, to start the databases, type:

    dbeng9 remote1.db

    For remote2, type:

    dbeng9 remote2.db
Migrating a subset of the consolidated database schema

Migrating a subset of the consolidated database schema involves:

  • Connecting to the remote database.

  • Creating a remote server and external login.

  • Using the Sybase Central Data Migration wizard.

toggle To migrate a subset of your consolidated database schema to remote1

  1. Start Sybase Central.

    From the Start menu, choose Programs > SQL Anywhere 9 > Sybase Central.

  2. Connect to the remote database:

    • Select Adaptive Server Anywhere 9 in the left pane of Sybase Central.

    • From the File menu choose Connect.

      The Connect dialog appears.

    • On the Identification tab, enter DBA as the User ID and SQL as the password. On the Database tab, enter remote1 as the server name.

    • Click OK to connect.

  3. Create a remote server:

    • Start the Remote Server Creation wizard.

      In the left pane, select the Remote Servers folder. From the File menu choose New > Remote Server.

      The Remote Server Creation wizard starts.

    • Name the remote server my_asa. Click Next to continue.

    • Choose Sybase Adaptive Server Anywhere as the type of server, and click Next.

    • On the next page of the wizard, type the datasource name asa_cons in the connection information section, and click Next.

    • On the final page of the wizard, called "Make this a readonly data source", choose Create an External Login. Use DBA for the Login name and SQL for the Password.

    • Click Finish to exit the Remote Server Creation wizard.

  4. Migrate the consolidated database schema:

    • In the left pane, select the Adaptive Server Anywhere 9 plug-in. In the right pane, select the Utilities tab and double-click Migrate Database:

      The ASA 9 plugin, showing the Migrate Database option

      The Data Migration wizard starts.

    • Select remote1 as the destination database.

    • On the next page, select my_asa as the remote server. Click Next to continue.

    • Choose Product as the only table to migrate, and click Next.

    • Choose user DBA, and click Next.

    • On the final page of the wizard, clear the Migrate the Data option.

    • Click Finish.

  5. Repeat the migration (steps 1 to 4 above) for the remote2 database.

Synchronization subscriptions and publications

Publications identify the tables and columns on your remote database that you want synchronized. These tables and columns are called articles. A synchronization subscription subscribes a MobiLink user to a publication.

Synchronization subscriptions and publications are stored in the remote database.

For more information about defining publications and subscriptions, see Publishing data.

toggle To create a remote synchronization publication, synchronization user, and synchronization subscription

  1. Start Interactive SQL:

    • In the left pane of Sybase Central, select the remote1 - DBA database. From the File menu choose Open Interactive SQL.

  2. Enter synchronization information for remote1:

    • Execute the following in Interactive SQL:

      CREATE PUBLICATION pub_1 (TABLE Product);
CREATE SYNCHRONIZATION USER user_1;
CREATE SYNCHRONIZATION SUBSCRIPTION TO pub_1
 FOR user_1 TYPE TCPIP ADDRESS 'host=localhost'
 OPTION scriptversion='ver1';

  3. Start Interactive SQL and connect to remote2.

  4. Enter synchronization information for remote2:

    • Execute the following in Interactive SQL:

      CREATE PUBLICATION pub_2 (TABLE Product);
CREATE SYNCHRONIZATION USER user_2;
CREATE SYNCHRONIZATION SUBSCRIPTION TO pub_2
 FOR user_2 TYPE TCPIP ADDRESS 'host=localhost'
 OPTION scriptversion='ver1';

Now you have prepared the remote and consolidated databases. In the next lesson you write synchronization scripts. In Lesson 4 you run the synchronization.


Lesson 3: Creating scripts for your synchronization

You can view, write, and modify synchronization scripts using Sybase Central. In this section you write the following synchronization scripts:

  • upload_insert To define how data inserted into the remote database is to be applied to the consolidated database.

  • download_cursor To define what data should be downloaded from the consolidated database.

Each script belongs to a designated script version. You must add a script version to the consolidated database before you add scripts.

toggle To add a script version

  1. Connect to the cons database using the MobiLink plug-in in Sybase Central.

    • Select the MobiLink Synchronization 9 plug-in in the left pane of Sybase Central.

    • Choose Tools > Connect.

      The New Connection dialog appears.

    • On the Identification tab, select the ODBC Data Source name option. Type asa_cons for the data source name.

    • Click OK to connect.

      The asa_cons datasource appears in the MobiLink plug-in.

      For more information about the MobiLink plug-in, see MobiLink Help.

  2. Add the script version ver1.

    In the left pane select the Versions folder. In the right pane double-click Add Version.

    The Add a New Script Version dialog appears.

  3. Name the new version ver1 and click Finish.

toggle To add synchronized tables to your consolidated database

  1. In the MobiLink Synchronization plug-in of Sybase Central, open the Tables folder and double-click DBA.

  2. Right-click the Product table and choose Add to Synchronized Tables.

    The Product table now appears in the Synchronized Tables folder.

Now that you have designated a synchronized table, you can add a new table script for each upload and download to the consolidated database.

toggle To add table scripts for the Product table

  1. In the MobiLink Synchronization plug-in of Sybase Central, open the Synchronized Tables folder and select the Product table.

  2. In the right pane double-click Add Table Script. The following dialog appears. Ensure that ver1 appears as the script version.

    The Add Table Script wizard.

  3. Select the upload_insert event from the dropdown list and click Finish.

    The Product upload_insert dialog appears.

  4. Type the following SQL statement into the edit screen:

    INSERT INTO Product( name, quantity, last_modified )
  VALUES( ?, ?, ? )

    The upload_insert event determines how data inserted into the remote database should be applied to the consolidated database.

    For more information about upload_insert, see upload_insert table event

  5. Save the script.

    From the File menu, choose Save.

  6. Repeat steps 1 to 5 for the download_cursor event using the following SQL statement:

    SELECT name, quantity, last_modified
  FROM Product where last_modified >= ?

    The download_cursor script defines a cursor to select consolidated database rows that are downloaded and inserted or updated in the remote database.

    For more information about download_cursor, see download_cursor table event

Further reading

For more information about the scripts you just created, see upload_insert table event and download_cursor table event.

For more information about script versions, see Script versions.

For more information about adding scripts, see Adding and deleting scripts in your consolidated database.

For more information about writing table scripts, see Table scripts.

For more information about writing synchronization scripts, see Writing Synchronization Scripts.

For a complete list of the events that you can program to customize your synchronization, see Synchronization Events.


Lesson 4: Run MobiLink synchronization

toggle To run the synchronizations for remote1 and remote2

  1. Start the MobiLink synchronization server.

    At a command prompt, type the following on a single line:

    dbmlsrv9 -c "dsn=asa_cons" -o mlserver.mls -v+ -dl -zu+ -x tcpip

    For a complete list of dbmlsrv9 options, see MobiLink Synchronization Server Options.

    The MobiLink server window appears to indicate the MobiLink synchronization server is ready to handle requests.

  2. Run the MobiLink synchronization client utility (dbmlsync) to initiate synchronizations.

    At the command prompt, type the following on a single line:

    dbmlsync -c "eng=remote1;uid=dba;pwd=sql" -o rem1.txt -v+

    For remote2:

    dbmlsync -c "eng=remote2;uid=dba;pwd=sql" -o rem2.txt -v+

    For a complete list of dbmlsync options, see Adaptive Server Anywhere Client Synchronization Parameters.

    Once you have started the MobiLink synchronization client, the DBMLSync window appears indicating that the MobiLink synchronization succeeded.

Further reading

For more information about the MobiLink synchronization server, see The MobiLink synchronization server.

For a complete list of dbmlsrv9 options, see MobiLink Synchronization Server Options.

For more information about the dbmlsync, see Adaptive Server Anywhere Clients.

For a complete list of dbmlsync options, see Adaptive Server Anywhere Client Synchronization Parameters.


Lesson 5: Monitoring your MobiLink synchronization using log files

Once the tables have synchronized, you can view the progress of the synchronization using the two message log files you created with each command line, namely, mlserver.mls, rem1.txt, and rem2.txt. The default location of these files is the directory where the command was run.

toggle To find errors in a MobiLink synchronization log file

  1. Open your log file in a text editor. For this tutorial, the log file is mlserver.mls.

  2. Search the file for the string MobiLink Server started.

  3. Scan down the left side of the file. A line beginning with I. contains an informational message, and a line beginning with E. contains an error message. For example:

    Entries in a MobiLink synchronization server message log

  4. Note that beside the E. in this example, there is the following text:

    04/27 16:01:01. <Main>: Error: Unable to initialize communications stream 1: tcpip.

    This message indicates an error prior to the upload and download. There may be errors in the synchronization subscription or publication definitions.

  5. Look for the clause that begins as follows:

    ASA Synchronization request from:

    This clause indicates that a synchronization request has been established.

  6. Look for the clause that begins Working on a request. This indicates that the client and server are communicating. You may get this message if you have specified a high level of verbosity.

toggle To detect errors in your MobiLink synchronization client log file

  1. Open the client log file rem1.txt in a text editor.

  2. Search the file for the string COMMIT. If it appears, your synchronization was successful.

  3. Search the file for the string ROLLBACK. If the transaction was rolled back, there were errors that prevented it from completing.

  4. Scan down the left side of the file. If you see an E. , you have an error. If you do1n't have any errors, your synchronization has completed successfully.

Further reading

For more information about MobiLink synchronization server log files, see Logging MobiLink synchronization server actions.


Lesson 6: Creating scripts for conflict detection and resolution

Conflicts arise during the upload of rows to the consolidated database. If two users modify the same row on different remote databases, a conflict is detected when the second row arrives at the MobiLink synchronization server. Using synchronization scripts you can detect and resolve conflicts.

For more information about MobiLink Conflict resolution, see Handling conflicts.

Inventory example

Consider the scenario of two salesmen in the field. Salesman1 starts with an inventory of ten items, and then sells three. He updates the inventory on his remote database, remote1, to seven items. Salesman2 sells four items and updates her inventory (on remote2) to six.

When remote1 synchronizes using the MobiLink synchronization client utility the consolidated database is updated to seven. When remote2 synchronizes, a conflict is detected because the inventory value in the consolidated database has changed.

To resolve this conflict programmatically, you need three row values:

  1. The current value in the consolidated database.

    After remote1 synchronizes, the value in the consolidated database is 7.

  2. The new row value that Remote2 uploaded.

  3. The old row value that Remote2 obtained during the previous synchronization.

In this case, you can use the following business logic to calculate the new inventory value and resolve the conflict:

current consolidated - (old remote - new remote)
that is, 7 - (10-6) = 3

The expression (old remote - new remote) provides the number of items sold by Salesman2 rather than the absolute inventory value.

Synchronization scripts for conflict detection and resolution

For conflict detection and resolution, you add the following scripts:

  • upload_update The upload_update event determines how data inserted into the remote database should be applied to the consolidated database. You can also use an extended prototype of upload_update to detect update conflicts.

    For more information about using upload_update to detect conflicts, see Detecting conflicts.

    For more information about upload_update, see upload_update table event.

  • upload_old_row_insert You use this script to handle old row values obtained by the remote database during its previous synchronization.

    For more information about upload_old_row_insert, see upload_old_row_insert table event.

  • upload_new_row_insert You use this script to handle new row values (the updated values on the remote database).

    For more information about upload_new_row_insert, see upload_new_row_insert table event.

  • resolve_conflict The resolve conflict script applies business logic to resolve the conflict.

    For more information about resolve_conflict, see resolve_conflict table event.

toggle To install scripts for conflict detection and resolution

  1. Start Interactive SQL.

    • At a command prompt enter:

      dbisql

      The Connect dialog appears.

    • On the identification tab, enter DBA as the User ID and SQL as the Password. On the Database tab, enter cons as the Server name.

  2. Install the conflict detection and resolution scripts.

    Execute the following in Interactive SQL:

    /* upload_update */
call ml_add_table_script( 'ver1', 'Product',
 'upload_update',
 'UPDATE Product
   SET quantity = ?, last_modified = ?
    WHERE name = ?
    AND quantity=? AND last_modified=?' )
go
    /* upload_old_row_insert */
call ml_add_table_script( 'ver1', 'Product',
 'upload_old_row_insert',
 'INSERT INTO Product_old (name,quantity,last_modified)
   values (?,?,?)')
go
    /* upload_new_row_insert */
call ml_add_table_script( 'ver1', 'Product',
 'upload_new_row_insert',
 'INSERT INTO Product_new (name,quantity,last_modified)
   values (?,?,?)')
go
    /* resolve_conflict */
call ml_add_table_script( 'ver1', 'Product',
 'resolve_conflict',
 'declare @product_name varchar(128);
  declare @old_rem_val integer;
  declare @new_rem_val integer;
  declare @curr_cons_val integer;
  declare @resolved_value integer;
      // obtain the product name
  SELECT name INTO @product_name
     FROM Product_old;

  // obtain the old remote value
  SELECT quantity INTO @old_rem_val
    FROM Product_old;

  //obtain the new remote value
  SELECT quantity INTO @new_rem_val
    FROM Product_new;
      // obtain the current value in cons
  SELECT quantity INTO @curr_cons_val
   FROM Product WHERE name = @product_name;
      // determine the resolved value
  SET @resolved_value =
    @curr_cons_val- (@old_rem_val - @new_rem_val);
      // update cons with the resolved value
  UPDATE Product
   SET quantity = @resolved_value
   WHERE name = @product_name;
      // clear the old and new row tables
  delete from Product_new;
  delete from Product_old
 ')

Setup for the Adaptive Server Anywhere consolidated database is complete.

Further reading

For more information about MobiLink conflict detection and resolution, see Handling conflicts.

For more information about MobiLink consolidated databases, see MobiLink Consolidated Databases.


Lesson 7: Use the MobiLink Monitor to detect update conflicts

You can use the MobiLink Monitor to collect statistical information about synchronizations as they occur. The Monitor's graphical chart shows tasks on the vertical axis against the progression of time on the horizontal axis.

Using the Monitor, you can quickly identify synchronizations that result in errors or satisfy certain conditions. Since the Monitor does not significantly degrade performance, it is recommended for both development and production.

In this section you:

  • Start and configure the MobiLink Monitor to visibly distinguish synchronizations that involve update conflicts.

  • Generate a conflict by updating the same row on remote1 and remote2.

  • Use the MobiLink Monitor to detect the conflict.

toggle To configure the MobiLink Monitor to detect update conflicts.

  1. Start the MobiLink Monitor.

    • From the Start menu, choose Programs > SQL Anywhere 9 > MobiLink > MobiLink Monitor, or type the following at a command prompt:

      dbmlmon

      The Connect to MobiLink server dialog appears.

    • Enter monitor_user for the User ID. Since you started the MobiLink synchronization server with the -zu+ option, this user will be added automatically. Leave the password field blank if you do not want to require a password for this user.

      The MobiLink Monitor connect dialog

    • Click OK to connect.

    The MobiLink Monitor connects to the MobiLink synchronization server (dbmlsrv9).

  2. Start the MobiLink Monitor Watch Manager.

    From the MobiLink Monitor file menu choose Tools > Watch Manager...

    The Watch Manager dialog appears.

  3. Add a new watch for update conflicts.

    • Click New.

      The New Watch dialog appears.

    • Name the watch conflict_detected.

    • Choose conflicted_updates for the Property field.

      The conflicted_updates statistical property indicates the number of uploaded updates for which conflicts were detected.

      For more information about MobiLink Monitor statistical properties, see MobiLink statistical properties.

    • Set the watch to detect cases where one or more update conflicts occurred.

      Set the Operator field to is greater than. Set the Value field to 0.

    • Click Add to save the settings.

    • Select a pattern for the watch in the Chart pane. (The Chart pane is the middle pane in MobiLink Monitor.)

    • Select a color for the watch in the Overview pane. (The Overview pane is the bottom pane in the MobiLink Monitor.)

    The Edit Watch dialog, showing the new conflict_detected watch

  4. Click OK to add the watch.

toggle To generate an update conflict

  1. Update the remote1 inventory value.

    Salesman1 starts with a Screwmaster Drill inventory of ten items, and then sells three. He updates the inventory on his remote database, remote1, to seven items. To perform the update:

    • Start Interactive SQL and connect to remote1 (if not already connected).

      At a command prompt, type:

      dbisql

      The Connect dialog appears.

      On the Identification tab, enter DBA as the User ID and SQL as the password. On the Database tab, enter remote1 as the server name.

    • Update the Screwmaster Drill inventory to 7 items.

      Execute the following in Interactive SQL.

      UPDATE Product SET quantity = 7
 WHERE name ='Screwmaster Drill'
COMMIT

  2. Synchronize remote1.

    At a command prompt, type the following to start the MobiLink synchronization client:

    dbmlsync -c "eng=remote1;uid=dba;pwd=sql" -v+

    Following synchronization, the consolidated database Screwmaster Drill inventory is 7 items.

  3. Update the remote2 inventory value.

    Salesman2 sells four items and updates her inventory (on remote2) to six. When remote2 synchronizes, a conflict is detected because the inventory value in the consolidated database has changed. To perform the update:

    • Start Interactive SQL and connect to remote2.

      At a command prompt, type:

      dbisql

      The Connect dialog appears.

      On the Identification tab, enter DBA as the User ID and SQL as the password. On the Database tab, enter remote2 as the server name.

    • Update the Screwmaster Drill inventory to 6 items.

      Execute the following in Interactive SQL.

      UPDATE Product SET quantity = 6
 WHERE name ='Screwmaster Drill'
COMMIT

  4. Synchronize remote2.

    At a command prompt, type the following to start the MobiLink synchronization client:

    dbmlsync -c "eng=remote2;uid=dba;pwd=sql" -v+

Now you can switch to the MobiLink Monitor and view the results of the synchronization.

toggle To detect the update conflict using the MobiLink Monitor

  1. Pause Chart Scrolling.

    From the File menu, choose Monitor > Pause Chart Scrolling.

  2. View statistical information about the synchronization using the MobiLink Monitor's Overview pane, Chart pane, and Details table.

    • Locate the synchronizations in the Monitor's Overview pane (the bottom pane in the MobiLink Monitor). The remote2 synchronization which generated an update conflict, appears in red:

      The Overview pane, showing user_1 and user_2 synchronizations

    • To view the remote2 synchronization in the Chart pane, click and drag over the synchronization object in the Overview pane:

      The Chart pane, showing the user_2 conflict synchronization

      The synchronization object is displayed with the pattern you chose for the conflict_detected watch.

    • Use the zoom tool to view synchronization detail.

      From the File menu choose View > Zoom In.

    • To view synchronization properties, double-click the synchronization object or the corresponding row in the details table. Choose the Upload tab to see the number of conflicted updates.

      The MobiLink Monitor Synchronization Properties dialog
Further reading

For more information about MobiLink Conflict resolution, see Handling conflicts.

For more information about the MobiLink Monitor, see MobiLink Monitor.

For more information about MobiLink Monitor statistical properties, see MobiLink statistical properties.


Tutorial cleanup

You should remove tutorial materials from your computer.

toggle To remove tutorial materials from your computer

  1. Close all instances of the following applications:

    • The MobiLink Monitor

    • Sybase Central

    • Interactive SQL

  2. Close the Adaptive Server Anywhere, MobiLink, and synchronization client windows by right-clicking each taskbar item and choosing Exit.

  3. Delete all tutorial-related data sources.

    • Start ODBC Administrator.

      From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > ODBC Administrator.

      Select asa_cons from the list of User Data Sources. Click Remove.

  4. Delete the consolidated and remote databases.

    • Navigate to the directory containing your consolidated and remote databases.

    • Delete cons.db, cons.log, remote1.db, remote1.log, remote2.db, remote2.log.


Further reading

The following documentation sections are a good starting point for further reading:

For more information about running the MobiLink synchronization server, see The MobiLink synchronization server.

For more information about synchronization scripting, see Writing Synchronization Scripts and Synchronization Events.

For an introduction to other methods of synchronization such as timestamp-based synchronization, see Synchronization Techniques.

For information about testing your scripts in Sybase Central, see Testing script syntax.

For more information about the MobiLink Monitor, see MobiLink Monitor.

For more information about MobiLink conflict detection and resolution, see Handling conflicts.


Tutorial: Using MobiLink with an Oracle 8i Consolidated Database

About this chapter

This chapter provides a tutorial to guide you through the process of setting up a synchronization system when the consolidated database is an Oracle database and the remote database is an Adaptive Server Anywhere database.

This tutorial will show you how to set up and synchronize the two databases.

Introduction
Lesson 1: Create your databases
Lesson 2: Running the MobiLink synchronization server
Lesson 3: Running the MobiLink synchronization client
Summary
Further reading


Introduction

In this tutorial, you prepare an Oracle consolidated database and an Adaptive Server Anywhere remote database. You then synchronize the two databases using MobiLink.

Required software

  • A full SQL Anywhere Studio installation.

  • A full installation of Oracle Enterprise Edition 8i.

Competencies and experience

You should have the following competencies and experience before beginning the tutorial:

  • Familiar with Sybase Central interface and functionality.

  • Competent with Interactive SQL and Oracle SQL Plus.

  • Competent programming Oracle.

Goals

The goals for the tutorial are:

  • To acquire familiarity with the MobiLink synchronization server and related components as they can be used with Oracle.

  • To gain competence in executing MobiLink server and client commands as they pertain to an Oracle consolidated database.

Suggested background reading

For more information about writing SQL scripts, see Tutorial: Writing MobiLink Scripts and Monitoring Synchronizations.

For more information about running the MobiLink synchronization server, see Synchronization Basics.


Lesson 1: Create your databases

MobiLink synchronization requires that you have data a relational database, an ODBC data source for each database and two compatible databases.


SQL files

You can enter data into an Oracle database using a number of different methods. This tutorial uses Oracle SQL Plus.

toggle To create your databases

  1. Start SQL Plus and connect to the Oracle consolidated database. Copy the following code into SQL Plus and execute it. These SQL statements drop, create and populate tables in the consolidated database. If there are no tables to drop, an error will appear in the SQL Plus output. This will not affect processing.

    CREATE SEQUENCE emp_sequence;
CREATE SEQUENCE cust_sequence;
DROP TABLE emp;
CREATE TABLE emp ( emp_id int primary key, emp_name varchar( 128 ) );
DROP TABLE cust;
CREATE TABLE cust ( cust_id int primary key, emp_id int references emp(emp_id), cust_name varchar( 128 ) );
INSERT INTO emp ( emp_id, emp_name ) VALUES ( emp_sequence.nextval, 'emp1' );
INSERT INTO emp ( emp_id, emp_name ) VALUES ( emp_sequence.nextval, 'emp2' );
INSERT INTO emp ( emp_id, emp_name ) VALUES ( emp_sequence.nextval, 'emp3' );
COMMIT;
INSERT INTO cust ( cust_id, emp_id, cust_name ) VALUES ( cust_sequence.nextval, 1, 'cust1' );
INSERT INTO cust ( cust_id, emp_id, cust_name ) VALUES ( cust_sequence.nextval, 1, 'cust2' );
INSERT INTO cust ( cust_id, emp_id, cust_name ) VALUES ( cust_sequence.nextval, 2, 'cust3' );
COMMIT;

  2. Start Interactive SQL.

    Choose Start > Programs > SQL Anywhere 9 > Adaptive Server Anywhere > Interactive SQL.

  3. Connect to the remote database.

  4. Copy the following code into Interactive SQL and execute it. These SQL statements drop and create tables in the remote databases. If there are no tables to drop, an error will appear in the Interactive SQL output. This will not affect processing. Synchronization subscriptions and publications are also inserted to define the synchronization parameters for the MobiLink synchronization server.

    CREATE TABLE emp ( emp_id int primary key ,emp_name varchar( 128 ) );
CREATE TABLE cust ( cust_id int primary key, emp_id int references emp ( emp_id ), cust_name varchar( 128 ) );
CREATE PUBLICATION emp_cust ( TABLE cust, TABLE emp );
CREATE SYNCHRONIZATION USER ml_user;
CREATE SYNCHRONIZATION SUBSCRIPTION
  TO emp_cust FOR ml_user TYPE TCPIP ADDRESS 'host=localhost';


ODBC data sources

You can now create ODBC data sources through which you connect to the Oracle consolidated database and the Adaptive Server Anywhere remote database. MobiLink requires an ODBC data source to perform data synchronization.

The consolidated data source

Ensure that you know your Instance, Service, and Database names, as these values are required for the ODBC portion of the installation. These values are established at the time of your Oracle installation.

The following steps set up an ODBC configuration for the Oracle consolidated database. You will set up the ODBC connections for the Adaptive Server Anywhere remote database later.

toggle To set up an ODBC data source for Oracle

  1. Choose Start > Programs > Sybase SQL Anywhere 9 > Adaptive Server Anywhere > ODBC Administrator.

    The ODBC Data Source Administrator opens.

  2. Click Add on the User DSN tab. The Create New Data Source window appears.

  3. Select iAnywhere Solutions - Oracle 8, 8i and 9i Driver, and click Finish.

    The ODBC Oracle Driver Setup window appears.

  4. Click the General tab and type the data source name ora_consol. This is the DSN used for connecting to your Oracle database. You will need it later.

  5. Enter the server name. This value depends on your Oracle installation. If the server is on your computer, you may be able to leave this field blank.

  6. Click the Advanced tab. Enter a Default User Name. For this tutorial you can use system, or any User Name with sufficient rights to create objects. Click OK.

  7. Click OK to close the ODBC Data Source Administrator.


MobiLink system tables

MobiLink comes with a script called syncora.sql, located in the MobiLink\setup subdirectory of your SQL Anywhere installation. You run this script to set up your Oracle database to work with MobiLink.

Syncora.sql contains SQL statements, written in Oracle SQL, to prepare Oracle databases for use as consolidated databases. It creates a series of system tables, triggers, and procedures for use by MobiLink. The system tables are prefaced with ML_. MobiLink works with these tables during the synchronization process.

toggle Create MobiLink system tables within Oracle

  1. Start SQL Plus. Choose Start > Programs > Oracle - OraHome81 > Application Development > SQL Plus.

    Connect to your Oracle database using Oracle SQL Plus. Log on using the system schema with password manager.

  2. Run syncora.sql by typing the following command:

    @path\syncora.sql;

    where path is the MobiLink\setup subdirectory of your SQL Anywhere 9 installation. If there are spaces in your path, you should enclose the path and filename in quotation marks.

toggle To verify that the system tables are installed

  1. Start SQL Plus. Choose Start > Programs > Oracle - OraHome81 > Application Development > SQL Plus.

  2. Run the following SQL statement to yield a listing of the MobiLink system tables, procedures, and triggers:

    SELECT object_name
FROM all_objects
WHERE object_name
LIKE 'ML_%';

    If all of the objects shown in the following table are included, you can proceed to the next step.

OBJECT_NAME
ML_ADD_CONNECTION_SCRIPT

ML_ADD_DNET_CONNECTION_SCRIPT

ML_ADD_DNET_TABLE_SCRIPT

ML_ADD_JAVA_CONNECTION_SCRIPT

ML_ADD_JAVA_TABLE_SCRIPT

ML_ADD_LANG_CONNECTION_SCRIPT

ML_ADD_LANG_TABLE_SCRIPT

ML_ADD_TABLE_SCRIPT

ML_ADD_USER

ML_CONNECTION_SCRIPT

ML_CONNECTION_SCRIPT_TRIGGER

ML_SCRIPT

ML_SCRIPTS_MODIFIED

ML_SCRIPT_TRIGGER

ML_SCRIPT_VERSION

ML_SUBSCRIPTION

ML_TABLE

ML_TABLE_SCRIPT

ML_TABLE_SCRIPT_TRIGGER

ML_USER
Note
If any of the objects are missing, the procedure you just completed was not successful. In this case, you need to review the MobiLink error messages to see what went wrong; correct the problem; and then drop the MobiLink system tables as follows. However, do not drop system tables if there are any tables starting with ML_ other than the ones listed above.
toggle To drop the MobiLink system tables

  1. Run the following SQL statement in SQL Plus:

    select 'drop ' || object_type || ' ' || object_name || ';'
from all_objects
where object_name like 'ML_%';

    This generates a list of tables, procedures and triggers to be dropped.

  2. Copy this list to a text file and save it as drop.sql in your OracleTut directory. Remove any lines that do not contain drop statements.

  3. Execute the SQL statements in drop.sql by running the following command:

    @path\OracleTut\drop.sql;

    Replace path with the location of your OracleTut directory. Run drop.sql a second time to delete tables that were not removed the first time because of dependencies.

  4. You can now repeat the instructions in Creating MobiLink system tables in Oracle, above.

The remote data source
toggle To initialize your remote database

  1. Open a command prompt and navigate to your OracleTut directory; for example c:\OracleTut. Run the following command line:

    dbinit remote.db

  2. Verify the successful creation of the database by getting a listing of the contents of this directory. The file remote.db should appear in the directory listing.

toggle To create an ODBC data source for the remote database

  • Open a command prompt and navigate to your OracleTut directory. Run the following command line:

    dbdsn -w test_remote -y -c "uid=DBA;pwd=SQL;
   dbf=path\OracleTut\remote.db;eng=remote"

    Replace path with the location of your OracleTut directory.


Databases

In this procedure, you build a consolidated database using the Interactive SQL command line utility. The Interactive SQL utility helps you to execute SQL commands within your database. This procedure executes SQL statements within each database.

For more information about Interactive SQL, see The Interactive SQL utility.

toggle To create and populate tables in the consolidated database

  1. Start SQL Plus and connect to your consolidated database. Choose Start > Programs > Oracle - OraHome81 > Application Development > SQL Plus.

  2. Execute the SQL statements in build_consol.sql by running the following command:

    @path\OracleTut\build_consol.sql;

    Replace path with the location of your OracleTut directory. If the path contains spaces, enclose the path and filename in double quotes.

  3. Verify the successful creation of each of the tables through SQL Plus directly from within the application. Run the following SQL statements:

    SELECT * FROM emp;
SELECT * FROM cust;

  4. Leave the consolidated database running.

toggle To create tables and synchronization information in the remote database

  1. Open a command prompt and navigate to your OracleTut directory. Run the following command line:

    dbisql -c "dsn=test_remote" build_remote.sql

    The Interactive SQL plug-in starts the remote database and executes the SQL statements in build_remote.sql.

  2. Verify the successful creation of the emp and cust tables using Interactive SQL or Sybase Central.

  3. Leave the consolidated and remote databases running.


Lesson 2: Running the MobiLink synchronization server

The MobiLink synchronization server can now be started from a command prompt. Since MobiLink synchronization server is a client to the consolidated database, your consolidated database must be started prior to starting MobiLink. If you shut down your consolidated database following Lesson 1, you should restart the database.

toggle To start the MobiLink synchronization server

  1. Ensure that your consolidated database is running.

  2. Open a command prompt and navigate to your OracleTut directory. Run the following command line:

    dbmlsrv9 -c "dsn=ora_consol;pwd=manager" -o mlserver.mls -v+ -za -zu+

This command line specifies the following dbmlsrv9 options:

  • -c Specifies connection parameters. Note that we only use the password as the User ID is contained in the DSN. For more information, see -c option.

  • -o Specifies the message log file. For more information, see -o option.

  • -v+ Sets verbose logging on. For more information, see -v option.

  • -dl Sets the display log feature ON.

  • -za Turns automated scripting ON. For more information, see -za option.

  • -zu+ Automates the user authentication process. For more information, see -zu option.

Further reading

For more information about dbmlsrv9, see The MobiLink synchronization server and MobiLink synchronization server.


Lesson 3: Running the MobiLink synchronization client

The MobiLink client may now be started from a command prompt. The MobiLink client initiates synchronization.

You can specify connection parameters on the dbmlsync command line using the -c option. These parameters are for the remote database.

toggle To start the MobiLink client

  1. Ensure that the MobiLink synchronization server is started.

  2. Open a command prompt and navigate to your OracleTut directory. Run the following command line:

    dbmlsync -c "dsn=test_remote" -o dbmlsync.out -v+ -e "SendColumnNames=ON"

    This command line specifies the following dbmlsync options:

    • -c Supply database connection parameters. For more information, see -c option.

    • -o Specify the message log file. For more information, see -o option.

    • -v+ Verbose operation. For more information, see -v option.

    • -e Extended options. Specifying "SendColumnNames=ON" sends column names to MobiLink. For more information, see dbmlsync extended options.

Further reading

For more information about dbmlsync, see MobiLink synchronization client.


Summary

During this tutorial, you accomplished the following tasks.

  • Created a new Adaptive Server Anywhere database to serve as a remote database.

  • Started a MobiLink synchronization server to work with your consolidated Oracle database.

  • Started the MobiLink synchronization client and synchronized the remote database with the consolidated Oracle database.

Learning accomplishments

In this tutorial, you gained:

  • Familiarity with the MobiLink synchronization server and client and how they work with an Oracle database.

  • Competence in executing MobiLink server and client commands.


Further reading

The following documentation areas are good starting points for further reading:

For more information about running the MobiLink synchronization server, see Running the MobiLink synchronization server.

For more information about synchronization scripting, see Writing Synchronization Scripts, and Synchronization Events.

For an introduction to other methods of synchronization such as timestamp, see Synchronization Techniques.


Tutorial: Java Synchronization Logic With Adaptive Server Anywhere

About this chapter

This tutorial guides you through the basic steps for using Java synchronization logic. Using the CustDB sample as a consolidated database, you specify simple class methods for MobiLink table-level events. The process also involves running the MobiLink synchronization server (dbmlsrv9) with an option to set the path of compiled Java classes.

Introduction
Lesson 1: Compiling the CustdbScripts Java class
Lesson 2: Specifying class methods for events
Lesson 3: Run the MobiLink server with -sl java
Lesson 4: Test synchronization
Cleanup
Further reading


Introduction

MobiLink connection-level and table-level event scripts can be written in SQL, Java or .NET. Java and .NET encapsulate event logic in class methods. In this tutorial you write Java class methods for MobiLink table-level events.

Required software

  • SQL Anywhere Studio 9.0.

  • Java Software Development Kit.

Competencies and experience

You will require:

  • Familiarity with Java.

  • Basic knowledge of MobiLink event scripts.

Goals

You will gain competence and familiarity with:

  • Utilizing simple Java class methods for MobiLink table-level events.

Key concepts

This section uses the following steps to implement basic Java-based synchronization using the MobiLink CustDB sample database:

  • Compiling the CustdbScripts.class file with MobiLink API references.

  • Specifying class methods for particular table-level events.

  • Running the MobiLink server (dbmlsrv9) with the -sl java option.

  • Testing synchronization with a sample Windows client application.

Suggested background reading

For more information about synchronization scripts, see Introduction to synchronization scripts.

For more information about Sybase Central, see Managing Databases with Sybase Central.


Lesson 1: Compiling the CustdbScripts Java class

Java classes encapsulate synchronization logic in methods.

In this lesson, you will compile a class associated with the CustDB sample database.

MobiLink Database Sample

SQL Anywhere Studio ships with an Adaptive Server Anywhere sample database (CustDB) that is already set up for synchronization, including the SQL scripts required to drive synchronization. The CustDB ULCustomer table, for example, is a synchronized table supporting a variety of table-level events.

CustDB is designed to be a consolidated database server for both UltraLite and Adaptive Server Anywhere clients. The CustDB database has a DSN called UltraLite 9.0 Sample.


The CustdbScripts class

In this section, you create a Java class called CustdbScripts with logic to handle the ULCustomer upload_insert and upload_update events. You enter the CustdbScripts code in a text editor and save the file as CustdbScripts.java.

toggle To create CustdbScripts.java

  1. Create a directory for the Java class and assembly.

    This tutorial assumes the path c:\mljava.

  2. Using a text editor, enter the CustdbScripts code:

    public class CustdbScripts
{
 public static String UploadInsert()
 {
   return("INSERT INTO ULCustomer(cust_id,cust_name) values (?,?)");
 }
 public String DownloadCursor(java.sql.Timestamp ts,String user )
 {
  return("SELECT cust_id, cust_name FROM ULCustomer where last_modified >= ' " + ts + " ' ");
 }
}
    Note:
    The class and associated methods must be set as public.

  3. Save the file as CustdbScripts.java in c:\mljava.


Compiling the Java class

The MobiLink API

To execute Java synchronization logic, the MobiLink synchronization server must have access to the classes in mlscript.jar. This jar file contains a repository of MobiLink API classes to utilize in your Java methods.

For more information about the MobiLink Java API, see MobiLink Java API Reference.

When compiling a Java class for MobiLink, you must include this JAR file to make use of the API. In this section, you use the javac utility -classpath option to specify mlscript.jar for the CustdbScripts class.

toggle To compile the Java class (Windows)

  1. On the command line, navigate to the folder containing CustdbScripts.java (c:\mljava).

  2. Enter the following:

    javac custdbscripts.java -classpath "%asany9%\java\mlscript.jar"

The CustdbScripts.class file is generated.

Further reading

For more information about the MobiLink API, see MobiLink Java API Reference.

For more information about Java methods, see Methods.

For more information about the CustDB sample database, and using alternate RDBMS servers, see Setting up the CustDB consolidated database.


Lesson 2: Specifying class methods for events

CustdbScripts.class, created in the previous lesson, encapsulates the methods UploadInsert() and DownloadCursor(). These methods contain implementation for the ULCustomer upload_insert and upload_update events, respectively.

In this section, you will specify class methods for table-level events using two approaches:

  1. Using the MobiLink Synchronization plug-in.

    You connect to the CustDB database with Sybase Central, change the language for the upload_insert script to Java, and specify CustdbScripts.UploadInsert to handle the event.

  2. Using the ml_add_java_table_script stored procedure.

    You will connect to the CustDB database with Interactive SQL and execute ml_add_java_table_script, specifying CustdbScripts.DownloadCursor for the download_cursor event.

toggle To specify CustdbScripts.UploadInsert for the ULCustomer upload_insert event

  1. Connect to the sample database using the MobiLink Synchronization plug-in:

    • Start Sybase Central.

    • In the left pane, right-click the MobiLink Synchronization 9 plug-in and choose Connect.

    • On the Identification tab, choose UltraLite 9.0 Sample for the ODBC Data Source name.

      On the Database tab, ensure the option to search for network database servers is not selected.

    • Click OK to Connect.

    • Sybase Central should now display the CustDB data source under the MobiLink Synchronization 9 plug-in.

      Connection via the MobiLink Synchronization plug-in

  2. Change the language for the ULCustomer table upload_insert event to Java:

    • In the left pane, open the Synchronized Tables folder and select the ULCustomer table. A list of table-level scripts appears in the right pane.

    • Click on the table script associated with the custdb 9.0 upload_insert event. From the File menu, choose Set Script Language to Java.

  3. Enter the fully-qualified Java method name as the upload_insert script.

    • Double-click the table script associated with the upload_insert event.

      A window revealing the script contents appears:

      SQL upload_insert script

    • Change the script contents to the fully-qualified method name, CustdbScripts.UploadInsert:

      The fully-qualified Java method name as the script contents
      Note:
      The fully qualified method name is case sensitive.

    • To save the script, select Save from the File menu.

  4. Exit Sybase Central.

This step used Sybase Central to specify a Java method as the script for the ULCustomer upload_insert event.

Alternatively, you can use the ml_add_java_connection_script and ml_add_java_table_script stored procedures. Using these stored procedures is more efficient, especially if you have a large number of Java methods to handle synchronization events.

For more information, see ml_add_java_connection_script and ml_add_java_table_script.

In the next section you will learn how to add a Java method as the script for a MobiLink event using the ml_add_java_connection_script stored procedure or the ml_add_java_table_script stored procedure.

To do this, you will connect to CustDB with Interactive SQL and execute ml_add_java_table_script, assigning CustdbScripts.DownloadCursor to the download_cursor event.

toggle To specify CustdbScripts.DownloadCursor for the ULCustomer download_cursor event

  1. Connect to the sample database with Interactive SQL.

    • Open Interactive SQL.

      The Connect dialog appears.

    • On the Identification tab, choose UltraLite 9.0 Sample for the ODBC Data Source:

      The MobiLink Synchronization 9 plug-in Connect dialog.

      On the Database tab, ensure the option to search for network database servers is not selected.

  2. Execute the following command in Interactive SQL:

    call ml_add_java_table_script(
'custdb 9.0',
'ULCustomer',
'download_cursor',
'CustdbScripts.DownloadCursor');
commit;

    Following is a description of each parameter:

    Parameter | Description
    custdb 9.0 | The script version.
    ULCustomer | The synchronized table.
    download_cursor | The event name.
    CustdbScripts.DownloadCursor | The fully qualified Java method.

  3. Exit Interactive SQL.

In this lesson, you specified your Java methods to handle ULCustomer table-level events. The next lesson ensures that the MobiLink server loads the appropriate class files and the MobiLink API.

Further reading

For more information about adding scripts with stored procedures, see ml_add_java_connection_script and ml_add_java_table_script.

For general information about adding and deleting synchronization scripts, see Adding and deleting scripts in your consolidated database.


Lesson 3: Run the MobiLink server with -sl java

Running the MobiLink server with the -sl java -cp option specifies a set of directories to search for class files, and forces the Java Virtual Machine to load on server startup.

toggle To start the MobiLink server (dbmlsrv9) and load Java assemblies

  • On a command line, enter the following on a single line:

    dbmlsrv9 -c "dsn=ultralite 9.0 sample" -sl java (-cp c:\mljava)

    A message dialog appears indicating that the server is ready to handle requests. Now the Java method is executed when the ULCustomer table upload_insert event triggers during synchronization.

Further reading

For more information, see -sl dnet option.


Lesson 4: Test synchronization

UltraLite comes with a sample Windows client that automatically invokes the dbmlsync utility when the user issues a synchronization. It is a simple sales-status application that you can run against the CustDB consolidated database you started in the previous lesson.


Start the application (Windows)

toggle To start and synchronize the sample application

  1. Launch the sample application.

    From the Start menu, choose Programs > Sybase SQL Anywhere 9 > UltraLite > Windows Sample Application.

  2. Enter an employee ID.

    Input a value of 50 and press Enter.

The application automatically synchronizes, and a set of customers, products, and orders are downloaded to the application from the CustDB consolidated database.

In the next section you will enter a new customer name and order details. During a subsequent synchronization, this information will be uploaded to the CustDB consolidated database and the upload_insert and download_cursor events for the ULCustomer table will trigger.


Add an order (Windows)

toggle To add an order

  1. From the Order menu, choose New.

    The Add New Order screen is displayed.

  2. Enter a new Customer Name.

    For example, enter Frank Javac.

  3. Choose a product, and enter the quantity and discount:

    The Add New Order dialog, showing the Frank Javac order information

  4. Press Enter to add the new order.

You have now modified the data in your local UltraLite database. This data is not shared with the consolidated database until you synchronize.

toggle To synchronize with the consolidated database and trigger the upload_insert event

  • From the file menu, choose Synchronize.

A window appears indicating one Insert successfully uploaded to the consolidated database.

Further reading

For more information about the CustDB Windows Application, see The CustDB Sample Application.


Cleanup

You should remove tutorial materials from your computer.

toggle To remove tutorial materials from your computer

  1. Return the ULCustomer table upload_insert and download_cursor scripts to their original SQL logic.

    • Open Interactive SQL.

      The Connect dialog appears.

    • On the Identification tab, choose UltraLite 9.0 Sample for the ODBC Data Source.

    • Click OK to Connect.

    • Execute the following commands in Interactive SQL:

      call ml_add_table_script( 'custdb 9.0',
   'ULCustomer',
   'upload_insert',
   'INSERT INTO ULCustomer( cust_id, cust_name ) VALUES( ?, ? )' );

call ml_add_table_script( 'custdb 9.0',
   'ULCustomer',
   'download_cursor',
   'SELECT "cust_id", "cust_name" FROM "ULCustomer" WHERE "last_modified" >= ?' );

  2. Close the Adaptive Server Anywhere, MobiLink, and synchronization client windows by right-clicking on each taskbar item and choosing Close.

  3. Delete all tutorial-related Java sources.

    Delete the folder containing your CustdbScripts.java and CustdbScripts.class files (c:\mljava).

    Note:
    Ensure that you do not have other important files in c:\mljava.

Previous Next


Further reading

The following documentation sections are a good starting point for further reading:

For more information about writing MobiLink synchronization scripts in Java, see Setting up Java synchronization logic.

For an example illustrating the use of Java synchronization scripts for custom authentication, see Java synchronization example.

For more information about synchronization scripting, see Writing Synchronization Scripts and Synchronization Events.

For an introduction to other methods of synchronization such as timestamp, see Synchronization Techniques.


Tutorial: .NET Synchronization Logic With Adaptive Server Anywhere

About this chapter

This tutorial guides you through the basic steps for using .NET synchronization logic. Using the CustDB sample as a consolidated database, you specify simple class methods for MobiLink table-level events. The process also involves running the MobiLink synchronization server (dbmlsrv9) with an option that sets the path of .NET assemblies.

Introduction
Lesson 1: Compile the CustdbScripts.dll assembly with MobiLink references
Lesson 2: Specify class methods for events
Lesson 3: Run MobiLink with -sl dnet
Lesson 4: Test synchronization
Cleanup
Further reading


Introduction

MobiLink connection-level and table-level event scripts can be written in SQL, Java, or .NET. Both Java and .NET encapsulate event logic in class methods. In this tutorial you will subscribe .NET class methods to MobiLink table-level events.

Required software

  • SQL Anywhere Studio 9.0.

  • Microsoft .NET Framework SDK.

Competencies and experience

You will require:

  • Familiarity with .NET.

  • Basic knowledge of MobiLink event scripts.

Goals

You will gain competence and familiarity with:

  • Utilizing .NET class methods for MobiLink table-level event scripts.

Key concepts

This section uses the following steps to implement basic .NET synchronization using the MobiLink CustDB sample database:

  • Compiling the CustdbScripts.dll private assembly with MobiLink references.

  • Specifying class methods for table-level events.

  • Running the MobiLink server (dbmlsrv9) with the -sl dnet option.

  • Testing synchronization with a sample Windows client application.

Suggested background reading

For more information about synchronization scripts, see Introduction to synchronization scripts.

For more information about Sybase Central, see Managing Databases with Sybase Central.


Lesson 1: Compile the CustdbScripts.dll assembly with MobiLink references

.NET classes encapsulate synchronization logic in methods.

In this lesson, you will compile a class associated with the CustDB sample database.

MobiLink Database Sample

SQL Anywhere Studio ships with an Adaptive Server Anywhere sample database (CustDB) that is already set up for synchronization, including the SQL scripts required to drive synchronization. The CustDB ULCustomer table, for example, is a synchronized table supporting a variety of table-level events.

CustDB is designed to be a consolidated database server for both UltraLite and Adaptive Server Anywhere clients. The CustDB database has a DSN called UltraLite 9.0 Sample.

In this section, you create a .NET class called CustdbScripts with logic to handle the ULCustomer upload_insert and upload_update events.

The CustdbScripts assembly


The CustdbScripts assembly

The MobiLink API

To execute .NET synchronization logic, the MobiLink synchronization server must have access to the classes in iAnywhere.MobiLink.Script.dll. iAnywhere.MobiLink.Script.dll contains a repository of MobiLink .NET API classes to utilize in your .NET methods.

For more information about the MobiLink .NET API, see MobiLink .NET API Reference.

When compiling the CustdbScripts class, you must include this assembly to make use of the API. You can compile your class using Visual Studio .NET or from the command line.

  • In Visual Studio .NET, create a new Class Library and enter the CustdbScripts code. Link iAnywhere.MobiLink.Script.dll, and build the assembly for your class.

  • On the command line, enter the CustdbScripts code in a text editor and save the file as CustdbScripts.cs ( CustdbScripts.vb for Visual Basic .NET). Using a command line compiler, reference iAnywhere.MobiLink.Script.dll and build the assembly for your class.

toggle To create the CustdbScripts assembly using Visual Studio .NET

  1. Start a new Visual C# or Visual Basic .NET Class Library project.

    Use CustdbScripts for the project Name and enter an appropriate path. This tutorial assumes the path c:\mldnet.

    The Visual Studio .NET new project dialog

  2. Enter the CustdbScripts code.

    For C#, type:

    namespace MLExample
{
class CustdbScripts
{
    public static string UploadInsert()
 {
   return("INSERT INTO ULCustomer(cust_id,cust_name) values (?,?)");
 }
 public static string DownloadCursor(System.DateTime ts, string user )
 {
   return("SELECT cust_id, cust_name FROM ULCustomer WHERE last_modified >= '" + ts.ToString("yyyy-MM-dd hh:mm:ss.fff") +"'");
 }
}
}

    For Visual Basic .NET, type:

    Namespace MLExample

 Class CustdbScripts

  Public Shared Function UploadInsert() As String
    Return("INSERT INTO ULCustomer(cust_id,cust_name) values (?,?)")
  End Function

  Public Shared Function DownloadCursor(ByVal ts As System.DateTime, ByVal user As String) As String
   Return("SELECT cust_id, cust_name FROM ULCustomer " + _
    "WHERE last_modified >= '" + ts.ToString("yyyy-MM-dd hh:mm:ss.fff") +"'")
  End Function

 End Class

End Namespace

  3. Add a reference to the MobiLink API.

    • From the Visual Studio .NET Project menu, choose Add Existing Item...

    • Select iAnywhere.MobiLink.Script.dll in the win32 directory of your SQL Anywhere Studio installation. From the Open drop down menu choose Link File.

  4. Build CustdbScripts.dll.

    From the Build menu choose Build CustdbScripts.

    This creates CustdbScripts.dll in C:\mldnet\CustdbScripts\CustdbScripts\bin\Debug.

toggle To create the CustdbScripts assembly using the command line

  1. Create a directory for the .NET class and assembly.

    This tutorial assumes the path c:\mldnet.

  2. Using a text editor, enter the CustdbScripts code.

    For C#, type:

    namespace MLExample
{
class CustdbScripts
{
    public static string UploadInsert()
 {
   return("INSERT INTO ulcustomer(cust_id,cust_name) values (?,?)");
 }
 public static string DownloadCursor(System.DateTime ts, string user )
 {
   return("SELECT cust_id, cust_name FROM ULCustomer where last_modified >= '" + ts.ToString("yyyy-MM-dd hh:mm:ss.fff") +"'");
 }
}
}

    For Visual Basic .NET, type:

    Namespace MLExample

 Class CustdbScripts

  Public Shared Function UploadInsert() As String
    Return("INSERT INTO ULCustomer(cust_id,cust_name) values (?,?)")
  End Function

  Public Shared Function DownloadCursor(ByVal ts As System.DateTime, ByVal user As String) As String
   Return("SELECT cust_id, cust_name FROM ULCustomer " + _
    "WHERE last_modified >= '" + ts.ToString("yyyy-MM-dd hh:mm:ss.fff") +"'")
  End Function

 End Class

End Namespace

  3. Save the file as CustdbScripts.cs ( CustdbScripts.vb for Visual Basic .NET) in c:\mldnet.

  4. Compile the file using the following command.

    For C#, type:

    csc /out:c:\mldnet\custdbscripts.dll /target:library /reference:"%asany9%\win32\iAnywhere.MobiLink.Script.dll" c:\mldnet\CustdbScripts.cs

    For Visual Basic .NET, type:

    vbc /out:c:\mldnet\custdbscripts.dll /target:library /reference:"%asany9%\win32\iAnywhere.MobiLink.Script.dll" c:\mldnet\CustdbScripts.vb

    The CustdbScripts.dll assembly is generated.

Further reading

For more information about the MobiLink API, see MobiLink .NET API Reference.

For more information about .NET methods, see Methods.


Lesson 2: Specify class methods for events

For more information about the CustDB sample database, and using alternate RDBMS servers, see Setting up the CustDB consolidated database.

CustdbScripts.dll, created in the previous lesson, encapsulates the methods UploadInsert() and DownloadCursor(). These methods contain implementation for the ULCustomer upload_insert and upload_update events, respectively.

In this section, you specify class methods for table-level events using two approaches:

  1. Using the MobiLink Synchronization plug-in.

    You connect to the CustDB database with Sybase Central, change the language for the upload_insert script to .NET, and specify MLExample.CustdbScripts.UploadInsert to handle the event.

  2. Using the ml_add_dnet_table_script stored procedure.

    You will connect to the CustDB database with Interactive SQL and execute ml_add_dnet_table_script, specifying MLExample.CustdbScripts.DownloadCursor for the download_cursor event.

toggle To subscribe CustdbScripts.uploadInsert() to the upload_insert event for the ULCustomer table

  1. Connect to the sample database using the MobiLink Synchronization plug-in:

    • Start Sybase Central.

      Choose Start > Programs > Sybase SQL Anywhere 9 > Sybase Central.

    • In the left pane, right-click the MobiLink Synchronization 9 plug-in and choose Connect.

    • Choose the UltraLite 9.0 Sample as the ODBC Data Source.

      On the Identification tab, select the ODBC Data Source name option. Type UltraLite 9.0 Sample for the data source name.

      On the Database tab, ensure the option to search for network database servers is not selected.

    • Click OK to Connect.

    • Sybase Central should now display the CustDB data source under the MobiLink Synchronization 9 plug-in.

      Connection via the MobiLink Synchronization plug-in

  2. Change the language for the ULCustomer table upload_insert event to .NET:

    • In the left pane, open the Synchronized Tables folder and select the ULCustomer table. A list of table-level scripts appears in the right pane.

    • Click on the table script associated with the custdb 9.0 upload_insert event. From the File menu, choose Set Script Language to .NET.

  3. Enter the fully-qualified .NET method name for the upload_insert script.

    • Double-click the table script associated with the upload_insert event.

      A window revealing the script contents appears.

    • Change the script contents to the fully-qualified method name, MLExample.CustdbScripts.UploadInsert.

      The upload_insert script showing the fully qualified name for the UploadInsert .NET method
      Note:
      The fully qualified method name is case sensitive.

    • To save the script, choose Save from the File menu.

  4. Exit Sybase Central.

This step used Sybase Central to specify a .NET method as the script for the ULCustomer upload_insert event.

Alternatively, you can use the ml_add_dnet_connection_script and ml_add_dnet_table_script stored procedures. Using these stored procedures is more efficient, especially if you have a large number of .NET methods to handle synchronization events.

For more information, see ml_add_dnet_connection_script and ml_add_dnet_table_script.

In the next section you connect to CustDB with Interactive SQL and execute ml_add_dnet_table_script, assigning MLExample.CustdbScripts.DownloadCursor to the download_cursor event.

toggle To specify MLExample.CustdbScripts.DownloadCursor for the ULCustomer download_cursor event

  1. Connect to the sample database with Interactive SQL.

    • Start Interactive SQL.

      Choose Start > Programs > SQL Anywhere 9 > Adaptive Server Anywhere > Interactive SQL, or enter the following at a command prompt:

      dbisql

      The Connect dialog appears.

    • On the Identification tab, choose UltraLite 9.0 Sample for the ODBC Data Source:

      The MobiLink Synchronization 9 plug-in Connect dialog.

      On the Database tab, ensure the option to search for network database servers is not selected.

  2. Execute the following command in Interactive SQL:

    call ml_add_dnet_table_script(
'custdb 9.0',
'ULCustomer',
'download_cursor',
'MLExample.CustdbScripts.DownloadCursor');
commit;

    Following is a description of each parameter:

    Parameter | Description
    custdb 9.0 | The script version.
    ULCustomer | The synchronized table.
    download_cursor | The event name.
    MLExample,CustdbScripts.DownloadCursor | The fully qualified .NET method.

  3. Exit Interactive SQL.

In this lesson, you specified .NET methods to handle ULCustomer table-level events. The next lesson ensures that the MobiLink server loads the appropriate class files and the MobiLink API.

Further reading

For more information about adding and deleting synchronization scripts, see Adding and deleting scripts in your consolidated database.

For more information about the scripts used in this lesson, see ml_add_dnet_connection_script and ml_add_dnet_table_script.


Lesson 3: Run MobiLink with -sl dnet

Running the MobiLink server with the -sl dnet option specifies the location of .NET assemblies and forces the CLR to load on server startup.

If you used Visual Studio .NET to compile, the location of CustdbScripts.dll is c:\mldnet\CustdbScripts\CustdbScripts\bin\Debug. If you used the command line, the location of CustdbScripts.dll is c:\mldnet.

toggle To start the MobiLink server (dbmlsrv9) and load .NET assemblies

  • Start the MobiLink server with the -sl dnet option.

    If you used Visual Studio .NET to compile your assembly:

    On a command line, enter the following on a single line:

    dbmlsrv9 -c "dsn=ultralite 9.0 sample" -dl -o cons1.txt -v+ -sl dnet(-MLAutoLoadPath=c:\mldnet\CustdbScripts\CustdbScripts\bin\Debug)

    If you used the command line to compile your assembly:

    On a command line, enter the following on a single line:

    dbmlsrv9 -c "dsn=ultralite 9.0 sample" -dl -o cons1.txt -v+ -sl dnet(-MLAutoLoadPath=c:\mldnet)

    A message dialog appears indicating that the server is ready to handle requests. Now the .NET method is executed when the upload_insert events triggers during synchronization.

Further reading

For more information see, -sl dnet option.


Start the application (Windows)

toggle To start and synchronize the sample application

  1. Launch the sample application.

    From the Start menu, choose Programs > SQL Anywhere 9 > UltraLite > Windows Sample Application.

  2. Enter an employee ID.

    Input a value of 50 and press Enter.

The application automatically synchronizes, and a set of customers, products, and orders are downloaded to the application from the CustDB consolidated database.

In the next section you will enter a new customer name and order details. During a subsequent synchronization, this information will be uploaded to the CustDB consolidated database and the upload_insert and download_cursor events for the ULCustomer table will trigger.


Add an order (Windows)

toggle To add an order

  1. From the Order menu, choose New.

    The Add New Order screen appears.

  2. Enter a new Customer Name.

    For example, enter Frank DotNET.

  3. Choose a product, and enter the quantity and discount:

    The Add New Order dialog, showing the order information for Frank DotNET

  4. Press Enter to add the new order.

You have now modified the data in your local UltraLite database. This data is not shared with the consolidated database until you synchronize.

toggle To synchronize with the consolidated database and trigger the upload_insert event

  • From the file menu, choose Synchronize.

A window appears indicating one Insert successfully uploaded to the consolidated database.

Further reading

For more information about the CustDB Windows Application, see The CustDB Sample Application.


Cleanup

You should remove tutorial materials from your computer.

toggle To remove tutorial materials from your computer

  1. Return the ULCustomer table upload_insert and download_cursor scripts to their original SQL logic.

    • Open Interactive SQL.

      Choose Start > Programs > SQL Anywhere 9 > Adaptive Server Anywhere > Interactive SQL, or enter the following at a command prompt:

      dbisql

      The Connect dialog appears.

    • On the Identification tab, choose UltraLite 9.0 Sample for the ODBC Data Source.

    • Click OK to Connect.

    • Execute the following commands in Interactive SQL:

      call ml_add_table_script( 'custdb 9.0',
   'ULCustomer',
   'upload_insert',
   'INSERT INTO ULCustomer( cust_id, cust_name ) VALUES( ?, ? )' );

call ml_add_table_script( 'custdb 9.0',
   'ULCustomer',
   'download_cursor',
   'SELECT "cust_id", "cust_name" FROM "ULCustomer" WHERE "last_modified" >= ?' );

  2. Close the Adaptive Server Anywhere, MobiLink, and synchronization client windows by right-clicking on each taskbar item and choosing Close.

  3. Delete all tutorial-related .NET sources.

    Delete the folder containing your CustdbScripts.cs and CustdbScripts.dll files (c:\mldnet).

    Note:
    Ensure that you do not have other important files in c:\mldnet.

Previous Next


Further reading

The following documentation sections are a good starting point for further reading:

For more information about writing MobiLink synchronization scripts in .NET, see Setting up .NET synchronization logic.

For information about debugging .NET synchronization logic, see Debugging .NET synchronization logic.

For a detailed example illustrating the use of .NET synchronization scripts for custom authentication, see .NET synchronization example.

For more information about synchronization scripting, see Writing Synchronization Scripts and Synchronization Events.

For an introduction to other methods of synchronization such as timestamp, see Synchronization Techniques.


The Contact Sample Application

About this chapter

This chapter uses the sample application called Contact to illustrate a variety of techniques that you can use for common synchronization tasks.

The techniques are illustrated using SQL scripts. Many of the same techniques can be implemented using Java or .NET synchronization logic.


Introduction

This chapter introduces you to the Contact sample application. This sample is a valuable resource for the MobiLink developer. It provides you with an example of how to implement many of the techniques you will need to develop MobiLink applications.

The Contact sample application includes an Adaptive Server Anywhere consolidated database and two Adaptive Server Anywhere remote databases. It illustrates several common synchronization techniques. To get the most out of this chapter, you should study the sample application as you read.

Although the consolidated database is an Adaptive Server Anywhere database, the synchronization scripts consist of SQL statements that should work with minimal changes on other database management systems.

The Contact sample is in the Samples\MobiLink\Contact subdirectory of your SQL Anywhere installation. For an overview, see Samples\MobiLink\Contact\readme.txt.

Synchronization design

The synchronization design in the Contact sample application uses the following features:

  • Column subsets A subset of the columns of the Customer, Product, SalesRep, and Contact tables on the consolidated database are shared with the remote databases.

  • Row subsets All of the columns but only one of the rows of the SalesRep table on the consolidated database are shared with each remote database.

    For more information, see Partitioning rows among remote databases.

  • Timestamp-based synchronization This is a way of identifying changes that were made to the consolidated database since the last time a device synchronized. The Customer, Contact, and Product tables are synchronized using a method based on timestamps.

    For more information, see Timestamp-based synchronization.


Setup

A Windows batch file called build.bat is provided to build the Contact sample databases. On UNIX systems, the file is build.sh. You may want to examine the contents of the batch file. It carries out the following actions:

  • Creates ODBC data source definitions for a consolidated database and each of two remote databases.

  • Creates a consolidated database named consol.db and loads the MobiLink system tables, database schema, some data, synchronization scripts, and MobiLink user names into the database.

  • Creates two remote databases, each named remote.db, in subdirectories named remote_1 and remote_2. Loads information common to both databases and applies customizations. These customizations include a global database identifier, a MobiLink user name, and subscriptions to two publications.

toggle To build the Contact sample

  1. Open a command prompt and navigate to the Samples\MobiLink\Contact subdirectory of your SQL Anywhere installation.

  2. Run build.bat (Windows) or build.sh (Unix).

Running the Contact sample


Running the Contact sample

The Contact sample includes batch files that carry out initial synchronizations and illustrate MobiLink synchronization server and dbmlsync command lines. You can examine the contents of the following batch files, located in the Samples\MobiLink\Contact subdirectory of your SQL Anywhere 9 installation, in a text editor:

  • step1.bat

  • step2.bat

  • step3.bat

toggle To run the Contact sample

  1. Start the MobiLink synchronization server.

    • Open a command prompt and navigate to the Samples\MobiLink\Contact subdirectory of your SQL Anywhere 9 installation and execute the following command:

      step1

      This command runs a batch file that starts the MobiLink synchronization server in a verbose mode. This mode is useful during development or troubleshooting, but has a significant performance impact and so would not be used in a routine production environment.

  2. Synchronize both remote databases.

    • Open a command prompt and navigate to the Samples\MobiLink\Contact subdirectory of your SQL Anywhere 9 installation and execute the following command:

      step2

      This is a batch file that synchronizes both remote databases.

  3. Shut down the MobiLink synchronization server.

    • Open a command prompt and navigate to the Samples\MobiLink\Contact subdirectory of your SQL Anywhere 9 installation and execute the following command:

      step3

      This is a batch file that shuts down the MobiLink synchronization server.

To explore how synchronization works in the Contact sample, you can use Interactive SQL to modify the data in the remote and consolidated databases, and use the batch files to synchronize.


Tables in the Contact databases

The table definitions for the Contact database are located in the following files:

  • Samples\MobiLink\Contact\build_consol.sql

  • Samples\MobiLink\Contact\build_remote.sql

Both the consolidated and the remote databases contain the following three tables, although their definition is slightly different in each place.

SalesRep

Each sales representative occupies one row in the SalesRep table. Each remote database belongs to a single sales representative.

In each remote database, SalesRep has the following columns:

  • rep_id A primary key column that contains an identifying number for the sales representative.

  • name The name of the representative.

In the consolidated database only, there is also an ml_username column holding the MobiLink user name for the representative.

Customer

This table holds one row for each customer. Each customer is a company with which a single sales representative does business. There is a one-to-many relationship between the SalesRep and Customer tables.

In each remote database, Customer has the following columns:

  • cust_id A primary key column holding an identifying number for the customer.

  • name The customer name. This is a company name.

  • rep_id A foreign key column referencing the SalesRep table. Identifies the sales representative assigned to the customer.

In the consolidated database, there are two additional columns, last_modified and active:

  • last_modified The last time the row was modified. This column is used for timestamp-based synchronization.

  • active A BIT column that indicates if the customer is currently active (1) or if the company no longer deals with this customer (0). If the column is marked inactive (0) all rows corresponding to this customer are deleted from remote databases.

Contact

This table holds one row for each contact. A contact is a person who works at a customer company. There is a one-to-many relationship between the Customer and Contact tables.

In each remote database, Contact has the following columns:

  • contact_id A primary key column holding an identifying number for the customer.

  • name The name of the individual contact.

  • cust_id The identifier of the customer for whom the contact works.

In the consolidated database, the table also has the following columns:

  • last_modified The last time the row was modified. This column is used for timestamp-based synchronization.

  • active A BIT column that indicates if the contact is currently active (1) or if the company no longer deals with this contact (0). If the column is marked inactive (0) the row corresponding to this contact is deleted from remote databases.

Product

Each product sold by the company occupies one row in the Product table. The Product table is held in a separate publication so that remote databases can synchronize the table separately.

In each remote database, Product has the following columns:

  • id A primary key column holding an identifying number for the product.

  • name The name of the individual item.

  • size The size of the item.

  • quantity The number of items in stock. When a sales representative takes an order, this column is updated.

  • unit_price The price per unit of the product.

In the consolidated database, the Product table has the following additional columns:

  • supplier The company that manufactures the product.

  • last_modified The last time the row was modified. This column is used for timestamp-based synchronization.

  • active A BIT column that indicates if the contact is currently active (1) or if the company no longer deals with this contact (0). If the column is marked inactive (0), the row corresponding to this contact is deleted from remote databases.

In addition to these tables, a set of tables is created at the consolidated database only. These include the product_conflict table, which is a temporary table used during conflict resolution, and a set of tables for monitoring MobiLink activities owned by a user named mlmaint. Scripts to create the MobiLink monitoring tables are in the file Samples\MobiLink\Contact\mlmaint.sql.


Users in the Contact sample

Several different database user IDs and MobiLink user names are included in the Contact sample.

Database user IDs

The two remote databases belong to sales representatives Samuel Singer (rep_id 856) and Pamela Savarino (rep_id 949).

When connecting to their remote database, these users both use the default Adaptive Server Anywhere user ID dba and password SQL.

Each remote database also has a user ID sync_user with password sync_user. This user ID is employed only on the dbmlsync command line. It is a user with REMOTE DBA authority, and so can carry out any operation when connected from dbmlsync, but has no authority when connected from any other application. The widespread availability of the user ID and password is thus not a problem.

At the consolidated database, there is a user named mlmaint, who owns the tables used for monitoring MobiLink synchronization statistics and errors. This user has no right to connect. The assignment of the tables to a separate user ID is done simply to separate the objects from the others in the schema for easier administration in Sybase Central and other utilities.

MobiLink user names

MobiLink user names are distinct from database user IDs. Each remote device has a MobiLink user name in addition to the user ID they use when connecting to a database. The MobiLink user name for Samuel Singer is SSinger. The MobiLink user name for Pamela Savarino is PSavarino. The MobiLink user name is stored or used in the following locations:

  • At the remote database, the MobiLink user name is added using a CREATE SYNCHRONIZATION USER statement.

  • At the consolidated database, the MobiLink user name and password are added using the dbmluser utility.

  • During synchronization, the MobiLink password for the connecting user is supplied on the dbmlsync command line listed in Samples\MobiLInk\Contact\step2.bat.

  • The MobiLink synchronization server supplies the MobiLink user name as a parameter to many of the scripts during synchronization.

  • The SalesRep table at the consolidated database has an ml_username column. The synchronization scripts match the MobiLink user name parameter against the value in this column.


Synchronization

The following sections describe the Contact sample's synchronization logic.

Synchronizing sales representatives in the Contact sample
Synchronizing customers in the Contact sample
Synchronizing contacts in the Contact sample
Synchronizing products in the Contact sample


Synchronizing sales representatives in the Contact sample

The synchronization scripts for the SalesRep table illustrates snapshot synchronization. Regardless of whether a sales representative's information has changed, it is downloaded.

For more information, see Snapshot synchronization.

Business rules

The business rules for the SalesRep table are as follows:

  • The table must not be modified at the remote database.

  • A sales representative's MobiLink user name and rep_id value must not change.

  • Each remote database contains a single row from the SalesRep table, corresponding to the remote database owner's MobiLink user name.

Downloads

  • download_cursor At each remote database, the SalesRep table contains a single row. There is very little overhead for the download of a single row, so a simple snapshot download_cursor script is used:

    SELECT rep_id, name
FROM SalesRep
WHERE ? IS NOT NULL
AND ml_username = ?

    The first parameter in the script is the last download timestamp, which is not used. The IS NOT NULL expression is a dummy expression supplied to use the parameter. The second parameter is the MobiLink user name.

Uploads

This table should not be updated at the remote database, so there are no upload scripts for the table.


Synchronizing customers in the Contact sample

The synchronization scripts for the Customer table illustrate timestamp-based synchronization and partitioning rows. Both of these techniques minimize the amount of data that is transferred during synchronization while maintaining consistent table data.

For more information, see Timestamp-based synchronization.

For more information, see Partitioning rows among remote databases.

Business rules

The business rules governing customers are as follows:

  • Customer information can be modified at both the consolidated and remote databases.

  • Periodically, customers may be reassigned among sales representatives. This process is commonly called territory realignment.

  • Each remote database contains only the customers they are assigned to.

Downloads

  • download_cursor The following download_cursor script downloads only active customers for whom information has changed since the last successful download. It also downloads only customers assigned to a particular sales representative.

    SELECT cust_id, Customer.name, Customer.rep_id
FROM Customer key join SalesRep
WHERE Customer.last_modified >= ?
AND SalesRep.ml_username = ?
AND Customer.active = 1

  • download_delete_cursor The following download_delete_cursor script downloads only customers for whom information has changed since the last successful download. It deletes all customers marked as inactive or who are not assigned to the sales representative.

    SELECT cust_id
FROM Customer key join SalesRep
WHERE Customer.last_modified >= ?
AND ( SalesRep.ml_username != ? OR Customer.active = 0 )

    If rows are deleted from the Customer table at the consolidated database, they do not appear in this result set and so are not deleted from remote databases. Instead, customers are marked as inactive.

    When territories are realigned, this script deletes those customers no longer assigned to the sales representative. It also deletes customers who are transferred to other sales representatives. Such additional deletes are flagged with a SQLCODE of 100 but do not interfere with synchronization. A more complex script could be developed to identify only those customers transferred away from the current sales representative.

    The MobiLink client carries out cascading deletes at the remote database, so this script also deletes all contacts who work for customers assigned to some other sales representative.

Uploads

Customer information can be inserted, updated, or deleted at the remote database. The scripts corresponding to these operations are as follows:

  • upload_insert The following upload_insert script adds a row to the Customer table, marking the customer as active:

    INSERT INTO Customer(
   cust_id, name, rep_id, active )
VALUES ( ?, ?, ?, 1 )

  • upload_update The following upload_update script modifies the customer information at the consolidated database:

    UPDATE Customer
SET name = ?, rep_id = ?
WHERE cust_id = ?

    Conflict detection is not carried out on this table.

  • upload_delete The following upload_delete script marks the customer as inactive at the consolidated database. It does not delete a row.

    UPDATE Customer
SET active = 0
WHERE cust_id = ?


Synchronizing contacts in the Contact sample

The Contact table contains the name of a person working at a customer company, a foreign key to the customer and a unique integer identifying the contact. It also contains a last_modified timestamp and a marker to indicate whether the contact is active.

Business rules

The business rules for this table are as follows:

  • Contact information can be modified at both the consolidated and remote databases.

  • Each remote database contains only those contacts who work for customers they are assigned to.

  • When customers are reassigned among sales representatives, contacts must also be reassigned

Trigger

A trigger on the Customer table is used to ensure that the contacts get picked up when information about a customer is changed. The trigger explicitly alters the last_modified column of each contact whenever the corresponding customer is altered:

CREATE TRIGGER UpdateCustomerForContact
AFTER UPDATE OF rep_id ORDER 1
ON DBA.Customer
REFERENCING OLD AS old_cust NEW as new_cust
FOR EACH ROW
BEGIN
  UPDATE Contact
  SET Contact.last_modified = new_cust.last_modified
  FROM Contact
  WHERE Contact.cust_id = new_cust.cust_id
END

By updating all contact records whenever a customer is modified, the trigger ties the customer and their associated contacts together so that whenever a customer is modified, all associated contacts are modified too, and will be downloaded together on the next synchronization.

Downloads

  • download_cursor The download_cursor script for Contact is as follows:

    SELECT contact_id, contact.name, contact.cust_id
FROM ( contact JOIN customer ) JOIN salesrep
ON contact.cust_id = customer.cust_id
   AND customer.rep_id = salesrep.rep_id
WHERE Contact.last_modified >= ?
   AND salesrep.ml_username = ?
   AND Contact.active = 1

    This script retrieves all contacts that are active, that have been changed since the last time the sales representative downloaded (either explicitly or by modification of the corresponding customer), and that are assigned to the representative. A join with the Customer and SalesRep table is needed to identify the contacts associated with this representative.

  • download_delete_cursor The download_delete_cursor for Contact is as follows:

    SELECT contact_id
FROM ( Contact JOIN Customer ) JOIN SalesRep
ON Contact.cust_id = Customer.cust_id
   AND Customer.rep_id = SalesRep.rep_id
WHERE Contact.last_modified >= ?
   AND Contact.active = 0

    The automatic use of cascading referential integrity by the MobiLink client deletes contacts when the corresponding customer is deleted from the remote database. The download_delete_cursor script therefore has to delete only those contact explicitly marked as inactive.

Uploads

Contact information can be inserted, updated, or deleted at the remote database. The scripts corresponding to these operations are as follows:

  • upload_insert The following upload_insert script adds a row to the Contact table, marking the contact as active:

    INSERT INTO Contact (
   contact_id, name, cust_id, active )
VALUES ( ?, ?, ?, 1 )

  • upload_update The following upload_update script modifies the contact information at the consolidated database:

    UPDATE Contact
SET name = ?, cust_id = ?
WHERE contact_id = ?

    Conflict detection is not carried out on this table.

  • upload_delete The following upload_delete script marks the contact as inactive at the consolidated database. It does not delete a row.

    UPDATE Contact
SET active = 0
WHERE contact_id = ?


Synchronizing products in the Contact sample

The scripts for the Product table illustrate conflict detection and resolution.

The Product table is kept in a separate publication from the other tables so that it can be downloaded separately. For example, if the price changes and the sales representative is synchronizing over a slow link, they can download the product changes without uploading their own customer and contact changes.

Business rules

The only change that can be made at the remote database is to change the quantity column, when an order is taken.

Downloads

  • download_cursor The following download_cursor script downloads all rows changed since the last time the remote database synchronized:

    SELECT id, name, size, quantity, unit_price
FROM product
WHERE last_modified >= ?
AND active = 1

  • download_delete_cursor The following download_delete_cursor script removes all products no longer sold by the company. These products are marked as inactive in the consolidated database.

    SELECT id, name, size, quantity, unit_price
FROM product
WHERE last_modified >= ?
AND active = 0
Uploads

Only UPDATE operations are uploaded from the remote database. The major feature of these upload scripts is a conflict detection and resolution procedure.

If two sales representatives take orders and then synchronize, each order is subtracted from the quantity column of the Product table. For example, if Sam Singer takes an order for 20 baseball hats (product ID 400), he will change the quantity from 90 to 70. If Pam Savarino takes an order for 10 baseball hats before receiving this change, she will change the column in her database from 90 to 80.

When Sam Singer synchronizes his changes, the quantity column in the consolidated database is changed from 90 to 70. When Pam Savarino synchronizes her changes, the correct action is to set the value to 60. This setting is accomplished by detecting the conflict.

The conflict detection scheme includes the following scripts:

  • upload_update The following upload_update script is a straightforward UPDATE at the consolidated database:

    UPDATE product
SET name = ?, size = ?, quantity = ?, unit_price = ?
WHERE product.id = ?

  • upload_fetch The following upload_fetch script fetches a single row from the Product table for comparison with the old values of the uploaded row. If the two rows differ, a conflict is detected.

    SELECT id, name, size, quantity, unit_price
FROM Product
WHERE id = ?

  • upload_old_row_insert If a conflict is detected, the old values are placed into the product_conflict table for use by the resolve_conflict script. The row is added with a value of O (for Old) in the row_type column.

    INSERT INTO DBA.product_conflict(
   id, name, size, quantity, unit_price, row_type )
VALUES( ?, ?, ?, ?, ?, 'O' )' )

  • upload_new_row_insert The following script adds the new values of the uploaded row into the product_conflict table for use by the resolve_conflict script:

    INSERT INTO DBA.product_conflict(
   id, name, size, quantity, unit_price, row_type )
VALUES( ?, ?, ?, ?, ?, 'N' )
Conflict resolution

  • resolve_conflict The following script resolves the conflict by adding the difference between new and old rows to the quantity value in the consolidated database:

    UPDATE Product
SET p.quantity = p.quantity
              - old_row.quantity
              + new_row.quantity
FROM Product p,
     DBA.product_conflict old_row,
     DBA.product_conflict new_row
WHERE p.id = old_row.id
    AND p.id = new_row.id
    AND old_row.row_type = 'O'
    AND new_row.row_type = 'N'


Monitoring statistics and errors in the Contact sample

The Contact sample contains some simple error reporting and monitoring scripts. The SQL statements to create these scripts are in the file Samples\MobiLink\Contact\mlmaint.sql.

The scripts insert rows into tables created to hold the values. For convenience, the tables are owned by a distinct user, mlmaint.


The CustDB Sample Application

About this chapter

This chapter uses the CustDB sample application to illustrate a variety of techniques that you can use for common synchronization tasks.

The techniques are illustrated using SQL scripts and Java synchronization logic. Many of the same techniques can be implemented using .NET synchronization logic.

Introduction
Setup
Tables in the CustDB databases
Users in the CustDB sample
Synchronization
Maintaining the customer and order primary key pools
Further reading


Introduction

This chapter introduces you to the CustDB (Customer Database) MobiLink sample application. CustDB is a sales-status application.

The CustDB sample is a valuable resource for the MobiLink developer. It provides you with examples of how to implement many of the techniques you will need to develop MobiLink applications.

The application has been designed to illustrate several common synchronization techniques. To get the most out of this chapter, you should study the sample application as you read.

A version of CustDB is supplied for each supported operating system and for each supported database type.

For the locations of CustDB and setup instructions, see Setting up the CustDB consolidated database.

Following is the schema of CustDB:

The UltraLite sample database, including tables, column names, primary keys, and foreign key relationships.
Scenario

The CustDB scenario is as follows.

A consolidated database is located at the head office. The following data is stored in the consolidated database:

  • The MobiLink system tables that hold the synchronization metadata.

  • The synchronization scripts that implement synchronization logic.

  • The CustDB data, including all customer, product, and order information, stored in the rows of base tables.

There are two types of remote databases, mobile managers and sales representatives.

Each mobile sales representative's database contains all products but only those orders assigned to that sales representative, while a mobile manager's database contains all products and orders.

Synchronization design

The synchronization design in the CustDB sample application uses the following features:

  • Complete table downloads All rows and columns of the ULProduct table are shared in their entirety with the remote databases.

  • Column subsets All rows, but not all columns, of the ULCustomer table are shared with the remote databases.

  • Row subsets Different remote users get different sets of rows from the ULOrder table.

    For more information about row subsets, see Partitioning rows among remote databases.

  • Timestamp-based synchronization This is a way of identifying changes that were made to the consolidated database since the last time a device synchronized. The ULCustomer and ULOrder tables are synchronized using a method based on timestamps.

    For more information, see Timestamp-based synchronization.

  • Snapshot synchronization This is a simple method of synchronization that downloads all rows in every synchronization. The ULProduct table is synchronized in this way.

    For more information, see Snapshot synchronization.

  • Primary key pools to maintain unique primary keys It is essential to ensure that primary key values are unique across a complete MobiLink installation. The primary key pool method used in this application is one way of ensuring unique primary keys.

    For more information, see Maintaining unique primary keys using key pools.

    For other ways to ensure that primary keys are unique, see Maintaining unique primary keys.


Setup

This section describes the pieces that make up the code for the CustDB sample application and database. These include:

  • The sample SQL scripts, located in the Samples\MobiLink\CustDB subdirectory of your SQL Anywhere installation.

  • The application code, located in Samples\UltraLite\CustDB.

  • Platform-specific user interface code, located in subdirectories of Samples\UltraLite\CustDB named for each operating system.


Setting up the CustDB consolidated database

The consolidated database may be Adaptive Server Anywhere, Sybase Adaptive Server Enterprise, Microsoft SQL Server, Oracle, or IBM DB2.

The following SQL scripts are provided in the Samples\MobiLink\CustDB subdirectory of your SQL Anywhere 9 installation to build the consolidated database on any of these platforms:

  • For an Adaptive Server Anywhere database, the file is custdb.sql.

  • For an IBM DB2 database, the file is custdb2.sql.

  • For an Adaptive Server Enterprise database, the file is custase.sql.

  • For a Microsoft SQL Server database, the file is custmss.sql.

  • For an Oracle database, the file is custora.sql.

Creating a consolidated database


Creating a consolidated database

The following procedures create a consolidated database for CustDB for each of the supported types of consolidated database.

For databases other than Adaptive Server Anywhere databases, you will first need to run a script to add the MobiLink system tables. This platform-specific script is located in the MobiLink\setup subdirectory of your SQL Anywhere 9 installation.

For more information about preparing a database for use as a consolidated database, see Setting up a consolidated database.

toggle To set up a consolidated database (Adaptive Server Enterprise, Oracle or SQL Server)

  1. Create the consolidated database.

  2. Add the MobiLink system tables by running one of the following SQL scripts, located in the MobiLink\setup subdirectory of your SQL Anywhere 9 installation:

    • For an Adaptive Server Enterprise consolidated database prior to version 12.5, run syncase.sql. Otherwise, run syncase125.sql.

    • For an Oracle consolidated database, run syncora.sql.

    • For a SQL Server consolidated database, run syncmss.sql.

  3. Add tables to the CustDB database by running one of the following SQL scripts, located in the Samples\MobiLink\CustDB subdirectory of your SQL Anywhere 9 installation:

    • For an Adaptive Server Enterprise consolidated database, run custase.sql.

    • For an Oracle consolidated database, run custora.sql.

    • For a SQL Server consolidated database, run custmss.sql.

  4. Create an ODBC data source called CustDB that references your database on the client machine.

    • Choose Start > Programs > Sybase SQL Anywhere 9 > Adaptive Server Anywhere > ODBC Administrator.

    • Click Add.

    • Select the appropriate driver from the list.

      Click Finish.

    • Name the ODBC data source CustDB.

    • Click the Login tab. Enter the user ID and password for your database.

toggle To set up a consolidated database (Adaptive Server Anywhere)

  1. Create the consolidated database:

    Navigate to the Samples\MobiLink\CustDB subdirectory of your SQL Anywhere 9 installation and run the following command line:

    dbinit consol.db

  2. Add tables to the CustDB database by running custdb.sql, located in the Samples\MobiLink\CustDB subdirectory of your SQL Anywhere 9 installation.

    • Choose Start > Programs > Sybase SQL Anywhere 9 > Sybase Central.

    • In the right pane of Sybase Central, right-click Adaptive Server Anywhere 9 and connect to the consolidated database you have created. The default user ID and password are DBA and SQL.

    • In the right pane, right-click the consolidated database and select Open Interactive SQL from the popup menu.

    • In Interactive SQL, select File > Run Script. Browse to custdb.sql. Click Open.

    • Close Interactive SQL.

  3. Create an ODBC data source called CustDB that references your database on the client machine.

    • In Sybase Central, select Tools > Adaptive Server Anywhere 9 > Open ODBC Administrator.

    • Click Add.

    • Select Adaptive Server Anywhere 9.0 Driver. Click Finish.

    • Name the ODBC data source CustDB.

    • Click the Login tab. Enter the user ID and password for your database. The default values are DBA and SQL.

    • Click the Database tab. Browse to the location of your database file.

toggle To set up a consolidated database (IBM DB2)

  1. Create a DB2 database on the DB2 server. Ensure that the default table space (usually called USERSPACE1) uses 8 Kb pages.

    If the default table space does not use 8 Kb pages, complete the following steps:

    • Verify that at least one of your buffer pools has 8 Kb pages. If not, create a buffer pool with 8 Kb pages.

    • Create a new table space and temporary table space with 8 Kb pages.

      For more information, consult your DB2 documentation.

  2. Add the MobiLink system tables using the file MobiLink\setup\syncdb2long.sql.

    • Change the connect command in syncdb2long.sql. Replace DB2Database with the name of your ODBC data source. In this example, the ODBC data source is CustDB. You could also add the user name and password as follows. Replace userid and password with your user name and password.

         connect to DB2Database user userid using password ~

    • Open a DB2 Command Window on either the server or client computer. Run syncdb2long.sql by typing the following command:

         db2 -c -ec -td~ +s -v -f syncdb2long.sql

  3. In order for DB2 to use the stored procedures defined in syncdb2long.sql, you must copy the syncdb2long_version Java and class files located in the MobiLink\setup subdirectory of your SQL Anywhere installation to the FUNCTION subdirectory of your DB2 installation.

  4. Copy custdb2.class located in the Samples\MobiLink\CustDB subdirectory of your SQL Anywhere installation to the SQLLIB\FUNCTION directory on your DB2 server machine. This class contains procedures used for the CustDB sample.

  5. Add tables to the CustDB database:

    • If necessary, change the connect command in custdb2.sql. For example, you could add the user name and password as follows. Replace userid and password with your user name and password.

         connect to CustDB user userid using password

    • Open a DB2 Command Window on either the server or client computer. Run custdb2.sql by typing the following command:

         db2 -c -ec -td~ +s -v -f custdb2.sql

    • When processing is complete, enter the following command to close the command window:

         exit

  6. Create an ODBC data source called CustDB that references the DB2 database on the DB2 client machine.

    • Start the ODBC Administrator:

      From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > ODBC Administrator.

      The ODBC Data Source Administrator appears.

    • On the User DSN tab, click Add.

      The Create New Data Source dialog appears.

    • Select iAnywhere Solutions 9 - DB2 Wire Protocol and click Finish.

      The ODBC DB2 Wire Protocol Driver Setup dialog appears.

    • On the General tab, type the Data Source Name db2_consolidated and enter the appropriate Ip Address, and Tcp port. For the IBM DB2 sample database use SAMPLE for the database name.

    • On the Bind tab, click Create Package. Enter the Username and Password for your IBM DB2 instance.

    • Click OK.

  7. Run the custdb2setuplong Java application on the DB2 client machine as follows. This application resets the CustDB example in the DB2 database. After the initial setup, you can run this application at any time to reset the DB2 CustDB database by typing the same command line.

    • If you use a name other than CustDB for the data source, you must modify the connection code in custdb2setuplong.java and recompile it as follows. If the path specified by the system variable %db2tempdir% contains spaces, you must enclose the path in quotation marks.

      javac -g -classpath %db2tempdir%\java\jdk\lib\classes.zip;
%db2tempdir%\java\db2java.zip;
%db2tempdir%\java\runtime.zip custdb2setuplong.java

    • Type the following, where userid and password are the user name and password for connecting to the CustDB ODBC data source.

      java custdb2setuplong userid password


Setting up an UltraLite remote database

The following procedure creates a remote database for CustDB. The CustDB remote database must be an UltraLite database.

The application logic for the remote database is located in the Samples\UltraLite\CustDB subdirectory of your SQL Anywhere 9 installation. It includes the following files:

  • Embedded SQL logic The file custdb.sqc contains the SQL statements needed to query and modify information from the UltraLite database and the calls required to start synchronization with the consolidated database.

  • C++ API logic The file custdbapi.cpp contains the C++ API logic.

  • User-interface features These features are stored separately, in platform-specific subdirectories of Samples\UltraLite\CustDB.

You will complete the following steps in order to install the sample application to a remote device that is running UltraLite:

toggle To install the sample application to a remote device

  1. Start the consolidated database.

  2. Start the MobiLink synchronization server.

  3. Install the sample application to your remote device.

  4. Start the sample application on the remote device.

  5. Synchronize the sample application.

Example

The following example installs the CustDB sample on a Palm device running against a DB2 consolidated database.

  1. Ensure that the consolidated database is running:

    • For a DB2 database, open a DB2 Command Window and run the following command line, where userid and password are the user ID and password for connecting to the DB2 database:

         db2 connect to CustDB user userid using password

  2. Start the MobiLink synchronization server:

    • For a DB2 database, run the following command at a command prompt:

      dbmlsrv9 -c "DSN=CustDB" -zp

  3. Install the sample application to your Palm device:

    • On your PC, start Palm Desktop.

    • Click Quick Install on the Palm Desktop toolbar.

    • Click Add. Browse to custdb.prc in the UltraLite\palm\68k subdirectory of your SQL Anywhere 9 installation.

    • Click Open.

    • HotSync your Palm device.

  4. Start the CustDB sample application on your Palm device:

    • Place your Palm device in its cradle.

      When you start the sample application for the first time, you are prompted to synchronize to download an initial copy of the data. This step is required only the first time you start the application. After that, the downloaded data is stored in the UltraLite database.

    • Launch the sample application.

      From the Applications view, tap CustDB.

      An initial dialog appears, prompting you for an employee ID.

    • Enter an employee ID.

      For the purpose of this tutorial, enter a value of 50. The sample application also allows values of 51, 52, or 53, but behaves slightly differently in these cases.

      For more information about the behavior of each user ID, see Users in the CustDB sample.

      A message box tells you that you must synchronize before proceeding.

    • Synchronize your application.

      Use HotSync to obtain an initial copy of the data.

    • Confirm that the data has been synchronized into the application.

      From the Applications view, tap the CustDB application. The display shows an entry sheet for a customer, with entries.

  5. Synchronize the remote application with the consolidated database. You will only need to complete this step when you have made changes to the database.

    • Ensure that the consolidated database and the MobiLink synchronization server are running.

    • Place the Palm device in its cradle.

    • Press the HotSync button to synchronize.

Clean up

You may want to reset the data in the CustDB database in order to restart the sample. To revert the data in the CustDB UltraLite database to its original state, complete the following steps.

toggle To reset the data in the sample application

  1. Install the ULUtil on your device:

    • For a Palm device, start Palm Desktop on your PC.

    • Click Install on the Palm Desktop toolbar.

    • Click Add. Browse to ulutil.prc in the UltraLite\palm\68k subdirectory of your SQL Anywhere 9 installation.

    • Click Done.

    • HotSync your Palm device.

  2. Delete the data using ULUtil:

    • For a Palm device, tap the ULUtil icon.

    • Select CustDB and tap Delete Data.

    • HotSync your Palm device.


Tables in the CustDB databases

The table definitions for the CustDB database are in platform-specific files in the Samples\MobiLink\CustDB subdirectory of your SQL Anywhere 9 installation.

Both the consolidated and the remote databases contain the following five tables, although their definitions are slightly different in each location.

ULCustomer

The ULCustomer table contains a list of customers.

In the remote database, ULCustomer has the following columns:

  • cust_id A primary key column that holds a unique integer identifying the customer.

  • cust_name A 30-character string containing the name of the customer.

In the consolidated database, ULCustomer has the following additional column:

  • last_modified A timestamp containing the last time the row was modified. This column is used for timestamp-based synchronization.

ULProduct

The ULProduct table contains a list of products.

In the both the remote and consolidated databases, ULProduct has the following columns:

  • prod_id A primary key column that holds a unique integer identifying the product.

  • price An integer identifying the unit price.

  • prod_name A 30-character string containing the name of the product.

ULOrder

The ULOrder table contains a list of orders, including details of the customer who placed the order, the employee who took the order, and the product being ordered.

In the remote database, ULOrder has the following columns:

  • order_id A primary key column that holds a unique integer identifying the order.

  • cust_id A foreign key column referencing ULCustomer.

  • prod_id A foreign key column referencing ULProduct.

  • emp_id A foreign key column referencing ULEmployee.

  • disc An integer containing the discount applied to the order.

  • quant An integer containing the number of products ordered.

  • notes A 50-character string containing notes about the order.

  • status A 20-character string describing the status of the order.

In the consolidated database, ULOrder has the following additional column:

  • last_modified A timestamp containing the last time the row was modified. This column is used for timestamp-based synchronization.

ULOrderIDPool

The ULOrderIDPool table is a primary key pool for ULOrder.

In the remote database, ULOrderIDPool has the following column:

  • pool_order_id A primary key column that holds a unique integer identifying the order ID.

In the consolidated database, ULOrderIDPool has the following additional columns:

  • pool_emp_id An integer column containing the employee ID of the owner of the remote database to which the order ID has been assigned.

  • last_modified A timestamp containing the last time the row was modified.

ULCustomerIDPool

The ULCustomerIDPool table is a primary key pool for ULCustomer.

In the remote database, ULCustomerIDPool has the following column:

  • pool_cust_id A primary key column that holds a unique integer identifying the customer ID.

In the consolidated database, ULCustomerIDPool has the following additional columns:

  • pool_emp_id An integer column containing the employee ID that will be used for a new employee generated at a remote database.

  • last_modified A timestamp containing the last time the row was modified.

The following tables are contained in the consolidated database only:

ULIdentifyEmployee_nosync

The ULIdentifyEmployee_nosync table exists only in the consolidated database. It has a single column as follows:

  • emp_id This primary key column contains an integer representing an employee ID.

ULEmployee

The ULEmployee table exists only in the consolidated database. It contains a list of sales employees.

ULEmployee has the following columns:

  • emp_id A primary key column that holds a unique integer identifying the employee.

  • emp_name A 30-character string containing the name of the employee.

ULEmpCust

The ULEmpCust table controls which customers' orders will be downloaded. If the employee needs a new customer's orders, inserting the employee ID and customer ID will force the orders for that customer to be downloaded.

  • emp_id A foreign key to ULEmployee.emp_id.

  • cust_id A foreign key to ULCustomer.cust_id. The primary key consists of emp_id and cust_id.

  • action A character used to determine if an employee record should be deleted from the remote database. If the employee no longer requires a customer's orders, set to D (delete). If the orders are still required, the action should be set to NULL.

    A logical delete must be used in this case so that the consolidated database can identify which rows to remove from the ULOrder table. Once the deletes have been downloaded, all records for that employee with an action of D can also be removed from the consolidated database.

  • last_modified A timestamp containing the last time the row was modified. This column is used for timestamp-based synchronization.

ULOldOrder and ULNewOrder

These tables exists only in the consolidated database. They are for conflict resolution and contain the same columns as ULOrder. In Adaptive Server Anywhere and Microsoft SQL Server these are temporary tables. In Adaptive Server Enterprise, these are normal tables and @@spid. DB2 and Oracle do not have temporary tables, so MobiLink needs to be able to identify which rows belong to the synchronizing user. Since these are base tables, if five users are synchronizing, they might each have a row in these tables at the same time.

For more information about @@spid, see Variables.


Users in the CustDB sample

There are two types of users in the CustDB sample, sales people and mobile managers. The differences are as follows:

  • Sales people User IDs 51, 52, and 53 identify remote databases that are associated with sales people. Sales people can carry out the following tasks:

    • View lists of customers and products.

    • Add new customers.

    • Add or delete orders.

    • Scroll through the list of outstanding orders.

    • Accept or deny orders.

    • Synchronize changes with the consolidated database.

  • Mobile managers User ID 50 identifies the remote database associated with the mobile manager. The mobile manager can perform the same tasks as a sales person. In addition, the mobile manager can do the following:

    • Accept or deny orders.


Synchronization

The following sections describe the CustDB sample's synchronization logic.

Synchronization logic source code
Synchronizing orders in the CustDB sample
Synchronizing customers in the CustDB sample
Synchronizing products in the CustDB sample


Synchronization logic source code

You can use Sybase Central to inspect the synchronization scripts in the consolidated database.

Script types and events

The custdb.sql file adds each synchronization script to the consolidated database by calling ml_add_connection_script or ml_add_table_script.

Example

The following lines in custdb.sql add a table-level script for the ULProduct table, which is executed during the download_cursor event. The script consists of a single SELECT statement.

call ml_add_table_script(
'CustDB',
'ULProduct', 'download_cursor',
'SELECT prod_id, price, prod_name FROM ULProduct' )
go


Synchronizing orders in the CustDB sample

Business rules

The business rules for the ULOrder table are as follows:

  • Orders are downloaded only if they they are not approved or the status is null.

  • Orders can modified at both the consolidated and remote databases.

  • Each remote database contains only the orders assigned to an employee.

Downloads

Orders can be inserted, deleted or updated at the consolidated database. The scripts corresponding to these operations are as follows:

  • download_cursor The first parameter in the download_cursor script is the last download timestamp. It is used to ensure that only rows that have been modified on either the remote or the consolidated database since the last synchronization are downloaded. The second parameter is the employee ID. It is used to determine which rows to download.

    The download_cursor script for CustDB is as follows:

    CALL ULOrderDownload( ?, ? )

    The ULOrderDownload procedure for CustDB is as follows:

    ALTER PROCEDURE ULOrderDownload ( IN LastDownload timestamp, IN EmployeeID integer )
BEGIN
  SELECT o.order_id, o.cust_id, o.prod_id, o.emp_id, o.disc, o.quant, o.notes, o.status
    FROM ULOrder o, ULEmpCust ec
    WHERE o.cust_id = ec.cust_id
    AND ec.emp_id = EmployeeID
    AND ( o.last_modified >= LastDownload
    OR ec.last_modified >= LastDownload)
    AND ( o.status IS NULL  OR  o.status != 'Approved' )
    AND ( ec.action IS NULL )
END

  • download_delete_cursor The download_delete_cursor script for CustDB is as follows:

SELECT o.order_id, o.cust_id, o.prod_id, o.emp_id, o.disc, o.quant, o.notes, o.status
 FROM ULOrder o, ULEmpCust ec
 WHERE o.cust_id = ec.cust_id
 AND ( ( o.status = 'Approved' AND o.last_modified >= ? )
 OR ( ec.action = 'D'  )  )
 AND ec.emp_id = ?
Uploads

Orders can be inserted, deleted or updated at the remote database. The scripts corresponding to these operations are as follows:

  • upload_insert The upload_insert script for CustDB is as follows:

INSERT INTO "ULOrder" ( "order_id", "cust_id", "prod_id", "disc", "quant", "notes", "status" )
  VALUES ( ?, ?, ?, ?, ?, ?, ? )

  • upload_update The upload_update script for CustDB is as follows:

UPDATE ULOrder SET cust_id=?, prod_id=?, emp_id=?, disc=?, quant=?, notes=?, status=?
   WHERE order_id = ?

  • upload_delete The upload_delete script for CustDB is as follows:

DELETE FROM "ULOrder" WHERE "order_id" = ?

  • upload_fetch The upload_fetch script for CustDB is as follows:

SELECT order_id, cust_id, prod_id, emp_id, disc, quant, notes, status
   FROM ULOrder WHERE order_id = ?

  • upload_old_row_insert The upload_old_row_insert script for CustDB is as follows:

INSERT INTO ULOldOrder ( order_id, cust_id, prod_id, emp_id, disc, quant, notes, status )
   VALUES( ?, ?, ?, ?, ?, ?, ?, ? )

  • upload_new_row_insert The upload_new_row_insert script for CustDB is as follows:

INSERT INTO ULNewOrder ( order_id, cust_id, prod_id, emp_id, disc, quant, notes, status )
   VALUES( ?, ?, ?, ?, ?, ?, ?, ? )
Conflict resolution

  • resolve_conflict The resolve_conflict script for CustDB is as follows:

    CALL ULResolveOrderConflict

    The ULResolveOrderConflict procedure for CustDB is as follows:

    ALTER PROCEDURE ULResolveOrderConflict()
BEGIN
  -- approval overrides denial
  IF 'Approved' = (SELECT status FROM ULNewOrder) THEN
    UPDATE ULOrder o
    SET o.status = n.status, o.notes = n.notes
    FROM ULNewOrder n
    WHERE o.order_id = n.order_id;
  END IF;
  DELETE FROM ULOldOrder;
  DELETE FROM ULNewOrder;
END


Synchronizing customers in the CustDB sample

Business rules

The business rules governing customers are as follows:

  • Customer information can be modified at both the consolidated and remote databases.

  • Both the remote and consolidated databases contain a complete listing of customers.

Downloads

Customer information can be inserted or updated at the consolidated database. The script corresponding to these operations is as follows:

  • download_cursor The following download_cursor script downloads all customers for whom information has changed since the last time the user downloaded information.

SELECT cust_id, cust_name FROM ULCustomer WHERE last_modified >= ?
Uploads

Customer information can be inserted, updated, or deleted at the remote database. The scripts corresponding to these operations are as follows:

  • upload_insert The upload_insert script for CustDB is as follows:

    INSERT INTO ULCustomer ( cust_id, cust_name ) VALUES ( ?, ? )

  • upload_update The upload_update script for CustDB is as follows:

    UPDATE ULCustomer SET cust_name = ?
WHERE "cust_id" = ?

    Conflict detection is not carried out on this table.

  • upload_delete The upload_delete script for CustDB is as follows:

    DELETE FROM ULCustomer WHERE cust_id = ?


Synchronizing products in the CustDB sample

Business rules

The business rules for the ULProduct table are as follows:

  • Products can only be modified at the consolidated database.

  • Each remote database contains all of the products.

Downloads

Product information can be inserted, deleted, or updated at the consolidated database. The script corresponding to these operations is as follows:

  • download_cursor The following download_cursor script downloads all of the rows and columns of the ULProduct table at each synchronization:

SELECT prod_id, price, prod_name FROM ULProduct


Maintaining the customer and order primary key pools

The CustDB sample database uses primary key pools in order to maintain unique primary keys in the ULCustomer and ULOrder tables. The primary key pools are the ULCustomerIDPool and ULOrderIDPool tables.


ULCustomerIDPool

The following scripts are defined in the ULCustomerIDPool table:

Downloads

  • download_cursor The download_cursor script for CustDB is as follows:

    SELECT pool_cust_id FROM ULCustomerIDPool
  WHERE last_modified >= ?
    AND pool_emp_id = ?
Uploads

  • upload_insert The upload_insert script for CustDB is as follows:

    INSERT INTO ULCustomerIDPool ( pool_cust_id ) VALUES( ? )

  • upload_delete The upload_delete script for CustDB is as follows:

    DELETE FROM ULCustomerIDPool WHERE pool_cust_id = ?

  • end_upload This end_upload script ensures that after each upload 20 customer IDs remain in the customer ID pool:

    CALL ULCustomerIDPool_maintain( ? )

    The UL_CustomerIDPool_maintain procedure for CustDB is as follows:

    ALTER PROCEDURE ULCustomerIDPool_maintain ( IN syncuser_id INTEGER )
BEGIN
  DECLARE pool_count INTEGER;
  -- Determine how many ids to add to the pool
  SELECT COUNT(*) INTO pool_count
    FROM ULCustomerIDPool
    WHERE pool_emp_id = syncuser_id;
  -- Top up the pool with new ids
  WHILE pool_count < 20 LOOP
    INSERT INTO ULCustomerIDPool ( pool_emp_id )
      VALUES ( syncuser_id );
    SET pool_count = pool_count + 1;
  END LOOP;
END


ULOrderIDPool

The following scripts are defined in the ULOrderIDPool table:

Downloads

  • download_cursor The download_cursor script for CustDB is as follows:

    SELECT pool_order_id FROM ULOrderIDPool
  WHERE last_modified >= ?
    AND pool_emp_id = ?
Uploads

  • end_upload This end_upload script ensures that after each upload 20 order IDs remain in the order ID pool.

    CALL ULOrderIDPool_maintain( ? )

    The UL_OrderIDPool_maintain procedure for CustDB is as follows:

    ALTER PROCEDURE ULOrderIDPool_maintain ( IN syncuser_id INTEGER )
BEGIN
  DECLARE pool_count INTEGER;
  -- Determine how many ids to add to the pool
  SELECT COUNT(*) INTO pool_count
    FROM ULOrderIDPool
    WHERE pool_emp_id = syncuser_id;
  -- Top up the pool with new ids
  WHILE pool_count < 20 LOOP
    INSERT INTO ULOrderIDPool ( pool_emp_id )
      VALUES ( syncuser_id );
    SET pool_count = pool_count + 1;
  END LOOP;
END

  • upload_insert The upload_insert script for CustDB is as follows:

    INSERT INTO ULOrderIDPool ( pool_order_id ) VALUES( ? )

  • upload_delete The upload_delete script for CustDB is as follows:

    DELETE FROM ULOrderIDPool WHERE pool_order_id = ?


Further reading

The following documentation sections are good starting points for further reading:

For more information about script types, see Script types.

For reference material, including detailed information about each script and its parameters, see Synchronization Events.


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

Version 9.0.2

DC20051-01-0902-01

October 2004

Copyright
About This Manual
Introduction to QAnywhere
Tutorial: A Sample QAnywhere Application
Setting Up QAnywhere Messaging
Writing QAnywhere Client Applications
QAnywhere Agent
Writing Secure Messaging Applications
QAnywhere Transmission Rules
QAnywhere C++ API Reference
iAnywhere.QAnywhere.Client namespace


About This Manual

Subject

This manual describes QAnywhere, which defines a messaging platform for mobile and wireless clients as well as traditional desktop and laptop clients.

Audience

This manual is for users of Adaptive Server Anywhere and other relational database systems who want to add messaging to their mobile applications, or who want to build new mobile application-to-application messaging solutions.


SQL Anywhere Studio documentation

This book is part of the SQL Anywhere documentation set. This section describes the books in the documentation set and how you can use them.

The SQL Anywhere Studio documentation

The SQL Anywhere Studio documentation is available in a variety of forms: in an online form that combines all books in one large help file; as separate PDF files for each book; and as printed books that you can purchase. The documentation consists of the following books:

  • Introducing SQL Anywhere Studio This book provides an overview of the SQL Anywhere Studio database management and synchronization technologies. It includes tutorials to introduce you to each of the pieces that make up SQL Anywhere Studio.

  • What's New in SQL Anywhere Studio This book is for users of previous versions of the software. It lists new features in this and previous releases of the product and describes upgrade procedures.

  • Adaptive Server Anywhere Database Administration Guide This book covers material related to running, managing, and configuring databases and database servers.

  • Adaptive Server Anywhere SQL User's Guide This book describes how to design and create databases; how to import, export, and modify data; how to retrieve data; and how to build stored procedures and triggers.

  • Adaptive Server Anywhere SQL Reference Manual This book provides a complete reference for the SQL language used by Adaptive Server Anywhere. It also describes the Adaptive Server Anywhere system tables and procedures.

  • Adaptive Server Anywhere Programming Guide This book describes how to build and deploy database applications using the C, C++, and Java programming languages. Users of tools such as Visual Basic and PowerBuilder can use the programming interfaces provided by those tools. It also describes the Adaptive Server Anywhere ADO.NET data provider.

  • Adaptive Server Anywhere SNMP Extension Agent User's Guide This book describes how to configure the Adaptive Server Anywhere SNMP Extension Agent for use with SNMP management applications to manage Adaptive Server Anywhere databases.

  • Adaptive Server Anywhere Error Messages This book provides a complete listing of Adaptive Server Anywhere error messages together with diagnostic information.

  • SQL Anywhere Studio Security Guide This book provides information about security features in Adaptive Server Anywhere databases. Adaptive Server Anywhere 7.0 was awarded a TCSEC (Trusted Computer System Evaluation Criteria) C2 security rating from the U.S. Government. This book may be of interest to those who wish to run the current version of Adaptive Server Anywhere in a manner equivalent to the C2-certified environment.

  • MobiLink Administration Guide This book describes how to use the MobiLink data synchronization system for mobile computing, which enables sharing of data between a single Oracle, Sybase, Microsoft or IBM database and many Adaptive Server Anywhere or UltraLite databases.

  • MobiLink Clients This book describes how to set up and synchronize Adaptive Server Anywhere and UltraLite remote databases.

  • MobiLink Tutorials This book provides several tutorials to help you learn MobiLink technology.

  • MobiLink Server-Initiated Synchronization User's Guide This book describes MobiLink server-initiated synchronization, a feature of MobiLink that allows you to initiate synchronization from the consolidated database.

  • QAnywhere User's Guide This manual describes MobiLink QAnywhere, a messaging platform that enables the development and deployment of messaging applications for mobile and wireless clients, as well as traditional desktop and laptop clients.

  • iAnywhere Solutions ODBC Drivers This book describes how to set up ODBC drivers to access consolidated databases other than Adaptive Server Anywhere from the MobiLink synchronization server and from Adaptive Server Anywhere remote data access.

  • SQL Remote User's Guide This book describes all aspects of the SQL Remote data replication system for mobile computing, which enables sharing of data between a single Adaptive Server Anywhere or Adaptive Server Enterprise database and many Adaptive Server Anywhere databases using an indirect link such as e-mail or file transfer.

  • SQL Anywhere Studio Help This book includes the context-sensitive help for Sybase Central, Interactive SQL, and other graphical tools. It is not included in the printed documentation set.

  • UltraLite Database User's Guide This book is intended for all UltraLite developers. It introduces the UltraLite database system and provides information common to all UltraLite programming interfaces.

  • UltraLite Interface Guides A separate book is provided for each UltraLite programming interface. Some of these interfaces are provided as UltraLite components for rapid application development, and others are provided as static interfaces for C, C++, and Java development.

In addition to this documentation set, PowerDesigner and InfoMaker include their own online documentation.

Documentation formats

SQL Anywhere Studio provides documentation in the following formats:

  • Online documentation The online documentation contains the complete SQL Anywhere Studio documentation, including both the books and the context-sensitive help for SQL Anywhere tools. The online documentation is updated with each maintenance release of the product, and is the most complete and up-to-date source of documentation.

    To access the online documentation on Windows operating systems, choose Start > Programs > SQL Anywhere 9 > Online Books. You can navigate the online documentation using the HTML Help table of contents, index, and search facility in the left pane, as well as using the links and menus in the right pane.

    To access the online documentation on UNIX operating systems, see the HTML documentation under your SQL Anywhere installation.

  • PDF books The SQL Anywhere books are provided as a set of PDF files, viewable with Adobe Acrobat Reader.

    The PDF books are accessible from the online books, or from the Windows Start menu.

  • Printed books The complete set of books is available from Sybase sales or from eShop, the Sybase online store, at [external link] http://eshop.sybase.com/eshop/documentation.


Introduction to QAnywhere

About this chapter

QAnywhere is a comprehensive application-to-application messaging system for mobile users. It provides the infrastructure for you to write applications that exchange messages with remote applications located on a variety of devices running on Windows or Windows CE operating systems.


Application-to-application messaging

Application-to-application messaging, including mobile device to mobile device and mobile device to and from the enterprise, permits communication between custom programs running on mobile or wireless devices and a centrally located server application. Messaging is a useful application-to-application communication mechanism in a variety of situations:

  • It provides communication in occasionally-connected environments.

    The store-and-forward nature of messaging means that messages can be constructed even when the destination application is not reachable over the network; the message is delivered when the network becomes available.

    QAnywhere messages are exchanged via a central server, so that the sender and recipient of a message never have to be connected to the network at the same time.

  • It provides network-independent communication.

    QAnywhere messages can be transported over TCP/IP, HTTP, or HTTPS protocols. They can also be delivered from a Windows CE handheld device by ActiveSync. The message itself is independent of the network protocol, and can be received by an application that communicates over a different network.

QAnywhere handles the challenges of wireless networks, such as slow speed, spotty geographic coverage, and dropped network connections. It can protect proprietary or sensitive information by encrypting all messages sent over public networks. You can customize the delivery of messages using transmission rules so that, for example, messages are transmitted at the most convenient times.

QAnywhere compresses and, optionally, encrypts data sent between mobile applications and enterprise servers. Furthermore, it implements a store-and-forward messaging paradigm that guarantees message delivery.

QAnywhere is designed for messaging solutions on a variety of handheld devices. This system provides both a QAnywhere C++ API and a QAnywhere .NET API to provide solutions to developers with different skill sets.

QAnywhere permits seamless communication with other messaging systems that have a JMS interface. This allows integration with J2EE applications.


What QAnywhere does

QAnywhere provides the following application-to-application features and components.

  • Programming API The object-oriented QAnywhere API provides the infrastructure to build messaging applications for Windows desktop and Windows CE devices.

  • Store-and-forward QAnywhere applications store messages in queues until a connection between the client and the server is available for data transmission.

  • Complements data synchronization QAnywhere applications use relational databases as a temporary message store. The relational database ensures that the message store has security, transaction-based computing, and the other benefits of relational databases.

    The use of Adaptive Server Anywhere relational databases as message stores makes it easy to use QAnywhere together with a data synchronization solution. Both use MobiLink synchronization as the underlying mechanism for exchanging information between client and server.

  • Integration with external messaging systems In addition to exchanging messages among QAnywhere applications, you can integrate QAnywhere clients into external messaging systems that support a JMS interface.

  • Encryption Messages can be sent encrypted using a 128-bit encryption key. In addition, messages stores can be encrypted using the AES algorithm.

  • Compression Messages can be stored compressed using the L277 (deflation variant) algorithm. Doing so reduces inflation of compressed data that is sometimes seen with the more common LZW algorithm.

  • Authentication Users can be authenticated using an existing authentication service provided by another application in your organization.

  • Multiple networks QAnywhere works over any wired or wireless network that supports TCP/IP or HTTP.

  • Failover You can run multiple MobiLink synchronization servers so that there are alternate servers in case one fails.

  • Multiple queues Support for multiple arbitrarily-named queues on client devices permits multiple client applications to coexist on a single device. Applications can send and receive on any number of queues. Messages can be sent between applications that are coexisting on the same device and between applications on different devices.

  • Server-initiated send and receive QAnywhere can push messages to client devices, allowing client applications to implement message-driven logic.

  • Rules for managing the message store You can create rules that specify when message transmission should occur, as well as customize the persistence of messages in the message stores.

  • Resumable downloads Large messages or groups of messages are sent to QAnywhere clients in piecemeal fashion to minimize the retransmission of data during network failures.

  • Guaranteed delivery QAnywhere guarantees the delivery of messages once and only once.


QAnywhere architecture

This section explains the architecture of QAnywhere messaging applications. The discussion begins with a simple messaging scenario and then progresses to more advanced scenarios.

Client applications send and receive messages using the QAnywhere programming API. Messages are queued in the client message store. Message transmission is the exchange of messages between client message stores through a central QAnywhere server message store.

Following are typical messaging scenarios that are supported by QAnywhere:

  • Simple messaging For exchanging messages among QAnywhere clients. Client applications control when to transmit messages between the client and server message stores.

    See Simple messaging scenario.

  • Messaging with push notifications For exchanging messages among QAnywhere clients. In this scenario, the QAnywhere server can initiate message transmission between client and server message stores.

    See Scenario for messaging with push notifications.

  • Messaging with external messaging systems For exchanging messages among QAnywhere clients or an external system that supplies a JMS provider, such as BEA WebLogic or Sybase EAServer.

    See Scenario for messaging with external messaging systems.

Push notifications and external messaging systems can be used together, providing the most general solution.


Simple messaging scenario

A simple QAnywhere messaging setup is illustrated in the following diagram. For simplicity, only a single client is shown.

QAnywhere architecture for simple messaging.

This setup includes the following components:

  • Server message store At the server, the messages are stored in a relational database. The database must be set up as a MobiLink consolidated database, and may be any supported consolidated database (Adaptive Server Anywhere, Adaptive Server Enterprise, Microsoft SQL Server, DB2, or Oracle).

  • Client message store The messages at each client are also stored in a relational database. The database used is Adaptive Server Anywhere.

  • MobiLink synchronization server with messaging MobiLink synchronization provides the transport for transmitting and tracking messages between QAnywhere clients and the server. MobiLink provides security, authentication, encryption, and flexibility. It also allows messaging to be combined with data synchronization.

    The MobiLink synchronization server must be started with messaging enabled in order to manage QAnywhere message transmission. You do this by supplying the MobiLink synchronization server -m command line option.

    For more information, see Starting the MobiLink synchronization server for QAnywhere messaging.

  • QAnywhere Agent The QAnywhere Agent manages transmitting messages on the client side.

    For more information, see Running the QAnywhere Agent.

  • QAnywhere client application An application written using the QAnywhere C++ API or the QAnywhere .NET API makes function calls to send and receive messages.

    For information about writing applications using the QAnywhere API, see Writing QAnywhere Client Applications.

Messages are sent and received by the QAnywhere clients. Messages at the server will not be picked up until the client initiates a message transmission. QAnywhere clients use policies to determine when to carry out a message transmission. Policies include on-demand, automatic, scheduled, and custom. The on-demand policy permits the user to control message transmission. The automatic policy initiates a message transmission each time a message at the client is ready for delivery.

For more information, see Determining when message transmission should occur on the client.


Scenario for messaging with push notifications

A push notification is a special message delivered from the server to a QAnywhere client. The push notification occurs when a message arrives at the server message store, and it prompts the client to initiate a message transmission that picks up messages that are ready for the client at the server.

Push notifications introduce two extra components to the QAnywhere architecture. At the server, a QAnywhere Notifier sends push notifications. At the client, a QAnywhere Listener receives these push notifications and passes them on to the QAnywhere Agent.

If you do not use push notifications, messages are still transmitted from the server message store to the client message store, but the transmission must be initiated at the client, such as by using a scheduled transmission.

The architecture for messaging with push notifications is an extension of that described in Simple messaging scenario. It looks like this:

QAnywhere architecture, including push notifications

The components that are added to the Simple messaging scenario in order to enable push notification are as follows:

  • QAnywhere Notifier The Notifier is a component of the MobiLink synchronization server that is used to deliver push notifications.

    The QAnywhere Notifier is a specially configured instance of the Notifier that sends push notifications when a message is ready for delivery.

  • QAnywhere Listener The QAnywhere Listener is a separate process that runs at the client. It receives push notifications and passes them on to the QAnywhere Agent.

See also

For more information, see:

  • Using push notifications
  • Receiving messages asynchronously
  • Introducing Server-Initiated Synchronization


Scenario for messaging with external messaging systems

In addition to exchanging messages among QAnywhere applications, you can exchange messages with systems that have a JMS interface using a specially configured client known as a connector. JMS is the Java Message Service API for adding messaging capabilities to Java applications.

The external messaging system is set up to act like a special client. It has its own address and configuration.

The architecture for messaging with external messaging systems is an extension of that described in Simple messaging scenario. It looks like this:

QAnywhere architecture, including an external messaging system

The component that is added to Simple messaging scenario in order to enable messaging with an external messaging system is as follows:

  • QAnywhere JMS Connector The JMS Connector provides an interface between QAnywhere and the external messaging system.

    The JMS Connector is a special QAnywhere client that moves messages between QAnywhere and the external JMS system.

    See also

    For more information, see:

    • Using JMS Connectors
    • Lesson 6: Start a JMS connector


Quick start

Following are the steps to set up and run a QAnywhere messaging system.

toggle To set up and run QAnywhere messaging

  1. Set up a server message store or use an existing MobiLink consolidated database.

    See Setting up the server message store.

  2. Start the MobiLink synchronization server with the -m option and a connection to the server message store.

    See Starting the MobiLink synchronization server for QAnywhere messaging.

  3. Set up client message stores. These are Adaptive Server Anywhere databases that are used to temporarily store messages.

    See Setting up the client message store.

  4. If you want to integrate with an external JMS messaging system, set up JMS messaging for QAnywhere.

    See Using JMS Connectors.

  5. For each client, write a messaging application.

    See Writing QAnywhere Client Applications.

  6. For each client, start the QAnywhere Agent with a connection to the local client message store.

    See Running the QAnywhere Agent.

Other resources for getting started
  • Tutorial: A Sample QAnywhere Application
  • Sample applications are installed to Samples\QAnywhere in your SQL Anywhere Studio installation directory.


Tutorial: A Sample QAnywhere Application

About this chapter

This tutorial explores the capabilities of QAnywhere through a sample client application named TestMessage. QAnywhere applications can run on many devices, such as PDAs, extending application-to-application messaging to these devices. However, for demonstration purposes, this tutorial runs the client on a Windows personal computer.

About the tutorial
Lesson 1: Start MobiLink with messaging
Lesson 2: Create a client message store
Lesson 3: Run the TestMessage application
Lesson 4: Send a message
Lesson 5: Explore the TestMessage client source code
Lesson 6: Start a JMS connector
Tutorial cleanup


About the tutorial

TestMessage is a sample QAnywhere client application. This application demonstrates how you can use QAnywhere to create your own messaging client applications. TestMessage provides a single client-to-client interface to send, receive, and display messages. Being human-readable, text messages provide a useful demonstration of QAnywhere messaging, but QAnywhere provides much more than text messaging. It is a general purpose application-to-application messaging system that provides message-based communication among many clients.

The tutorial is written for a Windows NT/2000/XP system. While these platforms are convenient for demonstration purposes, you can also use QAnywhere to write applications that run on Windows CE devices.


Lesson 1: Start MobiLink with messaging

Background

QAnywhere uses MobiLink synchronization to send and receive messages. All messages from one client to another are delivered through a central MobiLink synchronization server. The architecture of a typical system, with only two QAnywhere clients, is shown in the following diagram.

The architecture of a QAnywhere system. A QAnywhere Agent on a client device passes messages from one application, via the MobiLink synchronization server, to a second application.

The server message store is a database configured for use as a MobiLink consolidated database. The TestMessage sample uses an Adaptive Server Anywhere consolidated database as its server message store.

The only tables needed in the server message store are MobiLink system tables that are automatically added to any Adaptive Server Anywhere database when it is created. Any supported database that is set up as a MobiLink consolidated database also has these system tables.

The system tables are maintained by MobiLink. Using a relational database as a message store provides a secure, high performance store and means that you can easily integrate messaging into an existing data management and synchronization system.

QAnywhere messaging is usually carried out over separate machines, but in this tutorial all components are running on a single machine. It is important to keep track of which activities are client activities and which are server activities.

In this lesson, you are carrying out actions at the server.

Activity

The MobiLink synchronization server can be started with messaging by supplying the -m option, as well as specifying a connection string to the server message store. The TestMessage sample uses a QAnywhere Adaptive Server Anywhere sample database for the server message store. For the TestMessage sample, you can start the MobiLink synchronization server for messaging using the command line options, or using a sample shortcut in your SQL Anywhere Studio install.

toggle Start the messaging server

  1. From the Windows Start menu, choose Programs > SQL Anywhere 9 > MobiLink > MobiLink with Messaging Sample.

    Alternatively, from a command prompt, navigate to Samples\QAnywhere\server subdirectory of your SQL Anywhere Studio installation and type the following command:

    dbmlsrv9 -m qanyserv.props -c "dsn=QAnywhere 9.0 Sample" -vcrs -zu+

    This example uses the following dbmlsrv9 options:

    Option Description
    -m The -m option enables messaging. It also specifies the file qanyserv.props, which contains some sample messaging property settings.

    See -m option.
    -c The -c option specifies the connection string to the server message store, in this case using the QAnywhere 9.0 Sample ODBC data source.

    See -c option.
    -vcrs The -vcrs option provides verbose logging of server activities, which is useful during development.

    See -v option.
    -zu+ The -zu+ option automatically adds user names to the system; this is convenient for a tutorial or development but is not normally used in a production environment.

    See -zu option.

  2. Move the MobiLink synchronization server window to the left side of your screen, which represents the server machine in this tutorial.

Once the MobiLink synchronization server is started and its console window is displaying the message "Ready to handle requests", you are ready to move on to the next lesson.

Further reading

For more information, see:

  • Starting the MobiLink synchronization server for QAnywhere messaging
  • -m option
  • Quick start
  • Simple messaging scenario


Lesson 2: Create a client message store

Background

The QAnywhere Agent is a component that runs on each client device. It manages the transmission of messages by moving messages between server message stores and client message stores. The client message store is an Adaptive Server Anywhere database.

The QAnywhere Agent is designed to be running at all times when the device is turned on. QAnywhere applications, in contrast, may be launched and shut down at any time.

In this lesson, you are carrying out activities at a client. Typically, clients run on separate machines from the server, but in this lesson you can create them on the same machine.

In this lesson you will create a client message store.

Activity
toggle Create a client message store

  1. Create an Adaptive Server Anywhere database.

    There are several ways to create a database, but in this lesson you will use the dbinit command line utility. Navigate to a directory (for example, c:\sample\qanywhere) and type:

    dbinit -I clientstore.db

    The dbinit -I option causes the database to be smaller, which is better for many remote devices.

  2. Initialize the database as a client message store.

    Type:

    qaagent -si -c "DBF=clientstore.db" -id MyclientID

    This example uses the following options:

    Option Description
    -si The -si option initializes an Adaptive Server Anywhere database for use as a client message store.

    See -si option.
    -c The -c option specifies the connection string to the client message store. The connection string that is supplied specifies the database file name as clientstore.db.

    See -c option.
    -id The -id option specifies an ID for the client message store. Every time you connect to this client message store, you must specify this ID.

    See -id option.

    The QAnywhere Agent automatically shuts down after initializing a client message store.

Further reading

For more information about creating a client message store, see:

  • Initialization utility options
  • Setting up the client message store


Lesson 3: Run the TestMessage application

Background

TestMessage is a simple application that uses QAnywhere to send and receive text messages. Text messaging is used in this tutorial because it provides a simple and accessible demonstration of messaging. QAnywhere is, however, not just a text messaging system; it provides general purpose application-to-application messaging.

In this lesson, you are carrying out activities at a client. Typically, clients run on separate machines from the server.

In this Lesson, you start the client message store that is part of the TestMessage sample. In Lesson 4, you will use this message store to send a message to the client message store that you created in Lesson 2.

Activity
toggle Start the QAnywhere Agent with the TestMessage client message store

  1. From the Windows Start menu, choose Programs > SQL Anywhere Studio 9 > QAnywhere > QAnywhere Agent.

    This starts the TestMessage sample client message store.

  2. The QAnywhere Agent window displays the client message store ID, which by default is your machine name. Make a note of the ID.

  3. Move the QAnywhere Agent window to the right side of your screen, which represents the client machine in this tutorial.

toggle Start TestMessage

  1. From the Windows Start menu, choose Programs > SQL Anywhere 9 > QAnywhere > TestMessage Sample Application.

    The TestMessage window is displayed. The application is connected to the TestMessage client message store that you started in the above procedure.

  2. Move the TestMessage window to the right side of your screen, together with the QAnywhere Agent. Both these components belong on the client.

  3. Set a preferred name and check the message queue.

    From the TestMessage Tools menu, choose Options. Enter a preferred name, which is the name displayed when messages are sent. This name may include spaces.

    You will see that the queue name testmessage is specified. Do not change this name.

Discussion

You will see messages scrolling by in the MobiLink synchronization server window. This shows that the QAnywhere Agent is periodically transmitting messages between the server message store and client message store.

In a production environment there is generally no need for the frequent transmission activity you see in this tutorial. You can configure the way that the QAnywhere Agent monitors messages by setting a message transmission policy on the command line. The default policy setting is scheduled, which instructs the QAnywhere Agent to transmit periodically. If you don't specify an interval, the default is every 10 seconds. Other settings include automatic, which sets the QAnywhere Agent to send messages as soon as they are entered in the client message store, ondemand, which causes a message to be sent only when instructed to by an application, and a custom mode in which you provide a set of rules in a rules file to specify more complicated transmission behavior.

QAnywhere messages are delivered to a QAnywhere address, which consists of a client message store ID and a queue name. The default ID is the machine name on which the QAnywhere Agent is running. Each machine requires only one QAnywhere Agent, even if there are several messaging applications running on the machine. Each application can listen to multiple queues, but each queue should be specific to a single application.

Further reading
  • Running the QAnywhere Agent
  • Determining when message transmission should occur on the client
  • QAnywhere Agent syntax
  • QAnywhere Transmission Rules
  • Writing QAnywhere Client Applications
  • The QAnywhere samples, which are installed to Samples\QAnywhere in your SQL Anywhere Studio directory


Lesson 4: Send a message

Background

The TestMessage sample includes a client message store, which you started in Lesson 3. In addition, you created a client message store in Lesson 2. In this lesson you will send a message from the TestMessage sample store to the client message store that you created in Lesson 2.

Activity
toggle Send a message from TestMessage

  1. From the TestMessage Message menu, choose New. The New Message window appears.

  2. In the To field, enter MyclientID. This is the ID that you specified for the client message store that you created in Lesson 2.

    QAnywhere appends the queue name specified in the Options dialog to the ID to create a message address. If no queue name is specified in the Options dialog, TestMessage appends the queue name testmessage to the address.

  3. Fill out the Subject and Message fields with sample text, and click Send.

    When testing messaging, it is often useful to use the current time as a subject line to make it easy to track individual messages.

  4. Shut down TestMessage and the QAnywhere Agent. You should wait at least 10 seconds before doing this.

    In the TestMessage window, click File > Exit.

    On the QAnywhere Agent window, click Shutdown.

  5. Start the QAnywhere Agent with a connection to the client message store that you created in Lesson 2.

    To do this, navigate to the directory where you created the client message store in Lesson 2 and type:

    qaagent -c "DBF=clientstore.db;eng=qanywhere" -id MyclientID

    This example uses the following options:

    Option | Description
    -c | The connection string in this example connects to the client message store that you created in Lesson 2, called clientstore.db. It specifies eng=qanywhere because the TestMessage sample will attempt to connect to a message store with the database server name qanywhere.
    -id | You need to specify MyclientID as the ID because this is the ID you gave this client message store in Lesson 2.

  6. Start TestMessage.

    From the Windows Start menu, choose Programs > SQL Anywhere 9 > QAnywhere > TestMessage Sample Application.

    Your message appears in the TestMessage window. (If your message does not appear, you probably shut down the application too quickly in Step 4.)

  7. Read the message.

    Select the message to display its contents in the bottom pane of the window.

    The next time you start TestMessage, the message will not appear, as TestMessage is configured to delete messages once you have read them. You can change this default behavior by specifying delete rules.

Discussion

Like other QAnywhere applications, TestMessage uses the QAnywhere API to manage messages. The QAnywhere API is supplied as both a C++ API and as a Microsoft .NET API that can be used by Visual Basic .NET, C#, and C++ applications developed using Microsoft Visual Studio .NET.

Further reading

For more information, see:

  • Understanding QAnywhere message addresses
  • Sending QAnywhere messages
  • Delete rules


Lesson 5: Explore the TestMessage client source code

Background

This section of the tutorial takes you on a brief tour of the source code behind the TestMessage client application.

A good deal of the code implements the Windows interface, through which you can send, receive, and view the messages. This portion of the tutorial, however, focuses on the portions of the code given to QAnywhere.

You can find the TestMessage source code in the Samples\QAnywhere subdirectory of your SQL Anywhere Studio installation.

Several versions of the TestMessage source code are provided. The following versions are provided for Windows 2000 and Windows XP:

  • A C++ version built using the Microsoft Foundation Classes is provided as Samples\QAnywhere\Desktop\MFC\TestMessage\TestMessage.sln.

  • A Visual Basic .NET version built on the .NET Framework is provided as Samples\QAnywhere\Desktop\.NET\VB\TestMessage\TestMessage.sln.

  • A C# version built on the .NET Framework is provided as Samples\QAnywhere\Desktop\.NET\CS\TestMessage\TestMessage.sln.

  • A C++ version built on the .NET Framework is provided as Samples\QAnywhere\Desktop\.NET\CPP\TestMessage\TestMessage.sln.

The following version is provided for Pocket PC:

  • A C# version built on the .NET Compact Framework is provided as Samples\QAnywhere\PocketPC\.NET\CS\TestMessage\TestMessage.sln.

Required software

Visual Studio .NET 2003 is required to open the solution files and build the .NET Framework projects and the .NET Compact Framework project.

Exploring the C# or Visual Basic .NET source

This section takes you through the C# source code. The two versions are structured in a very similar manner.

Rather than look at each line in the application, this lesson picks out certain lines that are particularly useful for understanding QAnywhere applications. It uses the C# version to illustrate particular lines.

  1. Open the version of the TestMessage project that you are interested in.

    Double-click the solution file to open the project in Visual Studio .NET. For example, Samples\QAnywhere\Desktop\.NET\CS\TestMessage\TestMessage.sln is a solution file. There are several solution files for different environments.

  2. Ensure the Solution Explorer is displayed.

    You can open the Solution Explorer from the View menu.

  3. Inspect the Source Files folder.

    There are two files of particular importance. The MessageList file (MessageList.cs) receives messages and lets you view them. The NewMessage file (NewMessage.cs) allows you to construct and send messages.

  4. From the Solution Explorer, open the MessageList file.

  5. Inspect the included namespaces.

    Every QAnywhere application requires the iAnywhere.QAnywhere.Client namespace. The assembly that defines this namespace is supplied as the DLL iAnywhere.QAnywhere.Client.dll, in the ce or win32 subdirectory of your SQL Anywhere Studio installation. For your own projects, you must add this DLL as a reference. The namespace is included using the following line at the top of each file:

    using iAnywhere.QAnywhere.Client;

  6. Inspect the MessageList_Load method.

    This method performs initialization tasks that are common to QAnywhere applications:

    • Create a QAManager object.

      _qaManager =
QAManagerFactory.Instance.CreateQAManager( null );

      QAnywhere provides a QAManagerFactory object to create QAManager objects. The QAManager object handles QAnywhere messaging operations: in particular, receiving messages (getting messages from a queue) and sending messages (putting messages on a queue).

      QAnywhere provides two types of manager: QAManager and QATransactionalManager. The difference is that when using the transactional manager all send and receive operations occur within a transaction, so that either all messages are sent (or received) or none are.

    • Write a method to handle messages.

      The onMessage function that handles regular non-system messages calls the addMessage function. The message it receives is encoded as a QAMessage object. The QAMessage class together with its children (QATextMessage and QABinaryMessage) provide properties and methods that hold all the information QAnywhere applications need about a message.

      private void onMessage(QAMessage msg)
      {
         if( addMessage( msg ) ) {
            String info_msg = _resources.GetString( "MessageReceived" );
            MessageBox.Show( this, info_msg, "Test Message",
               MessageBoxButtons.OK, MessageBoxIcon.Information );
         }
      }

    • Declare a MessageListener.

      _receiveListener = new
    QAManager.MessageListener( onMessage );

      The OnMessage method is called whenever a message is received by the QAnywhere Agent and placed in the queue that the application listens to.

      Message listeners and notification listeners
      Message listeners are different from the Listener component described in Scenario for messaging with push notifications. The Listener component receives notifications, while message listener objects retrieve messages from the queue.

  7. Inspect the startReceiver method in the same file.

    This step assigns message listeners to queues. When you set a message listener for the queue, the QAnywhere Manager will pass messages that arrive on that queue to that listener. Only one listener can be set for a given queue. Setting with a null listener clears out any listener for that queue.

    Using a MessageListener is an asynchronous way of receiving messages. You can also receive messages synchronously; that is, the application explicitly goes and looks for messages on the queue, perhaps in response to a user action such as clicking a Refresh button, rather than being notified when messages appear.

    This method completes the initialization tasks:

    • Open and start the QAManager object.

      _qaManager.Open(
        AcknowledgementMode.EXPLICIT_ACKNOWLEDGEMENT );
_qaManager.Start();

      The AcknowledgementMode enumeration constants determine how the receipt of messages is acknowledged to the sender. The EXPLICIT_ACKNOWLEDGEMENT constant indicates that messages are not acknowledged until a call to one of the QAManager acknowledge methods is made.

    • Load any messages that are waiting in the queue.

      _mainWindow.LoadMessages();

    • Assign a listener to a queue for future messages.

      The listener was declared in the MessageList_Load method.

      _qaManager.SetMessageListener(
     Options.GetReceiveQueueName(),
     _receiveListener );

      The Options.GetReceiveQueueName() function returns the string testmessage, which is the TestMessage queue as set in the TestMessage Options dialog.

  8. Inspect the addMessage function in the same file.

    This method is called whenever the application receives a message. It gets properties of the message such as its ReplyToAddress, PreferredName, and the time it was sent (Timestamp), and displays the information in the TestMessage user interface. Here are the lines that cast the incoming message into a QATestMessage object and get the ReplyToAddress of the message:

    text_msg = ( QATextMessage )msg;
from = text_msg.ReplyToAddress;

    This completes a brief look at some of the major tasks carried out in the MessageList file.

  9. From the Solution Explorer, open the NewMessage file.

  10. Inspect the sendMessage function.

    This function takes the information entered in the New Message dialog and constructs a QATextMessage object. The QAManager then puts the message in the queue to be sent.

    Here are the lines that create a QATextMessage object and set its ReplyToAddress property:

    qa_manager = MessageList.GetQAManager();
msg = qa_manager.CreateTextMessage();
msg.ReplyToAddress = Options.GetReceiveQueueName();

    Here are the lines that put the message in the queue to be sent. The variable to is the destination address, supplied as an argument to the function.

    to = BuildQueue( to );
qa_manager.PutMessage( to, msg );
Further reading

For more information, see:

  • QAnywhere C++ API Reference
  • iAnywhere.QAnywhere.Client namespace
  • Writing QAnywhere Client Applications
  • The TestMessage sample, which is installed to Samples\QAnywhere in your SQL Anywhere Studio directory


Lesson 6: Start a JMS connector

A JMS connector provides connectivity between a JMS message system and QAnywhere.

Required software

For this lesson, you need access to a JMS provider and basic knowledge of how to configure it. In addition, you need JDK version 1.3.1 or later and any JAR files required by a JMS client of the JMS provider.

Activity
toggle Prepare your JMS provider

  1. Start your JMS server.

    See the documentation for your JMS server.

  2. Create two queues within your JMS server: qa_testmessage and qa_receive.

    See the documentation for your JMS server. You may need to restart your JMS server after creating the queues.

toggle Start QAnywhere client and server compnents

  1. Create a QAnywhere connector properties file.

    There are sample connector properties files in the Samples\QAnywhere\connectors subdirectory of your SQL Anywhere Studio installation.

  2. Specify your QAnywhere connector properties file in the file Samples\QAnywhere\server\qanyserv.props.

    This sample file contains commented lines that specify the sample connector properties files. You may just need to uncomment one of these lines.

  3. Start the MobiLink synchronization server for messaging, as described in Lesson 1: Start MobiLink with messaging.

  4. Start QAnywhere Agent as described in Lesson 2: Create a client message store.

  5. Start TestMessage as described in Lesson 3: Run the TestMessage application.

toggle Start the TestMessage client

  1. At a command prompt, navigate to Samples\QAnywhere\connectors\JMS\TestMessage and type the following:

    java -cp .;JMS-client-jar-files ianywhere.message.samples.TestMessage

    where JMS-client-jar-files is a semi-colon delimited list of jar files that the JMS server requires. See your JMS server documentation for details. For Sybase EAServer, this command would be:

    java -cp .; path\easclient.jar;path\easj2ee.jar ianywhere.message.samples.TestMessage

    where path is the location of the jar files.

  2. Move the JMS TestMessage window to the right side of your screen under the existing TestMessage window.

  3. From the JMS TestMessage Message menu, choose New.

    The New Message window appears.

  4. In the To field, enter the client message store ID that you noted in Lesson 2.

  5. Fill out the Subject and Message fields with sample text, and click Send.

    Within a short time a message box appears, indicating that a message has been received by the previously running instance of TestMessage.

  6. Switch to the other instance of TestMessage to receive the message.

Further reading

For more information, see:

  • Using JMS Connectors
  • Scenario for messaging with external messaging systems
  • The JMS sample properties files and other JMS samples that are installed to Samples\QAnywhere\connectors in your SQL Anywhere Studio directory


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

Tutorial: A Sample QAnywhere Application

Tutorial cleanup

Shut down TestMessage, the QAnywhere Agent, and the MobiLink synchronization server.


Setting Up QAnywhere Messaging

About this chapter

This chapter describes how to set up and run QAnywhere messaging.

QAnywhere uses MobiLink synchronization to transport messages. This chapter describes how to set up and run the MobiLink synchronization server with messaging.

Setting up server-side components
Setting up client-side components
Using push notifications
Using JMS Connectors
Using QAnywhere messaging and MobiLink data synchronization together
Setting up a failover mechanism


Setting up server-side components

toggle Overview of setting up QAnywhere server-side components

  1. Set up a server message store and start it. This can be any MobiLink consolidated database.

    See Setting up the server message store.

  2. Start dbmlsrv9 with the -m option and a connection to the server message store.

    See Starting the MobiLink synchronization server for QAnywhere messaging.

  3. Add client message store IDs to the server message store.

    See Adding client message store IDs.


Setting up the server message store

The server message store is a relational database on the server that temporarily stores messages until they are transmitted to a client message store or JMS system. Messages are exchanged between clients via the server message store.

A server message store is a MobiLink consolidated database, and so can be any RDBMS that MobiLink supports (Adaptive Server Anywhere, Adaptive Server Enterprise, Microsoft SQL Server, Oracle, or DB2). You can create a new database for this purpose, or use an existing database. The database does not need to be dedicated to acting as a server message store and so can also be used for other purposes.

Adaptive Server Anywhere databases are automatically configured so that they can be used as consolidated databases.

For information about creating Adaptive Server Anywhere databases, see The Initialization utility.

If you are using an Adaptive Server Anywhere database that was created before version 9.0.2, it must be upgraded.

To upgrade your database, see Upgrading Software and Databases.

For databases other than Adaptive Server Anywhere, you need to run a setup script that enables the database to be used as a consolidated database (if you have not already done so).

To set up a server message store for databases other than Adaptive Server Anywhere, see Setting up a consolidated database.

Notes

  • You can integrate messaging with MobiLink synchronization applications by using your MobiLink consolidated database as the server message store.

    See Using QAnywhere messaging and MobiLink data synchronization together.

Example

To create an Adaptive Server Anywhere database called qanysrv.db, type the following at a command prompt:

dbinit qanysrv.db

This database is ready to use as a server message store.


Starting the MobiLink synchronization server for QAnywhere messaging

QAnywhere uses MobiLink synchronization to transport messages. To use QAnywhere messaging, you must start the MobiLink synchronization server (dbmlsrv9) with the following options:

  • -c connection-string To connect to the server message store.

    See -c option.

  • -m To enable QAnywhere messaging. The -m option also allows you to optionally specify configuration information.

    See -m option.

  • -zu+ Optionally, you may want to specify -zu+ while in development mode. When you create client message stores, the client message store ID must be added to the consolidated database, and -zu+ allows this to happen automatically.

    See -zu option.

You can also use other MobiLink synchronization server options to customize your operations. For more information, see MobiLink synchronization server.

Notes

  • If you are integrating with a JMS messaging system, there are other options you must specify when you start the MobiLink synchronization server.

    See Starting the MobiLink server for JMS integration.

Example

To start QAnywhere messaging when you are using a server message store called qanysrv.db, type the following at a command prompt:

dbmlsrv9 -m -c "dbf=qanysrv.db"


Adding client message store IDs

Each client message store has a unique ID that identifies it. The client message store ID is a MobiLink user name. You may need to add this MobiLink user name to the server message store. There are several methods for doing this:

  • Use the dbmluser utility.

    For more information, see MobiLink user authentication utility.

  • Use Sybase Central.

  • Specify the -zu+ command line option with dbmlsrv9. In this case, any existing MobiLink users that have not been added to the consolidated database are added when they first synchronize. This is useful during development, but is not recommended for production environments.

    For more information, see -zu option.

For more information about MobiLink user names, see About MobiLink users.

For more information about client message store IDs, see -id option.


Setting up client-side components

toggle Overview of setting up client-side components

  1. Create an Adaptive Server Anywhere database and initialize it as a client message store.

    See Setting up the client message store.

  2. Ensure that the ID of the client message store is registered on the server message store.

    See Adding client message store IDs.

  3. Write client applications.

    See Writing QAnywhere Client Applications.

  4. Start the QAnywhere Agent.

    See Running the QAnywhere Agent.


Setting up the client message store

The client message store is an Adaptive Server Anywhere database on the remote device. The application connects to this message store using the QAnywhere client API.

The database that you use for the client message store must not be used by any other non-messaging applications. However, you can use a MobiLink remote database in conjunction with a client message store to integrate messaging with data synchronization.

Using a relational database as a message store provides a secure and high-performance store, and also enables easy integration of messaging with data synchronization.

For more information, see Using QAnywhere messaging and MobiLink data synchronization together and Creating a secure client message store.

toggle To create a client message store

  1. Create an Adaptive Server Anywhere database.

    See Creating a database.

  2. Initialize each client message store by running the QAnywhere Agent (qaagent) with the following options:

    • -c option to specify a connection string to the database you just created.

      See -c option.

    • -si option to initialize the database.

      See -si option.

    • -id option optionally, if you want to pre-assign a client message store ID.

      See Creating client message store IDs and -id option.

  3. Add client message store IDs to the server message store. This can be done automatically using the dbmlsrv9 -zu+ option, or can be done in other ways.

    See Adding client message store IDs.

  4. Change the default passwords and take other steps to ensure that the client message store is secure.

    See Creating a secure client message store.

You can also upgrade a client message store that was created in a previous version of QAnywhere.

See -su option.

Creating client message store IDs

Client message store IDs can be set in various ways:

  • You can specify the ID with the qaagent -id option when you use the qaagent -si option to initialize the client message store.

  • You can specify the ID with the -id option the first time you run qaagent after you initialize the client message store.

  • If you do not specify an ID in either of the previous ways, then the first time you run qaagent after you run qaagent with -si, the device name is assigned as the client message store ID.

For more information, see QAnywhere Agent.

Example of creating a client message store

The following command creates an Adaptive Server Anywhere database called qanyclient.db. (The dbinit -i option is not required, but is good practice as it reduces the size of the database.)

dbinit -i qanyclient.db

The following command connects to qanyclient.db and initializes it as a QAnywhere client database:

qaagent -si -c "DBF=qanyclient.db"

For more information about dbinit, see Creating a database using the dbinit command-line utility.


Running the QAnywhere Agent

The QAnywhere Agent (qaagent) is a separate process running on the client device that monitors the client message store and determines when message transmission should occur.

The QAnywhere Agent transmits messages between the server message store and the client message store. You can run only one instance of the QAnywhere Agent on a device at a time.

At a minimum, you need to start qaagent with the following options:

  • -c "connection-string" to connect to the client message store.

  • -id client-message-store-id to identify the client message store. The first time you run qaagent after you have initialized a client message store, you can optionally use this option to name the message store; if you do not, the device name is used by default. After that, you must use the -id option every time you start qaagent to specify the client message store ID.

  • -x protocol[ (protocol-options) ] to connect to the MobiLink synchronization server (necessary unless the MobiLink synchronization server is running on the same device as the QAnywhere agent).

For details of these options as well as a complete list of all qaagent options, see QAnywhere Agent syntax.

Determining when message transmission should occur on the client


Determining when message transmission should occur on the client

On the client side, you determine when message transmission should occur by specifying policies. A policy tells the QAnywhere Agent when a message should be moved from the client message store to the server message store. If you do not specify a policy, transmission occurs every 10 seconds by default. There are three pre-defined policies: scheduled, automatic and on-demand. These policies are specified using the qaagent -policy option.

You can also define a custom policy. A custom policy is a set a rules that determine when a message transmission is to occur. In addition, a custom policy can specify which messages should be transmitted. A custom policy is used when a file containing the transmission rules is specified using the -policy option.

Scheduled policy

The scheduled policy instructs the Agent to perform a transmission at a specified time interval. To invoke a schedule, use the scheduled keyword when you start the QAnywhere Agent:

qaagent –policy scheduled [ interval ] ...

where interval is in seconds. The default is 10 seconds.

When a schedule is specified, every n seconds the Agent performs a message transmission if any of the following conditions are met:

  • New messages were placed in the client message store since the previous time interval elapsed.

  • A message status change occurred since the previous time interval elapsed. This typically occurs when a message is acknowledged by the application.

  • A push notification was received since the previous time interval elapsed.

  • A network status change notification was received since the previous time interval elapsed.

  • Push notifications are disabled.

You can call the TriggerSendReceive() method to override the time interval. It forces a message transmission to occur before the time interval elapses.

Automatic policy

The automatic policy attempts to keep the client and server message stores as up-to-date as possible. To set up automatic message transmission, use the automatic keyword when you start the QAnywhere Agent:

qaagent –policy automatic

When using the automatic policy, a message transmission will be performed when any of the following occurs:

  • PutMessage() is called.

  • A message status change has occurred. This typically occurs when a message is acknowledged by the application.

  • A Push Notification is received.

  • A Network Status Change Notification is received.

  • TriggerSendReceive() is called.

On-demand policy

The on-demand policy causes a message transmission to occur only when instructed to do so by an application. To start this mode, use the ondemand keyword when you start the QAnywhere Agent:

qaagent –policy ondemand

An application forces a message transmission to occur by calling the TriggerSendReceive() method.

When the agent receives a Push Notification or a Network Status Change Notification, a corresponding message is sent to the "system" queue. This allows an application to detect these events and force a message transmission by calling the TriggerSendReceive() method.

Custom policy

A custom policy allows you to define when a message transmission is to occur and which messages are sent in the message transmission. The custom policy is defined by a set of rules stored in a file. To define a custom policy, specify a rules file when you start the QAnywhere Agent:

qaagent –policy rules-file

Each rule is of the following form:

schedule = condition

where schedule defines when condition is evaluated. For more information, see Schedule syntax.

All messages satisfying condition are transmitted. In particular, if schedule is automatic, the condition is evaluated when any of the following occurs.

  • PutMessage() is called.

  • A message status change has occurred. This typically occurs when a message is acknowledged by the application.

  • A Push Notification is received.

  • A Network Status Change Notification is received.

  • TriggerSendReceive ( ) is called.

For more information about specifying a custom policy in a rules file, see Transmission rules.

For more information about creating policies, see -policy option.


Using push notifications

A push notification is a special message delivered from the server to a QAnywhere client that prompts the client to initiate a message transmission. Push notifications introduce two extra components to the QAnywhere architecture:

  • At the server, a QAnywhere Notifier sends push notifications.

  • At the client, a QAnywhere Listener receives these push notifications and passes them on to the QAnywhere Agent.

Notification is enabled by default: the qaagent -push_notification option is by default set to enabled. Push notifications are delivered either over the UDP protocol or as SMS messages.

If you are using UDP, push notifications will probably work without any configuration, but due to a limitation in the UDP implementation of ActiveSync, they will not work with ActiveSync.

If you are using SMS, you need to start a Listener to use notifications. For more information, see Using push notifications with SMS.

To disable push notifications, see -push_notifications option.

See also

For more information about push notifications, see:

  • Scenario for messaging with push notifications
  • Handling push notifications and network status changes
  • -push_notifications option
  • Using push notifications with SMS

Using push notifications with SMS


Using push notifications with SMS

You can use QAnywhere notifications when your message transmission is occurring over SMS, but you must start a Listener using the dblsn executable.

For more information, see Listeners.

Start the QAnywhere Agent as you normally would:

qaagent -id device-id -c "connect-string"

On the server side, set SMTP properties that are required to send SMS messages.

For more information, see SMTP gateway properties.


Using JMS Connectors

JMS is the Java Message Service API for adding messaging capabilities to Java applications. In addition to exchanging messages among QAnywhere client applications, you can exchange messages with external messaging systems that support a JMS interface. You do this using a specially configured client known as a connector. In a QAnywhere application, the external messaging system is set up to act like a QAnywhere client. It has its own address and configuration.

For more information about the architecture of this approach, see Scenario for messaging with external messaging systems.

toggle Overview of integrating a QAnywhere application with an external JMS system

  1. Create JMS queues using the JMS administration tools for your JMS system. The QAnywhere connector listens on a single JMS queue for JMS messages. You must create this queue if it does not already exist.

    See the documentation of your JMS product for information about how to create queues.

  2. Create a JMS connector properties file and set the ianywhere.connector.address property to specify the connector address. This is the address used by QAnywhere applications to send messages through the connector.

    See Configuring the JMS connector properties file.

  3. Create a MobiLink messaging properties file and set the ianywhere.qa.server.connectorPropertiesFiles property to the name of the JMS connector properties file.

    For more information about specifying a Mobilink messaging properties file, see -m option.

  4. Start the MobiLink synchronization server with a connection to the server message store and the options -m and -sl java. The MobiLink messaging properties file you created in the previous step is referenced by the -m option.

    See Starting the MobiLink server for JMS integration.

  5. To send a message from an application in your QAnywhere system to the external messaging system, create a QAnywhere message and send it to connector-address\JMS-queue.

    See Addressing QAnywhere messages meant for JMS.

  6. To send a message from the external messaging system to an application in your QAnywhere system, create a JMS message, set the ias_ToAddress property to the QAnywhere id\queue (where id is the ID of your client message store and queue is your application queue name), put the message in the JMS queue and use the Send operation.

    See Addressing JMS messages meant for QAnywhere.

Starting the MobiLink server for JMS integration
Configuring the JMS connector properties file
Addressing QAnywhere messages meant for JMS
Addressing JMS messages meant for QAnywhere


Starting the MobiLink server for JMS integration

To exchange messages with an external messaging system that supports a JMS interface, you must start the MobiLink synchronization server (dbmlsrv9) with the following options:

  • -c connection-string To connect to the server message store.

    See -c option.

  • -m message-properties-file The message-properties-file must define an ianywhere.qa.server.connectorPropertiesFiles property that specifies a JMS Connector properties file or files. The message properties file should contain the following statement:

    ianywhere.qa.server.connectorPropertiesFiles=file1;[ file2; ]...

    See -m option.

  • -sl java (-cp "jarfile.jar") To add the client jar files required to use the external JMS provider.

    See -sl java option.

Example

The following example starts a MobiLink synchronization server using a message properties file called msg.props (in the current working directory), a JMS client library called jmsclient.jar (also in the current working directory), and the QAnywhere 9.0 Sample database as a message store. The command should be entered all on one line.

dbmlsrv9 -sl java(-cp "jmsclient.jar")
         -m msg.props
         -c "QAnywhere 9.0 Sample" ...


Configuring the JMS connector properties file

The JMS Connector properties file contains entries that specify connection information with the JMS system. It configures a connector to a third party JMS messaging system such as BEA WebLogic or Sybase EAServer.

The following properties are used to configure the JMS Connector.

  • ianywhere.connector.nativeConnection The Java class that implements the connector. This Java class is provided by QAnywhere and should always be set to ianywhere.message.connector.jms.NativeConnectionJMS.

  • ianywhere.connector.id An identifier that uniquely identifies the connector. This identifier is also used to prefix all logged error, warning, and informational messages appearing in the QAnywhere server console for this connector.

  • ianywhere.connector.address The connector address that a QAnywhere client should use to address the connector.

    For more information, see Addressing QAnywhere messages meant for JMS.

  • ianywhere.connector.outgoing.deadMessageAddress The address that a message is sent to when it cannot be processed. For example, if a message contains an address that is malformed or unknown, the message is sent to the dead message address.

    The default dead message address is ianywhere.connector.deadMessage.

  • ianywhere.connector.logLevel The amount of connector information displayed in the console and log file. Values for the log level are as follows:

    • 1 Log error messages.

    • 2 Log error and warning messages.

    • 3 Log error, warning, and information messages.

    • 4 Debug mode: provide most verbose logging.

  • ianywhere.connector.compressionLevel The default message compression factor of messages received from JMS: an integer between 0 and 9, with 0 indicating no compression and 9 indicating maximum compression.

    You can set the compression level for all connectors using the ianywhere.qa.compressionLevel property in the configuration file that you supply with the dbmlsrv9 -m option. If you set the compression level in both places, this setting for an individual connector overrides the setting for all connectors. For more information, see -m option.

  • xjms.jndi.authName The authentication name to connect to the external JMS JNDI name service.

  • xjms.jndi.factory The factory name used to access the external JMS JNDI name service.

  • xjms.jndi.password.e The authentication password to connect to the external JMS JNDI name service.

  • xjms.jndi.url The URL to access the JMS JNDI name service.

  • xjms.password.e The authentication password to connect to the external JMS provider.

  • xjms.queueFactory The external JMS provider queue factory name.

  • xjms.queueConnectionAuthName The user ID to connect to the external JMS queue connection.

  • xjms.queueConnectionPassword.e The password to connect to the external JMS queue connection.

  • xjms.topicFactory The external JMS provider topic factory name.

  • xjms.topicConnectionAuthName The used ID to connect to the external JMS topic connection.

  • xjms.topicConnectionPassword.e The password to connect to the external JMS topic connection.

  • xjms.receiveDestination The queue name used by the connector to listen for messages from JMS targeted for QAnywhere clients.

Example

You can find sample connector property files in the Samples\QAnywhere\connectors subdirectory of your SQL Anywhere Studio installation. Here is a sample properties file for Sybase EAServer:

ianywhere.connector.nativeConnection=ianywhere.message.connector.jms.NativeConnectionJMS
ianywhere.connector.id=easerver
ianywhere.connector.logLevel=4
ianywhere.connector.address=ianywhere.connector.easerver
xjms.jndi.factory=com.sybase.jms.InitialContextFactory
xjms.jndi.url=iiop://<substitute with host name>:9000
xjms.jndi.authName=jagadmin
xjms.jndi.password.e=
xjms.topicFactory=javax.jms.TopicConnectionFactory
xjms.topicConnectionAuthName=
xjms.topicConnectionPassword.e=
xjms.queueFactory=javax.jms.QueueConnectionFactory
xjms.queueConnectionAuthName=
xjms.queueConnectionPassword.e=
xjms.receiveDestination=qanywhere

Configuring multiple connectors


Configuring multiple connectors

QAnywhere can connect to multiple JMS message systems by defining a JMS connector file for each JMS system. Each connector to a JMS message system must be configured using its own JMS Connector properties file. The only property values that must be unique among the configured connectors are ianywhere.connector.id and ianywhere.connector.address.

  • The ianywhere.connector.id property must be unique. It is used to prefix all connector messages in the QAnywhere server console.

  • The ianywhere.connector.address property is the address prefix that QAnywhere clients must specify to address messages meant for the JMS system.

    For information about specifying the address of QAnywhere clients, see Addressing QAnywhere messages meant for JMS.

For information about the connector properties file, see Configuring the JMS connector properties file.


Addressing QAnywhere messages meant for JMS

A QAnywhere client can send a message to a JMS system by setting the address to connector_address\JMS_destination. The connector_address is the value of the connector property ianywhere.connector.address, while JMS_destination is the name used to look up the JMS queue or topic using the Java Naming and Directory Interface.

For more information, see Understanding QAnywhere message addresses.

Example

For example, if the ianywhere.connector.address is set to ianywhere.connector.easerver and the JMS queue name is myqueue, then the code to set the address would be:

C#
QAManagerBase mgr;
QAMessage msg;
// Initialize the manager
...
msg = mgr.CreateTextMessage();
// Set the message content
...
mgr.PutMessage(@"ianywhere.connector.easerver\myqueue", msg );
C++
QAManagerBase *mgr;
QATextMessage *msg;
// Initialize the manager
...
msg = mgr.createTextMessage();
// Set the message content
...
mgr->putMessage( "ianywhere.connector.easerver\\myqueue", msg );


Mapping QAnywhere messages on to JMS messages

QAnywhere messages are mapped naturally on to JMS messages.

QAnywhere message content
QAnywhere | JMS | Remarks
QATextMessage | javax.jms.TextMessage | message text copied as Unicode
QABinaryMessage | javax.jms.BytesMessage | message bytes copied exactly
QAnywhere built-in headers

The following table describes the mapping of built-in headers. In C++ and JMS, these are method names; for example, Address is called getAddress or setAddress for QAnywhere, and getJMSDestination or setJMSDestination for JMS. In .NET, these are properties with the exact name given below; for example, Address is Address.

QAnywhere | JMS | Remarks
Address | JMS Destination and JMS property ias_ToAddress | Only the JMS part of the address is mapped to the Destination. Under rare circumstances, in the case of a message looping back into QAnywhere, there may be an additional QAnywhere address suffix. This is put in ias_ToAddress.
Expiration | JMS Expiration |
InReplyToID | JMS CorrelationID |
MessageID | N/A | Not mapped.
Priority | JMS Priority |
Redelivered | N/A | Not mapped.
ReplyToAddress | JMS property ias_ReplyToAddress | Mapped to JMS property.
Connector's xjms.receiveDestination property value | JMS ReplyTo | ReplyTo set to Destination used by connector to receive JMS messages.
Timestamp | N/A | Not mapped.


QAnywhere properties

QAnywhere properties are all mapped naturally to JMS properties, preserving type, with one exception. If the QAnywhere message has a property called JMSType, then this is mapped to the JMS header property JMSType.


Addressing JMS messages meant for QAnywhere

A JMS client can send a message to a QAnywhere client by setting the JMS message property ias_ToAddress to the QAnywhere address, and then sending the message to the JMS Destination corresponding to the connector property xjms.receiveDestination.

For more information, see Understanding QAnywhere message addresses.

Example

For example, to send a message to the QAnywhere address "qaddr" (where the connector setting of xjms.receiveDestination is "ianywhere.connector.jms_receive"):

import javax.jms.*;
...
try {
  QueueSession session;
  QueueSender sender;
  TextMessage mgr;
  Queue connectorQueue;
  // Initialize the session
  ...
  connectorQueue = session.createQueue( "ianywhere.connector.jms_receive" );
  sender = session.createSender( connectorQueue );
  msg = session.createTextMessage();
  msg.setStringProperty( "ias_ToAddress", "qaddr" );
  // Set the message content
  ...
  sender.send( msg );
  } catch( JMSException e ) {
    // Handle the exception
  ...
}


Mapping JMS messages on to QAnywhere messages

QAnywhere messages are mapped naturally on to JMS messages.

JMS message content
JMS | QAnywhere | Remarks
javax.jms.TextMessage | QATextMessage | Message text copied as Unicode
javax.jms.BytesMessage | QABinaryMessage | Message bytes copied exactly
javax.jms.StreamMessage | N/A | Not supported
javax.jms.MapMessage | N/A | Not supported
javax.jms.ObjectMessage | N/A | Not supported
JMS built-in headers

The following table describes the mapping of built-in headers. In C++ and JMS, these are method names; for example, Address is called getAddress or setAddress for QAnywhere, and getJMSDestination or setJMSDestination for JMS. In .NET, these are properties with the exact name given below; for example, Address is Address.

JMS | QAnywhere | Remarks
JMS Destination | N/A | The JMS destination must be set to the queue specified in the connector property ianywhere.connector. jms_receive.
JMS Expiration | Expiration |
JMS CorrelationID | InReplyToID |
JMS MessageID | N/A | Not mapped.
JMS Priority | Priority |
JMS Redelivered | N/A | Not mapped.
JMS ReplyTo and connector's ianywhere.connector.address property value | ReplyToAddress | The connector address is concatenated with the JMS ReplyTo Destination name delimited by '\'.
JMS DeliveryMode | N/A | Not mapped.
JMS Type | QAnywhere message property JMSType |
JMS Timestamp | N/A | Not mapped.


JMS properties

JMS properties are all mapped naturally to QAnywhere properties, preserving type, with a few exceptions. The QAnywhere Address property is set from the value of the JMS message property ias_ToAddress. If the JMS message property ias_ReplyToAddress is set, then the QAnywhere ReplyToAddress is additionally suffixed with this value delimited by a '\'.


Using QAnywhere messaging and MobiLink data synchronization together

You can integrate QAnywhere messaging into MobiLink synchronization applications that use Adaptive Server Anywhere clients.

To do this,

  • The QAnywhere client message store database and the database used by the data synchronization application must be different database files. However, for efficiency on small devices, you can run both databases on the same database server.

  • You must use your MobiLink consolidated database as the server message store. This can be any supported MobiLink consolidated database (Adaptive Server Anywhere, Adaptive Server Enterprise, Oracle, DB2, or Microsoft SQL Server).

  • You can create a separate QAnywhere messaging application or integrate messaging into your data synchronization application.

Example

The following example integrates QAnywhere messaging into a MobiLink synchronization system that has a server named MyServer and an Adaptive Server Anywhere client database file called MyAppData.db.

Create the client message store database:

dbinit -i MyAppData.db

Initialize the client message store:

qaagent -id MyID -si -c "dbf=MyAppData.db"

Start the database server on the remote device with the MyAppData.db and qanywhere.db database files.

dbsrv9 -n MyServer MyAppData.db -n MyAppData qanywhere.db -n qanywhere

Start the QAnywhere Agent, using qanywhere.db as the message store:

qaagent -id MyID -c "eng=MyServer;dbn=qanywhere"

When creating a QAManager instance, use a QAManager properties file that includes the following line:

CONNECT_PARAMS=eng=MyServer;dbn=qanywhere

You can then start the MobiLink synchronization server just as you would for any other QAnywhere messaging application, but use your MobiLink consolidated database as the server message store. For example:

dbmlsrv9 -m -c "dbf=your_consolidated.db"


Setting up a failover mechanism

QAnywhere applications can be set up with failover mechanisms, such that there are alternate MobiLink synchronization servers that can be used if one fails. In order to support failover, each QAnywhere Agent must be started with a list of MobiLink servers. The first MobiLink server specified in the list is the primary server. The remaining servers in the list are alternate servers.

For example, running the following command on the remote device will start the QAnywhere Agent with one primary server and one alternate server:

qaagent –x tcpip(host=ml1.ianywhere.com)
        –x tcpip(host=ml2.ianywhere.com)

Each QAnywhere Agent can have a different primary server.

The following diagram describes a failover configuration in which you have multiple MobiLink servers and multiple QAnywhere agents. You have multiple client message stores, but all MobiLink servers are connected to the same server-side message store.

The server message store communicates with the client messages stores via MobiLink servers and remote agents.

This configuration has the following characteristics:

  • When a message transmission occurs, all messages in the server message store will be delivered to the client message store regardless of the server that the QAnywhere Agent is connected to.

  • Push Notifications will be sent to a QAnywhere Agent only when the QAnywhere Agent is connected to its primary server.

  • There is a single point of failure. If the machine with the server message store is unavailable, no messaging can take place.


Writing QAnywhere Client Applications

About this chapter

This chapter describes how to use the QAnywhere API. The API is provided both as a C++ API and as the iAnywhere.QAnywhere.Client namespace.

Introduction
Overview of writing a client application
Understanding QAnywhere message addresses
Initializing the QAnywhere client API
Setting QAManager properties
Sending QAnywhere messages
Receiving messages synchronously
Receiving messages asynchronously
Reading very large messages
Handling push notifications and network status changes
Implementing transactional messaging
Shutting down QAnywhere
Deploying QAnywhere applications


Introduction

QAnywhere client applications manage the receiving and sending of QAnywhere messages. The applications can be written using one of the following programming interfaces:

  • QAnywhere .NET API A programming interface for deployment to Windows computers using the Microsoft .NET Framework and to handheld devices running the Microsoft .NET Compact Framework. The QAnywhere .NET API is provided as the iAnywhere.QAnywhere.Client namespace.

    QAnywhere supports Microsoft Visual Studio 2003.

    In this chapter, code samples for the .NET API use the C# programming language, but the API can be used from any programming language supported by Microsoft .NET.

    Versions of the TestMessage sample application written in C#, Visual Basic .NET, and managed C++ are all supplied. For more information, see Lesson 5: Explore the TestMessage client source code.

    For more information about the QAnywhere .NET API, see iAnywhere.QAnywhere.Client namespace.

  • QAnywhere C++ API A programming interface for deployment to Windows computers. This interface is for programmers using C++.

    QAnywhere supports Microsoft Visual C++ 6.0, Microsoft Visual Studio .NET 2003, Microsoft eMbedded Visual C++ 3.0, and Microsoft eMbedded Visual C++ 4.0.

    The QAnywhere C++ API consists of the following:

    • A set of header files (the main one being qa.hpp) located in the QAnywhere\h subdirectory of your SQL Anywhere Studio installation.

    • An import library (qany9.lib) located in the QAnywhere\ce\arm.30\lib, QAnywhere\lib, and QAnywhere\ce\x86.30\lib subdirectories of your SQL Anywhere Studio installation.

    • A run-time DLL (qany9.dll) located in the win32, ce\arm.30, and ce\x86.30 subdirectories of your SQL Anywhere Studio installation.

    Your source code file must include the header file in order to access the API. The import library is used to link your application to the run-time DLL. The run-time DLL must be deployed with your application.

    A version of the TestMessage sample application written in C++ is supplied in the Samples\QAnywhere subdirectory of your SQL Anywhere Studio installation. For more information, see Lesson 5: Explore the TestMessage client source code.

    For more information about the C++ API, see QAnywhere C++ API Reference.


Overview of writing a client application

toggle To build a client application (C++ or .NET)

  1. Initialize the QAnywhere client API.

    See Initializing the QAnywhere client API.

  2. Set QAManager properties.

    See Setting QAManager properties.

  3. Write application code and compile. See:

    • Sending QAnywhere messages

    • Receiving messages synchronously

    • Receiving messages asynchronously

    • Reading very large messages

    • Handling push notifications and network status changes

    • Implementing transactional messaging

    • Shutting down QAnywhere

  4. Deploy the application to the target device.

    See Deploying QAnywhere applications.


Understanding QAnywhere message addresses

A QAnywhere message destination has two parts:

  • The client message store ID.

    For information about client message store IDs, see Setting up the client message store.

  • The application queue name.

    The queue name is specified inside the application, and must be known to instances of the sending application on other devices.

The form of the destination address is:

id\queue-name
Escape characters and addresses
When constructing addresses as strings in an application, be sure to escape the backslash character if necessary. Follow the string escaping rules for the programming language you are using.
Sending a message to a JMS connector

A QAnywhere-to-JMS destination address has two parts:

  • The connector address. This is the value of the ianywhere.connector.address property in the connector properties file.

    For more information, see Configuring the JMS connector properties file.

  • The JMS queue name. This is a queue that you create using your JMS administration tools.

    For more information, see Using JMS Connectors.

The form of the destination address is:

connector-address\JMS-queue-name

For more information about addressing messages in a JMS application, see Addressing QAnywhere messages meant for JMS and Addressing JMS messages meant for QAnywhere.


Initializing the QAnywhere client API

Before you can send or receive messages using QAnywhere, you must complete the following initialization tasks.

Setting up C++ applications
toggle To initialize the QAnywhere client API (C++)

  1. Include the QAnywhere header file.

    #include <qa.hpp>

    qa.hpp defines the QAnywhere classes.

  2. Initialize QAnywhere.

    To do this, initialize a factory for creating QAManager objects.

    QAManagerFactory *   factory;

factory = QAnywhereFactory_init();
if( factory == NULL ) {
      // fatal error
}

  3. Create a QAManager object.

    You can create a default QAManager object as follows:

    QAManager *   mgr;

// Create a manager
mgr = factory->createQAManager( NULL );
if( mgr == NULL ) {
  // fatal error
}

    You can customize a QAManager object programmatically or using a properties file.

    • To customize QAManager programmatically, use the setProperties method.

      For more information, see Setting properties programmatically.

    • To use a properties file, specify the properties file in the createQAManager method:

      mgr = factory->createQAManager( "qa_mgr.props" );

      where qa_mgr.props is the name of the properties file on the remote device.

      For more information, see Setting properties in a file.

  4. Initialize the QAManager object.

    qa_bool  rc;
rc=mgr->open(
     AcknowledgementMode::IMPLICIT_ACKNOWLEDGEMENT ) )

    The argument to the open method is an acknowledgement mode, which indicates how messages are to be acknowledged. It must be one of IMPLICIT_ACKNOWLEDGEMENT or EXPLICIT_ACKNOWLEDGEMENT. With implicit acknowledgement, messages are acknowledged as soon as they are received by the client. With explicit acknowledgement, you must call the acknowledgement method on the QAManager to acknowledge the message.

    For more information, see Class QAManager.

Setting up .NET applications

You must make two changes to your Visual Studio .NET project to be able to use it:

  • Add a reference to the QAnywhere .NET DLL. Adding a reference tells Visual Studio.NET which DLL to include to find the code for the QAnywhere .NET API.

  • Add a line to your source code to reference the QAnywhere .NET API classes. In order to use the QAnywhere .NET API, you must add a line to your source code to reference the data provider. You must add a different line for C# than for Visual Basic.NET.

In addition, you must initialize the QAnywhere client API.

toggle To add a reference to the QAnywhere .NET API in a Visual Studio .NET project

  1. Start Visual Studio .NET and open your project.

  2. In the Solution Explorer window, right-click the References folder and choose Add Reference from the popup menu.

    The Add Reference dialog appears.

  3. On the .NET tab, click Browse to locate iAnywhere.QAnywhere.Client.dll. (The default location is \Program Files\Sybase\SQL Anywhere 9\win32). Select the DLL and click Open.

    Note that there is a separate version of the DLL for each of Windows and Windows CE.

  4. You can verify that the DLL is added to your project. Open the Add Reference dialog and then click the .NET tab. iAnywhere.QAnywhere.Client.dll appears in the Selected Components list. Click OK to close the dialog.

    The DLL is added to the References folder in the Solution Explorer window of your project. Referencing the data provider classes in your source code.

toggle To reference the QAnywhere .NET API classes in your code

  1. Start Visual Studio .NET and open your project.

  2. If you are using C#, add the following line to the list of using directives at the beginning of your project:

    using iAnywhere.QAnywhere.Client;

  3. If you are using Visual Basic .NET, add the following line at the beginning of your project before the line Public Class Form1:

    Imports iAnywhere.QAnywhere.Client

    This line is not strictly required. However, it allows you to use short forms for the QAnywhere classes. Without it, you can still use

    iAnywhere.QAnywhere.Client.QAManager
mgr =
 new iAnywhere.QAnywhere.Client.QAManagerFactory.Instance.CreateQAManager(
"qa_manager.props" );

    instead of

    QAManager mgr = QAManagerFactory.Instance.CreateQAManager(
 "qa_manager.props" );

    in your code.

toggle To initialize the QAnywhere client API (.NET)

  1. Include the iAnywhere.QAnywhere.Client namespace.

    using iAnywhere.QAnywhere.Client;

  2. Create a QAManager object.

    You can create a default QAManager object as follows:

    QAManager mgr;
mgr = QAManagerFactory.Instance.CreateQAManager( null );

    You can alternatively create a QAManager object that is customized using a properties file. The properties file is specified in the CreateQAManager method:

    mgr = QAManagerFactory.Instance.CreateQAManager(
  "qa_mgr.props" );

    where qa_manager.props is the name of the properties file that resides on the remote device.

  3. Initialize the QAManager object.

    mgr.Open(
   AcknowledgementMode.EXPLICIT_ACKNOWLEDGEMENT);

    The argument to the open method is an acknowledgement mode, which indicates how messages are to be acknowledged. It must be one of IMPLICIT_ACKNOWLEDGEMENT or EXPLICIT_ACKNOWLEDGEMENT. With implicit acknowledgement, messages are acknowledged as soon as they are received by the client. With explicit acknowledgement, you must call the acknowledgement method on the QAManager to acknowledge the message.

    For more information, see QAManager class.

You are now ready to send messages.


Setting QAManager properties

You have two options for setting QAManager properties:

  • Create a properties text file to define the QAnywhere Manager properties that will be used by one Manager instance.

  • Programatically set QAnywhere Manager properties.


Setting properties in a file

The information in a QAManager properties file is specific to one instance of a QAManager. An instance of QAManager can only be used by the thread that creates it. Applications may use more than one QAManager, but each QAManager cannot be shared by more than one thread.

When using a properties file, it must be configured for and installed on the remote device with each deployed copy of your application.

You specify the name of this file in your application. If the properties file does not reside in the same directory as your client executable, you must also specify the absolute path. If you want to use the default settings for the properties, use NULL instead of a filename.

Values set in the file permit you to enable or disable some of the QAnywhere features, such as automatic message compression and logging.

For more information, seeQAManager properties.

Lines of this file that begin with the character # are treated as comments.

Example

For example, suppose you have a QAnywhere Manager properties file called mymanager.props with the following content:

COMPRESSION_LEVEL=9
CONNECT_PARMS=DBF=mystore.db

When you create QAManager, you reference the file by name.

Following is an example using C++:

QAManagerFactory *   qa_factory;
QAManager *      mgr;

qa_factory = QAnywhereFactory_init();
qa_factory->createQAManager( "mymanager.props" );
mgr->open( AcknowledgementMode::EXPLICIT_ACKNOWLEDGEMENT );

Following is an example using C#:

QAManager      mgr;

mgr = QAManagerFactory.Instance.CreateQAManager( "mymanager.props" );
mgr.Open( AcknowledgeMode.EXPLICIT_ACKNOWLEDGEMENT );


Setting properties programmatically

You can use the QAManager setProperties method to set properties programmatically. Setting QAManager properties programmatically must be done before calling the Open() method of a QAManager instance.

Example

The following C++ example sets properties programmatically. When you create the QAManager, you specify the property settings.

QAManagerFactory *   qa_factory;
QAManager *      mgr;

qa_factory = QAnywhereFactory_init();
mgr->createQAManager( NULL );
mgr->setProperty( "COMPRESSION_LEVEL", "9" );
mgr->setProperty( "CONNECT_PARAMS", "DBF=mystore.db" );
mgr->open( AcknowledgementMode::EXPLICIT_ACKNOWLEDGEMENT );

The following C# example sets properties programmatically. When you create the QAManager, you specify the property settings.

QAManager      mgr;

mgr = QAManagerFactory.Instance.CreateQAManager( null );
mgr.SetProperty( "COMPRESSION_LEVEL", "9" );
mgr.SetProperty( "CONNECT_PARAMS", "DBF=mystore.db" );
mgr.Open( AcknowledgeMode.EXPLICIT_ACKNOWLEDGEMENT );
See also
  • For .NET: iAnywhere.QAnywhere.Client namespace
  • For C++: QAnywhere C++ API Reference
  • QAManager properties


QAManager properties

The following table lists all the available properties.

Property | Notes
COMPRESSION_LEVEL=n | Set the compression level. n is the compression factor. It is an integer between 0 and 9, 0 indicating no compression and 9 indicating maximum compression.
CONNECT_PARAMS=connect-string | A connection string used by the QAnywhere Manager to connect to the message store database. The connect options are written in the form keyword=value. For a list of options, see Connection parameters.
LOG_FILE="filename" | The name of a file to which logging messages are to be written. Implicitly enables logging.
MAX_IN_MEMORY_MESSAGE_SIZE=n | When reading a message, n is the largest message, in bytes, for which a buffer will be allocated. A message larger than n bytes must be read using streaming operations. The default is 1000000 on Windows and 64000 on Windows CE.


Sending QAnywhere messages

The following procedures describe how to send messages from QAnywhere applications. These procedures assume that you have created and opened a QAManager object.

Sending a message from your application does not ensure it is delivered from your device. It simply places the message on a queue to be delivered. The QAnywhere Agent carries out the task of sending the message to the MobiLink synchronization server, which in turn delivers it to its destination.

toggle To send a message (C++)

  1. Create a new message.

    You can create either a text message or a binary message. Use the method for the type of message that you want to send.

    QATextMessage *   msg;
msg = mgr->createTextMessage();

  2. Set message properties.

    Use methods of the QATextMessage or QABinaryMessage class to set properties.

  3. Put the message on the queue, ready for sending.

    if( msg != NULL ) {
      if( !mgr->putMessage( "store-id\\queue-name", msg ) )
  {
         // display error using mgr->getLastErrorMsg()
      }
      mgr->deleteMessage( msg );
   }

    where store-id and queue-name are strings that combine to form the destination address.

toggle To send a message (.NET)

  1. Create a new message.

    You can create either a text message or a binary message. Use the method for the type of message that you want to send.

    QATextMessage      msg;
msg = mgr.CreateTextMessage();

  2. Set message properties.

    Use methods of the QATextMessage or QABinaryMessage class to set properties.

  3. Put the message on the queue, ready for sending.

    mgr.PutMessage( "store-id\\queue-name", msg );

    where store-id and queue-name are strings that combine to form the destination address.


Receiving messages synchronously

To receive messages synchronously, your application explicitly polls the queue for messages. It may poll the queue periodically, or when a user initiates a particular action such as clicking a Refresh button.

toggle To receive messages synchronously (C++)

  1. Declare message objects to hold the incoming messages.

    QAMessage *      msg;
QATextMessage *   text_msg;

  2. Poll the message queue, receiving messages:

    if( mgr->start() ) {
    for( ;; ) {
        msg = mgr->getMessageNoWait( "queue_name" );
        if( msg == NULL )  break;
        text_msg = msg->castToTextMessage();
        if( text_msg != NULL ) {
            // display text message using
            // text_msg->getText()
        }
        sleep( time-period );
    }
    mgr->stop();
}
toggle To receive messages synchronously (.NET)

  1. Declare message objects to hold the incoming messages.

    QAMessage       msg;
QATextMessage    text_msg;

  2. Poll the message queue, collecting messages:

    if(mgr.start()  )  {
  for(;;) {
    msg = mgr.GetMessageNoWait("queue_name");
    if( msg == null ) break;
    addMessage( msg );
  }
  mgr.stop();
}


Receiving messages asynchronously

To receive messages asynchronously you must write and register a message listener function that is called by QAnywhere when a message appears in the queue. The message listener takes the incoming message as a parameter. The task you perform in your message listener depends on your application. For example, in the TestMessage sample application that is installed with SQL Anywhere Studio, the message listener adds the message to the list of messages in the main TestMessage window.

toggle To receive messages asynchronously (C++)

  1. Create a class that implements the QAMessageListener interface.

    class MyClass: public QAMessageListener
{
   private:
   void onMessage( QAMessage * Msg);
};

  2. Implement the onMessage method.

    The QAMessageListener interface contains one method, onMessage. Each time a message arrives in the queue, the QAnywhere library calls this method, passing the new message as the single argument.

    void MyClass::onMessage(QAMessage * msg)
{
     // process msg
}

    Be particularly careful to handle errors. Failure to do so can cause you to miss messages.

  3. Register the message listener.

    my_listener = new MyClass();
mgr->setMessageListener( "queue-name", my_listener );
toggle To receive messages asynchronously (.NET)

  1. Implement a message handler.

    private void onMessage(QAMessage msg)
{
    // process msg
}

  2. Register the message handler.

    To register a message handler, create a QAManager.MessageListener object that has the message handler function as its argument. Then use the QAManager.SetMessageListener function to register the MessageListener with a specific queue.

    QAManager.MessageListener listener;
listener=new QAManager.MessageListener( onMessage );
mgr.SetMessageListener( "queue-name", listener );

    where queue-name is a string and is the name of the queue the QAManager object listens to.


Reading very large messages

Sometimes messages are so large that they exceed the limit set with the QAManager property MAX_IN_MEMORY_MESSAGE_SIZE or its defaults of 1MB on Windows and 64KB on Windows CE. In this case the message cannot be read from memory, so the usual read methods such as readInt and readString cannot be used. However, you can read very large messages directly from the message store in pieces. To do this, use QATextMessage.readText or QABinaryMessage.readBinary in a loop. At the end of the read, -1 is returned.

When you do this, you cannot use a QAManager that was opened with IMPLICIT_ACKNOWLEDGEMENT. You must use a QAManager that was opened with EXPLICIT_ACKNOWLEDGEMENT and you must do all calls to readText or readBinary before acknowledging the message.


Handling push notifications and network status changes

For background information about using notifications, see Scenario for messaging with push notifications.

Notifications and network status changes are both sent to QAnywhere applications as system messages. System messages are exactly the same as other messages, but are received in a separate queue named system.

For example, the following C# code deals with system and normal messages. It assumes that you have defined the message handling functions onMessage and onSystemMessage that implement the application logic for processing the messages.

// Declare the message listener and system listener
private QAManager.MessageListener _receiveListener;
private QAManager.MessageListener _systemListener;
...

// Create a MessageListener that uses the appropriate message handlers
_receiveListener = new QAManager.MessageListener( onMessage );
_systemListener = new QAManager.MessageListener( onSystemMessage );
...

// Register the message handler
mgr.SetMessageListener( queue-name, _receiveListener );
mgr.SetMessageListener( "system", _systemListener );

The system message handler may query the message properties to identify what information it contains. The message type property indicates if the message holds a network status notification. For example, for a message msg:

if( msg.PropertyExists(MessageProperties.MSG_TYPE) ) {
     msg_type=(MessageType)msg.GetIntProperty(...);
     ...
} else {
     // Process regular message
}
msg_type = (MessageType)msg.GetIntProperty( MessageProperties.MSG_TYPE );
if( msg_type == MessageType.NETWORK_STATUS_NOTIFICATION ) {
    // Process a network status change
} else if ( msg_type == MessageType.PUSH_NOTIFICATION ) {
    // Process a push notification
} else if ( msg_type == MessageType.REGULAR ) {
   //  This message type should not be received on the system
   //  queue. Take appropriate action here.
}
See also
  • ias_Status in Message headers
  • ias_Network in Client store properties


Implementing transactional messaging

Transactional messaging provides the ability to group messages in a way that guarantees that either all messages in the group are delivered, or none are. This is more commonly referred to as a single transaction.

When implementing transactional messaging, you create a special QAManager object called a transactional manager.

toggle To create a transactional manager (C++)

  1. Initialize QAnywhere.

    This step is exactly the same as in non-transactional messaging.

    #include <qa.hpp>
QAManagerFactory *   factory;

factory = QAnywhereFactory_init();
if( factory == NULL ) {
    // fatal error
}

  2. Create a transactional manager.

    QATransactionalManager *   mgr;

mgr = factory->createQATransactionalManager( NULL );
if( mgr == NULL ) {
    // fatal error
}

    As with non-transactional managers, you can specify a properties file to customize QAnywhere behavior. In this example, no properties file is used.

  3. Initialize the manager.

    if( !mgr->open() ) {
   // display message using mgr->getLastErrorMsg();
}

You are now ready to send messages. The following procedure sends two messages in a single transaction.

toggle To send multiple messages in a single transaction (C++)

  1. Initialize message objects.

    QATextMessage *   msg_1;
QATextMessage *   msg_2;

  2. Send the messages.

    The following code sends two messages in a single transaction:

    msg_1 = mgr->createTextMessage();
if( msg_1 != NULL )
{
  msg_2 = mgr->createTextMessage();
  if( msg_2 != NULL )
  {
    if( !mgr->putMessage( "jms_1\\queue_name", msg_1 ) )
    {
      // display message using mgr->getLastErrorMsg();
    } else {
      if( !mgr->putMessage( "jms_1\\queue_name", msg_2 ) )
      {
        // display message using mgr->getLastErrorMsg();
      } else {
        mgr->commit();
      }
    }
    mgr->deleteMessage( msg_2 );
  }
  mgr->deleteMessage( msg_1 );
}

    The commit() method actually sends the messages.


Shutting down QAnywhere

After you have completed sending and receiving messages, you can shut down the QAnywhere messaging system by completing the following step.

toggle To shut down QAnywhere (C++)

  1. Close the QAManager.

    mgr->stop();
mgr->close();

  2. Terminate the factory.

    QAnywhereFactory_term();

This step shuts down the messaging part of your application.

toggle To shut down QAnywhere (.NET)

  • Stop and close the QAManager.

    mgr.Stop();
mgr.Close();


Deploying QAnywhere applications

For information about the files needed to deploy QAnywhere applications, see Deploying QAnywhere applications.


QAnywhere Agent

About this chapter

This chapter describes the syntax of the QAnywhere Agent, qaagent.

For an overview of how to run the QAnywhere Agent, see Running the QAnywhere Agent.

QAnywhere Agent syntax


QAnywhere Agent syntax

Use the QAnywhere Agent to send and receive messages for all QAnywhere applications on a single client device.

Usage

The QAnywhere Agent controls other processes, which handle various messaging tasks. When you start the QAnywhere Agent command it spawns the following processes:

  • dbmlsync The dbmlsync executable is the MobiLink synchronization client. MobiLink synchronization is used to send and receive messages, so the dbmlsync executable is required.

  • dblsn The dblsn executable is the Listener utility. It receives push notifications. If you are not using push notifications, you do not need to supply the dblsn executable when you deploy your application, and you must run qaagent with push_notifications disabled.

  • database server The client message store is an Adaptive Server Anywhere database. QAnywhere Agent requires the Adaptive Server Anywhere database server to run the database. For Windows CE, the database server is dbsrv9.exe. For Windows, the database server is the personal database server dbeng9.exe.

    The QAnywhere Agent can spawn a database server or connect to a running server, depending on the communication parameters that you specify in the qaagent -c option.

Each of these processes is managed by the QAnywhere Agent, and does not need to be managed separately.

For deployment information, see Deploying QAnywhere applications.

Syntax

qaagent [ option ... ]

Option | Description
@data | Reads options from the specified environment variable or configuration file. See @data option.
-c connection-string | Specify a connection string to the client message store. See -c option.
-id id | Specify the ID of the client message store that the QAnywhere Agent is to connect to. See -id option.
-iu upload-size | Controls the size, in bytes, of incremental uploads. Use k or m to specify units of kilobytes or megabytes, respectively. See -iu option.
-la_port number | Specify the port on which the Listener listens for notifications from the MobiLink synchronization server. The default is 5001. See -la_port option.
-mp password | Specify the MobiLink password for the ID being synchronized. See -mp option.
-o logfile | Log output messages to this file. See -o option.
-on size | Specify a maximum size for the QAnywhere Agent message log file, after which the file is renamed with the extension .old and a new file is started. See -on option.
-os size | Specifies a maximum size for the QAnywhere Agent message log file, after which a new log file with a new name is created and used. See -os option.
-ot logfile | Truncate file and log output messages to file. See -ot option.
-policy policy-type | Specify the transmission policy used by the QAnywhere Agent. See -policy option.
-port number | Specify the port on which to listen for messages from the Listener. The default is 5002. See -port option.
-push_notifications value | Enable or disable push notifications. The default is enabled. See -push_notifications option.
-q | Start the QAnywhere Agent in quiet mode with the window minimized in the system tray. See -q option.
-qi | Start the QAnywhere Agent in quiet mode with the window completely hidden. See -qi option.
-si | Initialize the database for use as a client message store. See -si option.
-su | Upgrades a client message store from SQL Anywhere Studio version 9.0.1 to version 9.0.2. See -su option.
-v [levels] | Specify the level of verbosity. See -v option.
-x { http|tcpip } [ (keyword=value;...) ] | Specify protocol options for communication with the MobiLink synchronization server. See -x option.

@data option
-c option
-id option
-iu option
-la_port option
-mp option
-o option
-on option
-os option
-ot option
-policy option
-port option
-push_notifications option
-q option
-qi option
-si option
-su option
-v option
-x option


@data option

Function

Reads options from the specified environment variable or configuration file.

Syntax

qaagent @{ filename | environment-variable } ...

Remarks

With this option, you can put command line options in an environment variable or configuration file. If both exist with the name you specify, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

See Hiding the contents of files using the dbfhide command-line utility.


-c option

Function

Specify a connection string to the client message store.

Syntax

qaagent -c connection-string ...

Defaults
  • uid - ml_qa_user
  • pwd - qanywhere
  • dbn - id (where id is the client message store ID, and is specified with the -id option or defaults to the device name)
  • dbf - id.db (where id is the client message store ID, and is specified with the -id option or defaults to the device name)
Remarks

The connection string must specify connection parameters in the form keyword=value, separated by semicolons, with no spaces between parameters.

Connection parameters must be included in the ODBC data source specification if not given in the command line. Check your RDBMS and ODBC data source to determine required connection data.

For a complete list of connection parameters, see Connection parameters.

Following are some of the connection parameters you may need to use:

  • dbf=filename If you want QAnywhere Agent to start the client message store (rather than starting it from another application), you must specify a database file name. The default value of the database file is the name of the database. The default name for the database is the device name followed by .db; or you can specify a name with the -dbn connection parameter.

  • dbn=database-name If the client message store is already running when the QAnywhere Agent starts, you can connect to it by specifying a database name rather than a database file. The QAnywhere Agent looks on the default Adaptive Server Anywhere database server for a database with this name.

    The default database name of the client message store is the ID; for example, agent1. You can specify a name for the ID using the qaagent -id option, or use the default client message store ID, which is the device name.

  • eng=server-name If you want to use a database server that is already running, use this option to specify the server name. The default value is the name of the database.

  • uid=user Specify a database user ID to connect to the client message store. This is required if you change the defaults.

  • pwd=password Specify the password for the database user ID. This is required if you change the defaults.

  • dbkey=key If the client message store is encrypted using strong encryption, specify the encryption key required to access the database.

See also
  • Connection parameters
  • Connecting to a Database
  • Introduction to iAnywhere Solutions ODBC Drivers
Example
qaagent -id Device1 -c "DBF=qanyclient.db" -x tcpip(host=hostname) -policy automatic


-id option

Function

Specify the ID of the client message store that the QAnywhere Agent is to connect to.

Syntax

qaagent -id id ...

Default

The default value of the ID is the machine name on which the Agent is running. In some cases, machine names may not be unique, in which case you must use the -id option.

Remarks

Each client message store is represented by a unique sequence of characters called the message store ID. If you do not supply an ID when you first connect to the message store, the default is the device name. On subsequent connections, you must always specify the same message store ID with the -id option.

The message store ID is a MobiLink user name, and it is required because in all MobiLink applications, each remote database must have a unique MobiLink user name. As with all MobiLink user names, this must be added to a MobiLink system table on the consolidated database. You must do this even if you use the default, unless you use custom authentication.

For more information, see Creating MobiLink users.

You cannot use the following characters in an ID:

  • double quotes

  • control characters

  • double backslashes

In addition,

  • You can use a single backslash only if it is used as an escape character.

  • If your client message store database has the QUOTED_IDENTIFIER database option set to off (not the default), then your ID can only include alphanumeric characters and underscores, at signs, pounds, and dollar signs.

See also
  • About MobiLink users
  • Setting up the client message store


-iu option

Function

Synchronize messages using the MobiLink incremental uploads feature.

Syntax

qaagent -iu upload-size [ k | m ] ...

Default

Uploads are sent as a single unit.

Remarks

Using -iu, QAnywhere can synchronize messages using the MobiLink incremental uploads feature. This option specifies a minimum incremental scan volume in units of bytes.

Use the suffix k or m to specify units of kilobytes or megabytes, respectively.

When this option is specified, uploads are sent to the MobiLink synchronization server in one or more parts. This could be useful if a site has difficulty maintaining a connection for long enough to complete the full upload. When the option is not set, uploads are sent as a single unit.

Incremental uploads may be less efficient in that they send the schema with each increment.

See also
  • Increment (inc) extended option


-la_port option

Function

Specify the Listener port.

Syntax

qaagent -la_port number ...

Default

5001

Remarks

The port number on which the Listener listens for notifications from the MobiLink synchronization server. Notifications are used to inform the QAnywhere Agent that a message is waiting.

If no Listener is running on the device, qaagent starts the Listener on the specified port. If a Listener is running, you must specify the port that it is running on (or use the default port).

See also
  • Scenario for messaging with push notifications
  • -push_notifications option


-mp option

Function

Specify the MobiLink password for the client message store ID.

Syntax

qaagent -mp password ...

Default

None

Remarks

If the MobiLink synchronization server requires user authentication, use -mp to supply the MobiLink password corresponding to the ID. The ID identifies the client message store and is specified with the -id option.

See also
  • Authenticating MobiLink Users
  • -id option


-o option

Function

Sends output to a log file.

Syntax

qaagent -o logfile ...

Default

None

Remarks

The QAnywhere Agent logs output to the file name that you specify. The Adaptive Server Anywhere synchronization client (dbmlsync) logs output to a file with the same name, but including the suffix _sync. The Listener utility (dblsn) logs output to a file with the same name, but including the suffix _lsn.

For example, if you specify the log file c:\tmp\mylog.out, then qaagent will log to c:\tmp\mylog.out, dbmlsync will log to c:\tmp\mylog_sync.out and dblsn will log to c:\tmp\mylog_lsn.out.

See also
  • -ot option
  • -on option
  • -os option
  • -v option


-on option

Function

Specifies a maximum size for the QAnywhere Agent message log file, after which the file is renamed with the extension .old and a new file is started.

Syntax

qaagent –on size [ k | m ]...

Default

None

Description

The size is the maximum file size for the output log, in bytes. Use the suffix k or m to specify units of kilobytes or megabytes, respectively. The minimum size limit is 10KB.

When the log file reaches the specified size, the QAnywhere Agent renames the output file with the extension .old, and starts a new one with the original name.

Note
If the .old file already exists, it is overwritten. To avoid losing old log files, use the -os option instead.

This option cannot be used with the -os option.

See also
  • -o option
  • -ot option
  • -os option
  • -v option


-os option

Function

Specifies a maximum size for the QAnywhere Agent message log file, after which a new log file with a new name is created and used.

Syntax

dbmlsrv9 –os size [ k | m ]...

Default

None

Description

The size is the maximum file size for logging output messages. The default units is bytes. Use the suffix k or m to specify units of kilobytes or megabytes, respectively. The minimum size limit is 10KB.

Before the QAnywhere Agent logs output messages to a file, it checks the current file size. If the log message will make the file size exceed the specified size, the QAnywhere Agent renames the message log file to yymmddxx.mls. In this instance, xx are sequential characters ranging from 00 to 99, and yymmdd represents the current year, month, and day.

You can use this option to prune old message log files to free up disk space. The latest output is always appended to the file specified by -o or -ot.

You cannot use this option with the -on option.

See also
  • -o option
  • -ot option
  • -on option
  • -v option


-ot option

Function

Truncates the log file and appends output messages to it.

Syntax

qaagent -ot logfile ...

Default

None

Remarks

The QAnywhere Agent logs output to the file name that you specify. The Adaptive Server Anywhere synchronization client (dbmlsync) logs output to a file with the same name, but including the suffix _sync. The Listener utility (dblsn) logs output to a file with the same name, but including the suffix _lsn.

For example, if you specify the log file c:\tmp\mylog.out, then qaagent will log to c:\tmp\mylog.out, dbmlsync will log to c:\tmp\mylog_sync.out and dblsn will log to c:\tmp\mylog_lsn.out.

See also
  • -o option
  • -on option
  • -os option
  • -v option


-policy option

Function

Specify a policy to determine when to send and receive messages.

Syntax

qaagent -policy policy-type ...

policy-type: ondemand | scheduled[ interval ] | automatic | rules-file

Defaults
  • Scheduled policy with transmissions every 10 seconds.
  • If you do not specify persistence rules in a transmission rules file, messages are deleted when the final status of the message is determined to be received or expired.
Remarks

QAnywhere uses a policy to determine when to send and receive messages. The policy-type can be one of the following:

  • ondemand Only send messages when the QAnywhere client application makes the appropriate function call.

    The QAManager.PutMessage() method causes messages to be queued locally. These messages are not transmitted to the server until the QAManager.TriggerSendReceive() method is called. Similarly, messages waiting on the server are not sent to the client until the TriggerSendReceive() method is called by the client.

    You can an use ondemand policy to respond to notifications, but must do so in your application. A notification causes a system message to be delivered to the QAnywhere client. In your application, you may choose to respond to this system message by calling TriggerSendReceive().

    For information about notifications, see Scenario for messaging with push notifications.

  • scheduled Send and receive messages at a specified interval. The default is 10 seconds.

    Transmission of messages between the client and the server takes place at a specified time interval.

    The QAManager.PutMessage() method causes messages to be queued locally. These messages are not transmitted until the time interval has elapsed. Messages queued on the server for delivery to the client are also transmitted when the time interval has elapsed.

    If push notifications are enabled, messages queued on the server for delivery to the client are transmitted when the next time interval elapses.

    The TriggerSendReceive() method can be used to override the time interval. It forces a message transmission to occur before the time interval elapses.

    The optional interval argument is the number of seconds between send and receive operations. For example, the following command schedules the QA Agent to synchronize messages every 15 minutes:

    qaagent.exe -policy scheduled[900]

  • automatic Receive messages when a push notification is received or when one of the other events, described below, occurs.

    The QAnywhere agent attempts to keep message queues as current as possible. Any of the following events cause messages queued on the client to be delivered to the server and messages queued on the server to be delivered to the client:

    • Invoking the PutMessage() method.

    • Invoking the TriggerSendReceive() method.

    • A notification.

      For information about notifications, see Scenario for messaging with push notifications.

    • A message status change on the client. For example, a status change occurs when an application retrieves a message from a local queue which causes the message status to change from pending to delivered.

  • rules-file Specify a transmission rules file. The transmission rules file can indicate a more complicated set of rules to determine when messages are sent.

    For more information about transmission rules, see Transmission rules.

See also
  • Determining when message transmission should occur on the client
  • QAnywhere C++ API Reference
  • iAnywhere.QAnywhere.Client namespace


-port option

Function

Specify a port for the QAnywhere Agent.

Syntax

qaagent -port number ...

Default

5002

Remarks

The port number on which QAnywhere Agent listens for communications from the Listener.

The default value is 5002. If you set a different port, the QAnywhere Agent automatically configures the Listener to communicate on that port.


-push_notifications option

Function

Specify whether server notifications are supported.

Syntax

qaagent -push_notifications { enabled | disabled } ...

Default

Enabled.

Remarks

If you do not want to use notifications, set this option to disabled. You then do not have to deploy the dblsn.exe executable with your clients.

For a description of this setup, see Simple messaging scenario.

The dblsn.exe executable (the Listener) is not supported on Windows 95 or Windows NT.

If you are using UDP, you cannot use push notifications with ActiveSync due to the limitations of the UDP implementation of ActiveSync.

To use push notifications with SMS, see Using push notifications with SMS.


-q option

Function

Start the QAnywhere Agent in quiet mode with the window minimized in the system tray.

Syntax

qaagent -q ...

Default

None.

Remarks

When you start the QAnywhere Agent in quiet mode with -q, the main window is minimized to the system tray. In addition, the database server for the message store is started with the -qi option.

See also
  • -qi option


-qi option

Start the QAnywhere Agent in quiet mode with the window completely hidden.

Syntax

qaagent -qi ...

Default

None.

Remarks

When you start the QAnywhere Agent in quiet mode, on Windows desktop the main window is minimized to the system tray, and on Windows CE the main window is hidden. In addition, the database server for the message store is started with the -qi option.

Quiet mode is useful for some Windows CE applications because it prevents the situation where the application is closed when Windows CE reaches its limit of 32 concurrent processes. Quiet mode allows the QAnywhere Agent to run like a service.

When in -qi quiet mode, you can only stop the QAnywhere Agent by running qastop.

See also
  • -q option


-si option

Function

Initialize the database for use as a client message store.

Syntax

qaagent -c "connection-string" -si ...

Default

None. You only use this option once, to initialize the client message store.

Remarks

Before using this option, you must create an Adaptive Server Anywhere database. This database should not be used for any purpose other than as a message store. When you use -si, the QAnywhere Agent initializes the database with database objects such as MobiLink system tables; it then exits immediately.

When you run -si, you must specify a connection string with the -c option that indicates which database to initialize. The connection string specified in the -c option should also specify a user ID with DBA privileges. If you do not specify a user ID and password, the default user DBA with password SQL is used.

The -si option creates a database user named ml_qa_user and password qanywhere for the client message store. The user called ml_qa_user has permissions suitable for QAnywhere applications only. If you do not change this database user name and password, then you do not need to specify the pwd or uid in the -c option when you start qaagent. If you change either of them, then you must supply the uid and/or pwd in the -c option on the qaagent command line.

You should change the default passwords. To change them, use the GRANT statement. For more information, see Changing a password.

The -si option does not provide an ID for the client message store. You can assign an ID using the -id option when you run -si or the next time you run qaagent; or, if you do not do that, qaagent will by default assign the device name as the ID.

When a message store is set up but does not have an ID, QAnywhere applications local to the message store can send and receive messages, but cannot exchange messages with remote QAnywhere applications. Once an ID is assigned, remote messaging may also occur.

See also
  • Setting up the client message store
  • Creating a secure client message store
Examples

The following command connects to a database called qaclient.db and initializes it as a QAnywhere client message store. The QAnywhere Agent immediately exits when the initialization is complete.

qaagent -si -c "DBF=qaclient.db"


-su option

Function

Upgrades a client message store from SQL Anywhere Studio version 9.0.1 to version 9.0.2.

Syntax

qaagent -su -c "connection-string" ...

Remarks

This option is useful when you have a client message store with messages in it that was created with SQL Anywhere Studio 9.0.1.

Specify the database to upgrade in the connection string. Exits when done. This operation cannot be undone.


-v option

Function

Allows you to specify what information is logged to the message log file and displayed in the synchronization window. A high level of verbosity may affect performance and should normally be used in the development phase only.

Syntax

qaagent -v levels ...

Default

Minimal verbosity.

Remarks

The -v option affects the log files and synchronization window. You only have a message log if you specify -o or -ot on the qaagent command line.

If you specify –v alone, a small amount of information is logged.

The values of levels are as follows. You can use one or more of these options at once; for example, -vlm.

  • + Turn on all logging options.

  • l Show all MobiLink Listener logging. This causes the MobiLink Listener (dblsn) to start with verbosity level -v3.

    For more information, see the -v option in the The Listener utility.

  • m Show all dbmlsync logging. This causes the Adaptive Server Anywhere synchronization client (dbmlsync) to start with verbosity level -v+.

    For more information, see the dbmlsync -v option.

  • n Show all network status change notifications. the QAnywhere Agent receives these notifications from the Listener utility.

  • p Show all message push notifications. The QAnywhere Agent receives these notifications from the Listener utility via the QAnywhere server, which includes a MobiLink Notifier.

  • q Show the SQL that is used to represent the transmission rules.

  • s Show all the message synchronizations that are initialized by QAnywhere Agent.

See also
  • -o option
  • -ot option
  • -on option
  • -os option


-x option

Function

Specify the network protocol and protocol options for communication with the MobiLink synchronization server.

Syntax

qaagent -x protocol [ ( protocol-options;... ) ...

protocol: http, tcpip, https, or https_fips

protocol-options: keyword=value

Remarks

The -x option is required when the MobiLink synchronization server is not on the same device as the QAnywhere Agent.

You can specify -x multiple times. This allows you to set up failover to multiple MobiLink synchronization servers. When you set up failover, the QAnywhere Agent attempts the MobiLink synchronization servers in the order in which you enter them on the command line.

The QAnywhere Agent also has a Listener that receives notifications from the MobiLink synchronization server that messages are available at the server for synchronization. This Listener only uses the first MobiLink synchronization server that is specified, and does not fail over to others.

See also
  • For a complete list of protocol options that you can set for communication with the MobiLink synchronization server, see the dbmlsrv9 -x option.
  • Encrypting the communication stream
  • MobiLink Transport-Layer Security
  • Setting up a failover mechanism


Writing Secure Messaging Applications

About this chapter

This chapter describes techniques for implementing a secure messaging solution.


Creating a secure client message store

To create a secure client message store, you can:

  • Change the default passwords.

    See Manage client message store passwords.

  • Encrypt the contents of the message store.

    See Encrypting the client message store.

Example

First, create an Adaptive Server Anywhere database with an encryption key:

dbinit mystore.db -ek key

Next, initialize the database as a client message store:

qaagent -id mystore -si -c "dbf=mystore.db;dbkey=some_phrase"

Next, create a new remote user with DBA authority, and a password for this user. Revoke the default QAnywhere user and change the password of the default DBA user. Log in as user DBA with password SQL and execute the following SQL statements:

GRANT CONNECT TO secure_user IDENTIFIED BY secure_password
    GRANT MEMBERSHIP IN GROUP ml_qa_user_group TO secure_user
    GRANT REMOTE dba TO secure_user
    REVOKE CONNECT FROM ml_qa_user
    GRANT CONNECT TO dba IDENTIFIED BY new_dba_password
    COMMIT

Next, start the QAnywhere Agent with the secure DBA user:

    qaagent -id mystore -c "dbf=mystore.db;dbkey=some_phrase;uid=secure_user;pwd=secure_password"

You also need to set the connection parameters for your remote applications. For example, the QAManager properties file should contain this line:

CONNECT_PARAMS=dbn=mystore;dbkey=some_phrase;uid=secure_user;pwd=secure_password


Manage client message store passwords

You should change the passwords for the default user IDs that were created for the message store. The default user ID DBA with password SQL is created for every Adaptive Server Anywhere database. In addition, the qaagent -si option creates a default user ID of ml_qa_user, and creates a default password of qanywhere. To change these passwords, use the GRANT statement.

For more information, see Changing a password.


Encrypting the client message store

The following command can be used to encrypt the client message store when you create it.

dbinit –ek encryption-key database-file

When a message store has been initialized with an encryption key, the encryption key is required to start the database server on the encrypted message store.

Use the following command to specify the encryption key to start the QAnywhere Agent with an encrypted message store. The QAnywhere Agent will automatically start the database server on the encrypted message store using the encryption key provided.

qaagent –c "DBF=database-file;DBKEY=encryption-key"

Any application can now access the encrypted message store through the QAnywhere client API. Note that, since the database server used to manage the message store is already running, the application does not need to provide the encryption key.

If the QAnywhere Agent is not running and an application needs to access an encrypted message store, the QAnywhere client API will automatically start the database server using the connection parameters specified in the QAnywhere Manager initialization file. In order to start the database server on an encrypted message store, the encryption key must be specified in the database connection parameters as follows.

CONNECT_PARAMS=DBF=database-file;DBKEY=encryption-key


Encrypting the communication stream

The qaagent -x option can be used to specify a secure communication stream that the QAnywhere Agent can use to connect to a MobiLink synchronization server. It allows you to implement server authentication using server-side certificates, and it allows you to encrypt the communication stream using strong encryption.

For more information, see -x option.

You must set up transport-layer security for the MobiLink synchronization server as well. For more information, see MobiLink Transport-Layer Security.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Examples

The following examples show how to establish a secure communication stream between the QAnywhere Agent and the MobiLink synchronization server. They use sample certificates that are installed when the SQL Anywhere Studio security option is installed.

Secure TCP/IP using RSA:

dbmlsrv9 -x tcpip(security=rsa_tls(certificate=rsaserver.crt;certificate_password=test))
qaagent –x tcpip(security=rsa_tls(trusted_certificates=rsaroot.crt))

Secure TCP/IP using ECC:

dbmlsrv9 -x tcpip(security=ecc_tls(certificate=sample.crt;certificate_password=tJ1#m6+W))
qaagent –x tcpip(security=ecc_tls(trusted_certificates=eccroot.crt))

Secure HTTP using HTTPS (only RSA certificates are supported for HTTPS):

dbmlsrv9 -x https(certificate=rsaserver.crt;certificate_password=test)
qaagent –x https(trusted_certificates=rsaroot.crt)


Using password authentication with MobiLink

Once you have established a secure communication stream between the remote device and the server, you may also want to authenticate the user of the device to ensure that they are allowed to communicate with the server.

For more information, see:

  • -mp option
  • Authenticating MobiLink Users


QAnywhere Transmission Rules

About this chapter

This chapter describes how to write transmission rules. You can create transmission rules on the server to define which messages should be downloaded to the client, and transmission rules on the client to define which messages should be uploaded to the server.


Transmission rules

Message transmission is the action of moving messages from a client message store to a server message store, or vice versa.

Message transmission is handled by the QAnywhere Agent and the MobiLink synchronization server:

  • The QAnywhere Agent is connected to the client message store. It transmits messages to and from the MobiLink synchronization server.

  • The MobiLink synchronization server is connected to the server message store. It receives message transmissions from QAnywhere Agents and transmits them to other QAnywhere Agents.

Message transmission can only take place between a client message store and a server message store. A message transmission can only occur when a QAnywhere Agent is connected to a MobiLink synchronization server.

Transmission rules allow you to specify when message transmission is to occur and which messages to transmit. You can also use them to specify when messages should be deleted from the message stores, if you do not want to use the default behavior.

You can specify transmission rules on the server and on the client. See:

  • Client transmission rules
  • Server transmission rules

The transmission rules file holds the following kinds of entry:

  • Rules No more than one rule can be entered per line.

    Each rule must be entered on a single line, but you can use \ as a line continuation character.

  • Comments Comments are indicated by a line beginning with either a # or ; character. Any characters on that line are ignored.

For more information, see Schedule syntax and Condition syntax.

You can also use transmission rules files to determine when messages are to be deleted from the message stores.

For more information, see Delete rules.


Client transmission rules

Client transmission rules govern the behavior of messages going from the client to the server. Client transmission rules are handled by the QAnywhere Agent.

By default, QAnywhere messages are transmitted every 10 seconds. You can change and customize this behavior by specifying a transmission rules file as the transmission policy for the QAnywhere Agent.

The following partial qaagent command line shows how to specify a rules file for the QAnywhere Agent:

qaagent -policy myrules.txt ...

For a complete description of how to write transmission rules, see Schedule syntax.

For more information about policies, see Determining when message transmission should occur on the client.

Example

For example, the following client transmission rules file specifies that during business hours only small high priority messages should be sent, while outside of business hours, any message can be sent. This rule is automatic, which indicates that if the condition is satisfied, the message is transmitted immediately. This example demonstrates that conditions can use information derived from the message as well as other information such as the current time.

automatic = ( ias_ContentSize < 100000 and ias_Priority > 7 ) \
   or ias_CurrentDayOfWeek in ( 'Saturday', 'Sunday' ) \
   or ias_CurrentTime < '8:00AM' or ias_CurrentTime > '6:00PM'


Server transmission rules

Server transmission rules govern the behavior of messages going from the server to the client. Server transmission rules are handled by the MobiLink synchronization server. They apply both when you are using push notifications and when you are not using notifications.

You can create a server transmission rules file and specify it with the ianywhere.qa.server.transmissionRulesFile property in your QAnywhere messaging properties file.

Server transmission rules must be specified for each client by preceding a section of rules with the client message store ID in square brackets.

For more information about the message properties file, see -m option.

Example

Following is a sample server transmission rules file. In the following example, the rules apply only to the client identified by the client message store ID sample_store_id.

[sample_store_id]
; This rule governs when messages are transmitted to the client
; store with id sample_store_id.
;
;    ias_Priority >= 7
;
; Messages with priority 7 or greater should always be
; transmitted.
;
;    ias_ContentSize < 100
;
; Small messages, that is messages less than 100 characters or
; bytes in size, should always be transmitted.
;
;    ias_CurrentTime < '8:00am' or ias_CurrentTime > '6:00pm'
;
; Outside of business hours, messages should always be
; transmitted

auto = ias_Priority >= 7 or ias_ContentSize < 100 \
    or ias_CurrentTime < '8:00am' or ias_CurrentTime > '6:00pm'

[qanywhere]
; This rule governs when messages are transmitted to the client
; store with id qanywhere.
;
;    tm_Subject not like '%non-business%'
;
; Messages with the property tm_Subject set to a value that
; includes the phrase 'non-business should not be transmitted'
;
;    ias_CurrentTime < '8:00am' or ias_CurrentTime > '6:00pm'
;
; Outside of business hours, messages should always be
; transmitted

auto = tm_Subject not like '%non-business%' \
    or ias_CurrentTime < '8:00am' or ias_CurrentTime > '6:00pm'


Schedule syntax

Schedules are used to specify times when conditions are to be evaluated. At those times, the corresponding condition is evaluated for all messages ready to be sent. Those messages satisfying the condition are sent at that time.

Syntax

Each rule is of the following form:

schedules=condition

When the scheduled time occurs, the condition is applied to each message. If the message satisfies the condition, then the message is transmitted.

schedules : { AUTOMATIC | schedule-spec [,...] }

schedule-spec :
{ START TIME start-time | BETWEEN start-time AND end-time }
[ EVERY period { HOURS | MINUTES | SECONDS } ]
[ ON { ( day-of-week, ... ) | ( day-of-month, ... ) } ]
[ START DATE start-date ]

Parameters

  • AUTOMATIC AUTOMATIC indicates that conditions are evaluated whenever a message is available for transmitting. Messages that satisfy the corresponding condition are transmitted.

  • schedule-spec Schedule specifications other than AUTOMATIC specify times when conditions are to be evaluated. At those scheduled times, the corresponding condition is evaluated for all messages ready to be transmitted. Those messages satisfying the condition are transmitted at that time.

  • START TIME The first scheduled time for each day on which the event is scheduled. If a START DATE is specified, the START TIME refers to that date. If no START DATE is specified, the START TIME is on the current day (unless the time has passed) and each subsequent day (if the schedule includes EVERY or ON).

  • BETWEEN ... AND ... A range of times during the day outside of which no scheduled times occur. If a START DATE is specified, the scheduled times do not occur until that date.

  • EVERY An interval between successive scheduled events. Scheduled events occur only after the START TIME for the day, or in the range specified by BETWEEN ... AND.

  • ON A list of days on which the scheduled events occur. The default is every day if EVERY is specified. Days can be specified as days of the week or days of the month.

    Days of the week are Mon, Tues, and so on. You may also use the full forms of the day, such as Monday. You must use the full forms of the day names if the language you are using is not English, is not the language requested by the client in the connection string, and is not the language which appears in the server window.

    Days of the month are integers from 0 to 31. A value of 0 represents the last day of any month.

  • START DATE The date on which scheduled events are to start occurring. The default is the current date.

Usage

You can create more than one schedule for a given condition. This permits complex schedules to be implemented.

A schedule specification is recurring if its definition includes EVERY or ON; if neither of these reserved words is used, the schedule specifies at most a single time. An attempt to create a non-recurring schedule for which the start time has passed generates an error.

Each time a scheduled time occurs, the associated condition is evaluated and then the next scheduled time and date is calculated.

The next scheduled time is computed by inspecting the schedule or schedules, and finding the next schedule time that is in the future. If a schedule specifies every minute, and it takes 65 seconds to evaluate the conditions, it runs every two minutes. If you want execution to overlap, you must create more than one rule.

  1. If the EVERY clause is used, find whether the next scheduled time falls on the current day, and is before the end of the BETWEEN ... AND range. If so, that is the next scheduled time.

  2. If the next scheduled time does not fall on the current day, find the next date on which the event is to be executed.

  3. Find the START TIME for that date, or the beginning of the BETWEEN ... AND range.

The QAnywhere schedule syntax is derived from the Adaptive Server Anywhere CREATE EVENT schedule syntax.

Keywords are case insensitive.

See also
  • CREATE EVENT statement.

Condition syntax


Condition syntax

QAnywhere condition syntax uses a SQL-like syntax. An expression evaluates to true, false, or unknown. Messages are sent only if the condition evaluates to true. If a condition is empty, all messages are judged to satisfy the condition.

Keywords and string comparisons are case insensitive.

Syntax

condition :
| expression operator expression
| arithmetic-expr [ NOT ] BETWEEN start-expr AND end-expr
| rule-variable [ NOT ] IN ( string-literal, ... )
| rule-variable [ NOT ] LIKE pattern [ ESCAPE escape-character ]
| rule-variable IS [ NOT ] NULL

Parameters

  • condition An expression that evaluates to true, false, or unknown. Only messages for which the condition evaluates to true are judged to satisfy the condition.

  • expression An arithmetic or conditional expression. Standard bracketing using parentheses indicates the order of evaluation within expressions.

    • Arithmetic expressions are composed of themselves, arithmetic operators, numeric identifiers, and numeric literals.

      Arithmetic operators, in order of precedence, are:

      • +, - (unary sign indicators)
      • *, / (multiplication and division)
      • +, - (addition and subtraction)

    • Conditional expressions are composed of themselves, comparison operators, and logical operators.

      Comparison operators, in order of precedence, are:

      • = (equals)
      • > (greater than)
      • >= (greater than or equals)
      • < (less than)
      • <= (less than or equals)
      • <> (not equal)

      Logical operators, in order of precedence, are:

      • NOT
      • AND
      • OR

  • rule-variable A QAnywhere rule-variable is a message header, a message property, or a client store property.

    The type of a property value in a condition corresponds to the type used to set the property. If a property that does not exist in a message is referenced, its value is NULL.

    For more information, see Transmission rule variables.

  • string-literal A string literal is a sequence of characters enclosed in single quotes, using a string encoding as specified by the QAnywhere Agent.

    A single quote in a string literal is represented by doubled single quote,

    For example, the following are valid string literals:

    'literal'
    'literal''s'

  • numeric-literal An exact numeric literal is a numeric value without a decimal point, such as 57, -957, and +62. The value range is -263 to 263 - 1, or -9223372036854775808 to 9223372036854775807.

    An approximate numeric literal is a numeric value in scientific notation, such as 7E3 and -57.9E2, or a numeric value with a decimal, such as 7., -95.7, and +6.2. The value range is 2.22507385850721e-308 to 1.79769313486231e+308.

  • boolean-literal The boolean literals are TRUE and FALSE.

  • BETWEEN The BETWEEN condition can evaluate as true, false, or unknown. Without the NOT keyword, the condition evaluates as TRUE if arithmetic-expr is greater than or equal to start-expr and less than or equal to end-expr.

    The NOT keyword reverses the meaning of the condition but leaves UNKNOWN unchanged.

    The BETWEEN condition is equivalent to a combination of two inequalities:

    [ NOT ] ( arithmetic-expr >= start-expr AND arithmetic-expr <= end-expr )

    For example:

    • age BETWEEN 15 AND 19 is equivalent to age >=15 AND age <= 19

    • age NOT BETWEEN 15 AND 19 is equivalent to age < 15 OR age > 19.

  • IN The IN condition evaluates according to the following rules:

    • True if rule-variable is not null and equals at least one of the values.

    • Unknown if rule-variable is null and the values list is not empty, or if at least one of the values is null and expression does not equal any of the other values.

    • False if none of the values are null, and rule-variable does not equal any of the values.

    The NOT keyword interchanges true and false.

    For example:

    • Country IN ( 'UK', 'US', 'France' ) is true for 'UK' and false for 'Peru'. It is equivalent to the following:

      ( Country = 'UK' )       \
OR ( Country = 'US' )    \
OR ( Country = 'France' )

    • Country NOT IN ( 'UK', 'US', 'France' ) is false for 'UK' and true for 'Peru'. It is equivalent to the following:

      NOT (    ( Country = 'UK' )      \
      OR ( Country = 'US' )      \
      OR ( Country = 'France' ) )

    • If the rule-variable of an IN operation is NULL

  • LIKE The LIKE condition can evaluate as true, false, or unknown.

    Without the NOT keyword, the condition evaluates as TRUE if expression matches the pattern. If either expression or pattern is NULL, this condition is unknown.

    The NOT keyword reverses the meaning of the condition, but leaves UNKNOWN unchanged.

    The pattern may contain any number of wildcards. The wildcards are:

    Wildcard | Matches
    _ (underscore) | Any one character
    % (percent) | Any string of zero or more characters

    For example:

    • phone LIKE 12%3 is true for '123' or '12993' and false for '1234'

    • word LIKE 's_d' is true for 'sad' and false for 'said'

    • phone NOT LIKE '12%3' is false for '123' or '12993' and true for '1234'

  • ESCAPE CHARACTER A single character string literal whose character is used to escape the special meaning of the wildcard characters (_, %) in pattern. For example:

    • underscored LIKE '\_%' ESCAPE '\' is true for '_myvar' and false for 'myvar'.

  • IS NULL The IS NULL condition evaluates to true if the rule-variable is unknown; otherwise it evaluates to false. The NOT keyword reverses the meaning of the condition. This condition cannot evaluate to unknown.


Transmission rule variables

QAnywhere transmission rule variables are used in condition syntax in transmission rules files. They can be used to define transmission rules and delete rules. There are three types of rule variable:

  • Message headers

  • Message properties

  • Message store properties


Message headers

The following message headers are pre-defined.

  • ias_Address The address of the message. For example, myclient\myqueue.

  • ias_Originator The client message store ID associated with the message sender.

  • ias_Status The status of the message. Values can be:

    • ias_ExpireState The message expired before it could be received by the intended recipient.

    • ias_FinalState The message is received or expired. Therefore, >= ias_FinalState means that the message is received or expired, and > ias_FinalState means that the message is neither received nor expired.

    • ias_PendingState The message has not yet been received by the intended recipient.

    • ias_Received The message was received by the intended recipient.

  • ias_StatusTime The date and time when the message reached the current status.

  • ias_Expires The date and time when the message will expire if it is not delivered.

  • ias_Priority The priority of message: a number from 0 to 9.

  • ias_ContentSize The size of the message content. If the message is a text message, this is the number of characters. If the message is binary, this is the number of bytes.


Message properties

QAnywhere allows you to define message properties using the C++ or .NET QAnywhere APIs. These properties are shared between applications connected to the same message store. They are also synchronized to the server message store so that they are available to the transmission rules used by a QAnywhere Agent connected to the same client message store. You define message properties in messages, and then reference them in transmission rules.

Message property names are case insensitive. You can use a sequence of letters and digits, but the first character must be a letter. The following names are reserved and may not be used as message property names:

  • NULL
  • TRUE
  • FALSE
  • NOT
  • AND
  • OR
  • BETWEEN
  • LIKE
  • IN
  • IS
  • ESCAPE
  • Any name beginning with ias_

The following QAManager methods can be used to manage message properties.

C++ methods to manage message properties
qa_bool getBooleanProperty( qa_const_string name, qa_bool * value )
qa_bool setBooleanProperty( qa_const_string name, qa_bool value )
qa_bool getByteProperty( qa_const_string name, qa_byte * value )
qa_bool setByteProperty( qa_const_string name, qa_byte value )
qa_bool getShortProperty( qa_const_string name, qa_short * value )
qa_bool setShortProperty( qa_const_string name, qa_short value )
qa_bool getIntProperty( qa_const_string name, qa_int * value )
qa_bool setIntProperty( qa_const_string name, qa_int value )
qa_bool getLongProperty( qa_const_string name, qa_long * value )
qa_bool setLongProperty( qa_const_string name, qa_long value )
qa_bool getFloatProperty( qa_const_string name, qa_float * value )
qa_bool setFloatProperty( qa_const_string name, qa_float value )
qa_bool getDoubleProperty( qa_const_string name, qa_double * value )
qa_bool setDoubleProperty( qa_const_string name, qa_double value )
qa_int getStringProperty( qa_const_string name, qa_string value, qa_int len )
qa_bool setStringProperty( qa_const_string name, qa_const_string value )

For more information, see QAnywhere C++ API Reference.

C# methods to manage message properties
Object GetProperty( String name )
void SetProperty( String name, Object value )
boolean GetBooleanProperty( String name )
void SetBooleanProperty( String name, boolean value )
byte GetByteProperty( String name )
void SetByteProperty( String name, byte value )
short GetShortProperty( String name )
void SetShortProperty( String name, short value )
int GetIntProperty( String name )
void SetIntProperty( String name, int value )
long GetLongProperty( String name )
void SetLongProperty( String name, long value )
float GetFloatProperty( String name )
void SetFloatProperty( String name, float value )
double GetDoubleProperty( String name )
void SetDoubleProperty( String name, double value )
String GetStringProperty( String name )
void SetStringProperty( String name, String value )

For more information, see iAnywhere.QAnywhere.Client namespace.

Example
c++
QAManager *mgr = ...; // Init QAManager
QAMessage *msg = mgr->createTextMessage();
msg->setStringProperty( "tm_Subject", "Some message subject" );
mgr->putMessage( "myqueue", mgr );

c#
QAManager mgr = ...; // init QAManager
QAMessage msg = mgr.createTextMessage();
msg.setStringProperty( "tm_Subject", "Some message subject" );
mgr.putMessage( "myqueue", msg );


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere Transmission Rules

Transmission rule variables

Client store properties

There are two types of client store property:

  • pre-defined

  • user-defined


Pre-defined client store properties

The following client store properties are pre-defined.

  • ias_Network Information about the current network in use. ias_Network is a special property. It has a number of built-in attributes that provide information regarding the current network that is being used by the device. These attributes are automatically set by QAnywhere:

    • ias_Network.Adapter The current name of the network card, if any. (The name of the network card that is assigned to the Adapter attribute is displayed in the Agent window when the network connection is established.)

    • ias_Network.RAS The current RAS dial-up name, if any.

    • ias_Network.IP The current IP address assigned to the device, if any.

    • ias_Network.MAC The current MAC address of the network card being used, if any.

  • ias_CurrentDayOfWeek The current day of the week.

  • ias_CurrentDayOfMonth The current day of the month, from 1-31.

  • ias_CurrentMonth The current month, from 1-12.

  • ias_CurrentYear The current year.

  • ias_CurrentDate The current date.

    A string can be compared against ias_currentDate if it is supplied in one of two ways:

    • as a string of format yyyy/mm/dd or yyyy-mm-dd, which is interpreted unambiguously.

    • as a string according to the DATE_ORDER database option set for the client message store database.

      For more information, see Setting options and DATE_ORDER option [compatibility].

  • ias_CurrentTime The current time.

    A string can be compared against ias_CurrentTime if the hours, minutes, and seconds are separated by colons in the format hh:mm:ss:sss. A 24-hour clock is assumed unless am or pm are specified.


Custom client store properties

QAnywhere allows you to define your own client store properties using the C++ or .NET QAnywhere APIs. These properties are shared between applications connected to the same message store. They are also synchronized to the server message store so that they are available to the transmission rules used by a QAnywhere Agent connected to the same client message store.

Message store property names are case insensitive. You can use a sequence of letters and digits, but the first character must be a letter. The following names are reserved and may not be used as client store property names:

  • NULL
  • TRUE
  • FALSE
  • NOT
  • AND
  • OR
  • BETWEEN
  • LIKE
  • IN
  • IS
  • ESCAPE
  • Any name beginning with ias_

The following QAManager methods can be used to manage client store properties.

C++ methods to manage client store properties
qa_bool getBooleanStoreProperty( qa_const_string name, qa_bool * value )
qa_bool setBooleanStoreProperty( qa_const_string name, qa_bool value )
qa_bool getByteStoreProperty( qa_const_string name, qa_byte * value )
qa_bool setByteStoreProperty( qa_const_string name, qa_byte value )
qa_bool getShortStoreProperty( qa_const_string name, qa_short * value )
qa_bool setShortStoreProperty( qa_const_string name, qa_short value )
qa_bool getIntStoreProperty( qa_const_string name, qa_int * value )
qa_bool setIntStoreProperty( qa_const_string name, qa_int value )
qa_bool getLongStoreProperty( qa_const_string name, qa_long * value )
qa_bool setLongStoreProperty( qa_const_string name, qa_long value )
qa_bool getFloatStoreProperty( qa_const_string name, qa_float * value )
qa_bool setFloatStoreProperty( qa_const_string name, qa_float value )
qa_bool getDoubleStoreProperty( qa_const_string name, qa_double * value )
qa_bool setDoubleStoreProperty( qa_const_string name, qa_double value )
qa_int getStringStoreProperty( qa_const_string name, qa_string value, qa_int len )
qa_bool setStringStoreProperty( qa_const_string name, qa_const_string value )

For more information, see QAnywhere C++ API Reference.

C# methods to manage client store properties
Object GetStoreProperty( String name )
void SetStoreProperty( String name, Object value )
boolean GetBooleanStoreProperty( String name )
void SetBooleanStoreProperty( String name, boolean value )
byte GetByteStoreProperty( String name )
void SetByteStoreProperty( String name, byte value )
short GetShortStoreProperty( String name )
void SetShortStoreProperty( String name, short value )
int GetIntStoreProperty( String name )
void SetIntStoreProperty( String name, int value )
long GetLongStoreProperty( String name )
void SetLongStoreProperty( String name, long value )
float GetFloatStoreProperty( String name )
void SetFloatStoreProperty( String name, float value )
double GetDoubleStoreProperty( String name )
void SetDoubleStoreProperty( String name, double value )
String GetStringStoreProperty( String name )
void SetStringStoreProperty( String name, String value )

For more information, see iAnywhere.QAnywhere.Client namespace.

Client store properties can also have attributes. An attribute is specified by appending a dot after the property name followed by the attribute name. In the following example, the Object property has two attributes: Shape and Color. The value of the Shape attribute is Round and the value of the Color attribute is Blue.

C++
  setStoreStringProperty( "Object.Shape", "Round" );
  setStoreStringProperty( "Object.Colour", "Blue" );
C#
  SetStoreProperty( "Object.Shape", "Round" );
  SetStoreProperty( "Object.Color", "Blue" );

All client store properties have a Type attribute that initially has no value. The value of the Type attribute must be the name of another property. When setting the Type attribute of a property, the property inherits the attributes of the property being assigned to it. In the following example, the Object property inherits the attributes of the Circle property. Hence the value of Object.Shape is Round and the value of Object.Color is Blue.

C++
  setStoreStringProperty( "Circle.Shape", "Round" );
  setStoreStringProperty( "Circle.Color", "Blue" );
  setStoreStringProperty( "Object.Type", "Circle" );
C#
  SetStoreProperty( "Circle.Shape", "Round" );
  SetStoreProperty( "Circle.Color", "Blue" );
  SetStoreProperty( "Object.Type", "Circle" );
Example

This section provides an example in C# of how you can use client store properties in transmission rules.

Assume you have a Windows laptop that has the following network connectivity options: LAN, Wireless LAN, and Wireless WAN. Access to the network via LAN is provided by a network card named "My LAN Card". Access to the network via Wireless LAN is provided by a network card named "My Wireless LAN Card". Access to the network via Wireless WAN is provided by a network card named "My Wireless WAN Card".

Note: The names of network adapters are fixed when the card is plugged in and the driver is installed. To find the name of a particular network card, connect to the network through that adapter, and then run qaagent with the -vn option. The QAnywhere Agent will display the network adapter name as follows:

"Listener thread received message '[netstat] network-adapter-name !...'

You want to develop a messaging application that sends all messages to the server when connected using LAN or Wireless LAN and only high priority messages when connected using Wireless WAN. You define high priority messages as those whose priority is greater than or equal to 7.

First, define three client store properties for each of the network types: LAN, WLAN, and WWAN. Each of these properties will be assigned a Cost attribute. The Cost attribute is a value between 1 and 3 and represents the cost incurred when using the network. A value of 1 represents the lowest cost.

QAManager   qa_manager;

qa_manager.SetStoreProperty( "LAN.Cost", "1" );
qa_manager.SetStoreProperty( "WLAN.Cost", "2" );
qa_manager.SetStoreProperty( "WWAN.Cost", "3" );

Next, define three cilent store properties, one for each network card that will be used. The property name must match the network card name. Assign the appropriate network classification to each property by assigning the network type to the Type attribute. Each property will therefore inherit the attributes of the network types assigned to them.

QAManager   qa_manager;

qa_manager.SetStoreProperty( "My LAN Card.Type", "LAN" );
qa_manager.SetStoreProperty( "My Wireless LAN Card.Type", "WLAN" );
qa_manager.SetStoreProperty( "My Wireless WAN Card.Type", "WWAN" );

When network connectivity is established, QAnywhere will automatically define the Adapter attribute of the ias_Network property to one of "My LAN Card", "My Wireless LAN Card" or "My Wireless WAN Card", depending on the network in use. Similarly, it will automatically set the Type attribute of the ias_Network property to one of "My LAN Card", "My Wireless LAN Card" or "My Wireless WAN Card" so that the ias_Network property will inherit the attributes of the network being used.

Finally, create a transmission rules file with the following transmission rule.

ias_Network.Cost < 3 or ias_Priority >= 7


Delete rules

Delete rules determine the persistence of messages in the client message store and the server message store. They are specified in transmission rules files.

Client delete rules

By default, messages are deleted from the client message store when the final status of the message is determined to be received or expired. You may want messages to be deleted faster than that, or to hold on to messages after acknowledgement. You do that by creating a delete section in your client transmission rules file.

For more information about client transmission rules, see Client transmission rules.

Following is an example of the delete rules section in a client transmission rules file:

[system:delete]

; This rule governs when messages are deleted from the client
; store
;
;    start time '1:00am' on ( 'Sunday' )
;
; Messages are deleted every Sunday at 1:00AM.
;
;    ias_Status >= ias_FinalState
;
; Typically, messages are deleted when they reach a final
; state: received, unreceivable, expired, or cancelled.

start time '1:00am' on ( 'Sunday' ) = ias_Status >= ias_FinalState

For an explanation of ias_Status, see Message headers.

Server delete rules

By default, messages are deleted from the server message store as soon as the message has been delivered and delivery is confirmed. You may want to keep messages longer for purposes such as auditing. You do that by creating a delete section in your server transmission rules file.

Server-side delete rules apply to all QAnywhere clients.

For more information about server transmission rules, see Server transmission rules.

Following is an example of the delete rules section in a server transmission rules file:

[system:delete]

; This rule governs when messages are deleted from the server
; store
;
;    start time '1:00am' on ( 'Sunday' )
;
; Messages are deleted every Sunday at 1:00AM.
;
;    ias_Status >= ias_FinalState
;
; Typically messages are deleted when they reach a final
; status: received, unreceivable, expired or cancelled.

start time '1:00am' on ( 'Sunday' ) = ias_Status >= ias_FinalState

For an explanation of ias_Status, see Message headers.


QAnywhere C++ API Reference

About this chapter

This chapter describes the QAnywhere C++ API.

Class AcknowledgementMode
Class MessageProperties
Class MessageType
Class QABinaryMessage
Class QAError
Class QAManager
Class QAManagerBase
Class QAManagerFactory
Class QAMessage
Class QAMessageListener
Class QATextMessage
Class QATransactionalManager


Class AcknowledgementMode

Synopsis

public AcknowledgementMode

Remarks

The acknowledgement modes supported by QAnywhere are transactional, implicit and explicit. The client application specifies the acknowledgement mode when creating its instance of the Class QAManager.

Members

All members of AcknowledgementMode, including all inherited members.

  • EXPLICIT_ACKNOWLEDGEMENT Variable
  • IMPLICIT_ACKNOWLEDGEMENT Variable
  • TRANSACTIONAL Variable


EXPLICIT_ACKNOWLEDGEMENT Variable

Synopsis

const qa_short AcknowledgementMode::EXPLICIT_ACKNOWLEDGEMENT

Remarks

With explicit acknowledgement, messages are acknowledged by a call to one of the acknowledge methods of QAManager .


IMPLICIT_ACKNOWLEDGEMENT Variable

Synopsis

const qa_short AcknowledgementMode::IMPLICIT_ACKNOWLEDGEMENT

Remarks

With implicit acknowledgement, messages are acknowledged as soon as they are received by the client application.


TRANSACTIONAL Variable

Synopsis

const qa_short AcknowledgementMode::TRANSACTIONAL

Remarks

This mode indicates that messages are only acknowledged as part of the ongoing transaction. Hence, only a call to the commit method of QAManager acknowledges all outstanding messages.


Class MessageProperties

Synopsis

public MessageProperties

Remarks

This class defines constant values for useful message property names for sending messages to QAnywhere Server.

Members

All members of MessageProperties, including all inherited members.

  • ABS_RETRY_TIMEOUT Variable
  • ADAPTER Variable
  • FROM_ADDR Variable
  • MSG_TYPE Variable
  • NETWORK Variable
  • NETWORK_STATUS Variable
  • RETRY_FAILED Variable
  • RETRY_FAILED_ADDR Variable
  • RETRY_FAILED_PRIORITY Variable
  • RETRY_MAX Variable
  • RETRY_TIMEOUT Variable

ABS_RETRY_TIMEOUT Variable
ADAPTER Variable
FROM_ADDR Variable
MSG_TYPE Variable
NETWORK Variable
NETWORK_STATUS Variable
RETRY_FAILED Variable
RETRY_FAILED_ADDR Variable
RETRY_FAILED_PRIORITY Variable
RETRY_MAX Variable
RETRY_TIMEOUT Variable


ABS_RETRY_TIMEOUT Variable

Synopsis

const qa_string MessageProperties::ABS_RETRY_TIMEOUT

Remarks

Optional property for messages sent through a connector. The time at which send retries through the connector will be stopped and the send is failed.


ADAPTER Variable

Synopsis

const qa_string MessageProperties::ADAPTER

Remarks

For "system" queue messages, a delimited list of network adapters that can be used to connect to the QAnywhere server.


FROM_ADDR Variable

Synopsis

const qa_string MessageProperties::FROM_ADDR

Remarks

Optional property indicating the address of the sender.


MSG_TYPE Variable

Synopsis

const qa_string MessageProperties::MSG_TYPE

Remarks

Indicates the type of the message. If a message does not have this property set, it is a regular data message (ie. REGULAR Variable).

See Also

Class MessageType


NETWORK Variable

Synopsis

const qa_string MessageProperties::NETWORK

Remarks

For "system" queue messages, a delimited list of network names that can be used to connect to the QAnywhere server.


NETWORK_STATUS Variable

Synopsis

const qa_string MessageProperties::NETWORK_STATUS

Remarks

For "system" queue messages, the state of the network connection. Value is 1 if connected, 0 otherwise.


RETRY_FAILED Variable

Synopsis

const qa_string MessageProperties::RETRY_FAILED

Remarks

Set by the connector when sending a message to the RetryFailedAddress. The receiving client can use this property to identify messages for which re-sending failed.


RETRY_FAILED_ADDR Variable

Synopsis

const qa_string MessageProperties::RETRY_FAILED_ADDR

Remarks

Optional property for messages sent through a connector. Once either the RetryMax or RetryTimeout is exceeded, if this property is set, the message will be sent to this address.


RETRY_FAILED_PRIORITY Variable

Synopsis

const qa_string MessageProperties::RETRY_FAILED_PRIORITY

Remarks

Optional property for messages sent through a connector. If a message is sent to the RetryFailedAddress, the message priority will be set to this.


RETRY_MAX Variable

Synopsis

const qa_string MessageProperties::RETRY_MAX

Remarks

Optional property for messages sent through a connector. The maximum number of send retries at the connector before failing the send.


RETRY_TIMEOUT Variable

Synopsis

const qa_string MessageProperties::RETRY_TIMEOUT

Remarks

Optional property for messages sent through a connector. The duration after which send retries through the connector will be stopped and the send is failed.


Class MessageType

Synopsis

public MessageType

Remarks

This class defines constant values for the message property "ias_MessageType".

See Also

MSG_TYPE Variable

Members

All members of MessageType, including all inherited members.

  • NETWORK_STATUS_NOTIFICATION Variable
  • PUSH_NOTIFICATION Variable
  • REGULAR Variable


NETWORK_STATUS_NOTIFICATION Variable

Synopsis

const qa_int MessageType::NETWORK_STATUS_NOTIFICATION

Remarks

Message is a network status notification. Indicates a change in the network status.


PUSH_NOTIFICATION Variable

Synopsis

const qa_int MessageType::PUSH_NOTIFICATION

Remarks

Message is a push notification. Indicates that a message is waiting to be sent from the QAnywhere server.


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class MessageType

REGULAR Variable

Synopsis

const qa_int MessageType::REGULAR

Remarks

Regular data message.


Class QABinaryMessage

Synopsis

public QABinaryMessage

Base classes
  • Class QAMessage
Remarks

An QABinaryMessage object is used to send a message containing a stream of uninterpreted bytes. It inherits from the Class QAMessage class and adds a bytes message body. The receiver of the message supplies the interpretation of the bytes.

When the message is first created, the body of the message is in write-only mode. After the first call to reset has been made, the message body is in read-only mode. After a message has been sent, the client that sent it can retain and modify it without affecting the message that has been sent. The same message object can be sent multiple times. When a message has been received, the provider has called reset so that the message body is in read-only mode for the client.

If a client attempts to write a message in read-only mode, a COMMON_MSG_NOT_WRITEABLE_ERROR is set.

Members

All members of QABinaryMessage, including all inherited members.

  • castToBinaryMessage Function
  • castToTextMessage Function
  • clearProperties Function
  • DEFAULT_PRIORITY Variable
  • DEFAULT_TIME_TO_LIVE Variable
  • getAddress Function
  • getBodyLength Function
  • getBooleanProperty Function
  • getByteProperty Function
  • getDoubleProperty Function
  • getExpiration Function
  • getFloatProperty Function
  • getInReplyToID Function
  • getIntProperty Function
  • getLongProperty Function
  • getMessageID Function
  • getPriority Function
  • getPropertyNames Function
  • getPropertyType Function
  • getRedelivered Function
  • getReplyToAddress Function
  • getShortProperty Function
  • getStringProperty Function
  • getStringProperty Function
  • getTimestamp Function
  • getTimestampAsString Function
  • propertyExists Function
  • readBinary Function
  • readBoolean Function
  • readByte Function
  • readChar Function
  • readDouble Function
  • readFloat Function
  • readInt Function
  • readLong Function
  • readShort Function
  • readString Function
  • reset Function
  • setAddress Function
  • setBooleanProperty Function
  • setByteProperty Function
  • setDoubleProperty Function
  • setFloatProperty Function
  • setInReplyToID Function
  • setIntProperty Function
  • setLongProperty Function
  • setMessageID Function
  • setPriority Function
  • setRedelivered Function
  • setReplyToAddress Function
  • setShortProperty Function
  • setStringProperty Function
  • setTimestamp Function
  • writeBinary Function
  • writeBoolean Function
  • writeByte Function
  • writeChar Function
  • writeDouble Function
  • writeFloat Function
  • writeInt Function
  • writeLong Function
  • writeShort Function
  • writeString Function
  • ~QABinaryMessage Function
  • ~QAMessage Function

getBodyLength Function
readBinary Function
readBoolean Function
readByte Function
readChar Function
readDouble Function
readFloat Function
readInt Function
readLong Function
readShort Function
readString Function
reset Function
writeBinary Function
writeBoolean Function
writeByte Function
writeChar Function
writeDouble Function
writeFloat Function
writeInt Function
writeLong Function
writeShort Function
writeString Function
~QABinaryMessage Function


getBodyLength Function

Synopsis

virtual qa_long QABinaryMessage::getBodyLength()

Remarks

Returns the size in qa_bytes of the message body.


readBinary Function

Synopsis

virtual qa_int QABinaryMessage::readBinary(
qa_bytes value
qa_int length
)

Parameters

  • value the buffer into which the data is read

  • length the maximum number of bytes to read

Remarks

Reads a portion of the bytes message stream.

Returns

the total number of bytes read into the buffer, or -1 if there is no more data because the end of the stream has been reached


readBoolean Function

Synopsis

virtual qa_bool QABinaryMessage::readBoolean(
qa_bool * value
)

Parameters

  • value the destination of the qa_bool value read from the bytes message stream

Remarks

Reads a qa_bool from the bytes message stream.

Returns

true if and only if the operation succeeded


readByte Function

Synopsis

virtual qa_bool QABinaryMessage::readByte(
qa_byte * value
)

Parameters

  • value the destination of the qa_byte value read from the bytes message stream

Remarks

Reads a signed 8-bit value from the bytes message stream.

Returns

true if and only if the operation succeeded


readChar Function

Synopsis

virtual qa_bool QABinaryMessage::readChar(
qa_char * value
)

Parameters

  • value the destination of the qa_char value read from the bytes message stream

Remarks

Reads a character value from the bytes message stream.

Returns

true if and only if the operation succeeded


readDouble Function

Synopsis

virtual qa_bool QABinaryMessage::readDouble(
qa_double * value
)

Parameters

  • value the destination of the qa_double value read from the bytes message stream

Remarks

Reads a double from the bytes message stream.

Returns

true if and only if the operation succeeded


readFloat Function

Synopsis

virtual qa_bool QABinaryMessage::readFloat(
qa_float * value
)

Parameters

  • value the destination of the qa_float value read from the bytes message stream

Remarks

Reads a float from the bytes message stream.

Returns

true if and only if the operation succeeded


readInt Function

Synopsis

virtual qa_bool QABinaryMessage::readInt(
qa_int * value
)

Parameters

  • value the destination of the qa_int value read from the bytes message stream

Remarks

Reads a signed 32-bit integer from the bytes message stream.

Returns

true if and only if the operation succeeded


readLong Function

Synopsis

virtual qa_bool QABinaryMessage::readLong(
qa_long * value
)

Parameters

  • value the destination of the qa_long value read from the bytes message stream

Remarks

Reads a signed 64-bit integer from the bytes message stream.

Returns

true if and only if the operation succeeded


readShort Function

Synopsis

virtual qa_bool QABinaryMessage::readShort(
qa_short * value
)

Parameters

  • value the destination of the qa_short value read from the bytes message stream

Remarks

Reads a signed 16-bit number from the bytes message stream.

Returns

true if and only if the operation succeeded


readString Function

Synopsis

virtual qa_int QABinaryMessage::readString(
qa_string dest
qa_int maxLen
)

Parameters

  • dest the destination of the qa_string value read from the bytes message stream

  • maxLen the maximum number of qa_chars to read, including the null terminator qa_char

Remarks

Reads a string from the bytes message stream.

Returns

the total number of non-null qa_chars read into the buffer, or -1 if there is no more data, or the buffer is too small


reset Function

Synopsis

virtual void QABinaryMessage::reset()

Remarks

Puts the message body in read-only mode and repositions the stream of bytes to the beginning.


writeBinary Function

Synopsis

virtual void QABinaryMessage::writeBinary(
qa_const_bytes value
qa_int offset
qa_int length
)

Parameters

  • value the byte array value to be written

  • offset the initial offset within the byte array

  • length the number of bytes to write

Remarks

Writes a portion of a byte array to the bytes message stream.


writeBoolean Function

Synopsis

virtual void QABinaryMessage::writeBoolean(
qa_bool value
)

Parameters

  • value the qa_bool value to be written

Remarks

Writes a qa_bool to the bytes message stream as a 1-byte value. The value true is written as the value (qa_byte)1 ; the value false is written as the value (qa_byte)0 .


writeByte Function

Synopsis

virtual void QABinaryMessage::writeByte(
qa_byte value
)

Parameters

  • value the qa_byte value to be written

Remarks

Writes a qa_byte to the bytes message stream as a 1-byte value.


writeChar Function

Synopsis

virtual void QABinaryMessage::writeChar(
qa_char value
)

Parameters

  • value the qa_char value to be written

Remarks

Writes a qa_char to the bytes message stream as a 2-byte value, high byte first.


writeDouble Function

Synopsis

virtual void QABinaryMessage::writeDouble(
qa_double value
)

Parameters

  • value the qa_double to be written

Remarks

Converts the qa_double argument to a qa_long and then writes that qa_long value to the bytes message stream as an 8-byte quantity, high byte first.


writeFloat Function

Synopsis

virtual void QABinaryMessage::writeFloat(
qa_float value
)

Parameters

  • value the qa_float to be written

Remarks

Converts the qa_float argument to a qa_int and then writes that qa_int value to the bytes message stream as a 4-byte quantity, high byte first.


writeInt Function

Synopsis

virtual void QABinaryMessage::writeInt(
qa_int value
)

Parameters

  • value the qa_int to be written

Remarks

Writes a qa_int to the bytes message stream as four bytes, high byte first.


writeLong Function

Synopsis

virtual void QABinaryMessage::writeLong(
qa_long value
)

Parameters

  • value the qa_long to be written

Remarks

Writes a qa_long to the bytes message stream as eight bytes, high byte first.


writeShort Function

Synopsis

virtual void QABinaryMessage::writeShort(
qa_short value
)

Parameters

  • value the qa_short to be written

Remarks

Writes a qa_short to the bytes message stream as two bytes, high byte first.


writeString Function

Synopsis

virtual void QABinaryMessage::writeString(
qa_const_string value
)

Parameters

  • value the string to be written

Remarks

Writes a string to the bytes message stream.


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QABinaryMessage

~QABinaryMessage Function

Synopsis

virtual QABinaryMessage::~QABinaryMessage()

Remarks

Virtual destructor.


Class QAError

Synopsis

public QAError

Remarks

This class defines error constants associated with the QAnywhere client. A QAError object is used internally by the Class QAManager object to keep track of errors associated with messaging operations. The application programmer should not need to create an instance of this class. The error constants should be used by the application programmer when interpreting error codes returned by getLastError Function

See Also

getLastErrorMsg Function

Members

All members of QAError, including all inherited members.

  • COMMON_GET_INIT_FILE_ERROR Variable
  • COMMON_INIT_ERROR Variable
  • COMMON_INIT_THREAD_ERROR Variable
  • COMMON_INVALID_PROPERTY Variable
  • COMMON_MSG_NOT_WRITEABLE_ERROR Variable
  • COMMON_MSG_RETRIEVE_ERROR Variable
  • COMMON_MSG_STORE_ERROR Variable
  • COMMON_MSG_STORE_NOT_INITIALIZED Variable
  • COMMON_MSG_STORE_TOO_LARGE Variable
  • COMMON_NO_DEST_ERROR Variable
  • COMMON_NO_IMPLEMENTATION Variable
  • COMMON_OPEN_ERROR Variable
  • COMMON_OPEN_LOG_FILE_ERROR Variable
  • COMMON_TERMINATE_ERROR Variable
  • COMMON_UNEXPECTED_EOM_ERROR Variable
  • QA_NO_ERROR Variable
  • ~QAError Function

COMMON_GET_INIT_FILE_ERROR Variable
COMMON_INIT_ERROR Variable
COMMON_INIT_THREAD_ERROR Variable
COMMON_INVALID_PROPERTY Variable
COMMON_MSG_NOT_WRITEABLE_ERROR Variable
COMMON_MSG_RETRIEVE_ERROR Variable
COMMON_MSG_STORE_ERROR Variable
COMMON_MSG_STORE_NOT_INITIALIZED Variable
COMMON_MSG_STORE_TOO_LARGE Variable
COMMON_NO_DEST_ERROR Variable
COMMON_NO_IMPLEMENTATION Variable
COMMON_OPEN_ERROR Variable
COMMON_OPEN_LOG_FILE_ERROR Variable
COMMON_TERMINATE_ERROR Variable
COMMON_UNEXPECTED_EOM_ERROR Variable
QA_NO_ERROR Variable
~QAError Function


COMMON_GET_INIT_FILE_ERROR Variable

Synopsis

const qa_int QAError::COMMON_GET_INIT_FILE_ERROR

Remarks

Unable to access client properties file.


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QAError

COMMON_INIT_ERROR Variable

Synopsis

const qa_int QAError::COMMON_INIT_ERROR

Remarks

Initialization error.


COMMON_INIT_THREAD_ERROR Variable

Synopsis

const qa_int QAError::COMMON_INIT_THREAD_ERROR

Remarks

Error initializing background thread.


COMMON_INVALID_PROPERTY Variable

Synopsis

const qa_int QAError::COMMON_INVALID_PROPERTY

Remarks

There is an invalid property in the client properties file.


COMMON_MSG_NOT_WRITEABLE_ERROR Variable

Synopsis

const qa_int QAError::COMMON_MSG_NOT_WRITEABLE_ERROR

Remarks

Message is not writeable.


COMMON_MSG_RETRIEVE_ERROR Variable

Synopsis

const qa_int QAError::COMMON_MSG_RETRIEVE_ERROR

Remarks

Error retrieving message from message store.


COMMON_MSG_STORE_ERROR Variable

Synopsis

const qa_int QAError::COMMON_MSG_STORE_ERROR

Remarks

Error storing message to message store.


COMMON_MSG_STORE_NOT_INITIALIZED Variable

Synopsis

const qa_int QAError::COMMON_MSG_STORE_NOT_INITIALIZED

Remarks

The message store has not been initialized for messaging.


COMMON_MSG_STORE_TOO_LARGE Variable

Synopsis

const qa_int QAError::COMMON_MSG_STORE_TOO_LARGE

Remarks

The message store is too large relative to the disk free space on the device.


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QAError

COMMON_NO_DEST_ERROR Variable

Synopsis

const qa_int QAError::COMMON_NO_DEST_ERROR

Remarks

No destination.


COMMON_NO_IMPLEMENTATION Variable

Synopsis

const qa_int QAError::COMMON_NO_IMPLEMENTATION

Remarks

The function is not implemented.


COMMON_OPEN_ERROR Variable

Synopsis

const qa_int QAError::COMMON_OPEN_ERROR

Remarks

Error opening connection to message store.


COMMON_OPEN_LOG_FILE_ERROR Variable

Synopsis

const qa_int QAError::COMMON_OPEN_LOG_FILE_ERROR

Remarks

Error opening the log file.


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QAError

COMMON_TERMINATE_ERROR Variable

Synopsis

const qa_int QAError::COMMON_TERMINATE_ERROR

Remarks

Termination error.


COMMON_UNEXPECTED_EOM_ERROR Variable

Synopsis

const qa_int QAError::COMMON_UNEXPECTED_EOM_ERROR

Remarks

Unexpected end of message reached.


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QAError

QA_NO_ERROR Variable

Synopsis

const qa_int QAError::QA_NO_ERROR

Remarks

No error.


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QAError

~QAError Function

Synopsis

virtual QAError::~QAError()

Remarks

Virtual destructor.


Class QAManager

Synopsis

public QAManager

Base classes
  • Class QAManagerBase
Remarks

This class is the manager for non-transactional messaging.

Members

All members of QAManager, including all inherited members.

  • acknowledge Function
  • acknowledgeAll Function
  • acknowledgeUntil Function
  • close Function
  • createBinaryMessage Function
  • createTextMessage Function
  • deleteMessage Function
  • getBooleanStoreProperty Function
  • getByteStoreProperty Function
  • getDoubleStoreProperty Function
  • getFloatStoreProperty Function
  • getIntStoreProperty Function
  • getLastError Function
  • getLastErrorMsg Function
  • getLongStoreProperty Function
  • getMessage Function
  • getMessageNoWait Function
  • getMessageTimeout Function
  • getMode Function
  • getShortStoreProperty Function
  • getStringStoreProperty Function
  • open Function
  • peekFirstMessage Function
  • peekNextMessage Function
  • publishMessage Function
  • putMessage Function
  • putMessageTimeToLive Function
  • recover Function
  • setBooleanStoreProperty Function
  • setByteStoreProperty Function
  • setDoubleStoreProperty Function
  • setFloatStoreProperty Function
  • setIntStoreProperty Function
  • setLongStoreProperty Function
  • setMessageListener Function
  • setProperty Function
  • setShortStoreProperty Function
  • setStringStoreProperty Function
  • start Function
  • stop Function
  • triggerSendReceive Function
  • ~QAManager Function
  • ~QAManagerBase Function


acknowledge Function

Synopsis

virtual qa_bool QAManager::acknowledge(
QAMessage * msg
)

Parameters

  • msg the message

Remarks

Acknowledges the given message.

Returns

true if and only if the operation succeeded


acknowledgeAll Function

Synopsis

virtual qa_bool QAManager::acknowledgeAll()

Remarks

Acknowledges all messages.

Returns

true if and only if the operation succeeded


acknowledgeUntil Function

Synopsis

virtual qa_bool QAManager::acknowledgeUntil(
QAMessage * msg
)

Parameters

  • msg the message

Remarks

Acknowledges the given message and all previous messages.

Returns

true if and only if the operation succeeded


open Function

Synopsis

virtual qa_bool QAManager::open(
qa_short mode
)

Parameters

  • mode the acknowledge mode

Remarks

Opens the QAManager with the given acknowledge mode.

Returns

true if and only if the operation succeeded

See Also

Class AcknowledgementMode


recover Function

Synopsis

virtual qa_bool QAManager::recover()

Remarks

Recovers all unacknowledged messages.

Returns

true if and only if the operation succeeded


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QAManager

~QAManager Function

Synopsis

virtual QAManager::~QAManager()

Remarks

Virtual destructor.


Class QAManagerBase

Synopsis

public QAManagerBase

Derived classes
  • Class QAManager
  • Class QATransactionalManager
Remarks

This class acts as a base class for Class QATransactionalManager and Class QAManager, which manage transactional and non-transactional messaging respectively. There must be a single instance of QAManagerBase per thread in the application. This class is also a factory for creating messages. Since the getMessage Function methods also create messages, this class manages all messages, so that they can be released from memory either at a user method call, or when the QAManagerBase is closed. The publishMessage Function methods will always return false, since the publish/subscribe model is not supported.

Members

All members of QAManagerBase, including all inherited members.

  • close Function
  • createBinaryMessage Function
  • createTextMessage Function
  • deleteMessage Function
  • getBooleanStoreProperty Function
  • getByteStoreProperty Function
  • getDoubleStoreProperty Function
  • getFloatStoreProperty Function
  • getIntStoreProperty Function
  • getLastError Function
  • getLastErrorMsg Function
  • getLongStoreProperty Function
  • getMessage Function
  • getMessageNoWait Function
  • getMessageTimeout Function
  • getMode Function
  • getShortStoreProperty Function
  • getStringStoreProperty Function
  • peekFirstMessage Function
  • peekNextMessage Function
  • publishMessage Function
  • putMessage Function
  • putMessageTimeToLive Function
  • setBooleanStoreProperty Function
  • setByteStoreProperty Function
  • setDoubleStoreProperty Function
  • setFloatStoreProperty Function
  • setIntStoreProperty Function
  • setLongStoreProperty Function
  • setMessageListener Function
  • setProperty Function
  • setShortStoreProperty Function
  • setStringStoreProperty Function
  • start Function
  • stop Function
  • triggerSendReceive Function
  • ~QAManagerBase Function

close Function
createBinaryMessage Function
createTextMessage Function
deleteMessage Function
getBooleanStoreProperty Function
getByteStoreProperty Function
getDoubleStoreProperty Function
getFloatStoreProperty Function
getIntStoreProperty Function
getLastError Function
getLastErrorMsg Function
getLongStoreProperty Function
getMessage Function
getMessageNoWait Function
getMessageTimeout Function
getMode Function
getShortStoreProperty Function
getStringStoreProperty Function
peekFirstMessage Function
peekNextMessage Function
publishMessage Function
putMessage Function
putMessageTimeToLive Function
setBooleanStoreProperty Function
setByteStoreProperty Function
setDoubleStoreProperty Function
setFloatStoreProperty Function
setIntStoreProperty Function
setLongStoreProperty Function
setMessageListener Function
setProperty Function
setShortStoreProperty Function
setStringStoreProperty Function
start Function
stop Function
triggerSendReceive Function
~QAManagerBase Function


close Function

Synopsis

virtual qa_bool QAManagerBase::close()

Remarks

Closes the QAManagerBase. This releases all resources associated with the instance. When an instance of QAManagerBase is closed, it cannot be re-opened; a new instance must be created and opened in this case.

Returns

true if and only if the operation succeeded


createBinaryMessage Function

Synopsis

virtual QABinaryMessage * QAManagerBase::createBinaryMessage()

Remarks

Creates a QABinaryMessage object. A QABinaryMessage object is used to send a message containing a stream of uninterpreted bytes.

Returns

the message that was created


createTextMessage Function

Synopsis

virtual QATextMessage * QAManagerBase::createTextMessage()

Remarks

Creates a QATextMessage object. A QATextMessage object is used to send a message containing a qa_string value.

Returns

the message that was created


deleteMessage Function

Synopsis

virtual void QAManagerBase::deleteMessage(
QAMessage * msg
)

Parameters

  • msg the message to be deleted

Remarks

Deletes a QAMessage object. By default, messages created by the above methods are deleted automatically when the QAManagerBase is closed. This method allows more control over when messages are deleted.


getBooleanStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::getBooleanStoreProperty(
qa_const_string name
qa_bool * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_bool value

Remarks

Gets the value of the qa_bool message store property with the specified name.

Returns

true if and only if the operation succeeded


getByteStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::getByteStoreProperty(
qa_const_string name
qa_byte * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_byte value

Remarks

Gets the value of the qa_byte message store property with the specified name.

Returns

true if and only if the operation succeeded


getDoubleStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::getDoubleStoreProperty(
qa_const_string name
qa_double * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_double value

Remarks

Gets the value of the qa_double message store property with the specified name.

Returns

true if and only if the operation succeeded


getFloatStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::getFloatStoreProperty(
qa_const_string name
qa_float * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_float value

Remarks

Gets the value of the qa_float message store property with the specified name.

Returns

true if and only if the operation succeeded


getIntStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::getIntStoreProperty(
qa_const_string name
qa_int * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_int value

Remarks

Gets the value of the qa_int message store property with the specified name.

Returns

true if and only if the operation succeeded


getLastError Function

Synopsis

virtual qa_int QAManagerBase::getLastError()

Remarks

Gets the error code of the last method call that failed.

Returns

the error code


getLastErrorMsg Function

Synopsis

virtual qa_string QAManagerBase::getLastErrorMsg()

Remarks

Gets an error message corresponding to the error code.

Returns

the error message


getLongStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::getLongStoreProperty(
qa_const_string name
qa_long * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_long value

Remarks

Gets the value of the qa_long message store property with the specified name.

Returns

true if and only if the operation succeeded


getMessage Function

Synopsis

virtual QAMessage * QAManagerBase::getMessage(
qa_const_string dest
)

Parameters

  • dest the destination

Remarks

Gets the next message that is queued for the given destination, waiting indefinitely if there are currently no messages queued.

Returns

the next message, or qa_null if no message is available


getMessageNoWait Function

Synopsis

virtual QAMessage * QAManagerBase::getMessageNoWait(
qa_const_string dest
)

Parameters

  • dest the destination

Remarks

Gets the next message that is queued for the given destination, returning qa_null if there are currently no messages queued.

Returns

the next message, or qa_null if no message is available


getMessageTimeout Function

Synopsis

virtual QAMessage * QAManagerBase::getMessageTimeout(
qa_const_string dest
qa_long timeout
)

Parameters

  • dest the destination

  • timeout the maximum time, in milliseconds, to wait

Remarks

Gets the next message that is queued for the given destination, waiting at most timeout milliseconds if there are currently no messages queued.

Returns

the next message, or qa_null if no message is available


getMode Function

Synopsis

virtual qa_short QAManagerBase::getMode()

Remarks

Gets the acknowledge mode of this instance of QAManagerBase. Mode is IMPLICIT_ACKNOWLEDGE or EXPLICIT_ACKNOWLEDGE or TRANSACTIONAL.

Returns

the acknowledge mode

See Also

Class AcknowledgementMode


getShortStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::getShortStoreProperty(
qa_const_string name
qa_short * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_short value

Remarks

Gets the value of the qa_short message store property with the specified name.

Returns

true if and only if the operation succeeded


getStringStoreProperty Function

Synopsis

virtual qa_int QAManagerBase::getStringStoreProperty(
qa_const_string name
qa_string dest
qa_int maxlen
)

Parameters

  • name the name of the property to get

  • dest the destination for the qa_string value

  • maxlen the maximum number of qa_chars of the value to copy, including the null terminator qa_char

Remarks

Gets the value of the message store property with the specified name.

Returns

the number of non-null qa_chars actually copied, or -1 if the operation failed


peekFirstMessage Function

Synopsis

virtual QAMessage * QAManagerBase::peekFirstMessage(
qa_const_string dest
)

Parameters

  • dest the destination

Remarks

Looks at the first message that is queued for the given destination, returning qa_null if there are currently no messages queued. This method is used before peekNextMessage, which can be used to enumerate the messages queued for the given destination at the time this method was called.

Returns

the next message, or qa_null if no message is available


peekNextMessage Function

Synopsis

virtual QAMessage * QAManagerBase::peekNextMessage()

Remarks

Looks at the next message that is queued for the given destination, returning qa_null if there are currently no more messages queued. This method is used after peekFirstMessage, and can be used to enumerate the messages queued for the given destination at the time peekFirstMessage was called.

Returns

the next message, or qa_null if no message is available


publishMessage Function

Synopsis

virtual qa_bool QAManagerBase::publishMessage(
qa_const_string dest
QAMessage * msg
)

Parameters

  • dest the destination

  • msg the message

Remarks

Not implemented.


putMessage Function

Synopsis

virtual qa_bool QAManagerBase::putMessage(
qa_const_string dest
QAMessage * msg
)

Parameters

  • dest the destination

  • msg the message

Remarks

Puts a message into the queue for the given destination.

Returns

true if and only if the operation succeeded


putMessageTimeToLive Function

Synopsis

virtual qa_bool QAManagerBase::putMessageTimeToLive(
qa_const_string dest
QAMessage * msg
qa_long ttl
)

Parameters

  • dest the destination

  • msg the message

  • ttl the time-to-live, in milliseconds

Remarks

Puts a message into the queue for the given destination and a given time-to-live in milliseconds.

Returns

true if and only if the operation succeeded


setBooleanStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::setBooleanStoreProperty(
qa_const_string name
qa_bool value
)

Parameters

  • name the name of the property to set

  • value the qa_bool value of the property

Remarks

Sets a qa_bool message store property value with the specified name.

Returns

true if and only if the operation succeeded


setByteStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::setByteStoreProperty(
qa_const_string name
qa_byte value
)

Parameters

  • name the name of the property to set

  • value the qa_byte value of the property

Remarks

Sets a qa_byte message store property value with the specified name.

Returns

true if and only if the operation succeeded


setDoubleStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::setDoubleStoreProperty(
qa_const_string name
qa_double value
)

Parameters

  • name the name of the property to set

  • value the qa_double value of the property

Remarks

Sets a qa_double message store property value with the specified name.

Returns

true if and only if the operation succeeded


setFloatStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::setFloatStoreProperty(
qa_const_string name
qa_float value
)

Parameters

  • name the name of the property to set

  • value the qa_float value of the property

Remarks

Sets a qa_float message store property value with the specified name.

Returns

true if and only if the operation succeeded


setIntStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::setIntStoreProperty(
qa_const_string name
qa_int value
)

Parameters

  • name the name of the property to set

  • value the qa_int value of the property

Remarks

Sets a qa_int message store property value with the specified name.

Returns

true if and only if the operation succeeded


setLongStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::setLongStoreProperty(
qa_const_string name
qa_long value
)

Parameters

  • name the name of the property to set

  • value the qa_long value of the property

Remarks

Sets a qa_long message store property value with the specified name.

Returns

true if and only if the operation succeeded


setMessageListener Function

Synopsis

virtual void QAManagerBase::setMessageListener(
qa_const_string dest
QAMessageListener * listener
)

Parameters

  • dest the destination address that the listener applies to.

  • listener the message listener to associate with destination dest.

Remarks

Sets the message listener associated with a destination.


setProperty Function

Synopsis

virtual qa_bool QAManagerBase::setProperty(
qa_const_string name
qa_const_string value
)

Parameters

  • name the name of the property to set

  • value the value of the property

Remarks

Sets the named property to the given value. Properties for this QAManagerBase may be set with this method as an alternative to the properties file at creation. Properties must be set before calling the open() methods of the derived classes.

Returns

true if and only if the operation succeeded


setShortStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::setShortStoreProperty(
qa_const_string name
qa_short value
)

Parameters

  • name the name of the property to set

  • value the qa_short value of the property

Remarks

Sets a qa_short message store property value with the specified name.

Returns

true if and only if the operation succeeded


setStringStoreProperty Function

Synopsis

virtual qa_bool QAManagerBase::setStringStoreProperty(
qa_const_string name
qa_const_string value
)

Parameters

  • name the name of the property to set

  • value the qa_string value of the property

Remarks

Sets the named message store property to the given value.

Returns

true if and only if the operation succeeded


start Function

Synopsis

virtual qa_bool QAManagerBase::start()

Remarks

Starts the QAManagerBase for receiving incoming messages.

Returns

true if and only if the operation succeeded


stop Function

Synopsis

virtual qa_bool QAManagerBase::stop()

Remarks

Stops the QAManagerBase's reception of incoming messages.

Returns

true if and only if the operation succeeded


triggerSendReceive Function

Synopsis

virtual qa_bool QAManagerBase::triggerSendReceive()

Remarks

Causes any pending messages to be sent and received. This includes both messages queued locally, and messages queued on the server for local destinations.

Returns

true if and only if the operation succeeded


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QAManagerBase

~QAManagerBase Function

Synopsis

virtual QAManagerBase::~QAManagerBase()

Remarks

Virtual destructor


Class QAManagerFactory

Synopsis

public QAManagerFactory

Remarks

This class acts as a factory class for creating Class QATransactionalManager and Class QAManager objects.

Members

All members of QAManagerFactory, including all inherited members.

  • createQAManager Function
  • createQATransactionalManager Function
  • deleteQAManager Function
  • deleteQATransactionalManager Function
  • getLastError Function
  • getLastErrorMsg Function
  • ~QAManagerFactory Function

createQAManager Function
createQATransactionalManager Function
deleteQAManager Function
deleteQATransactionalManager Function
getLastError Function
getLastErrorMsg Function
~QAManagerFactory Function


createQAManager Function

Synopsis

virtual QAManager * QAManagerFactory::createQAManager(
qa_const_string iniFile
)

Parameters

  • iniFile the path of the properties file

Remarks

Returns a new instance of a Class QAManager with specified properties.

Returns

the Class QAManager instance


createQATransactionalManager Function

Synopsis

virtual QATransactionalManager * QAManagerFactory::createQATransactionalManager(
qa_const_string iniFile
)

Parameters

  • iniFile the path of the properties file

Remarks

Returns a new instance of a Class QATransactionalManager with specified properties.

Returns

the Class QATransactionalManager instance


deleteQAManager Function

Synopsis

virtual void QAManagerFactory::deleteQAManager(
QAManager * mgr
)

Parameters

  • mgr the Class QAManager to be destroyed

Remarks

Destroys a Class QAManager, freeing its resources. It is not necessary to use this method, since all created QAManager's will be destroyed when QAnywhereFactory_term() is called. It is provided as a convenience for when it is desirable to free resources in a timely manner.


deleteQATransactionalManager Function

Synopsis

virtual void QAManagerFactory::deleteQATransactionalManager(
QATransactionalManager * mgr
)

Parameters

  • mgr the Class QATransactionalManager to be destroyed

Remarks

Destroys a Class QATransactionalManager, freeing its resources. It is not necessary to use this method, since all created QATransactionalManager's will be destroyed when QAnywhereFactory_term() is called. It is provided as a convenience for when it is desirable to free resources in a timely manner.


getLastError Function

Synopsis

virtual qa_int QAManagerFactory::getLastError()

Remarks

Gets the error code of the last method call that failed.

Returns

the error code


getLastErrorMsg Function

Synopsis

virtual qa_string QAManagerFactory::getLastErrorMsg()

Remarks

Gets an error message corresponding to the error code.

Returns

the error message


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QAManagerFactory

~QAManagerFactory Function

Synopsis

virtual QAManagerFactory::~QAManagerFactory()

Remarks

Virtual destructor


Class QAMessage

Synopsis

public QAMessage

Derived classes
  • Class QABinaryMessage
  • Class QATextMessage
Remarks

The QAMessage interface is the root interface of all QAnywhere client messages.

Members

All members of QAMessage, including all inherited members.

  • castToBinaryMessage Function
  • castToTextMessage Function
  • clearProperties Function
  • DEFAULT_PRIORITY Variable
  • DEFAULT_TIME_TO_LIVE Variable
  • getAddress Function
  • getBooleanProperty Function
  • getByteProperty Function
  • getDoubleProperty Function
  • getExpiration Function
  • getFloatProperty Function
  • getInReplyToID Function
  • getIntProperty Function
  • getLongProperty Function
  • getMessageID Function
  • getPriority Function
  • getPropertyNames Function
  • getPropertyType Function
  • getRedelivered Function
  • getReplyToAddress Function
  • getShortProperty Function
  • getStringProperty Function
  • getStringProperty Function
  • getTimestamp Function
  • getTimestampAsString Function
  • propertyExists Function
  • setAddress Function
  • setBooleanProperty Function
  • setByteProperty Function
  • setDoubleProperty Function
  • setFloatProperty Function
  • setInReplyToID Function
  • setIntProperty Function
  • setLongProperty Function
  • setMessageID Function
  • setPriority Function
  • setRedelivered Function
  • setReplyToAddress Function
  • setShortProperty Function
  • setStringProperty Function
  • setTimestamp Function
  • ~QAMessage Function

DEFAULT_PRIORITY Variable
DEFAULT_TIME_TO_LIVE Variable
castToBinaryMessage Function
castToTextMessage Function
clearProperties Function
getAddress Function
getBooleanProperty Function
getByteProperty Function
getDoubleProperty Function
getExpiration Function
getFloatProperty Function
getInReplyToID Function
getIntProperty Function
getLongProperty Function
getMessageID Function
getPriority Function
getPropertyNames Function
getPropertyType Function
getRedelivered Function
getReplyToAddress Function
getShortProperty Function
getStringProperty Function
getStringProperty Function
getTimestamp Function
getTimestampAsString Function
propertyExists Function
setAddress Function
setBooleanProperty Function
setByteProperty Function
setDoubleProperty Function
setFloatProperty Function
setInReplyToID Function
setIntProperty Function
setLongProperty Function
setMessageID Function
setPriority Function
setRedelivered Function
setReplyToAddress Function
setShortProperty Function
setStringProperty Function
setTimestamp Function
~QAMessage Function


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QAMessage

DEFAULT_PRIORITY Variable

Synopsis

const qa_int QAMessage::DEFAULT_PRIORITY

Remarks

The default message priority.


DEFAULT_TIME_TO_LIVE Variable

Synopsis

const qa_long QAMessage::DEFAULT_TIME_TO_LIVE

Remarks

The default message time-to-live value.


castToBinaryMessage Function

Synopsis

virtual QABinaryMessage * QAMessage::castToBinaryMessage()

Remarks

Casts this QAMessage to a Class QABinaryMessage.

Returns

a pointer to the Class QABinaryMessage, or NULL if this message is not an instance of Class QABinaryMessage.


castToTextMessage Function

Synopsis

virtual QATextMessage * QAMessage::castToTextMessage()

Remarks

Casts this QAMessage to a Class QATextMessage.

Returns

a pointer to the Class QATextMessage, or NULL if this message is not an instance of Class QATextMessage.


clearProperties Function

Synopsis

virtual void QAMessage::clearProperties()

Remarks

Clears a message's properties. The message's header fields and body are not cleared.


getAddress Function

Synopsis

virtual qa_const_string QAMessage::getAddress()

Remarks

Gets the destination address for this message. When a message is sent, this field is ignored. After completion of the send or publish method, the field holds the destination specified by the method.

Returns

the destination address


getBooleanProperty Function

Synopsis

virtual qa_bool QAMessage::getBooleanProperty(
qa_const_string name
qa_bool * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_bool value

Remarks

Gets the value of the qa_bool property with the specified name.

Returns

true if and only if the operation succeeded


getByteProperty Function

Synopsis

virtual qa_bool QAMessage::getByteProperty(
qa_const_string name
qa_byte * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_byte value

Remarks

Gets the value of the qa_byte property with the specified name.

Returns

true if and only if the operation succeeded


getDoubleProperty Function

Synopsis

virtual qa_bool QAMessage::getDoubleProperty(
qa_const_string name
qa_double * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_double value

Remarks

Gets the value of the qa_double property with the specified name.

Returns

true if and only if the operation succeeded


getExpiration Function

Synopsis

virtual qa_long QAMessage::getExpiration()

Remarks

Gets the message's expiration value. When a message is sent, the Expiration header field is left unassigned. After completion of the send or publish method, it holds the expiration time of the message. This is the sum of the time-to-live value specified by the client and the GMT at the time of the send or publish. If the time-to-live is specified as zero, Expiration is set to zero to indicate that the message does not expire.

Returns

the expiration


getFloatProperty Function

Synopsis

virtual qa_bool QAMessage::getFloatProperty(
qa_const_string name
qa_float * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_float value

Remarks

Gets the value of the qa_float property with the specified name.

Returns

true if and only if the operation succeeded


getInReplyToID Function

Synopsis

virtual qa_const_string QAMessage::getInReplyToID()

Remarks

Gets the In-Reply-To ID for the message.

Returns

the In-Reply-To ID


getIntProperty Function

Synopsis

virtual qa_bool QAMessage::getIntProperty(
qa_const_string name
qa_int * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_int value

Remarks

Gets the value of the qa_int property with the specified name.

Returns

true if and only if the operation succeeded


getLongProperty Function

Synopsis

virtual qa_bool QAMessage::getLongProperty(
qa_const_string name
qa_long * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_long value

Remarks

Gets the value of the qa_long property with the specified name.

Returns

true if and only if the operation succeeded


getMessageID Function

Synopsis

virtual qa_const_string QAMessage::getMessageID()

Remarks

Gets the message ID. The MessageID header field contains a value that uniquely identifies each message sent by the QAnywhere client. When a message is sent, MessageID can be ignored. When the send method returns, it contains an assigned value. A MessageID is a qa_string value that should function as a unique key for identifying messages in a historical repository.

Returns

the message ID


getPriority Function

Synopsis

virtual qa_int QAMessage::getPriority()

Remarks

Gets the message priority level. The QAnywhere client API defines ten levels of priority value, with 0 as the lowest priority and 9 as the highest. In addition, clients should consider priorities 0-4 as gradations of normal priority and priorities 5-9 as gradations of expedited priority.

Returns

the priority


getPropertyNames Function

Synopsis

virtual qa_const_string * QAMessage::getPropertyNames()

Remarks

Returns a list of property names currently set in the QAMessage.

Returns

a NULL-terminated array of property names


getPropertyType Function

Synopsis

virtual qa_short QAMessage::getPropertyType(
qa_const_string name
)

Parameters

  • name the name of the property

Remarks

Returns the type of a property with the given name. One of PROPERTY_TYPE_BOOLEAN, PROPERTY_TYPE_BYTE, PROPERTY_TYPE_SHORT, PROPERTY_TYPE_INT, PROPERTY_TYPE_LONG, PROPERTY_TYPE_FLOAT, PROPERTY_TYPE_DOUBLE, PROPERTY_TYPE_STRING, PROPERTY_TYPE_UNKNOWN.

Returns

the type of the property


getRedelivered Function

Synopsis

virtual qa_bool QAMessage::getRedelivered()

Remarks

Gets an indication of whether this message is being redelivered.

Returns

whether the message was redelivered


getReplyToAddress Function

Synopsis

virtual qa_const_string QAMessage::getReplyToAddress()

Remarks

Gets the address to which a reply to this message should be sent.

Returns

the Reply-To address


getShortProperty Function

Synopsis

virtual qa_bool QAMessage::getShortProperty(
qa_const_string name
qa_short * value
)

Parameters

  • name the name of the property to get

  • value the destination for the qa_short value

Remarks

Gets the value of the qa_short property with the specified name.

Returns

true if and only if the operation succeeded


getStringProperty Function

Synopsis

virtual qa_int QAMessage::getStringProperty(
qa_const_string name
qa_string dest
qa_int maxlen
)

Parameters

  • name the name of the property to get

  • dest the destination for the qa_string value

  • maxlen the maximum number of qa_chars of the value to copy, including the null terminator qa_char

Remarks

Gets the value of the qa_string property with the specified name.

Returns

the number of non-null qa_chars actually copied, or -1 if the operation failed


getStringProperty Function

Synopsis

virtual qa_int QAMessage::getStringProperty(
qa_const_string name
qa_int offset
qa_string dest
qa_int maxlen
)

Parameters

  • name the name of the property to get

  • offset the starting offset into the property value from which to copy

  • dest the destination for the qa_string value

  • maxlen the maximum number of qa_chars of the value to copy, including the null terminator qa_char

Remarks

Gets the value of the qa_string property (starting at offset) with the specified name.

Returns

the number of non-null qa_chars actually copied, or -1 if the operation failed Returns the value of the qa_string property (starting at offset) with the specified name.


getTimestamp Function

Synopsis

virtual qa_long QAMessage::getTimestamp()

Remarks

Gets the message timestamp. The Timestamp header field contains the time a message was created. It is not the time the message was actually transmitted, because the actual send may occur later due to transactions or other client-side queuing of messages. It is in units that are natural for the platform. For Windows/PocketPC platforms, the timestamp is the SYSTEMTIME, converted to a FILETIME, which is copied to an qa_long value.

Returns

the message timestamp


getTimestampAsString Function

Synopsis

virtual qa_int QAMessage::getTimestampAsString(
qa_string buffer
qa_int bufferLen
)

Parameters

  • buffer the buffer for the formatted timestamp

  • bufferLen the size of the buffer

Remarks

Gets the message timestamp as a formatted string. The format is: "dow, MMM dd, yyyy hh:mm:ss.nnn GMT".

Returns

the number of non-null qa_char's written to the buffer


propertyExists Function

Synopsis

virtual qa_bool QAMessage::propertyExists(
qa_const_string name
)

Parameters

  • name the name of the property

Remarks

Indicates whether a property value exists.

Returns

true if and only if the property exists


setAddress Function

Synopsis

virtual void QAMessage::setAddress(
qa_const_string destination
)

Parameters

  • destination the destination address

Remarks

Sets the destination address for this message. This method can be used to change the value for a message that has been received.


setBooleanProperty Function

Synopsis

virtual void QAMessage::setBooleanProperty(
qa_const_string name
qa_bool value
)

Parameters

  • name the name of the property to set

  • value the qa_bool value of the property

Remarks

Sets a qa_bool property value with the specified name into the message.


setByteProperty Function

Synopsis

virtual void QAMessage::setByteProperty(
qa_const_string name
qa_byte value
)

Parameters

  • name the name of the property to set

  • value the qa_byte value of the property

Remarks

Sets a qa_byte property value with the specified name into the message.


setDoubleProperty Function

Synopsis

virtual void QAMessage::setDoubleProperty(
qa_const_string name
qa_double value
)

Parameters

  • name the name of the property to set

  • value the qa_double value of the property

Remarks

Sets a qa_double property value with the specified name into the message.


setFloatProperty Function

Synopsis

virtual void QAMessage::setFloatProperty(
qa_const_string name
qa_float value
)

Parameters

  • name the name of the property to set

  • value the qa_float value of the property

Remarks

Sets a qa_float property value with the specified name into the message.


setInReplyToID Function

Synopsis

virtual void QAMessage::setInReplyToID(
qa_const_string id
)

Parameters

  • id the In-Reply-To ID

Remarks

Sets the In-Reply-To ID for the message. A client can use the InReplyToID header field to link one message with another. A typical use is to link a response message with its request message.


setIntProperty Function

Synopsis

virtual void QAMessage::setIntProperty(
qa_const_string name
qa_int value
)

Parameters

  • name the name of the property to set

  • value the qa_int value of the property

Remarks

Sets a qa_int property value with the specified name into the message.


setLongProperty Function

Synopsis

virtual void QAMessage::setLongProperty(
qa_const_string name
qa_long value
)

Parameters

  • name the name of the property to set

  • value the qa_long value of the property

Remarks

Sets a qa_long property value with the specified name into the message.


setMessageID Function

Synopsis

virtual void QAMessage::setMessageID(
qa_const_string id
)

Parameters

  • id the message ID

Remarks

Sets the message ID. This method can be used to change the value for a message that has been received.


setPriority Function

Synopsis

virtual void QAMessage::setPriority(
qa_int priority
)

Parameters

  • priority the priority

Remarks

Sets the priority level for this message. This method can be used to change the value for a message that has been received.


setRedelivered Function

Synopsis

virtual void QAMessage::setRedelivered(
qa_bool redelivered
)

Parameters

  • redelivered the redelivered indication

Remarks

Sets an indication of whether this message was redelivered. This method can be used to change the value for a message that has been received.


setReplyToAddress Function

Synopsis

virtual void QAMessage::setReplyToAddress(
qa_const_string replyTo
)

Parameters

  • replyTo the Reply-To address

Remarks

Sets the address to which a reply to this message should be sent.


setShortProperty Function

Synopsis

virtual void QAMessage::setShortProperty(
qa_const_string name
qa_short value
)

Parameters

  • name the name of the property to set

  • value the qa_short value of the property

Remarks

Sets a qa_short property value with the specified name into the message.


setStringProperty Function

Synopsis

virtual void QAMessage::setStringProperty(
qa_const_string name
qa_const_string value
)

Parameters

  • name the name of the property to set

  • value the qa_string value of the property

Remarks

Sets a qa_string property value with the specified name into the message.


setTimestamp Function

Synopsis

virtual void QAMessage::setTimestamp(
qa_long timestamp
)

Parameters

  • timestamp the message timestamp

Remarks

Sets the message timestamp. This method can be used to change the value for a message that has been received.


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QAMessage

~QAMessage Function

Synopsis

virtual QAMessage::~QAMessage()

Remarks

Virtual destructor


Class QAMessageListener

Synopsis

public QAMessageListener

Remarks

A QAMessageListener object is used to receive asynchronously delivered messages.

Members

All members of QAMessageListener, including all inherited members.

  • onMessage Function
  • ~QAMessageListener Function


onMessage Function

Synopsis

virtual void QAMessageListener::onMessage(
QAMessage * message
)

Parameters

  • message the message passed to the listener

Remarks

Passes a message to the listener.


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QAMessageListener

~QAMessageListener Function

Synopsis

virtual QAMessageListener::~QAMessageListener()

Remarks

Virtual destructor


Class QATextMessage

Synopsis

public QATextMessage

Base classes
  • Class QAMessage
Remarks

A QATextMessage object is used to send a message containing an qa_string. It inherits from the Class QAMessage class and adds a text message body.

When a client receives an QATextMessage, it is in read-only mode. If a client attempts to write to the message at this point, a COMMON_MSG_NOT_WRITEABLE_ERROR is set.

Members

All members of QATextMessage, including all inherited members.

  • castToBinaryMessage Function
  • castToTextMessage Function
  • clearProperties Function
  • DEFAULT_PRIORITY Variable
  • DEFAULT_TIME_TO_LIVE Variable
  • getAddress Function
  • getBooleanProperty Function
  • getByteProperty Function
  • getDoubleProperty Function
  • getExpiration Function
  • getFloatProperty Function
  • getInReplyToID Function
  • getIntProperty Function
  • getLongProperty Function
  • getMessageID Function
  • getPriority Function
  • getPropertyNames Function
  • getPropertyType Function
  • getRedelivered Function
  • getReplyToAddress Function
  • getShortProperty Function
  • getStringProperty Function
  • getStringProperty Function
  • getText Function
  • getTextLength Function
  • getTimestamp Function
  • getTimestampAsString Function
  • propertyExists Function
  • readText Function
  • setAddress Function
  • setBooleanProperty Function
  • setByteProperty Function
  • setDoubleProperty Function
  • setFloatProperty Function
  • setInReplyToID Function
  • setIntProperty Function
  • setLongProperty Function
  • setMessageID Function
  • setPriority Function
  • setRedelivered Function
  • setReplyToAddress Function
  • setShortProperty Function
  • setStringProperty Function
  • setText Function
  • setTimestamp Function
  • writeText Function
  • ~QAMessage Function
  • ~QATextMessage Function


getText Function

Synopsis

virtual qa_string QATextMessage::getText()

Remarks

Gets the string containing this message's data. The default value is null.

Returns

the qa_string containing the message's data


getTextLength Function

Synopsis

virtual qa_long QATextMessage::getTextLength()

Remarks

Returns the text length. NOTE: If the text length is non-zero and getText Function returns qa_null then the text does not fit in memory, and must be read in pieces using readText Function.


readText Function

Synopsis

virtual qa_int QATextMessage::readText(
qa_string string
qa_int length
)

Parameters

  • string the destination for the text

  • length the maximum number of qa_chars to read into the destination buffer, including the null termination qa_char

Remarks

Reads the requested length of text from the current text position into a buffer.

Returns

the actual number of non-null qa_chars read, or -1 if the current text position is after the end of the text


setText Function

Synopsis

virtual void QATextMessage::setText(
qa_const_string string
)

Parameters

  • string the qa_string containing the message's data

Remarks

Sets the string containing this message's data.


writeText Function

Synopsis

virtual void QATextMessage::writeText(
qa_const_string string
qa_int offset
qa_int length
)

Parameters

  • string the source text to concatenate

  • offset the offset into the source text at which to start reading

  • length the number of qa_chars of the source text to read

Remarks

Concatenates text to the current text.


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QATextMessage

~QATextMessage Function

Synopsis

virtual QATextMessage::~QATextMessage()

Remarks

Virtual destructor


Class QATransactionalManager

Synopsis

public QATransactionalManager

Base classes
  • Class QAManagerBase
Remarks

This class is the manager for transactional messaging.

Members

All members of QATransactionalManager, including all inherited members.

  • close Function
  • commit Function
  • createBinaryMessage Function
  • createTextMessage Function
  • deleteMessage Function
  • getBooleanStoreProperty Function
  • getByteStoreProperty Function
  • getDoubleStoreProperty Function
  • getFloatStoreProperty Function
  • getIntStoreProperty Function
  • getLastError Function
  • getLastErrorMsg Function
  • getLongStoreProperty Function
  • getMessage Function
  • getMessageNoWait Function
  • getMessageTimeout Function
  • getMode Function
  • getShortStoreProperty Function
  • getStringStoreProperty Function
  • open Function
  • peekFirstMessage Function
  • peekNextMessage Function
  • publishMessage Function
  • putMessage Function
  • putMessageTimeToLive Function
  • rollback Function
  • setBooleanStoreProperty Function
  • setByteStoreProperty Function
  • setDoubleStoreProperty Function
  • setFloatStoreProperty Function
  • setIntStoreProperty Function
  • setLongStoreProperty Function
  • setMessageListener Function
  • setProperty Function
  • setShortStoreProperty Function
  • setStringStoreProperty Function
  • start Function
  • stop Function
  • triggerSendReceive Function
  • ~QAManagerBase Function
  • ~QATransactionalManager Function


commit Function

Synopsis

virtual qa_bool QATransactionalManager::commit()

Remarks

Commits the current transaction and begins a new transaction. The first transaction begins with the call to open Function.

Returns

true if and only if the operation was successful


open Function

Synopsis

virtual qa_bool QATransactionalManager::open()

Remarks

Opens the QATransactionalManager.

Returns

true if and only if the operation was successful


rollback Function

Synopsis

virtual qa_bool QATransactionalManager::rollback()

Remarks

Rolls back the current transaction and begins a new transaction.

Returns

true if and only if the operation was successful


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

QAnywhere C++ API Reference

Class QATransactionalManager

~QATransactionalManager Function

Synopsis

virtual QATransactionalManager::~QATransactionalManager()

Remarks

Virtual destructor


iAnywhere.QAnywhere.Client namespace

About this chapter

The iAnywhere.QAnywhere.Client namespace contains classes and enumerations for building applications that handle QAnywhere messages.

AcknowledgementMode enumeration
MessageProperties class
MessageType enumeration
QABinaryMessage class
QAException class
QAManager class
QAManagerBase class
QAManagerBase.MessageListener delegate
QAManagerFactory class
QAMessage class
QAPropertyType enumeration
QATextMessage class
QATransactionalManager class


AcknowledgementMode enumeration

The acknowledgement modes for QAManager instances

Prototypes

' Visual Basic
Public Enum AcknowledgementMode

// C#
public enum AcknowledgementMode

Members
Member | Description
EXPLICIT_ACKNOWLEDGEMENT | Indicates that messages are not acknowledged as received until a call to one of the manager acknowledge methods is made.
IMPLICIT_ACKNOWLEDGEMENT | Indicates that all messages are acknowledged as received as soon as the getMessage returns to the caller. Similarly, for message listeners, the message is acknowledged as soon as the call to the message listener delegate returns.
TRANSACTIONAL | All message puts and gets done via this mode are done transactionally. That is, all puts and gets occur within a transaction and are all committed or rolled back together. There is always a transaction. Committing or rolling back a transaction implicitly begins a new transaction.


MessageProperties class

Standard message property names

Prototypes

' Visual Basic
Public Class MessageProperties

// C#
public class MessageProperties

MessageProperties members
MessageProperties constructor
ABS_RETRY_TIMEOUT field
ADAPTER field
COMPRESSED field
FROM_ADDR field
MSG_TYPE field
NETWORK field
NETWORK_STATUS field
RETRY_FAILED field
RETRY_FAILED_ADDR field
RETRY_FAILED_PRIORITY field
RETRY_MAX field
RETRY_TIMEOUT field


MessageProperties members

Public static fields (Shared)
Member | Description
ABS_RETRY_TIMEOUT field | Optional property for messages sent through a connector. The time at which send retries through the connector will be stopped and the send is failed
ADAPTER field | For "system" queue messages, a delimited list of network adapters that can be used to connect to the QAnywhere server.
COMPRESSED field | Indicates whether the message content is compressed.
FROM_ADDR field | Optional property indicating the address of the sender
MSG_TYPE field | Optional property indicating the type of the message.
NETWORK field | For "system" queue messages, a delimited list of network names that can be used to connect to the QAnywhere server.
NETWORK_STATUS field | For "system" queue messages, the state of the network connection. Value is 1 if connected, 0 otherwise.
RETRY_FAILED field | Set by the connector when sending a message to the RetryFailedAddress. The receiving client can use this property to identify messages for which re-sending failed.
RETRY_FAILED_ADDR field | Optional property for messages sent through a connector. Once either the RetryMax or RetryTimeout is exceeded, if this property is set, the message will be sent to this address
RETRY_FAILED_PRIORITY field | Optional property for messages sent through a connector. If a message is sent to the RetryFailedAddress, the message priority will be set to this
RETRY_MAX field | Optional property for messages sent through a connector. The maximum number of send retries at the connector before failing the send
RETRY_TIMEOUT field | Optional property for messages sent through a connector. The duration after which send retries through the connector will be stopped and the send is failed
Public instance constructors
Member | Description
MessageProperties constructor | Initializes a new instance of the MessageProperties class.


MessageProperties constructor

Initializes a new instance of the MessageProperties class.

Prototypes

' Visual Basic
Public Sub New()

// C#
public MessageProperties();


ABS_RETRY_TIMEOUT field

Optional property for messages sent through a connector. The time at which send retries through the connector will be stopped and the send is failed

Prototypes

' Visual Basic
Public Shared ABS_RETRY_TIMEOUT As String

// C#
public const string ABS_RETRY_TIMEOUT;


ADAPTER field

For "system" queue messages, a delimited list of network adapters that can be used to connect to the QAnywhere server.

Prototypes

' Visual Basic
Public Shared ADAPTER As String

// C#
public const string ADAPTER;


COMPRESSED field

Indicates whether the message content is compressed.

Prototypes

' Visual Basic
Public Shared COMPRESSED As String

// C#
public const string COMPRESSED;


FROM_ADDR field

Optional property indicating the address of the sender

Prototypes

' Visual Basic
Public Shared FROM_ADDR As String

// C#
public const string FROM_ADDR;


MSG_TYPE field

Optional property indicating the type of the message.

Prototypes

' Visual Basic
Public Shared MSG_TYPE As String

// C#
public const string MSG_TYPE;


NETWORK field

For "system" queue messages, a delimited list of network names that can be used to connect to the QAnywhere server.

Prototypes

' Visual Basic
Public Shared NETWORK As String

// C#
public const string NETWORK;


NETWORK_STATUS field

For "system" queue messages, the state of the network connection. Value is 1 if connected, 0 otherwise.

Prototypes

' Visual Basic
Public Shared NETWORK_STATUS As String

// C#
public const string NETWORK_STATUS;


RETRY_FAILED field

Set by the connector when sending a message to the RetryFailedAddress. The receiving client can use this property to identify messages for which re-sending failed.

Prototypes

' Visual Basic
Public Shared RETRY_FAILED As String

// C#
public const string RETRY_FAILED;


RETRY_FAILED_ADDR field

Optional property for messages sent through a connector. Once either the RetryMax or RetryTimeout is exceeded, if this property is set, the message will be sent to this address

Prototypes

' Visual Basic
Public Shared RETRY_FAILED_ADDR As String

// C#
public const string RETRY_FAILED_ADDR;


RETRY_FAILED_PRIORITY field

Optional property for messages sent through a connector. If a message is sent to the RetryFailedAddress, the message priority will be set to this

Prototypes

' Visual Basic
Public Shared RETRY_FAILED_PRIORITY As String

// C#
public const string RETRY_FAILED_PRIORITY;


RETRY_MAX field

Optional property for messages sent through a connector. The maximum number of send retries at the connector before failing the send

Prototypes

' Visual Basic
Public Shared RETRY_MAX As String

// C#
public const string RETRY_MAX;


RETRY_TIMEOUT field

Optional property for messages sent through a connector. The duration after which send retries through the connector will be stopped and the send is failed

Prototypes

' Visual Basic
Public Shared RETRY_TIMEOUT As String

// C#
public const string RETRY_TIMEOUT;


MessageType enumeration

Valid values for the message type property of a message

Prototypes

' Visual Basic
Public Enum MessageType

// C#
public enum MessageType

Members
Member | Description
NETWORK_STATUS_NOTIFICATION | A message type indicating a message that notifies the receiver of a change to the network status of the current device.
PUSH_NOTIFICATION | A message type indicating a message that notifies the receiver of one or more messages ready for synchronizing from the message server.
REGULAR | If no message type property exists then the message type is assumed to be REGULAR. This type of message is not treated specially by the message system.


QABinaryMessage class

Encapsulation of a binary message

Prototypes

' Visual Basic
Public Class QABinaryMessage
Inherits QAMessage

// C#
public class QABinaryMessage :
QAMessage

QABinaryMessage members
BodyLength property
ReadBinary method
ReadBoolean method
ReadChar method
ReadDouble method
ReadFloat method
ReadInt method
ReadLong method
ReadSbyte method
ReadShort method
ReadString method
Reset method
WriteBinary method
WriteBoolean method
WriteChar method
WriteDouble method
WriteFloat method
WriteInt method
WriteLong method
WriteSbyte method
WriteShort method
WriteString method


QABinaryMessage members

Public instance properties
Member | Description
Address property (inherited from QAMessage) | The address of this message. May be null, but is null never null in a message received via getMessage or a message listener.
BodyLength property | The length in bytes of the message content
Expiration property (inherited from QAMessage) | Indicates the time after which the message may expire and be removed from the message system if it has not been received.
InReplyToID property (inherited from QAMessage) | The message id of the message for which this message is a reply. May be null.
MessageID property (inherited from QAMessage) | The globally unique message id of the message. This property is null until a message is put.
Priority property (inherited from QAMessage) | The priority of the message (ranging from 0 to 9)
Redelivered property (inherited from QAMessage) | Indicates whether the message has been previously received but not acknowledged.
ReplyToAddress property (inherited from QAMessage) | The replyTo address of this message. May be null.
Timestamp property (inherited from QAMessage) | The message timestamp.
Public instance methods
Member | Description
ClearProperties method (inherited from QAMessage) | Clear all the properties of the message
GetBooleanProperty method (inherited from QAMessage) | Gets a boolean message property
GetDoubleProperty method (inherited from QAMessage) | Gets a double message property
GetFloatProperty method (inherited from QAMessage) | Gets a float message property
GetIntProperty method (inherited from QAMessage) | Gets an int message property
GetLongProperty method (inherited from QAMessage) | Gets a long message property
GetProperty method (inherited from QAMessage) | Gets a message property
GetPropertyNames method (inherited from QAMessage) | Gets an enumerator over the property names of the message
GetPropertyType method (inherited from QAMessage) | Returns the property type of the given property
GetSbyteProperty method (inherited from QAMessage) | Gets a signed byte message property
GetShortProperty method (inherited from QAMessage) | Gets a short message property
GetStringProperty method (inherited from QAMessage) | Gets a string message property
PropertyExists method (inherited from QAMessage) | Indicates whether the given property has been set for this message
ReadBinary method | Read from the beginning of the unread part of the binary value the given number of bytes into a byte array.
ReadBoolean method | Read from the beginning of the unread part of the binary value as a boolean.
ReadChar method | Read from the beginning of the unread part of the binary value as a char.
ReadDouble method | Read from the beginning of the unread part of the binary value as a double.
ReadFloat method | Read from the beginning of the unread part of the binary value as a float.
ReadInt method | Read from the beginning of the unread part of the binary value as an int.
ReadLong method | Read from the beginning of the unread part of the binary value as a long.
ReadSbyte method | Read from the beginning of the unread part of the binary value as a signed byte.
ReadShort method | Read from the beginning of the unread part of the binary value as a short.
ReadString method | Read from the beginning of the unread part of the binary value as a string.
Reset method | Reset the message so that reading of values starts from the beginning of the message bytes
SetBooleanProperty method (inherited from QAMessage) | Sets a boolean property
SetDoubleProperty method (inherited from QAMessage) | Sets a double property
SetFloatProperty method (inherited from QAMessage) | Sets a float property
SetIntProperty method (inherited from QAMessage) | Sets an int property
SetLongProperty method (inherited from QAMessage) | Sets a long property
SetProperty method (inherited from QAMessage) | Sets a property. The property type must be one of the acceptable primitive types, or String.
SetSbyteProperty method (inherited from QAMessage) | Sets a byte property
SetShortProperty method (inherited from QAMessage) | Sets a short property
SetStringProperty method (inherited from QAMessage) | Sets a string property
WriteBinary method | Append the byte array value to the bytes of this message.
WriteBoolean method | Binary code, and append the boolean value to the bytes of this message.
WriteChar method | Binary code, and append the char value to the bytes of this message.
WriteDouble method | Binary code, and append the double value to the bytes of this message.
WriteFloat method | Binary code, and append the float value to the bytes of this message.
WriteInt method | Binary code, and append the int value to the bytes of this message.
WriteLong method | Binary code, and append the long value to the bytes of this message.
WriteSbyte method | Binary code, and append the signed byte value to the bytes of this message.
WriteShort method | Binary code, and append the short value to the bytes of this message.
WriteString method | Binary code, and append the string value to the bytes of this message.
Protected instance methods
Member | Description
Dispose method (inherited from QAMessage) | Clean up any resources being used.


BodyLength property

The length in bytes of the message content

Prototypes

' Visual Basic
Public Readonly Property BodyLength As Long

// C#
public long BodyLength {get;}


ReadBinary method

Read from the beginning of the unread part of the binary value the given number of bytes into a byte array.

Prototypes

' Visual Basic
Public Function ReadBinary( _
ByVal bytes As Byte(), _
ByVal len As Integer _
) As Integer

// C#
public int ReadBinary(
byte[] bytes,
int len
);

Parameters

  • bytes the byte array that will contain the read bytes

  • len the maximum number of bytes to read

Return value

the number of bytes read

Exceptions

  • QAException class - if there was a conversion error reading the value or if there is no more input


ReadBoolean method

Read from the beginning of the unread part of the binary value as a boolean.

Prototypes

' Visual Basic
Public Function ReadBoolean() As Boolean

// C#
public bool ReadBoolean();

Return value

the boolean value read

Exceptions

  • QAException class - if there was a conversion error reading the value or if there is no more input


ReadChar method

Read from the beginning of the unread part of the binary value as a char.

Prototypes

' Visual Basic
Public Function ReadChar() As Char

// C#
public char ReadChar();

Return value

the character value read

Exceptions

  • QAException class - if there was a conversion error reading the value or if there is no more input


ReadDouble method

Read from the beginning of the unread part of the binary value as a double.

Prototypes

' Visual Basic
Public Function ReadDouble() As Double

// C#
public double ReadDouble();

Return value

the double value read

Exceptions

  • QAException class - if there was a conversion error reading the value or if there is no more input


ReadFloat method

Read from the beginning of the unread part of the binary value as a float.

Prototypes

' Visual Basic
Public Function ReadFloat() As Single

// C#
public float ReadFloat();

Return value

the float value read

Exceptions

  • QAException class - if there was a conversion error reading the value or if there is no more input


ReadInt method

Read from the beginning of the unread part of the binary value as an int.

Prototypes

' Visual Basic
Public Function ReadInt() As Integer

// C#
public int ReadInt();

Return value

the int value read

Exceptions

  • QAException class - if there was a conversion error reading the value or if there is no more input


ReadLong method

Read from the beginning of the unread part of the binary value as a long.

Prototypes

' Visual Basic
Public Function ReadLong() As Long

// C#
public long ReadLong();

Return value

the long value read

Exceptions

  • QAException class - if there was a conversion error reading the value or if there is no more input


ReadSbyte method

Read from the beginning of the unread part of the binary value as a signed byte.

Prototypes

' Visual Basic
Public Function ReadSbyte() As System.SByte

// C#
public System.Sbyte ReadSbyte();

Return value

the signed byte value read

Exceptions

  • QAException class - if there was a conversion error reading the value or if there is no more input


ReadShort method

Read from the beginning of the unread part of the binary value as a short.

Prototypes

' Visual Basic
Public Function ReadShort() As Short

// C#
public short ReadShort();

Return value

the short value read

Exceptions

  • QAException class - if there was a conversion error reading the value or if there is no more input


ReadString method

Read from the beginning of the unread part of the binary value as a string.

Prototypes

' Visual Basic
Public Function ReadString() As String

// C#
public string ReadString();

Return value

the string value read

Exceptions

  • QAException class - if there was a conversion error reading the value or if there is no more input


Reset method

Reset the message so that reading of values starts from the beginning of the message bytes

Prototypes

' Visual Basic
Public Sub Reset()

// C#
public void Reset();


WriteBinary method

Append the byte array value to the bytes of this message.

Prototypes

' Visual Basic
Public Sub WriteBinary( _
ByVal val As Byte(), _
ByVal offset As Integer, _
ByVal len As Integer _
)

// C#
public void WriteBinary(
byte[] val,
int offset,
int len
);

Parameters

  • val the byte array value

  • len the number of bytes to write

  • offset the byte array offset to begin writing


WriteBoolean method

Binary code, and append the boolean value to the bytes of this message.

Prototypes

' Visual Basic
Public Sub WriteBoolean( _
ByVal val As Boolean _
)

// C#
public void WriteBoolean(
bool val
);

Parameters

  • val the boolean value


WriteChar method

Binary code, and append the char value to the bytes of this message.

Prototypes

' Visual Basic
Public Sub WriteChar( _
ByVal val As Char _
)

// C#
public void WriteChar(
char val
);

Parameters

  • val the char value


WriteDouble method

Binary code, and append the double value to the bytes of this message.

Prototypes

' Visual Basic
Public Sub WriteDouble( _
ByVal val As Double _
)

// C#
public void WriteDouble(
double val
);

Parameters

  • val the double value


WriteFloat method

Binary code, and append the float value to the bytes of this message.

Prototypes

' Visual Basic
Public Sub WriteFloat( _
ByVal val As Single _
)

// C#
public void WriteFloat(
float val
);

Parameters

  • val the float value


WriteInt method

Binary code, and append the int value to the bytes of this message.

Prototypes

' Visual Basic
Public Sub WriteInt( _
ByVal val As Integer _
)

// C#
public void WriteInt(
int val
);

Parameters

  • val the int value


WriteLong method

Binary code, and append the long value to the bytes of this message.

Prototypes

' Visual Basic
Public Sub WriteLong( _
ByVal val As Long _
)

// C#
public void WriteLong(
long val
);

Parameters

  • val the long value


WriteSbyte method

Binary code, and append the signed byte value to the bytes of this message.

Prototypes

' Visual Basic
Public Sub WriteSbyte( _
ByVal val As System.SByte _
)

// C#
public void WriteSbyte(
System.Sbyte val
);

Parameters

  • val the signed byte value


WriteShort method

Binary code, and append the short value to the bytes of this message.

Prototypes

' Visual Basic
Public Sub WriteShort( _
ByVal val As Short _
)

// C#
public void WriteShort(
short val
);

Parameters

  • val the short value


WriteString method

Binary code, and append the string value to the bytes of this message.

Prototypes

' Visual Basic
Public Sub WriteString( _
ByVal val As String _
)

// C#
public void WriteString(
string val
);

Parameters

  • val the string value


QAException class

Exception thrown by QAnywhere

Prototypes

' Visual Basic
Public Class QAException
Inherits ApplicationException

// C#
public class QAException :
ApplicationException


QAException members

Public instance constructors
Member | Description
QAException constructor | Create a QAException
QAException constructor | Create a QAException
Public instance properties
Member | Description
ErrorCode property | The error code of the exception
HelpLink (inherited from Exception) | Gets or sets a link to the help file associated with this exception.
InnerException (inherited from Exception) | Gets the System.Exception instance that caused the current exception.
Message (inherited from Exception) | Gets a message that describes the current exception.
Source (inherited from Exception) | Gets or sets the name of the application or the object that causes the error.
StackTrace (inherited from Exception) | Gets a string representation of the frames on the call stack at the time the current exception was thrown.
TargetSite (inherited from Exception) | Gets the method that throws the current exception.
Public instance methods
Member | Description
GetBaseException (inherited from Exception) | When overridden in a derived class, returns the System.Exception that is the root cause of one or more subsequent exceptions.
GetObjectData (inherited from Exception) | When overridden in a derived class, sets the System.Runtime.Serialization.SerializationInfo with information about the exception.
ToString (inherited from Exception) | Creates and returns a string representation of the current exception.
Protected instance properties
Member | Description
HResult (inherited from Exception) | Gets or sets HRESULT, a coded numerical value that is assigned to a specific exception.


QAException constructor

Create a QAException

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal msg As String _
)

// C#
public QAException(
string msg
);

Parameters

  • msg the exception description


QAException constructor

Create a QAException

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal msg As String, _
ByVal errCode As Integer _
)

// C#
public QAException(
string msg,
int errCode
);

Parameters

  • msg the exception description

  • errCode the error code


ErrorCode property

The error code of the exception

Prototypes

' Visual Basic
Public Readonly Property ErrorCode As Integer

// C#
public int ErrorCode {get;}


QAManager class

A manager for QA messaging operations. Unlike the transactional manager, message puts occur immediately and no other action is necessary to allow another client to get the message. Message gets are acknowledged via one of two modes. The implicit acknowledgement mode indicates that all messages are acknowledged as received as soon as the getMessage returns to the caller. Similarly, for message listeners, the message is acknowledged as soon as the call to the message listener delegate returns. The explicit acknowledgement mode indicates that messages are not acknowledged as received until a call to one of the acknowledge methods is made.

Prototypes

' Visual Basic
Public Class QAManager
Inherits QAManagerBase

// C#
public class QAManager :
QAManagerBase


QAManager members

Public instance properties
Member | Description
LastError property (inherited from QAManagerBase) | The error code of the last executed method, with 0 indicating success.
LastErrorMessage property (inherited from QAManagerBase) | The text of the error associated with the last executed method. Will be null if the last executed method result in a LastError of 0.
Mode property (inherited from QAManagerBase) | The acknowledgement mode for receiving all messages through this manager
Public instance methods
Member | Description
Acknowledge method | Acknowledges the given message as received.
AcknowledgeAll method | Acknowledges all the unacknowledged messages as received.
AcknowledgeUntil method | Acknowledges all the unacknowledged messages received before and up to the given message as received.
BrowseMessages method (inherited from QAManagerBase) | Browse the next available messages waiting that have been sent to the given address. The messages are just being browsed, so they cannot be acknowledged. Enumerators returned from the same manager cannot have their method calls interlaced. Interlacing calls may result in messages meant for one iterator to be browsed in another iterator.
Close method (inherited from QAManagerBase) | Closes the connection to the QA message system and releases any resources. Any calls to close beyond the first are ignored. Any subsequent calls to a method, other than close, will result in an exception being thrown.
CreateBinaryMessage method (inherited from QAManagerBase) | Create a BinaryMessage instance appropriate for sending.
CreateTextMessage method (inherited from QAManagerBase) | Create a TextMessage instance appropriate for sending.
GetBooleanStoreProperty method (inherited from QAManagerBase) | Gets a boolean message store property
GetDoubleStoreProperty method (inherited from QAManagerBase) | Gets a double message store property
GetFloatStoreProperty method (inherited from QAManagerBase) | Gets a float message store property
GetIntStoreProperty method (inherited from QAManagerBase) | Gets an int message store property
GetLongStoreProperty method (inherited from QAManagerBase) | Gets a long message store property
GetMessage method (inherited from QAManagerBase) | Get the next available message waiting that has been sent to the given address. If there is no message available, then this call blocks indefinitely until a message is available.
GetMessageNoWait method (inherited from QAManagerBase) | Get the next available message waiting that has been sent to the given address. If there is no message available, then it returns null immediately, without blocking.
GetMessageTimeout method (inherited from QAManagerBase) | Get the next available message waiting that has been sent to the given address. If there is no message available, then this call will wait up to the timeout time until a message is available.
GetSbyteStoreProperty method (inherited from QAManagerBase) | Gets a signed byte message store property
GetShortStoreProperty method (inherited from QAManagerBase) | Gets a short message store property
GetStoreProperty method (inherited from QAManagerBase) | Gets a message store property
GetStringStoreProperty method (inherited from QAManagerBase) | Gets a string message store property
Open method | Open the manager with the give acknowledgement mode. The open method must be the first method called after creating a manager.
PutMessage method (inherited from QAManagerBase) | Puts the message into the message system addressed to the given address.
PutMessageTimeToLive method (inherited from QAManagerBase) | Puts the message into the message system addressed to the given address, with the given time-to-live.
Recover method | Force all unacknowledged messages into a state of unreceived. That is, these messages must be received again via getMessage.
SetBooleanStoreProperty method (inherited from QAManagerBase) | Sets a boolean message store property
SetDoubleStoreProperty method (inherited from QAManagerBase) | Sets a double message store property
SetFloatStoreProperty method (inherited from QAManagerBase) | Sets a float message store property
SetIntStoreProperty method (inherited from QAManagerBase) | Sets an int message store property
SetLongStoreProperty method (inherited from QAManagerBase) | Sets a long message store property
SetMessageListener method (inherited from QAManagerBase) | Sets a listener for messages available for the given address. Only one listener can be set for a given address. Setting with a null listener clears out any listener for that address.
SetProperty method (inherited from QAManagerBase) | Sets the named property to the given value. Properties for this QAManagerBase may be set with this method as an alternative to the properties file at creation. Properties must be set before calling the open() methods of the derived classes.
SetSbyteStoreProperty method (inherited from QAManagerBase) | Sets a byte message store property
SetShortStoreProperty method (inherited from QAManagerBase) | Sets a short message store property
SetStoreProperty method (inherited from QAManagerBase) | Sets a message store property. The property type must be one of the acceptable primitive types, or String.
SetStringStoreProperty method (inherited from QAManagerBase) | Sets a string message store property
Start method (inherited from QAManagerBase) | Once started the manager will receive any incoming messages. Any calls to start beyond the first without an intervening stop are ignored.
Stop method (inherited from QAManagerBase) | Once stopped the manager will not receive any incoming messages. The messages are not lost. They just won't be received until the manager is started. Any calls to stop beyond the first without an intervening start are ignored.
TriggerSendReceive method (inherited from QAManagerBase) | Causes a synchronization with the QA message server, uploading any messages not meant for this client, and downloading any messages meant for this client.
Protected static fields (Shared)
Member | Description
isOpen field (inherited from QAManagerBase) | Indicates whether instance is in an open state
mgrBase field (inherited from QAManagerBase) | Handle to the underlying c++ qa manager
Protected instance fields
Member | Description
isOpen field (inherited from QAManagerBase) | Indicates whether instance is in an open state
mgrBase field (inherited from QAManagerBase) | Handle to the underlying c++ qa manager
Protected instance methods
Member | Description
Dispose method | Clean up any resources being used.


Acknowledge method

Acknowledges the given message as received.

Prototypes

' Visual Basic
Public Sub Acknowledge( _
ByVal msg As QAMessage _
)

// C#
public void Acknowledge(
QAMessage msg
);

Parameters

  • msg the message to acknowledge

Exceptions

  • QAException class - if there is a problem acknowledging the message


AcknowledgeAll method

Acknowledges all the unacknowledged messages as received.

Prototypes

' Visual Basic
Public Sub AcknowledgeAll()

// C#
public void AcknowledgeAll();

Exceptions

  • QAException class - if there is a problem acknowledging the messages


AcknowledgeUntil method

Acknowledges all the unacknowledged messages received before and up to the given message as received.

Prototypes

' Visual Basic
Public Sub AcknowledgeUntil( _
ByVal msg As QAMessage _
)

// C#
public void AcknowledgeUntil(
QAMessage msg
);

Parameters

  • msg the last message to acknowledge

Exceptions

  • QAException class - if there is a problem acknowledging the messages


Dispose method

Clean up any resources being used.

Prototypes

' Visual Basic
Overloads Overrides Protected Sub Dispose( _
ByVal disposing As Boolean _
)

// C#
protected override void Dispose(
bool disposing
);

Parameters

  • disposing true to release both managed and unmanaged resources; false to release only unmanaged resources.


Open method

Open the manager with the give acknowledgement mode. The open method must be the first method called after creating a manager.

Prototypes

' Visual Basic
Public Sub Open( _
ByVal mode As AcknowledgementMode _
)

// C#
public void Open(
AcknowledgementMode mode
);

Parameters

  • mode must be one of AcknowledgementMode.EXPLICIT_ACKNOWLEDGEMENT or AcknowledgementMode.IMPLICIT_ACKNOWLEDGEMENT

Exceptions

  • QAException class - if there is a problem opening the manager


Recover method

Force all unacknowledged messages into a state of unreceived. That is, these messages must be received again via getMessage.

Prototypes

' Visual Basic
Public Sub Recover()

// C#
public void Recover();

Exceptions

  • QAException class - if there is a problem recovering


QAManagerBase class

This class is an abstract base class for QA managers. It provides service for creating, sending, browsing and receiving messages. It is single threaded. That is, the thread that creates the manager is the only thread allowed to make calls into the manager.

Prototypes

' Visual Basic
Public Class QAManagerBase
Inherits Component

// C#
public class QAManagerBase :
Component

QAManagerBase members
isOpen field
mgrBase field
LastError property
LastErrorMessage property
Mode property
BrowseMessages method
Close method
CreateBinaryMessage method
CreateTextMessage method
Dispose method
GetBooleanStoreProperty method
GetDoubleStoreProperty method
GetFloatStoreProperty method
GetIntStoreProperty method
GetLongStoreProperty method
GetMessage method
GetMessageNoWait method
GetMessageTimeout method
GetSbyteStoreProperty method
GetShortStoreProperty method
GetStoreProperty method
GetStringStoreProperty method
PutMessage method
PutMessageTimeToLive method
SetBooleanStoreProperty method
SetDoubleStoreProperty method
SetFloatStoreProperty method
SetIntStoreProperty method
SetLongStoreProperty method
SetMessageListener method
SetProperty method
SetSbyteStoreProperty method
SetShortStoreProperty method
SetStoreProperty method
SetStringStoreProperty method
Start method
Stop method
TriggerSendReceive method


QAManagerBase members

Public instance properties
Member | Description
LastError property | The error code of the last executed method, with 0 indicating success.
LastErrorMessage property | The text of the error associated with the last executed method. Will be null if the last executed method result in a LastError of 0.
Mode property | The acknowledgement mode for receiving all messages through this manager
Public instance methods
Member | Description
BrowseMessages method | Browse the next available messages waiting that have been sent to the given address. The messages are just being browsed, so they cannot be acknowledged. Enumerators returned from the same manager cannot have their method calls interlaced. Interlacing calls may result in messages meant for one iterator to be browsed in another iterator.
Close method | Closes the connection to the QA message system and releases any resources. Any calls to close beyond the first are ignored. Any subsequent calls to a method, other than close, will result in an exception being thrown.
CreateBinaryMessage method | Create a BinaryMessage instance appropriate for sending.
CreateTextMessage method | Create a TextMessage instance appropriate for sending.
GetBooleanStoreProperty method | Gets a boolean message store property
GetDoubleStoreProperty method | Gets a double message store property
GetFloatStoreProperty method | Gets a float message store property
GetIntStoreProperty method | Gets an int message store property
GetLongStoreProperty method | Gets a long message store property
GetMessage method | Get the next available message waiting that has been sent to the given address. If there is no message available, then this call blocks indefinitely until a message is available.
GetMessageNoWait method | Get the next available message waiting that has been sent to the given address. If there is no message available, then it returns null immediately, without blocking.
GetMessageTimeout method | Get the next available message waiting that has been sent to the given address. If there is no message available, then this call will wait up to the timeout time until a message is available.
GetSbyteStoreProperty method | Gets a signed byte message store property
GetShortStoreProperty method | Gets a short message store property
GetStoreProperty method | Gets a message store property
GetStringStoreProperty method | Gets a string message store property
PutMessage method | Puts the message into the message system addressed to the given address.
PutMessageTimeToLive method | Puts the message into the message system addressed to the given address, with the given time-to-live.
SetBooleanStoreProperty method | Sets a boolean message store property
SetDoubleStoreProperty method | Sets a double message store property
SetFloatStoreProperty method | Sets a float message store property
SetIntStoreProperty method | Sets an int message store property
SetLongStoreProperty method | Sets a long message store property
SetMessageListener method | Sets a listener for messages available for the given address. Only one listener can be set for a given address. Setting with a null listener clears out any listener for that address.
SetProperty method | Sets the named property to the given value. Properties for this QAManagerBase may be set with this method as an alternative to the properties file at creation. Properties must be set before calling the open() methods of the derived classes.
SetSbyteStoreProperty method | Sets a byte message store property
SetShortStoreProperty method | Sets a short message store property
SetStoreProperty method | Sets a message store property. The property type must be one of the acceptable primitive types, or String.
SetStringStoreProperty method | Sets a string message store property
Start method | Once started the manager will receive any incoming messages. Any calls to start beyond the first without an intervening stop are ignored.
Stop method | Once stopped the manager will not receive any incoming messages. The messages are not lost. They just won't be received until the manager is started. Any calls to stop beyond the first without an intervening start are ignored.
TriggerSendReceive method | Causes a synchronization with the QA message server, uploading any messages not meant for this client, and downloading any messages meant for this client.
Protected static fields (Shared)
Member | Description
isOpen field | Indicates whether instance is in an open state
mgrBase field | Handle to the underlying c++ qa manager
Protected instance fields
Member | Description
isOpen field | Indicates whether instance is in an open state
mgrBase field | Handle to the underlying c++ qa manager
Protected instance methods
Member | Description
Dispose method | Clean up any resources being used.


isOpen field

Indicates whether instance is in an open state

Prototypes

' Visual Basic
FamilyisOpen As Boolean

// C#
family bool isOpen;


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

iAnywhere.QAnywhere.Client namespace

QAManagerBase class

mgrBase field

Handle to the underlying c++ qa manager

Prototypes

' Visual Basic
FamilymgrBase As IntPtr

// C#
family IntPtr mgrBase;


LastError property

The error code of the last executed method, with 0 indicating success.

Prototypes

' Visual Basic
Public Readonly Property LastError As Integer

// C#
public int LastError {get;}


LastErrorMessage property

The text of the error associated with the last executed method. Will be null if the last executed method result in a LastError of 0.

Prototypes

' Visual Basic
Public Readonly Property LastErrorMessage As String

// C#
public string LastErrorMessage {get;}


Mode property

The acknowledgement mode for receiving all messages through this manager

Prototypes

' Visual Basic
Public Readonly Property Mode As AcknowledgementMode

// C#
public AcknowledgementMode Mode {get;}


BrowseMessages method

Browse the next available messages waiting that have been sent to the given address. The messages are just being browsed, so they cannot be acknowledged. Enumerators returned from the same manager cannot have their method calls interlaced. Interlacing calls may result in messages meant for one iterator to be browsed in another iterator.

Prototypes

' Visual Basic
Public Function BrowseMessages( _
ByVal address As String _
) As System.Collections.IEnumerator

// C#
public System.Collections.IEnumerator BrowseMessages(
string address
);

Parameters

  • address the address of the messages

Return value

an enumerator over the available messages


Close method

Closes the connection to the QA message system and releases any resources. Any calls to close beyond the first are ignored. Any subsequent calls to a method, other than close, will result in an exception being thrown.

Prototypes

' Visual Basic
Public Sub Close()

// C#
public void Close();

Exceptions

  • QAException class - if there is a problem closing the manager.


CreateBinaryMessage method

Create a BinaryMessage instance appropriate for sending.

Prototypes

' Visual Basic
Public Function CreateBinaryMessage() As QABinaryMessage

// C#
public QABinaryMessage CreateBinaryMessage();

Return value

a new BinaryMessage

Exceptions

  • QAException class - if there is a problem creating the message.


CreateTextMessage method

Create a TextMessage instance appropriate for sending.

Prototypes

' Visual Basic
Public Function CreateTextMessage() As QATextMessage

// C#
public QATextMessage CreateTextMessage();

Return value

a new TextMessage

Exceptions

  • QAException class - if there is a problem creating the message.


GetBooleanStoreProperty method

Gets a boolean message store property

Prototypes

' Visual Basic
Public Function GetBooleanStoreProperty( _
ByVal propName As String _
) As Boolean

// C#
public bool GetBooleanStoreProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetDoubleStoreProperty method

Gets a double message store property

Prototypes

' Visual Basic
Public Function GetDoubleStoreProperty( _
ByVal propName As String _
) As Double

// C#
public double GetDoubleStoreProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetFloatStoreProperty method

Gets a float message store property

Prototypes

' Visual Basic
Public Function GetFloatStoreProperty( _
ByVal propName As String _
) As Single

// C#
public float GetFloatStoreProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetIntStoreProperty method

Gets an int message store property

Prototypes

' Visual Basic
Public Function GetIntStoreProperty( _
ByVal propName As String _
) As Integer

// C#
public int GetIntStoreProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetLongStoreProperty method

Gets a long message store property

Prototypes

' Visual Basic
Public Function GetLongStoreProperty( _
ByVal propName As String _
) As Long

// C#
public long GetLongStoreProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetMessage method

Get the next available message waiting that has been sent to the given address. If there is no message available, then this call blocks indefinitely until a message is available.

Prototypes

' Visual Basic
Public Function GetMessage( _
ByVal address As String _
) As QAMessage

// C#
public QAMessage GetMessage(
string address
);

Parameters

  • address the address of the message

Return value

the next available message

Exceptions

  • QAException class - if there is a problem getting the message.


GetMessageNoWait method

Get the next available message waiting that has been sent to the given address. If there is no message available, then it returns null immediately, without blocking.

Prototypes

' Visual Basic
Public Function GetMessageNoWait( _
ByVal address As String _
) As QAMessage

// C#
public QAMessage GetMessageNoWait(
string address
);

Parameters

  • address the address of the message

Return value

the next available message or null there is no available message

Exceptions

  • QAException class - if there is a problem getting the message.


GetMessageTimeout method

Get the next available message waiting that has been sent to the given address. If there is no message available, then this call will wait up to the timeout time until a message is available.

Prototypes

' Visual Basic
Public Function GetMessageTimeout( _
ByVal address As String, _
ByVal timeout As Long _
) As QAMessage

// C#
public QAMessage GetMessageTimeout(
string address,
long timeout
);

Parameters

  • address the address of the message

  • timeout the time to wait, in milliseconds, for a message to become available

Return value

the next available message or null there is no available message

Exceptions

  • QAException class - if there is a problem getting the message.


GetSbyteStoreProperty method

Gets a signed byte message store property

Prototypes

' Visual Basic
Public Function GetSbyteStoreProperty( _
ByVal propName As String _
) As System.SByte

// C#
public System.Sbyte GetSbyteStoreProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetShortStoreProperty method

Gets a short message store property

Prototypes

' Visual Basic
Public Function GetShortStoreProperty( _
ByVal propName As String _
) As Short

// C#
public short GetShortStoreProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetStoreProperty method

Gets a message store property

Prototypes

' Visual Basic
Public Function GetStoreProperty( _
ByVal propName As String _
) As Object

// C#
public object GetStoreProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if the property does not exist


GetStringStoreProperty method

Gets a string message store property

Prototypes

' Visual Basic
Public Function GetStringStoreProperty( _
ByVal propName As String _
) As String

// C#
public string GetStringStoreProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value or null if the property does not exist


PutMessage method

Puts the message into the message system addressed to the given address.

Prototypes

' Visual Basic
Public Sub PutMessage( _
ByVal address As String, _
ByVal msg As QAMessage _
)

// C#
public void PutMessage(
string address,
QAMessage msg
);

Parameters

  • address the address of the message

  • msg the message to put

Exceptions

  • QAException class - if there is a problem putting the message.


PutMessageTimeToLive method

Puts the message into the message system addressed to the given address, with the given time-to-live.

Prototypes

' Visual Basic
Public Sub PutMessageTimeToLive( _
ByVal address As String, _
ByVal msg As QAMessage, _
ByVal ttl As Long _
)

// C#
public void PutMessageTimeToLive(
string address,
QAMessage msg,
long ttl
);

Parameters

  • address the address of the message

  • msg the message to put

  • ttl the delay, in milliseconds, before the message will expire if it has not been delivered. A value of 0 indicates the message will not expire.

Exceptions

  • QAException class - if there is a problem putting the message.


SetBooleanStoreProperty method

Sets a boolean message store property

Prototypes

' Visual Basic
Public Sub SetBooleanStoreProperty( _
ByVal propName As String, _
ByVal val As Boolean _
)

// C#
public void SetBooleanStoreProperty(
string propName,
bool val
);

Parameters

  • propName the property name

  • val the property value


SetDoubleStoreProperty method

Sets a double message store property

Prototypes

' Visual Basic
Public Sub SetDoubleStoreProperty( _
ByVal propName As String, _
ByVal val As Double _
)

// C#
public void SetDoubleStoreProperty(
string propName,
double val
);

Parameters

  • propName the property name

  • val the property value


SetFloatStoreProperty method

Sets a float message store property

Prototypes

' Visual Basic
Public Sub SetFloatStoreProperty( _
ByVal propName As String, _
ByVal val As Single _
)

// C#
public void SetFloatStoreProperty(
string propName,
float val
);

Parameters

  • propName the property name

  • val the property value


SetIntStoreProperty method

Sets an int message store property

Prototypes

' Visual Basic
Public Sub SetIntStoreProperty( _
ByVal propName As String, _
ByVal val As Integer _
)

// C#
public void SetIntStoreProperty(
string propName,
int val
);

Parameters

  • propName the property name

  • val the property value


SetLongStoreProperty method

Sets a long message store property

Prototypes

' Visual Basic
Public Sub SetLongStoreProperty( _
ByVal propName As String, _
ByVal val As Long _
)

// C#
public void SetLongStoreProperty(
string propName,
long val
);

Parameters

  • propName the property name

  • val the property value


SetMessageListener method

Sets a listener for messages available for the given address. Only one listener can be set for a given address. Setting with a null listener clears out any listener for that address.

Prototypes

' Visual Basic
Public Sub SetMessageListener( _
ByVal address As String, _
ByVal listener As QAManagerBase.MessageListener _
)

// C#
public void SetMessageListener(
string address,
QAManagerBase.MessageListener listener
);

Parameters

  • address the address of messages

  • listener the listener


SetProperty method

Sets the named property to the given value. Properties for this QAManagerBase may be set with this method as an alternative to the properties file at creation. Properties must be set before calling the open() methods of the derived classes.

Prototypes

' Visual Basic
Public Sub SetProperty( _
ByVal name As String, _
ByVal val As String _
)

// C#
public void SetProperty(
string name,
string val
);

Parameters

  • name the property name

  • val the property value

Exceptions

  • QAException class - if there is a problem setting the property.


SetSbyteStoreProperty method

Sets a byte message store property

Prototypes

' Visual Basic
Public Sub SetSbyteStoreProperty( _
ByVal propName As String, _
ByVal val As System.SByte _
)

// C#
public void SetSbyteStoreProperty(
string propName,
System.Sbyte val
);

Parameters

  • propName the property name

  • val the property value


SetShortStoreProperty method

Sets a short message store property

Prototypes

' Visual Basic
Public Sub SetShortStoreProperty( _
ByVal propName As String, _
ByVal val As Short _
)

// C#
public void SetShortStoreProperty(
string propName,
short val
);

Parameters

  • propName the property name

  • val the property value


SetStoreProperty method

Sets a message store property. The property type must be one of the acceptable primitive types, or String.

Prototypes

' Visual Basic
Public Sub SetStoreProperty( _
ByVal propName As String, _
ByVal val As Object _
)

// C#
public void SetStoreProperty(
string propName,
object val
);

Parameters

  • propName the property name

  • val the property value


SetStringStoreProperty method

Sets a string message store property

Prototypes

' Visual Basic
Public Sub SetStringStoreProperty( _
ByVal propName As String, _
ByVal val As String _
)

// C#
public void SetStringStoreProperty(
string propName,
string val
);

Parameters

  • propName the property name

  • val the property value


Start method

Once started the manager will receive any incoming messages. Any calls to start beyond the first without an intervening stop are ignored.

Prototypes

' Visual Basic
Public Sub Start()

// C#
public void Start();

Exceptions

  • QAException class - if there is a problem starting the manager.


Stop method

Once stopped the manager will not receive any incoming messages. The messages are not lost. They just won't be received until the manager is started. Any calls to stop beyond the first without an intervening start are ignored.

Prototypes

' Visual Basic
Public Sub Stop()

// C#
public void Stop();

Exceptions

  • QAException class - if there is a problem stopping the manager.


TriggerSendReceive method

Causes a synchronization with the QA message server, uploading any messages not meant for this client, and downloading any messages meant for this client.

Prototypes

' Visual Basic
Public Sub TriggerSendReceive()

// C#
public void TriggerSendReceive();

Exceptions

  • QAException class - if there is a problem triggering the send/receive.


QAManagerBase.MessageListener delegate

MessageListener delegate definition

Prototypes

' Visual Basic
 Delegate Sub QAManagerBase.MessageListener( _
ByVal msg As QAMessage _
)

// C#
 delegate void QAManagerBase.MessageListener(
QAMessage msg
);

Parameters

  • msg the message that was received


QAManagerFactory class

Factory for creating QAManager and QATransactionalManager objects. There is only ever one instance of QAManagerFactory,

Prototypes

' Visual Basic
Public Class QAManagerFactory
Inherits Component

// C#
public class QAManagerFactory :
Component

QAManagerFactory members
InstanceID field
Instance property
InstanceCount property
LastError property
LastErrorMessage property
CreateQAManager method
CreateQATransactionalManager method
Dispose method
Finalize method


QAManagerFactory members

Public static fields (Shared)
Member | Description
InstanceID field | Factory id
Public static properties (Shared)
Member | Description
Instance property | A singleton QAManagerFactory instance.
InstanceCount property | Indicates the number of factory instances
Public instance fields
Member | Description
InstanceID field | Factory id
Public instance properties
Member | Description
LastError property | The error code of the last executed method, with 0 indicating success.
LastErrorMessage property | The text of the error associated with the last executed method. Will be null if the last executed method result in a LastError of 0.
Public instance methods
Member | Description
CreateQAManager method | Create a QA Manager configured from the INI file.
CreateQATransactionalManager method | Create a transactional QA Manager configured from the INI file.
Protected instance methods
Member | Description
Dispose method | Clean up any resources being used.
Finalize method | Cleanup the instance


Web Links Browse Collapse Expand PDF Previous Next

QAnywhere User's Guide

iAnywhere.QAnywhere.Client namespace

QAManagerFactory class

InstanceID field

Factory id

Prototypes

' Visual Basic
PublicInstanceID As Integer

// C#
public int InstanceID;


Instance property

A singleton QAManagerFactory instance.

Prototypes

' Visual Basic
Public Shared Readonly Property Instance As QAManagerFactory

// C#
public const QAManagerFactory Instance {get;}

Exceptions

  • QAException class - when there is a problem creating the manager factory


InstanceCount property

Indicates the number of factory instances

Prototypes

' Visual Basic
Public Shared Readonly Property InstanceCount As Long

// C#
public const long InstanceCount {get;}


CreateQAManager method

Create a QA Manager configured from the INI file.

Prototypes

' Visual Basic
Public Function CreateQAManager( _
ByVal iniFile As String _
) As QAManager

// C#
public QAManager CreateQAManager(
string iniFile
);

Parameters

  • iniFile properties file configuring the QAManager instance

Return value

the configured QAManager

Exceptions

  • QAException class - when there is a problem creating the manager


CreateQATransactionalManager method

Create a transactional QA Manager configured from the INI file.

Prototypes

' Visual Basic
Public Function CreateQATransactionalManager( _
ByVal iniFile As String _
) As QATransactionalManager

// C#
public QATransactionalManager CreateQATransactionalManager(
string iniFile
);

Parameters

  • iniFile properties file configuring the QATransactionalManager instance

Return value

the configured QATransactionalManager

Exceptions

  • QAException class - when there is a problem creating the manager


Finalize method

Cleanup the instance

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


QAMessage class

Encapsulates a QA message

Prototypes

' Visual Basic
Public Class QAMessage
Inherits Component

// C#
public class QAMessage :
Component

QAMessage members
Address property
Expiration property
InReplyToID property
MessageID property
Priority property
Redelivered property
ReplyToAddress property
Timestamp property
ClearProperties method
Dispose method
GetBooleanProperty method
GetDoubleProperty method
GetFloatProperty method
GetIntProperty method
GetLongProperty method
GetProperty method
GetPropertyNames method
GetPropertyType method
GetSbyteProperty method
GetShortProperty method
GetStringProperty method
PropertyExists method
SetBooleanProperty method
SetDoubleProperty method
SetFloatProperty method
SetIntProperty method
SetLongProperty method
SetProperty method
SetSbyteProperty method
SetShortProperty method
SetStringProperty method


QAMessage members

Public instance properties
Member | Description
Address property | The address of this message. May be null, but is null never null in a message received via getMessage or a message listener.
Expiration property | Indicates the time after which the message may expire and be removed from the message system if it has not been received.
InReplyToID property | The message id of the message for which this message is a reply. May be null.
MessageID property | The globally unique message id of the message. This property is null until a message is put.
Priority property | The priority of the message (ranging from 0 to 9)
Redelivered property | Indicates whether the message has been previously received but not acknowledged.
ReplyToAddress property | The replyTo address of this message. May be null.
Timestamp property | The message timestamp.
Public instance methods
Member | Description
ClearProperties method | Clear all the properties of the message
GetBooleanProperty method | Gets a boolean message property
GetDoubleProperty method | Gets a double message property
GetFloatProperty method | Gets a float message property
GetIntProperty method | Gets an int message property
GetLongProperty method | Gets a long message property
GetProperty method | Gets a message property
GetPropertyNames method | Gets an enumerator over the property names of the message
GetPropertyType method | Returns the property type of the given property
GetSbyteProperty method | Gets a signed byte message property
GetShortProperty method | Gets a short message property
GetStringProperty method | Gets a string message property
PropertyExists method | Indicates whether the given property has been set for this message
SetBooleanProperty method | Sets a boolean property
SetDoubleProperty method | Sets a double property
SetFloatProperty method | Sets a float property
SetIntProperty method | Sets an int property
SetLongProperty method | Sets a long property
SetProperty method | Sets a property. The property type must be one of the acceptable primitive types, or String.
SetSbyteProperty method | Sets a byte property
SetShortProperty method | Sets a short property
SetStringProperty method | Sets a string property
Protected instance methods
Member | Description
Dispose method | Clean up any resources being used.


Address property

The address of this message. May be null, but is null never null in a message received via getMessage or a message listener.

Prototypes

' Visual Basic
Public Property Address As String

// C#
public string Address {get;set;}


Expiration property

Indicates the time after which the message may expire and be removed from the message system if it has not been received.

Prototypes

' Visual Basic
Public Readonly Property Expiration As Long

// C#
public long Expiration {get;}


InReplyToID property

The message id of the message for which this message is a reply. May be null.

Prototypes

' Visual Basic
Public Property InReplyToID As String

// C#
public string InReplyToID {get;set;}


MessageID property

The globally unique message id of the message. This property is null until a message is put.

Prototypes

' Visual Basic
Public Readonly Property MessageID As String

// C#
public string MessageID {get;}


Priority property

The priority of the message (ranging from 0 to 9)

Prototypes

' Visual Basic
Public Property Priority As Integer

// C#
public int Priority {get;set;}


Redelivered property

Indicates whether the message has been previously received but not acknowledged.

Prototypes

' Visual Basic
Public Readonly Property Redelivered As Boolean

// C#
public bool Redelivered {get;}


ReplyToAddress property

The replyTo address of this message. May be null.

Prototypes

' Visual Basic
Public Property ReplyToAddress As String

// C#
public string ReplyToAddress {get;set;}


Timestamp property

The message timestamp.

Prototypes

' Visual Basic
Public Readonly Property Timestamp As Date

// C#
public DateTime Timestamp {get;}


ClearProperties method

Clear all the properties of the message

Prototypes

' Visual Basic
Public Sub ClearProperties()

// C#
public void ClearProperties();


GetBooleanProperty method

Gets a boolean message property

Prototypes

' Visual Basic
Public Function GetBooleanProperty( _
ByVal propName As String _
) As Boolean

// C#
public bool GetBooleanProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetDoubleProperty method

Gets a double message property

Prototypes

' Visual Basic
Public Function GetDoubleProperty( _
ByVal propName As String _
) As Double

// C#
public double GetDoubleProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetFloatProperty method

Gets a float message property

Prototypes

' Visual Basic
Public Function GetFloatProperty( _
ByVal propName As String _
) As Single

// C#
public float GetFloatProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetIntProperty method

Gets an int message property

Prototypes

' Visual Basic
Public Function GetIntProperty( _
ByVal propName As String _
) As Integer

// C#
public int GetIntProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetLongProperty method

Gets a long message property

Prototypes

' Visual Basic
Public Function GetLongProperty( _
ByVal propName As String _
) As Long

// C#
public long GetLongProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetProperty method

Gets a message property

Prototypes

' Visual Basic
Public Function GetProperty( _
ByVal propName As String _
) As Object

// C#
public object GetProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if the property does not exist


GetPropertyNames method

Gets an enumerator over the property names of the message

Prototypes

' Visual Basic
Public Function GetPropertyNames() As System.Collections.IEnumerator

// C#
public System.Collections.IEnumerator GetPropertyNames();

Return value

an enumerator over the message property names


GetPropertyType method

Returns the property type of the given property

Prototypes

' Visual Basic
Public Function GetPropertyType( _
ByVal propName As String _
) As QAPropertyType

// C#
public QAPropertyType GetPropertyType(
string propName
);

Parameters

  • propName the property name

Return value

the property type


GetSbyteProperty method

Gets a signed byte message property

Prototypes

' Visual Basic
Public Function GetSbyteProperty( _
ByVal propName As String _
) As System.SByte

// C#
public System.Sbyte GetSbyteProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetShortProperty method

Gets a short message property

Prototypes

' Visual Basic
Public Function GetShortProperty( _
ByVal propName As String _
) As Short

// C#
public short GetShortProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value

Exceptions

  • QAException class - if there is a conversion error getting the property value or if the property does not exist


GetStringProperty method

Gets a string message property

Prototypes

' Visual Basic
Public Function GetStringProperty( _
ByVal propName As String _
) As String

// C#
public string GetStringProperty(
string propName
);

Parameters

  • propName the property name

Return value

the property value or null if the property does not exist


PropertyExists method

Indicates whether the given property has been set for this message

Prototypes

' Visual Basic
Public Function PropertyExists( _
ByVal propName As String _
) As Boolean

// C#
public bool PropertyExists(
string propName
);

Parameters

  • propName the property name

Return value

whether the property exists


SetBooleanProperty method

Sets a boolean property

Prototypes

' Visual Basic
Public Sub SetBooleanProperty( _
ByVal propName As String, _
ByVal val As Boolean _
)

// C#
public void SetBooleanProperty(
string propName,
bool val
);

Parameters

  • propName the property name

  • val the property value


SetDoubleProperty method

Sets a double property

Prototypes

' Visual Basic
Public Sub SetDoubleProperty( _
ByVal propName As String, _
ByVal val As Double _
)

// C#
public void SetDoubleProperty(
string propName,
double val
);

Parameters

  • propName the property name

  • val the property value


SetFloatProperty method

Sets a float property

Prototypes

' Visual Basic
Public Sub SetFloatProperty( _
ByVal propName As String, _
ByVal val As Single _
)

// C#
public void SetFloatProperty(
string propName,
float val
);

Parameters

  • propName the property name

  • val the property value


SetIntProperty method

Sets an int property

Prototypes

' Visual Basic
Public Sub SetIntProperty( _
ByVal propName As String, _
ByVal val As Integer _
)

// C#
public void SetIntProperty(
string propName,
int val
);

Parameters

  • propName the property name

  • val the property value


SetLongProperty method

Sets a long property

Prototypes

' Visual Basic
Public Sub SetLongProperty( _
ByVal propName As String, _
ByVal val As Long _
)

// C#
public void SetLongProperty(
string propName,
long val
);

Parameters

  • propName the property name

  • val the property value


SetProperty method

Sets a property. The property type must be one of the acceptable primitive types, or String.

Prototypes

' Visual Basic
Public Sub SetProperty( _
ByVal propName As String, _
ByVal val As Object _
)

// C#
public void SetProperty(
string propName,
object val
);

Parameters

  • propName the property name

  • val the property value


SetSbyteProperty method

Sets a byte property

Prototypes

' Visual Basic
Public Sub SetSbyteProperty( _
ByVal propName As String, _
ByVal val As System.SByte _
)

// C#
public void SetSbyteProperty(
string propName,
System.Sbyte val
);

Parameters

  • propName the property name

  • val the property value


SetShortProperty method

Sets a short property

Prototypes

' Visual Basic
Public Sub SetShortProperty( _
ByVal propName As String, _
ByVal val As Short _
)

// C#
public void SetShortProperty(
string propName,
short val
);

Parameters

  • propName the property name

  • val the property value


SetStringProperty method

Sets a string property

Prototypes

' Visual Basic
Public Sub SetStringProperty( _
ByVal propName As String, _
ByVal val As String _
)

// C#
public void SetStringProperty(
string propName,
string val
);

Parameters

  • propName the property name

  • val the property value


QAPropertyType enumeration

QAMessage property type enumeration, corresponding naturally to the C# types

Prototypes

' Visual Basic
Public Enum QAPropertyType

// C#
public enum QAPropertyType

Members
Member | Description
BOOLEAN | Indicates a boolean property
BYTE | Indicates a signed byte property
DOUBLE | Indicates a double property
FLOAT | Indicates a float property
INT | Indicates an int property
LONG | Indicates an long property
SHORT | Indicates a short property
STRING | Indicates a string property
UNKNOWN | Indicates an unknown property type, usually because the property is unknown


QATextMessage class

Encapsulation of a text message.

Prototypes

' Visual Basic
Public Class QATextMessage
Inherits QAMessage

// C#
public class QATextMessage :
QAMessage


QATextMessage members

Public instance properties
Member | Description
Address property (inherited from QAMessage) | The address of this message. May be null, but is null never null in a message received via getMessage or a message listener.
Expiration property (inherited from QAMessage) | Indicates the time after which the message may expire and be removed from the message system if it has not been received.
InReplyToID property (inherited from QAMessage) | The message id of the message for which this message is a reply. May be null.
MessageID property (inherited from QAMessage) | The globally unique message id of the message. This property is null until a message is put.
Priority property (inherited from QAMessage) | The priority of the message (ranging from 0 to 9)
Redelivered property (inherited from QAMessage) | Indicates whether the message has been previously received but not acknowledged.
ReplyToAddress property (inherited from QAMessage) | The replyTo address of this message. May be null.
Text property | The message text. If the message exceeds the maximum message chunk size, then the Text value will be null. In the latter case, you should use the readText method to receive the text.
TextLength property | The length, in characters, of the message
Timestamp property (inherited from QAMessage) | The message timestamp.
Public instance methods
Member | Description
ClearProperties method (inherited from QAMessage) | Clear all the properties of the message
GetBooleanProperty method (inherited from QAMessage) | Gets a boolean message property
GetDoubleProperty method (inherited from QAMessage) | Gets a double message property
GetFloatProperty method (inherited from QAMessage) | Gets a float message property
GetIntProperty method (inherited from QAMessage) | Gets an int message property
GetLongProperty method (inherited from QAMessage) | Gets a long message property
GetProperty method (inherited from QAMessage) | Gets a message property
GetPropertyNames method (inherited from QAMessage) | Gets an enumerator over the property names of the message
GetPropertyType method (inherited from QAMessage) | Returns the property type of the given property
GetSbyteProperty method (inherited from QAMessage) | Gets a signed byte message property
GetShortProperty method (inherited from QAMessage) | Gets a short message property
GetStringProperty method (inherited from QAMessage) | Gets a string message property
PropertyExists method (inherited from QAMessage) | Indicates whether the given property has been set for this message
ReadText method | Read unread text into the given buffer. Any additional unread text must be read by subsequent calls to this method. Text is read from the beginning of any unread text.
SetBooleanProperty method (inherited from QAMessage) | Sets a boolean property
SetDoubleProperty method (inherited from QAMessage) | Sets a double property
SetFloatProperty method (inherited from QAMessage) | Sets a float property
SetIntProperty method (inherited from QAMessage) | Sets an int property
SetLongProperty method (inherited from QAMessage) | Sets a long property
SetProperty method (inherited from QAMessage) | Sets a property. The property type must be one of the acceptable primitive types, or String.
SetSbyteProperty method (inherited from QAMessage) | Sets a byte property
SetShortProperty method (inherited from QAMessage) | Sets a short property
SetStringProperty method (inherited from QAMessage) | Sets a string property
WriteText method | Append text to the text of the message.
Protected instance methods
Member | Description
Dispose method (inherited from QAMessage) | Clean up any resources being used.


Text property

The message text. If the message exceeds the maximum message chunk size, then the Text value will be null. In the latter case, you should use the readText method to receive the text.

Prototypes

' Visual Basic
Public Property Text As String

// C#
public string Text {get;set;}


TextLength property

The length, in characters, of the message

Prototypes

' Visual Basic
Public Readonly Property TextLength As Long

// C#
public long TextLength {get;}


ReadText method

Read unread text into the given buffer. Any additional unread text must be read by subsequent calls to this method. Text is read from the beginning of any unread text.

Prototypes

' Visual Basic
Public Function ReadText( _
ByVal buf As System.Text.StringBuilder _
) As Integer

// C#
public int ReadText(
System.Text.string Builder buf
);

Parameters

  • buf Target buffer for any read text

Return value

the number of characters read or -1 if there are no more characters to read


WriteText method

Append text to the text of the message.

Prototypes

' Visual Basic
Public Sub WriteText( _
ByVal val As String _
)

// C#
public void WriteText(
string val
);

Parameters

  • val the text to append


QATransactionalManager class

The transactional QA manager. All message puts and gets done via this manager are done transactionally. That is, all puts and gets occur within a transaction and are all committed or rolled back together. There is always a transaction. Committing or rolling back a transaction implicitly begins a new transaction.

Prototypes

' Visual Basic
Public Class QATransactionalManager
Inherits QAManagerBase

// C#
public class QATransactionalManager :
QAManagerBase


QATransactionalManager members

Public instance properties
Member | Description
LastError property (inherited from QAManagerBase) | The error code of the last executed method, with 0 indicating success.
LastErrorMessage property (inherited from QAManagerBase) | The text of the error associated with the last executed method. Will be null if the last executed method result in a LastError of 0.
Mode property (inherited from QAManagerBase) | The acknowledgement mode for receiving all messages through this manager
Public instance methods
Member | Description
BrowseMessages method (inherited from QAManagerBase) | Browse the next available messages waiting that have been sent to the given address. The messages are just being browsed, so they cannot be acknowledged. Enumerators returned from the same manager cannot have their method calls interlaced. Interlacing calls may result in messages meant for one iterator to be browsed in another iterator.
Close method (inherited from QAManagerBase) | Closes the connection to the QA message system and releases any resources. Any calls to close beyond the first are ignored. Any subsequent calls to a method, other than close, will result in an exception being thrown.
Commit method | Commits the putting and getting of all uncommitted puts and gets of messages. A message put using a transactional manager will not be received until commit occurs. Similarly, the get of a message via a transactional manager will not appear gotten until a commit occurs.
CreateBinaryMessage method (inherited from QAManagerBase) | Create a BinaryMessage instance appropriate for sending.
CreateTextMessage method (inherited from QAManagerBase) | Create a TextMessage instance appropriate for sending.
GetBooleanStoreProperty method (inherited from QAManagerBase) | Gets a boolean message store property
GetDoubleStoreProperty method (inherited from QAManagerBase) | Gets a double message store property
GetFloatStoreProperty method (inherited from QAManagerBase) | Gets a float message store property
GetIntStoreProperty method (inherited from QAManagerBase) | Gets an int message store property
GetLongStoreProperty method (inherited from QAManagerBase) | Gets a long message store property
GetMessage method (inherited from QAManagerBase) | Get the next available message waiting that has been sent to the given address. If there is no message available, then this call blocks indefinitely until a message is available.
GetMessageNoWait method (inherited from QAManagerBase) | Get the next available message waiting that has been sent to the given address. If there is no message available, then it returns null immediately, without blocking.
GetMessageTimeout method (inherited from QAManagerBase) | Get the next available message waiting that has been sent to the given address. If there is no message available, then this call will wait up to the timeout time until a message is available.
GetSbyteStoreProperty method (inherited from QAManagerBase) | Gets a signed byte message store property
GetShortStoreProperty method (inherited from QAManagerBase) | Gets a short message store property
GetStoreProperty method (inherited from QAManagerBase) | Gets a message store property
GetStringStoreProperty method (inherited from QAManagerBase) | Gets a string message store property
Open method | Open the transactional manager. The open method must be the first method called after creating a manager.
PutMessage method (inherited from QAManagerBase) | Puts the message into the message system addressed to the given address.
PutMessageTimeToLive method (inherited from QAManagerBase) | Puts the message into the message system addressed to the given address, with the given time-to-live.
Rollback method | Rolls back the putting and getting of all uncommitted puts and gets of messages. A message put using a transactional manager will not be sent. Similarly, the get of a message via a transactional manager will not appear to have not been gotten.
SetBooleanStoreProperty method (inherited from QAManagerBase) | Sets a boolean message store property
SetDoubleStoreProperty method (inherited from QAManagerBase) | Sets a double message store property
SetFloatStoreProperty method (inherited from QAManagerBase) | Sets a float message store property
SetIntStoreProperty method (inherited from QAManagerBase) | Sets an int message store property
SetLongStoreProperty method (inherited from QAManagerBase) | Sets a long message store property
SetMessageListener method (inherited from QAManagerBase) | Sets a listener for messages available for the given address. Only one listener can be set for a given address. Setting with a null listener clears out any listener for that address.
SetProperty method (inherited from QAManagerBase) | Sets the named property to the given value. Properties for this QAManagerBase may be set with this method as an alternative to the properties file at creation. Properties must be set before calling the open() methods of the derived classes.
SetSbyteStoreProperty method (inherited from QAManagerBase) | Sets a byte message store property
SetShortStoreProperty method (inherited from QAManagerBase) | Sets a short message store property
SetStoreProperty method (inherited from QAManagerBase) | Sets a message store property. The property type must be one of the acceptable primitive types, or String.
SetStringStoreProperty method (inherited from QAManagerBase) | Sets a string message store property
Start method (inherited from QAManagerBase) | Once started the manager will receive any incoming messages. Any calls to start beyond the first without an intervening stop are ignored.
Stop method (inherited from QAManagerBase) | Once stopped the manager will not receive any incoming messages. The messages are not lost. They just won't be received until the manager is started. Any calls to stop beyond the first without an intervening start are ignored.
TriggerSendReceive method (inherited from QAManagerBase) | Causes a synchronization with the QA message server, uploading any messages not meant for this client, and downloading any messages meant for this client.
Protected static fields (Shared)
Member | Description
isOpen field (inherited from QAManagerBase) | Indicates whether instance is in an open state
mgrBase field (inherited from QAManagerBase) | Handle to the underlying c++ qa manager
Protected instance fields
Member | Description
isOpen field (inherited from QAManagerBase) | Indicates whether instance is in an open state
mgrBase field (inherited from QAManagerBase) | Handle to the underlying c++ qa manager
Protected instance methods
Member | Description
Dispose method | Clean up any resources being used.


Commit method

Commits the putting and getting of all uncommitted puts and gets of messages. A message put using a transactional manager will not be received until commit occurs. Similarly, the get of a message via a transactional manager will not appear gotten until a commit occurs.

Prototypes

' Visual Basic
Public Sub Commit()

// C#
public void Commit();

Exceptions

  • QAException class - if there is a problem committing


Open method

Open the transactional manager. The open method must be the first method called after creating a manager.

Prototypes

' Visual Basic
Public Sub Open()

// C#
public void Open();

Exceptions

  • QAException class - if there is a problem opening the manager


Rollback method

Rolls back the putting and getting of all uncommitted puts and gets of messages. A message put using a transactional manager will not be sent. Similarly, the get of a message via a transactional manager will not appear to have not been gotten.

Prototypes

' Visual Basic
Public Sub Rollback()

// C#
public void Rollback();

Exceptions

  • QAException class - if there is a problem rolling back


Web Links Browse Collapse Expand PDF Previous Next

SQL Remote User's Guide

Version 9.0.2

DC38133-01-0902-01

October 2004

Copyright
About This Manual
Welcome to SQL Remote
SQL Remote Concepts
Setting Up SQL Remote
Tutorials for Adaptive Server Anywhere Users
A Tutorial for Adaptive Server Enterprise Users
Principles of SQL Remote Design
SQL Remote Design for Adaptive Server Anywhere
SQL Remote Design for Adaptive Server Enterprise
Deploying and Synchronizing Databases
SQL Remote Administration
Administering SQL Remote for Adaptive Server Anywhere
Administering SQL Remote for Adaptive Server Enterprise
Using SQL Remote with Replication Server
Utilities and Options Reference
System Objects for Adaptive Server Anywhere
System Objects for Adaptive Server Enterprise
Command Reference for Adaptive Server Anywhere
Command Reference for Adaptive Server Enterprise
SQL Remote for Adaptive Server Enterprise and Adaptive Server Anywhere: Differences
Supported Platforms and Message Links


About This Manual

Subject

This book describes all aspects of the SQL Remote data replication system for mobile computing, which enables sharing of data between a single Adaptive Server Anywhere or Adaptive Server Enterprise database and many Adaptive Server Anywhere databases using an indirect link such as e-mail or file transfer.

Audience

This book is for users of Adaptive Server Anywhere and Adaptive Server Enterprise who wish to add SQL Remote replication to their information systems.

Before you begin

For a comparison of SQL Remote with other replication technologies, see Introducing Replication Technologies.


Welcome to SQL Remote

About this chapter

This chapter introduces SQL Remote and the documentation.


About SQL Remote

SQL Remote is a data-replication technology designed for two-way replication between a consolidated data server and large numbers of remote databases, typically including many mobile databases.

SQL Remote replication is message based, and requires no direct server-to-server connection. An occasional dial-up or e-mail link is sufficient.

Administration and resource requirements at the remote sites are minimal. The time lag between the consolidated and remote databases is configurable, and can range from minutes to hours or days.

Sybase SQL Remote technology is provided in two forms:

  • SQL Remote for Adaptive Server Anywhere Enables replication between a consolidated Adaptive Server Anywhere database and a large number of remote databases.

  • SQL Remote for Adaptive Server Enterprise Enables replication between a consolidated Adaptive Server Enterprise database and a large number of remote Adaptive Server Anywhere databases.

This book describes both of these technologies.

In a SQL Remote installation, you must have properly licensed SQL Remote software at each participating database.

For a detailed introduction to SQL Remote concepts and features, see SQL Remote Concepts.

For a list of supported operating systems and message links, see Supported Platforms and Message Links.


About this manual

This manual describes how to design, build, and maintain SQL Remote installations.

The manual includes the following parts.

  • Introduction to SQL Remote Replication concepts and features of SQL Remote.

  • Replication Design for SQL Remote Designing SQL Remote installations.

  • SQL Remote Administration Deploying SQL Remote databases and administering a running SQL Remote setup.

  • Reference SQL Remote commands, system tables, and other reference material.

Product installation


Product installation

This section describes installation of SQL Remote for Adaptive Server Enterprise. If you obtained SQL Remote as part of another product, consult the installation instructions for the product you purchased.

toggle To install the SQL Remote software ( Windows )

  1. Insert the CD-ROM into your CD-ROM drive.

  2. If the installation program does not start automatically, start the setup application on the CD-ROM.

  3. Follow the instructions in the installation program.

toggle To install the SQL Remote software ( UNIX )

  • Consult the instructions for your operating system in the Adaptive Server Anywhere Read Me First booklet.

If you are using SQL Remote for Adaptive Server Enterprise, you must install SQL Remote into any database you wish to replicate.

For information about installing SQL Remote into a database, see Setting Up SQL Remote.


SQL Remote Concepts

About this chapter

This chapter introduces the concepts, design goals, and features of SQL Remote.


SQL Remote components

The following components are required for SQL Remote:

  • Data server An Adaptive Server Anywhere or Adaptive Server Enterprise database-management system is required at each site to maintain the data.

  • Message Agent A SQL Remote Message Agent is required at the consolidated site and at each remote site to send and receive SQL Remote messages.

    The Message Agent connects to the data server by a client/server connection. It may run on the same machine as the data server or on a different machine.

  • Database extraction utility The extraction utility is used to prepare remote databases from a consolidated database, during development and testing, and also at deployment time.

  • Message system client software SQL Remote uses existing message systems to transport replication messages. A file-sharing "message system" is provided, which does not require client software. Each computer involved in SQL Remote replication using a message system other than file sharing must have that message system installed.

  • Client applications The applications that work with SQL Remote databases are standard client/server database applications.

The architecture of a SQL Remote installation, showing the SQL Remote Message Agent, the data server, and the message system.


The data server

The data server may be an Adaptive Server Enterprise or an Adaptive Server Anywhere server. At the remote site the data server is commonly an Adaptive Server Anywhere personal server, but can also be an Adaptive Server Enterprise or Adaptive Server Anywhere server.


Client applications

Client applications work with the data in the database. Client applications use one of the client/server interfaces supported by the data server:

  • For Adaptive Server Anywhere, the client application may use ODBC, Embedded SQL, or Sybase Open Client to work with Adaptive Server Anywhere.

  • For Adaptive Server Enterprise, the client application may use one of the Sybase Client Server interfaces, ODBC, or Embedded SQL.

Client applications do not have to know if they are using a consolidated or remote database. From the client application perspective, there is no difference.


The Message Agent

The SQL Remote Message Agent sends and receives replication messages. It is a client application that sends and receives messages from database to database. The Message Agent must be installed at both the consolidated and at the remote sites.

For Adaptive Server Anywhere, the Message Agent is a program called dbremote.exe on PC operating systems, and dbremote on UNIX.

For Adaptive Server Enterprise, the Message Agent is a program called ssremote.exe on PC operating systems, and ssremote on UNIX.

Schematic diagram of the components involved in SQL Remote replication.


Message system client

If you are using a shared file message system, no message system client is needed.

If you are using an e-mail or other message system, you must have a message system for that client in order to send and receive messages.


Publications and subscriptions

The data that is replicated by SQL Remote is arranged in publications. Each database that shares information in a publication must have a subscription to the publication.

Data is organized into publications

The publication is a database object describing data to be replicated. Remote users of the database who wish to receive a publication do so by subscribing to a publication.

A publication may include data from several database tables. Each table's contribution to a publication is called an article. Each article may consist of a whole table, or a subset of the rows and columns in a table.

A two-table synchronization definition. The definition includes all of table A and part of table B.

Periodically, the changes made to each publication in a database are replicated to all subscribers to that publication. These replications are called publication updates.

Messages are always sent both ways

Remote databases subscribe to publications on the consolidated database so that they can receive data from the consolidated database. To do this, a subscription is created at the consolidated database, identifying the subscriber by name and by the publication they are to receive.

SQL Remote always involves messages being sent two ways. The consolidated database sends messages containing publication updates to remote databases, and remote databases also send messages to the consolidated database.

For example, if data in a publication at a consolidated database is updated, those updates are sent to the remote databases. And even if the data is never updated at the remote database, confirmation messages must still be sent back to the consolidated database, to keep track of the status of the replication.

Both databases subscribe

Messages must be sent both ways, so not only does a remote database subscribe to a publication created at the consolidated database, but the consolidated database must subscribe to a corresponding publication created at the remote database.

The SQL Remote publish and subscribe model. The remote and consolidated databases each subscribe to the other's publications.

When remote database users modify their own copies of the data, their changes are replicated to the consolidated database. When the messages containing the changes are applied at the consolidated database the changes become part of the consolidated database's publication, and are included in the next round of updates to all remote sites (except the one it came from). In this way, replication from remote site to remote site takes place via the consolidated database.

Synchronizing a remote database

When a subscription is initially set up, the two databases must be brought to a state where they both have the same set of information, ready to start replication. This process of setting up a remote database to be consistent with the consolidated database is called synchronization. Synchronization can be carried out manually, but the database extraction utility automates the process. You can run the Extraction utility as a command-line utility or, if you are using an Adaptive Server Anywhere consolidated database, from Sybase Central.

The appropriate publication and subscription are created automatically at remote databases when you use the SQL Remote database extraction utility to create a remote database.


SQL Remote features

The following features are key to SQL Remote's design.

Support for many subscribers SQL Remote is designed to support replication with many subscribers to a publication.

This feature is of particular importance for mobile workforce applications, which may require replication to the laptop computers of hundreds or thousands of sales representatives from a single office database.

Transaction log-based replication SQL Remote replication is based on the transaction log. This enables it to replicate only changes to data, rather than all data, in each update. Also, log-based replication has performance advantages over other replication systems.

The transaction log is the repository of all changes made to a database. SQL Remote replicates changes made to databases as recorded in the transaction log. Periodically, all committed transactions in the consolidated database transaction log belonging to any publication are sent to remote databases. At remote sites, all committed transactions in the transaction log are periodically submitted to the consolidated database.

By replicating only committed transactions, SQL Remote ensures proper transaction atomicity throughout the replication setup and maintains a consistency among the databases involved in the replication, albeit with some time lag while the data is replicated.

Central administration SQL Remote is designed to be centrally administered, at the consolidated database. This is particularly important for mobile workforce applications, where laptop users should not have to carry out database administration tasks. It is also important in replication involving small offices that have servers but little in the way of administration resources.

Administration tasks include setting up and maintaining publications, remote users, and subscriptions, as well as correcting errors and conflicts if they occur.

Economical resource requirements The only software required to run SQL Remote in addition to your Adaptive Server Anywhere or Adaptive Server Enterprise DBMS is the Message Agent, and a message system. If you use the shared file link, no message system software is required as long as each remote user ID has access to the directory where the message files are stored.

Memory and disk space requirements have been kept moderate for all components of the replication system, so that you do not have to invest in extra hardware to run SQL Remote.

Multi-platform support SQL Remote is provided on a number of operating systems and message links.

For a list of supported environments, see Supported Platforms and Message Links.


Some sample installations

While SQL Remote can provide replication services in many different environments, its features are designed with the following characteristics in mind:

  • SQL Remote should be a solution even when no administration load can be assigned to the remote databases, as in mobile workforce applications.

  • Data communication among the sites may be occasional and indirect: it need not be permanent and direct.

  • Memory and resource requirements at remote sites are assumed to be at a premium.

The following examples show some typical SQL Remote setups.


Server-to-laptop replication for mobile workforces

SQL Remote provides two-way replication between a database on an office network and personal databases on the laptop computers of sales representatives. Such a setup may use an e-mail system as a message transport.

A hierarchical database environment, with many remote laptop computers and a single consolidated database.

The office server may be running a server to manage the company database. The Message Agent at the company database runs as a client application for that server.

At the laptop computers each sales representative has an Adaptive Server Anywhere personal server to manage their own data.

While away from the office, a sales representative can make a single phone call from their laptop to carry out the following functions:

  • Collect new e-mail.

  • Send any e-mail messages they have written.

  • Collect publication updates from the office server.

  • Submit any local updates, such as new orders, to the office server.

The updates may include, for example, new specials on the products the sales representative handles, or new pricing and inventory information. These are read by the Message Agent on the laptop and applied to the sales rep's database automatically, without requiring any additional action on the sales representative's part.

The new orders recorded by the sales representative are also automatically submitted to the office without any extra action on the part of the sales representative.


Server-to-server replication among offices

SQL Remote provides two-way replication between database servers at sales offices or outlets and a central company office, without requiring database administration experience at each sales office beyond the initial setup and that required to maintain the server.

SQL Remote is not designed for up-to-the-minute data availability at each site. Instead, it is appropriate where data can be replicated at periods of an hour or so.

Such a setup may use an e-mail system to carry the replication, if there is already a company-wide e-mail system. Alternatively, an occasional dial-up system and file transfer software can be used to implement a FILE message system.

A multi-level hierarchy, with a central database, a set of office databases, and a set of desktop databases.

SQL Remote is easy to configure to allow each office to receive their own set of data. Tables that are of office interest only (staff records, perhaps, if the office is a franchise) may be kept private in the same database as the replicated data.

Layers can be added to SQL Remote hierarchies: for example, each sales office server could act as a consolidated database, supporting remote subscribers who work from that office.


Setting Up SQL Remote

About this chapter

This chapter describes how to add SQL Remote capabilities to your Adaptive Server Enterprise server.

Adaptive Server Enterprise users only
This chapter is required only for users of SQL Remote for Adaptive Server Enterprise. SQL Remote capability is automatically installed into Adaptive Server Anywhere databases.

This chapter assumes you have already installed the SQL Remote software onto your machine.


Setup overview

We call the collection of databases exchanging information using SQL Remote an installation. From a physical point of view, a SQL Remote installation may consist of hundreds or even thousands of databases sharing information; but as SQL Remote keeps the information in each physical database loosely consistent at a transactional level with that in other physical databases, you can also think of the whole installation as a single dispersed database.

Deploying a large-scale SQL Remote installation can involve setting up databases on many machines. While some changes to the design and setup configuration can be made on a running installation, it is highly recommended that you deploy only when you have completed a careful analysis and test of your design.

Setup tasks

Setup of a SQL Remote installation includes the following tasks:

  • Preparing your server for SQL Remote You must take some steps to configure your Adaptive Server Enterprise to act as a SQL Remote site. These include installing the SQL Remote system objects and the stable queue system objects.

  • Selecting message types You must decide whether you want to exchange information by file sharing, e-mail, some other message type, or a combination.

  • Ensuring proper permissions are set Each user in the installation requires permissions on both their own database and on the consolidated database.

  • Extracting remote databases You must extract an initial copy of each remote database from the consolidated database.

This chapter describes each of these tasks.

All administration is at the consolidated database

Like all SQL Remote administrative tasks, setup is carried out by a database administrator or system administrator at the consolidated database.

The Sybase System Administrator should perform all SQL Remote configuration tasks. See your Adaptive Server Enterprise documentation for more information about the Adaptive Server Enterprise environment.


Preparing your Adaptive Server Enterprise server

Before you start

This section assumes the following:

  • You have installed an Adaptive Server Enterprise server that is to contain the SQL Remote database.

  • You have installed the SQL Remote software on your computer. To install the SQL Remote software, run the setup program from the CD-ROM.

  • You have created a database in the Adaptive Server Enterprise server that will take part in your SQL Remote installation.

  • You have system administrator permissions on the Adaptive Server Enterprise server, and database owner permissions in the database.


Ensuring TEMPDB is large enough

SQL Remote uses the TEMPDB database for the following purposes:

  • The database extraction utility used to create remote databases uses TEMPDB to hold a temporary set of Adaptive Server Anywhere system tables.

  • The Message Agent creates a temporary table called #remote when it connects to the server.

For these reasons, you should make TEMPDB larger than the 2 MB default size. The size required depends on the number of tables and columns in your SQL Remote installation, but a size of 10 MB is generally sufficient.


Installing the SQL Remote system objects

For a database in your Adaptive Server Enterprise server to take part in a SQL Remote installation, you must install a number of SQL Remote system tables, views, and stored procedures in your database.

toggle To install the SQL Remote system objects

  1. Locate the SQL Remote initialization script ssremote.sql in your SQL Remote installation directory.

  2. Make a backup copy of the ssremote.sql script file. Then add the following two lines to the beginning of ssremote.sql:

    use database_name
go

    where database_name is the name of the database to take part in SQL Remote replication.

    These two lines set the current database to database_name, so that the SQL Remote tables are created in the database_name database. The SQL Remote tables are owned by the database owner.

  3. Run the script against your Adaptive Server Enterprise server.

    Change to the directory containing the script file and enter the following command line (which should be entered all on one line) to run the script:

    isql -S server-name -U login_id -P password -I ssremote.sql -o logfile

    where server-name is the name of the Adaptive Server Enterprise, login_id and password correspond to a user with system administrator permissions on the server who owns the database, and logfile is the name of a log file to hold the log information from the script.

    The login_id must correspond to the name used by the Message Agent. For more information, see The Message Agent and replication security.

  4. Inspect the log file to confirm that the tables and procedures were created without error.

The script creates a set of SQL Remote system objects in the database.

The SQL Remote system objects


The SQL Remote system objects

The script creates the following objects in the database:

  • SQL Remote system tables A set of tables used to maintain SQL Remote information. These tables have names beginning with sr_.

  • SQL Remote system views A set of views that hold the SQL Remote information in a more understandable form. These views have names beginning with sr_, and ending in s.

  • SQL Remote system procedures A set of stored procedures used to carry out SQL Remote configuration and administration tasks. These procedures have names beginning with sp_, indicating their system management roles.

Caution: Do not edit the SQL Remote system tables Do not, under any circumstances, alter the SQL Remote system tables directly. Doing so may corrupt the table and make it impossible for SQL Remote to function properly. Use the SQL Remote system procedures to carry out all system administration tasks.


Command-line installation of the stable queue

The stable queue is a pair of database tables that hold transactions until they are no longer needed by the replication system. Every Adaptive Server Enterprise database participating in a SQL Remote installation needs a stable queue.

For detailed information about the stable queue, see The stable queue.

The stable queue can exist in the same database as the database taking part in SQL Remote, or in a separate database. Keeping the stable queue in a separate database complicates the backup and recovery plan, but can improve performance by putting the stable queue workload on separate devices and/or a separate Adaptive Server Enterprise server.

toggle To install the stable queue

  1. Locate the stable queue initialization script stableq.sql in your SQL Remote installation directory.

  2. Make a backup copy of the stableq.sql script file. Then add the following two lines to the beginning of stableq.sql:

    use database_name
go

    where database_name is the name of the database that will hold the stable queue.

    These two lines set the current database to database_name, so that the stable queue is created in the database_name database. The stable queue tables are owned by the database owner.

  3. Run the script against your Adaptive Server Enterprise server.

    Change to the directory holding the stable queue script, and enter the following command line (which should be entered all on one line) to run the script:

    isql -S server-name -U login_id -P password -I stableq.sql -o logfile

    where server-name is the name of the Adaptive Server Enterprise, login_id and password correspond to a user with system administrator permissions on the server who owns the database, and logfile is the name of a log file to hold the log information from the script.

    The login_id must correspond to the name used by the Message Agent. For more information, see The Message Agent and replication security.

  4. Inspect the log file to confirm that the tables and procedures were created without error.


Upgrading SQL Remote for Adaptive Server Enterprise

This section describes the procedure for upgrading SQL Remote for Adaptive Server Enterprise.

As a SQL Remote installation may consist of a large number of databases, it is generally not practical to upgrade software on all machines at the same time. SQL Remote is designed so that upgrades can be carried out incrementally. It is not important what order SQL Remote machines are upgraded, as the message format is compatible with previous releases.

toggle To upgrade SQL Remote

  1. Back up both the consolidated database and, if it is separate, the stable queue database.

  2. Install the new SQL Remote for Adaptive Server Enterprise software.

  3. Run the script ssupdate.sql at the consolidated database to upgrade the SQL Remote system tables and procedures.

    The ssupdate.sql script is held in your Sybase directory.

  4. Run the script squpdate.sql at the stable queue database to upgrade the SQL Remote stable queue tables and procedures.

    The squpdate.sql script is held in your Sybase directory.

The software is now upgraded.


Uninstalling SQL Remote

This section describes how to uninstall the SQL Remote objects from a database, and uninstall the stable queue from a database.

toggle To uninstall the SQL Remote objects from a database

  1. Connect to the database containing the SQL Remote objects, as a user with dbo permissions.

  2. Run the sp_drop_sql_remote stored procedure to remove all SQL Remote objects apart from the procedure itself. The sp_drop_sql_remote procedure is installed along with the other SQL Remote objects.

    exec sp_drop_sql_remote
go

  3. Drop the sp_drop_sql_remote procedure to complete the uninstall procedure.

    drop procedure sp_drop_sql_remote
go
toggle To uninstall the stable queue from a database

  1. Connect to the database containing the stable queue, as a user with dbo permissions.

  2. Run the sp_queue_drop stored procedure to remove all stable queue objects apart from the procedure itself. The sp_queue_drop procedure is installed along with the other stable queue objects.

    exec sp_queue_drop
go

  3. Drop the sp_queue_drop procedure itself, to complete the uninstall procedure.

    drop procedure sp_queue_drop
go


Tutorials for Adaptive Server Anywhere Users

About this chapter

This chapter guides you through setting up a simple replication system using Adaptive Server Anywhere.

Introduction
Tutorial: Adaptive Server Anywhere replication using Sybase Central
Tutorial: Adaptive Server Anywhere replication using Interactive SQL and dbxtract
Start replicating data
A sample publication


Introduction

These tutorials describe how to set up a simple SQL Remote replication system using Adaptive Server Anywhere.


Goals

In the tutorials, you act as the system administrator of a consolidated Adaptive Server Anywhere database, and set up a simple replication system. The replication system consists of a simple sales database, with two tables.

The consolidated database holds all of the database, while the remote database has all of one table, but only some of the rows in the other table.

The tutorials take you through the following steps:

  • Creating a consolidated database on your Adaptive Server Anywhere server.

  • Creating a file-sharing replication system with a single Adaptive Server Anywhere remote database.

  • Replicating data between the two databases.


The database

The tutorials use a simple two-table database. One table holds information about sales representatives, and the other about customers. The tables are much simpler than you would use in a real database; this allows us to focus just on those issues important for replication.

Database schema

The database schema for the tutorials is illustrated in the figure.

The Customer table has a foreign key to the SalesRep table.

Features to note include the following:

  • Each sales representative is represented by one row in the SalesRep table.

  • Each customer is represented by one row in the Customer table.

  • Each customer is assigned to a single sales representative, and this assignment is built in to the database as a foreign key from the Customer table to the SalesRep table. The relationship between the Customer table and the SalesRep table is many-to-one.

The tables in the database

The tables are described in more detail as follows:

Table Description
SalesRep One row for each sales representative that works for the company. The SalesRep table has the following columns:

  • rep_key An identifier for each sales representative. This is the primary key.

  • name The name of each sales representative.

The SQL statement creating this table is as follows:
CREATE TABLE SalesRep (
   rep_key CHAR(12) NOT NULL,
   name CHAR(40) NOT NULL,
   PRIMARY KEY (rep_key)
)
Customer One row for each customer that does business with the company. The Customer table includes the following columns:

  • cust_key An identifier for each customer. This is the primary key.

  • name The name of each customer.

  • rep_key An identifier for the sales representative in a sales relationship. This is a foreign key to the SalesRep table.

The SQL statement creating this table is as follows:
CREATE TABLE Customer (
   cust_key CHAR(12) NOT NULL,
   name CHAR(40) NOT NULL,
   rep_key CHAR(12) NOT NULL,
   FOREIGN KEY ( rep_key )
      REFERENCES SalesRep (rep_key ),
   PRIMARY KEY (cust_key)
)


Replication goals

The goals of the replication design are to provide each sales representative with the following information:

  • The complete SalesRep table.

  • Those customers assigned to them.

The tutorials describe how to meet this goal using SQL Remote.


Sybase Central or command-line utilities

Use Sybase Central or the command line

The tutorial material is presented twice. One tutorial describes how to set up the installation using the Sybase Central management utility. The second tutorial describes how to set up the installation using command-line utilities: this requires typing commands individually.

Where next?

  • To work through the tutorial using Sybase Central, go to Tutorial: Adaptive Server Anywhere replication using Sybase Central.

  • To work through the tutorial entering commands explicitly, go to Tutorial: Adaptive Server Anywhere replication using Interactive SQL and dbxtract.


Tutorial: Adaptive Server Anywhere replication using Sybase Central

The following sections are a tutorial describing how to set up a simple SQL Remote replication system in Adaptive Server Anywhere using Sybase Central.

You do not need to enter SQL statements if you are using Sybase Central to administer SQL Remote. A tutorial for those who do not have access to Sybase Central, or who prefer to work with command-line utilities, is presented in Tutorial: Adaptive Server Anywhere replication using Interactive SQL and dbxtract. This tutorial contains the SQL statements executed behind the scenes by Sybase Central.

In this tutorial you act as the DBA of the consolidated database, and set up a simple replication system using the file-sharing message link. The simple example is a primitive model for a sales-force automation system, with two tables. One contains a list of sales representatives, and another a list of customers. The tables are replicated in a setup with one consolidated database and one remote database. You can install this example on one computer.

This tutorial assumes that you have some familiarity with Sybase Central.

For an introduction to Sybase Central, see Managing Databases with Sybase Central.


Preparing for the Sybase Central replication tutorial

This section describes the steps you need to take to prepare for the tutorial. These steps include the following:

  • Create the directories and databases required for the tutorial.

  • Add the tables to the consolidated database.

toggle To prepare for the tutorial

  1. Create a directory to hold the files you make during this tutorial; for example c:\tutorial.

    mkdir c:\tutorial

  2. Create a subdirectory for each of the two user IDs in the replication system, to hold their messages. Create these subdirectories using the following statements at a system command line:

    mkdir c:\tutorial\HQ
mkdir c:\tutorial\field

  3. Create the HQ database:

    • Start Sybase Central.

    • In the left pane, select the Adaptive Server Anywhere plug-in.

    • In the right pane, click the Utilities tab.

    • Double-click Create Database in the right pane.

      The Create Database wizard appears.

    • Create a database with filename c:\tutorial\HQ.db.

      Use the default settings for this database.

    An Adaptive Server Anywhere database is simply a file, which can be copied to other locations and computers when necessary.

The next step is to add a pair of tables to the consolidated database.

toggle To add tables to the consolidated database

  1. Connect to the HQ database from Sybase Central, with a user ID of DBA and a password of SQL.

  2. Select the Tables folder of the HQ database in the left pane.

  3. From the File menu, choose New > Table and create a table named SalesRep using the Table Creation wizard.

  4. Add the following columns to the table (you can add a column by choosing File > Add Column):

    Key | Column | Data Type | Size/Prec
    Primary key | Rep_key | char | 5
    Name | char | 40

    You do not need to use the Column property sheet.

  5. Save the table by choosing File > Save Table or pressing Ctrl+S.

  6. From the File menu, choose New > Table and create a table named Customer with the following columns:

    Key | Column | Data Type | Size/Prec
    Primary key | Cust_key | char | 10
    Name | char | 40
    Rep_key | char | 5

    Again, you do not need to use the property sheets.

  7. Save the table.

  8. In the Tables folder in the left pane, select the Customer table, then click the Foreign Keys tab in the right pane.

  9. From the File menu, choose New > Foreign Key. Using the wizard, add a foreign key to the Rep_key column of the SalesRep table. You can use the default settings for this foreign key.

You are now ready for the rest of the tutorial.


Setting up a consolidated database

This section of the tutorial describes how to prepare the consolidated database of a simple replication system.

Preparing a consolidated database for replication involves the following steps:

  1. Create a message type to use for replication.

  2. Grant PUBLISH permissions to a user ID to identify the source of outgoing messages.

  3. Grant REMOTE permissions to all user IDs that are to receive messages.

  4. Create a publication describing the data to be replicated.

  5. Create subscriptions describing who is to receive the publication.

You require DBA authority to carry out these tasks.


Add a SQL Remote message type

All messages sent as part of replication use a message type. A message type description has two parts:

  • A message link supported by SQL Remote. In this tutorial, we use the FILE link.

  • An address for this message link, to identify the source of outgoing messages.

Adaptive Server Anywhere databases already have message types created, but you need to supply an address for the message type you will use.

toggle To add an address to a message type

  1. From Sybase Central, connect to the HQ database.

  2. Open the SQL Remote Users folder for the HQ database.

  3. In the right pane, click the Message Types tab.

  4. In the right pane, right-click the FILE message type and choose Properties from the popup menu.

  5. Enter a publisher address to provide a return address for remote users. Enter the directory you have created to hold messages for the consolidated database (HQ).

    The address is taken relative to the SQLRemote environment variable or registry entry. As you have not set this value, the address is taken relative to the directory from which the Message Agent is run. You should run the Message Agent from your tutorial directory for the addresses to be interpreted properly.

    For information about setting the SQLRemote value, see Setting message type control parameters.

  6. Click OK to save the message type.


Add the publisher and remote user to the database

In SQL Remote's hierarchical replication system, each database may have zero or one database immediately above it (the consolidated database) and zero or more databases immediately below it (remote databases).

In this tutorial, the current database is the consolidated database of a two-level system. It has no database above it, and only one remote database below it.

The following diagram illustrates the two databases:

The HQ database and the Field database.

For any database in a SQL Remote replication setup, there are three permissions that may be granted to identify databases on the hierarchy:

  • PUBLISH permission Identifies the current database in all outgoing messages

  • REMOTE permission Identifies each database receiving messages from the current database that is below it on the hierarchy

  • CONSOLIDATE permission Identifies a database receiving messages from the current database that is directly above it on the hierarchy.

Permissions can only be granted by a user with DBA authority. To carry out these examples you should connect from Sybase Central to the hq database as user ID DBA, with password SQL.

Add a database publisher user ID

Any database, consolidated or remote, that distributes changes to other databases in the replication system is a publisher database. Each database in the replication system is identified by a single user ID. You set that ID for your database by adding a publisher to the database. This section describes setting permissions for the consolidated hq database.

First create a user ID named hq_user, who will be the publisher user ID.

toggle To create a new user as the publisher

  1. Select the Users & Groups folder.

  2. From the File menu, choose New > User.

    The User Creation wizard appears.

  3. Enter the name hq_user, with password hq_pwd, and click Finish.

  4. Right-click the hq_user icon and choose Change to Publisher from the popup menu.

    A database can have only one publisher. You can find out who the publisher is at any time by opening the Users & Groups folder.

Add a remote user

Each remote database is identified in the consolidated database by a user ID with REMOTE permissions. Whether the remote database is a personal database server or a network server with many users, it needs a single user ID to represent it to the consolidated database.

In a mobile workgroup setting, remote users may already be users of the consolidated database, and so no new users would need to be added; although they would need to be set as remote users.

When a remote user is added to a database, the message system they use and their address under that message system need to be stored along with their database user ID.

toggle To add a remote user

  1. Select the SQL Remote Users folder.

  2. From the File menu, choose New > SQL Remote User.

    The Create a New Remote User wizard appears.

  3. Create a remote user with user ID field_user with the following options:

    • Enter the password field_pwd.

    • Ensure that Remote DBA authority is selected, so that the user can run the Message Agent.

    • Select the message type FILE, and enter the address field.

      As with the publisher address, the address of the remote user is taken relative to the SQLREMOTE environment variable or registry entry. As you have not set this value, the address is taken relative to the directory from which the Message Agent is run. You should run the Message Agent from your tutorial directory for the addresses to be interpreted properly.

      For information about setting the SQLREMOTE value, see Setting message type control parameters.

    • Ensure that the Send Then Close option is selected.

      (In many production environments you would not choose Send Then Close, but it is convenient for this tutorial.)

  4. When you have finished, click Finish to create the remote user.

    You have now created the users who will use this system.


Add publications and subscriptions

This section describes how to add a publication to a database, and how to add a subscription to that publication for a user. The publication replicates all rows of the table SalesRep and some of the rows of the Customer table.

toggle To add a publication

  1. Select the Publications folder in the left pane.

  2. From the File menu, choose New > Publication.

    The Publication Creation wizard appears.

  3. Name the publication SalesRepData.

  4. On the Tables tab, select SalesRep from the list of Available Tables. Click Add.

    The table appears in the list of Selected Tables on the right.

  5. Select Customer from the list of Available Tables. Click Add.

  6. On the SUBSCRIBE BY Restrictions tab, select the Customer table and enter the expression rep_key.

  7. Click Finish to create the publication.

Add a subscription

Each user ID that is to receive changes to a publication must have a subscription to that publication. Subscriptions can only be created for a valid remote user. You need to add a subscription to the SalesRepData publication for the remote database user field_user.

toggle To add a subscription

  1. Open the Publications folder and select the SalesRepData publication in the left pane.

  2. Click the SQL Remote Subscriptions tab in the right pane.

  3. From the File menu, choose New > SQL Remote Subscription.

    The SQL Remote Subscription Creation wizard appears.

  4. Choose to subscribe field_user. Enter a Subscription value of rep1 and click Finish.

    The subscription value is an expression that matches the Subscribe By expression in the publication. In a later step, the field_user user ID is assigned a rep_key value of rep1.

You have now set up the consolidated database.


Set up the remote database in Sybase Central

The remote database needs to be created and configured in order to send and receive messages and participate in a SQL Remote setup.

Like the consolidated database, the remote database needs a publisher (in this case, the field_user user ID) to identify the source of outgoing messages, and it needs to have hq_user identified as a user with consolidated permissions. It needs the SalesRepData publication to be created and needs a subscription created for the hq_user user ID.

The remote database also needs to be synchronized with the consolidated database; that is, it needs to have a current copy of the data in order for the replication to start. In this case, there is no data in the publication as yet.

The database extraction utility enables you to carry out all the steps needed to create a remote database complete with subscriptions and required user IDs.

You need to extract a database from the consolidated database for remote user field_user.

toggle To extract a database

  1. Connect to the HQ database.

  2. Right-click the database and choose Extract Database from the popup menu.

  3. Choose to extract the HQ database with the following options:

    • Choose to extract at isolation level 3.

    • Choose to Start Subscriptions Automatically, for user field_user.

    • Choose Extract and Reload into a New Database.

    • Leave the reload file location at its default setting.

    • Choose to extract both structure and data.

    • Choose not to extract fully-qualified publication definitions.

    • Create the database as file c:\tutorial\field.db, and click Finish to create the remote database.

In a proper SQL Remote setup, the remote database field would need to be loaded on to the computer using it, together with an Adaptive Server Anywhere server and any client applications required. For this tutorial, we leave the database where it is and use Interactive SQL to input and replicate data.

You should connect to the field database as DBA and confirm that all the database objects are created. These include the SalesRep and Customer tables, the SalesRepData publication, and the subscription for the consolidated database.

What next?

The system is now ready for replication.

For the next step, inserting and replicating data, see the section Start replicating data.


Tutorial: Adaptive Server Anywhere replication using Interactive SQL and dbxtract

The following sections are a tutorial describing how to set up a simple SQL Remote replication system for users who prefer to use command-line tools or who want to know what Sybase Central is doing behind the scenes.

This tutorial describes the SQL statements for managing SQL Remote, which can be run from Interactive SQL. It also describes how to run the dbxtract command-line utility to extract remote databases from a consolidated database.

In this tutorial you act as the DBA of the consolidated database, and set up a simple replication system using the file-sharing message link. The simple example is a primitive model for a sales-force automation system, with two tables. One contains a list of sales representatives, and another a list of customers. The tables are replicated in a setup with one consolidated database and one remote database. You can install this example on one computer.


Preparing for the replication tutorial

This section describes the steps you need to take to prepare for the tutorial. These steps include the following:

  • Create the directories and databases required for the tutorial.

  • Add a table to the consolidated database.

toggle To create the databases and directories for the tutorial

  1. Create a directory to hold the files you make during this tutorial; for example c:\tutorial.

    mkdir c:\tutorial

  2. The tutorial uses two databases: a consolidated database named hq.db and a remote database named field.db. Change to the tutorial directory and create these databases using the following statements at a command prompt:

    dbinit hq.db
dbinit field.db

  3. Create a subdirectory for each of the two user IDs in the replication system. Create these subdirectories using the following statements at a command prompt:

    mkdir c:\tutorial\hq
mkdir c:\tutorial\field

The next step is to add a pair of tables to the consolidated database.

toggle To add the tables to the consolidated database

  1. Connect to hq.db from Interactive SQL with a user ID of DBA and a password of SQL.

  2. Execute the following CREATE TABLE statement to create the SalesRep table:

    CREATE TABLE SalesRep (
   rep_key CHAR(12) NOT NULL,
   name CHAR(40) NOT NULL,
   PRIMARY KEY ( rep_key )
);

  3. Execute the following CREATE TABLE statement to create the Customer table:

    CREATE TABLE Customer (
   cust_key CHAR(12) NOT NULL,
   name CHAR(40) NOT NULL,
   rep_key CHAR(12) NOT NULL,
   FOREIGN KEY REFERENCES SalesRep,
   PRIMARY KEY ( cust_key )
);

You are now ready for the rest of the tutorial.


Web Links Browse Collapse Expand PDF Previous Next

SQL Remote User's Guide

Tutorials for Adaptive Server Anywhere Users

Tutorial: Adaptive Server Anywhere replication using Interactive SQL and dbxtract

Set up the consolidated database

This section of the tutorial describes how to set up the consolidated database of a simple replication system.

You require DBA authority to carry out this task.


Create a SQL Remote message type

All messages sent as part of replication use a message type. A message type description has two parts:

  • A message link supported by SQL Remote. In this tutorial, we use the FILE link.

  • An address for this message link, to identify the source of outgoing messages.

toggle To create the message type

  • In Interactive SQL, create the file message type using the following statement:

CREATE REMOTE MESSAGE
TYPE file
ADDRESS 'hq'

The address (hq) for a file link is a directory in which files containing the message are placed. It is taken relative to the SQLRemote environment variable or registry entry. As you have not set this value, the address is taken relative to the directory from which the Message Agent is run. You should run the Message Agent from your tutorial directory for the addresses to be interpreted properly.

For information about setting the SQLRemote value, see Setting message type control parameters.


Grant PUBLISH and REMOTE at the consolidated database

In the hierarchical replication system supported by SQL Remote, each database may have one consolidated database immediately above it in the hierarchy and many databases immediately below it on the hierarchy (remote databases).

PUBLISH permission identifies the current database for outgoing messages, and the REMOTE permission identifies each database receiving messages from the current database.

Permissions can only be granted by a user with DBA authority. To carry out these examples you should connect using the Interactive SQL utility to hq as user ID DBA, with password SQL.

GRANT PUBLISH to identify outgoing messages

Each database that distributes its changes to other databases in the replication system is a publisher database. Each database in the replication system that publishes changes to a database is identified by a single user ID. You set that ID for your database using the GRANT PUBLISH statement. This section describes setting permissions for the consolidated database (hq.db).

toggle To create a publisher for the database

  • Connect to the database using Interactive SQL, and type the following statement:

    GRANT CONNECT
TO hq_user
IDENTIFIED BY hq_pwd ;

GRANT PUBLISH TO hq_user ;

You can check the publishing user ID of a database at any time using the CURRENT PUBLISHER special constant:

SELECT CURRENT PUBLISHER
GRANT REMOTE for each database to which you send messages

Each remote database is identified using the GRANT REMOTE statement. Whether the remote database is a personal server or a network server with many users, it needs a single user ID to represent it to the consolidated database.

In a mobile workgroup setting, remote users may already be users of the consolidated database, and so this would require no extra action on the part of the DBA.

The GRANT REMOTE statement identifies the message system to be used when sending messages to the recipient, as well as the address.

toggle To add a remote user

  • Connect to the database using Interactive SQL, and execute the following statements:

    GRANT CONNECT TO field_user
IDENTIFIED BY field_pwd ;

GRANT REMOTE TO field_user
TYPE file ADDRESS 'field' ;

    The address string is the directory used to hold messages for field_user, enclosed in single quotes. It is taken relative to the SQLRemote environment variable or registry entry. As you have not set this value, the address is taken relative to the directory from which the Message Agent is run. You should run the Message Agent from your tutorial directory for the addresses to be interpreted properly.

    For information about setting the SQLRemote value, see Setting message type control parameters.


Create publications and subscriptions

A publication is created using a CREATE PUBLICATION statement. This is a data definition language statement, and requires DBA authority. For the tutorial, you should connect to the hq database as user ID DBA, password SQL, to create a publication.

Set up a publication at the consolidated database

Create a publication named SalesRepData, which replicates all rows of the table SalesRep, and some of the rows of the table Customer.

toggle To create the publication

  • Connect to the database from Interactive SQL, and execute the following statement:

    CREATE PUBLICATION SalesRepData (
   TABLE SalesRep,
   TABLE Customer SUBSCRIBE BY rep_key
)
Set up a subscription

Each user ID that is to receive changes to the publication must have a subscription. The subscription can only be created for a user who has REMOTE permissions. The GRANT REMOTE statement contains the address to use when sending the messages.

toggle To create the subscription

  • Connect to the database from Interactive SQL, and execute the following statement:

    CREATE SUBSCRIPTION
TO SalesRepData ('rep1')
FOR field_user ;

    The value rep1 is the rep_key value we will give to the user field_user in the SalesRep table.

The full CREATE SUBSCRIPTION statement allows control over the data in subscriptions; allowing users to receive only some of the rows in the publication. For more information, see CREATE SUBSCRIPTION statement.

The CREATE SUBSCRIPTION statement identifies the subscriber and defines what they receive. However, it does not synchronize data, or start the sending of messages.


Set up the remote database

The remote database needs to be configured in order to send and receive messages and participate in a SQL Remote setup. Like the consolidated database, the remote database needs a CURRENT PUBLISHER to identify the source of outgoing messages, and it needs to have the consolidated database identified as a subscriber. The remote database also needs the publication to be created and needs a subscription created for the consolidated database. The remote database also needs to be synchronized with the consolidated database; that is, it needs to have a current copy of the data in order for the replication to start.

The dbxtract utility enables you to carry out all the steps needed to create a remote database complete with subscriptions and required user IDs.


Extract the remote database information

Leave the hq database running, and change to the tutorial directory.

Type the following command at the system command line (all on one line) to extract a database for the user field_user from the consolidated database:

dbxtract -v -c "dbn=hq;uid=dba;pwd=sql" c:\tutorial field_user

The -v option produces more verbose output. This is useful during development.

This command assumes the hq database is currently running on the default server. If the database is not running, you should enter a database file parameter in the connection string:

dbf=hq.db

instead of the dbn database name parameter.

For details of the dbxtract utility and its options, see The extraction utility.

The dbxtract command creates a SQL command file named reload.sql in the current directory and a data file in the c:\tutorial directory. It also starts the subscriptions to the remote user.

The next step is to load these files into the remote database.


Load the remote database information
toggle To load the database information

  1. From the tutorial directory, connect to the remote database field.db from Interactive SQL with a user ID of DBA and a password of SQL.

  2. Run the reload.sql command file:

    READ C:\tutorial\reload.sql

The reload.sql command file carries out the following tasks:

  • Creates a message type at the remote database.

  • Grants PUBLISH and REMOTE permissions to the remote and consolidated database, respectively.

  • Creates the table in the database. If the table had contained any data before extraction, the command file would fill the replicated table with a copy of the data.

  • Creates a publication to identify the data being replicated.

  • Creates the subscription for the consolidated database, and starts the subscription.

While connected to the field database as DBA, confirm that the tables are created by executing the following statements:

SELECT * FROM SalesRep ;

SELECT * FROM Customer ;
What next?

The system is now ready for replication.

For the next step, inserting and replicating data, see the section Start replicating data.


Start replicating data

You now have a replication system in place. In this section, data is replicated from the consolidated database to the remote database, and from the remote to the consolidated database.

Enter data at the consolidated database
Send data from the consolidated database
Receive data at the remote database
Replicate from the remote database to the consolidated database


Enter data at the consolidated database

First, enter some data into the consolidated database.

toggle To enter data at the consolidated database

  1. Connect to the consolidated database hq from the Interactive SQL utility with a user ID of DBA and a password of SQL.

  2. Insert two rows into the SalesRep table and commit the insertion by executing the following statement:

    INSERT INTO SalesRep (rep_key, name)
VALUES ('rep1', 'Field User') ;
INSERT INTO SalesRep (rep_key, name)
VALUES ('rep2', 'Another User') ;
COMMIT ;

  3. Insert two rows into the Customer table and commit the insertion by executing the following statement:

    INSERT INTO Customer (cust_key, name, rep_key)
VALUES ('cust1', 'Ocean Sports', 'rep1' ) ;
INSERT INTO Customer (cust_key, name, rep_key)
VALUES ('cust2', 'Sports Plus', 'rep2' ) ;
COMMIT ;

  4. Confirm that the data has been entered by executing the following statements:

    SELECT *
FROM SalesRep;

SELECT *
FROM Customer;

The next step is to send the relevant rows to the remote database.


Send data from the consolidated database

To send the rows to the remote database, you must run the Message Agent at the consolidated database. The dbremote program is the Message Agent for Adaptive Server Anywhere.

toggle To send the data to the remote database

  1. From a command prompt, change to your tutorial directory. For example,

    > c:
> cd c:\tutorial

  2. Enter the following statement at the command line to run the Message Agent against the consolidated database:

    dbremote -c "dbn=hq;uid=dba;pwd=sql"

    This command line assumes that the hq database is currently running on the default server. If the database is not running, you must supply a dbf parameter with the database file name instead of the dbn parameter.

    For more information on dbremote options, see The Message Agent.

  3. Click Shutdown on the Message Agent window to stop the Message Agent when the messages have been sent. The Message Agent window displays the message Execution completed when all processing is complete.


Receive data at the remote database

To receive the insert statement at the remote database, you must run the Message Agent, dbremote, at the remote database.

toggle To receive data at the remote database

  1. From a command prompt, change to your tutorial directory. For example,

    > c:
> cd c:\tutorial

  2. Enter the following statement at the command line to run the Message Agent against the field database:

    dbremote -c "dbn=field;uid=dba;pwd=sql"

    This command line assumes that the field database is currently running on the default server.

    For more information on dbremote options, see The Message Agent.

  3. Click Shutdown on the Message Agent window to stop the Message Agent when the messages have been processed. The Message Agent window displays the message Execution completed when all processing is complete.

The Message Agent window displays status information while running. This information can be output to a log file for record keeping in a real setup. You will see that the Message Agent first receives a message from hq, and then sends a message. This return message contains confirmation of successful receipt of the replication update; such confirmations are part of the SQL Remote message tracking system that ensures message delivery even in the event of message system errors.

Verify that the data has arrived

You should now connect to the remote field database using Interactive SQL, and inspect the SalesRep and Customer tables, to see which rows have been received.

toggle To verify that the data has arrived

  1. Connect to the field database using Interactive SQL.

  2. Inspect the SalesRep table by executing the following statement:

    SELECT * FROM SalesRep

    You will see that the SalesRep table contains both rows entered at the consolidated database. This is because the SalesRepData publication included all the data from the SalesRep table.

  3. Inspect the Customer table by executing the following statement:

    SELECT * FROM Customer

    You will also see that the Customer table contains only row (Ocean Sports) entered at the consolidated database. This is because the SalesRepData publication included only those customers assigned to the subscribed Sales Rep.


Replicate from the remote database to the consolidated database

You should now try entering data at the remote database and sending it to the consolidated database. Only the outlines are presented here.

toggle To replicate data from the remote database to the consolidated database

  1. Connect to the field database from Interactive SQL.

  2. Insert a row at the remote database by executing the following statement:

    INSERT INTO Customer (cust_key, name, rep_key)
VALUES ('cust3', 'North Land Trading', 'rep1')

  3. Commit the insertion by executing the following statement::

    COMMIT;

  4. With the field.db database running, run the dbremote utility from a command line to send the message to the consolidated database.

    dbremote -c "dbn=field;uid=dba;pwd=sql"

  5. With the hq.db database running, run the dbremote utility from a command line to receive the message at the consolidated database:

    dbremote -c "dbn=hq;uid=dba;pwd=sql"

  6. Connect to the consolidated database. Display the Customer table by executing the following statement:

    SELECT *
FROM Customer
    cust_key | name | rep_key
    cust1 | Ocean Sports | rep1
    cust2 | Sports Plus | rep2
    cust3 | North Land Trading | rep1

In this simple example, there is no protection against duplicate entries of primary key values. SQL Remote does provide for such protection. For information, see the chapters on SQL Remote Design.


A sample publication

The command file salespub.sql contains a set of statements that creates a publication on the sample database. This publication illustrates several of the points of the tutorials, in more detail.

toggle To add the publication to the sample database

  1. Connect to the sample database from Interactive SQL.

  2. In the SQL Statements pane, execute the following statement:

    READ path\scripts\salespub.sql

    where path is your SQL Anywhere directory.

    The salespub.sql publication adds columns to some of the tables in the sample database, creates a publication and subscriptions, and also adds triggers to resolve update conflicts that may occur.


A Tutorial for Adaptive Server Enterprise Users

About this chapter

This chapter presents a tutorial in which you set up a simple SQL Remote replication system between an Adaptive Server Enterprise database and an Adaptive Server Anywhere database, from scratch.


Introduction

This chapter presents a tutorial to lead you through setting up a SQL Remote installation. The installation replicates data between an Adaptive Server Enterprise database (the consolidated database) and an Adaptive Server Anywhere database (the remote database).


Goals

In the tutorial you act as the system administrator of a consolidated Adaptive Server Enterprise database, and set up a simple replication system. The replication system consists of a simple sales database, with two tables.

The consolidated database holds all of the database, while the remote database has all of one table, but only some of the rows in the other table.

The tutorial takes you through the following steps:

  • Creating a consolidated database on your Adaptive Server Enterprise server.

  • Creating a file-sharing replication system with a single Adaptive Server Anywhere remote database.

  • Replicating data between the two databases.


The database

The tutorial uses a simple two-table database. One table holds information about sales representatives, and the other about customers. The tables are much simpler than you would use in a real database; this allows us to focus just on those issues important for replication.

Database schema

The database schema for the tutorial is illustrated in the figure.

The Customer table has a foreign key to the SalesRep table.

Features to note include the following:

  • Each sales representative is represented by one row in the SalesRep table.

  • Each customer is represented by one row in the customer table.

  • Each customer is assigned to a single Sales representative, and this assignment is built in to the database as a foreign key from the Customer table to the SalesRep table. The relationship between the Customer table and the SalesRep table is many-to-one.

The tables in the database

The tables are described in more detail as follows:

Table Description
SalesRep One row for each sales representative that works for the company. The SalesRep table has the following columns:

  • rep_key An identifier for each sales representative. This is the primary key.

  • name The name of each sales representative.

The SQL statement creating this table is as follows:
CREATE TABLE SalesRep (
   rep_key CHAR(12) NOT NULL,
   name CHAR(40) NOT NULL,
   PRIMARY KEY (rep_key)
)
Customer One row for each customer that does business with the company. The Customer table includes the following columns:

  • cust_key An identifier for each customer. This is the primary key.

  • name The name of each customer.

  • rep_key An identifier for the sales representative in a sales relationship. This is a foreign key to the SalesRep table.

The SQL statement creating this table is as follows:
CREATE TABLE Customer (
   cust_key CHAR(12) NOT NULL,
   name CHAR(40) NOT NULL,
   rep_key CHAR(12) NOT NULL,
   FOREIGN KEY ( rep_key )
      REFERENCES SalesRep (rep_key ),
   PRIMARY KEY (cust_key)
)


Replication goals

The goals of the replication design are to provide each sales representative with the following information:

  • The complete SalesRep table.

  • Those customers assigned to them.

The tutorial describes how to meet this goal using SQL Remote.


Tutorial: Adaptive Server Enterprise replication

The following sections are a tutorial describing how to set up a simple SQL Remote replication system.

This tutorial describes the stored procedures used to configure and manage SQL Remote. It also describes how to run the ssxtract utility to extract remote databases from a consolidated database and the Message Agents to send information between the databases in the replication system.

In this tutorial you act as the administrator of the consolidated database, and set up a simple replication system using the file-sharing message link. The simple example is a primitive model for a sales-force automation system, with two tables. One contains a list of sales representatives, and another a list of customers. The tables are replicated in a setup with one consolidated database and one remote database. You can install this example on one computer.


First steps

Create a login name and password

To work through the tutorial, you must have system administrator privileges on an Adaptive Server Enterprise server. The tutorial assumes that your login name is the two-letter word sa and that your password is sysadmin.

The tutorial uses the Adaptive Server Enterprise isql utility. With the login name and password as given above, you can connect to your Adaptive Server Enterprise server using the following command line:

isql -S server-name -U sa -P sysadmin

where server-name is the name of the Adaptive Server Enterprise server to which you connect.

Ensure that you have an appropriate login ID and can connect to your server before starting this tutorial.

Create a database

Create a database named hq on your Adaptive Server Enterprise server with sufficient space to hold the tables and data required by the tutorial database. A space of 4 MB is sufficient.

toggle To create a database

  1. Using isql, connect to the server as a user with system administrator privileges:

    isql -S server-name -U sa -P sysadmin

  2. Use the master database:

    use master
go

  3. Create a database named hq. In this example, we use a 5 MB database with a 5 Mb log, on two different devices:

    create database hq
on database_device = 5
log on log_device = 5
go

For more information on how to create databases and assign space to them, see your Adaptive Server Enterprise documentation.

Install SQL Remote

You need to install SQL Remote into the hq database.

toggle To install SQL Remote into the hq database

  1. If the system administrator login name you are using does not have the hq database as the default database, make a backup copy of the ssremote.sql script from your installation directory, and add the following two lines to the beginning of the script:

    use hq
go

  2. Change to the tutorial directory. Then, using isql, connect to the server using the hq database, and run the ssremote.sql script from your SQL Remote installation directory. The following command should be entered all on one line:

    isql -S server-name -U sa -P sysadmin -I ssremote.sql

  3. If the system administrator login name you are using does not have the hq database as the default database, make a backup copy of the stableq.sql script from your installation directory, and add the following two lines to the beginning of the script:

    use hq
go

  4. Using isql, connect to the server using the hq database, and run the stableq.sql script from your SQL Remote installation directory. The following command should be entered all on one line:

    isql -S server-name -U sa -P sysadmin -I stableq.sql
Create directories for messages

Create a directory to hold the files from this tutorial. For example:

mkdir c:\tutorial

You should create a directory for each of the two users of the replication system under your parent directory for this tutorial:

mkdir c:\tutorial\hq
mkdir c:\tutorial\field

The next step is to add a pair of tables to the consolidated database.

toggle To add tables to the consolidated database

  1. Connect to the hq database from isql, as a system administrator.

  2. Use the hq database:

    use hq
go

  3. Create the SalesRep table with the following statement:

    create table SalesRep (
   rep_key char(12) not null,
   name char(40) not null,
   primary key (rep_key) )
go

  4. Create the Customer table with the following statement:

    create table Customer (
   cust_key char(12) not null,
   name char(40) not null,
   rep_key char(12) not null,
   primary key (cust_key) )
go

  5. Alter the Customer table to add a foreign key to the SalesRep table:

    alter table Customer
add foreign key
( rep_key ) references SalesRep
go

You are now ready for the rest of the tutorial.


Setting up the consolidated database

This section of the tutorial describes how to prepare the consolidated database of a simple replication system.

Preparing a consolidated database for replication involves the following steps:

  1. Create a message type to use for replication.

  2. Grant PUBLISH permissions to a user ID to identify the source of outgoing messages.

  3. Grant REMOTE permissions to all user IDs that are to receive messages.

  4. Create a publication describing the data to be replicated.

  5. Create subscriptions describing who is to receive the publication.

You should have system administrator authority to carry out these tasks.


Create the message links and addresses

In this tutorial, messages are exchanged using the shared file link. You must create a FILE message type supplying the address of the consolidated database publisher.

toggle To create the message type

  • Execute the sp_remote_type stored procedure, using HQ as the address of the consolidated database publisher:

    sp_remote_type file, hq
go

    The address (hq) for a file link is a directory in which files containing the message are placed. It is taken relative to the SQLRemote environment variable or registry entry. As you have not set this value, the address is taken relative to the directory from which the Message Agent is run. You should run the Message Agent from your tutorial directory for the addresses to be interpreted properly.

    For information about setting the SQLRemote value, see Setting message type control parameters.

With the message type defined, you can now make the necessary users.


Create the necessary users and permissions

A set of users and permissions are required for SQL Remote installations. In this tutorial, the following are required:

  • A remote user or subscriber, with name field_user.

  • A publisher user name, called hq_user.

This section describes the steps you need to take to create each user and assign them the necessary permissions.

toggle To create the publisher

  1. Add a login called hq_user, with hq as the default database and with system administrator access:

    exec sp_addlogin hq_user, hq_pwd, hq
go
exec sp_role 'grant', sa_role, hq_user
go

  2. Add the login name as a user to the HQ database:

    use hq
go
exec sp_adduser hq_user
go

  3. Make this user the publisher of the HQ database:

    exec sp_publisher hq_user
go
Add a remote user

Each remote database is identified in the consolidated database by a user ID with REMOTE permissions. Whether the remote database is a single-user server or a database server with many users, it needs a single user ID to represent it to the consolidated database.

In a mobile workgroup setting, remote users may already be users of the consolidated database, and so no new users would need to be added; although they would need to be set as remote users.

When a remote user is added to a database, the message system they use and their address under that message system need to be stored along with their database user ID.

toggle To create the subscriber

  1. If you do not have a login name that you can use for the remote user, add a login:

    exec sp_addlogin field_user, field_pwd, hq
go

  2. Add a user to the hq database:

    exec sp_adduser field_user
go

  3. Grant the user remote permissions. Execute the sp_grant_remote stored procedure, using field_user as the user name, file as the message type, and the appropriate directory as the address:

    exec sp_grant_remote field_user, file, field
go

    As with the publisher address, the address of the remote user (field) is a directory relative to the SQLRemote environment variable or registry entry. As you have not set this value, the address is taken relative to the directory from which the Message Agent is run. You should run the Message Agent from your tutorial directory for the addresses to be interpreted properly.

    For information about setting the SQLRemote value, see Setting message type control parameters.


Create the publication and subscription

The remaining task is to define the data to be replicated. To do this, you must first create a publication, which defines the available data, and then create a subscription for field_user, which defines the data that user is sharing.

In Adaptive Server Enterprise, they are created with the sp_create_publication procedure, which creates an empty publication, and the sp_add_article procedure, which adds articles to the procedure. Also, each table must be marked for replication before it can be included in a publication.

toggle To create the publication

  1. Create an empty publication:

    exec sp_create_publication SalesRepData
go

  2. Mark both the SalesRep table and the Customer table for publication:

    exec sp_add_remote_table SalesRep
go
exec sp_add_remote_table Customer
go

  3. Add the whole SalesRep table to the SalesRepData publication:

    exec sp_add_article SalesRepData, SalesRep
go

  4. Add the Customer table to the SalesRepData publication, using the rep_key column to partition the table. The following statement should be typed all on one line, except for the go:

    exec sp_add_article SalesRepData, Customer, NULL, 'rep_key'
go
Add a subscription

Each user ID that is to receive changes to a publication must have a subscription to that publication. Subscriptions can only be created for a valid remote user. You need to add a subscription to the SalesRepData publication for the remote database user field_user.

toggle To create a subscription

  • Create a subscription to SalesRepData for field_user, with a subscription value of rep1:

    exec sp_subscription 'create', SalesRepData, field_user, 'rep1'
go

    At this stage, the subscription is not started—that is, no data will be exchanged. The subscription is started by the database extraction utility.


Extract the remote database

There are three stages to producing a remote Adaptive Server Anywhere database:

  • Extract the schema and data into a set of files. You do this using the ssxtract utility.

  • Create an Adaptive Server Anywhere database.

  • Load the schema and data into the database.

Extracting the schema and data

With all the information included, the next step is to extract an Adaptive Server Anywhere database for user field_user. The following command line (entered all on one line, from the tutorial directory) carries out this procedure:

ssxtract -v -c "eng=server-name; dbn=hq;uid=sa;pwd=sysadmin" C:\tutorial\field field_user

The options have the following meaning.

  • -v Verbose mode. For development work, this provides additional output.

  • -c Connection string option. The connection string is supplied in double quotes following the -c.

  • eng=server-name Specifies the server to which the extraction utility is to connect.

  • dbn=hq Specifies the database on the server to use; in this case hq.

  • uid=sa The login ID to use to log on to the database.

  • pwd=sysadmin The password to use to log on to the database.

  • C:\tutorial\field The directory in which to place files holding the data.

  • field_user The user ID for which to extract the database.

For more information on extraction utility options, see The extraction utility.

Running this command produces the following files:

  • Reload script The reload script is named reload.sql, and is placed in the current directory.

  • Data files Files containing data to load into the database. In this case, these files are empty.

Creating an Adaptive Server Anywhere database

You can create an Adaptive Server Anywhere database using the dbinit utility. A simple Adaptive Server Anywhere database is a file, unlike Adaptive Server Enterprise databases.

You should create the Adaptive Server Anywhere database so that it is compatible with Adaptive Server Enterprise database behavior, unless you have set options in your Adaptive Server Enterprise server that are different from the default.

toggle To create a database file named field.db

  • Enter the following command from the c:\tutorial\field directory:

    dbinit -b -c -k field.db

    The -b option forces use of blank padding in string comparisons. The -c option enforces case sensitivity for string comparisons. The -k option makes the system catalog more compatible with Adaptive Server Enterprise.

Loading the data into the database

You can load the data into the database using the Adaptive Server Anywhere Interactive SQL utility or the rtsql utility. rtsql is an alternative to Interactive SQL for batch processes only, and is provided for the runtime database.

toggle To load the data into the database using Interactive SQL

  1. Start an Adaptive Server Anywhere server running on the field database:

    dbeng9 field.db

  2. Connect to the server using the Interactive SQL utility:

    dbisql -c "eng=field;dbn=field;uid=DBA;pwd=SQL"

    The user ID and password must be entered in upper case, as the Adaptive Server Anywhere database was created as case-sensitive.

  3. Load the data using the READ command:

    READ C:\TUTORIAL\RELOAD.SQL
toggle To load the data into the database as a batch process

  1. Start an Adaptive Server Anywhere server running on the field database:

    dbeng9 field.db

  2. Run the script from Interactive SQL:

    dbisql -c "eng=field;dbn=field;uid=DBA;pwd=SQL" reload.sql

    The user ID and password must be entered in upper case, as the Adaptive Server Anywhere database was created as case-sensitive.

What next?

The system is now ready for replication.

For the next step, inserting and replicating data, see the section Start replicating data.


Enter data at the consolidated database

In this section we enter data into the SalesRep and Customer tables at the consolidated (Adaptive Server Enterprise) database, and replicate this data to the Adaptive Server Anywhere database.

toggle To enter data at the Adaptive Server Enterprise database

  1. Connect to the Adaptive Server Enterprise server from isql:

    isql -S server-name -U sa -P sysadmin

  2. Ensure you are using the hq database, and enter a series of rows:

    use hq
go
insert into SalesRep (rep_key, name)
values ('rep1', 'Field User')
go
insert into SalesRep (rep_key, name)
values ('rep2', 'Another User')
go
insert into Customer (cust_key, name, rep_key)
values ('cust1', 'Ocean Sports', 'rep1')
go
insert into Customer (cust_key, name, rep_key)
values ('cust2', 'Sports Plus', 'rep2')
go
commit
go

    Ocean Sports is assigned to Field User, and Sports Plus is assigned to Another User. You must commit the changes, as SQL Remote replicates only committed changes.

Having entered the data at the consolidated database, you now need to send the relevant rows to the remote Adaptive Server Anywhere database.


Send data from the consolidated database

To send the rows to the remote database, you must run the Message Agent at the consolidated database. The ssremote program is the Message Agent for Adaptive Server Enterprise.

toggle To replicate the data from Adaptive Server Enterprise

  1. Enter the following statement (on a single line) at the command line to run the Message Agent against the consolidated database:

    ssremote -c "eng=server-name;dbn=hq;uid=sa;pwd=sysadmin"

  2. Click Shutdown on the Message Agent window to stop the Message Agent when the messages have been sent.


Receive data at the remote database

To receive the insert statement at the remote database, you must run the Message Agent, dbremote, at the remote database.

toggle To receive the data at Adaptive Server Anywhere

  1. With the database server running, receive the data using the Message Agent for Adaptive Server Anywhere:

    dbremote -c "eng=field;dbn=field;uid=DBA;pwd=SQL"

    For more information on dbremote options, see The Message Agent.

  2. Click Shutdown on the Message Agent window to stop the Message Agent when the messages have been processed.

The Message Agent window displays status information while running. This information can be output to a log file for record keeping in a production setup.

The Message Agent first receives a message from hq, and then sends a message. This return message contains confirmation of successful receipt of the replication update; such confirmations are part of the SQL Remote message tracking system that ensures message delivery even in the event of message system errors.

Verify that the data has arrived

You should now connect to the remote field database using Interactive SQL, and inspect the SalesRep and Customer tables, to see which rows have been received.

toggle To verify that the data has arrived

  1. Connect to the field database using Interactive SQL.

  2. Inspect the SalesRep table by typing the following statement:

    SELECT * FROM SalesRep

    You will see that the SalesRep table contains both rows entered at the consolidated database. This is because the SalesRepData publication included all the data from the SalesRep table.

  3. Inspect the Customer table by typing the following statement:

    SELECT * FROM Customer

    You will see that the Customer table contains only one row (Ocean Sports) entered at the consolidated database. This is because the SalesRepData publication included only those customers assigned to the subscribed Sales Rep.


Replicate from the remote database to the consolidated database

You should now try entering data at the remote database and sending it to the consolidated database. Only the outlines are presented here.

toggle To replicate data from the remote database to the consolidated database

  1. Connect to the field database from Interactive SQL.

  2. INSERT a row at the remote database. For example

    INSERT INTO Customer (cust_key, name, rep_key)
VALUES ('cust3', 'North Land Trading', 'rep1')

  3. COMMIT the row.

    COMMIT;

  4. With the field.db database running, run dbremote to send the message to the consolidated database.

    dbremote -c "eng=field;dbn=field;uid=DBA;pwd=SQL"

  5. Run ssremote to receive the message at the consolidated database:

    ssremote -c "eng=server-name;dbn=hq;uid=sa;pwd=sysadmin"

  6. Connect to the consolidated database and display the Customer table. This now has three rows:

    SELECT *
FROM Customer
    cust_key | name | rep_key
    cust1 | Ocean Sports | rep1
    cust2 | Sports Plus | rep2
    cust3 | North Land Trading | rep1

In this simple example, there is no protection against duplicate entries of primary key values. SQL Remote does provide for such protection. For information, see the chapters on SQL Remote Design.


Principles of SQL Remote Design

About this chapter

This chapter describes general issues and principles for designing a SQL Remote installation.

For system-specific details, see the chapters SQL Remote Design for Adaptive Server Enterprise and SQL Remote Design for Adaptive Server Anywhere.


Design overview

This chapter describes general publication design issues that you must address when designing a SQL Remote installation. It also describes how SQL Remote replicates data.

Design at the consolidated database

Like all SQL Remote administrative tasks, design is carried out by a database administrator or system administrator at the consolidated database.

The Adaptive Server Enterprise System Administrator or database administrator should perform all SQL Remote configuration tasks.


Ensuring compatible databases

You should ensure that all databases participating in a SQL Remote installation are compatible in terms of sort orders, character sets, and database option settings.

If your installation includes both Adaptive Server Enterprise and Adaptive Server Anywhere databases, you should ensure your Adaptive Server Anywhere databases are created in an Adaptive Server Enterprise-compatible fashion.

For a full description of how to create Enterprise-compatible Adaptive Server Anywhere databases, see Creating a Transact-SQL-compatible database. This section provides a brief description only.

toggle To create an Enterprise-compatible Adaptive Server Anywhere database ( Sybase Central )

  • The Create Database wizard provides a button that sets each of the available choices to emulate Adaptive Server Enterprise. This is the simplest way to create a Transact-SQL-compatible database.

toggle To create an Enterprise-compatible Adaptive Server Anywhere database ( Command line )

  1. Ensure trailing blanks are ignored You can do this using the dbinit -b option.

  2. Ensure the dbo user ID is set If you have a database that already has a user ID named dbo, then you can transfer the ownership of the Adaptive Server Anywhere Transact-SQL system views to another user ID. You can do this using the dbinit -g option.

  3. Remove historical system views You can do this with the dbinit -k option.

  4. Make the database case sensitive You can do this with the dbinit -c option.

The following command creates a case-sensitive database named test.db in the current directory, using the current dbo user, ignoring trailing blanks, and removing historical system views:

dbinit -b -c -k test.db


Using compatible sort orders and character sets

The SQL Remote Message Agent does not perform any character set conversions.

Character sets in Adaptive Server Anywhere installations

For an Adaptive Server Anywhere installation, the character set and collation used by the consolidated database must be the same as the remote databases. For information about supported character sets, see International Languages and Character Sets.

Character sets in Adaptive Server Enterprise installations

The Open Client/Open Server libraries perform character set conversions between SSREMOTE and Adaptive Server Enterprise whenever the LOCALES.DAT character set is different from the Adaptive Server Enterprise character set. Both character sets must be installed on the Adaptive Server Enterprise server and conversion must be supported.

Character sets in mixed installations

The locales.dat settings (which are used by all Open Client applications) must match the remote Adaptive Server Anywhere settings.

The following table provides recommended matches between Adaptive Server Enterprise and Adaptive Server Anywhere character sets. The matches are not all complete.

Adaptive Server Anywhere collation name | Open Client / Open Server name | Open Client / Open Server case-sensitive sort order | Open Client / Open Server case-insensitive sort order
default | cp850 | dictionary_cp850 | nocase_cp850
437LATIN1 | cp437 | dictionary_cp437 | nocase_cp437
437ESP | cp437 | espdict_cp437 | espnocs_cp437
437SVE | cp437 | bin_cp437 | bin_cp437
819CYR | iso_1 | bin_iso_1 | bin_iso_1
819DAN | iso_1 | bin_iso_1 | bin_iso_1
819ELL | iso_1 | bin_iso_1 | bin_iso_1
819ESP | iso_1 | espdict_iso_1 | espnocs_iso_1
819ISL | iso_1 | bin_iso_1 | bin_iso_1
819LATIN1 | iso_1 | dictionary_iso_1 | nocase_iso_1
819LATIN2 | iso_1 | bin_iso_1 | bin_iso_1
819NOR | iso_1 | bin_iso_1 | bin_iso_1
819RUS | iso_1 | bin_iso_1 | bin_iso_1
819SVE | iso_1 | bin_iso_1 | bin_iso_1
819TRK | iso_1 | bin_iso_1 | bin_iso_1
850CYR | cp850 | bin_cp850 | bin_cp850
850DAN | cp850 | scandict_cp850 | scannocp_cp850
850ELL | cp850 | bin_cp850 | bin_cp850
850ESP | cp850 | espdict_cp850 | espnocs_cp850
850ISL | cp850 | scandict_cp850 | scannocp_cp850
850LATIN1 | cp850 | dictionary_cp850 | nocase_cp850
850LATIN2 | cp850 | bin_cp850 | bin_cp850
850NOR | cp850 | scandict_cp850 | scannocp_cp850
850RUS | cp850 | bin_cp850 | bin_cp850
850SVE | cp850 | scandict_cp850 | scannocp_cp850
850TRK | cp850 | bin_cp850 | bin_cp850
852LATIN2 | cp852 | bin_cp852 | bin_cp852
852CYR | cp852 | bin_cp852 | bin_cp852
855CYR | cp855 | cyrdict_cp855 | cynocs_cp855
857TRK | cp857 | bin_cp857 | bin_cp857
860LATIN1 | cp860 | bin_cp860 | bin_cp860
866RUS | cp866 | rusdict_cp866 | rusnocs_cp866
869ELL | cp869 | bin_cp869 | bin_cp869
932JPN | sjis | bin_sjis | bin_sjis
EUC_JAPAN | eucjis | bin_eucjis | bin_eucjis
EUC_CHINA | eucgb | bin_eucgb | bin_eucgb
EUC_TAIWAN | eucb5 | bin_big5 | bin_big5
EUC_KOREA | eucksc | bin_eucksc | bin_eucksc
UTF8 | utf8 | bin_utf8 | bin_utf8


How statements are replicated

SQL Remote replication is based on the transaction log, enabling it to replicate only changes to data, rather than all data, in each update. When we say that SQL Remote replicates data, we really mean that SQL Remote replicates SQL statements that modify data .

Only committed transactions are replicated

SQL Remote replicates only statements in committed transactions, to ensure proper transaction atomicity throughout the replication setup and maintain a consistency among the databases involved in the replication, albeit with some time lag while the data is replicated.

Primary keys

When an UPDATE or a DELETE is replicated, SQL Remote uses the primary key columns to uniquely identify the row being updated or deleted. All tables being replicated must have a declared primary key or uniqueness constraint. A unique index is not sufficient. The columns of the primary key are used in the WHERE clause of replicated updates and deletes. If a table has no primary key, the WHERE clause refers to all columns in the table.

An UPDATE is not always an UPDATE

When a simple INSERT statement is entered at one database, it is sent to other databases in the SQL Remote setup as an INSERT statement. However, not all statements are replicated exactly as they are entered by the client application. This section describes how SQL Remote replicates SQL statements. It is important to understand this material if you are to design a robust SQL Remote installation.

The Message Agent is the component that carries out the replication of statements.


Replication of inserts and deletes

INSERT and DELETE statements are the simplest replication case. SQL Remote takes each INSERT or DELETE operation from the transaction log, and sends it to all sites that subscribe to the row being inserted or deleted.

If only a subset of the columns in the table is subscribed to, the INSERT statements sent to subscribers contains only those columns.

The Message Agent ensures that statements are not replicated to the user that initially entered them.


Replication of updates

UPDATE statements are not replicated exactly as the client application enters them. This section describes two ways in which the replicated UPDATE statement may differ from the entered UPDATE statement.

UPDATE statements replicated as INSERTS or DELETES

If an UPDATE statement has the effect of removing a row from a given remote user's subscription, it is sent to that user as a DELETE statement. If an UPDATE statement has the effect of adding a row to a given remote user's subscription, it is sent to that user as an INSERT statement.

The figure illustrates a publication, where each subscriber subscribes by their name:

A publication, with a Rep column containing Marc and Ann. Each subscriber receives the rows marked with their own name.

An UPDATE that changes the Rep value of a row from Marc to Ann is replicated to Marc as a DELETE statement, and to Ann as an INSERT statement.

This reassignment of rows among subscribers is sometimes called territory realignment, because it is a common feature of sales force automation applications, where customers are periodically reassigned among representatives.

UPDATE conflict detection

An UPDATE statement changes the value of one or more rows from some existing value to a new value. The rows altered depend on the WHERE clause of the UPDATE statement.

When SQL Remote replicates an UPDATE statement, it does so as a set of single-row updates. These single-row statements can fail for one of the following reasons:

  • The row to be updated does not exist Each row is identified by its primary key values, and if a primary key has been altered by some other user, the row to be updated is not found.

    In this case, the UPDATE does not update anything.

  • The row to be updated differs in one or more of its columns If one of the values expected to be present has been changed by some other user, an update conflict occurs.

    At remote databases, the update takes place regardless of the values in the row.

    At the consolidated database, SQL Remote allows conflict resolution operations to take place. Conflict resolution operations are held in a trigger or stored procedure, and run automatically when a conflict is detected.

    In Adaptive Server Anywhere, the conflict resolution trigger runs before the update, and the update proceeds when the trigger is finished. In Adaptive Server Enterprise, the conflict resolution procedure runs after the update has been applied.

  • A table without a primary key or uniqueness constraint refers to all columns in the WHERE clause of replicated updates When two users update the same row, replicated updates will not update anything and databases will become inconsistent. All replicated tables should have a primary key or uniqueness constraint and the columns in the constraint should never be updated.


Replication of procedures

Any replication system is faced with a choice between two options when replicating a stored procedure call:

  • Replicate the procedure call A corresponding procedure is executed at the replicate site, or

  • Replicate the procedure actions The individual actions (INSERTs, UPDATEs, DELETEs and so on) of the procedure are replicated.

SQL Remote replicates procedures by replicating the actions of a procedure. The procedure call is not replicated.


Replication of triggers

Trigger replication in SQL Remote is different for the Adaptive Server Enterprise Message Agent and the Adaptive Server Anywhere Message Agent.

Trigger replication from Adaptive Server Enterprise

From Adaptive Server Enterprise, trigger actions are replicated. You must ensure that triggers are not fired in the remote Adaptive Server Anywhere databases. If the trigger were fired, its actions would be executed twice.

The Adaptive Server Anywhere FIRE_TRIGGERS database option prevents triggers from being fired. If you set this option for the user ID used by the Message Agent, be careful to not use this user ID for other purposes.

An alternative approach to preventing trigger execution, available only for Adaptive Server Anywhere, is to use the following condition around the body of your triggers:

IF CURRENT REMOTE USER IS NULL

This make execution conditional on whether the current user is the Message Agent.

Trigger replication from Adaptive Server Anywhere

By default, the Message Agent for Adaptive Server Anywhere does not replicate actions performed by triggers; it is assumed that the trigger is defined remotely. This avoids permissions issues and the possibility of each action occurring twice. There are some exceptions to this rule:

  • Conflict resolution trigger actions The actions carried out by conflict resolution, or RESOLVE UPDATE, triggers are replicated from a consolidated database to all remote databases, including the one that sent the message causing the conflict.

  • Replication of BEFORE triggers Some BEFORE triggers can produce undesirable results when using SQL Remote, and so BEFORE trigger actions that modify the row being updated are replicated, before UPDATE actions.

    You must be aware of this behavior when designing your installation. For example, a BEFORE UPDATE that bumps a counter column in the row to keep track of the number of times a row is updated would double count if replicated, as the BEFORE UPDATE trigger will fire when the UPDATE is replicated. To prevent this problem, you must ensure that, at the subscriber database, the trigger is not present or does not carry out the replicated action. Also, a BEFORE UPDATE that sets a column to the time of the last update will get the time the UPDATE is replicated as well.

An option to replicate trigger actions

The Adaptive Server Anywhere Message Agent has an option that causes it to replicate all trigger actions when sending messages. This is the dbremote -t option.

If you use this option, you must ensure that the trigger actions are not carried out twice at remote databases, once by the trigger being fired at the remote site, and once by the explicit application of the replicated actions from the consolidated database.

To ensure that trigger actions are not carried out twice, you can wrap an IF CURRENT REMOTE USER IS NULL ... END IF statement around the body of the triggers or you can set the Adaptive Server Anywhere Fire_triggers option to OFF for the Message Agent user ID.


Replication of data definition statements

Data definition statements (CREATE, ALTER, DROP, and others that modify database objects) are not replicated by SQL Remote unless they are entered while in passthrough mode.

For information about passthrough mode for Adaptive Server Anywhere, see Using passthrough mode.


How data types are replicated

Long binary or character data, and datetime data, need special consideration.


Replication of blobs

Blobs are LONG VARCHAR, LONG BINARY, TEXT, and IMAGE data types: values that are longer than 256 characters.

Adaptive Server Anywhere replication

SQL Remote includes a special method for replicating blobs between Adaptive Server Anywhere databases.

The Message Agent uses a variable in place of the value in the INSERT or UPDATE statement that is being replicated. The value of the variable is built up by a sequence of statements of the form

SET vble = vble || 'more_stuff'

This makes the size of the SQL statements involving long values smaller, so that they fit within a single message. The SET statements are separate SQL statements, so that the blob is effectively split over several SQL Remote messages.

Adaptive Server Enterprise replication

Blobs can be replicated to and from Adaptive Server Enterprise as long as they fit into the Message Agent memory.

Sybase Open Client CTLIB applications that manipulate the CS_IODESC structure must not set the log_on_update member to FALSE.

Using the Verify_threshold option to minimize message size

The Verify_threshold database option can prevent long values from being verified (in the VERIFY clause of a replicated UPDATE). The default value for the option is 1000. If the data type of a column is longer than the threshold, old values for the column are not verified when an UPDATE is replicated. This keeps the size of SQL Remote messages down, but has the disadvantage that conflicting updates of long values are not detected.

There is a technique allowing detection of conflicts when Verify_threshold is being used to reduce the size of messages. Whenever a "blob" is updated, a last_modified column in the same table should also be updated. Conflicts can then be detected because the old value of the last_modified column is verified.

Using a work table to avoid redundant updates

Repeated updates to a blob should be done in a "work" table, and the final version should be assigned to the replicated table. For example, if a document in progress is updated 20 times throughout the day and the Message Agent is run once at the end of the day, all 20 updates are replicated. If the document is 200 KB in length, this causes 4 Mb of messages to be sent.

The better solution is to have a document_in_progress table. When the user is done revising a document, the application moves it from the document_in_progress table to the replicated table. The results in a single update (200 kb of messages).

Controlling replication of blobs

The Adaptive Server Anywhere BLOB_THRESHOLD option allows further control over the replication of long values. Any value longer than the BLOB_THRESHOLD option is replicated as a blob. That is, it is broken into pieces and replicated in chunks, before being reconstituted by using a SQL variable and concatenating the pieces at the recipient site.

By setting BLOB_THRESHOLD to a high value in remote Adaptive Server Anywhere databases, blobs are not broken into pieces, and operations can be applied to Adaptive Server Enterprise by the Message Agent. Each SQL statement must fit within a message, so this only allows replication of small blobs.


Replication of dates and times

When date or time columns are replicated, the Message Agent uses the setting of the SR_Date_Format, SR_Time_Format, and SR_Timestamp_Format database options to format the date.

For example, the following option setting instructs the Message Agent to send a date of May 2, 1987 as 1987-05-02.

SET OPTION SR_Date_Format = 'yyyy-mm-dd'

For more information, see SQL Remote options.

The following points may be useful when replicating dates and times:

  • The time, date, and timestamp formats must be consistent throughout the installation.

  • If the consolidated database is an Adaptive Server Anywhere database, ensure that the order of year, month, and day used for the date and timestamp formats matches the setting of the DATE_ORDER database option.

    You can change the DATE_ORDER option for the duration of each connection.

  • If the consolidated database is an Adaptive Server Enterprise database, ensure that the order of year, month, and day in the SQL Remote settings is consistent with the dateformat setting in the Adaptive Server Enterprise database.

toggle To find the dateformat settings on an Adaptive Server Enterprise database

  1. Login to the Adaptive Server Enterprise database from isql using the login ID used by ssremote. In this example, we use ssr for this login ID.

  2. Issue the following command:

    select *
from master..syslogins
where name = 'ssr'
go

    Adaptive Server Enterprise returns the default language for the ssr user.

  3. If ssr uses the default language (us_english) then the default dateformat is YMD. If the language is different from the default, enter the following command:

    sp_helplanguage language-name

    where language-name is the language in use by the ssr user. The information displayed includes the default date format for the language.


Who gets what?

Each time a row in a table is inserted, deleted, or updated, a message has to be sent to those subscribed to the row. In addition, an update may cause the subscription expression to change, so that the statement is sent to some subscribers as a delete, some as an update, and some as an insert.

For details of what statements get sent to which subscribers, see How statements are replicated. For details on subscriptions, see the following two chapters.

This section describes how SQL Remote sends the right operations to the right recipients.

The task of determining who gets what is divided between the database server and the Message Agent. The engine handles those aspects that are to do with publications, while the Message Agent handles aspects to do with subscriptions.

Adaptive Server Anywhere actions

Adaptive Server Anywhere evaluates the subscription expression for each update made to a table that is part of a publication. It adds the value of the expression to the log, both before and after the update.

Not the subscriber list
Adaptive Server Enterprise does not evaluate or enter into the log a list of subscribers. The subscription expression (a property of the publication) is evaluated and entered. All handling of subscribers is left to the Message Agent.

For a table that is part of more than one publication, the subscription expression is evaluated before and after the update for each publication.

The addition of information to the log can affect performance in the following cases:

  • Expensive expressions When a subscription expression is expensive to evaluate, it can affect performance.

  • Many publications When a table belongs to many publications, many expressions must be evaluated. In contrast, the number of subscriptions is irrelevant.

  • Many-valued expressions Some expressions are many-valued. This can lead to much additional in formation in the transaction log, with a corresponding effect on performance.

Adaptive Server Enterprise actions

In a SQL Remote for Adaptive Server Enterprise publication, the subscription expression must be a column. The subscription column contains either a single value or a comma-separated list of values.

Not the subscriber list
Adaptive Server Enterprise does not enter into the log a list of subscribers. The column value is entered. All handling of subscribers is left to the Message Agent.

When a table is marked for replication using sp_add_remote_table (which calls sp_setreplicate), Adaptive Server Enterprise places an entire before image of the row in the transaction log for deletes, and entire after image for inserts, and both images for updates. This means that the before and after values of the subscription column are available.

Message Agent actions

The Message Agent reads the evaluated subscription expressions or subscription column entries from the transaction log, and matches the before and after values against the subscription value for each subscriber to the publication. In this way, the Message Agent can send the correct operations to each subscriber.

While large numbers of subscribers do not have any impact on server performance, they can impact Message Agent performance. Both the work in matching subscription values against large numbers of subscription values, and the work in sending the messages, can be demanding.


Replication errors and conflicts

SQL Remote is designed to allow databases to be updated at many different sites. Careful design is required to avoid replication errors, especially if the database has a complicated structure. This section describes the kinds of errors and conflict that can occur in a replication setup; subsequent sections describe how you can design your publications to avoid errors and manage conflicts.

Delivery errors not discussed here
This section does not discuss issues related to message delivery failures. For information on delivery errors and how they are handled, see The message tracking system

Replication errors
Replication conflicts
Tracking SQL errors

Previous Next


Replication errors

Replication errors fall into the following categories:

  • Duplicate primary key errors Two users INSERT a row using the same primary key values, or one user updates a primary key and a second user inserts a primary key of the new value. The second operation to reach a given database in the replication system fails because it would produce a duplicate primary key.

  • Row not found errors A user DELETES a row (that is, the row with a given primary key value). A second user UPDATES or DELETES the same row at another site.

    In this case, the second statement fails, as the row is not found.

  • Referential integrity errors If a column containing a foreign key is included in a publication, but the associated primary key is not included, the extraction utility leaves the foreign key definition out of the remote database so that INSERTS at the remote database will not fail.

    This can be solved by including proper defaults into the table definitions.

    Also, referential integrity errors can occur when a primary table has a SUBSCRIBE BY expression and the associated foreign table does not: rows from the foreign table may be replicated, but the rows from the primary table may be excluded from the publication.


Replication conflicts

Replication conflicts are different from errors. Properly handled, conflicts are not a problem in SQL Remote.

  • Conflicts A user updates a row. A second user updates the same row at another site. The second user's operation succeeds, and SQL Remote allows a trigger to be fired (Adaptive Server Anywhere) or a procedure to be called (Adaptive Server Enterprise) to resolve these conflicts in a way that makes sense for the data being changed.

    Conflicts will occur in many installations. SQL Remote allows appropriate resolution of conflicts as part of the regular operation of a SQL Remote setup, using triggers and procedures.

    For information about how SQL Remote handles conflicts as they occur, see the following chapters.


Tracking SQL errors

SQL errors in replication must be designed out of your setup. SQL Remote includes an option to help you track errors in SQL statements, but this option is not intended to resolve such errors.

By setting the Replication_error option, you can specify a stored procedure to be called by the Message Agent when a SQL error occurs. By default no procedure is called.

toggle To set the Replication_error option in Adaptive Server Anywhere

  • Issue the following statement:

    SET OPTION
remote-user.Replication_error
= 'procedure-name'

    where remote-user is the user ID on the Message Agent command line, and procedure-name is the procedure called when a SQL error is detected.

toggle To set the Replication_error option in Adaptive Server Enterprise

  • Issue the following statement:

    exec sp_remote_option Replication_error, procedure-name
go

    where procedure-name is the procedure called when a SQL error is detected.

Replication error procedure requirements

The replication error procedure must have a single argument of type CHAR, VARCHAR, or LONG VARCHAR. The procedure is called once with the SQL error message and once with the SQL statement that causes the error.


SQL Remote Design for Adaptive Server Anywhere

About this chapter

This chapter describes how to design a SQL Remote installation when the consolidated database is an Adaptive Server Anywhere database.

Similar material for Adaptive Server Enterprise
Many of the principles of publication design are the same for Adaptive Server Anywhere and Adaptive Server Enterprise, but there are differences in commands and capabilities. There is a large overlap between this chapter and the corresponding chapter for Adaptive Server Enterprise users, SQL Remote Design for Adaptive Server Enterprise.

Design overview
Publishing data
Publication design for Adaptive Server Anywhere
Partitioning tables that do not contain the subscription expression
Sharing rows among several subscriptions
Managing conflicts
Ensuring unique primary keys
Creating subscriptions


Design overview

Designing a SQL Remote installation includes the following tasks:

  • Designing publications The publications determine what information is shared among which databases.

  • Designing subscriptions The subscriptions determine what information each user receives.

  • Implementing the design Creating publications and subscriptions for all users in the system.

All administration is at the consolidated database

Like all SQL Remote administrative tasks, design is carried out by a database administrator or system administrator at the consolidated database.

The Adaptive Server Anywhere Database Administrator should perform all SQL Remote configuration tasks.


Publishing data

This section describes how to create simple publications consisting of whole tables, or of column-wise subsets of tables; these tables are also called articles. You can perform these tasks using Sybase Central or with the CREATE PUBLICATION statement in Interactive SQL.

All publications in Sybase Central appear in the Publications folder. Any articles you create for a publication appear on the Articles tab in the right pane when a publication is selected.

Each publication can contain one or more entire tables, but partial tables are also permitted. A table can be subdivided by columns, rows, or both.

Publishing whole tables
Publishing only some columns in a table
Publishing only some rows in a table
Publishing only some rows using a WHERE clause
Publishing only some rows using a subscription expression
Altering existing publications
Dropping publications
Notes on publications


Publishing whole tables

The simplest publication you can make consists of a single article, which consists of all rows and columns of one or more tables. These tables must already exist.

toggle To publish one or more entire tables (Sybase Central)

  1. Connect to the database as a user with DBA authority.

  2. In the left pane, select the Publications folder.

  3. From the File menu, choose New > Publication.

    The Publication Creation wizard appears.

  4. Type a name for the publication. Click Next.

  5. On the Tables tab, select a table from the list of Available tables. Click Add. The table appears in the list of Selected Tables on the right.

  6. Optionally, you may add additional tables. The order of the tables is not important.

  7. Click Finish.

toggle To publish one or more entire tables (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute a CREATE PUBLICATION statement that specifies the name of the new publication and the table you want to publish.

Example

  • The following statement creates a publication that publishes the whole customer table:

    CREATE PUBLICATION pub_customer (
   TABLE customer
)

  • The following statement creates a publication including all columns and rows in each of a set of tables from the Adaptive Server Anywhere sample database:

    CREATE PUBLICATION sales (
   TABLE customer,
   TABLE sales_order,
   TABLE sales_order_items,
   TABLE product
)

For more information, see the CREATE PUBLICATION statement.


Publishing only some columns in a table

You can create a publication that contains all the rows, but only some of the columns, of a table from Sybase Central or by listing the columns in the CREATE PUBLICATION statement.

toggle To publish only some columns in a table (Sybase Central)

  1. Connect to the database as a user with DBA authority.

  2. In the left pane, select the Publications folder.

  3. From the File menu, choose New > Publication.

    The Publication Creation wizard appears.

  4. Type a name for the new publication. Click Next.

  5. On the Tables tab, select a table from the list of Available tables. Click Add. The table is added to the list of Selected Tables on the right.

  6. On the Columns tab, double-click the table's icon to expand the list of Available Columns. Select each column you want to publish and click Add. The selected columns appear on the right in the Selected Columns list.

  7. Click Finish.

toggle To publish only some columns in a table (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute a CREATE PUBLICATION statement that specifies the publication name and the table name. List the published columns in parenthesis following the table name.

Example

  • The following statement creates a publication that publishes all rows of the id, company_name, and city columns of the customer table:

    CREATE PUBLICATION pub_customer (
   TABLE customer (
      id,
      company_name,
      city )
)

For more information, see the CREATE PUBLICATION statement.


Publishing only some rows in a table

You can create a publication that contains all the columns, but only some of the rows, of a table from Sybase Central. In either case, you do so by writing a search condition that matches only the rows you want to publish.

Sybase Central and the SQL language provide two ways of publishing only some of the rows in a table; however, only one way is compatible with MobiLink.

  • WHERE clause You can use a WHERE clause to include a subset of rows in an article. All subscribers to the publication containing this article receive the rows that satisfy the WHERE clause.

  • Subscription expression You can use a subscription expression to include a different set of rows in different subscriptions to publications containing the article.

You can combine a WHERE clause and a subscription expression in an article. You can specify them in Sybase Central or in a CREATE PUBLICATION statement.

Use the Subscription expression when different subscribers to a publication are to receive different rows from a table. The Subscription expression is the most powerful method of partitioning tables.

Use the WHERE clause to exclude the same set of rows from all subscriptions to a publication.


Publishing only some rows using a WHERE clause

You can specify a WHERE clause to include in the publication only the rows that satisfy the WHERE conditions.

toggle To create a publication using a WHERE clause (Sybase Central)

  1. Connect to the database as a user with DBA authority.

  2. In the left pane, select the Publications folder.

  3. From the File menu, choose New > Publication.

    The Publication Creation wizard opens.

  4. Type a name for the new publication. Click Next.

  5. On the Tables tab, select a table from the list of Available tables. Click Add. The table is added to the list of Selected Tables on the right.

  6. On the WHERE Clauses tab, select the table then type the search condition in the lower box.

  7. Click Finish.

toggle To create a publication using a WHERE clause (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute a CREATE PUBLICATION statement that includes the rows you wish to include in the publication and a WHERE condition.

Examples

  • The following statement creates a publication that publishes the id, company_name, city, and state columns of the customer table, for the customers marked as active in the status column.

    CREATE PUBLICATION pub_customer (
   TABLE customer (
      id,
      company_name,
      city,
      state )
   WHERE status = 'active'
)

    In this case, the status column is not published. All unpublished rows must have a default value. Otherwise, an error occurs when rows are downloaded for insert from the consolidated database.

  • The following is a single-article publication sending relevant order information to Samuel Singer, a sales rep:

    CREATE PUBLICATION pub_orders_samuel_singer (
   TABLE sales_order WHERE sales_rep = 856
)

For more information, see the CREATE PUBLICATION statement.

SUBSCRIBE BY
The create publication statement also allows a SUBSCRIBE BY clause. This clause can also be used to selectively publish rows in SQL Remote. However, it is ignored during MobiLink synchronization.

Previous Next


Publishing only some rows using a subscription expression

You can specify a subscription expression to include a different set of rows in different subscriptions to publications containing the article.

For example, in a mobile workforce situation, a sales publication may be wanted where each sales rep subscribes to their own sales orders, enabling them to update their sales orders locally and replicate the sales to the consolidated database.

Using the WHERE clause model, a separate publication for each sales rep would be needed: the following publication is for sales rep Samuel Singer: each of the other sales reps would need a similar publication.

CREATE PUBLICATION pub_orders_samuel_singer (
   TABLE sales_order
      WHERE sales_rep = 856
)

To address the needs of setups requiring large numbers of different subscriptions, SQL Remote allows a subscription expression to be associated with an article. Subscriptions receive rows depending on the value of a supplied expression.

Benefits of subscription expressions

Publications using a subscription expression are more compact, easier to understand, and provide better performance than maintaining several WHERE clause publications. The database server must add information to the transaction log, and scan the transaction log to send messages, in direct proportion to the number of publications. The subscription expression allows many different subscriptions to be associated with a single publication, whereas the WHERE clause does not.

toggle To create an article using a subscription expression (Sybase Central)

  1. Connect to the database as a user with DBA authority.

  2. In the left pane, select the Publications folder.

  3. From the File menu, choose New > Publication.

    The Publication Creation wizard appears.

  4. Type a name for the publication and click Next.

  5. On the Tables tab, configure the desired values for that table.

  6. On the SUBSCRIBE BY Restrictions tab, use the controls to create the subscription expression.

  7. Follow the remaining instructions in the wizard.

toggle To create an article using a subscription expression (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute a CREATE PUBLICATION statement that includes the expression you wish to use as a match in the subscription expression.

Examples

  • The following statement creates a publication that publishes the id, company_name, city, and state columns of the customer table, and which matches the rows with subscribers according to the value of the state column:

    CREATE PUBLICATION pub_customer (
   TABLE customer (
      id,
      company_name,
      city,
      state )
   SUBSCRIBE BY state
)

  • The following statements subscribe two employees to the publication: Ann Taylor receives the customers in Georgia (GA), and Sam Singer receives the customers in Massachusetts (MA).

    CREATE SUBSCRIPTION
TO pub_customer ('GA')
FOR Ann_Taylor ;
CREATE SUBSCRIPTION
TO pub_customer ('MA')
FOR Sam_Singer

Users can subscribe to more than one publication, and can have more than one subscription to a single publication.

See also

  • CREATE PUBLICATION statement

  • Partitioning tables that do not contain the subscription expression

  • Creating subscriptions

  • Publishing only some rows using a WHERE clause

  • Altering existing publications


Altering existing publications

After you have created a publication, you can alter it by adding, modifying, or deleting articles, or by renaming the publication. If an article is modified, the entire specification of the modified article must be entered.

You can perform these tasks using Sybase Central or with the ALTER PUBLICATION statement in Interactive SQL.

toggle To modify the properties of existing publications or articles (Sybase Central)

  1. Connect to the database as a user who owns the publication or as a user with DBA authority.

  2. Right-click the publication or article and choose Properties from the popup menu.

  3. Configure the desired properties.

toggle To add articles (Sybase Central)

  1. Connect to the database as a user who owns the publication or as a user with DBA authority.

  2. In the left pane, open the Publications folder.

  3. Select the publication you want to add an article to.

  4. From the File menu, choose New > Article.

    The Article Creation wizard appears.

  5. In the Article Creation wizard, do the following:

    • Choose a table and click Next.

    • Choose the columns for the article. Click Next.

    • Enter a WHERE clause (if desired). Click Next.

    • Create a SUBSCRIBE BY restriction (if desired).

  6. Click Finish to create the article.

toggle To remove articles (Sybase Central)

  1. Connect to the database as a user who owns the publication or as a user with DBA authority.

  2. Open the Publications folder.

  3. Select the publication you want to remove an article from.

  4. Right-click the article you want to delete and choose Delete from the popup menu.

toggle To modify an existing publication (SQL)

  1. Connect to the database as a user who owns the publication or as a user with DBA authority.

  2. Connect to a database with DBA authority.

  3. Execute an ALTER PUBLICATION statement.

Example

  • The following statement adds the customer table to the pub_contact publication.

    ALTER PUBLICATION pub_contact (
   ADD TABLE customer
)

See also

  • ALTER PUBLICATION statement

  • Publishing only some rows using a WHERE clause

  • Publishing only some rows using a subscription expression


Dropping publications

You can drop a publication using either Sybase Central or the DROP PUBLICATION statement. If you drop a publication, all subscriptions to that publication are automatically deleted as well.

You must have DBA authority to drop a publication.

toggle To delete a publication (Sybase Central)

  1. Connect to the database as a user with DBA authority.

  2. Open the Publications folder.

  3. Right-click the desired publication and choose Delete from the popup menu.

toggle To delete a publication (SQL)

  1. Connect to the database as a user with DBA authority.

  2. Execute a DROP PUBLICATION statement.

Example

The following statement drops the publication named pub_orders.

DROP PUBLICATION pub_orders

See also the DROP PUBLICATION statement.


Notes on publications

  • The different publication types described above can be combined. A single publication can publish a subset of columns from a set of tables and use a WHERE clause to select a set of rows to be replicated.

  • DBA authority is required to create and drop publications.

  • Publications can be altered only by the DBA or the publication's owner.

  • Altering publications in a running SQL Remote setup is likely to cause replication errors and can lead to loss of data in the replication system unless carried out with care.

  • Views cannot be included in publications.

  • Stored procedures cannot be included in publications. For a discussion of how SQL Remote replicates procedures and triggers, see Replication of procedures.


Publication design for Adaptive Server Anywhere

Once you understand how to create simple publications, you must think about proper publication design. Sound design is an important part of building a successful SQL Remote installation. This section helps set out the principles of sound design as they apply to SQL Remote for Adaptive Server Anywhere.

Similar material for Adaptive Server Enterprise
Many of the principles of publication design are the same for Adaptive Server Anywhere and Adaptive Server Enterprise, but there are differences in commands and capabilities. There is a large overlap between this section and the corresponding section for Adaptive Server Enterprise users, Publication design for Adaptive Server Enterprise.

Design issues overview
Conditions for valid articles
Design tips for performance

Previous Next


Design issues overview

Each subscription must be a complete relational database

A remote database shares with the consolidated database the information in their subscriptions. The subscription is both a subset of the relational database held at the consolidated site, and also a complete relational database at the remote site. The information in the subscription is therefore subject to the same rules as any other relational database:

  • Foreign key relationships must be valid For every entry in a foreign key, a corresponding primary key entry must exist in the database.

    The database extraction utility ensures that the CREATE TABLE statements for remote databases do not have foreign keys defined to tables that do not exist remotely.

  • Primary key uniqueness must be maintained There is no way of checking what new rows have been entered at other sites, but not yet replicated. The design must prevent users at different sites adding rows with identical primary key values, as this would lead to conflicts when the rows are replicated to the consolidated database.

Transaction integrity must be maintained in the absence of locking

The data in the dispersed database (which consists of the consolidated database and all remote databases) must maintain its integrity in the face of updates at all sites, even though there is no system-wide locking mechanism for any particular row.

  • Locking conflicts must be prevented or resolved In a SQL Remote installation, there is no method for locking rows across all databases to prevent different users from altering the rows at the same time. Such conflicts must be prevented by designing them out of the system or must be resolved in an appropriate manner at the consolidated database.

These key features of relational databases must be incorporated into the design of your publications and subscriptions. This section describes principles and techniques for sound design.


Conditions for valid articles

All columns in the primary key must be included in the article.

Supporting INSERTS at remote databases

For INSERT statements at a remote database to replicate correctly to the consolidated database, you can exclude from an article only columns that can be left out of a valid INSERT statement. These are:

  • Columns that allow NULL.

  • Columns that have defaults.

If you exclude any column that does not satisfy one of these requirements, INSERT statements carried out at a remote database will fail when replicated to the consolidated database.

An insert fails when uploaded, because of a missing column.
Using BEFORE triggers as an alternative
An exception to this case is when the consolidated database is an Adaptive Server Anywhere database, and a BEFORE trigger has been written to maintain the columns that are not included in the INSERT statement.

Previous Next


Design tips for performance

This section presents a checklist for designing high performance SQL Remote installations.

  • Keep the number of publications small In particular, try not to reference the same table in many different publications.

    The work the database server needs to do is proportional to the number of publications. Keeping the number low and making effective use of subscriptions lightens the load on the database server.

    When operations occur on a table, the database server and the Message Agent must do some work for each publication that contains the table. Having one publication for each remote user will drastically increase the load on the database server. It is much better to have a few publications that use SUBSCRIBE BY and have subscriptions for each remote user. The database server does no additional work when more subscriptions are added for a publication. The Message Agent is designed to work efficiently with a large number of subscriptions.

  • Group publications logically For example, if there is a table that every remote user requires, such as a price list table, make a separate publication for that table. Make one publication for each table where the data can be partitioned by a column value.

  • Use subscriptions effectively When remote users receive similar subsets of the consolidated database, always use publications that incorporate SUBSCRIBE BY expressions. Do not create a separate publication for each remote user.

  • Pay attention to Update Publication Triggers In particular:

    • Use the NEW / OLD SUBSCRIBE BY syntax.

    • Tune the SELECT statements to ensure they are accessing the database efficiently.

  • Monitor the transaction log size The larger the transaction log, the longer it takes the Message Agent to scan it. Rename the log regularly and use the DELETE_OLD_LOGS option.


Partitioning tables that do not contain the subscription expression

In many cases, the rows of a table need to be partitioned even when the subscription expression does not exist in the table.

The Contact example
Partitioning the Customer table in the Contact example
Partitioning the Contact table in the Contact example
Territory realignment in the Contact example


The Contact example

The Contact database illustrates why and how to partition tables that do not contain the subscription expression.

Example

Here is a simple database that illustrates the problem.

The Contact table has a foreign key to Customer. The Customer table has a foreign key to SalesRep.

Each sales representative sells to several customers. At some customers there is a single contact, while other customers have several contacts.

The tables in the database

The three tables are described in more detail as follows:

Table Description
SalesRep All sales representatives that work for the company. The SalesRep table has the following columns:

  • rep_key An identifier for each sales representative. This is the primary key.

  • name The name of each sales representative.

The SQL statement creating this table is as follows:
CREATE TABLE SalesRep (
   Rep_key CHAR(12) NOT NULL,
   Name CHAR(40) NOT NULL,
   PRIMARY KEY (rep_key)
)
Customer All customers that do business with the company. The Customer table includes the following columns:

  • cust_key An identifier for each customer. This is the primary key.

  • name The name of each customer.

  • rep_key An identifier for the sales representative in a sales relationship. This is a foreign key to the SalesRep table.

The SQL statement creating this table is as follows:
CREATE TABLE Customer (
   Cust_key CHAR(12) NOT NULL,
   Name CHAR(40) NOT NULL,
   Rep_key CHAR(12) NOT NULL,
   FOREIGN KEY REFERENCES SalesRep,
   PRIMARY KEY (cust_key)
)
Contact All individual contacts that do business with the company. Each contact belongs to a single customer. The Contact table includes the following columns:

  • contact_key An identifier for each contact. This is the primary key.

  • name The name of each contact.

  • cust_key An identifier for the customer to which the contact belongs. This is a foreign key to the Customer table.

The SQL statement creating this table is:
CREATE TABLE Contact (
   Contact_key  CHAR(12) NOT NULL,
   Name  CHAR(40) NOT NULL,
   Cust_key  CHAR(12) NOT NULL,
   FOREIGN KEY  REFERENCES Customer,
   PRIMARY KEY  (contact_key)
)
Replication goals

The goals of the design are to provide each sales representative with the following information:

  • The complete SalesRep table.

  • Those customers assigned to them, from the Customer table.

  • Those contacts belonging to the relevant customers, from the Contact table.


Partitioning the Customer table in the Contact example

The Customer table can be partitioned using the rep_key value as a subscription expression. A publication that includes the SalesRep and Customer tables would be as follows:

CREATE PUBLICATION SalesRepData (
   TABLE SalesRep
   TABLE Customer SUBSCRIBE BY rep_key
)


Partitioning the Contact table in the Contact example

The Contact table must also be partitioned among the sales representatives, but contains no reference to the sales representative rep_key value. How can the Message Agent match a subscription value against rows of this table, when rep_key is not present in the table?

To solve this problem, you can use a subquery in the Contact article that evaluates to the rep_key column of the Customer table. The publication then looks like this:

CREATE PUBLICATION SalesRepData (
   TABLE SalesRep
   TABLE Customer
      SUBSCRIBE BY rep_key
   TABLE Contact
      SUBSCRIBE BY (SELECT rep_key
         FROM Customer
         WHERE Contact.cust_key = Customer.cust_key )
)

The WHERE clause in the subscription expression ensures that the subquery returns only a single value, as only one row in the Customer table has the cust_key value in the current row of the Contact table.

For an Adaptive Server Enterprise consolidated database, the solution is different. For more information, see Partitioning tables that do not contain the subscription column.


Territory realignment in the Contact example

In territory realignment, rows are reassigned among subscribers. In the present case, territory realignment is the reassignment of rows in the Customer table, and by implication also the Contact table, among the Sales Reps.

When a customer is reassigned to a new sales rep, the Customer table is updated. The UPDATE is replicated as an INSERT or a or a DELETE to the old and new sales representatives, respectively, so that the customer row is properly transferred to the new sales representative.

For information on the way in which Adaptive Server Anywhere and SQL Remote work together to handle this situation, see Who gets what?.

When a customer is reassigned, the Contact table is unaffected. There are no changes to the Contact table, and consequently no entries in the transaction log pertaining to the Contact table. In the absence of this information, SQL Remote cannot reassign the rows of the Contact table along with the Customer.

This failure will cause referential integrity problems: the Contact table at the remote database of the old sales representative contains a cust_key value for which there is no longer a Customer.

Use triggers to maintain Contacts

The solution is to use a trigger containing a special form of UPDATE statement, which does not make any change to the database tables, but which does make an entry in the transaction log. This log entry contains the before and after values of the subscription expression, and so is of the proper form for the Message Agent to replicate the rows properly.

The trigger must be fired BEFORE operations on the row. In this way, the BEFORE value can be evaluated and placed in the log. Also, the trigger must be fired FOR EACH ROW rather than for each statement, and the information provided by the trigger must be the new subscription expression. The Message Agent can use this information to determine which subscribers receive which rows.

Trigger definition

The trigger definition is as follows:

CREATE TRIGGER UpdateCustomer
BEFORE UPDATE ON Customer
REFERENCING NEW AS NewRow
   OLD as OldRow
FOR EACH ROW
BEGIN
   // determine the new subscription expression
   // for the Customer table
   UPDATE Contact
   PUBLICATION SalesRepData
   OLD SUBSCRIBE BY ( OldRow.rep_key )
   NEW SUBSCRIBE BY ( NewRow.rep_key )
   WHERE cust_key = NewRow.cust_key;
END;
A special UPDATE statement for publications

The UPDATE statement in this trigger is of the following special form:

UPDATE table-name
PUBLICATION publication-name
{ SUBSCRIBE BY subscription-expression |
OLD SUBSCRIBE BY old-subscription-expression
NEW SUBSCRIBE BY new-subscription-expression }
WHERE search-condition

  • Here is what the UPDATE statement clauses mean:

  • The table-name indicates the table that must be modified at the remote databases.

  • The publication-name indicates the publication for which subscriptions must be changed.

  • The value of subscription-expression is used by the Message Agent to determine both new and existing recipients of the rows. Alternatively, you can provide both OLD and NEW subscription expressions.

  • The WHERE clause specifies which rows are to be transferred between subscribed databases.

Notes on the trigger

  • If the trigger uses the following syntax:

    UPDATE table-name
PUBLICATION pub-name
   SUBSCRIBE BY sub-expression
WHERE search-condition

    the trigger must be a BEFORE trigger. In this case, a BEFORE UPDATE trigger. In other contexts, BEFORE DELETE and BEFORE INSERT are necessary.

  • If the trigger uses the alternate syntax:

    UPDATE table-name
PUBLICATION publication-name
   OLD SUBSCRIBE BY old-subscription-expression
   NEW SUBSCRIBE BY new-subscription-expression }
WHERE search-condition

    The trigger can be a BEFORE or AFTER trigger.

  • The UPDATE statement lists the publication and table that is affected. The WHERE clause in the statement describes the rows that are affected. No changes are made to the data in the table itself by this UPDATE, it makes entries in the transaction log.

  • The subscription expression in this example returns a single value. Subqueries returning multiple values can also be used. The value of the subscription expression must the value after the UPDATE.

    In this case, the only subscriber to the row is the new sales representative. In Sharing rows among several subscriptions, we see cases where there are existing as well as new subscribers.

Information in the transaction log

Here we describe the information placed in the transaction log. Understanding this helps in designing efficient publications.

  • Assume the following data:

    • SalesRep table

    rep_key | Name
    rep1 | Ann
    rep2 | Marc

    • Customer table

    cust_key | name | rep_key
    cust1 | Sybase | rep1
    cust2 | ASA | rep2

    • Contact table

    contact_key | name | cust_key
    contact1 | David | cust1
    contact2 | Stefanie | cust2

  • Now apply the following territory realignment Update statement

    UPDATE Customer
SET rep_key = 'rep2'
WHERE cust_key = 'cust1'

    The transaction log would contain two entries arising from this statement: one for the BEFORE trigger on the Contact table, and one for the actual UPDATE to the Customer table.

    SalesRepData – Publication Name
rep1 – BEFORE list
rep2 – AFTER list
UPDATE Contact
SET contact_key = 'contact1',
    name = 'David',
    cust_key = 'cust1'
WHERE contact_key = 'contact1'
SalesRepData – Publication Name
rep1 – BEFORE list
rep2 – AFTER list
UPDATE Customer
SET rep_key = 'rep2'
WHERE cust_key = 'cust1'

    The Message Agent scans the log for these tags. Based on this information it can determine which remote users get an INSERT, UPDATE or DELETE.

    In this case, the BEFORE list was rep1 and the AFTER list is rep2. If the before and after list values are different, the rows affected by the UPDATE statement have "moved" from one subscriber value to another. This means the Message Agent will send a DELETE to all remote users who subscribed by the value rep1 for the Customer record cust1 and send an INSERT to all remote users who subscribed by the value rep2.

    If the BEFORE and AFTER lists are identical, the remote user already has the row and an UPDATE will be sent.


Sharing rows among several subscriptions

There are cases where a row may need to be included in several subscriptions. For example, we may have a many-to-many relationship. In this section, we use a case study to illustrate how to handle this situation.


The Policy example

The Policy database illustrates why and how to partition tables when there is a many-to-many relationship in the database.

Example database

Here is a simple database that illustrates the problem.

The Policy table has foreign keys to both the SalesRep and Customer tables.

Each sales representative sells to several customers, and some customers deal with more than one sales representative. In this case, the relationship between Customer and SalesRep is thus a many-to-many relationship.

The tables in the database

The three tables are described in more detail as follows:

Table Description
SalesRep All sales representatives that work for the company. The SalesRep table has the following columns:

  • rep_key An identifier for each sales representative. This is the primary key.

  • name The name of each sales representative.

The SQL statement creating this table is as follows:
CREATE TABLE SalesRep (
   Rep_key CHAR(12) NOT NULL,
   Name CHAR(40) NOT NULL,
   PRIMARY KEY (rep_key)
);
Customer All customers that do business with the company. The Customer table includes the following columns:

  • cust_key A primary key column containing an identifier for each customer

  • name A column containing the name of each customer

The SQL statement creating this table is as follows:
CREATE TABLE Customer (
   Cust_key CHAR(12) NOT NULL,
   Name CHAR(40) NOT NULL,
   PRIMARY KEY (cust_key)
);
Policy A three-column table that maintains the many-to-many relationship between customers and sales representatives. The Policy table has the following columns:

  • policy_key A primary key column containing an identifier for the sales relationship.

  • cust_key A column containing an identifier for the customer representative in a sales relationship.

  • rep_key A column containing an identifier for the sales representative in a sales relationship.

The SQL statement creating this table is as follows.
CREATE TABLE Policy (
   policy_key CHAR(12) NOT NULL,
   cust_key CHAR(12) NOT NULL,
   rep_key CHAR(12) NOT NULL,
   FOREIGN KEY ( cust_key )
   REFERENCES Customer ( cust_key )
   FOREIGN KEY ( rep_key )
   REFERENCES SalesRep (rep_key ),
   PRIMARY KEY ( policy_key )
);
Replication goals

The goals of the replication design are to provide each sales representative with the following information:

  • The entire SalesRep table.

  • Those rows from the Policy table that include sales relationships involving the sales rep subscribed to the data.

  • Those rows from the Customer table listing customers that deal with the sales rep subscribed to the data.

New problems

The many-to-many relationship between customers and sales representatives introduces new challenges in maintaining a proper sharing of information:

  • We have a table (in this case the Customer table) that has no reference to the sales representative value that is used in the subscriptions to partition the data.

    Again, this problem is addressed by using a subquery in the publication.

  • Each row in the Customer table may be related to many rows in the SalesRep table, and shared with many sales representatives databases.

    Put another way, the rows of the Contact table in Partitioning tables that do not contain the subscription expression were partitioned into disjoint sets by the publication. In the present example there are overlapping subscriptions.

To meet the replication goals we again need one publication and a set of subscriptions. In this case, we use two triggers to handle the transfer of customers from one sales representative to another.

The publication


The publication

A single publication provides the basis for the data sharing:

CREATE PUBLICATION SalesRepData (
   TABLE SalesRep,
   TABLE Policy SUBSCRIBE BY rep_key,
   TABLE Customer SUBSCRIBE BY (
      SELECT rep_key FROM Policy
      WHERE Policy.cust_key =
         Customer.cust_key
   ),
);

The subscription statements are exactly as in the previous example.

How the publication works

The publication includes part or all of each of the three tables. To understand how the publication works, it helps to look at each article in turn:

  • SalesRep table There are no qualifiers to this article, so the entire SalesRep table is included in the publication.

    ...
   TABLE SalesRep,
...

  • Policy table This article uses a subscription expression to specify a column used to partition the data among the sales reps:

    ...
   TABLE Policy
   SUBSCRIBE BY rep_key,
...

    The subscription expression ensures that each sales rep receives only those rows of the table for which the value of the rep_key column matches the value provided in the subscription.

    The Policy table partitioning is disjoint: there are no rows that are shared with more than one subscriber.

    Customer table A subscription expression with a subquery is used to define the partition. The article is defined as follows:

    ...
   TABLE Customer SUBSCRIBE BY (
      SELECT rep_key
      FROM Policy
      WHERE Policy.cust_key =
         Customer.cust_key
   ),
...

    The Customer partitioning is non-disjoint: some rows are shared with more than one subscriber.

Multiple-valued subqueries in publications

The subquery in the Customer article returns a single column (rep_key) in its result set, but may return multiple rows, corresponding to all those sales representatives that deal with the particular customer. When a subscription expression has multiple values, the row is replicated to all subscribers whose subscription matches any of the values. It is this ability to have multiple-valued subscription expressions that allows non-disjoint partitionings of a table.


Territory realignment with a many-to-many relationship

The problem of territory realignment (reassigning rows among subscribers) requires special attention, just as in the section Territory realignment in the Contact example.

You need to write triggers to maintain proper data throughout the installation when territory realignment (reassignment of rows among subscribers) is allowed.

How customers are transferred

In this example, we require that a customer transfer be achieved by deleting and inserting rows in the Policy table.

To cancel a sales relationship between a customer and a sales representative, a row in the Policy table is deleted. In this case, the Policy table change is properly replicated to the sales representative, and the row no longer appears in their database. However, no change has been made to the Customer table, and so no changes to the Customer table are replicated to the subscriber.

In the absence of triggers, this would leave the subscriber with incorrect data in their Customer table. The same kind of problem arises when a new row is added to the Policy table.

Using Triggers to solve the problem

The solution is to write triggers that are fired by changes to the Policy table, which include a special syntax of the UPDATE statement. The special UPDATE statement makes no changes to the database tables, but does make an entry in the transaction log that SQL Remote uses to maintain data in subscriber databases.

A BEFORE INSERT trigger

Here is a trigger that tracks INSERTS into the Policy table, and ensures that remote databases contain the proper data.

CREATE TRIGGER InsPolicy
BEFORE INSERT ON Policy
REFERENCING NEW AS NewRow
FOR EACH ROW
BEGIN
   UPDATE Customer
   PUBLICATION SalesRepData
   SUBSCRIBE BY (
      SELECT rep_key
      FROM Policy
      WHERE cust_key = NewRow.cust_key
      UNION ALL
      SELECT NewRow.rep_key
   )
   WHERE cust_key = NewRow.cust_key;
END;
A BEFORE DELETE trigger

Here is a corresponding trigger that tracks DELETES from the Policy table:

CREATE TRIGGER DelPolicy
BEFORE DELETE ON Policy
REFERENCING OLD AS OldRow
FOR EACH ROW
BEGIN
   UPDATE Customer
   PUBLICATION SalesRepData
   SUBSCRIBE BY (
      SELECT rep_key
      FROM Policy
      WHERE cust_key = OldRow.cust_key
      AND Policy_key <> OldRow.Policy_key
   )
   WHERE cust_key = OldRow.cust_key;
END;

Some of the features of the trigger are the same as in the previous section. The major new features are that the INSERT trigger contains a subquery, and that this subquery can be multi-valued.

Multiple-valued subqueries

The subquery in the BEFORE INSERT trigger is a UNION expression, and can be multi-valued:

...
SELECT rep_key
FROM Policy
WHERE cust_key = NewRow.cust_key
UNION ALL
SELECT NewRow.rep_key
...

  • The second part of the UNION is the rep_key value for the new sales representative dealing with the customer, taken from the INSERT statement.

  • The first part of the UNION is the set of existing sales representatives dealing with the customer, taken from the Policy table.

    This illustrates the point that the result set of the subscription query must be all those sales representatives receiving the row, not just the new sales representatives.

The subquery in the BEFORE DELETE trigger is multi-valued:

...
SELECT rep_key
FROM Policy
WHERE cust_key = OldRow.cust_key
AND rep_key <> OldRow.rep_key
...

  • The subquery takes rep_key values from the Policy table. The values include the primary key values of all those sales reps who deal with the customer being transferred (WHERE cust_key = OldRow.cust_key), with the exception of the one being deleted (AND rep_key <> OldRow.rep_key).

    This again emphasizes that the result set of the subscription query must be all those values matched by sales representatives receiving the row following the DELETE.

Notes

  • Data in the Customer table is not identified with an individual subscriber (by a primary key value, for example) and is shared among more than one subscriber. This allows the possibility of the data being updated in more than one remote site between replication messages, which could lead to replication conflicts. You can address this issue either by permissions (allowing only certain users the right to update the Customer table, for example) or by adding RESOLVE UPDATE triggers to the database to handle the conflicts programmatically.

  • UPDATES on the Policy table have not been described here. They should either be prevented, or a BEFORE UPDATE trigger is required that combines features of the BEFORE INSERT and BEFORE DELETE triggers shown in the example.


Using the Subscribe_by_remote option with many-to-many relationships

When the Subscribe_by_remote option is ON, operations from remote databases on rows with a subscribe by value of NULL or an empty string will assume the remote user is subscribed to the row. By default, the Subscribe_by_remote option is set to ON. In most cases, this setting is the desired setting.

The Subscribe_by_remote option solves a problem that otherwise would arise with some publications, including the Policy example. This section describes the problem, and how the option automatically avoids it.

The publication uses a subquery for the Customer table subscription expression, because each Customer may belong to several Sales Reps:

CREATE PUBLICATION SalesRepData (
   TABLE SalesRep,
   TABLE Policy SUBSCRIBE BY rep_key,
   TABLE Customer SUBSCRIBE BY (
      SELECT rep_key FROM Policy
      WHERE Policy.cust_key =
         Customer.cust_key
   ),
);

Marc Dill is a Sales Rep who has just arranged a policy with a new customer. He inserts a new Customer row and also inserts a row in the Policy table to assign the new Customer to himself.

The data are Marc's database.

As the INSERT of the Customer row is carried out by the Message Agent at the consolidated database, Adaptive Server Anywhere records the subscription value in the transaction log, at the time of the INSERT.

Later, when the Message Agent scans the log, it builds a list of subscribers from the subscription expression, and Marc Dill is not on the list, as the row in the Policy table assigning the customer to him has not yet been applied. If Subscribe_by_remote were set to OFF, the result would be that the new Customer is sent back to Marc Dill as a DELETE operation.

As long as Subscribe_by_remote is set to ON, the Message Agent assumes the row belongs to the Sales Rep that inserted it, the INSERT is not replicated back to Marc Dill, and the replication system is intact.

If Subscribe_by_remote is set to OFF, you must ensure that the Policy row is inserted before the Customer row, with the referential integrity violation avoided by postponing checking to the end of the transaction.


Managing conflicts

An UPDATE conflict occurs when the following sequence of events takes place:

  1. User 1 updates a row at remote site 1.

  2. User 2 updates the same row at remote site 2.

  3. The update from User 1 is replicated to the consolidated database.

  4. The update from User 2 is replicated to the consolidated database.

When the SQL Remote Message Agent replicates UPDATE statements, it does so as a separate UPDATE for each row. Also, the message contains the old row values for comparison. When the update from user 2 arrives at the consolidated database, the values in the row are not those recorded in the message.

Conflict resolution: the second update overwrites the first update.
Default conflict resolution

By default, the UPDATE still proceeds, so that the User 2 update (the last to reach the consolidated database) becomes the value in the consolidated database, and is replicated to all other databases subscribed to that row.

In general, the default method of conflict resolution is that the most recent operation (in this case that from User 2) succeeds, and no report is made of the conflict. The update from User 1 is lost. SQL Remote also allows custom conflict resolution, using a trigger to resolve conflicts in a way that makes sense for the data being changed.

Conflict resolution does not apply to primary key updates
UPDATE conflicts do not apply to primary key updates. You should not update primary keys in a SQL Remote installation. Primary key conflicts must be excluded from the installation by proper design.

This section describes how you can build conflict resolution into your SQL Remote installation at the consolidated database.

How SQL Remote handles conflicts
Implementing conflict resolution
Using conflict resolution triggers
Conflict resolution examples
Designing to avoid referential integrity errors
Designing triggers to avoid errors


How SQL Remote handles conflicts

When a conflict is detected

SQL Remote replication messages include UPDATE statements as a set of single row updates, each with a VERIFY clause that includes values prior to updating.

An UPDATE conflict is detected by the database server as a failure of the VERIFY clause values to match the rows in the database.

Conflicts are detected and resolved by the Message Agent, but only at a consolidated database. When an UPDATE conflict is detected in a message from a remote database, the Message Agent causes the database server to take two actions:

  1. Any conflict resolution (RESOLVE UPDATE) triggers are fired.

  2. The UPDATE is applied.

UPDATE statements are applied even if the VERIFY clause values do not match, whether or not there is a RESOLVE UPDATE trigger.

Conflict resolution can take several forms. For example,

  • In some applications, resolution could mean reporting the conflict into a table.

  • You may wish to keep updates made at the consolidated database in preference to those made at remote sites.

  • Conflict resolution can be more sophisticated, for example in resolving inventory numbers in the face of goods deliveries and orders.

The method of conflict resolution is different at an Adaptive Server Enterprise consolidated database. For more information, see How SQL Remote handles conflicts.


Implementing conflict resolution

This section describes what you need to do to implement custom conflict resolution in SQL Remote for Adaptive Server Anywhere. The concepts are the same in SQL Remote for Adaptive Server Enterprise, but the implementation is different.

SQL Remote allows you to define conflict resolution triggers to handle UPDATE conflicts. Conflict resolution triggers are fired only at a consolidated database, when messages are applied by a remote user. When an UPDATE conflict is detected at a consolidated database, the following sequence of events takes place.

  1. Any conflict resolution triggers defined for the operation are fired.

  2. The UPDATE takes place.

  3. Any actions of the trigger, as well as the UPDATE, are replicated to all remote databases, including the sender of the message that triggered the conflict.

    In general, SQL Remote for Adaptive Server Anywhere does not replicate the actions of triggers: the trigger is assumed to be present at the remote database. Conflict resolution triggers are fired only at consolidated databases, and so their actions are replicated to remote databases.

  4. At remote databases, no RESOLVE UPDATE triggers are fired when a message from a consolidated database contains an UPDATE conflict.

  5. The UPDATE is carried out at the remote databases.

At the end of the process, the data is consistent throughout the setup.

UPDATE conflicts cannot happen where data is shared for reading, but each row (as identified by its primary key) is updated at only one site. They only occur when data is being updated at more than one site.


Using conflict resolution triggers

This section describes how to use RESOLVE UPDATE, or conflict resolution triggers.

UPDATE statements with a VERIFY clause

Conflict resolution triggers are fired by the failure of values in the VERIFY clause of an UPDATE statement to match the values in the database before the update. An UPDATE statement with a VERIFY clause takes the following form:

UPDATE table-list
SET column-name = expression, ...
[ VERIFY (column-name, ...)
VALUES ( expression, ...) ]
[ WHERE search-condition ]

The VERIFY clause can be used only if table-list consists of a single table. It compares the values of specified columns to a set of expected values, which are the values that were present in the publisher database when the UPDATE statement was applied there. When the VERIFY clause is specified, only one table can be updated at a time.

The VERIFY clause is useful only for single-row updates. However, multi-row update statements entered at a database are replicated as a set of single-row updates by the Message Agent, so this imposes no constraints on client applications.

Conflict resolution trigger syntax

The syntax for a RESOLVE UPDATE trigger is as follows:

CREATE TRIGGER trigger-name
RESOLVE UPDATE
OF column-name ON table-name
[ REFERENCING [ OLD AS old_val ]
[ NEW AS new_val ]
[ REMOTE AS remote_val ] ]
FOR EACH ROW
BEGIN
...
END

RESOLVE UPDATE triggers fire before each row is updated. The REFERENCING clause allows access to the values in the row of the table to be updated (OLD), to the values the row is to be updated to (NEW) and to the rows that should be present according to the VERIFY clause (REMOTE). Only columns present in the VERIFY clause can be referenced in the REMOTE AS clause; other columns produce a "column not found" error.

Using the VERIFY_ALL_ COLUMNS option

The database option VERIFY_ALL_COLUMNS is OFF by default. If it is set to ON, all columns are verified on replicated updates, and a RESOLVE UPDATE trigger is fired whenever any column is different. If it is set to OFF, only those columns that are updated are checked.

Setting this option to ON makes messages bigger, because more information is sent for each UPDATE.

If this option is set at the consolidated database before remote databases are extracted, it will be set at the remote databases also.

You can set the VERIFY_ALL_COLUMNS option either for the PUBLIC group or just for the user contained in the Message Agent connection string.

Using the CURRENT REMOTE USER special constant

The CURRENT REMOTE USER special constant holds the user ID of the remote user sending the message. This can be used in RESOLVE UPDATE triggers that place reports of conflicts into a table, to identify the user producing a conflict.


Web Links Browse Collapse Expand PDF Previous Next

SQL Remote User's Guide

SQL Remote Design for Adaptive Server Anywhere

Managing conflicts

Conflict resolution examples

This section describes some ways of using RESOLVE UPDATE triggers to handle conflicts.


Resolving date conflicts

Suppose a table in a contact management system has a column holding the most recent contact with each customer.

One representative talks with a customer on a Friday, but does not upload his changes to the consolidated database until the next Monday. Meanwhile, a second representative meets the customer on the Saturday, and updates the changes that evening.

There is no conflict when the Saturday UPDATE is replicated to the consolidated database, but when the Monday UPDATE arrives it finds the row already changed.

By default, the Monday UPDATE would proceed, leaving the column with the incorrect information that the most recent contact occurred on Friday.

Update conflicts on this column should be resolved by inserting the most recent date in the row.

Implementing the solution

The following RESOLVE UPDATE trigger chooses the most recent of the two new values and enters it in the database.

CREATE TRIGGER contact_date RESOLVE UPDATE
ON contact
REFERENCING OLD AS old_name
NEW AS new_name
FOR EACH ROW
BEGIN
   IF new_name.contact_date <
         old_name.contact_date THEN
      SET new_name.contact_date
            = old_name.contact_date
   END IF
END

If the value being updated is later than the value that would replace it, the new value is reset to leave the entry unchanged.


Resolving inventory conflicts

Consider a warehouse system for a manufacturer of sporting goods. There is a table of product information, with a quantity column holding the number of each product left in stock. An update to this column will typically deplete the quantity in stock or, if a new shipment is brought in, add to it.

A sales representative at a remote database enters an order, depleting the stock of small tank top tee shirts by five, from 28 to 23, and enters this in on her database. Meanwhile, before this update is replicated to the consolidated database, a new shipment of tee shirts comes in, and the warehouse enters the shipment, adding 40 to the quantity column to make it 68.

The first update adds 40 to the quantity column.

The warehouse entry gets added to the database: the quantity column now shows there are 68 small tank-top tee shirts in stock. When the update from the sales representative arrives, it causes a conflict–Adaptive Server Anywhere detects that the update is from 28 to 23, but that the current value of the column is 68.

By default, the most recent UPDATE succeeds, and the inventory level is set to the incorrect value of 23.

Incorrect conflict resolution: the second update incorrectly overwrites the first update.

In this case the conflict should be resolved by summing the changes to the inventory column to produce the final result, so that a final value of 63 is placed into the database.

Correct conflict resolution: the second update modifies the first update.
Implementing the solution

A suitable RESOLVE UPDATE trigger for this situation would add the increments from the two updates. For example,

CREATE TRIGGER resolve_quantity
RESOLVE UPDATE OF quantity
ON "DBA".product
REFERENCING OLD AS old_name
NEW AS new_name
REMOTE AS remote_name
FOR EACH ROW
BEGIN
   SET new_name.quantity =   new_name.quantity
                        + old_name.quantity
                        - remote_name.quantity
END

This trigger adds the difference between the old value in the consolidated database (68) and the old value in the remote database when the original UPDATE was executed (28) to the new value being sent, before the UPDATE is implemented. Thus, new_val.quantity becomes 63 (= 23 + 68 - 28), and this value is entered into the quantity column.

Consistency is maintained at the remote database as follows:

  1. The original remote UPDATE changed the value from 28 to 23.

  2. The warehouse's entry is replicated to the remote database, but fails as the old value is not what was expected.

  3. The changes made by the RESOLVE UPDATE trigger are replicated to the remote database.


Reporting conflicts

In some cases, you may not want to alter the default way in which SQL Remote resolves conflicts; you may just want to report the conflicts by storing them in a table. In this way, you can look at the conflict table to see what, if any, conflicts have occurred, and if necessary take action to resolve the conflicts.


Designing to avoid referential integrity errors

The tables in a relational database are related through foreign key references. The referential integrity constraints applied as a consequence of these references ensure that the database remains consistent. If you wish to replicate only a part of a database, there are potential problems with the referential integrity of the replicated database.

By paying attention to referential integrity issues while designing publications you can avoid these problems. This section describes some of the more common integrity problems and suggests ways to avoid them.

Unreplicated referenced table errors

The sales publication described in Publishing whole tables includes the sales_order table:

CREATE PUBLICATION pub_sales (
   TABLE customer,
   TABLE sales_order,
   TABLE sales_order_items,
   TABLE product
)

The sales_order table has a foreign key to the employee table. The id of the sales rep is a foreign key in the sales_order table referencing the primary key of the employee table. However, the employee table is not included in the publication.

If the publication is created in this manner, new sales orders would fail to replicate unless the remote database has the foreign key reference removed from the sales_order table.

If you use the extraction utility to create the remote databases, the foreign key reference is automatically excluded from the remote database, and this problem is avoided. However, there is no constraint in the database to prevent an invalid value from being inserted into the sales_rep_id column of the sales_order table, and if this happens the INSERT will fail at the consolidated database. To avoid this problem, you can include the employee table (or at least its primary key) in the publication.


Designing triggers to avoid errors

Actions performed by triggers are not replicated: triggers that exist at one database in a SQL Remote setup are assumed by the replication procedure to exist at other databases in the setup. When an action that fires a trigger at the consolidated database is replicated at the replicate site, the trigger is automatically fired. By default, the database extraction utility extracts the trigger definitions, so that they are in place at the remote database also.

If a publication includes only a subset of a database, a trigger at the consolidated database may refer to tables or rows that are present at the consolidated database, but not at the remote databases. You can design your triggers to avoid such errors by making actions of the trigger conditional using an IF statement. The following list suggests some ways in which triggers can be designed to work on consolidated and remote databases.

  • Have actions of the trigger be conditional on the value of CURRENT PUBLISHER. In this case, the trigger would not execute certain actions at the remote database.

  • Have actions of the trigger be conditional on the object_id function not returning NULL. The object_id function takes a table or other object as argument, and returns the ID number of that object or NULL if the object does not exist.

  • Have actions of the trigger be conditional on a SELECT statement which determines if rows exist.

The RESOLVE UPDATE trigger is a special trigger type for the resolution of UPDATE conflicts, and is discussed in the section Conflict resolution examples. The actions of RESOLVE UPDATE triggers are replicated to remote databases, including the database that caused the conflict.


Ensuring unique primary keys

Primary key values must be unique. When all users are connected to the same database, there is no problem keeping unique values. If a user tries to re-use a value, the INSERT statement fails.

The situation is different in a replication system because users are connected to many databases. A potential problem arises when two users, connected to different databases, insert a row using the same primary key value. Each of their statements succeeds because the value is unique in each database.

However, problems arise in a replication system when two users, connected to separate databases, INSERT a row using the same primary key value. The second INSERT to reach a given database in the replication system fails. As SQL Remote is a replication system for occasionally connected users, there can be no locking mechanism across all databases in the installation. It is necessary to design your SQL Remote installation so that primary key duplication errors do not occur.

For primary key errors to be designed out of SQL Remote installations, the primary keys of tables that may be modified at more than one site must be guaranteed unique. There are several ways of achieving this goal. This chapter describes two general, economical, and reliable methods.

  1. Using the default global autoincrement feature of Adaptive Server Anywhere.

  2. Using the primary key pools to maintain a list of unused, unique primary key values at each site.

You can use these techniques either separately or together to avoid duplicate values.

Using global autoincrement default column values
Using primary key pools
The primary key pool table
Replicating the primary key pool
Filling and replenishing the key pool
Adding new customers
Primary key pool summary


Using global autoincrement default column values

In Adaptive Server Anywhere, you can set the default column value to be GLOBAL AUTOINCREMENT. You can use this default for any column in which you want to maintain unique values, but it is particularly useful for primary keys. This feature is intended to simplify the task of generating unique values in setups where data is being replicated among multiple databases, typically by MobiLink synchronization.

When you specify default global autoincrement, the domain of values for that column is partitioned. Each partition contains the same number of values. For example, if you set the partition size for an integer column in a database to 1000, one partition extends from 1001 to 2000, the next from 2001 to 3000, and so on.

You assign each copy of the database a unique global database identification number. Adaptive Server Anywhere supplies default values in a database only from the partition uniquely identified by that database's number. For example, if you assigned the database in the above example the identity number 10, the default values in that database would be chosen in the range 10001–11000. Another copy of the database, assigned the identification number 11, would supply default value for the same column in the range 11001–12000.

Declaring default global autoincrement
Setting the Global_database_id value
Setting unique database identification numbers when extracting databases
How default values are chosen


Declaring default global autoincrement

You can set default values in your database by selecting the column properties in Sybase Central, or by including the DEFAULT GLOBAL AUTOINCREMENT phrase in a TABLE or ALTER TABLE statement.

Optionally, the partition size can be specified in parentheses immediately following the AUTOINCREMENT keyword. The partition size may be any positive integer, although the partition size is generally chosen so that the supply of numbers within any one partition will rarely, if ever, be exhausted.

For columns of type INT or UNSIGNED INT, the default partition size is 216 = 65536; for columns of other types the default partition size is 232 = 4294967296. Since these defaults may be inappropriate, especially if our column is not of type INT or BIGINT, it is best to specify the partition size explicitly.

For example, the following statement creates a simple table with two columns: an integer that holds a customer identification number and a character string that holds the customer's name.

CREATE TABLE customer (
   id   INT          DEFAULT GLOBAL AUTOINCREMENT (5000),
   name VARCHAR(128) NOT NULL,
   PRIMARY KEY (id)
)

In the above example, the chosen partition size is 5000.

For more information on GLOBAL AUTOINCREMENT, see CREATE TABLE statement.


Setting the Global_database_id value

When deploying an application, you must assign a different identification number to each database. You can accomplish the task of creating and distributing the identification numbers by a variety of means. One method is to place the values in a table and download the correct row to each database based on some other unique property, such as user name.

toggle To set the global database identification number

  • You set the identification number of a database by setting the value of the public option Global_database_id. The identification number must be a non-negative integer.

For example, the following statement sets the database identification number to 20.

SET OPTION PUBLIC.Global_database_id = 20

If the partition size for a particular column is 5000, default values for this database are selected from the range 100001–105000.


Setting unique database identification numbers when extracting databases

If you use the extraction utility to create your remote databases, you can write a stored procedure to automate the task. If you create a stored procedure named sp_hook_dbxtract_begin, it is called automatically by the extraction utility. Before the procedure is called, the extraction utility creates a temporary table named #hook_dict, with the following contents:

name | value
extracted_db_global_id | user ID being extracted

If you write your sp_hook_dbxtract_begin procedure to modify the value column of the row, that value is used as the GLOBAL_DATABASE_ID option of the extracted database, and marks the beginning of the range of primary key values for GLOBAL DEFAULT AUTOINCREMENT values.

Example

Consider extracting a database for remote user user2 with a user_id of 101. If you do not define an sp_hook_dbxtract_begin procedure, the extracted database will have Global_database_id set to 101.

If you define a sp_hook_dbxtract_begin procedure, but it does not modify any rows in the #hook_dict then the option will still be set to 101.

If you set up the database as follows:

set option "PUBLIC"."Global_database_id" = '1';
create table extract_id ( next_id integer not null) ;
insert into extract_id values( 1 );
create procedure sp_hook_dbxtract_begin
as
    declare @next_id  integer
    update extract_id set next_id = next_id + 1000
    select @next_id = (next_id )
    from extract_id
    commit
    update #hook_dict
    set value = @next_id
    where name = 'extracted_db_global_id'

Then each extracted or re-extracted database will get a different Global_database_id. The first starts at 1001, the next at 2001, and so on.

To assist in debugging procedure hooks, dbxtract outputs the following when it is set to operate in verbose mode:

  • the procedure hooks found

  • the contents of #hook_dict before the procedure hook is called

  • the contents of #hook_dict after the procedure hook is called.


How default values are chosen

The public option Global_database_id in each database must be set to a unique, non-negative integer. The range of default values for a particular database is pn + 1 to p(n + 1), where p is the partition size and n is the value of the public option Global_database_id. For example, if the partition size is 1000 and Global_database_id is set to 3, then the range is from 3001 to 4000.

If Global_database_id is set to a non-negative integer, Adaptive Server Anywhere chooses default values by applying the following rules:

  • If the column contains no values in the current partition, the first default value is pn + 1.

  • If the column contains values in the current partition, but all are less than p(n + 1), the next default value will be one greater than the previous maximum value in this range.

  • Default column values are not affect by values in the column outside of the current partition; that is, by numbers less than pn + 1 or greater than p(n + 1). Such values may be present if they have been replicated from another database via MobiLink synchronization.

If the public option Global_database_id is set to the default value of 2147483647, a null value is inserted into the column. Should null values not be permitted, the attempt to insert the row causes an error. This situation arises, for example, if the column is contained in the table's primary key.

Because the public option Global_database_id cannot be set to negative values, the values chosen are always positive. The maximum identification number is restricted only by the column data type and the partition size.

Null default values are also generated when the supply of values within the partition has been exhausted. In this case, a new value of Global_database_id should be assigned to the database to allow default values to be chosen from another partition. Attempting to insert the null value causes an error if the column does not permit nulls. To detect that the supply of unused values is low and handle this condition, create an event of type GlobalAutoincrement.

Should the values in a particular partition become exhausted, you can assign a new database id to that database. You can assign new database id numbers in any convenient manner. However, one possible technique is to maintain a pool of unused database id values. This pool is maintained in the same manner as a pool of primary keys.

You can set an event handler to automatically notify the database administrator (or carry out some other action) when the partition is nearly exhausted. For more information, see Defining trigger conditions for events.

For more information, see GLOBAL_DATABASE_ID option [database].

For further information on pools, see Using primary key pools.


Using primary key pools

The primary key pool is a table that holds a set of primary key values for each database in the SQL Remote installation. Each remote user receives their own set of primary key values. When a remote user inserts a new row into a table, they use a stored procedure to select a valid primary key from the pool. The pool is maintained by periodically running a procedure at the consolidated database that replenishes the supply.

The method is described using a simple example database consisting of sales representatives and their customers. The tables are much simpler than you would use in a real database; this allows us to focus just on those issues important for replication.


The primary key pool table

The pool of primary keys is held in a separate table. The following CREATE TABLE statement creates a primary key pool table:

CREATE TABLE KeyPool (
   table_name VARCHAR(40) NOT NULL,
   value INTEGER NOT NULL,
   location CHAR(12) NOT NULL,
   PRIMARY KEY (table_name, value),
);

The columns of this table have the following meanings:

Column | Description
table_name | Holds the names of tables for which primary key pools must be maintained. In our simple example, if new sales representatives were to be added only at the consolidated database, only the Customer table needs a primary key pool and this column is redundant. It is included to show a general solution.
value | Holds a list of primary key values. Each value is unique for each table listed in table_name.
location | An identifier for the recipient. In some setups, this could be the same as the rep_key value of the SalesRep table. In other setups, there will be users other than sales representatives and the two identifiers should be distinct.

For performance reasons, you may wish to create an index on the table:

CREATE INDEX KeyPoolLocation
ON KeyPool (table_name, location, value);


Replicating the primary key pool

You can either incorporate the key pool into an existing publication, or share it as a separate publication. In this example, we create a separate publication for the primary key pool.

toggle To replicate the primary key pool (SQL)

  1. Create a publication for the primary key pool data.

    CREATE PUBLICATION KeyPoolData (
   TABLE KeyPool SUBSCRIBE BY location
);

  2. Create subscriptions for each remote database to the KeyPoolData publication.

    CREATE SUBSCRIPTION
TO KeyPoolData( 'user1' )
FOR user1;
CREATE SUBSCRIPTION
TO KeyPoolData( 'user2' )
FOR user2;
...

    The subscription argument is the location identifier.

In some circumstances it makes sense to add the KeyPool table to an existing publication and use the same argument to subscribe to each publication. Here we keep the location and rep_key values distinct to provide a more general solution.

See also

  • CREATE PUBLICATION statement

  • CREATE SUBSCRIPTION statement


Filling and replenishing the key pool

Every time a user adds a new customer, their pool of available primary keys is depleted by one. The primary key pool table needs to be periodically replenished at the consolidated database using a procedure such as the following:

CREATE PROCEDURE ReplenishPool()
BEGIN
   FOR EachTable AS TableCursor
   CURSOR FOR
      SELECT table_name
      AS CurrTable, max(value) as MaxValue
      FROM KeyPool
      GROUP BY table_name
   DO
      FOR EachRep AS RepCursor
      CURSOR FOR
         SELECT location
         AS CurrRep, count(*) as NumValues
         FROM KeyPool
         WHERE table_name = CurrTable
         GROUP BY location
      DO
         // make sure there are 100 values.
         // Fit the top-up value to your
         // requirements
         WHILE NumValues < 100 LOOP
            SET MaxValue = MaxValue + 1;
            SET NumValues = NumValues + 1;
            INSERT INTO KeyPool
            (table_name, location, value)
            VALUES
            (CurrTable, CurrRep, MaxValue);
         END LOOP;
      END FOR;
   END FOR;
END;

This procedure fills the pool for each user up to 100 values. The value you need depends on how often users are inserting rows into the tables in the database.

The ReplenishPool procedure must be run periodically at the consolidated database to refill the pool of primary key values in the KeyPool table.

The ReplenishPool procedure requires at least one primary key value to exist for each subscriber, so that it can find the maximum value and add one to generate the next set. To initially fill the pool you can insert a single value for each user, and then call ReplenishPool to fill up the rest. The following example illustrates this for three remote users and a single consolidated user named Office:

INSERT INTO KeyPool VALUES( 'Customer', 40, 'user1' );
INSERT INTO KeyPool VALUES( 'Customer', 41, 'user2' );
INSERT INTO KeyPool VALUES( 'Customer', 42, 'user3' );
INSERT INTO KeyPool VALUES( 'Customer', 43, 'Office');
CALL ReplenishPool();
Cannot use a trigger to replenish the key pool
You cannot use a trigger to replenish the key pool, as trigger actions are not replicated.

Previous Next


Adding new customers

When a sales representative wants to add a new customer to the Customer table, the primary key value to be inserted is obtained using a stored procedure. This example shows a stored procedure to supply the primary key value, and also illustrates a stored procedure to carry out the INSERT.

The procedures takes advantage of the fact that the Sales Rep identifier is the CURRENT PUBLISHER of the remote database.

  • NewKey procedure The NewKey procedure supplies an integer value from the key pool and deletes the value from the pool.

    CREATE PROCEDURE NewKey(
      IN @table_name VARCHAR(40),
      OUT @value INTEGER )
BEGIN
   DECLARE NumValues INTEGER;

   SELECT count(*), min(value)
   INTO NumValues, @value
         FROM KeyPool
         WHERE table_name = @table_name
         AND location = CURRENT PUBLISHER;
   IF NumValues > 1 THEN
      DELETE FROM KeyPool
      WHERE table_name = @table_name
      AND value = @value;
   ELSE
   // Never take the last value, because
   // ReplenishPool will not work.
   // The key pool should be kept large enough
   // that this never happens.
      SET @value = NULL;
   END IF;
END;

  • NewCustomer procedure The NewCustomer procedure inserts a new customer into the table, using the value obtained by NewKey to construct the primary key.

    CREATE PROCEDURE NewCustomer(
      IN customer_name CHAR( 40 ) )
BEGIN
   DECLARE new_cust_key INTEGER ;
   CALL NewKey( 'Customer', new_cust_key );
   INSERT
   INTO Customer (
      cust_key,
      name,
      location
      )
   VALUES (
      'Customer ' ||
      CONVERT (CHAR(3), new_cust_key),
      customer_name,
      CURRENT PUBLISHER
      );
);
END

    You may want to enhance this procedure by testing the new_cust_key value obtained from NewKey to check that it is not NULL, and preventing the insert if it is NULL.


Primary key pool summary

The primary key pool technique requires the following components:

  • Key pool table A table to hold valid primary key values for each database in the installation.

  • Replenishment procedure A stored procedure keeps the key pool table filled.

  • Sharing of key pools Each database in the installation must subscribe to its own set of valid values from the key pool table.

  • Data entry procedures New rows are entered using a stored procedure that picks the next valid primary key value from the pool and delete that value from the key pool.


Creating subscriptions

To subscribe to a publication, each subscriber must be granted REMOTE permissions and a subscription must also be created for that user. The details of the subscription are different depending on whether or not the publication uses a subscription expression.

Working with subscriptions in Sybase Central
toggle To create and manage subscriptions in Sybase Central

  1. In the left pane, open the Publications folder.

  2. Select the desired publication. You can perform the following tasks in Sybase Central:

  3. In the right pane, click the SQL Remote Subscriptions tab. You can configure the appropriate settings as follows:

    • To subscribe a remote user to the publication, from the File menu choose New > SQL Remote Subscription and follow the instructions in the SQL Remote Subscription Creation wizard.

    • To unsubscribe a remote user, right-click the user in the Subscribers list and choose Delete from the popup menu.

    • To manually start, stop, or synchronize subscriptions, select the user in the Subscribers list and choose Properties from the popup menu.

      Click the Advanced tab. On this tab, click Start Now to start subscriptions, Stop Now to stop subscriptions, or Synchronize Now to synchronize subscriptions.

      The subscriptions are affected as soon as you click the button. Subsequently clicking Cancel on the property sheet does not cancel your start/stop/synchronize action.

Subscriptions with no subscription expression

To subscribe a user to a publication, if that publication has no subscription expression, you need the following information:

  • User ID The user who is being subscribed to the publication. This user must have been granted remote permissions.

  • Publication name The name of the publication to which the user is being subscribed.

The following statement creates a subscription for a user ID SamS to the pub_orders_samuel_singer publication, which was created using a WHERE clause:

CREATE SUBSCRIPTION
TO pub_orders_samuel_singer
FOR SamS
Subscriptions with a subscription expression

To subscribe a user to a publication, if that publication does have a subscription expression, you need the following information:

  • User ID The user who is being subscribed to the publication. This user must have been granted remote permissions.

  • Publication name The name of the publication to which the user is being subscribed.

  • Subscription value The value that is to be tested against the subscription expression of the publication. For example, if a publication has the name of a column containing an employee ID as a subscription expression, the value of the employee ID of the subscribing user must be provided in the subscription. The subscription value is always a string.

The following statement creates a subscription for Samuel Singer (user ID SamS, employee ID 856) to the pub_orders publication, defined with a subscription expression sales_rep, requesting the rows for Samuel Singer's own sales:

CREATE SUBSCRIPTION
TO pub_orders ( '856' )
FOR SamS
Starting a subscription

In order to receive and apply updates properly, each subscriber needs to have an initial copy of the data. The synchronization process is discussed in Synchronizing databases.

For more information, see CREATE SUBSCRIPTION statement.


SQL Remote Design for Adaptive Server Enterprise

About this chapter

This chapter describes how to design a SQL Remote installation when the consolidated database is at an Adaptive Server Enterprise server.

Similar material for Adaptive Server Anywhere
Many of the principles of publication design are the same for Adaptive Server Anywhere and Adaptive Server Enterprise, but there are differences in commands and capabilities. There is a large overlap between this chapter and the corresponding chapter for Adaptive Server Anywhere users, SQL Remote Design for Adaptive Server Anywhere.

Design overview
Creating publications
Publication design for Adaptive Server Enterprise
Partitioning tables that do not contain the subscription column
Sharing rows among several subscriptions
Managing conflicts
Ensuring unique primary keys
Creating subscriptions


Design overview

Designing a SQL Remote installation includes the following tasks:

  • Designing publications The publications determine what information is shared among which databases.

  • Designing subscriptions The subscriptions determine what information each user receives.

  • Implementing the design Creating publications and subscriptions for all users in the system.

All administration is at the consolidated database

Like all SQL Remote administrative tasks, design is carried out by a database administrator or system administrator at the consolidated database. The Sybase System Administrator should perform all SQL Remote configuration tasks.

For more information about the Adaptive Server Enterprise environment, see your Adaptive Server Enterprise documentation.


Creating publications

In this section

This section describes how to create simple publications consisting of whole tables, or of column-wise subsets of tables.

Simple publications are also discussed in the chapter A Tutorial for Adaptive Server Enterprise Users.

Creating whole-table articles
Creating articles containing some of the columns in a table
Creating articles containing some of the rows in a table
Notes on articles


Creating whole-table articles

The simplest type of article is one that includes all the rows and columns of a database table.

toggle To create an article that includes all the rows and columns of a table

  1. Mark the table for replication. You do this by executing the sp_add_remote_table procedure:

    sp_add_remote_table table-name

  2. Add the table to the publication. You do this by executing the sp_add_article procedure:

    sp_add_article publication-name, table-name
Example

  • The following commands add the table SalesRep to the SalesRepData publication:

    sp_add_remote_table 'SalesRep'
sp_add_article 'SalesRepData', 'SalesRep'
go


Creating articles containing some of the columns in a table

To create an article that includes only some of the columns from a table, you need to list the columns that you wish to include, using sp_add_article_col. If no columns are listed, the article includes all columns of the table.

toggle To create an article that includes some of the columns and all the rows of a table

  1. Mark the table for replication. You do this by executing the sp_add_remote_table procedure:

    sp_add_remote_table table-name
go

  2. Add the table to the publication. You do this by executing the sp_add_article procedure:

    sp_add_article publication-name, table-name
go

    The sp_add_article procedure adds a table to a publication. By default, all columns of the table are added to the publication. If you wish to add only some of the columns, you must use the sp_add_article_col procedure to specify which columns you wish to include.

  3. Add individual columns to the publication. You do this by executing the sp_add_article_col procedure for each column:

    sp_add_article_col publication-name,
   table-name,
   column-name
go
Example

  • The following commands add only the rep_key column of the table SalesRep to the SalesRepData publication:

    sp_add_remote_table 'SalesRep'
sp_add_article 'SalesRepData',
   'SalesRep'
sp_add_article_col 'SalesRepData',
   'SalesRep',
   'rep_key'
go


Creating articles containing some of the rows in a table

There are two ways of including only some of the rows from a table in an article:

  • WHERE clause You can use a WHERE clause to include a subset of rows in an article. All subscribers to the publication containing this article receive the rows that satisfy the WHERE clause.

  • subscription column You can use a subscription column to include a different set of rows in different subscriptions to publications containing the article.

Allowed clauses

In SQL Remote for Adaptive Server Enterprise, the following limitations apply to each of these cases:

  • WHERE clause limitations The only form of WHERE clause supported is the following:

    WHERE column-name IS NOT NULL.

  • Subscription column SQL Remote for Adaptive Server Anywhere supports expressions other than column names. For Adaptive Server Enterprise, the subscription expression must be a column name.

When to use WHERE and SUBSCRIBE BY

You should use a subscription expression when different subscribers to a publication are to receive different rows from a table. The subscription expression is the most powerful method of partitioning tables.


Creating an article using a WHERE clause

The WHERE clause is used to exclude a set of rows from all subscriptions to a publication.

toggle To create an article using a WHERE clause

  1. If you have not already done so, mark the table for replication. You do this by executing the sp_add_remote_table procedure:

    sp_add_remote_table table_name

  2. Add the table to the publication. You do this by executing the sp_add_article procedure: Specify the column name corresponding to the WHERE column IS NOT NULL clause in the third argument to the procedure:

    sp_add_article publication_name,
   table_name,
   column_name

    Do not specify IS NOT NULL; it is implicit. Specify the column name only.

  3. If you wish to include only a subset of the columns in the table, specify the columns using the sp_add_article_col procedure. You must include the column specified in your WHERE clause in the article.

Example

  • The following set of statements create a publication containing a single article, which includes only those rows of test_table for which column col_1 is not null:

    sp_create_publication test_pub
sp_add_remote_table test_table
sp_add_article test_pub, test_table, col_1
go


Creating an article using a subscription column

The subscription column is used when rows are to be shared among many remote databases.

toggle To create an article using a subscription column

  1. If you have not already done so, mark the table for replication. You do this by executing the sp_add_remote_table procedure:

    sp_add_remote_table table_name

  2. Add the table to the publication. You do this by executing the sp_add_article procedure: Specify the column name you wish to use as a subscription expression in the fourth argument to the procedure:

    sp_add_article publication_name,
    table_name,
    NULL,
    column_name

    You must include the NULL entry to avoid adding a WHERE clause.

  3. If you wish to include only a subset of the columns in the table, specify the columns using the sp_add_article_col procedure. You must include the column specified in your subscription expression in the article.

Example

  • The following set of statements create a publication containing a single article, which supports subscriptions based on the value of column col_1:

    sp_create_publication test_pub
sp_add_remote_table test_table
sp_add_article test_pub,
   test_table,
   NULL,
   col_1
go


Notes on articles

  • You can combine a WHERE clause and a subscription expression in an article.

  • All columns in the primary key must be included in any article.

  • You must not include a subset of columns in an article unless either:

    • The remaining columns have default values or allow NULLs.

    • No inserts are carried out at remote databases. Updates would not cause problems as long as they do not change primary key values.

    If you include a subset of columns in an article in situations other than these, INSERT statements at the consolidated database will fail.


Publication design for Adaptive Server Enterprise

Once you understand how to create simple publications, you must think about proper design of publications. This section describes the issues involved in designing publications, and how to take steps towards sound design.


Conditions for valid articles

All columns in the primary key must be included in the article.

Supporting INSERTS at remote databases

For INSERT statements at a remote database to replicate correctly to the consolidated database, you can exclude from an article only columns that can be left out of a valid INSERT statement. These are:

  • Columns that allow NULL.

  • Columns that have defaults.

If you exclude any column that does not satisfy one of these requirements, INSERT statements carried out at a remote database will fail when replicated to the consolidated database.

An insert fails when uploaded, because of a missing column.
Conditions on rows

There are two ways of including only some of the rows in a publication:

  • WHERE clause You can use a WHERE clause to include a subset of rows in an article. All subscribers to the publication containing this article receive the rows that satisfy the WHERE clause.

    In SQL Remote for Adaptive Server Enterprise, the only supported WHERE clause is

    WHERE column-name IS NOT NULL

  • Subscription columns You can use a subscription column to include a different set of rows in different subscriptions to publications containing the article.

For more information on restrictions on rows, see Creating articles containing some of the rows in a table.


Partitioning tables that do not contain the subscription column

In many cases, the rows of a table need to be partitioned even when the subscription column does not exist in the table. This section describes how to handle this case, using an example.

The Contact example
Territory realignment in the Contact example
Partitioning the Customer table in the Contact example
Adding a subscription-list column to the Contact table
Maintaining the subscription-list column
Tuning extraction performance


The Contact example

The Contact database illustrates why and how to partition tables that do not contain the subscription column.

Example

Here is a simple database that illustrates the problem. We call this database the Contact database, because it contains a Contact table in addition to the two tables described earlier in this chapter.

The Contact table has a foreign key to Customer. The Customer table has a foreign key to SalesRep.

Each sales representative sells to several customers. At some customers there is a single contact, while other customers have several contacts.

The tables in the database

The three tables are described in more detail as follows:

Table Description
SalesRep All sales representatives that work for the company. The SalesRep table has the following columns:

  • rep_key An identifier for each sales representative. This is the primary key.

  • name The name of each sales representative.

The SQL statement creating this table is as follows:
CREATE TABLE SalesRep (
   rep_key CHAR(12) NOT NULL,
   name CHAR(40) NOT NULL,
   PRIMARY KEY (rep_key)
)
go
Customer All customers that do business with the company. The Customer table includes the following columns:

  • cust_key An identifier for each customer. This is the primary key.

  • name The name of each customer.

  • rep_key An identifier for the sales representative in a sales relationship. This is a foreign key to the SalesRep table.

The SQL statement creating this table is as follows:
CREATE TABLE Customer (
   cust_key CHAR(12) NOT NULL,
   name CHAR(40) NOT NULL,
   rep_key CHAR(12) NOT NULL,
   FOREIGN KEY ( rep_key )
   REFERENCES SalesRep,
   PRIMARY KEY (cust_key)
)
go
Contact All individual contacts that do business with the company. Each contact belongs to a single customer. The Contact table includes the following columns:

  • contact_key An identifier for each contact. This is the primary key.

  • name The name of each contact.

  • cust_key An identifier for the customer to which the contact belongs. This is a foreign key to the Customer table.

The SQL statement creating this table is:
CREATE TABLE Contact (
   contact_key  CHAR(12) NOT NULL,
   name  CHAR(40) NOT NULL,
   cust_key  CHAR(12) NOT NULL,
   FOREIGN KEY (cust_key)
   REFERENCES Customer,
   PRIMARY KEY  (contact_key)
)
go
Replication goals

The goals of the design are to provide each sales representative with the following information:

  • The complete SalesRep table.

  • Those customers assigned to them, from the Customer table.

  • Those contacts belonging to the relevant customers, from the Contact table.

  • Maintenance of proper information when Sales Representative territories are realigned.


Territory realignment in the Contact example

In territory realignment, rows are reassigned among subscribers. In the current example, territory realignment involves reassigning customers among the sales representatives. It is carried out by updating the rep_key column of the Customer table.

The UPDATE is replicated as an INSERT or a DELETE to the old and new sales representatives, respectively, so that the customer row is properly transferred to the new sales representative.

No log entries for the Contact table when territories realigned

When a customer is reassigned, the Contact table is unaffected. There are no changes to the Contact table, and consequently no entries in the transaction log pertaining to the Contact table. In the absence of this information, SQL Remote cannot reassign the rows of the Contact table along with the Customer. This failure would cause referential integrity problems: the Contact table at the remote database of the old sales representative contains a cust_key value for which there is no longer a Customer.

In this section, we describe how to reassign the rows of the Contact table.


Partitioning the Customer table in the Contact example

The Customer table can be partitioned using the rep_key value as a subscription column. A publication that includes the SalesRep and Customer tables would be as follows:

exec sp_add_remote_table 'SalesRep'
exec sp_add_remote_table 'Customer'
go
exec sp_create_publication 'SalesRepData'
go
exec sp_add_article 'SalesRepData', 'SalesRep'
exec sp_add_article SalesRepData,
         Customer, NULL,
         'rep_key'
go


Adding a subscription-list column to the Contact table

The Contact table must also be partitioned among the sales representatives, but contains no reference to the sales representative rep_key value.

Add a subscription-list column

To solve this problem in Adaptive Server Enterprise, you must add a column to the Contact table containing a comma-separated list of subscription values to the row. ( In the present case, there can only be a single subscription value.) The column can be maintained using triggers, so that applications against the database are unaffected by the presence of the column. We call this column a subscription-list column.

When a row in the Customer table is inserted, updated or deleted, a trigger updates rows in the Contact table. In particular, the trigger updates the subscription-list column. As the Contact table is marked for replication, the before and after image of the row is recorded in the log.

Log entries are values, not subscribers
Although in this case the values entered correspond to subscribers, it is not a list of subscribers that is entered in the log. The server handles only information about publications, and the Message Agent handles all information about subscribers. The values entered in the log are for comparison to the subscription value in each subscription. For example, if rows of a table were divided among sales representatives by state or province, the state or province value would be entered in the transaction log.

A subscription-list column is a column added to a table for the sole purpose of holding a comma-separated list of subscribers. In the present case, there can only be a single subscriber to each row of the Contact table, and so the subscription-list column holds only a single value.

For a discussion of the case where the subscription-list column can hold many values, see Sharing rows among several subscriptions.

Contact table definition

In the case of the Contact table, the table definition would be changed to the following:

CREATE TABLE Contact (
   contact_key CHAR( 12 ) NOT NULL,
   name CHAR( 40 ) NOT NULL,
   cust_key CHAR( 12 ) NOT NULL,
   subscription_list CHAR( 12 ) NULL,
   FOREIGN KEY ( cust_key )
   REFERENCES Customer ( cust_key ),
   PRIMARY KEY ( contact_key )
)
go

The additional column is created allowing NULL, so that existing applications can continue to work against the database without change.

The subscription_list column holds the rep_key value corresponding to the row with primary key value cust_key in the Customer table. A set of triggers handles maintenance of the subscription_list column.

The rows in the Contact and Customer tables.

For an Adaptive Server Anywhere consolidated database, the solution is different. For more information, see Partitioning tables that do not contain the subscription expression.


Maintaining the subscription-list column

In order to keep the subscription_list column up to date, triggers are needed for the following operations:

  • INSERT on the Contact table.

  • UPDATE on the Contact table.

  • UPDATE on the Customer table.

The UPDATE of the Customer table addresses the territory realignment problem, where customers are assigned to different Sales Reps.

An INSERT trigger for the Contact table

The trigger for an INSERT on the Contact table sets the subscription_list value to the corresponding rep_key value from the Customer table:

CREATE TRIGGER set_contact_sub_list
ON Contact
FOR INSERT
AS
BEGIN
   UPDATE Contact
   SET Contact.subscription_list = (
         SELECT rep_key
         FROM Customer
         WHERE Contact.cust_key = Customer.cust_key )
   WHERE Contact.contact_key IN (
         SELECT contact_key
         FROM inserted
   )
END

The trigger updates the subscription_list column for those rows being inserted; these rows being identified by the subquery

SELECT contact_key
FROM inserted
An UPDATE trigger for the Contact table

The trigger for an UPDATE on the Contact table checks to see if the cust_key column is changed, and if it has updates the subscription_list column.

CREATE TRIGGER update_contact_sub_list
ON Contact
FOR UPDATE
AS
IF UPDATE ( cust_key )
   BEGIN
      UPDATE Contact
      SET subscription_list = Customer.rep_key
      FROM Contact, Customer
      WHERE Contact.cust_key=Customer.cust_key
   END

The trigger is written using a join; a subquery could also have been used.

An UPDATE trigger for the Customer table

The following trigger handles UPDATES of customers, transferring them to a new Sales Rep:

CREATE TRIGGER transfer_contact_with_customer
ON Customer
FOR UPDATE
AS
IF UPDATE ( rep_key )
BEGIN
   UPDATE Contact
   SET Contact.subscription_list = (
      SELECT rep_key
      FROM Customer
      WHERE Contact.cust_key = Customer.cust_key )
   WHERE Contact.contact_key IN (
         SELECT cust_key
      FROM inserted
   )
END


Tuning extraction performance

When extracting or synchronizing a user, the subscription-list column can cause performance problems as it necessitates a full table scan.

If you are extracting databases for many users, and performance is a problem for you, you can use a subscription view to improve performance. The view must contain a subquery, which is used for extraction and synchronization only, and is ignored during log scanning. The tables involved still need to have triggers defined to maintain the subscription-list column.

toggle To create a subscription view

  1. Design a query that uses a subquery to select the proper rows for a subscription from a table.

    For example, continuing the example from the preceding sections, the following query selects the rows of the Contact table for a user subscribed by rep_key value rep5:

    SELECT *
FROM Contact
WHERE 'rep5' = (SELECT rep_key
               FROM Customer
               WHERE cust_key = Contact.cust_key )

  2. Create a view that contains this subquery. For example:

    CREATE VIEW Contact_sub_view AS
SELECT *
FROM dbo.Contact
WHERE 'repxx' = ( SELECT rep_key
   FROM dbo.Customer
   WHERE cust_key = dbo.Contact.cust_key )

    In this view definition, it does not matter what value you use on the left-hand side of the WHERE clause (repxx in the example above). The replication tools use the subquery for extraction and synchronization only. Rows for which the SUBSCRIBE BY value is equal to the subquery result set are extracted or synchronized.

  3. Give the name of the view as a parameter to sp_add_article or sp_modify_article:

    exec sp_add_remote_table 'Contact'
go
exec sp_add_article SalesRepData,
                  'Contact',
                  NULL,
                  'subscription_list',
                  'Contact_sub_view'

    The subscription_list column is used for log scanning and the subquery is used for extraction and synchronization.

    For more information, see Tuning extraction performance for shared rows, sp_add_article procedure, and sp_modify_article procedure.


Sharing rows among several subscriptions

There are cases where a row may need to be included in several subscriptions. For example, if instead of the many-to-one relationship between customers and sales representatives that we had above, we may have a many-to-many relationship.

The Policy example
Maintaining the subscription-list column
Tuning extraction performance for shared rows
Using the Subscribe_by_remote option with many-to-many relationships


The Policy example

The Policy database illustrates why and how to partition tables when there is a many-to-many relationship in the database.

Example database

Here is a simple database that illustrates the problem.

The Policy table has foreign keys to both the SalesRep and Customer tables.

The Policy table has a row for each of a set of policies. Each policy is drawn up for a customer by a particular sales representative. There is a many-to-many relationship between customers and sales representatives, and there may be several policies drawn up between a particular rep/customer pair.

Any row in the Customer table may need to be shared with none, one, or several sales representatives.


Solving the problem

To support this case, you need to write triggers to build a comma-delimited list of values to store in a redundant subscription-list column of the Customer table, and include this column as the subscription column when adding the Customer table to the publication. The row is shared with any subscription for which the subscription value matches any of the values in the subscription-list column.

The database, with the subscription-list column included, is as follows:

The Customer table now includes a subscription_list column.

Adaptive Server Enterprise VARCHAR columns are limited to 255 characters, and this limits the number of values that can be stored in the comma-delimited list.

Table definitions

The table definitions are as follows:

CREATE TABLE SalesRep (
   rep_key CHAR( 12 ) NOT NULL,
   name CHAR( 40 ) NOT NULL,
   PRIMARY KEY ( rep_key )
)
go
CREATE TABLE Customer (
   cust_key CHAR( 12 ) NOT NULL,
   name CHAR( 40 ) NOT NULL,
   subscription_list VARCHAR( 255 ) NULL,
   PRIMARY KEY ( cust_key )
)
go
CREATE TABLE Policy (
   policy_key   INTEGER NOT NULL,
   cust_key CHAR( 12 ) NOT NULL,
   rep_key CHAR( 12 ) NOT NULL,
   FOREIGN KEY   ( cust_key )
   REFERENCES Customer (cust_key ),
   FOREIGN KEY (rep_key )
   REFERENCES SalesRep ( rep_key ),
   PRIMARY KEY   (policy_key)
)
Notes:

  • The subscription_list column in the Customer table allows NULLs so that customers can be added who do not have any sales representatives in the subscription_list column.


The publication

The publication for this database can be created by the following set of statements:

//Mark the tables for replication
exec sp_add_remote_table 'SalesRep'
exec sp_add_remote_table 'Policy'
exec sp_add_remote_table 'Customer'
go
// Create an empty publication
exec sp_create_publication 'SalesRepData'
//Add the Sales Rep table to the publication
exec sp_add_article 'SalesRepData', 'SalesRep'
//Add the Policy table to the publication
exec sp_add_article 'SalesRepData', 'Policy',
      NULL, 'rep_key'
// Add the Customer table to the publication.
// Subscribe by the subscription_list column
// Exclude the subscription_list column
exec sp_add_article 'SalesRepData', 'Customer',
      NULL, 'subscription_list'
exec sp_add_article_col 'SalesRepData', 'Customer', 'cust_key'
exec sp_add_article_col 'SalesRepData', 'Customer', 'name'
go

Subscriptions to this publication take the following form:

exec sp_subscription 'create',
         'SalesRepData',
         'userID',
         'rep_key'
go

where userID identifies the subscriber, and rep_key is the subscription column, which is the value of the rep_key column in the SalesRep table.


Maintaining the subscription-list column

You need to write a procedure and a set of triggers to maintain the subscription-list column added to the Customer table. This section describes these objects.

Stored procedure

The following procedure is used to build the subscription-list column, and is called from the triggers that maintain the subscription_list column.

CREATE PROCEDURE SubscribeCustomer @cust_key CHAR(12)
AS
BEGIN
   --  Rep returns the rep list for customer @cust_key
   DECLARE Rep CURSOR FOR
      SELECT DISTINCT RTRIM( rep_key )
      FROM Policy
      WHERE cust_key = @cust_key
   DECLARE @rep_key    CHAR(12)
   DECLARE @subscription_list   VARCHAR(255)

   -- build comma-separated list of rep_key
   -- values for this Customer
   OPEN Rep
   FETCH Rep INTO @rep_key
   IF @@sqlstatus = 0 BEGIN
      SELECT @subscription_list = @rep_key
      WHILE 1=1 BEGIN
         FETCH Rep INTO @rep_key
         IF @@sqlstatus != 0 BREAK
         SELECT @subscription_list =
            @subscription_list + ',' + @rep_key
      END
   END
   ELSE BEGIN
      SELECT @subscription_list = ''
   END

   -- update the subscription_list in the
   -- Customer table
   UPDATE Customer
   SET subscription_list = @subscription_list
   WHERE cust_key = @cust_key
END
Notes:

  • The procedure takes a Customer key as input argument.

  • Rep is a cursor for a query that lists each of the Sales Representatives with which the customer has a contract.

  • The WHILE loop builds a VARCHAR(255) variable holding the comma-separated list of Sales Representatives.

Triggers

The following trigger updates the subscription_list column of the Customer table when a row is inserted into the Policy table.

CREATE TRIGGER InsPolicy
ON Policy
FOR INSERT
AS
BEGIN
   -- Cust returns those customers inserted
   DECLARE Cust CURSOR FOR
      SELECT DISTINCT cust_key
      FROM inserted
   DECLARE @cust_key CHAR(12)

   OPEN Cust
   -- Update the rep list for each Customer
   -- with a new rep
   WHILE 1=1 BEGIN
      FETCH Cust INTO @cust_key
      IF @@sqlstatus != 0 BREAK
      EXEC SubscribeCustomer @cust_key
   END
END

The following trigger updates the subscription_list column of the Customer table when a row is deleted from the Policy table.

CREATE TRIGGER DelPolicy
ON Policy
FOR DELETE
AS
BEGIN
   -- Cust returns those customers deleted
   DECLARE Cust CURSOR FOR
      SELECT DISTINCT cust_key
      FROM deleted
   DECLARE @cust_key CHAR(12)

   OPEN Cust
   -- Update the rep list for each Customer
   -- losing a rep
   WHILE 1=1 BEGIN
      FETCH Cust INTO @cust_key
      IF @@sqlstatus != 0 BREAK
      EXEC SubscribeCustomer @cust_key
   END
END
Excluding the subscription-list column from the publication

The subscription-list column should be excluded from the publication, as inclusion of the column leads to excessive updates being replicated.

For example, consider what happens if there are many policies per customer. If a new Sales Representative is assigned to a customer, a trigger fires to update the subscription-list column in the Customer table. If the subscription-list column is part of the publication, then one update for each policy will be replicated to all sales reps that are assigned to this customer.

Triggers at the consolidated database only

The values in the subscription-list column are maintained by triggers. These triggers fire at the consolidated database when the triggering inserts or updates are applied by the Message Agent. The triggers must be excluded from the remote databases, as they maintain a column that does not exist.

You can use the sp_user_extraction_hook procedure to exclude only certain triggers from a remote database on extraction. The procedure is called as the final part of an extraction. By default, it is empty.

toggle To customize the extraction procedure to omit certain triggers

  1. Ensure the quoted_identifier option is set to ON:

    set quoted_identifier on
go

  2. Any temporary tables referenced in the procedure must exist, or the CREATE PROCEDURE statement will fail. The temporary tables referenced in the following procedure are available in the ssremote.sql script. Copy any required table definitions from the script and execute the CREATE TABLE statements, so they exist on the current connection, before creating the procedure.

  3. Create the following procedure:

    CREATE PROCEDURE sp_user_extraction_hook
AS
BEGIN
  -- We do not want to extract the INSERT and
  -- DELETE triggers created on the Policy table
  -- that maintain the subscription_list
  -- column, since we do not include that
  -- column in the publication.
  -- If these objects were extracted the
  -- INSERTs would fail on the remote database
  -- since they reference a column
  -- ( subscription_list ) that does not exist.
  DELETE FROM #systrigger
  WHERE table_id = object_id( 'Policy' )
  -- Do not create any procedures
  DELETE FROM #sysprocedure
  WHERE proc_name = 'SubscribeCustomer'
END
go


Tuning extraction performance for shared rows

When extracting or synchronizing a user, the subscription-list column can cause performance problems as it necessitates a full table scan.

If you are extracting databases for many users, and performance is a problem for you, you can use a subscription view to improve performance. The view must contain a subquery, which is used for extraction and synchronization only, and is ignored during log scanning. The tables involved still need to have triggers defined to maintain the subscription-list column.

toggle To create a subscription view

  1. Design a query that uses a subquery to select the proper rows for a subscription from a table.

    For example, continuing the example from the preceding sections, the following query selects the rows of the Contact table for a user subscribed by rep_key value rep5:

    SELECT *
FROM Contact
WHERE 'rep5' = (SELECT rep_key
               FROM Customer
               WHERE cust_key = Contact.cust_key )

  2. Create a view that contains this subquery. For example:

    CREATE VIEW Customer_sub_view AS
SELECT *
FROM dbo.Customer
WHERE 'repxx' IN ( SELECT rep_key
   FROM dbo.Policy
   WHERE dbo.Policy.cust_key = dbo.Customer.cust_key )

    In this view definition, it does not matter what value you use on the left-hand side of the WHERE clause (repxx in the example above). The replication tools use the subquery for extraction and synchronization only. Rows for which the SUBSCRIBE BY value is in the subquery result set are extracted or synchronized.

  3. Give the name of the view as a parameter to sp_add_article or sp_modify_article:

    exec sp_add_article SalesRepData,
                  'Customer',
                  NULL,
                  'subscription_list',
                  'Customer_sub_view'

    The subscription_list column is used for log scanning and the subquery is used for extraction and synchronization.

    For more information, see Tuning extraction performance, sp_add_article procedure, and sp_modify_article procedure.


Using the Subscribe_by_remote option with many-to-many relationships

When the SUBSCRIBE_BY_REMOTE option is ON, operations that arrive from remote databases on rows with a subscribe by value of NULL or '' will assume the remote user is subscribed to the row. By default, the SUBSCRIBE_BY_REMOTE option is set to ON. In most cases, this setting is the desired setting.

The SUBSCRIBE_BY_REMOTE option solves a problem that otherwise would arise with publications including the Policy example. This section describes how the option automatically avoids the problem.

The database uses a subscription-list column for the Customer table, because each Customer may belong to several Sales Reps:

Marc Dill is a Sales Rep who has just arranged a policy with a new customer. He inserts a new Customer row and also inserts a row in the Policy table to assign the new Customer to himself. Assuming that the subscription-list column is not included in the publication, the operation at Marc's remote database is as follows:

The data are Marc's database.

As the INSERT of the Customer row is carried out by the Message Agent at the consolidated database, Adaptive Server Enterprise records the subscription value in the transaction log, at the time of the INSERT.

Later, when the Message Agent scans the log, it builds a list of subscribers to the new row, using the subscription value stored in the log, and Marc Dill is not on that list. If SUBSCRIBE_BY_REMOTE were set to OFF, the result would be that the new Customer is sent back to Marc Dill as a DELETE operation.

As long as SUBSCRIBE_BY_REMOTE is set to ON, the Message Agent assumes that, as the subscription-list column is NULL, the row belongs to the Sales Rep that inserted it. As a result, the INSERT is not replicated back to Marc Dill, and the replication system is intact.

You can use a trigger, which executes after the INSERT, to maintain the subscription-list column.


Managing conflicts

An UPDATE conflict occurs when the following sequence of events takes place:

  1. User 1 updates a row at remote site 1.

  2. User 2 updates the same row at remote site 2.

  3. The update from User 1 is replicated to the consolidated database.

  4. The update from User 2 is replicated to the consolidated database.

When the SQL Remote Message Agent replicates UPDATE statements, it does so as a separate UPDATE for each row. Also, the message contains the old row values for comparison. When the update from user 2 arrives at the consolidated database, the values in the row are not those recorded in the message.

Conflict resolution: the second update overwrites the first update.
Default conflict resolution

By default, the UPDATE still proceeds, so that the User 2 update (the last to reach the consolidated database) becomes the value in the consolidated database, and is replicated to all other databases subscribed to that row. In general, the default method of conflict resolution is that the most recent operation (in this case that from User 2) succeeds, and no report is made of the conflict. The update from User 1 is lost.

SQL Remote also allows custom conflict resolution, using a stored procedure to resolve conflicts in a way that makes sense for the data being changed.

Conflicts do not apply to primary keys

UPDATE conflicts do not apply to primary key updates. If the column being updated is a primary key, then when the update from User 2 arrives at the consolidated database, no row will be updated.

This section describes how you can build conflict resolution into your SQL Remote installation at the consolidated database.

How SQL Remote handles conflicts
Implementing conflict resolution
A first conflict resolution example
A second conflict resolution example
Designing to avoid referential integrity errors


How SQL Remote handles conflicts

When a conflict is detected

SQL Remote replication messages include UPDATE statements as a set of single row updates, each including the values prior to updating.

An UPDATE conflict is detected by the database server as a failure of the values to match the rows in the database.

Conflicts are detected and resolved by the Message Agent, but only at a consolidated database. When an UPDATE conflict is detected in a message from a remote database, the Message Agent causes the database server to take two actions:

  1. The UPDATE is applied.

  2. Any conflict resolution procedures are called.

UPDATE statements are applied even if the VERIFY clause values do not match, whether or not there is a resolve update procedure.

The method of conflict resolution is different at an Adaptive Server Anywhere consolidated database. For more information, see How SQL Remote handles conflicts.


Implementing conflict resolution

This section describes what you need to do to implement custom conflict resolution in SQL Remote.

Required objects

For each table on which you wish to resolve conflicts, you must create three database objects to handle the resolution:

  • An old value table To hold the values that were stored in the table when the conflicting message arrived.

  • A remote value table To hold the values stored in the table at the remote database when the conflicting update was applied, as determined from the message.

  • A stored procedure To carry out actions to resolve the conflict.

These objects need to exist only in the consolidated database, as that is where conflict resolution occurs. They should not be included in any publications.

Naming the objects

When a table is marked for replication, using the sp_add_remote_table or sp_modify_remote_table stored procedure, optional parameters specify the names of the conflict resolution objects.

The sp_add_remote_table and sp_modify_remote_table procedures take one compulsory argument, which is the name of the table being marked for replication. It takes three additional arguments, which are the names of the objects used to resolve conflicts. For example, the syntax for sp_add_remote_table is:

exec sp_add_remote_table table_name
[ , resolve_procedure ]
[ , old_row_table ]
[ , remote_row_table ]

You must create each of the three objects resolve_procedure, old_row_table, and remote_row_table. These three are discussed in turn.

  • old_row_table This table must have the same column names and data types as the table table_name, but should not have any foreign keys. When a conflict occurs, a row is inserted into old_row_table containing the values of the row in table_name being updated before the UPDATE was applied. Once resolve_procedure has been run, the row is deleted.

    As the Message Agent applies updates as a set of single-row updates, the table only ever contains a single row.

  • remote_row_table This table must have the same column names and data types as the table table_name, but should not have any foreign keys. When a conflict occurs, a row is inserted into remote_row_table containing the values of the row in table_name from the remote database before the UPDATE was applied. Once resolve_procedure has been run, the row is deleted.

    As the Message Agent applies updates as a set of single-row updates, the table only ever contains a single row.

  • resolve_procedure This procedure carries out whatever actions are required to resolve a conflict, which may include altering the value in the row or reporting values into a separate table.

Once these objects are created, you must run the sp_add_remote_table or sp_modify_remote_table procedure to flag them as conflict resolution objects for a table.

Limitations

  • At an Adaptive Server Enterprise database, conflict resolution will not work on a table with more than 128 columns while the VERIFY_ALL_COLUMNS option is set to ON. Even if VERIFY_ALL_COLUMNS is set to OFF, if an UPDATE statement updates more than 128 columns, conflict resolution will not work.


A first conflict resolution example

In this example, conflicts in the Customer table in the two-table example used in the tutorials are reported into a table for later review.

The database

The two-table database is as follows:

The Customer table has a foreign key to the SalesRep table.
Goals of the conflict resolution

The conflict resolution will report conflicts on updates to the name column in the Customer table into a separate table named ConflictLog.

The conflict resolution objects

The conflict resolution tables are defined as follows:

CREATE TABLE OldCustomer(
   cust_key CHAR( 12 ) NOT NULL,
   name CHAR( 40 ) NOT NULL,
   rep_key CHAR( 5 ) NOT NULL,
   PRIMARY KEY ( cust_key )
)
CREATE TABLE RemoteCustomer(
   cust_key CHAR( 12 ) NOT NULL,
   name CHAR( 40 ) NOT NULL,
   rep_key CHAR( 5 ) NOT NULL,
   PRIMARY KEY ( cust_key )
)

Each of these tables has exactly the same columns and data types as the Customer table itself. The only difference in their definition is that they do not have a foreign key to the SalesRep table.

The conflict resolution procedure reports conflicts into a table named ConflictLog, which has the following definition:

CREATE TABLE ConflictLog (
   conflict_key numeric(5, 0) identity not null,
   lost_name char(40) not null ,
   won_name char(40) not null ,
   primary key ( conflict_key )
)

The conflict resolution procedure is as follows:

CREATE PROCEDURE ResolveCustomer
AS
BEGIN
   DECLARE @cust_key CHAR(12)
   DECLARE @lost_name CHAR(40)
   DECLARE @won_name CHAR(40)
 // Get the name that was lost
   // from OldCustomer
   SELECT @lost_name=name,
      @cust_key=cust_key
   FROM OldCustomer
 // Get the name that won
   // from Customer
   SELECT @won_name=name
   FROM Customer
   WHERE cust_key = @cust_key
 INSERT INTO ConflictLog ( lost_name, won_name )
   VALUES ( @lost_name, @won_name )
END

This resolution procedure does not use the RemoteCustomer table.

How the conflict resolution works

The stored procedure is the key to the conflict resolution. It works as follows:

  1. Obtains the @lost_name value from the OldCustomer table, and also obtains a primary key value so that the real table can be accessed.

    The @lost_name value is the value that was overridden by the conflict-causing UPDATE.

  2. Obtains the @won_name value from the Customer table itself. This is the value that overrode @lost_name. The stored procedure runs after the update has taken place, which is why the value is present in the Customer table. This behavior is different from SQL Remote for Adaptive Server Anywhere, where conflict resolution is implemented in a BEFORE trigger.

  3. Adds a row into the ConflictLog table containing the @lost_name and @won_name values.

  4. After the procedure is run, the rows in the OldCustomer and RemoteCustomer tables are deleted by the Message Agent. In this simple example, the RemoteCustomer row was not used.

Testing the example
toggle To test the example

  1. Create the tables and the procedure in the consolidated database, and add them as conflict resolution objects to the Customer table.

  2. Insert and commit a change at the consolidated database. For example:

    UPDATE Customer
SET name = 'Sea Sports'
WHERE cust_key='cust1'
go
COMMIT
go

  3. Insert and commit a different change to the same line at the remote database. For example:

    UPDATE Customer
SET name = 'C Sports'
WHERE cust_key='cust1'
go
COMMIT
go

  4. Replicate the change from the remote to the consolidated database, by running the Message Agent at the remote database to send the message, and then at the consolidated database to receive and apply the message.

  5. At the consolidated database, view the Customer table and the ConflictLog table. The Customer table contains the value from the remote database:

    cust_key | name | rep_key
    cust1 | C Sports | rep1

    The ConflictLog table has a single row, showing the conflict:

    conflict_key | lost_name | won_name
    1 | Sea Sports | C Sports


A second conflict resolution example

This example shows a slightly more elaborate example of resolving a conflict, based on the same situation as the previous example, discussed in A first conflict resolution example.

Goals of the conflict resolution

In this case, the conflict resolution has the following goals:

  • Disallow the update from a remote database. The previous example allowed the update.

  • Report the name of the remote user whose update failed, along with the lost and won names.

The conflict resolution objects

In this case, the ConflictLog table has an additional column to record the user ID of the remote user. The table is as follows:

CREATE TABLE ConflictLog (
   conflict_key numeric(5, 0) identity not null,
   lost_name char(40) not null ,
   won_name char(40) not null ,
   remote_user char(40) not null ,
   primary key ( conflict_key )
)

The stored procedure is more elaborate. As the update will be disallowed, rather than allowed, the lost_name value now refers to the value arriving in the message. It is first applied, but then the conflict resolution procedure replaces it with the value that was previously present.

The stored procedure uses data from the temporary table #remote. In order to create a procedure that references a temporary table you first need to create that temporary table. The statement is as follows:

CREATE TABLE #remote (
   current_remote_user varchar(128),
   current_publisher varchar(128)
)

This table is created in TEMPDB, and exists only for the current session. The Message Agent creates its own #remote table when it connects, and uses it when the procedure is executed.

CREATE PROCEDURE ResolveCustomer
AS
BEGIN
   DECLARE @cust_key CHAR(12)
   DECLARE @lost_name CHAR(40)
   DECLARE @won_name CHAR(40)
   DECLARE @remote_user varchar(128)
 -- Get the name that was present before
   -- the message was applied, from OldCustomer
   -- This will "win" in the end
   SELECT @won_name=name,
      @cust_key=cust_key
   FROM OldCustomer
 -- Get the name that was applied by the
   -- Message Agent from Customer. This will
   -- "lose" in the end
   SELECT @lost_name=name
   FROM Customer
   WHERE cust_key = @cust_key
 -- Get the remote user value from #remote
   SELECT @remote_user = current_remote_user
   FROM #remote
 -- Report the problem
   INSERT INTO ConflictLog ( lost_name,
      won_name, remote_user )
   VALUES ( @lost_name, @won_name, @remote_user )
 -- Disallow the update from the Message Agent
   -- by resetting the row in the Customer table
   UPDATE Customer
   SET name = @won_name
   WHERE cust_key = @cust_key
END
Notes

There are several points of note here:

  • The user ID of the remote user is stored by the Message Agent in the current_remote_user column of the temporary table #remote.

  • The UPDATE from the Message Agent is applied before the procedure runs, so the procedure has to explicitly replace the values. This is different from the case in SQL Remote for Adaptive Server Anywhere, where conflict resolution is carried out by BEFORE triggers.

Testing the example
toggle To test the example

  1. Create the tables and the procedure in the consolidated database, and add them as conflict resolution objects to the Customer table.

  2. Insert and commit a change at the consolidated database. For example:

    UPDATE Customer
SET name = 'Consolidated Sports'
WHERE cust_key='cust1'
go
COMMIT
go

  3. Insert and commit a different change to the same line at the remote database. For example:

    UPDATE Customer
SET name = 'Field Sports'
WHERE cust_key='cust1'
go
COMMIT
go

  4. Replicate the change from the remote to the consolidated database, by running the Message Agent at the remote database to send the message, and then at the consolidated database to receive and apply the message.

  5. At the consolidated database, view the Customer table and the ConflictLog table. The Customer table contains the value from the consolidated database:

    cust_key | name | rep_key
    cust1 | Consolidated Sports | rep1

    The ConflictLog table has a single row, showing the conflict and recording the value entered at the remote database:

    conflict_key | lost_name | won_name | remote_user
    1 | Field Sports | Consolidated Sports | field_user

  6. Run the Message Agent again at the remote database. This receives the corrected update from the consolidated database, so that the name of the customer is set to Consolidated Sports here as well.


Designing to avoid referential integrity errors

The tables in a relational database are related through foreign key references. The referential integrity constraints applied as a consequence of these references ensure that the database remains consistent. If you wish to replicate only a part of a database, there are potential problems with the referential integrity of the replicated database.

Referential integrity errors stop replication
If a remote database receives a message that includes a statement that cannot be executed because of referential integrity constraints, no further messages can be applied to the database (because they come after a message that has not yet been applied), including passthrough statements, which would sit in the message queue.

By paying attention to referential integrity issues while designing publications you can avoid these problems. This section describes some of the more common integrity problems and suggests ways to avoid them.

Unreplicated referenced table errors

Consider the following SalesRepData publication:

exec sp_add_remote_table 'SalesRep'
exec sp_create_publication 'SalesRepData'
exec sp_add_article 'SalesRepData', 'SalesRep'
go

If the SalesRep table had a foreign key to another table (say, Employee) that was not included in the publication, inserts or updates to SalesRep would fail to replicate unless the remote database had the foreign key reference removed.

If you use the extraction utility to create the remote databases, the foreign key reference is automatically excluded from the remote database, and this problem is avoided. However, there is no constraint in the database to prevent an invalid value from being inserted into the rep_id column of the SalesRep table, and if this happens the INSERT will fail at the consolidated database. To avoid this problem, you could include the Employee table (or at least its primary key) in the publication.


Ensuring unique primary keys

Users at physically distinct sites can each INSERT new rows to a table, so there is an obvious problem ensuring that primary key values are kept unique.

If two users INSERT a row using the same primary key values, the second INSERT to reach a given database in the replication system will fail. As SQL Remote is a replication system for occasionally-connected users, there can be no locking mechanism across all databases in the installation. It is necessary to design your SQL Remote installation so that primary key errors do not occur.

For primary key errors to be designed out of SQL Remote installations; the primary keys of tables that may be modified at more than one site must be guaranteed unique. There are several ways of achieving this goal. This chapter describes a general, economical and reliable method that uses a pool of primary key values for each site in the installation.

Overview of primary key pools

The primary key pool is a table that holds a set of primary key values for each database in the SQL Remote installation. Each remote user receives their own set of primary key values. When a remote user inserts a new row into a table, they use a stored procedure to select a valid primary key from the pool. The pool is maintained by periodically running a procedure at the consolidated database that replenishes the supply.

The method is described using a simple example database consisting of sales representatives and their customers. The tables are much simpler than you would use in a real database; this allows us to focus just on those issues important for replication.

The primary key pool
Replicating the primary key pool
Filling and replenishing the key pool
Adding new customers
Testing the key pool
Primary key pool summary


The primary key pool

The pool of primary keys is held in a separate table. The following CREATE TABLE statement creates a primary key pool table:

CREATE TABLE KeyPool (
   table_name VARCHAR(40) NOT NULL,
   value INTEGER NOT NULL,
   location VARCHAR(6) NOT NULL,
   PRIMARY KEY (table_name, value),
)
go

The columns of this table have the following meanings:

Column | Description
table_name | Holds the names of tables for which primary key pools must be maintained. In our simple example, if new sales representatives were to be added only at the consolidated database, only the Customer table needs a primary key pool and this column is redundant. It is included to show a general solution.
value | Holds a list of primary key values. Each value is unique for each table listed in table_name.
location | In some setups, this could be the same as the rep_key value of the SalesRep table. In other setups, there will be users other than sales representatives and the two identifiers should be distinct.

For performance reasons, you may wish to create an index on the table:

CREATE INDEX KeyPoolLocation
ON KeyPool (table_name, location, value)
go


Replicating the primary key pool

You can either incorporate the key pool into an existing publication, or share it as a separate publication. In this example, we create a separate publication for the primary key pool.

toggle To replicate the primary key pool

  1. Create a publication for the primary key pool data.

    sp_create_publication 'KeyPoolData'
go
sp_add_remote_table 'KeyPool'
go
sp_add_article 'KeyPoolData', 'KeyPool',
   NULL, 'location'
go

  2. Create subscriptions for each remote database to the KeyPoolData publication.

    sp_subscription 'create',
   KeyPoolData,
   field_user,
   rep1
go

    The subscription argument is the location identifier.

In some circumstances it makes sense to add the KeyPool table to an existing publication and use the same argument to subscribe to each publication. Here we keep the location and rep_key values distinct to provide a more general solution.


Filling and replenishing the key pool

Every time a user adds a new customer, their pool of available primary keys is depleted by one. The primary key pool table needs to be periodically replenished at the consolidated database using a procedure such as the following:

CREATE PROCEDURE ReplenishPool AS
BEGIN
   DECLARE @CurrTable  VARCHAR(40)
   DECLARE @MaxValue   INTEGER
   DECLARE EachTable   CURSOR FOR
            SELECT table_name, max(value)
            FROM KeyPool
            GROUP BY table_name
   DECLARE @CurrLoc    VARCHAR(6)
   DECLARE @NumValues  INTEGER
   DECLARE EachLoc       CURSOR FOR
            SELECT location, count(*)
            FROM KeyPool
            WHERE table_name = @CurrTable
            GROUP BY location
 OPEN EachTable
   WHILE 1=1 BEGIN
      FETCH EachTable INTO @CurrTable, @MaxValue
      IF @@sqlstatus != 0 BREAK
      OPEN EachLoc
      WHILE 1=1 BEGIN
         FETCH EachLoc INTO @CurrLoc, @NumValues
         IF @@sqlstatus != 0 BREAK
         -- make sure there are 10 values
         WHILE @NumValues < 10 BEGIN
            SELECT @MaxValue = @MaxValue + 1
            SELECT @NumValues = @NumValues + 1
            INSERT INTO KeyPool
                   (table_name, location, value)
            VALUES (@CurrTable, @CurrLoc, @MaxValue)
         END
      END
      CLOSE EachLoc
   END
   CLOSE EachTable
END
go

This procedure fills the pool for each user up to ten values. You may wish to use a larger value in a production environment. The value you need depends on how often users are inserting rows into the tables in the database.

The ReplenishPool procedure must be run periodically at the consolidated database to refill the pool of primary key values in the KeyPool table.

The ReplenishPool procedure requires at least one primary key value to exist for each subscriber, so that it can find the maximum value and add one to generate the next set. To initially fill the pool you can insert a single value for each user, and then call ReplenishPool to fill up the rest. The following example illustrates this for three remote users and a single consolidated user named Office:

INSERT INTO KeyPool VALUES( 'Customer', 40, 'rep1' )
INSERT INTO KeyPool VALUES( 'Customer', 41, 'rep2' )
INSERT INTO KeyPool VALUES( 'Customer', 42, 'rep3' )
INSERT INTO KeyPool VALUES( 'Customer', 43, 'Office')
EXEC ReplenishPool
go
Cannot use a trigger to replenish the key pool
You cannot use a trigger to replenish the key pool, as no actions are replicated to the remote database performing the original operation, including trigger actions.

Previous Next


Adding new customers

When a sales representative wants to add a new customer to the Customer table, the primary key value to be inserted is obtained using a stored procedure. This example shows a stored procedure to supply the primary key value, and also illustrates a stored procedure to carry out the INSERT.

The procedures takes advantage of the fact that the Sales Rep identifier is the CURRENT PUBLISHER of the remote database.

  • NewKey procedure The NewKey procedure supplies an integer value from the key pool and deletes the value from the pool.

    CREATE PROCEDURE NewKey
         @TableName VARCHAR(40),
         @Location VARCHAR(6),
         @Value INTEGER OUTPUT AS
   BEGIN
      DECLARE @NumValues INTEGER
      SELECT @NumValues = count(*),
             @Value = min(value)
      FROM KeyPool
      WHERE table_name = @TableName
      AND location = @Location
      IF @NumValues > 1
         DELETE FROM KeyPool
         WHERE table_name = @TableName
         AND value = @Value
      ELSE
         -- Never take the last value,
         -- because RestorePool will not work.
         -- The key pool should be kept large
         -- enough so this never happens.
         SELECT @Value = NULL
   END

  • NewCustomer procedure The NewCustomer procedure inserts a new customer into the table, using the value obtained by NewKey to construct the primary key.

    CREATE PROCEDURE NewCustomer @name VARCHAR(40),
         @loc VARCHAR(6) AS
BEGIN
   DECLARE @cust  INTEGER
   DECLARE @cust_key  VARCHAR(12)

   EXEC NewKey 'Customer', @loc, @cust output
   SELECT @cust_key = 'cust' +
      convert( VARCHAR(12), @cust )
   INSERT INTO Customer (cust_key, name, rep_key )
   VALUES ( @cust_key, @name, @loc )
END

    You may want to enhance this procedure by testing the @cust value obtained from NewKey to check that it is not NULL, and preventing the insert if it is NULL.


Testing the key pool

toggle To test the primary key pool

  1. Re-extract a remote database using the field_user user ID.

  2. Try this sample INSERT at the remote and consolidated sites:

    EXEC NewCustomer 'Great White North', rep1


Creating subscriptions

To subscribe to a publication, each subscriber must be granted REMOTE permissions and a subscription must also be created for that user. The details of the subscription are different depending on whether or not the publication uses a subscription column.

Subscriptions with no subscription column

To subscribe a user to a publication, if that publication has no subscription column, you need the following information:

  • User ID The user who is being subscribed to the publication. This user must have been granted remote permissions.

  • Publication name The name of the publication to which the user is being subscribed.

The following statement creates a subscription for a user ID SamS to the pub_orders_samuel_singer publication, which was created without using a subscription column:

sp_subscription 'create',
   'pub_orders_samuel_singer',
   'SamS'
Subscriptions with a subscription column

To subscribe a user to a publication, if that publication does have a subscription column, you need the following information:

  • User ID The user who is being subscribed to the publication. This user must have been granted remote permissions.

  • Publication name The name of the publication to which the user is being subscribed.

  • Subscription value The value that is to be tested against the subscription column of the publication. For example, if a publication has the name of a column containing an employee ID as a subscription column, the value of the employee ID of the subscribing user must be provided in the subscription. The subscription value is always a string.

The following statement creates a subscription for Samuel Singer (user ID SamS, employee ID 856) to the pub_orders publication, defined with a subscription column sales_rep, requesting the rows for Samuel Singer's own sales:

sp_subscription create,
   pub_orders,
   SamS,
   '856'
Starting a subscription

In order to receive and apply updates properly, each subscriber needs to have an initial copy of the data. The synchronization process is discussed in Synchronizing databases.


Deploying and Synchronizing Databases

About this chapter

This chapter describes the steps you need to take to deploy and synchronize a SQL Remote replication installation.


Deployment overview

When you have completed the design phase of a SQL Remote system, the next step is to create and deploy the remote databases and applications.

Deployment tasks

In some cases, deployment is a major undertaking. For example, if you have a large number of remote users in a sales force automation system, deployment involves the following steps:

  1. Building an Adaptive Server Anywhere database for each remote user, with their own initial copy of the data.

  2. Installing the database, together with the Adaptive Server Anywhere database server, the SQL Remote Message Agent, and client application, on each user's machine.

  3. Ensuring that the system is properly configured, with correct user names, Message Agent connection strings, permissions, and so on.

In the case of large-scale deployments, remote sites are most commonly Adaptive Server Anywhere databases, and this chapter focuses on this case.

Topics covered

This chapter covers the following topics:

  • Creating remote databases Before you can deploy a SQL Remote system, you must create a remote database for each remote site.

    Most of the description focuses on creating remote Adaptive Server Anywhere databases.

  • Synchronizing data Synchronization of a database is the setting up of the initial copy of data in the remote database.


Test before deployment

Thorough testing of your SQL Remote system should be carried out before deployment, especially if you have a large number of remote sites.

When you are in the design and setup phase, you can alter many facets of the SQL Remote setup. Altering publications, message types, writing triggers to resolve update conflicts are all easy to do.

Once you have deployed a SQL Remote application, the situation is different. A SQL Remote setup can be seen as a single dispersed database, spread out over many sites, maintaining a loose form of consistency. The data may never be in exactly the same state in all databases in the setup at once, but all data changes are replicated as complete transactions around the system over time. Consistency is built in to a SQL Remote setup through careful publication design, and through the reconciliation of UPDATE conflicts as they occur.

Upgrading and resynchronization

Once a SQL Remote setup is deployed and is running, it is not easy to tinker with. An upgrade to a SQL Remote installation needs to be carried out with the same care as an initial deployment. This applies also to upgrading maintenance releases of the Adaptive Server Enterprise or Adaptive Server Anywhere database software. Any such software upgrade needs to be tested for compatibility before deployment.

Making changes to a database schema at one database within the system can cause failures because of incompatible database objects. The passthrough mode does allow schema changes to be sent to some or all databases in a SQL Remote setup, but must still be used with care and planning.

The loose consistency in the dispersed database means that updates are always in progress: you cannot generally stop changes being made to all databases, make some changes to the database schema, and restart.

Without careful planning, changes to a database schema will produce errors throughout the installation, and will require all subscriptions to be stopped and resynchronized. Resynchronization involves loading new copies of the data in each remote database, and for more than a few subscribers is a time-consuming process involving work interruptions and possible loss of data.

Changes to avoid on a running system


Changes to avoid on a running system

The following are examples of changes that should not be made to a deployed and running SQL Remote setup. From the list, you will see that there is a class of changes that are permissive, and these are generally permissible, while other changes are restrictive, and must be avoided.

The following changes must be avoided, except under the conditions stated:

  • Change the publisher for the consolidated database.

  • Make restrictive changes to tables, such as dropping a column or altering a column to not allow NULL values. Changes that include the column or including NULL entries may already be being sent in messages around the SQL Remote setup, and will fail.

  • Alter a publication. Publication definitions must be maintained at both local and remote sites, and changes that rely on the old publication definition may already be being sent in messages around the SQL Remote setup.

    You can make permissive changes, such as adding a new table or column, as long as you use passthrough to ensure that the new table or column exists in the remote database and in the publication at the remote database.

  • Drop a subscription. This can be done only if you use passthrough deletes to remove the data at the remote site.

  • Unload and reload an Adaptive Server Anywhere database.

    If an Adaptive Server Anywhere database is participating in replication, it cannot be unloaded and reloaded without re-synchronizing the database. Replication is based on the transaction log, and when a database is unloaded and reloaded, the old transaction log is no longer available. For this reason, good backup practices are especially important when participating in replication.

    An Adaptive Server Enterprise database can be unloaded and reloaded as long as the system is quiet and the transaction log is fully scanned. The page_id and row_id rows in the sr_queue_state table of the stable queue must be reset.


Synchronizing databases

What is synchronization?

SQL Remote replication is carried out using the information in the transaction log, but there are two circumstances where SQL Remote deletes all existing rows from those tables of a remote database that form part of a publication, and copies the publication's entire contents from the consolidated database to the remote site. This process is called synchronization.

When to synchronize

Synchronization is used under the following circumstances:

  • When a subscription is created at a consolidated database a synchronization is carried out, so that the remote database starts off with a database in the same state as the consolidated database.

  • If a remote database gets corrupt or gets out of step with the consolidated database, and cannot be repaired using SQL passthrough mode, synchronization forces the remote site database back in step with the consolidated site.

How to synchronize

Synchronizing a remote database can be done in the following ways:

  • Use the database extraction utility This utility creates a schema for a remote Adaptive Server Anywhere database, and synchronizes the remote database. This is generally the recommended procedure.

  • Manual synchronization Synchronize the remote database manually by loading from files, using the PowerBuilder pipeline, or some other tool.

  • Synchronize over the message system Synchronize the remote database via the message system using the SYNCHRONIZE SUBSCRIPTION statement (Adaptive Server Anywhere ) or sp_subscription 'synchronize' procedure (Adaptive Server Enterprise).

    Caution Do not execute SYNCHRONIZE SUBSCRIPTION or sp_subscription 'synchronize' at a remote database.


Mixed operating systems and database extraction

In many installations, the consolidated server will be running on a different operating system than the remote databases.

Adaptive Server Anywhere databases can be copied from one file or operating system to another. This allows you flexibility in how you carry out your initial synchronization of databases.

Example

For example, you may be running an Adaptive Server Enterprise server on a UNIX system that holds the consolidated database, but wish to deploy remote databases on laptop computers running some flavor of Windows.

In this circumstance, you have several options for the platforms on which you extract the database, including the following, assuming you have the requisite software:

  • Run the extraction utility on UNIX to create the reload script and data files. Copy the script and data files to a Windows machine. Create the Adaptive Server Anywhere databases and load them up with the schema and data on Windows.

  • Run the extraction utility on UNIX to create the reload script and data files. Create the Adaptive Server Anywhere databases and load them up with the schema and data on the same UNIX platform, and then copy the database files onto Windows machines for deployment.

  • Run the extraction utility on Windows, and carry out all database creation and other tasks on the Windows operating system.


Notes on synchronization and extraction

  • Extracting large numbers of subscriptions, or synchronizing subscriptions to large, frequently-used tables, can slow down database access for other users. You may wish to extract such subscriptions when the database is not in heavy use. This happens automatically if you use a SEND AT clause with a quiet time specified.

  • Synchronization applies to an entire subscription. There is currently no straightforward way of synchronizing a single table.

For performance tips for Adaptive Server Enterprise users using a subscription-list column, see Tuning extraction performance and Tuning extraction performance for shared rows.


Using the extraction utility

The extraction utility is an aid to creating remote Adaptive Server Anywhere databases. It cannot be used to create remote Adaptive Server Enterprise databases.

Running the extraction utility

The extraction utility can be accessed in the following ways:

  • From Sybase Central, if your consolidated database is Adaptive Server Anywhere.

  • As a command-line utility. This is the dbxtract utility (Adaptive Server Anywhere), or the ssxtract utility (Adaptive Server Enterprise).

Caution Do not run the Message Agent while running the extraction utility. The results are unpredictable.

Creating a database from the reload files
Before extracting a database
Using the extraction utility from Sybase Central
Designing an efficient extraction procedure
Extracting groups
Limits to using the extraction utility
Using the extraction utility for Adaptive Server Enterprise


Creating a database from the reload files

The command-line utility unloads a database schema and data suitable for building a remote Adaptive Server Anywhere database for a named subscriber. It produces a SQL command file with default name reload.sql and a set of data files. You can use these files to create a remote Adaptive Server Anywhere database.

Editing of reload.sql may be needed
The database extraction utility is intended to assist in preparing remote databases, but is not intended as a black box solution for all circumstances. You should edit the reload.sql command file as needed when creating remote databases.
toggle To create a remote database from the reload file

  1. Create an Adaptive Server Anywhere database using one of the following:

    • the Sybase Central Create Database wizard (from the Tools menu, choose Adaptive Server Anywhere 9 > Create Database)

    • the dbinit utility

  2. Connect to the database from the Interactive SQL utility, and run the reload.sql command file. The following statement entered in the SQL Statements pane runs the reload.sql command file:

    read path\reload.sql

    where path is the path of the reload command file.

When used from Sybase Central, the extraction utility carries out the database unloading task, in the same way that dbxtract does, and then takes the additional step of creating the new database.

The extraction utility does not use a message system. The reload file (ssxtract/dbxtract) or database (from Sybase Central) is created in a directory accessible from the current machine. Synchronizing many subscriptions over a message link can produce heavy message traffic and, if the message system is not completely reliable, it may take some time for all the messages to be properly received at the remote sites.


Before extracting a database

You must complete the following tasks before using the extraction utility at a consolidated database.

  • Create message types for replication.

  • Add a publisher user ID to the database.

  • Add remote users to the database.

  • Add the publication to the database.

  • Created a subscription for the remote users.

  • If you need to specify message link parameters, you must have set them.

For a description of how to carry out these steps, see the tutorial in the chapter Tutorials for Adaptive Server Anywhere Users. For a description of setting message link parameters, see Setting message type control parameters.

When you use the extraction utility to create a remote database, the user for which you are creating the database receives the same permissions they have in the consolidated database. Further, if the user is a member of any groups on the consolidated database, those group IDs are created in the remote database with the permissions they have in the consolidated database.


Using the extraction utility from Sybase Central

This section describes how to extract a database for a remote user from the current consolidated database. This section applies only to Adaptive Server Anywhere consolidated databases.

When you complete the Extract Database wizard, it does the following on your machine:

  • Creates the remote database

  • Extracts (unloads) the relevant structures and/or data from the consolidated database to files

  • Loads those files into the newly created remote database

toggle To extract a database for a remote user (Sybase Central)

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Extract Database.

  4. Follow the instructions in the wizard.

Notes

  • You can also access this wizard by clicking Tools > Adaptive Server Anywhere > Extract Database.

  • If you use the wizard to extract a non-running database, it is only able to unload the structure and data for you. It cannot create the remote database and reload it. For this reason, we recommend that you always extract from a consolidated database that you are connected to in Sybase Central.

  • You can also invoke the extraction wizard for a particular database or for a particular remote user—Sybase Central automatically fills in the appropriate entries in the wizard.

  • The extraction wizard always extracts (synchronizes) the remote database using the WITH SYNCHRONIZATION option. In those rare cases where you don't want to use this option, you must use the dbxtract utility instead.

  • Only tables for users selected in the Filter Objects by Owner dialog appear in the Extract Database wizard. If you wish to view tables belonging to a particular database user, right-click the database you are unloading, choose Filter Objects by Owner from the popup menu, and then select the desired user in the resulting dialog.

For more information

For information about the extraction utility options, available as command-line options or as choices presented by the extraction wizard, see Extraction utility options.


Designing an efficient extraction procedure

It is very inefficient to create a large number of remote databases by running the extraction utility for each one. You can make the process much more efficient. This section describes one way of making the process more efficient.

For performance tips for Adaptive Server Enterprise users using a subscription-list column, see Tuning extraction performance and Tuning extraction performance for shared rows.

There are several potential causes of inefficiency in a large-scale extraction process:

  • The extraction utility extracts one database at a time, including the schema and data for each user. Commonly, many users share a common schema, and only the data differs. The brute force method of running the extraction utility for each user repeats large amounts of work unnecessarily. Extracting schema and data separately can help with this problem.

  • Running from Sybase Central, the extraction utility creates a new database for each user. If subscribers share a common schema, you could create a single database, with schema but no data, and copy the file.

  • By default, the extraction utility runs at isolation level zero. If you are extracting a database from an active server, you should run it at isolation level 3 (see Extraction utility options) to ensure that data in the extracted database is consistent with data on the server.

    Running at isolation level 3 may hamper others' turnaround time on the server because of the large number of locks required. It is recommended that you run the extraction utility when the server is not busy, or run it against a copy of the database.

An efficient approach to extracting many databases

One approach that avoids these problems is as follows:

  1. Make a copy of the consolidated database, and at the same time start the subscriptions from the live database. Messages will now start being sent to subscribers, even though they have no database and will not receive them yet.

    To start several subscriptions within a single transaction, use the REMOTE RESET statement (Adaptive Server Anywhere ) or sp_remote procedure (Adaptive Server Enterprise).

  2. Extract the remote databases from the copy of the database. As the database is a copy, there are no locking and concurrency problems. For a large number of remote databases, this process may take several days.

  3. As each remote database is created, it is out of date, but its user can receive and apply messages that have been being sent from the live consolidated database, to bring themselves up to date.

This solution interferes with the production database only during the first step. The copy must be made at isolation level three if the database is in use, and uses large numbers of locks. Also, the subscriptions must be started at the same time that the copy is made. Any operations that take place between the copy and the starting of the subscriptions would be lost, and could lead to errors at remote databases.


Extracting groups

If the remote user is a group user ID, the extraction utility extracts all the user IDs of members of that group. You can use this feature to all multiple users on each remote database, using different user IDs, without requiring a custom extraction process.

When a database is extracted for a user, all message link parameters for that user and the groups of which the user is a member are extracted.


Limits to using the extraction utility

While the extraction utility is the recommended way of creating and synchronizing remote databases from a consolidated databases, there are some circumstances where it cannot be used, and you must synchronize remote databases manually. This section describes some of those cases.

  • Cannot create Adaptive Server Enterprise remote databases The extraction utility can only be used for Adaptive Server Anywhere remote databases.

  • Additional tables at the remote database Remote databases can have tables not present at their consolidated database as long as these tables do not take part in replication. Of course, the extraction utility cannot extract such tables from a consolidated database.

  • Adaptive Server Enterprise/Adaptive Server Anywhere differences Some features in Adaptive Server Enterprise are not present in Adaptive Server Anywhere. The extraction utility carries out a mapping onto similar features, but the mapping is not complete.

    For more information on Adaptive Server Enterprise/Adaptive Server Anywhere issues, see Using the extraction utility for Adaptive Server Enterprise.

  • Extracting procedures and views By default, the extraction utility extracts all stored procedures and views from the database. While some of these views and procedures are likely to be required at the remote site, others may not be required—they may refer only to parts of the database that are not included in the remote site.

    After running the extraction utility, you should edit the reload script and remove unnecessary views and procedures.

  • Using the extraction utility in multi-tiered setups To understand the role of the extraction utility in multi-tiered arrangements, consider a three-tiered SQL Remote setup.

    This setup is illustrated in the following diagram.

    A three-tiered setup. The middle tier databases act as both remote and consolidated databases.

    From the consolidated database at the top level, you can use the extraction utility to create the second-level databases. You can then add remote users to these second-level databases, and use the extraction utility from each second-level database to create the remote databases. However, if you have to re-extract the second-level databases from the top-level consolidated database, you will delete the remote users that were created, along with their subscriptions and permissions, and will have to rebuild those users. The exception is if you resynchronize data only, in which case you can use the extraction utility to replace the data in the database, without replacing the schema.


Using the extraction utility for Adaptive Server Enterprise

The extraction utility for Adaptive Server Enterprise takes an Adaptive Server Enterprise database schema, and produces an Adaptive Server Anywhere database. There are several limitations and techniques specific to this tool.


Adaptive Server Enterprise features unsupported in Adaptive Server Anywhere

There are some features in Adaptive Server Enterprise that are either not supported or are only partially supported in Adaptive Server Anywhere. The extraction utility handles some of these features partially, and some not at all.

For a full description of Adaptive Server Enterprise/Adaptive Server Anywhere compatibility, see the part Transact-SQL Compatibility, in the Adaptive Server Anywhere User's Guide.

Features not supported in ssxtract include the following:

  • Grouped procedures Adaptive Server Anywhere does not support procedure groups, and they are not extracted by ssxtract.

  • Named constraints and defaults Adaptive Server Anywhere does not support named constraints and named defaults. Any such objects are extracted directly as constraints and defaults that apply to a single object, and the name is lost.

  • Roles ssxtract extracts roles using the Adaptive Server Anywhere concept of groups. It creates a group with the named role, and assigns users to it.

  • Passwords If the user for whom a database is being extracted does not have an entry in SYSLOGINS, no password is extracted. If the user does have a login ID, a dummy password is extracted.

  • NCHAR, NVARCHAR These data types are extracted as CHAR and VARCHAR, with NULLS allowed.

  • timestamp columns Although Adaptive Server Anywhere does provide a timestamp column, it is a different data type from that of Adaptive Server Enterprise. Timestamp columns are not extracted.


Customizing the system tables

The objects that are to be loaded into an Adaptive Server Anywhere database are described in the system catalog. The extraction utility for Adaptive Server Enterprise first creates a set of Adaptive Server Anywhere system tables in TEMPDB, and fills them with data from the Adaptive Server Enterprise catalog. It then unloads this set of tables to provide the reload script that in turn builds an Adaptive Server Anywhere database.

There may be cases where you wish to change the content of the Adaptive Server Anywhere system tables held in TEMPDB. SQL Remote provides a place for you to do that.

The stored procedure that creates and fills the Adaptive Server Anywhere system objects in TEMPDB is called sp_populate_sql_anywhere. As its final operation, this procedure calls a procedure called sp_user_extraction_hook. This procedure, by default, does nothing. If you wish to customize the extraction procedure, you can do so by writing a suitable sp_user_extraction_hook procedure.


Synchronizing data over a message system

Creating subscriptions

A subscription is created at a consolidated Adaptive Server Enterprise database using the sp_subscription procedure with a first argument of create.

Creating a subscription defines the data to be received. It does not synchronize a subscription (provide an initial copy of the data) or start (exchange messages) a subscription.

Synchronizing subscriptions

Synchronizing a subscription causes the Message Agent to send a copy of all rows in the subscription to the subscriber. It assumes that an appropriate database schema is in place. At an Adaptive Server Anywhere consolidated database, subscriptions are synchronized using the SYNCHRONIZE SUBSCRIPTION statement. At an Adaptive Server Enterprise consolidated database, subscriptions are synchronized using the sp_subscription procedure with a first argument of synchronize.

When synchronization messages are received at a subscriber database, the Message Agent replaces the current contents of the database with the new copy. Any data at the subscriber that is part of the subscription, and which has not been replicated to the consolidated database, is lost. Once synchronization is complete, the subscription is started by the Message Agent using the START SUBSCRIPTION statement or sp_subscription procedure with a first argument of start.

Large volume of messages may result
Synchronizing databases over a message system may lead to large volumes of messages. In many cases, it is preferable to use the extraction process to synchronize a database locally without placing this burden on the message system.
Synchronizing subscriptions during operation

If a remote database becomes out of step with the consolidated database, and cannot be brought back in step using the SQL passthrough capabilities of SQL Remote, synchronizing the subscription forces the remote database into step with the consolidated database by copying the rows of the subscription from the consolidated database over the contents at the remote database.

Data loss on synchronization
Any data in the remote database that is part of the subscription, but which has not been replicated to the consolidated database, is lost when the subscription is synchronized. You may wish to unload or back up the remote database using Sybase Central or, for Adaptive Server Anywhere, the dbunload utility before synchronizing the database.

Previous Next


SQL Remote Administration

About this chapter

This chapter describes general issues and principles for administering a running SQL Remote installation.

For system-specific details, see the chapters Administering SQL Remote for Adaptive Server Enterprise and Administering SQL Remote for Adaptive Server Anywhere.

Management overview
Managing SQL Remote permissions
Using message types
Running the Message Agent
Tuning Message Agent performance
Encoding and compressing messages
The message tracking system


Management overview

This chapter describes administration issues for SQL Remote installations.

Administration of a deployed and running SQL Remote setup is carried out at a consolidated database.

  • Permissions As a SQL Remote installation includes many different physical databases, a consistent scheme for users having permissions on remote and consolidated databases is necessary. A section of this chapter describes the considerations you need to make when assigning users permissions.

  • Configuring message systems Each message system that is used in a SQL Remote installation has control parameters and other settings that must be set up. These settings are discussed in this chapter.

  • The Message Agent The Message Agent is responsible for sending and receiving messages. While some details of how the Message Agent operates and the configuration options for it, are different for Adaptive Server Anywhere and Adaptive Server Enterprise, some concepts and methods are common to both. These common features are discussed here.

  • Message tracking Administering a SQL Remote installation means managing large numbers of messages being handed back and forth among many databases. A section on the SQL Remote message tracking system is included to help you understand what the messages contain, when they are sent, how they are applied, and so on.

  • Log management SQL Remote obtains the data to send from the transaction log. Consequently, proper management of the transaction log, and proper backup procedures, are essential for a smoothly running SQL Remote installation. While many details depend on the server you are running, the generic issues are discussed in this chapter.

  • Passthrough mode This is a method for directly intervening at a remote site from a consolidated database. This method is discussed in this chapter.


Managing SQL Remote permissions

Users of a database involved in SQL Remote replication are identified by one of the following sets of permissions:

  • PUBLISH A single user ID in a database is identified as the publisher for that database. All outgoing SQL Remote messages, including both publication updates and receipt confirmations, are identified by the publisher user ID. Every database in a SQL Remote setup must have a single publisher user ID, as every database in a SQL Remote setup sends messages.

  • REMOTE All recipients of messages from the current database, or senders of messages to the current database, who are immediately lower on the SQL Remote hierarchy than the current database must be granted REMOTE permissions.

  • CONSOLIDATE At most one user ID may be granted CONSOLIDATE permissions in a database. CONSOLIDATE permissions identifies a database immediately above the current database in a SQL Remote setup. Each database can have only one consolidated database directly above it.

Information about these permissions are held in the SQL Remote system tables, and are independent of other database permissions.


Granting and revoking PUBLISH permissions

When a database sends a message, a user ID representing that database is included with the message to identify its source to the recipient. This user ID is the publisher user ID of the database. A database can have only one publisher. You can find out who the publisher of an Adaptive Server Anywhere database is at any time in Sybase Central by opening the Users & Groups folder.

A publisher is required even for read-only remote databases within a replication system, as even these databases send confirmations to the consolidated database to maintain information about the status of the replication. The GRANT PUBLISH statement for remote Adaptive Server Anywhere databases is carried out automatically by the database extraction utility.

Granting and revoking PUBLISH permissions from Sybase Central

You can grant PUBLISH permissions on an Adaptive Server Anywhere database from Sybase Central. You must connect to the database as a user with full system or database administrator permissions.

toggle To create a new user as the publisher (Sybase Central)

  1. In the left pane, select the Users & Groups folder.

  2. From the File menu, choose New > User.

    The User Creation wizard appears.

  3. Follow the instructions in the wizard. Ensure that the user has a password and is granted Remote DBA authority; this enables the user ID to run the Message Agent.

  4. Click Finish to create the user.

  5. In the Users & Groups folder, right-click the user you just created and choose Change to Publisher from the popup menu.

toggle To make an existing user the publisher (Sybase Central)

  • In the Users & Groups folder, right-click a user and choose Change to Publisher from the popup menu.

You can also revoke PUBLISH permissions from Sybase Central.

toggle To revoke PUBLISH permissions (Sybase Central)

  • In the Users & Groups folder, right-click the user who has granted PUBLISH permissions and choose Revoke Publisher from the popup menu.

Granting and revoking PUBLISH permissions [Adaptive Server Anywhere]

For Adaptive Server Anywhere, PUBLISH permissions are granted using the GRANT PUBLISH statement:

GRANT PUBLISH TO userid ;

The userid is a user with CONNECT permissions on the current database. For example, the following statement grants PUBLISH permissions to user S_Beaulieu:

GRANT PUBLISH TO S_Beaulieu

The REVOKE PUBLISH statement revokes the PUBLISH permissions from the current publisher:

REVOKE PUBLISH FROM userid
Granting and revoking PUBLISH permissions [Adaptive Server Enterprise]

For Adaptive Server Enterprise, PUBLISH permissions are granted using the sp_publisher procedure:

sp_publisher userid

The userid is a user with CONNECT permissions on the current database. For example, the following statement grants PUBLISH permissions to user S_Beaulieu:

exec sp_publisher 'S_Beaulieu'
go

The database is set to have no publisher by executing the sp_publisher procedure with no argument:

exec sp_publisher
go
Notes on PUBLISH permissions

  • To see the publisher user ID for an Adaptive Server Anywhere database outside Sybase Central, use the CURRENT PUBLISHER special constant. The following statement retrieves the publisher user ID:

    SELECT CURRENT PUBLISHER

  • To see the publisher user ID for an Adaptive Server Enterprise database, use the following statement:

    SELECT name
FROM sysusers
WHERE uid = ( SELECT user_id
               FROM sr_publisher )
go

  • If PUBLISH permissions is granted to a user ID with GROUP permissions, it is not inherited by members of the group.

  • PUBLISH permissions carry no authority except to identify the publisher in outgoing messages.

  • For messages sent from the current database to be received and processed by a recipient, the publisher user ID must have REMOTE or CONSOLIDATE permissions on the receiving database.

  • The publisher user ID for a database cannot also have REMOTE or CONSOLIDATE permissions on that database. This would identify them as both the sender of outgoing messages and a recipient of such messages.

  • Changing the user ID of a publisher at a remote database will cause serious problems for any subscriptions that database is involved in, including loss of information. You should not change a remote database publisher user ID unless you are prepared to resynchronize the remote user from scratch.

  • Changing the user ID of a publisher at a consolidated database while a SQL Remote setup is operating will cause serious problems, including loss of information. You should not change the consolidated database publisher user ID unless you are prepared to close down the SQL Remote setup and resynchronize all remote users.


Granting and revoking REMOTE and CONSOLIDATE permissions

REMOTE and CONSOLIDATE permissions are very similar. Each database receiving messages from the current database must have an associated user ID on the current database that is granted one of REMOTE or CONSOLIDATE permissions. This user ID represents the receiving database in the current database.

Databases directly below the current database on a SQL Remote hierarchy are granted REMOTE permissions, and the at most one database above the current database in the hierarchy is granted CONSOLIDATE permissions.

Setting REMOTE and CONSOLIDATE permissions

For Adaptive Server Anywhere, the GRANT REMOTE and GRANT CONSOLIDATE statements identify the message system and address to which replication messages must be sent.

For Adaptive Server Enterprise, the sp_grant_remote procedure sets REMOTE permissions, and the sp_grant_consolidate procedure sets CONSOLIDATE permissions.

CONSOLIDATE permissions must be granted even from read-only remote databases to the consolidated database, as receipt confirmations are sent back from the remote databases to the consolidated database. The GRANT CONSOLIDATE statement at remote Adaptive Server Anywhere databases is executed automatically by the database extraction utility.


Granting REMOTE permissions

Each remote database must be represented by a single user ID in the consolidated database. This user ID must be granted REMOTE permissions to identify their user ID and address as a subscriber to publications.

Granting REMOTE permissions accomplishes several tasks:

  • It identifies a user ID as a remote user.

  • It specifies a message type to use for exchanging messages with this user ID.

  • It provides an address to where messages are to be sent.

  • It indicates how often messages should be sent to the remote user.

Granting REMOTE permissions is also referred to as adding a remote user to the database.

Sybase Central example

You can add a remote user to a database using Sybase Central. Remote users and groups appear in two locations in Sybase Central: in the Users & Groups folder, and in the SQL Remote Users folder. This section applies only to Adaptive Server Anywhere databases.

By default, remote users are created with remote DBA authority. Since the message agent for access to the remote database requires this authority, you shouldn't revoke it.

You cannot create a new remote user until at least one message type is defined in the database.

While you can grant remote permissions to a group, those remote permissions do not automatically apply to users in the group (unlike table permissions, for example). To do this, you must explicitly grant remote permissions to each user in the group. Otherwise, remote groups behave exactly like remote users (and are categorized as remote users).

toggle To add a new user to the database as a remote user (Sybase Central)

  1. In the left pane, select the SQL Remote Users folder.

  2. From the File menu, choose New > SQL Remote User.

    The Create a New Remote User wizard appears.

  3. Follow the instructions in the wizard.

toggle To make an existing user remote (Sybase Central)

  1. Open the Users & Groups folder.

  2. Right-click the user you want to make remote and choose Change to Remote User from the popup menu.

  3. In the resulting dialog, select the message type from the list, enter an address, choose the frequency of sending messages, and click OK to make the user a remote user.

    This user now appears in both the Users & Groups folder and the SQL Remote Users folder.

Adaptive Server Anywhere example

The following statement grants remote permissions to user S_Beaulieu, with the following options:

  • Use an SMTP e-mail system

  • Send messages to e-mail address s_beaulieu@acme.com:

  • Send message daily, at 10 p.m.

GRANT REMOTE TO S_Beaulieu
TYPE smtp
ADDRESS 's_beaulieu@acme.com'
SEND AT '22:00'
Adaptive Server Enterprise example

The following statement grants remote permissions to user S_Beaulieu with the following options:

  • Use the file-sharing system to exchange messages.

  • Place messages in the directory beaulieu under the address root directory.

    The address root directory (for both Adaptive Server Anywhere and Adaptive Server Enterprise) is indicated by the SQLREMOTE environment variable, if it is set. Alternatively, it is indicated by the Directory setting in the FILE message control parameters (held in the registry or INI file).

  • Send messages every twelve hours:

exec sp_grant_remote 'S_Beaulieu',
   'file',
   'beaulieu',
   'SEND EVERY',
   '12:00'
go


Selecting a send frequency

There are three alternatives for the setting the frequency with which messages are sent. The three alternatives are:

  • SEND EVERY A frequency can be specified in hours, minutes, and seconds in the format 'HH:MM:SS'.

    When any user with SEND EVERY set is sent messages, all users with the same frequency are sent messages also. For example, all remote users who receive updates every twelve hours are sent updates at the same times, rather than being staggered. This reduces the number of times the Adaptive Server Anywhere transaction log or Adaptive Server Enterprise stable queue has to be processed. You should use as few unique frequencies as possible.

  • SEND AT A time of day, in hours and minutes.

    Updates are started daily at the specified time. It is more efficient to use as few distinct times as possible than to stagger the sending times. Also, choosing times when the database is not busy minimizes interference with other users.

  • Default setting (no SEND clause) If any user has no SEND AT or SEND EVERY clause, the Message Agent sends messages every time it is run, and then stops: it runs in batch mode.

Setting the send frequency in Sybase Central

In Sybase Central, you can specify the send frequency in the following ways:

  • When you make an existing user or group remote. For more information, see Granting REMOTE permissions.

  • On the SQL Remote tab of the property sheet of a remote user or group. You can access the property sheet by right-clicking the remote user or group and choosing Properties from the popup menu.


Granting CONSOLIDATE permissions

In the remote database, the publish and subscribe user IDs are inverted compared to the consolidated database. The subscriber (remote user) in the consolidated database becomes the publisher in the remote database. The publisher of the consolidated database becomes a subscriber to publications from the remote database, and is granted CONSOLIDATE permissions.

At each remote database, the consolidated database must be granted CONSOLIDATE permissions. When you produce a remote database by running the database extraction utility, the GRANT CONSOLIDATE statement is executed automatically at the remote database.

Adaptive Server Anywhere example

The following Adaptive Server Anywhere statement grants CONSOLIDATE permissions to the hq_user user ID, using the VIM e-mail system:

GRANT CONSOLIDATE TO hq_user
TYPE vim
ADDRESS 'hq_address'

There is no SEND clause in this statement, so the default is used and messages will be sent to the consolidated database every time the Message Agent is run.

Adaptive Server Enterprise example

The following Adaptive Server Enterprise statement grants CONSOLIDATE permissions to user hq_user, using the file message link:

exec sp_grant_consolidate 'hq_user', 'file', address
go


Revoking REMOTE and CONSOLIDATE permissions

A user can be removed from a SQL Remote installation by revoking their REMOTE permissions. When you revoke remote permissions from a user or group, you revert that user or group to a normal user/group. You also automatically unsubscribe that user or group from all publications.

Revoking permissions from Sybase Central

You can revoke REMOTE permissions on Adaptive Server Anywhere databases from Sybase Central.

toggle To revoke REMOTE permissions (Sybase Central)

  1. Open either the Users & Groups folder or the SQL Remote Users folder.

  2. Right-click the remote user or group and choose Revoke Remote from the popup menu.

Revoking permissions in Adaptive Server Anywhere

REMOTE and CONSOLIDATE permissions can be revoked from a user using the REVOKE statement. The following statement revokes REMOTE permission from user S_Beaulieu.

REVOKE REMOTE FROM S_Beaulieu

DBA authority is required to revoke REMOTE or CONSOLIDATE access.

Revoking permissions in Adaptive Server Enterprise

REMOTE permissions can be revoked from a user using the sp_revoke_remote procedure. This procedure takes a single argument, which is the user ID of the user. The following statement revokes REMOTE permission from user S_Beaulieu.

exec sp_revoke_remote 'S_Beaulieu'
go


Assigning permissions in multi-tier installations

Special considerations are needed for assigning permissions in multi-tier installations. The permissions in a three-level SQL Remote setup are summarized in the following diagrams. In each diagram one database is shaded; the diagram shows the permissions that need to be granted in that database for the user ID representing each of the other databases. The phrase "No permissions" means that the database is not granted any permissions in the shaded database.

The following picture shows SQL Remote permissions, as granted at the consolidated site of a three-tier installation.

The middle tier database had Remote permission. The bottom tier databases have no permissions.

The following picture shows SQL Remote permissions, as granted at an internal site of a three-tier installation.

The top tier database has Consolidate permissions. The bottom tier databases have Remote permissions.

The following picture shows SQL Remote permissions, as granted at an internal site of a three-tier installation.

The middle tier database has Consolidate permissions. Other databases have no permissions.

Granting the appropriate PUBLISH and CONSOLIDATE permissions at remote databases is done automatically by the database extraction utility.


Using message types

SQL Remote supports several different systems for exchanging messages. The message systems supported by SQL Remote are:

  • file Storage of message files in directories on a shared file system for reading by other databases.

  • ftp Storage of message files in directories accessible by a file transfer protocol (ftp) link.

  • mapi Microsoft's messaging API (MAPI) link, used in Microsoft Mail and other electronic mail systems.

  • smtp Internet Simple Mail Transfer Protocol (SMTP/POP), used in Internet e-mail.

  • vim Lotus's Vendor Independent Messaging (VIM), used in Lotus Notes and cc:Mail.

A database can exchange messages using one or more of the available message systems.

Operating system availability

Not all message systems are supported on all operating systems for which SQL Remote is available. The links are implemented as DLLs on Windows operating systems.

For a listing of which message systems are supported on which operating system, see Supported Platforms and Message Links.

For more information

  • For more information on the file message system, see The file message system.

  • For more information on the ftp message system, see The ftp message system.

  • For more information on the smtp message system, see The SMTP message system.

  • For more information on the mapi message system, see The MAPI message system.

  • For more information on the vim message system, see The VIM message system.

Working with message types
Setting message type control parameters
The file message system
The ftp message system
The SMTP message system
The MAPI message system
The VIM message system


Working with message types

Each message type definition includes the type name (file, ftp, smtp, mapi, or vim) and also the address of the publisher under that message type. The publisher address at a consolidated database is used by the database extraction utility as a return address when creating remote databases. It is also used by the Message Agent to identify where to look for incoming messages for the file system.

The address supplied with a message type definition is closely tied to the publisher ID of the database. Valid addresses are considered in following sections.

Before you can use a message system, you must set the publisher's address.


Using Sybase Central to work with message types

You can create and alter message types in Sybase Central. Message types appear on the Message Types tab in the right pane when the SQL Remote Users folder is selected. This section applies only to Adaptive Server Anywhere databases.

You must have DBA authority to create and alter message types.

toggle To add a message type (Sybase Central)

  1. Connect to a database.

  2. In the left pane, open the SQL Remote Users folder for that database.

  3. In the right pane, click the Message Types tab.

  4. From the File menu, choose New > Message Type.

    The Message Type Creation wizard appears.

  5. In the Message Type Creation wizard, enter a message type name. The name should correspond to a message-type DLL already installed in your Adaptive Server Anywhere directory. Click Next.

  6. Enter a publisher address and click Finish to save the definition in the database.

If you wish to change the publisher's address, you can do so by altering a message type. You cannot change the name of an existing message type; instead, you must delete it and create a new message type with the new name.

toggle To alter a message type (Sybase Central)

  1. In the left pane, open the SQL Remote Users folder for a database.

  2. In the right pane, click the Message Types tab.

  3. In the right pane, right-click the message type you wish to alter and choose Properties from the popup menu.

  4. On the property sheet, configure the various options.

If you wish to drop a message type from the installation, you can do so.

toggle To drop a message type (Sybase Central)

  1. In the left pane, open the SQL Remote Users folder for a database.

  2. In the right pane, click the Message Types tab.

  3. In the right pane, right-click the message type you wish to alter and choose Delete from the popup menu.

Creating message types for Windows CE

From within the Sybase Central Utilities tab (select Adaptive Server Anywhere 9 in the left pane, and then click the Utilities tab in the right pane), if you have Windows CE services installed, you have an option to set up SQL Remote for ActiveSync synchronization. This sets your folder for FILE message link messages to be the ActiveSync folder. When you dock your Windows CE machine to your desktop machine, ActiveSync keeps the files in your desktop machine's ActiveSync folder synchronized with those in the Windows CE ActiveSync folder.


Using commands to work with message types
toggle To create a message type (SQL)

  1. Make sure you have decided on an address for the publisher under the message type.

  2. Execute a CREATE REMOTE MESSAGE TYPE command.

    For Adaptive Server Anywhere, the CREATE REMOTE MESSAGE TYPE statement has the following syntax:

    CREATE REMOTE MESSAGE TYPE type-name
    ADDRESS address-string

    For Adaptive Server Enterprise, use the sp_remote_type procedure. This procedure takes the following arguments:

    sp_remote_type type-name, address-string

    In these statements, type-name is one of the message systems supported by SQL Remote, and address-string is the publisher's address under that message system.

If you wish to change the publisher's address, you can do so by altering the message type.

toggle To alter a message type (SQL)

  1. Make sure you have decided on a new address for the publisher under the message type.

  2. Execute an ALTER REMOTE MESSAGE TYPE statement.

    For Adaptive Server Anywhere, the ALTER REMOTE MESSAGE TYPE statement has the following syntax:

    ALTER REMOTE MESSAGE TYPE type-name
    ADDRESS address-string

    For Adaptive Server Enterprise, use the sp_remote_type procedure in the same way as creating a message type. This procedure takes the following arguments:

    sp_remote_type type-name, address-string

    In these statements, type-name is one of the message systems supported by SQL Remote, and address-string is the publisher's address under that message system.

You can also drop message types if they are no longer used in your installation. This has the effect of removing the publisher's address from the definition.

toggle To drop a message type (SQL)

  • Execute a DROP REMOTE MESSAGE TYPE statement.

    For Adaptive Server Anywhere, the DROP REMOTE MESSAGE TYPE statement has the following syntax:

    DROP REMOTE MESSAGE TYPE type-name

    For Adaptive Server Enterprise, use the sp_drop_remote_type procedure in the same way as creating a message type. This procedure takes the following arguments:

    sp_drop_remote_type type-name

    In these statements, type-name is one of the message systems supported by SQL Remote.

See also

  • CREATE REMOTE MESSAGE TYPE statement

  • ALTER REMOTE MESSAGE TYPE statement

  • DROP REMOTE MESSAGE TYPE statement


Setting message type control parameters

Each message link has several parameters that govern aspects of its behavior. The parameters differ from message system to message system, but all are managed in the same way.

When you first use the Message Agent for a particular message link, it displays a dialog box showing a set of parameters that control the behavior of the link. These parameters may be a user ID for the message system, a host name where ftp messages are held, and so on. The parameters you enter are saved by the Message Agent. You can also set these parameters explicitly.

Message link parameters stored in the database

The message control parameters are held in the database. You can set the options as follows:

toggle To set a message control parameter (Adaptive Server Anywhere)

  • Execute the following statement:

    SET REMOTE link-name OPTION
    [username.]option-name = option-value

toggle To set a message control parameter (Adaptive Server Enterprise)

  • Execute the following statement:

    exec sp_link_option link-name, [username],
    option-name, option-value

You can see the current message link parameters by querying the sys.sysremoteoptions view (Adaptive Server Anywhere) or the sr_remoteoptions view (Adaptive Server Enterprise).

Holding the message link parameters on disk

Earlier versions of this software stored the message link parameters outside the database. You can still use this method, but storing the parameters inside the database is recommended unless you have specific reasons to choose otherwise.

The message link control parameters are stored in the following places:

  • Windows In the registry, at the following location:

    \\HKEY_CURRENT_USER
   \Software
      \Sybase
         \SQL Remote

    The parameters for each message link go in a key under the SQL Remote key, with the name of the message link (4, smtp, and so on).

  • NetWare You should create a file named dbremote.ini in the sys:\system directory to hold the FILE system directory setting. This file is not a Windows-format INI file: it must consist of a single line, holding only the directory name.

    For example, if the directory is user:\dbr43, then the dbremote.ini file would contain the following:

    user:\dbr43

  • UNIX The FILE system directory setting is held in the SQLREMOTE environment variable.

The sqlremote environment variable holds a path that can be used as an alternative to one of the control parameters for the file sharing system.

The parameters available for each message system are discussed in the following sections. Each section describes a single message system.

When the Message Agent loads a message link, the link uses the settings of the current publisher or, if a setting is not specified, of groups to which the publisher belongs. On Windows, the first time a version of the Message Agent is run that supports storing the message link parameters in the database, it copies the link options from the registry to the database.


The file message system

SQL Remote can be used even if you do not have a message system in place, by using the file message system.

Addresses in the file message system

The file message system is a simple file-sharing system. A file address for a remote user is a subdirectory into which all their messages are written. To retrieve messages from their "inbox", an application reads the messages from the directory containing the user's files. Return messages are sent to the address (written to the directory) of the consolidated database.

When running as an NT service make sure that the account under which the Message Agent is running has permissions to read and write all necessary directories. This is often a problem when accessing network drives.

Root directory for addresses

The file system addresses are typically subdirectories of a shared directory that is available to all SQL Remote users, whether by modem or on a local area network. Each user should have a registry entry, initialization file entry, or SQLREMOTE environment variable pointing to the shared directory.

You can also use the file system to put the messages in directories on the consolidated and remote machines. A simple file transfer mechanism can then be used to exchange the files periodically to effect replication.

FILE message control parameters

The FILE message system uses the following control parameters:

  • Directory This is set to the directory under which the messages are stored. The setting is an alternative to the SQLREMOTE environment variable.

  • Debug This is set to either YES or NO, with the default being NO. When set to YES, all file system calls made by the FILE link are displayed.

  • Unlink_delay This is the number of seconds to wait before attempting to delete a file if the previous attempt to delete the file failed. If no value is defined for unlink_delay, then the default behavior is to pause for 1 second after the first failed attempt, 2 seconds after the second failed attempt, 3 seconds after the third failed attempt, and 4 seconds after the fourth failed attempt.

On NetWare, you should create a file named dbremote.ini in the sys:\system directory to hold the directory setting.


The ftp message system

Addresses for ftp

In the ftp message system, messages are stored in directories under a root directory on an ftp host. The ftp host and the root directory are specified by message system control parameters held in the registry or initialization file, and the address of each user is the subdirectory where their messages are held.

For a list of operating systems for which ftp is supported, see Supported operating systems.

FTP message control parameters

The ftp message system uses the following control parameters:

  • host The host name of the computer where the messages are stored. This can be a host name (such as ftp.ianywhere.com) or an IP address (such as 192.138.151.66).

  • user The user name for accessing the ftp host.

  • password The password for accessing the ftp host.

  • root_directory The root directory within the ftp host site, under which the messages are stored.

  • port Usually not required. This is the IP port number used for the Ftp connection.

  • debug This is set to either YES or NO, with the default being NO. When set to YES, debugging output is displayed.

  • active_mode This is set to either YES or NO, with the default being NO (passive mode).

Troubleshooting ftp problems


Troubleshooting ftp problems

Most problems with the FTP message link are network setup issues. This section contains a list of tests you can try to troubleshoot problems.

Set the DEBUG message control parameter Looking over the debug output should indicate whether you are connecting to the FTP server. If you are connecting, it will indicate which FTP commands are failing.

Ping the ftp server If the FTP link is not able to connect to the FTP server, try testing your systems network configuration. If your system has the ping command, try typing the following command:

ping ftp-server-name

You should see output indicating the IP address of the server and the ping (round trip) time to the server. If you can not ping the server than you have a network configuration problem, and you should contact you network administrator.

Check that passive mode works If the FTP link is connecting to the FTP server, but is unable to open a data connection, make sure that an FTP client can use passive mode to transfer data with the server.

Passive mode is the preferred transfer mode and the default for the FTP message link. In passive mode all data transfer connections are initiated by the client, in this case the message link. In Active mode the server initiates all data connections. If your FTP server is sitting behind an incorrectly configured firewall you may not be able to use the default passive transfer mode. In this situation the firewall blocks socket connections to the FTP server on ports other than the FTP control port.

Using an FTP user program that allows you to set the transfer mode between active and passive, set the transfer mode to passive and try to upload/download a file. If the client you are using cannot transfer the file without using active mode than you should either reconfigure the firewall and FTP server to allow passive mode transfers or set the active_mode message control parameter to YES. Active mode transfers may not work in all network configurations. For example: if your client is sitting behind an IP masquerading gateway incoming connections may fail depending on you gateway software.

Check permissions and directory structures If the FTP server is connecting and having problems getting directory listings or manipulating files; make sure your permissions are set up correctly and the directories that you need exist.

Log into the FTP server using an FTP program. Change directories to the location stored in the root_directory parameter. If the directories you need do not show up, the root_directory control parameter may be wrong or the directories may not exist.

Test permissions by fetching a file in your message directory and uploading a file to the consolidated database directory. If you get errors your FTP server permissions are set up incorrectly.


The SMTP message system

The Simple Mail Transfer Protocol (SMTP) is used in Internet e-mail products.

With the SMTP system, SQL Remote sends messages using Internet mail. The messages are encoded to a text format and sent in an e-mail message to the target database. The messages are sent using an SMTP server, and retrieved from a POP server: this is the way that many e-mail programs send and receive messages.

For a list of operating systems for which SMTP is supported, see Supported operating systems.

SMTP addresses and user IDs

To use SQL Remote and an SMTP message system, each database participating in the setup requires a SMTP address, and a POP3 user ID and password. These are distinct identifiers: the SMTP address is the destination of each message, and the POP3 user ID and password are the name and password entered by a user when they connect to their mail box.

Separate e-mail account recommended
It is recommended that a separate POP e-mail account be used for SQL Remote messages.
Troubleshooting

If you can not get the SMTP Link to work try connecting to the SMTP/POP3 server from the same machine on which the Message Agent is running using the same account and password. Use an Internet e-mail program that supports SMTP/POP3 and make sure to disable the program once the SMTP message link is working.

SMTP message control parameters

Before the Message Agent connects to the message system to send or receive messages, the user must either have a set of control parameters already set on their machine, or must fill in a window with the needed information. This information is needed only on the first connection. It is saved and used as the default entries on subsequent connects.

The SMTP message system uses the following control parameters:

  • local_host This is the name of the local computer. It is useful on machines where SQL Remote is unable to determine the local host name. The local host name is needed to initiate a session with any SMTP server. In most network environments, the local host name can be determined automatically and this entry is not needed.

  • TOP_supported SQL Remote uses a POP3 command called TOP when enumerating incoming messages. The TOP command may not be supported by all POP servers. Setting this entry to NO will use the RETR command, which is less efficient but will work with all POP servers. The default is YES.

  • smtp_authenticate Determines whether the SMTP link authenticates the user. The default value is YES. Set to NO for no SMTP authentication to be carried out.

  • smtp_userid The user ID for SMTP authentication. By default this parameter takes the same value as the pop3_userid parameter. The smtp_userid only needs to be set if the user ID is different to that on the POP server.

  • smtp_password The password for SMTP authentication. By default this parameter takes the same value as the pop3_password parameter. The smtp_password only needs to be set if the user ID is different to that on the POP server.

  • smtp_host This is the name of the computer on which the SMTP server is running. It corresponds to the SMTP host field in the SMTP/POP3 login dialog.

  • pop3_host This is the name of the computer on which the POP host is running. It is commonly the same as the SMTP host. It corresponds to the POP3 host field in the SMTP/POP3 login dialog.

  • pop3_userid This is used to retrieve mail. The POP user ID corresponds to the user ID field in the SMTP/POP3 login dialog. You must obtain a user ID from your POP host administrator.

  • pop3_password This is used to retrieve mail. It corresponds to the password field in the SMTP/POP3 login dialog. If all of these five fields are set, the login dialog is not displayed.

  • Debug When set to YES, displays all SMTP and POP3 commands and responses. This is useful for troubleshooting SMTP/POP support problems. Default is NO.

Sharing SMTP/POP addresses


Sharing SMTP/POP addresses

The database should have its own e-mail account for SQL Remote messages, separate from personal e-mail messages intended for reading. This is because many e-mail readers will collect e-mail in the following manner:

  1. Connect to the POP Host and download all messages.

  2. Delete all messages from POP Host

  3. Disconnect from POP Host.

  4. Read mail from the local file or from memory

This causes a problem, as the e-mail program downloads and deletes all of the SQL Remote e-mail messages as well as personal messages. If you are certain that your e-mail program will not delete unread messages from the POP Host then you may share an e-mail address with the database as long as you take care not to delete or alter the database messages.

These messages are easy to recognize, as they are filled with lines of seemingly random text.


The MAPI message system

The Message Application Programming Interface (MAPI) is used in several popular e-mail systems, such as Microsoft Mail and later versions of Lotus cc:Mail.

For a list of operating systems for which MAPI is supported, see Supported operating systems.

MAPI addresses and user IDs

To use SQL Remote and a MAPI message system, each database participating in the setup requires a MAPI user ID and address. These are distinct identifiers: the MAPI address is the destination of each message, and the MAPI user ID is the name entered by a user when they connect to their mail box.

MAPI message and the e-mail inbox

Although SQL Remote messages may arrive in the same mailbox as e-mail intended for reading, they do not in general show up in your e-mail inbox.

SQL Remote attempts to send application-defined messages, which MAPI identifies and hides when the mailbox is opened. In this way, users can use the same e-mail address and same connection to receive their personal e-mail and their database updates, yet the SQL Remote messages do not interfere with the mail intended for reading.

If a message is routed via the Internet, or if certain security patches are applied to the operating system, the special message type information can be lost. The message then does show up in the recipient's mailbox.

MAPI message control parameters

The MAPI message system uses the following control parameters:

  • Debug When set to YES, displays all MAPI calls and the return codes. This is useful for troubleshooting MAPI support problems. Default is NO.

  • Force_Download (default YES) controls if the MAPI_FORCE_DOWNLOAD flag is set when calling MapiLogon. This might be useful when using remote mail software that dials when this flag is set.

  • IPM_Receive This can be set to YES or NO (default YES). If set to NO, the MAPI link receives IPC messages, which are not visible in the mailbox. If set to YES, the MAPI link receives IPM messages, which are visible in the mailbox, and IPC messages, which are not visible in the mailbox. It is recommended that this value remain at YES to ensure that both IPC and IPM messages are picked up by SQL Remote.

  • IPM_Send This can be set to YES or NO (default NO). If set to YES, the MAPI link sends IPM messages, which are visible in the mailbox. If set to NO, the MAPI link attempts to send IPC messages, which are not visible in the mailbox. If a message is routed via the Internet, or if certain security patches are applied to the operating system, SQL Remote may be unable to send IPC messages.

  • Profile Use the specified Microsoft Exchange profile. You should use this if you are running the Message Agent as a service.


The VIM message system

The Vendor Independent Messaging system (VIM) is used in Lotus Notes and in some releases of Lotus cc:Mail.

To use SQL Remote and a VIM message system, each database participating in the setup requires a VIM user ID and address. These are distinct identifiers: the VIM address is the destination of each message, and the VIM user ID is the name entered by a user when they connect to their mail box.

For a list of operating systems for which VIM is supported, see Supported operating systems.

VIM message control parameters

The VIM message system uses the following control parameters:

  • Path This corresponds to the Path field in the cc:Mail login dialog. It is not applicable to and is ignored under Lotus Notes.

  • Userid This corresponds to the User ID field in the cc:Mail login dialog.

  • Password This corresponds to the Password field in the cc:Mail login dialog. If all of Path, Userid, and Password are set, the login dialog is not displayed.

  • Debug When set to YES, displays all VIM calls and the return codes. This is useful for troubleshooting VIM support problems. Default is NO.

  • Receive_All When set to YES, the Message Agent checks all messages to see if they are SQL Remote messages. When set to NO (the default), the Message Agent looks only for messages of the application-defined type SQLRemoteData. This leads to improved performance in Notes.

    Setting ReceiveAll to YES is useful in setups where the message type is lost, reset, or never set. This includes setups including cc:Mail messages, or over the Internet.

  • Send_VIM_Mail When set to YES, the Message Agent sends messages compatible with Adaptive Server Anywhere releases before 5.5.01, and compatible with cc:Mail. If this is set to YES, you should ensure that Receive_All is set to YES also.


Running the Message Agent

The SQL Remote Message Agent is a key component in SQL Remote replication. The Message Agent handles both the sending and receiving of messages. It carries out the following functions:

  • It processes incoming messages, and applies them in the proper order to the database.

  • It scans the transaction log or stable queue at each publisher database, and translates the log entries into messages for subscribers.

  • It parcels the log entries up into messages no larger than a fixed maximum size (50,000 bytes by default), and sends them to subscribers.

  • It maintains the message tracking information in the system tables, and manages the guaranteed transmission mechanism.

Executable names

On Windows operating systems, the Message Agent for Adaptive Server Enterprise is named ssremote.exe, and the Message Agent for Adaptive Server Anywhere is named dbremote.exe. On UNIX operating systems, the names are ssremote and dbremote, respectively.

The Message Agent for Adaptive Server Enterprise uses a stable queue to hold transactions until they are no longer needed. For more information on the stable queue, see How the Message Agent for Adaptive Server Enterprise works.

Message Agent batch and continuous modes
Connections used by the Message Agent
Replication system recovery procedures
Ensuring consistent Message Agent settings
The Message Agent and replication security
Troubleshooting errors at remote sites


Message Agent batch and continuous modes

The Message Agent can be run in one of two modes:

  • Batch mode In batch mode, the Message Agent starts, receives and sends all messages that can be received and sent, and then shuts down.

    Batch mode is useful at occasionally-connected remote sites, where messages can only be exchanged with the consolidated database when the connection is made: for example, when the remote site dials up to the main network.

  • Continuous mode In continuous mode, the Message Agent periodically sends messages, at times specified in the properties of each remote user. When it is not sending messages, it receives messages as they arrive.

    Continuous mode is useful at consolidated sites, where messages may be coming in and going out at any time, to spread out the workload and to ensure prompt replication.

The options available depend on the send frequency options selected for the remote users. Sending frequency options are described in Selecting a send frequency.

toggle To run the Message Agent in continuous mode

  1. Ensure that every user has a sending frequency specified. The sending frequency is specified by a SEND AT or SEND EVERY option in the GRANT REMOTE statement (Adaptive Server Anywhere) or sp_grant_remote procedure (Adaptive Server Enterprise).

  2. Start the Message Agent without using the -b option.

toggle To run the Message Agent in batch mode

  • Either:

    • Have at least one remote user who has neither a SEND AT nor a SEND EVERY option in their remote properties, or

    • Start the Message Agent using the -b option.


Connections used by the Message Agent

The Message Agent uses a number of connections to the database server. These are:

  • One global connection, alive all the time the Message Agent is running.

  • One connection for scanning the log. This connection is alive during the scan phase only.

  • One connection for executing commands from the log-scanning thread. This connection is alive during the scan phase only.

  • One connection for the stable queue (Adaptive Server Enterprise only). This connection is alive during the scan and send phases.

  • One connection for processing synchronize subscription requests. This connection is alive during the send phase only.

  • One connection for each worker thread. These connections are alive during the receive phase only.


Replication system recovery procedures

SQL Remote replication places new requirements on data recovery practices at consolidated database sites. Standard backup and recovery procedures enable recovery of data from system or media failure. In a replication installation, even if such recovery is achieved, the recovered database can be out of synch with remote databases. This can require a complete resynchronization of remote databases, which can be a formidable task if the installation involves large numbers of databases.

In short, recovery of the consolidated database from a failure at the consolidated site is only part of the task of recovering the entire replication installation.

Protection of the replication system against media failures has two aspects:

  • Backup and log management Solid backup procedures and log management procedures for the consolidated database server are an essential part of recovery plans. Backup procedures protect against media failure on the database device. Using a transaction log mirror protects against media failure on the transaction log device.

    For more information about backup and log management procedures, see the sections Transaction log and backup management and Adaptive Server Enterprise transaction log and backup management.

  • Message Agent configuration The Message Agent command-line options provide ways for you to tune Message Agent behavior to match your backup and recovery requirements.

    Message Agent configuration is discussed in the following pages.

Replicating only backed-up transactions

By default, the Message Agent processes all committed transactions. When the Message Agent is run with the -u option, only transactions that have been backed up by the database backup commands are processed.

For Adaptive Server Anywhere, transaction log backup is carried out using Sybase Central or the dbbackup utility, or off-line copying and renaming of the log file. For Adaptive Server Enterprise, transaction log backup is carried out using the dump transaction statement.

By sending only backed-up transactions, the replication installation is protected against media failure on the transaction log. Maintaining a mirrored transaction log also accomplishes this goal.

The -u option provides additional protection against total site failure, if backups are carried out to another site.


Ensuring consistent Message Agent settings

Some Message Agent settings need to be the same throughout an installation, and so should be set before deployment. This section lists the settings that need to be the same.

  • Maximum message length The maximum message length for SQL Remote messages has a default value of 50K. This is configurable, using the Message Agent -l option. However, the maximum message length must be the same for each Message Agent in the installation, and may be restricted by operating system memory allocation limits.

    Received messages that are longer than the limit are deleted as corrupt messages.

    For details of this setting, see The Message Agent.


The Message Agent and replication security

Messages sent by the SQL Remote Message Agent have a very simple encryption that protects against casual snooping. However, the encryption scheme is not intended to provide full protection against determined efforts to decipher them.


Troubleshooting errors at remote sites

There are obvious obstacles for an administrator who has access only to the consolidated site to troubleshoot errors that occur at remote sites. To assist with this task, you can set up SQL Remote so that portions of the output log from remote sites are delivered to the consolidated site and written to a file. This one file contains logging information from some or all sites in the system.

To set up SQL Remote to collect log information, you must configure both the remote and the consolidated sites.

toggle To configure a remote database to send log information to the consolidated database

  1. Set a link option to send log information when an error is encountered.

    Execute the following command against the remote database:

    SET REMOTE link-name OPTION
PUBLIC.OUTPUT_LOG_SEND_ON_ERROR = 'YES'

    With this option set, any message that starts with the error indicator 'E' causes SQL Remote to send log information to the consolidated site.

    For more information, see SET REMOTE OPTION statement [SQL Remote].

  2. Set a link option to limit the amount of information sent to the consolidated site. This step is optional.

    Execute the following command against the remote database:

    SET REMOTE link-name OPTION
PUBLIC.OUTPUT_LOG_SEND_LIMIT = 'nnn'

    The value of this option is the number of bytes at the tail of the output log (that is, the most recent entries) which are sent to the consolidated site. You can use nnnK to indicate kilobytes. The default setting is '5K'.

    If you supply a value that is too large to fit in the maximum message size, SQL Remote overrides the option value and sends only what will fit in the message.

You can also send log information even in the absence of errors by setting the OUTPUT_LOG_SEND_NOW option to YES. SQL Remote then sends the output log information on the next poll and resets the option to 'NO' after the log is sent.

toggle To configure a consolidated site to receive log information

  • Use either the -ro or the -rt Message Agent option.

    For more information, see The Message Agent.


Tuning Message Agent performance

Who needs to read this section?
If performance is not a problem at your site, you do not need to read this section.

There are several options you can use to tune the performance of the Message Agent. This section describes those options.

Sending messages and receiving messages are two separate processes. The major performance issues for these two processes are different.

  • Replication throughput The major bottleneck for total throughput of SQL Remote sites is generally receiving messages from many remote databases and applying them to the database at the consolidated site. You can control this step by tuning the receive process of the Message Agent at the consolidated site.

  • Replication turnaround The time lag from when data is entered at one site to when it appears at other sites is the turnaround time for replication. You can control this time lag.

Tuning throughput by controlling Message Agent threading
Tuning throughput by caching messages
Tuning incoming message polling
Tuning the message sending process


Tuning throughput by controlling Message Agent threading

It is assumed in this section that you are tuning the performance of a Message Agent that is running in continuous mode at a consolidated site.

Worker threads can be used by the Message Agent to apply incoming messages from remote users. This can improve throughput by allowing messages to be applied in parallel rather than serially.

Setting the number of worker threads

The number of worker threads is set on the Message Agent command line, using the -w option. The following command line starts the Message Agent for Adaptive Server Enterprise with twenty worker threads applying messages:

ssremote -c "eng=..." -w 20

The default is to use no worker threads, so that all messages are applied serially. The maximum number of worker threads is 50.

Performance benefits from worker threads

For the Message Agent for Adaptive Server Anywhere, the performance advantage will be most significant when the server is on a system with a striped drive array.

For Adaptive Server Enterprise, the Message Agent will benefit even more if the Server is used with multiple engines configured.

What messages are applied in parallel

When worker threads are being used, messages from different remote users are applied in parallel. Messages from a single remote user are applied serially. For example, ten messages from a single remote user will be applied by a single worker thread in the correct order.

Deadlock is handled by re-applying the rolled back transaction at a later time.

Reading messages from the message system is single-threaded. Messages are read and the header information is examined (to determine the remote user and the correct order of application) before passing them off to worker threads to be applied.

Building messages and sending messages is single-threaded.

Open Client version

To use multiple worker threads with the Adaptive Server Enterprise Message Agent, you need to be using Open Client version 11.1 or above.

The Message Agent prints a message and then does not use worker threads when pre-11.1 versions are being used. The Open Client version is displayed in the first few lines of the Message Agent output.


Tuning throughput by caching messages

The Message Agent caches incoming messages in a configurable area of memory as it reads them.

Specifying the message cache size

The size of the message cache is specified on the Message Agent command line, using the -m option.

The -m option specifies the maximum amount of memory to be used by the Message Agent for building messages. The allowed size can be specified as n (in bytes), nK, or nM. The default is 2048K (2M).

Example

The following command line starts an Adaptive Server Anywhere Message Agent using twelve Megabytes of memory as a message cache:

dbremote -c "eng=..." -m 12M
How messages are cached

When transactions are large, or messages arrive out of order, they are stored in memory by the Message Agent until the message is to be applied. This caching of messages prevents rereading of out-of-order messages from the message system , which may lower performance on large installations. It is especially important when messages are being read over a WAN (such as Remote Access Services or POP3 through a modem). It also avoids contention between worker threads reading messages (a single threaded task) because the message contents are cached.

When the memory usage specified using the -m option is exceeded, messages are flushed in a least-recently-used fashion.

This option is provided primarily for customers considering a single consolidated database for thousands of remote databases.


Tuning incoming message polling

When running a Message Agent in continuous mode, typically at a consolidated database site, you can control how often it polls for incoming messages, and how "patient" it is in waiting for messages that arrive out of order before requesting that the message be resent. Tuning these aspects of the behavior can have a significant effect on performance in some circumstances.

Issues to consider

The issues to consider when tuning the message-receiving process are similar to those when tuning the message-sending process.

  • Regular messages Your choices dictate how often the Message Agent polls for incoming messages from remote databases.

  • Resend requests You can control how many polls to wait until an out-of-order message arrives, before requesting that it be resent.

  • Processing incoming messages If your polling period for incoming messages is too long, compared to the frequency with which messages are arriving, you could end up with messages sitting in the queue, waiting to be processed. If your polling period is too short, you will waste resources polling when no messages are in the queue.

For more information on the message sending process, see Tuning the message sending process.


Polling interval

By default, a Message Agent running in continuous mode polls one minute after finishing the previous poll, to see whether new messages have arrived. You can configure the polling interval using the -rd option.

The default polling interval from the end of one poll to the start of another is one minute. You can poll more frequently using a value in seconds, as in the following command line:

dbremote -rd 30s

Alternatively, you can poll less frequently, as in the following command line, which polls every five minutes:

dbremote -rd 5

Setting a very small interval may have some detrimental impact on overall system throughput, for the following reasons:

  • Each poll of the mail server (if you are using e-mail) places a load on your message system. Too-frequent polling may affect your message system and produce no benefits.

  • If you do not modify the Message Agent patience before it assumes that an out of sequence message is lost, and requests it be sent again, you can flood your system with resend requests.

In general, you should not use a very small polling interval unless you have a specific reason for requiring a very quick response time for messages.

Setting larger intervals may provide a better overall throughput of messages in your system, at the cost of waiting somewhat longer for each message to be applied. In many SQL Remote installations, optimizing turnaround time is not the primary concern.


Requesting resends

If, when the Message Agent polls for incoming messages, one message is missing from a sequence, the Message Agent does not immediately request that the message be resent. Instead, it has a default patience of one poll.

If the next message expected is number 6 and message 7 is found, the Message Agent takes no action until the next poll. Then, if no new message for that user is found, it issues a resend request.

You can change the number of polls for which the Message Agent waits before sending a request using the -rp option. This option is often used in conjunction with the -rd option that sets the polling interval.

For example, if you have a very small polling interval, and a message system that does not preserver the order in which messages arrive, it may be very common for out-of-sync messages to arrive only after two or three polls have been completed. In such a case, you should instruct the Message Agent to be more patient before sending a resend request, by increasing the -rp value. If you do not do this, a large number of unnecessary resend requests may be sent.


Example

Suppose there are two remote users, named user1 and user2, and suppose the Message Agent command line is as follows:

dbremote -rd 30s -rp 3

In the following sequence of operations, messages are marked as userX.n so that user1.5 is the sixth message from user1. The Message Agent expects messages to start at number 1 for both users.

At time 0 seconds:

  1. The Message Agent reads user1.1, user2.4

  2. The Message Agent applies user1.1

  3. The Message Agent patience is now user1: N/A, user2: 3, as an out of sequence message has arrived from user 2.

At time 30 seconds:

  1. The Message Agent reads: no new messages

  2. The Message Agent applies: none

  3. The Message Agent patience is now user1: N/A, user2: 2

At time 60 seconds:

  1. The Message Agent reads: user1.3

  2. The Message Agent applies: no new messages

  3. The Message Agent patience: user1: 3, user2: 1

At time 90 seconds:

  1. The Message Agent reads: user1.4

  2. The Message Agent applies: none

  3. The Message Agent patience user1: 3, user2: 0

  4. The Message Agent issues resend to user2.

When a user receives a new message, it resets the Message Agent patience even if that message is not the one expected.


Tuning the message sending process

The turnaround time for replication is governed by how often each sites sends messages and how often each site polls for incoming messages. To achieve a small time lag between data entry and data replication, you can set a small value for the -sd Message Agent option, which controls the frequency for polling to see if more data needs to be sent.

Issues to consider

The issues to consider when tuning the message-sending process are similar to those when tuning the incoming-message polling frequency:

  • Regular messages Your choices dictate how often updates are sent to remote databases.

  • Resend requests When a remote user requests that a message be resent, the Message Agent needs to take special action that can interrupt regular message sending. You can control the urgency with which these resend requests are processed.

  • Number and size of messages If you send messages very frequently, there is more chance of small messages being sent. Sending messages less frequently allows more instructions to be grouped in a single message. If a large number of small messages is a concern for your message system, then you may have to avoid using very small polling periods.

For more information on tuning polling for the incoming-messages, see Tuning incoming message polling.


Polling interval

You control the interval to wait between polls for more data from the transaction log to send using the -sd option, which has a default of one minute. The following example sets the polling interval to 30 seconds:

dbremote -sd 30s ...

Alternatively, you can poll less frequently, as in the following command line, which polls every five minutes:

dbremote -sd 5

Setting a very small interval may have some detrimental impact on overall system throughput, for the following reasons:

  • Too-frequent polling produces many short messages. If the message load places a strain on your message system, throughput could be affected.

Setting larger intervals may provide a better overall throughput of messages in your system, at the cost of waiting somewhat longer for each message to be applied. In many SQL Remote installations, optimizing turnaround time is not the primary concern.


Resending messages

When a user requests that a message be resent, the message has to be retrieved from early in the transaction log. Going back in the transaction log to retrieve this message and send it causes the Message Agent to interrupt the regular sending process. If you are tuning your SQL Remote installation for optimum performance, you must balance the urgency of sending requests for resent messages with the priority of processing regular messages.

The -ru option controls the urgency of the resend requests. The value for the parameter is a time in minutes (or in other units if you add s or h to the end of the number), with a default of zero.

To help the Message Agent delay processing resend requests until more have arrived before interrupting the regular message sending activity, set this option to a longer time.

The following command line waits one hour until processing a resend request.

dbremote -ru 1h ...

If you do not specify the -ru option, then a default value is picked by the Message Agent, based on the send interval of the users that have requested that data be resent. The elapsed time between receiving a resend request for a user and rescanning the log does not exceed half of the send interval for that user.


Encoding and compressing messages

As messages pass through e-mail and other message systems, there is a danger of them becoming corrupted. For example, some message systems use certain characters or character combinations as control characters.

Message size affects the efficiency with which messages pass through a system. Compressed messages can be processed more efficiently by a message system than uncompressed messages. On the other hand, carrying out compression can itself take a significant amount of time.

SQL Remote encoding and compression

SQL Remote has a message encoding and compression scheme built in to the Message Agent. The scheme provides the following features:

  • Compatibility The system can be set up to be compatible with previous versions of the software.

  • Compression You can select a level of compression for your messages.

  • Encoding SQL Remote encodes messages to ensure that they pass through message systems uncorrupted. The encoding scheme can be customized to provide extra features.

Settings for compatibility

To be compatible with previous versions of the software, you should set the database option COMPRESSION to be -1 (minus one) at each database running the Version 6 software. This setting ensures that messages are sent out in a format compatible with older versions of the software.

Upgrading SQL Remote

If you upgrade the consolidated database Message Agent first, you should set its COMPRESSION database option to -1. As each remote site in your replication system is upgraded to Version 6, you can change its setting of the COMPRESSION option to a value between 0 (no compression) and 9 (maximum compression). This allows you to take advantage of compression features on messages being sent to the consolidated database. Once all remote sites are upgraded, you can set the consolidated site Message Agent COMPRESSION option to a value other than -1.

In addition, setting COMPRESSION to a value other than -1 allows you to take advantage of the Version 6 message encoding improvements.


The encoding scheme

The default message-encoding behavior of SQL Remote is as follows:

  • For message systems that can use binary message formats, no encoding is carried out.

  • Some message systems, including SMTP, VIM, and MAPI, require text-based message formats. For these systems, an encoding DLL (dbencod.dll for Adaptive Server Anywhere and ssencod.dll for Adaptive Server Enterprise) translates messages into a text format before sending. The message format is unencoded at the receiving end using the same DLL.

  • You can instruct SQL Remote to use a custom encoding scheme. The tools for building a custom encoding scheme are described in the following section.

  • If the COMPRESSION database option is set to -1, then a Version 5 compatible encoding is carried out for all message systems.


Creating custom encoding schemes

You can implement a custom encoding scheme by building a custom encoding DLL. You could use this DLL to apply special features required for a particular messages system, or to collect statistics, such as how many messages or how many bytes were sent to each user.

The header file dbrmt.h, installed into the h subdirectory of your installation directory, provides an application programming interface for building such a scheme.

To instruct SQL Remote to use your DLL for a particular message system, you must make a registry entry for that system. The registry entry should be made in the following location:

Software
    \Sybase
         \SQL Remote
              \message-system
                     \encode_dll

where message-system is one of the SQL Remote message systems (file, smtp, and so on). You should set this registry entry to the name of your encoding DLL.

Encoding and decoding must be compatible
If you implement a custom encoding, you must make sure that the DLL is present at the receiving end, and that the DLL is in place to decode your messages properly.

Previous Next


The message tracking system

SQL Remote has a message tracking system to ensure that all replicated operations are applied in the correct order, no operations are missed, and no operation is applied twice.

Message system failures may lead to replication messages not reaching their destination, or reaching it in a corrupt state. Also, messages may arrive at their destination in a different order from that in which they were sent. This section describes the SQL Remote system for detecting and correcting message system errors, and for ensuring correct application of messages.

If you are using an e-mail message system, you should confirm that e-mail is working properly between the two machines if SQL Remote messages are not being sent and received properly.

The SQL Remote message tracking system is based on status information maintained in the remoteuser SQL Remote system table. The table is maintained by the Message Agent. The Message Agent at a subscriber database sends confirmation to the publisher database to ensure that remoteuser is maintained properly at each end of the subscription.

For Adaptive Server Anywhere, the remoteuser table is the sys.sysremoteuser system table. For Adaptive Server Enterprise, this is the sr_remoteuser table.


Status information in the remoteuser table

The remoteuser SQL Remote system table contains a row for each subscriber, with status information for messages sent to and received by that subscriber. At the consolidated database, remoteuser contains a row for each remote user. At each remote database, remoteuser contains a single row maintaining information for the consolidated database. (Recall that the consolidated database subscribes to publications from the remote database.)

The remoteuser SQL Remote system table at each end of a subscription is maintained by the Message Agent.


Tracking messages by transaction log offsets

The message-tracking status information takes the form of offsets in the transaction logs of the publisher and subscriber databases. Each COMMIT is marked in the transaction log by a well-defined offset. The order of transactions can be determined by comparing their offset values.

Message ordering

When messages are sent, they are ordered by the offset of the last COMMIT of the preceding message. If a transaction spans several messages, there is a serial number within the transaction to order the messages correctly. The default maximum message size is 50,000 bytes, but you can use the Message Agent -l option to change this setting.

Sending messages

The log_sent column holds the local transaction log offset for the latest message sent to the subscriber. When the Message Agent sends a message, it sets the log_sent value to the offset of the last COMMIT in the message. Once the message has been received and applied at the subscribed database, confirmation is sent back to the publisher. When the publisher Message Agent receives the confirmation, it sets the confirm_sent column for that subscriber with the local transaction log offset. Both log_sent and confirm_sent are offsets in the local database transaction log, and confirm_sent cannot be a later offset than log_sent.

Receiving messages

When the Message Agent at a subscriber database receives and applies a replication update, it updates the log_received column with the offset of the last COMMIT in the message. The log_received column at any subscriber database therefore contains a transaction log offset in the publisher database's transaction log. After the operations have been received and applied, the Message Agent sends confirmation back to the publisher database and also sets the confirm_received value in the local SYSREMOTEUSER table. The confirm_received column at any subscriber database contains a transaction log offset in the publisher database's transaction log.

Subscriptions are two-way

SQL Remote subscriptions are two-way operations: each remote database is a subscriber to publications of the consolidated database and the consolidated database subscribes to a matching publication from each remote database. Therefore, the remoteuser SQL Remote system tables at the consolidated and remote database hold complementary information.

The Message Agent applies transactions and updates the log_received value atomically. If a message contains several transactions, and a failure occurs while a message is being applied, the log_received value corresponds exactly to what has been applied and committed.

Resending messages

The remoteuser SQL Remote table contains two other columns that handle resending messages. The resend_count and rereceive_count columns are retry counts that are incremented when messages get lost or deleted for some reason.

In general, the log_send column has the same value as the log_sent column. However, if the log_send has a value that is greater than log_sent, the Message Agent sends messages to the subscriber immediately on its next run.


Handling of lost or corrupt messages

When messages are received at a subscriber database, the Message Agent applies them in the correct order (determined from the log offsets) and sends confirmation to the publisher. If a message is missing, the Message Agent increments the local value of rereceive_count, and requests that it be resent. Other messages present or en route are not applied.

The request from a subscriber to resend a message increments the resend_count value at the publisher database, and also sets the publisher's log_sent value to the value of confirm_sent. This resetting of the log_sent value causes operations to be resent.

Users cannot reset log_sent
The log_sent value cannot be reset by a user, as it is in a system table.
Message identification

Each message is identified by three values:

  • Its resend_count.

  • The transaction log offset of the last COMMIT in the previous message.

  • A serial number within transactions, for transactions that span messages.

Messages with a resend_count value smaller than rereceive_count are not applied; they are deleted. This ensures that operations are not applied more than once.


Administering SQL Remote for Adaptive Server Anywhere

About this chapter

This chapter details set-up, and management issues for SQL Remote administrators using Adaptive Server Anywhere as a consolidated database.


Running the Message Agent

This section describes how to run the Message Agent for Adaptive Server Anywhere.

For information on features of the Message Agent that are common to Adaptive Server Anywhere and Adaptive Server Enterprise, see SQL Remote Administration.


Starting the Message Agent

The Message Agent has a set of options that control its behavior. The only option that is required for the Message Agent to run is the connection parameters option (-c).

For more information on connection parameters, see Connection parameters.

Verbose keyword | Short form | Argument
DatabaseFile | DBF | string
DatabaseName | DBN | string
DatabaseSwitches | DBS | string
EngineName | ENG | string
Password | PWD | string
Start | Start | string
Userid | UID | string


Running the Message Agent as a service

If you are running the Message Agent in continuous mode (not batch mode) you may wish to keep the Message Agent running all the time that the server is running.

You can do this by running the Message Agent as a Windows service. A service can be configured to keep running even when the current user logs out, and to start as soon as the operating system is started.

For a full description of running programs as services, see Running the Database Server.


The Message Agent and replication security

In the tutorials in the previous chapter, the Message Agent was run using a user ID with DBA permissions. The operations in the messages are carried out from the user ID specified in the Message Agent connection string; by using the user ID DBA, you can be sure that the user has permissions to make all the changes.

In many situations, distributing the DBA user ID and password to all remote database users is an unacceptable practice for security and data privacy reasons. SQL Remote provides a solution that enables the Message Agent to have full access to the database in order to make any changes contained in the messages without creating security problems.

A special permission, REMOTE DBA, has the following properties:

  • No distinct permissions when not connected from the Message Agent A user ID granted REMOTE DBA authority has no extra privileges on any connection apart from the Message Agent. Therefore, even if the user ID and password for a REMOTE DBA user is widely distributed, there is no security problem. As long as the user ID has no permissions beyond CONNECT granted on the database, no one can use this user ID to access data in the database.

  • Full DBA permissions from the Message Agent When connecting from the Message Agent, a user ID with REMOTE DBA authority has full DBA permissions on the database.

Using REMOTE DBA permission

A suggested practice is to grant REMOTE DBA authority at the consolidated database to the publisher and to each remote user. When the remote database is extracted, the remote user becomes the publisher of the remote database, and is granted the same permissions they were granted on the consolidated database, including the REMOTE DBA authority which enables them to use this user ID in the Message Agent connection string. Adopting this procedure means that there are no extra user IDs to administer, and each remote user needs to know only one user ID to connect to the database, whether from the Message Agent (which then has full DBA authority) or from any other client application (in which case the REMOTE DBA authority grants them no extra permissions).

Granting REMOTE DBA permission

You can grant REMOTE DBA permissions to a user ID named dbremote as follows:

GRANT REMOTE DBA
TO dbremote
IDENTIFIED BY dbremote

In Adaptive Server Anywhere, you can add the REMOTE DBA authority to a remote user by checking the appropriate option on the Authorities tab of the remote user's property sheet.


Web Links Browse Collapse Expand PDF Previous Next

SQL Remote User's Guide

Administering SQL Remote for Adaptive Server Anywhere

Error reporting and handling

This section describes how errors are reported and handled by the Message Agent.


Default error handling

The default action taken by the Message Agent when an error occurs is to record the fact in its log output. The Message Agent sends log output to a window or a log file recording its operation. By default, log output is sent to the window only; the -o option sends output to a log file as well.

The Message Agent may print more information in the output log than in the window. The Message Agent log includes the following:

  • Listing of messages applied.

  • Listing of failed SQL statements.

  • Listing of other errors.

UPDATE conflicts are not errors

UPDATE conflicts are not errors, and so are not reported in the Message Agent output.

For more information on the log file, see The Message Agent.


Ignoring errors

There may be exceptional cases where you wish to allow an error encountered by the Message Agent when applying SQL statements to go unreported. This may arise when you know the conditions under which the error occurs and are sure that it does not produce inconsistent data and that its consequences can safely be ignored.

To allow errors to go unreported, you can create a BEFORE trigger on the action that causes the known error. The trigger should signal the REMOTE_STATEMENT_FAILED SQLSTATE (5RW09) or SQLCODE (-288) value.

For example, if you wish to quietly fail INSERT statements on a table that fail because of a missing referenced column, you could create a BEFORE INSERT trigger that signals the REMOTE_STATEMENT_FAILED SQLSTATE when the referenced column does not exist. The INSERT statement fails, but the failure is not reported in the Message Agent log.


Implementing error handling procedures

SQL Remote allows you to carry out some other process in addition to logging a message if an error occurs. The Replication_error database option allows you to specify a stored procedure to be called by the Message Agent when an error occurs. By default no procedure is called.

The procedure must have a single argument of type CHAR, VARCHAR, or LONG VARCHAR. The procedure is called twice: once with the error message and once with the SQL statement that causes the error.

While the option allows you to track and monitor errors in replication, you must still design them out of your setup: this option is not intended to resolve such errors.

For example, the procedure could insert the errors into a table with the current time and remote user ID, and this information can then replicate back to the consolidated database. An application at the consolidated database can create a report or send e-mail to an administrator when errors show up.

For information on setting the REPLICATION_ERROR option, see SQL Remote options.

Example: e-mailing notification of errors


Example: e-mailing notification of errors

You may wish to receive some notification at the consolidated database when the Message Agent encounters errors. This section demonstrates a method to send Email messages to an administrator when an error occurs.

A stored procedure

The stored procedure for this example is called sp_LogReplicationError, and is owned by the user cons. To cause this procedure to be called in the event of an error, set the Replication_error database option using Interactive SQL or Sybase Central:

SET OPTION PUBLIC.Replication_error =
   'cons.sp_LogReplicationError'

The following stored procedure implements this notification:

CREATE PROCEDURE cons.sp_LogReplicationError
   (IN error_text LONG VARCHAR)
BEGIN
   DECLARE current_remote_user CHAR(255);
   SET current_remote_user = CURRENT REMOTE USER;
 // Log the error
   INSERT INTO cons.replication_audit
      ( remoteuser, errormsg)
   VALUES
      ( current_remote_user, error_text);
   COMMIT WORK;
 //Now notify the DBA an error has occurred
   // using email. We only want this information if
 // the error occurred on the consolidated database
   // We want the email to contain the error strings
 // the Message Agent is passing to the procedure
   IF CURRENT PUBLISHER = 'cons' THEN
      CALL sp_notify_DBA( error_text );
   END IF
END;

The stored procedure calls another stored procedure to manage the sending of Email:

CREATE PROCEDURE sp_notify_DBA( in msg long varchar)
BEGIN
   DECLARE rc INTEGER;
   rc=call xp_startmail( mail_user='davidf' );
   //If successful logon to mail
   IF rc=0 THEN
   rc=call xp_sendmail(
         recipient='Doe, John; John, Elton',
         subject='SQL Remote Error',
         "message"=msg);
   //If mail sent successfully, stop
      IF rc=0 THEN
         call xp_stopmail()
      END IF
   END IF
END;
An audit table

An audit table could be defined as follows:

CREATE TABLE replication_audit (
   id       INTEGER DEFAULT AUTOINCREMENT,
   pub      CHAR(30) DEFAULT CURRENT PUBLISHER,
   remoteuser   CHAR(30),
   errormsg   LONG VARCHAR,
   timestamp    DATETIME DEFAULT CURRENT TIMESTAMP,
   PRIMARY KEY (id,pub)
);

The columns have the following meaning:

Column | Description
pub | Current publisher of the database (lets you know at what database it was inserted)
remoteuser | Remote user applying the message (lets you know what database it came from)
errormsg | Error message passed to the Replication_error procedure

Here is a sample insert into the table from the above error:

INSERT INTO cons.replication_audit
   (   id,
      pub,
      remoteuser,
      errormsg,
      "timestamp")
VALUES
   (   1,
      'cons',
      'sales',
      'primary key for table ''reptable'' is not unique (-193)',
      '1997/apr/21 16:03:13.836')
COMMIT WORK

Since Adaptive Server Anywhere supports calling external DLLs from stored procedures you can also design a paging system, instead of using Email.

An example of an error

For example, if a row is inserted at the consolidated using the same primary key as one inserted at the remote, the Message Agent displays the following errors:

Received message from "cons" (0-0000000000-0)

SQL statement failed: (-193) primary key for table 'reptable' is not unique

INSERT INTO cons.reptable( id,text,last_contact )

VALUES (2,'dave','1997/apr/21 16:02:38.325')

COMMIT WORK

The messages that arrived in Doe, John and Elton, John's email each had a subject of SQL Remote Error:

primary key for table 'reptable' is not unique (-193)

INSERT INTO cons.reptable( id,text,last_contact ) VALUES (2,'dave','1997/apr/21 16:02:52.605')


Transaction log and backup management

The importance of good backup practices

Replication depends on access to operations in the transaction log, and access to old transaction logs is sometimes required. This section describes how to set up backup procedures at the consolidated and remote databases to ensure proper access to old transaction logs.

It is crucial to have good backup practices at SQL Remote consolidated database sites. A lost transaction log could easily mean having to re-extract remote users. At the consolidated database site, a transaction log mirror is recommended.

For information on transaction log mirrors and other backup procedure information, see Backup and Data Recovery.

Ensuring access to old transactions

All transaction logs must be guaranteed available until they are no longer needed by the replication system.

In many setups, users of remote databases may receive updates from the office server every day or so. If some messages get lost or deleted, and have to be resent by the message-tracking system, it is possible that changes made several days ago will be required. If a remote user takes a vacation, and messages have been lost in the meantime, changes weeks old may be required. If the transaction log is backed up daily, the log with the changes will no longer be running on the server.

Because the transaction log continually grows in size, space can become a concern. You can use an event handler on transaction log size to rename the log when it reaches a given size. Then you can use the DELETE_OLD_LOGS option to clean up log files that are no longer needed.

For more information about controlling transaction log size, see the BACKUP statement.

Setting the transaction log directory
Backup utility options
Managing old transaction logs
Recovery from database media failure for consolidated databases
Backup procedures at remote databases
Upgrading consolidated databases
Unloading and reloading a database participating in replication


Setting the transaction log directory

When the Message Agent needs to scan transaction logs other than the current log, it looks through all the transaction log files kept in a designated transaction log directory. A setting on the Message Agent command line tells the Message Agent which directory this is.

Example

For example, the following command line tells the Message Agent to look in the directory e:\archive to find old transaction logs. The command must be entered all on one line.

dbremote -c "eng=server_name;uid=DBA;pwd=SQL" e:\archive
Log names are not important

The Message Agent opens all the files in the transaction log directory to determine which files are logs, so the actual names of the log files are not important.

This section describes how you can set up a backup procedure to ensure that such a directory is kept in proper shape.


Backup utility options

The Adaptive Server Anywhere backup utility has several options, accessible through Sybase Central wizard selections or through dbbackup options, that control its behavior.

This section describes two approaches to using the backup utility in SQL Remote consolidated database backups. Backups must ensure that a set of transaction logs suitable for use by the Message Agent is always available.


Using the live directory as the transaction log directory

It is recommended that you use the option to rename and restart the transaction log when backing up the consolidated database and remote database transaction logs. For the dbbackup utility, this is the -r option.

The figure below illustrates a database named consol.db, with a transaction log named consol.log in the same directory. For the sake of simplicity, we consider the log to be in the same directory as the database, although this would not be generally safe practice in a production environment. The directory is named c:\live.

The log files are held in the Live directory.
A backup command line

The following command line backs up the database using the rename and restart option:

dbbackup -r -c "uid=DBA;pwd=SQL" c:\archive

The connection string options would be different for each database.

Effects of the backup

If you back up the transaction log to a directory c:\archive using the rename and restart option, the Backup utility carries out the following tasks:

  1. Backs up the transaction log file, creating a backup file c:\archive\consol.log.

  2. Renames the existing transaction log file to 971201xx.log, where xx are sequential characters ranging from AA to ZZ.

  3. Starts a new transaction log, as consol.log.

After several backups, the live directory contains a set of sequential transaction logs.

The Live directory contains a set of sequential transaction logs.
A Message Agent command line

You can run the Message Agent with access to these log files using the following command line:

dbremote -c "dbn=hq;..." c:\live


Using the backup directory as the transaction log directory

An alternative procedure is to use the backup directory as the transaction log directory.

Again, the figure below illustrates a database named consol.db, with a transaction log named consol.log in the same directory. For the sake of simplicity, we consider the log to be in the same directory as the database, although this would not be generally safe practice in a production environment. The directory is named c:\live.

The log files are held in the Live directory.
A backup command line

The following command line backs up the database using the rename and restart option, and also uses an option to rename the transaction log backup file:

dbbackup -r -k -c "uid=DBA;pwd=SQL" c:\archive

The connection string options would be different for each database.

Effects of the backup

If you back up the transaction log to a directory c:\archive using the rename and restart option and the log renaming option, the Backup utility carries out the following tasks:

  1. Renames the existing transaction log file to 971201xx.log, where xx are sequential characters ranging from AA to ZZ.

  2. Backs up the transaction log file to the backup directory, creating a backup file named 971201xx.log

  3. Starts a new transaction log, as consol.log.

After several backups, the live directory and also the archive directory contain a set of sequential transaction logs.

The Live directory and the Archive directory both contain a set of sequential transaction logs.
A Message Agent command line

You can run the Message Agent with access to these log files using the following command line:

dbremote -c "dbn=hq;..." c:\archive
Old log names different before 8.0.1
Prior to release 8.0.1 of Adaptive Server Anywhere, the old log files were named yymmdd01.log, yymmdd02.log, and so on. The name change was introduced to allow more old logs to be stored. As the Message Agent scans all the files in the specified directory, regardless of their names, the name change should not affect existing applications.

Previous Next


Managing old transaction logs

All transaction logs must be guaranteed available until they are no longer needed by the replication system: at that point, they can be discarded.

The replication system no longer needs the logs when all remote databases have received and successfully applied the messages contained in the log files. Remote databases confirm the successful receipt of messages from the consolidated database, and the confirmation sets a value in the consolidated database SQL Remote tables (see The message tracking system). The old transaction logs at the consolidated database are no longer needed by SQL Remote when this receipt confirmation has been received from all remote databases.

Using the Delete_old_logs option

You can use the Delete_old_logs database option at the consolidated database to manage old transaction logs automatically.

The DELETE_OLD_LOGS database option is set by default to OFF. If it is set to ON, then the old transaction logs are deleted automatically by the Message Agent when they are no longer needed. A log is no longer needed when all subscribers have confirmed receiving all changes recorded in that log file.

You can set the DELETE_OLD_LOGS option either for the PUBLIC group or just for the user contained in the Message Agent connection string.

Example

  • The following statement sets the public DELETE_OLD_LOGS:

SET OPTION PUBLIC.DELETE_OLD_LOGS = 'ON'


Recovery from database media failure for consolidated databases

This section describes how to recover from a media failure on the database device at the consolidated database.

The procedures to follow are easiest to describe if there is only one transaction log file. While this might not be common for consolidated databases, it is described first, followed by a more common but complicated situation with a set of transaction log files.


Recovery with a single transaction log

In this case, we assume that there is a single transaction log file, which has existed since the database was created. Also, we assume previous backups of the database file have been made and are available, for example on tape.

toggle To recover the database

  1. Make a copy of the database and log file.

  2. Restore the database (.db) file, not the log file, from tape into a temporary directory.

  3. Start the database using the existing transaction log and the -a option, to apply the transactions and bring the database file up to date.

  4. Start the database in your normal way. Any new activity will be appended to the current transaction log.

The transaction log operations are applied to the database.
Example

This example illustrates recovery using a mirrored transaction log.

Suppose you have a consolidated database file named consol.db in a directory c:\dbdir, and a transaction log file c:\logdir\consol.log which is mirrored to d:\mirdir\consol.mlg.

toggle To recover from media failure on the C drive

  1. Backup the mirrored transaction log d:\mirdir\consol.mlg.

  2. Replace the failed hardware and re-install all affected software.

  3. Create a temporary directory to perform the recovery in (for example, c:\recover)

  4. Restore the most recent backup of the database file, consol.db, to c:\recover\consol.db.

  5. Copy the mirror transaction log, d:\mirdir\consol.mlg, to the recovery directory with a .log extension, giving c:\recover\consol.log.

  6. Start the database using the following command line:

    dbeng9 -a C:\RECOVER\CONSOL.DB

  7. Shutdown the database server.

  8. Backup the recovered database and transaction log from c:\recover.

  9. Copy the files from c:\recover to the appropriate production directories:

    • Copy c:\recover\consol.db to c:\dbdir\consol.db

    • Copy c:\recover\consol.log to c:\dbdir\consol.lOG, and to d:\mirdir\consol.mlg.

  10. Restart your system normally.


Recovery with multiple transaction logs

If you have a set of transaction logs, the procedure is different. We assume previous backups of the database file have been made and are available, for example on tape.

toggle To recover the database

  1. Make a copy of the database and log file.

  2. Restore the database (.db) file, not the log file, from tape into a temporary directory.

  3. In the temporary directory, start the database, applying the old logs using the -a option, applying the named transaction logs in the correct order.

  4. Start the database using the current transaction log and the -a option, to apply the transactions and bring the database file up to date.

  5. Start the database in your normal way. Any new activity will be appended to the current transaction log.

Example

Suppose you have a consolidated database file named c:\dbdir\cons.db. The transaction log file c:\dbdir\cons.log is mirrored to d:\mirdir\cons.mlg.

Assume that you perform full backups weekly, and you perform incremental backups daily using the following command:

dbbackup -c "uid=DBA;pwd=SQL" -r -t E:\BACKDIR

This command backs up the transaction log cons.log to the directory e:\backdir. The transaction log file is then renamed to datexx.log, where date is the current date and xx is the next set of letters in sequence, and a new transaction log is started. The directory e:\backdir is then backed up using a third-party utility.

In this scenario you would be running the Message Agent with the optional directory to point to the renamed transaction log files. The Message Agent command line would be

dbremote -c "uid=DBA;pwd=SQL" C:\DBDIR

On the third day following the weekly backup the database file gets corrupted because of a bad disk block.

toggle To recover from media failure on the C drive

  1. Backup the mirrored transaction log d:\mirdir\cons.mlg.

  2. Create a temporary directory to perform the recovery in. We will call it c:\recover.

  3. Restore the most recent backup of the database file, cons.db to c:\recover\cons.db.

  4. Apply the renamed transaction logs in order, as follows

    dbeng9 -a C:\DBDIR\date00.LOG C:\RECOVER\CONS.DB
dbeng9 -a C:\DBDIR\date01.LOG C:\RECOVER\CONS.DB

  5. Copy the current transaction log, c:\dbdir\cons.log to the recovery directory, giving c:\recover\cons.log.

  6. Start the database using the following command:

    dbeng9 C:\RECOVER\CONS.DB

  7. Shutdown the database server.

  8. Backup the recovered database and transaction log from c:\recover.

  9. Copy the files from c:\recover to the appropriate production directories.

    • Copy c:\recover\cons.db to c:\dbdir\cons.db.

    • Copy c:\recover\cons.log to c:\dbdir\cons.log, and to d:\mirdir\cons.mlg.

  10. Restart your system as normal.


Backup procedures at remote databases

Backup procedures are not as crucial at remote databases as at the consolidated database. You may choose to rely on replication to the consolidated database as a data backup method. In the event of a media failure, the remote database would have to be re-extracted from the consolidated database, and any operations that have not been replicated would be lost. (You could use the log translation utility to attempt to recover lost operations.)

Even if you do choose to rely on replication to protect remote database data, backups still need to be done periodically at remote databases to prevent the transaction log from growing too large. You should use the same option (rename and restart the log) as at the consolidated database, running the Message Agent so that it has access to the renamed log files. If you set the DELETE_OLD_LOGS option to ON at the remote database, the old log files will be deleted automatically by the Message Agent when they are no longer needed.

Automatic transaction log renaming

You can use the -x Message Agent option to eliminate the need to rename the transaction log on the remote computer when the database server is shut down. The -x option renames transaction log after it has been scanned for outgoing messages.


Upgrading consolidated databases

This section describes issues in upgrading a consolidated database in a SQL Remote environment. The same considerations apply to Adaptive Server Anywhere databases that are primary sites in a Sybase Replication Server installation.

Installing new software does not always make new features available. In many cases, new features require the Upgrade utility to be run on databases. The Upgrade utility adds any information to the system catalog required for new features to be available. When you run the Upgrade utility, it tells you to archive the transaction log. The reason for this is that a new transaction log is created by the Upgrade utility, with a new file format.

When using SQL Remote or Replication Server, the transaction log must be kept for the Message Agent and the Replication Agent, respectively. After running the Upgrade utility, you should shut down the engine, rename the log, and leave it for the Message Agent to delete. The log should also be archived for backup purposes.

For information on the Upgrade utility, see The Upgrade utility.


Unloading and reloading a database participating in replication

If a database is participating in replication, particular care needs to be taken if you wish to unload and reload the databases.

For instructions for unloading and reloading a database in Upgrading the database file format. The instructions in that section apply to databases involved in SQL Remote replication.

This section describes a manual way of unloading and reloading a database, and is provided in case there are special circumstances that make the use of the more automated procedure referenced above impossible, such as a schema or other significant database change.

Replication is based on the transaction log. When a database is unloaded and reloaded, the old transaction log is no longer available. For this reason, good backup practices are especially important when participating in replication.

toggle To unload and reload a consolidated database (manual)

  1. Shut down the existing database.

  2. Perform a full off-line backup by copying the database and transaction log files to a secure location.

  3. Run the dbtran utility to display the starting offset and ending offset of the database's current transaction log file. Note the ending offset for later use.

  4. Rename the current transaction log file so that it is not modified during the unload process, and place this file in the off-line directory.

  5. Start the existing database.

  6. Unload the database.

  7. Shut down the existing database. This database and any log file created in this and the previous step is no longer needed.

  8. Initialize a new database.

  9. Reload the data into the new database.

  10. Shut down the new database.

  11. Erase the current transaction log file for the new database.

  12. Use dblog on the new database with the ending offset noted in step 3 as the -z option, and also set the relative offset to zero.

    dblog -x 0 -z 137829 database-name.db

  13. When you run the Message Agent, provide it with the location of the original off-line directory on its command line.


Using passthrough mode

The publisher of the consolidated database can directly intervene at remote sites using a passthrough mode, which enables standard SQL statements to be passed through to a remote site. By default, passthrough mode statements are executed at the local (consolidated) database as well, but an optional keyword prevents the statements from being executed locally.

Caution Always test your passthrough operations on a test database with a remote database subscribed. Never run untested passthrough scripts against a production database.
Starting and stopping passthrough

Passthrough mode is started and stopped using the PASSTHROUGH statement. Any statement entered between the starting PASSTHROUGH statement and the PASSTHROUGH STOP statement which terminates passthrough mode is checked for syntax errors, executed at the current database, and also passed to the identified subscriber and executed at the subscriber database. We can call the statements between a starting and stopping passthrough statement a passthrough session.

The following statement starts a passthrough session which passes the statements to a list of two named subscribers, without being executed at the local database:

PASSTHROUGH ONLY
FOR userid_1, userid_2;
Directing passthrough statements

The following statement starts a passthrough session that passes the statements to all subscribers to the specified publication:

PASSTHROUGH ONLY
FOR SUBSCRIPTION TO [owner].pubname [ ( string ) ] ;

Passthrough mode is additive. In the following example, statement_1 is sent to user_1, and statement_2 is sent to both user_1 and user_2.

PASSTHROUGH ONLY FOR user_1 ;
statement_1 ;
PASSTHROUGH ONLY FOR user_2 ;
statement_2 ;

The following statement terminates a passthrough session:

PASSTHROUGH STOP ;

PASSTHROUGH STOP terminates passthrough mode for all remote users.

Order of application of passthrough statements

Passthrough statements are replicated in sequence with normal replication messages, in the order in which the statements are recorded in the log.

Passthrough is commonly used to send data definition language statements. In this case, replicated DML statements use the before schema before the passthrough and the after schema following the passthrough.

Notes on using passthrough mode

  • You should always test your passthrough operations on a test database with a remote database subscribed. You should never run untested passthrough scripts against a production database.

  • You should always qualify object names with the owner name. PASSTHROUGH statements are not executed at remote databases from the same user ID. Consequently, object names without the owner name qualifier may not be resolved correctly.


Uses and limitations of passthrough mode

Passthrough mode is a powerful tool, and should be used with care. Some statements, especially data definition statements, could cause a running SQL Remote setup to come tumbling down. SQL Remote relies on each database in a setup having the same objects: if a table is altered at some sites but not at others, attempts to replicate data changes will fail.

Also, it is important to remember that in the default setting passthrough mode also executes statements at the local database. To send statements to a remote database without executing them locally you must supply the ONLY keyword. When a passthrough session contains calls to stored procedures, the procedures must exist in the server that is issuing the passthrough commands, even if they are not being executed locally at the server. The following set of statements drops a table not only at a remote database, but also at the consolidated database.

-- Drop a table at the remote database
-- and at the local database
PASSTHROUGH TO Joe_Remote ;
DROP TABLE CrucialData ;
PASSTHROUGH STOP ;

The syntax to drop a table at the remote database only is as follows:

-- Drop a table at the remote database only
PASSTHROUGH ONLY TO Joe_Remote ;
DROP TABLE CrucialData ;
PASSTHROUGH STOP ;

The following are tasks that can be carried out on a running SQL Remote setup:

  • Add new users.

  • Resynchronize users.

  • Drop users from the setup.

  • Change the address, message type, or frequency for a remote user.

  • Add a column to a table.

Many other schema changes are likely to cause serious problems if executed on a running SQL Remote setup.

Passthrough works on only one level of a hierarchy

In a multi-tier SQL Remote installation, it becomes important that passthrough statements work on the level of databases immediately beneath the current level. In a multi-tier installation, passthrough statements must be entered at each consolidated database, for the level beneath it.


Operations not replicated in passthrough mode

There are special considerations for some statements in passthrough mode.

Calling procedures

When a stored procedure is called in passthrough mode using a CALL or EXEC statement, the CALL statement itself is replicated and none of the statements inside the procedure are replicated. It is assumed that the procedure on the replicate side has the correct effect.

Control of flow statements and cursor operations

Control-flow statements such as IF and LOOP, as well as any cursor operations, are not replicated in passthrough mode. Any statements within the loop or control structure are replicated.

Operations on cursors are not replicated. Inserting rows through a cursor, updating rows in a cursor, or deleting rows through a cursor are not replicated in passthrough mode.

Static embedded SQL SET OPTION statements are not replicated. The following statement is not replicated in passthrough mode:

EXEC SQL SET OPTION . . .

However, the following dynamic SQL statement is replicated:

EXEC SQL EXECUTE IMMEDIATE "SET OPTION . . . "
Batches

Batch statements ( a group of statements surrounded with a BEGIN and END) are not replicated in passthrough mode. You receive an error message if you try to use batch statements in passthrough mode.


Administering SQL Remote for Adaptive Server Enterprise

About this chapter

This chapter details setup and management issues for SQL Remote administrators using Adaptive Server Enterprise as the server for the consolidated database.

How the Message Agent for Adaptive Server Enterprise works
Running the Message Agent
Error reporting and handling
Adaptive Server Enterprise transaction log and backup management
Making schema changes
Using passthrough mode


How the Message Agent for Adaptive Server Enterprise works

This section describes how the Message Agent for Adaptive Server Enterprise works. There are some significant differences between how the Message Agent for Adaptive Server Enterprise and the Message Agent for Adaptive Server Anywhere operate, which accommodate the different roles of the two servers.

For information on features of the Message Agent that are common to Adaptive Server Anywhere and Adaptive Server Enterprise, see Running the Message Agent.

Message Agent is ssremote

The Message Agent for Adaptive Server Enterprise is the following executable:

  • On Windows operating systems, the Message Agent is ssremote.exe

  • On UNIX operating systems, the Message Agent is ssremote.


Scanning the transaction log

The Message Agent scans the Adaptive Server Enterprise transaction log in order to collect transactions to be sent to remote databases. It stores these transactions in a stable queue.

For more information about the stable queue, see The stable queue. For more information about how the Message Agent uses the stable queue, see Message Agent operation phases.

The SQL Remote Message Agent uses the same transaction log scanning interface as the Adaptive Server Enterprise Log Transfer manager (LTM). Adaptive Server Enterprise maintains a truncation point, which is an identifier for the oldest page in the transaction log needed by the replication system.

The SQL Remote Message Agent sets the truncation point as soon as transactions are scanned from the transaction log and committed in the stable queue. This allows the dump transaction command to reclaim space in the transaction log as soon as possible. The Message Agent does not wait until confirmation is received from remote databases before setting the truncation point.

Message Agent must be run to reclaim log space
The Message Agent must be run frequently enough to prevent the transaction log from running out of space. The dump transaction command does not reclaim space from pages after the truncation point.
Replication Server and SQL Remote

Using SQL Remote on an Adaptive Server Enterprise database participating in a Replication Server setup may involve other considerations. If your database has a replication agent (LTM) running against it, then you need to use the SQL Remote Open Server as an additional component. Adaptive Server Enterprise databases have replication agents running against them in the following circumstances:

  • The database is participating in a Replication Server setup as a primary database, or

  • The database is participating in a Replication Server setup and is using asynchronous procedure calls.

If the database is participating in a Replication Server setup as a replicate site, and no asynchronous procedure calls are being used, there is no need for the SQL Remote Open Server.

For more information about the SQL Remote Open Server, see Using SQL Remote with Replication Server.


The stable queue

The Message Agent for Adaptive Server Enterprise uses a stable queue to hold transactions until they can be deleted. A stable queue is a pair of database tables that hold messages that may still be needed by the replication system.

SQL Remote for Adaptive Server Anywhere does not use a stable queue.

Stable queue not identical to Replication Server stable queue
Sybase Replication Server also uses stable queues as storage areas for replication messages. The Replication Server and SQL Remote stable queues perform similar functions, but are not the same thing.
Stable queue location

The stable queue may be kept in the same database as the tables being replicated, or in a different database. Keeping the stable queue in a separate database complicates the backup and recovery plan, but can improve performance by putting the stable queue workload on separate devices and/or a separate Adaptive Server Enterprise server.

Do not modify the stable queue directly
The stable queue is maintained by and for the Message Agent. You should not modify the stable queue directly.

The stable queue consists of a set of tables that contain information on all transactions scanned from the transaction log,

For a description of each of the columns of these tables, see Stable Queue tables.


Message Agent operation phases

The Message Agent has the following phases of execution:

  • Receiving messages During this phase, the Message Agent receives incoming messages and applies them to the Adaptive Server Enterprise server. The Message Agent processes incoming messages.

  • Populating the stable queue During this phase the Message Agent scans the Adaptive Server Enterprise transaction log into the stable queue. The Message Agent populates the Stable Queue.

  • Sending messages During this phase, the Message Agent builds outgoing messages from the stable queue. The Message Agent delivers messages from the Stable Queue.

    The transactions remain in the stable queue until confirmation has been received from all remote databases. When confirmation is received, the transactions are automatically removed from the stable queue by the Message Agent.

The Message Agent does not scan the transaction log of the database in which the stable queue resides if it is different from the database with SQL Remote system tables.

For information on running multiple copies of the Message Agent to carry out these tasks, see Running multiple Message Agents.


Running the Message Agent

This section describes how to run the Message Agent for Adaptive Server Enterprise. For information on features of the Message Agent that are common to Adaptive Server Anywhere and Adaptive Server Enterprise, see Running the Message Agent.


The Message Agent and replication security

In the tutorials earlier in this book, the Message Agent was run using a user ID with system administrator permissions. The operations in the messages are carried out from the user ID specified in the Message Agent connection string; by using a system administrator user ID, you can be sure that the user has permissions to make all the changes.

In practice, you will not use such a user ID, but the Message Agent needs to run using a user ID with replication role. You can grant replication role with the following statement:

sp_role 'grant', replication_role, user_name

The user for the Message Agent must have insert, update and delete permissions on all replicated tables, in order to apply the changes. Also, the replication error procedure must be created under the Message Agent user ID.

When you setup your Adaptive Server Enterprise database, the scripts ssremote.sql and squeue.sql must be run under the same user name you use for the Message Agent.

For setup instructions, see Setting Up SQL Remote.

To hide the user password for the Message Agent user ID, you can store the ssremote command-line options in a file, and use ssremote with the @data parameter. You can use file system security to prevent unauthorized access to the file.


Running multiple Message Agents

The three phases of Message Agent operation are described in the section Message Agent operation phases. To summarize, these phases are:

  • Receiving messages.

  • Scanning the transaction log.

  • Sending messages.

You may wish to run separate copies of the Message Agent to carry out these different phases. You can specify which phases a given Message Agent is to execute on the Message Agent command line.

Specifying which phases to execute

The command-line options are as follows:

  • Receive The -r command-line option instructs the Message Agent to receive messages while it is running. To cause the Message Agent to shut down after receiving available messages, use the -b option in addition to -r.

  • Scan log The -I command-line option instructs the Message Agent to scan the transaction log into the stable queue while it is running.

  • Send The -s command-line option instructs the Message Agent to send messages while it is running.

  • Multiple phases If none of -r, -I, or -s is specified, the Message Agent executes all three phases. Otherwise, only the indicated phases are executed.

There are several circumstances where you may wish to run multiple Message Agents.

  • Ensuring the transaction log does not run out of space It is important that the transaction log not be allowed to become full. For this reason, you must scan the transaction log frequently enough to ensure that all entries required by SQL Remote are placed in the stable queue. Therefore, you may want to run a Message Agent that scans the transaction log continuously, even if you are only receiving and sending messages in batch mode.

  • Mixing operating systems If you wish to use a message link supported under one operating system, you must use a Message Agent on that platform to send and receive messages. You can do this, while running the log scanning on a UNIX machine, by running two copies of the Message Agent.

How Message Agents are synchronized

The operations of two or more Message Agents are synchronized by a table called sr_marker. This table has a single column called marker, of data type datetime.

When the Message Agent wants to wait for transactions to be scanned into the stable queue, it updates sr_marker and waits for it to work its way through the system. The column in sr_queue_state is also called marker, and contains the most recent marker to be scanned from the transaction log.


Web Links Browse Collapse Expand PDF Previous Next

SQL Remote User's Guide

Administering SQL Remote for Adaptive Server Enterprise

Error reporting and handling

This section describes how errors are reported and handled by the Message Agent.


Default error handling

The default action taken by the Message Agent when an error occurs is to record the fact in its log output. The Message Agent sends log output to a window or a log file recording its operation. By default, log output is sent to the window only; the -o command-line option sends output to a log file as well.

The Message Agent may print more information in the output log than in the window. The Message Agent log includes the following:

  • Listing of messages applied.

  • Listing of failed SQL statements.

  • Listing of other errors.

UPDATE conflicts are not errors

UPDATE conflicts are not errors, and so are not reported in the Message Agent output.


Implementing error handling procedures

SQL Remote allows you to carry out some other process in addition to logging a message if an error occurs. The REPLICATION_ERROR database option allows you to specify a stored procedure to be executed by the Message Agent when an error occurs. By default no procedure is executed .

The procedure must have a single argument of type CHAR or VARCHAR. The procedure is called with any error messages and with the SQL statement that causes the error.

While the option allows you to track and monitor errors in replication, you must still design them out of your setup: this option is not intended to resolve such errors.

For example, the procedure could insert the errors into a table with the current time and remote user ID, and this information can then replicate back to the consolidated database. An application at the consolidated database can create a report or send e-mail to an administrator when errors show up.

For information on setting the REPLICATION_ERROR option, see SQL Remote options.


Adaptive Server Enterprise transaction log and backup management

You must protect against losing transactions that have been replicated to remote databases. If transactions are lost that have already been replicated to remote databases, the remote databases will be inconsistent with the consolidated database. In this situation, you may have to re-extract all remote databases.


Protecting against media failure on the transaction log

Media failure on the transaction log can cause committed transactions to be lost. If the transaction log has been scanned and these transactions have already been sent to subscriber databases, then the subscribing databases contain transactions that are lost from the publishing database, and the databases are in an inconsistent state.

Why the transaction log is needed

The transaction log is needed, even after the entries have been scanned into the stable queue, to guard against media failure on the database file. If the database is lost, it must be recovered to a point that includes every transaction that may have been sent to remote databases.

This recovery is done by restoring a database dump and loading transaction dumps to bring the database up to date. The last transaction dump restored is the dump of the active transaction log at the time of the failure.

Protecting against transaction log loss

There are two ways of protecting against inconsistency arising from media failure on the transaction log:

  • Mirror the transaction log When a device is mirrored, all writes to the device are copied to a separate physical device.

  • Only replicate backed-up transactions There is a command-line option for the Message Agent that prevents it from sending transactions until they are backed up.

Mirroring the transaction log

The only way to protect against media failure on the transaction log is by mirroring the transaction log.

Disk mirroring can provide nonstop recovery in the event of media failure. The disk mirror command causes an Adaptive Server Enterprise database device to be duplicated—that is, all writes to the device are copied to a separate physical device. If one of the devices fails, the other contains an up-to-date copy of all transactions.

For information on disk mirroring in Adaptive Server Enterprise, see the chapter "Mirroring Database Devices", in the Adaptive Server Enterprise System Administration Guide.

Replicating only backed-up transactions

The Message Agent also provides a command-line option (-u) that only sends transactions that have been backup up. In Adaptive Server Enterprise, this means transactions complete before the latest dump database command or dump transaction command.

Choosing an approach

The goal of the strategy is to reduce the possibility of requiring re-extraction of remote databases to an acceptable level. In large setups, the possibility must be as close to zero as possible, as the cost of re-extraction (in terms of down time) is very high.

  • The Message Agent -u command-line option can be used instead of transaction log mirroring when recovery of all transactions in a consolidated database is not needed and mirroring is considered too expensive. This may be true in small setups or setups where there are no local users on the consolidated database.

  • The Message Agent -u command-line option can also be used in addition to mirroring to provide additional protection against total site failure or double media failure.


Stable queue recovery issues

Keeping the stable queue in a separate database complicates backup and recovery, as consistent versions of the two databases have to be recovered.

Normal recovery automatically restores the two databases to a consistent state, but recovery from media failure takes some care. When restoring database dumps and transaction dumps, it is important to recover the stable queue to a consistent point.

Two procedures in the stable store database are provided to help with recovery from media failure:

  • sp_queue_dump_database This procedure is called whenever a dump database is scanned from the transaction log.

  • sp_queue_dump_transaction This procedure is called whenever a dump transaction is scanned from the transaction log.

You can modify these stored procedures to issue dump database and dump transaction commands in the stable store database.


Transaction log management

The Adaptive Server Enterprise log transfer interface allows the Message Agent to scan the Adaptive Server Enterprise transaction log. When this interface is being used, it sets a truncation point in the transaction log. The truncation point prevents Adaptive Server Enterprise from re-using pages in the transaction log before they have been scanned by SSREMOTE. For this reason, DUMP TRANSACTION will not necessarily release transaction log pages that are before the oldest open transaction. DUMP TRANSACTION will not release transaction log pages beyond the "truncation point".

Initializing the truncation point

The SQL Remote setup script (ssremote.sql) initializes the truncation point with the following command

dbcc settrunc( 'ltm', 'valid' ).

The truncation point can be reset with the following command

dbcc settrunc( 'ltm', 'ignore' ).

This command tells Adaptive Server Enterprise to ignore the truncation point, allowing transaction log pages beyond the truncation point to be released for reuse. You should only use this command when you are no longer interested in SQL Remote replication with the database and you want to be able to reclaim space in the transaction device with DUMP TRANSACTION commands. Continuing to run SQL Remote after ignoring the truncation point will fail to replicate any transactions that were in transaction log pages that were not scanned by the Message Agent and were freed by DUMP TRANSACTION.


Making schema changes

Schema changes to tables being replicated by SQL Remote must be made on a quiet system. A quiet system means the following:

  • No transactions being replicated There can be no transactions being replicated that modify the tables that are to be altered. All transactions that modify tables being altered must be scanned from the transaction log into the stable queue before the schema is altered. This is performed by running the Message Agent normally, or using the -I -b options. After the Message Agent completes, you can make the schema change.

  • Message Agent The Message Agent must be shut down when the schema change is being made.

  • SQL Remote Open Server If you are using the SQL Remote Open Server, it must be shut down when the schema change is being made.

Schema changes include changes to publications, such as adding articles or modifying articles. However, creating or dropping subscriptions, and adding or removing remote users do not need to be done on a quiet system.

In the Adaptive Server Enterprise transaction log, there is no information recording table structure changes: the SQL Remote log scanning process gets the table structure from the Adaptive Server Enterprise system tables. Consequently, the Message Agent cannot scan an operation from the transaction log that happened against the old table structure.

Information stored in the stable queue before the schema change uses the old table definitions and information stored after the schema change uses the new table definitions.

Passthrough mode can be used at the same time as the schema change to make sure that schema changes at remote databases occur in the correct sequence.


Using passthrough mode

The publisher of the consolidated database can directly intervene at remote sites using a passthrough mode, which enables standard SQL statements to be passed through to a remote site.

Determining recipients of passthrough statements

Passthrough destinations are determined by sp_passthrough_user and sp_passthrough_subscription. Executing either of these procedures determines a set of recipients for any subsequent passthrough statements.

Executing either sp_passthrough_user and sp_passthrough_subscription adds to the current list of recipients. The sp_passthrough_stop procedure resets passthrough (that is, resets the list of recipients to be empty).

In Adaptive Server Enterprise, sp_passthrough never executes statements in the consolidated database. Passthrough SQL statements are applied only to remote databases.

Passthrough statements

To cause passthrough SQL statements to replicate, you call sp_passthrough.

Due to the VARCHAR(255) limitation in Adaptive Server Enterprise, you should build a long SQL statement up in pieces. Calls to sp_passthrough_piece will build up a single SQL statement. Calling sp_passthrough with the last piece will cause the built up statement to replicate.

Notes on using passthrough mode

  • You should always test your passthrough operations on a test database with a remote database subscribed. You should never run untested passthrough scripts against a production database.

  • You should always qualify object names with the owner name. PASSTHROUGH statements are not executed at remote databases from the same user ID. Consequently, object names without the owner name qualifier may not be resolved correctly.

Schema modifications


Schema modifications

The Adaptive Server Enterprise log transfer interface does not contain information about the number of columns and data types of the columns in a table. SSREMOTE gets this information directly from the Adaptive Server Enterprise system tables. For this reason, altering a table and then scanning operations that happened before the ALTER TABLE will lead to errors. SSREMOTE must set the "truncation point" beyond all operations on replicated tables before schema changes can be made. Operations on replicated tables need to be prevented between SSREMOTE running and the schema changes being made.


Using SQL Remote with Replication Server

About this chapter

This chapter describes the additional components needed to use SQL Remote on an Adaptive Server Enterprise database that also participates in a Replication Server installation.

When you need to use the SQL Remote Open Server
Architecture for Replication Server/SQL Remote installations
Setting up SQL Remote Open Server
Configuring Replication Server
Other issues


When you need to use the SQL Remote Open Server

The Message Agent for Adaptive Server Enterprise scans the Adaptive Server Enterprise transaction log to populate the stable queue, as described in the section The stable queue). SQL Remote messages are built from the transactions in the stable queue.

The Message Agent uses the same interface to scan the transaction log as the Replication Agent for Adaptive Server Enterprise. This means the Message Agent cannot scan the transaction log of an Enterprise database that is a primary site in a Replication Server setup (or a replicate site that allows asynchronous updates to primary data).

If there is a Replication Agent running against your Adaptive Server Enterprise database, you must use the SQL Remote Open Server as an additional component. In this case, SQL Remote is set up so that Replication Server populates the stable queue. The SQL Remote Message Agent does not scan the transaction log. Instead, the SQL Remote Open Server receives transactions from Replication Server. The transactions are parsed by the SQL Remote Open Server and stored in the SQL Remote stable queue.

This chapter assumes knowledge of Replication Server. For information, see your Replication Server documentation.

Open Server runtime components required
The Open Server runtime components are not included with SQL Remote. You must obtain them separately from Sybase in order to use the SQL Remote Open Server.

Previous Next


Architecture for Replication Server/SQL Remote installations

The arrangement for using a database as a Replication Server primary site and as a SQL Remote database is illustrated in the following diagram. The diagram illustrates a case where the stable queue is held in a different database from the data being replicated. The stable queue may alternatively be held in the same database as the data being replicated. All connections are client/server connections, and so the components may be running on the same or different machines.

The components in a Stable Queue installation.

How the pieces fit together


How the pieces fit together

The SQL Remote Open Server acts as a replicate database in the Replication Server setup, and so replication definitions and subscriptions are required in the Adaptive Server Enterprise database on all tables participating in SQL Remote replication and on several of the SQL Remote system tables.

Contents of the stable queue

All operations are replicated to the SQL Remote Open Server, which stores them in the stable queue. The stable queue does not have copies of the tables being replicated. It parses the inserts, updates, and deletes to build transactions. All transactions are stored in an image column of a single table. These transactions are used by the Message Agent to build SQL Remote messages.

The Message Agent delivers messages from the Stable Queue.
Incoming messages

The Message Agent always applies incoming SQL Remote messages directly to Adaptive Server Enterprise. It does not send operations to Replication Server. Incoming messages are applied directly to the consolidated database regardless of how the stable queue is populated. Conflict resolution is also performed in the same way.

The Message Agent processes incoming messages.
Replication Server and SQL Remote

SQL Remote allows two-way replication between the consolidated database and remote databases. Replication Server is performing one-way replication from the consolidated database to the SQL Remote Open Server. From Replication Server's perspective, transactions that originate in remote SQL Remote databases appear as transactions originating in the consolidated SQL Remote database.

SQL Remote system tables

The SQL Remote Open Server requires information from the SQL Remote system tables concerning publications and subscriptions. The Open Server uses a connection to the Adaptive Server Enterprise database holding that information to retrieve it when it starts.

If the SQL Remote system tables are updated while the Open Server is running, the SQL Remote Open Server needs to receive this information at the correct time. For this reason, some of the SQL Remote system tables need to be marked for replication. This is described in Setting up SQL Remote Open Server.

The SQL Remote Open Server executable

The SQL Remote Open Server is the following executable:

  • On Windows operating systems, the SQL Remote Open Server is ssqueue.exe.

  • On UNIX operating systems, the SQL Remote Open Server is ssqueue.


Setting up SQL Remote Open Server

This section describes how to set up a SQL Remote installation using the SQL Remote Open Server. The procedure depends on whether the SQL Remote stable queue is being kept in a separate Adaptive Server Enterprise database from the tables being replicated or in the same Adaptive Server Enterprise database.

For more information about stable queue location, see The stable queue.

Initial copies of the data

The setup procedure assumes you are using the extraction utility to produce an initial copy of the data in each remote database. You must be sure not to use the Replication Server materialization feature for this purpose.

The procedure for setting up SQL Remote Open Server has two stages:

  • Prepare a SQL Remote setup This stage depends on whether you have an existing SQL Remote installation or not.

  • Add the SQL Remote Open Server to the setup This stage is the same regardless of previous installations.

toggle To prepare your SQL Remote setup, if you have an existing SQL Remote installation

  1. On a quiet primary database, use the Message Agent to scan any remaining transactions into the stable queue.

    A quiet database is one where neither the Message Agent nor the SQL Remote Open Server is running, and where no transactions are being replicated.

  2. Follow the steps in the section Upgrading SQL Remote for Adaptive Server Enterprise to upgrade your SQL Remote software at the consolidated site.

  3. Invalidate the Message Agent truncation point at the consolidated database using the following command:

    dbcc settrunc( 'ltm', 'ignore' )

  4. At the stable queue database, execute the stored procedure sp_queue_log_transfer_reset.

toggle To prepare your SQL Remote setup, with no existing installation

  1. Set up SQL Remote as described in Setting Up SQL Remote.

  2. Set up your SQL Remote publications and subscriptions at this point. For information on this procedure, see SQL Remote Design for Adaptive Server Enterprise.

  3. Extract the remote databases. For information on this procedure, see Using the extraction utility.

You are now ready to set up the SQL Remote Open Server.

toggle To set up the SQL Remote Open Server

  1. If the SQL Remote stable queue is in a separate database:

    • Set up the stable queue database as a replicate database in a Replication Server setup. This will create the tables and procedures needed by Replication Server, such as rs_lastcommit.

    • Drop the Replication Server connection to the stable queue database.

  2. Add an entry to your interfaces file for the SQL Remote Open Server. The default name used on the SQL Remote Open Server command line is SSQueue.

  3. Start the SQL Remote Open Server.

  4. Create a Replication Server connection to the SQL Remote Open Server. The user ID and password for this connection must match the user ID and password specified on the SQL Remote Open Server command line for the stable queue connection (that is, the -cq option, or -c if -cq is not specified).

    Configure Replication Server now
    You should configure Replication Server for this connection at this point. For a description, see Configuring Replication Server.

  5. Define, activate, and validate Replication Server replication definitions and subscriptions for the SQL Remote tables sr_marker, sr_remoteuser, sr_subscription, and sr_passthrough. The script ssremote.rs is a sample script to perform this task. You will need to edit the server and database names in the script to match your names.

    If the SQL Remote system tables have any data in them, create the replication definitions so that no materialization happens.

    For information on creating replication definitions with no materialization, see the Replication Server Administration Guide. The section in Chapter 10, Managing Subscriptions entitled Bulk Materialization describes how to set up Replication Server for the case where data exists at a remote database.

  6. Define, activate, and validate replication definitions and subscriptions for the tables in your database that need to be replicated by SQL Remote. These must be created without materialization.


Configuring Replication Server

This section describes how to configure Replication Server for use with the SQL Remote Open Server

The Replication Server connection to the SQL Remote Open Server must have several configuration parameters set.

Set the dsi_xact_group_size parameter
Set the dsi_num_threads parameter
Create replication definitions for SQL Remote data
Suspend and restart the connection


Set the dsi_xact_group_size parameter

By default, Replication Server groups multiple transactions into larger transactions. The dsi_xact_group_size parameter controls the maximum size of a grouped transaction.

The dsi_xact_group_size parameter must be set to –1 to disable transaction grouping. Transactions that originate from different remote databases in a SQL Remote setup must not be grouped together.

How to set the parameter

You can set the parameter using the following statement:

CONFIGURE CONNECTION TO  "ssqueue_server"
SET dsi_xact_group_size TO '-1'


Set the dsi_num_threads parameter

The SQL Remote Open Server does not support multiple DSI threads. Replication Server should not be configured to use multiple DSI threads on SQL Remote connections.


Create replication definitions for SQL Remote data

Replication definitions for tables being replicated by SQL Remote must have certain characteristics. This section describes those characteristics.

In some circumstances SQL Remote replicates an UPDATE operation as an INSERT or a DELETE (see Replication of updates). This is referred to as subscription migration in the Replication Server documentation. In order to replicate an UPDATE as an INSERT, SQL Remote requires the full pre-image of the row. This means that Replication Server must specify the values of every column in the WHERE clause of any UPDATE to a table that might need to be replicated as an INSERT.

The simplest way to achieve this is to list all columns in the PRIMARY KEY of the replication definition. This forces Replication Server to include every column in the WHERE clause of every update. REPLICATE MINIMAL COLUMNS can be used on these replication definitions to prevent every column from being listed in the SET clause of the update.

Text and image columns

Replication Server does not accept TEXT or IMAGE columns in the primary key of a replication definition. You should include all the columns except for the TEXT and IMAGE columns in the PRIMARY KEY list of your replication definition, and specify all the TEXT and IMAGE columns in the ALWAYS_REPLICATE clause. You should use REPLICATE ALL COLUMNS, instead of REPLICATE MINIMAL COLUMNS in your replication definition. This forces Replication Server to send the pre-image of the TEXT and IMAGE columns to the SQL Remote Open Server whenever an update occurs.

Using the dsi_sql_data_style data style

Replication Server 11.5 has a new dsi_sql_data_style for SQL Remote. This data style automatically includes all columns in the WHERE clause of every UPDATE. It is not necessary to list all columns in the PRIMARY KEY of the replication definition. A replication definition using REPLICATE MINIMAL COLUMNS prevents Replication Server from keeping the full pre-image of rows being updated, so the SQL Remote dsi_sql_data_style will not work with REPLICATE MINIMAL COLUMNS.


Suspend and restart the connection

After configuring the Replication Server connection to the SQL Remote Open Server, you should suspend and resume the connection so that the parameter settings can take effect. The following commands accomplish this task:

suspend connection to ssqueue_server
go
resume connection to ssqueue_server
go


Other issues

This section lists other issues regarding using SQL Remote with Replication Server.

Running the Message Agent The Message Agent should be run with command-line options to receive and send (-r and -s). This will prevent the Message Agent from attempting to scan the transaction log. If the Message Agent attempts to scan the transaction log while the Replication Agent is running, it will get an error attempting to reserve the "log transfer context".

Procedure calls in SQL Remote Open Server The SQL Remote Open Server passes all procedure calls it receives from Replication Server through to the stable queue database. For example, rs_get_lastcommit and rs_update_lastcommit are executed in the stable queue database.

Coordinated dumps Replication Server provides a mechanism to coordinate database dumps and transaction log dumps between the main database and the stable queue database. The rs_dumpdb and rs_dumptran function strings can be used to perform coordinated dumps of the stable queue database. Please see the Replication Server documentation for more information.

Schema changes If you make any schema changes to a SQL Remote installation, you must do so on a quiet system. This includes shutting down the SQL Remote Open Server.


Utilities and Options Reference

About this chapter

This chapter provides reference material for the SQL Remote utilities and SQL Remote database options.

It also describes client event-hook stored procedures, which can be used to customize the replication process.


The Message Agent

Purpose

To send and apply SQL Remote messages, and to maintain the message tracking system to ensure message delivery.

Syntax

{ dbremote | ssremote } [ options ] [ directory ]

Options
Option | Description
@data | Read options from the specified environment variable or configuration file
–a | Do not apply received transactions
–b | Run in batch mode
–c "keyword=value; ..." | Supply database connection parameters
–cq "keyword=value; ..." | Supply database connection parameters for the stable queue (Adaptive Server Enterprise only)
–dl | Display log messages on screen
–ek key | Specify encryption key
–ep | Prompt for encryption key
–e locale-string | Locale setting (Adaptive Server Enterprise only)
–fq | Full scan of the stable queue when sending messages (Adaptive Server Enterprise only)
–g n | Group transactions consisting of less than n operations.
–I | Scan transactions from the transaction log into the stable queue (Adaptive Server Enterprise only).
–k | Close window on completion
–l length | Maximum message length
–m size | Maximum amount of memory used for building messages
-ml directory | Specify the location of offline mirror logs
–o file | Output messages to file
–os size | Maximum file size for logging output messages
–ot file | Truncate file and log output messages
–p | Do not purge messages
–q | Run with minimized window
–r | Receive messages
–rd minutes | Polling frequency for incoming messages
-ro filename | Log remote output to file
–rp number | Number of receive polls before message is assumed lost
-rt filename | Truncate, and log remote output to file.
–ru time | Waiting period to re-scan log on receipt of a resend.
–s | Send messages
–sd time | Send polling period
–t | Replicate all triggers (Adaptive Server Anywhere only)
–u | Process only backed up transactions
–ud | On UNIX platforms, run as a daemon.
–v | Verbose operation
–w n | Number of worker threads to apply incoming messages (Not NetWare or Windows CE)
–x [ size ] | Rename and restart the transaction log (Adaptive Server Anywhere only).
directory | The directory in which old transaction logs are held (Adaptive Server Anywhere only)
Description

The Message Agent sends and applies messages for SQL Remote replication, and maintains the message tracking system to ensure message delivery.

The name of the Message Agent executable is as follows:

  • dbremote The Message Agent for Adaptive Server Anywhere.

  • ssremote The Message Agent for Adaptive Server Enterprise.

    Deprecated feature
    In the next major release of SQL Anywhere Studio, SQL Remote for Adaptive Server Enterprise will not be present. MobiLink provides a more flexible and scalable solution for data synchronization between Adaptive Server Enterprise and Adaptive Server Anywhere databases.

You can also run the Message Agent from your own application by calling into the DBTools library. For more information, see the file dbrmt.h in the h subdirectory of your SQL Remote installation directory.

For Adaptive Server Anywhere, the user ID in the Message Agent command must have either REMOTE DBA or DBA authority. For Adaptive Server Enterprise, the user ID must have replication role.

The optional directory parameter specifies a directory in which old transaction logs are held, so that the Message Agent has access to events from before the current log was started.

The Message Agent uses a number of connections to the database. For a listing, see Connections used by the Message Agent.

For information on REMOTE DBA authority, see The Message Agent and replication security.

Option details

@data Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

The environment variable may contain any set of options. For example, the first of the following pair of statements sets an environment variable holding a set of options for a database server that starts with a cache size of 4 Mb, receives messages only, and connects to a database named field on a server named myserver. The set statement should be entered all on one line:

set envvar=-m 4096 -r
   -c "eng=myserver;dbn=field;uid=sa;pwd=sysadmin"
ssremote @envvar

The configuration file may contain line breaks, and may contain any set of options. For example, the following command file holds a set of options for a Message Agent that starts with a cache size of 4 Mb, sends messages only, and connects to a database named field on a server named myserver:

-m 4096
-s
-c "eng=myserver;dbn=field;uid=sa;pwd=sysadmin"

If this configuration file is saved as c:\config.txt, it can be used in a command as follows:

ssremote @c:\config.txt

or

dbremote @c:\config.txt

-a Process the received messages (those in the inbox) without applying them to the database. Used together with -v (for verbose output) and -p (so the messages are not purged), this option can help detect problems with incoming messages. Used without -p, this option purges the inbox without applying the messages, which may be useful if a subscription is being restarted.

-b Run in batch mode. In this mode, the Message Agent processes incoming messages, scans the transaction log once and processes outgoing messages, and then stops.

-c "parameter=value; ..." Specify connection parameters. For Adaptive Server Anywhere, if this option is not specified, the environment variable SQLCONNECT is used.

For example, the following statement runs dbremote on a database file named c:Program Files\Sybase\SQL Anywhere 9\asademo.db, connecting with user ID DBA and password SQL:

dbremote -c "uid=DBA;pwd=SQL;dbf=c:\Program Files\Sybase\SQL Anywhere 9\asademo.db"

The Message Agent must be run by a user with REMOTE DBA authority or DBA authority.

For information on REMOTE DBA authority, see The Message Agent and replication security.

The Message Agent for Adaptive Server Anywhere supports the full range of Adaptive Server Anywhere connection parameters. The Message Agent for Adaptive Server Enterprise supports the following connection parameters:

Parameter | Description
UID | Login ID
PWD | Password
DBN | (optional) Database name. If this parameter is not supplied, the connection defaults to the default database for the login ID.
ENG | Adaptive Server Enterprise name.

-cq "parameter=value; ..." Specify connection parameters for the stable queue. This option applies to Adaptive Server Enterprise only. If not supplied, the values default to the -c values.

-dl Display messages in the Message Agent window or at the command prompt and also in the log file if specified.

Specify encryption key (-ek) This option allows you to specify the encryption key for strongly encrypted databases directly at the command prompt. If you have a strongly encrypted database, you must provide the encryption key to use the database or transaction log in any way, including offline transaction logs. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify a key for a strongly encrypted database.

Prompt for encryption key (-ep) This option allows you to specify that you want to be prompted for the encryption key. This option causes a dialog box to appear, in which you enter the encryption key. It provides an extra measure of security by never allowing the encryption key to be seen in clear text. For strongly encrypted databases, you must specify either -ek or -ep, but not both. The command will fail if you do not specify a key for a strongly encrypted database.

-e locale-string This option applies to Adaptive Server Enterprise only. Specify Adaptive Server Enterprise locale information. The locale string has the following format:

"language_name,charset_name[,sort_order]"

By default, the Message Agent uses the default locale, which is defined in the file sybase\locales\locales.dat.

If language_name and charset_name are not supplied, the Message Agent obtains them from Adaptive Server Enterprise. If sort_order is not supplied, the Message Agent uses a binary sort order (sort by byte value).

-fq This option is for use only with Adaptive Server Enterprise. It permits a full scan of the stable queue when sending messages, starting from the oldest confirm_sent value in the sr_remoteuser table.

This feature is intended for occasional use to clean out a large stable queue. If, for example, a single user has not confirmed receipt of a message from a long time ago, the stable queue may be very large. However, by running -fq you can delete entries from more up-to-date users that have been confirmed, even though they are more recent than the cutoff value at which entries are deleted by default.

-g nInstructs the Message Agent to group transactions containing less than n operations together with transactions that follow. The default is twenty operations. Increasing the value of n can speed up processing of incoming messages, by doing less commits. However, it can also cause deadlock and blocking by increasing the size of transactions.

-I Scan transactions from the transaction log into the stable queue. This option is available for Adaptive Server Enterprise only. It is used when you wish to run a separate copy of the Message Agent for scanning the transaction log and for sending and receiving messages.

If none of -r, -I, or -s is specified, the Message Agent executes all three phases. Otherwise, only the indicated phases are executed.

For more information, see Running multiple Message Agents.

-k Close window on completion when used together with the -o parameter.

-l length Specifies the maximum length of each message to be sent, in bytes. Longer transactions are split into more than one message. The default is 50000 bytes and the minimum length is 10000.

Caution The maximum message length must be the same at all sites in an installation.

For platforms with restricted memory allocation, the value must be less than the maximum memory allocation of the operating system.

-m size Specifies a maximum amount of memory to be used by the Message Agent for building messages and caching incoming messages. The allowed size can be specified as n (in bytes), nK, or nM. The default is 2048K (2M).

When all remote databases are receiving unique subsets of the operations being replicated, a separate message for each remote database is built up concurrently. Only one message is built for a group of remote users that are receiving the same operations. When the memory being used exceeds the -m value, messages are sent before reaching their maximum size (as specified by the -l option).

When messages arrive, they are stored in memory by the Message Agent until they are applied. This caching of messages prevents rereading of messages that are out of order from the message system, which may lower performance on large installations. When the memory usage specified using the -m option is exceeded, messages are flushed in a least-recently used fashion.

-ml This option makes it possible for dbremote to delete old mirror log files when either of the following two circumstances occur:

  • the offline mirror log is located in a different directory from the mirror transaction log

  • dbremote is run on a different machine from the remote database server

In a typical setup, the active mirror log and renamed mirror transaction logs are located in the same directory, and dbremote is run on the same machine as the remote database, so this option is not required and old mirror log files are automatically deleted. Transaction logs in this directory are only affected if the DELETE_OLD_LOGS database option is set to ON or DELAY.

-o Append output to a log file. Default is to send output to the screen.

-os Specifies the maximum file size for logging output messages. The allowed size can be specified as n (bytes), n K (Kb), or n M (Mb). By default there is no limit, and the minimum limit is 10000 bytes.

Before SQL Remote logs output messages to a file, it checks the current file size. If the log message will make the file size exceed the specified size, SQL Remote renames the output file to yymmddxx.dbr (for dbremote) and yymmddxx.ssr (for ssremote) where xx are sequential characters ranging from AA to ZZ, and yymmdd represents the current year, month, and date.

If the Message Agent us running in continuous mode for a long time, this option allows you to manually delete old log files and free up disk space.

-ot Truncate the log file and then append output messages to it. Default is to send output to the screen.

-p Process the messages without purging them.

-q For Windowing operating systems only, starts the Message Agent with a minimized window.

-r Receive messages. If none of -r, -I, or -s is specified, the Message Agent executes all three phases. Otherwise, only the indicated phases are executed.

The Message Agent runs in continuous mode if called with -r. To have the Message Agent shut down after receiving messages, use the -b option in addition to -r.

-rd time By default, the Message Agent polls for incoming messages every minute. This option (rd stands for receive delay) allows the polling frequency to be configured, which is useful when polling is expensive.

You can use a suffix of s after the number to indicate seconds, which may be useful if you want frequent polling. For example:

dbremote -rd 30s

polls every thirty seconds.

For more information on polling, see Tuning incoming message polling.

-ro This option is for use at consolidated sites. When remote databases are configured to send output log information to the consolidated database, this option writes the information to a file. The option is provided to help administrators troubleshoot errors at remote sites.

For more information, see Troubleshooting errors at remote sites.

-rp When running in continuous mode, the Message Agent polls at certain intervals for messages. After polling a set number of times (by default, one), if a message is missing, the Message Agent assumes it has got lost and requests that it be resent. On slow message systems, this can result in many unnecessary resend requests. You can set the number of polls before a resend request is issued using this option, to cut down on the number of resend requests.

For more information on configuring this option, see Tuning incoming message polling.

-rt This option is for use at consolidated sites. It is identical to the -ro option except that the file is truncated on startup.

-ru Control the resend urgency. This is the time between detection of a resend request and when the Message Agent starts fulfilling the request. Use this option to help the Message Agent collect resend requests from multiple users before rescanning the log. The time unit can be any of {s = seconds; m = minutes; h = hours; d = days}

-s Send messages. If none of -r, -I, or -s is specified, the Message Agent executes all three phases. Otherwise, only the indicated phases are executed.

-sd time Control the send delay which is the time to wait between polls for more transaction log data to send.

-t All trigger actions are replicated. If you do use this option, you must ensure that the trigger actions are not carried out twice at remote databases, once by the trigger being fired at the remote site, and once by the explicit application of the replicated actions from the consolidated database.

To ensure that trigger actions are not carried out twice, you can wrap an IF CURRENT REMOTE USER IS NULL ... END IF statement around the body of the triggers. This option is available for Adaptive Server Anywhere only.

-u Process only transactions that have been backed up. This option prevents the Message Agent from processing transactions since the latest backup. Using this option, outgoing transactions and confirmation of incoming transactions are not sent until they have been backed up.

In Adaptive Server Anywhere, this means only transactions from renamed logs are processed. In Adaptive Server Enterprise, this means that only transactions committed before the latest dump database or dump transaction statement are processed.

-ud On UNIX platforms, you can run the Message Agent as a daemon by supplying the -ud option.

If you run the Message Agent as a daemon, you must also supply the -o or -ot option, to log output information.

If you run the Message Agent as a daemon and are using FTP or SMTP message links, you must store the message link parameters in the database, because the Message Agent does not prompt the user for these options when running as a daemon.

For information on message link parameters, see Setting message type control parameters.

-v Verbose output. This option displays the SQL statements contained in the messages to the screen and, if the -o or -ot option is used, to a log file.

-w n The number of worker threads used to apply incoming messages. The default is zero, which means all messages are applied by the main (and only) thread. A value of 1 (one) would have one thread receiving messages from the message system and one thread applying messages to the database.

The -w option makes it possible to increase the throughput of incoming messages with hardware upgrades. Putting the consolidated database on a device that can perform many concurrent operations (a RAID array with a striped logical drive) will improve throughput of incoming messages. Multiple processors in the computer running the Message Agent could also improve throughput of incoming messages.

The -w option will not improve performance significantly on hardware that cannot perform many concurrent operations.

Incoming messages from a single remote database will never be applied on multiple threads. Messages from a single remote database are always applied serially in the correct order.

-x Rename and restart the transaction log after it has been scanned for outgoing messages. In some circumstances, replicating data to a consolidated database can take the place of backing up remote databases, or renaming the transaction log when the database server is shut down. This option is available for Adaptive Server Anywhere only.

If the optional size qualifier is supplied, the transaction log is renamed only if it is larger than the specified size. The allowed size can be specified as n (in bytes), nK, or nM. The default is 0.

Message system control parameters

SQL Remote uses several registry settings to control aspects of message link behavior.

The message link control parameters are stored in the following places:

  • Windows In the registry, at the following location:

    \\HKEY_CURRENT_USER
   \Software
      \Sybase
            \SQL Remote

  • NetWare You should create a file named dbremote.ini in the sys:\system directory to hold the FILE system directory setting.

For a listing of registry settings, see the section for each message system under Using message types.


The Database Extraction utility

You can access the remote database extraction utility in the following ways:

  • From Sybase Central, for interactive use.

  • From the system command prompt, using the ssxtract or dbxtract utilities. This is useful for incorporating into batch or command files.

    ssxtract is the extraction utility for Adaptive Server Enterprise, dbxtract is the extraction utility for Adaptive Server Anywhere.

By default, the extraction utility runs at isolation level zero. If you are extracting a database from an active server, you should run it at isolation level 3 (see Extraction utility options) to ensure that data in the extracted database is consistent with data on the server. Running at isolation level 3 may hamper others' turnaround time on the server because of the large number of locks required. It is recommended that you run the extraction utility when the server is not busy, or run it against a copy of the database (see Designing an efficient extraction procedure).

Objects owned by dbo

The dbo user ID owns a set of Adaptive Server Enterprise-compatible system objects in an Adaptive Server Anywhere database.

For Adaptive Server Anywhere, the extraction utility does not unload the objects created for the dbo user ID during database creation. Changes made to these objects, such as redefining a system procedure, are lost when the data is unloaded. Any objects created by the dbo user ID since the initialization of the database are unloaded by the Extraction utility, and so these objects are preserved.


Extracting a remote database in Sybase Central

Running the extraction utility from Sybase Central carries out the following tasks related to creating and synchronizing SQL Remote subscriptions:

  • Creates a command file to build a remote database containing a copy of the data in a specified publication.

  • Creates the necessary SQL Remote objects, such as message types, publisher and remote user IDs, publication and subscription, for the remote database to receive messages from and send messages to the consolidated database.

  • Starts the subscription at both the consolidated and remote databases.

Note
Only tables for users selected in the Filter Objects by Owner dialog appear in the Extract Database wizard. If you wish to view tables belonging to a particular database user, right-click the database you are unloading, choose Filter Objects by Owner from the popup menu, and then select the desired user in the resulting dialog.
toggle To extract a remote database from a running database (Sybase Central)

  1. Connect to the database.

  2. Right-click the database and choose Extract Database from the popup menu.

  3. Follow the instructions in the wizard.

toggle To extract a remote database from a database file or a running database (Sybase Central)

  1. In the left pane, select the Adaptive Server Anywhere plug-in.

  2. In the right pane, click the Utilities tab.

  3. In the right pane, double-click Extract Database.

  4. Follow the instructions in the wizard.


The extraction utility

Purpose

To extract a remote Adaptive Server Anywhere database from a consolidated Adaptive Server Enterprise or Adaptive Server Anywhere database.

Syntax

{ ssxtract | dbxtract } [ options ] [ directory ] subscriber

Option | Description
@data | Read in options from a configuration file. See @data server option.
–an database | Creates a database file with the same settings as the database being unloaded and automatically reloads it.
–ac "keyword=value; ..." | Connect to the database specified in the connect string to do the reload.
–b | Do not start subscriptions
–c "keyword=value; ..." | Supply database connection parameters
–d | Unload data only
–e language,charset | Specify the locale to be used
–ea alg | Specify the encryption algorithm for the new database
–ek key | Specify the encryption key for the new database
–ep | Prompt for the encryption key for the new database
–f | Extract fully qualified publications
–ii | Internal unload, internal reload
–ix | Internal unload, external reload
–j count | Iteration count for view creation statements
–l level | Perform all extraction operations at specified isolation level
–k | Close window on completion
–n | Extract schema definition only
–o file | Output messages to file
–p character | Escape character
–q | Operate quietly: do not print messages or show windows. When this option is specified, –y must also be specified or the operation will fail.
–r file | Specify name of generated reload Interactive SQL command file (default "reload.sql")
–u | Unordered data
–v | Verbose messages
–x | Use external table loads
–xf | Exclude foreign keys
–xi | External unload, internal reload
–xp | Exclude stored procedures
–xt | Exclude triggers
–xv | Exclude views
–xx | External unload, external load
–y | Overwrite command file without confirmation
directory | The directory to which the files are written. This is not needed if you use -an or -ac
subscriber | The subscriber for whom the database is to be extracted.
Description

ssxtract is the extraction utility for Adaptive Server Enterprise. It is run against a Adaptive Server Enterprise and creates a command file for a remote Adaptive Server Anywhere database.

dbxtract is the extraction utility for Adaptive Server Anywhere. It is run against an Adaptive Server Anywhere database and creates a command file for a remote Adaptive Server Anywhere database.

There is no extraction utility to create remote Adaptive Server Enterprise databases.

The extraction utility creates a command file and a set of associated data files. The command file can be run against a newly-initialized Adaptive Server Anywhere database to create the database objects and load the data for the remote database.

By default, the command file is named reload.sql.

If the remote user is a group, then all the user IDs that are members of that group are extracted. This allows multiple users on a remote database with different user IDs, without requiring a custom extraction process.

SSXtract notes
Deprecated feature
In the next major release of SQL Anywhere Studio, SQL Remote for Adaptive Server Enterprise will not be present. MobiLink provides a more flexible and scalable solution for data synchronization between Adaptive Server Enterprise and Adaptive Server Anywhere databases.

Not all Adaptive Server Enterprise objects have corresponding objects in Adaptive Server Anywhere. The ssxtract utility has the following limitations:

  • Single database All extracted objects must be in a single Adaptive Server Enterprise database.

  • Passwords The password for the extracted user IDs are the same as the user ID itself.

  • Permissions The extracted user ID is granted REMOTE DBA authority.

  • Named constraints These are extracted as Adaptive Server Anywhere CHECK constraints.

  • System tables The sp_populate_sql_anywhere SQL Remote procedure builds a set of Adaptive Server Anywhere system tables in TEMPDB from the Adaptive Server Enterprise system tables. The extracted schema comes from these temporary system tables.

For more information about the Extraction utility options, see Extraction utility options.


Extraction utility options

Write file utility options (@data) Use this option to read in options from the specified environment variable or configuration file. If both exist with the same name, the environment variable is used.

For more information about configuration files, see Using configuration files.

If you want to protect passwords or other information in the configuration file, you can use the File Hiding utility to obfuscate the contents of the configuration file.

For more information, see Hiding the contents of files using the dbfhide command-line utility.

Create a database for reloading (-an) You can combine the operations of unloading a database, creating a new database, and loading the data using this option.

For example, the following command (which should be entered all on one line) creates a new database file named asacopy.db and copies the schema and data for the field_user subscriber of asademo.db into it:

dbxtract -c "uid=dba;pwd=sql;dbf=asademo.db"
-an asacopy.db field_user

If you use this option, no copy of the data is created on disk, so you do not specify an unload directory in the command. This provides greater security for your data, but at some cost for performance.

Reload the data to an existing database (-ac) You can combine the operation of unloading a database and reloading the results into an existing database using this option.

For example, the following command (which should be entered all on one line) loads a copy of the data for the field_user subscriber into an existing database file named newdemo.db:

dbxtract -c "uid=dba;pwd=sql;dbf=asademo.db"
-ac "uid=dba;pwd=sql;dbf=newdemo.db" field_user

If you use this option, no copy of the data is created on disk, so you do not specify an unload directory in the command. This provides greater security for your data, but at some cost for performance.

Do not start subscriptions automatically (-b) If this option is selected, subscriptions at the consolidated database (for the remote database) and at the remote database (for the consolidated database) must be started explicitly using the START SUBSCRIPTION statement for replication to begin.

Connection parameters (-c) A set of connection parameters, in a string.

  • dbxtract connection parameters The user ID should have DBA authority to ensure that the user has permissions on all the tables in the database.

    For example, the following statement (which should be typed on one line) extracts a database for remote user ID joe_remote from the asademo database running on the sample_server server, connecting as user ID DBA with password SQL. The data is unloaded into the c:\unload directory.

    ssxtract -c "eng=sample_server;dbn=sademo;
uid=dba;pwd=sql" c:\extract joe_remote

    If connection parameters are not specified, connection parameters from the SQLCONNECT environment variable are used, if set.

  • ssxtract connection parameters The following connection parameters are supported:

    Parameter | Description
    UID | Login ID
    PWD | Password
    DBN | (optional) Database name. If this parameter is not supplied, the connection defaults to the default database for the login ID.
    ENG | Adaptive Server Enterprise name.

    ssxtract cannot extract passwords. It sets passwords to be the same as the user ID.

Unload the data only (-d) If this option is selected, the schema definition is not unloaded, and publications and subscriptions are not created at the remote database. This option is for use when a remote database already exists with the proper schema, and needs only to be filled with data.

Use specified locale (-e) This option applies to Adaptive Server Enterprise only.

Specify Adaptive Server Enterprise locale information. The locale string has the following format:

"language_name,charset_name[,sort_order]"

By default, the Message Agent uses the default locale, which is defined in the file sybase\locales\locales.dat.

If language_name and charset_name are not supplied, the Message Agent obtains them from Adaptive Server Enterprise. If sort_order is not supplied, the Message Agent uses a binary sort order (sort by byte value).

Specify encryption algorithm (-ea) This option allows you to choose a strong encryption algorithm to encrypt your new database. You can choose either AES (the default) or AES_FIPS for the FIPS-approved algorithm. AES_FIPS uses a separate library and is not compatible with AES. Algorithm names are case insensitive. If you specify the -ea option, you must also specify -ep or -ek.

For more information, see Strong encryption.

Separately licensable option required
Strong database encryption using AES_FIPS requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

Specify encryption key (-ek) This option allows you to create a strongly encrypted database by specifying an encryption key directly in the command. The algorithm used to encrypt the database is AES or AES_FIPS as specified by the -ea option. If you specify the -ek option without specifying -ea, the AES algorithm is used.

Caution Protect your key! Be sure to store a copy of your key in a safe location. A lost key will result in a completely inaccessible database, from which there is no recovery.

The following are invalid for database encryption keys:

  • keys that begin with white space or single or double quotes

  • keys that end with white space

  • keys that contain semicolons

Prompt for encryption key (-ep) This option allows you to specify that you want to create a strongly encrypted database by inputting the encryption key in a dialog box. This provides an extra measure of security by never allowing the encryption key to be seen in clear text.

You must input the encryption key twice to confirm that it was entered correctly. If the keys don't match, the initialization fails.

For more information, see Strong encryption.

Extract fully qualified publications (-f) In most cases, you do not need to extract fully qualified publication definitions for the remote database, since it typically replicates all rows back to the consolidated database anyway.

However, you may want fully qualified publications for multi-tier setups or for setups where the remote database has rows that are not in the consolidated database.

Internal unload, internal load (-ii) Using this option forces the reload script to use the internal UNLOAD and LOAD TABLE statements rather than the Interactive SQL OUTPUT and INPUT statements to unload and load data, respectively.

This combination of operations is the default behavior.

External operations takes the path of the data files relative to the current working directory of dbxtract, while internal statements take the path relative to the server.

Internal unload, external load (-ix) Using this option forces the reload script to use the internal UNLOAD statement to unload data, and the Interactive SQL INPUT statement to load the data into the new database.

External operations takes the path of the data files relative to the current working directory of dbxtract, while internal statements take the path relative to the server.

Iteration count for views (-j) If there are nested views in the consolidated database, this option specifies the maximum number of iterations to use when extracting the views.

Perform extraction at a specified isolation level (-l) The default setting is an isolation level of zero. If you are extracting a database from an active server, you should run it at isolation level 3 (see Extraction utility options) to ensure that data in the extracted database is consistent with data on the server. Increasing the isolation level may result in large numbers of locks being used by the extraction utility, and may restrict database use by other users.

Unload the schema definition only (-n) With this definition, none of the data is unloaded. The reload file contains SQL statements to build the database structure only. You can use the SYNCHRONIZE SUBSCRIPTION statement to load the data over the messaging system. Publications, subscriptions, PUBLISH and SUBSCRIBE permissions are part of the schema.

Output messages to file (-o) Outputs the messages from the extraction process to a file for later review.

Escape character (-p) The default escape character (\) can be replaced by another character using this option.

Operate quietly (-q) Display no messages except errors. This option is not available from other environments. This is available only from the command-line utility.

Reload filename (-r) The default name for the reload command file is reload.sql in the current directory You can specify a different file name with this option.

Output the data unordered (-u) By default the data in each table is ordered by primary key. Unloads are quicker with the -u option, but loading the data into the remote database is slower.

Verbose mode (-v) The name of the table being unloaded and the number of rows unloaded are displayed. The SELECT statement used is also displayed.

Exclude foreign key definitions (-xf) You can use this if the remote database contains a subset of the consolidated database schema, and some foreign key references are not present in the remote database.

External unload, internal load (-xi) The default behavior for unloading the database is to use the UNLOAD statement, which is executed by the database server. If you choose an external unload, dbxtract uses the OUTPUT statement instead. The OUTPUT statement is executed at the client.

External operations takes the path of the data files relative to the current working directory of dbxtract, while internal statements take the path relative to the server.

Exclude stored procedure (-xp) Do not extract stored procedures from the database.

Exclude triggers (-xt) Do not extract triggers from the database.

Exclude views (-xv) Do not extract views from the database.

External unload, external load (-xx) Use the OUTPUT statement to unload the data, and the INPUT statement to load the data into the new database.

The default unload behavior is to use the UNLOAD statement, and the default loading behavior is to use the LOAD TABLE statement. The internal UNLOAD and LOAD TABLE statements are faster than OUTPUT and INPUT.

External operations takes the path of the data files relative to the current working directory of dbxtract, while internal statements take the path relative to the server.

Operate without confirming actions (-y) Without this option, you are prompted to confirm the replacement of an existing command file.


The SQL Remote Open Server

Purpose

To take replication data from Replication Server and apply it to the SQL Remote stable queue. This utility is needed only for databases participating in both Replication Server (and using a Replication Agent) and SQL Remote replication.

Deprecated feature
In the next major release of SQL Anywhere Studio, SQL Remote for Adaptive Server Enterprise will not be present. MobiLink provides a more flexible and scalable solution for data synchronization between Adaptive Server Enterprise and Adaptive Server Anywhere databases.
Syntax

ssqueue [ options ] [ open-server-name ]

Options
Option | Description
open-server-name | An open server name, which must be declared in the interfaces file.
–c "keyword=value; ..." | Supply database connection parameters
–cq "keyword=value; ..." | Supply database connection parameters for the stable queue
–dl | Display messages in window
–k | Close window on completion
–o file | Output messages to file
–os file | Maximum file size for logging output messages
–ot file | Truncate file and log output messages
–q | Run with minimized window
–ud | Run as a daemon [UNIX]
–v | Verbose operation
Description

The SQL Remote Open Server is used to enable an Adaptive Server Enterprise database to take part in both SQL Remote replication while acting as a primary site in a Replication Server installation (or a replicate site using asynchronous procedure calls).

The name of the executable is as follows:

  • ssqueue.exe Windows operating systems.

  • ssqueue UNIX operating systems.

Option details

open-server-name Replication Server must connect to the SQL Remote Open Server, which therefore must have an open server name. This open server name is set at the command prompt, and must correspond to a master and query entry in the interfaces file on the machine running the SQL Remote Open Server, and to a query entry on the interfaces file of the machine running Replication Server.

The interfaces file is named sql.ini on Windows operating systems, and interfaces on UNIX.

The default value for the open server name is SSQueue.

-c Specify connection parameters to the database holding the data being replicated. This connection is required for the SQL Remote Open Server to gain access to the SQL Remote system tables.

The connection parameters must come from the following list:

Parameter | Description
UID | Login ID
PWD | Password
DBN | (optional) Database name. If this parameter is not supplied, the connection defaults to the default database for the login ID.
ENG | Server name.

-cq Specify connection parameters for the stable queue. If not supplied, the values default to the -c values.

-dl Display messages in the window or at the command prompt and also in the log file.

-k Close window on completion.

-o Append output to a log file. Default is to send output to the screen.

-os Specifies the maximum file size for logging output messages. The allowed size can be specified as n (bytes), n K (kb), or n M (Mb). By default there is no limit, and the minimum limit is 10000 bytes.

Before SQL Remote logs output messages to a file, it checks the current file size. If the log message will make the filesize exceed the specified size, SQL Remote renames the output file to yymmddxx.dbr (for dbremote) and yymmddxx.ssr (for ssremote) where xx are sequential characters ranging from AA to ZZ, and yymmdd represents the current year, month, and date.

If the Message Agent us running in continuous mode for a long time, this option allows you to manually delete old log files and free up disk space.

-ot Truncate the log file and then append output messages to it. Default is to send output to the screen.

-q For Windowing operating systems only, starts the Message Agent with a minimized window.

-ud On UNIX platforms, you can run the SQL Remote Open Server as a daemon by supplying the -ud option.

If you run as a daemon, you must also supply the -o or -ot option, to log output information.

-v Verbose output. This option displays the SQL statements contained in the messages to the screen and, if the -o option is used, to a log file.


SQL Remote options

Function

Replication options are database options included to provide control over replication behavior.

Adaptive Server Anywhere Syntax

SET [ TEMPORARY ] OPTION
[ userid. | PUBLIC. ]option_name = [ option_value ]

Adaptive Server Enterprise syntax:

exec sp_remote_option option-name, option-value

Parameters
Argument | Description
option_name | The name of the option being changed.
option-value | A string containing the setting for the option.
Description

The following options are available.

OPTION | VALUES | DEFAULT
Blob_threshold | integer, in kb | 256
Compression | –1 to 9 | 6
Delete_old_logs | ON, OFF | OFF
External_remote_options | ON, OFF | OFF
Qualify_owners | ON, OFF | ON
Quote_all_identifiers | ON, OFF | OFF
Replication_error | procedure-name | NULL
Save_remote_passwords | ON, OFF | ON
SR_Date_Format | date-string | yyyy/mm/dd
SR_Time_Format | time-string | hh:nn:ss.Ssssss
SR_Timestamp_Format | timestamp-string | yyyy/mm/dd hh:nn:ss.Ssssss
Subscribe_by_remote | ON,OFF | ON
Verify_threshold | integer | 256
Verify_all_columns | ON,OFF | OFF

These options are used by the Message Agent, and should be set for the user ID specified in the Message Agent command. They can also be set for general public use.

The options are as follows:

Blob_threshold option Any value longer than the Blob_threshold option is replicated as a blob. That is, it is broken into pieces and replicated in chunks, before being reconstituted by using a SQL variable and concatenating the pieces at the recipient site.

If you are replicating blobs in an installation with Adaptive Server Enterprise, you must ensure that Blob_threshold is set to a value larger the largest blob being replicated.

For information on blob replication and Adaptive Server Enterprise, see Replication of blobs.

Compression option Set the level of compression for messages. Values can be from -1 to 9, and have the following meanings:

  • -1 Send messages in Version 5 format. Message Agents (both dbremote and ssremote) from previous versions of SQL Remote cannot read messages sent in Version 6 format. You should ensure that COMPRESSION is set to -1 until all Message Agents in your system are upgraded to Version 6.

  • 0 No compression.

  • 1 to 9 Increasing degrees of compression. Creating messages with high compression can take longer than creating messages with low compression.

Delete_old_logs option This option is used by SQL Remote and by the Adaptive Server Anywhere Replication Agent. The default setting is OFF. When set to ON, the Message Agent (DBREMOTE) deletes each old transaction log when all the changes it contains have been sent and confirmed as received.

External_remote_options This option is used by SQL Remote to indicate whether the message link parameters should be stored in the database (OFF) or externally (ON). By default, the setting is OFF.

Qualify_owners option Controls whether SQL statements being replicated by SQL Remote should use qualified object names. The default in Adaptive Server Anywhere is ON and the default in Adaptive Server Enterprise is OFF.

Qualifying owners in Adaptive Server Enterprise setups is rarely needed because it is common for objects to be owned by dbo. When qualification is not needed in Adaptive Server Anywhere setups, messages will be slightly smaller with the option off.

Quote_all_identifiers option Controls whether SQL statements being replicated by SQL Remote should use quoted identifiers. The default is OFF.

When this option is off, the dbremote quotes identifiers that require quotes by Adaptive Server Anywhere (as it has always done) and ssremote does not quote any identifiers. When the option is on, all identifiers are quoted.

Replication_error option Specifies a stored procedure called by the Message Agent when a SQL error occurs. By default no procedure is called.

The replication error procedure must have a single argument of type CHAR, VARCHAR, or LONG VARCHAR. The procedure may be called once with the SQL error message and once with the SQL statement that causes the error.

While the option allows you to track and monitor SQL errors in replication, you must still design them out of your setup: this option is not intended to resolve such errors.

You can use a table with DEFAULT CURRENT REMOTE USER to record the remote site that caused the error.

Save_remote_passwords option When a password is entered into the message link dialog box on first connection, the parameter values are saved. By default, Save_remote_passwords is ON and the password is saved. If you are storing the message link parameters externally, rather than in the database, you may wish not to save the passwords. You can prevent the passwords from being saved by setting this option to NO.

SR_Date_Format option The Message Agent uses this option when replicating columns that store a date. The option is a string build from the following symbols:

Symbol | Description
yy | Two digit year
yyyy | Four-digit year
mm | Two-digit month
mmm | Character format for month
dd | Two-digit day

Each symbol is substituted with the date being replicated.

If you set the mm format symbol in upper case, the corresponding characters are also upper case.

For the digit formats, the case of the option setting controls padding. If the symbols are the same case (such as DD), the number is padded with zeroes. If the symbols are mixed case (such as Mm), the number is not zero padded.

SR_Time_Format option The Message Agent uses this option when replicating columns that store a time. The option is a string build from the following symbols:

Symbol | Description
hh | Two digit hours (24-hour clock)
nn | Two-digit minutes
mm | Two-digit minutes if following a colon (as in hh:mm)
ss[.s...] | Two-digit seconds plus optional fractions of a second.

Using mixed case in the formatting string suppresses leading zeroes.

SR_Timestamp_Format The Message Agent replicates datetime information using this option. For Adaptive Server Anywhere this is the timestamp, datetime, and smalldatetime data types. For Adaptive Server Enterprise, this is the datetime and smalldatetime data types.

The format strings are taken from the SR_Date_Format and SR_Time_Format settings.

The default setting is the SR_Date_Format setting, followed by the SR_Time_Format setting.

Subscribe_by_remote option When set to ON, operations from remote databases on rows with a subscribe by value that is NULL or an empty string assume the remote user is subscribed to the row. When set to OFF, the remote user is assumed not to be subscribed to the row.

The only limitation of this option is that it will lead to errors if a remote user really does want to INSERT (or UPDATE) a row with a NULL or empty subscription expression (for information held only at the consolidated database). This is reasonably obscure and can be worked around by assigning a subscription value in your installation that belongs to no remote user.

For more information about this option, see Using the Subscribe_by_remote option with many-to-many relationships, and Using the Subscribe_by_remote option with many-to-many relationships.

Verify_threshold option If the data type of a column is longer than the threshold, old values for the column are not verified when an UPDATE is replicated. The default setting is 1000.

This option keeps the size of SQL Remote messages down, but has the disadvantage that conflicting updates of long values are not detected.

Verify_all_columns option The default setting is OFF. When set to ON, messages containing updates published by the local database are sent with all column values included, and a conflict in any column triggers a RESOLVE UPDATE trigger at the subscriber database.

The extraction utility for Adaptive Server Enterprise sets the public option in remote Adaptive Server Anywhere databases to match the setting in the Adaptive Server Enterprise database.

Examples

  • The following statement sets the Verify_all_columns option to OFF in Adaptive Server Anywhere, for all users:

    SET OPTION PUBLIC.Verify_all_columns = 'OFF'

  • The following statements set the Verify_all_columns option to OFF in Adaptive Server Enterprise:

    exec sp_remote_option Verify_all_columns, 'OFF'
go

    In Adaptive Server Enterprise, replication options are used only by SQL Remote.


SQL Remote event-hook procedures

The following stored procedure names and arguments provide the interface for customizing synchronization at SQL Remote databases.

Notes

Unless otherwise stated, the following apply to event-hook procedures:

  • The stored procedures must either have DBA authority ( Adaptive Server Anywhere ) or dbo authority (Adaptive Server Enterprise).

  • The procedure must not commit or rollback operations, or perform any action that performs an implicit commit. The actions of the procedure are automatically committed by the calling application.

  • You can troubleshoot the hooks by turning on the Message Agent verbose mode.

  • The hooks for dbremote and ssremote differ only in name.

The #hook_dict table

The #hook_dict table is created immediately before a hook is called using the following CREATE statement:

CREATE table #hook_dict(
name VARCHAR(128) NOT NULL UNIQUE,
value VARCHAR(255) NOT NULL )

The Message Agent uses the #hook_dict table to pass values to hook functions; hook functions use the #hook_dict table to pass values back to the Message Agent.

sp_hook_dbremote_begin and sp_hook_ssrmt_begin
sp_hook_dbremote_end and sp_hook_ssrmt_end
sp_hook_dbremote_shutdown and sp_hook_ssrmt_shutdown
sp_hook_dbremote_receive_begin and sp_hook_ssrmt_receive_begin
sp_hook_dbremote_receive_end and sp_hook_ssrmt_receive_end
sp_hook_dbremote_send_begin and sp_hook_ssrmt_send_begin
sp_hook_dbremote_send_end and sp_hook_ssrmt_send_end
sp_hook_dbremote_message_sent and sp_hook_ssrmt_message_sent
sp_hook_dbremote_message_missing and sp_hook_ssrmt_message_missing
sp_hook_dbremote_message_apply_begin and sp_hook_ssrmt_message_apply_begin
sp_hook_dbremote_message_apply_end and sp_hook_ssrmt_message _apply_end


sp_hook_dbremote_begin and sp_hook_ssrmt_begin

Function

Use this stored procedure to add custom actions at the beginning of the replication process.

Rows in #hook_dict table
Name | Values | Description
send | true or false | Indicates if the process is performing the send phase of replication.
receive | true or false | Indicates if the process is performing the receive phase of replication
Description

If a procedure of this name exists, it is called when the Message Agent starts.


sp_hook_dbremote_end and sp_hook_ssrmt_end

Function

Use this stored procedure to add custom actions just before the Message Agent exits.

Rows in #hook_dict table
Name | Values | Description
send | true or false | Indicates if the process is performing the send phase of replication.
receive | true or false | Indicates if the process is performing the receive phase of replication
exit code | integer | A non-zero exit code indicates an error.
Description

If a procedure of this name exists, it is called as the last event before the Message Agent shuts down.


sp_hook_dbremote_shutdown and sp_hook_ssrmt_shutdown

Function

Use this stored procedure to initiate a Message Agent shutdown.

Rows in #hook_dict table
Name | Values | Description
send | true or false | Indicates if the process is performing the send phase of replication.
receive | true or false | Indicates if the process is performing the receive phase of replication
shutdown | true or false | This row is false when the procedure is called. If the procedure updates the row to true the Message Agent is shut down.
Description

If a procedure of this name exists, it is called when the Message Agent is neither sending nor receiving messages, and permits a hook-initiated shutdown of the Message Agent.


sp_hook_dbremote_receive_begin and sp_hook_ssrmt_receive_begin

Function

Use this stored procedure to perform actions before the start of the receive phase of replication.

Rows in #hook_dict

None


sp_hook_dbremote_receive_end and sp_hook_ssrmt_receive_end

Function

Use this stored procedure to perform actions after the end of the receive phase of replication.

Rows in #hook_dict

None


sp_hook_dbremote_send_begin and sp_hook_ssrmt_send_begin

Function

Use this stored procedure to perform actions before the start of the send phase of replication.

Rows in #hook_dict

None


sp_hook_dbremote_send_end and sp_hook_ssrmt_send_end

Function

Use this stored procedure to perform actions after the end of the send phase of replication.

Rows in #hook_dict

None


sp_hook_dbremote_message_sent and sp_hook_ssrmt_message_sent

Function

Use this stored procedure to perform actions after any message is sent.

Rows in #hook_dict
Name | Values
remote user | The message destination


sp_hook_dbremote_message_missing and sp_hook_ssrmt_message_missing

Function

Use this stored procedure to perform actions when the Message Agent has determined that one or more messages is missing from a remote user.

Rows in #hook_dict
Name | Values
remote user | The name of the remote user who will have to resend messages.


sp_hook_dbremote_message_apply_begin and sp_hook_ssrmt_message_apply_begin

Function

Use this stored procedure to perform actions just before the Message Agent applies a set of messages from a user.

Rows in #hook_dict
Name | Values
remote user | The name of the remote user who sent the messages about to be applied.


sp_hook_dbremote_message_apply_end and sp_hook_ssrmt_message _apply_end

Function

Use this stored procedure to perform actions just after the Message Agent has applied a set of messages from a user.

Rows in #hook_dict
Name | Values
remote user | The name of the remote user who sent the messages that have been applied.


System Objects for Adaptive Server Anywhere

About this chapter

SQL Remote-specific system information is held in the Adaptive Server Anywhere catalog. A more comprehensible version of this information is held in a set of system views.


SQL Remote system tables

This section describes the system tables used by SQL Remote to define and manage SQL Remote information. In the following diagram, arrows indicate foreign key relations between tables: the arrow leads from the foreign table to the primary table.

The SYSSUBSCRIPTION, SYSPUBLICATION, SYSARTICLE, SYSARTICLECOL, SYSREMOTEUSER, and SYSREMOTETYPE system tables.

These tables are described in more detail in the following sections.

SYSARTICLE table
SYSARTICLECOL table
SYSPUBLICATION table
SYSREMOTEOPTION table
SYSREMOTEOPTIONTYPE table
SYSREMOTETYPE table
SYSREMOTEUSER table
SYSSUBSCRIPTION table


SYSARTICLE table

Function

Each row describes an article in a SQL Remote publication.

Columns
Column | Data type | Description
publication_id | UNSIGNED INT | The publication of which this article is a part.
table_id | UNSIGNED INT | Each article consists of columns and rows from a single table. This column contains the table ID for this table.
where_expr | LONG VARCHAR | For articles that contain a subset of rows defined by a WHERE clause, this column contains the search condition.
subscribe_by_expr | LONG VARCHAR | For articles that contain a subset of rows defined by a SUBSCRIBE BY expression, this column contains the expression.
query | CHAR(1) | The SUBSCRIBE BY expression could be a subquery that returns multiple values. This column contains Y or N to indicate if the expression is a subquery (Y) or not (N). This column is used by the Extraction utility


SYSARTICLECOL table

Function

Each row identifies a column in an article, identifying the column, the table it is in, and the publication it is part of.

Columns
Column | Data type | Description
publication_id | UNSIGNED INT | A unique identifier for the publication of which the column is a part.
table_id | UNSIGNED INT | The table to which the column belongs.
column_id | UNSIGNED INT | The column identifier, from the SYSCOLUMN system table.


SYSPUBLICATION table

Function

Each row describes a SQL Remote publication.

Columns
Column | Data type | Description
publication_id | UNSIGNED INT | A unique identifier for the publication
creator | UNSIGNED INT | The user ID that owns the publication
publication_name | VARCHAR(128) | The name of the publication
remarks | LONG VARCHAR | Comments


SYSREMOTEOPTION table

Function

Each row describes the values of a SQL Remote message link parameter.

Columns
Column | Data type | Description
option_id | UNSIGNED INT | An identification number for the message link parameter.
user_id | UNSIGNED INT | The user ID for which the parameter is set.
"setting00" | VARCHAR(255) | The value of the message link parameter.


SYSREMOTEOPTIONTYPE table

Function

Each row describes one of the SQL Remote message link parameters.

Columns
Column | Data type | Description
option_id | UNSIGNED INT | An identification number for the message link parameter.
type_id | SMALLINT | An identification number for the message type that uses this parameter
"option" | VARCHAR(128) | The name of the message link parameter.


SYSREMOTETYPE table

Function

Each row describes one of the SQL Remote message types, including the publisher address.

Columns
Column | Data type | Description
type_id | SMALLINT | An identification number for the message type.
type_name VARCHAR(128) The message type. There is a separate row for each of the following:

  • FILE

  • MAPI

  • VIM

  • SMTP
publisher_address | VARCHAR(128) | The publisher's address for the message type type_name. SQL Remote receives messages from this address.
remarks | LONG VARCHAR | Comments


SYSREMOTEUSER table

Function

Each row describes a user ID with REMOTE permissions (a subscriber), together with the status of SQL Remote messages sent to and from that user.

Columns
Column | Data type | Description
user_id | UNSIGNED INT | The user ID of the user with REMOTE permissions.
consolidate | CHAR(1) | The column contains either an N to indicate a user granted REMOTE permissions, or a Y to indicate a user granted CONSOLIDATE permissions.
type_id | SMALLINT | The ID of the message system used to send messages to this user.
address | LONG VARCHAR | The address to which SQL Remote messages are to be sent. The address must be appropriate for the address_type.
frequency | CHAR(1) | How frequently SQL Remote messages are to be sent. P for Periodically, and A stands for Occasionally.
send_time | TIME | The next time messages are to be sent to this user.
log_send | NUMERIC(20, 0) | If log_send is greater than log_sent, the Message Agent resends messages immediately to the subscriber the next time it is run.
time_sent | TIMESTAMP | The time the most recent message was sent to this subscriber.
log_sent | NUMERIC(20, 0) | The local log offset for the most recently sent operation to this subscriber.
confirm_sent | NUMERIC(20, 0) | The log offset for the most recently confirmed operation from this subscriber.
send_count | INT | The number of SQL Remote messages have been sent to this subscriber.
resend_count | INT | Counter to ensure messages are applied only once at the subscriber database.
time_received | DATETIME | The time the most recent message was received from this subscriber.
log_received | NUMERIC(20, 0) | The log offset in the subscriber's database for the operation most recently received at the current database.
confirm_received | NUMERIC(20, 0) | The log offset in the subscriber's database for the most recent operation for which a confirmation message has been sent.
receive_count | INT | How number of messages received from this subscriber.
rereceive_count | INT | Counter to ensure messages are applied only once at the current database.


SYSSUBSCRIPTION table

Function

Each row describes a subscription from one user ID (which must have REMOTE permissions) to one publication.

Columns
Column | Data type | Description
publication_id | UNSIGNED INT | The identifier for the publication to which the user ID is subscribed.
user_id | UNSIGNED INT | The user ID that is subscribed to the publication.
subscribe_by | VARCHAR(128) | For publications with a SUBSCRIBE BY expression, this column holds the matching value for this subscription.
created | NUMERIC(20, 0) | The offset in the transaction log at which the subscription was created.
started | NUMERIC(20, 0) | The offset in the transaction log at which the subscription was started.


SQL Remote system views

This section describes the database views used by SQL Remote to present and summarize SQL Remote information.


SYSARTICLES view

Function

Each row lists describes an article.

Columns
Column | Description
publication_name | The publication of which this article is a part.
table_name | Each article consists of columns and rows from a single table. This column contains the name of this table.
where_expr | For articles that contain a subset of rows defined by a WHERE clause, this column contains the search condition.
subscribe_by_expr | For articles that contain a subset of rows defined by a SUBSCRIBE BY expression, this column contains the expression.


SYSARTICLECOLS view

Function

Each row describes a column that appears in an article.

Columns
Column | Description
publication_name | The name of the publication of which the column is a part.
table_name | The name of the table to which the column belongs.
column_name | The column name.


SYSPUBLICATIONS view

Function

Lists the names of all publications.

Columns
Column | Description
publication_name | The name of the publication
creator | The owner of the publication
remarks | Comments


SYSREMOTEOPTIONS view

Function

Lists the SQL Remote message link parameters and their values, as stored in the SYSREMOTEOPTION and SYSREMOTEOPTIONTYPE system tables, in more readable form.

Columns
Column | Description
type_name | The message link type.
"option" | The option name.
setting | The option value.


SYSREMOTEUSERS view

Function

Lists information about remote users and their status.

Columns
Column | Description
user_name | The user ID of the user with REMOTE permissions.
consolidate | The column contains either an N to indicate a user with REMOTE permissions, or a Y to indicate a user with CONSOLIDATE permissions.
type_name | The name of the message type used to send messages to this user.
address | The address to which SQL Remote messages are to be sent. The address must be appropriate for the address_type.
frequency | How frequently SQL Remote messages are to be sent.
send_time | The next time messages are to be sent to this user.
next_send | The next time messages are to be sent to this user, in a more comprehensible format.
log_send | Messages are sent only to subscribers for whom log_send is greater than log_sent.
time_sent | The time the most recent message was sent to this subscriber.
log_sent | The transaction log offset for the most recently sent operation.
confirm_sent | The transaction log offset for the most recently confirmed operation from this subscriber.
send_count | How many SQL Remote messages have been sent.
resend_count | Counter to ensure messages are applied only once at the subscriber database.
time_received | The time the most recent message was received from this subscriber.
log_received | The log offset in the subscriber's database for the operation most recently received at the current database.
confirm_received | The log offset in the subscriber's database for the most recent operation for which a confirmation message has been sent.
receive_count | How many messages have been received.
rereceive_count | Counter to ensure messages are applied only once at the current database.


SYSSUBSCRIPTIONS view

Function

Each row lists information about a subscription.

Columns
Column | Description
publication_name | The name of the publication to which the user ID is subscribed.
user_name | The user ID that is subscribed to the publication.
subscribe_by | For publications with a SUBSCRIBE BY expression, this column holds the matching value for this subscription.
created | The offset in the transaction log at which the subscription was created.
started | The offset in the transaction log at which the subscription was started.


System Objects for Adaptive Server Enterprise

About this chapter

SQL Remote-specific system information is held in a set of tables called the SQL Remote system tables. A more comprehensible version of this information is held in a set of views, called the SQL Remote system views.


SQL Remote system tables

This section describes the database tables used by SQL Remote to define and manage SQL Remote information.

Caution These tables are for use only by SQL Remote. Do not alter these tables or their contents directly.

#remote table
sr_article table
sr_articlecol table
sr_marker table
sr_object table
sr_option table
sr_passthrough table
sr_publication table
sr_publisher table
sr_remoteoption table
sr_remoteoptiontype table
sr_remotetable table
sr_remotetype table
sr_remoteuser table
sr_subscription table


#remote table

Function

This temporary table is created by the Message Agent to hold the name of the current remote user and of the current publisher. This table exists only in Adaptive Server Enterprise.

Columns
Column | Data type | Description
current_remote_user | VARCHAR(128) | Current remote user (from the Message Agent command line).
current_publisher | VARCHAR(128) | Current publisher
Description

This is not a system table. When the Message Agent for Adaptive Server Enterprise connects to the server, it holds the value of the current remote user ID and the value of the current publisher in the #remote table. This temporary table is held in TEMPDB.

The values from #remote can be used in conflict resolution procedures.

The CREATE TABLE statement for this table is:

CREATE TABLE #remote (
   current_remote_user varchar(128),
   current_publisher varchar(128)
)

The table has a single row.


sr_article table

Function

Each row describes an article in a SQL Remote publication.

Columns
Column | Data type | Description
publication_id | INT | The publication of which this article is a part.
table_id | INT | Each article consists of columns and rows from a single table. This column contains the table ID for this table.
where_expr | VARCHAR(128) | For articles that contain a subset of rows defined by a WHERE clause, this column contains the search condition.
subscribe_by_expr | VARCHAR(128) | For articles that contain a subset of rows defined by a SUBSCRIBE BY expression, this column contains the expression.
subscribe_by_view | VARCHAR(128) | For articles that contain a subset of the rows defined by a view. This column contains the name of the view.


sr_articlecol table

Function

Each row identifies a column in an article, identifying the column, the table it is in, and the publication it is part of.

Columns
Column | Data type | Description
publication_id | INT | A unique identifier for the publication of which the column is a part.
table_id | INT | The table to which the column belongs.
column_id | INT | The column identifier, from the SYSCOLUMN system table.


sr_marker table

Function

To ensure that messages received by the Message Agent are sent to remote databases in the same session.

Columns
Column | Data type | Description
marker | DATETIME | A time value indicating when the latest messages were applied.
Description

When a consolidated database uses two Message Agents, one to populate the stable queue (-I) and one to receive and send messages (-r -s), the single row of the sr_marker table is used to ensure that messages received and applied to the database are sent before the Message Agent closes down.


sr_object table

Function

Holds a list of SQL Remote objects. The extraction utility needs to know not to extract the SQL Remote system objects. The sp_populate_sql_anywhere procedure that creates a set of Adaptive Server Anywhere system tables in TEMPDB gets a list of SQL Remote objects from the sr_object table.

Columns
Column | Data type | Description
name | VARCHAR(128) | The name of the object.
type CHAR(1) One of the following:

  • U User-defined table

  • V View

  • P Procedure


sr_option table

Function

Each row describes a replication option used by SQL Remote.

Columns
Column | Data type | Description
option | VARCHAR(128) | The name of the option.
value | VARCHAR(128) | The setting for the option.
Description

For information about available options, see SQL Remote options.


sr_passthrough table

Function

Each row describes a passthrough operation being sent to a user or to subscribers to a publication.

Columns
Column | Data type | Description
operation | VARCHAR(20) | A passthrough operation, or piece of a passthrough operation, entered using sp_passthrough or sp_passthrough_piece.
value | VARCHAR(255) | A subscription column value indicating which users are to receive the operation.
id | INT | A user who is to receive the operation.


sr_publication table

Function

Each row describes a SQL Remote publication.

Columns
Column | Data type | Description
publication_id | INT | An identifier for the publication
publication_name | VARCHAR(128) | The name of the publication.


sr_publisher table

Function

The row holds the user ID of the publisher.

Columns
Column | Data type | Description
user_id | INT | The user ID of the publisher.


sr_remoteoption table

Function

Each row describes the values of a SQL Remote message link parameter.

Columns
Column | Data type | Description
option_id | INTEGER | An identification number for the message link parameter.
user_id | INTEGER | The user ID for which the parameter is set.
"setting00" | VARCHAR(255) | The value of the message link parameter.


sr_remoteoptiontype table

Function

Each row describes one of the SQL Remote message link parameters.

Columns
Column | Data type | Description
option_id | INTEGER | An identification number for the message link parameter.
type_id | INTEGER | An identification number for the message type that uses this parameter
"option" | VARCHAR(128) | The name of the message link parameter.


sr_remotetable table

Function

Each row describes a table that is marked for replication using SQL Remote.

Columns
Column | Data type | Description
table_id | INT | The id of the table.
resolve_name | VARCHAR(128) | The name of the stored procedure to be executed in the case of conflicts.
old_row_name | VARCHAR(128) | The table that holds the old row name.
remote_row_name | VARCHAR(128) | The table that holds the remote row name.


sr_remotetype table

Function

Each row describes one of the SQL Remote message types, including the publisher address.

Columns
Column | Data type | Description
type_id | INT | An identification number for the message type.
type_name VARCHAR(128) The message type. There is a separate row for each of the following:

  • FILE

  • MAPI

  • VIM

  • SMTP
publisher_address | VARCHAR(128) | The publisher's address for the message type type_name.


sr_remoteuser table

Function

Each row describes a user ID with REMOTE permissions (a subscriber), together with the status of SQL Remote messages sent to and from that user.

Columns
Column | Data type | Description
user_id | INT | The user ID of the user with REMOTE permissions.
consolidate | CHAR(1) | The column contains either an N to indicate a user granted REMOTE permissions, or a Y to indicate a user granted CONSOLIDATE permissions.
type_id | INT | The ID of the message system used to send messages to this user.
address | VARCHAR(128) | The address to which SQL Remote messages are to be sent. The address must be appropriate for the address_type.
frequency | CHAR(1) | How frequently SQL Remote messages are to be sent.
send_time | DATETIME | The next time messages are to be sent to this user.
log_send | NUMERIC(20, 0) | Messages are sent only to subscribers for whom log_send is greater than log_sent.
time_sent | DATETIME | The time the most recent message was sent to this subscriber.
log_sent | NUMERIC(20, 0) | The log offset for the most recently sent operation.
confirm_sent | NUMERIC(20, 0) | The log offset for the most recently confirmed operation from this subscriber.
send_count | INT | How many SQL Remote messages have been sent.
resend_count | INT | Counter to ensure messages are applied only once at the subscriber database.
time_received | DATETIME | The time the most recent message was received from this subscriber.
log_received | NUMERIC(20, 0) | The log offset in the subscriber's database for the operation most recently received at the current database.
confirm_received | NUMERIC(20, 0) | The log offset in the subscriber's database for the most recent operation for which a confirmation message has been sent.
receive_count | INT | How many messages have been received from this subscriber.
rereceive_count | INT | Counter to ensure messages are applied only once at the current database.
filler1 | CHAR(255) | Reserved
filler2 | CHAR(255) | Reserved
filler3 | CHAR(255) | Reserved
filler4 | CHAR(255) | Reserved


sr_subscription table

Function

Each row describes a subscription from one user ID (which must have REMOTE permissions) to one publication.

Columns
Column | Data type | Description
publication_id | INT | The identifier for the publication to which the user ID is subscribed.
user_id | INT | The user ID that is subscribed to the publication.
subscribe_by | VARCHAR(128) | For publications with a SUBSCRIBE BY expression, this column holds the matching value for this subscription.
created | NUMERIC(20, 0) | The offset in the transaction log at which the subscription was created.
started | NUMERIC(20, 0) | The offset in the transaction log at which the subscription was started.
operation | VARCHAR(20) |


SQL Remote system views

This section describes the database views used by SQL Remote to present and summarize SQL Remote information.

sr_articles view
sr_articlecols view
sr_publications view
sr_remoteoptions view
sr_remotetables view
sr_remotetypes view
sr_remoteusers view
sr_subscriptions view


sr_articles view

Function

Each row lists describes an article.

Columns
Column | Description
publication_name | The publication of which this article is a part.
table_name | Each article consists of columns and rows from a single table. This column contains the name of this table.
where_expr | For articles that contain a subset of rows defined by a WHERE clause, this column contains the search condition.
subscribe_by_expr | For articles that contain a subset of rows defined by a SUBSCRIBE BY expression, this column contains the expression.
subscribe_by_view | For articles that contain a subset of rows defined by a view, this column contains the name of the view.


sr_articlecols view

Function

Each row describes a column that appears in an article.

Columns
Column | Description
publication_name | The name of the publication of which the column is a part.
table_name | The name of the table to which the column belongs.
column_name | The column name.


Web Links Browse Collapse Expand PDF Previous Next

SQL Remote User's Guide

System Objects for Adaptive Server Enterprise

SQL Remote system views

sr_publications view

Function

Lists the names of all publications.

Columns
Column | Description
publication_name | The name of the publication


sr_remoteoptions view

Function

Lists the SQL Remote message link parameters and their values, as stored in the remoteoption and remoteoptiontype system tables, in more readable form.

Columns
Column | Description
type_name | The message link type.
"option" | The option name.
setting | The option value.


sr_remotetables view

Function

Lists the tables marked for SQL Remote replication, as stored in the remotetable system table, in more readable form.

This table exists only in Adaptive Server Enterprise.

Columns
Column | Description
table_name | The name of the table.
resolve_name | The name of the stored procedure to be executed in the case of conflicts.
old_row_name | The table that holds the old row name.
remote_row_name | The table that holds the remote row name.


sr_remotetypes view

Function

Lists the message types, as stored in the remotetype system table.

Columns
Column | Description
type_id | An identification number for the message type.
type_name The message type. There is a separate row for each of the following:

  • FILE

  • MAPI

  • VIM

  • SMTP
publisher_address | The publisher's address for the message type type_name.


sr_remoteusers view

Function

Lists information about remote users and their status.

Columns
Column | Description
user_name | The user ID of the user with REMOTE permissions.
consolidate | The column contains either an N to indicate a user granted REMOTE permissions, or a Y to indicate a user granted CONSOLIDATE permissions.
type_name | The name of the message system used to send messages to this user.
address | The address to which SQL Remote messages are to be sent. The address must be appropriate for the address_type.
frequency | How frequently SQL Remote messages are to be sent.
send_time | The next time messages are to be sent to this user.
next_send | The next time messages are to be sent to this user, in a more comprehensible format.
log_send | Messages are sent only to subscribers for whom log_send is greater than log_sent.
time_sent | The time the most recent message was sent to this subscriber.
log_sent | The log offset for the most recently sent operation.
confirm_sent | The log offset for the most recently confirmed operation from this subscriber.
send_count | How many SQL Remote messages have been sent.
resend_count | Counter to ensure messages are applied only once at the subscriber database.
time_received | The time the most recent message was received from this subscriber.
log_received | The log offset in the subscriber's database for the operation most recently received at the current database.
confirm_received | The log offset in the subscriber's database for the most recent operation for which a confirmation message has been sent.
receive_count | How many messages have been received.
rereceive_count | Counter to ensure messages are applied only once at the current database.


sr_subscriptions view

Function

Each row lists information about a subscription.

Columns
Column | Description
publication_name | The name of the publication to which the user ID is subscribed.
user_name | The user ID that is subscribed to the publication.
subscribe_by | For publications with a SUBSCRIBE BY expression, this column holds the matching value for this subscription.
created | The offset in the transaction log at which the subscription was created.
started | The offset in the transaction log at which the subscription was started.


Stable Queue tables

This section describes the database tables used by SQL Remote to define and manage the stable queue information. The stable queue may be kept in the same database as the SQL Remote database, or in a separate database.

The stable queue is used only by SQL Remote for Adaptive Server Enterprise.


sr_queue_state table

Function

A single row table that stores persistent global information about the state of the stable queue.

Columns
Column | Data type | Description
version | INT | The stable queue version number
page_id | INT | Transaction log page_id of the last entry scanned.
row_id | INT | Transaction log row_id of the last entry scanned.
confirm_offset | NUMERIC(20,0) | The minimum value of the confirmation offsets received from all remote users. This value is used by the Message Agent to decide which transactions can be deleted from the stable queue.
commit_offset | NUMERIC(20,0) | The transaction log offset of the most recent transaction completed before the oldest incomplete transaction.
backup_offset | NUMERIC(20,0) | The transaction log offset of the last dump database or dump transaction command. This information is used when the Message Agent is run with the -u option (replicate only backed up transactions).
marker | DATETIME | The most recent incoming message that has been scanned into the stable queue. When a message is applied to the Adaptive Server Enterprise server, it sets the time_received column in sr_remoteuser. When the transaction log is scanned and the transactions from that message are scanned into the stable queue, it sets the time_received column of sr_queue_state. The purpose of the column is co-ordination between one Message Agent that is scanning the transaction log continuously and another Message Agent that is receiving messages and sending messages in batch mode. When in batch mode, the Message Agent receives messages, waits for those messages to be scanned into the stable queue, and then sends messages. The waiting is done through the database by looking at the time_received column of sr_queue_state.
confirmed_id | NUMERIC(20,0) | The sending thread deletes rows with confirmed_id less than this value from sr_confirmed_transaction.


sr_transaction table

Function

This table has one row for each transaction in the stable queue.

Columns
Column | Description
offset | The transaction log offset of the commit operation for the transaction. This value uniquely identifies each transaction
user_id | The remote user where the transaction originated. This column holds NULL if the transaction did not originate from a remote user. The user_id column is used to ensure that actions are not replicated back to the remote site that entered them.
data | The transaction itself, in an internal representation.


sr_confirmed_transaction table

Function

Each row marks the corresponding row in sr_transaction.

Columns
Column | Data type | Description
confirmed_id | NUMERIC (20,0) | A unique ID
offset | NUMERIC (20,0) | A copy of an offset used to mark rows in sr_transaction for deletion.


sr_queue_coordinate table

Function

A single row, that coordinates the SQL Remote log scanning thread and the sending thread to access the stable queue and related tables.

Columns
Column | Data type | Description
status | CHAR(1) | N if the stable queue has not yet been used by SQL Remote. I and S if the SQL Remote log scanning thread and sending thread have accessed the queue.


Command Reference for Adaptive Server Anywhere

About this chapter

This chapter describes the SQL statements used for executing SQL Remote commands, and the system tables, used for storing information about the SQL Remote installation and its state.

ALTER REMOTE MESSAGE TYPE statement
CREATE PUBLICATION statement
CREATE REMOTE MESSAGE TYPE statement
CREATE SUBSCRIPTION statement
CREATE TRIGGER statement
DROP PUBLICATION statement
DROP REMOTE MESSAGE TYPE statement
DROP SUBSCRIPTION statement
GRANT CONSOLIDATE statement
GRANT PUBLISH statement
GRANT REMOTE statement
GRANT REMOTE DBA statement
PASSTHROUGH statement
REMOTE RESET statement
REVOKE CONSOLIDATE statement
REVOKE PUBLISH statement
REVOKE REMOTE statement
REVOKE REMOTE DBA statement
SET REMOTE OPTION statement
START SUBSCRIPTION statement
STOP SUBSCRIPTION statement
SYNCHRONIZE SUBSCRIPTION statement
UPDATE statement


ALTER REMOTE MESSAGE TYPE statement

Function

Use this statement to change the publisher's message system, or the publisher's address for a given message system, for a message type that has been created.

Syntax

ALTER REMOTE MESSAGE TYPE message-system
ADDRESS address

message-system: FILE | FTP | MAPI | SMTP | VIM

address: string

Parameters
Parameter | Description
message-system | One of the message systems supported by SQL Remote. It must be one of the following values:
address | A string containing a valid address for the specified message system.
Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

ALTER REMOTE MESSAGE TYPE statement [SQL Remote]

CREATE REMOTE MESSAGE TYPE statement

sp_remote_type procedure


CREATE PUBLICATION statement

Function

Use this statement to create a publication. In SQL Remote, publications identify replicated data in both consolidated and remote databases.

Syntax

CREATE PUBLICATION [ owner.]publication-name
( TABLE article-description, ... )

owner, publication-name : identifier

article-description:
table-name [ ( column-name, ... ) ]
[ WHERE search-condition ]
[ SUBSCRIBE BY expression ]

See also

CREATE PUBLICATION statement


CREATE REMOTE MESSAGE TYPE statement

Function

Use this statement to identify a message-link and return address for outgoing messages from a database.

Syntax

CREATE REMOTE MESSAGE TYPE message-system
ADDRESS address

message-system: FILE | FTP | MAPI | SMTP | VIM

address: string

Parameters
Parameter | Description
message-system | One of the supported message systems.
address | The address for the specified message system.
Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

CREATE REMOTE MESSAGE TYPE statement [SQL Remote]

GRANT PUBLISH statement

GRANT REMOTE statement

GRANT CONSOLIDATE statement

sp_remote_type procedure

Using message types


CREATE SUBSCRIPTION statement

Function

Use this statement to create a subscription for a user to a publication.

Syntax

CREATE SUBSCRIPTION
TO publication-name [ ( subscription-value ) ]
FOR subscriber-id

publication-name: identifier

subscription-value, subscriber-id: string

subscriber-id: string

Parameters
Parameter | Description
publication-name | The name of the publication to which the user is being subscribed. This may include the owner of the publication.
subscription-value | A string that is compared to the subscription expression of the publication. The subscriber receives all rows for which the subscription expression matches the subscription value.
subscriber-id | The user ID of the subscriber to the publication. This user must have been granted REMOTE permissions.
Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

CREATE SUBSCRIPTION statement [SQL Remote]

DROP SUBSCRIPTION statement

GRANT REMOTE statement

SYNCHRONIZE SUBSCRIPTION statement

START SUBSCRIPTION statement

sp_subscription procedure


CREATE TRIGGER statement

Function

Use this statement to create a new trigger in the database. One form of trigger is designed specifically for use by SQL Remote.

Syntax

CREATE TRIGGER trigger-name trigger-time
trigger-event, ...
[ ORDER integer ] ON table-name
[ REFERENCING [ OLD AS old-name ]
[ NEW AS new-name ] ]
[ REMOTE AS remote-name ] ]
[ FOR EACH { ROW | STATEMENT } ]
[ WHEN ( search-condition ) ]
[ IF UPDATE ( column-name ) THEN
[ { AND | OR } UPDATE ( column-name ) ] ... ]
compound-statement
[ ELSEIF UPDATE ( column-name ) THEN
[ { AND | OR } UPDATE ( column-name ) ] ...
compound-statement
END IF ] ]

trigger-time:
BEFORE | AFTER | RESOLVE

trigger-event:
DELETE | INSERT | UPDATE
| UPDATE OF column-name [, column-name, ...]

Parameters

trigger-time Row-level triggers can be defined to execute BEFORE or AFTER the insert, update, or delete. Statement-level triggers execute AFTER the statement. The RESOLVE trigger time is for use with SQL Remote: it fires before row-level UPDATE or UPDATE OF column-lists only.

BEFORE UPDATE triggers fire any time an UPDATE occurs on a row, whether or not the new value differs from the old value. AFTER UPDATE triggers fire only if the new value is different from the old value.

Trigger events Triggers can be fired by one or more of the following events:

  • DELETE Invoked whenever a row of the associated table is deleted.

  • INSERT Invoked whenever a new row is inserted into the table associated with the trigger.

  • UPDATE Invoked whenever a row of the associated table is updated.

  • UPDATE OF column-list Invoked whenever a row of the associated table is updated and a column in the column-list is modified.

Usage

Anywhere.

Permissions

Must have RESOURCE authority and have ALTER permissions on the table, or must have DBA authority. CREATE TRIGGER puts a table lock on the table and thus requires exclusive use of the table.

Side effects

Automatic commit.

See also

CREATE TRIGGER statement [SQL Remote]

UPDATE statement


DROP PUBLICATION statement

Function

Use this statement to drop a publication. In SQL Remote, publications identify replicated data in both consolidated and remote databases.

Syntax

DROP PUBLICATION [ owner.]publication-name

owner, publication-name : identifier

See also

DROP PUBLICATION statement


DROP REMOTE MESSAGE TYPE statement

Function

Use this statement to delete a message type definition from a database.

Syntax

DROP REMOTE MESSAGE TYPE message-system

message-system: FILE | FTP | MAPI | SMTP | VIM

Parameters
Parameter | Description
message-system | One of the message systems supported by SQL Remote.
Permissions

Must have DBA authority. To be able to drop the type, there must be no user granted REMOTE or CONSOLIDATE permissions with this type.

Side effects

Automatic commit.

See also

DROP REMOTE MESSAGE TYPE statement [SQL Remote]

CREATE REMOTE MESSAGE TYPE statement

ALTER REMOTE MESSAGE TYPE statement

sp_drop_remote_type procedure

Using message types.


DROP SUBSCRIPTION statement

Function

Use this statement to drop a subscription for a user from a publication.

Syntax

DROP SUBSCRIPTION TO publication-name [ ( subscription-value ) ]
FOR subscriber-id, ...

subscription-value: string

subscriber-id: string

Parameters
Parameter | Description
publication-name | The name of the publication to which the user is being subscribed. This may include the owner of the publication.
subscription-value | A string that is compared to the subscription expression of the publication. This value is required because a user may have more than one subscription to a publication.
subscriber-id | The user ID of the subscriber to the publication.
Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

DROP SUBSCRIPTION statement [SQL Remote]

CREATE SUBSCRIPTION statement

DROP SUBSCRIPTION statement


GRANT CONSOLIDATE statement

Function

Use this statement to identify the database immediately above the current database in a SQL Remote hierarchy, who will receive messages from the current database.

Syntax

GRANT CONSOLIDATE
TO userid, ...
TYPE message-system, ...
ADDRESS address-string, ...
[ SEND { EVERY | AT }'hh:mm: ss' ]

message-system: FILE | FTP | MAPI | SMTP | VIM

address: string

Parameters
Parameter | Description
userid | The user ID for the user to be granted the permission
message-system | One of the message systems supported by SQL Remote.
address | The address for the specified message system.
Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

GRANT CONSOLIDATE statement [SQL Remote]

GRANT REMOTE statement

REVOKE CONSOLIDATE statement

GRANT PUBLISH statement

sp_grant_consolidate procedure


GRANT PUBLISH statement

Function

Use this statement to identify the publisher of the current database.

Syntax

GRANT PUBLISH TO userid

Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

GRANT PUBLISH statement [SQL Remote]

GRANT REMOTE statement

GRANT CONSOLIDATE statement

REVOKE PUBLISH statement

CREATE PUBLICATION statement

CREATE SUBSCRIPTION statement

sp_publisher procedure


GRANT REMOTE statement

Function

Use this statement to identify a database immediately below the current database in a SQL Remote hierarchy, who will receive messages from the current database. These are called remote users.

Syntax

GRANT REMOTE TO userid, ...
TYPE message-system, ...
ADDRESS address-string, ...
[ SEND { EVERY | AT } 'send-time' ]

Parameters
Parameter | Description
userid | The user ID for the user to be granted the permission
message-system One of the message systems supported by SQL Remote. It must be one of the following values:

  • FILE

  • FTP

  • MAPI

  • SMTP

  • VIM
address-string | A string containing a valid address for the specified message system.
send-time | A string containing a time specification in the form hh:mm:ss.
Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

GRANT REMOTE statement [SQL Remote]

GRANT CONSOLIDATE statement

REVOKE REMOTE statement

GRANT PUBLISH statement

sp_grant_remote procedure

Granting and revoking REMOTE and CONSOLIDATE permissions


GRANT REMOTE DBA statement

Function

Use this statement to provide DBA privileges to a user ID, but only when connected from the Message Agent.

Syntax

GRANT REMOTE DBA
TO userid, ...
IDENTIFIED BY password

Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

GRANT REMOTE DBA statement [SQL Remote]

The Message Agent and replication security

REVOKE REMOTE DBA statement


PASSTHROUGH statement

Function

Use this statement to start or stop passthrough mode for SQL Remote administration. Forms 1 and 2 start passthrough mode, while form 3 stops passthrough mode.

Syntax 1

PASSTHROUGH [ ONLY ] FOR userid, ...

Syntax 2

PASSTHROUGH [ ONLY ] FOR SUBSCRIPTION
TO [ ( owner ) ].publication-name [ ( constant ) ]

Syntax 3

PASSTHROUGH STOP

Permissions

Must have DBA authority.

Side effects

None.

See also

PASSTHROUGH statement [SQL Remote]

sp_passthrough procedure


REMOTE RESET statement

Function

Use this statement in custom database-extraction procedures to start all subscriptions for a remote user in a single transaction.

Syntax

REMOTE RESET userid

Permissions

Must have DBA authority.

Side effects

No automatic commit is done by this statement.

See also

REMOTE RESET statement [SQL Remote]

START SUBSCRIPTION statement


REVOKE CONSOLIDATE statement

Function

Use this statement to stop a consolidated database from receiving SQL Remote messages from this database.

Syntax

REVOKE CONSOLIDATE FROM userid, ...

Permissions

Must have DBA authority.

Side effects

Automatic commit. Drops all subscriptions for the user.

See also

REVOKE CONSOLIDATE statement [SQL Remote]

GRANT CONSOLIDATE statement

sp_revoke_consolidate procedure


REVOKE PUBLISH statement

Function

Use this statement to terminate the identification of the named user ID as the CURRENT publisher.

Syntax

REVOKE PUBLISH FROM userid

Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

REVOKE PUBLISH statement [SQL Remote]

GRANT PUBLISH statement

REVOKE REMOTE statement

CREATE PUBLICATION statement

CREATE SUBSCRIPTION statement

sp_publisher procedure


REVOKE REMOTE statement

Function

Use this statement to stop a user from being able to receive SQL Remote messages from this database.

Syntax

REVOKE REMOTE FROM userid, ...

Permissions

Must have DBA authority.

Side effects

Automatic commit. Drops all subscriptions for the user.

See also

REVOKE REMOTE statement [SQL Remote]

sp_revoke_remote procedure


REVOKE REMOTE DBA statement

Function

Use this statement to provide DBA privileges to a user ID, but only when connected from the Message Agent.

Syntax 1

REVOKE REMOTE DBA
FROM userid, ...

Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

REVOKE REMOTE DBA statement [SQL Remote]

The Message Agent and replication security

GRANT REMOTE DBA statement


SET REMOTE OPTION statement

Function

Use this statement to set a message control parameter for a SQL Remote message link.

Syntax

SET REMOTE link-name OPTION
[ userid.| PUBLIC.]link-option-name = link-option-value

Parameters

link-name:
file | ftp | mapi | smtp | vim

link-option-name:
file-option | ftp-option | mapi-option | smtp-option | vim-option

file-option:
debug | directory | unlink_delay

ftp-option:
active_mode | debug | host | password
| port | root_directory | user

mapi-option:
debug | force_download | ipm_receive
| ipm_send | profile

smtp-option:
debug | local_host | pop3_host
| pop3_password | pop3_userid
| smtp_host | top_supported

vim-option:
debug | password | path | receive_all
| send_vim_mail | userid

link-option-value:
string

Permissions

Must have DBA authority. The publisher can set their own options.

Side effects

Automatic commit.

See also

sp_link_option procedure


START SUBSCRIPTION statement

Function

Use this statement to start a subscription for a user to a publication.

Syntax

START SUBSCRIPTION
TO publication-name [ ( subscription-value ) ]
FOR subscriber-id, ...

Parameters
Parameter | Description
publication-name | The name of the publication to which the user is being subscribed. This may include the owner of the publication.
subscription-value | A string that is compared to the subscription expression of the publication. The value is required here because each subscriber may have more than one subscription to a publication.
subscriber-id | The user ID of the subscriber to the publication. This user must have a subscription to the publication.
Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

START SUBSCRIPTION statement [SQL Remote]

CREATE SUBSCRIPTION statement

REMOTE RESET statement

SYNCHRONIZE SUBSCRIPTION statement

sp_subscription procedure


STOP SUBSCRIPTION statement

Function

Use this statement to stop a subscription for a user to a publication.

Syntax

STOP SUBSCRIPTION
TO publication-name [ ( subscription-value) ]
FOR subscriber-id, ...

Parameters
Parameter | Description
publication-name | The name of the publication to which the user is being subscribed. This may include the owner of the publication.
subscription-value | A string that is compared to the subscription expression of the publication. The value is required here because each subscriber may have more than one subscription to a publication.
subscriber-id | The user ID of the subscriber to the publication. This user must have a subscription to the publication.
Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

STOP SUBSCRIPTION statement [SQL Remote]

CREATE SUBSCRIPTION statement

SYNCHRONIZE SUBSCRIPTION statement


SYNCHRONIZE SUBSCRIPTION statement

Function

Use this statement to synchronize a subscription for a user to a publication.

Syntax

SYNCHRONIZE SUBSCRIPTION
TO publication-name [ ( subscription-value) ]
FOR remote-user, ...

Parameters
Parameter | Description
publication-name | The name of the publication to which the user is being subscribed. This may include the owner of the publication.
subscription-value | A string that is compared to the subscription expression of the publication. The value is required here because each subscriber may have more than one subscription to a publication.
remote-user | The user ID of the subscriber to the publication. This user must have a subscription to the publication.
Permissions

Must have DBA authority.

Side effects

Automatic commit.

See also

SYNCHRONIZE SUBSCRIPTION statement [SQL Remote]

CREATE SUBSCRIPTION statement

START SUBSCRIPTION statement


UPDATE statement

Function

Use this statement to modify data in the database.

Syntax 1

UPDATE table-list
SET column-name = expression, ...
[ VERIFY ( column-name, ... ) VALUES ( expression, ... ) ]
[ WHERE search-condition ]
[ ORDER BY expression [ ASC | DESC ], ... ]

Syntax 2

UPDATE table
PUBLICATION publication
{ SUBSCRIBE BY expression |
OLD SUBSCRIBE BY expression
NEW SUBSCRIBE BY expression }
WHERE search-condition

expression: value | subquery

Usage

Syntax 1 and Syntax 2 are applicable only to SQL Remote.

Syntax 2 with no OLD and NEW SUBSCRIBE BY expressions must be used in a BEFORE trigger.

Syntax 2 with OLD and NEW SUBSCRIBE BY expressions can be used anywhere.

Permissions

Must have UPDATE permission for the columns being modified.

Side effects

None.

See also

UPDATE statement [SQL Remote]

CREATE TRIGGER statement


Command Reference for Adaptive Server Enterprise

About this chapter

This chapter describes the SQL Remote stored procedures, used for executing SQL Remote commands.

sp_add_article procedure
sp_add_article_col procedure
sp_add_remote_table procedure
sp_create_publication procedure
sp_drop_publication procedure
sp_drop_remote_type procedure
sp_drop_sql_remote procedure
sp_grant_consolidate procedure
sp_grant_remote procedure
sp_link_option procedure
sp_modify_article procedure
sp_modify_remote_table procedure
sp_passthrough procedure
sp_passthrough_piece procedure
sp_passthrough_stop procedure
sp_passthrough_subscription procedure
sp_passthrough_user procedure
sp_populate_sql_anywhere procedure
sp_publisher procedure
sp_queue_clean procedure
sp_queue_confirmed_delete_old procedure
sp_queue_confirmed_transaction procedure
sp_queue_delete_old procedure
sp_queue_drop procedure
sp_queue_dump_database procedure
sp_queue_dump_transaction procedure
sp_queue_get_state procedure
sp_queue_log_transfer_reset procedure
sp_queue_read procedure
sp_queue_reset procedure
sp_queue_set_confirm procedure
sp_queue_set_progress procedure
sp_queue_transaction procedure
sp_remote procedure
sp_remote_option procedure
sp_remote_type procedure
sp_remove_article procedure
sp_remove_article_col procedure
sp_remove_remote_table procedure
sp_revoke_consolidate procedure
sp_revoke_remote procedure
sp_subscription procedure
sp_subscription_reset procedure


sp_add_article procedure

Purpose

To add an article to a publication.

Syntax

sp_add_article publication_name,
table_name,
where_expr,
subscribe_by_expr,
subscribe_by_view

Argument | Description
publication_name | The name of the publication to which the article is to be added.
table_name | The table containing the article.
where_expr | This optional argument must be a column name or NULL. The publication includes only rows for which the supplied column value is not NULL. The default value is NULL, in which case no rows are excluded from the publication.
subscribe_by_expr | The new subscription expression defining which rows are to be included in the publication for each subscription. The expression must be the name of a column in table_name. The default value is NULL.
subscribe_by_view | A view defining the columns and rows to be included in the publication. For more information, see Tuning extraction performance and Tuning extraction performance for shared rows.
See also

sp_add_remote_table procedure

sp_create_publication procedure

sp_remove_article procedure

CREATE PUBLICATION statement

Description

Running sp_add_article adds an article to a publication. The table must be marked for replication using sp_add_remote_table before it can be added to a publication; failure to do so leads to an error.

Calling sp_add_article adds all the columns of the table to a publication. If you wish to include only some of the columns of the table in a publication you must first run sp_add_article and then call sp_add_article_col.

As with other data definition changes, in a production environment this procedure should only be run on a quiet SQL Remote installation.

For more information on the requirements for a quiet system, see Making schema changes.

Example

  • The following statement adds the SalesRep table to a publication named SalesRepData:

    sp_add_article 'SalesRepData', 'SalesRep'
go


sp_add_article_col procedure

Purpose

To add a column to an article in a publication.

Syntax

sp_add_article_col publication_name,
table_name,
column_name

Argument | Description
publication_name | The name of the publication to which the article is to be added.
table_name | The table containing the article.
column_name | The column to be added to the article in a publication
See also

sp_add_article procedure

sp_remove_article procedure

ALTER PUBLICATION statement

Description

Running sp_add_article_col adds a column to an article in a publication. The table must first be added to the publication using the sp_add_article procedure.

To add all the columns of a table to a publication you do not need to use sp_add_article_col; just call sp_add_article.

To add only some of the columns of a table to a publication you first call sp_add_article, and then call sp_add_article_col for each of the columns you wish to include in the publication.

As with other data definition changes, in a production environment this procedure should only be run on a quiet SQL Remote installation.

For more information on the requirements for a quiet system, see Making schema changes.

Example

  • The following statements add the emp_id and emp_lname columns of the employee table to a publication named Personnel:

    sp_add_article 'Personnel', employee'
sp_add_article_col 'Personnel', 'employee', 'emp_id'
sp_add_article_col 'Personnel', 'employee', 'emp_lname'
go


sp_add_remote_table procedure

Purpose

To mark a table for SQL Remote replication.

Syntax

sp_add_remote_table table_name,
[ resolve_procedure, ]
[ old_row_name, ]
[ remote_row_name ]

Argument | Description
table_name | The table to be marked for SQL Remote replication.
resolve_procedure | The name of a stored procedure that carries out actions when a conflict occurs.
old_row_name | The name of a table holding the values in the table when a conflict occurs.
remote_row_name | The name of a table holding the values at the remote database when a conflict-causing UPDATE statement was applied.
Authorization

You must be a system administrator to execute this procedure.

See also

sp_modify_remote_table procedure

sp_remove_remote_table procedure

Managing conflicts.

Description

Each table in a database must be marked for replication by using sp_add_remote_table before it can be included in any SQL Remote publications. After executing sp_add_remote_table, you can add the table to a publication using the sp_add_article procedure and the sp_add_article_col procedure.

The sp_add_remote_table procedure calls sp_setreplicate, which flags the table for replication. This tells Adaptive Server Enterprise to put extended information into the transaction log. This information includes the entire before and after images of the row.

The first argument is the name of the table to be marked for replication.

The remaining three arguments are optional. They are object names required only for custom conflict resolution. If you are implementing custom conflict resolution, you must supply the names of two tables, and a stored procedure. The sp_add_remote_table procedure does not check for the existence of the conflict resolution arguments: you can create them either before or after marking the table for replication.

The two tables must have the same columns and data types as table table_name.

Examples

  • The following statement marks the Customer table for replication, using default conflict resolution:

    exec sp_add_remote_table Customer

  • The following statement marks the Customer table for replication, using a stored procedure named Customer_Conflict to resolve conflicts. The old and remote rows are stored in tables named old_Customer and remote_Customer, respectively:

    exec sp_add_remote_table Customer, Customer_Conflict, old_Customer, remote_Customer


sp_create_publication procedure

Purpose

To create a publication.

Syntax

sp_create_publication publication_name

Argument | Description
publication_name | The name of the publication
See also

sp_drop_publication procedure

CREATE PUBLICATION statement

Description

Running sp_create_publication creates a publication, but one with no content. Once the publication is created, you must add articles to it using the sp_add_remote_table procedure and the sp_add_article procedure.

Example

  • The following statement creates a publication named SalesRepData:

    sp_create_publication 'SalesRepData'
go


sp_drop_publication procedure

Purpose

To drop a publication from the database.

Syntax

sp_drop_publication publication_name

Argument | Description
publication_name | The name of the publication to be dropped
See also

sp_create_publication procedure

DROP PUBLICATION statement

Description

Running sp_drop_publication drops a publication from the database. All articles that make up the publication, and subscriptions to the publication, are also dropped.

Example

  • The following statement drops the publication named SalesRep:

sp_drop_publication 'SalesRep'
go


sp_drop_remote_type procedure

Purpose

To drop a message type from the database.

Syntax

sp_drop_remote_type type_name

Argument Description
type_name The message type to drop. This must be a string containing one of the following:

  • file

  • ftp

  • smtp

  • mapi

  • vim
See also

sp_remote_type procedure

DROP REMOTE MESSAGE TYPE statement

Description

Drops the named message type from the database.

Example

  • The following statement drops the MAPI message type from the database:

    sp_drop_remote_type mapi
go


sp_drop_sql_remote procedure

Purpose

To drop the SQL Remote system objects from a database.

Syntax

sp_drop_sql_remote

See also

sp_queue_drop procedure

Description

Drops the SQL Remote system objects from the database, so that it can no longer function in a SQL Remote installation.

The sole SQL Remote object not removed is the sp_drop_sql_remote procedure itself (a procedure cannot drop itself from a database). To complete removal of SQL Remote requires that sp_drop_sql_remote be dropped explicitly after it is called.

The sp_drop_sql_remote procedure does not remove stable queue objects from the database. To remove the stable queue, use the sp_queue_drop procedure.

Example

  • The following statements remove SQL Remote system objects from a database:

    sp_drop_sql_remote_type
go
drop procedure sp_drop_sql_remote
go


sp_grant_consolidate procedure

Purpose

To identify a database immediately above the current database in a SQL Remote hierarchy, who will receive messages from the current database. This procedure applies only to Adaptive Server Enterprise databases acting as remote databases.

Syntax

sp_grant_consolidate user_name,
type_name,
address
[, frequency ]
[, send_time ]

Argument | Description
user_name | The user ID who will be able to receive SQL Remote messages.
type_name The message type to be used. This must be one of the following:

  • file

  • ftp

  • smtp

  • mapi

  • vim
address | A string holding the address, according to the specified message type, to which the replication messages should be sent for this user.
frequency A string containing one of the following:

  • SEND EVERY Indicates that messages are sent at a frequency specified by send_time.

  • SEND AT Indicates that messages are sent at a time of day specified by send_time.
send_time A string containing a time specification with the following meaning:

  • If frequency is SEND EVERY, specifies a length of time between messages.

  • If frequency is SEND AT, specifies a time of day at which messages will be sent.

If no frequency is specified, the Message Agent sends messages, and then stops.
See also

sp_grant_remote procedure

sp_revoke_consolidate procedure

GRANT CONSOLIDATE statement

Description

If the Adaptive Server Enterprise server is acting as a remote database in a SQL Remote installation, the single database above the current database must be granted consolidated permissions using the sp_grant_consolidate procedure.

The consolidated user is identified by a message system, identifying the method by which messages are sent to and received from the consolidated user. The address-name must be a valid address for the message-system, enclosed in single quotes.

The sp_grant_consolidate procedure is required for the remote database to receive messages, but does not by itself subscribe the remote user to any data. To subscribe to data, a subscription must be created for the user ID to one of the publications in the current database.

The optional frequency argument specifies a frequency at which messages are sent. The send_time argument contains a time that is a length of time between messages (for SEND EVERY) or a time of day at which messages are sent (for SEND AT). With SEND AT, messages are sent once per day.

If no frequency argument is supplied, the Message Agent processes messages, and then stops. In order to run the Message Agent continuously, you must ensure that every user with remote or consolidated permission has a frequency specified.

Example

  • The following statement grants consolidated permissions to user hq_user, using a file sharing system, sending messages to the address hq_dir: No frequency arguments are specified, and the Message Agent will run in batch mode.

    sp_grant_consolidate
   @user_name=hq_user,
   @address=hq_dir,
   @type_name=file
go


sp_grant_remote procedure

Purpose

To identify a database immediately below the current database in a SQL Remote hierarchy, who will receive messages from the current database. These are called remote users.

Syntax

sp_grant_remote user_name,
type_name,
address
[, frequency ]
[, send_time ]

Argument | Description
user_name | The user ID who will be able to receive SQL Remote messages.
type_name The message type to be used. This must be one of the following:

  • file

  • ftp

  • smtp

  • mapi

  • vim
address | A string holding the address, according to the specified message type, to which the replication messages should be sent for this user.
frequency A string containing one of the following:

  • SEND EVERY Indicates that messages are sent at a frequency specified by send_time.

  • SEND AT Indicates that messages are sent at a time of day specified by send_time.
send_time An optional string containing a time specification with the following meaning:

  • If frequency is SEND EVERY, specifies a length of time between messages.

  • If frequency is SEND AT, specifies a time of day at which messages will be sent.

If no frequency is specified, the Message Agent sends messages, and then stops.
See also

sp_revoke_remote procedure

GRANT REMOTE statement

Description

In a SQL Remote installation, each database receiving messages from the current database must be granted REMOTE permissions using the sp_grant_remote procedure.

The remote user is identified by a message system, identifying the method by which messages are sent to and received from the consolidated user. The address-name must be a valid address for the message-system, enclosed in single quotes.

The sp_grant_remote procedure is required for the remote database to receive messages, but does not by itself subscribe the remote user to any data. To subscribe to data, a subscription must be created for the user ID to one of the publications in the current database.

The optional frequency argument specifies a frequency at which messages are sent. The send_time argument contains a time that is a length of time between messages (for SEND EVERY) or a time of day at which messages are sent (for SEND AT). With SEND AT, messages are sent once per day.

If no frequency argument is supplied, the Message Agent processes messages, and then stops. In order to run the Message Agent continuously, you must ensure that every user with REMOTE permission has a frequency specified.

It is anticipated that at many consolidated databases, the Message Agent will be run continuously, so that all remote databases would have a frequency argument specified. A typical setup may involve sending messages to laptop users daily (SEND AT) and to remote servers every hour or two (SEND EVERY). You should use as few different times as possible, for efficiency.

Example

  • The following statement grants remote permissions to user SamS, using a MAPI e-mail system, sending messages to the address Singer, Samuel once every two hours:

    exec sp_grant_remote 'SamS',
   'mapi',
   'Singer, Samuel',
   'SEND EVERY',
   '02:00'
go


sp_link_option procedure

Purpose

To set a message control parameter for a SQL Remote message link.

Syntax

sp_link_option link-name,
userid,
option-name,
option-value

Parameters

link-name:
file | ftp | mapi | smtp | vim

link-option-name:
file-option | ftp-option | mapi-option | smtp-option | vim-option

file-option:
debug | directory | unlink_delay

ftp-option:
active_mode | debug | host
| password | port | root_directory | user

mapi-option:
debug | force_download
| ipm_receive | ipm_send | profile

smtp-option:
debug | local_host | pop3_host | pop3_password
| pop3_userid | smtp_host | top_supported

vim-option:
debug | password | path | receive_all
| send_vim_mail | userid

link-option-value:
string

Permissions

Must have DBA authority. The publisher can set their own options.

Side effects

Automatic commit.

See also

SET REMOTE OPTION statement

Description

The Message Agent saves message link parameters when the user enters them in the message link dialog box when the message link is first used. In this case, it is not necessary to use this procedure explicitly. This procedure is most useful when preparing a consolidated database for extracting many databases.

The option names are case sensitive. The case sensitivity of option values depends on the option: boolean values are case insensitive, while the case sensitivity of passwords, directory names, and other strings depend on the cases sensitivity of the file system (for directory names), or the database (for user IDs and passwords).

userid If no userid is specified, then the current publisher is assumed.

Option values The option values are message-link dependent. For more information, see the following locations:

  • The file message system.

  • The ftp message system.

  • The MAPI message system.

  • The SMTP message system.

  • The VIM message system.

Example

The following statement sets the FTP host to ftp.mycompany.com for the ftp link for user myuser:

exec sp_link_option ftp, myuser,
   host, 'ftp.mycompany.com'


sp_modify_article procedure

Purpose

To change the description of an article in a procedure.

Syntax

sp_modify_article
publication_name,
table_name,
[ where_expr, ]
[ subscribe_by_expr ]
[ subscribe_by_view ]

Argument | Description
publication_name | The name of the publication for which the article is to be modified.
table_name | The table containing the article.
where_expr | This optional argument must be a column name or NULL. The publication includes only rows for which the supplied column name is not NULL. The default value is NULL, in which case no rows are excluded from the publication..
subscribe_by_expr | The new subscription expression defining which rows are to be included in the publication for each subscription. The default value is NULL.
subscribe_by_view | A view defining the rows and columns to be included in the publication. The default is NULL. For more information, see Tuning extraction performance and Tuning extraction performance for shared rows.
See also

sp_add_article procedure

sp_remove_article procedure

ALTER PUBLICATION statement

Description

To change the description of an article in a publication. The WHERE expression, the subscription expression, and the subscription view can each be changed.

As with other data definition changes, in a production environment this procedure should only be run on a quiet SQL Remote installation.

For more information on the requirements for a quiet system, see Making schema changes.

Examples

The following statement changes an article in the SalesRepData publication that takes information from the Customer table, so that it has no subscription expression:

sp_modify_article SalesRepData, Customer
go

The following statement changes an article in the SalesRepData publication that takes information from the Customer table, so that it has a subscription expression that is the rep_key column:

sp_modify_article SalesRepData,    Customer,
   NULL, rep_key
go


sp_modify_remote_table procedure

Purpose

To change the resolution objects for a table marked for SQL Remote replication.

Syntax

sp_modify_remote_table table_name,
[ resolve_name, ]
[ old_row_name, ]
[ remote_row_name ]

Argument | Description
table_name | A table marked for SQL Remote replication.
resolve_procedure | The name of the new stored procedure for carrying out actions when a conflict occurs.
old_row_name | The name of the new table for holding the values in the table when a conflict occurs.
remote_row_name | The name of the new table for holding the values at the remote database when a conflict-causing UPDATE statement was applied.
See also

sp_add_remote_table procedure

sp_remove_remote_table procedure

Managing conflicts.

Description

Each table in a database must be marked for replication by using sp_add_remote_table before it can be included in any SQL Remote publications.

The sp_modify_remote_table allows you to change the way in which conflict resolution is carried out for update conflicts occurring on this table.

The arguments are, in addition to the table name, the object names required for custom conflict resolution. If you are implementing custom conflict resolution, you must supply the names of two tables, and a stored procedure. The sp_modify_remote_table procedure does not check for the existence of the conflict resolution arguments: you can create them either before or after marking the table for replication.

The two tables must have the same columns and data types as table table_name.

Example

The following statement instructs SQL Remote to use the resolve_Cust procedure, the old_Cust table, and the remote_Cust table to resolve update conflicts on the Customer table:

sp_add_remote_table Customer, resolve_Cust,
   old_Cust, remote_Cust
go


sp_passthrough procedure

Purpose

To send a SQL statement in passthrough mode.

Syntax

sp_passthrough statement

Argument | Description
statement | A string containing a statement to be executed in passthrough mode.
See also

sp_passthrough_piece procedure

sp_passthrough_stop procedure

sp_passthrough_subscription procedure

sp_passthrough_user procedure

PASSTHROUGH statement

Description

To send passthrough operations. The recipients of the passthrough statement are determined by previous calls to sp_passthrough_user and sp_passthrough_subscription.

The string must be less than 255 characters long. For SQL statements longer than 255 characters, you should execute a sequence of calls to the sp_passthrough_piece procedures, and execute sp_passthrough for the final piece of the statement and to cause the replication to occur.

Caution You should always test your passthrough operations on a test database with a remote database subscribed. You should never run untested passthrough scripts against a production database.
Example

  • The following statement sends a create table statement to the current recipients of passthrough statements.

    exec sp_passthrough
   'CREATE TABLE simple (
      id integer NOT NULL,
      name char(50) )'
go


sp_passthrough_piece procedure

Purpose

To build a long SQL statement for passthrough.

Syntax

sp_passthrough_piece string

Argument | Description
string | A piece of a statement to be executed in passthrough mode.
See also

sp_passthrough procedure

sp_passthrough_stop procedure

sp_passthrough_subscription procedure

sp_passthrough_user procedure

PASSTHROUGH statement

Description

The sp_passthrough procedure is used to send statements directly to a set of remote users. Statements that are longer than 255 characters have to be built up piece by piece.

To build and send a long SQL statement, call sp_passthrough_piece for all but the final piece of the statement, and then call sp_passthrough for the final piece. This completes and replicates the statement.

All pieces of a passthrough statement must be built within a single transaction.

Example

  • The following statements send a long passthrough statement to the current list of passthrough recipients:

    begin transaction
go
exec sp_passthrough_piece 'CREATE TABLE
   DBA.employee
   (
   emp_id  integer NOT NULL,
   manager_id  integer NULL,
   emp_fname  char(20) NOT NULL,
   emp_lname  char(20) NOT NULL,'
go
exec sp_passthrough_piece '
   dept_id  integer NOT NULL,
   street  char(40) NOT NULL,
   city  char(20) NOT NULL,
   state  char(4) NOT NULL,
   zip_code  char(9) NOT NULL,
   phone  char(10) NULL,'
go
exec sp_passthrough_piece 'status  char(1) NULL,
   ss_number  char(11) NOT NULL,
   salary  numeric(20,3) NOT NULL,
   start_date  date NOT NULL,
   termination_date  date NULL,
   birth_date  date NULL,'
go
exec sp_passthrough '
   bene_health_ins  char(1) NULL,
   bene_life_ins  char(1) NULL,
   bene_day_care  char(1) NULL,
   sex  char(1) NULL,
   PRIMARY KEY (emp_id),
   )'
go
commit
go


sp_passthrough_stop procedure

Purpose

Resents passthrough mode

Syntax

sp_passthrough_stop

See also

sp_passthrough procedure

sp_passthrough_subscription procedure

sp_passthrough_user procedure

PASSTHROUGH statement

Description

The sp_passthrough_stop procedure resents the list of recipients of passthrough statements to be empty, and clears any statements that are currently being built.

Example

  • The following statement resets the passthrough recipient list to be empty.

    exec sp_passthrough_stop
go


sp_passthrough_subscription procedure

Purpose

Adds subscribers to a given publication to the recipient list for passthrough statements.

Syntax

sp_passthrough_subscription publication_name,
subscribe_by

Argument | Description
publication_name | The name of the publication
subscribe_by | The subscription value for recipients to receive passthrough statements.
See also

sp_passthrough procedure

sp_passthrough_piece procedure

sp_passthrough_stop procedure

sp_passthrough_user procedure

PASSTHROUGH statement

Description

This is one of two ways that you can add to the list of recipients for passthrough statements, the other being to use the sp_passthrough_user procedure.

The users that are added to the recipient list by a call to the sp_passthrough_subscription procedure are all those users subscribing to the publication publication_name with a subscription value of subscribe_by.

The default setting for subscribe_by is NULL. In this case, all subscribers to the publication receive the passthrough statements.

Example

  • The following statement adds to the list of passthrough recipients the subscriber or subscribers to the SalesRepData publication who use subscription values of 'rep1'.

    sp_passthrough_subscription SalesRepData, rep1


sp_passthrough_user procedure

Purpose

Adds a named user to the list of recipients for passthrough statements.

Syntax

sp_passthrough_user user_name

Argument | Description
user_name | The user to be added to the list of recipients.
See also

sp_passthrough procedure

sp_passthrough_piece procedure

sp_passthrough_stop procedure

sp_passthrough_subscription procedure

PASSTHROUGH statement

Description

This is one of two ways that you can add to the list of recipients for passthrough statements, the other being to use the sp_passthrough_subscription procedure.

The sp_passthrough_user procedure adds the named user to the list of recipients for passthrough statements. The list remains in force until reset using the sp_passthrough_stop procedure.

Example

  • The following statement adds the user field_user to the list of recipients for passthrough statements:

    sp_passthrough_user 'field_user'
go


sp_populate_sql_anywhere procedure

Purpose

To create a copy of the Adaptive Server Anywhere system tables in the TEMPDB. This procedure is used by the extraction utility ssxtract.

Syntax

sp_populate_sql_anywhere

Description

To create a set of Adaptive Server Anywhere system tables for a remote Adaptive Server Anywhere database, in TEMPDB. The information is used by the extraction utility to construct an Adaptive Server Anywhere database schema from the set of publications in the Adaptive Server Enterprise consolidated database.

This procedure is used by the ssxtract extraction utility. It should not be called directly.


sp_publisher procedure

Purpose

To set the publisher of the current database, or to remove the publisher.

Syntax

sp_publisher [ user_name ]

Argument | Description
user_name | The user ID to be identifies as the publisher for the database.
See also

Managing SQL Remote permissions.

GRANT PUBLISH statement

Description

Each database in a SQL Remote installation is identified in outgoing messages by a user ID, called the publisher. The sp_publisher procedure sets the publisher user ID associated with these outgoing messages.

Each database can have at most one publisher; if a publisher already exists, sp_publisher changes the name of the publisher.

If no user_name argument is provided, the current publisher is removed, so that the database has no publisher. Only the permission to be the publisher is removed; the user ID is not removed from the database.

Examples

  • The following statement identifies the user ID joe as the publisher of the current database:

    sp_publisher joe
go

  • The following statement sets the current database to have no publisher:

    sp_publisher
go


sp_queue_clean procedure

Purpose

This procedure is used by the SQL Remote Message Agent, and should not be called directly.

Syntax

sp_queue_clean

Description

This procedure is used by the SQL Remote Message Agent, and should not be called directly. It removes from the stable queue any transactions that completed after the start of the oldest incomplete transaction the last time the log was scanned.


sp_queue_confirmed_delete_old procedure

Purpose

This procedure is used by the SQL Remote Message Agent, and should not be called directly.

Syntax

sp_queue_confirmed_delete_old

Description

This procedure is used by the SQL Remote Message Agent, and should not be called directly. It removes from the stable queue any transactions whose offsets are shown in sr_confirmed_transaction.


sp_queue_confirmed_transaction procedure

Purpose

This procedure is used by the SQL Remote Message Agent, and should not be called directly.

Syntax

sp_queue_confirmed_transaction offset

Description

This procedure is used by the SQL Remote Message Agent, and should not be called directly. It adds the supplied offset to sr_confirmed_transaction. SQL Remote removes from the stable queue any transactions whose offsets match this offset.


sp_queue_delete_old procedure

Purpose

This procedure is used by the SQL Remote Message Agent, and should not be called directly.

Syntax

sp_queue_delete_old

Description

This procedure is used by the SQL Remote Message Agent, and should not be called directly. It deletes from the stable queue any transactions that have been confirmed by all remote databases.


sp_queue_drop procedure

Purpose

To drop the stable queue objects from a database.

Syntax

sp_queue_drop

See also

sp_drop_sql_remote procedure

Description

Drops the stable queue system objects from the database, so that the database no longer supports a SQL Remote stable queue.

The sole stable queue object not removed is the sp_queue_drop procedure itself (a procedure cannot drop itself from a database). To complete removal of the stable queue requires that sp_queue_drop be dropped explicitly after it is called.

The sp_queue_drop procedure does not remove SQL Remote system objects from the database. To remove the SQL Remote system objects, use the sp_drop_sql_remote procedure.

Examples

  • The following statements remove the stable queue objects from the database:

    sp_queue_drop
go
drop procedure sp_queue_drop
go


sp_queue_dump_database procedure

Purpose

To facilitate recovery from media failure when the stable queue is in a separate database from the SQL Remote objects.

Syntax

sp_queue_dump_database

See also

sp_queue_dump_transaction procedure

Stable queue recovery issues

Description

Keeping the stable queue in a separate database complicates backup and recovery, as consistent versions of the two databases have to be recovered.

Normal recovery automatically restores the two databases to a consistent state, but recovery from media failure takes some care. When restoring database dumps, it is important to recover the stable queue to a consistent point. The sp_queue_dump_database procedure is provided to help with recovery from media failure. It is called whenever a dump database is scanned.

As provided, the procedure does not carry out any operations. You can modify this stored procedure to issue a dump database command in the stable store database.


sp_queue_dump_transaction procedure

Purpose

To facilitate recovery from media failure, when the stable queue is in a separate database from the SQL Remote objects.

Syntax

sp_queue_dump_transaction

See also

sp_queue_dump_database procedure

Stable queue recovery issues

Description

Keeping the stable queue in a separate database complicates backup and recovery, as consistent versions of the two databases have to be recovered.

Normal recovery automatically restores the two databases to a consistent state, but recovery from media failure takes some care. When restoring database dumps, it is important to recover the stable queue to a consistent point. The sp_queue_dump_transaction procedure is provided to help with recovery from media failure. It is called whenever a dump transaction is scanned.

As provided, the procedure does not carry out any operations. You can modify this stored procedure to issue a dump transaction command in the stable store database.


sp_queue_get_state procedure

Purpose

This procedure is used by the SQL Remote Message Agent, and should not be called directly.

Syntax

sp_queue_get_state

Description

This procedure is used by the SQL Remote Message Agent, and should not be called directly. It returns a description of the current state of the stable queue.


sp_queue_log_transfer_reset procedure

Purpose

This procedure is used by the SQL Remote Message Agent, and should not be called directly.

Syntax

sp_queue_log_transfer_reset

Description

This procedure is used by the SQL Remote Message Agent, and should not be called directly. It resets the page and row IDs to zero in the sr_queue_state table.


sp_queue_read procedure

Purpose

This procedure is used by the SQL Remote Message Agent, and should not be called directly.

Syntax

sp_queue_read start_offset,
stop_offset

Description

This procedure reads transactions from the stable queue. It is exclusively for use by the Message Agent.


sp_queue_reset procedure

Purpose

To reset the server to a point where the stable queue is empty.

Syntax

sp_queue_reset

Description

This procedure is used by the SQL Remote Message Agent, and should not be called directly in a production environment. It deletes all rows from the stable queue sr_transaction table, and resets the sr_queue_state table, ready for a new SQL Remote setup.

In a development phase, this procedure can be useful to reset the server.


sp_queue_set_confirm procedure

Purpose

This procedure is used by the SQL Remote Message Agent, and should not be called directly.

Syntax

sp_queue_set_confirm confirm_offset

Description

This procedure is used by the SQL Remote Message Agent, and should not be called directly. It sets the minimum confirmation offset from all remote users in the sr_queue_state table.


sp_queue_set_progress procedure

Purpose

This procedure is used by the SQL Remote Message Agent, and should not be called directly.

Syntax

sp_queue_set_progress page_id,
row_id,
commit_offset,
backup_offset,
marker

Description

This procedure is used by the SQL Remote Message Agent, and should not be called directly. It sets the transaction log scanning progress value in the sr_queue_state table.


sp_queue_transaction procedure

Purpose

This procedure is used by the SQL Remote Message Agent, and should not be called directly.

Syntax

sp_queue_transaction offset,
user_id

Description

This procedure is used by the SQL Remote Message Agent, and should not be called directly. It adds a new transaction to the stable queue.


sp_remote procedure

Purpose

This procedure is used by the SQL Remote Message Agent, and should not be called directly, with a single exception described below. It manages rows in the sr_remoteuser table.

Syntax

sp_remote operation,
user_name
[ , offset ]
[ , confirm ]

Argument | Description
operation | The name of an action. The only value that should be used by a user is reset; all others are for use by the Message Agent.
user_name | The name of the remote user being reset
offset | Not used
confirm | Not used
Description

This procedure is used by the SQL Remote Message Agent, and should not be called directly with the single exception of the reset call. It maintains the message tracking information in the sr_remoteuser table.

The following special case can be used directly, when creating a custom database extraction process:

sp_remote reset, remote_user

where remote_user is the remote user name.

This command starts all subscriptions for a remote user in a single transaction. It sets the log_sent and confirm_sent values in sr_remoteuser table to the current position in the transaction log. It also sets the created and started values in sr_subscription to the current position in the transaction log for all subscriptions for this remote user. The procedure does not do a commit. You must do an explicit commit after this call.

In order to write an extraction process that is safe on a live database, the data must be extracted at isolation level 3 in the same transaction as the subscriptions are started.


sp_remote_option procedure

Purpose

To set a SQL Remote option.

Syntax

sp_remote_option option_name,
option_value

Argument | Description
option_name | The name of one of the SQL Remote options
option_value | The value to which the option is set.
See also

SQL Remote options.

Description

The SQL Remote options provide control over replication behavior. The following options are available in Adaptive Server Enterprise:

OPTION | VALUES | DEFAULT
Blob_threshold | Integer, in K | 256
Compression | -1 to 9 | 6
Delete_old_logs | ON, OFF | OFF
Qualify_owners | ON, OFF | ON
Quote_all_identifiers | ON, OFF | OFF
Replication_error | procedure-name | NULL
SR_Date_Format | time-string | hh:mm:ss.Ssssss
SR_Time_Format | date-string | yyyy/mm/dd
SR_Timestamp_Format | timestamp-string | yyyy/mm/dd hh:nn:ss.Ssssss
Subscribe_by_remote | ON,OFF | ON
Verify_threshold | integer | 256
Verify_all_columns | ON,OFF | OFF

For a complete description of these options, see SQL Remote options.

Example

  • The following statement sets the Verify_all_columns option to OFF, so that old values of update statements applied by the Message Agent are not checked automatically for all columns.

    sp_remote_option Verify_all_columns, OFF
go


sp_remote_type procedure

Purpose

To create or modify a SQL Remote message type.

Syntax

sp_remote_type type_name publisher_address

Argument | Description
type_name The message type to create or alter. This must be one of the following:

  • file

  • ftp

  • smtp

  • mapi

  • vim
publisher_address | The address of the publisher under the specified message type.
See also

sp_drop_remote_type procedure

ALTER REMOTE MESSAGE TYPE statement

Description

The Message Agent sends outgoing messages from a database using one of the supported message links. Return messages for users employing the specified link are sent to the specified address as long as the remote database is created by the Extraction Utility. The Message Agent starts links only if it has remote users for those links.

The address is the publisher's address under the specified message system. If it is an e-mail system, the address string must be a valid e-mail address. If it is a file-sharing system, the address string is a subdirectory of the directory set in the SQLREMOTE environment variable or registry entry, or of the current directory if that is not set.

Example

The following example creates a FILE message type for a database, and gives the publisher's address as a subdirectory of the SQLREMOTE location named publisher:

sp_remote_type file, publisher
go


sp_remove_article procedure

Purpose

To remove an article from a publication

Syntax

sp_remove_article publication_name,
table_name

Argument | Description
publication_name | The name of the publication from which the article is to be deleted.
table_name | The table containing the article.
See also

sp_add_article procedure

ALTER PUBLICATION statement

Description

Running sp_add_article removes an article from a publication. Any article including parts of the named table is removed from the publication.

Example

  • The following statement removes any articles that use part of the SalesRep table from a publication named SalesRepData:

    sp_remove_article SalesRepData, SalesRep
go


sp_remove_article_col procedure

Purpose

To remove a column from an article in a publication.

Syntax

sp_remove_article_col publication_name,
article_name,
column_name

Argument | Description
publication_name | The name of the publication to which the article belongs.
article_name | The article from which the column is to be removed.
column_name | The column to be removed from the article.
See also

sp_add_article_col procedure

sp_remove_article procedure

ALTER PUBLICATION statement

Description

You can remove a column from a publication using sp_remove_article_col.

To remove a column using sp_remove_article_col, the column must have been explicitly added to a publication using the sp_add_article_col procedure. Although the sp_add_article procedure, without use of sp_add_article_col, adds all the columns of a table to a publication, you cannot remove a single column from such a publication using sp_remove_article_col.

Example

  • The following statement removes the column emp_lname of the employee table from a publication named Personnel:

    sp_remove_article_col 'Personnel', 'employee', 'emp_lname'
go


sp_remove_remote_table procedure

Purpose

To mark a table as unavailable for SQL Remote replication.

Syntax

sp_remove_remote_table table_name

Argument | Description
table_name | The table to be marked as not available for SQL Remote replication.
See also

sp_add_remote_table procedure

sp_modify_remote_table procedure

Description

Marks a table as unavailable for replication. Once this procedure has been called, the data in the table cannot be shared with other databases using SQL Remote.

Example

  • The following statement marks the employee table as unavailable for replication:

    sp_remove_remote_table employee
go


sp_revoke_consolidate procedure

Purpose

To stop a user from being able to receive SQL Remote messages from this database.

Syntax

sp_revoke_consolidate user_name

Argument | Description
user_name | The user ID who will no longer be able to act as a consolidated database.
See also

sp_grant_consolidate procedure

Description

The sp_revoke_consolidate procedure removes the consolidated database user ID from the list of users receiving messages from the current database.

Example

  • The following statement revokes consolidated permissions from user hq_user:

    sp_revoke_consolidate hq_user
go


sp_revoke_remote procedure

Purpose

To stop a user from being able to receive SQL Remote messages from this database.

Syntax

sp_revoke_remote user_name

Argument | Description
user_name | The user ID who will no longer be able to receive SQL Remote messages.
See also

sp_grant_remote procedure

Description

The sp_revoke_remote procedure removes a user ID from the list of users receiving messages from the current database.

Example

  • The following statement revokes remote permissions from user Field User:

    sp_revoke_remote 'Field user'
go


sp_subscription procedure

Purpose

To manage subscriptions.

Syntax

sp_subscription operation,
publication_name,
user_name,
[ subscribe_by ]

Argument | Description
operation The operation to be performed. This must be one of the following:

  • create To create a subscription to a given publication for a user.

  • drop To drop a subscription to a given publication for a user.

  • start To start a subscription to the named publication.

  • stop To stop a subscription to the named publication.

  • synchronize To synchronize a subscription to the named publication.
publication_name | The name of the publication to which the subscription refers.
user_name | The user ID who is being subscribed to the publication.
subscribe_by | The subscription value.
See also

Creating subscriptions.

Description

The sp_subscription procedure is used to manage subscriptions. The first argument to the procedure (operation) specified whether the procedure is being created, dropped, started, stopped, or synchronized.

In general, starting and synchronizing subscriptions is done using the extraction utility.

Example

  • The following statement creates a subscription for user SalesRep1 to the SalesRepData publication, which has no subscription expression.

    sp_subscription create,
   SalesRepData,
   SalesRep1
go


sp_subscription_reset procedure

Purpose

To reset all SQL Remote information for all remote users.

Syntax

sp_subscription_reset

Description

This procedure resets all the entries in the sr_remote_user and sr_subscription tables to zero or NULL.


SQL Remote for Adaptive Server Enterprise and Adaptive Server Anywhere: Differences

About this Appendix

This appendix summarizes the differences between SQL Remote for Adaptive Server Enterprise and for Adaptive Server Anywhere.

This appendix describes the main differences between these versions of the technology.


Types of difference

The differences between the versions of the software are of the following kinds:

  • Functionality Tasks that can be carried out by one of the two versions, but not by the other.

  • Approach Although a similar result can be obtained, a different approach is required in each version. This includes tasks that are carried out in ways that are superficially different, but which have the same result.

  • Server differences Tasks associated with SQL Remote, such as backup management, are different for the two servers. These differences are not described here.

This appendix addresses only replication using Adaptive Server Anywhere as remote databases. There are additional limitations if using Adaptive Server Enterprise as remote servers.


Differences in functionality

The major differences in functionality between SQL Remote for Adaptive Server Enterprise (SRE) and SQL Remote for Adaptive Server Anywhere (SRA) are as follows:

  • Schema changes For SRE, schema changes must be made on a quiet system. A quiet system means the following:

    • No transactions being replicated There can be no transactions being replicated that modify the tables that are to be altered. All transactions that modified tables being altered must be scanned from the transaction log into the stable queue before the schema is altered. This is performed by running the Message Agent normally, or using the -I -b options. After the Message Agent completes, you can make the schema change.

    • Message Agent shut down The Message Agent must be shut down when the schema change is being made.

    • SQL Remote Open Server If you are using the SQL Remote Open Server, it must be shut down when the schema change is being made.

  • Trigger action replication In SRE, trigger actions are replicated. In SRA you have the choice of replicating trigger actions, but by default they are not replicated. The replication of trigger actions requires SRE users to ensure that triggers are not fired at remote databases.

  • Platform availability SRA is available on a wider variety of platforms that SRE, reflecting the platform availability of the two servers.

  • Publication definitions Publications in SRA can be more selective than those in SRE. For example, in SRA you can use a WHERE clause with any value. In SRE, you can only use IS NULL and IS NOT NULL conditions in the WHERE clause.


Differences in approach

There are some features of SQL Remote that must be approached in a different manner in SRE and SRA.

  • Partitioning tables that do not contain the subscription expression In SRA, publications can contain subqueries, and these allow tables that do not contain a partition expression to nevertheless be distributed properly among subscribers. In SRE, an additional column must be added to such tables, containing a list of subscribers, and triggers must be written to maintain the column. This column can have a maximum size of 255.

    For descriptions, see Partitioning tables that do not contain the subscription expression, and Partitioning tables that do not contain the subscription column.

  • Conflict resolution In SRA, conflict resolution is carried out using a special trigger syntax. In SRE, stored procedures must be written to carry out this task.

    For descriptions, see Managing conflicts, and Managing conflicts.

  • Storing messages before sending In SRE, a separate table named the stable queue is used to hold changes before replication. In SRA, there is no stable queue; instead, the messages are retrieved from current and old transaction log files.

  • Commands Whereas SQL Remote tasks such as creating publications are carried out using SQL statements in SRA, they are carried out using system stored procedures in SRE.

Adaptive Server Enterprise procedures and Adaptive Server Anywhere statements


Adaptive Server Enterprise procedures and Adaptive Server Anywhere statements

In SQL Remote for Adaptive Server Anywhere, SQL statements are used to carry out the tasks that these stored procedures carry out in Adaptive Server Enterprise. The following table lists the SQL Remote procedures, and how they correspond to SQL statements in Adaptive Server Anywhere:

Adaptive Server Enterprise procedure | Corresponding Adaptive Server Anywhere statement
sp_remote_type | CREATE REMOTE MESSAGE TYPE
sp_remote_type | ALTER REMOTE MESSAGE TYPE
sp_drop_remote_type | DROP REMOTE MESSAGE TYPE
sp_grant_remote | GRANT REMOTE
sp_revoke_remote | REVOKE REMOTE
sp_publisher | GRANT PUBLISH
sp_publisher | REVOKE PUBLISH
sp_create_publication sp_add_article sp_add_article_col | CREATE PUBLICATION
sp_add_article sp_remove_article sp_add_article_col sp_remove_article_col | ALTER PUBLICATION
sp_drop_publication | DROP PUBLICATION
sp_subscription 'create' | CREATE SUBSCRIPTION
sp_subscription 'drop' | DROP SUBSCRIPTION
sp_subscription 'start' | START SUBSCRIPTION
sp_subscription 'stop' | STOP SUBSCRIPTION
sp_subscription 'synchronize' | SYNCHRONIZE SUBSCRIPTION
sp_passthrough_user | PASSTHROUGH FOR USERID
sp_passthrough_subscription | PASSTHROUGH FOR SUBSCRIPTION
sp_passthrough_stop | PASSTHROUGH STOP


Limitations for Enterprise to Enterprise replication

If you wish to use SQL Remote for replication between Adaptive Server Enterprise databases, rather than with Adaptive Server Anywhere remote databases, you should be aware of the following limitations:

  • Database extraction The extraction utility creates RELOAD.SQL scripts and data files for building Adaptive Server Anywhere remote databases. Setting up remote ASE databases requires an extraction process created by the customer.

    For more information about how to create an extraction process, see sp_remote procedure.

  • Referential integrity errors Referential integrity is always checked immediately in Adaptive Server Enterprise, while Adaptive Server Anywhere provides the WAIT_FOR_COMMIT option to control when integrity is checked. This presents difficulties when rows move between remote databases, as in territory realignment.

    For example, suppose an Order table has a foreign key to a Customer table which has a foreign key to a SalesRep table. The Customer table is subscribed by sales rep. The Order table is also subscribed by sales rep (it has a redundant column maintained by a trigger).

    When a row in Customer is updated to point to a new sales rep, a trigger fires to update the sales rep column in Order. The update on Customer is replicated as a delete to the old rep and an insert to the new rep. Similarly, the triggered update on Order is replicated as a delete to the old rep and an insert to the new rep.

    The problem occurs because SQL Remote replicates the operations in the order they occur, which means the Customer row is deleted before the Order rows. This causes a referential integrity error.

  • Schema upgrades Schema upgrades are difficult to manage when both consolidated and remote databases are Adaptive Server Enterprise databases. Passthrough to remote Adaptive Server Enterprise databases is difficult to carry out.

    The problem is due to the need for a quiet system for schema upgrades (see Differences in functionality). Passthrough puts schema upgrade statements into the normal message stream. The operations that precede the schema upgrade (in the same message or a previous message) cannot possibly have been scanned from the transaction log into the stable queue before the schema change takes place.

  • Synchronize subscription This is not implemented for Adaptive Server Enterprise remote databases.


Supported Platforms and Message Links

About this Appendix

This appendix summarizes the platforms and message links that SQL Remote supports.


Supported message systems

SQL Remote exchanges data among databases using an underlying message system. SQL Remote supports the following message systems:

  • File sharing A simple system requiring no extra software.

  • FTP Internet file transfer protocol.

  • SMTP/POP Internet e-mail protocol.

  • MAPI Microsoft Messaging Application Programming Interface, used in Microsoft products and in cc:Mail release 8 and later.

  • VIM Vendor Independent Messaging, used in Lotus Notes and in some versions of Lotus cc:Mail.

Not all systems are supported on all operating systems. For all systems other than the file sharing system, you must have purchased and installed the appropriate message system software for SQL Remote to function over this system. SQL Remote does not include the underlying message system software.


Supported operating systems

SQL Remote for Adaptive Server Enterprise

SQL Remote for Adaptive Server Enterprise is available for the following operating systems and message links:

  • Windows NT/2000/XP All message protocols.

  • Sun Microsystems Solaris/Sparc File sharing, FTP, and SMTP/POP only.

SQL Remote for Adaptive Server Anywhere

SQL Remote for Adaptive Server Anywhere is available for the following operating systems:

  • Windows 95/98/Me All message links.

  • Windows NT/2000/XP All message links.

  • Windows CE FILE, FTP, and SMTP/POP links. For the file link, dbremote looks in \My Documents\Synchronized Files. On the desktop machine, the SQLREMOTE environment variable or directory message link parameter for the FILE link should be set to the following:

%SystemRoot%\Profiles\userid\Personal\ce-machine-name\ Synchronized Files

where userid and ce-machine-name are set to the appropriate values. With this setup, ActiveSync automatically synchronizes the message files between the desktop and CE system.

Check Mobile Devices > Tools > ActiveSync Options to ensure that file synchronization is activated.

For information on setting message link parameters, see The file message system.

  • Sun Microsystems Solaris/Sparc File sharing, FTP, and SMTP/POP only.

  • Novell NetWare File sharing, FTP, and SMTP/POP only.

  • Linux File sharing, FTP, and SMTP/POP only.

For details of the supported UNIX operating system versions, see the SQL Anywhere Studio Read Me First for UNIX.


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Version 9.0.2

DC38176-01-0902-01

October 2004

Copyright
About This Manual
Connect Dialog Help
ODBC Configuration Dialog Help
Adaptive Server Anywhere Help
Interactive SQL Help
MobiLink Help
MobiLink Monitor Help
Query Editor Help
Adaptive Server Anywhere Console Utility Help
SQL Language Links
UltraLite Schema Painter Help
UltraLite Interactive SQL Help


About This Manual

Subject

This manual provides context-sensitive help for the Connect dialog, the Query Editor, the MobiLink Monitor, the Adaptive Server Anywhere Console utility, the Index Consultant, and the UltraLite Schema Painter. It also contains context-sensitive help for all the property sheets and dialog boxes that are available in Sybase Central, as well as for MobiLink wizards.

Audience

This manual is for all users of SQL Anywhere Studio.


SQL Anywhere Studio documentation

This book is part of the SQL Anywhere documentation set. This section describes the books in the documentation set and how you can use them.

The SQL Anywhere Studio documentation

The SQL Anywhere Studio documentation is available in a variety of forms: in an online form that combines all books in one large help file; as separate PDF files for each book; and as printed books that you can purchase. The documentation consists of the following books:

  • Introducing SQL Anywhere Studio This book provides an overview of the SQL Anywhere Studio database management and synchronization technologies. It includes tutorials to introduce you to each of the pieces that make up SQL Anywhere Studio.

  • What's New in SQL Anywhere Studio This book is for users of previous versions of the software. It lists new features in this and previous releases of the product and describes upgrade procedures.

  • Adaptive Server Anywhere Database Administration Guide This book covers material related to running, managing, and configuring databases and database servers.

  • Adaptive Server Anywhere SQL User's Guide This book describes how to design and create databases; how to import, export, and modify data; how to retrieve data; and how to build stored procedures and triggers.

  • Adaptive Server Anywhere SQL Reference Manual This book provides a complete reference for the SQL language used by Adaptive Server Anywhere. It also describes the Adaptive Server Anywhere system tables and procedures.

  • Adaptive Server Anywhere Programming Guide This book describes how to build and deploy database applications using the C, C++, and Java programming languages. Users of tools such as Visual Basic and PowerBuilder can use the programming interfaces provided by those tools. It also describes the Adaptive Server Anywhere ADO.NET data provider.

  • Adaptive Server Anywhere SNMP Extension Agent User's Guide This book describes how to configure the Adaptive Server Anywhere SNMP Extension Agent for use with SNMP management applications to manage Adaptive Server Anywhere databases.

  • Adaptive Server Anywhere Error Messages This book provides a complete listing of Adaptive Server Anywhere error messages together with diagnostic information.

  • SQL Anywhere Studio Security Guide This book provides information about security features in Adaptive Server Anywhere databases. Adaptive Server Anywhere 7.0 was awarded a TCSEC (Trusted Computer System Evaluation Criteria) C2 security rating from the U.S. Government. This book may be of interest to those who wish to run the current version of Adaptive Server Anywhere in a manner equivalent to the C2-certified environment.

  • MobiLink Administration Guide This book describes how to use the MobiLink data synchronization system for mobile computing, which enables sharing of data between a single Oracle, Sybase, Microsoft or IBM database and many Adaptive Server Anywhere or UltraLite databases.

  • MobiLink Clients This book describes how to set up and synchronize Adaptive Server Anywhere and UltraLite remote databases.

  • MobiLink Synchronization Server-Initiated Synchronization User's Guide This book describes MobiLink server-initiated synchronization, a feature of MobiLink that allows you to initiate synchronization from the consolidated database.

  • MobiLink Tutorials This book provides several tutorials that walk you through how to set up and run MobiLink applications.

  • QAnywhere User's Guide This manual describes MobiLink QAnywhere, a messaging platform that enables the development and deployment of messaging applications for mobile and wireless clients, as well as traditional desktop and laptop clients.

  • iAnywhere Solutions ODBC Drivers This book describes how to set up ODBC drivers to access consolidated databases other than Adaptive Server Anywhere from the MobiLink synchronization server and from Adaptive Server Anywhere remote data access.

  • SQL Remote User's Guide This book describes all aspects of the SQL Remote data replication system for mobile computing, which enables sharing of data between a single Adaptive Server Anywhere or Adaptive Server Enterprise database and many Adaptive Server Anywhere databases using an indirect link such as e-mail or file transfer.

  • SQL Anywhere Studio Help This book includes the context-sensitive help for Sybase Central, Interactive SQL, and other graphical tools. It is not included in the printed documentation set.

  • UltraLite Database User's Guide This book is intended for all UltraLite developers. It introduces the UltraLite database system and provides information common to all UltraLite programming interfaces.

  • UltraLite Interface Guides A separate book is provided for each UltraLite programming interface. Some of these interfaces are provided as UltraLite components for rapid application development, and others are provided as static interfaces for C, C++, and Java development.

In addition to this documentation set, PowerDesigner and InfoMaker include their own online documentation.

Documentation formats

SQL Anywhere Studio provides documentation in the following formats:

  • Online documentation The online documentation contains the complete SQL Anywhere Studio documentation, including both the books and the context-sensitive help for SQL Anywhere tools. The online documentation is updated with each maintenance release of the product, and is the most complete and up-to-date source of documentation.

    To access the online documentation on Windows operating systems, choose Start > Programs > SQL Anywhere 9 > Online Books. You can navigate the online documentation using the HTML Help table of contents, index, and search facility in the left pane, as well as using the links and menus in the right pane.

    To access the online documentation on UNIX operating systems, see the HTML documentation under your SQL Anywhere installation.

  • PDF books The SQL Anywhere books are provided as a set of PDF files, viewable with Adobe Acrobat Reader.

    The PDF books are accessible from the online books, or from the Windows Start menu.

  • Printed books The complete set of books is available from Sybase sales or from eShop, the Sybase online store at [external link] http://eshop.sybase.com/eshop/documentation.


Finding out more and providing feedback

We would like to receive your opinions, suggestions, and feedback on this documentation.

You can provide feedback on this documentation and on the software through newsgroups set up to discuss SQL Anywhere technologies. These newsgroups can be found on the forums.sybase.com news server.

The newsgroups include the following:

  • [external link] sybase.public.sqlanywhere.general.

  • [external link] sybase.public.sqlanywhere.linux.

  • [external link] sybase.public.sqlanywhere.mobilink.

  • [external link] sybase.public.sqlanywhere.product_futures_discussion.

  • [external link] sybase.public.sqlanywhere.replication.

  • [external link] sybase.public.sqlanywhere.ultralite.

  • [external link] ianywhere.public.sqlanywhere.qanywhere

Newsgroup disclaimer
iAnywhere Solutions has no obligation to provide solutions, information or ideas on its newsgroups, nor is iAnywhere Solutions obliged to provide anything other than a systems operator to monitor the service and insure its operation and availability.

iAnywhere Solutions Technical Advisors as well as other staff assist on the newsgroup service when they have time available. They offer their help on a volunteer basis and may not be available on a regular basis to provide solutions and information. Their ability to help is based on their workload.

You can e-mail comments and suggestions to the SQL Anywhere documentation team at [external link] iasdoc@ianywhere.com. Although we do not undertake to reply to e-mails at that address, you can be sure we will read your suggestions with interest.


Connect Dialog Help

About this chapter

This chapter describes the Connect dialog used by Sybase Central, Interactive SQL, and the Adaptive Server Anywhere Console utility (dbconsole).

The settings in this dialog are preserved for the current Sybase Central, Interactive SQL, or Adaptive Server Anywhere Console session only. You can preserve connection settings in Sybase Central using Connection Profiles.


Connect dialog: Identification tab

The Identification tab of the Connect dialog has the following components:

User ID Type a user ID for the connection. The default user ID for Adaptive Server Anywhere databases is DBA. The user ID you supply must have permissions on a database in order to connect.

Password Type a password for the connection. The default password for Adaptive Server Anywhere databases is SQL when you connect with the default user, DBA. The password must be the correct password for the user ID you supply.

Extended characters used in passwords are case-sensitive, regardless of the database sensitivity setting.

For more information about passwords and case sensitivity, see Initialization utility options.

Use integrated login Select this option to connect to the database using an integrated login on Windows.

If you select this option, your database user ID and password do not need to be specified: instead, your Windows user ID and password are supplied to the Adaptive Server Anywhere integrated login mechanism.

To use integrated logins, you must have been granted integrated login permission on the database and the database server must be set up to accept integrated logins. As well, you must connect using the iAnywhere JDBC driver (the iAnywhere JDBC driver is selected by default when you choose the Use Integrated Login option).

For more information about integrated logins, see Using integrated logins.

None Select this option if you are not using an ODBC data source for the connection.

ODBC Data Source name Select this option to choose a data source (a stored set of connection parameters) for connecting to your database. This field is equivalent to the DSN connection parameter, which references a data source in the registry. You can view a list of data sources by clicking Browse.

You can also select a recently used ODBC data source from the dropdown list.

For information about the DSN connection parameter, see DataSourceName connection parameter [DSN].

  • Open the ODBC Data Source Administrator button Click the Open the ODBC Data Source Administrator button to open the ODBC Administrator dialog where you can select an ODBC data source from the list of available data sources. If you want to select a data source, select it from the list and then click OK.

    You may also choose to create a new data source or configure an existing data source to use for the connection.

    For information about using the ODBC Administrator dialog, see Working with ODBC data sources.

Tip
ODBC data sources allow you to store connection information. If you have connection information stored in an ODBC data source, do not repeat this information in the Connect dialog. For example, if the ODBC data source already contains a user ID, then do not supply the user ID in the User ID field of the Connect dialog.
Note

Any information you enter in the Connect dialog, such as the user ID or database name, takes precedence over the parameters stored in an ODBC data source or an ODBC data source file.

ODBC Data Source file Select this option to choose a data source file for the connection. You can search for the file by clicking Browse. The ODBC data source file is often used for UNIX systems.

You can also select a recently used ODBC Data Source File from the dropdown list.

File data sources hold the same information as ODBC data sources stored in the registry.

Troubleshooting
If you use an ODBC data source and fail to connect, test your data source.

To test an ODBC data source, click the Open ODBC Administrator Button on the Identification tab of the Connect dialog, or from the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > ODBC Administrator.

On the User DSN tab of the ODBC Data Source Administrator dialog, select an ODBC data source from the list and click Configure. This opens the ODBC Configuration for Adaptive Server Anywhere dialog.

On the ODBC tab of the ODBC Configuration for Adaptive Server Anywhere dialog, click Test Connection. A dialog appears telling you whether or not the connection succeeds.

For more information about ODBC data sources, see Working with ODBC data sources.

See also
  • Simple connection examples
  • Troubleshooting connections
  • Troubleshooting server startup
  • Troubleshooting network communications


Connect dialog: Database tab

The Database tab of the Connect dialog has the following components:

Server name Type the name of the Adaptive Server Anywhere personal server or network server. For example, asademo. You need to supply a server name if you want to connect to a network server.

Do not enter a Server Name if you want to connect to the default local personal server or if you want to start a database server from a database file on your local machine. If you do not have a default personal server and you omit the server name, the connection fails.

You can select a recently-used server name from the dropdown list or click Find to search for a server. When you click Find, a dialog appears listing running local personal servers and network servers. To choose a server from this dialog, select a server from the list and then click OK. The server name appears on the Database tab in the Server Name field.

For more information about the server name, see Naming the server and the databases.

Start line The start line is a command to start a personal database server or a network server on your machine. Enter a start line only if you want to connect to a local database server that is not currently running and if you want to set your own start parameters. You must enter the full path of the server, for example to start the personal database server enter, c:\Program Files\Sybase\SQL Anywhere 9\win32\dbeng9.exe. Alternatively, you can select a recently used start line from the dropdown list.

You can also include options in the Start Line field. The start line and options are used when you want to:

  • Employ any advanced server features.

  • Control protocol options.

  • Provide diagnostic or troubleshooting messages.

  • Set permissions.

  • Set database parameters (including encryption).

    For more information about options you can specify in the Start Line field, see Some common options and The database server.

Search network for database servers Select this option if you want to connect to a server that is running on a machine other than your local machine. You should clear this option if you want to connect to a database server on your local machine.

Database name Each database running on a server is identified by a database name. Type the name of the database you are connecting to.

You need a database name only if there is more than one database running on the server. If the database is not already running on the server, you should specify the database file instead.

You can also select a recently-used database name from the dropdown list or click Browse to locate the database file.

For more information about the database name, see Naming the server and the databases and DatabaseName connection parameter [DBN].

Database file Specify the database file when the database you want to connect to is not currently running on a server. It is recommended that you type the full path and name of the database file, for example, C:\sample.db. Otherwise, the path of the file is relative to the working directory of the server.

You can also select a recently-used database file from the dropdown list or click Browse to search for the database file.

Note
If you specify both the database name and database file when trying to connect to a database that is already running, the database file is ignored.

  • Encryption key If the database file is encrypted, you must supply a key to the database server every time the database server starts the database.

    For more information about encryption keys, see DatabaseKey connection parameter [DBKEY].

    The Encryption key field is enabled only after you fill in the Database File field. You can also supply encryption options in the Start Line field.

Start database automatically Select this option to start the database specified in the Database File field before you connect to it.

You should clear the Start Database Automatically option if you want to ensure that you connect only to a running database.

Stop database after last disconnect Select this option to automatically shut down the database after the last user disconnects.

See also
  • Simple connection examples
  • Troubleshooting connections
  • Troubleshooting server startup
  • Troubleshooting network communications


Connect dialog: Advanced tab

The Advanced tab of the Connect dialog has the following components:

Connection name This field only appears when you open the Connect dialog from Interactive SQL. Type a name to identify the connection. If specified, the name appears in the title bar in Interactive SQL.

Enter connection parameters, one per line, in the form "name=value" Type any additional connection parameters in this field, entering one connection parameter per line. The following connection parameters log debugging information regarding connections:

DEBUG=YES
LOG=connection.log

When you enter the connection parameters one per line, a semicolon is not required between the parameters.

Tip
You can specify a network protocol as a CommLinks connection parameter on this tab, but the protocols available depend on the driver you select. For jConnect, the TCP/IP protocol is used automatically.

Parameters set in this field take precedence over parameters set throughout the rest of this dialog. For example, if you enter the user ID DBA on the Identification tab, and set the connection parameter "uid=bsmith" in this field, a connection with the user ID bsmith is attempted.

For more information about connection parameters, see Connection parameters and How connection parameters work.

Select a JDBC driver Lets you choose the type of driver you want to use for the connection. All requests and commands you make when working with the database go through this driver. You have the following choices:

  • iAnywhere JDBC driver Select this option to use the iAnywhere JDBC driver to connect using an ODBC driver. The iAnywhere JDBC driver is, in many cases, the preferred driver. It is the default driver for Interactive SQL and Sybase Central.

    When you choose the iAnywhere JDBC driver, and you supply an ODBC data source, only the items on the Identification tab are used to establish a connection.

    For more information about the iAnywhere JDBC driver, see Using the iAnywhere JDBC driver and Choosing a JDBC driver.

    For more information about selecting a driver, see Specifying a driver for your connection.

  • jConnect 5 Select this option to use a JDBC driver called jConnect for JDBC (a Sybase product). This driver is platform-independent and it supports all connection features, including the use of ODBC data sources.

See also
  • Simple connection examples
  • Troubleshooting connections
  • Troubleshooting server startup
  • Troubleshooting network communications


ODBC Configuration Dialog Help

About this chapter

This chapter provides a description of the ODBC Configuration and Certicom Encryption Options dialogs that are provided with Adaptive Server Anywhere.

Using the ODBC Configuration dialog
ODBC Configuration dialog: DBMLSync tab
ODBC Configuration dialog: ODBC tab
ODBC Configuration dialog: Login tab
ODBC Configuration dialog: Database tab
ODBC Configuration dialog: Network tab
ODBC Configuration dialog: Advanced tab
Certicom Encryption Options dialog


Using the ODBC Configuration dialog

You connect to an ODBC database using an ODBC data source. The ODBC Configuration dialog allows you to save a set of Adaptive Server Anywhere connection parameters as an ODBC data source. Once you have a data source, your connection string can simply name the data source to use.

DSN=my data source

For Adaptive Server Anywhere, the use of ODBC data sources goes beyond Windows applications using the ODBC interface:

  • Adaptive Server Anywhere client applications on UNIX can use ODBC data sources, as well as those on Windows operating systems.

  • Adaptive Server Anywhere client applications using the OLE DB, ADO.NET, or embedded SQL interfaces can use ODBC data sources, as well as ODBC applications.

  • Interactive SQL and Sybase Central can use ODBC data sources.


ODBC Configuration dialog: DBMLSync tab

This tab provides options for the dbmlsync Adaptive Server Anywhere client synchronization utility.

The DBMLSync tab of the ODBC Configuration dialog has the following components:

Publication Type the name of the publication that is to be synchronized.

If there is only one publication in your database, you do not need to enter anything in this field.

ML password Type the MobiLink password for user authentication. If you have not entered a password, you must enter one here. If you are being prompted for a password, this is likely the only field you need to complete.

Change password Select this option to change the MobiLink password when synchronization occurs. Unless you are changing the MobiLink password, leave the checkbox blank.

  • New When changing the MobiLink password, type the new password. Unless you are changing the MobiLink password, leave this field blank.

  • Verify When changing the MobiLink password, type the new password again for verification. Unless you are changing the MobiLink password, leave this field blank.

Extended option Supply extended options to customize synchronization. You can supply schedule specifications, stream compression values, and other extended options. For a list of available extended options, click the Extended Option Help button. This field is optional.

Site script Type the name of the script to be executed after synchronization. This field is optional. You can click Browse to locate the site script.

Retry on remote progress If the consolidated and client databases have different information about the last synchronization, you can select this option to retry the upload operation.

By default, uploads continue from the offset recorded by the consolidated database. If you select Retry on Remote Progress, the upload continues from the offset recorded in the client database as long as the offset recorded in the consolidated database is ahead of that at the client database.

If, in addition, you select Remote is Ahead, the upload is retried starting from the offset recorded in the client database even if the offset recorded in the client database is ahead of that recorded in the consolidated database. This option should be used with care. If the offset mismatch is the result of a restore of the consolidated database, changes that happened in the client database in the gap between the two recorded offsets are lost. The Remote is Ahead option may be useful when the client database transaction log has been truncated after the last successful synchronization.

  • Remote is behind Select Remote is Behind to retry the upload from the consolidated database's offset as long as the consolidated database's offset is ahead of that at the client database. This option is only enabled when you select Retry on Remote Progress. This is the default setting.

  • Remote is ahead Select Remote is Ahead to retry the upload from the offset recorded in the client database even if the client's offset is ahead of that recorded at the consolidated database. This option is only enabled when you select Retry on Remote Progress. This option should be used with care.

    This option may be useful when the client database transaction log has been truncated and the synchronization definition has been recreated after the last successful synchronization or when you do not want to upload changes between the last successful synchronization and the recreation.

Verbose operation Select this option to record debugging and other diagnostic information in a log file. This field is optional.

Drop conflicting connections Synchronization requires access to all rows on the tables to be synchronized. Select this option to force connections with locks on these tables to be dropped. This field is optional.

Cmdline help Each of the options on the DBMLSync tab has an equivalent command-line option. Click Cmdline Help to view a list of switches and their description.

Extended option help Click Extended Option Help to view a list of the names, default values, and descriptions of available extended options. You can also supply these options in the Extended Option field to customize synchronization.


ODBC Configuration dialog: ODBC tab

This tab appears only when you are creating or modifying ODBC data sources.

The ODBC tab of the ODBC Configuration dialog has the following components:

Data source name

Type a name to identify this ODBC data source. You can use any descriptive name for the data source (spaces are allowed) but it is recommended that you keep the name short, as you may need to enter it in connection strings.

For more information, see DataSourceName connection parameter [DSN].

Description

You can provide a description of the data source. This description may help you or your end users to identify this data source from among their list of available data sources. This is an optional field.

Isolation level

Type a numerical value to specify the initial isolation level for this data source:

  • 0 This is also called the read uncommitted isolation level. This is the default isolation level. It provides the maximum level of concurrency, but dirty reads, non-repeatable reads, and phantom rows may be observed in result sets.

  • 1 This is also called the read committed level. This provides less concurrency than level 0, but eliminates some of the inconsistencies in result sets at level 0. Non-repeatable rows and phantom rows may occur, but dirty reads are prevented.

  • 2 This is also called the repeatable read level. Phantom rows may occur. Dirty reads and non-repeatable rows are prevented.

  • 3 This is also called the serializable level. This provides the least concurrency, and is the strictest isolation level. Dirty reads, non-repeatable reads, and phantom rows are prevented.

For more information, see Choosing isolation levels.

Microsoft applications (Keys in SQLStatistics)

Select this option if you want the SQLStatistics function to return foreign keys. The ODBC specification states that SQLStatistics should not return primary and foreign keys; however, some Microsoft applications (such as Visual Basic and Access) assume that primary and foreign keys are returned by SQLStatistics.

Delphi applications

Select this option if you use the Borland Delphi application development tool to create applications that produce your data source.

When this option is selected, one bookmark value is assigned to each row instead of the two that are otherwise assigned (one for fetching forwards and a different one for fetching backwards).

Delphi cannot handle multiple bookmark values for a row. If the option is cleared, scrollable cursor performance can suffer since scrolling must always take place from the beginning of the cursor to the row requested in order to get the correct bookmark value.

Suppress fetch warnings

Select this option if you want to suppress warning messages that are returned from the database server on a fetch.

Versions 8.0 and later of the database server return a wider range of fetch warnings than earlier versions of the software. For applications that are deployed with an earlier version of the software, you can select this option to ensure that fetch warnings are handled properly.

Prevent driver not capable errors

The Adaptive Server Anywhere ODBC driver returns a Driver not capable error because it does not support qualifiers. Some ODBC applications do not handle this error properly. Select this option to prevent this error code from being returned, allowing these applications to work.

Delay AutoCommit until statement close

Select this option to delay the commit operation until a statement closes.

Describe Cursor Behavior

Choose how often you want a cursor to be redescribed when a procedure is executed. The default setting is If Required.

  • Never Select this option if you know that your cursors do not have to be redescribed. Redescribing cursors is expensive and can decrease performance.

  • If required When you select this option, the ODBC driver determines whether a cursor must be redescribed. The presence of a RESULT clause in your procedure prevents ODBC applications from redescribing the result set after a cursor is opened. This is the default.

  • Always The cursor is redescribed each time it is opened. If you use Transact-SQL procedures or procedures that return multiple result sets, you must redescribe the cursor each time it is opened.

Translator The translator converts characters between ANSI and OEM code pages. Most databases do not require a translator because the ODBC Driver Manager automatically performs a conversion between the client's character set and the database's character set. If your database uses an ANSI code page (the default) do not select a translator.

If you require a translator, click Select and choose the translator from the list of installed translators.

  • Select Translator Click Select Translator to choose the ODBC translator you require from a list of installed translators.

Test Connection Tests whether the information provided results in a proper connection. In order for the test to work, a user ID and password must be specified on the Login tab.


ODBC Configuration dialog: Login tab

The Login tab of the ODBC Configuration dialog Login tab has the following components:

Use integrated login

Select this option to connect using an integrated login.

If you select this option, the user ID and password do not need to be specified: instead, your operating system user ID and password are supplied to the Adaptive Server Anywhere integrated login mechanism.

To use integrated logins, users must have been granted integrated login permission and the database you are connecting to must also be set up to accept integrated logins. Only users with DBA access may administer integrated login permissions.

For more information, see Using integrated logins.

Supply user ID and password Select this option if you want to specify the user ID and password for the connection.

  • User ID Type a user ID for the connection. The user ID you supply must have permissions on a database in order to connect.

  • Password Type a password for the connection. The password must be the correct password for the user ID you supply.

    Extended characters used in passwords are case-sensitive, regardless of the database sensitivity setting.

    For more information about passwords and case sensitivity, see Initialization utility options.

    • Encrypt password Select this option if you want the password to be stored in encrypted form in the profile.

      This option only appears when creating ODBC data sources. It does not appear when you access this dialog using the dbmlsync utility.

      For more information, see EncryptedPassword connection parameter [ENP].

It is recommended that you do not include the password in the data source as it is a significant security risk.

Data source name This option only appears when you open this dialog using the dbmlsync utility. Select this option to choose a data source (a stored set of connection parameters) for connecting to your database. This field is equivalent to the DSN connection parameter, which references a data source in the registry. You can view a list of data sources by clicking Browse.

Data source file This option only appears when you open this dialog using the dbmlsync utility. Select this option to choose a data source file for the connection. You can search for the file by clicking Browse. The ODBC data source file is often used for UNIX systems. You can click Browse to locate an ODBC data source.


ODBC Configuration dialog: Database tab

The Database tab of the ODBC Configuration dialog has the following components:

Server name

Type the name of the Adaptive Server Anywhere personal server or network server. For example, asademo. You need to supply a server name if you want to connect to a network server.

Do not enter a Server Name if you want to connect to the default local personal server or if you want to start a database server from a database file on your local machine. If you do not have a default personal server and you omit the server name, the connection fails.

For more information about the server name, see Naming the server and the databases.

For more information, see EngineName connection parameter [ENG].

Start line

The start line is a command to start a personal database server or a network server on your machine. Enter a start line only if you want to connect to a local database server that is not currently running and if you want to set your own start parameters. You must enter the full path of the server, for example to start the personal database server enter, c:\Program Files\Sybase\SQL Anywhere 9\win32\dbeng9.exe.

You can also include options in the Start Line field. The start line and options are used when you want to:

  • Employ any advanced server features.

  • Control protocol options.

  • Provide diagnostic or troubleshooting messages.

  • Set permissions.

  • Set database parameters (including encryption).

    For more information about options you can specify in the Start Line field, see Some common options and The database server.

    For more information, see StartLine connection parameter [START].

Database name

Each database running on a server is identified by a database name. Type the name of the database you are connecting to.

For more information about the database name, see Naming the server and the databases and DatabaseName connection parameter [DBN].

Database file

Specify the database file when the database you want to connect to is not currently running on a server. It is recommended that you type the full path and name of the database file, for example, C:\sample.db. Otherwise, the path of the file is relative to the working directory of the server. This option is only necessary for starting a database that is not already running. You can click Browse to select the database file from the file directory.

For more information, see DatabaseFile connection parameter [DBF].

Encryption key

If the database file is encrypted, you must supply a key to the database server every time the database server starts the database.

For more information about encryption keys, see DatabaseKey connection parameter [DBKEY].

Start database automatically

Select this option to start the database specified in the Database File field before you connect to it.

You should clear the Start Database Automatically option if you want to ensure that you connect only to a running database.

Stop database after last disconnect Select this option to automatically shut down the database after the last user disconnects.

For more information, see AutoStop connection parameter [ASTOP].


ODBC Configuration dialog: Network tab

The Network tab of the ODBC Configuration dialog has the following components:

TCP/IP If you want to use ECC_TLS (formerly Certicom) or RSA_TLS strong encryption for network packets, you must select the TCP/IP protocol to access the network database server. In the adjacent field, you may enter communication parameters that establish and tune the connection from your client application to a database.

For example, to look on the machine server1 on port 4436 for a database server, you would enter HOST=server1;PORT=4436.

Contact your network administrator if you are unsure which protocol to use.

SPX You can select the SPX protocol to connect to databases on Novell NetWare networks. NetWare also supports the TCP/IP protocol. In the adjacent field, you may type communication parameters that establish and tune the connection from your client application to a database.

For example, you could enter the following communication parameters for an SPX connection HOST=0:0:0:0:0:1/4:236:121:215;PORT=2369.

Contact your network administrator if you are unsure which protocol to use.

Named pipes The Named Pipes protocol is used for client/server communication on the same machine. If you want to run under a certified security environment, you can use the named pipes protocol. It is only provided on Windows NT.

Contact your network administrator if you are unsure which protocol to use.

Shared memory The shared memory protocol is used for communication between a client and server running under the same operating system on the same machine.

Contact your network administrator if you are unsure which protocol to use.

For more information, see CommLinks connection parameter [LINKS], and Network protocol options.

Liveness timeout

A liveness packet is sent across a client/server to confirm that a connection is intact. If the client runs for the liveness timeout period without detecting a liveness packet, the communication is severed. This parameter only works with network server and TCP/IP or IPX communication protocols.

The default liveness timeout is 120 seconds.

For more information, see LivenessTimeout connection parameter [LTO].

Idle timeout

Set the amount of client idle time before the connection is terminated. If a client runs for the idle timeout period without submitting a request, the connection is severed.

The default client idle time is 240 minutes.

For more information, see Idle connection parameter [IDLE].

Buffer size

Set the maximum size of communication packets, in bytes. You should set the buffer size to be smaller than that allowed by your network because the network software may add information to each buffer before sending it over the network.

The default buffer size is 1460 bytes.

For more information, see CommBufferSize connection parameter [CBSIZE].

Compress network packets Select this option to turn on compression for the connection. Using compression for a connection can significantly improve Adaptive Server Anywhere performance under some circumstances.

For more information, see Compress connection parameter [COMP].

Select the method for encryption of network packets

Allows the encryption of packets transmitted from the client machine over the network.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

  • None Communication packets transmitted from the client are not encrypted. This is the default setting.

  • Simple Communication packets transmitted from the client are encrypted with Simple encryption. Simple encryption is supported on all platforms, as well as on previous versions of Adaptive Server Anywhere. Simple encryption is not as strong as ECC_TLS or RSA_TLS encryption.

  • ECC_TLS Select this option to enable ECC_TLS (formerly Certicom) encryption. ECC_TLS encryption protects the confidentiality and integrity of network packets as they pass between the client and the server. It is only available over the TCP/IP protocol.

    In the adjacent field you must supply a trusted certificate value. You can also click Edit to supply this value.

  • RSA_TLS Select this option to enable RSA_TLS encryption. RSA_TLS encryption protects the confidentiality and integrity of network packets as they pass between the client and the server. It is only available over the TCP/IP protocol.

    In the adjacent field you must supply a trusted certificate value. You can also click Edit to supply this value.

  • RSA_TLS_FIPS Select this option to enable RSA_TLS_FIPS encryption. When this option is selected, the database server accepts communication packets encrypted using FIPS-approved RSA encryption technology. RSA_TLS_FIPS uses a separate approved library than RSA_TLS, but is compatible with clients specifying RSA_TLS with Adaptive Server Anywhere 9.0.2 or later. To use this type of encryption, both the client and the server must be operating on a supported 32-bit Windows operating system, and the connection must be over the TCP/IP port.

    In the adjacent field you must supply a trusted certificate value. You can also click Edit to supply this value.

    • Edit Click Edit to supply encryption values for trusted certificates, certificate company, certificate unit, and certificate name in the Certicom Encryption Options dialog.

    For more information, see Encryption connection parameter [ENC] and FIPS 140-2 certification.

See also
  • Certicom Encryption Options dialog


ODBC Configuration dialog: Advanced tab

The Advanced tab of the ODBC Configuration dialog has the following components:

Connection name

Type a name to identify the connection. This field is optional.

Character set Type a character set name. By default, the client's ANSI character set is used, for example cp1252 for English systems. You can also supply an OEM character set instead of an ANSI character set.

Allow multiple record fetching

Select this option to retrieve multiple records at one time, instead of individually, for improved performance.

Display debugging information in a log file Select this option to record diagnostic information on communications links in the log file.

  • Log file Type the name of the log file where you want to save the debugging information.

Additional connection parameters Type any additional connection parameters in this field in a semicolon separated list. For example,

DEBUG=YES;LOG=connection.log

Parameters set in this field take precedence over parameters set throughout the rest of this dialog. For example, if you enter the user ID DBA on the Identification tab, and set the connection parameter "uid=bsmith" in this field, a connection with the user ID bsmith is attempted.

For more information about connection parameters, see Connection parameters and How connection parameters work.


Certicom Encryption Options dialog

This dialog displays fields for the client's Certicom encryption settings.

The Certicom Encryption Options dialog has the following components:

Trusted certificates Type the name of the certificate file the client uses to authenticate the server. You can also click Browse to select the trusted certificate from the file directory. This is a required field.

Certificate company Type the name of the certificate authority or organization that issued the certificate. The server's and the client's values must match. This is an optional field.

Certificate unit Type the certificate unit. This is also called the organizational unit. The server's and the client's values must match. This is an optional field.

Certificate name Type the certificate's common name. The server's and the client's values must match. This is an optional field.


Adaptive Server Anywhere Help

About this chapter

This chapter provides descriptions of all the property sheets and dialogs you can access from the Adaptive Server Anywhere plug-in in Sybase Central.


Introduction to property sheets

The Adaptive Server Anywhere plug-in provides a number of property sheets that let you configure object properties.

The following sections contain detailed descriptions of each property sheet in the Adaptive Server Anywhere plug-in. Each one becomes available in the File menu when you select an object, and is also available in a popup menu when you right-click an object.

Article property sheet
Check Constraint property sheet
Column property sheet
Column property sheet (View)
Connected User property sheet
Consolidated User property sheet
Database property sheet
Dbspace property sheet
Domain property sheet
Event property sheet
External Login property sheet
Foreign Key property sheet
Function property sheet
Group property sheet
Index property sheet
Integrated Login property sheet
JAR File property sheet
Java Class property sheet
Message Type property sheet
MobiLink User property sheet
Parameter property sheet
Procedure property sheet
Proxy Table property sheet
Publication property sheet
Publisher property sheet
Remote Procedure property sheet
Remote Server property sheet
Remote User property sheet
Server property sheet
Service property sheet
SQL Remote Subscription property sheet
Statistic property sheet
Synchronization Subscription property sheet
System Trigger property sheet
Table property sheet
Template property sheet, Definition property sheet, and Site property sheet
Trigger property sheet
UltraLite Project property sheet
UltraLite Statement property sheet
Unique Constraint property sheet
User property sheet
View property sheet
Web Service property sheet


Article property sheet

The Article property sheet consists of four tabs: General, Columns, WHERE Clause, and SUBSCRIBE BY Restriction.

See also
  • Publication design for Adaptive Server Anywhere

Article property sheet: General tab
Article property sheet: Columns tab
Article property sheet: WHERE Clause tab
Article property sheet: SUBSCRIBE BY Restriction tab


Article property sheet: General tab

The General tab of the Article property sheet has the following components:

Name Shows the name of the article and the article's owner in parentheses.

Type Shows the type of the object.

Publication Shows the publication the article belongs to. The name of the publication's owner appears in parentheses.

See also
  • Table property sheet
  • Publication design for Adaptive Server Anywhere


Article property sheet: Columns tab

The Columns tab of the Article property sheet has the following components:

All columns Select this option to include all the columns of the table in the article.

Selected columns Select this option if you want the article to contain only some of the columns from the table. Selecting this option enables the checkboxes beside the column names in the Selected Columns list. The list includes all the columns of the table the article is based on.

When you choose this option, you must include at least one column in the article. To include a column in the article, select the checkbox beside the column name so that a checkmark appears. You can click Select All to include all the columns in the list in the article.

  • Select All Select this option to include all the columns of the table in the article.

  • Clear All Select this option clear all the checkboxes in the Selected Columns list.

See also
  • Publication design for Adaptive Server Anywhere


Article property sheet: WHERE Clause tab

Articles defined for SQL Remote and MobiLink publications can use a WHERE clause to define a subset of rows of a table to be included in an article. UltraLite applications can use row subsets by supplying a WHERE clause, with one exception: articles in UltraLite publications governing HotSync synchronization cannot use a WHERE clause.

The WHERE Clause tab of the Article property sheet has the following components:

This article has the following WHERE clause You can edit the WHERE clause in the window to restrict the table rows that are included in the article.

For example, to include only the rows that contain a salary of more than $50000, type:

WHERE salary > 50000
See also
  • CREATE PUBLICATION statement
  • Publication design for Adaptive Server Anywhere
  • The WHERE clause: specifying rows


Article property sheet: SUBSCRIBE BY Restriction tab

This tab only applies to SQL Remote articles.

The SUBSCRIBE BY Restriction tab of the Article property sheet has the following components:

None Sets the article to avoid using SUBSCRIBE BY columns or clauses to partition rows.

Column Sets the article to partition rows from the table based on a column (SUBSCRIBE BY columns). Once you select this option, you must select a column from the dropdown list.

Expression Sets the article to partition rows from the table based on an expression entered in the field below.

See also
  • Publication design for Adaptive Server Anywhere
  • CREATE PUBLICATION statement


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Check Constraint property sheet

The Check Constraint property sheet consists of two tabs: General and Definition.


Check Constraint property sheet: General tab

The General tab of the Check Constraint property sheet has the following components:

Name Shows the name of the selected check constraint. You can edit the name of the check constraint in the adjacent field.

Type Shows the type of object.

Table Shows the table the check constraint belongs to.

Column Shows the column the check constraint applies to. This information appears only for column check constraints, not for table constraints.

See also
  • Choosing constraints
  • Using CHECK constraints on tables
  • Using CHECK constraints on columns


Check Constraint property sheet: Definition tab

The Definition tab of the Check Constraint property sheet has the following components:

This check constraint has the following definition Provides a place for you to type the check constraint. A column check constraint is used to ensure that no inappropriate values are entered into any column of the specified type, while a table check constraint ensures that no row in a table violates the constraint.

See also
  • Choosing constraints
  • Using CHECK constraints on columns
  • Using CHECK constraints on tables


Column property sheet

This Column property sheet displays information about columns that belong to a table. If you want to view column properties for columns that belong a view, see Column property sheet (View).

The Column property sheet for tables consists of four tabs: General, Data Type, Value, and Constraints.

See also
  • Working with tables


Column property sheet: General tab

The General tab of the Column property sheet has the following components:

Name The name of the column. You can change the column name in the adjacent field.

Type Shows the object's type.

Table Shows the name of the table the column belongs to, as well as the table's owner.

Comment Provides a place for you to type a text description of the column. For example, you could use this area to describe the column's purpose in the system.

See also
  • Working with tables


Column property sheet: Data Type tab

The Data Type tab of the Column property sheet has the following components:

Built-in type Select this option to choose a predefined data type for the column from the dropdown list. Integers, character strings, and dates are examples of predefined data types. For some of these types, you can specify size and/or scale.

  • Size Specifies the length of string columns, or the total number of digits to the left and right of the decimal point in the result of any decimal arithmetic for numeric columns. For numeric columns, the size is also called the PRECISION value.

    For more information about the PRECISION value, see PRECISION option [database].

  • Scale Specifies the minimum number of digits after the decimal point when an arithmetic result is truncated to the maximum PRECISION value.

For more information about data types, see SQL Data Types.

Domain Select this option to choose a domain from the dropdown list. A domain is a named combination of built-in data types, default value, check condition, and nullability.

Java class Select this option to choose a Java class for the column from the dropdown list. If the database does not support Java, this option is not enabled.

See also
  • Choosing data types for columns
  • Using domains
  • Ensuring Data Integrity
  • Using Java in the Database
  • Working with tables


Column property sheet: Value tab

The Value tab of the Column property sheet has the following components:

No default or computed value Select this option if the column is not a computed value and has no default value.

Default value Select this option if the column has a default value. If the column is based on a domain, this setting inherits the domain's default value (if any), but the value can be overridden for the column. Choosing the Default Value option enables the User-defined and System defined options.

  • User-defined Lets you type a custom value (string, number, or other expression) for the default value. If you've based the column on a domain, you can retain the domain's default value (if any) or override it for the column.

    • Literal string Lets you specify whether or not the default value for the column should be treated as a literal string. This option is selected by default for character columns and domains with a character base type. When this option is selected, the default text does not need to be enclosed in single quotes, and you do not need to escape embedded single quotes or backslashes in the string.

      When this option is cleared, the automatic quoting and escaping behavior is turned off and the specified default value text is passed as is to the server.

  • System-defined Lets you select a pre-defined value (for example, current date) for the default value. You must select a value from the dropdown list. If you have based the column on a domain, you can retain the domain's default value (if any) or override it for the column.

    • Partition size When you select global autoincrement for the system-defined value, you can also supply a partition size.

      Global autoincrement assigns each new row a value of one greater than the previous highest value in the column. The partition size restricts the maximum value that global autoincrement can use. You can enter any positive integer for the partition size. Generally, you should select a value so that the supply of numbers is rarely, if ever, exhausted.

      For more information, see The AUTOINCREMENT default and CREATE TABLE statement.

Computed value Select this option to define a computed value for the column. A computed column derives its values from calculations of values in other columns. Type an expression in the text box to describe the relationship between the other columns and the value that appears in the computed column.

For more information about computed values, see ALTER TABLE statement and Subqueries in expressions.

See also
  • SQL Functions
  • Using column defaults
  • Working with computed columns


Column property sheet: Constraints tab

The Constraints tab of the Column property sheet has the following components:

Values can be null Select this option if values in the column can be NULL. If the column is based on a domain, you can retain the domain's nullability or override it for the column.

Values cannot be null Select this option to allow duplicate values, but not allow NULL values in this column.

Values cannot be null and must be unique Select this option if values in the column cannot be NULL and must be unique.

See also
  • Choosing constraints
  • Ensuring Data Integrity


Column property sheet (View)

This Column property sheet displays information about columns that belong to a view. If you want to obtain information about columns that belong to a table, see Column property sheet.

The Column property sheet for views consists of one tab: General.

Column property sheet (View): General tab


Column property sheet (View): General tab

The General tab of the Column property sheet has the following components:

Name Shows the name of the selected column.

Type Shows the type of object.

View Shows the name of the view the column belongs to, with the name of the view's owner in parenthesis.

Data type Shows the data type of the selected column.

Allows null Shows whether the selected column allows NULL values.

See also
  • SQL Data Types
  • Choosing constraints


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Connected User property sheet

The Connected User property sheet consists of two tabs: General and Extended Information.


Connected User property sheet: General tab

The General tab of the Connected User property sheet has the following components:

Connection ID Shows the connection ID for the user.

When a user connects to a database, the database server assigns the connection a unique connection ID. For each new connection to the database server, the server increments the connection ID value by 1.

Type Shows the type of object.

User Shows the database user ID.

Connection name Shows the connection name for the database the user is connected to. Naming your connections allows multiple connections to the same database, or multiple connections to the same or different database server, to be easily identified.

Communication link Shows the type of communications link used by the user's connection. If the connection is between an Adaptive Server Anywhere client and network server, the link type represents the network protocol being used.

Node address Shows the communications port ID used by the user's connection.

Last request type Shows the type of the last request.

Last request time Shows the time at which the last request for the connection started.

Blocked on connection Shows whether the connection is blocked. If the current connection is not blocked, this is zero. If it is blocked, the connection number on which the connection is blocked due to a locking conflict.

See also
  • Managing connected users
  • Connection-level properties


Connected User property sheet: Extended Information tab

The Extended Information tab of the Connected User property sheet has the following components:

Connected user properties list Lists the name and value of the properties for the connected user. Click Refresh to update the values. You can also press F5 to refresh the values.

  • Refresh Click Refresh to update the values in the Connected user properties list.

Description Provides a description of the selected property.

See also
  • Managing connected users
  • Connection-level properties


Consolidated User property sheet

The Consolidated User property sheet consists of four tabs: General, Authorities, Permissions, and SQL Remote.

See also
  • Managing User IDs and Permissions
  • Granting and revoking remote permissions

Consolidated User property sheet: General tab
Consolidated User property sheet: Authorities tab
Consolidated User property sheet: Permissions tab
Consolidated User property sheet: SQL Remote tab


Consolidated User property sheet: General tab

The General tab of the Consolidated User property sheet has the following components:

Name Shows the name of the consolidated user.

Type Shows the type of object.

Allowed to connect Select this option to allow the consolidated user to connect to the database. If the consolidated user is not allowed to connect, the password (if one was supplied) is removed from the account. If you later change the consolidated user to allow them to connect, you must supply a new password. Clearing this option disables the Password and Confirm Password options.

Users are almost always allowed to connect.

  • Password Type the password for the consolidated user. For added security, the characters appear as asterisks.

  • Confirm password Confirm the password that you typed in the Password text box by entering it again. The contents of the two fields must match exactly.

Comment Provides a place for you to type a text description of the consolidated user. For example, you could use this area to describe the consolidated user's purpose in the system.

See also
  • GRANT CONSOLIDATE statement [SQL Remote]
  • Granting and revoking remote permissions
  • Managing User IDs and Permissions


Consolidated User property sheet: Authorities tab

The Authorities tab of the Consolidated User property sheet has the following components:

DBA Select this option to grant DBA authority to the consolidated user; a user with DBA authority can fully administer the database.

Resource Select this option to grant resource authority to the consolidated user; a user with resource authority can create database objects.

Remote DBA Select this option to grant Remote DBA authority to the consolidated user. The SQL Remote Message Agent should be run using a user ID with this type of authority to ensure that actions can be carried out without creating security loopholes. The MobiLink client utility, dbmlsync, also requires Remote DBA authority.

See also
  • Managing User IDs and Permissions


Consolidated User property sheet: Permissions tab

The Permissions tab of the Consolidated User property sheet has the following components:

Permissions list Shows all tables the consolidated user has permissions on, as well as the user who owns each table. You can click the fields beside each user to grant or revoke permissions; double-clicking (so that a checkmark and two + signs appear) gives the user grant options for the permission.

Show Select what type of object appears in the Permissions list:

  • Tables Displays all tables the consolidated user has permissions on.

  • Views Displays all views the consolidated user has permissions on.

  • Procedures & functions Displays all procedures and functions the consolidated user has permissions on. You can only grant Execute permissions for procedures and functions.

See also
  • Managing User IDs and Permissions


Consolidated User property sheet: SQL Remote tab

The SQL Remote tab of the Consolidated User property sheet has the following components:

Message type Select a message type for communicating with the publisher.

Address Type the destination for replication messages. Publishers and remote users each have their own address. The address must be valid for the Message Type you select. For example, if you select the FTP message type, a valid address is a host (such as ftp.mycompany.com) or an IP address (such as 192.138.151.66).

Send then close Select this option to set the replication frequency so that the publisher's agent runs once, sends all pending messages to this remote user, and then shuts down. The agent must be restarted each time the publisher wants to send messages. This option is only useful when you are running the message agent at a remote site.

Send every Select this option to set the replication frequency so that the publisher's agent runs continuously, sending messages to this remote user at the given periodic interval. This option is useful at both consolidated and remote sites.

Send daily at Select this option to set the replication frequency so that the publisher's agent runs continuously, sending messages to this remote user each day at the given time. This option is particularly useful at remote sites.

See also
  • GRANT REMOTE statement [SQL Remote]


Database property sheet

The Database property sheet consists of five tabs: General, Settings, Extended Information, SQL Remote, and Profiling.

See also
  • Working with databases

Database property sheet: General tab
Database property sheet: Settings tab
Database property sheet: Extended Information tab
Database property sheet: SQL Remote tab
Database property sheet: Profiling tab


Database property sheet: General tab

Database properties listed on this tab cannot be changed without rebuilding the database.

For information about rebuilding a database, see Rebuilding databases.

The General tab of the Database property sheet has the following components:

Name Shows the name of the database.

Type Shows the type of object.

ID Shows a unique number assigned by the server to each database that is started on it. The number makes it possible to distinguish between databases running on the same server.

Capability ID Shows the capability bits enabled for the database. This value only appears for Adaptive Server Anywhere databases that are version 8 and higher.

You can view a list of the capabilities that are enabled for the database on the Extended Information tab of the Database property sheet.

Java JDK version Shows the version of the JDK supported by the database at the time of installation. If Java is not supported in the database, None appears.

Page size Shows the page size of the database in bytes.

Database file Shows the root database file for the database.

Log file Shows the name and location of the transaction log file for the database.

Mirror log file Shows the name and location of the transaction log mirror file for the database.

User Shows the user ID of the user connected to the database.

Connection ID Shows the connection ID for the database's connection from Sybase Central.

Connection name Shows the connection name for the user connected to this database. Naming your connections allows multiple connections to the same database, or multiple connections to the same or different database server, to be easily identified.

Communication link Shows the type of communications link used by the user's connection. If the connection is between an Adaptive Server Anywhere client and network server, the link type represents the network protocol being used.

Total connections Shows the total number of current connections to the database from all users, including the Sybase Central connection.

See also
  • Database-level properties
  • Working with databases


Database property sheet: Settings tab

Database properties listed on this tab cannot be changed without rebuilding the database.

For information about rebuilding a database, see Rebuilding databases.

The Settings tab of the Database property sheet has the following components:

Encryption type Shows whether or not the database is encrypted, and the type of encryption: Simple, AES, or MDSR. If encryption is not supported in the database, None appears.

For information about the types of encryption supported by Adaptive Server Anywhere, see Encrypting a database.

Case sensitive Shows whether or not the database is case sensitive. This property applies to the data in the database, and to passwords, but not to table names, column names, and other identifiers.

Ignore trailing blanks Shows whether the database ignores trailing blanks in comparisons.

Default collation Shows the default collation of the database.

Checkpoint urgency Shows the time that has elapsed since the last checkpoint as a percentage of the checkpoint time setting of the database. Click Refresh or press F5 to update the Checkpoint urgency value.

Recovery urgency Shows an estimate of the amount of time required to recover the database. Click Refresh or press F5 to update the Recovery urgency value.

  • Refresh Click Refresh to update the checkpoint urgency and recovery urgency values.

Database Capabilities Lists database capabilities. A green checkmark appears beside the capabilities that are enabled for the database. A red X appears beside capabilities that are not enabled for the database.

See also
  • Working with databases
  • Database-level properties


Database property sheet: Extended Information tab

The Extended Information tab of the Database property sheet has the following components:

Database properties list Lists the name and value of the properties for the database. Click Refresh to update the values. You can also press F5 to refresh the values.

  • Refresh Click Refresh to update the values in the Database Properties list.

Description Provides a description of the selected property.

See also
  • Working with databases
  • Database-level properties


Database property sheet: SQL Remote tab

The SQL Remote tab of the Database property sheet has the following components:

This database has a publisher Select this option to supply the name of the database's publisher. Selecting this option enables the Publisher field below.

  • Publisher Type the name of the publisher for the database. You can click Change to select a publisher in the Set Publisher dialog.

This remote database has a corresponding consolidated database Select this option if the database is acting as a remote database.

  • Consolidated user Click Change to select the consolidated user from the list of available candidates in the Set Consolidated User dialog.

  • Message type Select the message type for communicating with the publisher from the dropdown list.

    For information about the message types supported by SQL Remote, see Using message types.

  • Address Provides a place for you to type the remote address of the consolidated user. The address is a string, according to the specified message type, to which the replication messages should be sent for the user.

    • Send then close Sets the replication frequency so that the Message Agent runs once, sends all pending messages then shuts down. The Message Agent must be restarted each time the publisher wants to send messages. This option is only useful when you are running the message agent at a remote site.

      In most replication setups, this option is not used for sending publications from the consolidated publisher to the remote group.

    • Send every Select this option to set the replication frequency so that the Message Agent runs continuously, sending messages to this consolidated user at the given periodic interval. This option is useful at both consolidated and remote sites.

    • Send daily at Select this option to set the replication frequency so that the Message Agent runs continuously, sending messages each day at the given time.

Subscribers Shows the number of remote users subscribing to publications in the database.

Subscriptions Shows the number of subscriptions to publications in the database.

Started subscriptions Shows the number of subscriptions in the database that have been started.

See also
  • Publications and subscriptions
  • Set Publisher dialog
  • Set Consolidated User dialog


Database property sheet: Profiling tab

The Profiling tab of the Database property sheet has the following components:

Enable profiling on this database Select this option if you want Adaptive Server Anywhere to monitor the execution times of stored procedures, functions, events, and triggers. You can use database profiling information to determine which procedures can be fine-tuned to increase performance within your database. Profiling information appears on the Profile tab in Sybase Central.

Reset Now Deletes all the collected profiling data for the database. The database immediately starts collecting new profiling information about procedures, functions, events, and triggers.

Clear Now Select this option to delete all the collected profiling data for the database and turn off profiling for the database. This button is only enabled when profiling is turned on for the database.

See also
  • Profiling database procedures


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Dbspace property sheet

The Dbspace property sheet consists of one tab: General.

Dbspace property sheet: General tab


Dbspace property sheet: General tab

The General tab of the Dbspace property sheet has the following components:

Name Shows the name of the dbspace.

Type Shows the type of object.

File name Shows the name of the database file that the dbspace points to. For new spaces, you can supply a new file name.

Pre-allocate Space Now Displays the Pre-allocate Space for Dbspace dialog, which lets you pre-allocate storage in the dbspace by adding pages to it. Adding pages may improve performance for bulk-loading operations.

See also
  • Pre-allocating space for database files
  • Pre-allocate Space for Dbspace dialog


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Domain property sheet

The Domain property sheet consists of two tabs: General and Check Constraint.


Domain property sheet: General tab

The General tab of the Domain property sheet has the following components:

Name Shows the name of the domain.

Type Shows the type of object.

Creator Shows the database user who created and owns the domain.

Base type Shows the pre-defined data type of the domain. If the data type has a format, it is listed after the type's name.

Allows null Shows whether columns based on the domain allow NULLs.

Default value Shows the default value of the domain. If the domain does not have a default value, nothing appears. Columns based on the domain inherit the default value, but you can subsequently override it.

See also
  • Domains


Domain property sheet: Check Constraint tab

The Check Constraint tab of the Domain property sheet has the following components:

This domain has the following check constraint Lets you define specified conditions on a column or set of columns to make up the check constraint of the table and restrict the values that can be entered in the column(s).

For example, to check whether an employee's start date falls in a particular range, type:

CHECK ( start_date BETWEEN '1983/06/27'
                   AND CURRENT DATE )

For more information about check constraints, see Using CHECK constraints on columns.

See also
  • Using domains
  • Choosing constraints


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Event property sheet

The Event property sheet consists of two tabs: General and Conditions.


Event property sheet: General tab

The General tab of the Event property sheet has the following components:

Name Shows the name of the event.

Type Shows the type of object.

Creator Shows the database user who created and owns the event.

Enabled Select this option to execute the event when the scheduled time or trigger condition occurs.

You must enable the event to trigger it manually from Sybase Central.

Executes at Shows which of the following locations the event executes at.

  • All databases Executes the event at all remote locations

  • Consolidated database For databases involved in SQL Remote replication, this executes the event at the consolidated database only, and not at any of the remote locations.

  • Remote database For databases involved in SQL Remote replication, this executes the event at a remote database only, and not at the consolidated database.

Comment Provides a place for you to type a text description of the event. For example, you could use this area to describe the event's purpose in the system.

See also
  • CREATE EVENT statement
  • Automating Tasks Using Schedules and Events
  • Trigger Event dialog


Event property sheet: Conditions tab

The Conditions tab of the Event property sheet has the following components:

Manually Executes the event only when you manually trigger it.

By the following schedules Executes the event according to the schedule you define.

  • New Displays the Create Schedule dialog, which lets you create a new schedule for the event.

  • Edit Displays the Edit Schedule dialog, which lets you change an existing schedule.

  • Delete Removes the schedule from the list so that the event no longer executes according to that schedule.

When the following occurs Executes the event when a circumstance or condition is met.

  • System event Select a system event that must occur to trigger the event.

    For more information about system events, see Choosing a system event.

  • And the following trigger conditions Set trigger conditions that must be satisfied, in addition to the system event, which trigger the event.

    For more information about trigger conditions, see Defining trigger conditions for events.

    • New Displays the Create Trigger Condition dialog, which lets you create a new trigger condition for the event.

    • Edit Displays the Edit Trigger Condition dialog, which lets you change an existing trigger condition.

    • Delete Removes the trigger condition from the list so that the event no longer executes based on that trigger condition.

See also
  • CREATE EVENT statement
  • Automating Tasks Using Schedules and Events


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

External Login property sheet

The External Login property sheet consists of one tab: General.

External Login property sheet: General tab


External Login property sheet: General tab

The General tab of the External Login property sheet has the following components:

Name Shows the name of the external login.

Type Shows the type of object.

Remote server Shows the name of the remote server the external login is used to communicate with.

User Shows the name of the database user the external login is for.

Login name Shows the login name on the remote server.

See also
  • Working with external logins
  • CREATE EXTERNLOGIN statement


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Foreign Key property sheet

The Foreign Key property sheet consists of two tabs: General and Columns.

See also
  • Managing foreign keys


Foreign Key property sheet: General tab

The General tab of the Foreign Key property sheet has the following components:

Name Shows the name of the foreign key. You can change the name of the foreign key in this field.

Type Shows the type of object.

Foreign table Shows the name of the table the foreign key belongs to, as well as the table's owner.

Primary table Shows the table containing primary key in this foreign key relationship.

Check on commit Forces the database to wait for a COMMIT before checking the integrity of the foreign key, overriding the setting of the WAIT_FOR_COMMIT database option.

Allows null Determines whether the foreign key columns allow NULL values. To use this option, the foreign key columns must all have Allow Nulls set to Yes.

  • Change Opens the Change Settings dialog where you can change the settings for this primary key.

Update action Uses one of the following settings to define the behavior of the table when a user tries to update data.

  • Not permitted Prevents updates of the associated primary table's primary key value if there are no corresponding foreign keys.

  • Cascade Updates the foreign key to match a new value for the associated primary key.

  • Set to null Sets all the foreign key values that correspond to the updated primary key of the associated primary table to NULL.

    To use this option, the foreign key columns must all have Allow Nulls set to Yes.

  • Set Default Sets foreign key values that match the updated or deleted primary key value to values specified in the DEFAULT clause of each foreign key column. To use this option, the foreign key columns must all have default values.

Delete action Uses one of the following settings to define the behavior of the table when a user tries to delete data.

  • Not permitted Prevents deletion of the associated primary table's primary key value if there are no corresponding foreign keys in the table.

  • Cascade Deletes the rows from the table that match the deleted primary key of the associated primary table.

  • Set values to NULL Sets all the foreign key values in the table that correspond to the deleted primary key of the associated primary table to NULL.

    To use this option, the foreign key columns must all have Allow Nulls set to Yes.

  • Set Default Sets foreign key values that match the updated or deleted primary key value to values specified in the DEFAULT clause of each foreign key column. To use this option, the foreign key columns must all have default values.

Clustered Shows whether the primary or foreign table uses a clustered index. Clustered indexes are supported for Adaptive Server Anywhere databases that are version 8.0.2 and higher.

Clustered indexes in Adaptive Server Anywhere store the table rows in approximately the same order as they appear in the corresponding index. Using a clustered index can lead to performance benefits by reducing the number of times each page needs to be read into memory. Only one index on a table can be a clustered index.

For more information about clustered indexes, see CREATE INDEX statement.

  • Set Clustered Index Now Opens the Set Clustered Index dialog where you can specify that an index on the primary or foreign table is a clustered index.

Index type Shows the type of index the table has.

For more information about indexes, see Indexes.

Maximum hash size This information only appears for databases that are created with Adaptive Server Anywhere 7 or earlier. The hash size is the number of bytes used to store a value in an index.

Adaptive Server Anywhere version 6 and 7 databases use regular B-tree indexes with a hash size of 10.

Comment Provides a place for you to type a text description of the foreign key. For example, you could use this area to describe the foreign key's purpose in the system.

See also
  • Managing foreign keys
  • Ensuring Data Integrity
  • Set Clustered Index dialog
  • Change Settings dialog


Foreign Key property sheet: Columns tab

The Columns tab of the Foreign Key property sheet has the following components:

Foreign Columns list Shows the column in the foreign table that references the primary key.

Primary Columns list Shows the column containing the primary key that the foreign key references.

  • Details Displays the Column Details dialog, which shows a summary of the properties of the selected column.

See also
  • Managing foreign keys


Function property sheet

The Function property sheet consists of three tabs: General, Parameters, and Permissions. In most cases, the term procedure refers to both user-defined procedures and user-defined functions.


Function property sheet: General tab

The General tab of the Function property sheet has the following components:

Name Shows the name of the function.

Type Shows the type of object.

Owner Shows the name of the database user who created and owns the function.

Dialect Shows the SQL dialect in which the code was last saved. The dialect is either Watcom-SQL or Transact-SQL.

Comment Provides a place for you to type a description of the function. For example, you could use this area to describe the function's purpose in the system.

See also
  • Function types
  • CREATE PROCEDURE statement


Function property sheet: Parameters tab

The Parameters tab of the Function property sheet has the following components:

Parameters list Displays the name, data type, parameter type, and mode of the function's parameters. The mode has one of the following values:

  • In The parameter is an expression that provides a value to the function.

  • Out The parameter is a variable that could be given a value by the function.

  • Inout The parameter is a variable that provides a value to the function, and could be given a new value by the function.

See also
  • Declaring parameters for procedures
  • Using Procedures, Triggers, and Batches
  • CREATE PROCEDURE statement


Function property sheet: Permissions tab

The Permissions tab of the Function property sheet has the following components:

Users list Lists the users who have permissions on the function. If you want to add users to the list, click Grant. To remove permissions from a user, select the user and click Revoke. You can select multiple users by holding Shift while you click.

Click the Execute field beside each user to grant or revoke permissions.

  • Grant Displays the Grant Permissions dialog, which lets you grant permissions for the function to other users or groups.

  • Revoke Revokes permissions for the function from the user or group and removes them from the Users list.

See also
  • Granting permissions on procedures
  • Grant Permissions dialog


Group property sheet

The Group property sheet consists of three tabs: General, Authorities, and Permissions.

See also
  • Managing User IDs and Permissions
  • Granting and revoking remote permissions


Group property sheet: General tab

The General tab of the Group property sheet has the following components:

Name Shows the name of the group.

Type Shows the type of object.

Allowed to connect Select this option to allow the group to connect to the database. If the group is not allowed to connect, the password (if one was supplied) is removed from the account. If you later change the group to allow them to connect, you must supply a new password. Clearing this option disables the Password and Confirm Password options.

Users are almost always allowed to connect. For a group, however, turning this option off prevents anyone from connecting to the database using the group account itself.

  • Password Type the password for the group. For added security, the characters appear as asterisks.

  • Confirm password Confirm the password that you typed in the Password text box by entering it again. The contents of the two fields must match exactly.

Comment Provides a place for you to type a text description of the group. For example, you could use this area to describe the group's purpose in the system.

See also
  • Creating groups
  • Managing User IDs and Permissions


Group property sheet: Authorities tab

The Authorities tab of the Group property sheet has the following components:

DBA Grants DBA authority to the group; a group with DBA authority can fully administer the database.

Resource Grants resource authority to the group; a group with resource authority can create database objects.

Remote DBA Grants Remote DBA authority to the group. A user ID with this type of authority should run the SQL Remote Message Agent to ensure that actions can be carried out without creating security loopholes. The MobiLink client utility, dbmlsync, also requires Remote DBA authority.

See also
  • Permissions of groups


Group property sheet: Permissions tab

The Permissions tab of the Group property sheet has the following components:

Permissions list Shows all the tables the group has permissions on, as well as the user who owns each table. You can click the fields beside each group to grant or revoke permissions; double-clicking (so that a checkmark and two + signs appear) gives the group grant options for the permission.

Show Select what type of object appears in the Permissions list:

Tables All tables the group has permissions on.

Views All views that the group has permissions on.

Procedures & functions All procedures and functions the group has permissions on. You can only grant Execute permissions for procedures and functions.

See also
  • Creating groups


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Index property sheet

The Index property sheet consists of two tabs: General and Columns.


Index property sheet: General tab

The General tab of the Index property sheet has the following components:

Name Shows the name of the index.

Type Shows the type of object.

Table Shows the name and owner of the table with which the index is associated.

Dbspace Shows the database file, or dbspace, where the index is located.

Unique Shows whether values in the index must be unique. The unique value is set when you create a new index.

Clustered Shows whether this index is a clustered index. Clustered indexes are supported for Adaptive Server Anywhere databases that are version 8.0.2 and higher.

Clustered indexes in Adaptive Server Anywhere store the table rows in approximately the same order as they appear in the corresponding index. Using a clustered index can lead to performance benefits by reducing the number of times each page needs to be read into memory. Only one index on a table can be a clustered index.

For more information about clustered indexes, see CREATE INDEX statement.

  • Set Clustered Index Now Opens the Set Clustered Index dialog where you can specify that this index is a clustered index.

Index type Shows the type of index the table has.

Maximum hash size This information only appears for databases that are created with Adaptive Server Anywhere 7 or earlier. The hash size is the number of bytes used to store a value in an index.

For more information about indexes, see Indexes.

Adaptive Server Anywhere version 6 and 7 databases use regular B-tree indexes with a hash size of 10.

Comment Provides a place for you to type a text description of the index. For example, you could use this area to describe the index's purpose in the system.

See also
  • Indexes
  • CREATE INDEX statement


Index property sheet: Columns tab

The Columns tab of the Index property sheet has the following components:

Columns list Shows all the columns in the index, as well as their order, either ascending or descending. You set the order when you create a new index.

The columns are sorted by their sequence, which is a unique number starting at 0. The order of the numbers determines the relative position of the columns in the index.

  • Details Displays the Column Details dialog, which shows a summary of the properties of the selected column.

See also
  • Indexes
  • Working with indexes
  • CREATE INDEX statement


Integrated Login property sheet

The Integrated Login property sheet consists of one tab: General.

Integrated Login property sheet: General tab


Integrated Login property sheet: General tab

The General tab of the Integrated Login property sheet has the following components:

Name Shows the name of the integrated login.

Type Shows the type of object.

Database user Shows the database user the integrated login is for.

Comment Provides a place for you to type a text description of the integrated login. For example, you could use this area to describe the integrated login's purpose in the system.

See also
  • Using integrated logins


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

JAR File property sheet

The JAR File property sheet consists of one tab: General.

JAR File property sheet: General tab


JAR File property sheet: General tab

The General tab of the JAR file property sheet has the following components:

Name Shows the name of the JAR file.

Type Shows the type of object.

Creator Shows the database user who created and owns the JAR file.

Date created Shows the date the JAR file was created.

Date modified Shows the date the JAR file was last modified.

Comment Provides a place for you to type a text description of the JAR file. For example, you could use this area to describe the JAR file's purpose in the system.

Update Now Displays the Update JAR File dialog, which lets you update the JAR file.

For more information about updating a Java Class, see Updating classes and Jars.


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Java Class property sheet

The Java Class property sheet consists of one tab: General.

Java Class property sheet: General tab


Java Class property sheet: General tab

The General tab of the Java Class property sheet has the following components:

Name Shows the name of the Java class.

Type Shows the type of object.

Creator Shows the database user who created the Java class.

JAR file Shows the name of the JAR file containing the Java class. Java classes do not have to be contained in a JAR file.

Date created Shows the date the JAR file was created.

Date modified Shows the date the JAR file was last modified.

Comment Provides a place for you to type a text description of the Java class. For example, you could use this area to describe the Java Class's purpose in the system.

Update Now Displays the Update Java Class dialog, which lets you update the Java class.

For more information about updating Java classes, see Updating classes and Jars.


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Message Type property sheet

The Message Type property sheet consists of two tabs: General and SQL Remote Users.


Message Type property sheet: General tab

The General tab of the Message Type property sheet has the following components:

Name Shows the name of the message type.

Type Shows the type of object.

Publisher address Provides a place for you to type the address of the publisher. Each remote database sends a replication message back to the consolidated database at the address.

Comment Provides a place for you to type a text description of the message type. For example, you could use this area to describe the message type's purpose in the system.

See also
  • Using message types


Message Type property sheet: SQL Remote Users tab

The SQL Remote Users tab of the Message Type property sheet has the following components:

Remote Users list Lists all the remote users that are currently using the message type by name, address, and comment.

Properties Displays the property sheet for the remote user selected in the Remote Users list.

See also
  • Using message types


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

MobiLink User property sheet

The MobiLink User property sheet consists of three tabs: General, Connection, and Extended Options.


MobiLink User property sheet: General tab

The General tab of the MobiLink User property sheet has the following components:

Name Shows the name of the MobiLink user.

Type Shows the type of object.

See also
  • About MobiLink users


MobiLink User property sheet: Connection tab

The Connection tab of the MobiLink User property sheet has the following components:

Protocol Specify the communication protocol to use for synchronization. TCP/IP is used by default.

The settings you can specify on the Connection tab depend on the communication protocol you are using. Any additional parameters, such as buffer_size, can be set in the Advanced field.

For a complete list of parameters supported by each of the protocols, see CREATE SYNCHRONIZATION USER statement [MobiLink] or CommunicationType (ctp) extended option.

  • TCP/IP Select this option to use the TCP/IP protocol for synchronization. TCP/IP supports both elliptic-curve (formerly Certicom) and RSA encryption.

  • HTTP Select this option to use the HTTP protocol for synchronization. HTTP supports both elliptic-curve (formerly Certicom) and RSA encryption.

  • HTTPS Select this option to use the HTTPS protocol for synchronization. You can only use RSA encryption with the HTTPS protocol.

  • HTTPS FIPS Select this option to use the HTTPS_FIPS protocol for synchronization.

  • ActiveSync Select this option to use ActiveSync to exchange data with the MobiLink provider for ActiveSync, which resides on the desktop machine. The ActiveSync parameters describe the communications between the MobiLink provider for ActiveSync and the MobiLink synchronization server.

    For more information, see ActiveSync provider installation utility.

Host The IP number or host name of the machine on which the MobiLink synchronization server is running. The default value is localhost. You can use localhost if the synchronization server is running on the same machine as the client.

For Windows CE, the default value is the value of ipaddr in the registry folder Comm\Tcpip\Hosts\ppp_peer. This allows a Windows CE device to connect to a MobiLink synchronization server executing on the desktop machine where the Windows CE device's cradle is connected.

For the Palm Computing Platform, the default value of localhost refers to the device. It is recommended that you specify an explicit host name or IP address.

  • Port The MobiLink synchronization server communicates over a specific port. The default port number is 2439 for TCP/IP, 80 for HTTP, and 443 for HTTPS. If you choose a different value, you must configure your MobiLink synchronization server to listen on the port you specify.

Proxy host Type the host name or IP address of the proxy server. The default value is localhost. This option is only available for HTTP and HTTPS synchronization.

  • Proxy port Type the port number of the proxy server. The default value is 80 for HTTP and 443 for HTTPS. This option is only available for HTTP and HTTPS synchronization.

URL suffix Type the suffix to add to the URL on the first line of each HTTP request. The default value is MobiLink. This option is only available for HTTP and HTTPS synchronization.

When synchronizing through a proxy server, the suffix may be necessary in order to find the MobiLink synchronization server.

  • HTTP Version Type the value specifying the version of HTTP to use for synchronization. You have a choice of 1.0 or 1.1. The default value is 1.1.

Automatic connection The following options allow MobiLink clients running on Pocket PC 2002 or Windows desktop computers to connect through dial-up network connections.

When used with scheduling, your remote device can synchronize unattended. When used without scheduling, you can run dbmlsync without manually dialing a connection.

For more information about scheduling, see Scheduling synchronization.

Network name Specify the network name so that you can use MobiLink's auto-dial feature. This allows you to connect from a Pocket PC 2002 or Windows desktop computer without manually dialing. The name should be the network name that you have specified in the dropdown list in Settings > Connections > Connections (Pocket PC) or Network & Dialup Connections (Windows).

Network connect timeout When you specify a network name, you can optionally specify a timeout after which the dial-up fails. This feature applies only to Pocket PC 2002. (On Windows, you can control this feature by configuring the connection profile.) The default is 120 seconds.

Leave open When you supply a network name, you can optionally specify whether the connection should be left open (1) or closed (0) after synchronization finishes. By default, the connection is closed.

Security These options allow you to use a cipher suite to encrypt all communication through this connection. You can provide information about the certificate used to authenticate the server in the fields below for both the elliptic-curve and RSA ciphers.

Enable Certicom security Select this option to encrypt all communication through this connection. You can use the elliptic-curve or RSA cipher. By default, elliptic curves are used.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

For more information about security, see MobiLink Transport-Layer Security.

  • Elliptic curves Uses the elliptic-curve cipher to encrypt connections. You can use this cipher to encrypt TCP/IP and HTTP connections. This was formerly called Certicom encryption.

  • RSA Uses the RSA cipher to encrypt all connections. You can use this cipher to encrypt TCP/IP, HTTP, and HTTPS connections.

  • RSA FIPS Uses the RSA FIPS cipher to encrypt all connection. You can use this cipher to encrypt communications over the TCP/IP and HTTPS FIPS protocols.

    • Certificate company Type the name of the certificate authority or organization that issued the certificate. The server's and the client's values must match.

    • Certificate unit Type the certificate unit. This is also called the organizational unit. The server's and the client's values must match.

    • Certificate name Type the certificate's common name. The server's and the client's values must match.

    • Trusted certificates Type the name of the certificate file the client uses to authenticate the server.

Advanced Type any additional connection parameters in this field, entering them in the form parameter=value, with multiple parameters separated by semicolons. For example, to set the maximum body size for a fixed content length message, and to instruct the client to attempt to use the same TCP/IP connection for all HTTP requests in a synchronization, you would enter the following in the Advanced field:

buffer_size=58000;persistent=TRUE

For a complete list of connection parameters you can enter in this field, see CREATE SYNCHRONIZATION USER statement [MobiLink].

Note

You can set connection parameters for synchronization in several ways.

For information about how dbmlsync resolves conflicting options, see Priority order for extended options and connection parameters.

If a field is blank on the Connection tab of the MobiLink User property sheet, the MobiLink user may be inheriting the connection parameter setting from the synchronization subscription. You should only supply connection parameters on the Connection tab of the MobiLink User property sheet if you want to override the publication's settings.

See also
  • CREATE SYNCHRONIZATION USER statement [MobiLink]
  • ALTER SYNCHRONIZATION USER statement [MobiLink]
  • dbmlsync extended options
  • -eu option
  • CommunicationAddress (adr) extended option


MobiLink User property sheet: Extended Options tab

The Extended Options tab of the MobiLink User property sheet has the following components:

This MobiLink user has the following extended options Lists the extended options and the values set for the MobiLink user. Click the Value field beside the option name to set the value for the MobiLink user.

The table below lists all the available extended options for synchronization.

For more information about these options, see dbmlsync extended options.

Extended option | Default | Description
ConflictRetries (cr) extended option | -1 (continue indefinitely) | Specifies the number of retries if the download fails because of conflicts.
ContinueDownload (cd) extended option | OFF | Specifies restartable downloads.
DisablePolling (p) extended option | OFF | Disables automatic logscan polling.
DownloadBufferSize (dbs) extended option | 32 K on Windows CE, 1 M on all other operating systems. | Specifies the size of the download buffer. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
DownloadOnly (ds) extended option | OFF | Specifies that synchronization should be download-only.
DownloadReadSize (drs) extended option | 32 K | For restartable downloads, specifies the maximum amount of data that may need to be resent after a communications failure.
ErrorLogSendLimit (el) extended option | 32 K | Specifies how much of the remote log file dbmlsync should send to the server when synchronization occurs. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively. If you don't want to send any dbmlsync output log messages, a zero value should be set for this extended option.
FireTriggers (ft) extended option | ON | Specifies that triggers should be fired on the remote database when the download is applied.
HoverRescanThreshold (hrt) extended option | 1 M | When you are using scheduling, this limits the amount of discarded memory that is allowed to accumulate before a rescan is performed. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
IgnoreHookErrors (eh) extended option | OFF | Specifies that errors that occur in hook functions should be ignored.
IgnoreScheduling (isc) extended option | OFF | Specifies that scheduling settings should be ignored.
Increment (inc) extended option | (infinite) | Controls the size of incremental uploads. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
LockTables (lt) extended option | ON | Specifies that articles (tables or parts of tables in the publications being synchronized) should be locked before synchronizing.
Memory (mem) extended option | 1 M | Specifies a cache size. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
MirrorLogDirectory (mld) extended option | (none) | Specifies the location of old mirror log files so that they can be deleted.
MobiLinkPwd (mp) extended option | NULL | Specifies the MobiLink password.
NewMobiLinkPwd (mn) extended option | NULL | Specifies a new MobiLink password.
OfflineDirectory (dir) extended option | NULL | Specifies the path containing offline transaction logs.
PollingPeriod (pp) extended option | 1 minute | Specifies the logscan polling period. By default, units of minutes are used. You can use the suffix s, m, h, or d to specify units of seconds, minutes, hours, or days, respectively.
Schedule (sch) extended option | No schedule | Specifies a schedule for synchronization.
ScriptVersion (sv) extended option | DEFAULT | Specifies a script version.
SendColumnNames (scn) extended option | OFF | Specifies that column names should be sent in the upload.
SendDownloadACK (sa) extended option | OFF | Specifies that a download acknowledgement should be sent from the client to the server.
SendTriggers (st) extended option | OFF | Specifies that trigger actions should be sent on upload.
TableOrder (tor) extended option | (none) | Specifies the order of tables in the upload stream.
UploadOnly (uo) extended option | OFF | Specifies that synchronization should only include an upload.
Verbose (v) extended option | OFF | Specifies full verbosity. This option is identical to dbmlsync -v+.
VerboseHooks (vs) extended option | OFF | Specifies that messages related to hook scripts should be logged. This option is identical to dbmlsync -vs.
VerboseMin (vm) extended option | OFF | Specifies that a small amount of information should be logged. This option is identical to dbmlsync -v.
VerboseOptions (vo) extended option | OFF | Specifies that information should be logged about the command line options (including extended options) that you have specified. This option is identical to dbmlsync -vo.
VerboseRowCounts (vn) extended option | OFF | Specifies that the number of rows that are uploaded and downloaded should be logged. This option is identical to dbmlsync -vn.
VerboseRowValues (vr) extended option | OFF | Specifies that the values of rows that are uploaded and downloaded should be logged. This option is identical to dbmlsync -vr.
VerboseUpload (vu) extended option | OFF | Specifies that information about the upload stream should be logged. This option is identical to dbmlsync -vu.
Note

You can set connection parameters for synchronization in several ways.

For information about how dbmlsync resolves conflicting options, see Priority order for extended options and connection parameters.


Parameter property sheet

The Parameter property sheet consists of one tab: General. In most cases, the term procedure refers to both user-defined procedures and user-defined functions.

Parameter property sheet: General tab


Parameter property sheet: General tab

The General tab of the Parameter property sheet has the following components:

Name Shows the name of the selected parameter.

Type Shows the type of object.

Procedure Shows the name of the procedure the parameter belongs to, with the name of the procedure's owner in parenthesis.

Data type Shows the data type of the parameter.

For a list of valid data types, see SQL Data Types.

Parameter type Shows the type of parameter. The parameter has one of the following types:

  • Variable A normal procedure parameter.

  • Result A column in a result set returned by the procedure.

  • SQLSTATE The special SQLSTATE output parameter. This parameter is an OUT parameter that outputs the SQLSTATE value when the procedure ends.

    For more information about the SQLSTATE parameter, see CREATE PROCEDURE statement.

  • SQLCODE The special SQLCODE output parameter. This parameter is an OUT parameter that outputs the SQLCODE value when the procedure ends.

    For more information about the SQLCODE parameter, see CREATE PROCEDURE statement.

  • Return The return value. This parameter type only applies to functions.

Mode Shows the mode of the parameter. The mode has one of the following values:

  • In The parameter is an expression that provides a value to the function.

  • Out The parameter is a variable that could be given a value by the function.

  • Inout The parameter is a variable that provides a value to the function, and could be given a new value by the function.

See also
  • CREATE PROCEDURE statement


Procedure property sheet

The Procedure property sheet consists of three tabs: General, Parameters, and Permissions. In most cases, the term procedure refers to both user-defined procedures and user-defined functions.


Procedure property sheet: General tab

The General tab of the Procedure property sheet has the following components:

Name Shows the name of the procedure.

Type Shows the type of object.

Owner Shows the name of the database user who created and owns the procedure.

Dialect Shows the SQL dialect in which the code was last saved. The dialect is either Watcom-SQL or Transact-SQL.

Comment Provides a place for you to type a description of the procedure. For example, you could use this area to describe the procedure's purpose in the system.

See also
  • CREATE PROCEDURE statement


Procedure property sheet: Parameters tab

The Parameters tab of the Procedure property sheet has the following components:

Parameters list Displays the name, data type, parameter type, and mode of the procedure's parameters. The mode has one of the following values:

  • IN The parameter is an expression that provides a value to the procedure.

  • OUT The parameter is a variable that could be given a value by the procedure.

  • INOUT The parameter is a variable that provides a value to the procedure, and could be given a new value by the procedure.

See also
  • Declaring parameters for procedures
  • Using Procedures, Triggers, and Batches
  • CREATE PROCEDURE statement


Procedure property sheet: Permissions tab

The Permissions tab of the Procedure property sheet has the following components:

Users list Lists the users who have permissions on the procedure. If you want to add users to the list, click Grant. To remove permissions from a user, select the user and click Revoke. You can select multiple users by holding Shift while you click.

Click the Execute field beside each user to grant or revoke permissions.

  • Grant Displays the Grant Permission dialog, which lets you grant permissions for the procedure to other users or groups.

  • Revoke Revokes permissions for the procedure from the user or group and removes them from the Users list.

See also
  • Granting permissions on procedures
  • CREATE PROCEDURE statement


Proxy Table property sheet

The Proxy Table property sheet consists of four tabs: General, Columns, Permissions, and Miscellaneous.

See also
  • Working with proxy tables

Proxy Table property sheet: General tab
Proxy Table property sheet: Columns tab
Proxy Table property sheet: Permissions tab
Proxy Table property sheet: Miscellaneous tab


Proxy Table property sheet: General tab

The General tab of the Proxy Table property sheet has the following components:

Name Shows the name of the proxy table. You cannot change the name of the proxy table.

Type Shows the type of object.

Owner Shows the name of the database user who created and owns the proxy table.

Remote location Shows the name of the remote server that contains the remote table, the remote database, the remote database user who owns the remote table, and the name of the remote table the proxy table is based on.

Columns Shows the primary key columns for the proxy table.

Comment Provides a place for you to type a text description of the proxy table. For example, you could use this area to describe the proxy table's purpose in the system.

See also
  • Working with proxy tables


Proxy Table property sheet: Columns tab

The Columns tab of the Proxy Table property sheet has the following components:

Columns list Lists all the columns in the proxy table, as well as their type and comments. You can double-click a column to open the Column Details dialog.

Details Displays the Column Details dialog, which shows a summary of the properties for the selected column.

See also
  • Working with proxy tables


Proxy Table property sheet: Permissions tab

The Permissions tab of the Proxy Table property sheet has the following components:

Users list Lists the users who have permissions on the proxy table. If you want to add users to the list, click Grant. To remove permissions from a user, select the user and click Revoke. You can select multiple users by holding Shift while you click.

To grant or revoke permissions, click the fields beside each user. Double-clicking (so that a check mark and two + signs appear) gives the user grant options.

  • Grant Displays the Grant Permission dialog, which lets you grant permissions for the proxy table to other users or groups.

  • Revoke Revokes permissions for the proxy table from the user or group and removes them from the Users list.

Select You must select a user from the Users list to enable this option. Shows whether the Select permissions for the user apply to all columns or a subset of columns. Click Change to open the Column Permissions dialog where you can grant Select permissions for a subset of columns.

Update You must select a user from the Users list to enable this option. Shows whether the user's Update permissions apply to all columns or a subset of columns. Click Change to open the Column Permissions dialog where you can grant Update permissions for a subset of columns.

References You must select a user from the Users list to enable this option. Shows whether the Reference permissions for the user apply to all columns or a subset of columns. Click Change to open the Column Permissions dialog where you can grant Reference permissions for a subset of columns.

See also
  • Working with proxy tables


Proxy Table property sheet: Miscellaneous tab

The Miscellaneous tab of the Proxy Table property sheet has the following components:

Maximum table width Shows the number of bytes required for each row in the proxy table. The number is calculated from the length of the string columns, the precision of numeric columns, and the number of bytes of storage for all other data types. If the proxy table includes long binary or long VARCHAR columns, their arbitrary widths are not included, so the row width can only be approximated.

Number of rows This option is not available for proxy tables.

  • Calculate The button is not enabled for proxy tables.

See also
  • Working with proxy tables


Publication property sheet

The Publication property sheet consists of four tabs: General, Articles, Connection, and Extended Options.

Publication property sheet: General tab
Publication property sheet: Articles tab
Publication property sheet: Connection tab
Publication property sheet: Extended Options tab


Publication property sheet: General tab

The General tab of the Publication property has the following components:

Name Shows the name of the publication. You can change the publication's name in the text box.

Type Shows the type of object.

Owner Shows the name of the database user who created and owns the publication.

Comment Provides a place for you to type a text description of the publication. For example, you could use this area to describe the publication's purpose in the system.

See also
  • CREATE PUBLICATION statement


Publication property sheet: Articles tab

The Articles tab of the Publication property sheet has the following components:

  • Tables tab The Tables tab lets you select tables to include in your client database.

  • Columns tab The Columns tab lets you select columns from the tables to include in your client database.

  • WHERE Clauses tab The WHERE Clauses tab lets you type a WHERE clause to restrict the rows included in the article.

    Articles defined for SQL Remote and MobiLink publications can use a WHERE clause to define a subset of rows of a table to be included in an article. UltraLite applications can use row subsets by supplying a WHERE clause, with one exception: articles in UltraLite publications governing HotSync synchronization cannot use a WHERE clause.

  • SUBSCRIBE BY Restrictions tab The SUBSCRIBE BY Restrictions tab lets you type a SUBSCRIBE BY restriction to define a subset of rows to be included in the article. This tab only applies to SQL Remote articles.

Each tab is described in detail below.

See also
  • CREATE PUBLICATION statement
  • Publishing only some rows using a WHERE clause
Tables tab

The Tables tab lets you select tables and add them to the list of articles that are included in the client database.

Available Tables list Lists all the base table in the database you are currently connected to. To add a table to the Selected Tables list, select the table in the Matching Tables list, then click Add.

Selected Tables list Lists all the tables that are included in the article for the client database. If you want to remove a table from the Selected Tables list, select the table, then click Delete.

You can use the Table Pattern and Owner Pattern fields to limit the tables shown in the Matching Tables list, and so locate the tables you want to include.

  • Add Adds the table selected in the Matching Tables list to the Selected Tables list so the table is included in the article.

  • Remove Removes the selected table from the Selected Tables list so the table is not included in the article.

Columns tab

The Columns tab lets you select columns from tables and add them to the list of articles that are included in the client database.

Available columns list Lists the tables selected on the Tables tab. Double-click a table in the list to display its columns. To add a column to the Selected Columns list, select the table in the Available Columns list, then click Add.

Selected columns list Lists all the columns that are included in the article for the client database. If you want to remove a column from the Selected Columns list to remove the column from the article, select the column, then click Delete.

  • Add Adds the column selected in the Available Columns list to the Selected Columns list so it is included in your client database articles.

  • Remove Removes the column from the Selected Columns list so it is not included in the article.

WHERE Clauses tab

Articles defined for SQL Remote and MobiLink publications can use a WHERE clause to define a subset of rows of a table to be included in an article. UltraLite applications can use row subsets by supplying a WHERE clause, with one exception: articles in UltraLite publications governing HotSync synchronization cannot use a WHERE clause.

The WHERE Clauses tab lets you supply a WHERE clause to restrict the rows that are included in the client database.

Articles list Select a table from the list of tables included in the article.

The selected article has the following WHERE clause In the text box, type the WHERE clause for the table to restrict the rows that are included in the article.

For more information, see Publishing only some rows using a WHERE clause.

See also
  • The WHERE clause: specifying rows
SUBSCRIBE BY Restrictions tab

This tab only applies to SQL Remote articles.

The SUBSCRIBE BY Restrictions tab lets you define a subset of rows of a table for inclusion in the article.

Articles list Select a table from the list of tables included in the article.

The selected article has the following SUBSCRIBE BY restriction You can choose one of the following options for the SUBSCRIBE BY restriction for the article:

  • None Select this option if the article does not have a SUBSCRIBE BY restriction.

  • Column Select this option if you want to include a specific column in the article.

  • Expression In the text box, type a subscription expression to include a different set of rows in different subscriptions to publications containing the article.

See also
  • Publishing only some rows using a subscription expression


Publication property sheet: Connection tab

The Connection tab of the Publication property sheet has the following components:

Protocol Specify the communication protocol to use for synchronization. TCP/IP is used by default.

The settings you can specify on the Connection tab depend on the communication protocol you are using. Any additional parameters, such as buffer_size, can be set in the Advanced field.

For a complete list of parameters supported by each of the protocols, see CREATE SYNCHRONIZATION USER statement [MobiLink] or CommunicationType (ctp) extended option.

  • TCP/IP Select this option to use the TCP/IP protocol for synchronization. TCP/IP supports both elliptic-curve (formerly Certicom) and RSA encryption.

  • HTTP Select this option to use the HTTP protocol for synchronization. HTTP supports both elliptic-curve (formerly Certicom) and RSA encryption.

  • HTTPS Select this option to use the HTTPS protocol for synchronization. You can only use RSA encryption with the HTTPS protocol.

  • HTTPS FIPS Select this option to use the HTTPS_FIPS protocol for synchronization.

  • ActiveSync Select this option to use ActiveSync to exchange data with the MobiLink provider for ActiveSync, which resides on the desktop machine. The ActiveSync parameters describe the communications between the MobiLink provider for ActiveSync and the MobiLink synchronization server.

    For more information, see ActiveSync provider installation utility.

Host The IP number or host name of the machine on which the MobiLink synchronization server is running. The default value is localhost. You can use localhost if the synchronization server is running on the same machine as the client.

For Windows CE, the default value is the value of ipaddr in the registry folder Comm\Tcpip\Hosts\ppp_peer. This allows a Windows CE device to connect to a MobiLink synchronization server executing on the desktop machine where the Windows CE device's cradle is connected.

For the Palm Computing Platform, the default value of localhost refers to the device. It is recommended that you specify an explicit host name or IP address.

  • Port The MobiLink synchronization server communicates over a specific port. The default port number is 2439 for TCP/IP, 80 for HTTP, and 443 for HTTPS. If you choose a different value, you must configure your MobiLink synchronization server to listen on the port you specify.

Proxy host Type the host name or IP address of the proxy server. The default value is localhost. This option is only available for HTTP and HTTPS synchronization.

  • Proxy port Type the port number of the proxy server. The default value is 80 for HTTP and 443 for HTTPS. This option is only available for HTTP and HTTPS synchronization.

URL suffix Type the suffix to add to the URL on the first line of each HTTP request. The default value is MobiLink. This option is only available for HTTP and HTTPS synchronization.

When synchronizing through a proxy server, the suffix may be necessary in order to find the MobiLink synchronization server.

  • HTTP Version Type the value specifying the version of HTTP to use for synchronization. You have a choice of 1.0 or 1.1. The default value is 1.1.

Automatic connection The following options allow MobiLink clients running on Pocket PC 2002 or Windows desktop computers to connect through dial-up network connections.

When used with scheduling, your remote device can synchronize unattended. When used without scheduling, you can run dbmlsync without manually dialing a connection.

For more information about scheduling, see Scheduling synchronization.

  • Network name Specify the network name so that you can use MobiLink's auto-dial feature. This allows you to connect from a Pocket PC 2002 or Windows desktop computer without manually dialing. The name should be the network name that you have specified in the dropdown list in Settings > Connections > Connections (Pocket PC) or Network & Dialup Connections (Windows).

  • Network connect timeout When you specify a network name, you can optionally specify a timeout after which the dial-up fails. This feature applies only to Pocket PC 2002. (On Windows, you can control this feature by configuring the connection profile.) The default is 120 seconds.

  • Leave open When you supply a network name, you can optionally specify whether the connection should be left open (1) or closed (0) after synchronization finishes. By default, the connection is closed.

Enable Certicom security Select this option to encrypt all communication through this connection. You can use the elliptic-curve or RSA cipher. By default, elliptic curves are used.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

For more information about security, see MobiLink Transport-Layer Security.

  • Elliptic curves Uses the elliptic-curve cipher to encrypt connections. You can use this cipher to encrypt TCP/IP and HTTP connections. This was formerly called Certicom encryption.

  • RSA Uses the RSA cipher to encrypt all connections. You can use this cipher to encrypt TCP/IP, HTTP, and HTTPS connections.

  • RSA FIPS Uses the RSA FIPS cipher to encrypt all connection. You can use this cipher to encrypt communications over the TCP/IP and HTTPS FIPS protocols.

    • Certificate company Type the name of the certificate authority or organization that issued the certificate. The server's and the client's values must match.

    • Certificate unit Type the certificate unit. This is also called the organizational unit. The server's and the client's values must match.

    • Certificate name Type the certificate's common name. The server's and the client's values must match.

    • Trusted certificates Type the name of the certificate file the client uses to authenticate the server.

Advanced Type any additional connection parameters in this field, entering them in the form parameter=value, with multiple parameters separated by semicolons. For example, to set the maximum body size for a fixed content length message, and to instruct the client to attempt to use the same TCP/IP connection for all HTTP requests in a synchronization, you would enter the following in the Advanced field:

buffer_size=58000;persistent=TRUE

For a complete list of connection parameters you can enter in this field, see CREATE SYNCHRONIZATION USER statement [MobiLink].

Notes

You can set connection parameters for synchronization in several ways.

For information about how dbmlsync resolves conflicting options, see Priority order for extended options and connection parameters.

If a field is blank on the Connection tab of the Publication property sheet, the publication may be inheriting the connection parameter setting from the synchronization subscription or the MobiLink user.

See also
  • CREATE SYNCHRONIZATION USER statement [MobiLink]
  • ALTER SYNCHRONIZATION USER statement [MobiLink]
  • CREATE PUBLICATION statement
  • ALTER PUBLICATION statement
  • -x option
  • CommunicationAddress (adr) extended option


Publication property sheet: Extended Options tab

The Extended Options tab of the Publication property sheet has the following components:

This publication has the following MobiLink extended options Lists the extended options and values set for the publication. Click the Value field beside the option name to set the value for the publication.

The table below lists all the available extended options for synchronization.

For more information about these options, see dbmlsync extended options.

Extended option | Default | Description
ConflictRetries (cr) extended option | -1 (continue indefinitely) | Specifies the number of retries if the download fails because of conflicts.
ContinueDownload (cd) extended option | OFF | Specifies restartable downloads.
DisablePolling (p) extended option | OFF | Disables automatic logscan polling.
DownloadBufferSize (dbs) extended option | 32 K on Windows CE, 1 M on all other operating systems. | Specifies the size of the download buffer. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
DownloadOnly (ds) extended option | OFF | Specifies that synchronization should be download-only.
DownloadReadSize (drs) extended option | 32 K | For restartable downloads, specifies the maximum amount of data that may need to be resent after a communications failure.
ErrorLogSendLimit (el) extended option | 32 K | Specifies how much of the remote log file dbmlsync should send to the server when synchronization occurs. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively. If you don't want to send any dbmlsync output log messages, a zero value should be set for this extended option.
FireTriggers (ft) extended option | ON | Specifies that triggers should be fired on the remote database when the download is applied.
HoverRescanThreshold (hrt) extended option | 1 M | When you are using scheduling, this limits the amount of discarded memory that is allowed to accumulate before a rescan is performed. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
IgnoreHookErrors (eh) extended option | OFF | Specifies that errors that occur in hook functions should be ignored.
IgnoreScheduling (isc) extended option | OFF | Specifies that scheduling settings should be ignored.
Increment (inc) extended option | (infinite) | Controls the size of incremental uploads. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
LockTables (lt) extended option | ON | Specifies that articles (tables or parts of tables in the publications being synchronized) should be locked before synchronizing.
Memory (mem) extended option | 1 M | Specifies a cache size. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
MirrorLogDirectory (mld) extended option | (none) | Specifies the location of old mirror log files so that they can be deleted.
MobiLinkPwd (mp) extended option | NULL | Specifies the MobiLink password.
NewMobiLinkPwd (mn) extended option | NULL | Specifies a new MobiLink password.
OfflineDirectory (dir) extended option | NULL | Specifies the path containing offline transaction logs.
PollingPeriod (pp) extended option | 1 minute | Specifies the logscan polling period. By default, units of minutes are used. You can use the suffix s, m, h, or d to specify units of seconds, minutes, hours, or days, respectively.
Schedule (sch) extended option | No schedule | Specifies a schedule for synchronization.
ScriptVersion (sv) extended option | DEFAULT | Specifies a script version.
SendColumnNames (scn) extended option | OFF | Specifies that column names should be sent in the upload.
SendDownloadACK (sa) extended option | OFF | Specifies that a download acknowledgement should be sent from the client to the server.
SendTriggers (st) extended option | OFF | Specifies that trigger actions should be sent on upload.
TableOrder (tor) extended option | (none) | Specifies the order of tables in the upload stream.
UploadOnly (uo) extended option | OFF | Specifies that synchronization should only include an upload.
Verbose (v) extended option | OFF | Specifies full verbosity. This option is identical to dbmlsync -v+.
VerboseHooks (vs) extended option | OFF | Specifies that messages related to hook scripts should be logged. This option is identical to dbmlsync -vs.
VerboseMin (vm) extended option | OFF | Specifies that a small amount of information should be logged. This option is identical to dbmlsync -v.
VerboseOptions (vo) extended option | OFF | Specifies that information should be logged about the command line options (including extended options) that you have specified. This option is identical to dbmlsync -vo.
VerboseRowCounts (vn) extended option | OFF | Specifies that the number of rows that are uploaded and downloaded should be logged. This option is identical to dbmlsync -vn.
VerboseRowValues (vr) extended option | OFF | Specifies that the values of rows that are uploaded and downloaded should be logged. This option is identical to dbmlsync -vr.
VerboseUpload (vu) extended option | OFF | Specifies that information about the upload stream should be logged. This option is identical to dbmlsync -vu.
Note

You can set connection parameters for synchronization in several ways.

For information about how dbmlsync resolves conflicting options, see Priority order for extended options and connection parameters.


Publisher property sheet

The Publisher property sheet consists of three tabs: General, Authorities, and Permissions.

See also
  • Managing User IDs and Permissions
  • Granting and revoking remote permissions


Publisher property sheet: General tab

The General tab of the Publisher property sheet has the following components:

Name Shows the name of the publisher.

Type Shows the type of object.

Allowed to connect Select this option to allow the publisher to connect to the database. If the publisher is not allowed to connect, the password (if one was supplied) is removed from the account. If you later change the publisher to allow them to connect, you must supply a new password. Clearing this option disables the Password and Confirm Password options.

Users are almost always allowed to connect.

  • Password Type the password for the publisher. For added security, the characters appear as asterisks.

  • Confirm password Confirm the password that you typed in the Password text box by entering it again. The contents of the two fields must match exactly.

Comment Provides a place for you to type a text description of the publisher. For example, you could use this area to describe the publisher's purpose in the system.

See also
  • Granting and revoking remote permissions
  • Managing User IDs and Permissions


Publisher property sheet: Authorities tab

The Authorities tab of the Publisher property sheet has the following components:

DBA Select this option to grant DBA authority to the publisher; a user with DBA authority can fully administer the database.

Resource Select this option to grant resource authority to the publisher; a user with resource authority can create database objects.

Remote DBA Select this option to grant Remote DBA authority to the publisher. The SQL Remote Message Agent should be run using a user ID with this type of authority to ensure that actions can be carried out without creating security loopholes. The MobiLink client utility, dbmlsync, also requires Remote DBA authority.

See also
  • Granting and revoking remote permissions
  • Managing User IDs and Permissions


Publisher property sheet: Permissions tab

The Permissions tab of the Publisher property sheet has the following components:

Permissions list Shows all tables the publisher has permissions on, as well as the user who owns each table. You can click the fields beside each user to grant or revoke permissions; double-clicking (so that a checkmark and two + signs appear) gives the user grant options for the permission.

Show Select what type of object appears in the Permissions list:

  • Tables All tables the publisher has permissions on.

  • Views All views the publisher has permissions on.

  • Procedures & functions Displays all procedures and functions the publisher has permissions on. You can only grant Execute permissions for procedures and functions.

See also
  • Granting and revoking remote permissions


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Remote Procedure property sheet

The Remote Procedure property sheet consists of three tabs: General, Parameters, and Permissions.


Remote procedure property sheet: General tab

The General tab of the Remote Procedure property sheet has the following components:

Name Shows the name of the remote procedure.

Type Shows the type of object.

Owner Shows the name of the database user who created and owns the remote procedure.

Dialect Shows the SQL dialect in which the code was last saved. The dialect is either Watcom-SQL or Transact-SQL.

Remote server The remote database containing the procedure.

Comment Provides a place for you to type a description of the remote procedure. For example, you could use this area to describe the remote procedure's purpose in the system.


Remote procedure property sheet: Parameters tab

The Parameters tab of the Remote Procedure property sheet has the following components:

Parameters list Displays the name, data type, parameter type, and mode of the remote procedure's parameters. The mode has one of the following values:

  • IN The parameter is an expression that provides a value to the procedure.

  • OUT The parameter is a variable that could be given a value by the procedure.

  • INOUT The parameter is a variable that provides a value to the procedure, and could be given a new value by the remote procedure.

See also
  • Using Procedures, Triggers, and Batches
  • CREATE PROCEDURE statement
  • Declaring parameters for procedures


Remote procedure property sheet: Permissions tab

The Permissions tab of the Remote Procedure property sheet has the following components:

Users list Lists the users who have permissions on the remote procedure. If you want to add users to the list, click Grant. To remove permissions from a user, select the user and click Revoke. You can select multiple users by holding Shift while you click.

Click the Execute field beside each user to grant or revoke permissions.

  • Grant Displays the Grant Permission dialog, which lets you grant permissions for the remote procedure to other users or groups.

  • Revoke Revokes permissions for the remote procedure from the user or group and removes them from the Users list.

See also
  • Granting permissions on procedures


Remote Server property sheet

The Remote Server property sheet consists of one tab: General.

See also
  • Working with remote servers
  • Server property sheet

Remote Server property sheet: General tab


Remote Server property sheet: General tab

The General tab of the Remote Server property sheet has the following components:

Name Shows the name of the remote server.

Type Shows the type of object.

Read-only Shows whether or not the remote server is read-only.

Server type Shows the class or software platform of the database server. You can select a different software platform from the dropdown list to change the server type.

The server type that you select restricts the types of connection you can choose from. For example, if you select Generic Server from the Server Type dropdown list, you can only connect using ODBC.

Connection type Lets you choose between the ODBC and JDBC connection protocols.

  • Open database connectivity (ODBC) Select this option to use the ODBC connection protocol. You can use ODBC with any of the servers listed in the Server Type dropdown list.

  • Java database connectivity (JDBC) Select this option to use the JDBC connection protocol. You can use JDBC with the following server types: Sybase Adaptive Server Anywhere and Sybase Adaptive Server Enterprise. If your database is not Java-enabled, the Java Database Connectivity (JDBC) option is not enabled.

    For more information about ODBC and JDBC connection protocols, see JDBC overview and Creating remote servers using Sybase Central.

Connection Information Lets you specify startup connection parameters, such as the name and address of the server.

For ODBC data sources, type the name of the data source. For JDBC access, type a machine name or IP address and a port number in the form hostname:portnumber.

Test Connection Click this button to test whether the information provided in the remote server definition results in a proper connection.

See also
  • CREATE SERVER statement
  • Working with remote servers


Remote User property sheet

The Remote User property sheet consists of four tabs: General, Authorities, Permissions, and SQL Remote.

See also
  • Managing User IDs and Permissions
  • Granting and revoking remote permissions

Remote User property sheet: General tab
Remote User property sheet: Authorities tab
Remote User property sheet: Permissions tab
Remote User property sheet: SQL Remote tab


Remote User property sheet: General tab

The General tab of the Remote User property sheet has the following components:

Name Shows the name of the remote user.

Type Shows the type of object.

Allowed to connect Select this option to allow the remote user to connect to the database. If the remote user is not allowed to connect, the password (if one was supplied) is removed from the account. If you later change the remote user to allow them to connect, you must supply a new password. Clearing this option disables the Password and Confirm Password options.

Users are almost always allowed to connect.

  • Password Type the password for the remote user. For added security, the characters appear as asterisks.

  • Confirm password Confirm the password that you typed in the Password text box by entering it again. The contents of the two fields must match exactly.

Comment Provides a place for you to type a text description of the remote user. For example, you could use this area to describe the remote user's purpose in the system.

See also
  • Granting and revoking remote permissions
  • Managing User IDs and Permissions


Remote User property sheet: Authorities tab

The Authorities tab of the Remote User property sheet has the following components:

DBA Select this option to grant DBA authority to the remote user; a user with DBA authority can fully administer the database.

Resource Select this option to grant resource authority to the remote user; a user with resource authority can create database objects.

Remote DBA Select this option to grant Remote DBA authority to the remote user. The SQL Remote Message Agent should be run using a user ID with this type of authority to ensure that actions can be carried out without creating security loopholes. The MobiLink client utility, dbmlsync, also requires Remote DBA authority.

See also
  • Granting and revoking remote permissions
  • Managing User IDs and Permissions


Remote User property sheet: Permissions tab

The Permissions tab of the Remote User property sheet has the following components:

Permissions list Shows all tables the remote user has permissions on, as well as the user who owns each table. You can click the fields for each table to grant or revoke permissions; double-clicking (so that a checkmark and two + signs appear) gives the user grant options for the permission.

Show Select what type of object appears in the Permissions list:

  • Tables All tables the remote user has permissions on.

  • Views All views the remote user has permissions on.

  • Procedures & functions All procedures and functions the remote user has permissions on. You can only grant Execute permissions for procedures and functions.

See also
  • Granting and revoking remote permissions


Remote User property sheet: SQL Remote tab

The SQL Remote tab of the Remote User property sheet has the following components:

Message type Lets you select a message type for communicating with the publisher.

Address Provides a place for you to type the remote address of the remote user. The address is a string, according to the specified message type, to which the replication messages should be sent for the user.

For information about what address to use with a specific message type, see Using message types.

  • Send then close Sets the replication frequency so that the publisher's agent runs once, sends all pending messages to the remote group, and then shuts down. The means that the agent must be restarted each time the publisher wants to send messages.

    In most replication setups, this option is not used for sending publications from the consolidated publisher to the remote group.

  • Send every Sets the replication frequency so that the publisher's agent runs continuously, sending messages to the remote group at the given periodic interval.

  • Send daily at Sets the replication frequency so that the publisher's agent runs continuously, sending messages to the remote group each day at the specified time.

See also
  • Granting and revoking remote permissions
  • CREATE SUBSCRIPTION statement [SQL Remote]


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Server property sheet

The Server property sheet consists of three tabs: General, Extended Information, and Options.


Server property sheet: General tab

The General tab of the Server property sheet has the following components:

Name Shows the name of the server.

Type Shows the type of object.

Product Shows the server's product type; for example, the product could be Sybase Adaptive Server Anywhere.

Version Shows the version number of the server.

Computer Shows the name of the computer on which the database server is running.

Operating system Shows the operating system that the server is currently running on.

Operating system version Shows the operating system version that the server is currently running on.

See also
  • Server-level properties


Server property sheet: Extended Information tab

The Extended Information tab of the Server property sheet has the following components:

Database server properties list An extended list of server properties and their values. Click Refresh to update the values. You can also press F5 to refresh the server property values.

Refresh Click Refresh to update the values in the Server Properties list.

Description When you select a property from the list, a description of the property appears in the Description window.

See also
  • Server-level properties


Server property sheet: Options tab

The database server options on this tab correspond to server options that can be reset while the server is running.

For more information, see sa_server_option system procedure.

The Options tab of the Server property sheet has the following components:

Current time Displays the current time. Click Refresh to update the Current Time. You can also press F5 to update the current time.

Quitting time You can type a time when the database server is to shut down. Use the same format as the current time, which is as follows:

YYYY-MM-DD HH:NN:SS.SS

Disable new connections Select this option to prevent other users from connecting to the database. The may be useful for some maintenance operations.

Enable request logging Select this option to record requests that the server processes to the log file. This option is primarily for troubleshooting purposes. Selecting Enable Request Logging enables the options below.

  • Log all requests All requests that the server processes are recorded to the log file.

  • Log SQL requests only Limits the types of requests recorded to the log file.

    For a list of the SQL Statements that are logged when you select SQL Requests, see sa_server_option system procedure.

    • Log file name When you select Enable Request Logging, you must provide a log file name. You can also click Browse to locate the file.

    For information about request logging, see -zr server option.

Remember the last statement executed on each connection Select this option to instruct the database server to capture the most recently-prepared SQL statement for each connection to a database on the server.

For more information, see -zl server option.

See also
  • Server-level properties


Service property sheet

The Service property sheet consists of five tabs: General, Configuration, Account, Dependencies, and Polling.

See also
  • Managing services

Service property sheet: General tab
Service property sheet: Configuration tab
Service property sheet: Account tab
Service property sheet: Dependencies tab
Service property sheet: Polling tab


Service property sheet: General tab

The General tab of the Service property sheet has the following components:

Name Shows the name of the service. A service runs a database server or other application with a set of options.

Type Shows the type of object.

Service type Shows the type of service, Network, Standalone, DBRemote, or MobiLink.

Status Shows whether service is started, stopped, or paused.

For more information about the service status, see Starting, stopping, and pausing services.

Startup type You can select one of the following startup options for the service. The startup option is applied the next time you start Windows.

  • Automatic Select this option to start the service automatically whenever the operating system starts.

  • Manual Select this option to start the service manually. Only a user with Administrator permissions can start the service if it requires manual startup.

    For information about Administrator permissions, see your Windows documentation.

  • Disabled Select this option to disable the service so it does not start.

See also
  • Managing services
  • Understanding Windows services


Service property sheet: Configuration tab

The Configuration tab of the Service property sheet has the following components:

File name Provides a place for you to type the path of the executable file. For example, f:\Sybase\ASA90\win32\dbeng9.exe.

You can also click Browse to search for a file.

Parameters Type additional parameters (file names and options) for the executable file in the text box. You can use the same options for a service that you use for the executable.

For example to start a SQL Remote Message Agent service, connecting to the sample database as user ID DBA, type the following:

-c "uid=DBA;pwd=SQL;dbn=asademo"
See also
  • The Service Creation utility
  • The database server


Service property sheet: Account tab

The Account tab of the Service property sheet has the following components:

Local system account Select this option to run the service under your system's local account.

  • Allow service to interact with desktop This option is only available when you select Local System Account. Select this option if you want to display the server window by clicking an icon on your desktop.

Other account Select this option to run the service under an account other than the local account. You must choose a user ID from the dropdown list. Selecting this option enables the Password and Confirm Password fields.

  • Password When you select Other Account, you must supply the appropriate password for the user ID. You must confirm the password in the Confirm Password text box.

  • Confirm password Re-type the user ID's password to confirm that it was entered correctly.

See also
  • Managing services
  • The Service Creation utility


Service property sheet: Dependencies tab

The Dependencies tab of the Service property sheet has the following components:

The service belongs to a service group Select this option if you want to assign the service to be a member of a service group.

  • Service group Lets you specify which service group the service belongs to. To change which service group the service belongs to, click Change. The Set Service Group dialog appears, which lets you specify a service group for the service.

Services list Lists all the services and service groups that must be started before the service. The list also shows the type of service or service group.

To add services or service groups to this list, click Add Services or Add Service Groups, respectively. If you want to remove a service or service group from the Services list, select the service or service group, then click Remove. You can select multiple services or service groups by holding Shift while you click.

  • Add Services Displays the Add Service Dependencies dialog, which lets you view all services and select the ones you want to add to the Services list.

  • Add Service Groups Displays the Add Service Group Dependencies dialog, which lets you select the service groups that you want to add to the Services list.

  • Remove Removes the service or service group from the Services list. The group or service no longer starts before the service.

See also
  • Service dependencies
  • Managing services
  • Running more than one service


Service property sheet: Polling tab

Settings on this tab apply to all services, not just the currently selected service.

The Polling tab of the Service property sheet has the following components:

Enable polling Select this option if you want Sybase Central to poll the services for changes to their states (started, stopped, paused, or removed).

  • Poll every When you select Enable Polling, you must specify how often Sybase Central polls the service to check for status changes. The default interval is 10 seconds. The polling time you set in the window remains in effect for subsequent sessions until you change it explicitly.

See also
  • Setting the service polling frequency
  • Managing services


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

SQL Remote Subscription property sheet

The SQL Remote Subscription property sheet consists of two tabs: General and Advanced.


SQL Remote Subscription property sheet: General tab

The General tab of the SQL Remote Subscription property sheet has the following components:

Name Shows the name of the SQL Remote subscription.

Type Shows the type of object.

Publication Shows the publication the SQL Remote user is subscribed to.

Subscriber Shows the SQL Remote user who is subscribed to the publication.

Subscription value Shows the subscription value for the SQL Remote subscription. The subscription value is a string that is compared to the subscription expression of the publication. The subscriber receives all rows for which the subscription expression matches the subscription value.


SQL Remote Subscription property sheet: Advanced tab

The Advanced tab of the SQL Remote Subscription property sheet has the following components:

Start subscription Click Start Now to manually start subscriptions. However, it is recommended that you let the Extraction utility start subscriptions automatically.

Stop subscription Click Stop Now to stop a subscription that has been started.

Synchronize subscription Click Synchronize Now to synchronize subscriptions manually. However, it is recommended that you let the Extraction utility synchronize subscriptions automatically.

See also
  • START SUBSCRIPTION statement [SQL Remote]


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Statistic property sheet

The Statistic property sheet consists of one tab: the General tab.

Statistic property sheet: General tab


Statistic property sheet: General tab

The General tab of the Statistic property sheet has the following components:

Name Shows the name of the statistic.

Type Shows the type of object.

Description Provides a brief explanation of the statistic.

Graph this statistic in the Performance Monitor Select this option to add the statistic to the Performance Monitor. Clear the checkbox to remove the statistic from the Performance Monitor.

See also
  • Monitoring and Improving Performance


Synchronization Subscription property sheet

The Synchronization Subscription property sheet consists of three tabs: General, Connection, and Extended Options.

Synchronization Subscription property sheet: General tab
Synchronization Subscription property sheet: Connection tab
Synchronization Subscription property sheet: Extended Options tab


Synchronization Subscription property sheet: General tab

The General tab of the Synchronization Subscription property sheet has the following components:

Name Shows the name of the synchronization subscription.

Type Shows the type of object.

Publication Shows the publication the MobiLink user is subscribed to.

Subscriber Shows the MobiLink user who is subscribed to the publication.

Last download time Shows the time of the last download.

Last upload time Shows the time of the last upload.

Generation number Shows the generation number for the synchronization subscription.

Generation numbers provide a mechanism for forcing remote databases to upload data before applying any more download files. A separate generation number is automatically maintained for each synchronization subscription on the database.

For more information about generation numbers, see MobiLink generation numbers.

See also
  • Publications and subscriptions


Synchronization Subscription property sheet: Connection tab

The Connection tab of the Synchronization Subscription property sheet has the following components:

Protocol Specify the communication protocol to use for synchronization. TCP/IP is used by default.

The settings you can specify on the Connection tab depend on the communication protocol you are using. Any additional parameters, such as buffer_size, can be set in the Advanced field.

For a complete list of parameters supported by each of the protocols, see CREATE SYNCHRONIZATION USER statement [MobiLink] or CommunicationType (ctp) extended option.

  • TCP/IP Select this option to use the TCP/IP protocol for synchronization. TCP/IP supports both elliptic-curve (formerly Certicom) and RSA encryption.

  • HTTP Select this option to use the HTTP protocol for synchronization. HTTP supports both elliptic-curve (formerly Certicom) and RSA encryption.

  • HTTPS Select this option to use the HTTPS protocol for synchronization. You can only use RSA encryption with the HTTPS protocol.

  • HTTPS FIPS Select this option to use the HTTPS_FIPS protocol for synchronization.

  • ActiveSync Select this option to use ActiveSync to exchange data with the MobiLink provider for ActiveSync, which resides on the desktop machine. The ActiveSync parameters describe the communications between the MobiLink provider for ActiveSync and the MobiLink synchronization server.

    For more information, see ActiveSync provider installation utility.

Host The IP number or host name of the machine on which the MobiLink synchronization server is running. The default value is localhost. You can use localhost if the synchronization server is running on the same machine as the client.

For Windows CE, the default value is the value of ipaddr in the registry folder Comm\Tcpip\Hosts\ppp_peer. This allows a Windows CE device to connect to a MobiLink synchronization server executing on the desktop machine where the Windows CE device's cradle is connected.

For the Palm Computing Platform, the default value of localhost refers to the device. It is recommended that you specify an explicit host name or IP address.

  • Port The MobiLink synchronization server communicates over a specific port. The default port number is 2439 for TCP/IP, 80 for HTTP, and 443 for HTTPS. If you choose a different value, you must configure your MobiLink synchronization server to listen on the port you specify.

Proxy host Type the host name or IP address of the proxy server. The default value is localhost. This option is only available for HTTP and HTTPS synchronization.

  • Proxy port Type the port number of the proxy server. The default value is 80 for HTTP and 443 for HTTPS. This option is only available for HTTP and HTTPS synchronization.

URL suffix Type the suffix to add to the URL on the first line of each HTTP request. The default value is MobiLink. This option is only available for HTTP and HTTPS synchronization.

When synchronizing through a proxy server, the suffix may be necessary in order to find the MobiLink synchronization server.

  • HTTP Version Type the value specifying the version of HTTP to use for synchronization. You have a choice of 1.0 or 1.1. The default value is 1.1.

Automatic connection The following options allow MobiLink clients running on Pocket PC 2002 or Windows desktop computers to connect through dial-up network connections.

When used with scheduling, your remote device can synchronize unattended. When used without scheduling, you can run dbmlsync without manually dialing a connection.

For more information about scheduling, see Scheduling synchronization.

  • Network name Specify the network name so that you can use MobiLink's auto-dial feature. This allows you to connect from a Pocket PC 2002 or Windows desktop computer without manually dialing. The name should be the network name that you have specified in the dropdown list in Settings > Connections > Connections (Pocket PC) or Network & Dialup Connections (Windows).

  • Network connect timeout When you specify a network name, you can optionally specify a timeout after which the dial-up fails. This feature applies only to Pocket PC 2002. (On Windows, you can control this feature by configuring the connection profile.) The default is 120 seconds.

  • Leave open When you supply a network name, you can optionally specify whether the connection should be left open (1) or closed (0) after synchronization finishes. By default, the connection is closed.

Enable Certicom security Select this option to encrypt all communication through this connection. You can use the elliptic-curve or RSA cipher. By default, elliptic curves are used.

Separately licensable option required
Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

To order this component, see Separately-licensable components.

For more information about security, see MobiLink Transport-Layer Security.

  • Elliptic curves Uses the elliptic-curve cipher to encrypt connections. You can use this cipher to encrypt TCP/IP and HTTP connections. This was formerly called Certicom encryption.

  • RSA Uses the RSA cipher to encrypt all connections. You can use this cipher to encrypt TCP/IP, HTTP, and HTTPS connections.

  • RSA FIPS Uses the RSA FIPS cipher to encrypt all connection. You can use this cipher to encrypt communications over the TCP/IP and HTTPS FIPS protocols.

    • Certificate company Type the name of the certificate authority or organization that issued the certificate. The server's and the client's values must match.

    • Certificate unit Type the certificate unit. This is also called the organizational unit. The server's and the client's values must match.

    • Certificate name Type the certificate's common name. The server's and the client's values must match.

    • Trusted certificates Type the name of the certificate file the client uses to authenticate the server.

Advanced Type any additional connection parameters in this field, entering them in the form parameter=value, with multiple parameters separated by semicolons. For example, to set the maximum body size for a fixed content length message, and to instruct the client to attempt to use the same TCP/IP connection for all HTTP requests in a synchronization, you would enter the following in the Advanced field:

buffer_size=58000;persistent=TRUE

For a complete list of connection parameters you can enter in this field, see CREATE SYNCHRONIZATION USER statement [MobiLink].

Note

You can set connection parameters for synchronization in several ways.

For information about how dbmlsync resolves conflicting options, see Priority order for extended options and connection parameters.

See also
  • CREATE SYNCHRONIZATION USER statement [MobiLink]
  • ALTER SYNCHRONIZATION USER statement [MobiLink]
  • -x option
  • CommunicationAddress (adr) extended option


Synchronization Subscription property sheet: Extended Options tab

The Extended Options tab of the Synchronization Subscription property sheet has the following components:

This subscription has the following extended options Lists the extended options and the values set for the MobiLink user. Click the Value field beside the option name to set the value for the MobiLink user.

The table below lists all the available extended options for synchronization.

For more information about these options, see dbmlsync extended options.

Extended option | Default | Description
ConflictRetries (cr) extended option | -1 (continue indefinitely) | Specifies the number of retries if the download fails because of conflicts.
ContinueDownload (cd) extended option | OFF | Specifies restartable downloads.
DisablePolling (p) extended option | OFF | Disables automatic logscan polling.
DownloadBufferSize (dbs) extended option | 32 K on Windows CE, 1 M on all other operating systems. | Specifies the size of the download buffer. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
DownloadOnly (ds) extended option | OFF | Specifies that synchronization should be download-only.
DownloadReadSize (drs) extended option | 32 K | For restartable downloads, specifies the maximum amount of data that may need to be resent after a communications failure.
ErrorLogSendLimit (el) extended option | 32 K | Specifies how much of the remote log file dbmlsync should send to the server when synchronization occurs. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively. If you don't want to send any dbmlsync output log messages, a zero value should be set for this extended option.
FireTriggers (ft) extended option | ON | Specifies that triggers should be fired on the remote database when the download is applied.
HoverRescanThreshold (hrt) extended option | 1 M | When you are using scheduling, this limits the amount of discarded memory that is allowed to accumulate before a rescan is performed. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
IgnoreHookErrors (eh) extended option | OFF | Specifies that errors that occur in hook functions should be ignored.
IgnoreScheduling (isc) extended option | OFF | Specifies that scheduling settings should be ignored.
Increment (inc) extended option | (infinite) | Controls the size of incremental uploads. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
LockTables (lt) extended option | ON | Specifies that articles (tables or parts of tables in the publications being synchronized) should be locked before synchronizing.
Memory (mem) extended option | 1 M | Specifies a cache size. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
MirrorLogDirectory (mld) extended option | (none) | Specifies the location of old mirror log files so that they can be deleted.
MobiLinkPwd (mp) extended option | NULL | Specifies the MobiLink password.
NewMobiLinkPwd (mn) extended option | NULL | Specifies a new MobiLink password.
OfflineDirectory (dir) extended option | NULL | Specifies the path containing offline transaction logs.
PollingPeriod (pp) extended option | 1 minute | Specifies the logscan polling period. By default, units of minutes are used. You can use the suffix s, m, h, or d to specify units of seconds, minutes, hours, or days, respectively.
Schedule (sch) extended option | No schedule | Specifies a schedule for synchronization.
ScriptVersion (sv) extended option | DEFAULT | Specifies a script version.
SendColumnNames (scn) extended option | OFF | Specifies that column names should be sent in the upload.
SendDownloadACK (sa) extended option | OFF | Specifies that a download acknowledgement should be sent from the client to the server.
SendTriggers (st) extended option | OFF | Specifies that trigger actions should be sent on upload.
TableOrder (tor) extended option | (none) | Specifies the order of tables in the upload stream.
UploadOnly (uo) extended option | OFF | Specifies that synchronization should only include an upload.
Verbose (v) extended option | OFF | Specifies full verbosity. This option is identical to dbmlsync -v+.
VerboseHooks (vs) extended option | OFF | Specifies that messages related to hook scripts should be logged. This option is identical to dbmlsync -vs.
VerboseMin (vm) extended option | OFF | Specifies that a small amount of information should be logged. This option is identical to dbmlsync -v.
VerboseOptions (vo) extended option | OFF | Specifies that information should be logged about the command line options (including extended options) that you have specified. This option is identical to dbmlsync -vo.
VerboseRowCounts (vn) extended option | OFF | Specifies that the number of rows that are uploaded and downloaded should be logged. This option is identical to dbmlsync -vn.
VerboseRowValues (vr) extended option | OFF | Specifies that the values of rows that are uploaded and downloaded should be logged. This option is identical to dbmlsync -vr.
VerboseUpload (vu) extended option | OFF | Specifies that information about the upload stream should be logged. This option is identical to dbmlsync -vu.
Note

You can set connection parameters for synchronization in several ways.

For information about how dbmlsync resolves conflicting options, see Priority order for extended options and connection parameters.


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

System Trigger property sheet

The System Trigger property sheet consists of one tab: General.

System Trigger property sheet: General tab


System Trigger property sheet: General tab

The General tab of the System Trigger property sheet has the following components:

Name Shows the name of the system trigger.

Type Shows the type of object.

Foreign table Shows the table containing the foreign key.

Primary table Shows the table containing the primary key in the foreign key relationship.

Event Shows which kind of event, Insert, Delete, Update, or Update Columns, causes the system trigger to execute.

Timing Shows whether the trigger executes before or after the event.

Action Shows which of the available referential integrity actions is used for updates and deletes of the primary key:

  • Restrict Generates an error and prevents the modification if an attempt to modify a referenced primary key value occurs. This is the default referential integrity action.

  • Set null Sets all foreign keys that reference the modified primary key to NULL.

  • Set default Sets all foreign keys that reference the modified primary key to the default value for that column (as specified in the table definition).

  • Cascade When used with ON UPDATE, this action updates all foreign keys that reference the updated primary key to the new value. When used with ON DELETE, this action deletes all rows containing foreign keys that reference the deleted primary key.

See also
  • Referential integrity actions


Table property sheet

The Table property sheet consists of four tabs: General, Columns, Permissions, and Miscellaneous.

See also
  • Working with tables

Table property sheet: General tab
Table property sheet: Columns tab
Table property sheet: Permissions tab
Table property sheet: Miscellaneous tab
Table property sheet: Constraints tab


Table property sheet: General tab

The General tab of the Table property sheet has the following components:

Name Shows the name of the table.

Type Shows the type of object.

Owner Shows the database user who created and owns the table.

Dbspace Shows the database file (or dbspace) where the table is located.

Name Shows the name of the primary key for the selected table. Primary keys can be named for tables in Adaptive Server Anywhere databases that are version 9 and higher.

  • Set Primary Key Now Opens the Set Primary Key dialog where you can specify or change the primary key for the selected table.

Columns Shows the primary key columns for the table.

Clustered Shows whether the table has a clustered index. Clustered indexes are supported for Adaptive Server Anywhere databases that are version 8.0.2 and higher.

Clustered indexes in Adaptive Server Anywhere store the table rows in approximately the same order as they appear in the corresponding index. Using a clustered index can lead to performance benefits by reducing the number of times each page needs to be read into memory. Only one index on a table can be a clustered index.

For more information about clustered indexes, see CREATE INDEX statement.

  • Set Clustered Index Now Opens the Set Clustered Index dialog where you can specify that an index on this table is a clustered index.

Index type Shows the type of index the table has.

Maximum hash size This information only appears for databases created with Adaptive Server Anywhere 7 or earlier. The hash size is the number of bytes used to store a value in an index.

For more information about indexes, see Indexes.

Adaptive Server Anywhere version 6 and 7 databases use regular B-tree indexes with a hash size of 10.

Comment Provides a place for you to type a text description of the table. For example, you could use this area to describe the table's purpose in the system.

On commit This control only appears when the table was created as a global temporary table. Shows whether the rows of the table are deleted or preserved when a COMMIT is executed.

See also
  • Working with tables


Table property sheet: Columns tab

The Columns tab of the Table property sheet has the following components:

Columns list Lists all the columns of the table, as well as their type and comments.

Details Displays the Column Details dialog, which shows a summary of the properties for the column.

See also
  • Managing primary keys (Sybase Central)
  • Working with tables


Table property sheet: Permissions tab

The Permissions tab of the Table property sheet has the following components:

Permissions list Lists the users who have permissions on the table. If you want to add users to the list, click Grant. To remove a user from the list, select the user, then click revoke. You can select multiple users by holding Shift while you click.

To grant or revoke permissions, click the fields beside each user. Double-clicking (so that a check mark and two + signs appear) gives the user grant options.

  • Grant Displays the Grant Permission dialog, which lets you grant permissions on the table to other users.

  • Revoke Revokes permissions from the users and removes them from the Permissions list.

Select Shows whether the Select permissions for the user applies to all columns or a subset of columns. Click Change to grant Select permissions for a subset of columns.

Update Shows whether the Update permissions for the user applies to all columns or a subset of columns. Click Change to grant Update permissions for a subset of columns.

References Shows whether the Reference permissions for the user applies to all columns or a subset of columns. Click Change to grant Reference permissions for a subset of columns.

  • Change Click Change to grant Select, Update, or Reference permissions for a subset of columns.

See also
  • Table and views permissions overview
  • Working with tables


Table property sheet: Miscellaneous tab

The Miscellaneous tab of the Table property sheet has the following components:

Maximum table width The number of bytes required for each row in the table. The number is calculated from the length of the string columns, the precision of numeric columns, and the number of bytes of storage for all other data types. If the table includes long binary or long VARCHAR columns, their arbitrary widths are not included, so the row width can only be approximated.

Number of rows Shows the approximate number of rows in the table. To update this value, click Calculate.

  • Calculate Calculates the number of rows in the table.

Free space Specifies the amount of free space you want to reserve for each table page. The free space is used if rows increase in size when the data is updated. If there is no free space in a table page, every increase in the size of a row on that page requires the row to be split across multiple table pages, causing row fragmentation and possible performance degradation.

For more information, see ALTER TABLE statement.

  • Default Choose this option to reserve 200 bytes in each page.

  • Percentage Choose this option to specify an integer between 0 and 100. The former specifies that no free space is to be left on each page—each page is to be fully packed. A high value causes each row to be inserted into a page by itself.

Table is replicating data Select this option to include the table as part of a replication primary site.

For more information about replication primary sites, see Primary site components.

See also
  • Working with tables


Table property sheet: Constraints tab

This tab only appears for databases created with version 8.x and earlier of Adaptive Server Anywhere.

The Constraints tab of the Table property sheet has the following components:

Unique constraints list Lists each unique constraint defined for the table.

To create a new unique constraint for the table, click New. If you want to remove a unique constraint from the table, select the unique constraint from the list, then click Delete. You can select multiple unique constraints by holding Shift while you click.

  • New Displays the Create Unique Constraint dialog, which lets you create new unique constraints for columns of the table.

  • Delete Removes the unique constraint from the list.

Check constraint Lets you define conditions on a column or set of columns to make up the check constraint of the table. The check constraint restricts the values that can be entered in the column(s).

For example, to check that an employee's start date falls in a particular range, type:

CHECK ( start_date BETWEEN '1983/06/27'
                   AND CURRENT DATE )

For more information, see Using CHECK constraints on columns.


Template property sheet, Definition property sheet, and Site property sheet

The Template property sheet, Definition property sheet, and Site property sheet consist of four tabs: General, Articles, Connection, and Extended Options.

Note

The Template, Definition, and Site property sheets are only available for databases created with version 7.x or earlier of Adaptive Server Anywhere.

Template, Definition, and Site property sheet: General tab
Template and Definition property sheet: Articles tab
Template, Definition, and Site property sheet: Connection tab
Template, Definition, and Site property sheet: Extended Options tab


Template, Definition, and Site property sheet: General tab

The General tab of the Template, Definition, and Site property sheets has the following components:

Name Shows the name of the template, definition, or site.

Type Shows the type of object.

Creator Shows the database user who created and owns the template, definition, or site.

Site This field only appears on the Definition property sheet. Shows the name that uniquely identifies this remote database within your MobiLink setup. You can edit the Site name in the adjacent field.

Template This field only appears on the Site property sheet. Shows the name of the template used by the site.


Template and Definition property sheet: Articles tab

The Site property sheet does not have an Articles tab.

The Articles tab of the Template and Definition property sheets has the following components:

Tables tab The Tables tab lets you select tables to include in your client database.

Columns tab The Columns tab lets you select columns from the tables to include in your client database.

WHERE Clauses tab The WHERE Clauses tab lets you type a WHERE clause to restrict the rows included in the article.

Each tab is described in detail below.

See also
  • CREATE PUBLICATION statement
  • Publishing only some rows using a WHERE clause
Tables tab

The Tables tab lets you select tables and add them to the list of articles that are included in the client database.

Available tables list Lists all the base table in the database you are currently connected to.

Selected tables list Lists all the tables that are included in the article for the client database.

  • Add Adds the table in the Matching Tables list to the Tables list so it is included in the article.

  • Remove Removes the table from the Tables list so it is not included in the article.

Columns tab

The Columns tab lets you select columns from tables and add them to the list of articles that are included in the client database.

Available columns list Lists the tables selected on the Tables tab. Click a table in the list to display its columns.

Selected columns list Lists all the columns that are included in the article for the client database.

  • Add Adds the column selected in the Available Columns list to the columns list so it is included in your articles to include in the client database.

  • Delete Removes the column from the Columns list so it is not included in the article.

WHERE Clauses tab

The WHERE Clauses tab lets you supply a WHERE clause to restrict the rows that are included in the client database.

Articles list Select a table from the list of tables included in the article.

The selected article has the following WHERE clause In the text box, type the WHERE clause for the table to restrict the rows that are included in the article.

For more information, see Publishing only some rows using a WHERE clause.

See also
  • The WHERE clause: specifying rows


Template, Definition, and Site property sheet: Connection tab

The Connection tab of the Template, Definition, and Site property sheets has the following components:

Protocol Specify the communication protocol to use for synchronization. TCP/IP is used by default.

  • TCP/IP Select this option to use the TCP/IP protocol for synchronization. TCP/IP supports elliptic-curve (formerly Certicom) encryption.

  • HTTP Select this option to use the HTTP protocol for synchronization. HTTP supports elliptic-curve (formerly Certicom) encryption.

Host The IP number or name of the machine on which the MobiLink synchronization server is running. On a local area network, the may be a machine name. The default value is localhost. You can use localhost if the synchronization server is running on the same machine as the client.

  • Port The MobiLink synchronization server communicates over a specific port. By default, the port number is 2439 for TCP/IP and 80 for HTTP. If you choose a value other than these, you must configure your MobiLink synchronization server to listen on the port you specify.

Proxy host Type the host name or IP address of the proxy server. The default value is localhost. This field is enabled only when the HTTP protocol is selected.

  • Proxy port The port number of the proxy server. The default value is 80. This field is enabled only when the HTTP protocol is selected.

URL suffix The suffix to add to the URL on the first line of each HTTP request. The parameter can be used to help ensure that a particular client connects to the intended server. This field is enabled only when the HTTP protocol is selected.

HTTP version A string specifying the version of HTTP to use. You have a choice of 1.0 or 1.1. This field is enabled only when the HTTP protocol is selected.

Security You can encrypt all communication through the connection using elliptic-curve (formerly Certicom) encryption.

  • Enable Certicom security Select this option to use the elliptic-curve (formerly Certicom) encryption. Selecting this option enables the fields below.

  • Certificate company Type the name of the certificate authority or organization that issued the certificate. The server's and the client's values must match.

  • Certificate unit Type the certificate unit. The is also called the organizational unit. The server's and the client's values must match.

  • Certificate name Type the certificate's common name. The server's and the client's values must match.

  • Trusted certificates Type the name of the certificate file the client uses to authenticate the server.

See also
  • -x option


Template, Definition, and Site property sheet: Extended Options tab

The Extended Options tab of the Template, Definition, and Site property sheets has the following components:

Extended option | Default | Description
ConflictRetries (cr) extended option | -1 (continue indefinitely) | Specifies the number of retries if the download fails because of conflicts.
FireTriggers (ft) extended option | ON | Specifies that triggers should be fired on the remote database when the download is applied.
Increment (inc) extended option | (infinite) | Controls the size of incremental uploads. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
LockTables (lt) extended option | ON | Specifies that articles (tables or parts of tables in the publications being synchronized) should be locked before synchronizing.
Memory (mem) extended option | 1 M | Specifies a cache size. By default, units of bytes are used. You can use the suffix k or m to specify units of kilobytes or megabytes, respectively.
OfflineDirectory (dir) extended option | NULL | Specifies the path containing offline transaction logs.
Schedule (sch) extended option | No schedule | Specifies a schedule for synchronization.
ScriptVersion (sv) extended option | DEFAULT | Specifies a script version.
SendTriggers (st) extended option | OFF | Specifies that trigger actions should be sent on upload.
TableOrder (tor) extended option | (none) | Specifies the order of tables in the upload stream.
Verbose (v) extended option | OFF | Specifies full verbosity.


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Trigger property sheet

The Trigger property sheet consists of one tab: General.

Trigger property sheet: General tab


Trigger property sheet: General tab

The General tab of the Trigger property sheet has the following components:

Name Shows the name of the trigger.

Type Shows the type of object.

Table Shows the table the trigger is associated with.

Dialect Shows the SQL dialect in which the code was last saved, either Watcom-SQL or Transact-SQL.

Events Shows which kind of event, Insert, Delete, Update, or Update Columns, causes the trigger to execute.

Timing Shows whether the trigger executes before or after the event. Row-level triggers can also have SQL Remote conflict timing, which executes before UPDATE or UPDATE OF column-lists events.

Level Shows whether the trigger is a row-level trigger or a statement-level trigger.

Order For triggers in the table that execute for the same kind of event with the same timing, the number determines the order in which these triggers fire.

Comment Provides a place for you to type a text description of the trigger. For example, you could use this area to describe the trigger's purpose in the system.

See also
  • Procedure and trigger overview
  • Using Procedures, Triggers, and Batches


UltraLite Project property sheet

The UltraLite Project property sheet consists of one tab: General.

UltraLite Project property sheet: General tab


UltraLite Project property sheet: General tab

The General tab of the UltraLite Project property sheet has the following components:

Name Shows the name of the UltraLite project.

Type Shows the type of object.

See also
  • Creating an UltraLite project


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

UltraLite Statement property sheet

The UltraLite Statement property sheet consists of two tabs: General and SQL Statement.


UltraLite Statement property sheet: General tab

The General tab of the UltraLite Statement property sheet has the following components:

Name Shows the name of the UltraLite statement.

Type Shows the type of object.

Project Shows the name of the UltraLite project this UltraLite statement belongs to.

Code segment You only need to provide a segment name if you are developing a multi-segment application for the Palm Computing Platform and you want to override the UltraLite default assignment.

When building applications for the Palm Computing Platform, you must supply a code segment name to indicate where the UltraLite statement is stored. You can select a segment name from the dropdown list or supply a new segment name. If you leave the field blank, the UltraLite statement is saved in the default segment, ULSEGDEF.

The Code Segment Name is a string and must be 8 characters or less in length, must start with a letter, and cannot contain spaces. You can use alphanumeric characters and underscores in the Code Segment Name.

For more information about code segments, see UltraLite Databases.

See also
  • Adding statements to a project


UltraLite Statement property sheet: SQL Statement

The SQL Statement tab of the UltraLite Statement property sheet has the following components:

This UltraLite statement contains the following SQL statement Shows the UltraLite statement. You can edit the SQL statement in this window.

See also
  • Defining SQL statements for your application
  • Adding statements to a project


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Unique Constraint property sheet

The Unique Constraint property sheet consists of two tabs: General and Columns.


Unique Constraint property sheet: General tab

The General tab of the Unique Constraint property sheet has the following components:

Name Shows the name of the unique constraint. You can change the name of the unique constraint in the adjacent field.

Type Shows the type of object.

Table Shows the table to which the unique constraint belongs.

Clustered Shows whether the table containing the unique constraint has a clustered index. Clustered indexes are supported for Adaptive Server Anywhere databases that are version 8.0.2 and higher.

Clustered indexes in Adaptive Server Anywhere store the table rows in approximately the same order as they appear in the corresponding index. Using a clustered index can lead to performance benefits by reducing the number of times each page needs to be read into memory. Only one index on a table can be a clustered index.

For more information about clustered indexes, see CREATE INDEX statement.

  • Set Clustered Index Now Opens the Set Clustered Index dialog where you can specify that an index on the table containing the unique constraint is a clustered index.

Index type Shows the type of index the table has.

See also
  • CREATE TABLE statement


Unique Constraint property sheet: Columns tab

The Columns tab of the Unique Constraint property sheet has the following components:

Columns list Shows all the columns in the unique constraint, as well as the data type and comment for each column.

  • Details Displays the Column Details dialog, which shows a summary of the properties of the selected column.

See also
  • CREATE TABLE statement


User property sheet

The User property sheet consists of three tabs: General, Authorities, and Permissions.

See also
  • Managing User IDs and Permissions
  • Granting and revoking remote permissions


User property sheet: General tab

The General tab of the User property sheet has the following components:

Name Shows the name of the user.

Type Shows the type of object.

Allowed to connect Select this option to allow the user to connect to the database. If the user is not allowed to connect, the password (if one was supplied) is removed from the account. If you later change the user to allow them to connect, you must supply a new password. Clearing this option disables the Password and Confirm Password options.

Users are almost always allowed to connect.

  • Password Type the password for the user. For added security, the characters appear as asterisks.

  • Confirm password Confirm the password that you typed in the Password text box by entering it again. The contents of the two fields must match exactly.

Comment Provides a place for you to type a text description of the user. For example, you could use this area to describe the remote user's purpose in the system.

See also
  • Granting and revoking remote permissions
  • Managing User IDs and Permissions


User property sheet: Authorities tab

The Authorities tab of the User property sheet has the following components:

DBA Select this option to grant DBA authority to the user; a user with DBA authority can fully administer the database.

Resource Select this option to grant resource authority to the user; a user with resource authority can create database objects.

Remote DBA Select this option to grant Remote DBA authority to the user. The SQL Remote Message Agent should be run using a user ID with this type of authority to ensure that actions can be carried out without creating security loopholes. The MobiLink client utility, dbmlsync, also requires Remote DBA authority.

See also
  • Managing User IDs and Permissions
  • GRANT statement


User property sheet: Permissions tab

The Permissions tab of the User property sheet has the following components:

Permissions list Shows all tables the user has permissions on, as well as the user who owns each table. You can click the fields for each table to grant or revoke permissions; double-clicking (so that a checkmark and two + signs appear) gives the user grant options for the permission.

Show Select what type of object appears in the Permissions list:

  • Tables All tables the user has permissions on.

  • Views All views the user has permissions on.

  • Procedures & functions All procedures and functions the user has permissions on. You can only grant Execute permissions for procedures and functions.

See also
  • Granting and revoking remote permissions


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

View property sheet

The View property sheet consists of three tabs: General, Columns, and Permissions.


View property sheet: General tab

The General tab of the View property sheet has the following components:

Name Shows the name of the view.

Type Shows the type of object.

Owner Shows the database user who created and owns the object.

Comment Provides a place for you to type a description of the view. For example, you could use this area to describe the view's purpose in the system.

See also
  • Creating views
  • Working with views


View property sheet: Columns tab

The Columns tab of the View property sheet has the following components:

Columns list Lists the columns included in the view.

See also
  • Working with views


View property sheet: Permissions tab

The Permissions tab of the View property sheet has the following components:

Permissions list Lists the users who have permissions on the view. If you want to add users to the list, click Grant. To remove a user from the list, select the user, then click revoke. You can select multiple users by holding Shift while you click.

To grant or revoke permissions for a specific user, click the fields beside each user. Double-clicking (so that a check mark and two + signs appear) gives the user grant options.

  • Grant Displays the Grant Permission dialog, which lets you grant permissions on the table to other users.

  • Revoke Revokes permissions from the users and removes them from the Permissions list.

See also
  • Granting permissions on views
  • Working with views


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to property sheets

Web Service property sheet

The Web Service property sheet consists of two tabs: General and SQL Statement.


Web Service property sheet: General tab

The General tab of the Web Service property sheet has the following components:

Name Shows the name of the selected web service.

Type Shows the type of object.

Service type Shows whether the selected web service is an RAW, XML, HTML, SOAP, or DISH web service. You can change the service type by selecting a different type from the dropdown list.

Format This field applies only to SOAP and DISH services.

Generates output formats compatible with various types of SOAP clients, such as .NET or Java JAX-RPC. If a SOAP service's format is not specified, the format is inherited from the service's DISH service declaration. If the DISH service does not declare a format, it defaults to DNET, which is compatible with .NET clients. A SOAP service that does not declare a format may be used with different types of SOAP clients by defining multiple DISH services, each with a different format type.

Service name prefix This field applies only to DISH services. Only SOAP services whose names begin with this prefix are handled by the DISH service.

Authorization required Indicates whether users must authenticate in order to use this web service.

Place a checkmark in the box to indicate that authorization is required. When authorization is required, all users connecting to this service must provide a user name and password. If a checkmark appears beside the User field, you must authenticate as the specified user in order to use this web service. However, if a checkmark does not appear beside the User field and authentication is required, then you can authenticate with any database user in order to use this web service.

If authorization is not required, you must select a user from the dropdown list below. All requests are run using the account and permissions of the user specified in the User field.

User Shows which user's account is used to execute service requests. If the service does not require authorization, you must select a user from the dropdown list. All requests are run using the account and permissions of this user.

Security required Shows whether unsecure connections are accepted. Place a checkmark in the box to indicate that the web service requires security. If the web service requires security, then only HTTPS connections are accepted. If the checkbox is cleared, then both HTTP and HTTPS connections are accepted.

URL path Specifies whether URI paths are accepted, and if so, how they are processed.

For more information about URIs, see How URLs are interpreted.

  • Off Select this option if the remainder of the URI path is not permitted. If the service name ends with a forward slash (/), select Off. For example, if Off is selected and you have the following URL path:

    http://<host-name>/<service-name>/aaa/bbb/ccc

    only http://<host-name>/<service-name> is permitted. The remainder of the URI path, /<aaa/bbb/ccc is not permitted.

  • On Select this option if the remainder of the URI path is permitted and is set as a single parameter. For example, in the following URL path:

    http://<host-name>/<service-name>/aaa/bbb/ccc

    the remainder of the URI path is /aaa/bbb/ccc. It is treated as a single parameter.

  • Elements Select this option if the remainder of the URL path is permitted and is set as multiple parameters. For example, in the following URL path:

    http://<host-name>/<service-name>/aaa/bbb/ccc

    each element of the path is treated as a separate parameter. For example, url1=aaa, url2=bbb, url3=ccc, and so on.

Comment Provides a place for you to type a description of the web service. For example, you could use this area to describe the web service's purpose in the system.

See also
  • Using Web Services
  • CREATE SERVICE statement


Web Service property sheet: SQL Statement tab

The SQL Statement tab of the Web Service property sheet has the following components:

This web service has the following SQL statement Shows the SQL statement for the web service (if one has been specified). Selecting this option enables the text box below where you can enter the SQL statement for the web service.

The statement is the command, usually a stored procedure, that is called when someone access the service. If you define a statement, this is the only statement that can be run through this service. Services without statements are a serious security risk as they permit web clients to execute arbitrary commands. When creating such services, you must enable authorization, which forces all clients to provide a valid user name and password. Even so, only services that define statements should be run in a production system.

The SQL statement is required for SOAP services. It is optional for RAW, XML, and HTML services, and is not applicable to DISH services.

See also
  • Creating web services
  • CREATE SERVICE statement


Introduction to dialog boxes

You can find most of the configurable settings in the Adaptive Server Anywhere plug-in in dialog boxes, which can be accessed either through the File menu or the Tools menu. If you have different plug-ins installed in Sybase Central, each plug-in may provide different menu items.

The File menu contains commands related to the objects that appear in the main Sybase Central window. These menu items change depending on which object you select. For example, if you select a table, the File menu shows commands and options related to tables. Likewise, if you select a column, the File menu changes to show column options. You can also access all these menu items in popup menus when you right-click an object.

The Tools menu contains commands related to connecting, disconnecting, plug-ins, and Sybase Central options. These menu items always remain visible, regardless of the objects you select in the main window.

You can also configure settings in Adaptive Server Anywhere using property sheets. These property sheets appear in the File menu (or the popup menu) when you select an object that has configurable properties.

For descriptions of these property sheets, see Introduction to property sheets.

Adaptive Server Anywhere 9 Plug-in Preferences dialog
Add Service Dependencies dialog
Add Service Group Dependencies dialog
Change Settings dialog
Change User to Consolidated User dialog
Change User to Remote User dialog
Column Permissions dialog
Consolidated User Options dialog
Create Schedule dialog
Create Trigger Condition dialog
Database Options dialog
Edit Schedule dialog
Edit Trigger Condition dialog
Filter Objects by Owner dialog
Grant Permissions dialog
Group Options dialog
New Members dialog
New Memberships dialog
Options dialog
Pre-allocate Space for Dbspace dialog
Publisher Options dialog
Remote User Options dialog
Set Consolidated User dialog
Set Clustered Index dialog
Set Primary Key dialog
Set Publisher dialog
Set Service Group dialog
Start Database dialog
Trigger Event dialog
Unload Data dialog
Update JAR File dialog
Update Java Class dialog
User Options dialog
Windows CE Message Types for SQL Remote dialog


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to dialog boxes

Adaptive Server Anywhere 9 Plug-in Preferences dialog

The Plug-in Preferences dialog consists of two tabs: General and Utilities.


Plug-in Preferences dialog: General tab

The General tab of the Plug-in Preferences dialog has the following components:

Settings The preferences on the General tab govern how Adaptive Server Anywhere responds when you perform specific tasks in Sybase Central.

  • Warn when connecting with user ID without DBA authority Select this preference if you want Adaptive Server Anywhere to warn you when you are connecting with a user ID that does not have DBA authority.

  • Inform when a breakpoint is hit while debugging Select this preference if you want Adaptive Server Anywhere to notify you when a breakpoint is hit when you are working in debug mode.

  • Inform when a statement is canceled while debugging Select this option if you want Adaptive Server Anywhere to notify you when a statement is canceled when you are working in debug mode.

  • Confirm granting of permissions via clipboard and drag-and-drop operations Sybase Central allows you to use drag-and-drop operations and copy and paste operations to grant permissions on tables, views, procedures, and functions to users or groups.

    Select this preference if you want Sybase Central to prompt you before permissions are granted to a user or group by dragging or copying and pasting them to a table, view, procedure, or function.

  • Confirm creation of SQL Remote subscriptions via clipboard and drag-and-drop operations Sybase Central allows you to use drag-and-drop operations and copy and paste operations to create SQL Remote subscriptions for remote users and consolidated users.

    Select this preference if you want Sybase Central to prompt you before you subscribe a remote user or consolidated user to a publication by dragging or copying and pasting the user to a publication.

  • Confirm creation of MobiLink synchronization subscriptions via clipboard and drag-and-drop operations Sybase Central allows you to use drag-and-drop operations and copy and paste operations to create synchronization subscriptions for MobiLink users.

    Select this preference if you want Sybase Central to prompt you before you subscribe a MobiLink user to a publication by dragging or copying and pasting the MobiLink user to a publication.

  • Confirm deletions when editing table data Select this preference if you want Adaptive Server Anywhere to prompt you before table data is deleted on the Data tab in Sybase Central.

  • Confirm updates when editing table data Select this preference if you want Adaptive Server Anywhere to prompt you before table data is updated on the Data tab in Sybase Central.

  • Confirm implicit updates when editing table data Select this preference if you want Adaptive Server Anywhere to prompt you before implicit updates are made in Sybase Central. Implicit updates are made when you are editing a row on the Data tab and then click anywhere else in Sybase Central outside the row you are currently editing.

  • Confirm cancellations when editing table data Select this preference if you want Sybase Central to prompt you when you cancel changes to table data on the Data tab in Sybase Central.

Restore Defaults Click Restore Defaults to return the preferences on this tab to their default values (selected or cleared). By default, all the preferences on this tab are selected.


Plug-in Preferences dialog: Utilities tab

The Utilities tab of the Plug-in Preferences dialog has the following components:

Settings The preferences on the Utilities tab govern whether wizard introduction pages appear and whether wizard message windows close when the wizard is finished.

  • Show Create Database wizard introduction page Select this preference if you want the Create Database wizard introduction page to appear when you open the wizard.

  • Show Upgrade Database wizard introduction page Select this preference if you want the Upgrade Database wizard introduction page to appear when you open the wizard.

  • Show Backup Database wizard introduction page Select this preference if you want the Backup Database wizard introduction page to appear when you open the wizard.

  • Show Restore Database wizard introduction page Select this preference if you want the Restore Database wizard introduction page to appear when you open the wizard.

  • Show Create Backup Images wizard introduction page Select this preference if you want the Create Image Backup wizard introduction page to appear when you open the wizard.

  • Show Unload Database wizard introduction page Select this preference if you want the Unload Database wizard introduction page to appear when you open the wizard.

  • Show Extract Database wizard introduction page Select this preference if you want the Extract Database wizard introduction page to appear when you open the wizard.

  • Show Validate Database wizard introduction page Select this preference if you want the Validate Database wizard introduction page to appear when you open the wizard.

  • Show Compress Database wizard introduction page Select this preference if you want the Compress Database wizard introduction page to appear when you open the wizard.

  • Show Uncompress Database wizard introduction page Select this preference if you want the Uncompress Database wizard introduction page to appear when you open the wizard.

  • Show Create Write File wizard introduction page Select this preference if you want the Create Write File wizard introduction page to appear when you open the wizard.

  • Show Create Custom Collation wizard introduction page Select this preference if you want the Create Custom Collation wizard introduction page to appear when you open the wizard.

  • Show Translate Log File wizard introduction page Select this preference if you want the Translate Log File wizard introduction page to appear when you open the wizard.

  • Show Change Log File Settings wizard introduction page Select this preference if you want the Change Log File Settings wizard introduction page to appear when you open the wizard.

  • Show Erase Database wizard introduction page Select this preference if you want the Erase Database wizard introduction page to appear when you open the wizard.

  • Show Migrate Database wizard introduction page Select this preference if you want the Migrate Database wizard introduction page to appear when you open the wizard.

  • Show Index Consultant introduction page Select this preference if you want the Index Consultant introduction page to appear when you open the Index Consultant.

  • Close wizard messages window when completed Select this preference if you want the wizard messages window to close after it is finished. By default, this preference is not selected.

Restore Defaults Click Restore Defaults to return the preferences on this tab to their default values (selected or cleared). By default, all preferences on this tab except Close Wizard Messages Window When Completed are selected.


Plug-in Preferences dialog: Table Data tab

The Table tab of the Plug-in Preferences dialog has the following components:

Which font do you want to use to show table data? Select one of the following options to specify the font that is used for table data on the Data tab when viewing table data in Sybase Central.

  • System Select this option to use the machine's normal text font. This is the default setting.

  • Editor Select this option to use the same font as the Code Editor.

    For more information about the Code Editor, see Format tab.

  • Custom Select this option to specify the font, font style, and point size you want to use. Click Browse to select the desired settings in the Font dialog.


Add Service Dependencies dialog

The Add Service Dependencies dialog has the following components:

Choose one or more services from the list of candidates Lists all the services on your system. Select a service from this list and click OK to add it to the list of services and service groups on the Dependencies tab of the Service property sheet.

You can select multiple services by holding Shift while you click. Double-clicking a service adds the selected service to the list on the Dependencies tab and closes the dialog.

See also
  • Service dependencies
  • Running more than one service


Add Service Group Dependencies dialog

The Add Service Group Dependencies dialog has the following components:

Choose one or more service groups from the list of candidates Lists all the service groups on your system. Select a service group from this list and click OK to add it to the list of services and service groups on the Dependencies tab of the Service property sheet.

You can select multiple service groups by holding Shift while you click. Double-clicking adds the selected service group to the list on the Dependencies tab and closes the dialog.

See also
  • Service groups overview
  • Running more than one service


Change Settings dialog

This dialog allows you to change a foreign key's settings for check on commit, whether NULL values are allowed, and update and delete behavior.

The Change Settings dialog has the following components:

Check only on a commit Forces the database to wait for a COMMIT before checking the integrity of the foreign key, overriding the setting of the WAIT_FOR_COMMIT database option.

Allow null values Determines whether the foreign key columns allow NULL values. To use this option, the foreign key columns must all have Allow Nulls set to Yes.

Update action Uses one of the following settings to define the behavior of the table when a user tries to update data.

  • Not permitted Prevents updates of the associated primary table's primary key value if there are no corresponding foreign keys.

  • Cascade values Updates the foreign key to match a new value for the associated primary key.

  • Set values to null Sets all the foreign key values that correspond to the updated primary key of the associated primary table to NULL.

  • Set values to default Sets foreign key values that match the updated or deleted primary key value to values specified in the DEFAULT clause of each foreign key column. To use this option, the foreign key columns must all have default values.

Delete action Uses one of the following settings to define the behavior of the table when a user tries to delete data.

  • Not permitted Prevents deletion of the associated primary table's primary key value if there are no corresponding foreign keys in the table.

  • Cascade values Deletes the rows from the table that match the deleted primary key of the associated primary table.

  • Set values to null Sets all the foreign key values in the table that correspond to the deleted primary key of the associated primary table to NULL. To use this option, the foreign key columns must all have Allows Null set to Yes.

  • Set values to default Sets foreign key values that match the updated or deleted primary key value to values specified in the DEFAULT clause of each foreign key column. To use this option, the foreign key columns must all have default values.

See also
  • Foreign Key property sheet
  • Managing foreign keys
  • Ensuring Data Integrity


Change User to Consolidated User dialog

The Change User to Consolidated User dialog has the following components:

User Shows the name of the selected user.

Message type Select a message type for communicating with the publisher.

Address Type the destination for replication messages. Publishers and consolidated users each have their own address. The address must be valid for the Message Type you select. For example, if you select the FTP message type, a valid address is a host (such as ftp.mycompany.com) or an IP address (such as 192.138.151.66).

Send frequency Select one of the following values to specify how often the Message Agent should run.

  • Send then close Select this option to set the replication frequency so that the Message Agent runs once, sends all pending messages to this consolidated user, and then shuts down. The Message Agent must be restarted each time the publisher wants to send messages. This option is only useful when you are running the message agent at a remote site.

  • Send every Select this option to set the replication frequency so that the Message Agent runs continuously, sending messages to this consolidated user at the given periodic interval. This option is useful at both consolidated and remote sites.

  • Send daily at Select this option to set the replication frequency so that the Message Agent runs continuously, sending messages to this consolidated user each day at the given time. This option is particularly useful at remote sites.

See also
  • GRANT CONSOLIDATE statement [SQL Remote]
  • Working with message types
  • Granting and revoking remote permissions
  • Managing SQL Remote permissions


Change User to Remote User dialog

The Change User to Remote User dialog has the following components:

User Shows the name of the selected user.

Message type Select a message type for communicating with the publisher.

Address Type the destination for replication messages. Publishers and remote users each have their own address. The address must be valid for the Message Type you select. For example, if you select the FTP message type, a valid address is a host (such as ftp.mycompany.com) or an IP address (such as 192.138.151.66).

Send frequency Select one of the following values to specify how often the Message Agent should run.

  • Send then close Select this option to set the replication frequency so that the publisher's agent runs once, sends all pending messages to this remote user, and then shuts down. The agent must be restarted each time the publisher wants to send messages. This option is only useful when you are running the message agent at a remote site.

  • Send every Select this option to set the replication frequency so that the publisher's agent runs continuously, sending messages to this remote user at the given periodic interval. This option is useful at both consolidated and remote sites.

  • Send daily at Select this option to set the replication frequency so that the publisher's agent runs continuously, sending messages to this remote user each day at the given time. This option is particularly useful at remote sites.

See also
  • GRANT REMOTE statement [SQL Remote]
  • Working with message types
  • Granting and revoking remote permissions
  • Managing SQL Remote permissions


Column Permissions dialog

The Column Permissions dialog has the following components:

This user has the following column permissions Lists columns and type of permissions the selected user has on each column in the table. You can click in the fields beside each column to grant or revoke permissions; double-clicking (so that a checkmark and two + signs appear) gives the user grant options for the permission.

Details Displays the Column Details dialog for the selected column. The Column Details dialog shows the name, type, primary key, unique constraints, whether NULLs are allowed, and comment for the selected column.

See also
  • Granting permissions on tables


Consolidated User Options dialog

The Consolidated User Options dialog has the following components:

Consolidated user Displays the name of the selected consolidated user.

Show Provides a list of option types. For example, if you choose Database Options, only database-related options appear in the Options list.

Options list Shows the option settings and default values based on the type of options selected in the Show list. Once you select an option, you can use the buttons at the side of the dialog.

  • New This button is not enabled when you are setting consolidated user options. You must open the Database Options dialog to add new options.

  • Remove Now This button is not enabled when you are setting consolidated user options. You must open the Database Options dialog to remove options.

  • Set Temporary Now To temporarily change an option setting for the consolidated user, select an option from the Options list, type the desired setting in the Value field, then click Set Temporary Now.

    Temporary values only last for the current Sybase Central session.

  • Set Permanent Now To permanently change a setting for the consolidated user, select an option from the Options list, type the desired setting in the Value field, then click Set Temporary Now.

    Permanent values last between sessions until they are explicitly changed again.

Value Select an option in the Options list and type the desired setting in the Value field. You can make the setting temporary or permanent by clicking Set Temporary Now and Set Permanent Now respectively. An option value cannot be set for an individual user ID unless there is already a PUBLIC group setting for that option.

Note

When you change options settings, some of the settings take effect immediately, while for others to take effect you must restart the database.

For information about specific options, see Alphabetical list of options.

See also
  • SET OPTION statement
  • Working with databases
  • Managing User IDs and Permissions


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to dialog boxes

Create Schedule dialog

The Create Schedule dialog consists of two tabs: General and Recurrence.


Create Schedule dialog: General tab

The General tab of the Create Schedule dialog has the following components:

Schedule The name of the event schedule. You can change the name of the schedule in the adjacent text box.

Start time Select one of the following options to specify a when the event occurs.

  • At Select this option to specify a scheduled time for each day the event is scheduled. If a Start Date is specified, the Start Time refers to that date. If you do not specify a Start Date, the Start Time is on the current day (unless the time has passed) and each subsequent day.

  • Between A range of times during the day outside of which no scheduled times occur. If you specify a Start Date, the scheduled times do not occur until that date.

Start date The date on which the scheduled event starts occurring. The current date is the default. You can type the date in the text box or select the month, day, and year from the lists.

See also
  • CREATE EVENT statement
  • Automating Tasks Using Schedules and Events


Create Schedule dialog: Recurrence tab

All of the settings on this tab are optional.

The Recurrence tab of the Create Schedule dialog has the following components:

Repeat every Select the interval between successive scheduled events.

Trigger on the following Select the day of the week and/or month on which the selected event occurs. You must select this checkbox to enable the Days of the Week and Days of the Month options below.

  • days of the week Select the day(s) of the week on which the selected event occurs by clicking the checkbox beside the desired day.

  • days of the month Select the day(s) of the month on which the selected event occurs by clicking the checkbox beside the desired day.

See also
  • CREATE EVENT statement
  • Automating Tasks Using Schedules and Events


Create Trigger Condition dialog

The Create Trigger Condition dialog has the following components:

Condition Select a preset trigger condition from the list. When this condition and the value (specified below) are satisfied, the selected event is triggered.

Operator Select an operator from the list. The comparison operator compares the condition and value in the trigger condition.

Value Enter a value for the condition. When this value and the condition (specified above) are satisfied, the selected event is triggered.

See also
  • Defining trigger conditions for events


Database Options dialog

Any options you set in this dialog are set for the PUBLIC group. Changing the value of an option for the PUBLIC group sets the value of the option for all users who have not set their own value. An option value cannot be set for an individual user ID unless there is already a PUBLIC group setting for that option.

The Database Options dialog has the following components:

Database Displays the name of the selected database.

Show Provides a list of option types. For example, if you choose Database Options, only database-related options appear in the Options list.

Options list Shows the option settings and default values based on the type of options selected in the Show list. Once you select an option, you can use the buttons at the side of the dialog.

  • New Displays the Create Public Option dialog. In this dialog, you can define new options and set their values.

  • Remove Now Removes the selected option from the list.

  • Set Temporary Now To temporarily change an option setting for the database, select an option from the Options list, type the desired setting in the Value field, then click Set Temporary Now.

    Temporary values only last for the current Sybase Central session.

  • Set Permanent Now To permanently change an option setting for the database, select an option from the Options list, type the desired setting in the Value field, then click Set Permanent Now.

    Permanent values last between sessions until they are explicitly changed again.

Value Select an option in the Options list and type the desired setting in the Value field. You can make the setting temporary or permanent by clicking Set Temporary Now and Set Permanent Now respectively.

Note

When you change options, some of the settings take effect immediately, while for others to take effect, you must restart the database.

For information about specific options, see Alphabetical list of options.

See also
  • SET OPTION statement
  • Working with databases
  • Managing User IDs and Permissions


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to dialog boxes

Edit Schedule dialog

The Edit Schedule dialog consists of two tabs: General and Recurrence.


Edit Schedule dialog: General tab

The General tab of the Edit Schedule dialog has the following components:

Schedule The name of the schedule. When you are editing the schedule, you cannot change the schedule's name.

Start time Select one of the following options to specify a when the event occurs.

  • At Select this option to specify a scheduled time for each day the event is scheduled. If a Start Date is specified, the Start Time refers to that date. If you do not specify a Start Date, the Start Time is on the current day (unless the time has passed) and each subsequent day.

  • Between A range of times during the day outside of which no scheduled times occur. If you specify a Start Date, the scheduled times do not occur until that date.

Start date The date on which the scheduled event starts occurring. The current date is the default. You can enter a date in the text box or select the month, day, and year from the lists.

See also
  • CREATE EVENT statement
  • Automating Tasks Using Schedules and Events


Edit Schedule dialog: Recurrence tab

All of the settings on this tab are optional.

The Recurrence tab of the Edit Schedule dialog has the following components:

Repeat every Select the interval between successive scheduled events.

Trigger on the following Select the day of the week and/or month on which the selected event occurs. You must select this checkbox to enable the Days of the Week and Days of the Month options below.

  • days of the week Select the day(s) of the week on which the selected event occurs by clicking the checkbox beside the desired day.

  • days of the month Select the day(s) of the month on which the selected event occurs by clicking the checkbox beside the desired day.

See also
  • CREATE EVENT statement
  • Automating Tasks Using Schedules and Events


Edit Trigger Condition dialog

The Edit Trigger Condition dialog has the following components:

Condition Select a preset trigger condition from the list. When this condition and the value (specified below) are satisfied, the selected event is triggered.

Operator Select an operator from the list. The comparison operator compares the condition and value in the trigger condition.

Value Enter a value for the condition. When this value and the condition (specified above) are satisfied, the selected event is triggered.

See also
  • Defining trigger conditions for events


Filter Objects by Owner dialog

The Filter Objects by Owner dialog has the following components:

Database Displays the name of the selected database.

Select the users and groups whose objects you want to view Lists the names and comments for all the users and groups connected to the database. Select the checkbox beside a user or group if you want their objects to appear.

The user SYS owns system tables. Other built-in tables, such as the MobiLink system tables, are owned by the user dbo.

Select All Click Select All to view objects belonging to all users in the Users list.

Clear All Click Clear All to clear all the checkboxes in the Users list.

Restore Defaults Click Restore Defaults to return the list of users on this tab to their default values (selected or cleared).

See also
  • Working with databases
  • Displaying system objects in a database


Grant Permissions dialog

The Grant Permissions dialog has the following components:

Choose one or more users or groups from the list of candidates Lists the users or groups you can grant permissions to. Select a user and click OK to grant permissions on the selected table, procedure, function, or view to the user or group. Double-clicking a user or group grants them permission on the selected database object and closes the dialog.

You can grant permissions to multiple users by holding the Shift key while you click the users' or groups' names.

See also
  • Granting permissions on tables
  • GRANT statement


Group Options dialog

The Group Options dialog has the following components:

Group Displays the name of the selected group.

Show Provides a list of option types. For example, if you choose Database Options, only database-related options appear in the Options list.

Options list Shows the option settings and their default values based on the type of options selected in the Show list. Once you select an option, you can use the buttons at the side of the dialog.

  • New This button is not enabled when you are setting group options. You must open the Database Options dialog to add new options to the Options list.

  • Remove Now This button is not enabled when you are setting group options. You must open the Database Options dialog to remove options from the Options list.

  • Set Temporary Now To temporarily change an option setting for a group, select an option from the Options list, type the desired setting in the Value field, then click Set Temporary Now.

    Temporary values only last for the current Sybase Central session.

  • Set Permanent Now To permanently change an option setting for a group, select an option from the Options list, type the desired setting in the Value field, then click Set Permanent Now.

    Permanent values last between sessions until they are explicitly changed again.

Value Select an option in the Options list and type the desired setting in the Value field. You can make the setting temporary or permanent by clicking Set Temporary Now and Set Permanent Now respectively. An option value cannot be set for a group unless there is already a PUBLIC group setting for that option.

Note

When you change options, some of the settings take effect immediately, while for others you must restart the database before they take effect.

For information about specific options, see Alphabetical list of options.

See also
  • SET OPTION statement
  • Working with databases
  • Managing User IDs and Permissions


New Members dialog

The New Members dialog has the following components:

Choose one or more users and groups from the list of candidates Lists the names and comments for all the users and groups in the database that can be added to the selected group.


New Memberships dialog

The New Memberships dialog has the following components:

Choose one or more groups from the list of candidates Lists the names and comments for all the groups in the database to which the selected group can be added.


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

Adaptive Server Anywhere Help

Introduction to dialog boxes

Options dialog

The Options dialog has two tabs: Check for updates and Logging.


Options dialog: Check for updates tab

This tab allows you to configure whether SQL Anywhere Studio should check for software updates and how often it should do so. Checking for updates is done on application startup.

You can also check for updates any time from the Start menu by choosing Programs > SQL Anywhere 9 > Check For Updates and from the Sybase Central, Interactive SQL, and Console utility Help menus.

The Check For Updates tab of the Options dialog in Sybase Central has the following components:

When to check for updates Choose one of the following options to specify how often SQL Anywhere Studio should check for updates. By default, Never is selected.

  • On application startup Select this option if you want SQL Anywhere Studio to check for updates each time Sybase Central is started.

  • Daily Select this option if you want SQL Anywhere Studio to check for updates the first time Sybase Central is started each day.

  • Weekly Select this option if you want SQL Anywhere Studio to check for updates the first time Sybase Central is started each week.

  • Monthly Select this option if you want SQL Anywhere Studio to check for updates the first time Sybase Central is started each month.

  • Never Select this option if you do not want SQL Anywhere Studio to check for updates. This is the default setting.

What to check for Choose any combination of the following options to specify what types of updates SQL Anywhere Studio should check for. By default, all of the following options are selected.

  • Express Bug Fix Select this option if you want SQL Anywhere Studio to check for Express Bug Fixes.

    An express bug fix is a subset of the software with one or more bug fixes. The bug fixes are listed in the release notes for the update. Bug fix updates may only be applied to installed software with the same version number. Some testing has been performed on the software, but the software has not undergone full testing. You should not distribute these files with your application unless you have verified the suitability of the software yourself.

  • Maintenance Release Select this option if you want SQL Anywhere Studio to check for maintenance releases of the software.

    A maintenance release is a complete set of software that upgrades installed software from an older version with the same major version number (version number format is major.minor.patch.build). Bug fixes and other changes are listed in the release notes for the upgrade.

  • Other Information Select this option to check for other information, such as new product releases or upcoming events.


Options dialog: Logging tab

The Logging tab of the Options dialog has the following components:

Enable logging Select this option to enable logging for a database.

  • Add date and time to output Select this option to include the date and time of each SQL statement occurrence in the log window or file.

Wrap text Specify the length of each line in the Design Details pane or log file. Each line wraps automatically to the next line after the number of characters that you specify. By default, there are 80 characters per line.

Save Click Save to save the logging information to a file.

Clear Clears the contents of the selected tab in the Design Details pane.


Pre-allocate Space for Dbspace dialog

The Pre-allocate Space for Dbspace dialog has the following components:

How much space would you like to pre-allocate for the dbspace? Enter the amount of space you want to pre-allocate to the dbspace. Pre-allocating disk space for the dbspace extends the size of the corresponding database file by the amount of space you specify.

You cannot change the page size of a database because the page size is fixed when the database is created.

See also
  • ALTER DBSPACE statement
  • Pre-allocating space for database files


Publisher Options dialog

The Publisher Options dialog has the following components:

Publisher Displays the name of the publisher.

Show Provides a list of option types. For example, if you choose Database Options, only database-related options appear in the Options list.

Options list Shows the option settings and default values based on the type of options selected in the Show list. Once you select an option, you can use the buttons at the side of the dialog.

  • New This button is not enabled when you are setting publisher options. You must open the Database Options dialog to add new options.

  • Remove Now This button is not enabled when you are setting publisher options. You must open the Database Options dialog to remove options.

  • Set Temporary Now To temporarily change an option setting for the publisher, select an option from the Options list, type the desired setting in the Value field, then click Set Temporary Now.

    Temporary values only last for the current Sybase Central session.

  • Set Permanent Now To permanently change a setting for the publisher, select an option from the Options list, type the desired setting in the Value field, then click Set Temporary Now.

    Permanent values last between sessions until they are explicitly changed again.

Value Select an option in the Options list and type the desired setting in the Value field. You can make the setting temporary or permanent by clicking Set Temporary Now and Set Permanent Now respectively. An option value cannot be set for an individual user ID unless there is already a PUBLIC group setting for that option.

Note

When you change options settings, some of the settings take effect immediately, while for others to take effect you must restart the database.

For information about specific options, see Alphabetical list of options.

See also
  • SET OPTION statement
  • Working with databases
  • Managing User IDs and Permissions


Remote User Options dialog

The Remote User Options dialog has the following components:

Remote User Displays the name of the selected remote user.

Show Provides a list of option types. For example, if you choose Database Options, only database-related options appear in the Options list.

Options list Shows the option settings and default values based on the type of options selected in the Show list. Once you select an option, you can use the buttons at the side of the dialog.

  • New This button is not enabled when you are setting remote user options. You must open the Database Options dialog to add new options.

  • Remove Now This button is not enabled when you are setting remote user options. You must open the Database Options dialog to remove options.

  • Set Temporary Now To temporarily change an option setting for the consolidated user, select an option from the Options list, type the desired setting in the Value field, then click Set Temporary Now.

    Temporary values only last for the current Sybase Central session.

  • Set Permanent Now To permanently change a setting for the consolidated user, select an option from the Options list, type the desired setting in the Value field, then click Set Temporary Now.

    Permanent values last between sessions until they are explicitly changed again.

Value Select an option in the Options list and type the desired setting in the Value field. You can make the setting temporary or permanent by clicking Set Temporary Now and Set Permanent Now respectively. An option value cannot be set for an individual user ID unless there is already a PUBLIC group setting for that option.

Note

When you change options settings, some of the settings take effect immediately, while for others to take effect you must restart the database.

For information about specific options, see Alphabetical list of options.

See also
  • SET OPTION statement
  • Working with databases
  • Managing User IDs and Permissions


Set Consolidated User dialog

The Set Consolidated User dialog has the following components:

Choose the new consolidated user from the list of candidates Lists the users from which you can select the consolidated user for the database. Select a user and click OK to grant CONSOLIDATED permissions to the selected user. Double-clicking a user grants that user CONSOLIDATE permissions and closes the dialog.

You can only select one consolidated user for the database. The name of the consolidated user appears on the SQL Remote tab of the Database property sheet.

See also
  • GRANT CONSOLIDATE statement [SQL Remote]
  • Managing SQL Remote permissions


Set Clustered Index dialog

Clustered indexes are supported for Adaptive Server Anywhere databases that are version 8.0.2 and higher.

The Set Clustered Index dialog has the following components:

Table Shows the name of the table for which you are specifying a clustered index.

Specify an index on this table to be clustered Select this option to enable the list of indexes below where you specify which index is to be clustered.

Indexes list Shows all the indexes for the table. Select an index from the list and then click OK to specify a clustered index. Note that only one index on a table can be a clustered index.

See also
  • CREATE INDEX statement
  • Using clustered indexes


Set Primary Key dialog

The Set Primary Key dialog has the following components:

Table Shows the name of the selected table.

Specify a primary key for this table Select this option to enable the options below where you can name and choose a primary key for the selected table.

Name Shows the name of the primary key. You can edit the name in the adjacent field. Primary keys can be named for tables in Adaptive Server Anywhere databases that are version 9 and higher.

Columns list Shows all the columns in the table. Place a checkmark in the checkbox beside the column name to make the column a primary key column. Clear the checkbox to remove a column from the primary key.

Create a clustered primary key Select this option if you want the primary key to have a clustered index. Note that only one index on a table can be a clustered index.

See also
  • Managing primary keys
  • Using clustered indexes


Set Publisher dialog

The Set Publisher dialog has the following components:

Choose the new publisher from the list of candidates Lists the users you can select the publisher from. Select a user and click OK to grant PUBLISH permissions to the selected user. Double-clicking a user grants that user PUBLISH permissions and closes the dialog.

You can only select one publisher for the database.

See also
  • GRANT PUBLISH statement [SQL Remote]
  • Managing SQL Remote permissions


Set Service Group dialog

The Set Service Group dialog has the following components:

New service group Select this option to create a new service group to assign the selected service to.

  • Service group name Type the name of the new service group when you select New Service Group above.

Existing service group Select this option if you want to assign the selected service to be a member of an existing service group.

  • Service groups list Lists all the existing service groups. The list is enabled when you select the Existing Service Group option. To assign the selected service to a service group, select an existing service group from the list and click OK. Double-clicking a service group assigns the service to that service group and closes the dialog.

See also
  • Running more than one service


Start Database dialog

The Start Database dialog has the following components:

Server Shows the name of the selected server on which the database is started.

Database file Type the full path and name of the Adaptive Server Anywhere database file or write file on the server machine. For example, to start the sample database, type C:\Program Files\Sybase\SQL Anywhere 9\asademo.db.

You can also click Browse to locate the file.

Encryption key Enter the encryption key to start the database. You must supply the encryption key to start a database that is strongly encrypted. This field is only enabled for strongly encrypted databases.

For more information, see Encrypting a database and Creating a database using the dbinit command-line utility.

Database name Type a name for the database you are connecting to. You can use a database name to provide a more meaningful name than the file name for users of client applications. Since more than one database can run on a database server at one time, supplying a database name lets you distinguish between databases running on the same server. The name you supply identifies the database until it is stopped.

The database name is optional. If you don't supply a database name, the default database name is the root of the Database file name (the file name without the .db extension). For example, if you have a database called sample.db, the default database name is sample.

Stop database after last disconnect Select this option to shut down the database when the last connection to it closes.

This option is different from the –ga server option, which automatically stops the database server itself.

See also
  • Running the Database Server
  • Working with databases


Trigger Event dialog

The Trigger Event dialog has the following components:

Event Displays the name and owner of the event.

Parameters Type any event parameters in this field in the form name=value,name=value...

If the event does not require any parameters, click OK to trigger the event.

This dialog allows you to explicitly supply parameters in order to simulate a context for the event handler. You can use this dialog to test trigger conditions such as disk space restrictions (when a disk fills beyond a specified percentage) or other trigger conditions that are required to trigger an event handler.

For example, you can have an event that takes different actions depending which user ID is connected to the database: calling the event parameter ( 'User' ) in the event handler does this. To simulate triggering this event for the user P_Chin, type the following in the Parameters text box:

"User"='P_Chin'

The word User must be contained in double quotes because it is a reserved word in SQL.

See also
  • TRIGGER EVENT statement
  • EVENT_CONDITION function [System]
  • CREATE EVENT statement
  • Automating Tasks Using Schedules and Events


Unload Data dialog

The Unload Data dialog has the following components:

Save the data files on the server computer using UNLOAD statements Select this option to export data to files on the server machine. Selecting this option places an exclusive lock on the whole table while you are unloading it. UNLOAD statements provide better performance than OUTPUT statements. In the file, the data is exported with one row per line, values are separated by a comma delimiter, and strings are enclosed in single quotes. The Browse button is disabled if you select this option and the database is running on a different computer.

Save the data files on the local computer using OUTPUT statements Select this option to export data files on the local computer. In the file, the data is exported with one row per line, values are separated by a comma delimiter, and strings are enclosed in single quotes

Save the data in the following directory Type the directory where you want the data saved. If you choose to save the data files on the server computer, relative file names specify files relative to the database server's starting directory. You can click Browse to locate the directory where you want to save the files.

Order data by primary key Select this option to order the exported data in order by primary key values to make reloading quicker.

Save the reload file to the following file on the local computer Type a name and location for the reload.sql file that is used to reload the data.

Use LOAD statements to reload the data from the server computer Select this option to use LOAD statements to reload the data. LOAD statements provide better performance than INPUT statements.

For more information, see Using the LOAD TABLE statement to import data.

Use INPUT statements to reload the data from the local computer Select this option to use INPUT statements to reload the data.

See also
  • UNLOAD TABLE statement
  • OUTPUT statement [Interactive SQL]
  • LOAD TABLE statement
  • INPUT statement [Interactive SQL]


Update JAR File dialog

The Update JAR file dialog has the following components:

Where is the updated JAR file located? In the text box, type the path of the JAR file that you want to update. If you don't know the path, you can click the Browse button to search for the file. For example, C:\ProgramFiles\Sybase\Shared\java\Silver.jar.

Install all classes Select this option if you want to install all the classes in this JAR file.

Install selected classes Select this option to identify specific classes to install from the selected JAR file. Separate each class with a comma. You can click the Select button to view a list of classes in the selected JAR file.

  • Select All Installs all the classes in the JAR file list.

  • Clear All Clears all the classes in the JAR file list so they are not installed.

See also
  • Using Java in the Database


Update Java Class dialog

The Update Java Class dialog has the following components:

Where is the updated Java Class file located? Type the complete path of the Java class that you want to update. For example, C:\my classes\Utility.class.

Alternatively, you can click the Browse button to search for the Java class.

See also
  • Using Java in the Database
  • Updating classes and Jars


User Options dialog

The User Options dialog has the following components:

User Displays the name of the selected user.

Show Provides a list of option types. For example, if you choose Database Options, only database-related options appear in the Options list.

Options list Shows the option settings and default values based on the type of options selected in the Show list. Once you select an option, you can use the buttons at the side of the dialog.

  • New This button is not enabled when you are setting user options. You must open the Database Options dialog to add new options.

  • Remove Now This button is not enabled when you are setting user options. You must open the Database Options dialog to remove options.

  • Set Temporary Now To temporarily change an option setting for a user, select an option from the Options list, type the desired setting in the Value field, then click Set Temporary Now.

    Temporary values only last for the current Sybase Central session.

  • Set Permanent Now To permanently change a setting for a user, select an option from the Options list, type the desired setting in the Value field, then click Set Temporary Now.

    Permanent values last between sessions until they are explicitly changed again.

Value Select an option in the Options list and type the desired setting in the Value field. You can make the setting temporary or permanent by clicking Set Temporary Now and Set Permanent Now respectively. An option value cannot be set for an individual user ID unless there is already a PUBLIC group setting for that option.

Note

When you change options settings, some of the settings take effect immediately, while for others to take effect you must restart the database.

For information about specific options, see Alphabetical list of options.

See also
  • SET OPTION statement
  • Working with databases
  • Managing User IDs and Permissions


Windows CE Message Types for SQL Remote dialog

The Windows CE Message Types for SQL Remote dialog has the following components:

Your Windows CE device has the following message types This window lists the available message types for your Windows CE device. To select a message type for SQL Remote replication, select a message type from the list and click OK.

  • The supported message types are FILE, FTP, and SMTP.

The selected message type has the following parameters This window lists the name and value for each parameter for the selected message type.

  • Name Lists the parameter names for the selected message type.

  • Value Shows the value for the parameter for the selected message type. You can change the value by clicking in the field and typing a different value.

The following tables list the parameters for each of the supported SQL Remote message types.

FILE message control parameters
Name | Values | Default | Description
Directory String
''
 Set to the directory under which the messages are stored. The setting is an alternative to the SQLREMOTE environment variable.
Debug | YES, NO | NO | When set to YES, all file system calls made by the FILE link are displayed.
Unlink_delay | Integer | Pause for 1 second after first failed attempt, 2 seconds after second failed attempt, etc. | Set to the number of seconds to wait before attempting to delete a file if the previous attempt to delete the file failed.

For more information about the FILE message system, see The file message system.

FTP message control parameters
Name | Values | Default | Description
Host String
''
 The host name or IP address of the computer where the messages are stored.
User String
''
 The user name for accessing the ftp host.
Password String
''
 The password for accessing the ftp host.
Root_Directory String
''
 The root directory within the ftp host site under which the messages are stored.
Port String
''
 The IP port number used for the ftp connection. This is usually not required.
Debug | YES, NO | NO | This parameter controls whether debugging output appears.
Active_Mode YES, NO NO This parameter controls whether the client or the server initiates all data transfer connections.

When this parameter is set to NO, (Passive mode) the client initiates all data transfer connections, in this case the message link.

When this parameter is set to YES (Active mode) the server initiates all data connections.

If your FTP server is sitting behind an incorrectly configured firewall you may not be able to use the default passive transfer mode.

For more information about this parameter, see Troubleshooting ftp problems.

For more information about the FTP message system, see The ftp message system.

SMTP message control parameters
Name | Values | Default | Description
Local_Host String
''
 The name of the local computer. The local host name is required to initiate a session with any SMTP server. In most network environments, the local host name can be determined automatically and you do not need to supply this value.
TOP_Supported YES, NO YES SQL Remote uses a POP3 command called TOP when enumerating incoming messages. The TOP command may not be supported by all POP servers.

Set this value to NO to use the RETR command, which is less efficient but works with all POP servers.
Smtp_Host String
''
 The name of the computer on which the SMTP server is running. It corresponds to the SMTP host field in the SMTP/POP3 login dialog.
Pop3_Host String
''
 The name of the computer on which the POP host is running. It corresponds to the POP3 host field in the SMTP/POP3 login dialog.
Pop3_Userid String
''
 The POP user ID corresponds to the user ID field in the SMTP/POP3 login dialog.
Pop3_password String
''
 The POP password corresponds to the password field in the SMTP/POP3 login dialog.
Debug | YES, NO | NO | This parameter controls whether debugging information appears. When set to YES, SMTP and POP3 commands and responses appear.

For more information about the SMTP message system, see The SMTP message system.

See also

  • Working with message types

  • Using message types


Debugger help

The following sections describe the dialogs available in the Sybase debugger.

For more information about using the debugger, see Debugging Logic in the Database.


Debugger Add Watch dialog

Enter a SQL expression (for stored procedures) or Java expression (for Java classes) to watch. The expression appears in the Watch window when Sybase Central is running a Debug task.

For example, to track the SQLSTATE value when debugging stored procedures, just enter SQLSTATE.

See also
  • Expressions


Debugger Breakpoints dialog

The Debugger Breakpoints dialog has the following components:

All breakpoints A list of all breakpoints in the current database.

Close Close the Breakpoints dialog.

Edit Edit the currently selected breakpoint. For example, you can set or modify a condition that must be satisfied before the breakpoint interrupts execution.

View Code Close the Breakpoints dialog and show code for the selected breakpoint.

Enable Enable the selected breakpoint, so that it interrupts execution. The breakpoint is shown as a red circle in the code window.

Disable Disable the selected breakpoint, so that it does not interrupt execution. The breakpoint is shown as a gray circle in the code window.

Remove Delete the selected breakpoint from the list.

New Breakpoint Create a new breakpoint.

See also
  • Working with breakpoints


Debugger Edit or Add Breakpoint dialog

The Debugger Edit or Add Breakpoint dialog has the following components:

Server The database server to which the breakpoint applies.

Database The database to which the breakpoint applies.

Procedure For SQL procedures, the stored procedure to which the breakpoint applies.

Class For Java classes, the class to which the breakpoint applies.

Condition A condition that must evaluate to true for the breakpoint to interrupt execution.

The condition does not have to depend only on variables within the procedure. For example, you can set a breakpoint to apply to a connection made by a specified user, you can enter the following condition:

CURRENT USER = 'user-name'

For more information, see Search conditions.

Count The number of times the breakpoint is skipped before it interrupts execution. A value of 0 means that the breakpoint always stops execution.

Enable this breakpoint Check this box for the breakpoint to interrupt execution.

See also
  • Editing breakpoint conditions


Debugger Java Source dialog

The Debugger Java Source dialog has the following components:

List of folders A list of folders or individual files where the debugger looks for Java source.

Browse Folder Locate a folder to add to the list.

Browse File Locate an individual file to add to the list.

See also
  • Creating a class


Index Consultant

The Index Consultant guides you in the proper selection of indexes for your database. It guides you through the process of selecting indexes for a single query or for a set of database requests (called a workload). It creates many different sets of virtual indexes. For each set, the Index Consultant optimizes queries and other requests as if those virtual indexes were present. The Index Consultant then gathers the results of these explorations into a set of recommendations.

See also
  • Index Consultant overview
  • Understanding the Index Consultant
  • Understanding workloads
  • Understanding the analysis
  • Understanding the recommendations
  • Assessing the recommendations
  • Implementing the recommendations


Interactive SQL Help

About this chapter

This chapter provides descriptions of all the dialog boxes and wizards you can access in Interactive SQL.


About Interactive SQL

The following table provides a guide to where you can look for information about how to run and use Interactive SQL.

If you want to know... | Then see...
How to start Interactive SQL | Lesson 2: The Interactive SQL interface
How to connect to a database | The Sample Database
How to use the Interactive SQL toolbar | Interactive SQL main window description
How to open a new Interactive SQL window | Opening multiple windows
Where to find information about keyboard shortcuts | Interactive SQL keyboard shortcuts
How to display data | Lesson 3: Displaying data using Interactive SQL
How to execute SQL commands in Interactive SQL | Lesson 4: Working with SQL statements
Where to find more detailed information on selecting data | Selecting Data from Database Tables
Where to find information about using the Query Editor to build SELECT statements | Introducing the Query Editor
Where to find more information on loading and unloading data | Transferring data into and out of databases
How to set Interactive SQL options | Options dialog
How to automate common tasks | Using SQL command files
How to use JDBC escape syntax | Using JDBC escape syntax
How to print from Interactive SQL | Printing SQL statements
How to print the graphical plan from Interactive SQL | Graphical plans
How to analyze queries using the Index Consultant | Starting the Index Consultant


Introduction to Interactive SQL dialog boxes

You can access all the dialogs in Interactive SQL through the Tools menu. With these dialogs, you can configure Interactive SQL settings, search for table and procedure names to insert into your queries, and edit your queries.

The Tools menu contains the following dialogs:

Lookup Table Name The Lookup Table Name dialog lets you browse table and column names and insert them into the SQL Statements pane.

Lookup Procedure Name The Lookup Procedure Name dialog lets you browse procedure names and insert them into the SQL Statements pane.

Edit Query The Query Editor provides an alternative way to create and edit SELECT statements in Interactive SQL.

For information, see Introducing the Query Editor.

Index Consultant The Index Consultant guides you in the proper selection of indexes. You can use the Index Consultant to analyze the benefits of indexes for an individual query.

For more information, see Starting the Index Consultant.

Options The Options dialog sets options for commands, appearance, importing and exporting data, and messages in Interactive SQL.


Lookup Procedure Name dialog

The Lookup Procedure Name dialog allows you to look up the names of procedures stored in the database. Once you find the procedure you are looking for, you can insert it into the SQL Statements pane at your current cursor position.

The Lookup Procedure Name dialog has the following components:

Type the first few characters of the procedure you're looking for Type the first few characters of the procedure name in the text box to restrict the list of procedures to only those that start with the text you enter.

Click the procedure you want, then click OK Select the procedure from the list. Click OK to insert the procedure name into the SQL Statements pane at your current cursor position.

Show owner names Select this option if you want to prefix each procedure name in the list with the name of the database user who owns the procedure.

Show system objects Select this option if you want the system-supplied stored procedures to appear in the list.

Tip
You can use the SQL wildcard characters '%' (percent sign) and '_' (underscore) to help narrow your search. '%' matches any string of zero or more characters, while '_' matches any one character.

For example, to list all the procedures that contain the word profile, type %profile%.

If you want to search for a percent sign or underscore within a procedure name, you must prefix the percent sign or underscore with an escape character. The escape character depends on the JDBC driver that you are using. If you are connected via jConnect, the escape character is '\' (backslash) while the escape character for the iAnywhere JDBC driver is '~' (tilde).


Lookup Table Name dialog

The Lookup Table Name dialog allows you to look up the names of tables and columns stored in the database that you are currently connected to. Once you find the table or column name you are looking for, you can insert it into the SQL Statements pane at your current cursor position.

The Lookup Table Name dialog has the following components:

Type the first few characters of the table you're looking for Type the first few characters of the table name in the text box to restrict the list of tables to only those that start with the text you enter.

Click the table you want, then click OK or Show Columns Select the desired table from the list and then click OK to insert the table name into the SQL Statements pane.

You can use the following options to restrict the tables that appear in the list. If you know what type of table you are looking for, select only that type to restrict the list. You can select any or all of the table types listed below, and you can also choose to show the names of the table owner in the list.

  • Show tables All permanent, non-system tables owned by any owner. Temporary tables do not appear in the list of tables.

  • Show system tables All system tables.

  • Show views All views.

  • Show owner names Select this option to include table owners in the list.

Show Columns Once you select a table from the list, click Show Columns to see a list of all of the columns in the selected table. In the Select Column dialog, click OK to enter the selected column name into the SQL Statements pane at your current cursor position.

Tip
You can use the SQL wildcard characters '%' (percent sign) and '_' (underscore) to help narrow your search. '%' matches any string of zero or more characters, while '_' matches any one character.

For example, to list all the tables that contain the word profile, type %profile%.

If you want to search for a percent sign or underscore within a table name, you must prefix the percent sign or underscore with an escape character. The escape character depends on the JDBC driver that you are using. If you are connected via jConnect, the escape character is '\' (backslash) while the escape character for the iAnywhere JDBC driver is '~' (tilde).


Options dialog

You can configure Interactive SQL using the Options dialog. This dialog provides settings for commands, appearance, result sets, import/export features, messages, the appearance of the query optimization plan, and Code Editor settings.

The Interactive SQL Options dialog consists of eight tabs: General, Results, Import/Export, Messages, Plan, Editor, Query Editor, and Check For Updates.

Options dialog: General tab
Options dialog: Results tab
Options dialog: Import/Export tab
Options dialog: Messages tab
Options dialog: Plan tab
Options dialog: Editor tab
Options dialog: Query Editor tab
Options dialog: Check for Updates tab


Options dialog: General tab

The General tab of the Options dialog in Interactive SQL has the following components:

Commit The following options let you select when to commit changes to the database. You can also commit manually by entering an explicit COMMIT command whenever appropriate.

  • After each command Select this option to commit changes to the database after each SQL statement is executed.

  • On exit Select this option to commit changes to the database when you exit your Interactive SQL session. This is the default setting.

    For more information, see AUTO_COMMIT option [Interactive SQL].

Command files The following options control Interactive SQL's behavior when running command files.

  • When an error occurs Select an option to control how Interactive SQL responds when it encounters an error while executing statements from a command file. Depending on the option you choose, Interactive SQL can continue executing the file, stop executing the file, or shut down. The default setting is Prompt.

    For more information about configuring how Interactive SQL responds to errors while executing statements from a command file, see ON_ERROR option [Interactive SQL].

  • Echo command files to log If you select this option, Interactive SQL logs SQL statements that are executed from command files to the log file.

    By default, command files are copied to the log.

    For more information, see ECHO option [Interactive SQL].

When browsing for files, where should the browser start? Select one of the following options to specify which directory Interactive SQL uses first when browsing for files. If you wish to use this setting in subsequent Interactive SQL sessions, click Make Permanent after selecting one of the following options.

  • Last folder used If you select this option, the initial browser directory is the one where you last used the file browser. This is the default setting.

  • Current folder If you select this option, the initial directory used by the browser is the current folder, as defined by the operating system.

Fast Launcher

The fast launcher is designed to reduce Interactive SQL's startup time. When the fast launcher is turned on, the fast launcher process (dbisqlg.exe for Interactive SQL) starts when you log in. The fast launcher is only available on Windows platforms. You can change the settings for the fast launcher on the Interactive SQL Options dialog (opened by choosing Tools > Options in Interactive SQL).

Sybase Central has its own fast launcher process (scjview.exe) that is turned on and off separately from the Interactive SQL fast launcher. You can configure the Sybase Central fast launcher from the Sybase Central Options dialog (opened by choosing Tools > Options in Sybase Central).

Note that the fast launcher process requires a significant amount of memory, and the impact on application startup time depends on your system configuration.

  • Enable fast launcher Select this option to turn on the fast launcher. The fast launcher is turned on by default. If you want to turn the fast launcher off, clear this checkbox. You must log out and log in again for these settings to take effect.

  • Configure Opens the DBISQL Fast Launcher Configuration dialog where you can configure the TCP/IP port used by the fast launcher and set the inactivity timer.

    The fast launcher uses a TCP/IP port on your machine. If another program is already using this port, you can change the port number used by the fast launcher in this dialog.

    When the fast launcher is not used for the amount of time specified in the inactivity timer, it shuts down, which frees up memory for other applications. By default, the inactivity timer is set to never shut down.

File Association On Windows platforms, you can make Interactive SQL the default editor for .SQL files.

  • Make DBISQL the default editor for .SQL files Select this option to make Interactive SQL the default editor for .SQL files on Windows.

    Windows uses Interactive SQL to automatically open the file when you double-click on it. Note that Interactive SQL does not run the file automatically.

See also
  • SET OPTION statement [Interactive SQL]


Options dialog: Results tab

The Results tab of the Options dialog in Interactive SQL has the following components:

Display null values as Specify how you want nulls to appear in table columns. You can use any string for this value. The default value is (NULL). If this field is blank, null values appear as an empty string.

For more information, see NULLS option [Interactive SQL].

Maximum number of rows to display Specify the maximum number of rows that appear in the Results pane. The default is 500.

Truncation length Specify the number of characters that are displayed in each column in the Results pane. If you enter a value of 0, the columns are not truncated. The default is 256.

For more information, see TRUNCATION_LENGTH option [Interactive SQL].

Show multiple result sets Select this option if you want Interactive SQL to display multiple result sets in the Results pane when you execute a procedure that returns multiple SELECT statements. Each result set appears on a separate tab in the Results pane. By default, Interactive SQL does not display multiple result sets.

If you use the jConnect driver and select the Show Multiple Result Sets option, Interactive SQL must wait until the entire result set is retrieved before any rows appear in the Results pane. This can result in slower processing of large result sets.

Show row number Select this option if you want row numbers to appear beside your results in the Results pane. This option is on by default.

Automatically refetch results Select this option if you want Interactive SQL to automatically regenerate the result set after you execute an INSERT, UPDATE, or DELETE statement. By default, Interactive SQL refetches result sets.

For more information, see AUTO_REFETCH option [Interactive SQL].

When running in console mode, which result sets do you want to see? The following options let you specify which result set(s) are printed when a .SQL file is run. This option has no effect when running in windowed mode and is set on a per-machine basis. This option is set only for the current Interactive SQL unless you click the Make Permanent button.

  • The last one Prints the result set from the last statement in the file.

  • All of them Prints result sets for each statement in the file that returns a result set.

  • None Does not print any result sets.

    For more information, see ISQL_PRINT_RESULT_SET option [Interactive SQL].

Which font do you want to use to show results? Select one of the following options to specify the font that is used for table data in the Interactive SQL Results pane.

  • System font Select this option to use the machine's normal text font. This is the default setting.

  • Editor font Select this option to use the same font as the Code Editor.

    For more information about the Code Editor, see Format tab.

  • Custom font Select this option to specify the font, font style, and point size you want to use. Click Browse to select the desired settings in the Font dialog.

See also
  • SET OPTION statement [Interactive SQL]


Options dialog: Import/Export tab

The Import/Export tab of the Options dialog in Interactive SQL has the following components:

Default export format To choose a format for exporting files, select a file format from the dropdown list. By default, the export format is ASCII.

Default import format To choose a format for importing files, select a file format from the dropdown list. By default, the import format is ASCII.

For more information about the import and export file formats supported by Interactive SQL, see INPUT statement [Interactive SQL] and OUTPUT statement [Interactive SQL].

ASCII Options Specify the default symbols used for the field separator, quote string, and escape character when you import or export data in ASCII format.

  • Default field separator The symbol used to separate values in ASCII files. The default value is a comma (,).

  • Default quote string The symbol used to enclose strings in ASCII files. The default value is a single quote (').

  • Default escape character The symbol used in place of unprintable characters in ASCII files. The escape character must be one, single-byte character. The default value is a backslash (\).

  • Default encoding The encoding used when importing and exporting files. If you change this value, it is only changed for the current Interactive SQL session. When you start a new Interactive SQL session, it is restored to its default value. The default value is (Default). If you select (Default), the encoding is determined as follows:

    • the code page specified in the ENCODING clause of the INPUT, OUTPUT, or READ statement

    • the code page specified with the DEFAULT_ISQL_ENCODING option (if this option is set)

    • the code page specified with the -codepage command-line option when Interactive SQL was started

    • the default code page for the computer Interactive SQL is running on

See also
  • Importing and Exporting Data
  • SET OPTION statement [Interactive SQL]


Options dialog: Messages tab

The Messages tab of the Options dialog in Interactive SQL has the following components:

Measure execution time for SQL statements Select this option if you want Interactive SQL to measure the time it takes for a statement to execute. The time appears on the Messages tab. By default, this option is selected.

Show separate Messages pane Select this option if you want information from the database server, such as execution time, to appear in the Messages pane between the SQL Statements and Results panes rather than on the Messages tab in the Results pane. By default, database server information appears on the Messages tab in the Results pane.

Default number of lines in Messages pane Type the number of lines you want returned in the Messages pane. The default number is 7. If you select Show Separate Messages Pane, the number is also the height (in lines) of the Messages pane.

See also
  • SET OPTION statement [Interactive SQL]


Options dialog: Plan tab

The Plan tab of the Options dialog in Interactive SQL has the following components:

Execution plan options These options allow you to select the level of detail Interactive SQL provides about the way your query is optimized, select a plan type from the list of plan types. Plan information appears on the Plan tab in the Results pane.

  • Graphical plan The execution plan is displayed as a tree diagram in the Plan tab. You can click on a node in the plan diagram to see details about that part of the query. This plan is the default.

  • Graphical plan with statistics The execution plan is displayed as a tree diagram in the Plan tab, and you can click on a node to see details about that part of the query. Statistics are also displayed which indicate the resources used by the part of the query that is selected.

  • Short plan Basic information about an execution plan appears in one line on the Plan tab in the Results pane. This line lists the table(s) accessed and whether the rows are to be read sequentially or accessed through an index.

  • Long plan Detailed information about an execution plan appears in multiple lines on the Plan tab.

    For more information about the different types of execution plans, see Accessing the plan in Interactive SQL.

Assume read-only cursor Select this option if you want the query optimizer to treat the query as if it had been executed for a read-only cursor. By default, this option is not selected, indicating that the optimizer should get the plan for a read-write cursor.

For more information, see PLAN function [Miscellaneous].

Assume cursor is You can obtain a plan based on the type of cursor you specify. The query optimizer can assume the cursor is Asensitive, Insensitive, Sensitive, or Keyset-driven. The default is Asensitive.

For more information, see PLAN function [Miscellaneous], Asensitive cursors, Insensitive cursors, Sensitive cursors, and Value-sensitive cursors.

Show UltraLite plan Select this option if you want the UltraLite plan to appear on a separate tab in the Results pane in Interactive SQL.

You control the UltraLite plan type by selecting one of the types above (Graphical, Graphical Plan With Statistics, Short Plan, or Long Plan). This option is selected by default.

For more information, see GRAPHICAL_ULPLAN function [Miscellaneous], LONG_ULPLAN function [Miscellaneous], and SHORT_ULPLAN function [Miscellaneous].

See also
  • Accessing the plan in Interactive SQL
  • Reading access plans


Options dialog: Editor tab

This tab allows you to configure the appearance of text typed in the SQL Statements pane. Note that any settings you specify on this tab also apply to the Code Editor when it is used in Sybase Central.

The Editor tab of the Options dialog in Interactive SQL consists of four tabs: Editor, Tabs, Format, and Print.


Editor tab

The Editor tab has the following components:

Vertical scroll bar Shows or hides a vertical scroll bar when the window is too small to contain all the text.

Horizontal scroll bar Shows or hides a horizontal scroll bar when the window is too small to contain all the text.


Tabs tab

The Tabs tab has the following components:

Tab size Lets you set the tab size (in number of spaces).

Indent size Lets you set the size of indents (in number of spaces).

Insert spaces Inserts n spaces when you press Tab instead of inserting one tab character. The value for n will be between one and the number of indent size spaces, depending on how many spaces are required to move the cursor forward to the next tab stop.

Keep tabs Inserts a tab character into the document and moves the cursor forward to the next tab stop when you press Tab.

Auto indent Lets you set the auto indent feature. You have the following options:

  • None disables the feature.

  • Default uses the tab and indent sizes that are set.

  • Smart uses previous lines of code as a guideline for indenting open and closing braces.

    • Indent opening brace Select this option if you wish opening braces to be indented. This option is enabled when the Smart option is selected.

    • Indent closing brace Select this option if you wish closing braces to be indented. This option is enabled when the Smart option is selected.

Sample The Sample field shows an example of how code is formatted based on the options you choose for indenting opening and closing braces.


Format tab

The Format tab has the following components:

Text Highlighting Lets you specify the color and style of different types of text in the main editing window. Choose a type of text and then set the foreground, background, and style for that text type.

  • Foreground Foreground refers to the color of the text.

  • Background Background refers to the color of the screen behind the text.

  • Style Lets you specify the type of formatting for a text type. You have the following choices:

    • Plain

    • Italic

    • Bold

    • Italic and Bold

Font size Lets you specify the font point size of the text that appears in the SQL Statements pane.

Caret color Lets you specify the color of the blinking on-screen cursor indicator.

Sample Shows an updated sample of the text with the settings you configure above.

Reset All Returns all settings to their default values.


Print tab

The Print tab has the following components:

Header Lets you specify what information appears in the header, as well as how it is formatted, when you print the contents of the SQL Statements pane. The header text is left aligned by default. Press the > button for a list of available options.

Footer Lets you specify what information appears in the footer, as well as how it is formatted, when you print the contents of the SQL Statements pane. The footer text is left aligned by default. Press the > button for a list of available options.

  • > button Pressing the > button lets you choose from the following options for the header or footer:

    • File Name

    • File Time

    • File Date

    • Page Number

    • Page Count

    • Current Time

    • Current Date

    • Left Align

    • Center

    • Right Align

    The items that you select do not all need to have the same alignment. For example, you can choose to left align the file name and right align the date in the header. By default, all text in both the header and the footer is left aligned. You must specify the alignment before the type of text. For example, if you want the file name to be centered in the header, type &C&F in the Header field, or press the > button and select the Center option and then press the > button again and select the Filename option.

    In addition to specifying these options, you can type text that you want to appear in the header and footer fields. For example, if you type Page &P of &p in the Footer field, Page 1 of 1 appears in the footer of the printed document.

Font size Lets you select the font point size for the printed text.


Options dialog: Query Editor tab

This tab allows you to configure settings for the Query Editor.

The Query Editor tab of the Interactive SQL Options dialog has the following components:

Fully qualify table and column names Select this option if you want table and column names to be fully qualified with their owner names when constructing queries in the Query Editor.

For information about qualifying table and column names, see SQL queries.

Quote names Select this option if you want the names of identifiers to be enclosed in double quotes when constructing queries in the Query Editor.

For information about quoting identifiers, see Identifiers.

Get list of tables on startup Select this option if you want the Query Editor to populate its list of tables as soon as it opens. This option is selected by default. If you are connected to a database with a large number of tables or have a slow communications link, you may wish to turn this option off so the Query Editor opens more quickly.


Options dialog: Check for Updates tab

This tab allows you to configure whether Adaptive Server Anywhere should check for software updates and how often it should do so. Checking for updates is done on application startup.

You can also check for updates any time from the Start menu by choosing Programs > SQL Anywhere 9 > Check For Updates and from the Sybase Central, Interactive SQL, and Console utility Help menus.

The Check For Updates tab of the Options dialog has the following components:

When to check for updates Choose one of the following options to specify how often Adaptive Server Anywhere should check for updates. By default, Never is selected.

  • On application startup Select this option if you want Interactive SQL to check for updates each time the current application is launched.

  • Daily Select this option if you want Adaptive Server Anywhere to check for updates the first time the current application is started each day.

  • Weekly Select this option if you want Adaptive Server Anywhere to check for updates the first time the current application is started each week.

  • Monthly Select this option if you want Adaptive Server Anywhere to check for updates the first time the current application is started each month.

  • Never Select this option if you do not want Interactive SQL to check for updates. This is the default setting.

What to check for Choose any combination of the following options to specify what types of updates Interactive SQL should check for. By default, all of the following options are selected.

  • Express Bug Fix Select this option if you want Interactive SQL to check for Express Bug Fixes.

    An express bug fix is a subset of the software with one or more bug fixes. The bug fixes are listed in the release notes for the update. Bug fix updates may only be applied to installed software with the same version number. Some testing has been performed on the software, but the software has not undergone full testing. You should not distribute these files with your application unless you have verified the suitability of the software yourself.

  • Maintenance Release Select this option if you want Interactive SQL to check for maintenance releases of the software.

    A maintenance release is a complete set of software that upgrades installed software from an older version with the same major version number (version number format is major.minor.patch.build). Bug fixes and other changes are listed in the release notes for the upgrade.

  • Other Information Select this option to check for other information, such as new product releases or upcoming events.


Interactive SQL wizards

Interactive SQL provides an Export wizard to walk you through the process of exporting result sets.

Export wizard


Export wizard

The Export dialog allows you to set options when exporting a result set to a file in Interactive SQL.

File name Type the name of the file you are exporting the result set to. Alternatively, you can click Browse to locate a file.

Format Select one of the following output formats:

  • ASCII The output is an ASCII format file with one row per line in the file. All values are separated by commas, and strings are enclosed in apostrophes (single quotes).

    Three other special sequences are also used. The two characters \n represent a newline character, \\ represents a single \, and the sequence \xDD represents the character with hexadecimal code DD. This is the default output format.

  • dBase II The output is a dBASE II format file with the column definitions at the top of the file. Note that a maximum of 32 columns can be output. Column names are truncated to 11 characters, and each row of data in each column is truncated to 255 characters.

  • dBase III The output is a dBASE III format file with the column definitions at the top of the file. Note that a maximum of 128 columns can be output. Column names are truncated to 11 characters, and each row of data in each column is truncated to 255 characters.

  • Excel The output is an Excel 2.1 worksheet. The first row of the worksheet contains column labels (or names if there are no labels defined). Subsequent worksheet rows contain the actual table data.

  • Fixed The output is fixed format with each column having a fixed width. The width for each column can be specified using the COLUMN WIDTHS clause. No column headings are output in this format. If the COLUMN WIDTHS clause is omitted, the width for each column is computed from the data type for the column, and is large enough to hold any value of that data type. The exception is that LONG VARCHAR and LONG BINARY data defaults to 32 kb.

  • FoxPro The output is a FoxPro format file (the FoxPro memo field is different than the dBASE memo field) with the column definitions at the top of the file. Note that a maximum of 128 columns can be output. Column names are truncated to 11 characters. Column names are truncated to 11 characters, and each row of data in each column is truncated to 255 characters.

  • HTML The output is in the Hyper Text Markup Language format.

  • Lotus 1-2-3 The output is a Lotus WKS format worksheet. Column names will be put as the first row in the worksheet. Note that there are certain restrictions on the maximum size of Lotus WKS format worksheets that other software (such as Lotus 1-2-3) can load. There is no limit to the size of file Interactive SQL can produce.

  • SQL Statements The output is an Interactive SQL INPUT statement required to recreate the information in the table.

  • XML The output is an XML file encoded in UTF-8 and containing an embedded DTD. Binary values are encoded in CDATA blocks with the binary data rendered as 2-hex-digit strings. The INPUT statement does not accept XML as a file format.

Encoding Specify the code page that is used to write the file. You can only specify this option if you have selected the ASCII format. You can specify the encoding to be used, or if you select (Default), the default encoding for the machine Interactive SQL is running on is used.

Escape text data When you select this option, characters following the escape character are recognized and interpreted as special characters by the database server. The default escape character is the backslash (\). New line characters can be included as the combination \n, other characters can be included in data as hexadecimal ASCII codes, such as \x09 for the tab character. A sequence of two backslash characters ( \\ ) is interpreted as a single backslash. A backslash followed by any character other than n, x, X or \ is interpreted as two separate characters. For example, \q inserts a backslash and the letter q.

  • Escape character You can specify the escape character for characters stored as hexadecimal codes. The default escape character is the backslash (\).

See also
  • OUTPUT statement [Interactive SQL]


MobiLink Help

About this chapter

This chapter provides descriptions of all the property sheets, dialog boxes, and wizards you can access when you connect using the MobiLink plug-in.


Introduction

When you connect to MobiLink, Sybase Central provides property sheets that let you configure object properties. You can view and change the settings for various objects using dialog boxes, while wizards can walk you through the steps for carrying out common administrative tasks.

See also
  • MobiLink property sheets
  • MobiLink dialog boxes
  • MobiLink wizards


MobiLink property sheets

This section contains detailed descriptions of each MobiLink property sheet where you can view and configure an object's properties. When you are connected to MobiLink, each property sheet becomes available in the Sybase Central File menu when you select an object, or in a popup menu when you right-click an object.

Carrier property sheet
Database property sheet
Device Tracker Gateway property sheet
Global Notification property sheet
Notifier property sheet
Service property sheet
SMTP Gateway property sheet
UDP Gateway property sheet
User property sheet
Version property sheet


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

MobiLink Help

MobiLink property sheets

Carrier property sheet

The Carrier property sheet consists of three tabs: General, Identification, and SMTP.


Carrier property sheet: General tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The General tab of the Carrier property sheet has the following components:

Name Shows the name of the carrier. You can change the name of the carrier in this field.

Type Shows the type of object.

Enable this carrier Select this option to use this carrier. You can define and use multiple carrier mappings.

For more information, see enable property.

Description Provides a place for you to type a text description of this carrier.

See also
  • Setting properties
  • Configuring gateways and carriers


Carrier property sheet: Identification tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The Identification tab of the Carrier property sheet has the following components:

Network Provider ID Type the network provider ID.

For more information, see network_provider_id property.

See also
  • Setting properties
  • Configuring gateways and carriers


Carrier property sheet: SMTP tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The SMTP tab of the Carrier property sheet has the following components:

User Prefix Type the prefix used in e-mail addresses

For more information, see sms_email_user_prefix property.

Domain Type the domain of the carrier.

For more information, see sms_email_domain property.

See also
  • Setting properties
  • Configuring gateways and carriers


Database property sheet

The Database property sheet allows you to view information about the database you are currently connected to.

The Database property sheet consists of one tab: General.

Database property sheet: General tab


Database property sheet: General tab

The General tab of the Database property sheet has the following components:

Name Shows the name of the selected database.

Type Shows the type of database.

Version Shows the version number of the selected database.


Device Tracker Gateway property sheet

The Device Tracker Gateway property sheet consists of three tabs: General, Gateways, and Delivery.

Device Tracker Gateway property sheet: General tab
Device Tracker Gateway property sheet: Gateways tab
Device Tracker Gateway property sheet: Delivery tab


Device Tracker Gateway property sheet: General tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The General tab of the Device Tracker Gateway property sheet has the following components:

Name Shows the name of the gateway. You can change the name of the gateway in this field.

Type Shows the type of object.

Enable this gateway Select this option to use this gateway.

For more information, see enable property.

Description Provides a place for you to type a text description of the device tracker gateway.

See also
  • Device tracker gateway properties
  • Device tracking


Device Tracker Gateway property sheet: Gateways tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The Gateways tab of the Device Tracker Gateway property sheet has the following components:

Use these gateways for device tracking Select one of the following options to specify the gateways that are used for device tracking.

  • Only the UDP gateway Select this option if you wish to identify a UDP gateway that the device tracker might use. The gateway must be enabled. A device tracker gateway can only use one UDP gateway.

  • Only the SMTP gateway Select this option if you wish to identify an SMTP gateway that the device tracker might use. The gateway must be enabled. A device tracker gateway can only use one SMTP gateway.

  • Both the UDP gateway and the SMTP gateway Select this option if you wish to identify a UDP gateway and an SMTP gateway that the device tracker might use. The gateways must be enabled. The device tracker gateway can only use one UDP gateway and one SMTP gateway.

UDP gateway Select the UDP gateway used by the device tracker. The default is Default-UDP. This option is only enabled if you choose Only the UDP Gateway or Both the UDP Gateway and the SMTP Gateway option above.

For more information, see udp_gateway property.

SMTP gateway Select the SMTP gateway used by the device tracker. The default is Default-SMTP. This option is only enabled if you choose Only the SMTP Gateway or Both the UDP Gateway and the SMTP Gateway option above.

For more information, see smtp_gateway property.

See also
  • Device tracker gateway properties
  • Device tracking


Device Tracker Gateway property sheet: Delivery tab

The Delivery tab of the Device Tracker Gateway property sheet has the following components:

Confirm message delivery Select this option if you want the Listener to initiate synchronization when it receives a message to confirm with the consolidated database that the message was received. The Listener must be started with the -x option in order to provide connection information. This option is turned on by default.

See also
  • Device tracker gateway properties
  • Device tracking
  • confirm_delivery property


Global Notification property sheet

The Global Notification property sheet consists of one tab: General.

Global Notification property sheet: General tab


Global Notification property sheet: General tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The General tab of the Global Notification property sheet has the following components:

Verbosity Specify the level of verbosity for all Notifiers, gateways, and carriers. You must choose one of the following levels:

  • No tracing (level 0) Do not use tracing. This is the default setting.

  • Startup and shutdown tracing (level 1) Use a startup, shutdown, and property trace.

  • Show notifications (level 2) Display notification messages.

  • Full tracing (level 3) Use a poll-level trace.

See also
  • verbosity property


Notifier property sheet

The Notifier property sheet consists of four tabs: General, Connection, Polling, and Logic.


Notifier property sheet: General tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The General tab of the Notifier property sheet has the following components:

Name Shows the name of the Notifier. You can change the name of the Notifier in this field.

Type Shows the type of object.

Enable this notifier Select this option to be able to use this Notifier.

For more information, see enable property.

Display control window when running Select this option if you want the Notifier dialog to be open on the computer where the Notifier is running. This user interface allows users to temporarily change the polling interval, or poll immediately. It can also be used to shut down the Notifier without shutting down the MobiLink synchronization server. (Once stopped, the Notifier can only be restarted by shutting down and restarting the MobiLink synchronization server.) This option is selected by default.

For more information, see gui property.

Description Provides a place for you to type a description of the Notifier.

See also
  • MobiLink Notification Properties


Notifier property sheet: Connection tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The Connection tab of the Notifier property sheet has the following components:

Isolation Level Specify an isolation level for the connection. The default isolation level is Read Committed (Level 1). You must choose one of the following:

  • Read uncommitted (level 0)

  • Read committed (level 1)

  • Repeatable read (level 2)

  • Serializable (level 3)

For more information, see isolation property and Isolation levels and consistency.

Connection String Specify a JDBC connection string to override the default connection behavior. This is an optional value.

By default, the Notifier uses ianywhere.ml.script.ServerContext to connect to the consolidated database. This means that it uses the connection string that was specified in the current dbmlsrv9 session's command line.

You may wish to specify a connection string in this field if want to connect to a different database because you want notification logic and data to be separate from your synchronization data.

For more information, see connect_string property.

See also
  • MobiLink Notification Properties


Notifier property sheet: Polling tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The Polling tab of the Notifier property sheet has the following components:

Poll every Select a polling interval from the dropdown list. The default is 30 seconds.

Use this polling interval Specify a polling interval for the Notifier.

For more information, see poll_every property.

See also
  • MobiLink Notification Properties


Notifier property sheet: Logic tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The Logic tab of the Notifier property sheet has the following components:

When this notifier event occurs Select one of the following Notifier events that causes the SQL statement below to execute. When you select an event from the dropdown list, the contents of the SQL statement pane below change to the SQL statement for the selected event.

  • begin_connection The SQL statement runs in a separate transaction after the Notifier connects to the database and before the first poll. If the Notifier loses its connection to the consolidated database, it will re-execute this transaction immediately after reconnecting.

    For more information, see begin_connection property.

  • begin_poll The SQL statement is executed before each Notifier poll.

    For more information, see begin_poll property.

  • end_connection The SQL statement runs as a separate transaction just before a Notifier database connection is closed.

    For more information, see end_connection property.

  • end_poll The SQL statement is executed after each poll.

    For more information, see end_poll property.

  • request_cursor The SQL statement for the Notifier to collect push requests from the consolidated database. You must specify a SQL statement for this event. The result set of this statement must contain five columns, and can optionally contain two other columns. These columns can have any name, but must be in the following order in the result set:

    • request id

    • gateway

    • subject

    • content

    • address

    • resend

    • interval time to live

    For more information, see request_cursor property.

  • request_delete The SQL statement specifies cleanup operations. The statement takes the request id as its only parameter. The placeholder for a parameter is a question mark (?).

    You should define a SQL statement for this event unless you have provided another process to do the cleanup.

    For more information, see request_delete property.

  • shutdown_query The SQL statement is executed right after begin_poll. The result should contain only the value yes (or 1) or no (or 0). To shut down the Notifier, specify yes or 1.

    For more information, see shutdown_query property.

Execute this SQL statement Type the SQL statement that is to be executed when the specified Notifier event occurs.

See also
  • MobiLink Notification Properties


Service property sheet

The Service property sheet allows you to view information about the selected service.

The Service property sheet consists of four tabs: General, Configuration, Account, and Dependencies.

Service property sheet: General tab
Service property sheet: Configuration tab
Service property sheet: Account tab
Service property sheet: Dependencies tab


Service property sheet: General tab

The General tab of the Service property sheet has the following components:

Name Shows the name of the selected service.

Type Shows the type of the selected object. A service runs a database server or other application with a set of options.

Service type Shows the type of service. For example, it could be a MobiLink Synchronization service, Network Database Server service, or some other type of service.

Status Shows whether the selected service is started, stopped, or paused.

For more information about the service status, see Adding, modifying, and removing services.

Startup type You must select one of the following startup types for the selected service. The startup type is applied the next time you start Windows.

  • Automatic Select this option to start the service automatically whenever the operating system starts.

  • Manual Select this option to start the service manually. Only a user with Administrator permissions can start the service if it requires manual startup.

    For information about Administrator permissions, see your Windows documentation.

  • Disabled Select this option to disable the service so it does not start.

See also
  • Managing services
  • Understanding Windows services


Service property sheet: Configuration tab

The Configuration tab of the MobiLink Service property sheet has the following components:

File name Type the path of the executable file. For example, f:\Sybase\ASA90\win32\dbmlsrv9.exe.

Parameters Type additional parameters, including file names and options, for the executable file in the text box. You can use the same options for a service that you use for the executable.

For example, to start a MobiLink synchronization service with verbose logging and three worker threads, type the following:

-c "dsn=ASA 9.0 Sample;uid=DBA;pwd=SQL"
-vc
-wu 3
See also
  • The Service Creation utility


Service property sheet: Account tab

The Account tab of the MobiLink Service property sheet has the following components:

Local system account Select this option to run the service under your system's local account.

  • Allow service to interact with desktop Select this option if you want to display the server window by clicking an icon on your desktop. This option is only available when you select Local System Account.

Other Select this option to run the service under an account other than the local account. You must choose a user ID from the dropdown list.

  • Password Type the password for the account the service is to run under. When you select Other Account, you must supply the appropriate password for the selected user ID and confirm the password in the Confirm Password text box.

  • Confirm password Re-type the password to confirm that it was entered correctly.

See also
  • The Service Creation utility


Service property sheet: Dependencies tab

The Dependencies tab of the MobiLink Service property sheet has the following components:

This service belongs to the following load ordering group Lets you specify which service group the selected service belongs to. To view all the service groups that exist on your system, click Change. The Look Up Group dialog appears, which lets you specify a service group for the selected service.

Change Displays the Look Up Group dialog, which lets you, select which service group the selected service belongs to.

Services list Lists all the services and service groups that must be started before the selected service. This list also shows the type of service or service group.

  • Add Services Displays the Add Services to Dependencies dialog, which lets you view all services and select the ones you wish to add to the Services list on the Dependencies tab of the Service property sheet.

  • Add Service Groups Displays the Add Service Groups to Dependencies dialog, which lets you select the service groups that you want to add to the Services list on the Dependencies tab of the Service property sheet.

  • Remove Removes the selected service or service group from the Services list. The group or service no longer starts before the selected service.

See also
  • Managing services
  • Running more than one service


SMTP Gateway property sheet

The SMTP Gateway property sheet consists of four tabs: General, Server, Headers, and Delivery.

SMTP Gateway property sheet: General tab
SMTP Gateway property sheet: Server tab
SMTP Gateway property sheet: Headers tab
SMTP Gateway property sheet: Delivery tab


SMTP Gateway property sheet: General tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The General tab of the SMTP gateway property sheet has the following components:

Name Shows the name of the gateway. You can change the name of the gateway in this field.

Type Shows the type of object.

Enable this gateway Select this option to use this gateway.

For more information, see enable property.

Description Provides a place for you to type a text description of this SMTP gateway.

See also
  • SMTP gateway properties


SMTP Gateway property sheet: Server tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The Server tab of the SMTP gateway property sheet has the following components:

Host This is the IP address of the SMTP server for sending the message to the Listener. The default is mail.

Authentication You can provide the user name and password for your SMTP service if they are required.

  • This server requires authentication Select this option if you must supply a user name and password for your SMTP service. Selecting this option enables the fields below.

    • User Type the user name for your SMTP service. Your SMTP service may not require a user name.

      For more information, see user property.

    • Password Type the password for your SMTP service.

      For more information, see password property.

See also
  • SMTP gateway properties


SMTP Gateway property sheet: Headers tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The Headers tab of the SMTP gateway property sheet has the following components:

From Type the sender address of the e-mails (SMTP requests).

For more information, see sender property.


SMTP Gateway property sheet: Delivery tab

The Delivery tab of the SMTP gateway property sheet has the following components:

Client Version You can provide information about the version of the client using this gateway.

  • This gateway only supports 9.0.1 and higher clients Select this option if all Listeners are SQL Anywhere Studio version 9.0.1 or later clients. This is the default setting.

    • Confirm message delivery Select this option to confirm message delivery. This setting has an effect only when sending directly through this gateway. This option is turned off by default.

      For more information, see confirm_delivery property.

  • This gateway only supports 9.0.0 clients Select this option if all Listeners are SQL Anywhere Studio version 9.0.0 clients.

    For more information about the version of Listeners, see listeners_are_900 property.

Confirmation Timeout You must provide the amount of time before a confirmation should time out. The default confirmation timeout is 10 minutes.

For more information, see confirm_timeout property.

  • Timeout after Select a timeout interval for confirmations from the dropdown list.

  • Use this timeout Specify the timeout interval for confirmations.

See also
  • SMTP gateway properties


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

MobiLink Help

MobiLink property sheets

UDP Gateway property sheet

The UDP Gateway property sheet consists of three tabs: General, Ports, and Delivery.


UDP Gateway property sheet: General tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The General tab of the UDP gateway property sheet has the following components:

Name Shows the name of the gateway. You can change the name of the gateway in this field.

Type Shows the type of object.

Enable this gateway Select this option to use this gateway.

For more information, see enable property.

Description Provides a place for you to type a text description of this UDP gateway.


UDP Gateway property sheet: Ports tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The Ports tab of the UDP Gateway property sheet has the following components:

Destination Port You can specify the port on the remote device where the gateway sends the UDP packet.

  • Use the default port (5001) Choose this option to use the default listening port of the supplied UDP Listener (5001).

  • Use this port Specify the port on the remote device where the gateway sends the UDP packet.

For more information, see listener_port property.

Origin Port You specify the port to use for sending the UDP packet. You may need to set it if your firewall restricts outgoing traffic.

  • Use a system-assigned port Select this option if you want your operating system to assign a free port.

  • Use this port Select this option to specify the port used for sending the UDP packet.

For more information, see sender_port property.

Network Address You can optionally specify the IP address of the sender.

  • Use the default network address Select this option to use the default network address, localhost.

  • Use this address Select this option to specify the IP address of the sender. You should specify an address if you have multi-homed hosts.

For more information, see sender property.


UDP Gateway property sheet: Delivery tab

Properties are read at startup. When you change properties, you must shut down and restart the MobiLink synchronization server for them to take effect.

The Delivery tab of the SMTP gateway property sheet has the following components:

Client version You can provide information about the version of the client using this gateway.

  • This gateway only supports 9.0.1 and higher clients Select this option if all Listeners are SQL Anywhere Studio version 9.0.1 or later clients. This is the default setting.

    • Confirm message delivery Select this option to confirm message delivery. This setting has an effect only when sending directly through this gateway. This option is turned off by default.

      For more information, see confirm_delivery property.

  • This gateway only supports 9.0.0 clients Select this option if all Listeners are SQL Anywhere Studio version 9.0.0 clients.

    For more information about the version of Listeners, see listeners_are_900 property.

Confirmation Timeout You must provide the amount of time before a confirmation should time out. The default confirmation timeout is 10 minutes.

For more information, see confirm_timeout property.

  • Timeout after Select a timeout interval for confirmations from the dropdown list.

  • Use this timeout Specify the timeout interval for confirmations.


User property sheet

The User property sheet allows you to view information about the selected user.

The User property sheet consists of one tab: General.

User property sheet: General tab


User property sheet: General tab

The General tab of the User property sheet has the following components:

Name Shows the name of the selected MobiLink user.

Type Shows the type of the selected object.

User ID Shows an integer that uniquely identifies the selected MobiLink user.

Password Shows whether the selected MobiLink user has a password.

If the selected MobiLink user does not have a password, (none) appears in the adjacent field. If the selected MobiLink user has a password, asterisks appear in place of the actual password.

Modify Displays the User Authentication dialog where you can change the MobiLink user's name and password.

See also
  • Authenticating MobiLink Users
  • User Authentication dialog


Version property sheet

The Version property sheet allows you to view information about the selected script version. Script versions allow you to organize your scripts into sets, which are run under different circumstances. By specifying a particular version, MobiLink clients can select which set of synchronization scripts will be used to process the upload stream and prepare the download stream.

The Version property sheet consists of one tab: General.

Version property sheet: General tab


Version property sheet: General tab

The General tab of the Version property sheet has the following components:

Name Shows the name of the selected script version. A script version name is a string. You can edit the version name in the text box.

Type Shows the type of the selected object. In this case, the object type is a Version.

Version ID Shows an integer that uniquely identifies the selected version.

Description Provides a place for you to type a text description of the version. For example, you could use this area to describe the version's purpose in the system.

See also
  • Script versions


MobiLink dialog boxes

You can find many of the configurable settings in MobiLink in dialog boxes, which can be accessed through the File menu Sybase Central.

The File menu contains commands related to the objects that appear in the main Sybase Central window. These menu items change depending which object you select. For example, if you select a table, the File menu shows commands and options related to tables. Likewise, if you select a user, the File menu changes to show options related to users. You can also access all of these menu items in popup menus when you right-click an object.


Share Version dialog

The Share Version dialog allows you to associate versions with more than one MobiLink event.

The Share Version dialog has the following components:

Version Select the version to indicate which scripts are executed when the Event below occurs. A version can be associated with more than one event.

Event Shows the name of the event that causes the scripts to execute.


Test Scripts dialog

You can write scripts that are associated with events so that whenever an event occurs, the MobiLink synchronization server executes the associated script if one exists. The Test Scripts dialog allows you to test your synchronization scripts.

The Test Scripts dialog has the following components:

Version Select a version to identify the set of synchronization scripts you want to test.

User Type the user name of a MobiLink Synchronization Server user. If you do not specify a user, the user <Default User> is used for testing the synchronization scripts.

Script-testing window Once you specify a version and a user, you can test your synchronization scripts by clicking Test. The test results appear in this window and include a list of which scripts are executed in which order. If there are any syntax errors or data type errors found during the test, they also appear in this window.

Test Click Test to test for syntax errors in your synchronization scripts (identified by the version). The results appear in the Script-testing window.

Options Displays the Test Scripts Options dialog where you can specify the synchronized table order for the synchronization script you are testing.

See also
  • Test Scripts Options dialog


Test Scripts Options dialog

You can set options for when you test your synchronization scripts in the Test Scripts Options dialog.

The Test Scripts Options dialog has the following components:

Synchronization Tables Lists all the tables in the consolidated database that you can synchronize. Select a table from this list and click Add to add it to the Synchronized Table Order list. You can select multiple tables by holding Shift while you click.

Synchronized Table Order The order of tables in this list is the order in which the tables are synchronized when you test your synchronization scripts in the Test Scripts dialog. If you want to remove a table from this list, select a table and click Delete. You can select multiple tables by holding Shift while you click.

Add Adds tables from the Synchronization Tables list to the Synchronized Table Order list.

Delete Removes tables from the Synchronized Table Order list.

Default Adds all the tables in the Synchronization Tables list to the Synchronized Table Order list and orders them based on the order of the rows in the ml_table table.

See also
  • Test Scripts dialog


User Authentication dialog

The User Authentication dialog allows you to change the name and password for a MobiLink user.

The User Authentication dialog has the following components:

User name Shows the name of the selected user. You can edit the user name in the adjacent field.

No Password Select this option if the selected user does not require a password.

Password Type the Password for the selected user. You must confirm the Password in the Confirm Password field.

Confirm password Re-type the user's password to confirm that it was entered correctly.

See also
  • authenticate_user connection event
  • Authenticating MobiLink Users


MobiLink wizards

Wizards walk you through the steps for carrying out many common administrative tasks in MobiLink. You can also perform many of these tasks using stored procedures.

For more information about MobiLink stored procedures, see Stored Procedures.

Add Carrier wizard
Add Connection Script wizard and Add Table Script wizard
Add Gateway wizard
Add Notifier wizard
Add Service wizard
Add Synchronized Table wizard
Add User wizard
Add Version wizard
Export Notification Settings wizard
Import Notification Settings wizard


Add Carrier wizard

The Add Carrier wizard walks you through the steps for adding a new carrier. You configure carriers to store information about the public wireless carriers that you want to use. Carrier information is used to create SMS e-mail addresses from tracked listening information. New carriers are enabled by default.

You can configure the settings for the new carrier on its property sheet by right-clicking it in Sybase Central and choosing properties from the popup menu.

You can also add a Carrier using the ml_add_property stored procedure.

The Add Carrier wizard has the following components:

What is the name of the new carrier? Type a name for the new carrier.

What is the description of the new carrier? Optionally, you can type a description of the new carrier.

See also
  • Configuring gateways and carriers
  • Carrier properties
  • ml_add_property


Add Connection Script wizard and Add Table Script wizard

About the Add Connection Script wizard

The Add Connection Script wizard walks you through the steps for creating a connection script. Connection scripts control actions centered on connecting and disconnecting. They also permit actions at synchronization-level events such as beginning and ending the upload or download process. You only need to write a connection-level script when some action must occur at a particular event.

About the Add Table Script wizard

The Add Table Script wizard walks you through the steps for creating a table script. Table scripts allow actions at specific events relating to the synchronization of a specific table, such as the start or end of uploading rows, resolving conflicts, or selecting rows to download.

The Add Connection Script wizard and Add Table Script wizard have the following components:

What is the version for the script? Select a version for the table or connection script from the dropdown list.

What event is the new script for? Select the event that causes this script to be executed from the dropdown list.

What is the language for the script? Select a language for the script. You can choose SQL, .NET, or Java.

Edit the script of the new event immediately Select this option if you want the script to appear in a window where you can edit it when you click Finish.

See also
  • Script types
  • Writing Synchronization Scripts in Java
  • Writing Synchronization Scripts in .NET
  • Connection scripts
  • ml_add_connection_script
  • Table scripts
  • ml_add_table_script


Add Gateway wizard

The Add Gateway wizard walks you through the steps for adding a new gateway. Gateways are the mechanisms for sending messages. You can define UDP gateways and SMTP gateways. In addition, you can use a device tracker gateway that automatically decides which gateway to use.

You can configure the settings for the new gateway on its property sheet by right-clicking the gateway and choosing Properties from the popup menu.

You can also add a Gateway using the ml_add_property stored procedure.

The Add Gateway wizard has the following components:

What is the name of the new gateway? Type a name for the new gateway.

What is the type of the new gateway? Select one of the following types for the new gateway:

  • SMTP SMTP gateways can be used to send e-mail messages. They can also send SMS messages to SMS listeners via a wireless carrier's e-mail-to-SMS service.

    For more information about SMTP gateways, see SMTP gateway properties.

  • UDP UDP is useful for development and for applications over wireless LANs.

    For more information, see UDP gateway properties.

  • DeviceTracker Device tracking allows you to address a remote database by supplying only its MobiLink user name. When device tracking is enabled, MobiLink keeps track of how to reach users. The device tracker gateway automatically routes messages to its subordinate gateways. A device tracker gateway can have up to two subordinate gateways: one SMS and one UDP.

    For more information, see Device tracking.

What is the description of the new gateway? Optionally, you can type a description of the new gateway.

See also
  • Gateways and carriers
  • ml_add_property


Add Notifier wizard

The Add Notifier wizard walks you through the steps for adding a new gateway. In the following illustration, the Notifier polls a consolidated database and detects a change that it has been configured to look for.

You can configure the settings for the new notifier on its property sheet by right-clicking the gateway and choosing Properties from the popup menu.

You can also add a Notifier using the ml_add_property stored procedure.

The Add Notifier wizard has the following components:

What is the name of the new notifier? Type the name of the new notifier.

What is the description of the new notifier? Optionally, you can type a description of the new notifier.

See also
  • Notifiers
  • Configuring Notifiers
  • ml_add_property


Add Service wizard

The Add Service wizard walks you through the steps for creating a MobiLink service. You can set up MobiLink synchronization server to be available all the time. The Add Service wizard allows you to set up a service on Windows so that you can run the MobiLink synchronization server in such a way that when you log off the computer it remains running.

The Add Service wizard consists of six pages: Choose Service Name and Startup, Choose Path Name, Specify Parameters, Choose Account, Choose Options, and Ready to Create a New Service.

See also
  • Running MobiLink Outside the Current Session


Choose Name and Startup page

The Choose Name and Startup page of the Add Service wizard has the following components:

What is the name of the new service? Type a name for the new service.

Which startup option would you like? You can select one of the following startup options for the new service. The Startup option is applied the next time you start Windows.

  • Automatic Select this option to start the service automatically whenever the operating system starts.

  • Manual Select this option to start the service manually. Only a user with Administrator permissions can start the service if it requires manual startup.

    For information about Administrator permissions, see your Windows documentation.

  • Disabled Select this option to disable the service so it does not start.

See also
  • Running MobiLink Outside the Current Session


Choose Path Name page

The Choose Path Name page of the Add Service wizard has the following components:

What is the executable file for the new service? Provides a place for you to type the path of the executable file, for example, f:\Sybase\ASA90\win32\dbmlsrv9.exe. You can click Default if you want MobiLink to find the executable file.

Default Click Default if you want MobiLink to find the MobiLink Server executable in the Adaptive Server Anywhere installation directory.

See also
  • Running MobiLink Outside the Current Session


Specify Parameters page

The Specify Parameters page of the Add Service wizard has the following components:

What parameters do you want to use for this service? Type additional parameters (file names and options) for the executable file in the text box. You can use the same options for a service that you use for the executable.

For example, to create a MobiLink synchronization service with verbose logging and three worker threads, enter the following:

-c "dsn=ASA 9.0 Sample;uid=DBA;pwd=SQL"
-vc
-wu 3

For a list of options, see dbmlsrv9 options.

Path Provides a place for you to edit the path of the executable file.

See also
  • Running MobiLink Outside the Current Session


Choose Account page

The Choose Account page of the Add Service wizard has the following components:

Local system account Select this option to run the service under your system's local account.

Other Select this option to run the service under an account other than the local account. You must choose a user ID from the dropdown list.

  • Password When you select Other Account, you must type the appropriate password for the selected account. You must confirm the password in the Confirm Password text box.

  • Confirm Re-type the password to confirm that it was entered correctly.

See also
  • Running MobiLink Outside the Current Session


Choose Options page

The Choose Options page of the Add Service wizard has the following components:

Allow service to interact with desktop Select this option if you want to display the server window by clicking an icon on your desktop. This option is only available when you select Local System Account on the Choose Account page of the Add Service wizard.

Start service when created Select this option to start the new service once the wizard closes. This option is only available if you selected Automatic or Manual on the Choose Name and Startup page of the Add Service wizard.

See also
  • Running MobiLink Outside the Current Session


Ready to Create New Service page

The Ready to Create New Service page of the Add Service wizard has the following components:

Name Shows the name of the new service.

Path Shows the path of the executable file.

Parameters Shows the connection parameters for the service.

Startup Show the startup setting for the service, Automatic, Manual, or Disabled.

Account Shows the name of the account the service runs under.

Interaction Shows whether the service interacts with the desktop.

Start now Shows whether the service starts once the wizard closes.

See also
  • Running MobiLink Outside the Current Session


Add Synchronized Table wizard

The Add Synchronized Table wizard allows you to add a table to the list of tables to be synchronized.

The Add Synchronized Table wizard has the following components:

Specify the remote table name Select this option if the table you want to synchronize already exists in the remote database. Type the name of the remote table you want to add to the list of synchronized tables in the adjacent text box. The remote table and consolidated tables do not have to have the same name.

Consolidated has a table with the same name as the remote table Select this option if the consolidated database already contains a table with the same name as the remote table you want to synchronize. Selecting this option enables both options below.

  • Select the owner of the consolidated table with the same name Select the owner of the consolidated database table that has the same name as the remote table from the dropdown list. You must select a consolidated table owner.

  • Select the consolidated table Select the consolidated table name from the list.


Add User wizard

The Add User wizard has the following components:

What is the name of the new user? Type a name for the new MobiLink user in the text box.

No Password Select this option if the new MobiLink user does not require a password.

Password Select this option if the new MobiLink user requires a password. Type a password for the new MobiLink user in the text box. You must confirm the password in the text box below.

Confirm password Re-type the password to confirm it. The password must match exactly.

See also
  • Authenticating MobiLink Users


Add Version wizard

The Add Version wizard allows you to add a new script version. Script versions allow you to organize your scripts into sets, which are run under different circumstances. By specifying a particular version, MobiLink clients can select which set of synchronization scripts will be used to process the upload stream and prepare the download stream.

The Add Version wizard has the following components:

What is the name of the new version? Type a name for the version in the text box. The version name must be unique: different versions cannot have the same name.

What is the description of the new version? Provides a place for you to type a text description of the version.

See also
  • Script versions


Export Notification Settings wizard

The Export Notification Settings wizard walks you through the steps of exporting the settings from Sybase Central to a Notifier properties file.

The Export Notification Settings wizard consists of three pages: File, Objects, and Settings.


Export Notification Settings wizard: File page

The File page of the Export Notification Settings wizard has the following components:

Create the following file Type a name for the Notifier properties file where the Notifier, gateway, and carrier properties are to be stored. You can click Browse to locate an existing file where you wish to save the Notifier properties.

The Notifier properties file is a text file. It can have any name.

See also
  • Notifier properties file


Export Notification Settings wizard: Objects page

The Objects page of the Export Notification Settings wizard has the following components:

Select the carriers, gateways and notifiers you wish to export This list includes all the user-defined and pre-defined (default) carriers, gateways, and notifiers. Select the ones you wish to export to the Notifier properties file.

  • Select all Click this button to select all the carriers, gateways, and notifiers in the list and add them to the Notifier properties file.

  • Clear all Click this button to clear all the selected carriers, gateways, and notifiers in the list.


Export Notification Settings wizard: Settings page

The Settings page of the Export Notification Settings wizard has the following components:

Select the global notification settings you wish to export Select the settings you wish to export.

For a description of the available settings, see Configuring Redirector properties (all versions).

  • Select All Click this button to select all the global notification settings in the list.

  • Clear All Click this button to clear all the selected items in the global notification settings list.


Import Notification Settings wizard

The Import Notification Settings wizard walks you through the steps of importing the settings from a Notifier properties file.

The Import Notification Settings wizard consists of three pages: File, Objects, and Settings.


Import Notification Settings wizard: File page

The File page of the Import Notification Settings wizard has the following components:

Import the following file Type the name of the Notifier properties file you wish to import. Alternatively, you can locate the file on your machine by clicking Browse.

See also
  • Notifier properties file


Import Notification Settings wizard: Objects page

The Objects page of the Import Notification Settings wizard has the following components:

Select the carriers, gateways and notifiers you wish to import Select the carriers, gateways, and notifiers you wish to import. This list includes all the carriers, gateways, and notifiers defined in the Notifier properties file.


Import Notification Settings wizard: Settings page

The Settings page of the Import Notification Settings wizard has the following components:

Select the global notification settings you wish to import Select the settings you wish to import.

For a description of the available settings, see Configuring Redirector properties (all versions).

  • Select All Click this button to select all the global notification settings in the list.

  • Clear All Click this button to clear all the selected items in the global notification settings list.


MobiLink Monitor Help

About this chapter

This chapter provides descriptions of all the dialog boxes and property sheets you can access from the MobiLink Monitor.

Connect to MobiLink Server dialog
Edit Watch dialog
Go To dialog
New Watch dialog
Export to Database dialog
Options dialog
Session property sheet
Synchronization property sheet
Watch Manager dialog


Connect to MobiLink Server dialog

This dialog lets you connect to a running MobiLink synchronization server. A Monitor connection is like a synchronization connection to the MobiLink synchronization server in that most of the parameters are the same. You must use parameters that are compatible with the MobiLink synchronization server's settings. For all MobiLink Monitor sessions, the script version is set to for_MLMonitor_only.

Tip
If synchronizations are occurring when the MobiLink Monitor is started, the Monitor must wait until a worker thread is free before it can start. Therefore, you may want to start the Monitor before starting synchronizations. Once the Monitor is running, it does not use a MobiLink worker thread.

The Connect To MobiLink Server dialog has the following components:

User Type the name of the MobiLink user for the connection. If you started the MobiLink synchronization server with -zu+, then it doesn't matter what user ID you supply here.

Password Type a password for the connection. This must be the correct password for the MobiLink user you specify. Leave this field blank if the MobiLink user does not have a password.

Host The network name or IP address of the machine on which the MobiLink synchronization server is running. By default, it is the computer where the Monitor is running. You can use localhost if the synchronization server is running on the same machine as the Monitor.

Network protocol Select the communications stream and port to be used for the connection. These values should be set to the same protocol and port as the MobiLink synchronization server is using for synchronization requests.

  • TCP/IP Select this option to connect via TCP/IP.

    • Port The MobiLink synchronization server communicates over a specific port. By default, the port number is 2439 for TCP/IP. If you choose a value other than this, you must configure your MobiLink synchronization server to listen on the port you specify.

  • HTTP Select this option to connect via HTTP. By default, version 1.1 is used.

    • Port The MobiLink synchronization server communicates over a specific port. By default, the port number is 80 for HTTP. If you choose a value other than this, you must configure your MobiLink synchronization server to listen on the port you specify.

  • HTTPS Select this option to connect via HTTPS. The HTTPS communication stream uses Certicom RSA security.

    Note
    The MobiLink Monitor cannot connect to a MobiLink synchronization server that is running HTTPS_FIPS.

    In order to use HTTPS, you must have MobiLink client-side data stream encryption installed on the computer running the MobiLink Monitor. The MobiLink Monitor trusts all certificates, so when you use HTTPS, you do not specify any certificate-related parameters in the Additional Network Parameters field.

    Separately licensable option required
    Transport-layer security requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations.

    To order this component, see Separately-licensable components.

    For more information about security, see MobiLink Transport-Layer Security.

    • Port The MobiLink synchronization server communicates over a specific port. By default, the port number is 443 for HTTPS. If you choose a value other than this, you must configure your MobiLink synchronization server to listen on the port you specify.

Additional network parameters Specify optional network parameters in this field. The allowed values depend on the connection stream type.

The following table lists the parameters you can specify. These parameters are supported by all connection streams (TCP/IP, HTTP, and HTTPS), except where noted otherwise.

Parameter | Description
buffer_size=number | HTTP and HTTPS only. The maximum body size for a fixed content length message, in bytes. Changing the option will decrease or increase the amount of memory allocated for sending content. The default is 65 535, except on UltraLite and Pocket PC, in which case it is 1 024.
client_port=nnnnn client_port=nnnnn-mmmmm | A range of client ports for communication. If only one value is specified, the end of the range is 100 greater than the initial value, for a total of 101 ports. The option can be useful for clients inside a firewall communicating with a MobiLink synchronization server outside the firewall.
persistent={ 0 | 1 } | HTTP and HTTPS only. 1 (True) means that the client will attempt to use the same TCP/IP connection for all HTTPS requests in a synchronization. A setting of 0 (False) is more compatible with intermediate agents. The default is 0, except on Palm devices it is 1. Note: Except on Palm devices, you should only set persistent to 1 if you are connecting directly to MobiLink. If you are connecting through an intermediate agent such as a proxy or redirector, a persistent connection may cause problems.
proxy_host=proxy_hostname | HTTP and HTTPS only. The host name of the proxy server.
proxy_port= proxy_portnumber | HTTP and HTTPS only. The port number of the proxy server. The default value is 80.
url_suffix=suffix | HTTP and HTTPS only. The suffix to add to the URL on the first line of each HTTP request. When synchronizing through a proxy server or the MobiLink redirector, the suffix may be necessary in order to find the MobiLink synchronization server. The default value is MobiLink.
version= versionnumber | HTTP and HTTPS only. A string specifying the version of HTTP to use. You have a choice of 1.0 or 1.1. The default value is 1.1.

For more information about these network parameters, see Network protocol options for UltraLite synchronization clients.

See also
  • Starting the MobiLink Monitor


Edit Watch dialog

The Edit Watch dialog has the following components:

Name The name of the watch. You cannot change the name of a predefined watch (Active, Completed, or Failed).

Conditions You must specify a property, comparison operator, and value to identify synchronizations the Monitor should track. You can specify as many conditions as you wish. Once you select a property, an operator, and a value, click Add to add the condition to the watch.

You cannot edit the values that appear in the Conditions list. To change a watch condition, select the condition from the Conditions list and click Remove. Then, add a new condition with the desired settings.

  • Property Select the property you want the Monitor to track from the dropdown list.

    For a complete list of properties that are available in the MobiLink Monitor, see MobiLink statistical properties.

  • Operator Select a comparison operator. The list of available operators depends on the property you select.

  • Value Enter the value to which the property is compared.

Synchronization display These options let you specify a pattern and color to identify the watch in the Chart and Overview panes.

  • Chart pattern Select a pattern for the watch in the Chart pane.

  • Overview color Select a color for the watch in the Overview pane.

See also
  • Customizing your statistics


Go To dialog

The Go To dialog has the following components:

Start date & time The Go To dialog takes you to the specified date and time in the Chart pane of the Monitor. Type the start date and time of the data that you want to view. If you change this setting, you must specify the year, month, and date.

Chart range Lets you specify the duration of time that appears in the Chart pane. The chart range can be viewed in milliseconds, seconds, minutes, hours, or days by selecting one of these options from the dropdown list. The chart range determines the granularity of the data: a smaller length of time means that more detail is visible.

See also
  • Chart pane


New Watch dialog

The New Watch dialog has the following components:

Name Type a name for the watch.

Conditions You must specify a property, comparison operator, and value to identify synchronizations the Monitor should track. You can specify as many conditions as you wish. Once you select a property, an operator, and a value, click Add to add the condition to the new watch.

You cannot edit the values that appear in the Conditions list. To change a watch condition, select the condition from the Conditions list and click Remove. Then, add a new condition with the desired settings.

  • Property Select the property you want the Monitor to track.

    For a complete list of properties that are available, see MobiLink statistical properties.

  • Operator Select a comparison operator. The list of available operators depends on the property you select.

  • Value Enter a value for the specified property.

Synchronization display These options let you select a pattern and color to identify the watch in the Chart and Overview panes.

  • Chart pattern Select a pattern for the watch in the Chart pane.

  • Overview color Select a color for the watch in the Overview pane.

See also
  • Customizing your statistics


Export to Database dialog

You can save MobiLink Monitor data to any consolidated database supported by MobiLink, or to Excel spreadsheets using the Export to Database dialog. You must be disconnected from the MobiLink synchronization server when you export data from the Monitor.

Note
The data source must have quoted identifiers enabled because some of the columns are reserved words. The MobiLink Monitor enables quoted identifiers automatically for Adaptive Server Anywhere, Adaptive Server Enterprise, and Microsoft SQL Server databases. If quoted identifiers is not enabled, the export will fail.

For more information about quoted identifiers, see Character strings and quotation marks and QUOTED_IDENTIFIER option [compatibility].

The Export to Database dialog has the following components:

Master table Type a name for the master table created to hold Monitor data. The table name must be 128 characters or less. If the table does not exist, it will be created by the Monitor. For Excel output, the table name identifies the worksheet that is created.

This table contains one row per synchronization, including all the information that can appear in the Monitor's Details Table pane, as well as an export_time column that contains the time the export was performed. Its primary key consists of the export_time and sync columns. By default this table is called mlm_by_sync.

Details table Type a name for the details table created to hold Monitor data. The table name must be 128 characters or less. By default this table is called mlm_by_table. If the table does not exist, it will be created by the Monitor. For Excel output, the table name identifies the worksheet that is created.

This table contains one row per table per synchronization, and has a column for each of the upload, download, and synchronization statistics that appear on the Synchronization property sheet in the Monitor, as well as an export_time column that contains the time the export was performed. The details table has a foreign key relationship to the master table's export_time and sync columns. The primary key for the details table consists of the export_time, sync, and table_name columns.

Overwrite any existing data Select this option if you want to overwrite data in existing tables. If you do not choose to overwrite the data, new data is appended to existing data.

See also
  • Saving Monitor data
  • Synchronization property sheet


Options dialog

The Options dialog consists of four tabs: General, Chart Layout, Chart Colors, and Overview.

To restore the Monitor's default settings, delete the file .mlMonitorSettings. This file is stored in your user profiles directory.


Options dialog: General tab

The General tab of the Options dialog has the following components:

Prompt to connect on startup This option controls whether the Connect To MobiLink Server dialog appears when the MobiLink Monitor is started. By default, this option is selected, which means that when the Monitor is started without any command-line options, the Connect To MobiLink Server dialog appears. If you do not want the Connect To MobiLink Server dialog to appear when you start the Monitor without command-line options, clear the checkbox beside this option.

Max synchronization count This is the maximum number of synchronizations that are kept in the current session. The default maximum synchronization count is 100 000. Once the limit is reached, you can choose to replace the oldest synchronizations with new ones by selecting the Replace Old Synchronizations With New Ones option.

Replace old synchronizations with new ones This option controls whether new synchronizations replace the oldest or newest synchronizations in the session when the monitor reaches the maximum synchronization count for the current session. This option is selected by default, meaning that new synchronizations replace the oldest synchronizations in the session.

Save automatically when connected to MobiLink server Select this option to save Monitor sessions automatically to a file when the Monitor is connected to a MobiLink synchronization server. The setting for this option takes effect the next time the MobiLink Monitor connects to a synchronization server. It does not change the setting for current connections. Data from the Monitor session is saved as a binary file (.mlm) by default. Selecting this option enables the Output File and Save Every fields. When this option is selected for a connection, the Monitor starts saving session information when it connects to a MobiLink synchronization server and stops saving information when it disconnects. The data contained in the output file is overwritten by new data for each time the Monitor connects to a MobiLink synchronization server.

  • Output file Type the name of the binary file (with the extension .mlm) where you want to save the current session automatically. You can also click Browse to locate the file.

    If you want to view the data in another tool, such as Microsoft Excel, you must save the data in a comma-separated file (.csv) by choosing File > Save As.

    If you supply an extension to the file name, it must be .mlm or .csv. These are the only file formats the MobiLink Monitor supports.

  • Save every Specify how often you want the data saved to the file specified above. By default, the output file is saved every 120 seconds.

Note

To restore the Monitor's default settings, delete the file .mlMonitorSettings. This file is stored in your user profiles directory.


Options dialog: Table tab

This tab lets you configure the columns that appear in the Details Table pane. The settings on this tab persist between MobiLink Monitor sessions.

The Table tab of the Options dialog has the following components:

Hidden Columns Lists all the columns that can appear in the Details Table pane that are not currently visible in the pane. To display a column in the Details Table pane, select the column or columns in the Hidden Columns list and click the right arrow. The selected column or columns appear in the Visible Columns list.

Visible Columns Lists all the columns that currently appear in the Details Table pane. To remove a column from the Visible Columns list so that it no longer appears in the Details Table pane, click the left arrow. Columns that are added to the Visible Columns list are added to the end of the list.

The order of the columns in the Visible Columns list determines the order of the columns in the Details Table pane. To move a column up the list, select the column and click the up arrow. To move a column further down the list, select the column and click the down arrow.

Tip
You can also change the order of the columns by dragging the column headings in the Details Table pane.

Reset Click Reset to restore the list of columns that appear in the Details Table pane to its default settings.

See also
  • Details Table pane


Options dialog: Chart Layout tab

This tab lets you configure the appearance and behavior of the Chart pane.

The Chart Layout tab of the Options dialog has the following components:

Minimum synchronization bar height Specifies the minimum display height for synchronization bars. Together with the Vertical Gap Between Synchronization Bars option, this determines the threshold for the Chart pane to have a vertical scroll bar.

The default minimum height of synchronization bars in the Chart pane is 5 pixels.

Vertical gap between synchronization bars Specifies how much relative vertical space should appear between synchronization bars in the Chart pane.

The default gap size between synchronization bars in the Chart pane is 150%.

Show horizontal chart ruler Select this option if you want to see the chart ruler showing the synchronization time. This option is selected by default.

Show vertical chart ruler Select this option if you want to see the chart ruler showing the data grouped by worker thread or synchronization user. This option is selected by default. You can choose whether you want the data grouped by worker thread or synchronization user from the View menu.

Scroll chart automatically when connected Select this option if you want the chart to scroll automatically when you are connected to a MobiLink synchronization server. This option is selected by default.

If you want to see the complete date and time in the Chart pane, hover your cursor over the ruler.

Note

To restore the Monitor's default settings, delete the file .mlMonitorSettings. This file is stored in your user profiles directory.


Options dialog: Chart Colors tab

This tab lets you specify the colors used in the Chart pane.

The default color scheme for the Chart pane uses green for uploads, red for downloads, and blue for begin and end phases. A darker shade indicates earlier parts of a phase.

The Chart Colors tab of the Options dialog has the following components:

Verify upload By default, the verify upload phase is Gold.

Preload upload By default, the preload upload phase is Dark Green.

Begin synchronization By default, the begin synchronization phase is Ocean Blue.

Upload By default, the upload phase is Lime Green.

Prepare for download By default, the prepare for download phase is Dark Red.

Download By default, the download phase is Coral.

End synchronization By default, the end synchronization phase is Periwinkle.

Selected sync outline By default, the outline for a selected synchronization is Black.

Sync outline By default, synchronizations are outlined in Gray.

Chart background By default, the background of the Chart pane is White.

Note

To restore the Monitor's default settings, delete the file .mlMonitorSettings. This file is stored in your user profiles directory.


Options dialog: Overview tab

The Overview tab of the Options dialog has the following components:

Keep overview window attached to main window Clear this checkbox if you want the Overview pane to be detached from the Chart pane.

Vertical gap between synchronization bars Specifies the relative size of the vertical gap that appears between synchronization bars in the Overview pane. The default size is 25%.

Colors for built-in watches Use the dropdown boxes to choose the colors used to identify the components of predefined watches.

  • Active synchronizations Select a color to identify synchronizations that are still active. By default, active synchronizations are Light Gray. You can also set the color for active synchronizations in the Edit Watch dialog.

  • Completed synchronizations Select a color to identify synchronizations that have completed. By default, completed synchronizations are Light Gray. You can also set the color for completed synchronizations in the Edit Watch dialog.

  • Failed synchronizations Select a color to identify failed synchronizations. By default, failed synchronizations are Red. You can also set the color for failed synchronizations in the Edit Watch dialog.

Chart region outline Select a color for the outline that is used to select synchronizations you want to appear in the Chart pane. By default, the chart outline is Black.

Overview background Select a background color for the Overview pane. By default, the background is White.

Note

To restore the Monitor's default settings, delete the file .mlMonitorSettings. This file is stored in your user profiles directory.


Session property sheet

The Session property sheet consists of one tab: General.

Session property sheet: General tab


Session property sheet: General tab

The General tab of the Session property sheet has the following components:

Name The name of the file to which the session is saved. You name the session when you save it to a file (this can be done on the General tab of the Options dialog). If the session is not saved to a file, a name does not appear for the session.

Number of workers The number of MobiLink worker threads.

Number of synchronizations The total number of synchronizations in the session.

Replaced synchronizations The number of synchronizations that have been replaced because of the maximum synchronization count. You can change the maximum synchronization count on the General tab of the Options dialog.

Monitor session started The date and time when the session started. If you opened a .csv file, this is the start time of the first synchronization.

Monitor session ended The date and time when the session ended. If you opened a .csv file, this is the end time of the last synchronization.

Monitor session duration The total length of the session. If you have opened a .csv file, this is the time between the start of the first synchronization and the last synchronization.


Synchronization property sheet

The Synchronization property sheet consists of four tabs: General, Upload, Download, and Synchronization.

Synchronization property sheet: General tab
Synchronization property sheet: Upload tab
Synchronization property sheet: Download tab
Synchronization property sheet: Synchronization tab


Synchronization property sheet: General tab

The General tab of the Synchronization property sheet has the following components:

Overall Synchronization Statistics These statistics provide general information about the selected synchronization.

  • Sync A unique number assigned to each synchronization within a session by the MobiLink Monitor.

  • Worker thread The MobiLink worker thread used for the synchronization in the form n.m, where n is the stream number and m is the thread number.

  • User The name of MobiLink client.

  • Version The name of the synchronization version.

  • Start time Date-time (in ISO-8601 extended format) for the start of the synchronization. The format will be either YYYY-MM-DD hh:mm:ss.sss or YYYY-MM-DD hh:mm:ss,sss, depending on your locale setting.

    This time may be later than when the synchronization was requested by the client.

  • End time Date-time (in ISO-8601 extended format) for the end of the synchronization. The format will be either YYYY-MM-DD hh:mm:ss.sss or YYYY-MM-DD hh:mm:ss,sss, depending on your locale setting.

  • Active Yes if the synchronization is in progress, otherwise no.

  • Completed Yes if the synchronization completed successfully, otherwise no.

Synchronization Phase Statistics These statistics provide information about each phase of the synchronization.

  • Verify upload The time required to verify the synchronization protocol and authenticate the synchronization client.

  • Preload upload The time required for the transfer of the upload data from the client to the MobiLink synchronization server.

  • Begin synchronization The time required for the begin_synchronization event.

  • Upload The time required for the uploaded data to be applied to the consolidated database.

  • Prepare for download The time required for the prepare_for_download event.

  • Download The time required for data to be fetched from the consolidated database and downloaded to the remote database.

  • End synchronization The time required for the end_synchronization event.

See also
  • MobiLink statistical properties


Synchronization property sheet: Upload tab

The Upload tab of the Synchronization property sheet has the following components:

Statistics for You can choose to view upload statistics for all the tables that were synchronized or for individual tables. If you have opened a .csv file, you cannot view statistics for individual tables.

Number of warnings Total number of warnings that occurred for the upload.

Number of errors Total number of errors that occurred for the upload.

Inserted rows Number of row insertions that were uploaded from the synchronization client.

Deleted rows Number of row deletions that were uploaded from the synchronization client.

Updated rows Number of row updates that were uploaded from the synchronization client.

Conflicted inserts Number of uploaded inserts for which conflicts were detected.

Conflicted deletes Number of uploaded deletes for which conflicts were detected.

Conflicted updates Number of uploaded updates for which conflicts were detected.

Ignored inserts Number of uploaded inserts that were ignored.

Ignored deletes Number of uploaded deletes that were ignored.

Ignored updates Number of uploaded updates that were ignored.

Total bytes Total number of bytes uploaded from the synchronization client.

Deadlocks Number of deadlocks in the consolidated database that were detected during the upload.

Total rows Total number of rows uploaded from the synchronization client.

See also
  • MobiLink statistical properties


Synchronization property sheet: Download tab

The Download tab of the Synchronization property sheet has the following components:

Statistics for You can choose to view download statistics for all the tables that were synchronized or for individual tables. If you have opened a .csv file, you cannot view statistics for individual tables.

Number of warnings Number of warnings that occurred during the download.

Number of errors Number of errors that occurred during the download.

Rows fetched Number of rows fetched from the consolidated database by the MobiLink synchronization server (using download_cursor scripts).

Rows for delete Number of row deletions fetched from the consolidated database by the MobiLink synchronization server (using download_delete_cursor scripts).

Filtered rows Number of fetched rows that were not downloaded to the MobiLink client because they matched rows that the client uploaded.

Total bytes Bytes downloaded to the synchronization client.

Total rows Total number of rows downloaded to the synchronization client.

See also
  • MobiLink statistical properties


Synchronization property sheet: Synchronization tab

The Synchronization tab of the Synchronization property sheet has the following components:

Statistics for You can choose to view synchronization statistics for all the tables that were synchronized or for individual tables. If you have opened a .csv file, you cannot view statistics for individual tables.

Number of warnings Total number of warnings that occurred for the synchronization.

Number of errors Total number of errors that occurred for the synchronization.

Deadlocks Total number of deadlocks that occurred for the synchronization.

Number of tables Number of client tables that were involved in the synchronization.

Connection retries Number of times the MobiLink synchronization server retried the connection to the consolidated database.

See also
  • MobiLink statistical properties


Watch Manager dialog

The Watch Manager allows you to visibly distinguish synchronizations that meet criteria you specify, such as synchronizations that receive warnings or take a long time.

The Watch Manager dialog has the following components:

Available watches This pane lists all available watches. There are three predefined watches: Active, Completed, and Failed. When you create a new watch, it is added to this list of watches.

  • New Opens the New Watch dialog where you can create a new watch.

  • Edit Opens the Edit Watch dialog where you can add or remove watch conditions and configure the synchronization display of the selected watch. You can edit any watch in the Available Watches list. For the predefined watches (Active, Completed, and Failed), you can only change the Chart pattern and overview color.

  • Delete Deletes the selected watch from the Available Watches pane.

Current watches Lists the watches that are active in order of their precedence. These watches can be edited to change the way they display, and you can deactivate them by removing them from the Current Watches pane.

The order of watches in the Current Watches pane is important. Watches that are closer to the top of the list are processed first. You can use the Move Up and Move Down buttons to organize the order of the watches in the Current Watches pane.

  • Move Up Moves the selected watch up one position in the list in the Current Watches pane.

  • Move Down Moves the selected watch down one position in the list in the Current Watches pane.

Add Adds the watch selected in the Available Watches pane to the list of Current Watches.

Remove Removes the selected watch from the list of Current Watches.

Add All Adds all the available watches to the Current Watches pane.

Remove All Removes all the watches from the Current Watches pane.

See also
  • Customizing your statistics


Query Editor Help

About this chapter

This section describes the Query Editor, which is a tool for building and editing SQL queries.

Introducing the Query Editor
Tables tab
Joins tab
Columns tab
INTO tab
WHERE tab
GROUP BY tab
HAVING tab
ORDER BY tab
Expression Editor
Results pane
SQL pane


Introducing the Query Editor

The Query Editor is a tool that helps you build Adaptive Server Anywhere SELECT statements. You can create SQL queries in the Query Editor, or you can import queries and edit them. When you have finished your query, click OK to export it back into Interactive SQL for processing.

The Query Editor provides a series of tabs that guide you through the components of a SQL query, most of which are optional. The tabs are presented in the order that SQL queries are usually built:

  • Tables tab Use this tab to specify the tables in your query.

  • Joins tab Use this tab to specify a join strategy for combining the data in the tables. If you include more than one table in your query, you should specify a join strategy for combining the data in the tables. If you do not specify a join strategy for tables you added in the Tables tab, the Query Editor suggests one; if there is a foreign key relationship between the tables, it generates a join condition based on that relationship, or it suggests a cross product. When you import queries, the Query Editor accepts exactly the join strategy that you have specified (and an unspecified JOIN is not defaulted to KEY JOIN, as it would be otherwise in Adaptive Server Anywhere).

  • Columns tab Use this tab to specify the columns in your result set. If you do not specify columns, all columns appear.

  • INTO tab Use this tab if you want to return results as procedure parameters.

  • WHERE tab Use this tab if you want to specify conditions for restricting the rows in your result set.

  • GROUP BY tab Use this tab if you want to group rows in the result set.

  • HAVING tab Use this tab to restrict the rows in your result set based on group values.

  • ORDER BY tab Use this tab if you want to sort the rows.

The Query Editor also contains

  • Expression Editor Use the Expression Editor to build search conditions or define computed columns.

  • Derived table or subquery dialog Use this dialog, which is nearly identical to the main Query Editor, to create derived tables and subqueries.

Each component of the Query Editor has context-sensitive online help that describes how to use the tab, and provides links into the Adaptive Server Anywhere documentation that explains relevant concepts and usage.

Using the Query Editor

To open the Query Editor, open Interactive SQL, connect to a database, and click Tools > Edit Query. If you have SQL code selected in Interactive SQL, the selected code is automatically imported into the Query Editor.

When you finish creating a query in the Query Editor, click OK to write the query to the Interactive SQL Statements pane.

You do not need to use SQL code to create queries with the Query Editor. However, you can use SQL with the Query Editor in the following ways:

  • You can create a query in the SQL Statements pane in Interactive SQL, and import it into the Query Editor by highlighting the code before you open the editor.

  • At any time while using the Query Editor, you can click SQL at the bottom of the dialog to see the SQL code for the query you are building. You can directly edit the code, and the fields are automatically updated in the Query Editor user interface. You will notice that this SQL looks a little different from the SQL you normally write. This SQL is fully formed, meaning that all tables are prefixed with owner name, all strings are enclosed in quotation marks, and so on. This extra formatting is not normally necessary, but it ensures that the SQL will work in all situations.

Query Editor limitations

The Query Editor builds Adaptive Server Anywhere SELECT statements. It is not designed to create views, although you can create them in Interactive SQL and reference them in the Query Editor. Nor was it designed to create update statements or other non-SELECT SQL statements. It creates a single SELECT statement, so it does not build unions or intersects of SELECT statements. In addition, the Query Editor does not support Transact-SQL syntax.

More information

  • For an introduction to selecting data, see Selecting Data from Database Tables.

  • For reference documentation, see SELECT statement.

  • For more information about selecting data, see Queries: Selecting Data from a Table.


Tables tab

Use the Tables tab to select the tables, derived tables, and views you want to include in your query. You can create derived tables using the Create a Derived Table button. You cannot create views in the Query Editor, but you can create them in Interactive SQL and reference them in the Query Editor.

Include tables that you want to get data from, and tables that you want to include in joins. If you include more than one table or view in your query, you should use the Joins tab to specify how the tables are to be joined.

Warning: If you are including more than one table in your query, and the tables are large, you should define a join strategy on the Joins tab after adding each table. The processing can become very slow if you do not change the join strategy because the Query Editor sometimes has to default to a cross product and the Query Editor processes your query as you work.

Dialog components

Table pattern To restrict the tables in the Matching Tables box, type the name or partial name of tables. You can use wildcard characters in the pattern. For example, to get only tables starting with SYS, type SYS%.

For more information about using wild cards in the table pattern, see LIKE conditions.

Owner pattern To restrict the tables in the Matching Tables box, type the name or partial name of an owner. You can use wildcard characters in the pattern. For example, to get only tables starting with SYS, type SYS%.

For more information about using wild cards in the owner pattern, see LIKE conditions.

Table type To restrict the tables in the Matching Tables box, choose a type of table from the dropdown list. For example, you can choose to view only system tables.

Matching tables This lists all the tables in the database that match the criteria above. The default is all tables.

Selected tables To add a table to your query, select a table in the Matching Tables box and click the right arrow. The table appears in the Selected Tables box. To create a derived table for your query, click the middle icon (between the two arrows). If you add more than one table, you should use the Joins tab to specify a join strategy. When you add tables to your query by specifying them in the Selected Tables box, they are joined by default as cross products.

Results Click Results at the bottom of the dialog to see the results of your query, or an error message if the query contains errors.

SQL Click SQL at the bottom of the dialog to see the SQL code for your query. You will notice that this SQL looks a little different from the SQL you normally write. This SQL is fully formed, meaning that all tables are prefixed with owner name, all strings are enclosed in quotation marks, and so on. This extra formatting is not normally necessary, but it ensures that the SQL will work in all situations.

About views and derived tables

You can add views and derived tables to your query, as well as tables.

A view is a SELECT statement that is stored in the database as an object. You cannot create views in the Query Editor, but you can create them in Interactive SQL and enter them as tables in the Query Editor.

You can create derived tables in the Query Editor. Derived tables allow you to nest queries within a FROM clause. With derived tables, you can perform grouping of groups, or you can construct a join with a group, without having to create a view.

More information

  • For more information about the Query Editor, see Introducing the Query Editor.

  • For an introduction to specifying tables, see The FROM clause: specifying tables.

  • For reference information about specifying tables, see FROM clause.

  • For reference information about derived tables, see FROM clause.

  • For an introduction to subqueries, see Selecting Data Using Subqueries.

  • For more information about subqueries, see Subqueries in search conditions.


Joins tab

Use this tab if you have more than one table in your query.

When you include more than one table in a query, the tables must somehow be joined. This tab allows you to define your joins.

Default joins

When you specify tables in the Tables tab, the Query Editor tries to generate a default join condition. It does this for two reasons. First, the Query Editor processes the query as you create it. If there is no default join, the tables create a cross product, and this can result in slow processing. Secondly, the Query Editor suggests a join strategy that might work for you.

If you add tables in the Query Editor Tables tab, the Query Editor checks to see if a foreign key relationship has been created between the tables. If there is one foreign key, it uses it to generate an ON condition. If there is more than one foreign key relationship, it uses the first one it finds. If there are no foreign keys, it does not generate an ON clause and the tables become a cross product.

You can always review your query by clicking the SQL tab, which is located at the bottom of the Query Editor dialog. You can edit your join strategy directly on the SQL tab, or you can use the Joins tab user interface to change it.

For more information about key joins, ON conditions, and cross products, see Joins: Retrieving Data from Several Tables.

Tip: All the fields in the Joins tab are resizable. You can also expand the Query Editor by pulling on its edges. You may need to resize the fields and dialog in order to read your table names.

Dialog components

Left table expression Select a table from the dropdown list. Only tables that have been entered in the Tables tab are available. Placing a table on the right or left is significant for outer joins.

Join type Select a join type from the dropdown list.

For information about join types, see Joined tables.

Right table expression Select a table from the dropdown list. Only tables that have been entered in the Tables tab are available. Placing a table on the right or left is significant for outer joins.

Condition Double-click to create an ON condition, if desired. The Query Editor inserts the keyword ON. For key joins and natural joins, the ON condition is generated by Adaptive Server Anywhere.

For information about ON conditions, see Explicit join conditions (the ON phrase).

Add/Delete Use to add or delete lines. Click the gray circle to the left of the line to select the line.

You must delete blank lines. This does not affect the tables in your query: to add or delete a table, use the Tables tab.

Results This pane displays the results of your query, or an error message if the query contains errors.

SQL Click SQL at the bottom of the dialog to see the SQL code for your query.

Using the joins tab

When you add more than one table to a query, the Query Editor attempts to create a default join strategy. If it cannot find a foreign key relationship between the tables, the default is a cross product. In most cases, cross products are not desirable.

To add or edit the join strategy, choose a table, a join type, and another table, all from the dropdown lists. Alternatively, click the SQL tab and edit the code directly.

Troubleshooting

If you receive an error message indicating that your join is not correct, click the SQL tab at the bottom of the window to review the SQL code. It may happen that empty quotation marks or extra commas have been inserted in your code, particularly if you have added and deleted lines on the Join tab. For example, the following query produces an error message. You need to delete the empty quotes that appear after sales_order:

FROM ("DBA"."customer"
   JOIN "DBA"."sales_order")""
     JOIN "DBA"."sales_order_items"
More information

  • For more information about the Query Editor, see Introducing the Query Editor.

  • For an introduction to joins, see Selecting Data from Multiple Tables.

  • For more information about joins, see Joins: Retrieving Data from Several Tables.


Columns tab

Use this tab to restrict the columns that appear in your result set. You can specify columns, column aliases, computed columns, or subqueries. You specify subqueries using the Expression Editor.

Dialog components

Available columns This box lists all the tables you have chosen for your query, and the columns in each table.

Selected columns By default, all columns are selected for your query. To delete a column, select it in the Selected Columns box and click the left arrow. To display a column in your result set, select a column or set of columns in the Available Columns box and click the right arrow. Use the up and down arrows to scroll through the columns in the Selected Columns box.

If you select the same column more than once, an alias is applied. You can edit the alias name.

DISTINCT Select DISTINCT if you want to eliminate duplicate rows from your result set.

Note: Many statements take significantly longer to execute when DISTINCT is specified, so you should reserve DISTINCT for cases where it is necessary. In addition, DISTINCT treats nulls as duplicates, so when you select DISTINCT, only one null is returned in the results.

Limit rows You can choose to retrieve only the first row of the result set, or only the number of rows that you specify. No matter what you choose, the maximum number of rows that appear in the Query Editor is 25.

Results Click Results at the bottom of the dialog to see the results of your query, or an error message if the query contains errors.

SQL Click SQL at the bottom of the dialog to see the SQL code for your query.

Adding a subquery

To add a subquery in the Query Editor, click the Add a Computed Column button, which is located between the lists of columns. The Expression Editor appears. In the Expression Editor, click the Subquery button, which is located beside the Not button.

More information

  • For more information about the Query Editor, see Introducing the Query Editor.

  • For an introduction to columns, see Lesson 5: Design column properties.

  • For information about selecting columns, see The SELECT list: specifying columns.

  • For more information about creating subqueries, see Expression Editor.


INTO tab

Use this tab if you want to return results as procedure parameters.

Dialog components

Include INTO variables Select this option if you want to edit the variable names in the INTO variables column.

Selected columns This box lists all the columns you have chosen for your query.

INTO variables This is a list of variables to receive the value for each select list item. You can type the variable names directly into the fields.

Results Click Results at the bottom of the dialog to see the results of your query, or an error message if the query contains errors.

SQL Click SQL at the bottom of the dialog to see the SQL code for your query.

About INTO

INTO is used in procedures and triggers only. It specifies where the result set goes. There must be one variable for each column.

More information

  • For more information about the Query Editor, see Introducing the Query Editor.

  • For more information about INTO, see Returning results as procedure parameters.


WHERE tab

Use this tab to restrict the rows in your result set.

Dialog components

Criteria Use the Criteria pane to enter your WHERE conditions. You can type directly into this pane, or use the Expression Editor. To edit existing expressions, highlight the expression before you open the Expression Editor. Otherwise, what you create in the Expression Editor is appended to previously existing expressions.

Expression Editor Click the Calculator icon, located in the bottom right of the Criteria pane, to open the Expression Editor and build your WHERE condition.

Results Click Results at the bottom of the dialog to see the results of your query, or an error message if the query contains errors.

SQL Click SQL at the bottom of the dialog to see the SQL code for your query.

More information

  • For more information about the Query Editor, see Introducing the Query Editor.

  • For an introduction to search conditions, see Selecting rows from a table.

  • For more information about search conditions, see Search conditions.


GROUP BY tab

Use this tab if you want to group rows in the result set.

Dialog components

Available columns This box lists all the tables you have chosen for your query, and the columns in each table.

GROUP BY columns To group by a column, select a column or set of columns in the Available Columns box and click the right arrow. To delete a column, select it in the GROUP BY Columns box and click the left arrow. Use the up and down arrows to scroll through the columns in the GROUP BY Columns box.

Expression Editor Click the Calculator icon, located between the right and left arrows, to open the Expression Editor and build your GROUP BY condition.

CUBE button Click this button to create a CUBE operation query. CUBE adds subtotal rows into the result sets of queries with GROUP BY clauses, providing all possible combinations of the variables specified in the query.

ROLLUP button Click this button to create a ROLLUP operation query. ROLLUP adds subtotal rows into the result sets of queries with GROUP BY clauses.

Set button Click this button to create a concatenated grouping sets operation query. Like ROLLUP and CUBE, this operation adds subtotal rows into the result sets of queries with GROUP BY clauses.

GROUPING SETS check box Enable this check box to add GROUPING SETS to a query.

Results Click the Results tab at the bottom of the dialog to see the results of your query, or an error message if the query contains errors.

SQL Click the SQL tab at the bottom of the dialog to see the SQL code for your query.

About GROUP BY conditions

You can group by columns, alias names, or functions. The result of the query contains one row for each distinct set of values in the named columns, aliases, or functions. All null-containing rows are treated as a single set. The resulting rows are often referred to as groups since there is one row in the result for each group of rows from the table list. Aggregate functions can then be applied to these groups to get meaningful results.

When GROUP BY is used, the Columns tab, HAVING tab, and ORDER BY tab must not reference any identifier that is not named in the GROUP BY tab. The exception is that the Columns tab and HAVING tab may contain aggregate functions.

More information

  • For more information about the Query Editor, see Introducing the Query Editor.

  • For an introduction to GROUP BY, see Applying aggregate functions to grouped data.

  • For more information about GROUP BY, see The GROUP BY clause: organizing query results into groups.

  • For more information about ROLLUP, see Using ROLLUP.

  • For more information about CUBE, see Using CUBE.

  • For more information about GROUPING SETS, see Using GROUPING SETS.


HAVING tab

Use this tab to restrict the rows in your result set based on group values.

Dialog components

Criteria Use the Criteria pane to enter your HAVING conditions. You can type directly into this pane, or use the Expression Editor. To edit existing expressions, highlight the expression before you open the Expression Editor. Otherwise, what you create in the Expression Editor is appended to previously existing expressions.

Expression Editor Click the Calculator icon, located in the bottom right of the Criteria pane, to open the Expression Editor and build your HAVING condition.

Results Click Results at the bottom of the dialog to see the results of your query, or an error message if the query contains errors.

SQL Click SQL at the bottom of the dialog to see the SQL code for your query.

About HAVING conditions

HAVING conditions can only be used if either the statement has a GROUP BY clause or the selected columns in the Columns tab include only aggregate functions. Any column names referenced in the HAVING clause must either be in the GROUP BY clause or be used as a parameter to an aggregate function in the HAVING clause.

More information

  • For more information about the Query Editor, see Introducing the Query Editor.

  • For an introduction to HAVING, see Applying aggregate functions to grouped data.

  • For more information about HAVING, see The HAVING clause: selecting groups of data.


ORDER BY tab

Use this tab to sort the rows in your result set.

Dialog components

Available columns This box lists all the tables you have chosen for your query, and the columns in each table. It also lists any computed columns that you defined in the Columns tab.

ORDER BY columns This box stores the columns you have chosen to sort on. To sort on a column, select a column or set of columns in the Available Columns box and click the right arrow. To delete a column, select it in the ORDER BY Columns box and click the left arrow. Use the up and down arrows to specify the order of column evaluation. You can sort on column aliases.

Expression Editor Click the Calculator icon, located between the right and left arrows, to open the Expression Editor and build your Order By condition.

Results Click Results at the bottom of the dialog to see the results of your query, or an error message if the query contains errors.

SQL Click SQL at the bottom of the dialog to see the SQL code for your query.

About ORDER BY conditions

Each item in the ORDER BY list can be labeled as an up arrow for ascending order (the default) or a down arrow for descending order. To change the order from ascending to descending, double-click the arrow. Alternatively, you can select the arrow and press F2.

The only way to ensure that rows are returned in a particular order is to use ORDER BY. In the absence of an ORDER BY clause, Adaptive Server Anywhere returns rows in whatever order is most efficient. This means that the appearance of result sets may vary depending on when you last accessed the row and other factors.

More information

  • For more information about the Query Editor, see Introducing the Query Editor.

  • For an introduction to ORDER BY, see Ordering query results.

  • For more information about ORDER BY, see The ORDER BY clause: sorting query results and Sorting query results.


Expression Editor

The Expression Editor helps you create search conditions, computed columns, and subqueries. To edit existing expressions, highlight the expression before you open the Expression Editor. Otherwise, what you create in the Expression Editor is appended to previously existing expressions when you click OK.

Dialog components

Expression This is where you build your expression.

Columns This box lists the columns that are in your query. To insert a column into your expression, double-click it here, or type it directly into the Expression box.

Functions Functions are predefined expressions used to return information about the database. To insert a function into your expression, choose it from the dropdown list.

For information about functions, see SQL Functions.

Stored Procedures This box lists the stored procedures that you can use.

Numeric keypad The numeric keypad is located in the bottom left section of the dialog. Click a number to insert it into the expression. You can also type numbers from your keyboard.

Comparison operators These arithmetic symbols, such as =, appear in the middle of the bottom section of the dialog. Click a symbol to insert it into the expression. Only a subset of common operators are included here, but you can type others from your keyboard.

For information about comparison operators, see Comparison operators.

Logical operators Logical operators, such as AND, appear in the right bottom section of the dialog. Click an operator to insert it into the expression. This group is a subset of commonly used logical operators. You can use any logical operator by typing it from your keyboard.

For information about logical operators, see Logical operators.

Create a subquery button The subquery button is located with the logical operators. Click it to access a dialog that guides you in creating subqueries.

Adding a subquery

To create a subquery, open the Expression Editor and click the Subquery button (located next to the NOT button). This opens the Subquery dialog, which looks identical to the main Query Editor except that the words Subquery are in the title bar. You create a subquery just as you create a main query.

Editing a subquery

To edit a subquery in the Query Editor, highlight the subquery in the Criteria box, and click the Expression Editor button. Highlight the code in the Expression Editor, and click the Subquery button.

More information

  • For more information about the Query Editor, see Introducing the Query Editor.

  • For an introduction to search conditions, see Selecting rows from a table.

  • For more information about search conditions, see Search conditions.

  • For an introduction to subqueries, see Selecting Data Using Subqueries.

  • For more information about subqueries, see Subqueries in search conditions.


Results pane

This pane shows you your result set or an error message. By default, you get only the first 25 rows of your result set. To see the entire result set, export your query back to Interactive SQL by clicking OK.

More information

  • For more information about the Query Editor, see Introducing the Query Editor.

  • For a complete list of error messages, see ASA Error Messages.


SQL pane

This pane shows you the SQL code as it is developed. You can directly edit the code, and the fields are automatically updated in the Query Editor user interface.

You will notice that this SQL looks a little different from the SQL you normally write. This SQL is fully formed, meaning that all tables are prefixed with owner name, all strings are enclosed in quotation marks, and so on. This extra formatting is not normally necessary, but it ensures that the SQL will work in all situations.

More information

  • For more information about the Query Editor, see Introducing the Query Editor.


Adaptive Server Anywhere Console Utility Help

About this chapter

This chapter contains help for the Adaptive Server Anywhere Console (dbconsole) utility.


Using the Adaptive Server Anywhere Console utility

The Adaptive Server Anywhere Console utility provides administration and monitoring facilities for database server connections. The Adaptive Server Anywhere Console utility is available on all operating systems.

For more information about the Adaptive Server Anywhere Console utility, see The Adaptive Server Anywhere Console utility.


Options dialog

You can configure the Adaptive Server Anywhere Console utility using the Options dialog.

The Adaptive Server Anywhere Console utility Options dialog consists of five tabs: Console, Connection Viewer, Message Viewer, Property Viewer, and Check For Updates.


Console options

You can set the following options for the Adaptive Server Anywhere Console utility:

Disable new connections Select this option to prevent other users from connecting to the database. The may be useful for some maintenance operations.

Enable request logging Select this option to record requests that the server processes to the log file. This option is primarily for troubleshooting purposes.

For more information, see -zr server option.

Remember last statement Select this option to instruct the database server to capture the most recently-prepared SQL statement for each connection to databases on the server. For stored procedure calls, only the outermost procedure call appears, not the statements within the procedure.

For more information, see -zl server option.

Idle client shutdown time Select this option to disconnect connections that have not submitted a request for the amount of time specified in the adjacent field. By default, this value is 120 seconds.

Quitting time You can type a time when the database server is to shut down. Use the same format as the current time, which is as follows:

YYYY-MM-DD HH:NN:SS.SS

Current time Displays the current time.

Log messages to file Select this option to log server messages to a file that you specify in the field below. You can click Browse to locate a file to which server messages are logged.

See also
  • sa_server_option system procedure
  • Server-level properties


Connection Viewer

You can set the following options for the Connection Viewer:

Select which connection properties to display Shows the name and description of all connection properties. Select the connection properties you want to appear by placing a checkmark in the checkbox beside the property name.

For more information about the connection properties in this list, see Connection-level properties.

Refresh rate Type a time to specify how often the values are refreshed for selected properties. By default, values are refreshed every 4 seconds.


Message Viewer

Setting these options configures the Message Viewer in all places it can be viewed, including the Messages Pane in the Adaptive Server Anywhere Console utility, and the Design Details pane in Sybase Central.

You can set the following options for the Message Viewer:

Messages only Select if you only want messages to appear in the Message Viewer.

Time and messages Select this option if you want the date and time for each message to appear in the Message Viewer.

Refresh rate Type a time to specify how often the values are refreshed for selected properties. By default, values are refreshed every 4 seconds.


Property Viewer

You can set the following options for the Property Viewer:

Database Properties

You can set the following options for database properties:

Select which database properties to display Shows the name and description of all database properties. Select the database properties you want to appear by placing a checkmark in the checkbox beside the property name.

For more information about database properties, see Database-level properties.

Refresh rate Type a time to specify how often the values are refreshed for selected properties. By default, values are refreshed every 4 seconds.

Server Properties

You can set the following options for server properties:

Select which server properties to display Shows the name and description of all database server properties. Select the database server properties you want to appear by placing a checkmark in the checkbox beside the property name.

For more information about server properties, see Server-level properties.

Refresh rate Type a time to specify how often the values are refreshed for selected properties. By default, values are refreshed every 4 seconds.


Check For Updates

You can configure whether the Adaptive Server Anywhere Console utility should check for software updates and how often it should do so. Checking for updates is done on application startup.

You can check for updates any time from the Start menu by choosing Programs > SQL Anywhere 9 > Check For Updates and from the Sybase Central, Interactive SQL, and Console utility Help menus.

The Check For Updates tab of the Options dialog in the Adaptive Server Anywhere Console utility has the following components:

When to check for updates Choose one of the following options to specify how often the Adaptive Server Anywhere Console utility should check for updates. By default, Never is selected.

  • On application startup Select this option if you want the Adaptive Server Anywhere Console utility to check for updates each time it is launched.

  • Daily Select this option if you want the Adaptive Server Anywhere Console utility to check for updates the first time it is started each day.

  • Weekly Select this option if you want SQL Anywhere Studio to check for updates the first time the Adaptive Server Anywhere Console utility is started each week.

  • Monthly Select this option if you want the Adaptive Server Anywhere Console utility to check for updates the first time it is started each month.

  • Never Select this option if you do not want the Adaptive Server Anywhere Console utility to check for updates. This is the default setting.

What to check for Choose any combination of the following options to specify what types of updates the Adaptive Server Anywhere Console utility should check for. By default, all of the following options are selected.

  • Express Bug Fix Select this option if you want the Adaptive Server Anywhere Console utility to check for Express Bug Fixes.

    An express bug fix is a subset of the software with one or more bug fixes. The bug fixes are listed in the release notes for the update. Bug fix updates may only be applied to installed software with the same version number. Some testing has been performed on the software, but the software has not undergone full testing. You should not distribute these files with your application unless you have verified the suitability of the software yourself.

  • Maintenance Release Select this option if you want the Adaptive Server Anywhere Console utility to check for maintenance releases of the software.

    A maintenance release is a complete set of software that upgrades installed software from an older version with the same major version number (version number format is major.minor.patch.build). Bug fixes and other changes are listed in the release notes for the upgrade.

  • Other Information Select this option to check for other information, such as new product releases or upcoming events.


SQL Language Links

About this chapter

This chapter provides a list of SQL statements that are available to users of Adaptive Server Anywhere. It also includes links to the SQL language elements, data types, and functions supported by Adaptive Server Anywhere.

SQL syntax help


SQL syntax help

The following list provides links into the Adaptive Server Anywhere documentation for the following topics: SQL language elements, SQL statements, data types, and functions that are available to users of Adaptive Server Anywhere.

Character data types

Numeric data types

Money data types

BIT data type

Date and time data types

Binary data types

Domains

Data type conversions

Year 2000 compliance

Function types

Alphabetical list of functions

Keywords

Identifiers

Strings

Operators

Expressions

Search conditions

Special values

Variables

Comments

NULL value

Using the SQL statement reference

ALLOCATE DESCRIPTOR statement [ESQL]

ALTER DATABASE statement

ALTER DBSPACE statement

ALTER DOMAIN statement

ALTER EVENT statement

ALTER FUNCTION statement

ALTER INDEX statement

ALTER PROCEDURE statement

ALTER PUBLICATION statement

ALTER REMOTE MESSAGE TYPE statement [SQL Remote]

ALTER SERVER statement

ALTER SERVICE statement

ALTER SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]

ALTER SYNCHRONIZATION USER statement [MobiLink]

ALTER TABLE statement

ALTER TRIGGER statement

ALTER VIEW statement

ALTER WRITEFILE statement (deprecated)

BACKUP statement

BEGIN statement

BEGIN TRANSACTION statement

CALL statement

CASE statement

CHECKPOINT statement

CLEAR statement [Interactive SQL]

CLOSE statement [ESQL] [SP]

COMMENT statement

COMMIT statement

CONFIGURE statement [Interactive SQL]

CONNECT statement [ESQL] [Interactive SQL]

CREATE COMPRESSED DATABASE statement (deprecated)

CREATE DATABASE statement

CREATE DBSPACE statement

CREATE DECRYPTED FILE statement

CREATE DOMAIN statement

CREATE ENCRYPTED FILE statement

CREATE EVENT statement

CREATE EXISTING TABLE statement

CREATE EXTERNLOGIN statement

CREATE FUNCTION statement

CREATE INDEX statement

CREATE MESSAGE statement [T-SQL]

CREATE PROCEDURE statement

CREATE PROCEDURE statement [T-SQL]

CREATE PUBLICATION statement

CREATE REMOTE MESSAGE TYPE statement [SQL Remote]

CREATE SCHEMA statement

CREATE SERVER statement

CREATE SERVICE statement

CREATE STATISTICS statement

CREATE SUBSCRIPTION statement [SQL Remote]

CREATE SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]

CREATE SYNCHRONIZATION USER statement [MobiLink]

CREATE TABLE statement

CREATE TRIGGER statement

CREATE TRIGGER statement [SQL Remote]

CREATE TRIGGER statement [T-SQL]

CREATE VARIABLE statement

CREATE VIEW statement

CREATE WRITEFILE statement (deprecated)

DEALLOCATE statement

DEALLOCATE DESCRIPTOR statement [ESQL]

Declaration section [ESQL]

DECLARE statement

DECLARE CURSOR statement [ESQL] [SP]

DECLARE CURSOR statement [T-SQL]

DECLARE LOCAL TEMPORARY TABLE statement

DELETE statement

DELETE (positioned) statement [ESQL] [SP]

DESCRIBE statement [ESQL]

DISCONNECT statement [ESQL] [Interactive SQL]

DROP statement

DROP DATABASE statement

DROP CONNECTION statement

DROP EXTERNLOGIN statement

DROP PUBLICATION statement

DROP REMOTE MESSAGE TYPE statement [SQL Remote]

DROP SERVER statement

DROP SERVICE statement

DROP STATEMENT statement [ESQL]

DROP STATISTICS statement

DROP SUBSCRIPTION statement [SQL Remote]

DROP SYNCHRONIZATION SUBSCRIPTION statement [MobiLink]

DROP SYNCHRONIZATION USER statement [MobiLink]

DROP VARIABLE statement

EXCEPT operation

EXECUTE statement [ESQL]

EXECUTE statement [T-SQL]

EXECUTE IMMEDIATE statement [SP]

EXIT statement [Interactive SQL]

EXPLAIN statement [ESQL]

FETCH statement [ESQL] [SP]

FOR statement

FORWARD TO statement

FROM clause

GET DATA statement [ESQL]

GET DESCRIPTOR statement [ESQL]

GET OPTION statement [ESQL]

GOTO statement [T-SQL]

GRANT statement

GRANT CONSOLIDATE statement [SQL Remote]

GRANT PUBLISH statement [SQL Remote]

GRANT REMOTE statement [SQL Remote]

GRANT REMOTE DBA statement [SQL Remote]

GROUP BY clause

HELP statement [Interactive SQL]

IF statement

IF statement [T-SQL]

INCLUDE statement [ESQL]

INPUT statement [Interactive SQL]

INSERT statement

INSTALL JAVA statement

INTERSECT operation

LEAVE statement

LOAD STATISTICS statement

LOAD TABLE statement

LOCK TABLE statement

LOOP statement

MESSAGE statement

OPEN statement [ESQL] [SP]

OUTPUT statement [Interactive SQL]

PARAMETERS statement [Interactive SQL]

PASSTHROUGH statement [SQL Remote]

PREPARE statement [ESQL]

PREPARE TO COMMIT statement

PRINT statement [T-SQL]

PUT statement [ESQL]

RAISERROR statement [T-SQL]

READ statement [Interactive SQL]

READTEXT statement [T-SQL]

RELEASE SAVEPOINT statement

REMOTE RESET statement [SQL Remote]

REMOVE JAVA statement

REORGANIZE TABLE statement

RESIGNAL statement

RESTORE DATABASE statement

RESUME statement

RETURN statement

REVOKE statement

REVOKE CONSOLIDATE statement [SQL Remote]

REVOKE PUBLISH statement [SQL Remote]

REVOKE REMOTE statement [SQL Remote]

REVOKE REMOTE DBA statement [SQL Remote]

ROLLBACK statement

ROLLBACK TO SAVEPOINT statement

ROLLBACK TRANSACTION statement

ROLLBACK TRIGGER statement

SAVE TRANSACTION statement

SAVEPOINT statement

SELECT statement

SET statement

SET statement [T-SQL]

SET CONNECTION statement [Interactive SQL] [ESQL]

SET DESCRIPTOR statement [ESQL]

SET OPTION statement

SET OPTION statement [Interactive SQL]

SET REMOTE OPTION statement [SQL Remote]

SET SQLCA statement [ESQL]

SETUSER statement

SIGNAL statement

START DATABASE statement [Interactive SQL]

START ENGINE statement [Interactive SQL]

START JAVA statement

START LOGGING statement [Interactive SQL]

START SUBSCRIPTION statement [SQL Remote]

START SYNCHRONIZATION DELETE statement [MobiLink]

STOP DATABASE statement

STOP ENGINE statement

STOP JAVA statement

STOP LOGGING statement [Interactive SQL]

STOP SUBSCRIPTION statement [SQL Remote]

STOP SYNCHRONIZATION DELETE statement [MobiLink]

SYNCHRONIZE SUBSCRIPTION statement [SQL Remote]

SYSTEM statement [Interactive SQL]

TRIGGER EVENT statement

TRUNCATE TABLE statement

UNION operation

UNLOAD statement

UNLOAD TABLE statement

UPDATE statement

UPDATE (positioned) statement [ESQL] [SP]

UPDATE statement [SQL Remote]

VALIDATE CHECKSUM statement

VALIDATE INDEX statement

VALIDATE TABLE statement

WAITFOR statement

WHENEVER statement [ESQL]

WHILE statement [T-SQL]

WRITETEXT statement [T-SQL]


UltraLite Schema Painter Help

About this chapter

This chapter provides descriptions of all the dialog boxes you can access from the UltraLite Schema Painter.

UltraLite Schema Painter Options dialog
New UltraLite Schema dialog
Save Schema to PDB file dialog
Schema Deployment dialog
Database Schema property sheet
Database Property Editor dialog
New Table dialog
New Column property sheet
Set Primary Key dialog
Save Certificate dialog
Set Index dialog
Create Foreign Key dialog
Map Primary Column dialog
Foreign Key property sheet
Table property sheet
Publication dialog
MobiLink Synchronization property sheet
Generate Consolidated Database and MobiLink Scripts dialog
Preview Scripts and Consolidated Database Table Definitions dialog
MobiLink Table Settings dialog
Create UltraLite Database dialog


UltraLite Schema Painter Options dialog

This dialog provides options for running the UltraLite Schema Painter.

The UltraLite Schema Painter Options dialog has the following components:

Informational messages Select the warnings and messages you wish to receive.

  • Warn before closing an open schema file. Select this option for a warning when closing a schema file that is in use.

  • Show post-deployment info. Select this option for post-deployment messages.

  • Warn when attempting to edit an indexed column. Select this option for a warning when editing a column already in an index.

  • Warn before changing the Nullability of a column being added to a primary key. Select this option for a warning when adding a column that allows null values to a primary key.

Recent files options Click Clear Now to delete the list of recently accessed schema files.


New UltraLite Schema dialog

This dialog provides options for the creation of a new UltraLite schema file.

The New UltraLite Schema dialog has the following components:

What should the new filename for the new UltraLite schema be? Enter a name for your UltraLite schema or click Browse to select an existing schema.

If you choose to browse to an existing schema, click Save to open it.

What collation sequence should be used for your new UltraLite schema? Select a collation sequence from the dropdown list. A collation sequence is a character set and sorting order. For languages based on the Roman alphabet, such as most European languages, the default sequence, 1252LATIN1 - Code Page 122, Windows Latin 1, Western, will suffice.

Check this to make your UltraLite database case-sensitive. Select this option if you want your UltraLite database to be case-sensitive.


Save Schema to PDB file dialog

This dialog provides options for deploying your schema to a Palm device.

The Save Schema to PDB file dialog has the following components:

Palm Creator ID Enter a Palm Creator ID.

A Palm creator ID is assigned to you by Palm. You can use Syb3 as your creator ID when you make sample applications for your own learning. However, when you create your commercial application, you should use your own creator ID.

What should the filename for the PDB be? Enter a filename and path for your Palm database file, or click Browse to select a path and filename.


Schema Deployment dialog

This dialog provides options for modifying your database upon deployment.

The Schema Deployment dialog has the following components:

Tables in this schema Lists the tables in the schema.

The current table names are listed in the New Name column; the original table names are in the Old Name column. If a table name has been changed more than once, Old Name will record the name originally given to the table upon creation.

To edit a table's old name, select the table from the list by clicking on it and then click its old name.

Columns for table Lists all the columns in a selected table.

The current column names are listed in the New Name column; the original column names are in the Old Name column. If a column name has been changed more than once, Old Name will record the name originally given to the column upon creation.

To edit a column's old name, select the column from the list by clicking on it and then click its old name.


Database Schema property sheet

The Database Schema property sheet consists of two tabs: General and Certification.


Database Schema property sheet: General tab

The General tab of the Database Schema property sheet has the following components:

Name The name of the schema.

Type The file type (usually UltraLite Schema).

Location The path of the schema file.

Collation sequence The collation sequence used in the file. A collation sequence is a character set and sorting order.

Case-sensitive Yes if the database is case-sensitive, no if it is not.

Database properties Lists various database properties and the values they are set to. Select a database property from the list to edit its value.

Edit Click Edit to edit the selected database property.

Set Defaults Click Set Defaults to set all database properties to their default values.


Database Schema property sheet: Certification tab

The Certification tab of the Database Schema property sheet has the following components:

Set Trusted Roots Certificate Click Set to browse to a Certicom encryption certificate.

Clear Trusted Roots Certificate Click Clear to remove the encryption certificate associated with your schema.

Save/View Trusted Roots Certificate Save and view the certificate associated with your schema.


Database Property Editor dialog

This dialog allows you to edit the values of database properties.

The Database Property Editor dialog has the following components:

Please enter a new value for the database option Enter a new value for the selected database property. Most database properties are very specific about the formatting of their values. If a database property is incorrectly formatted, an error will appear when trying to apply the changes in the Database Schema property sheet.


New Table dialog

This dialog provides options for the creation of a new table in your UltraLite database.

The New Table dialog has the following components:

Name Enter a name for the table.

Columns Lists all the columns currently in the table. Select a column by clicking on its name in the table.

Add Click Add to add a new column to the table.

Edit Click Edit to edit the selected column. This button is only available when a column is selected from the Columns table. Columns included in an index or primary key cannot be edited without first removing them from the index or primary key.

Remove Click Remove to remove the selected column. This button is only available when a column is selected from the Columns table. Columns included in an index or primary key cannot be removed without first removing them from the index or primary key.

Remove All Click Remove All to delete all columns from the table.

Primary Key Click Primary key to designate one or more of the columns in the table as its primary key or to edit an existing primary key.

Synchronize Select synchronization options for the table.

  • Only changed rows (default) Synchronizes only those rows that have been changed since the last synchronization.

  • All rows Synchronizes all rows in the table.

  • No rows This table is not synchronized.


Web Links Browse Collapse Expand PDF Previous Next

SQL Anywhere Studio Help

UltraLite Schema Painter Help

New Column property sheet

The New Column property sheet consists of two tabs: General and Indexes.


New Column property sheet: General tab

The General tab of the New Column property sheet has the following components:

Name Enter a name for the column.

Type Select a data type from the dropdown list.

  • Size/Precision Specify the size of the column for binary or char types, or the precision for numeric types.

  • Scale Specify the scale value for a numeric column.

Column allows null values Check this option to allow null values. Null values are not permitted in primary keys.

Column default Set a default value for the column.

  • Default Select a default value for the column from the list, or choose Specify value... to set a constant value.

  • Value Specify the column value. This option is only available when Specify value is selected as the default value.

  • Partition size (optional) Specify the partition size. The partition size restricts the maximum value that global autoincrement can use. This option is only available when Global autoincrement is selected as the default value.


New Column property sheet: Indexes tab

The Indexes tab of the New Column property sheet has the following components:

Indexes Lists the indexes that contain the selected column.


Set Primary Key dialog

This dialog provides options for the creation and editing of a primary key.

The Set Primary Key dialog has the following components:

Index information Provides information on the index.

  • Index name Enter a name for the index. For primary key indexes, the name is set to primary and cannot be changed.

  • Unique index Select Unique index to ensure that values are unique and not null. For primary key indexes, this option is checked and cannot be changed.

  • Unique key Select Unique key to ensure that values are unique. They may be null. For primary key indexes, this option is checked and cannot be changed.

Indexed Columns Allows you to add or remove columns from the primary key index.

  • Columns in the table Lists all columns in the table that are not in the primary key index. Click a column to select it, or hold down Control to select more than one column at a time.

  • Asc.>> Click Asc.>> to add one or more columns, chosen from the Columns in table list, to the index in ascending order.

  • Desc.>> Click Desc.>> to add one or more columns, chosen from the Columns in table list, to the index in descending order.

  • << Click << to remove one or more columns, chosen from the Columns in the index list, from the index.

  • Columns in the index Lists all columns in the primary key index. Click a column to select it, or hold down Control to select more than one column at a time.


Save Certificate dialog

This dialog allows you to save and view the trusted root certificate associated with your schema.

The Save Certificate dialog has the following components:

What should the filename for the certificate be? Enter a filename and path or click Browse to select one.

View certificate after saving Select this option to view the certificate once you have saved it.


Set Index dialog

This dialog provides options for the creation of a new index.

The Set Index dialog has the following components:

Index information Provides information on the index.

  • Index name Enter a name for the index.

  • Unique index Select Unique index to ensure that values are unique and not null.

  • Unique key Select Unique key to ensure that values are unique. They may be null.

Indexed Columns Allows you to add or remove columns from the index.

  • Columns in the table Lists all columns in the table that are not in the index. Click a column to select it, or hold down Control to select more than one column at a time.

  • Asc.>> Click Asc.>> to add one or more columns, chosen from the Columns in table list, to the index in ascending order.

  • Desc.>> Click Desc.>> to add one or more columns, chosen from the Columns in table list, to the index in descending order.

  • << Click << to remove one or more columns, chosen from the Columns in the index list, from the index.

  • Columns in the index Lists all columns in the index. Click a column to select it, or hold down Control to select more than one column at a time.

Index property sheet: General tab


Index property sheet: General tab

The General tab of the Index property sheet has the following components:

Index name The name of the index.

Table The name of the table containing the index.

Unique If yes, values in the index must be unique and not null.

Unique key If yes, values in the index must be unique, but they may be null.

This index includes the following columns: Lists the columns contained in the index and their directions.


Create Foreign Key dialog

This dialog provides options for the creation of a foreign key.

The Create Foreign Key dialog has the following components:

Foreign key name Enter a name for the foreign key.

Primary table Select the primary table from the list of tables in your database.

Eligible indexes Select an index from the list of indexes in your primary table.

Only check values on commit Select this option to check values at commit, rather than upon insertion.

Allow Null in the foreign key columns Allows null values in the columns of your foreign key.

Map Click Map to map a column in your primary table, selected from the table above, to a column in your current table, selected in a subsequent dialog.


Map Primary Column dialog

This dialog provides options for the mapping of a column in your primary table to a column in your current table.

The Map Primary Column dialog has the following components:

Name The name of your primary column.

Type The data type of your primary column.

Default The default value for your primary column.

Direction Select ascending to sort your column in ascending order or descending to sort your column in descending order.

Foreign column Select a column in your current table from the dropdown list to which to map the selected column in your primary table.

Properties Displays the properties of the selected foreign column.


Foreign Key property sheet

The Foreign Key property sheet has a single tab, which has the following components:

Foreign key name The name of the foreign key.

Table The table that contains the foreign key.

Referenced table The table referenced by the foreign key.

Referenced index The index referenced by the foreign key.

Check on commit If yes, checks values at commit, rather than upon insertion.

Nullable If yes, allows null values in the columns of the foreign key.

This foreign key contains the following columns: Lists columns in the foreign key and the columns they map to in the primary table.


Table property sheet

The Table property sheet has a single tab, which has the following components:

Table The name of the referencing table.

Synchronization The synchronization scheme of the referencing table, one of Only changed rows, All rows, or No rows.

Columns Lists the names, types, and inclusion in the primary key for all the columns in the referencing table.

Access the Table property sheet from the Publication dialog.


Publication dialog

This dialog provides options for the creation of a new publication for your UltraLite database. A publication is a database object describing data to be replicated.

The Publication dialog has the following components:

Publication name Enter a name for the publication.

Available tables Lists all the tables in your database not yet in the publication. Click a table to select it, or hold down Control to select more than one table at a time.

>> Click >> to add one or more tables, chosen from the Available tables list, to the publication.

<< Click << to add one or more tables, chosen from the Tables in the publication list, to the publication.

Tables in the publication Lists all the tables in the publication. Click a table to select it, or hold down Control to select more than one table at a time.


MobiLink Synchronization property sheet

The MobiLink Synchronization property sheet consists of several tabs, listed here.

If you open the property sheet from the MobiLink Synchronization folder, the settings on the tabs are default settings that apply to all tables, unless you override them by creating individual table settings.

If you open the property sheet from an individual table, the settings apply to that table only and override the default settings.

To generate consolidated table definitions and synchronisation scripts using the settings in this property sheet, close the property sheet and choose Tools > Generate Consolidated Tables and Scripts.

MobiLink Synchronization property sheet: Direction tab
MobiLink Synchronization property sheet: Row Increment tab
MobiLink Synchronization property sheet: Row partition tab
MobiLink Synchronization property sheet: Deleted Rows tab
MobiLink Synchronization property sheet: Conflict tab
MobiLink Synchronization property sheet: Resolution tab


MobiLink Synchronization property sheet: Direction tab

The Direction tab of the MobiLink Synchronization property sheet has the following component:

Table synchronization direction Choose whether any scripts generated for this table are for full two-way synchronization, for download only, or for upload only.

  • Full synchronization Upload changes to the consolidated database and download changes to this table in the UltraLite database.

  • Download only Do not upload changes from this table to the consolidated database. Do download changes from the consolidated database to this table in the UltraLite database.

  • Upload only Upload changes from this table to the consolidated database, but do not download changes from the consolidated database to this table.

The details of the synchronization are controlled by settings on the other tabs of this property sheet.

About this property sheet

For more information about this property sheet and setting up synchronization scripts, see MobiLink Synchronization property sheet.


MobiLink Synchronization property sheet: Row Increment tab

The Row Increment tab of the MobiLink Synchronization property sheet has the following component:

Download increment Specify a method to select the rows that are downloaded to this table.

  • Snapshot In a snapshot download, all rows of the table on the consolidated database are downloaded to the UltraLite database at each synchronization, whether or not they have changed.

  • Timestamp In a timestamp-based download, only those rows that have changed since the last download are downloaded.

    This choice requires that the timestamp values be stored somewhere. You can choose to use a shadow table to store these values. If you check the box to use a shadow table, a table with the suffix _updated is created in the consolidated database, to hold the primary key values and a timestamp indicating when the row was last updated.

    If you do not use a shadow table, an additional column is added to the table and holds the time that the row was last updated as a timestamp.

  • Sequence number In a sequence-based download, you need to specify a column and an expression. For each row, the value in the specified column is compared to the value of the expression you provide. Only rows for which the column value is greater than the expression are downloaded.

  • Custom SQL expression Advanced users can specify a custom SQL expression that is evaluated for each row. Only rows for which the expression is true are downloaded.

For more information on these synchronization techniques, see Synchronization Techniques.

About this property sheet

For more information about this property sheet and setting up synchronization scripts, see MobiLink Synchronization property sheet.

SQL Expression dialog


SQL Expression dialog

The SQL Expression dialog provides a space for advanced users to enter custom SQL expressions for use in defining synchronization. The dialog can be displayed from several of the tabs on the MobiLink Synchronization property sheet.

For custom downloads, only rows for which the expression evaluates to true are returned.

For sequence number downloads, only rows for which a specified column is equal to this expression are downloaded.


MobiLink Synchronization property sheet: Row partition tab

The Row Partition tab of the MobiLink Synchronization property sheet has the following component:

Partition download rows Specify which rows are present on each remote UltraLite database.

  • Same data on all remote databases Each UltraLite database has the same set of rows.

  • Each row downloaded by only one database If you choose this option, a column named ml_user is added to the consolidated database table. Only rows for which the value in this column matches the MobiLink user name are downloaded.

  • Use an existing relationship table to partition rows If you choose this option, only rows for which the indicated column and table matches the MobiLink user name are downloaded.

  • Partition based on custom expression Advanced users can specify a table and a SQL expression that specify rows to be downloaded.

For more information on partitioning tables, see Partitioning rows among remote databases.

About this property sheet

For more information about this property sheet and setting up synchronization scripts, see MobiLink Synchronization property sheet.


MobiLink Synchronization property sheet: Deleted Rows tab

The Deleted Rows tab of the MobiLink Synchronization property sheet has the following component:

Deleted row handling There are several options for managing rows that are deleted from the consolidated database:

  • Never download deletions Operations that delete rows from this table are not downloaded to the UltraLite database.

  • Truncate and reload remote table The entire table is deleted in the UltraLite database, and is refilled with all the rows currently in the consolidated database (subject to any row partitioning).

  • Download deletions There are two options for this choice:

    • You can create a shadow table that holds primary key values for rows to be deleted at the UltraLite database.

    • You can choose to add a column named inActive to the table at the consolidated database. This column holds a value that marks the row as inactive.

      A disadvantage of this option is that any other application using the consolidated database must be sure to check if a row is inactive in queries from the table.

About this property sheet

For more information about this property sheet and setting up synchronization scripts, see MobiLink Synchronization property sheet.


MobiLink Synchronization property sheet: Conflict tab

The Conflict tab of the MobiLink Synchronization property sheet has the following component:

Upload conflict handling Conflicts arise during the upload of rows to the consolidated database. If two users modify the same row on different remote databases, a conflict is detected when the second of the rows arrives at the MobiLink synchronization server. When conflicts can occur, you should define a process to compute the correct values, or at least to log the conflict. For more information about conflicts, see Handling conflicts.

  • Default: conflicts will not be raised The data from the UltraLite database is used to update the table.

  • Update table values The dropdown list supplies several common choices for conflict resolution. The appropriate choice depends on your business rules for the particular information being updated.

About this property sheet

For more information about this property sheet and setting up synchronization scripts, see MobiLink Synchronization property sheet.


MobiLink Synchronization property sheet: Resolution tab

The Resolution tab of the MobiLink Synchronization property sheet has the following component:

When to resolve conflicts Conflict resolution can be carried out immediately, or when all changes have been made to the table. In addition, you can choose whether to use a temporary table to store intermediate values or not.

About this property sheet

For more information about this property sheet and setting up synchronization scripts, see MobiLink Synchronization property sheet.


Generate Consolidated Database and MobiLink Scripts dialog

This dialog lets you generate a set of table definitions and synchronization scripts that define an Adaptive Server Anywhere consolidated database. The synchronization scripts are determined by the settings in the MobiLink Synchronization property sheet for each table and the default settings.

The settings you make here may depend on whether this is the first time you have generated a database and scripts or whether you are modifying an existing consolidated database.

This dialog has the following components:

Settings General settings defining global settings for the generation.

  • MobiLink script version The synchronization scripts are defined for a script version. Your UltraLite application must specify this version name when it synchronizes to use the generated scripts.

  • Publications to sync You can specify one or more publications to synchronize.

  • Output conflict status messages to ASA window This option is useful during development.

  • Emit calls to drop tables and procedures before definition Check this box if you intend to run the generated SQL script against a database that already contains a previous version of these tables and procedures, and you want to override the definitions with a new set.

Generated SQL Choose the objects you wish to generate. If you have already generated table definitions (for example) you may not wish to re-generate them.

Generated SQL file Specify a file name for the generated SQL file. Once generated, you can run the SQL file against an Adaptive Server Anywhere database from Interactive SQL to create or modify the consolidated database.


Preview Scripts and Consolidated Database Table Definitions dialog

Use this dialog to inspect the table definitions, scripts, and procedures before you generate them. Use the Settings option to filter the objects you wish to inspect.

The scripts and table definitions are defined from the MobiLink Synchronization property sheet. For more information, see MobiLink Synchronization property sheet.


MobiLink Table Settings dialog

Use this dialog to override the default MobiLink synchronization properties for an individual table. The dialog has the following components:

Available tables Lists all the tables in your database that use the default MobiLink synchronization properties. Click a table to select it, or hold down Control to select more than one table at a time.

>> Click >> to add one or more tables, chosen from the Available tables list, to the list of tables with MobiLink settings.

<< Click << to add one or more tables, chosen from the Tables in the publication list, to the list of tables with MobiLink settings.

Tables with MobiLink settings Lists all the tables for which individual settings are defined, or for which you wish to define individual settings. Click a table to select it, or hold down Control to select more than one table at a time.


Create UltraLite Database dialog

Use this dialog to create an empty UltraLite database file from the schema file you are currently editing. The UltraLite database file typically has extension .udb. Utilities such as UltraLite Interactive SQL and UltraLite command-line utilities operate on UltraLite database files, and the combination of this dialog and the UltraLite utilities is useful in designing and testing databases.

The dialog has the following components:

Database type Choose one of the following options:

  • UNICODE Strings in the database are stored as Unicode strings. Use this option for Windows CE databases. You can also use it for Windows databases.

  • Multibyte character set Strings in the database are stored using an ASCII-based character set or, for languages that use multiple bytes per character, as a multibyte character set such as Shift-JIS. The character set is determined by your Windows operating system settings. You can use this setting for Windows databases.

  • Palm OS The database is created as a pdb file that can be exported to a Palm OS device.

Initial database ID If you are using primary keys that have a default global autoincrement setting, you must supply an initial database ID that acts as a starting point for the values in those columns.

For more information on global autoincrement columns, see Maintaining unique primary keys using global autoincrement.

UltraLite database file Enter the filename for the database you are creating.

See also
  • The UltraLite Interactive SQL utility
  • UltraLite Utilities Reference


UltraLite Interactive SQL Help

About this chapter

This chapter provides descriptions of all the dialog boxes you can access from UltraLite Interactive SQL.


Connection Dialog

The Connection dialog has the following components:

Filename An UltraLite database file.

For databases created on CE and the desktop, this is a .udb file. For UltraLite databases created on the Palm Computing Platform, this is a .pdb file.

User ID An UltraLite user ID.

If the UltraLite database does not have user authentication enabled, this field is ignored and you can leave it empty.

Password The password corresponding to the UltraLite user ID.

If the UltraLite database does not have user authentication enabled, this field is ignored and you can leave it empty.

Encryption Key If the database file is encrypted, you must supply the key used to encrypt the file.

Additional Other connection parameters. For a complete list of connection parameters, see Connection Parameters.

See also
  • User authentication in UltraLite


Old Database Format Dialog

This dialog has the following components:

  • Upgrade If you choose this option, UltraLite upgrades the database file to the native format of the current version of the software. This upgrade makes it impossible to use the database from older versions of UltraLite, including applications developed with older versions of the software.

  • Open Read Only If you choose this option, UltraLite opens the database in read-only mode. Any changes you make are discarded when UltraLite Interactive SQL closes, even if you commit your changes.


Command History Dialog

The Command History dialog has the following components:

SQL Statements A list of SQL statements executed from this utility in previous sections.


Lookup Table Dialog

The Lookup Table dialog has the following components:

Table list A list of the tables in the database. To display a list of columns in the table, select a table and click Show Columns. To paste the name of a table into the SQL pane of the main window, select a table and click OK.


Options Dialog

The Options dialog has the following components:

Display Null Values As A string that is displayed in the results pane to represent NULL values in the result set.

Fetching Data You can specify a length (number of bytes) at which to truncate long column values for better performance.

Automatic Commit Choose whether to automatically execute a COMMIT statement after each statement or only on exiting the application. If you choose to COMMIT only on exiting the application, changes you make to the database are not permanent until you either enter an explicit COMMIT statement or exit the application.

Plan Display Choose whether to display the query plan graphically or in text format.

The text version can be difficult to interpret but is useful for pasting into other applications. The graphical version is easier to interpret.

For more information on query plans, see Query optimization.


Web Links Browse Collapse Expand PDF Previous Next

ODBC Drivers for MobiLink and Remote Data Access

Version 9.0.2

DC30129-01-0902-01

October 2004

Copyright
About This Manual
Introduction to iAnywhere Solutions ODBC Drivers
iAnywhere Solutions ODBC Driver for Sybase Adaptive Server Enterprise
iAnywhere Solutions ODBC Driver for Oracle
iAnywhere Solutions ODBC Driver for DB2
ODBC Functions
Values for IANAAppCodePage Connection String Attribute


About This Manual

Subject

This manual describes how to use the iAnywhere Solutions ODBC drivers for Oracle, DB2, and Sybase Adaptive Server Enterprise. These ODBC drivers are included with SQL Anywhere Studio for use with MobiLink synchronization and Adaptive Server Anywhere remote data access.

Note
The ODBC driver for Adaptive Server Anywhere is described in the main Adaptive Server Anywhere documentation, and not in this book. For more information, see Working with ODBC data sources.
Audience

This manual is for MobiLink synchronization users working with Oracle, DB2, or Sybase Adaptive Server Enterprise consolidated databases.


SQL Anywhere Studio documentation

This book is part of the SQL Anywhere documentation set. This section describes the books in the documentation set and how you can use them.

The SQL Anywhere Studio documentation

The SQL Anywhere Studio documentation is available in a variety of forms: in an online form that combines all books in one large help file; as separate PDF files for each book; and as printed books that you can purchase. The documentation consists of the following books:

  • Introducing SQL Anywhere Studio This book provides an overview of the SQL Anywhere Studio database management and synchronization technologies. It includes tutorials to introduce you to each of the pieces that make up SQL Anywhere Studio.

  • What's New in SQL Anywhere Studio This book is for users of previous versions of the software. It lists new features in this and previous releases of the product and describes upgrade procedures.

  • Adaptive Server Anywhere Database Administration Guide This book covers material related to running, managing, and configuring databases and database servers.

  • Adaptive Server Anywhere SQL User's Guide This book describes how to design and create databases; how to import, export, and modify data; how to retrieve data; and how to build stored procedures and triggers.

  • Adaptive Server Anywhere SQL Reference Manual This book provides a complete reference for the SQL language used by Adaptive Server Anywhere. It also describes the Adaptive Server Anywhere system tables and procedures.

  • Adaptive Server Anywhere Programming Guide This book describes how to build and deploy database applications using the C, C++, and Java programming languages. Users of tools such as Visual Basic and PowerBuilder can use the programming interfaces provided by those tools. It also describes the Adaptive Server Anywhere ADO.NET data provider.

  • Adaptive Server Anywhere SNMP Extension Agent User's Guide This book describes how to configure the Adaptive Server Anywhere SNMP Extension Agent for use with SNMP management applications to manage Adaptive Server Anywhere databases.

  • Adaptive Server Anywhere Error Messages This book provides a complete listing of Adaptive Server Anywhere error messages together with diagnostic information.

  • SQL Anywhere Studio Security Guide This book provides information about security features in Adaptive Server Anywhere databases. Adaptive Server Anywhere 7.0 was awarded a TCSEC (Trusted Computer System Evaluation Criteria) C2 security rating from the U.S. Government. This book may be of interest to those who wish to run the current version of Adaptive Server Anywhere in a manner equivalent to the C2-certified environment.

  • MobiLink Administration Guide This book describes how to use the MobiLink data synchronization system for mobile computing, which enables sharing of data between a single Oracle, Sybase, Microsoft or IBM database and many Adaptive Server Anywhere or UltraLite databases.

  • MobiLink Clients This book describes how to set up and synchronize Adaptive Server Anywhere and UltraLite remote databases.

  • MobiLink Tutorials This book provides several tutorials that walk you through how to set up and run MobiLink applications.

  • MobiLink Server-Initiated Synchronization User's Guide This book describes MobiLink server-initiated synchronization, a feature of MobiLink that allows you to initiate synchronization from the consolidated database.

  • QAnywhere User's Guide This manual describes MobiLink QAnywhere, a messaging platform that enables the development and deployment of messaging applications for mobile and wireless clients, as well as traditional desktop and laptop clients.

  • iAnywhere Solutions ODBC Drivers This book describes how to set up ODBC drivers to access consolidated databases other than Adaptive Server Anywhere from the MobiLink synchronization server and from Adaptive Server Anywhere remote data access.

  • SQL Remote User's Guide This book describes all aspects of the SQL Remote data replication system for mobile computing, which enables sharing of data between a single Adaptive Server Anywhere or Adaptive Server Enterprise database and many Adaptive Server Anywhere databases using an indirect link such as e-mail or file transfer.

  • SQL Anywhere Studio Help This book includes the context-sensitive help for Sybase Central, Interactive SQL, and other graphical tools. It is not included in the printed documentation set.

  • UltraLite Database User's Guide This book is intended for all UltraLite developers. It introduces the UltraLite database system and provides information common to all UltraLite programming interfaces.

  • UltraLite Interface Guides A separate book is provided for each UltraLite programming interface. Some of these interfaces are provided as UltraLite components for rapid application development, and others are provided as static interfaces for C, C++, and Java development.

In addition to this documentation set, PowerDesigner and InfoMaker include their own online documentation.

Documentation formats

SQL Anywhere Studio provides documentation in the following formats:

  • Online documentation The online documentation contains the complete SQL Anywhere Studio documentation, including both the books and the context-sensitive help for SQL Anywhere tools. The online documentation is updated with each maintenance release of the product, and is the most complete and up-to-date source of documentation.

    To access the online documentation on Windows operating systems, choose Start > Programs > SQL Anywhere 9 > Online Books. You can navigate the online documentation using the HTML Help table of contents, index, and search facility in the left pane, as well as using the links and menus in the right pane.

    To access the online documentation on UNIX operating systems, see the HTML documentation under your SQL Anywhere installation.

  • PDF books The SQL Anywhere books are provided as a set of PDF files, viewable with Adobe Acrobat Reader.

    The PDF books are accessible from the online books, or from the Windows Start menu.

  • Printed books The complete set of books is available from Sybase sales or from eShop, the Sybase online store, at [external link] http://eshop.sybase.com/eshop/documentation.


Introduction to iAnywhere Solutions ODBC Drivers

About this chapter

This chapter introduces the iAnywhere Solutions ODBC drivers that are included in SQL Anywhere Studio for use with MobiLink synchronization or Adaptive Server Anywhere remote data access. It provides general information and key settings. For details of how to configure the iAnywhere Solutions ODBC drivers, see:

  • iAnywhere Solutions ODBC Driver for Sybase Adaptive Server Enterprise

  • iAnywhere Solutions ODBC Driver for Oracle

  • iAnywhere Solutions ODBC Driver for DB2

Note
The ODBC driver for Adaptive Server Anywhere is described in the main Adaptive Server Anywhere documentation, and not in this book. For more information, see Working with ODBC data sources.

About iAnywhere Solutions ODBC drivers
Quick start for Windows
Quick start for UNIX
Error messages

Previous Next


About iAnywhere Solutions ODBC drivers

iAnywhere Solutions ODBC drivers are compliant with the Open Database Connectivity (ODBC) specification. ODBC is a specification for an application program interface (API) that enables applications to access multiple database management systems using SQL.

The iAnywhere Solutions ODBC drivers are for use only with MobiLink synchronization server and administration tools, and with Adaptive Server Anywhere remote data access. Other ODBC client applications cannot use these drivers.

iAnywhere Solutions ODBC drivers are provided for the following operating systems:

  • Windows operating systems, except Windows CE and 64-bit drivers

  • UNIX operating systems: Solaris, AIX, and Linux

The iAnywhere Solutions ODBC drivers are installed by the SQL Anywhere Studio Setup program.

Note
The ODBC driver for Adaptive Server Anywhere is described in the main Adaptive Server Anywhere documentation, and not in this book. For more information, see Working with ODBC data sources.

Previous Next


Quick start for Windows

The iAnywhere Solutions ODBC drivers support the following Windows operating systems:

  • Windows 95, Windows 98, Windows Me, Windows XP

  • Windows NT with Service Pack 5 and higher

  • Windows 2000 with Service Pack 1 and higher

On Windows, the ODBC drivers are 32-bit drivers. All required network software supplied by your database system vendors must be 32-bit compliant.


Starting the ODBC Administrator

The ODBC Administrator is used to manage data sources created for each driver.

toggle To start the ODBC Administrator (Windows)

  • Double-click the ODBC Data Sources icon in the Control Panel.

toggle To start the ODBC Administrator (command line)

  • At a command prompt, enter the command odbcad32.

Once in the ODBC Administrator, you can create a new data source by clicking Add and choosing one of the iAnywhere Solutions ODBC drivers.


Web Links Browse Collapse Expand PDF Previous Next

ODBC Drivers for MobiLink and Remote Data Access

Introduction to iAnywhere Solutions ODBC Drivers

Quick start for Windows

Driver file names

The prefix for all iAnywhere Solutions ODBC driver file names is wq. The file extension is .dll. This indicates that they are dynamic link libraries.


Quick start for UNIX

The following UNIX operating systems are supported:

  • Solaris

  • Linux (Red Hat, Caldera, and SuSE)

  • AIX

For more information about the versions that are supported, see the UNIX Readme First , which is installed in your SQL Anywhere installation directory in two formats: readme.txt and readme.pdf.


The system information file (.odbc.ini)

In the UNIX environment, there is no ODBC administrator. To configure a data source, you must edit the system information file, a plain text file that is normally located in your $HOME directory and is usually called .odbc.ini. This file is maintained using any text editor, and defines data source entries as described in the following sections:

  • Sybase Adaptive Server Enterprise Connecting to a data source using a connection string.

  • Oracle Connecting to a data source using a connection string.

  • IBM DB2 Connecting to a data source using a connection string.

You must use the long name of connection string attributes when defining data source entries. A sample file (odbc.ini.sample) is located in the driver installation directory.

Caution You should not add simple encryption to the .odbc.ini system information file with the File Hiding utility (dbfhide) on UNIX unless you will only be using Adaptive Server Anywhere data sources. If you plan to use other data sources (for example, for MobiLink synchronization), then obfuscating the contents of the .odbc.ini file may prevent other drivers from functioning properly.

For more information, see Hiding the contents of .ini files.

System information file contents

There must be an [ODBC] section in the system information file that includes the InstallDir keyword. The value of this keyword must be the path to the directory under which the /lib and /messages directories are contained. For example, if you choose the default install directory, then the following line must be in the [ODBC] section:

InstallDir=/opt/sybase/SYBSsa9/drivers
Sample system information file

The following is a sample system information file for Solaris:

; This is only a sample .odbc.ini file
; IT WILL NOT WORK AS IS.
; You need to make a copy of this file
; into the user's home directory and modify
; the DSNs (Data Source Names) to your needs:
;
; cp odbc.ini.sample ~/.odbc.ini
; vi ~/.odbc.ini
;
; You also need to modify the default
; value of your ODBCINI environment variable.
; It should be set to point to your local
; copy of the .odbc.ini file:
; export ODBCINI=~/.odbc.ini
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[ODBC Data Sources]
SybaseASA=Adaptive Server Anywhere 9 Driver
Oracle Wire Protocol=iAnywhere Solutions 9 - Oracle Wire Protocol Driver
Sybase ASE Wire Protocol=iAnywhere Solutions 9 - Sybase ASE Driver
DB2 Wire Protocol=iAnywhere Solutions 9 - DB2 Wire Protocol Driver

[SybaseASA]
Driver=/opt/sybase/SYBSsa9/lib/libdbodbc9_r.so
UID=dba
PWD=sql
ServerName=asademo
CommLinks=tcpip

[Oracle Wire Protocol]
Driver=/opt/sybase/SYBSsa9/drivers/lib/wqora19.so
Description=iAnywhere Solutions 9 - Oracle Wire Protocol
ApplicationUsingThreads=1
ArraySize=60000
CachedCursorLimit=32
CachedDescLimit=0
CatalogIncludesSynonyms=1
CatalogOptions=0
DefaultLongDataBuffLen=1024
DescribeAtPrepare=0
EnableDescribeParam=0
EnableNcharSupport=0
EnableScrollableCursors=1
EnableStaticCursorsForLongData=0
EnableTimestampWithTimeZone=0
HostName=oracleserver
LocalTimeZoneOffset=
LockTimeOut=-1
LogonID=uid
Password=pwd
PortNumber=1521
ProcedureRetResults=1
SID=oraclesid
UseCurrentSchema=1

[Sybase ASE Wire Protocol]
Driver=/opt/sybase/SYBSsa9/drivers/lib/wqase19.so
Description=iAnywhere Solutions 9 - Sybase ASE  Wire Protocol
ApplicationName=
ApplicationUsingThreads=1
ArraySize=50
Charset=
CursorCacheSize=1
Database=db
DefaultLongDataBuffLen=1024
EnableDescribeParam=1
EnableQuotedIdentifiers=0
InitializationString=
Language=
LogonID=uid
NetworkAddress=serverhost,4100
OptimizePrepare=2
PacketSize=0
Password=pwd
RaiseErrorPositionBehavior=0
SelectMethod=0
WorkStationID=

[DB2 Wire Protocol]
Driver=/opt/sybase/SYBSsa9/drivers/lib/wqdb219.so
Description=iAnywhere Solutions 9 - DB2 Wire Protocol
AddStringToCreateTable=
AlternateID=
Collection=
Database=db
DynamicSections=100
GrantAuthid=PUBLIC
GrantExecute=1
IpAddress=db2host
IsolationLevel=CURSOR_STABILITY
Location=
LogonID=uid
Password=pwd
Package=pkg
PackageOwner=uid
TcpPort=50000
WithHold=1

[ODBC]
IANAAppCodePage=4
InstallDir=/opt/sybase/SYBSsa9/drivers
Trace=0
TraceDll=/opt/sybase/SYBSsa9/drivers/lib/odbctrac.so
TraceFile=odbctrace.out
UseCursorLib=0
Using a centralized file

UNIX support of the database drivers also permits the use of a centralized system information file that a system administrator can control. This is accomplished by setting the environment variable ODBCINI to point to the fully qualified path name of the centralized file. For example, in the C shell you could set this variable as follows:

setenv ODBCINI /opt/odbc/system_odbc.ini

In the Bourne or Korn shell, you would set it as:

ODBCINI=/opt/odbc/system_odbc.ini;export ODBCINI

The search order for the location of the system information file is as follows:

  1. Check ODBCINI

  2. Check $HOME for .odbc.ini


Driver file names

The iAnywhere Solutions ODBC drivers are ODBC API-compliant dynamic link libraries, referred to in UNIX as shared objects. The prefix for all ODBC driver file names on UNIX is wq. On UNIX, the driver file names are lowercase and the extension is .so.


Environment variables

To use iAnywhere Solutions ODBC drivers on UNIX, there are several environment variables that you may need to set. It is recommended that you use the appropriate file for your shell, either asa_config.sh or asa_config.csh (located in the directory /opt/sybase/SYBSsa9/bin) as a template for setting the required environment variables. Some of the environment variables set by the asa_config files include PATH, LD_LIBRARY_PATH, ASANY9, and ASANYSH9.

Library Path environment variable

You must include the full path to the dynamic link libraries in the environment variable LD_LIBRARY_PATH. For example, if you install the ODBC drivers in the system directory /opt/sybase/SYBSsa9/drivers, then the fully qualified path for the ODBC pack is /opt/sybase/SYBSsa9/drivers/lib.

If you do not include the path /opt/sybase/SYBSsa9/drivers/lib in the environment variable LD_LIBRARY_PATH, then your applications are unable to load the ODBC drivers dynamically at runtime or to display error message text.

Additional environment variables

Some iAnywhere Solutions ODBC drivers must have environment variables set as required by the database client components used by the drivers. Consult the driver requirements in each of the individual driver sections for additional information pertaining to individual driver requirements.

ODBCINI is an optional environment variable that all iAnywhere Solutions ODBC drivers recognize. ODBCINI is used to locate an ODBC information file other than the default file.

Linux Redhat version 9

To use the iAnywhere Solutions ODBC driver on Linux Redhat version 9 and Linux Redhat Enterprise Server 3.0, you must also set the following environment variable:

LD_ASSUME_KERNEL=2.4.1


Error messages

Error messages can come from the following sources:

  • An ODBC driver

  • The database system

  • The ODBC driver manager

ODBC driver errors

An error reported on an ODBC driver has the following format:

[vendor] [ODBC_component] message

where ODBC_component is the component in which the error occurred. If you receive this type of error, check the last ODBC call made by your application for possible problems or contact your ODBC application vendor.

An error that occurs in the data source includes the data store name, in the following format:

[vendor] [ODBC_component] [data_store] message

With this type of message, ODBC_component is the component that received the error from the data store indicated. For example, you may receive the following message from an Oracle data store:

[DataDirect] [ODBC Oracle driver] [Oracle] ORA-0919: specified length too long for CHAR column

If you receive this type of error, something is wrong with the database system. Check your database system documentation for more information or consult your database administrator. In this example, you would check your Oracle documentation.

Driver Manager errors

The driver manager is a DLL or shared object that establishes connections with drivers, submits requests to drivers, and returns results to applications. An error that occurs in the driver manager has the following format:

[vendor] [ODBC XXX] message

For example, an error from the Microsoft driver manager might look like this:

[Microsoft] [ODBC Driver Manager] Driver does not support this function

If you receive this type of error, consult the Programmer's Reference for the Microsoft ODBC Software Development Kit that is available from Microsoft.

UNIX error handling


UNIX error handling

UNIX error handling follows the X/Open XPG3 messaging catalog system. Localized error messages are stored in the subdirectory locale/localized_territory_directory/LC_MESSAGES, where localized_territory_directory depends on your language.

For instance, German localization files are stored in locale/de/LC_MESSAGES, where de is the locale for German.

If localized error messages are not available for your locale, then they will contain message numbers instead of text. For example:

[DataDirect] [ODBC 20101 driver] 30040


iAnywhere Solutions ODBC Driver for Sybase Adaptive Server Enterprise

About this chapter

This chapter describes how to configure and use the iAnywhere Solutions ODBC driver for Sybase Adaptive Server Enterprise databases.

Introduction
Key settings for MobiLink and Adaptive Server Enterprise
Configuring data sources
Connecting to a data source using a logon dialog box
Connecting to a data source using a connection string
Data types
Unicode support
Default Unicode mapping
Supported features


Introduction

The iAnywhere Solutions ODBC driver for Sybase Adaptive Server Enterprise supports Adaptive Server Enterprise 11.0 and higher database systems in the Windows and UNIX environments.

Driver requirements

The Adaptive Server Enterprise driver is a wire protocol driver, which means that there is no additional client software required.


Key settings for MobiLink and Adaptive Server Enterprise

The ODBC driver for Adaptive Server Enterprise does not require any Adaptive Server Enterprise client software. The following are key settings for Adaptive Server Enterprise. Other parameters are available and described elsewhere, but are less important.

  • Basic connection settings Set the following basic connection settings:

    • Data source name This value is used to identify the data source. On Windows, it is located on the General tab. On UNIX, this attribute is called DataSourceName (DSN).

    • Network library name For TCP/IP networks, set this to Winsock. On Windows, it is located on the General tab. On UNIX, this attribute is called NetworkLibraryName (NLM).

    • Network address and port of the server (General tab) These should be separated by commas; for example, server-machine,1500. On Windows, it is located on the General tab. On UNIX, this attribute is called NetworkAddress (NA).

    • Default Logon ID used for the connection This is case sensitive and must correspond to a valid logon ID on the server. On Windows, it is located on the Connection tab. On UNIX, this attribute is called LogonID (UID).

  • DefaultLongDataBuffLen

    This parameter specifies (in Kb) the size of the largest LONG BINARY or LONG VARCHAR column value being synchronized. The default setting is 1024, which is equivalent to 1 Mb. If you are synchronizing long columns with entries larger than this, set the value higher.

    This parameter appears on the Advanced tab of the Windows driver ODBC setup dialog. On UNIX, this attribute is called DefaultLongDataBuffLen (DLDBL).

  • SelectMethod

    This parameter can be 0 or 1. When you use 0 (the default), database cursors are used. When set to 1, SELECT statements are run directly, without cursors.

    This parameter appears on the Performance tab of the Windows driver ODBC setup dialog. On UNIX, this attribute is called SelectMethod (SM).

  • OptimizePrepare This parameter can be 0, 1, 2, or 3. For use with MobiLink, set it to 2.

    This parameter appears on the Performance tab of the Windows driver ODBC setup dialog. On UNIX, this attribute is called OptimizePrepare (OP).

For complete information about settings for the Adaptive Server Enterprise driver, see Connecting to a data source using a connection string.


Configuring data sources

On Windows, data sources are configured and modified through the ODBC Administrator.

toggle To configure a Sybase Adaptive Server Enterprise data source (UNIX)

  • In the UNIX environment, there is no ODBC administrator. To configure a data source in the UNIX environment, you must edit the system information file.

    For information about editing this file, see Quick start for UNIX.

toggle To configure a Sybase Adaptive Server Enterprise data source (Windows)

  1. Start the ODBC Administrator to display a list of data sources.

  2. If you are configuring an existing data source, select the data source name and click Configure to display the Adaptive Server Enterprise Driver Setup dialog box.

  3. If you are configuring a new data source, click Add to display a list of installed drivers. Select the iAnywhere Solutions 9 - Sybase ASE driver and click Finish to display the Adaptive Server Enterprise Driver Setup dialog box.

  4. On the General tab, provide the following connection information and then click Apply.

    • Data Source Name Type a string that identifies this Adaptive Server Enterprise data source configuration in the system information. Examples include Accounting or Sys11-Serv1.

    • Description Type an optional long description of a data source name. For example, My Accounting Database or System 11 on Server number 1.

    • Network Library Name Select the name of the network library. This specifies which network protocol to use. The values are Winsock and NamedPipes.

    • Network Address Type the network address. The value you specify depends on which network protocol is chosen under Network Library Name and on the Adaptive Server Enterprise server.

      If you choose Winsock for the Network Library Name, specify an IP address as follows: servername-or-IP-address, port-number. For example, if your network supports named servers, you may specify an address such as Sybaseserver, 5000. You may also specify the IP address directly such as 199.226.224.34, 5000.

      If you choose NamedPipes as the network protocol, you must specify the pipe address of the server. For example, \\machine1\sybase\pipe\query.

    • Database Name Type the name of the database to which you want to connect by default. If you do not specify a value, the default is the database defined by the system administrator for each user.

  5. Configure other settings in a manner appropriate for your application.

    Most settings can be left at their default values. For a list of key driver settings when using MobiLink, see Key settings for MobiLink and Adaptive Server Enterprise.

  6. At any point during the configuration process, you can click Test Connect to attempt to connect to the data source using the connection properties specified in the Driver Setup dialog box. A logon dialog box is displayed. For more information, see Connecting to a data source using a logon dialog box. Note that the information you enter in the logon dialog box during a test connect is not saved.

    • If the driver can connect, it releases the connection and displays a "connection established" message. Click OK.

    • If the driver cannot connect because of an improper environment or incorrect connection value, it will display an appropriate error message. Click OK.

  7. Click OK or Cancel. If you click OK, the values you have specified become the defaults when you connect to the data source. You can change these defaults by using this procedure to reconfigure your data source. You can override these defaults by connecting to the data source using a connection string with alternate values.


Connecting to a data source using a logon dialog box

Some ODBC applications display a Logon dialog box when you are connecting to a data source. In these cases, the data source name has already been specified.

In this dialog box, perform the following steps:

  1. In the Network Library field, select the name of the network library. This specifies which network protocol to use. Valid values are Winsock and NamedPipes.

  2. In the Network Address field, type the network address, which depends on the network protocol chosen under Network Library and on the Adaptive Server Enterprise server. If you choose Winsock, specify an IP address as follows: servername-or-IP-address, port-number. For example, if your network supports named servers, you may specify an address such as Sybaseserver, 5000. You may also specify the IP address directly such as 199.226.224.34, 5000.

    If you have chosen NamedPipes as the network protocol, you must specify the pipe address of the server. For example, \\machine1\sybase\pipe\query.

  3. If required, type your case-sensitive login ID.

  4. If required, type your case-sensitive password for the system.

  5. In the Database field, type the name of the database you want to access (case-sensitive) or select the name from the Database drop-down list, which displays the names you specified in the Adaptive Server Enterprise Driver Setup dialog box.

  6. Click OK to complete the logon and to update the values in the system information.


Connecting to a data source using a connection string

If your application requires a connection string to connect to a data source, you must specify the data source name that tells the driver which section in the system information to use for the default connection information. Optionally, you may specify attribute=value pairs in the connection string to override the default values stored in the system information. These values are not written to the system information.

You can specify either long or short names in the connection string. The connection string has the form:

DSN=data_source_name[;attribute=value[;attribute=value]...]

An example of a connection string for Adaptive Server Enterprise is:

DSN=SYS11 TABLES;SRVR=QESRVR;DB=PAYROLL;UID=JOHN;PWD=XYZZY

The following table gives the long and short names for each attribute, as well as a description. To configure a data source in the UNIX environment, you must edit the system information file. This file accepts only long names for attributes.

For information about editing this file, see Quick start for UNIX.

The defaults listed in the table are initial defaults that apply when no value is specified in either the connection string or in the data source definition in the system information. If you specified a value for the attribute when configuring the data source, that value is the default.

Most settings can be left at their default values. For a list of key driver settings when using MobiLink, see Key settings for MobiLink and Adaptive Server Enterprise.

Attribute | Description
AppCodePage (ACP) | AppCodePage has been replaced by IANAAppCodePage (IACP). See below.
ApplicationName (APP) | The name used by Sybase to identify your application.
ApplicationUsingThreads (AUT) ApplicationUsingThreads={0|1}. Ensures that the driver works with multi-threaded applications.

When set to 1 (the initial default), the driver is thread-safe.

When using the driver with single-threaded applications, you can set this option to 0 to avoid additional processing required for ODBC thread-safety standards.
ArraySize (AS) The number of rows the driver retrieves from the server for a fetch. This is not the number of rows given to the user. This increases performance by reducing network traffic.

The initial default is 50 rows.
Charset (CS) | The name of a character set. This character set must be installed on the Sybase server. The default is the setting on the Sybase server. For this driver to support Unicode, this attribute must be set to UTF-8. Refer to the Sybase server documentation for a list of valid character set names.
CursorCacheSize (CCS) The number of connections that the connection cache can hold. To set the connection cache, you must set the SelectMethod attribute to 1. Increasing the connection cache may increase performance of some applications but requires additional database resources.

The initial default is 1 (one cursor).
Database (DB) | The name of the database to which you want to connect.
DataSourceName (DSN) | A string that identifies a single connection to a Sybase database. Examples include "Accounting" or "Sys10-Serv1."
DefaultLongDataBuffLen (DLDBL) An integer value that specifies, in 1024-byte multiples, the maximum length of data fetched from a TEXT or IMAGE column. You will need to increase this value if the total size of any long data exceeds 1 MB.

The default is 1024.
DistributedTransactionModel (DTM) DistributedTransactionModel={XA Protocol0 21| Native OLE}. Determines which model is used for distributed transaction support. The initial default is XA Protocol.

Leave this option at the default setting.
EnableDescribeParam (EDP) EnableDescribeParam={0|1}. Determines whether the ODBC API function SQLDescribeParam is enabled.

When set to 0 (the initial default), SQLDescribeParam is disabled.

When set to 1, SQLDescribeParam is enabled, which allows an application to describe parameters in SQL statements and in stored procedure calls. To use this option, OptimizePrepare must be set to 0 or 1, and the SQL statement must not include long parameters. This attribute should be set to 1 when using Microsoft Remote Data Objects (RDO) to access data.
EnableQuotedIdentifiers (EQI) EnableQuotedIdentifiers={0|1}. Enables quoted identifiers.

When set to 0 (the initial default), quoted identifiers are disabled.

When set to 1, quoted identifiers are enabled.
FailoverNetworkAddress (FNA) Specifies the address of the High Availability (HA) Failover server to be used in the event of a connection loss. The driver detects the dropped connection and automatically reconnects to the HA Failover server specified by this attribute. This attribute is valid only for Sybase version 12 or higher servers that have the High Availability Failover feature enabled.

See the description of the Network Address attribute for an explanation of valid values.
IANAAppCodePage (IACP) Valid values for this attribute are listed in Values for IANAAppCodePage Connection String Attribute. The code page that you specify must be the same as the code page used by your application. The driver on UNIX determines the value of the application's code page by checking for an IANAAppCodePage value in the following order:

  • In the connection string

  • In the DataSource section of the system file (odbc.ini)

  • In the ODBC section of the system file (odbc.ini)

If no IANAAppCodePage value is found, the driver uses the default value of 4 (ISO 8859-1 Latin-1).

NOTE: The IANAAppCodePage connection string attribute replaces the AppCodePage connection string attribute in earlier versions of Connect for ODBC. The drivers are backwardly compatible with the AppCodePage attribute, but you must now use the IANAAppCodePage attribute.

InitializationString (IS) | InitializationString={Sybase set commands;...}. Supports the execution of Sybase commands at connect time. Multiple commands must be separated by semicolons.
InterfacesFile (IF) | Specifies the path name of the Interfaces file. If you do not specify a value for this attribute, but specify a value for the Interfaces File Server Name attribute, the driver looks for the path name of the Interfaces file in the Registry under HKEY_LOCAL_MACHINE\SOFTWARE\DataDirect\InterfacesFile. If this Registry value is empty, then the driver attempts to open the SQL.INI file found in the same directory as the driver and use it as the Interfaces file.
InterfacesFileServer Name (IFSN) | Specifies the name of the section in the Interfaces file that contains the network connection information for the Sybase server you want to access. The section name typically is the host name of the server that contains the Sybase Server you want to access.
Language (LANG) The national language. This language must be installed on the Sybase server.

The initial default is English.
LogonID (UID) | The default logon ID used to connect to your Sybase database. This ID is case-sensitive. A logon ID is required only if security is enabled on your database. If so, contact your system administrator to get your logon ID.
NetworkAddress (NA) The network address depends on which network protocol is chosen under Network Library Name and on the Sybase server. If you have chosen Winsock, specify an IP address as follows: "servername-or-IP-address, port-number". For example, if your network supports named servers, you may specify an address such as "Sybaseserver, 5000". You may also specify the IP address directly such as "199.226.224.34, 5000".

If you have chosen NamedPipes as the network protocol, you must specify the pipe address of the server. For example, "\\machine1\sybase\pipe\query".
NetworkLibraryName (NLM) NetworkLibraryName={Winsock|NamedPipes}. The name of the network library. This specifies which network protocol to use.

The initial default is Winsock.

This option has no effect on UNIX; on UNIX, TCP/IP is used.
OptimizePrepare (OP) OptimizePrepare={0|1|2|3}. Determines whether stored procedures are created on the server for calls to SQLPrepare.

For use with MobiLink, set this parameter to 2.

When set to 0, stored procedures are created for every call to SQLPrepare. This setting can result in decreased performance when processing statements that do not contain parameters.

When set to 1 (the initial default), the driver creates stored procedures only if the statement contains parameters. Otherwise, the statement is cached and run directly at the time of SQLExecute.

When set to 2, stored procedures are never created. The driver caches the statement, executes it directly at the time of SQLExecute, and reports any syntax or similar errors at the time of SQLExecute.

When set to 3, stored procedures are never created. This is identical to value 2 except that any syntax or similar errors are returned at the time of SQLPrepare instead of SQLExecute. Use this setting only if you must have syntax errors reported at the time of SQLPrepare.
PacketSize (PS) When set to -1, the driver computes the maximum allowable packet size on the first connect to the data source and saves the value in the system information.

When set to 0 (the initial default), the driver uses the default packet size as specified in the Sybase server configuration.

When set to x, an integer from 1 to 1024, the driver uses a packet size represented by x times 512 bytes. For example, PacketSize=6 means to set the packet size to 6 * 512 bytes (3072 bytes).

To take advantage of this connection attribute, you must configure the Sybase server for a maximum network packet size greater than or equal to the value you specified for PacketSize. For example:

sp_configure "maximum network packet size", 5120
reconfigure
Restart Sybase Server
NOTE: The ODBC specification specifies a connect option, SQL_PACKET_SIZE, that offers this same functionality. To avoid conflicts with applications that may set both the connection string attribute and the ODBC connect option, they have been defined as mutually exclusive. If PacketSize is specified, you will receive a message "Driver Not Capable" if you attempt to call SQL_PACKET_SIZE. If you do not set PacketSize, then application calls to SQL_PACKET_SIZE are accepted by the driver.
Password (PWD) | A case-sensitive password.
RaiseErrorPositionBehavior (REPB) RaiseErrorPositionBehavior={0|1}. Specifies when the error is returned and where the cursor is positioned when raiserror is encountered.

When set to 0 (the initial default), raiserror is handled separately from surrounding statements. The error is returned when raiserror is processed via SQLExecute, SQLExecDirect, or SQLMoreResults. The result set is empty.

When set to 1 (MS compatible), raiserror is handled with the next statement. The error is returned when the next statement is processed and the cursor is positioned on the first row of subsequent result set. This could result in multiple raiserrors being returned on a single execute.
SelectMethod (SM) SelectMethod={0|1}. Determines whether database cursors are used for SELECT statements.

When set to 0 (the initial default), database cursors are used. In some cases performance degradation can occur when performing large numbers of sequential SELECT statements because of the amount of overhead associated with creating database cursors.

When set to 1, SELECT statements are run directly without using database cursors, and the data source is limited to one active statement.

To set the connection cache, SelectMethod must be set to 1. For more information, see CursorCacheSize, above.
TightlyCoupled DistributedTransactions (TCDT) TightlyCoupledDistributedTransactions={0|1}. Determines whether the driver uses tightly coupled distributed transactions when connected to an Adaptive Server Enterprise version 12 or higher database. When set to 1 (the initial default), the driver uses this type of transaction and multiple connections within the same distributed transaction do not obey each other's locks.

When set to 0, the overall performance of the driver is better, but multiple connections within the same distributed transaction may hang each other because the connections do not obey each other's locks.

This attribute is valid only when the driver is enlisted in a distributed transaction or when it is connected to a Sybase version 12 or higher database. Otherwise, this attribute is ignored.
WorkstationID (WKID) | The workstation ID used by the client.
XAOpenStringParameters (XAOSP) | Specifies trace file names. Use the syntax -Ltrace_filename, where trace_filename specifies the name of two trace files that will be created. The first trace file will trace all XA call activities and will be named exactly as you specified. The second trace file will contain tracing of any enlistment and unenlistment procedures and will be named as you specified with a "driver" extension. For example, if you specify XAtrace as the file name, the driver will create two trace files-XAtrace and XAtrace.driver.


Data types

The following table shows how the Sybase data types are mapped to the standard ODBC data types.

Adaptive Server Enterprise | ODBC
binary | SQL_BINARY
bit | SQL_BIT
char | SQL_CHAR
datetime | SQL_TYPE_TIMESTAMP
decimal | SQL_DECIMAL
float | SQL_FLOAT
image | SQL_LONGVARBINARY
int | SQL_INTEGER
money | SQL_DECIMAL
numeric | SQL_NUMERIC
real | SQL_REAL
smalldatetime | SQL_TYPE_TIMESTAMP
smallint | SQL_SMALLINT
smallmoney | SQL_DECIMAL
sysname | SQL_VARCHAR
text | SQL_LONGVARCHAR
timestamp | SQL_TYPE_TIMESTAMP
tinyint | SQL_TINYINT
varbinary | SQL_VARBINARY
varchar | SQL_VARCHAR
Adaptive Server Enterprise 12.5
The iAnywhere Solutions ODBC driver supports extended new limits (XNL) for character and binary columns—columns with lengths greater than 255.

Previous Next


Unicode support

The Sybase Wire Protocol driver supports Unicode if the Sybase data source you are using to connect to the database is configured to use the UTF-8 character set. The data source is configured to use the UTF-8 character set by either setting the Charset attribute to UTF-8 in the connection string or in the odbc.ini file. See Table 14-1 for more information about the Charset attribute.

If the UTF-8 character set is installed, the driver maps the Sybase data types as follows:

ASE data type... | Mapped to...
Char | SQL_WCHAR
Unichar | SQL_WCHAR
Univarchar | SQL_WVARCHAR
Varchar | SQL_WVARCHAR
Text | SQL_WLONGVARCHAR

This driver supports the Unicode ODBC W (Wide) function calls, such as SQLConnectW. This allows the Driver Manager to transmit these calls directly to the driver. Otherwise, the Driver Manager would incur the additional overhead of converting the W calls to ANSI function calls, and vice versa.


Default Unicode mapping

The default Unicode mapping for an application's SQL_C_WCHAR variable is:

Platform | Default Unicode Mapping
Windows | UTF-16
AIX | UTF-8
HP-UX | UTF-8
Solaris | UTF-8
Linux | UTF-8


Web Links Browse Collapse Expand PDF Previous Next

ODBC Drivers for MobiLink and Remote Data Access

iAnywhere Solutions ODBC Driver for Sybase Adaptive Server Enterprise

Supported features

This section lists features supported by the ODBC driver for Sybase Adaptive Server Enterprise.


Web Links Browse Collapse Expand PDF Previous Next

ODBC Drivers for MobiLink and Remote Data Access

iAnywhere Solutions ODBC Driver for Sybase Adaptive Server Enterprise

Supported features

Support for query timeout

The Adaptive Server Enterprise driver supports the QUERY_TIMEOUT statement attribute on Windows only.


Number of connections and statements supported

The Sybase database system supports multiple connections and multiple statements per connection. If SelectMethod=1, Sybase data sources are limited to one active statement in manual commit mode.


iAnywhere Solutions ODBC Driver for Oracle

About this chapter

This chapter describes how to configure and use the iAnywhere Solutions ODBC driver for Oracle databases.

Introduction
Key settings for MobiLink and Oracle
Configuring data sources
Connecting to a Data Source Using a Logon Dialog Box
Connecting to a data source using a connection string
Data types
Unicode support
Default Unicode Mapping
Stored procedure results
Supported features


Introduction

The iAnywhere Solutions ODBC driver for Oracle supports Oracle 8.1.6 and higher database systems (including Oracle 9i) on UNIX and Windows.

Driver requirements

The Oracle driver is a wire protocol driver, which means that there is no additional client software required.


Key settings for MobiLink and Oracle

There is one iAnywhere Solutions Oracle driver available: the Oracle Wire Protocol driver.

The iAnywhere Solutions Oracle Wire Protocol ODBC driver does not require Oracle client software.

The following are key settings for the Oracle wire protocol driver:

  • Basic connection settings Set the following basic connection settings:

    • Data source name This value is used to identify the data source. On Windows, it is located on the General tab. On UNIX, this attribute is called DataSourceName (DSN).

    • Host This value provides the location of your Oracle server. On Windows, it is located on the General tab. On UNIX, this attribute is called HostName (HOST).

    • Port Identifies the port number of your Oracle listener. On Windows, it is located on the General tab. On UNIX, this attribute is called PortNumber (PORT).

    • SID Identifies the Oracle database system ID. On Windows, it is located on the General tab. On UNIX, this attribute is called Sid (SID).

    • Default user name This must correspond to a valid user name on the server. On Windows, it is located on the Advanced tab. On UNIX, this attribute is called LoginID (UID).

    • Default Buffer Size for Long/LOB Columns(DLDBL) This parameter specifies (in Kb) the size of the largest LONG BINARY or LONG VARCHAR column value being synchronized. The default setting is 1024, which is equivalent to 1 Mb. If you are synchronizing long columns with entries larger than this, set the value higher.

      This parameter appears on the Advanced tab of the Windows driver ODBC setup dialog. On UNIX, this attribute is called DefaultLongDataBuffLen (DLDBL).

For complete information about settings for the Oracle driver, see Connecting to a data source using a connection string.


Configuring data sources

On Windows, data sources are configured and modified through the ODBC Administrator.

In the UNIX environment, there is no ODBC Administrator. To configure a data source in the UNIX environment, you must edit the system information file using the attributes in Values for IANAAppCodePage Connection String Attribute. You must also edit this file to perform a translation.

For more information, see The system information file (.odbc.ini).

toggle To configure an Oracle data source

  1. Start the ODBC Administrator to display a list of data sources.

  2. If you are configuring an existing data source, select the data source name and click Configure to display iAnywhere Solutions 9 - Oracle Wire Protocol Driver Setup.

    If you are configuring a new data source, click Add to display a list of installed drivers. Select the Oracle Wire Protocol driver of your choice and click Finish to display the iAnywhere Solutions 9 - Oracle Wire Protocol Driver Setup.

    NOTE: The General tab displays only fields that are required for creating a data source. The fields on all other tabs are optional, unless noted otherwise.

  3. On the General tab, provide the following information and then click Apply.

    • Data Source Name Type a string that identifies this Oracle Wire Protocol data source configuration in the system information. Examples include "Accounting" or "Oracle-Serv1."

    • Description Type an optional long description of a data source name. For example, "My Accounting Database" or "Oracle on Server number 1."

    • Host Type either the name or the IP address of the server to which you want to connect. For example, if your network supports named servers, you can specify a server name such as Oracleserver. Or, you can specify an IP address such as 199.226.224.34.

    • Port number Type the port number of your Oracle listener. Check with your database administrator for the correct number.

    • SID Type the Oracle System Identifier that refers to the instance of Oracle running on the server.

  4. Optionally, click the Advanced tab to specify data source settings. On this tab, provide any of the following optional information; then, click Apply.

    • Default User Name Type the default user name used to connect to your Oracle database. A default user name is required only if security is enabled on your database. Your ODBC application may override this value or you may override this value in the logon dialog box or connection string.

    • Array Size Type the number of bytes the driver uses for fetching multiple rows. Values can be an integer from 1 up to 4 GB; the default is 60000. Larger values increase throughput by reducing the number of times the driver fetches data across the network. Smaller values increase response time, as there is less of a delay waiting for the server to transmit data.

    • Lock Timeout Type 0, -1, or any integer value greater than 0. The value 0 specifies that Oracle does not wait for a lock to be freed before raising an error when processing a Select...For Update statement. The value -1 waits forever. When connected to an Oracle9i server, you can specify the number of seconds to wait by setting this option to an integer greater than 0. If you are connected to an Oracle8i or lower server, any value greater than 0 is equivalent to the value -1.

    • Default Buffer Size for Long/LOB Columns (in Kb) Type an integer value that specifies the maximum length of data fetched from Long/LOB columns. The value must be in multiples of 1024 (for example, 1024, 2048). The default is 1024 KB. You will need to increase this value if the total size of any long data exceeds 1 MB.

    • Local Timezone Offset This feature is not supported. Do not enter anything.

    • Enable Timestamp with Timezone This feature is not supported. Do not select it. By default, the check box is not selected.

    • Catalog Options Select this check box if you want the result column REMARKS for the catalog functions SQLTables and SQLColumns, and the result column COLUMN_DEF for the catalog function SQLColumns to have meaning for Oracle. Selecting this box reduces the performance of your queries. By default, the check box is not selected, which returns SQL_NULL_DATA for the result columns COLUMN_DEF and REMARKS.

    • Enable SQLDescribeParam Select this check box to enable the SQLDescribeParam function, which results in all parameters being described with a data type of SQL_VARCHAR. This option should be selected when using Microsoft Remote Data Objects (RDO) to access data. By default, the check box is not selected.

    • Application Using Threads This check box must be selected. Selecting this option ensures that the driver works with multi-threaded applications. By default, the check box is selected.

    • Procedure Returns Results Select this check box to enable the driver to return result sets from stored procedures/functions. If this check box is selected and you execute a stored procedure that does not return result sets, you will incur a small performance penalty. By default, the check box is not selected.

    • Enable Static Cursors for Long Data: Select this check box to enable the driver to support long columns when using a static cursor. Selecting this check box causes a performance penalty at the time of execution when reading long data. By default, the check box is not selected.

      NOTE: You must select this check box if you want to persist a result set that contains LONG data into an XML data file.

    • Use Current Schema for SQLProcedures Select this check box to specify only the current user when executing SQLProcedures. When this check box is selected (the default), the call for SQLProcedures is optimized, but only procedures owned by the user are returned.

    • Catalog Functions Include Synonyms By default, the check box is selected.

    • Describe at Prepare Select this check box to enable the driver to describe the SQL statement at prepare time. By default, the check box is not selected.

    • Translate Click Translate to display the Select Translator dialog box, which lists the translators specified in the ODBC Translators section of the system information. DataDirect provides a translator named "OEM TO ANSI" that translates your data from the IBM PC character set to the ANSI character set. Select a translator; then, click OK to close this dialog box and perform the translation.

  5. At any point during the configuration process, you can click Test Connect to attempt to connect to the data source using the connection properties specified in the Driver Setup dialog box. A logon dialog box is displayed. Note that the information you enter in the logon dialog box during a test connect is not saved. If the driver can connect, it releases the connection and displays a "connection established" message. Click OK. If the driver cannot connect because of an improper environment or incorrect connection value, it will display an appropriate error message. Click OK.


Connecting to a Data Source Using a Logon Dialog Box

Some ODBC applications display a logon dialog box when you are connecting to a data source. In these cases, the data source name has already been specified.

In this dialog box, perform the following steps:

In the Host field, type either the name or the IP address of the server to which you want to connect.

In the Port Number field, type the number of your Oracle listener. Check with your database administrator for the correct number.

In the SID field, type the Oracle System Identifier that refers to the instance of Oracle running on the server.

If required, type your Oracle user name.

If required, type your Oracle password.

Click OK to log on to the Oracle database installed on the server you specified and to update the values in the system information.

NOTE: Oracle has a feature that allows you to connect to Oracle via the operating system user name and password. To connect, use a slash ( / ) for the user name and leave the password blank. To configure the Oracle server, refer to the Oracle server documentation.


Connecting to a data source using a connection string

If your application requires a connection string to connect to a data source, you must specify the data source name that tells the driver which section in the system information to use for the default connection information. Optionally, you may specify attribute=value pairs in the connection string to override the default values stored in the system information. These values are not written to the system information.

You can specify either long or short names in the connection string. The connection string has the form:

DSN=data_source_name[;attribute=value[;attribute=value]...]

An example of a connection string for Oracle is:

DSN=Accounting;SRVR=QESRVR;UID=JOHN;PWD=XYZZY

If the server name contains a semicolon, enclose it in quotation marks:

DSN=Accounting;SRVR="QE;SRVR";UID=JOHN;PWD=XYZZY

To configure a data source in the UNIX environment, you must edit the system information file. This file accepts only long names for attributes.

For more information, see Quick start for UNIX.

The defaults listed in the table are initial defaults that apply when no value is specified in either the connection string or in the data source definition in the system information. If you specified a value for the attribute when configuring the data source, that value is the default.

Most settings can be left at their default values. For a list of key driver settings when using MobiLink, see Key settings for MobiLink and Oracle.

Attribute | Description
AppCodePage (ACP) | AppCodePage has been replaced by IANAAppCodePage (IACP). See below.
ApplicationUsingThreads (AUT) ApplicationUsingThreads={0 | 1}. Ensures that the driver works with multi-threaded applications.

When set to 1 (the initial default), the driver is thread-safe.

When using the driver with single-threaded applications, you can set this option to 0 to avoid additional processing required for ODBC thread-safety standards.

Set to 1 for DSNs used with MobiLink server.
ArraySize (AS) The number of bytes the driver uses for fetching multiple rows. Values can be an integer from 1 up to 4 GB. Larger values increase throughput by reducing the number of times the driver fetches data across the network. Smaller values increase response time, as there is less of a delay waiting for the server to transmit data.

The initial default is 60,000.
CachedCursorLimit (CCL) | The number of Oracle Cursor Identifiers that the driver stores in cache. A cursor identifier is needed for each open result set. When a result set is closed the driver stores the identifier in its cache, up to the limit specified, rather than tell the Oracle database server to close the cursor identifier. When a new cursor identifier is needed, the driver takes one from its cache, if one is available. Cached cursor identifiers are closed when the connection is closed. The initial default is 32.
CachedDescriptionLimit (CDL) The number of descriptions, from 0 to 65535, that the driver saves for SELECT statements. These descriptions include number of columns, data type, length, and scale for each column. The matching is done by an exact-text match through the FROM clause. The default is 0 because of the overhead of parsing the SQL statement. Using the FROM clause, applications that issue a SELECT statement that returns a few rows repeatedly can realize a significant performance benefit when using this option.

NOTE: If the statement contains a UNION or a nested SELECT, the description is not cached.

CatalogIncludesSynonyms (CIS) CatalogIncludesSynonyms={0 | 1}. Determines whether synonyms are included in calls to SQLProcedures, SQLStatistics, and SQLProcedureColumns. When set to 1, synonyms are included in these calls. When set to 0, synonyms are not included (a non-standard behavior) and performance is improved.

The ODBC specification requires that synonyms be included in the result sets of these catalog calls when the calls are unqualified. Most users do not qualify queries; therefore, synonyms are included by default, which slows down performance. This option allows you to improve performance by not including synonyms. The initial default is 1.

CatalogOptions (CO) | CatalogOptions={0 | 1}. Determines whether the result column REMARKS for the catalog functions SQLTables and SQLColumns and COLUMN_DEF for the catalog function SQLColumns have meaning for Oracle. If you want to obtain the actual default value, set CO=1. The initial default is 0.
DataSourceName (DSN) | A string that identifies an Oracle data source configuration in the system information. Examples include "Accounting" or "Oracle-Serv1."
DefaultLongDataBuffLen (DLDBL) | An integer value that specifies, in 1024-byte multiples, the maximum length of data fetched from Long/LOB columns. You will need to increase this value if the total size of any long data exceeds 1 MB. The default is 1024.
DescribeAtPrepare (DAP) DescribeAtPrepare={0 | 1}. Determines whether the driver describes the SQL statement at prepare time.

When set to 0 (the initial default), the driver does not describe the SQL statement at prepare time.
EnableDescribeParam (EDP) EnableDescribeParam={0 | 1}. Determines whether the ODBC API function SQLDescribeParam is enabled, which results in all parameters being described with a data type of SQL_VARCHAR.

This attribute should be set to 1 when using Microsoft Remote Data Objects (RDO) to access data. The initial default is 0.
EnableScrollableCursors (ESC) | EnableScrollableCursors={0 | 1}. Enables scrollable cursors for the data source. Both Keyset and Static cursors are enabled. The initial default is 1.
EnableStatic CursorsForLongData (ESCLD) EnableStaticCursorsForLongData={0 | 1}. Determines whether the driver supports long columns when using a static cursor. Using this attribute causes a performance penalty at the time of execution when reading long data.

The initial default is 0.
EnableTimestampWithTimezone (ETWT) | EnableTimestampWithTimezone={0 | 1}. Determines whether the driver exposes timestamps with time zones to the application. When set to 1, the driver issues an "ALTER SESSION" at connection time to modify NLS_TIMESTAMP_TZ_FORMAT. NLS_TIMESTAMP_TZ_FORMAT is changed to the ODBC definition of a timestamp literal with the addition of the timezone literal: 'YYYY-MM-DD HH24:MI:SSXFF TZR'. The initial default is 0.
HostName (HOST) | HostName={servername | IP_address}. Identifies the Oracle server to which you want to connect. If your network supports named servers, you can specify a host name such as Oracleserver. Otherwise, specify an IP address such as 199.226.224.34.
IANAAppCodePage (IACP) Valid values for this attribute are listed in Values for IANAAppCodePage Connection String Attribute. The code page that you specify must be the same as the code page used by your application. The driver on UNIX determines the value of the application's code page by checking for an IANAAppCodePage value in the following order:

  • In the connection string

  • In the DataSource section of the system file (odbc.ini)

  • In the ODBC section of the system file (odbc.ini)

If no IANAAppCodePage value is found, the driver uses the default value of 4 (ISO 8859-1 Latin-1).

NOTE: The IANAAppCodePage connection string attribute replaces the AppCodePage connection string attribute in earlier versions of Connect for ODBC. The drivers are backwardly compatible with the AppCodePage

LocalTimeZoneOffset (LTZO) | The default for this attribute is "" (empty string). This means that the driver determines local time zone information from the operating system. If it is not available from the operating system, the driver defaults to using the setting on the Oracle server. Other possible values are specified as offsets from GMT in the following format: (-)HH:MM. For example, "-08:00" equals GMT minus 8 hours. The driver uses the value of the attribute to issue an "ALTER SESSION" for the local time zone at connect time.
LockTimeOut (LTO) LockTimeOut={0 | -1}. Determines whether Oracle should wait for a lock to be freed before raising an error when processing a Select...For Update statement.

When set to 0, Oracle does not wait.

When set to -1 (the initial default), Oracle waits forever.
LogonID (UID) | The default logon ID (user name) that the application uses to connect to your Oracle database. A logon ID is required only if security is enabled on your database. If so, contact your system administrator to get your logon ID.
Password (PWD) | The password that the application uses to connect to your Oracle database.
PortNumber (PORT) | Identifies the port number of your Oracle listener. The initial default value is 1521. Check with your database administrator for the correct number.
ProcedureRetResults (PRR) ProcedureRetResults={0 | 1}. Determines whether the driver returns result sets from stored procedure functions.

When set to 0 (the initial default), the driver does not return result sets from stored procedures.

When set to 1, the driver returns result sets from stored procedures. When set to 1 and you execute a stored procedure that does not return result sets, you will incur a small performance penalty. For details, see Stored procedure results.
Sid (SID) | The Oracle System Identifier that refers to the instance of Oracle running on the server. This item is required when connecting to servers that support more than one instance of an Oracle database.
UseCurrentSchema (UCS) UseCurrentSchema={0 | 1}. Determines whether the driver specifies only the current user when executing SQLProcedures.

When set to 0, the driver does not specify only the current user.

When set to 1 (the initial default), the call for SQLProcedures is optimized, but only procedures owned by the user are returned.


Data types

The following table shows how the Oracle data types are mapped to the standard ODBC data types.

Oracle | ODBC
Bfile | SQL_LONGVARBINARY1, 2
BLOB | SQL_LONGVARBINARY2
Char | SQL_CHAR
CLOB | SQL_LONGVARCHAR2
Date | SQL_TYPE_TIMESTAMP
Long | SQL_LONGVARCHAR
Long Raw | SQL_LONGVARBINARY
Number | SQL_DOUBLE
Number(p,s) | SQL_DECIMAL
Raw | SQL_VARBINARY
Varchar1 | SQL_VARCHAR

1 Valid when connecting to Oracle 8 servers; these data types support output parameters to stored procedures.

The Oracle Wire Protocol driver does not support any Abstract Data Types. When the driver encounters an Abstract Data Type during data retrieval, it will return an Unknown Data Type error (SQL State HY000).


Unicode support

The Oracle Wire Protocol driver automatically determines whether the Oracle database is a Unicode database.

The Oracle Wire Protocol driver maps the Oracle data types as follows:

Oracle Data Type | Mapped to
Char | SQL_WCHAR
Varchar2 | SQL_WVARCHAR
Long | SQL_WLONGVARCHAR
Clob | SQL_WLONGVARCHAR

This driver supports the Unicode ODBC function calls, called W (Wide) calls (for example, SQLConnectW). These calls are used to accept Unicode datastreams.


Default Unicode Mapping

The default Unicode mapping for an application's SQL_C_WCHAR variable is as follows:

Platform | Default Unicode Mapping
Windows | UTF-16
AIX | UTF-8
Solaris | UTF-8
Linux | UTF-8


Stored procedure results

When the connection option ProcedureRetResults is active, the driver returns result sets from stored procedures/functions. In addition, SQLGetInfo(SQL_MULT_RESULTS_SETS) will return Y and SQLGetInfo(SQL_BATCH_SUPPORT) will return SQL_BS_SELECT_PROC. If this option is on and you execute a stored procedure that does not return result sets, you will incur a small performance penalty.

This feature requires that stored procedures be in a certain format. First, a package must be created to define all of the cursors used in the procedure, then the procedure can be created using the new cursor. For example:

Create or replace package GEN_PACKAGE as
CURSOR G1 is select CHARCOL from GTABLE2;
type GTABLE2CHARCOL is ref cursor return G1%rowtype;
end GEN_PACKAGE;
Create or replace procedure GEN_PROCEDURE1 (
  rset IN OUT GEN_PACKAGE.GTABLE2
  CHARCOL, icol INTEGER) as
begin
   open rset for select CHARCOL from GTABLE2
     where INTEGERCOL <= icol order by INTEGERCOL;
end;

When executing the stored procedures with result sets, do not include the result set arguments in the list of procedure arguments. The previously described example would be executed as:

{call GEN_PROCEDURE1 (?)}

where ? is the parameter for the icol argument.

For more information, consult your Oracle SQL manual.


Web Links Browse Collapse Expand PDF Previous Next

ODBC Drivers for MobiLink and Remote Data Access

iAnywhere Solutions ODBC Driver for Oracle

Supported features

This section lists features supported by the iAnywhere Solutions 9 — Oracle Wire Protocol ODBC driver.


Isolation and lock levels supported

Oracle supports isolation level 1 (read committed) and isolation level 3 (serializable isolation ). Oracle supports record-level locking.


ODBC conformance level

For a list of the API functions supported by the Oracle Wire Protocol driver, see ODBC Functions.

The Oracle Wire Protocol driver also support the following functions:

  • SQLColumnPrivileges

  • SQLDescribeParam (if EnableDescribeParam=1)

  • SQLForeignKeys

  • SQLPrimaryKeys

  • SQLProcedures

  • SQLProcedureColumns

  • SQLSetPos

  • SQLTablePrivileges

The drivers support the core SQL grammar.


Web Links Browse Collapse Expand PDF Previous Next

ODBC Drivers for MobiLink and Remote Data Access

iAnywhere Solutions ODBC Driver for Oracle

Supported features

Number of connections and statements supported

The Oracle driver supports multiple connections and multiple statements per connection.


iAnywhere Solutions ODBC Driver for DB2

About this chapter

This chapter describes how to configure and use the iAnywhere Solutions ODBC driver for IBM DB2 databases.

Introduction
Key settings for MobiLink and DB2
Configuring data sources
Connecting to a data source using a logon dialog box
Connecting to a data source using a connection string
Data types
Supported features
Unicode support
Default Unicode mapping


Introduction

The iAnywhere Solutions ODBC driver for DB2 (the "DB2 driver") supports DB2 Universal Database versions 7 and 8 on UNIX and Windows.

Note: When used with DB2 UDB versions 7.1 or 7.2, this driver does not support the DB2 BLOB data type, and only supports 32 Kb CLOB data. If you are using these data types with DB2 7.1 or 7.2, you should use the IBM DB2 UDB 7.2 driver (version 7.01.00.65 or 7.02.00.05).

Driver requirements

The server requirement for all platforms is the same. The UDB DB2 database must be installed as the Server Version (not the Local Version).

The DB2 driver is a wire protocol driver, which means that there is no additional client software required.


Key settings for MobiLink and DB2

The iAnywhere Solutions ODBC driver for IBM DB2 does not require any DB2 client software. The following are key settings for DB2. Other parameters are available and described elsewhere, but are of less importance.

  • Basic connection settings Set the following basic connection settings:

    • Data Source Name (DSN) This value is used to identify the data source.

    • Ip Address (IP) The IP address of the machine where the catalog tables are stored.

    • Default User ID (UID) This default user ID must correspond to a valid user name on the server.

    • Tcp Port The port number of the DB2 DRDA listener process on the server host.

    • Database Name The name of the database to which you want to connect.

  • WithHold (WH) For use with MobiLink, this attribute must be set to 1 in the ODBC configuration file.

For complete information about settings for DB2, see Connecting to a data source using a connection string.

Bind packages

Users must create the DB2 bind packages on every server to which they intend to connect with the driver. The driver will not work properly with any server that does not have the packages created. The UNIX version of the driver is provided with a program that creates the bind package. It is the equivalent of the Create Package button on the Bind tab of the DB2 driver setup on Windows.

The bind program is shipped with SQL Anywhere Studio, and can be found in the drivers/lib directory under your SQL Anywhere directory. You must export LD_LIBRARY_PATH or LIBPATH before creating bind packages.

For more information, see Configuring data sources.


Configuring data sources

To configure a data source in the UNIX environment, you must edit the system information file using the attributes in Values for IANAAppCodePage Connection String Attribute. You must also edit this file to perform a translation.

For more information, see Quick start for UNIX.

Creating DB2 bind packages

Users must create the DB2 bind packages on every server to which they intend to connect with the driver. The driver will not work properly with any server that does not have the packages created. The UNIX version of the driver is provided with a program that creates the bind package. It is the equivalent of the Create Package button on the Bind tab of the DB2 driver setup.

The bind program is shipped with SQL Anywhere Studio, and can be found in the drivers/lib directory under your SQL Anywhere directory. You must export LD_LIBRARY_PATH or LIBPATH before creating bind packages.

toggle To bind a package (UNIX)

  • At a command prompt, enter the following command:

    bind19 dsn

    where dsn is the ODBC data source name. You are prompted for a user ID and password if they are not stored in the system information file.

toggle To configure a DB2 Wire Protocol data source (Windows)

  1. Start the ODBC Administrator to display a list of data sources.

  2. If you are configuring an existing data source, select the data source name and click Configure to display the ODBC DB2 Wire Protocol Driver Setup dialog box.

    If you are configuring a new data source, click Add to display a list of installed drivers. Select the DB2 Wire Protocol driver and click Finish to display the ODBC DB2 Wire Protocol Driver Setup dialog box.

    NOTE: The General and Bind tabs display only fields that are required for creating a data source. The fields on other tabs are optional, unless noted otherwise.

  3. On the General tab, provide the following information and click Apply.

    • Data Source Name Type a string that identifies this DB2 data source configuration in the system information. If you are creating a new data source definition, type a unique name of up to 32 characters. If you specify the name of an existing data source definition, the new settings will replace the existing ones.

    • Description Type an optional descriptive comment for this data source definition. ODBC-related applications and development tools often display this description with the data source name when they display a list of data sources. If you want to include a description for this data source definition, type a comment of up to 64 characters.

    • Ip Address Type the IP (Internet Protocol) address of the machine where the catalog tables are stored. Specify the address using the machine's numeric address (for example, 123.456.78.90) or specify its host name. If you enter a host name, the driver must find this name (with the correct address assignment) in the HOSTS file on the workstation or in a DNS server.

    • Tcp Port Type the port number that is assigned to the DB2 DRDA listener process on the server host machine. Specify either this port's numeric address or its service name (5179 is the default port address). If you specify a service name, the driver must find this name (with the correct port assignment) in the SERVICES file on the workstation.

    • Location Name This field is valid only if you are connecting to a DB2 database running on OS/390 or AS/400. This field is disabled if the Database Name field is populated.

    • Collection This field is valid only if you are connecting to a DB2 database running on OS/390 or AS/400. This field is disabled if the Database Name field is populated.

    • Database Name This field is valid only if you are connecting to a DB2 database running on UNIX or NT. Type the name of the database to which you want to connect. NOTE: This field is disabled if the Location Name field is populated.

    • Package Type the name of the package that the driver uses to process dynamic SQL for applications that use this data source definition. The default name is DDODBC.

    • Default User ID Type the default logon ID used to connect to your DB2 database. Your ODBC application may override this value or you may override it in the logon dialog box or connection string. This field is optional.

  4. Optionally, click the Advanced tab to specify data source settings.

    On this tab, provide any of the following optional information and click Apply.

    • With Hold Cursors This option specifies the cursor behavior for the application used with this data source-either DB2 closes all open cursors (Delete cursors) after a commit or rollback or leaves them open (Preserve cursors). When this check box is selected (the default), the cursor behavior is Preserve (SQLGetInfo( ) returns SQL_CB_PRESERVE for SQL_COMMIT_CURSOR_BEHAVIOR). When the check box is not selected, the cursor behavior is Delete ( SQLGetInfo( ) returns SQL_CB_DELETE). For information about this function, refer to the Microsoft ODBC API.

    • Add to Create Table Type a string that is automatically added to all Create Table statements. This field is primarily for users who need to add an "in database" clause.

    • Alternate ID Type a value to be substituted at connect time for the current schema. This sets the default qualifier for unqualified object names in SQL statements. If the attempt to change the current schema fails, the connection fails with "Invalid value for Alternate ID." DB2 permissions should be set to SYSADM. (Not valid for AS/400 V4R5 and V5R1.)

    • Translate Click Translate to display the Select Translator dialog box, which lists the translators specified in the ODBC Translators section of the system information. DataDirect provides a translator named "OEM to ANSI" that translates your data from the IBM PC character set to the ANSI character set.

      Select a translator and click OK to close this dialog box and perform the translation.

  5. Click the Bind tab to configure options for creating bind packages.

    The Bind tab allows you to create the bind packages on the server that will be used by the driver. The tab also allows you to specify the behavior of the package. You must create the bind packages on every server to which you intend to connect with the driver. The driver will not work properly with any server that does not have the packages created.

  6. On the Bind tab, provide the following information and click Apply.

    • Grant Execute Select this check box to grant execute privileges on the package that you are creating. The default value is grant execute privileges on the package to PUBLIC. You can also specify to whom to grant execute privileges.

    • Isolation Level Select the method by which locks are acquired and released by the system. Valid values are:

      • All Prevents any other process from accessing data that your application has read or modified. All read or modified data is locked until the end of the transaction.

      • Change Allows other processes to read from the database. Only modified data is locked until the end of the transaction.

      • Cursor Stability (the default) Allows other processes to change a row that your application has read if the cursor is not on the row you want to change. Prevents other processes from changing records that your application has changed until your program commits them or terminates. Prevents your program from reading a modified record that has not been committed by another process.

      • No Commit Allows your program to read modified records even if they have not been committed by another person. (On AS/400, this is the only the only isolation level that works for collections that do not have journaling enabled.)

      • Repeatable Read Prevents other processes from changing records that are read or changed by your application (including phantom records) until your program commits them or terminates. Prevents the application from reading modified records that have not been committed by another process. If your program opens the same query during a single unit of work under this isolation level, the results table will be identical to the previous table; however, it can contain updates made by your program.

    • Package Owner Package Owner: Type the AuthID assigned to the package. This DB2 AuthID must have authority to execute all the SQL in the package.

    • Dynamic Sections Type the number of statements that the DB2 Wire Protocol driver package can prepare for a single user. The default is 100.

    • Create Package Click to configure a package. When you click the Create Package button, a logon dialog is displayed. Enter your user ID and password; then, click Login. A message similar to the following is displayed if the package was not created successfully:

      Program name DDODBC not found in plan. Please bind the
required packages through the DB2 driver setup screen

  7. At any point during the configuration process, you can click Test Connect to attempt to connect to the data source using the connection properties specified in the Driver Setup dialog box. A logon dialog box is displayed; see Connecting to a data source using a logon dialog box. Note that the information you enter in the logon dialog box during a test connect is not saved.

    • If the driver can connect, it releases the connection and displays a "connection established" message. Click OK.

    • If the driver cannot connect because of an improper environment or incorrect connection value, it will display an appropriate error message. Click OK.

  8. Click OK or Cancel. If you click OK, the values you have specified become the defaults when you connect to the data source. You can change these defaults by using this procedure to reconfigure your data source. You can override these defaults by connecting to the data source using a connection string with alternate values.


Connecting to a data source using a logon dialog box

On Windows, some ODBC applications display a logon dialog box when you are connecting to a data source. In these cases, the data source name has already been specified. For DB2, the dialog box is as follows:

In this dialog box, perform the following steps:

  1. In the IP Address field, type the IP address of the machine where the catalog tables are stored. Specify the address using the machine's numeric address (for example, 123.456.78.90) or specify its host name. If you enter a host name, the driver must find this name (with the correct address assignment) in the HOSTS file on the workstation or in a DNS server.

  2. In the TCP Port field, type the port number that is assigned to the DB2 server on the machine where the catalog tables are stored. Specify either this port's numeric address or its service name (5179 is the default port address). If you specify a service name, the driver must find this name (with the correct port assignment) in the SERVICES file on the workstation.

  3. Click OK to complete the logon and to update the values in the system information.


Connecting to a data source using a connection string

If your application requires a connection string to connect to a data source, you must specify the data source name that tells the driver which section in the system information to use for the default connection information. Optionally, you may specify attribute=value pairs in the connection string to override the default values stored in the system information. These values are not written to the system information.

You can specify either long or short names in the connection string. The connection string has the form:

DSN=data_source_name[;attribute=value[;attribute=value]...]

An example of a connection string for DB2 is:

DSN=DB2MVS;LOC=TESTMVSDB2;UID=JOHN;PWD=XYZZY

To configure a data source in the UNIX environment, you must edit the system information file. This file accepts only long names for attributes.

For more information, see Quick start for UNIX.

The defaults listed in the table are initial defaults that apply when no value is specified in either the connection string or in the data source definition in the system information. If you specified a value for the attribute when configuring the data source, that value is the default.

Most settings can be left at their default values. For a list of key driver settings when using MobiLink, see Key settings for MobiLink and DB2. For other information, about using ODBC drivers with MobiLink, see [external link] http://www.ianywhere.com/developer/technotes/odbc_mobilink.html.

Attribute | Description
AddStringTo CreateTable (ASCT) | A string that is automatically added to all Create Table statements. This field is primarily for users who need to add an "in database" clause.
AlternateID (AID) | This connection string changes the current schema to a user-specified value at connect time. It sets the default qualifier for unqualified object names in SQL statements. If the attempt to change the current schema fails, the connection fails with "Invalid value for Alternate ID." DB2 permissions should be set to SYSADM. (Not valid for AS/400 V4R5 and V5R1.)
AppCodePage (ACP) | AppCodePage has been replaced by IANAAppCodePage (IACP). See below.
Collection (COL) | A name that identifies a group of packages. This attribute is valid only if you are connecting to DB2 on OS/390.
Database (DB) | The name of the database to which you want to connect.
DataSourceName (DSN) | A string that identifies a DB2 data source configuration in the system information. Examples include "Accounting" and "DB2-Serv1".
DynamicSections (DS) | The number of statements that the DB2 driver package can prepare for a single user. The initial default is 32.
GrantAuthid (GA) A value that determines to whom execute privileges are granted.

The default value is grant execute privileges on the package to PUBLIC.
GrantExecute (GE) GrantExecute={0|1}. Indicates whether or not to grant privileges on the package that you are creating.

When set to 0, privileges are not granted.

When set to 1, privileges are granted.
IANAAppCodePage (IACP) Valid values for this attribute are listed in Values for IANAAppCodePage Connection String Attribute. The code page that you specify must be the same as the code page used by your application. The driver on UNIX determines the value of the application's code page by checking for an IANAAppCodePage value in the following order:

  • In the connection string

  • In the DataSource section of the system file (odbc.ini)

  • In the ODBC section of the system file (odbc.ini)

If no IANAAppCodePage value is found, the driver uses the default value of 4 (ISO 8859-1 Latin-1).

NOTE: The IANAAppCodePage connection string attribute replaces the AppCodePage connection string attribute in earlier versions of Connect for ODBC. The drivers are backwardly compatible with the AppCodePage attribute, but you must now use the IANAAppCodePage attribute.

IPAddress (IP) | The IP address of the machine where the catalog tables are stored. Enter the address using the machine's numeric address (for example, 123.456.78.90) or type its address name. If you enter an address name, the driver must find this name (with the correct address assignment) in the HOSTS file on the workstation or in a DNS server.
IsolationLevel (IL) IsolationLevel={ALL|CHANGE|CURSOR_STABILITY|NO_COMMIT|REPEATABLE_READ}. Specifies the method by which locks are acquired and released by the system. Valid values are:

All Prevents any other process from accessing data that your application has read or modified. All read or modified data is locked until the end of the transaction.

Change Allows other processes to read from the database. Only modified data is locked until the end of the transaction.

Cursor Stability Allows other processes to change a row that your application read if the cursor is not on the row that you want to change. Prevents other processes from changing records that your application has changed until your program commits them or terminates. Prevents your program from reading a modified record that has not been committed by another process.
IsolationLevel (IL) (cont.) No Commit Allows your program to read modified records even if they have not been committed by another person.

Repeatable Read Prevents other processes from changing records that are read or changed by your application (including phantom records) until your program commits them or terminates. Prevents the application from reading modified records that have not been committed by another process. If your program opens the same query during a single unit of work under this isolation level, the results table will be identical to the previous table; however, it can contain updates made by your program.
Location (LOC) | A path that specifies the DB2 location name. This attribute is valid and required only if you are connecting to DB2 on OS/390.
LogonID (UID) The default logon ID used to connect to your DB2 database. A logon ID is required only if security is enabled on your database. If so, contact your system administrator to get your logon ID.

For DB2 on UNIX, normal UNIX security is used. The LogonID value is your UNIX user ID.
Package (PCK) | The name of the package that the driver uses to process static and dynamic SQL for applications that use this data source definition. The default name is DEFxx, where xx is the version number.
PackageOwner (PO) | The AuthID assigned to the package. This DB2 AuthID must have authority to execute all the SQL in the package.
Password (PWD) | A password used to connect to your DB2 database.
TcpPort (PORT) | The port number that is assigned to the DB2 server on the machine where the catalog tables are stored. Specify this port's numeric address or its name (5179 is the default port address). If you specify a port name, the driver must find this name (with the correct port assignment) in the SERVICES file on the workstation.
WithHold (WH) Set this attribute to 1 for use with MobiLink.

WithHold={0|1}. Specifies the cursor behavior for the application used with this data source. Either DB2 closes all open cursors (Delete cursors) after a commit or rollback, or leaves them open (Preserve cursors). When set to 1, the cursor behavior is Preserve. When set to 0, the cursor behavior is Delete (the default).

If you are using the Static Bind Administrator and you want your package to use cursors WITH HOLD, you must set this attribute to 1. Note that any application using this package must use a data source with this attribute set to 1.

When set to 1, the Static Bind Administrator automatically adds the WITH HOLD clause to queries that it puts in the application's database resource module (DBRM). The WITH HOLD clause prevents DB2 from automatically closing the cursor when the application executes a Commit statement.

SQLGetInfo( ) returns SQL_CB_PRESERVE for SQL_COMMIT_CURSOR_BEHAVIOR
When set to 0, SQLGetInfo( ) returns SQL_CB_DELETE. For information about this function, refer to the Microsoft ODBC API.


Data types

The following table shows how the DB2 data types map to the standard ODBC data types.

DB2 | ODBC
Bigint1 | SQL_BIGINT
Blob2 | SQL_LONGVARBINARY
Char | SQL_CHAR
Char() for Bit Data | SQL_BINARY
CLOB3 | SQL_LONGVARCHAR
Date | SQL_TYPE_DATE
Decimal | SQL_DECIMAL
Float | SQL_DOUBLE
Integer | SQL_INTEGER
Long Varchar | SQL_LONGVARCHAR
Long Varchar for Bit Data | SQL_LONGVARBINARY
Smallint | SQL_SMALLINT
Time | SQL_TYPE_TIME
Timestamp | SQL_TYPE_TIMESTAMP
Varchar | SQL_VARCHAR
Varchar() for Bit Data | SQL_VARBINARY

1 - Supported on DB2 Universal Database 8.1.

2 - Supported on DB2 Universal Database 8.1.

3 - On DB2 Universal Database versions previous to 8.1, only the first 32Kb of the Clob data type are returned when fetching, and only 32Kb can be inserted and updated.


Web Links Browse Collapse Expand PDF Previous Next

ODBC Drivers for MobiLink and Remote Data Access

iAnywhere Solutions ODBC Driver for DB2

Supported features

This section lists features supported by the ODBC driver for DB2.


Stored procedure support

The DB2 driver supports DB2 Remote Procedure Calls (RPCs) with the following restrictions:

  • Multiple result sets are returned.

  • RPCs must take an argument list. The driver does not support RPCs that use a SQL descriptor area (SQLDA) data structure to specify the arguments.

  • Literals are supported as stored procedure parameters.


Isolation and lock levels supported

DB2 supports isolation levels 0 (read uncommitted), 1 (read committed), and 2 (repeatable read). It supports record-level locking.

NOTE: An isolation level can be set only before connecting to a DB2 database.


Web Links Browse Collapse Expand PDF Previous Next

ODBC Drivers for MobiLink and Remote Data Access

iAnywhere Solutions ODBC Driver for DB2

Supported features

Number of connections and statements supported

The DB2 database system supports multiple connections and multiple statements per connection.


Unicode support

The DB2 driver supports Unicode data types if the database was created with a multi-byte character set.

The driver maps the following DB2 data types to Unicode data types:

DB2 Data Type | Mapped to . . .
Graphic | SQL_WCHAR
Long Vargraphic | SQL_WLONGVARCHAR
Vargraphic | SQL_WVARCHAR

This driver supports the Unicode ODBC W (Wide) function calls, such as SQLConnectW. This allows the Driver Manager to transmit these calls directly to the driver. Otherwise, the Driver Manager would incur the additional overhead of converting the W calls to ANSI function calls, and vice versa.


ODBC Functions

About this appendix

This appendix lists the ODBC functions that you can use in SQL statements.

ODBC functions


ODBC Functions

ODBC functions

This section lists the scalar functions that ODBC supports. Your database system may not support all of these functions. See the documentation for your database system to find out which functions are supported.

You can use these functions in SQL statements using the following syntax:

{fn scalar-function}

where scalar-function is one of the functions listed in the following tables. For example:

SELECT {fn UCASE(NAME)} FROM EMP


String functions

The following table lists the string functions that ODBC supports.

The string functions listed can take the following arguments:

  • string_exp can be the name of a column, a string literal, or the result of another scalar function, where the underlying data type is SQL_CHAR, SQL_VARCHAR, or SQL_LONGVARCHAR.

  • start, length, and count can be the result of another scalar function or a literal numeric value, where the underlying data type is SQL_TINYINT, SQL_SMALLINT, or SQL_INTEGER.

The string functions are one-based; that is, the first character in the string is character 1.

Character string literals must be surrounded in single quotation marks.

Function | Returns
ASCII(string_exp) | ASCII code value of the leftmost character of string_exp as an integer.
BIT_LENGTH(string_exp) | The length in bits of the string expression.
CHAR(code) | The character with the ASCII code value specified by code. code should be between 0 and 255; otherwise, the return value is data-source dependent.
CHAR_LENGTH(string_exp) | The length in characters of the string expression, if the string expression is of a character data type; otherwise, the length in bytes of the string expression (the smallest integer not less than the number of bits divided by 8). (This function is the same as the CHARACTER_LENGTH function.)
CHARACTER_LENGTH(string_exp) | The length in characters of the string expression if the string expression is of a character data type; otherwise, the length in bytes of the string expression (the smallest integer not less than the number of bits divided by 8). (This function is the same as the CHAR_LENGTH function.)
CONCAT(string_exp1, string_exp2) | The string resulting from concatenating string_exp2 and string_exp1. The string is system dependent.
DIFFERENCE(string_exp1, string_exp2) | An integer value that indicates the difference between the values returned by the SOUNDEX function for string_exp1 and string_exp2.
INSERT(string_exp1, start, length, string_exp2) | A string where length characters have been deleted from string_exp1 beginning at start and where string_exp2 has been inserted into string_exp, beginning at start.
LCASE(string_exp) | Uppercase characters in string_exp converted to lowercase.
LEFT(string_exp, count) | The count of characters of string_exp.
LENGTH(string_exp) | The number of characters in string_exp, excluding trailing blanks and the string termination character.
LOCATE(string_exp1, string_exp2[,start]) | The starting position of the first occurrence of string_exp1 within string_exp2. If start is not specified, the search begins with the first character position in string_exp2. If start is specified, the search begins with the character position indicated by the value of start. The first character position in string_exp2 is indicated by the value 1. If string_exp1 is not found, 0 is returned.
LTRIM(string_exp) | The characters of string_exp, with leading blanks removed.
OCTET_LENGTH(string_exp) | The length in bytes of the string expression. The result is the smallest integer not less than the number of bits divided by 8.
POSITION(character_exp IN character_exp) | The position of the first character expression in the second character expression. The result is an exact numeric with an implementation-defined precision and a scale of 0.
REPEAT(string_exp, count) | A string composed of string_exp repeated count times.
REPLACE(string_exp1, string_exp2, string_exp3) | Replaces all occurrences of string_exp2 in string_exp1 with string_exp3.
RIGHT(string_exp, count) | The rightmost count of characters in string_exp.
RTRIM(string_exp) | The characters of string_exp with trailing blanks removed.
SOUNDEX(string_exp) | A data-source-dependent string representing the sound of the words in string_exp.
SPACE(count) | A string consisting of count spaces.
SUBSTRING(string_exp, start, length) | A string derived from string_exp beginning at the character position start for length characters.
UCASE(string_exp) | Lowercase characters in string_exp converted to uppercase.


Numeric functions

The following table lists the numeric functions that ODBC supports.

The numeric functions listed can take the following arguments:

  • numeric_exp can be a column name, a numeric literal, or the result of another scalar function, where the underlying data type is SQL_NUMERIC, SQL_DECIMAL, SQL_TINYINT, SQL_SMALLINT, SQL_INTEGER, SQL_BIGINT, SQL_FLOAT, SQL_REAL, or SQL_DOUBLE.

  • float_exp can be a column name, a numeric literal, or the result of another scalar function, where the underlying data type is SQL_FLOAT.

  • integer_exp can be a column name, a numeric literal, or the result of another scalar function, where the underlying data type is SQL_TINYINT, SQL_SMALLINT, SQL_INTEGER, or SQL_BIGINT.

    Function | Returns
    ABS(numeric_exp) | Absolute value of numeric_exp.
    ACOS(float_exp) | Arc-cosine of float_exp as an angle in radians.
    ASIN(float_exp) | Arc-sine of float_exp as an angle in radians.
    ATAN(float_exp) | Arc-tangent of float_exp as an angle in radians.
    ATAN2(float_exp1, float_exp2) | Arc-tangent of the x and y coordinates, specified by float_exp1 and float_exp2 as an angle in radians.
    CEILING(numeric_exp) | Smallest integer greater than or equal to numeric_exp.
    COS(float_exp) | Cosine of float_exp as an angle in radians.
    COT(float_exp) | Cotangent of float_exp as an angle in radians.
    DEGREES(numeric_exp) | Number if degrees converted from numeric_exp radians.
    EXP(float_exp) | Exponential value of float_exp.
    FLOOR(numeric_exp) | Largest integer less than or equal to numeric_exp.
    LOG(float_exp) | Natural log of float_exp.
    LOG10(float_exp) | Base 10 log of float_exp.
    MOD(integer_exp1, integer_exp2) | Remainder of integer_exp1 divided by integer_exp2.
    PI() | Constant value of pi as a floating-point number.
    POWER(numeric_exp, integer_exp) | Value of numeric_exp to the power of integer_exp.
    RADIANS(numeric_exp) | Number of radians converted from numeric_exp degrees.
    RAND([integer_exp]) | Random floating-point value using integer_exp as the optional seed value.
    ROUND(numeric_exp, integer_exp) | numeric_exp rounded to integer_exp places right of the decimal (left of the decimal if integer_exp is negative).
    SIGN(numeric_exp) | Indicator of the sign of numeric_exp. If numeric_exp < 0, -1 is returned. If numeric_exp = 0, 0 is returned. If numeric_exp > 0, 1 is returned.
    SIN(float_exp) | Sine of float_exp, where float_exp is an angle in radians.
    SQRT(float_exp) | Square root of float_exp.
    TAN(float_exp) | Tangent of float_exp, where float_exp is an angle in radians.
    TRUNCATE(numeric_exp, integer_exp) | numeric_exp truncated to integer_exp places right of the decimal. (If integer_exp is negative, truncation is to the left of the decimal).


Date and Time Functions

The following table lists the date and time functions that ODBC supports.

The date and time functions listed can take the following arguments:

  • date_exp can be a column name, a date or timestamp literal, or the result of another scalar function, where the underlying data type can be represented as SQL_CHAR, SQL_VARCHAR, SQL_DATE, or SQL_TIMESTAMP.

  • time_exp can be a column name, a timestamp or timestamp literal, or the result of another scalar function, where the underlying data type can be represented as SQL_CHAR, SQL_VARCHAR, SQL_TIME, or SQL_TIMESTAMP.

  • timestamp_exp can be a column name, a time, date, or timestamp literal; or the result of another scalar function, where the underlying data type can be represented as SQL_CHAR, SQL_VARCHAR, SQL_TIME, SQL_DATE, or SQL_TIMESTAMP.

    Function | Returns
    CURRENT_DATE() | Current date.
    CURRENT_TIME[(time-precision)] | Current local time. The time-precision argument determines the seconds precision of the returned value.
    CURRENT_TIMESTAMP[(timestamp-precision)] | Current local date and local time as a timestamp value. The timestamp-precision argument determines the seconds precision of the returned timestamp.
    CURDATE() | Current date as a date value.
    CURTIME() | Current local time as a time value.
    DAYNAME(date_exp) | Character string containing a data-source-specific name of the day for the day portion of date_exp.
    DAYOFMONTH(date_exp) | Day of the month in date_exp as an integer value.
    DAYOFWEEK(date_exp) | Day of the week in date_exp as an integer value.
    DAYOFYEAR(date_exp) | Day of the year in date_exp as an integer value.
    HOUR(time_exp) | Hour in time_exp as an integer value.
    MINUTE(time_exp) | Minute in time_exp as an integer value.
    MONTH(date_exp) | Month in date_exp as an integer value.
    MONTHNAME(date_exp) | Character string containing the data source-specific name of the month.
    NOW() | Current date and time as a timestamp value.
    QUARTER(date_exp) | Quarter in date_exp as an integer value.
    SECOND(time_exp) | Second in time_exp as an integer value.
    TIMESTAMPADD(interval, integer_exp, time_exp) Timestamp calculated by adding integer_exp intervals of type interval to time_exp. The interval can be SQL_TSI_FRAC_SECOND, SQL_TSI_SECOND, SQL_TSI_MINUTE, SQL_TSI_HOUR,SQL_TSI_DAY, SQL_TSI_WEEK, SQL_TSI_MONTH, SQL_TSI_QUARTER, or SQL_TSI_YEAR

    Fractional seconds are expressed in billionths of a second.
    TIMESTAMPDIFF(interval, time_exp1, time_exp2) | Integer number of intervals of type interval by which time_exp2 is greater than time_exp1. interval has the same values as TIMESTAMPADD. Fractional seconds are expressed in billionths of a second.
    WEEK(date_exp) | Week of the year in date_exp as an integer value.
    YEAR(date_exp) | Year in date_exp. The range is data-source dependent.


System functions

The following table lists the system functions that ODBC supports.

Function | Returns
DATABASE() | Name of the database, corresponding to the connection handle (hdbc).
IFNULL(exp, value) | value, if exp is null.
USER() | Authorization name of the user.


Values for IANAAppCodePage Connection String Attribute

About this appendix

This appendix contains specific information about using Connect ODBC in the UNIX environments.

Table of IANAAppCodePage values


Web Links Browse Collapse Expand PDF Previous Next

UltraLite Database User's Guide

Version 9.0.2

DC37121-01-0902-01

October 2004

Copyright
About This Manual
Welcome to UltraLite
Tutorial: The CustDB Sample UltraLite Application
UltraLite Databases
Connection Parameters
UltraLite Utilities Reference
Tutorial: Working with UltraLite Databases
SQL Language Elements
Dynamic SQL
Developing Applications for the Palm OS
Using UltraLite Static Interfaces
UltraLite Static Interfaces Reference


Copyright

Copyright © 1989–2004 Sybase, Inc. Portions copyright © 2001–2004 iAnywhere Solutions, Inc. All rights reserved.

No part of this publication may be reproduced, transmitted, or translated in any form or by any means, electronic, mechanical, manual, optical, or otherwise, without the prior written permission of iAnywhere Solutions, Inc. iAnywhere Solutions, Inc. is a subsidiary of Sybase, Inc.

Sybase, SYBASE (logo), 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-Library, APT-Translator, ASEP, AvantGo, AvantGo Application Alerts, AvantGo Mobile Delivery, AvantGo Mobile Document Viewer, AvantGo Mobile Inspection, AvantGo Mobile Marketing Channel, AvantGo Mobile Pharma, AvantGo Mobile Sales, AvantGo Pylon, AvantGo Pylon Application Server, AvantGo Pylon Conduit, AvantGo Pylon PIM Server, AvantGo Pylon Pro, Backup Server, BayCam, Bit-Wise, BizTracker, Certified PowerBuilder Developer, Certified SYBASE Professional, Certified SYBASE Professional Logo, 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, Dynamic Mobility Model, Dynamo, e-ADK, E-Anywhere, e-Biz Integrator, 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 Portal (logo), Enterprise SQL Server Manager, Enterprise Work Architecture, Enterprise Work Designer, Enterprise Work Modeler, eProcurement Accelerator, eremote, Everything Works Better When Everything Works Together, EWA, E-Whatever, Financial Fusion, Financial Fusion (and design), Financial Fusion Server, Formula One, Fusion Powered e-Finance, Fusion Powered Financial Destinations, Fusion Powered STP, Gateway Manager, GeoPoint, GlobalFIX, iAnywhere, iAnywhere Solutions, ImpactNow, Industry Warehouse Studio, InfoMaker, Information Anywhere, Information Everywhere, InformationConnect, InstaHelp, Intelligent Self-Care, InternetBuilder, iremote, iScript, Jaguar CTS, jConnect for JDBC, KnowledgeBase, Logical Memory Manager, Mail Anywhere Studio, MainframeConnect, Maintenance Express, Manage Anywhere Studio, MAP, M-Business Channel, M-Business Network, M-Business Server, MDI Access Server, MDI Database Gateway, media.splash, Message Anywhere Server, MetaWorks, MethodSet, ML Query, MobiCATS, My AvantGo, My AvantGo Media Channel, My AvantGo Mobile Marketing, MySupport, Net-Gateway, Net-Library, New Era of Networks, Next Generation Learning, Next Generation Learning Studio, O DEVICE, OASiS, OASiS logo, 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++, Orchestration Studio, Partnerships that Work, PB-Gen, PC APT Execute, PC DB-Net, PC Net Library, PhysicalArchitect, Pocket PowerBuilder, PocketBuilder, Power Through Knowledge, power.stop, Power++, 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, QAnywhere, Rapport, Relational Beans, RepConnector, Replication Agent, Replication Driver, Replication Server, Replication Server Manager, Replication Toolkit, Report Workbench, Report-Execute, Resource Manager, RW-DisplayLib, RW-Library, 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 (logo), 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, TotalFix, TradeForce, Transact-SQL, Translation Toolkit, Turning Imagination Into Reality, UltraLite, UltraLite.NET, UNIBOM, Unilib, Uninull, Unisep, Unistring, URK Runtime Kit for UniCode, Versacore, Viewer, 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, and XP Server are trademarks of Sybase, Inc. or its subsidiaries.

Certicom and SSL Plus are trademarks and Security Builder is a registered trademark of Certicom Corp. Copyright © 1997–2001 Certicom Corp. Portions are Copyright © 1997–1998, Consensus Development Corporation, a wholly owned subsidiary of Certicom Corp. All rights reserved. Contains an implementation of NR signatures, licensed under U.S. patent 5,600,725. Protected by U.S. patents 5,787,028; 4,745,568; 5,761,305. Patents pending.

All other trademarks are property of their respective owners.


About This Manual

Subject

This manual introduces the UltraLite database system for small devices.

Audience

This manual is intended for all developers who wish to take advantage of the performance, resource efficiency, robustness, and security of an UltraLite relational database for data storage and synchronization.


Welcome to UltraLite

About this chapter

This chapter introduces you to UltraLite features, platforms, architecture, and functionality.


Introduction to UltraLite

UltraLite is a relational database management and synchronization system for small, mobile, and embedded devices. It provides the following benefits:

  • Robust data management Data held on small devices is as important as data in enterprise databases. UltraLite brings transaction processing, referential integrity, and other benefits of relational database systems to small devices.

    For more information about UltraLite database features, see UltraLite database features.

  • Powerful synchronization UltraLite gives you the ability to synchronize data with a central database.

    UltraLite uses MobiLink synchronization technology, included in SQL Anywhere Studio, to synchronize with industry-standard database-management systems. MobiLink synchronization works with Sybase Adaptive Server Anywhere, Sybase Adaptive Server Enterprise, IBM DB2, Microsoft SQL Server, and Oracle. It provides flexible, programmable, and scalable synchronization that can manage thousands of UltraLite databases.

    For more information, see UltraLite Clients.

  • Your choice of programming interface UltraLite components provide the option of using an object-based programming interface for straightforward access to data. Integration into popular development tools such as Visual Studio .NET, AppForge MobileVB and Crossfire, Borland JBuilder, and eMbedded Visual Basic improves developers' productivity. Graphical tools enable you to design and modify UltraLite databases quickly.

    For more information, see UltraLite programming interfaces and Choosing an UltraLite programming interface.

  • Multi-platform availability You can develop and deploy UltraLite database applications for Windows CE, Palm OS, Windows XP, and Java-based devices.

    For more information, see UltraLite development platforms.


UltraLite programming interfaces

UltraLite provides a variety of programming interfaces and integrates into several popular programming tools. Each interface uses the same underlying UltraLite runtime library.

The interfaces fall into two categories: components and static interfaces. Each interface has its own strengths and has particular cases for which it is an appropriate choice. For tips on choosing a programming interface, see Choosing an UltraLite programming interface.

  • UltraLite components UltraLite components provide users of development tools with a relational database and synchronization features. They provide a familiar interface for each supported development tool. UltraLite components provide a simple table-based data access interface and also dynamic SQL for more complex queries.

    The following components are available:

    • UltraLite for MobileVB Development using the AppForge MobileVB extension to Microsoft Visual Basic or the AppForge Crossfire extension to Microsoft Visual Studio .NET.

      See UltraLite for MobileVB User's Guide.

    • UltraLite ActiveX Development using eMbedded Visual Basic or JScript with Pocket IE.

      See UltraLite ActiveX User's Guide.

    • Native UltraLite for Java Development using a supported JDK. The UltraLite component itself accesses native (C++) methods for improved performance.

      See Native UltraLite for Java User's Guide.

    • UltraLite.NET Development using Visual Studio .NET, including an ADO.NET programming interface.

      See UltraLite.NET User's Guide.

    • UltraLite C++ Component Development using a C++ interface.

      See UltraLite C/C++ User's Guide.

    • UltraLite for M-Business Anywhere Development using M-Business Anywhere.

      See UltraLite for M-Business Anywhere User's Guide.

    • ODBC UltraLite supports a subset of the ODBC programming interface.

      See Tutorial: Build an Application Using ODBC and UltraLite ODBC API Reference.

  • Static interfaces Static interfaces provide a rich SQL interface for C/C++ and Java developers comfortable with a preprocessor-based interface. All SQL statements used in the application must be defined at compile time.

    The following static interfaces are available:

    • Embedded SQL and Static C++ API Development using C/C++ with embedded SQL statements.

      See UltraLite C/C++ User's Guide.

    • UltraLite Static Java Development in pure Java using a JDBC interface. This interface uses a different runtime library to the other UltraLite interfaces.

      See UltraLite Static Java User's Guide.


UltraLite database features

UltraLite provides the following features:

  • Tables A single UltraLite database file can hold many tables. The number and type of columns in a table is fixed at design time, but each table can have any number of rows (up to 64 K). Each row has a single entry for each column. The special NULL entry is used when there is no value for the entry.

    When designing your database, each table should represent a separate type of item, such as customers or employees.

  • Data types UltraLite databases can hold a full range of data types, as well as default values and NULL values.

  • Indexes The rows in a relational database table are not ordered. You can create indexes to access the rows in order and to provide fast access to data. Indexes are commonly associated with a single column, but UltraLite also provides multi-column indexes.

  • Keys Each table has a special index called the primary key. Entries in the primary key column or columns must be unique.

    Foreign keys relate the data in one table to that in another. Each entry in the foreign key column must correspond to an entry in the primary key of another table.

    Between them, primary keys and foreign keys ensure that the database has referential integrity. Referential integrity is enforced in UltraLite databases so that you cannot, for example, enter an order for a customer unless that customer exists in the database.

    By enforcing referential integrity, UltraLite ensures that the data in your UltraLite database is correct, in the same manner that data elsewhere in the enterprise is correct. Referential integrity is checked when operations are committed, providing you with flexibility in the order with which you make changes to your data.

  • Publications To synchronize the data in your UltraLite database with other databases you must have a valid SQL Anywhere Studio license. SQL Anywhere Studio includes MobiLink synchronization technology to synchronize UltraLite databases with desktop, workgroup or enterprise databases.

    A publication defines a set of data to be synchronized. It is often desirable to synchronize all the data in an UltraLite database, but publications provide extra flexibility and control. They allow you to perform priority synchronizations, which means you can specify that only certain tables or groups of tables should be synchronized.

  • Transactions and recovery UltraLite has commit and rollback features, together with automatic recovery in the event of device failure, to guarantee that transactions are executed completely or not at all.

  • Security UltraLite provides user authentication and database encryption, as well as encryption during synchronization, to build secure applications.

  • Performance and small footprint UltraLite target devices tend to have relatively slow processors. UltraLite employs algorithms and data structures that provide high performance and low memory use. For example, UltraLite provides a caching algorithm designed specifically for small devices.

  • Multi-threaded applications For platforms that support multi-threaded applications, UltraLite supports both multi-threaded applications and multiple applications connecting to a single database.

For information about working with UltraLite databases, see UltraLite Databases.


UltraLite application architecture

All UltraLite applications are built on the same underlying database management code. UltraLite components include this code in the component itself, while static interfaces use the code in the form of a separate UltraLite runtime library.

UltraLite application architecture

UltraLite applications consist of the following:

  • Your application code

  • The UltraLite component or runtime library

  • An UltraLite database or schema file


Using the UltraLite documentation

Once you have selected an UltraLite programming interface, you can find the information you need in the following books, all of which are included in the SQL Anywhere online books.

For tips on choosing a programming interface, see Choosing an UltraLite programming interface.

  • UltraLite Database User's Guide (this book) This book presents information that is useful for all UltraLite interfaces, including information about UltraLite database management, SQL, and synchronization.

  • Interface books Each UltraLite interface has a separate book, which contains all the information you need for developing applications using that interface.

    • Native UltraLite for Java User's Guide

    • UltraLite ActiveX User's Guide

    • UltraLite C/C++ User's Guide

    • UltraLite for MobileVB User's Guide

    • UltraLite Static Java User's Guide

    • UltraLite.NET User's Guide

    • UltraLite for M-Business Anywhere User's Guide

  • MobiLink books If your application includes synchronization, the MobiLink Administration Guide and the MobiLink Clients provide a complete guide to the synchronization system.


Choosing an UltraLite programming interface

Choosing which UltraLite programming interface to use depends primarily on your answers to the following questions:

  • What is your target platform or platforms?

  • Which programming language do you wish to use?

The availability of more than one interface for C/C++ developers, and for Java developers, provides further flexibility.

Each interface is described in a separate book. For more information, see Using the UltraLite documentation.

Cross platform development for Palm OS, Windows XP, and Windows CE

Your options are as follows:

  • C/C++ You can choose from the following:

    • UltraLite C++ Component
    • Static C++ API
    • Embedded SQL (static interface)

    For information about choosing between these interfaces, see Choosing between components and static interfaces.

  • Visual Basic .NET and Visual Basic You can use UltraLite for MobileVB together with AppForge MobileVB or AppForge Crossfire to develop cross-platform applications from a Microsoft development environment.

  • Web development You can use UltraLite for M-Business Anywhere to develop cross-platform web applications.

Development for Palm OS only

Your options are as follows:

  • C/C++ You can choose from the following:

    • UltraLite C++ Component
    • Static C++ API
    • Embedded SQL (static interface)

    For information about choosing between these interfaces, see Choosing between components and static interfaces.

  • Visual Basic You can use UltraLite for MobileVB to develop Visual Basic applications for the Palm OS.

  • Web development You can use UltraLite for M-Business Anywhere to develop browser-based applications for the Palm OS.

Development for Windows CE and Windows XP

Your options are as follows:

  • C/C++ You can choose from the following:

    • UltraLite C++ Component
    • ODBC
    • Static C++ API
    • Embedded SQL (static interface)

    For information about choosing between these interfaces, see Choosing between components and static interfaces.

  • Java You can choose from the following:

    • Native UltraLite for Java (component)
    • Static Java API

    For information about choosing between these interfaces, see Choosing between components and static interfaces.

  • Visual Basic You can choose from the following:

    • UltraLite.NET, which provides an interface from Visual Basic .NET.

    • UltraLite for MobileVB, which provides an interface from Visual Basic, using the AppForge MobileVB extension.

    • UltraLite ActiveX, which provides an interface from eMbedded Visual Basic.

  • C# You can use UltraLite.NET to develop C# applications for Windows CE or Windows XP.

  • Web development You can build JavaScript applications using the following:

    • UltraLite for M-Business Anywhere
    • UltraLite ActiveX
Development for other platforms

UltraLite Static Java provides a pure Java solution for any platform supporting JDK 1.1.8 or later.


Choosing between components and static interfaces

UltraLite applications are built using either an UltraLite component or a static interface.

The choice of which to use depends partly on the language you wish to use. If you are a C#, Visual Basic, or JavaScript programmer, you should choose an UltraLite component. If you are a C/C++ or Java programmer, you have a choice between using a component or a static interface. This section compares components and static interfaces.

Data access features

UltraLite components can use either dynamic SQL or a table-based API to access data.

  • Dynamic SQL provides many common SQL features, including multi-table joins. In contrast to the static interfaces, dynamic SQL permits SQL statements to be constructed at runtime.

    For a full description, see Dynamic SQL.

  • The UltraLite component table-based API accesses rows one at a time. It is simple, but if you require logic such as joining tables, then you must implement it yourself within your application.

You can combine dynamic SQL and the table-based API in a single application.

Static interfaces (embedded SQL, the Static C++ API, and the static Java API) use SQL to access data. A wider range of SQL is supported in the static interfaces than in dynamic SQL, but all queries must be specified at compile time. For example, UNION and FULL OUTER JOIN queries are currently supported only from the static interfaces. In both static and dynamic SQL, queries can contain parameters, for which you can supply values at runtime.

The Static C++ API also provides a table-based API, which has some of the benefits and limitations of the component table-based API. For a description, see Developing Applications Using the Static C++ API.

Application size

The UltraLite components include code to parse, optimize, and execute arbitrary queries. In contrast, the static interfaces generate code that executes specified queries, but do not need to generate code to parse or optimize queries. For this reason, applications built using the static interfaces are typically much smaller than those built with UltraLite components.

As the number of queries and tables in the database increases, the size advantage of the static interfaces is lost. For complex applications using many queries and addressing databases that contain many tables, the components can be smaller as they do not need to contain code for each separate query.

Development model

Each UltraLite component exposes an object-oriented API designed to be familiar to users of the language supported by that component. The development model is similar to that for many other kinds of applications.

The UltraLite static interfaces require a more complicated development model, in which a preprocessing step generates application code from a reference database.

For many users, the UltraLite components are easier to learn than the static interfaces.

For more information, see the following sections:

  • Developing applications with UltraLite components

  • Developing Static C++ applications

  • Developing embedded SQL applications

  • Data Access Using the Static Java API

Performance

Queries included as part of an application that uses a static interface are already parsed and optimized. Therefore, they may perform better than queries in UltraLite components. The optimization of queries in the static interface depends on the distribution of data in the reference database. The closer the data in the reference database is to that in the UltraLite database, the better the performance will be.

For more information about Adaptive Server Anywhere SQL support, see SQL Statements.

Compatibility with Adaptive Server Anywhere

Embedded SQL provides a common static programming interface for UltraLite and Adaptive Server Anywhere databases. ADO.NET and ODBC provide programming models that are shared between UltraLite components and Adaptive Server Anywhere.

Maintaining a common interface may be particularly useful on platforms such as Windows CE, where both databases are available. If you need to move from UltraLite to the more powerful and full-featured Adaptive Server Anywhere database, using embedded SQL, ODBC, or ADO.NET makes migrating your application easier.


Developing applications with UltraLite components

toggle To develop an UltraLite component application

  1. Design your database schema file.

    You create a database schema using the UltraLite Schema Painter or by writing an XML file. Users of SQL Anywhere Studio can generate an UltraLite database schema from an Adaptive Server Anywhere database.

    For more information, see The UltraLite Schema Painter, The ulxml utility, and The ulinit utility.

  2. Set up your development environment for UltraLite projects.

    For more information, see the following:

    • UltraLite for MobileVB: Lesson 1: Create a project architecture.
    • UltraLite.NET: Lesson 1: Create a Visual Studio project.
    • UltraLite C++ Component: Tutorial: Build an Application Using the C++ Component.
    • UltraLite ActiveX: Adding UltraLite ActiveX to the eMbedded Visual Basic design environment.
    • Native UltraLite for Java: Developing applications with Borland JBuilder.
    • UltraLite for M-Business Anywhere: UltraLite for M-Business Anywhere Quick Start.

  3. Write your application code using the UltraLite API for a particular language.

  4. Deploy your application and database schema.

    The steps depend on the target device and on the component used.


Tutorial: The CustDB Sample UltraLite Application

About this chapter

This chapter uses the CustDB sample application to illustrate some key features of UltraLite.

These techniques are illustrated using a desktop version of CustDB. Additionally, a version of CustDB is provided for each of the supported interfaces. For more information, see What Next?.

Much of the material in this chapter is explained in a more general manner elsewhere in this book.

Introduction
Lesson 1: Start the MobiLink synchronization server
Lesson 2: Start the sample application and synchronize
Lesson 3: Add an order
Lesson 4: Approve or deny an existing order
Lesson 5: Synchronize your changes
Lesson 6: Browse the consolidated database


Introduction

This chapter introduces you to the CustDB (Customer Database) UltraLite sample application. CustDB is a sales-status application.

The CustDB sample application provides you with examples of how to implement many of the techniques you will need to develop UltraLite applications.

This chapter uses the compiled version of the application for Windows NT/2000/XP.

A separate version of the CustDB application is provided for each UltraLite programming interface. Each version has similar features, with some variation to conform to the conventions of each platform.

UltraLite features

This chapter illustrates the following UltraLite features:

  • UltraLite database applications run on small devices using very limited resources.

  • UltraLite applications include a relational database engine.

  • UltraLite applications share data with a central, consolidated database in a two-way synchronization scheme. UltraLite databases are also called remote databases.

  • Each remote database contains a subset of the data in the consolidated database.

  • The MobiLink synchronization server, included with SQL Anywhere Studio, carries out data synchronization between the consolidated database and each UltraLite installation.

  • SQL scripts stored in the consolidated database implement the synchronization logic.

  • You can use Sybase Central to browse and edit the synchronization scripts.

Scenario

The CustDB scenario is as follows:

A consolidated database is stored at the head office.

There are two types of remote databases, sales representatives and mobile managers. Each sales representative's UltraLite remote database contains all products but only those orders assigned to that sales representative. A mobile manager's UltraLite remote database contains all products and orders.

You can carry out the following tasks with the sample application.

  • View lists of customers and products.

  • Add new customers.

  • Add or delete orders.

  • Scroll through the list of outstanding orders.

  • Accept or deny orders.

  • Synchronize changes with the consolidated database.

When you run the CustDB UltraLite application, you are working on a single remote database, and synchronizing your changes with a consolidated database.

In a typical UltraLite installation, there will be many remote databases, each running on a handheld device, and each containing a small subset of the data from the consolidated database.


File locations

The CustDB sample application is included in the following locations within your UltraLite installation.

Runtime file locations

To run the CustDB sample application, you need the following components:

  • The consolidated database An Adaptive Server Anywhere version of the CustDB database is located in Samples\UltraLite\Custdb\custdb.db. For information about the schema, and information about using one of the other supported consolidated database types, see The CustDB Sample Application.

    This database serves as the consolidated database. It contains the following information.

    • MobiLink system tables that hold the synchronization metadata.

    • The CustDB data, stored in rows in base tables.

    • The synchronization scripts.

    During installation, an ODBC data source named UltraLite 9.0 Sample is created for this database.

  • The UltraLite application executable and source code A version of the sample is supplied for each interface.

    The executable and source code are located in the following subdirectories of your SQL Anywhere Studio installation:

    Component | Location
    UltraLite for MobileVB | Samples\UltraLiteForMobileVB and Samples\UltraLiteForCrossfire
    UltraLite ActiveX | Samples\UltraLiteActiveX
    UltraLite.NET | Samples\UltraLite.NET
    Native UltraLite for Java | Samples\NativeUltraLiteForJava
    C++ Component | Samples\UltraLite
    Embedded SQL | Samples\UltraLite
    Static C++ API | Samples\UltraLite
    Static Java API | Samples\UltraLite
    UltraLite for M-Business Anywhere | Samples\UltraLiteForMBusinessAnywhere

    To browse the samples from the Start menu, choose Programs > SQL Anywhere 9 > Sample Applications and Projects.


Synchronization techniques in the sample application

Synchronization with the CustDB sample database is carried out by the MobiLink synchronization server running on your desktop computer.

The CustDB sample application demonstrates several useful synchronization techniques. For a more detailed explanation of how synchronization works, refer to the following sections in the MobiLink documentation.

  • For an overview of the synchronization process, see The synchronization process.

  • For a description of how to write the synchronization scripts that control synchronization, see Writing Synchronization Scripts.

  • For information about the synchronization techniques used in the CustDB sample application, see The CustDB Sample Application.


Lesson 1: Start the MobiLink synchronization server

When you start the sample UltraLite application for the first time, the remote database contains no data. The application carries out synchronization to download an initial copy of the data from a consolidated database.

Before you can carry out synchronization, you must start the database server, and start the MobiLink synchronization server running against the UltraLite sample database.

The following procedure uses some of the shortcuts that the SQL Anywhere Studio installation adds to the Start menu.

toggle To start the MobiLink synchronization server

  1. Start the Adaptive Server Anywhere CustDB sample database.

    From the Start menu, choose Programs > Sybase SQL Anywhere 9 > UltraLite > Personal Server Sample for UltraLite.

    The CustDB sample database is the consolidated database in this tutorial. You will synchronize data between an UltraLite database and this consolidated database. You can also use database servers other than Adaptive Server Anywhere as consolidated databases. For more information, see The CustDB Sample Application.

  2. Start the MobiLink synchronization server, running against the CustDB database.

    From the Start menu, select Programs > SQL Anywhere 9 > MobiLink > Synchronization Server Sample.

    The MobiLink synchronization server uses an ODBC driver to connect to the consolidated database server. It can run on a separate computer from the database server, but in this example it runs on the same computer.


Lesson 2: Start the sample application and synchronize

The following procedure starts the sample application, and synchronizes with the consolidated database to obtain an initial set of data. The data you download depends on the user ID you enter when you start the application.

toggle To start and synchronize the sample application

  1. Launch the sample application.

    From the Start menu, choose Programs > SQL Anywhere 9 > UltraLite > Windows Sample Application.

    In this walkthrough the sample application is running on the same desktop machine as the MobiLink synchronization server. In a production environment, UltraLite applications more commonly run on handheld devices.

  2. Enter an employee ID.

    Enter a value of 50 and click Enter. The application also allows values of 51, 52, or 53, but behaves slightly differently in these cases.

    After you enter the employee ID, the application synchronizes, and a set of customers, products, and orders is downloaded to the application. The MobiLink synchronization server window displays messages showing the synchronization taking place.

  3. Confirm that the application contains data.

    A company name and a sample order should appear on the application window.


Lesson 3: Add an order

In this section, you add a new order to the database. Adding an order is carried out in a similar way in each version of the application.

The database contains a table in which each row holds information about a particular order. For each order, this data includes the customer, the product, the quantity, the price, and any applicable discount. Also included are a status field and a notes field, which you can modify from this application.

The remote database does not receive all the orders listed in the ULOrder table in the consolidated database. Only orders that have not yet been approved are downloaded. Synchronization scripts allow you to control which information is sent to your application.

Add an order


Add an order

toggle To add an order

  1. Scroll through the outstanding orders.

    Click Next to display the next customer.

  2. Enter a new order.

    From the Order menu, choose New.

    The Add New Order screen is displayed.

  3. Choose a customer.

    Choose Basements R Us from the dropdown list. This list exposes the complete list of customers from the consolidated database.

    The current list of orders does not have any from this customer.

  4. Choose a product.

    The UltraLite application holds the complete list of products from the consolidated database. To see this list, open the Product drop-down list box.

    Choose Screwmaster Drill from the list. The price of this item is automatically entered in the Price field.

  5. Enter the quantity and discount.

    Enter a value of 20 for the quantity, and a value of 5 for the discount.

  6. Click Enter to add the new order.

By adding an order, you have modified the data in your local UltraLite database. This data is not shared with the consolidated database until you synchronize.


Lesson 4: Approve or deny an existing order

In this step, you approve one order and deny another. Approving or denying orders updates two columns in the local database. The data in the consolidated database is unchanged until you synchronize.

toggle To approve, deny, and delete orders

  1. Approve the order from Apple Street Builders.

    • Go to the first order in the list, which is from Apple Street Builders.

    • Click Approve to approve the order.

    • Add a note to your approval, saying Good Work.

    • The order appears with a status of Approved.

  2. Deny the order from Art's Renovations.

    • Go to the next order in the list, which is from Art's Renovations.

    • Click Deny to deny this order.

    • Add a note stating Discount too high.

  3. Delete the order from Awnings R Us.

    • Go to the next order in the list, which is from Awnings R Us.

    • Delete this order by choosing the menu item Order > Delete. It disappears from your local copy of the data.


Lesson 5: Synchronize your changes

In this section, you synchronize the changes you made to the remote database with the consolidated database.

For synchronization to take place, the MobiLink synchronization server must be running. If you have shut down your MobiLink synchronization server, restart it as described in Lesson 1: Start the MobiLink synchronization server.

toggle To synchronize your changes

  1. Choose File > Synchronize to synchronize your data.

  2. Confirm that synchronization took place.

    The synchronization process for the sample application removes approved orders from your database. Confirm that the approved order for Apple Street Builders is no longer in your application.

Confirm the synchronization at the consolidated database


Confirm the synchronization at the consolidated database

In this section, you use Interactive SQL to connect to the consolidated database to confirm that your changes were synchronized.

toggle To confirm the synchronization at the consolidated database

  1. Connect to the consolidated database from Interactive SQL.

    • Choose Start > Programs > SQL Anywhere 9 > Adaptive Server Anywhere > Interactive SQL.

      The Interactive SQL Connect dialog appears.

    • Select ODBC Data Source Name and choose UltraLite 9.0 Sample from the dropdown list.

  2. Confirm the status change of the approved and denied orders.

    To confirm that the approval and denial have been synchronized, issue the following statement.

    SELECT order_id, status
FROM ULOrder
WHERE status IS NOT NULL

    The results show that order 5100 is approved, and 5101 is denied.

  3. Confirm that the deleted order has been removed.

    The deleted order has an order_id of 5102. The following query returns no rows, demonstrating that the order has been removed from the system.

    SELECT *
FROM ULOrder
WHERE order_id = 5102


Lesson 6: Browse the consolidated database

You can use Sybase Central to manage MobiLink synchronization. The synchronization logic is held in the consolidated database.

This section describes how to use Sybase Central to browse the scripts in the CustDB consolidated database.


Connect to the CustDB database from Sybase Central

  1. Start the CustDB database.

    • Select Programs > Sybase SQL Anywhere 9 > UltraLite > Personal Server Sample for UltraLite.

  2. Start Sybase Central.

    • From the Start menu, select Programs > SQL Anywhere 9 > Sybase Central.

  3. Connect to the sample database.

    • In Sybase Central, select Tools > Connect. If there is a choice of connection types, select MobiLink.

      The MobiLink Connect dialog appears.

    • Select ODBC and enter UltraLite 9.0 Sample in the Data Source box. Click OK to connect.


Browse the synchronization scripts

From Sybase Central, you can browse the tables, users, synchronized tables, and synchronization scripts that are stored in the consolidated database. Sybase Central is the primary tool for adding these scripts to the database.

toggle To browse the synchronization scripts

  1. Open the Connection Scripts folder.

    The right hand pane lists a set of synchronization scripts and a set of events with which these scripts are associated. As the MobiLink synchronization server carries out the synchronization process, it triggers a sequence of events. Any synchronization script associated with an event is run at that time. By writing synchronization scripts and assigning them to the synchronization events, you can control the actions that are carried out during synchronization.

  2. Open the Synchronized Tables folder, and open the ULCustomer table folder.

    The right hand pane lists a pair of scripts that are specific to this table, and their corresponding events. These scripts control the way that data in the ULCustomer table is synchronized with the remote databases.

The content of the synchronization scripts is discussed in detail in Writing Synchronization Scripts and The CustDB Sample Application.


What Next?

In addition to the CustDB application, tutorials are provided for each of the supported interfaces. For more information, see the following sections:

  • Native UltraLite for Java Tutorial: The CustDB Sample Application.

  • UltraLite ActiveX Tutorial: A Sample UltraLite ActiveX Application or Tutorial: An UltraLite ActiveX Application for Pocket IE.

  • UltraLite C++ Component Tutorial: Build an Application Using the C++ Component.

  • UltraLite Embedded SQL Tutorial: Build an Application Using Embedded SQL.

  • UltraLite for MobileVB Tutorial: A Sample UltraLite for MobileVB Application.

  • UltraLite.NET Tutorial: Build an UltraLite.NET Application.

  • UltraLite for M-Business Anywhere UltraLite for M-Business Anywhere Quick Start


UltraLite Databases

About this chapter

This chapter provides basic information about data storage, user authentication, and character set issues in UltraLite databases.

Creating UltraLite databases and schemas
Setting UltraLite database properties
User authentication in UltraLite
Character sets in UltraLite
UltraLite database internals
UltraLite database limitations
Upgrading UltraLite database schemas
The UltraLite runtime


Creating UltraLite databases and schemas

UltraLite databases are held in a single file (or, in the case of Palm OS, in the Palm persistent store). The database file contains tables, indexes, and also contains additional information required for synchronization.

Every database contains a schema: information about the tables, indexes, and so on that make up the database. This metadata includes column names and data types, primary and foreign key definitions, and so on. Most relational databases store the schema in a special set of tables called the system tables, or catalog. UltraLite stores its schema in a more compact form.

Creating an UltraLite schema

To create an UltraLite database, you create an UltraLite schema externally, separately from the database itself.

If you are developing applications using an UltraLite component, you create the schema in a schema file. You then apply the schema to an UltraLite database file.

If you are developing applications using a static interface, you create the schema in a reference database; when you generate your application code from the reference database, the schema is added to the application itself.

For more information, see Creating UltraLite schema files.

Applying a schema to a database

It is common not to deploy UltraLite database files with your application, but instead to let UltraLite create the database file and to use synchronization to fill up the database with the appropriate data.

UltraLite component applications require that you deploy a database schema file. You can write your application so that it creates a database file on the first connection attempt, and applies the schema file to this database file. Sample code is provided in the tutorials for each programming interface.

UltraLite static interface applications contain a database schema definition in the generated code. They automatically create a database and apply the schema on the first connection attempt.

For more information, see Creating UltraLite databases.

Altering a database schema

You can alter the schema of an UltraLite database by applying a new schema to the database file. As with the original schema, a new schema may be held in a schema file (UltraLite components) or in a new version of the application (static interfaces).

If you are using an UltraLite component, you can also alter the schema of an UltraLite database by executing SQL statements that modify tables and indexes (data definition statements).

For more information, see Upgrading UltraLite database schemas.

See also

For an introduction to UltraLite database features, see UltraLite database features.


Creating UltraLite schema files

UltraLite schema files are used with UltraLite components. You can create an UltraLite schema file in the following ways:

  • UltraLite Schema Painter The simplest way to create a schema file is to use the graphical UltraLite Schema Painter.

    To start the Schema Painter, choose Start > Programs > SQL Anywhere 9 > UltraLite > UltraLite Schema Painter, or double-click a schema file (with extension .usm) in Windows Explorer. For more information, see The UltraLite Schema Painter.

  • Generate the schema from an Adaptive Server Anywhere database If you already have an Adaptive Server Anywhere database with the schema needed for your UltraLite database, or a superset of that schema, you can generate an UltraLite schema file using the ulinit command line utility.

    For more information, see The ulinit utility.

    You can use the Adaptive Server Anywhere migration wizard to migrate table definitions, indexes, and data from other databases into an Adaptive Server Anywhere database. You can use this wizard to assist in creating UltraLite schema definitions from Adaptive Server Enterprise, Oracle, SQL Server, or DB2 databases.

    For more information, see Migrating databases to Adaptive Server Anywhere.

  • Convert an XML file to a schema file The ulxml command line utility allows you to convert XML files to schema files. It can also carry out the conversion of schema files to XML files.

    The utility is useful, for example, if you wish to keep your database definition under source control. It also integrates well into automated build processes.

    For more information, see The ulxml utility.

  • Unload the schema from an existing UltraLite database The ulconv command line utility allows you to carry out numerous operations on UltraLite databases, including unloading a schema from an existing database.

    For more information, see The ulconv utility.

When you create an UltraLite schema file, you set some database-wide characteristics. These include the following:

  • Case sensitivity The case sensitivity of a database affects all string comparisons. It must be specified when the database is created because indexes are stored in sorted order, and the order depends on whether the database is case sensitive or not.

  • Character set Each database has a well-defined collation sequence (character set and sort order). The collation sequence is defined when the database is created.

    For more information, see Character sets in UltraLite.


Creating UltraLite databases

The way you create an UltraLite database depends on the development model you use.

toggle To create an UltraLite database (UltraLite components)

  1. Create an UltraLite schema file.

    For more information, see Creating UltraLite schema files.

  2. Write your application to use the schema file when a database is not found.

    Your code that connects to the database should carry out the following steps:

    Open Connection( database identification parameters )
If ( database not found ) Then
    Create Database( database schema parameters )
End If

    For a list of database identification parameters, see Database Identification parameters. For a list of database schema parameters, see Database Schema parameters.

    The specifics depend on the component you are using. For more information, see the following:

    • UltraLite for MobileVB: Connecting to an UltraLite database
    • UltraLite ActiveX: Connecting to an UltraLite database
    • Native UltraLite for Java: Connecting to a database
    • UltraLite.NET: Connecting to a database
    • UltraLite C++ Component: Connecting to a database
    • UltraLite for M-Business Anywhere: Connecting to an UltraLite database

  3. Add data to the UltraLite database from the application or by synchronizing.

toggle To create an UltraLite database (static interface)

  1. Create an Adaptive Server Anywhere reference database. A reference database holds the same tables and indexes as your UltraLite database.

    For more information, see Preparing a reference database.

  2. Generate an UltraLite application from the reference database.

    For more information, see Generating the UltraLite data access code.

  3. When your application first runs, it creates an UltraLite database file with the information from the reference database.

  4. Add data to the UltraLite database from the application or by synchronizing.


Creating UltraLite database files

UltraLite applications require a schema definition in order to create a database. If you are using an UltraLite component, you deploy the database schema in a separate schema file. If you are using a static development model, your application contains the schema definition.

The physical storage of the UltraLite database depends on the target platform.

  • Palm Computing Platform The database is stored in the Palm persistent (static) memory using the Data Manager API. For devices operating Palm OS version 4.0, you can store UltraLite databases in the file-based storage of expansion cards.

    For more information, see Choosing database storage on the Palm OS and Database On Palm connection parameter.

  • Windows and Windows CE The database is stored in the file system. On Windows CE the default file is \UltraLiteDB\ul.udb. On other versions of Windows the default file is ul_<project>.udb in the working directory of the application, where <project> is the UltraLite project name used during the development process.

    You can choose to explicitly specify a database file name , or you can choose to use the default file name.

    For more information, see Database On CE connection parameter.

  • Static Java The database is either transient, or is stored as a file in the file system. By default, it is transient.

For static APIs, you can supply parameters that control features such as database encryption on your first connection attempt (which is when the database is created). For UltraLite components, set the schema parameters of the Create Database method.

For more information

  • UltraLite for MobileVB See CreateDatabaseWithParms method.

  • UltraLite ActiveX See CreateDatabaseWithParms method.

  • Native UltraLite for Java See ianywhere.native_ultralite.DatabaseManager in the Native UltraLite for Java API Reference.

  • UltraLite.NET See ULDatabaseManager class (iAnywhere.Data.UltraLite namespace) or DatabaseManager class (iAnywhere.UltraLite namespace).

  • UltraLite C++ Component See Class UltraLite_DatabaseManager.

  • UltraLite for embedded SQL See Macros and compiler directives for UltraLite C/C++ applications.

  • UltraLite Static C++ See Macros and compiler directives for UltraLite C/C++ applications.

  • UltraLite Static Java See UltraLite API reference.

  • UltraLite for M-Business Anywhere See Method createDatabaseWithParms.


Setting UltraLite database properties

You can set global characteristics of UltraLite databases when the database is first created, either in the schema or on the first connection attempt.

  • Character set.

    See Creating UltraLite schema files.

  • Case sensitivity.

    See Creating UltraLite schema files.

  • Data encryption.

    See Encrypting UltraLite databases and Obfuscate connection parameter.

  • Database page size.

    See UltraLite database files and Page Size connection parameter .

  • Date and time formats.

    These must be set in the schema file as database options. See UltraLite database options.

  • Precision and scale for arithmetic operations.

    These must be set in the schema file as database options. See UltraLite database options.

  • The amount of memory used as a cache by the UltraLite runtime.

    See Cache Size connection parameter .

  • Preallocation of file-system space.

    See Reserve Size connection parameter .


UltraLite database options

UltraLite databases support the following set of database options, which must be set in the schema file. One set of options controls the handling of dates and times. A second set controls the default handling of arithmetic operations.

Setting database options

For UltraLite components, the database options must be set in the schema file.

  • If you are using the Schema Painter, set the options in the database property sheet.

  • If you are using the ulinit utility, set the options in your Adaptive Server Anywhere reference database.

  • If you are using the ulxml utility, set the options in the XML document that describes the database schema.

For UltraLite static interfaces, set the options in your Adaptive Server Anywhere reference database.

For information about setting Adaptive Server Anywhere database options, see Setting options.

Date and time options

The following database options control the default handling of dates and times. These settings can be changed within SQL operations by using functions such as the DATEFORMAT function.

  • DateFormat Sets the default string format in which dates are retrieved from the database.

    Allowed values are constructed from the symbols listed in the table that follows this list. The default value is YYYY-MM-DD.

    The corresponding Adaptive Server Anywhere database option is DATE_FORMAT. See DATE_FORMAT option [compatibility].

  • DateOrder Sets the default interpretation of dates when submitted to the database.

    Allowed values are MDY, YMD, DMY. The default value is YMD.

    The corresponding Adaptive Server Anywhere database option is DATE_ORDER. See DATE_ORDER option [compatibility].

  • NearestCentury Sets the interpretation of two-integer year values when submitted to the database.

    Allowed values are integers from 0 to 100 inclusive. The default value is 50. Two digit years YY less than the value are converted to 20YY, while years greater than or equal to the value are converted to 19YY.

    The corresponding Adaptive Server Anywhere database option is NEAREST_CENTURY. See NEAREST_CENTURY option [compatibility].

  • TimeFormat Sets the default format for times retrieved from the database.

    Allowed values are constructed from the symbols listed in the table that follows this list. The default value is HH:NN:SS.SSS.

    The corresponding Adaptive Server Anywhere database option is TIME_FORMAT. See TIME_FORMAT option [compatibility].

  • TimestampFormat Sets the default format for timestamp values retrieved from the database.

    Allowed values are constructed from the symbols listed in the table that follows this list. The default value is YYYY-MM-DD HH:NN:ss.SSS.

    The corresponding Adaptive Server Anywhere database option is TIMESTAMP_FORMAT. See TIMESTAMP_FORMAT option [compatibility].

  • TimestampIncrement As timestamps are inserted into the database, UltraLite truncates them to match this increment. This value is useful when a DEFAULT TIMESTAMP column is being used as a primary key or row identifier. In particular, during synchronization it can be important that timestamps match, and different supported consolidated databases maintain timestamps to different resolution. Setting the TimestampIncrement to match that of the consolidated database can help to avoid spurious inequalities.

    Allowed values are integers greater than zero. The default value is 1.

    The corresponding Adaptive Server Anywhere database option is TRUNCATE_TIMESTAMP_VALUES. See TRUNCATE_TIMESTAMP_VALUES option [database].

The symbols used in DateFormat, TimeFormat, and TimestampFormat values are taken from the following table:

Symbol | Description
yy | Two digit year.
yyyy | Four digit year.
mm | Two digit month, or two digit minutes if following a colon (as in hh:mm).
mmm[m...] | Character short form for months—as many characters as there are "m"s. An upper case M causes the output to be made upper case.
d | Single digit day of week, (0 = Sunday, 6 = Saturday).
dd | Two digit day of month. A leading zero is not required.
ddd[d...] | Character short form for day of the week. An upper case D causes the output to be made upper case.
hh | Two digit hours. A leading zero is not required.
nn | Two digit minutes. A leading zero is not required.
ss[.ss..] | Seconds and parts of a second.
aa | Indicate AM or PM (12 hour clock).
pp | Indicate times after noon by PM (12 hour clock).
jjj | Day of the year, from 1 to 366.
Arithmetical operations

The Precision and Scale options control the handling of arithmetical operations.

  • Precision Sets the maximum number of digits in the result of any decimal arithmetic.

    Allowed values are integers between 0 and 127 inclusive. The default value is 30.

    Precision is the total number of digits to the left and right of the decimal point. The Scale option specifies the minimum number of digits after the decimal point when an arithmetic result is truncated to the maximum Precision.

  • Scale Sets the minimum number of digits after the decimal point when an arithmetic result is truncated to the maximum Precision.

    Allowed values are integers between 0 and 127 inclusive. The default value is 6.

For example, when a DECIMAL(8,2) value is multiplied by a DECIMAL(9,2) value, the result could require a DECIMAL(17,4). If Precision is 15, only 15 digits are kept in the result. If Scale is 4, the result is a DECIMAL(15,4). If Scale is 2, the result is a DECIMAL(15,2). In both cases, there is a possibility of overflow.


Encrypting UltraLite databases

By default, UltraLite databases are unencrypted on disk and in permanent memory. Text and binary columns are plainly readable within the database file when using a viewing tool such as a hex editor. Two options are provided for greater security:

  • Obfuscation This option provides protection against casual attempts to access data in the database. It does not provide as much security as strong encryption. Obfuscation has minimal performance impact.

  • Strong encryption UltraLite database files can be strongly encrypted using the AES 128-bit algorithm, which is the same algorithm used to encrypt Adaptive Server Anywhere databases. Use of strong encryption provides security against skilled and determined attempts to gain access to the data, but has a significant performance impact.

    Caution If the encryption key for a strongly encrypted database is lost or forgotten, there is no way to access the database. Under these circumstances, technical support cannot gain access to the database for you. It must be discarded and you must create a new database.
Encrypting UltraLite databases

To encrypt an UltraLite database, you supply an encryption key when you create the database file. The supplied key is used to encrypt the database. On subsequent attempts, the supplied key is checked against the encryption key, and connection fails unless the key matches.

Changing the encryption key

Each interface provides a function to change the encryption key for a database. The application must already be connected to the database using the existing key before the change can be made.

Caution When the key is changed, every row in the database is decrypted using the old key and re-encrypted using the new key. This operation is unrecoverable. If the application is interrupted part-way through, the database is invalid and cannot be accessed. A new one must be created.
For more information

  • UltraLite for MobileVB See Encryption and obfuscation.

  • UltraLite ActiveX See Encryption and obfuscation.

  • Native UltraLite for Java See ianywhere.native_ultralite.ConnectionParms in the API Reference.

  • UltraLite.NET See ULConnectionParms class (iAnywhere.Data.UltraLite namespace) or ConnectionParms class (iAnywhere.UltraLite namespace).

  • UltraLite C++ Component See Class UltraLite_Connection_iface.

  • Embedded SQL and Static C++ API See Encrypting data.

  • UltraLite Static Java See Encrypting UltraLite databases.

  • UltraLite for M-Business Anywhere See Encryption and obfuscation.

Palm OS considerations


Palm OS considerations

If you encrypt an UltraLite database on the Palm Computing Platform, the end user is prompted to re-enter the key each time they launch the application. This section describes how to add code that circumvents the re-entering of the key.

You can save the encryption key in dynamic memory as a Palm feature, and retrieve the key when you launch the application rather than prompting the user. Features are indexed by creator and a feature number. Users can pass in their creator ID or NULL, along with the feature number or NULL, to save and retrieve the encryption key.

The encryption key is not backed up and is cleared on any reset of the device. The retrieval of the key then fails, and the user is prompted to re-enter the key.

The following sample code (embedded SQL) illustrates how to save and retrieve the encryption key:

#define UL_STORE_PARMS StoreParms
static ul_char StoreParms[STORE_PARMS_MAX];
...
startupRoutine() {
   ul_char buffer[MAX_PWD];

   if( !ULRetrieveEncryptionKey(
          buffer, MAX_PWD, NULL, NULL  ) ){
      // prompt user for key
      userPrompt( buffer, MAX_PWD );
      if( !ULSaveEncryptionKey( buffer, NULL, NULL ) ) {
         // inform user save failed
      }
   }
   // build store parms
   StrCopy( StoreParms, "key=" );
   StrCat( StoreParms, buffer );
   ULPalmLaunch( &sqlca, UL_NULL );
}

The following sample code illustrates how to use a menu item to secure the device by clearing the encryption key:

case MenuItemClear
    ULClearEncryptionKey( NULL, NULL );
    break;


User authentication in UltraLite

UltraLite provides optional database user IDs and passwords for user authentication. Unlike Adaptive Server Anywhere and other multi-user database systems, UltraLite user IDs are used for authentication only, not for permission checking or object ownership within a database. By default, UltraLite databases have no user authentication. Once connected to the database, each user has full access to the database.

When an UltraLite database is created, it has an initial user ID of DBA, with a password of SQL. These are also the default values when you connect, so that you can avoid user authentication by not supplying user ID or password connection parameters.

UltraLite permits up to four different user IDs to be defined at a time, with both user ID and password being less than 16 characters long.

If the database is case insensitive (the default) then the user ID and password are case insensitive. If the database is case sensitive, then the password is case sensitive.

UltraLite users have to be added from an existing connection. This means that if you want to add user authentication to your application by changing the user ID or password, you must do so once you have connected using the default user ID and password. What is more, you cannot change a user ID: you add a user and delete an existing user. The function used for changing a password is the same as for changing a user ID.

The general scheme for adding user authentication is as follows:

toggle To add user authentication to your application

  1. Connect to the database using the default uid and pwd parameters.

    New users have to be added from an existing connection, so the first connection to a database must be made using the default user ID and password of DBA and SQL.

  2. Prompt for a user ID and password.

    The way in which you prompt the user depends on your application.

  3. Grant access to this user ID and password combination.

    The method for granting access depends on the interface you are using.

  4. Revoke access from the original user ID.

    In a production environment, it is a security problem if you leave the default user ID and password with access to the database.

UltraLite user IDs are separate from MobiLink user names and from user IDs in any reference database or consolidated databases you use during development and after deployment. In many cases you may wish to provide code so that the values used for each are the same, but they do remain distinct concepts. For example, in the CustDB sample application, you are prompted for an employee number when starting the application. This employee number identifies the database for the purposes of MobiLink synchronization, and is not an UltraLite user ID for connection or data access purposes.

For more information

  • UltraLite for MobileVB See Authenticating users.

  • UltraLite.NET See User authentication.

  • UltraLite C++ Component See Authenticating users.

  • UltraLite ActiveX See Authenticating users.

  • Native UltraLite for Java See User authentication.

  • Embedded SQL See Authenticating users.

  • Static C++ API See Authenticating users.

  • UltraLite Static Java See Adding user authentication to your application.

  • UltraLite for M-Business Anywhere See Authenticating users.

Sharing MobiLink and UltraLite user IDs


Sharing MobiLink and UltraLite user IDs

Although UltraLite and MobiLink user authentication mechanisms are separate, you may wish to provide your end users with a single user ID and password that provides both MobiLink and UltraLite user authentication. To share user IDs and passwords, store them in variables and use the same variable in the UltraLite user authentication calls and the synchronization call.

You can design your application so that, if passwords are reset at a MobiLink consolidated site, your application prompts for the new password.

toggle To prompt for a new MobiLink or UltraLite password

  1. Save the user ID and password in variables.

  2. Synchronize.

  3. If synchronization fails because the user was not authenticated, prompt the user for a new password.

  4. Update the UltraLite user's password using the appropriate function or method.

  5. Update the synchronization information and synchronize again.

For information on MobiLink user authentication, see Authenticating MobiLink Users.


Character sets in UltraLite

There are several places in UltraLite applications where character set issues can arise:

  • The UltraLite schema The database itself has a single collating sequence (character set and sort order), which is specified when the database is created. The collating sequence determines the order of character data in indexes, the results of string comparisons, and so on.

    For more information, see UltraLite database character sets.

  • The UltraLite runtime library or component The UltraLite component or runtime library that accesses the database uses a character set for messages and other interactions with the environment.

    The runtime character sets may be Unicode or ANSI. The character set used determines how the data is stored in the database file. To manage a database, you must use a runtime of the same character set as the one used to create it.

    For more information, see UltraLite runtime character sets.

  • Synchronization When data in the UltraLite database is synchronized with a MobiLink synchronization server, the character set used in the UltraLite database and that in the consolidated database must be consistent.

    For more information, see Synchronization and character sets .


UltraLite database character sets

If you are using an UltraLite component, and create an UltraLite database schema using the Schema Painter, you specify the character set and collating sequence as you create the database schema.

UltraLite applications use the native multi-byte character encoding of the target platform for reasons of efficiency. When the reference database uses a different character encoding, the UltraLite application uses the default collation of the target device.

UltraLite applications use the collating sequence of the reference database if either of the following conditions is met.

  • The reference database uses a single-byte character set.

  • The native character encoding of the target device is multi-byte, the reference database uses the same multi-byte character encoding, and the UltraLite analyzer can find a compact representation for the collation sequence used by the reference database.

For example, if you use a 932JPN reference database to build an application for the Japanese Palm Computing Platform, then the UltraLite application can inherit the collation information because the native character encoding is the same as that of the reference database. However, if you use a 932JPN reference database to build an UltraLite application for the Windows CE platform, the application will use Unicode and the default Unicode collation information.

Sort orders

If the character set is single byte, or the native character set of the target device is the same as the character set of the reference database, columns that are CHAR(n) or VARCHAR(n) compare and sort according to the collation sequence of the reference database.

For information about creating databases, see Creating UltraLite databases and schemas.

Data storage

The way that character data is stored depends not only on the collation sequence used when creating the schema, but also on the character set (ANSI or Unicode) of the UltraLite runtime library that manages the database.

For more information, see UltraLite runtime character sets.


UltraLite runtime character sets

The character set of the UltraLite runtime library is different depending on the target operating system. The character set determines how data is exchanged with the application and also affects data storage. This section provides background information on character sets used on platforms supported by UltraLite.

Palm Computing Platform

Single-byte Palm Computing Platform devices use a character set based on code page 1252 (the Windows US code page). The 1252Latin1 code page is appropriate for developing applications for the Palm Computing Platform. The 1252Latin1 code page is the default Adaptive Server Anywhere collation sequence. Japanese Palm Computing Platform devices use the 932JPN character set.

Windows CE

The Windows CE operating system uses Unicode. UltraLite running on Windows CE also uses Unicode to store CHAR(n) and VARCHAR(n) columns. Adaptive Server Anywhere collating sequences define behavior for 8-bit ASCII character sets.

UltraLite for Windows CE uses the Adaptive Server Anywhere collating sequence when comparing Unicode characters that have a corresponding 8-bit ASCII character in the collating sequence being used, allowing accented characters to be considered equal to and to sort with unaccented characters. Unicode characters that have no corresponding 8-bit ASCII character use a comparison of two Unicode values.

Windows desktop operating systems

The UltraLite components are all Unicode based.

The runtime library used by UltraLite embedded SQL and Static C++ applications on Windows NT/2000/XP and Windows 98 is provided in both ANSI and UNICODE versions. UltraLite versions before version 9 included only an ANSI version of the runtime library.

Compatibility of database files

The runtime or component that is used to create the database determines how characters are stored within the database. You cannot create an UltraLite database using an ANSI component or runtime library and then use that database file with a Unicode component or runtime library.

The following table lists the character set in use by UltraLite components and runtime libraries. These character sets dictate whether or not you can use a database file created by one version of UltraLite in another. In particular, note that you cannot open a database created by version 8.0.2 UltraLite for MobileVB or UltraLite ActiveX on a Windows operating system (other than Windows CE) in version 9.0 or later software.

Environment | 8.0.2 | 9.0 and later
Windows components | ANSI | Unicode
Windows CE components | Unicode | Unicode
Windows (Native UltraLite for Java) | Unicode | Unicode
Windows 8.0.2 DLL | ANSI | N/A
Windows (ulrt9.dll) | N/A | ANSI
Windows (ulrtw9.dll) | N/A | Unicode
Windows (ulrtcw9.dll (engine)) | N/A | Unicode
Windows CE | Unicode | Unicode
Static Java

The error-handling objects SQLException and SQLWarning provide the capability for Java applications to obtain error or warning messages. By default, these messages are supplied in English.

Localized error and warning messages may be obtained in a non-English language by setting the Java Locale to the appropriate language. For example, to obtain French messages, the following code fragment might be used:

java.util.Locale locale = new java.util.Locale( "fr", "" );
java.util.Locale.setDefault( locale );

The default Locale should be set at the start of the program. Once a message is placed in an error-handling object, the language to be used for the message is established for that execution of the program. For more information, see your Java documentation.


Synchronization and character sets

When you synchronize, the MobiLink synchronization server always translates characters uploaded from your application database to Unicode and passes them to your consolidated database server using the Unicode ODBC API. The consolidated database server, or its ODBC driver, then performs any translation that may be required to convert them to the character encoding of your consolidated database. This second translation will always occur unless your consolidated database uses Unicode.

When information is downloaded, the consolidated database server converts the characters to Unicode. The MobiLink synchronization server then automatically translates the characters, if necessary, to suit the requirements of your UltraLite application.

When both UltraLite application and consolidated database use the same character encoding, no translation is necessary. If translation is necessary, problems can arise when multiple character codes in your UltraLite application map to a single Unicode value, or vice versa. In this event, the MobiLink synchronization server translates in a consistent manner, but the behavior is influenced by the translation mechanism within the consolidated database server.


UltraLite database internals

In addition to storing the rows of data in each table, UltraLite stores state information about each row, and stores indexes to efficiently access the rows.

UltraLite database files
How UltraLite tracks row states
UltraLite tables must have primary keys
Indexes in UltraLite databases
Transaction processing, recovery, and backup


UltraLite database files

UltraLite databases are stored in a single file that holds the tables, indexes, and all other information in the database.

The tables and indexes are stored in fixed-size pages. Database I/O operations are carried out a page at a time. The default page size is 4K. For more information, see Page Size connection parameter .

The temporary file

UltraLite maintains a temporary file to hold information while processing and to hold application state information. This file can be deleted without loss of data when UltraLite is not running.

On Windows and Windows CE, UltraLite database files typically have a name of the form dbname.udb. In this case, the temporary file is dbname.~db (with the same path). If the database name has a different form, a '~' is appended to the end of the name for the temporary file. On Palm OS the temporary file is ul_tmp_<creator-id>.

Palm OS

UltraLite databases on the Palm OS can be stored in the Palm virtual file system for expansion cards, or they can be stored in the Palm record-based data store. For more information, see Choosing database storage on the Palm OS.


How UltraLite tracks row states

Each row in an UltraLite database has a one-byte marker to keep track of the state of the row. The row states are used to control transaction processing, recovery, and synchronization.

When a delete is issued, the state of each affected row is changed to reflect the fact that it was deleted. Rolling back a delete is as simple as restoring the original state of the row.

When a delete is committed, the affected rows are not always removed from memory. If the row has never been synchronized, then it is removed. If the row has been synchronized, then it is not removed until the next synchronization confirms the delete with the consolidated database. After the next synchronization, the row is removed from memory.

Similarly, when a row is updated in an UltraLite database, a new version of the row is created. The states of the old and new rows are set so the old row is no longer visible and the new row is visible. When an update is synchronized, both the old and new versions of the row are needed to allow conflict detection and resolution.

The old version of the row is deleted after synchronization. If a row is updated many times between synchronizations, only the oldest version of the row and the most recent version of the row are kept.


UltraLite tables must have primary keys

Tables in UltraLite applications must include a primary key.

Primary keys are also required during MobiLink synchronization, to associate rows in the UltraLite database with rows in the consolidated database.

For static APIs, the UltraLite generator uses primary key columns from your reference database to generate primary key columns in the UltraLite database. If the primary key columns for any table are not included in the data required in the UltraLite database, the UltraLite generator looks for a uniqueness constraint on the table, and promotes the columns with such a constraint to a primary key in the UltraLite database. If there are no unique columns, the generator reports an error.


Indexes in UltraLite databases

UltraLite indexes are similar to B+ trees with very small index entries.

Except for pure Java databases, each index entry is exactly two bytes, and each index page contains 256 entries. Since index pages are rarely 100% full and each index has some fixed overhead, the memory used by an UltraLite index is more than two bytes per row in the table. The overhead for each index is just over 1 K per index. Typically, UltraLite index pages on larger tables will be least 85% full.

No similar consistent rule can be given for the memory requirements of UltraLite Java databases.


Transaction processing, recovery, and backup

UltraLite provides transaction processing. A transaction is a logical set of operations that are executed atomically; that is, either all operations in the transaction are stored in the database or none are. If a transaction is committed, all operations are stored in the database; if a transaction is rolled back, none are.

Some transactions consist of a single operation. Many programming interfaces use an autocommit setting to commit a transaction after each operation. If you are using one of these interfaces, you must set autocommit to off in order to exploit multi-operation transactions. The way of setting autocommit off depends on the programming interface you are using; in most interfaces it is a property of the connection object.

Recovery from system failure

If an application using an UltraLite database stops running unexpectedly, the UltraLite database automatically recovers to a consistent state when the application is restarted. All transactions committed prior to the unexpected failure are present in the UltraLite database. All transactions not committed at the time of the failure are rolled back.

UltraLite does not use a transaction log to perform recovery. Instead, UltraLite uses the state byte for every row to determine the fate of a row when recovering. When a row is inserted, updated, or deleted in an UltraLite database, the state of the row is modified to reflect the operation and the connection that performed the operations. When a transaction is committed, the states of all rows affected by the transaction are modified to reflect the commit. If an unexpected failure occurs during a commit, the entire transaction is rolled back on recovery.

For information about state bytes, see How UltraLite tracks row states.

Backups

UltraLite provides protection against system failures, but not against media failures. If the UltraLite data store itself is corrupted, the only way to protect is through synchronization.

The best way of making a backup of an UltraLite application is to synchronize with a consolidated database. To restore an UltraLite database, start with an empty database and populate it from the consolidated database through synchronization.


UltraLite database limitations

The following table lists the absolute limitations imposed by data structures in the software on the size and number of objects in an UltraLite database. In most cases, the memory, CPU, and storage device of the computer impose stricter limits.

Item | Limitation
Number of connections per database | 14
Number of columns per table | 65535 but limited by row size. Row size is limited to about 4 KB, so the practical limit on the number of columns per table is much smaller than this: much less than 4000 in most situations.
Number of indexes | Approximately 1000. If you set the page size to 2 KB, the maximum number of indexes per table is reduced to approximately 500.
Number of rows per database | Limited by persistent store.
Number of rows per table | 65534.
Number of tables per database | Approximately 1000. If you set the page size to 2 KB, the maximum number of tables is reduced to approximately 500.
Number of tables referenced per transaction | No limit
Row size | Approximately 4 KB (compressed). LONG VARCHAR and LONG BINARY values are stored separately, and are in addition to the 4 KB limit.
File-based persistent store | 2 GB file or OS limit on file size
Palm Computing Platform database size | 128 Mb (Primary storage) 2 GB (expansion card file system)

For other limitations, see Overview of SQL support in UltraLite.

Adaptive Server Anywhere features not available in UltraLite


Adaptive Server Anywhere features not available in UltraLite

The following Adaptive Server Anywhere features are not available in UltraLite databases:

  • Cascading updates and deletes Some applications rely on declarative referential integrity to implement business rules. These features are not available in UltraLite databases except during synchronization downloads, when updates and deletes are cascaded automatically.

    Any attempt to delete a primary key that has a corresponding value in a foreign key fails with an error. Any attempt to update a primary key value when foreign keys reference the original value also fails.

  • Check constraints You cannot include table or column check constraints in an UltraLite database.

  • Computed columns You cannot include computed columns in an UltraLite database.

  • Global temporary tables The temporary aspect of global temporary tables is not recognized by UltraLite. They are treated as if they were permanent base tables, which you should use instead.

  • Declared temporary tables You cannot declare a temporary table within an UltraLite application.

  • Stored procedures You cannot call stored procedures or user-defined functions in an UltraLite application.

  • Functions Not all SQL functions are available for use in UltraLite applications.

    Use of an unsupported function gives a Feature not available in UltraLite error.

    For a list of supported functions, see UltraLite SQL functions.

  • Triggers Triggers are not supported in UltraLite databases.

  • System table access There are no system tables in an UltraLite database.

  • System functions You cannot use Adaptive Server Anywhere system functions, including property functions, in UltraLite applications.

  • Java in the database You cannot include Java methods in your queries or make any other use of Java in the database.

  • Timestamp columns You cannot use Transact-SQL timestamp columns in UltraLite databases. Transact-SQL timestamp columns are created with the following default:

    DEFAULT TIMESTAMP

    You can use columns created as follows:

    DEFAULT CURRENT TIMESTAMP

    There is a behavior difference between the two: a DEFAULT CURRENT TIMESTAMP column is not automatically updated when the row is updated, while a DEFAULT TIMESTAMP column is automatically updated. You must explicitly update columns created with DEFAULT CURRENT TIMESTAMP if you wish the column to reflect the latest update time.

SQL limitations

If you are using dynamic SQL in your UltraLite application, the range of SQL available is less than in Adaptive Server Anywhere.

For more information, see Dynamic SQL.

UltraLite applications using static interfaces can use a wider range of SQL, but the following SQL features are not supported.

  • Dynamic SQL Dynamic SQL is not available to applications using static interfaces.

  • SAVEPOINT statement UltraLite databases support transactions, but not savepoints within transactions.

  • SET OPTION statement UltraLite databases do support a set of options, but you cannot use the SET OPTION statement in an UltraLite application to change option settings.

    For UltraLite components, you can set options in the database schema file, either by setting them in the reference database and using ulinit, or from the UltraLite Schema Painter, or in an XML document holding the schema.

    For more information about UltraLite database options, see UltraLite database options.

  • Schema modification To modify the schema of a UltraLite database from a static interface application, you must build a new version of your application.

    To modify the schema of an UltraLite database from an UltraLite component, you can use schema modification statements or you can deploy an updated schema file.

    For more information, see Upgrading UltraLite database schemas.


Upgrading UltraLite database schemas

If you develop a new version of an UltraLite application, you may wish to alter the database schema. You can deploy an upgraded UltraLite schema and maintain the data in existing end-user databases subject to some restrictions. This feature is not available to UltraLite applications built using the Static Java API.

Caution Schema upgrade is not a reversible process. If an error occurs during schema upgrade, it is possible to be left with an unusable database. Ensure that your application has backed up all changes (by synchronizing or by copying the database file) before upgrading the schema of databases containing important data.

The mechanism for deploying an upgraded schema depends on whether you use an UltraLite component (which requires a new schema file) or whether you use a static interface (in which case the schema definition is held in the generated application code).

toggle To deploy a new schema (UltraLite components)

  1. Create a new schema file.

    You can create your new schema using the Schema Painter or using ulinit.

    If you use the schema painter, prepare the schema for deployment by defining the mapping between old and new names. This mapping is used to avoid losing data during the migration.

    1. In the schema painter, choose File > Prepare Schema for Deployment.

    2. Specify the mappings between old table or column names and their equivalent in the new database schema.

    If you use ulinit to create the new schema, you lose any data held in renamed columns—the schema is interpreted as dropping the old column and creating a new column.

  2. Apply the schema file to the existing database.

    The components expose a database schema as a DatabaseSchema or ULDatabaseSchema object. You obtain a schema object using the DatabaseSchema property on the Connection or ULConnection object.

    Use the ApplyFile method on the ULDatabaseSchema object to apply the new schema.

toggle To deploy a new schema (embedded SQL and Static C++ API)

  1. Modify the schema in your reference database.

  2. Create the new version of your application.

  3. Ensure that your application calls ULEnableGenericSchema().

    When a new UltraLite application built with a static interface is deployed to a device, UltraLite by default recreates an empty database, losing any data that was in the database before the new application was deployed. If you call ULRegisterSchemaUpgradeObserver, the existing database is instead upgraded to the schema of the new application. Applications that upgrade a database schema must call this function.

    See ULRegisterSchemaUpgradeObserver function.

  4. The schema is upgraded automatically when the new application is applied.

    For information on how the schema upgrade happens, see How schema upgrade works.

Monitoring schema upgrades

Database schema upgrades can be a time-consuming process. An upgrade observer lets you display progress information to the user, and allows the user to cancel the upgrade during the initial step of the process.

The mechanism depends on the interface you are using.

  • UltraLite for MobileVB Implement handlers for the OnSchemaUpgradeStateChange and OnSchemaUpgradeProgress events.

    See OnSchemaUpgradeProgress event and OnSchemaUpgradeStateChange event.

  • UltraLite.NET Implement the SchemaUpgradeListener interface and supply the object to DatabaseSchema.ApplyFile(). During the schema upgrade, your SchemaUpgradeListener.SchemaUpgrading method is invoked.

    See SchemaUpgradeListener in the API Reference.

  • Native UltraLite for Java Implement the SchemaUpgradeListener interface and supply the object to DatabaseSchema.applyFile(). During the schema upgrade, your SchemaUpgradeListener.schemaUpgrading method is invoked.

    See ianywhere.native_ultralite.SchemaUpgradeListener in the API Reference.

  • UltraLite C/C++ interfaces Implement and register a callback function that handles the schema upgrade events.

    See ULRegisterSchemaUpgradeObserver function and Callback function for ULRegisterSchemaUpgradeObserver.

  • UltraLite ActiveX This feature is not available for UltraLite ActiveX.

  • UltraLite for M-Business Anywhere This feature is not available for UltraLite for M-Business Anywhere.


How schema upgrade works

Back up before upgrading
It is strongly recommended that you back up your data before attempting a schema upgrade, either by copying the database file or by synchronizing.

The schema upgrading process relies on matching names in the old and new schema. If a row in the database is incompatible with the new schema, that row is deleted from the database. In general, adding constraints to tables that have data in them or carrying out unpredictable column conversions may result in lost rows.

The schema upgrade proceeds as follows:

  1. Any old tables not in the new schema are dropped.

  2. Any new tables are created.

  3. For any table that exists in both the old and new schema, columns are added and dropped as needed. If a new column is not nullable and has no default value, it is filled with zeros (numeric data types), the empty string (character data types), and an empty binary value.

  4. Columns whose properties have changed are then modified.

    Caution If an error occurs during conversion for any row, that row is dropped and the SQL warning SQLE_ROW_DROPPED_DURING_SCHEMA_UPGRADE is generated.

  5. Indexes and constraints are rebuilt. This step may also result in rows being dropped if, for example, an index is redefined as UNIQUE but has duplicate values.


Upgrading UltraLite software

On Windows operating systems other than Windows CE, if you are using UltraLite for MobileVB or UltraLite ActiveX, you cannot open an UltraLite database file created using 8.0.2 software. For more information, see UltraLite behavior changes.

For compatibility of UltraLite database files with previous releases, see UltraLite runtime character sets.


The UltraLite runtime

The UltraLite runtime manages UltraLite databases and synchronization. With the exception of the Static Java API, the UltraLite runtime for each target platform is based on a single code base. The UltraLite runtime is provided in several different forms:

  • Components The UltraLite runtime is linked into each component.

  • Static library For static interfaces, the UltraLite runtime is provided as a static library that you link into your application. There is then no separate file to deploy.

  • Dynamic library For C/C++ Windows and Windows CE applications, the UltraLite runtime is provided as a dynamically linked library (DLL).

  • Separate executable For Windows and Windows CE a separate executable called the UltraLite engine is provided. The UltraLite engine is the only version of the runtime to support connections from multiple applications. Each such application must link against a client library when using the UltraLite engine.

    For more information, see Using the UltraLite engine.


Understanding concurrency in UltraLite

UltraLite databases may receive multiple concurrent requests. In order to design applications that handle concurrent requests properly you should understand how UltraLite manages concurrency in the database.

Concepts

It is helpful to separate several concepts when thinking about concurrent database access. These concepts are ordered from high-level to low-level:

  • Applications The UltraLite engine can respond to requests from multiple separate applications. Other versions of the UltraLite runtime permit only a single application to connect to a database at a time.

    For more information, see The UltraLite runtime.

  • Threads The UltraLite runtime supports multi-threaded applications. A single application may be written to use multiple threads, each of which may connect to the database.

    For more information, see Threading in UltraLite applications.

  • Connections Even a single-threaded application may open multiple connections to a database. In any case, individual connections can employ only a single thread.

  • Transactions Each connection can have a single transaction in progress at any one time. Transactions may consist of a single request or multiple requests. Data modifications made during a transaction are not permanent in the database until the transaction is committed. Either all data modifications made in a transaction are committed, or all are rolled back.

  • Requests A transaction consists of one or more requests. A request may be a query that reads data, or an insert, update, or delete that modifies data, or a synchronization.

  • The current row When an application is working with the result set of a query, UltraLite maintains a pointer to the current row within the result set. In some interfaces, this current row is tracked explicitly using a cursor (a pointer to a position in a result set). In others, the application uses methods on a result set object or table object to identify and change the current row. Such methods use a cursor "under the covers".

Multiple databases

The UltraLite runtime can manage a maximum of four databases at any one time. A single UltraLite application may open multiple connections to separate databases. No concurrency issues arise from such applications, as the data in each database is independent.

Locking

When a transaction changes a row, UltraLite locks that row until the transaction is committed or rolled back. The lock prevents other transactions from changing the row, although they can still read the row. An attempt to change a locked row sets error SQLCODE SQLE_LOCKED, while an attempt to change a deleted row sets the error SQLE_NOTFOUND. Your applications should check the SQLCODE value after attempting to modify data.

Re-reading rows

To understand how locking and concurrency is managed, it helps to consider two connections, A and B, each with their own transaction.

As connection A works with the result set of a query, UltraLite fetches a copy of the current row into a buffer. If A modifies the current row, it changes the copy in the buffer. The copy in the buffer is written back into the database when connection A calls an Update method or closes the result set. At that time, a write lock is placed on the row to prevent other transactions from modifying it. The change to the database is not permanent until connection A commits the transaction.

Reading or fetching a row does not lock the row. If connection A fetches but does not modify a row, connection B can still modify the row.

If connection B does modify the current row, the row becomes locked. Connection A can then not modify the current row. If connection A fetches the current row again, and the row has been deleted, connection A gets the next row in the result set. If the row has been modified, connection A gets the latest copy of the row. If the columns of the index used by connection A have been modified, connection A sees the change as a delete followed by an insert, and so gets the next row in the result set.

Synchronization

Synchronization behaves as a separate connection. During the upload phase, UltraLite applications can access UltraLite databases in a read-only fashion. During the download phase, read-write access is permitted but if an application changes a row that the download then attempts to change, the download will fail and roll back. You can disable access to data during synchronization by setting the Disable Concurrency synchronization parameter.

For more information, see Disable Concurrency synchronization parameter.


Threading in UltraLite applications

The UltraLite runtime is thread safe. You can develop multi-threaded applications as long as the development tool and the target platform both support multi-threaded applications. The exceptions are as follows:

  • You cannot develop multi-threaded applications using UltraLite for MobileVB, because of limitations in the underlying development tools.

  • You cannot develop multi-threaded applications using UltraLite ActiveX or UltraLite for M-Business Anywhere, because of limitations in eMbedded Visual Basic, JScript, and JavaScript.

  • You cannot develop multi-threaded applications for the Palm OS, because of limitations in the operating system.

  • From static interfaces, the same query cannot be executed more than once at a time. As a result, you cannot access more than one instance at a time of a result set for a given query.

Each thread must manage its own set of objects, including the Database Manager object or its equivalents in the static interfaces (ULData, SQLCA). The database manager object can be passed to a thread rather than being initialized on the thread, but all management of data must be carried out on an individual thread.

Static Java API

The UltraLite runtime used by the Static Java API permits access to a single database by a single application.

The UltraLite runtime is thread safe. Users of the Sun Java VM must use version 1.2 or later to run multi-threaded UltraLite applications. Users of the Jeode VM on Pocket PC and the IBM Java VM can run multi-threaded UltraLite applications even though these VMs are based on JDK 1.1.8.

The entire UltraLite runtime is treated as a single critical section, only allowing one thread to enter it at a time.

For more information, see Using the UltraLite JdbcDatabase.connect method.


Using the UltraLite engine

You can deploy the UltraLite runtime in the form of the UltraLite engine as an alternative to deploying the UltraLite runtime as a library or in a component.

The UltraLite engine acts as a database server for UltraLite databases. It is provided for Windows and Windows CE platforms, as a separate executable. The advantage of the UltraLite engine is that it provides same-machine access to the database from multiple applications. The disadvantage is that the UltraLite engine requires more system resources than other versions of the UltraLite runtime and may yield lower performance.

toggle To use the UltraLite engine

  1. Deploy the client version of your component.

    The client versions are as follows. Paths are relative to your SQL Anywhere installation:

    • UltraLite.NET (Windows CE) UltraLite\UltraLite.NET\ce\arm\ulnetclient9.dll

    • UltraLite.NET (Windows XP) win32\ulnetclient9.dll

    • Native UltraLite for Java (Windows CE) UltraLite\NativeUltraLiteForJava\ce\arm\julclient9.dll

    • Native UltraLite for Java (Windows XP) UltraLite\NativeUltraLiteForJava\win32\julclient9.dll

    • C++ Component (Windows CE) UltraLite\ce\arm\lib\ulrtc.lib (static library)

    • C++ Component (Windows XP) UltraLite\win32\386\lib\ulimpcw.lib (import library) and UltraLite\win32\386\ulrtcw9.dll (dynamic library)

    • UltraLite for M-Business Anywhere (Windows CE) UltraLite\UltraLiteForMBusinessAnywhere\ce\arm\ulpodclient9.dll. The client library must be deployed under the AvantGo\Pods directory.

    • UltraLite for M-Business Anywhere (Windows XP) UltraLite\UltraLiteForMBusinessAnywhere\win32\386\ulpodclient9.dll. The client library must be deployed under the AvantGo\Pods directory.

    • UltraLite ActiveX Not available.

    • UltraLite for MobileVB Not available.

  2. Specify the runtime type in the DatabaseManager constructor.

    This step is required for Native UltraLite for Java and for UltraLite.NET only.

Starting the engine

You can start the UltraLite engine in the following ways.

  • Manually starting the UltraLite engine Enter the following command at a command prompt.

    dbuleng9

  • Let your application start the UltraLite engine When you deploy your UltraLite application using the client version of your UltraLite component, it starts the UltraLite engine on the first connection attempt. If an engine is already running, it uses that engine to connect to the database.

    To specify the location of dbuleng9.exe, use the StartLine connection parameter when connecting to the database for the first time. If the StartLine parameter is not provided, the client looks for dbuleng9.exe in the \Windows, root (\), and \UltraLiteDB directories in that order on Windows CE and in the win32 subdirectory of your SQL Anywhere installation on other Windows operating systems.

To connect to a database using the UltraLite engine, you must supply the user ID (uid) and password (pwd) connection parameters.

You can stop the UltraLite engine manually using the dbulstop utility. Alternatively, you can let the application stop the engine. The last application to disconnect from the database stops the UltraLite engine automatically.


Connection Parameters

About this chapter

This chapter provides a reference for the parameters that establish and describe connections from client applications to a database.


Overview

You must supply connection parameters for an application to connect to an UltraLite database. The connection parameters must specify the database to which the connection is to be established, usually by providing a database filename and path.

As an application may be compiled for more than one platform, a separate parameter for each target platform is available to identify the database. If user authentication is enabled, the connection parameters must also specify a user name and password.

For more information, see Database Identification parameters, and Open Connection parameters.

UltraLite databases are often created by the application itself, and characteristics of the database are defined by connection parameters. The connection parameters must include a schema file (for UltraLite components) as well as optional parameters to adjust database features. If you are using embedded SQL, the static C++ API, or the Static Java API, the database is created from information already stored in the application and no schema file is needed.

For more information, see Database Schema parameters, and Additional connection parameters.

All connection parameters are case insensitive.

The following table lists the available connection parameters. Database Schema parameters, used only when creating a database are marked with an asterisk (*).

Parameter | Description
Additional Parms | A placeholder for additional connection parameters. See Additional Parms connection parameter
Cache Size | Defines the size of the cache. See Cache Size connection parameter .
Connection Name | Specifies a connection name. See Connection Name connection parameter.
Database On CE | The path and filename of the UltraLite database file to which you want to connect on Windows CE. See Database On CE connection parameter.
Database On Desktop | The path and filename of the UltraLite database file to which you want to connect. See Database On Desktop connection parameter.
Database On Palm | An identifier for the UltraLite database on Palm OS. See Database On Palm connection parameter.
Encryption Key | An encryption key for the database. See Encryption Key connection parameter .
Obfuscate* | Apply a simple encryption scheme to the database. See Obfuscate connection parameter.
Page Size | The database page size. See Page Size connection parameter .
Palm Allow Backup | Controls HotSync backup behavior on Palm OS devices. See Palm Allow Backup parameter.
Password | A password for the user. See Password connection parameter.
Reserve Size | Defines the reserve size. See Reserve Size connection parameter .
Schema On CE* | The path and filename of the UltraLite schema on Windows CE. See Schema On CE connection parameter .
Schema On Desktop* | The path and filename of the UltraLite schema. See Schema On Desktop connection parameter
Schema On Palm* | The UltraLite schema for the Palm OS. See Schema On Palm connection parameter .
User ID | The user ID with which you connect to the database. See User ID connection parameter.
VFS On Palm* | Identifies the Palm card as using the virtual file system. See VFS On Palm parameter .


Specifying file paths

Filenames and paths in connection parameters are subject to the following requirements, depending on the UltraLite Component you are using:

Target platform | Requirement
Java | All backslashes must be escaped. For example, "file_name=\\UltraLite\\MyFile.udb".
Windows CE | Paths are absolute.
Windows | Paths may be absolute or relative.


Specifying connection parameters

Each connection parameter can be specified in the following ways:

  • As a property of a Connection Parameters object The following interfaces provide a connection parameters object. This object has properties that are individual connection parameters.

    • UltraLite for MobileVB. You can specify connection parameters by adding an UltraLite control to a form and specifying its properties in the Properties window.

    • UltraLite ActiveX

    • Native UltraLite for Java

    • UltraLite.NET. You can specify connection parameters by adding an UltraLite.NET control to a form and specifying its properties in the Properties window.

  • In the AdditionalParms property The interfaces that supply a connection parameters object include an Additional Parms property. This property takes a connection string as its value.

  • As a keyword in a connection string UltraLite interfaces can supply a connection string when connecting. The keywords in the connection string are individual connection parameters.

  • In the UL_STORE_PARMS macro Embedded SQL and the static C++ API both use the UL_STORE_PARMS macro to hold connection parameters that affect database file. The parameters are used only on the initial connection attempt, when the database is created. The UL_STORE_PARMS macro takes a connection string.

    For example, the following definition sets a connection parameter.

    #define UL_STORE_PARMS    UL_TEXT( "reserve_size=2m" )

Where possible, it is recommended that you use the Connection Parameters object. It provides easier checking and a more systematic interface than using a connection string.

Connection strings and connection parameters

Some less commonly used parameters can be specified only in a connection string. Depending on the interface, the connection string can be supplied in the AdditionalParms property, in the UL_STORE_PARMS macro, or in an Open method that takes a connection string as argument.

If a parameter is specified both in a property and in a connection string, the value in the property takes precedence.

Troubleshooting tip
UltraLite ignores unrecognized connection string parameters. As a result, spelling mistakes may not be immediately obvious.

Previous Next


Database Identification parameters

The connection parameters in this section are used to identify the UltraLite database. At least one of these parameters must be specified on each connection attempt.

Database Identification parameters are also used when dropping (deleting) a database.

For more information

  • UltraLite for MobileVB See OpenConnection method, and OpenConnectionWithParms method.

  • UltraLite ActiveX See OpenConnection method, and OpenConnectionWithParms method.

  • Native UltraLite for Java See ianywhere.native_ultralite.DatabaseManager in the Native UltraLite for Java API Reference.

  • UltraLite.NET See ULDatabaseManager class (iAnywhere.Data.UltraLite namespace) or DatabaseManager class (iAnywhere.UltraLite namespace).

  • UltraLite C++ Component See Class UltraLite_DatabaseManager.

  • UltraLite for M-Business Anywhere See Method openConnection, and Method openConnectionWithParms.

  • UltraLite for Embedded SQL See Initializing the SQL Communications Area.

  • UltraLite Static C++ API See Connecting to a database.

  • UltraLite Static Java See Connecting to the database using JDBC.

Additional Parms connection parameter
Database On CE connection parameter
Database On Desktop connection parameter
Database On Palm connection parameter


Additional Parms connection parameter

Function

Permits additional connection parameters to be specified.

Syntax
Interface | Connection parameter
UltraLite for MobileVB | AdditionalParms
UltraLite ActiveX | AdditionalParms
UltraLite.NET | AdditionalParms
Native UltraLite for Java | additionalParms
UltraLite for M-Business Anywhere | additionalParms

For information about using the connection parameter, see Specifying connection parameters and Additional connection parameters.

Usage

Some less commonly used connection parameters do not have properties associated with them in the UltraLite components. These parameters can be specified as a connection string in AdditionalParms.

Values

A connection string.

Default

None.

See also

Specifying connection parameters


Database On CE connection parameter

Function

The path and filename of the UltraLite database file to which you want to connect on Windows CE.

Syntax
Interface | Connection parameter
UltraLite for MobileVB | DatabaseOnCE
UltraLite ActiveX | DatabaseOnCE
UltraLite.NET | DatabaseOnCE
Native UltraLite for Java | databaseOnCE
UltraLite for M-Business Anywhere | databaseOnCE
Connection string | ce_file

For information about using the connection parameter, see Specifying connection parameters.

Values

String

Default

If Database On CE is not specifed then the value for Database On Desktop is used.

If neither is specified then the default value of \UltraLiteDB\ulstore.udb is used. It is recommended that you explicitly specify the parameter, and not rely on default behavior.

Description

When creating a database, this parameter names the new database file.

When opening a connection to an existing database, the parameter identifies the database.

  • If the filename does not include an extension, the file of extension .udb is presumed.

  • The full path of the file must be specified. No substitutions are performed on this value.

  • The schema file is not required if a .udb file already exists.

  • Database On CE is required if you use a database with any name other than the default.

  • You must ensure that this directory exists when the connection parameter is used. UltraLite does not create the directory automatically.

Example

To create and connect to the sample database, udemo.udb:

"schema_file=MyOrders.usm;CE_FILE=udemo.udb"
See also

Specifying file paths


Database On Desktop connection parameter

Function

The database file to which you want to connect in the desktop development environment.

Syntax
Interface | Connection parameter
UltraLite for MobileVB | DatabaseOnDesktop
UltraLite ActiveX | DatabaseOnDesktop
UltraLite.NET | DatabaseOnDesktop
Native UltraLite for Java | databaseOnDesktop
UltraLite for M-Business Anywhere | databaseOnDesktop
Connection string | { file_name | DBF }

For information about using the connection parameter, see Specifying connection parameters.

Values

String

Default

The default value is ulstore.udb.

It is recommended that you explicitly specify the parameter, and not rely on default behavior.

Description

When creating a database, this parameter names the new database file.

When opening a connection to an existing database, the parameter identifies the database.

If the filename does not include an extension, the file of extension .udb is assumed.

Example

  • To create and connect to the sample database, udemo.udb, installed in the directory c:\mydb, use the following connection string:

    "schema_file=MyOrders.usm;DBF=c:\mydb\udemo.udb"
See also

Specifying file paths


Database On Palm connection parameter

Function

The Palm creator ID of the database to which you want to connect.

Syntax
Interface | Connection parameter
UltraLite for MobileVB | DatabaseOnPalm
UltraLite for M-Business Anywhere | databaseOnPalm
Connection string | palm_db

For information about using the connection parameter, see Specifying connection parameters.

Values

String

Default

For C++, the creator ID of the application. For MobileVB applications, there is no default.

Description

For many applications, there is no need to supply a Database On Palm connection parameter. From UltraLite for MobileVB, supply a DatabaseOnPalm connection parameter that matches the creator ID of your application.

On first connecting to a database, UltraLite creates a database which is named ul_udb_creator-id and which has a creator ID of creator-id, where creator-id is the value of the Database On Palm connection parameter, or (if that parameter is not supplied) is the creator ID of the application.

See also
  • Specifying file paths
  • Understanding the Palm Creator ID


Open Connection parameters

Open Connection parameters are used, together with Database Identification parameters, by OpenConnection methods and OpenConnectionWithParms methods.

For more information

  • UltraLite for MobileVB See OpenConnection method, and OpenConnectionWithParms method.

  • UltraLite ActiveX See OpenConnection method, and OpenConnectionWithParms method.

  • Native UltraLite for Java See ianywhere.native_ultralite.DatabaseManager in the Native UltraLite for Java API Reference.

  • UltraLite.NET See ULConnectionParms class (iAnywhere.Data.UltraLite namespace) or ConnectionParms class (iAnywhere.UltraLite namespace).

  • UltraLite C++ Component See OpenConnection Function.

  • UltraLite for M-Business Anywhere See Method openConnection, and Method openConnectionWithParms.

  • UltraLite for Embedded SQL See Authenticating users.

  • UltraLite Static C++ API See Authenticating users.

  • UltraLite Static Java See Adding user authentication to your application.

Cache Size connection parameter
Connection Name connection parameter
Encryption Key connection parameter
Password connection parameter
User ID connection parameter


Cache Size connection parameter

Function

Defines the size of the database cache.

Syntax
Interface | Connection parameter
Connection string | cache_size

For information about using the connection parameter, see Specifying connection parameters.

Usage

Used when you configure a database. Use k or K, m or M to denote kilobytes or megabytes, respectively.

Values

The minimum cache size is 4K.

Default

The default is 16 x page_size. Actual value used is rounded down to the nearest multiple of page_size.

Description

Defines the size of the cache. You can specify the size in units of bytes. Use the suffix k or K to indicate units of kilobytes and use the suffix M or m to indicate megabytes

The default cache size is sixteen pages. Using the default page size of 4 K, the default cache size is therefore 64 K. The minimum cache size is platform dependent.

The default cache size is conservative. If your testing shows the need for better performance, you should increase the cache size.

Increasing the cache size beyond the size of the database itself provides no performance improvement. Also, large cache sizes may interfere with the number of other applications you can use.

On the Palm Computing Platform, the parameter applies only to virtual file system (VFS) databases. The cache itself resides in record storage, not VFS storage.

Example

For example, the following string sets the cache size to 128 K.

"cache_size=128k"


Connection Name connection parameter

Function

Specifies a name for the connection. This is only needed if you create more than one connection to the database.

Syntax
Interface | Connection parameter
UltraLite for MobileVB | ConnectionName
UltraLite ActiveX | ConnectionName
UltraLite.NET | ConnectionName
Native UltraLite for Java | connectionName
UltraLite for M-Business Anywhere | connectionName
Connection string | con

For information about using the connection parameter, see Specifying connection parameters.

Usage

The Connection Name parameter is global to the application.


Encryption Key connection parameter

Function

An encryption key for the database. You can define an encryption key for your UltraLite database when CreateDatabase is called.

Syntax
Interface | Connection parameter
UltraLite for MobileVB | EncryptionKey
UltraLite ActiveX | EncryptionKey
UltraLite.NET | EncryptionKey
Native UltraLite for Java | encryptionKey
UltraLite for M-Business Anywhere | encryptionKey
Connection string | { key | dbkey }

For information about using the connection parameter, see Specifying connection parameters.

Values

String

Default

No key is provided.

Description

Used only when you create a database.

If a database is created using an encryption key, the database file is strongly encrypted using the AES 128-bit algorithm, which is the same algorithm used to encrypt Adaptive Server Anywhere databases. Use of strong encryption provides security against skilled and determined attempts to gain access to the data, but may have a significant performance impact.

Example
"schema_file=MyOrders.usm;KEY=MyKey"
See also

Encrypting UltraLite databases


Password connection parameter

Function

A password for the user. Passwords are case insensitive if the database is case insensitive and case sensitive if the database is case sensitive.

Syntax
Interface | Connection parameter
UltraLite for MobileVB | Password
UltraLite ActiveX | Password
UltraLite.NET | Password
Native UltraLite for Java | password
UltraLite for M-Business Anywhere | password
Connection string | { password | PWD }

For information about using the connection parameter, see Specifying connection parameters.

Usage

Anywhere

Values

String

Default

SQL

Description

Every user of a database has a password. The password must be supplied for the user to be allowed to connect to the database.

The Password (PWD) connection parameter is not encrypted.

Example

  • The following connection string fragment supplies the user ID DBA and password SQL.

    "UID=DBA;PWD=SQL;schema_file=MyOrders.usm"


User ID connection parameter

Function

The user ID with which you log on to the database. The value must be an authenticated user for the database. User ID's are case-insensitive if the database is case-insensitive and case sensitive if the database is case sensitive.

Databases are created with a single authenticated user DBA whose initial password is SQL. By default, connections are opened using the UID=DBA and the PWD=SQL. To disable the default user, use

connection.revokeConnectionFrom.

To add a user or change a user's password, use

connection.grantConnectTo.
Syntax
Interface | Connection parameter
UltraLite for MobileVB | UserID
UltraLite ActiveX | UserID
UltraLite.NET | UserID
Native UltraLite for Java | userID
UltraLite for M-Business Anywhere | userID
Connection string | { userid | UID }

For information about using the connection parameter, see Specifying connection parameters.

Usage

Anywhere

Values

String

Default

DBA

Description

You must always supply a user ID when connecting to a database, unless you leave the database using the default user ID and password of DBA and SQL.

Example

  • The following connection string fragment supplies the user ID DBA and password SQL:

    "schema_file=MyOrders.usm;uid=DBA;pwd=SQL"


Database Schema parameters

The keywords in this section are used to specify a schema for an UltraLite database.

For more information

  • UltraLite for MobileVB See CreateDatabase method, and CreateDatabaseWithParms method.

  • UltraLite ActiveX See CreateDatabase method, and CreateDatabaseWithParms method.

  • Native UltraLite for Java See ianywhere.native_ultralite.DatabaseManager in the Native UltraLite for Java API Reference.

  • UltraLite.NET See OpenWithCreate method (iAnywhere.Data.UltraLite namespace) or CreateDatabase method (iAnywhere.UltraLite namespace).

  • UltraLite C++ Component See CreateAndOpenDatabase Function.

  • UltraLite for M-Business Anywhere See Method createDatabase, and Method createDatabaseWithParms.

  • UltraLite for embedded SQL See Macros and compiler directives for UltraLite C/C++ applications.

  • UltraLite static C++ See Macros and compiler directives for UltraLite C/C++ applications.


Schema On CE connection parameter

Function

To identify the schema filename deployed to Windows CE.

Syntax
Interface | Connection parameter
UltraLite for MobileVB | SchemaOnCE
UltraLite ActiveX | SchemaOnCE
UltraLite.NET | SchemaOnCE
Native UltraLite for Java | schemaOnCE
UltraLite for M-Business Anywhere | schemaOnCE
Connection string | ce_schema

For information about using the connection parameter, see Specifying connection parameters.

Values

String

Default

The recommended file extension is .usm.

Description

Used only when you create a database.

The path and filename of the UltraLite schema file on Windows CE. The default extension for UltraLite schema files is .usm. This is a required parameter when using CreateDatabase for CE.

Example

  • The following connection string fragment supplies the ce_schema and schema_file parameters. When run on the desktop, MyOrders.usm is used; when run on a CE device (including the emulator), orders.usm is used.

    "CE_SCHEMA=orders.usm;SCHEMA_FILE=MyOrders.usm"


Schema On Desktop connection parameter

Function

To identify the schema file in the desktop development environment.

Syntax
Interface | Connection parameter
UltraLite for MobileVB | SchemaOnDesktop
UltraLite ActiveX | SchemaOnDesktop
UltraLite.NET | SchemaOnDesktop
Native UltraLite for Java | schemaOnDesktop
UltraLite for M-Business Anywhere | schemaOnDesktop
Connection string | schema_file

For information about using the connection parameter, see Specifying connection parameters.

Values

String

Default

The recommended file extension is .usm.

Description

Used only when you create a database.

The path and filename of the UltraLite schema in the development environment.

Example

  • The following connection string fragment supplies the ce_schema and schema_file parameters. When run on the desktop, MyOrders.usm is used; when run on a CE device (including the emulator), orders.usm is used.

    "CE_SCHEMA=orders.usm;SCHEMA_FILE=MyOrders.usm"


Schema On Palm connection parameter

Function

To identify the schema file deployed to a Palm OS device.

Syntax
Interface | Connection parameter
UltraLite for MobileVB | SchemaOnPalm
UltraLite for M-Business Anywhere | schemaOnPalm
Connection string | palm_schema

For information about using the connection parameter, see Specifying connection parameters.

Values

String

Default

There is no default value.

Description

This parameter specifies the UltraLite schema for a Palm OS device. It is required only when you create a database.

Although .pdb is the extension on the desktop, do not supply .pdb in your connection parameter string.

Example

  • The following connection string fragment supplies the palm_schema and schema_file parameters.

    "PALM_SCHEMA=orders;SCHEMA_FILE=MyOrders.usm"


VFS On Palm parameter

Function

Identifies the Palm card as using the virtual file system.

This parameter is available only in UltraLite for MobileVB. To use the virtual file system from an embedded SQL or static C++ API application, use the EnablePalmFileDB function.

Syntax
Interface | Connection parameter
UltraLite for MobileVB | VFSOnPalm
Connection string (UltraLite for MobileVB) | PALM_FS=VFS

For information about using the connection parameter, see Specifying connection parameters.

Values

As a parameter, VFSOnPalm is a boolean value.

In the connection string, the parameter must be specified as follows:

PALM_FS=VFS
Description

The palm_fs=vfs parameter needs to be specified both for CreateDatabase and OpenConnection if you are using the VFS card for Palm devices and you want the database stored on the card.

The default database filename is ul_udb_YYYY.udb, where YYYY is the creator ID of the application. You can control the filename by specifying a different creator ID in the DatabaseOnPalm parameter. For example, the following connection string references a database on the card with filename ul_udb_XXXX.udb:

palm_db=XXXX;palm_fs=vfs

Even when the VFSOnPalm parameter is specified, the palm_db parameter (Database on Palm) must be set to a valid creator ID.

If the VFS On Palm parameter is not specified, the database is created (or dropped from or to which you are connecting) on the device and not the card.


Additional connection parameters

These are optional parameters to configure a database when it is created. Some of these parameters can influence performance, so it is suggested that you test these parameters to find the optimal performance for your application.

For more information

  • UltraLite for MobileVB See CreateDatabase method, and CreateDatabaseWithParms method.

  • UltraLite ActiveX See CreateDatabase method, and CreateDatabaseWithParms method.

  • Native UltraLite for Java See ianywhere.native_ultralite.DatabaseManager in the Native UltraLite for Java API Reference.

  • UltraLite.NET See OpenWithCreate method (iAnywhere.Data.UltraLite namespace) or CreateDatabase method (iAnywhere.UltraLite namespace).

  • UltraLite C++ Component See CreateAndOpenDatabase Function.

  • UltraLite for M-Business Anywhere See Method createDatabase, and Method createDatabaseWithParms.

  • UltraLite for embedded SQL See Macros and compiler directives for UltraLite C/C++ applications.

  • UltraLite static C++ See Macros and compiler directives for UltraLite C/C++ applications.

Database Name connection parameter
Obfuscate connection parameter
Page Size connection parameter
Palm Allow Backup parameter
Reserve Size connection parameter


Database Name connection parameter

Function

For applications that connect to more than one database, this parameter can be used to distinguish the databases.

Syntax
Interface | Connection parameter
Connection string | dbn
Usage

Specify this parameter either in connection strings or in the AdditionalParms string.

Once a database has been started, UltraLite sets the database name. You can then make new connections using the database name parameter instead of specifying the database file.

Default

The default value is derived from the database file name by removing the path and extension. On Palm OS, the default value is the creator ID.


Obfuscate connection parameter

Function

Obfuscates the database. Obfuscation is a form of simple encryption.

Syntax
Interface | Connection parameter
Connection string | obfuscate

For information about using the connection parameter, see Specifying connection parameters.

Values

0 or 1. A value of 1 indicates that the database should be obfuscated.

Usage

Used only when you create a database.

Embedded SQL and static C++ API developers can also use the UL_ENABLE_OBFUSCATION macro to obfuscate a database. See UL_ENABLE_OBFUSCATION macro.

Default

By default, databases are not obfuscated.

See also

Encrypting UltraLite databases


Page Size connection parameter

Function

Defines the database page size.

Syntax
Interface | Connection parameter
Connection string | page_size

For information about using the connection parameter, see Specifying connection parameters.

Usage

Used only when you create a database.

Used when you create a database. Use k or K to denote kilobytes.

Default

The default page size for UltraLite databases is 4 K. The range of size is 2 K to 4 K.

Description

UltraLite databases are stored in pages. I/O operations are carried out a page at a time. It can be used on any target platform. Setting a page size of 2 K reduces the maximum number of tables to approximately 500.

This parameter is ignored when starting an existing database.

Example

You can specify 2 kb pages using the following storage parameters string:

"schema_file=MyOrders.usm;PAGE_SIZE=2K"


Palm Allow Backup parameter

Function

Control backup behavior over HotSync on Palm devices.

Syntax
Interface | Connection parameter
Connection string | palm_allow_backup

For information about using the connection parameter, see Specifying connection parameters.

Usage

Used when you configure a database.

Values

yes or no.

Description

If the backup bit is set on the UltraLite database, and if this parameter is set to yes, the entire Palm database is backed up every time the device is synchronized using HotSync. If this parameter is not set, UltraLite ensures that the backup bit is cleared. In most applications, data is backed up by synchronization, so there is no need to set this parameter.

The backup bit is set when a database file is deployed by HotSync, and can also be set by the ULUtil utility. For more information, see The ULUtil utility.

Example

The following string sets the parameter.

#define UL_STORE_PARMS UL_TEXT("palm_allow_backup=yes")


Reserve Size connection parameter

Function

Reserves file system space for storage of UltraLite persistent data.

Syntax
Interface | Connection parameter
Connection string | reserve_size

For information about using the connection parameter, see Specifying connection parameters.

Usage

Use k or K, m or M to denote kilobytes or megabytes, respectively.

Values

Values can be expressed in KB or MB.

Description

The reserve_size parameter allows you to pre-allocate the file system space required for your UltraLite database without actually inserting any data. Reserving file system space can improve performance slightly and also prevent out of memory failures. By default, the persistent storage file only grows when required as the application updates the database.

Reserve_size reserves file system space, which includes the metadata in the persistent store file, and not just the raw data. The metadata overhead as well as data compression must be considered when deriving the required file system space from the amount of database data. Running the database with test data and observing the persistent store file size is recommended.

The reserve_size parameter reserves space by growing the persistent store file to the given reserve size on startup, regardless of whether the file previously existed. The file is never truncated.

This parameter does not apply to the Palm Computing Platform unless the application uses the Virtual File System (VFS).

Example

Use the reserve_size parameter to pre-allocate space as follows:

"CE_SCHEMA=orders;RESERVE_SIZE=128K"

This example ensures that the persistent store file is at least 128 K upon startup.


UltraLite Utilities Reference

About this chapter

This chapter provides reference information about UltraLite utility programs.

The UltraLite engine
The UltraLite Generator
The SQL Preprocessor
The HotSync Conduit Installer
The dbulstop utility
The ulconv utility
The ulcreate utility
The uldbsgen utility
The ulinit utility
The UltraLite Interactive SQL utility
The ulload utility
The ulsync utility
The ulunload utility
The ULUtil utility
The UltraLite Schema Painter
The ulxml utility


The UltraLite engine

Function

Manages UltraLite databases. In contrast to the UltraLite runtime, which hosts a single application, the UltraLite engine permits multiple applications to access UltraLite databases concurrently.

Syntax

dbuleng9

Applies to

Windows XP and Windows CE.

Remarks

There are no command line options for the UltraLite engine.

See also
  • Using the UltraLite engine
  • The dbulstop utility


The UltraLite Generator

Applies to

Static interfaces only.

Function

The UltraLite generator implements your application database and generates additional C/C++ or Java source files, which must be compiled and linked into your application.

Syntax

ulgen [ options ] [ project [ output-filename ] ]

Option | Description
-a | Uppercase SQL string names [ Java ]
-c "keyword=value;..." | Supply database connection parameters for your reference database
-e | Replace SQL strings with generated constants [ Java ]
-f filename | Specify output file name
-g | Do not display warnings
-I | Generate inner classes [ Java ]
-j project-name | Project name
-l type Log the execution plan for each statement to a file. The type must be one of the following:

  • xml

  • short

  • long
-m version | Specify the version name for generated synchronization scripts
-o table-name,... | Specify the order in which tables are uploaded during synchronization
-p package-name | Package name for generated classes [ Java ]
-q | Do not print the banner
-r filename | The file containing the trusted root certificates
-s filename | Generate a list of SQL strings in an interface definition [ Java ]
-t target Target language. Must be one of the following:

  • c

  • c++

  • java
-u pub-name | The publication to use ©++ API only)
-v pub-name | The publication to use for synchronization
-x | Generate more and smaller C/C++ files.
Remarks

The UltraLite generator creates code that you compile and make part of an UltraLite application. Its output is based on the schema of the Adaptive Server Anywhere reference database and the specific SQL statements or tables that you use in your embedded SQL source files.

You must ensure that all your statements and tables are defined in the dbo.ul_statement table before running the generator. You do this as follows:

  • In embedded SQL, run the SQL preprocessor on each file.

  • In the C/C++ API and Java, add statements to the database using ul_add_statement, and/or define publications in the database.

In this table, statements are associated with projects. By specifying a project name on the generator command line, you determine which statements are included in your generated database.

You can include multiple projects, and also mix projects with a publication, on the generator command line. You must run the generator only once for each generated database.

If you do not specify an output file name, the generated code is written to a file with a name of project. It is recommended that you specify an output file name using the –f command line option.

Customizing UltraLite generator operations The UltraLite analyzer provides hooks that you can use to customize the code generation process. These hooks are stored procedure names. If you supply stored procedures with the following names, the UltraLite analyzer invokes them before and after the analysis process:

  • sp_hook_ulgen_begin( )

  • sp_hook_ulgen_end( )

These hooks are defined in the reference database and are used only during the analyzer analysis phase. The hooks can be created as follows:

CREATE PROCEDURE sp_hook_ulgen_begin ()
BEGIN
// actions here
END
CREATE PROCEDURE sp_hook_ulgen_end ()
BEGIN
// actions here
END
Options

project The project name determines the set of statements that are to be included in the generated database. For a more precise specification of the filename, use the –j option.

output-filename The name for the generated file, without extension. For a more precise specification of the filename, use the –f option.

In Java, this name is also the database name, which you must supply on connection.

-a If you are developing a Java application, the names of the SQL statements in the project are used as constants in your application. By convention, constants are upper case, with underscore characters between words. The –a option makes the names of SQL statements fit this convention by making the characters upper case and inserting an underscore whenever an uppercase character in the original name is found if not already preceded by an underscore or an uppercase character. For example, a statement named MyStatement becomes MY_STATEMENT, and a statement named AStatement becomes ASTATEMENT.

The generated names have spaces and non-alphanumeric characters replaced with an underscore, regardless of whether –a is used.

-c connection-string The connection string must give the generator permission to read and modify your reference database. This parameter is required.

-e The SQL strings in the generated database are replaced by smaller, generated strings. This option is useful when you are trying to reduce the footprint of a database with a lot of statements.

-f filename This is the recommended way to specify the output file. Do not specify an extension.

-g Suppress the display of warning messages. Error messages are still displayed.

The UltraLite generator provides warnings to indicate that some generated code may, under some circumstances, cause problems. For example, it generates a warning for SQL statements that include temporary tables.

-I By default, generated classes are written as top-level non-public classes except for the main database class. If you use –I, the generated classes are written as inner classes. If you use this option, you must use a Java compiler that can correctly compile inner classes.

-j project-name This is the recommended way to specify the project. You can specify multiple projects using this option as follows:

ulgen -j project1 -j project2 ...

-l type Log the execution plan for queries in the application. These plans can be viewed in Interactive SQL. The types available are:

  • xml Description in XML format. Use the Interactive SQL File > Open command to display the plan.

  • short Brief description of the plan in a file named <statement>.txt. The content is that generated by the EXPLANATION function

  • long Detailed description of the plan in a file named <statement>.txt. The content is that generated by the PLAN function.

-m version Specify the version name for generated synchronization scripts. The generated synchronization scripts can be used in a MobiLink consolidated database for simple synchronization. The default value is ul_default.

-o table-name,... Specify the order in which tables are uploaded during synchronization. This option can be used to avoid referential integrity errors during upload. Each table to be uploaded must be specified exactly once.

-p package-name A package name for generated files when generating Java output.

-q Do not display output messages.

-r filename The file containing the trusted root certificates used for secure synchronization using Certicom security software.

The generator embeds these trusted roots into the UltraLite application. When the application receives a certificate chain from a MobiLink synchronization server, it checks if its root is among the trusted roots, and only accepts a connection if it is.

The generator checks the expiry dates of all the certificates in the trusted root certificate file and issues the following warning for any certificate that expires in less than 6 months (180 days):

Warning: Certificate will expire in %1 days"

The generator issues a Certificate has expired error for any certificate that has already expired.

On platforms other than Palm OS, an alternative to using -r is to supply the certificate separately and address it with the trusted_certificates security parameter. For more information, see trusted_certificates.

For more information, see UltraLite Synchronization Parameters, and MobiLink Transport-Layer Security.

-s filename Generate an interface that contains the SQL statements as constants. This option is for use with Java only. The interface file has a format similar to the following example:

package com.sybase.test;
public interface EmpTestSQL {
    String EMPLOYEE = "select emp_fname, emp_lname
      from employee where emp_id = ?";
    String UPDATE_EMPLOYEE = "update employee
      set emp_fname = ?, emp_lname = ?
      where emp_id = ?";
}

Do not supply the .java extension in filename. The –a option controls the case of the statement names.

-t target Specifies the kind and extension of the generated file.

  • If you are using Java, you must use a target of java. If you are using embedded SQL or the C++ API, you can use a target of either c or c++. Which one you choose decides the extension of the file name, and has nothing to do with whether you are using the C++ API or embedded SQL.

  • If you specify c++, the following files are generated:

    • filename.cpp The code for the generated API.

    • filename.h A header file. You do not need to look at this file.

    • filename.hpp The C++ API definition for your application.

  • If you specify a target of c, filename.c is generated.

-u pub-name If you are generating a C++ API for a publication, specify the publication name with the -u option.

-v pub-name Specifies a publication to synchronize. If you do not use publications to define which changes are to be synchronized, all changes are synchronized.

If columns or tables specified in publications are not referenced by SQL statements in your application, they are not included in the UltraLite database.

To specify multiple publications, repeat the -v option. For example:

ulgen -v pub1 -v pub2 ...

The maximum number of publications is 32.

For more information, see UltraLite Clients.

-x This option is intended for use in situations where the file containing the generated code is too large for the C/C++ compiler to compile.

This option causes the UltraLite generator to produce more and smaller files. When -x is used, the UltraLite generator writes out one C/C++ file for the database and one for each SQL statement.

This option has no effect when generating Java code.


The SQL Preprocessor

Applies to

Embedded SQL static development model only.

Function

The SQL preprocessor processes a C or C++ program containing embedded SQL, before the compiler is run.

Syntax

sqlpp [ options ] sql-filename [ output-filename ]

Option | Description
–c "keyword=value;...." | Supply database connection parameters for your reference database
-d | Generate code that favors small data size
–e level | Flag non-conforming SQL syntax as an error
-g | Do not display UltraLite warnings
–h line-width | Limit the maximum line length of output
-k | Include user declaration of SQLCODE
-m version | Specify the version name for generated synchronization scripts
–n | Line numbers
-o operating-sys | Target operating system: WIN32, WINNT, NETWARE, or UNIX
–p project-name | UltraLite project name
–q | Quiet mode—do not print banner
–s string-len | Maximum string length for the compiler
–w level | Flag non-conforming SQL syntax as a warning
–x | Change multi-byte SQL strings to escape sequences.
–z sequence | Specify collation sequence
See also

Introduction

Remarks

The SQL preprocessor processes a C or C++ source file that contains embedded SQL, before the compiler is run. This preprocessor translates the SQL statements in the input-file into C/C++. It writes the result to the output-file. The normal extension for source files containing embedded SQL is sqc. The default output filename is the SQL-filename base name with an extension of c. However, if the SQL-filename already has the .c extension, the default output extension is .cc.

When preprocessing files that are part of an UltraLite application, the SQL preprocessor requires access to an Adaptive Server Anywhere reference database. You must supply the connection parameters for the reference database using the –c option.

If you specify no project name, the SQL preprocessor also runs the UltraLite generator and appends additional code to the generated C/C++ source file. This code contains a C/C++ language description of your database schema as well as the implementation of the SQL statements in the application.

Customizing UltraLite generator operations The UltraLite analyzer provides hooks that you can use to customize the code generation process. These hooks are stored procedure names. If you supply stored procedures with the following names, the UltraLite analyzer invokes them before and after the analysis process:

  • sp_hook_ulgen_begin( )

  • sp_hook_ulgen_end( )

These hooks are defined in the reference database and are used only during the analyzer analysis phase. The hooks can be created as follows:

CREATE PROCEDURE sp_hook_ulgen_begin ()
BEGIN
// actions here
END
CREATE PROCEDURE sp_hook_ulgen_end ()
BEGIN
// actions here
END
Options

-c Required when preprocessing files that are part of an UltraLite application. The connection string must give the SQL preprocessor access to read and modify your reference database.

-d Generate code that reduces data space size. Data structures are reused and initialized at execution time before use. This increases code size.

-e This option flags any embedded SQL that is not part of a specified set of SQL/92 as an error. The option is not applicable to UltraLite.

The allowed values of level and their meanings are as follows:

  • e flag syntax that is not entry-level SQL/92 syntax

  • i flag syntax that is not intermediate-level SQL/92 syntax

  • f flag syntax that is not full-SQL/92 syntax

  • t flag non-standard host variable types

  • u flag features not supported by UltraLite

  • w allow all supported syntax

-g Do not display warning specific to UltraLite code generation.

-h num Limits the maximum length of lines output by sqlpp to NUM characters. The continuation character is a backslash (\), and the minimum value of NUM is ten.

-k Notifies the preprocessor that the program to be compiled includes a user declaration of SQLCODE.

-m version Specify the version name for generated synchronization scripts. The generated synchronization scripts can be used in a MobiLink consolidated database for simple synchronization. The default value is ul_default.

-n Generate line number information in the C file. This consists of #line directives in the appropriate places in the generated C code. If your compiler supports the #line directive, this option will make the compiler report errors on line numbers in the SQL-filename, as opposed to reporting errors on line numbers in the C/C++ output file. Also, the #line directives will indirectly be used by the source-level debugger so that you can debug while viewing the SQL-filename.

-o Specify the target operating system. Note that this option must match the operating system where you will run the program. A reference to a special symbol will be generated in your program. This symbol is defined in the interface library. If you use the wrong operating system specification or the wrong library, an error will be detected by the linker. The supported operating systems are:

  • WIN32 Microsoft Windows 95/98/Me and Windows CE

  • WINNT Microsoft Windows NT/2000/XP

-p project-name Identifies the UltraLite project to which the embedded SQL files belong. Applies only when processing files that are part of an UltraLite application.

-q Operate quietly. Do not print the banner.

-s string-len Set the maximum size string that the preprocessor will put into the C file. Strings longer than this value will be initialized using a list of characters ('a','b','c', and so on). Most C compilers have a limit on the size of string literal they can handle. This option is used to set that upper limit. The default value is 500.

-w level This option flags any embedded SQL that is not part of a specified set of SQL/92 as a warning. The option is not applicable to UltraLite.

The allowed values of level and their meanings are as follows:

  • e flag syntax that is not entry-level SQL/92 syntax

  • i flag syntax that is not intermediate-level SQL/92 syntax

  • f flag syntax that is not full-SQL/92 syntax

  • t flag non-standard host variable types

  • u flag features not supported by UltraLite

  • w allow all supported syntax

-x Change multi-byte strings to escape sequences so that they can pass through compilers.

-z sequence This option specifies the collation sequence or filename. For a listing of recommended collation sequences, type dbinit –l at the command prompt.


The HotSync Conduit Installer

Function

The utility installs or removes a HotSync conduit onto the current machine.

Syntax

dbcond9 [ options ] id

Option | Description
id | The creator ID of the application to use the conduit
-n name | The name displayed by the HotSync manager.
-k key | Default encryption key
-p parms | Default client synchronization parameters.
-x | Remove the conduit for the specified creator ID
Remarks

The utility installs a HotSync conduit onto the current machine. HotSync Manager must be present in order for the HotSync Conduit Installer to run.

Options

id The application user ID who is to use the conduit. If a conduit already exists for the specified creatorID, it is replaced by the new conduit. This is a required option.

-k key The default encryption key. Supply an empty string (-k "") to clear an existing encryption key.

-n name The name displayed by the HotSync manager. This is also the name of the subdirectory where the conduit stores data. Do not use this option together with –x. The default value is MobiLink conduit.

-p parms The default client synchronization parameters. Supply an empty string (-p "") to clear any existing parameters.

-x Remove the conduit for the named creatorID. If –x is not specified, a conduit is installed.

Examples

The following command line installs the conduit for the CustDB sample application, which has a creator ID of Syb2:

dbcond9 -n CustDB Syb2


The dbulstop utility

Function

Stops the UltraLite engine.

Syntax

dbulstop

Applies to

Windows XP and Windows CE.

Remarks

There are no command line options for the UltraLite engine stop utility.

See also
  • Using the UltraLite engine
  • The UltraLite engine


The ulconv utility

Function

This utility converts UltraLite databases and schema files among formats.

Syntax

ulconv create [ options ]

ulconv { load | unload } [ options ] xml-file

ulconv sync [ options ] [ sync-parms ]

The options depend on the syntax used. Command line options for this utility are case sensitive.

  • create Create a new, empty UltraLite database from a specified schema file. The following options are supported:

    Option | Description
    -c "keyword=value;..." | UltraLite database connection parameters. Required.
    -m | Create a multibyte UltraLite database.
    -p creator-id Create a Palm OS database, using the supplied creator ID. The database file is given a Palm OS PDB name of ul_udb_creator-id.

    For more information about creator IDs, see Understanding the Palm Creator ID.
    -q | Do not print the banner or messages.
    -S schema-file | Use the specified schema file to define the database schema.
    -u | Create a Unicode UltraLite database. Default behavior.
    -v | Print verbose messages.
    -y | Overwrite the database file if it exists.

  • load Read an XML file and load the data into a new or existing database. The following options are supported:

    Option | Description
    xml-file | The XML file that holds the data to be loaded.
    -c "keyword=value;..." | UltraLite database connection parameters. Required.
    -d Create a new database only if an existing database cannot be opened. If an existing database can be opened, ignore the schema definition in the XML file.

    If -d is not supplied, a new database is created.
    -D directory Specify a directory for files holding external data.

    The xml-file may contain column data for long binary and long character columns in an external file, as follows:

    <uldata>
  <table name="table-name">
    <row
     longData.File="column.dat" .../>
    ...
  </table>
  ...
</uldata>
    If -D is supplied, the path of column.dat is interpreted as relative to the supplied directory. If no -D is supplied, the path is relative to the xml-file.
    -i | Include inserted rows in the next upload synchronization. By default, rows inserted by this utility are not uploaded during synchronization.
    -m | Create a multibyte UltraLite database.
    -n | Load schema only. Ignore data.
    -p creator-id | Create a Palm OS database, using the supplied creator ID.
    -q | Do not print the banner or messages.
    -S schema-file | Save the schema to the specified schema file.
    -u | Create a Unicode UltraLite database. Default behavior.
    -v | Print verbose messages.
    -y | Overwrite the database file if it exists.

  • sync Open and synchronize an UltraLite database, using the supplied synchronization parameter. The following options are supported:

    Option | Description
    sync-parms A semicolon-separated list of keyword=value pairs that control synchronization.

    The keywords must be taken from the following case-insensitive list:

    • downloadOnly (boolean)
    • newpasswd (string)
    • passwd (string)
    • publicationMask (integer)
    • sendColumnNames (boolean)
    • uploadOnly (boolean)
    • username (string)
    • version (string)
    For more information about synchronization parameters, see UltraLite Synchronization Parameters.
    -a auth-parm MobiLink authentication parameters. Several authentication parameters can be specified using multiple -a auth-parm options.

    The parameters are sent in the order they appear on the command line.

    For information on MobiLink authentication parameters, see authenticate_parameters connection event.
    -c "keyword=value;..." | UltraLite database connection parameters. Required.
    -k stream-type The synchronization stream to use.

    stream-type must be one of the following case-insensitive values:

    • tcpip (the default)
    • http
    -q | Do not print the banner or messages.
    -s streamParms=keyword=value;... The stream parameters to use when synchronizing.

    Stream parameters are stream-type specific. The default streamParms is "host=localhost", which corresponds to the -k tcpip stream-type.

    For a list of available stream parameters, see Network protocol options for UltraLite synchronization clients.

    Boolean false can be specified by 0, no, off or false; true with the values 1, yes, on, or true.

    Integer values can be given in octal, hex, or decimal.

    String values can be quoted (quotation marks are removed).
    -v | Print verbose messages.

  • unload Save an UltraLite database file to an XML document. The following options are supported:

    Option | Description
    xml-file | The XML file to which data is to be unloaded.
    -B max-blob-size The maximum size of long binary or long character data to write to the XML file. The default value is 10 KB.

    A value of -1 corresponds to no maximum size (all data is stored in the XML file).
    -c "keyword=value;..." | UltraLite database connection parameters. Required.
    -d | Unload data only. Do not unload the schema.
    -D blob-directory The directory in which to store long binary data that exceeds the -B max-blob-size limit.

    Values are stored as files named tableName-columnName-rowNumber.bin.

    The default directory is the same directory as the XML file.
    -e table,... | Exclude data for the named tables.
    -n | Unload schema only. Do not unload data.
    -q | Quiet mode—do not print messages.
    -S schema-file | Save the schema to the named UltraLite schema file.
    -t table,... | Only output data for the named tables.
    -v | Verbose messages.
    -y | Overwrite the XML file if it exists.
Remarks

The XML file that is a central format for unloading and loading databases is the file win32\usm.xsd in your SQL Anywhere installation. This file is the same as that for the UltraLite XML utility.

If your application is built using embedded SQL or the Static C++ API, if you are deploying it to the Palm OS, and if you wish to use a database created using the UltraLite database converter, you must make a special call in your application. Before initializing the database APIs, call ULEnableGenericSchemaEx ( &sqlca, false ).

The connection string must include a database file (DBF) parameter.

When used for unload, the utility makes a temporary copy of the UltraLite database file before unloading data.

When used for load or create, you can specify a user ID and password combination in the connection string. The utility adds this user ID and password combination to the list of authenticated users, in addition to the default user ID and password combination of DBA and SQL.

Examples

The following examples illustrate uses of the UltraLite database converter.

  • Create an UltraLite database for distribution on the Palm OS with an application.

    1. Start MobiLink against the consolidated database:

      start dbmlsrv9 -c dsn=...

    2. Create an UltraLite schema file:

      ulinit -f app.usm -c dsn=...

    3. Create a database in Palm OS format with creator ID SYB2:

      ulconv create -p SYB2 -c DBF=app.udb;schema_file=app.usm

      This command creates a desktop file named app.udb which, when synchronized to a Palm OS device using HotSync, appears as the PDF ul_udb_SYB2. It you export the file back to the desktop, it appears as ul_udb_SYB2.

    4. Synchronize with MobiLink, downloading application data. The following command must be entered all on one line.

      ulconv sync -c "DBF=app.pdb"
username=appuid;version=app;downloadOnly=true

      The username, version, and downloadOnly values are the synchronization parameters that control the synchronization.

    5. Copy palmos.pdb to Palm devices with the UltraLite application.

  • Defragment an existing Windows CE UltraLite database, already copied to the desktop.

    1. Unload the schema and data into an XML file cedatabase.xml.

      ulconv unload -c DBF=cedatabase.udb cedatabase.xml

    2. Load the new database from the XML file (-u forces a new Unicode database)

      ulconv load -u -c DBF=newdb.udb cedatabase.xml

    3. Copy the new database file to the Windows CE device.

  • Convert an existing UltraLite database from desktop to Palm OS format.

    1. Unload data to database.xml:

      ulconv unload -c DBF=database.udb database.xml

    2. Create and load a new UltraLite database in Palm OS format, with creator ID CREA.

      ulconv load -p CREA -c dbf=palm.pdb database.xml

    3. Copy palm.pdb to the Palm OS device.

  • Convert from a UNICODE UltraLite database into a multibyte character set database:

    ulconv unload -c DBF=CEDatabase.udb newdb.xml
ulconv load -m -c DBF=MBDatabase.udb newdb.xml

  • Save the indicated tables as data only:

    ulconv unload -c dbf=existingDB.udb -d -t table1,table2


The ulcreate utility

Function

Creates UltraLite databases.

Syntax

ulcreate options

Command line options for this utility are case sensitive.

Option | Description
-c "keyword=value;..." | UltraLite database connection string. Required. Use the DBF parameter to set the database file name. For information about UltraLite connection strings, see Connection Parameters.
-C | Create the database as case-sensitive for all string comparisons.
-I database-id | Set the initial database ID for global autoincrement columns.
-l | List the available collation sequences and exit. For a list of collation sequences, see Supplied and recommended collations.
-m | Create a multibyte UltraLite database.
-p creator-id | Create a Palm OS database, using the supplied creator ID. The database file is given a Palm OS PDB name of ul_udb_creator-id. For more information about creator IDs, see Understanding the Palm Creator ID.
-q | Quiet mode—do not print messages.
-S schema-file | Use the specified schema file to define the database schema.
-u | Create a Unicode database. (default)
-v | Print verbose messages.
-y | Overwrite the database file if it exists.
-z collation-sequence | Specify the collation sequence.
Remarks

It the database file does not exist, the database is created as case insensitive, non-Unicode database with a collation sequence that depends on the current locale.

Examples

Create an UltraLite database in the file with all default settings:

ulcreate -c "dbf=test.udb"

Create a case-sensitive Unicode database, overwriting the database file if it exists:

ulcreate -c "dbf=test.udb" -C -u -y

Create a database and apply the schema supplied in the file myschema.usm:

ulcreate -c "dbf=test.udb" -S myschema.usm

Create an encrypted database with encryption key afvc_1835:

ulcreate -c "dbf=test.udb;key=afvc_1835"


The uldbsgen utility

Function

Writes SQL statements defining the schema of an Adaptive Server Anywhere consolidated database to a file, including table definitions and MobiLink synchronization scripts.

This utility is called by the UltraLite Schema Painter when it generates synchronization scripts.

Syntax

uldbsgen options sql-file

Command line options for this utility are case sensitive.

Option | Description
-a sync-info-file | Specify a file containing synchronization settings, saved by the UltraLite Schema Painter.
-c "keyword=value;..." | UltraLite database connection string. Required. For information about UltraLite connection strings, see Connection Parameters.
-d var=value | Set initial value for a script.
-e table,... | Exclude listed tables.
-gm | Write MobiLink synchronization scripts only.
-gt | Write table definitions only.
-m ml-version | Set the MobiLink synchronization version.
-oa | Cancel if database would be upgraded (default)
-or | Read only. Do not upgrade database.
-ou | Upgrade database if it is from an older UltraLite release.
-p publication,... | Write statements only for tables contained in the listed publications.
-q | Quiet mode—do not print messages.
-s event,... | Write MobiLink synchronization scripts only for the specified synchronization events.
-t table,... | Write statements only for the listed tables.
-v | Verbose messages.
-y | Overwrite sql-file without confirmation.
Remarks

The uldbsgen utility is primarily used by the UltraLite Schema Painter. It is provided as a command-line utility for optional batch-mode use.

See also
  • The UltraLite Schema Painter
  • Generate Consolidated Database and MobiLink Scripts dialog


The ulinit utility

Applies to

UltraLite components.

Function

The ulinit utility lets you create a .usm file for use with any UltraLite component. The utility connects to an Adaptive Server Anywhere database. Consequently, SQL Anywhere Studio (version 8.0.2 or later) is required in order to use it.

Syntax

ulinit -f schema_file -n pub_name [ options ]

Option | Description
-c "connection_string" | Supply database connection parameters in the form keyword=value, separated by semi-colons. You supply these so you may connect to an Adaptive Server Anywhere database.
-f schema_file | Specify the name of the output file. This option is required.
-m version | Specify the version string for generated MobiLink scripts.
-n pubname | Add tables to the UltraLite database schema. pubname specifies a publication in the reference database. Tables in the publication are added to the UltraLite database schema. Specify the option multiple times to add multiple publications in to the UltraLite database schema. To add all tables in the reference database to the UltraLite schema, specify -n*. This option is required.
-o "keyword=value;..." | Supply schema creation options.
-palm id | Create a schema file compatible with Palm OS. Id is the four digit Palm creator id that identifies the database.
-q | Quiet operation — only report errors and warnings.
-s pubname | Specify a publication for synchronization. pubname specifies a publication in the reference database that is added as a named publication to the UltraLite database. If -s is not supplied, the UltraLite schema has no named publications. This option can be used multiple times.
-t file | Specify the file containing the trusted root certificates.
-w | Do not display warnings.
-z ordering | Specify the order in which tables are uploaded during synchronization (for example, -z table1,table2).
Remarks

The -n and -s options both take publication names in the reference database as arguments, but serve different purposes:

  • The -n option defines the tables to be included in the UltraLite database schema. It does not create named publications in the UltraLite database, and is not used for synchronization.

  • The -s option defines named publications in the UltraLite database. These named publications are used for synchronization. The -s option does not define which tables are included in the UltraLite database schema.

Examples

Create a file called customer.usm that contains the tables in TestPublication:

ulinit -c "uid=dba;pwd=sql" -f customer.usm -n TestPublication

Create a schema with two distinct publications:

ulinit -c "dsn=dsn-name" -f schema.usm -n Pub1 -n Pub2 -s Pub1 -s Pub2

For example, one of the publications may contain a small subset of data for priority synchronization, while the other would contain the bulk of the data.

Synchronization of publications is managed with a bit mask in the UltraLite schema. For more information, see Designing sets of data to synchronize separately.

When creating an UltraLite schema for Palm with ulinit, use the -palm option to generate a .pdb file. For example:

ulinit -c "uid=dba;pwd=sql;dsn=ASA 9.0 Sample"
-f tutcustomer.usm -n TutCustomersPub -palm Syb3
Note
Syb3 is an example of a Palm creator ID. Use the four digit Palm registered creator ID that matches the creator ID of your application. For MobileVB developers, this must be set in your MobileVB project settings.

The PDB file generated by ulinit must be loaded to the Palm device. The creator ID used by the application should match the PDF filename. When an UltraLite application creates its database from the schema file, it should include the creator ID in the parameters of the call to Open, without the .pdb file extension. For example:

DatabaseManager.CreateDatabase( "palm_schema=Syb3" )


The UltraLite Interactive SQL utility

Function

Execute SQL statements against an UltraLite database.

Syntax

ulisql [ options ] [ command-file ]

Option | Description
-c "keyword=value;..." UltraLite database connection string. If you do not supply a connection string, a connection dialog is displayed.

The connection string must include the following keywords:

  • dbf (database file)
  • uid (user ID)
  • pwd (password)
For more information on connection strings, see Connection Parameters.
-oa | Do not open databases with old file formats.
-or | Open databases with old file formats as read-only.
-ou | Upgrade databases with old file formats to the format of the current version.
command-file A file containing one or more SQL statements to be executed. When command-file is specified, the user interface is not displayed.

The file must follow the following conventions:

  • Each statement must end with a semi-colon. No characters other than white space are allowed between the semi-colon and the end of the line.
  • Each statement must begin on a new line. Only white space is allowed to precede a statement.
  • There is no support for comment characters.
  • Statements that return a result set (queries) are ignored.
Remarks

UltraLite Interactive SQL is a graphical utility for executing SQL statements against an UltraLite database. It is useful during application development for developing and testing SQL statements, and for browsing data in databases.

UltraLite Interactive SQL has a window that displays the access plan of a query. If you have queries that demonstrate slow performance, this query plan may be helpful in diagnosing the problem. For example, it may be the case that creating a suitable index would help speed up your query.

If you choose to do so, UltraLite upgrades old database files to the native file format of the current version of the software. This upgrade makes it impossible to use the database from older versions of UltraLite, including applications developed with older versions of the software. Use the -or or -oa options to ensure that old databases are not upgraded. If you choose the -or option, UltraLite opens the database in read-only mode. Any changes you make are discarded when UltraLite Interactive SQL closes, even if you commit your changes.

If you do not specify any of the -o parameters and if the database needs to be upgraded, the Upgrade dialog box is displayed. This dialog allows you to choose whether to upgrade, open in read-only mode or cancel the operation.

See also
  • Dynamic SQL statements
  • Query optimization


The ulload utility

Function

Loads data from an XML file into an UltraLite database.

Syntax

ulload options xml-file

Command line options for this utility are case sensitive.

Option | Description
-c "keyword=value;..." | UltraLite database connection string. Required. Use the DBF parameter to set the database file name. For information about UltraLite connection strings, see Connection Parameters.
-d | Load data only.
-D directory | Specify the directory for data stored in external files. The default is the same directory as the XML file. This option is primarily for use with XML files created by ulunload.
-i | Include inserted rows in the next upload synchronization. By default, rows inserted by this utility are not uploaded during synchronization.
-m | Create a multibyte database.
-n | Schema only—ignore data.
-p creator-id | Create a Palm OS database using the named creator-id.
-q | Quiet mode—do not print messages.
-S schema-file | Save UltraLite schema to the named schema file.
-u | Create a Unicode database. (default).
-v | Verbose messages.
-y | Replace the database without confirmation. This option has no effect if -d is used.
Remarks

The ulload utility loads data from an XML file into an UltraLite database. It creates the UltraLite database file if it does not already exist. Options allow you to specify whether to load database schema, data, or both, as well as to specify the character set of the UltraLite database.

Examples

Create a new UltraLite database in the file sample.udb from the schema and data in sample.xml:

ulload -c dbf=sample.udb sample.xml

Load the data from sample.xml into the existing database sample.udb:

ulunload -d -c dbf=sample.udb sample.xml


The ulsync utility

Function

Synchronize an UltraLite database.

Syntax

ulsync options sync-parms

Command line options for this utility are case sensitive.

Option | Description
-a authentication-parameter | MobiLink authentication parameter.
-c "keyword=value;..." UltraLite database connection string. Required.

Use the DBF parameter to set the database file name. For information about UltraLite connection strings, see Connection Parameters.
-k stream-type | Specify the synchronization stream. stream-type must be either tcpip or http. The default stream is tcpip.
-q | Quiet mode—do not print messages.
-s stream-parm=value;... A semicolon-separated list of synchronization stream parameters. The default value is host=localhost.

For more information, see Network protocol options for UltraLite synchronization clients.
-v | Verbose messages.
-y | Replace the database without confirmation.
sync-parms A semicolon-separated list of keyword-value pairs. The keywords are case insensitive, and are drawn from the following list:
  • downloadOnly (Boolean)
  • newpasswd (string)
  • passwd (string)
  • publicationMask (integer)
  • sendColumnNames (Boolean)
  • uploadOnly (Boolean)
  • username (string)
  • version (string)
Remarks

The ulsync utility synchronizes an UltraLite database with a MobiLink synchronization server. It is a tool for testing synchronization during application development.

Do not confuse the sync-parms option (which sets synchronization parameters) with the -s stream-parms option (which sets synchronization stream parameters).

For more information on synchronization parameters, see Synchronization parameters; for more information on stream parameters, see Network protocol options for UltraLite synchronization clients.

Example

The following command synchronizes a database file ul.udb over HTTP with a MobiLink synchronization server running on a machine server and listening on port 8181. The MobiLink user name is ml-user and the script version is script-version.

The command must be entered on a single line.

ulsync -c "dbf=ul.udb"
       -k http
       -s "host=server;port=8181"
       "username=ml-user;version=script-version"


The ulunload utility

Function

Unloads data from an UltraLite database into an XML file.

Syntax

ulunload options xml-file

Command line options for this utility are case sensitive.

Option | Description
-B max-size | Maximum size of binary or character data to be stored in the XML file. The default is 10K. Use -B -1 to have no maximum size, and to store all data in the XML file. Data that is over the maximum size is saved as a file named tablename-columname-rownumber.bin in the same directory as the XML file, or in the directory specified by -D.
-c "keyword=value;..." | UltraLite database connection string. Required. Use the DBF parameter to set the database file name. For information about UltraLite connection strings, see Connection Parameters.
-d | Unload data only. Do not unload the schema definition.
-D directory | Specify the directory to store data larger than the maximum size specified by -B. The default is the same directory as the XML file.
-e table,... | Exclude the listed tables.
-n | Schema only—ignore data.
-q | Quiet mode—do not print messages.
-S schema-file | Save UltraLite schema to the named schema file.
-t table,... | Unload only the listed tables.
-v | Verbose messages.
-y | Overwrite xml-file without confirmation.
Remarks

The ulunload utility unloads data from an UltraLite database into an XML file. As long as you do not use the -d option, the unloaded file can be loaded into a new database using the ulload utility.

Examples

Unload the UltraLite database sample.udb into the XML file sample.xml:

ulunload -c "dbf=sample.udb" sample.xml

Unload the data from the UltraLite database sample.udb into the XML file sample.xml, overwriting the file if it exists:

ulunload -c "dbf=sample.udb" -d -y sample.xml


The ULUtil utility

Function

The UltraLite Palm utility is a Palm Computing Platform application that deletes all of the data stored in an UltraLite application's remote database.

Remarks

The UltraLite Palm utility is installed as the following file:

%ASANY9%\UltraLite\Palm\68k\ULUtil.prc

ULUtil is useful in deployments where devices are shared between different users. When a different user gets a device, they may want to clear out the previous user's data, to save storage space. Also, the previous user might want to clear out their data because it is confidential. Without ULUtil, the only way to clear out an application's data would be to delete and re-install the application.

You can set ULUtil to back up the Palm store to the PC on subsequent synchronization. You can use this feature to perform an initial synchronization and then backup the store which can be deployed on other devices so they do not need to perform an initial synchronization. The backup option is automatically turned off by the UltraLite runtime to prevent subsequent backups. If you explicitly want to require the database to be backed up on every synchronization, you must add the palm_allow_backup parameter in UL_STORE_PARMS.

For more information, see UL_STORE_PARMS macro.

Once ULUtil is installed on the device, you can delete an UltraLite application's data as follows:

  1. Switch to ULUtil.

  2. Select an application from the list of UltraLite Applications. Only applications built with version 8 or later are displayed.

  3. Tap the Delete button.

On devices with expansion cards, ULUtil provides access to both file-based and record-based stores.


The UltraLite Schema Painter

Function

The UltraLite Schema Painter allows you to create a new UltraLite schema file or edit an existing one. You can also use it to define table definitions and synchronization scripts for an Adaptive Server Anywhere consolidated database.

For a tutorial that walks you through some of the features of the UltraLite Schema Painter, see Tutorial: Working with UltraLite Databases.


Starting the UltraLite Schema Painter

toggle To start the UltraLite Schema Painter

  • From the Start menu, choose Start > Programs > SQL Anywhere 9 > UltraLite > UltraLite Schema Painter.

    Alternatively, open a command prompt and enter the following command:

    ulview


Creating, saving and exporting schema files

toggle To create a new schema file

  1. Open the Tools folder and double-click Create UltraLite Schema.

  2. In the New Schema dialog, type in a file name.

  3. Click OK to create the schema.

toggle To save a file

  1. Choose File > Save to save the file.

  2. You can select to Save in .xml or .usm format.

toggle To export a Palm schema file

  1. Right-click the schema icon and choose Export Schema for Palm from the popup menu.

  2. Enter a Palm Creator ID.

  3. Click OK.


Managing schema files

When you first rename a table or column in your schema UltraLite stores the original name of the table or column. For example, if you create a table named cust, and later rename it to customer, cust is saved as the old name. If you then renamed the table a second time, to customer_info, the old name remains cust.

The scheme is designed so that a schema file can be used to alter the schema of an existing database. For example, assume that version one of your application shipped with a table named cust. As part of the changes for version two, you modify your version one schema file by renaming the table to customer. This automatically saves cust as the old name. If you now apply this schema file to a version one database file, UltraLite looks for a table named cust, the old name, and renames it Customer. The same applies to columns in a table.

It is therefore important for future compatibility that you clear the old names from a schema file after a schema file is deployed.

For more information, see Upgrading UltraLite database schemas.

toggle To clear all of the old names in the schema file after deployment

  1. Open the schema file in the UltraLite Schema Painter.

  2. Choose File > Clear Upgrade Information.

This sets all of the old names for tables and columns to empty values. You can then safely edit your schema file for the next version of your application.

Manual renaming of object names

Sometimes it may be desirable to manually alter the names of tables and columns. For example, you may have versions one and two of your application deployed and wish to create a single UltraLite schema file that can upgrade both versions one and two of this database to version three.

toggle To manually change object names

  1. Open your schema in the UltraLite Schema Painter.

  2. Choose File > Export Schema for Palm.

You can use this feature to inspect the current old names in your schema. If you use ulxml, you can explicitly set the old name of tables and columns in the <table> and <column> XML elements.


The ulxml utility

Applies to

UltraLite components.

Function

The ulxml utility lets you convert UltraLite database schema definitions among XML, USM and Palm PDB file formats. For example, you can create a .usm file from an XML file. The resulting schema file can be used with any UltraLite component.

Syntax

ulxml [ options ] input-file output-file

Option | Description
-y | Overwrite output file if it already exists.
-to type where type=xml|usm|pdb Note: pdb files require a CreatorID. | Converts the file to one of these standard formats. Use toxml to convert an UltraLite schema to XML. Use tousm to convert an XML file to an UltraLite schema Use topdb creator-id to convert an XML file to an UltraLite schema for Palm.

You can export your UltraLite schema so that you can work in XML format:

The database schema for CustDB is shown in this screen shot in XML format.

The XML schema that defines the documents is in win32\usm.xsd in your SQL Anywhere installation. The ulxml utility requires that schema file.

You can view and use the documented sample located in Samples\NativeUltraLiteForJava\sample.xml, Samples\UltraLiteActiveX\sample.xml, and Samples\UltraLiteForMobileVB\sample.xml.

UltraLite Schema Painter
The UltraLite Schema Painter by default creates, opens and saves UltraLite schema files in their native USM file format. However, you are given the option to create, open and save XML files as well by choosing UltraLite XML Schema Files in any file type dropdown box.
Return code

0 on success, less than 0 on failure.


Tutorial: Working with UltraLite Databases

About this chapter

This chapter walks you through several tasks related to UltraLite database schemas and database files. It introduces the UltraLite Schema Painter, the UltraLite Interactive SQL utility, and the UltraLite command-line administration tools. It also shows how you can generate and synchronize with an Adaptive Server Anywhere consolidated database from an UltraLite database.

Lesson 1: Create an UltraLite database schema
Lesson 2: Define and create a consolidated database
Lesson 3: Enter data in your UltraLite database
Lesson 4: Synchronize your databases


Lesson 1: Create an UltraLite database schema

In this lesson, you build a single-table UltraLite database schema for Windows CE, Windows XP, and Palm OS devices.

This lesson is the first in a complete tutorial on working with UltraLite databases. You may also have reached this lesson from one of several UltraLite component tutorials, in which case you should return to your main tutorial after creating a schema file.

For more information on UltraLite schemas, see Creating UltraLite databases and schemas.

To start this tutorial, create a directory to hold the schema and other files. This directory is assumed to be C:\tutorial\. If you create your tutorial directory elsewhere, supply the path to your location instead of c:\tutorial\ throughout.

toggle To create a schema file

  1. Start the UltraLite Schema Painter:

    Choose Start > Programs > SQL Anywhere 9 > UltraLite > UltraLite Schema Painter.

  2. Create a new schema file called tutCustomer.

    • From the File menus, select New > UltraLite Schema.

    • For a filename, enter c:\tutorial\tutCustomer.usm or Browse to the folder and enter tutCustomer.usm.

    • Leave the other settings at their default values and click OK to create the schema.

  3. Create a table called customer.

    • In the left pane of the UltraLite Schema Painter, expand the tutCustomer item and select the Tables folder.

    • In the right pane, double-click Add Table.

      The New Table dialog appears.

    • Enter the name Customer.

    • Click Add to add the following columns:

      Column name | Data type (Size) | Column Allows NULL values? | Default value
      ID | integer | No | autoincrement
      FName | char (15) | No | None
      LName | char (20) | No | None
      City | char (20) | Yes | None
      Phone | char (12) | Yes | 555-1234
      Tutorial use only
      The use of autoincrement as a primary key is not recommended in a database that is going to be synchronized. Instead, use a global autoincrement or UUID value. For the purposes of this tutorial, an autoincrement is sufficient.

      For more information on maintaining unique primary keys in a synchronization setup, see Maintaining unique primary keys.

    • Set ID as the primary key: click Primary Key and add ID to the index, marking it as ascending.

    • Check your work and click OK to complete the table definition and dismiss the New Table dialog.

  4. Click File > Save to save the tutcustomer.usm file.

  5. Optionally, export a Palm schema file.

    If you intend to work with the Palm OS as a target platform, you may want to export a schema definition for the Palm OS.

    • From the File menu, choose Export Schema for Palm.

    • Enter a Palm Creator ID. For tutorial purposes you could use Syb3, but do not use this for deployed applications.

      A note on Palm Creator IDs
      A Palm creator ID is assigned to you by Palm. You can use Syb3 as your creator ID when you make sample applications. However, when you create production applications, you should obtain and use your own creator ID.

    • Leave the filename at its default setting to save the PDB file in your tutorial directory. Click OK.

You have now defined the schema of an UltraLite database. Although this database contains only a single table, you can use many tables in UltraLite databases.

UltraLite component tutorial readers
You may be carrying out this lesson as part of an UltraLite component tutorial or you may be working through the complete tutorial in this chapter. If you reached this lesson from an UltraLite component tutorial, you only need the schema file and so you can return to your main tutorial now. Otherwise, continue.
toggle To create an UltraLite database file

  1. From the Tools menu of the UltraLite Schema Painter, choose Create UltraLite Database.

    The Create UltraLite Database dialog appears.

  2. Choose Multibyte Character Database (Desktop) and leave the other settings at their default values.

  3. Click OK to create the database.


Lesson 2: Define and create a consolidated database

You can use the UltraLite Schema Painter to generate a SQL command file that defines tables and synchronization scripts for an Adaptive Server Anywhere consolidated database. This feature is useful if you are extending an UltraLite application to include synchronization.

In this lesson, you create a consolidated database that manages timestamp-based synchronization with your UltraLite database. The task involves the following procedures:

  1. Create a publication that holds the Customer table.

  2. Define synchronization settings for the table.

  3. Generate the table definitions and synchronization scripts.

  4. Create the consolidated Adaptive Server Anywhere database.

This lesson assumes that you have the UltraLite Schema Painter open with the tutCustomer schema opened, as at the end of Lesson 1: Create an UltraLite database schema.

toggle To create a publication holding the Customer table

  1. Create the publication:

    In the left pane, select the Publications folder. In the right pane, double click Add Publication. The Publication dialog appears.

  2. In the Publication Name field, enter CustomerPublication.

  3. Select the Customer table and click >> to add it to the list of tables in the publication. Click OK.

The next step defines synchronization settings.

toggle To define synchronization settings

  1. Add the table to the list of tables with custom settings:

    • In the left pane, open the MobiLink Synchronization folder. In the right pane, double click Add Table-specific Settings.

      The MobiLink Table Settings dialog appears.

    • Select the Customer table and click >> to add it to the list of tables with MobiLink settings. Click OK.

  2. Define the settings.

    In the left pane, select the MobiLink Synchronization folder.

    Right click the Customer table and choose Properties. The MobiLink Synchronization Property sheet appears. The settings here are chosen for simplicity in this demonstration: in a production environment the settings depend on your business rules.

    1. On the Direction tab, leave the setting at Full Synchronization.

    2. On the Row Increment tab, choose Timestamp. Leave the Use Shadow Table option.

      An additional column will be created in the consolidated database that holds the timestamp values for this table.

    3. On the Row Partition tab, leave the setting at Same Data on All Remote Databases.

    4. On the Deletions tab, choose Download Deletions and select the first of the two options. A table named Customer_deletes will be created in the consolidated database that holds identifying values for the deleted rows.

    5. On the Conflict tab and the Resolution tab, leave the values at their default settings.

    6. Click OK to save the settings.

  3. Optionally, preview the table definitions and synchronization scripts.

    You can preview the table definitions and synchronization scripts by right-clicking the table and choosing Preview Consolidated Tables and Scripts from the popup menu. The previewed definitions and scripts define the tables and synchronization scripts needed for an Adaptive Server Anywhere consolidated database that can synchronize with this UltraLite database. Comment lines are prefixed by --.

The next step is to generate the SQL command file that holds the table definitions and synchronization scripts.

toggle To generate the consolidated database table and script definitions

  1. From the Tools menu, choose Generate Consolidated Tables and Scripts.

    The Generate Consolidated Tables and MobiLink Scripts dialog appears.

  2. In the Settings group, set the MobiLink script version is to Tutorial. Leave the other two checkboxes at their default values.

  3. In the Generated SQL group, ensure the Consolidated Tables, Triggers, MobiLink Scripts and Procedures checkbox is selected.

    During the development of real applications, you may regenerate synchronization scripts and table definitions several times as you modify your application. For this reason, the dialog provides you with the option to generate only some of the database objects.

  4. Leave the Generated SQL file as the default setting (tutCustomer.sql) and click OK to generate the scripts.

The final step is to use the generated SQL command file to create an Adaptive Server Anywhere consolidated database.

toggle To create a consolidated database

  1. Create the consolidated database file.

    Open a command prompt, and change to the tutorial directory. Enter the following command to create a database file named consol.db:

    dbinit consol.db

  2. Define an ODBC data source for the database.

    1. Open the ODBC Administrator.

      From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > ODBC Administrator.

    2. On the User DSN table, click Add. The Create New Data Source dialog appears.

    3. From the list, choose Adaptive Server Anywhere 9.0 and click Finish. The Adaptive Server Anywhere ODBC Configuration dialog appears.

    4. Enter the following settings in the dialog:

      Field | Value
      Data Source Name (ODBC tab) | Consolidated
      User ID (Login tab) | DBA
      Password (Login tab) | SQL
      Server name (Database tab) | consol
      Database file (Database tab) | c:\tutorial\consol.db

    5. On the ODBC tab, click Test Connection to test the settings.

    6. Once the Test Connection succeeds, click OK to save your definition and close the ODBC Administrator. If it fails, review the settings.

  3. Connect to the consolidated database using Interactive SQL.

    1. From the Start menu, choose Programs > SQL Anywhere 9 > Adaptive Server Anywhere > Interactive SQL.

    2. In the Connection dialog, specify an ODBC data source of Consolidated, and click OK to connect.

  4. Open the generated SQL command file.

    From the File Menu, choose Open. Open the file c:\tutorial\tutCustomer.sql.

  5. Run the SQL command file.

    Choose SQL > Execute to execute the SQL statements and create the tables and synchronization scripts in the consolidated database.

Your consolidated database is now created. It does not, of course, contain any data.


Lesson 3: Enter data in your UltraLite database

In this tutorial we use UltraLite Interactive SQL to add data to the UltraLite database. This lesson introduces the UltraLite Interactive SQL utility.

toggle To enter data in your UltraLite database

  1. Start UltraLite Interactive SQL

    At a command prompt, enter the following command:

    ulisql

    A Connect dialog appears.

  2. In the Filename field, browse to the tutCustomer.udb file that you created in lesson 1.

    Enter a user ID of DBA and a password of SQL. Click OK to connect to the database.

  3. Enter the following statement to add a Customer name to the database:

    INSERT Customer (FName, LName, City )
VALUES ('Jane', 'Doe', 'Boston')

    Press F5 to execute the statement and add the row to the table.

  4. Optionally, add some other names of your choice by modifying this statement. The number of names is not important for this tutorial.

  5. Enter the following statement to commit the changes.

    COMMIT

  6. Check the values in the table by executing this statement:

    SELECT * FROM Customer

  7. Close UltraLite Interactive SQL.


Lesson 4: Synchronize your databases

In this lesson, you upload the changes you have made to your UltraLite database. As you do not have an UltraLite application, this lesson uses the ulsync command-line utility to synchronize.

toggle To synchronize your databases

  1. Start the MobiLink synchronization server running against the consolidated database.

    At a command prompt, change directories to your tutorial directory (holding the consol.db consolidated database file) and enter the following command:

    dbmlsrv9 -c "dsn=Consolidated" -zu+

    The -zu+ command-line option is a convenience option that allows unrecognized users to synchronize. It should not be used in production environments.

  2. Synchronize the UltraLite database.

    Ensure that UltraLite Interactive SQL is closed, as only one application at a time can access this UltraLite database.

    At the command prompt, enter the following command, which must be entered on a single line:

    ulsync -c "dbf=tutCustomer.udb" "version=Tutorial;username=test"

    The database synchronizes.

The tutorial is now complete. You can inspect the data in either of the databases, make more changes to either database using Interactive SQL (for the consolidated database) or UltraLite Interactive SQL (for the UltraLite database), and synchronize them using the techniques described here.


SQL Language Elements

About this chapter

This chapter describes the building blocks of SQL statements and data management in UltraLite databases. These building blocks are common to all UltraLite databases.


Overview of SQL support in UltraLite

In UltraLite, both the data types available to represent data and the SQL features available to access that data depend on the development model you adopt.

If you use a static interface (embedded SQL, static C++ API, or static Java API), the range of SQL available is wider, but all statements used by the application must be specified at compile time. If you develop your application using an UltraLite component, dynamic SQL provides a narrower range of SQL, but the SQL statements can be constructed at runtime.

When an UltraLite program attempts to use a SQL statement or feature that is not supported in UltraLite, the SQL error Feature not available with UltraLite (SQLCODE -749) is reported. Dynamic SQL may also return syntax errors.

  • Data types UltraLite supports a subset of the data types available in Adaptive Server Anywhere.

    If you create a database from an Adaptive Server Anywhere reference database, you can use a wide range of data types. Those Adaptive Server Anywhere data types not supported in UltraLite are converted by the UltraLite generator into a smaller set of base types. If you create an UltraLite database using the Schema Painter, you are restricted to the smaller set of base types.

    For a listing of the UltraLite base types, see Data types in UltraLite.

    For a complete listing of Adaptive Server Anywhere data types, see SQL Data Types.

  • Identifiers Identifiers are the names of database objects, such as columns and tables. UltraLite supports the same rules for identifiers as Adaptive Server Anywhere.

    Tables in UltraLite do not have an owner. As a convenience for existing SQL and for SQL that is programmatically generated, UltraLite does support the syntax owner.table-name in SQL statements but the owner part is not checked.

    For information about identifiers, see Identifiers.

  • Strings Strings are used to hold character data in the database. UltraLite supports the same rules for strings as Adaptive Server Anywhere.

    If you create an UltraLite database from an Adaptive Server Anywhere reference database, the rules for strings are determined by the database options in effect in the reference database when the UltraLite generator is run. The QUOTED_IDENTIFIER option is particularly important in setting rules for strings. Dynamic SQL always operates as if this option is ON (the default in Adaptive Server Anywhere).

    For information about strings, see Strings.

    The results of comparisons on strings, and the sort order of strings, depends on both the case sensitivity of the database and the character set. These properties are set when the database is created.

    For more information, see Creating UltraLite databases.

  • Functions UltraLite supports the same range of functions as Adaptive Server Anywhere, with a few minor exceptions. The functions supported are the same for static interfaces such as embedded SQL as they are for dynamic SQL.

    For a list of supported functions, see UltraLite SQL functions.

  • Expressions Expressions are formed by combining data, often in the form of column references, with operators or functions.

    Adaptive Server Anywhere provides a wide range of operators that it uses to form expressions. These operators are available if you develop your UltraLite application using a static interface (embedded SQL, static C++ API, or static Java API). One exception is that in Adaptive Server Anywhere you can use SQL variables to form expressions. You cannot use SQL variables (including global variables) in UltraLite applications. The @@identity global variable is an exception, and can be used within UltraLite applications.

    For information about expressions in Adaptive Server Anywhere, see Expressions.

    Dynamic SQL is more limited in the range of expressions it supports than is static SQL. For example, dynamic SQL does not support subqueries in all the places that they are supported by static SQL.

    For information about the expressions available in dynamic SQL, see Dynamic SQL expressions.

  • Search conditions Search conditions or predicates are used in the WHERE clause, the HAVING clause, and the ON clause of SELECT statements.

    Dynamic SQL is more limited in the range of conditions that it supports than is static SQL.

    For information about search conditions available in dynamic SQL, see Dynamic SQL search conditions.

    Static interfaces have the entire range of conditions supported in Adaptive Server Anywhere available.

    For information about search conditions in Adaptive Server Anywhere, see Search conditions.

  • Statements SQL statements are constructed from the building blocks listed above.

    For a list of SQL statements available in dynamic SQL, see Dynamic SQL statements.

    The following SQL statements can be used in static UltraLite applications:

    • Data Manipulation Language SELECT, INSERT, UPDATE, and DELETE statements can be included. You can use placeholders in these statements that are filled in at runtime.

      For more information, see Writing UltraLite SQL statements.

    • TRUNCATE TABLE statement You can use this statement to rapidly delete entire tables.

    • Transaction control You can use COMMIT and ROLLBACK statements to provide transaction control within your UltraLite application.

    • START/STOP SYNCHRONIZATION DELETE statements These statements are used to temporarily suspend synchronization of delete operations.

      For more information, see Temporarily stopping synchronization of deletes.

For information on other UltraLite limitations, see UltraLite database limitations.


Data types in UltraLite

The following are the SQL data types supported in UltraLite databases.

If you create an UltraLite database from an Adaptive Server Anywhere reference database, you can use other data types, including user-defined data types, in the reference database. The UltraLite generator casts those data types into a data type supported in UltraLite databases. You cannot use user-defined data types that include DEFAULT values or CHECK constraints.

If you use dynamic SQL, or if you design an UltraLite database using the Schema Painter, you are limited to the use of the types listed here.

For data types in Adaptive Server Anywhere, see SQL Data Types.

Data type Remarks
BIT
 Boolean values (0 or 1). See BIT data type
{CHAR|CHARACTER}
[( max-length )]
 Character data of maximum length max-length characters. The maximum length is 2048 bytes. See CHAR data type [Character]
{VARCHAR
| CHARACTER
  VARYING}
[( max-length )]
 In UltraLite, VARCHAR is implemented identically to CHAR. In other databases, VARCHAR is used for variable-length character data of maximum length max-length. See CHARACTER VARYING (VARCHAR) data type [Character]
LONG VARCHAR
 Arbitrary length character data. Conditions in SQL statements (such as in the WHERE clause) cannot operate on LONG VARCHAR columns. The only operations allowed on LONG VARCHAR columns are to insert, update, or delete them, or to include them in the select-list of a query.

For static interfaces, the maximum size of LONG VARCHAR values is 64 KB. There is no explicit limit for the component interfaces.

See LONG VARCHAR data type [Character]
[UNSIGNED]
BIGINT
 An integer requiring 8 bytes of storage. See BIGINT data type [Numeric]
{DECIMAL | DEC}
[( precision
   [,scale] )]
 A decimal number with precision total digits and with scale of the digits after the decimal point. See DECIMAL data type [Numeric]
NUMERIC
[( precision
   [,scale] )]
 Same as DECIMAL. See NUMERIC data type [Numeric]
DOUBLE
[PRECISION]
 A double-precision floating-point number. See DOUBLE data type [Numeric]
FLOAT
[( precision )]
 A floating point number, which may be single or double precision. See FLOAT data type [Numeric]
[UNSIGNED]
{INT|INTEGER}
 An integer requiring 4 bytes of storage. See INT or INTEGER data type [Numeric]
REAL
 A single-precision floating-point number stored in 4 bytes. See REAL data type [Numeric]
[UNSIGNED]
SMALLINT
 An integer requiring 2 bytes of storage. See SMALLINT data type [Numeric]
[UNSIGNED]
TINYINT
 An integer requiring 1 byte of storage. See TINYINT data type [Numeric]
DATE
 A calendar date, such as a year, month and day. See DATE data type [Date and Time]
TIME
 The time of day, containing hour, minute, second and fraction of a second. See TIME data type [Date and Time]
DATETIME
 Identical to TIMESTAMP. See DATETIME data type [Date and Time]
TIMESTAMP
 The point in time, containing year, month, day, hour, minute, second and fraction of a second. See TIMESTAMP data type [Date and Time]
VARBINARY
[( max-length )]
 Identical to BINARY. See VARBINARY data type [BINARY]
BINARY
[( max-length )]
 Binary data of maximum length max-length bytes. The maximum length is 2048 bytes. See BINARY data type [Binary]
LONG BINARY
 Arbitrary length binary data. Conditions in SQL statements (such as in the WHERE clause) cannot operate on LONG BINARY columns. The only operations allowed on LONG BINARY columns are to insert, update, or delete them, or to include them in the select-list of a query.

For static interfaces, the maximum size of LONG BINARY values is 64 KB. There is no explicit limit for the component interfaces.

See LONG BINARY data type [BINARY]
UNIQUEIDENTIFIER
 Typically used for a primary key or other unique column to hold UUID (Universally Unique Identifier) values that uniquely identify rows. UltraLite provides functions that generate UUID values in such a way that a value produced on one computer will not match a UUID produced on another computer. UNIQUEIDENTIFIER values generated in this way can therefore be used as keys in a synchronization environment.

See UNIQUEIDENTIFIER data type [Binary].


UltraLite SQL functions

The following is a convenient reference for finding functions in dynamic SQL. Each function is listed, and the function type (numeric, character, and so on) is indicated next to it.

For information about functions in Adaptive Server Anywhere, see SQL Functions.

Function Remarks
ABS (
numeric-expression )
 See ABS function [Numeric]
ACOS (
numeric-expression )
 See ACOS function [Numeric]
ARGN (
integer-expression,
expression [ , ...] )
 See ARGN function [Miscellaneous]
ASCII (
string-expression )
 See ASCII function [String]
ASIN (
numeric-expression )
 See ASIN function [Numeric]
ATAN (
numeric-expression )
 See ATAN function [Numeric]
{ ATN2 | ATAN2 } (
numeric-expression1,
numeric-expression2 )
 See ATN2 function [Numeric]
AVG (
numeric-expression
| DISTINCT column-name )
 DISTINCT column-name cannot be used from dynamic SQL.

See AVG function [Aggregate]

BYTE_LENGTH (
string-expression )
 See BYTE_LENGTH function [String]
BYTE_SUBSTR (
string-expression,
start [, length ] )
 See BYTE_SUBSTR function [String]
CAST (
expression AS data type )
 See CAST function [Data type conversion]
CEILING (
numeric-expression )
 See CEILING function [Numeric]
CHAR (
integer-expression )
 See CHAR function [String]
CHARINDEX (
string-expression1,
string-expression2 )
 See CHARINDEX function [String]
CHAR_LENGTH (
string-expression )
 See CHAR_LENGTH function [String]
COALESCE (
expression,
expression [ , ...] )
 See COALESCE function [Miscellaneous]
CONVERT (
data-type,
expression
[ , format-style ] )
 See CONVERT function [Data type conversion]
COS (
numeric-expression )
 See COS function [Numeric]
COT (
numeric-expression )
 See COT function [Numeric]
COUNT (
 * | expression
| DISTINCT
{ expression
 column-name } )
 DISTINCT column-name cannot be used from dynamic SQL.

See COUNT function [Aggregate]

DATALENGTH (
expression )
 See DATALENGTH function [System]
DATE (
expression )
 See DATE function [Date and time]
DATEADD (
date-part,
numeric-expression,
date-expression )
 See DATEADD function [Date and time]
DATEDIFF (
date-part,
date-expression1,
date-expression2 )
 See DATEDIFF function [Date and time]
DATEFORMAT (
datetime-expression,
string-expression )
 See DATEFORMAT function [Date and time]
DATENAME (
date-part,
date-expression )
 See DATENAME function [Date and time]
DATEPART (
date-part,
date-expression )
 See DATEPART function [Date and time]
DATETIME (
expression )
 See DATETIME function [Date and time]
DAY (
date-expression )
 See DAY function [Date and time]
DAYNAME(
date-expression )
 See DAYNAME function [Date and time]
DAYS (
[datetime-expression,]
datetime-expression )
 See DAYS function [Date and time]
DAYS (
datetime-expression,
integer-expression )
 See DAYS function [Date and time]
DEGREES (
numeric-expression )
 See DEGREES function [Numeric]
DIFFERENCE (
string-expression-1,
string-expression-2 )
 See DIFFERENCE function [String]
DOW (
date-expression )
 See DOW function [Date and time]
EXP (
numeric-expression )
 See EXP function [Numeric]
FLOOR (
numeric-expression )
 See FLOOR function [Numeric]
GETDATE ()
 See GETDATE function [Date and time]
GREATER (
expression1,
expression2 )
 See GREATER function [Miscellaneous]
HEXTOINT (
hexadecimal-string )
 See HEXTOINT function [Data type conversion]
HOUR (
datetime-expression )
 See HOUR function [Date and time]
HOURS (
[ datetime-expression, ]
datetime-expression )
 See HOURS function [Date and time]
HOURS (
datetime-expression,
integer-expression )
 See HOURS function [Date and time]
IFNULL (
expression-1,
expression-2
[ , expression-3 ] )
 See IFNULL function [Miscellaneous]
INSERTSTR (
integer-expression,
string-expression-1,
string-expression-2 )
 See INSERTSTR function [String]
INTTOHEX (
integer-expression )
 See INTTOHEX function [Data type conversion]
ISDATE (
string )
 See ISDATE function [Data type conversion]
ISNULL (
expression,
expression [ , ... ] )
 See ISNULL function [Data type conversion]
LCASE (
string-expression )
 See LCASE function [String]
LEFT (
string-expression,
para-expression
 See LEFT function [String]
LENGTH (
string-expression )
 See LENGTH function [String]
LESSER (
expression1,
expression2 )
 See LESSER function [Miscellaneous]
LIST (
{ string-expression
 | DISTINCT column-name }
[ , delimiter-string ] )
 DISTINCT column-name cannot be used from dynamic SQL.

See LIST function [Aggregate]

LOCATE (
string-expression-1,
string-expression-2
[, integer-expression ] )
 See LOCATE function [String]
LOG (
numeric-expression )
 See LOG function [Numeric]
LOG10 (
numeric-expression )
 See LOG10 function [Numeric]
LOWER (
string-expression )
 See LOWER function [String]
LTRIM (
string-expression )
 See LTRIM function [String]
MAX ( expression )
 See MAX function [Aggregate]
MIN ( expression )
 See MIN function [Aggregate]
MINUTE (
datetime-expression )
 See MINUTE function [Date and time]
MINUTES (
[ datetime-expression, ]
datetime-expression )
 See MINUTES function [Date and time]
MINUTES (
datetime-expression,
integer-expression )
 See MINUTES function [Date and time]
MOD (
dividend,
divisor )
 See MOD function [Numeric]
MONTH (
date-expression )
 See MONTH function [Date and time]
MONTHNAME (
date-expression )
 See MONTHNAME function [Date and time]
MONTHS (
[ datetime-expression, ]
datetime-expression )
 See MONTHS function [Date and time]
MONTHS (
datetime-expression,
integer-expression )
 See MONTHS function [Date and time]
NEWID( )
 This function is not supported by the UltraLite static Java API.

See NEWID function [Miscellaneous]

NOW ( * )
 See NOW function [Date and time]
NULLIF (
expression-1,
expression-2 )
 See NULLIF function [Miscellaneous]
PATINDEX (
'%pattern%',
string-expression )
 See PATINDEX function [String]
PI ( * )
 See PI function [Numeric]
POWER (
numeric-expression-1,
numeric-expression-2 )
 See POWER function [Numeric]
QUARTER (
date-expression )
 See QUARTER function [Date and time]
RADIANS (
numeric-expression )
 See RADIANS function [Numeric]
REMAINDER (
dividend,
divisor )
 See REMAINDER function [Numeric]
REPEAT (
string-expression,
integer-expression )
 See REPEAT function [String]
REPLACE (
original-string,
search-string,
replace-string )
 See REPLACE function [String]
REPLICATE (
string-expression,
integer-expression )
 See REPLICATE function [String]
RIGHT (
string-expression,
integer-expression )
 See RIGHT function [String]
ROUND (
numeric-expression,
integer-expression )
 See ROUND function [Numeric]
RTRIM (
string-expression )
 See RTRIM function [String]
SECOND (
datetime-expression )
 See SECOND function [Date and time]
SECONDS (
[ datetime-expression, ]
datetime-expression )
 See SECONDS function [Date and time]
SECONDS (
datetime-expression,
integer-expression )
 See SECONDS function [Date and time]
SIGN (
numeric-expression )
 See SIGN function [Numeric]
SIMILAR (
string-expression-1,
string-expression-2 )
 See SIMILAR function [String]
SIN (
numeric-expression )
 See SIN function [Numeric]
SOUNDEX (
string-expression )
 See SOUNDEX function [String]
SPACE (
integer-expression )
 See SPACE function [String]
SQRT (
numeric-expression )
 See SQRT function [Numeric]
STR (
numeric-expression
[, length
  [, decimal ] ] )
 See STR function [String]
STRING (
string-expression
[, ...] )
 See STRING function [String]
STRTOUUID (
string-expression )
 This function is not supported by the UltraLite static Java API.

See STRTOUUID function [String]

STUFF (
string-expression1,
start,
length,
string-expression2 )
 See STUFF function [String]
{ SUBSTRING | SUBSTR }(
string-expression,
 start
[, length ] )
 See SUBSTRING function [String]
SUM (
expression
| DISTINCT column-name )
 DISTINCT column-name cannot be used from dynamic SQL.

See SUM function [Aggregate]

TAN (
numeric-expression )
 See TAN function [Numeric]
TODAY ( * )
 See TODAY function [Date and time]
TRIM (
string-expression )
 See TRIM function [String]
"TRUNCATE" (
numeric-expression,
integer-expression )
 See TRUNCATE function [Numeric]
TRUNCNUM (
numeric-expression,
integer-expression )
 See TRUNCNUM function [Numeric]
UCASE (
string-expression )
 See UCASE function [String]
UPPER (
string-expression )
 See UPPER function [String]
UUIDTOSTR(
uuid-expression )
 This function is not supported by the UltraLite static Java API.

See UUIDTOSTR function [String]

WEEKS (
[ datetime-expression, ]
datetime-expression )
 See WEEKS function [Date and time]
WEEKS (
datetime-expression,
integer-expression )
 See WEEKS function [Date and time]
YEAR (
[ datetime-expression, ]
datetime-expression )
 See YEAR function [Date and time]
YEARS (
datetime-expression,
integer-expression )
 See YEARS function [Date and time]
YMD (
integer-expression,
integer-expression,
integer-expression )
 See YMD function [Date and time]


Dynamic SQL

About this chapter

Dynamic SQL is the version of SQL available to UltraLite components. This chapter describes the features of the dynamic SQL in UltraLite.

Dynamic SQL statements can be constructed at run time. This is in contrast to the static SQL available to embedded SQL, static C++ API, and static Java API applications, which must have all SQL statements specified at compile time.


Introduction to dynamic SQL

Structured Query Language (SQL) can be used by an application to perform a database task, such as retrieving information using a query or inserting a new row into a table. SQL is a relational database language standardized by the ANSI and ISO standards bodies. UltraLite dynamic SQL is a variant designed for use on small-footprint devices.

SQL statements are supplied as strings in function calls from the programming language you are using. UltraLite components provide functions for building and generating SQL statements. The programming interface delivers the SQL statement to the database. The database receives the statement and executes it, returning the required information (such as query results) back to the application.

Queries are one form of Data Manipulation Language used in SQL. In fact, the "Q" in "SQL" stands for query. You query, or retrieve, data from a database with a SELECT statement. A query produces a result set, which is a collection of rows that satisfy the query. The basic query operations in a relational system are projection, restriction, and join. The SELECT statement implements all of them.

A projection is a subset of the columns in a table. A restriction, also called selection, is a subset of the rows in a table, based on some conditions. For example, the following SELECT statement retrieves the names and prices of all products that cost more than $15:

SELECT name, unit_price
FROM product
WHERE unit_price > 15

This query uses both a projection, as shown in the SELECT clause, and a restriction, given in the WHERE clause.

You can do more with dynamic SQL than just query the data. It also includes statements that modify data (the INSERT, UPDATE, and DELETE statements), statements that control transactions (COMMIT and ROLLBACK) and statements for creating and dropping tables and indexes (CREATE or DROP TABLE or INDEX).

Availability

Dynamic SQL is the variant of SQL available for UltraLite components. UltraLite static interfaces use a different variant of SQL. The UltraLite components can use a table-based interface as well as dynamic SQL.

For a comparison of these data access methods, see Choosing between components and static interfaces.

Using dynamic SQL


Using dynamic SQL

Dynamic SQL can be used from UltraLite components, but not from static development models. The steps in executing dynamic SQL statements are common to all components:

  1. Prepare the statement using a prepared statement method on the connection object. The name of the method varies slightly with the interface.

    Preparing a statement causes the character string representing the statement to be parsed and optimized (prepared) and returns an object representing the prepared statement. The optimization is necessarily less involved than that in Adaptive Server Anywhere.

  2. Set the value of any parameters.

    Optionally, when the statement has input parameters (identified by question marks), then your application can call methods on the prepared statement object to set the value of these parameters. Any parameters for which values are not set are set to NULL.

  3. Execute the statement.

    If the statement is an INSERT, UPDATE, or DELETE, use the ExecuteStatement method. This method returns the number of rows modified by the statement.

    If the statement is a SELECT statement, use the ExecuteQuery method. This method returns an object that holds the query result set.

  4. For queries, navigate the result set and access the values in the result set.

    • You can use methods on the result set object to set the position to different rows in the result set. Some examples are MoveNext, MovePrevious, MoveFirst, MoveLast, Relative, BeforeFirst, and AfterLast.

    • When the current position is at a row of the result set, the values of columns in the result set can be obtained by methods that get values. The names of the methods depend on the interface. The methods convert data to application data types automatically. For example, an integer result expression can automatically be converted to a string if the result is assigned to a string variable.

  5. For repeated execution of a prepared statement, repeat steps 2 through 4. Using parameters is more efficiient than preparing the entire statement again.

    The values for input variables persist after a prepared statement is executed. If you use a different value, you must reset the value of the parameter.


Dynamic SQL expressions

Expressions in UltraLite dynamic SQL are built from column names, constants, and operators. Expressions evaluate to a value, and so have data types associated with them.

Syntax

expression :
constant
| column-name
| - expression
| expression operator expression
| ( expression )
| function-name ( expression, ...)
| if-expression
| case-expression

See also
  • Subqueries in expressions
  • IF expressions
  • CASE expressions
  • UltraLite SQL functions
  • Dynamic SQL operators CASE expressions Dynamic SQL operators
Aggregate expressions

An aggregate expression calculates a single value from a range of rows. For example, the following query computes the total payroll for employees in the employee table. In this query, SUM( salary ) is an aggregate expression:

SELECT sum( salary )
FROM employee

An aggregate expression is one in which either an aggregate function is used, or in which one or more of the operands is an aggregate expression.

When a SELECT statement does not have a GROUP BY clause, the expressions in the select-list must be either all aggregate expressions or none of the expressions can be an aggregate expression. When a SELECT statement does have a GROUP BY clause, any non-aggregate expression in the select-list must appear in the GROUP BY list.


Subqueries in expressions

A subquery is a SELECT statement that is nested inside another SELECT statement. Subqueries can be used as a table expression in the FROM clause, where they are also called derived tables.

Subqueries can be written with references to names that are specified before (to the left of) the subquery, sometimes known as outer references to the left. There can be no references to items within subqueries, sometimes known as inner references. In the case of derived tables, it is required to have a derived table name and to specify the column names by which values in the SELECT list are fetched.

For other uses of subqueries, see Dynamic SQL search conditions.


IF expressions

The syntax of the IF expression is as follows:

IF condition
THEN expression1
[ ELSE expression2 ]
ENDIF

This expression returns the following:

  • If condition is TRUE, the IF expression returns expression1.

  • If condition is FALSE, the IF expression returns expression2.

  • If condition is FALSE, and there is no expression2, the IF expression returns NULL.

  • If condition is UNKNOWN, the IF expression returns NULL.

For more information about TRUE, FALSE and UNKNOWN conditions, see NULL value, and Search conditions.


CASE expressions

The CASE expression provides conditional SQL expressions. Case expressions can be used anywhere an expression can be used.

Syntax 1

CASE expression
WHEN expression THEN expression, ...
[ ELSE expression ]
END

If the expression following the CASE statement is equal to the expression following the WHEN statement, then the expression following the THEN statement is returned. Otherwise the expression following the ELSE statement is returned, if it exists.

For example, the following code uses a case expression as the second clause in a SELECT statement.

SELECT id,
   ( CASE name
      WHEN 'Tee Shirt' then 'Shirt'
      WHEN 'Sweatshirt' then 'Shirt'
      WHEN 'Baseball Cap' then 'Hat'
      ELSE 'Unknown'
   END ) as Type
FROM Product
Syntax 2

CASE
WHEN search-condition
THEN expression, ...
[ ELSE expression ]
END

If the search-condition following the WHEN statement is satisfied, the expression following the THEN statement is returned. Otherwise the expression following the ELSE statement is returned, if it exists.

For example, the following statement uses a case expression as the third clause of a SELECT statement to associate a string with a search-condition.

SELECT id, name,
   ( CASE
      WHEN name='Tee Shirt' then 'Sale'
      WHEN quantity >= 50  then 'Big Sale'
      ELSE 'Regular price'
   END ) as Type
FROM Product
NULLIF function for abbreviated CASE expressions

The NULLIF function provides a way to write some CASE statements in short form. The syntax for NULLIF is as follows:

NULLIF ( expression-1, expression-2 )

NULLIF compares the values of the two expressions. If the first expression equals the second expression, NULLIF returns NULL. If the first expression does not equal the second expression, NULLIF returns the first expression.


Dynamic SQL operators

Operators are used to compare, combine, or modify expressions. Dynamic SQL supports the operators listed in this section. UltraLite static interfaces have access to all of the Adaptive Server Anywhere operators.

For information about operators in Adaptive Server Anywhere, see Operators.


Binary comparison operators

The syntax for binary comparison conditions is as follows:

expression compare expression

where compare is a comparison operator. The following comparison operators are available:

Operator | Description
= | Equal to
[ NOT ] LIKE | A text comparison, possibly using regular expressions
> | Greater than
< | Less than
>= | Greater than or equal to
<= | Less than or equal to
!= | Not equal to
<> | Not equal to
!> | Not greater than
!< | Not less than

  • Case sensitivity Comparisons are carried out with the same attention to case as the database on which they are operating. By default, UltraLite databases are created as case insensitive.

  • NULL operators Comparisons involving NULL expressions follow these rules:

    Two null values compare as equals. When exactly one of the operands being compared is NULL, the result is UNKNOWN. Thus, SQL comparisons produce one of three results (TRUE, FALSE, and UNKNOWN). Similarly, logical expressions (AND, OR, NOT) can also produce these results.


Arithmetic operators

expression + expression Addition. If either expression is NULL, the result is NULL.

expression - expression Subtraction. If either expression is NULL, the result is NULL.

- expression Negation. If the expression is NULL, the result is NULL.

expression * expression Multiplication. If either expression is NULL, the result is NULL.

expression / expression Division. If either expression is NULL or if the second expression is 0, the result is NULL.

expression % expression Modulo finds the integer remainder after a division involving two whole numbers. For example, 21 % 11 = 10 because 21 divided by 11 equals 1 with a remainder of 10.


String operators

expression || expression String concatenation (two vertical bars). If either string is NULL, it is treated as the empty string for concatenation.

expression + expression Alternative string concatenation. When using the + concatenation operator, you must ensure the operands are explicitly set to character data types rather than relying on implicit data conversion.

For example, the following query returns the integer value 579:

SELECT 123 + 456

whereas the following query returns the character string 123456:

SELECT '123' + '456'

You can use the CAST or CONVERT function to explicitly convert data types.


Bitwise operators

The following operators can be used on integer data types in UltraLite.

Operator | Description
& | bitwise AND
| | bitwise OR
^ | bitwise exclusive OR
~ | bitwise NOT

The bitwise operators &, | and ~ are not interchangeable with the logical operators AND, OR, and NOT. The bitwise operators operate on integer values using the bit representation of the values.

Example

For example, the following statement selects rows in which the correct bits are set.

SELECT *
FROM tableA
WHERE (options & 0x0101) <> 0


Logical operators

Logical operators compare conditions (AND, OR, and NOT) or test the truth or NULL value nature of expressions (IS)

Conditions are combined using AND as follows:

condition1 AND condition2

The combined condition is TRUE if both conditions are TRUE, FALSE if either condition is FALSE, and UNKNOWN otherwise.

Conditions are combined using OR as follows:

condition1 OR condition2

The combined condition is TRUE if either condition is TRUE, FALSE if both conditions are FALSE, and UNKNOWN otherwise.

The syntax for the NOT operator is as follows:

NOT condition

The NOT condition is TRUE if condition is FALSE, FALSE if condition is TRUE, and UNKNOWN if condition is UNKNOWN.

The IS operator provides a means to test a logical value. The syntax for the IS operator is as follows:

expression IS [ NOT ] { truth-value | NULL }

The condition is TRUE if the expression evaluates to the supplied truth-value, which must be one of TRUE, FALSE, or UNKNOWN. Otherwise, the value is FALSE.


Operator precedence

The precedence of operators in expressions is as follows. The operators at the top of the list are evaluated before those at the bottom of the list.

  1. Names, functions, constants

  2. ()

  3. unary operators (operators that require a single operand): +, -

  4. ~

  5. &, | , ^

  6. *, /, %

  7. +, -

  8. ||

  9. Comparisons: >, <, <>, !=, <=, >=, [ NOT ] BETWEEN, [ NOT ] IN, [ NOT ] LIKE

  10. Comparisons: IS [NOT] TRUE, FALSE, UNKNOWN

  11. NOT

  12. AND

  13. OR

When you use more than one operator in an expression, it is recommended that you make the order of operation explicit using parentheses rather than relying on an identical operator precedence in UltraLite.


Dynamic SQL search conditions

Search conditions appear in the WHERE clause or the ON phrase in SQL queries. The following search conditions are supported in dynamic SQL.

Syntax

search-condition:
expression compare expression
| expression IS [ NOT ] { NULL | TRUE | FALSE | UNKNOWN }
| expression [ NOT ] BETWEEN expression AND expression
| expression [ NOT ] IN ( expression, ... )
| expression [ NOT ] IN ( subquery )
| expression [ NOT ] { ANY | ALL } ( subquery )
| expression [ NOT ] EXISTS ( subquery )
| NOT search-condition
| search-condition AND search-condition
| search-condition OR search-condition
| ( search-condition )


ALL conditions

The syntax for ALL conditions is

expression compare [ NOT ] ALL ( subquery )

where compare is a comparison operator.


ANY conditions

The syntax for ANY conditions is

expression compare [ NOT ] ANY ( subquery )

where compare is a comparison operator.

For example, an ANY condition with an equality operator,

expression = ANY ( subquery )

is TRUE if expression is equal to any of the values in the result of the subquery, and FALSE if the expression is not NULL and does not equal any of the values returned by the subquery. The ANY condition is UNKNOWN if expression is the NULL value, unless the result of the subquery has no rows, in which case the condition is always FALSE.


BETWEEN conditions

The syntax for BETWEEN conditions is as follows:

expression [ NOT ] BETWEEN start-expression AND end-expression

The BETWEEN condition can evaluate as TRUE, FALSE, or UNKNOWN. Without the NOT keyword, the condition evaluates as TRUE if expression is between start-expression and end-expression. The NOT keyword reverses the meaning of the condition but leaves UNKNOWN unchanged.

The BETWEEN conditions is equivalent to a combination of two inequalities:

[ NOT ] ( expression >= start-expression
AND expression <= end-expression )


EXISTS conditions

The syntax for EXISTS conditions is as follows:

[ NOT ] EXISTS( subquery )

The EXISTS condition is TRUE if the subquery result contains at least one row, and FALSE if the subquery result does not contain any rows. The EXISTS condition cannot be UNKNOWN.


IN conditions

The syntax for IN conditions is as follows:

expression [ NOT ] IN { ( subquery ) | ( value-expr, ... ) }

An IN condition, without the NOT keyword, evaluates according to the following rules:

  • TRUE if expression is not NULL and equals at least one of the values.

  • UNKNOWN if expression is NULL and the values list is not empty, or if at least one of the values is NULL and expression does not equal any of the other values.

  • FALSE if expression is NULL and subquery returns no values; or if expression is not NULL, none of the values are NULL, and expression does not equal any of the values.

The NOT keyword interchanges TRUE and FALSE.

The search condition expression IN ( values ) is identical to the search condition expression = ANY ( values ). The search condition expression NOT IN ( values ) is identical to the search condition expression <> ALL ( values ).

The value-expr arguments are expressions that take on a single value, which may be a string, a number, a date, or any other SQL data type.


Dynamic SQL statements

The following are dynamic SQL statements that you can use in UltraLite.

COMMIT statement
CREATE INDEX statement
CREATE TABLE statement
DELETE statement
DROP INDEX statement
DROP TABLE statement
INSERT statement
ROLLBACK statement
SELECT statement
UPDATE statement


COMMIT statement

Description

Use this statement to make changes to the database permanent, or to terminate a user-defined transaction.

Syntax

COMMIT [ WORK ]

Usage

A transaction is the logical unit of work done on one database connection to a database between COMMIT or ROLLBACK statements. The COMMIT statement ends a transaction and makes all changes made during this transaction permanent in the database.

CREATE and DROP statements both carry out a COMMIT automatically.

Side effects

Closes all cursors.


CREATE INDEX statement

Description

Use this statement to create an index on a specified table. Indexes can improve query performance by providing quick ways for UltraLite to look up specific rows.

For more information about indexes, see Query optimization.

Syntax

CREATE [ UNIQUE ] INDEX index-name
ON [ owner.]table-name ( column-name, ...)

Parameters

UNIQUE keyword The UNIQUE attribute ensures that there will not be two rows in the table with identical values in all the columns in the index. Each index key must be unique or contain a NULL in at least one column.

There is a difference between a unique constraint on a table and a unique index. Columns of a unique index are allowed to be NULL, while columns in a unique constraint are not. A foreign key can reference either a primary key or a column with a unique constraint, but not a unique index, because it can include multiple instances of NULL.

UltraLite tables do not have owners. The optional owner is supported as a convenience for existing SQL and for programmatically-generated SQL. UltraLite accepts but ignores owner.

Usage

The CREATE INDEX statement creates a sorted index on the specified columns of the named table. Indexes are automatically used to improve the performance of queries issued to the database, and to sort queries with an ORDER BY clause. Once an index is created, it is never referenced in a SQL statement again except to delete it with DROP INDEX.

Indexes do take space in the database. Also, the additional work required to maintain indexes can affect the performance of data modification operations. For these reasons, you should avoid creating indexes that do not assist in query performance.

  • Exclusive table use CREATE INDEX is prevented whenever the statement affects a table currently being used by another connection. CREATE INDEX can be time consuming and the server will not process requests referencing the same table while the statement is being processed.

  • Automatically created indexes UltraLite automatically creates indexes for primary keys and for unique constraints.


CREATE TABLE statement

Description

Use this statement to create a table in the database.

Syntax

CREATE TABLE [ owner.]table-name
( { column-definition | table-constraint }, ... )

column-definition :
column-name data-type [ NOT NULL ]
[ DEFAULT default-value ]
[ UNIQUE | PRIMARY KEY ]

default-value :
| constant-expression
| AUTOINCREMENT
| GLOBAL AUTOINCREMENT [ ( partition-size ) ]
| NULL
| NEWID ( )
| CURRENT DATE
| CURRENT TIME
| CURRENT TIMESTAMP

table-constraint :
UNIQUE ( column-name, ... )
| PRIMARY KEY ( column-name, ... )
| foreign-key-constraint

foreign-key-constraint :
[ NOT NULL ] FOREIGN KEY (column-name, ... )
REFERENCES table-name (column-name, ... )
[ CHECK ON COMMIT ]

Parameters

column-definition Define a column in the table. The following are part of column definitions.

  • column-name The column name is an identifier. Two columns in the same table cannot have the same name.

  • data-type For information on data types, see Data types in UltraLite.

  • NOT NULL If NOT NULL is specified, or if the column is in a UNIQUE or PRIMARY KEY constraint, the column cannot contain NULL in any row.

  • DEFAULT The DEFAULT value is used as the value for the column in any INSERT statement that does not specify a value for the column. If no DEFAULT is specified, it is equivalent to DEFAULT NULL.

    • constant-expression The default value is the supplied constant expression. Only constant expressions that do not reference database objects are allowed in a DEFAULT clause. If the expression is not a simple value, for example if it is an expression involving an addition operator, it must be enclosed in parentheses.

    • AUTOINCREMENT The default value is an autoincremented value for each row in the table. When using AUTOINCREMENT, the column must be one of the integer data types, or an exact numeric type.

      On inserts into the table, if a value is not specified for the AUTOINCREMENT column, a unique value larger than any other value in the column is generated. If an INSERT specifies a value for the column, it is used; if the specified value is larger than the current maximum value for the column, that value will be used as a starting point for subsequent inserts.

      Deleting rows does not decrement the AUTOINCREMENT counter. Gaps created by deleting rows can only be filled by explicit assignment when using an insert. After an explicit insert of a row number less then the maximum, subsequent rows without explicit assignment are still automatically incremented with a value of one greater than the previous maximum.

      The next value to be used for each column is stored as an integer. Using values greater than (231 – 1) may cause wraparound to incorrect values, and AUTOINCREMENT should not be used in such cases.

    • GLOBAL AUTOINCREMENT The default value is an autoincremented value within a partition of values provided for this database. The GLOBAL AUTOINCREMENT default is intended for use when multiple databases will be used in a synchronization environment.

      This default is similar to AUTOINCREMENT, except that the domain is partitioned. Each partition contains the same number of values. You assign each copy of the database a unique global database identification number.

      The partition size can be specified in parentheses immediately following the AUTOINCREMENT keyword. The partition size may be any positive integer, although the partition size is generally chosen so that the supply of numbers within any one partition will rarely, if ever, be exhausted.

      If the column is of type BIGINT or UNSIGNED BIGINT, the default partition size is 232 = 4294967296; for columns of all other types the default partition size is 216 = 65536. Since these defaults may be inappropriate, especially if the column is not of type INT or BIGINT, it is best to specify the partition size explicitly.

      When using this default, the Global Database ID of each database must be set to a unique, non-negative integer. This value uniquely identifies the database and indicates from which partition default values are to be assigned. The range of allowed values is n p + 1 to (n + 1) p, where n is the value of the Global Database ID and p is the partition size. For example, if you define the partition size to be 1000 and set the Global Database ID to 3, then the range is from 3001 to 4000.

      If the previous value is less than (n + 1) p, the next default value will be one greater than the previous largest value in column. If the column contains no values, the first default value is n p + 1. Default column values are not affected by values in the column outside of the current partition; that is, by numbers less than pn + 1 or greater than p(n + 1). Such values may be present if they have been replicated from another database via MobiLink synchronization.

      Because the Global Database ID cannot be set to negative values, the values chosen are always positive. The maximum identification number is restricted only by the column data type and the partition size.

      If the Global Database ID is set to the default value of 2147483647, a NULL is inserted into the column. Should null values not be permitted, attempting to insert the row causes an error. This situation arises, for example, if the column is contained in the table's primary key.

      NULL default values are generated when the supply of values within the partition has been exhausted. In this case, a new Global Database ID should be assigned to the database to allow default values to be chosen from another partition. Attempting to insert the null value causes an error if the column does not permit nulls.

    • NULL The default value is NULL. A column that is DEFAULT NULL is equivalent to a column that allows NULL and has no explicit default value.

    • NEWID The default value is a universal unique identifier (UUID). UUIDs can be used as an alternative to GLOBAL AUTOINCREMENT to uniquely identify rows in a table even in a synchronized environment of many databases. The values are generated such that a value produced on one computer will not match that produced on another. Hence they can also be used as keys in synchronization environments.

      The column type must be a UNIQUEIDENTIFIER or a BINARY column of size at least 16.

      NEWID is a non-deterministic function. Successive calls to NEWID may return different values.

    • CURRENT DATE The default value is the current date.

    • CURRENT TIME The default value is the current time.

    • CURRENT TIMESTAMP The default value is the current timestamp, which specifies a date and time.

  • UNIQUE Imposes the restriction that all values in the column must be distinct. A column that is declared UNIQUE does not allow NULL.

  • PRIMARY KEY Declares the column as the primary key for the table. The primary key column cannot hold NULL, and each row must be unique.

    A table can have only one primary key, although that key may be composed of more than one column. To create a table with a multiple column primary key, declare the primary key in a table constraint.

table-constraint A table constraint restricts the values that one or more columns in the table can hold.

Table constraints help ensure the integrity of data in the database. UltraLite prevents the execution of statements that cause constraint violations and reports an error.

Table constraints must be used instead of column constraints when the constraint references more than one column in the table.

  • UNIQUE Identifies one or more columns that uniquely identify each row in the table. No two rows in the table can have the same values in all the named column(s). A table may have more than one unique constraint.

    Columns of a unique index are allowed to be NULL, while columns in a unique constraint are not. A foreign key can reference either a primary key or a unique constraint, but not a unique index, because it can include multiple instances of NULL.

    For information about unique indexes, see CREATE INDEX statement.

  • PRIMARY KEY This is the same as a unique constraint, except that a table can have only one primary key constraint.

    Columns included in primary keys cannot allow NULL. Each row in the table has a unique primary key value. A table can have only one PRIMARY KEY.

  • foreign-key-constraint A foreign key constraint restricts the values for a set of columns to match the values in a primary key or, less commonly, a unique constraint of another table (the primary table). For example, a foreign key constraint could be used to ensure that a customer number in an invoice table corresponds to a customer number in the customer table.

    If you do not explicitly define a foreign key column, it is created with the same data type as the corresponding column in the primary table. These automatically-created columns cannot be part of the primary key of the foreign table. Thus, a column used in both a primary key and foreign key of the same table must be explicitly created.

    If foreign key column names are specified, then primary key column names must also be specified, and the column names are paired according to position in the lists. If the primary table column names are not specified in a FOREIGN KEY table constraint, then the primary key columns are used. If foreign key column names are not specified then the foreign key columns are give the same names as the columns in the primary table.

    If at least one value in a multi-column foreign key is NULL, there is no restriction on the values that can be held in other columns of the key.

    The CHECK ON COMMIT clause causes UltraLite to wait for a COMMIT before checking that the action does not violate the foreign key constraint.

UltraLite tables do not have owners. The optional owner is supported as a convenience for existing SQL and for programmatically-generated SQL. UltraLite accepts but ignores owner.


DELETE statement

Description

Use this statement to delete rows from the database.

Syntax

DELETE
[ FROM ] [ owner.]table-name
[ WHERE search-condition ]

Usage

The DELETE statement deletes all the rows that satisfy the search condition from the named table.

Caution If no WHERE clause is specified, all rows from the named table are deleted.

UltraLite tables do not have owners. The optional owner is supported as a convenience for existing SQL and for programmatically-generated SQL. UltraLite accepts but ignores owner.

Side effects

None.

Example

Remove employee 105 from the database.

DELETE
FROM employee
WHERE emp_id = 105

Remove all data prior to 2000 from the fin_data table.

DELETE
FROM fin_data
WHERE year < 2000


DROP INDEX statement

Description

Use this statement to permanently remove an index definition from the database.

Syntax

DROP INDEX [[ owner.]table-name.]index-name

Usage

The DROP INDEX statement removes the definition of the indicated index.

DROP INDEX is prevented whenever the statement affects a table that is currently being used by another connection.

UltraLite tables do not have owners. The optional owner is supported as a convenience for existing SQL and for programmatically-generated SQL. UltraLite accepts but ignores owner.


DROP TABLE statement

Description

Use this statement to permanently remove a table definition and all data in the table from a database.

Syntax

DROP TABLE [ owner.]table-name

Usage

The DROP TABLE statement removes the definition of the indicated table. All data in the table is automatically deleted as part of the dropping process. Also, all indexes and keys for the table are dropped by the DROP TABLE statement.

DROP TABLE is prevented whenever the statement affects a table that is currently being used by another connection.

UltraLite tables do not have owners. The optional owner is supported as a convenience for existing SQL and for programmatically-generated SQL. UltraLite accepts but ignores owner.


INSERT statement

Description

Use this statement to insert a single row into a table (Syntax 1) or to insert the results from a SELECT statement into the table (Syntax 2).

Syntax 1

INSERT [ INTO ] [ owner.]table-name [ ( column-name, ... ) ]
VALUES ( expression, ... )

Syntax 2

INSERT [ INTO ] [ owner.]table-name [ ( column-name, ... ) ]
SELECT statement

Usage

The INSERT statement is used to add new rows to a database table.

Insert a single row with the specified expression values. If the optional list of column names is given, the values are inserted one for one into the specified columns. If the list of column names is not specified, the values are inserted into the table columns in the order they were created (the same order as retrieved with SELECT *). The row is inserted into the table at an arbitrary position.

If you specify column names, the columns from the select list are matched ordinally with the columns specified in the column list, or sequentially in the order in which the columns were created.

Character strings inserted into tables are always stored in the same case as they are entered, regardless of whether the database is case sensitive or not. Thus a string Value inserted into a table is always held in the database with an upper-case V and the remainder of the letters lower case. SELECT statements return the string as Value. If the database is not case sensitive, however, all comparisons make Value the same as value, VALUE, and so on. Further, if a single-column primary key already contains an entry Value, an INSERT of value is rejected, as it would make the primary key not unique.

UltraLite tables do not have owners. The optional owner is supported as a convenience for existing SQL and for programmatically-generated SQL. UltraLite accepts but ignores owner.

Side effects

None.

Examples

Add an Eastern Sales department to the database.

INSERT
INTO department ( dept_id, dept_name )
VALUES ( 230, 'Eastern Sales' )


ROLLBACK statement

Description

Use this statement to end a transaction and undo any changes made since the last COMMIT or ROLLBACK.

Syntax

ROLLBACK [ WORK ]

Usage

A transaction is the logical unit of work done on one database connection to a database between COMMIT or ROLLBACK statements. The ROLLBACK statement ends the current transaction and undoes all changes made to the database since the previous COMMIT or ROLLBACK.


SELECT statement

Description

Use this statement to retrieve information from the database.

Syntax

SELECT [ DISTINCT ] [ FIRST | TOP n ] select-list
[ FROM table-expression ]
[ WHERE search-condition ]
[ GROUP BY group-by-expression,...group-by-expression ]
[ HAVING search-condition ]
[ ORDER BY order-by-expression,...order-by-expression ]
[ OPTION ( FORCE ORDER ) ]

table-expression :
[ owner.]table-name [ [ AS ] correlation-name ]
| table-expression { join-operator table-expression
[ ON join-condition ] ,... }
| ( table-expression, ... )
| ( select-statement ) [ AS ] derived-table-name ( [ column-name, ... ] column-name )

join-operator :
, (ON condition not allowed)
| CROSS JOIN (ON condition not allowed)
| INNER JOIN
| JOIN (ON phrase required)
| LEFT OUTER JOIN

order-by-expression :
{ integer | expression } [ ASC | DESC ]

Parameters

DISTINCT If you do not specify DISTINCT, all rows that satisfy the clauses of the SELECT statement. If DISTINCT is specified, duplicate output rows are eliminated. Many statements take significantly longer to execute when DISTINCT is specified, so you should reserve DISTINCT for cases where it is necessary.

FIRST or TOP You can explicitly retrieve only the first row of a query or the first n rows of a query. These keywords are principally for use with ORDER BY queries.

select-list The select-list is a list of expressions, separated by commas, specifying what will be retrieved from the database. An asterisk (*) means select all columns of all tables in the FROM clause. Subqueries are not allowed in the select-list.

An alias name can be specified following an expression in the select-list to represent that expression. The alias name can then be used elsewhere in the query, such as in the WHERE clause or ORDER BY clause.

FROM clause Rows are retrieved from the tables and views specified in the table-expression. The table-expression is built from base tables and subqueries, as listed in the syntax above.

For information on expressions, see Dynamic SQL expressions.

ON condition The ON condition is specified for a single join operation and indicates how the join is to create rows in the result set. A WHERE clause is used to restrict the rows in the result set, after potential rows have been created by a join. For INNER joins restricting with an ON or WHERE is equivalent. For OUTER joins, they are not equivalent.

WHERE clause This clause limits the rows that are selected from the tables named in the FROM clause. It can be used to restrict rows between multiple tables.

Although both the ON phrase (which is part of the FROM clause) and the WHERE clause restrict the rows in the result set, they differ in that the WHERE clause is applied at a later stage of query execution. The ON phrase is part of the join operation between tables, while the WHERE clause is applied after the join is complete. In some queries, a condition can be specified in a WHERE clause or in the ON phrase with the same net result, but in other cases the results differ. For example, for outer joins, a condition specified in a WHERE clause gives different results from the same condition specified in the ON phrase.

The search-condition is built from expressions, including subqueries. For more information, see Dynamic SQL search conditions.

GROUP BY clause You can group by columns, alias names, or functions. The result of the query contains one row for each distinct set of values in the named columns, aliases, or functions. All NULL-containing rows are treated as a single set. The resulting rows are often referred to as groups since there is one row in the result for each group of rows from the table list. Aggregate functions can then be applied to these groups to get meaningful results.

A group-by-expr is a (non-aggregate) expression written exactly the same as one of the expressions in the select-list.

When GROUP BY is used, the select-list and ORDER BY expressions must not reference any identifier that is not named in the GROUP BY clause. The exception is that the select-list may contain aggregate functions.

HAVING clause This clause selects rows based on the group values and not on the individual row values. The HAVING clause can only be used if either the statement has a GROUP BY clause or the select list consists solely of aggregate functions. Any column names referenced in the HAVING clause must either be in the GROUP BY clause or be used as a parameter to an aggregate function in the HAVING clause.

ORDER BY clause This clause sorts the results of a query. Each item in the ORDER BY list can be labeled as ASC for ascending order (the default) or DESC for descending order. If the expression is an integer n, then the query results will be sorted by the nth item in the select list.

The only way to ensure that rows are returned in a particular order is to use ORDER BY. In the absence of an ORDER BY clause, UltraLite returns rows in whatever order is most efficient. This means that the appearance of result sets may vary depending on when you last accessed the row and other factors.

OPTION ( FORCE ORDER ) clause This clause is not recommended for general use. It overrides UltraLite's choice of the order in which to access tables, and require that UltraLite access the tables in the order they appear in the query. In general, it is best to let UltraLite decide on the table access order.

For more information, see Query optimization.

Usage

The SELECT statement is used for retrieving results from the database.

UltraLite tables do not have owners. The optional owner is supported as a convenience for existing SQL and for programmatically-generated SQL. UltraLite accepts but ignores owner.

See also

SELECT statement

Example

How many employees are there?

SELECT count(*)
FROM employee


UPDATE statement

Description

Use this statement to modify existing rows in database tables.

Syntax

UPDATE [ owner.]table-name
SET column-name = expression
[ WHERE search-condition ]

Parameters

table-name The table-name specifies the name of the table to be updated. Only a single table is allowed.

SET clause Each named column is set to the value of the expression on the right hand side of the equal sign. There are no restrictions on the expression. If the expression is a column-name, the old value is used.

Only columns specified in the SET clause have their values changed. In particular, you cannot use UPDATE to set a column's value to its default.

WHERE clause If a WHERE clause is specified, only rows satisfying search-condition are updated. For information about search conditions, see Dynamic SQL search conditions.

Caution If no WHERE clause is specified, every row in the table is updated.

Case sensitivity Character strings inserted into tables are always stored in the same case as they are entered, regardless of whether the database is case sensitive or not. A CHAR data type column updated with a string Value is always held in the database with an upper case V and the remainder of the letters lower case. SELECT statements return the string as Value. If the database is not case sensitive, however, all comparisons make Value the same as value, VALUE, and so on. Further, if a single-column primary key already contains an entry Value, an INSERT of value is rejected, as it would make the primary key not unique.

Usage

The UPDATE statement modifies values in a table.

UltraLite tables do not have owners. The optional owner is supported as a convenience for existing SQL and for programmatically-generated SQL. UltraLite accepts but ignores owner.

Side effects

None.

See also
  • INSERT statement
  • DELETE statement
Example

Transfer employee Philip Chin (employee 129) from the sales department to the marketing department.

UPDATE employee
SET dept_id = 400
WHERE emp_id = 129


Query optimization

There are many different ways for UltraLite to execute any query. Each distinct way of executing a query is called a plan. In UltraLite a plan is defined mainly by the order in which tables are accessed and by whether each table is searched using an index or by scanning the rows directly. For some queries, there can be an orders of magnitude difference in execution times between efficient and inefficient plans.

UltraLite includes a query optimizer: an internal component of the UltraLite runtime that inspects alternative plans and attempts to select an efficient one. The primary goal of optimization in UltraLite is to choose indexes so that data can be accessed in an efficient order. The optimizer attempts to avoid the use of temporary tables to store intermediate results and attempts to ensure that only the pertinent subset of a table is accessed when a query joins two tables.

UltraLite optimizes queries automatically. The main area in which you can tune execution time is by creating indexes in your database that UltraLite can exploit as it optimizes queries.

Inspecting query plans

As a development aid, you can use the UltraLite Interactive SQL to display the plan that summarizes how a prepared statement is to be executed. The plan is displayed on a tab in the bottom pane of the utility. You can choose whether to display a plan graphically or in a text format.

For example, the statement

SELECT I.inv_no, I.name, T.quantity, T.prod_no
FROM Invoice I, Transactions T
WHERE I.inv_no = T.inv_no

might produce the following plan:

join[scan(Invoice,0),index-scan(Transactions,1)]

The plan indicates that the join operation is accomplished by reading all rows from the Invoice table (following index[0]) and then using the index[1] from the Transaction table to read only the row whose inv_no column matches.

For more information about UltraLite Interactive SQL, see The UltraLite Interactive SQL utility.

Overriding the optimizer

To be usable on small devices, query optimization in UltraLite is not as extensive as that carried out in Adaptive Server Anywhere. You can override the table order it selects by adding the OPTION (FORCE ORDER) clause to a query, which forces UltraLite to access the tables in the order they appear in the query. This option is not recommended for general use. If performance is slow, a better approach is usually to create appropriate indexes to speed up execution.


Developing Applications for the Palm OS

About this chapter

This chapter describes general issues when developing applications for the Palm OS.


Choosing database storage on the Palm OS

On the Palm OS, it is important to distinguish between UltraLite databases and the Palm data store, which is sometimes called the Palm database. In this documentation, the term PDB means a Palm database and database refers to an UltraLite relational database. In addition to the Palm data store, Palm OS version 4.0 and later also support a virtual file system (VFS) on expansion cards.

Palm data store or virtual file system

UltraLite databases can be stored either in the Palm data store on the virtual file system on expansion cards. The way of specifying the storage depends on the interface used:

  • UltraLite for MobileVB To use the virtual file system, set the VFS On Palm parameter. See VFS On Palm parameter .

  • UltraLite C++ component, static C++ API, embedded SQL Call ULEnablePalmRecordDB or ULEnableFileDB at the beginning of your application. See ULEnablePalmRecordDB function and ULEnableFileDB function.

Storage details

When using the Palm data store, UltraLite actually stores database information in multiple PDBs, whose names are constructed using the given creator ID. For example, a database created with a creator ID of ABCD causes the following files to be created:

  • ul_state_ABCD

  • ul_udb_ABCD

UltraLite uses the state PDB (ul_state_ABCD) to hold the current row on which the application is positioned for any open tables when the application exits. The state PDB allows UltraLite allows you to write your application so that when it is launched, users can resume where they left off.


Understanding the Palm Creator ID

UltraLite applications for the Palm OS, like all Palm OS applications, require a creator ID. You assign this creator ID to your application at development time and, if you are using HotSync synchronization, you register the creator ID with HotSync manager for use by the MobiLink synchronization.

For information about assigning creator IDs to applications, see your development tool documentation. For information about registering creator IDs with HotSync manager, see Registering the MobiLink HotSync conduit to HotSync Manager.

UltraLite uses the creator ID to manage databases and HotSync synchronization. In many scenarios, you do not need to know the details of how UltraLite uses creator IDs. However, if you create an application that connects to more than one UltraLite database and that uses HotSync for synchronization, you do need to know more about how UltraLite uses creator IDs. This section is provided for those users.

Palm OS uses a creator ID to associate related PDBs and applications. For example, the CustDB sample application has the creator ID Syb1. The MobiLink conduit uses this Syb1 creator ID to find the associated UltraLite database on the device.

The creator ID is a string from one to four characters long. The first character should be an upper case letter, as Palm OS uses an initial lower-case letter for its system files.

UltraLite database names

UltraLite assigns each new database a creator ID and a PDB name based on the value of the creator ID supplied in the Database On Palm connection parameter or, if no Database On Palm connection parameter is supplied, the creator ID of your application:

  • For applications that use the record-based Palm OS store, the PDB name is ul_udb_creator-id.

  • For applications that use the virtual file system, the name of the file is ul_udb_creator-id.udb.

For more information, see Database On Palm connection parameter.

HotSync and creator IDs

The use of creator IDs to identify both applications and their related databases can cause problems if your application connects to multiple databases.

During HotSync synchronization, HotSync Manager checks the creator ID of each application. It passes those creator IDs registered by the MobiLink conduit to the conduit for synchronization. The conduit looks for a database named ul_udb_creator-id, where creator-id is the name supplied to it by HotSync manager.

If your application connects to two databases, at least one must have a different creator ID from the application. Because the database and application creator IDs do not match, HotSync Manager does not find an application associated with the database, which is therefore not included in the synchronization.

To work around this limitation, and to use HotSync for several UltraLite applications on the Palm OS, write a dummy Palm application for each creator ID. The dummy Palm application does not need to carry out any actions at all; it simply has to have a creator ID that HotSync can hand to the MobiLink conduit for synchronization, and which the MobiLink conduit can map to your UltraLite database creator ID. With this approach, the MobiLink HotSync conduit can identify multiple copies of UltraLite databases and synchronize them.


Using UltraLite Static Interfaces

About this chapter

This chapter presents an overview of the UltraLite static programming interfaces.

When using static interfaces, the SQL statements to be used in an application must be specified at compile time. In a dynamic model, SQL statements can be specified at run time. The static interfaces are embedded SQL, the Static C++ API, and the Static Java API which uses JDBC. This chapter describes aspects common to all static UltraLite interfaces.

Overview
Choosing an UltraLite static interface
Preparing a reference database
Defining SQL statements for your application
Generating the UltraLite data access code
Configuring development tools for static UltraLite development


Web Links Browse Collapse Expand PDF Previous Next

UltraLite Database User's Guide

Using UltraLite Static Interfaces

Overview

This section describes the development environment and process for UltraLite static interfaces.


The development environment for static UltraLite applications

Developing UltraLite applications using a static interface requires the following tools.

  • A reference database A reference database is an Adaptive Server Anywhere database that serves as a model of the UltraLite database you want to create. You create this database yourself, using tools such as Sybase Central.

    Your UltraLite database is a subset of the columns, tables, and indexes, in your reference database. The arrangement of tables and of the foreign key relationships between them is called the database schema.

    In addition to modeling the UltraLite database, you need to add the SQL statements that are to be included in your UltraLite application to the reference database.

    For more information, see Preparing a reference database.

  • A supported development tool You use a standard development tool to develop UltraLite applications. For the non-UltraLite specific portions of your application, such as the user interface, use your development tool in the usual way. For the UltraLite-specific data-access portions, you also need to use the UltraLite development tools.

    It can be convenient to separate the data access code from the user interface and internal logic of your application.

    For information about supported application development tools, see UltraLite development platforms.

  • UltraLite development tools UltraLite includes several tools for development using the static interfaces.

    • The UltraLite generator This application generates source code that implements the underlying query execution, data storage, and synchronization features of your application. The generator is required for all kinds of UltraLite development using static SQL.

    • The SQL preprocessor This application is needed only if you are developing an UltraLite application using embedded SQL. It reads your embedded SQL source files and generates standard C/C++ files. As it scans the embedded SQL source files, it also stores information in the reference database that is used by the generator.

  • UltraLite runtime libraries UltraLite includes a runtime library for each target platform. On some platforms, this is a static library that becomes part of your application executable; on other platforms it is a dynamic link library. For Java, the runtime library is a jar file. UltraLite includes all the header files and import files needed to use the runtime libraries.


The static interface UltraLite development process

The basic features of the development process are common to all static interfaces. The following diagram summarizes the key features.

The static interface UltraLite development process.

  • Create a reference database, which contains a superset of the tables to be included in your application. It may also contain representative data for your application. This reference database is needed only as part of the development process, and is not required by your final application.

  • Add the SQL statements into a special table in the reference database. The way this is accomplished is dependent on the interface you choose:

    • If you are using the Static C++ API or Java, these statements are added to your database using Sybase Central or a stored procedure.

    • If you are using embedded SQL, the SQL preprocessor adds the statements to the reference database for you.

  • Run the UltraLite generator, which produces source files that include code needed to execute your SQL statements, and code needed to define the database schema for your UltraLite application. This generated code includes function calls into the UltraLite runtime library.

  • Create application source files. If you are using embedded SQL, the SQL preprocessor reads your .sqc files and inserts the SQL statements into the reference database for you.

  • Compile your application source files together with the generated source files to produce your UltraLite application.


Adding synchronization

Most UltraLite applications include synchronization to integrate their data with data on a consolidated database.

For more information about synchronization, and the kinds of synchronization available, see UltraLite Clients.


Choosing an UltraLite static interface

There are three static interfaces for developing UltraLite applications:

  • Static C++ API Development using C or C++ with data access features using a result-set based API.

  • Embedded SQL Development using C or C++ with data access features using embedded SQL statements.

  • Static Java API Development using the Java programming language.

The decision whether to use Java or C/C++ development will be determined primarily by your target platform.

Here are some considerations when choosing between embedded SQL and the Static C++ API:

  • Embedded SQL is an industry standard programming method, while the Static C++ API is a proprietary API.

  • Embedded SQL gives more control in designing your application. If you are experienced with embedded SQL development, you can design a more efficient application using this method.

  • Many programmers are more familiar with API-based programming. The Static C++ API requires less learning for these developers.

  • The Static C++ API generates classes and associated methods for manipulating the database. It enforces standardized function names and so can be a quicker approach in terms of development time.


Preparing a reference database

To implement the UltraLite database engine for your application, the UltraLite generator must have access to an Adaptive Server Anywhere reference database. This database must contain the following information:

  • Database schema The database objects used in your UltraLite application, including tables and any indexes on those tables you wish to use in your application.

    For more information, see Using an existing database as a reference database.

  • Data (Optional) You can fill your reference database with data that is similar in quantity and distribution to the data you expect your UltraLite database to hold. The UltraLite analyzer automatically uses this information to optimize the performance of your application.

    For more information, see Using an existing database as a reference database.

  • Queries The UltraLite system tables must contain any SQL statements you wish to use in your application.

    For more information, see Defining SQL statements for your application.

  • Publications If you wish to add multiple synchronization options to your application, you can do so using publications. You also add publications to your database if you wish to develop a C++ API application without defining queries.

    For information on multiple synchronization options, see Designing sets of data to synchronize separately.

  • Database options Database options such as date formats and govern some aspects of database behavior that can make applications behave differently. The UltraLite database is generated with the same option settings as those in the reference database.

    For many purposes, you can leave all database options at their default settings.

    For more information, see Setting database options in the reference database.

Creating a reference database
Setting database options in the reference database
Using an existing database as a reference database
Optimizing query execution


Creating a reference database

The analyzer uses the reference database as a template when constructing your UltraLite application.

toggle To create a reference database

  1. Start with an existing Adaptive Server Anywhere database or create a new database using the dbinit command.

    For more information on upgrading a database, see Using an existing database as a reference database.

  2. Add the tables and foreign key relationships that you need within your application. You can use any convenient tool, such as Sybase Central or Sybase PowerDesigner Physical Architect (included with SQL Anywhere Studio), or a more powerful database design tool such as the complete Sybase PowerDesigner package.

Performance tip
You do not need to include any data in your reference database. However, if you populate your database tables with data representative of the data you expect to be stored by a typical user of your application, the UltraLite analyzer automatically uses this data to optimize the performance of your application.

For information about designing a database and creating a schema, see Designing Your Database.

Example

  1. Create a database.

    From a command prompt, execute the following statement:

    dbinit path\dbname.db

  2. Use Sybase Central to add tables for your UltraLite application, based on your own needs.

  3. Add your sample data. Interactive SQL includes an Import menu item that allows several common file formats to be imported.

    For more information, see Importing and Exporting Data.


Setting database options in the reference database

UltraLite does not support the getting or setting of option values.

When the UltraLite application is generated, certain option values in the reference database affect the behavior of the generated code. The following options have an effect:

  • Date_format

  • Date_order

  • Nearest_century

  • Precision

  • Scale

  • Time_format

  • Timestamp_format

By setting these options in the reference database, you can control the behavior of your UltraLite database. The option setting in your reference database is used when generating your UltraLite application.


Using an existing database as a reference database

Many UltraLite applications synchronize data via MobiLink with a central, master store of data called the consolidated database. Do not confuse a reference database with a consolidated database. The reference database for the UltraLite application is generally a different database from the consolidated database.

Only an Adaptive Server Anywhere consolidated database can also be used as a reference database. If your consolidated database is of another type, you must create an Adaptive Server Anywhere reference database. Even if your consolidated database is Adaptive Server Anywhere, you must create a separate reference database if you wish to have a different schema or use different settings in your UltraLite application.

You can choose any of the supported ODBC-compliant database management products to create and manage the consolidated database, including Adaptive Server Enterprise, Adaptive Server Anywhere, Oracle, Microsoft SQL Server, and IBM DB2.

If you have an existing Adaptive Server Anywhere database that you will be using as a consolidated database, you could make a copy of it for your reference database.

toggle To create a reference database from a non-Adaptive Server Anywhere database

  1. Create a new Adaptive Server Anywhere database.

    You can use the dbinit command or use Sybase Central.

  2. Add the tables and foreign-key relationships that you need within your application using your consolidated database as a guide.

    You can use a tool such as Sybase Physical Data Architect to re-engineer the consolidated database.

  3. Populate your database tables with representative data from your consolidated database.

    You need not transfer all the information in your consolidated database, only a representative sample. In the early stages of development, you do not need sample data at all. For production applications, you may want to use representative data because access plans of UltraLite queries are based on the distribution of data in the reference database.

For more information on creating reference databases from non-Adaptive Server Anywhere databases, see Migrating databases to Adaptive Server Anywhere.


Optimizing query execution

You can improve the performance of your static UltraLite applications using the following techniques.

  • add an index If you frequently retrieve information in a particular order, consider adding an index to your reference database. Primary keys are automatically indexed, but other columns are not. Particularly on slow devices, an index can improve performance dramatically.

  • add representative data The Adaptive Server Anywhere optimizer automatically optimizes the performance of your queries. It chooses access plans using the information present in your reference database. To improve application performance, fill your reference database with data that is representative in size and distribution of the data you expect your application will hold once it is deployed.


Defining SQL statements for your application

All the data access instructions for your application are defined by adding SQL statements to the reference database.

If you use the Static C++ API, you can also use publications to define data access methods. For information on using publications, see Defining UltraLite tables.

If you are using embedded SQL, the SQL preprocessor carries out the tasks in this section for you.


Creating an UltraLite project

When you add SQL statements to a reference database, you assign them to an UltraLite project. By grouping them this way, you can develop multiple applications using the same reference database.

When the UltraLite generator runs against a reference database to generate the database source code files, it takes a project name as an argument and generates the code for the SQL statements in that project.

You can define an UltraLite project using Sybase Central or by directly calling a system stored procedure.

If you are using embedded SQL, the SQL preprocessor defines the UltraLite project for you and you do not need to create it explicitly.

toggle To create an UltraLite project (Sybase Central)

  1. In Sybase Central, connect to your database if you are not already connected.

  2. In the left pane, open the database container.

  3. In the left pane, open the UltraLite Projects folder.

  4. From the File menu, choose New > UltraLite Project.

    The UltraLite Project Creation wizard appears.

  5. Enter an UltraLite project name and click Finish to create the project in the database.

    For information on UltraLite project naming rules, see ul_add_project system procedure.

toggle To create an UltraLite project (SQL)

  • From Interactive SQL or another application, enter the following command:

    call ul_add_project( 'project-name' )

    where project-name is the name of the project.

    For more information, see ul_add_project system procedure.

toggle To create an UltraLite project (embedded SQL)

  • If you are using the embedded SQL interface, specify the UltraLite project name on the SQL Preprocessor command line, and the preprocessor adds the project to the database for you.

    For more information, see Building embedded SQL applications.

Notes

UltraLite project names must conform to the rules for database identifiers. If you include spaces in the project name, do not enclose the name in double quotes, as these are added for you by Sybase Central or the stored procedure.

For more information, see Identifiers.


Adding SQL statements to an UltraLite project

Each UltraLite application carries out a set of data access requests. These requests are implemented differently in each interface, but the data access requests are defined in the same way for each model.

You define the data access requests that an UltraLite application can carry out by adding a set of SQL statements to the UltraLite project for that application in your reference database. The UltraLite generator then creates the code for a database engine that can execute the set of SQL statements.

In the Static C++ API, you can also use publications to define data access methods. For information on using publications, see Defining UltraLite tables.

You can add SQL statements to an UltraLite project using Sybase Central, or by directly calling a system stored procedure. If you are using embedded SQL, the SQL preprocessor adds the SQL statements in your embedded SQL source files to the reference database for you.

toggle To add a SQL statement to an UltraLite project (Sybase Central)

  1. In Sybase Central, connect to your database if you are not already connected.

  2. In the left pane, open the database container.

  3. In the left pane, open the UltraLite Projects folder.

  4. Open the project for your application.

  5. From the File menu, choose New > UltraLite statement.

    The UltraLite Statement Creation wizard appears.

  6. Enter a short, descriptive name for the statement, and click Next

  7. Enter the statement itself, and click Finish to add the statement to the project.

    You can test the SQL statements against the database by right-clicking the statement and choosing Execute From Interactive SQL from the popup menu.

    For information on what kinds of statement you can use, see Writing UltraLite SQL statements.

toggle To add a SQL statement to an UltraLite project (SQL)

  • From Interactive SQL or another application, enter the following command:

    call ul_add_statement( 'project-name',
   'statement-name',
   'sql-statement' )

    where project-name is the name of the project, statement-name is a short descriptive name, and sql-statement is the actual SQL statement.

    For more information, see ul_add_statement system procedure.

toggle To add a SQL statement to an UltraLite project (embedded SQL)

  • If you are using the embedded SQL interface, specify the UltraLite project name on the SQL Preprocessor command line.

    No statement name is used in embedded SQL development.

    For more information, see Building embedded SQL applications.

Notes

Statement names should be short and descriptive. They are used by the UltraLite generator to identify the statement for use in Java or in the C++ API. For example, a statement named ProductQuery generates a C++ API class named ProductQuery and a Java constant named PRODUCT_QUERY. Names should be valid SQL identifiers.

The SQL statement syntax is checked when you add the statement to the database, and syntax errors give an error message to help you identify mistakes.

You can use Sybase Central or ul_add_statement to update a statement in a project, in just the same way as you add a statement. If a statement already exists, it is overwritten with the new syntax. You must regenerate the UltraLite code whenever you modify a statement.


Writing UltraLite SQL statements

This section describes what SQL statements you can add to an UltraLite project, and describes how to use placeholders in your SQL statements.

For information on the range of SQL that you can use, see Overview of SQL support in UltraLite.

How to supply double quotes

The SQL statement that you enter, whether into Sybase Central or as an argument to ul_add_statement, is added to the reference database as a string. It must therefore conform to the rules for SQL strings.

You must escape some characters in your SQL statements using the backslash character.

For information on SQL strings, see Strings.

Using variables with statements

For most insert or update statements, you do not know the new values ahead of time. You can use question marks as placeholders for variables, and supply values at run time:

call ul_add_statement(
   'ProductApp',
   'AddCap',
   'INSERT INTO \"DBA\".product ( id, name, price )
      VALUES( ?, ?, ? )'
)

Placeholders can also be used in the WHERE clause of queries:

call ul_add_statement(
   'ProductApp',
   'ProductQuery',
   'SELECT id, name, price
    FROM \"DBA\".product
    WHERE price > ?'
)

The backslash characters are used to escape the double quotes.

In embedded SQL, you use host variables as placeholders. For more information, see Using host variables.

For SQL statements containing placeholders, an extra parameter on the Open or Execute method of the generated C++ class is defined for each parameter. For Java applications, you use the JDBC set methods to assign values for the parameters.


Generating the UltraLite data access code

To generate the code for storing and accessing the UltraLite database, the UltraLite generator analyzes your reference database and the SQL statements you use in your application. The UltraLite generator is a command-line application. It takes a set of command-line options to customize the behavior for each project. For example, it can generate either C/C++ or Java code, depending on the command-line options you supply.

The data storage code includes only those tables and columns of the reference database that you use in your application. Additionally, the UltraLite generator includes indexes present in your reference database whenever they improve the efficiency of your application.

The data access code includes only those SQL statements that you have added to the project in the reference database.

The result is a custom database engine tailored to your application. The engine is much smaller than a general-purpose database engine because the UltraLite generator includes only the features your application uses.

For more information about the UltraLite generator, see The UltraLite Generator.


Configuring development tools for static UltraLite development

Most development tools use a dependency model, sometimes expressed as a makefile, in which the timestamp on each source file is compared with that on the target file (object file, in most cases) to decide whether the target file needs to be regenerated.

With UltraLite development, a change to any SQL statement in a development project means that the generated code needs to be regenerated. Changes are not reflected in the timestamp on any individual source file because the SQL statements are stored in the reference database.

For specific instructions on adding UltraLite projects to a dependency-based development environment, see Configuring development tools for embedded SQL development.


UltraLite Static Interfaces Reference

About this chapter

This chapter provides reference information about for the Ultralite static interfaces: embedded SQL, the Static C++ API, and the Static Java API.

Reference database stored procedures


Reference database stored procedures

This section describes system stored procedures in the Adaptive Server Anywhere reference database, which can be used to add SQL statements to a project.

For each SQL statement added in this way, the UltraLite generator defines a C++ or Java class.

These system procedures are owned by the built-in user ID dbo.

ul_add_statement system procedure
ul_add_project system procedure
ul_delete_project system procedure
ul_delete_statement system procedure
ul_set_codesegment system procedure


ul_add_statement system procedure

Function

Adds a SQL statement to an UltraLite project.

Syntax

ul_add_statement (in @project char(128),
in @name char(128),
in @statement text )

Permissions

DBA authority required

Side effects

None

See also

ul_add_project system procedure

ul_delete_statement system procedure

Description

Adds or modifies a statement to an UltraLite project.

project The UltraLite project to which the statement should be added. The UltraLite generator defines classes for all statements in a project at one time.

name The name of the statement. This name is used in the generated classes.

statement A string containing the SQL statement.

If a statement of the same name in the same project exists, it is updated with the new syntax. If project does not exist, it is created.

Examples

The following call adds a statement to the TestSQL project:

call ul_add_statement(
'TestSQL', 'TestQuery',
'select prod_id, price, prod_name from ulproduct where price < ?' )


ul_add_project system procedure

Function

Creates an UltraLite project.

Syntax

ul_add_project (in @project char(128) )

Permissions

DBA authority required

Side effects

None

See also

ul_delete_statement system procedure

Description

Adds an UltraLite project to the database. The project acts as a container for the SQL statements in an application, and the project name is supplied on the UltraLite generator command line so that it can define classes for all statements in the project.

project The UltraLite project name.

Examples

The following call adds a project named Product to the database:

call ul_add_project( 'Product' )


ul_delete_project system procedure

Function

Removes an UltraLite project from a database.

Syntax

ul_delete_project (in @project char(128) )

Permissions

DBA authority required

Side effects

None

See also

ul_add_project system procedure

ul_delete_statement system procedure

Description

Removes an UltraLite project from the database.

project The UltraLite project to be deleted from the database.

Examples

The following call deletes the Product project:

call ul_delete_project( 'Product' )


ul_delete_statement system procedure

Function

Removes a SQL statement from an UltraLite project.

Syntax

ul_delete_statement (in @project char(128),
in @name char(128) )

Permissions

DBA authority required

Side effects

None

See also

ul_add_project system procedure

ul_add_statement system procedure

Description

Removes a statement from an UltraLite project.

project The UltraLite project from which the statement should be removed.

name The name of the statement. This name is used in the generated classes.

Examples

The following call removes a statement from the Product project:

call ul_delete_statement( 'Product', 'AddProd' )


ul_set_codesegment system procedure

Function

For Palm Computing Platform development using the C++ API, assigns a SQL statement from an UltraLite project to a particular segment.

Syntax

ul_set_codesegment(in @project char(128),
in @name char(128), in @segment_name char(8) )

Side effects

None

See also

ul_add_statement system procedure

Explicitly assigning segments

Description

Explicitly assigns the generated code for a C++ API SQL statement to a named Palm segment.

project The UltraLite project to which the statement applies.

name The name of the statement as defined in ul_add_statement system procedure..

segment_name The name of the segment to which the statement is assigned.

Examples

The following call assigns the statement mystmt in project myproject to segment MYSEG1.

call ul_set_codesegment(
     'myproject', 'mystmt', 'MYSEG1' )


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for MobileVB User's Guide

Version 9.0.2

DC36292-01-0902-01

October 2004

Copyright
About This Manual
Introduction to UltraLite for MobileVB
Understanding UltraLite for MobileVB Development
Tutorial: A Sample UltraLite for MobileVB Application
Tutorial: A Sample Application for AppForge Crossfire
UltraLite for MobileVB API Reference


About This Manual

Subject

This manual describes UltraLite for MobileVB. With UltraLite for MobileVB you can develop and deploy database applications to handheld, mobile, or embedded devices, running Palm OS or Windows CE.

Audience

This manual is intended for AppForge MobileVB and AppForge Crossfire application developers who wish to take advantage of the performance, resource efficiency, robustness, and security of an UltraLite relational database for data storage and synchronization.


Introduction to UltraLite for MobileVB

About this chapter

This chapter introduces UltraLite for MobileVB. It assumes that you are familiar with the features of UltraLite, as described in Welcome to UltraLite.


UltraLite for MobileVB features

UltraLite for MobileVB is a relational data management system for mobile devices. It has the performance, resource efficiency, robustness, and security required by business applications. UltraLite also provides synchronization with enterprise data stores.

System requirements and supported platforms


System requirements and supported platforms

Development platforms

To develop applications using UltraLite for MobileVB, you require the following:

  • Microsoft Visual Basic .NET or Visual Basic 6.

    You must install a service pack that meets the requirements for the version of AppForge MobileVB or AppForge Crossfire that you are using. For more information, see [external link] the AppForge web site. If you are using Visual Basic 6, it is recommended that you install at least service pack 5.

    AppForge Booster
    To deploy applications using UltraLite for MobileVB you need the AppForge Booster. If you are missing the AppForge Booster, you can get it from [external link] www.appforge.com/booster.html. BoosterPlus is not needed for UltraLite applications.

  • AppForge MobileVB Version 3.x or later, or AppForge Crossfire.

    Compatibility
    If you are using versions of MobileVB earlier than 3.0 and are developing for Windows CE on an ARM device, you must copy ultralite\UltraLiteForMobileVB\ce\arm\ulmvb9.dll under your SQL Anywhere directory to the \Program Files\AppForge directory on your device.

For more information, see UltraLite development platforms.

Target platforms

UltraLite for MobileVB supports the following target platforms:

  • Windows CE 3.0 and higher, with Pocket PC on the ARM and MIPS processors.

  • Palm OS version 3.5 and higher.

For more information, see UltraLite target platforms.


UltraLite for MobileVB architecture

The UltraLite programming interface exposes a set of objects for data manipulation using an UltraLite database. The following figure describes the object hierarchy.

The UltraLite for MobileVB object hierarchy

The following list describes some of the more commonly-used high level objects.

  • ULDatabaseManager manages connections to UltraLite databases.

    For more information, see ULDatabaseManager class.

  • ULConnectionParms holds a set of connection parameters.

    You can use a Connection Parameters control and specify connection parameters in a Visual Basic property sheet.

    For more information, see ULConnectionParms class.

  • ULConnection represents a database connection, and governs transactions.

    For more information, see ULConnection class.

  • ULPreparedStatement, ULResultSet, and ULResultSetSchema manage database requests and their results using SQL.

    For more information, see ULPreparedStatement class, ULResultSet class, and ULResultSetSchema class.

  • ULTable and ULColumn manage data using a table-based API.

    For more information, see ULTable class and ULColumn class.

  • ULSyncParms and ULSyncResult manage synchronization through the MobiLink synchronization server.

    For more information about synchronization with MobiLink, see UltraLite Clients.


Understanding UltraLite for MobileVB Development

About this chapter

This chapter explains how to develop applications using UltraLite for MobileVB.

For a hands-on tutorial, see Tutorial: A Sample UltraLite for MobileVB Application.

Preparing to use UltraLite for MobileVB
Working with the database schema
Connecting to an UltraLite database
Encryption and obfuscation
Working with data using dynamic SQL
Working with data using the table API
Accessing schema information
Handling errors
Authenticating users
Synchronizing data
Deploying UltraLite applications
Maintaining state in UltraLite Palm applications


Preparing to use UltraLite for MobileVB

The following procedures describe the steps you must take before you can build an application using UltraLite for MobileVB.


Adding UltraLite to the MobileVB design environment

To access the UltraLite control from your MobileVB or Crossfire project, you must add UltraLite for MobileVB to the design environment.

toggle To add the UltraLite connection parameters control

  1. From the Visual Basic menu, choose Project > Components.

  2. Click the Controls tab.

  3. Scroll down the list to select UltraLite Connection Parameters 9.0. Click OK.

    If this item does not appear in the list of available controls, complete the following steps:

    • Close MobileVB and save your project.

    • Open a command prompt at ultralite\UltraLiteforMobileVB\win32 and run the following command:

      ulmvbreg -r

    • Restart MobileVB and open your project.

    • Choose Project > Components.

    • Select UltraLite Connection Parameters 9.0.

    A database icon is added to your toolbar. To add a ULConnectionParms object to your form you double-click this icon.

Adding a reference to UltraLite for MobileVB

Once SQL Anywhere Studio is installed, UltraLite for MobileVB is automatically added to any new MobileVB project. It is therefore not usually necessary to manually add a reference to UltraLite for MobileVB to a project. The following procedure is provided for occasional situations where you may need to add a reference manually, such as if you install MobileVB after installing SQL Anywhere Studio.

toggle To add a reference to UltraLite for MobileVB

  1. From the Visual Basic menu, choose Project > References.

  2. If iAnywhere Solutions, UltraLite for MobileVB 9.0 is included in the list of available references, select it and click OK.

    If iAnywhere Solutions, UltraLite for MobileVB 9.0 does not appear in the list of available references:

    • Open a command prompt at ultralite\UltraLiteforMobileVB\win32 and run the following command:

      ulmvbreg -r

    • Select iAnywhere Solutions, UltraLite for MobileVB 9.0 and click OK.


Adding UltraLite to the Crossfire design environment

Although the SQL Anywhere Studio Setup program automatically adds UltraLite to your Crossfire design environment, there are cases where you may have to add UltraLite to the environment manually. For example, if you install Crossfire after you install SQL Anywhere Studio, you may need to carry out this procedure.

To find out if you need to add UltraLite to Crossfire, check that a new Crossfire project includes a reference to iAnywhere.UltraLiteForAppForge. If it does not, you need to add UltraLite to the environment. Also, check if the ULConnectionParms class appears in the AppForge panel of the toolbox. If it does not, you need to add UltraLite to the environment.

toggle To add UltraLite references and controls to your Crossfire project

  1. Register UltraLite for MobileVB with Crossfire.

    1. Ensure that Crossfire is closed.

    2. Open a command prompt at the ultralite\UltraLiteforMobileVB\win32 subdirectory of your SQL Anywhere installation and run the following command:

      ulmvbreg -r

    3. If you have upgraded a MobileVB project remove the reference to UltraLiteAFLib from the Visual Basic.NET Solution Explorer.

    4. Add a reference to iAnywhere.UltraLiteForAppForge.dll

      1. From the Microsoft Development Environment menu, choose Project > Add Reference and browse to the ultralite\UltraLiteforMobileVB\win32 subdirectory of your SQL Anywhere installation.

      2. Select iAnywhere.UltraLiteForAppForge.dll and click Open.

      3. Choose OK to add the reference.

  2. Add the ULConnectionParms control to the AppForge toolbox.

    1. In the Microsoft Development Environment, right click the AppForge toolbox and choose Add/Remove Items. A dialog appears.

    2. Click the COM Components tab.

    3. Scroll down to the entry named ULConnectionParms Class. Check the box beside this component and click OK.

    4. The ULConnectionParms control is added to the toolbox.


Working with the database schema

The schema is the structure of a database. It is the collection of table definitions, index definitions, and publication definitions within the database, and all the relationships between them.

You create UltraLite databases by creating an UltraLite database schema file and apply that file to a database by calling a function in your application.

For information on creating UltraLite database schema files, see


Creating UltraLite database schema files

You can create an UltraLite schema file using the UltraLite Schema Painter or the ulinit utility.

  • UltraLite Schema Painter The UltraLite Schema Painter is a graphical utility for creating and editing UltraLite schema files.

    To start the Schema painter, choose Start > Programs > SQL Anywhere 9 > UltraLite > UltraLite Schema Painter, or double-click a schema (.usm) file in Windows Explorer.

    For more information about using the UltraLite Schema Painter, see Lesson 1: Create an UltraLite database schema.

  • The ulinit utility If you have the Adaptive Server Anywhere database management system, you can generate an UltraLite schema file using the ulinit command line utility.

    For more information about using the ulinit utility, see The ulinit utility.


Changing the schema of a database

To change the schema of an existing database, create a schema file with the new schema and apply this schema to the existing database. In most cases there will be no data loss, but data loss can occur if columns are deleted or if the data type for a column is changed to an incompatible type.

For more information about these methods, see ApplyFile method and ApplyFileWithParms method.

For information about preparing a new schema file for deployment, see Upgrading UltraLite database schemas.

Example

The following code applies a new schema file.

Connection.Schema.ApplyFile("schema_file=\My Documents\myschema.usm")


Connecting to an UltraLite database

UltraLite applications must connect to a database before carrying out operations on the data in it. This section describes how to connect to an UltraLite database.

Using the ULConnection object

The following properties of the ULConnection object govern global application behavior.

For more information about the ULConnection object, see ULConnection class.

  • Commit behavior By default, UltraLite applications are in AutoCommit mode. Each insert, update, or delete statement is committed to the database immediately. Set ULConnection.AutoCommit to false to build transactions into your application. Turning AutoCommit off and performing commits directly can improve the performance of your application.

    For more information, see Commit method.

  • User authentication You can change the user ID and password for the application from the default values of DBA and SQL by using the GrantConnectTo and RevokeConnectFrom methods.

    For more information, see Authenticating users.

  • Synchronization A set of objects governing synchronization are accessed from the ULConnection object.

    For more information, see Synchronizing data.

  • Tables UltraLite tables are accessed using the ULConnection.GetTable method.

    For more information, see GetTable method.

Connecting to a database

You can connect to a database using either a ULConnectionParms object or a connection string. Methods that use a ULConnectionParms object allow you to manipulate connection parameters with ease and accuracy. Methods that use a connection string require that you successfully create a connections string.

The following procedure uses a ULConnectionParms object to connect to an UltraLite database.

For more information about connecting to an UltraLite database using a ULConnectionParms object, see CreateDatabaseWithParms method and OpenConnectionWithParms method.

toggle To connect to an UltraLite database using ULConnectionParms

  1. Create a ULDatabaseManager object.

    You should create only one DatabaseManager object per application. This object is at the root of the object hierarchy. For this reason, it is often best to declare the DatabaseManager object as global to the application or as a class-level variable.

    'MobileVB
Public DatabaseMgr As ULDatabaseManager
Set DatabaseMgr = New ULDatabaseManager
    'Crossfire
Public DatabaseMgr As New UltraLiteAFLib.ULDatabaseManager

  2. Declare a ULConnection object.

    Most applications use a single connection to an UltraLite database, and keep the connection open all the time. For this reason, it is often best to declare the ULConnection object as global to the application.

    'MobileVB
Public Connection As New ULConnection
    'Crossfire
Public Connection As UltraLiteAFLib.ULDatabaseManager

  3. Create a ULConnectionParms object.

    Double-click the ULConnectionParms object on the MobileVB tool palette. A ULConnectionParms object appears on your form.

  4. Set the required properties of the ULConnectionParms object.

    In the ULConnectionParms properties window, specify properties such as the location of the database, the schema file, and a username and password for your database.

    Using the following properties, you must specify a schema file for CreateDatabaseWithParms or a database file for OpenConnectionWithParms. For information about additional properties, see Properties.

    Keyword | Description
    DatabaseOnCE | The path and filename of the UltraLite database on Windows CE.
    DatabaseOnDesktop | The path and filename of the UltraLite database on the desktop machine
    SchemaOnCE | The path and filename of the UltraLite schema on Windows CE.
    SchemaOnDesktop | The path and filename of the UltraLite schema on the desktop machine.

  5. Open a connection to the database.

    CreateDatabaseWithParms and OpenConnectionWithParms return an open connection as a ULConnection object. Each method takes a single ULConnectionParms object as its argument.

    The following code attempts to connect to an existing database. If the database does not exist, the OpenConnectionWithParms method returns an error. This causes CreateDatabaseWithParms to create a database using the specified schema file.

    In Crossfire, be sure to include the GetOcx method on the ULConnectionParms object.

    'MobileVB
On Error Resume Next
Set Connection = DatabaseMgr.OpenConnectionWithParms( LoginParms)
If Err.Number <> ULSQLCode.ulSQLE_NOERROR Then
  Set Connection = DatabaseManager.CreateDatabaseWithParms( LoginParms )
End If
    'Crossfire
Try
  Connection = _
    DatabaseMgr.OpenConnectionWithParms( _
        ULConnectionParms1.GetOcx)
Catch
  If Err.Number = _
    UltraLiteAFLib.ULSQLCode.ulSQLE_ULTRALITE_DATABASE_NOT_FOUND _
  Then
    Err.Clear()
    Connection = _
      DatabaseMgr.CreateDatabaseWithParms( _
      ULConnectionParms1.GetOcx)
End Try


Encryption and obfuscation

You can encrypt or obfuscate your UltraLite database using UltraLite for MobileVB.

Encryption

To create a database with encryption, set the ULConnectionParms.EncryptionKey property. When you call CreateDatabaseWithParms and pass in the ConnectionParms object, the database created and encrypted with the specified key.

For more information about the EncryptionKey property, see Encryption Key connection parameter and ChangeEncryptionKey method.

Example

You can change the encryption key by specifying the new encryption key on the Connection object. In this example, "apricot" is the encryption key.

Connection.ChangeEncryptionKey("apricot")

After the database is encrypted, connections to the database must specify the correct encryption key. Otherwise, the connection fails.

Obfuscation

To obfuscate the database, specify obfuscate=1 as a creation parameter.

For more information about database encryption, see Encrypting UltraLite databases.

Example

The following code obfuscates a new database.

open_parms = "ce_file=\tutorial.udb;ce_schema=\tutorial.usm;obfuscate=1"
Set Connection = DatabaseManager.CreateDatabase( open_parms )


Working with data using dynamic SQL

UltraLite applications can access table data using dynamic SQL or the Table API. This section describes data access using dynamic SQL.

For information about the Table API, see Working with data using the table API.

This section explains how to perform the following tasks using dynamic SQL.

  • Scrolling through the rows of a table.

  • Accessing the values of the current row.

  • Locating rows in a table.

  • Inserting, deleting, and updating rows.

This section does not describe the SQL language itself. For information about dynamic SQL features, see Dynamic SQL.

The sequence of operations required is similar for any SQL operation. For an overview, see Using dynamic SQL.


Data manipulation: INSERT, UPDATE and DELETE

With UltraLite, you can perform SQL Data Manipulation Language operations. These operations are performed using the ExecuteStatement method, a member of the ULPreparedStatement class.

For more information the ULPreparedStatement class, see ULPreparedStatement class.

Using parameters in your prepared statements
Placeholders for parameters are supplied using the ? character. For any INSERT, UPDATE or DELETE, each ? is referenced according to its ordinal position in the prepared statement. For example, the first ? is referred to as 1, and the second as 2.
toggle To INSERT a row

  1. Declare a ULPreparedStatement object.

    'MobileVB
Dim PrepStmt As ULPreparedStatement
    'Crossfire
Dimr PrepStmt As UltraLiteAFLib.ULPreparedStatement

  2. Assign an INSERT statement to your prepared statement object. In the following code, TableName and ColumnName are the names of a table and column.

    'MobileVB
Set PrepStmt = Connection.PrepareStatement( _
    "INSERT INTO TableName(ColumnName) VALUES ( ? )")
    'Crossfire
PrepStmt = Connection.PrepareStatement( _
    "INSERT INTO TableName(ColumnName) VALUES( ? )")

  3. Assign parameter values for the statement.

    Dim NewValue As String
NewValue = "Bob"
PrepStmt.SetStringParameter 1, NewValue

  4. Execute the statement.

    PrepStmt.ExecuteStatement
toggle To UPDATE a row

  1. Declare a ULPreparedStatement object.

    Dim PrepStmt As ULPreparedStatement

  2. Assign an UPDATE statement to your prepared statement object. In the following code, TableName and ColumnName are the names of a table and column.

    Set PrepStmt = Connection.PrepareStatement( _
    "UPDATE TableName SET ColumnName = ? WHERE ID = ?")

  3. Assign parameter values for the statement.

    Dim NewValue As String
NewValue = "Bob"
PrepStmt.SetParameter 1, NewValue
PrepStmt.SetParameter 2, "6"

  4. Execute the statement

    PrepStmt.ExecuteStatement
toggle To DELETE a row

  1. Declare a ULPreparedStatement object.

    'MobileVB
Dim PrepStmt As ULPreparedStatement
    'Crossfire
Dim PrepStmt As UltraLiteAFLib.ULPreparedStatement

  2. Assign a DELETE statement to your prepared statement object.

    'MobileVB
Set PrepStmt = Connection.PrepareStatement( _
    "DELETE FROM customer WHERE ID = ?")
    'Crossfire
PrepStmt = Connection.PrepareStatement( _
    "DELETE FROM customer WHERE ID = ?")

  3. Assign parameter values for the statement.

    Dim IDValue As String
IDValue = "6"
PrepStmt.SetParameter 1, IDValue

  4. Execute the statement.

    PrepStmt.ExecuteStatement


Data retrieval: SELECT

When you execute a SELECT statement, the ULPreparedStatement.ExecuteQuery method returns a ULResultSet object.

The ULResultSet class contains methods for navigating within a result set. The values are then accessed using methods of the ULResultSet class.

For more information about ULResultSet objects, see ULResultSet class.

Example

In the following code, the results of a SELECT query are accessed through a ULResultSet. When first assigned, the ULResultSet is positioned before the first row. The ULResultSet.MoveFirst method is then called to navigate to the first record in the result set.

For more information about navigating a result set, see Navigation with dynamic SQL.

'MobileVB
Dim MyResultSet As ULResultSet
Dim PrepStmt As ULPreparedStatement
PrepStmt = Connection.PrepareStatement( _
    "SELECT ID, Name FROM customer")
MyResultSet = PrepStmt.ExecuteQuery
MyResultSet.MoveFirst
'Crossfire
Dim MyResultSet As UltraLiteAFLib.ULResultSet
Dim PrepStmt As UltraLiteAFLib.ULPreparedStatement
PrepStmt = Connection.PrepareStatement( _
    "SELECT ID, Name FROM customer")
MyResultSet = PrepStmt.ExecuteQuery
MyResultSet.MoveFirst

UltraLite for MobileVB provides you with methods to get data of particular types from the UltraLite database into a result set. MobileVB does not support the use of Variant data types and, because of this, UltraLite for MobileVB includes functions to handle all types of data. Each of these methods is called using the following template, where Index is the ordinal position of the column name in your SELECT statement:

 MyResultSetName.MethodName( Index )
Example

The following code demonstrates how to use the GetString method to obtain the column values for the current row.

The GetString method uses the following syntax, where Index is the ordinal position of the column name in your SELECT statement.

MyResultSetName.GetString(Index)

The MoveRelative( 0 ) method is called to refresh the contents of the current buffer from the result set, so that the effects of any data modification are included.

If MyResultSet.RowCount = 0 Then
  lblID.Caption = ""
  txtName.Text = ""
Else
  lblID.Caption = MyResultSet.GetString(1)
  txtName.Text = MyResultSet.GetString(2)
      MyResultSet.MoveRelative(0)
End If

The following procedure uses a SELECT statement to retrieve information from the database. The results of the query are assigned to a ULResultSet object.

toggle To perform a SELECT statement

  1. Declare a ULPreparedStatement object.

    'MobileVB
Dim PrepStmt As ULPreparedStatement
    'Crossfire
Dim PrepStmt As UltraLiteAFLib.ULPreparedStatement

  2. Assign a prepared statement to your ULPreparedStatement object. In the following code, TableName and ColumnName are the names of a table and column.

    Set PrepStmt = Connection.PrepareStatement( _
    "SELECT ColumnName FROM TableName")

  3. Execute the query.

    In the code below, an AFListBox captures the result of the SELECT query.

    Dim MyResultSet As ULResultSet
Set MyResultSet = PrepStmt.ExecuteQuery
While MyResultSet.MoveNext
  aflistbox.AddItem MyResultSet.GetString(1)
Wend


Navigation with dynamic SQL

UltraLite for MobileVB provides you with a number of methods to navigate a result set in order to perform a wide range of navigation tasks.

The following methods of the ULResultSet object allow you to navigate your result set:

  • MoveAfterLast moves to a position after the last row.

  • MoveBeforeFirst moves to a position before the first row.

  • MoveFirst moves to the first row.

  • MoveLast moves to the last row.

  • MoveNext moves to the next row.

  • MovePrevious moves to the previous row.

  • MoveRelative moves a certain number of rows relative to the current row. Positive index values move forward in the result set, negative index values move backward in the result set, and zero does not move the cursor. Zero is useful if you want to repopulate a row buffer.

Example

The following code demonstrates how to use the MoveFirst method to navigate within a result set.

'MobileVB
Set PrepStmt = Connection.PrepareStatement( _
    "SELECT ID, Name FROM customer")
Set MyResultSet = PrepStmt.ExecuteQuery
MyResultSet.MoveFirst
'Crossfire
PrepStmt = Connection.PrepareStatement( _
    "SELECT ID, Name FROM customer")
MyResultSet = PrepStmt.ExecuteQuery
MyResultSet.MoveFirst

The same technique is used for all of the Move methods.

For more information about these navigational methods, see ULResultSet class.


ULResultSet schema property

The ULResultSet.Schema property allows you to retrieve information about the columns in the query. The properties of this ULResultSetSchema object include ColumnName, ColumnCount, ColumnPrecision, ColumnScale, ColumnSize, and ColumnSQLType.

Example

The following example shows how you can use ULResultSet.Schema to display schema information in a MobileVB grid. The example assumes you have a ULResultSet named MyResultSet and a MobileVB grid named grdSchema.

Dim i As Integer
For i = 1 To MyResultSet.Schema.ColumnCount
  grdSchema.AddItem (MyResultSet.Schema.ColumnName(i) _
  & Chr(9) & MyResultSet.Schema.ColumnSQLType(i)), 0
Next i
grdSchema.AddItem _
  ("Column Name" & Chr(9) & "Column Type"), 0


Working with data using the table API

UltraLite applications can access table data using dynamic SQL or the Table API. This section describes data access using the Table API.

For information about dynamic SQL, see Working with data using dynamic SQL.

This section explains how to perform the following tasks using the Table API.

  • Scrolling through the rows of a table.

  • Accessing the values of the current row.

  • Using find and lookup methods to locate rows in a table.

  • Inserting, deleting, and updating rows.

Navigation with the Table API
Accessing the values of the current row
Searching rows with find and lookup
Inserting, updating, and deleting rows
Working with BLOB data
Transaction processing in UltraLite


Navigation with the Table API

UltraLite for MobileVB provides you with a number of methods to navigate a table in order to perform a wide range of navigation tasks.

The following methods of the ULTable object allow you to navigate your result set:

  • MoveAfterLast moves to a position after the last row.

  • MoveBeforeFirst moves to a position before the first row.

  • MoveFirst moves to the first row.

  • MoveLast moves to the last row.

  • MoveNext moves to the next row.

  • MovePrevious moves to the previous row.

  • MoveRelative moves a certain number of rows relative to the current row. Positive index values move forward in the table, negative index values move backward in the table, and zero does not move the cursor. Zero is useful if you want to repopulate a row buffer.

Example

The following code opens the customer table and scrolls through its rows. It then displays a message box with the last name of each customer.

'MobileVB
Dim TCustomer as ULTable
Set TCustomer = Conn.GetTable("customer")
TCustomer.Open
While TCustomer.MoveNext
   MsgBox TCustomer.Column( "lname" ).StringValue
Wend
'Crossfire
Dim TCustomer as UltraLiteAFLib.ULTable
Set TCustomer = Conn.GetTable("Customer")
TCustomer.Open
While TCustomer.MoveNext
   MsgBox TCustomer.Column("LName").StringValue
Wend
Example
Specifying an index

You expose the rows of the table to the application when you open the table object. By default, the rows are exposed in order by primary key value, but you can specify an index to access the rows in a particular order.

Example

The following code moves to the first row of the customer table as ordered by the ix_name index.

'MobileVB
Set TCustomer = Conn.GetTable("customer")
TCustomer.Open "ix_name"
TCustomer.MoveFirst
'Crossfire
TCustomer = Conn.GetTable("customer")
TCustomer.Open "ix_name"
TCustomer.MoveFirst


Accessing the values of the current row

At any time, a ULTable object is positioned at one of the following places.

  • Before the first row of the table.

  • On a row of the table.

  • After the last row of the table.

If the ULTable object is positioned on a row, you can use the Column method together with an appropriate property to get the value of that column for the current row.

Example

The following code retrieves the value of three columns from the tCustomer ULTable object, and displays them in text boxes.

Dim colID, colFirstName, colLastName As ULColumn
Set colID = tCustomer.Column("ID")
Set colFirstName = tCustomer.Column("fname")
Set colLastName = tCustomer.Column("lname")
txtID.Text = colID.IntegerValue
txtFirstName.Text = colFirstName.StringValue
txtLastName.Text = colLastName.StringValue

You can also use the properties of ULColumn to set values.

colLastName.StringValue = "Kaminski"

By assigning values to these properties you do not alter the value of the data in the database.

You can assign values to the properties even if you are before the first row or after the last row of the table. You cannot, however, get values from the column. For example, the following code generates an error.

' This code is incorrect
TCustomer.MoveBeforeFirst
id = TCustomer.Column( "ID" ).IntegerValue

To work with binary data, use the GetByteChunk method instead of a property.

For more information, see GetByteChunk method.

Casting values

The ULColumn property you choose must match the Visual Basic data type you wish to assign. UltraLite automatically casts incompatible data types, so that you could use the StringValue method to fetch an integer value into a string variable, and so on.

For more information about accessing values of the current row, see ULColumn class.


Searching rows with find and lookup

UltraLite has several modes of operation for working with data. Two of these modes, the find and lookup modes, are used for searching. The ULTable object has methods corresponding to these modes for locating particular rows in a table.

Note
The columns searched using Find and Lookup methods must be in the index used to open the table.

  • Find methods move to the first row that exactly matches a specified search value, under the sort order specified when the ULTable object was opened.

    For more information about find methods, see FindBegin method.

  • Lookup methods move to the first row that matches or is greater than a specified search value, under the sort order specified when the ULTable object was opened.

    For more information about lookup methods, see LookupBackward method.

toggle To search for a row

  1. Enter find or lookup mode.

    Call the FindBegin or LookupBegin method. For example, the following code calls ULTable.FindBegin.

    tCustomer.FindBegin

  2. Set the search values.

    You do this by setting values in the current row. Setting these values affects the buffer, not the database. For example, the following code sets the last name column in the buffer to Kaminski.

    tCustomer.Column("lname").StringValue = "Kaminski"

    For multi-column indexes, a value for the first column is required, but you can omit the other columns.

  3. Search for the row.

    Use the appropriate method to carry out the search. For example, the following instruction looks for the first row that exactly matches the specified value in the current index.

    tCustomer.FindFirst


Inserting, updating, and deleting rows

UltraLite exposes the rows in a table to your application one at a time. The ULTable object has a current position, which may be on a row, before the first row, or after the last row of the table.

When your application changes location, UltraLite makes a copy of the row in a buffer. Any operations to get or set values affect only the copy of data in this buffer. They do not affect the data in the database.

Example

The following statement changes the value of the ID column in the buffer to 3.

colID.IntegerValue = 3
Using UltraLite modes

The UltraLite mode determines the purpose for which the values in the buffer will be used. UltraLite has the following four modes of operation, in addition to a default mode.

  • Insert mode The data in the buffer is added to the table as a new row when the ULTable.Insert method is called.

  • Update mode The data in the buffer replaces the current row when the ULTable.Update method is called.

  • Find mode Used to locate a row whose value exactly matches the data in the buffer when one of the ULTable.Find methods is called.

  • Lookup mode Used to locate a row whose value matches or is greater than the data in the buffer when one of the ULTable.Lookup methods is called.

toggle To update a row

  1. Move to the row you wish to update.

    You can move to a row by scrolling through the table or by searching using Find and Lookup methods.

  2. Enter Update mode.

    For example, the following instruction enters Update mode on the table tCustomer.

    tCustomer.UpdateBegin

  3. Set the new values for the row to be updated.

    For example, the following instruction sets the new value to Elizabeth.

    ColFirstName.StringValue = "Elizabeth"

  4. Execute the Update.

    tCustomer.Update

After the update operation, the current row is the row that was just updated. If you changed the value of a column in the index specified when the ULTable object was opened, the current position is undefined.

By default, UltraLite operates in AutoCommit mode, so that the update is immediately applied to the row in permanent storage. If you have disabled AutoCommit mode, the update is not applied until you execute a commit operation. For more information, see Transaction processing in UltraLite.

Caution Do not update the primary key of a row: delete the row and add a new row instead.
Inserting rows

The steps to insert a row are similar to those for updating rows, except that there is no need to locate any particular row in the table before carrying out the insert operation. Rows are automatically sorted by the index specified when opening the table.

toggle To insert a row

  1. Enter Insert mode.

    For example, the following instruction enters Insert mode on the table CustomerTable.

    CustomerTable.InsertBegin

  2. Set the values for the new row.

    If you do not set a value for one of the columns, and that column has a default, the default value is used. If the column has no default, NULL is used. If the column does not allow NULL, the following defaults are used:

    • For numeric columns, zero.

    • For character columns, an empty string.

    To set a value to NULL explicitly, use the setNull method.

    CustomerTable.Column("FName").StringValue = fname
CustomerTable.Column("LName").StringValue = lname

  3. Execute the insertion.

    The inserted row is permanently saved to the database when a Commit is carried out. In AutoCommit mode, a Commit is carried out as part of the Insert method.

    CustomerTable.Insert
Deleting rows

There is no delete mode corresponding to the insert or update modes.

The following procedure deletes a row.

toggle To delete a row

  1. Move to the row you wish to delete.

  2. Execute the deletion.

    tCustomer.Delete


Working with BLOB data

You can fetch BLOB data for columns declared BINARY or LONG BINARY using the GetByteChunk method.

For more information, see GetByteChunk method.

Example

The following code demonstrates how to use the ULColumn.GetByteChunk method to get BLOB data.

'MobileVB
Dim table as ULTable
Dim col As ULColumn
Dim data(1 to 1024) As Byte
Dim data_fit As Boolean
Dim size As Long
Set table = Conn.GetTable("image")
table.Open
size = 1024
Set col = table.Column("img_data")
data_fit = col.GetByteChunk(VarPtr(data(1)), size)
If data_fit Then
  'No truncation
Else
  'data truncated at 1024
End if
table.Close
'Crossfire
Dim table as ULTable
Dim col As ULColumn
Dim data(1 to 1024) As Byte
Dim data_fit As Boolean
Dim size As Long
Set table = Conn.GetTable("image")
table.Open
size = 1024
Set col = table.Column("img_data")
' The data argument must be a local variable
data_fit = col.GetByteChunk(data, size)
If data_fit Then
  'No truncation
Else
  'data truncated at 1024
End if
table.Close


Transaction processing in UltraLite

UltraLite provides transaction processing to ensure the integrity of the data in your database. A transaction is a logical unit of work. Either the entire transaction is executed, or none of the statements in the transaction are executed.

By default, UltraLite operates in AutoCommit mode. In AutoCommit mode, each insert, update, or delete is executed as a separate transaction. Once the operation is completed, the change is made to the database.

If you set the ULConnection.AutoCommit property to false, you can use multi-statement transactions. For example, if your application transfers money between two accounts, the deduction from the source account and the addition to the destination account constitute a single transaction. If AutoCommit is false, you must execute a ULConnection.Commit statement to complete a transaction and make changes to your database permanent, or you may execute a ULConnection. Rollback statement to cancel all the operations of a transaction. Turning off AutoCommit improves performance.

Note
Synchronization causes a Commit even if you have AutoCommit set to False.

Previous Next


Accessing schema information

Each ULConnection, ULTable, and ULColumn object contains a schema property. These schema objects provide information about the tables, columns, indexes, and publications in a database.

Note
You cannot modify the schema through the API. You can only retrieve information about the schema.

For information about modifying the schema, see Changing the schema of a database.

  • ULDatabaseSchema The number and names of the tables in the database, as well as global properties such as the format of dates and times.

    To obtain a ULDatabaseSchema object, access the ULConnection.Schema property.

  • ULTableSchema The number and names of columns in the table, as well as the Indexes collections for the table.

    To obtain a ULTableSchema object, access the ULTable.Schema property.

  • ULColumnSchema Information about an individual column, including its default value, name, and whether it is autoincrement.

    To obtain a ULColumnSchema object, access the ULColumn.Schema property.

  • ULIndexSchema Information about the column, or columns, in the index. As an index has no data directly associated with it, there is no separate ULIndex object, only a ULIndexSchema object.

    The ULIndexSchema objects are accessed using the ULTableSchema.GetIndex method.

  • ULPublicationSchema The numbers and names of tables and columns contained in a publication. Publications are also comprised of schema only, so there is a ULPublicationSchema object but no ULPublication object.

    The ULPublicationSchema objects are accessible using the ULDatabaseSchema.GetPublicationSchema method.

  • ULResultSetSchema The number and names of the columns in a result set.

    The ULResultSetSchema objects are accessible using the ULPreparedStatement.ResultSetSchema property.


Handling errors

In normal operation, UltraLite for MobileVB can throw errors. Errors are expressed as SQLCODE values, negative numbers indicating the particular kind of error.

For a list of error codes thrown by UltraLite for MobileVB, see ULSQLCode enumeration.

UltraLite for MobileVB throws errors only from the ULDatabaseManager and ULConnection objects. The following methods of ULDatabaseManager can throw errors.

  • CreateDatabase

  • CreateDatabaseWithParms

  • DropDatabase

  • DropDatabaseWithParms

  • OpenConnection

  • OpenConnectionWithParms

All other errors and exceptions within UltraLite for MobileVB are routed through the ULConnection object.

For more information about accessing error numbers from ULDatabaseManager and ULConnection objects, see ULConnection class and ULDatabaseManager class.

You can use the standard MobileVB or Crossfire error-handling features to handle errors. When an UltraLite object is the source of an error, the Err object is assigned a ULSQLCode number. ULSQLCodes are negative numbers indicating the particular kind of error. The ULSQLCode enumeration provides a set of descriptive constants associated with these values.

For more information, see ULSQLCode enumeration.

To make use of type completion in the MobileVB environment, you may want to create an error handling function such as the following:

'MobileVB
Public Function GetError() As ULSQLCode
    GetError = Err.Number
End Function

You can then easily access UltraLite errors using the GetError function.


Authenticating users

New users have to be added from an existing connection. As all UltraLite databases are created with a default user ID and password of DBA and SQL, respectively, you must first connect as this initial user.

You cannot change a user ID: you add a user and delete an existing user. A maximum of four user IDs are permitted for each UltraLite database.

For more information about granting or revoking connection authority, see GrantConnectTo method and RevokeConnectFrom method.

toggle To add a user or change the password for an existing user

  1. Connect to the database as a user with DBA authority.

  2. Grant the user connection authority with the desired password.

    conn.GrantConnectTo("Robert", "newPassword")
toggle To delete an existing user

  1. Connect to the database as a user with DBA authority.

  2. Revoke the user's connection authority as follows.

    conn.RevokeConnectFrom("Robert")


Synchronizing data

You can UltraLite applications with a central database. Synchronization requires the MobiLink synchronization server and appropriate licensing.

This section provides a brief introduction to synchronization and describes some features of particular interest to users of UltraLite for MobileVB. For a detailed explanation of synchronization, see UltraLite Clients.

You can also find a working example of synchronization in the CustDB sample application. This sample is described in Tutorial: A Sample UltraLite for MobileVB Application

UltraLite for MobileVB supports TCP/IP, HTTP, and HTTPS synchronization. Synchronization is initiated by the UltraLite application. In all cases, you use methods and properties of the ULConnection object to control synchronization.

Note
To synchronize using encrypted synchronization (HTTPS) or to use encryption over TCP/IP you must obtain the separately-licensable security option. To order this option, see the card in your SQL Anywhere Studio package or see [external link] http://www.sybase.com/detail?id=1015780.

For more information, see Welcome to SQL Anywhere Studio.

toggle To synchronize over TCP/IP or HTTP

  1. Prepare the synchronization information.

    Assign values to the required properties of the ULConnection.SyncParms object.

    For information about the properties and the values that you should set, see UltraLite Clients.

  2. Synchronize.

    Call the ULConnection.Synchronize method.


Adding the synchronization template

UltraLite for MobileVB includes a template form that can be used to monitor the status of a synchronization session. A version of this form is included for both Palm OS and Pocket PC. You can use these templates in your application, you can customize them, or you can simply examine them to learn how UltraLite synchronization events work.

Synchronization dialog showing progress bar

The way to add this template to your application depends on whether you are using MobileVB or Crossfire.

toggle To add a synchronization template to your application (MobileVB)

  1. From the project menu, choose Add Form.

  2. Select either UltraLite for MobileVB Sync Form (Windows CE) or UltraLite for MobileVB Sync Form (Palm).

  3. Click Open. A copy of the form is added to your application.

toggle To add a synchronization template to your application (Crossfire)

  1. From the project menu, choose Add New Item.

  2. From Local Project Items > Ultralite_Crossfire Forms, select UltraLite Crossfire 9 Sync Form for CE, Palm or PalmHires depending on your application.

  3. Click Open. A copy of the form is added to your application.


Writing code to use the synchronization form

Call the InitSyncForm function, passing it your ULConnection object. This must be done before each synchronization.

Example

The following code uses a synchronization status form named Form_Sync and a ULConnection object named Connection.

Form_Sync.InitSyncForm Connection
Connection.Synchronize

Each time your application synchronizes, the synchronization status form appears. As synchronization progresses, your end user can observe the progress bar and byte count. When synchronization completes, the form closes. The Cancel button instructs UltraLite to cancel the current synchronization.

For more details, see Tutorial: A Sample UltraLite for MobileVB Application.


Deploying UltraLite applications

When you have completed your application or when you wish to test your application, you need to deploy it to a device. This section outlines the steps needed to deploy an UltraLite application to a device.


Deploying UltraLite for MobileVB applications to Windows CE

You must carry out the following steps to deploy an UltraLite application to Windows CE:

  • Deploy your application and UltraLite component.

    1. Configure the application settings.

      • From the MobileVB menu, choose MobileVB Settings. A dialog appears.

      • In the left pane, choose Dependencies and click the User Dependencies tab.

      • Click the Add button and select the c:\tutorial\mvb\tutCustomer.usm. This indicates to MobileVB that the file should be included in the deployment.

      • Choose the PocketPC Settings item in the left pane

      • Enter \tutorial\mvb for the Device Installation Path.

      • Click OK to close the dialog.

    2. From the MobileVB menu, choose Deploy to Device, and select the PocketPC device. If a dialog appears asking if you want to save the project, choose Yes.

    3. If you are running MobileVB 3.0 or later, the UltraLite component is deployed automatically along with your application.

      If you are using an older version of MobileVB, you need to copy the UltraLite component to the device. Copy the file ulmvb9.dll to \Program Files\AppForge on your device. The file is located in one of the following platform-specific subdirectories of your SQL Anywhere 9 installation: \UltraLite\UltraLiteForMobileVB\ce\arm or \UltraLite\UltraLiteForMobileVB\ce\mips. This step only needs to be performed once per device.

  • Deploy an initial copy of the UltraLite database or schema.

    In many situations it is sufficient to deploy an UltraLite schema file only. UltraLite creates a database file from the schema on the first connection attempt. You can then use synchronization to load an initial copy of the data. You can deploy the .prc file in the standard manner from the Install Tool included with your Palm Desktop Organizer Software.

    You must place the database or schema file so that it can be located by the application. The Database On CE and Schema On CE connection parameters define the location.

    See Database On CE connection parameter, and Schema On CE connection parameter .

  • Deploy the MobiLink provider for ActiveSync.

    This step is required only if the application is synchronizing using ActiveSync.

    For instructions, see Installing the MobiLink provider for ActiveSync


Deploying UltraLite for MobileVB applications to Palm OS

You must carry out the following steps to deploy an UltraLite application to a Palm OS device:

  • Deploy your application and UltraLite component.

    1. Configure the application settings.

      • From the MobileVB menu, choose MobileVB Settings. A dialog appears.

      • In the left pane, choose Dependencies and click the User Dependencies tab.

      • Click the Add button and select the c:\tutorial\mvb\tutCustomer.pdb. This indicates to MobileVB that the file should be included in the deployment.

      • Choose the Palm OS Settings item in the left pane and enter the Creator ID of your application. Select a valid HotSync name. Click OK to close the dialog.

    2. From the MobileVB menu, choose Deploy to Device, and select the Palm OS device. If a dialog appears asking if you want to save the project, choose Yes.

    3. If you are running MobileVB 3.0 or later, the UltraLite component is deployed automatically along with your application.

      If you are using an older version of MobileVB, you need to copy the UltraLite component to the device. Copy the file ulmvb9.prc to \Program Files\AppForge on your device. The file is located in the \UltraLite\UltraLiteForMobileVB\palm\68k subdirectory of your SQL Anywhere installation. This step only needs to be performed once per device.

  • Deploy an initial copy of the UltraLite database or schema.

    In many situations it is sufficient to deploy an UltraLite schema file only. UltraLite creates a database file from the schema on the first connection attempt. You can then use synchronization to load an initial copy of the data.

    You can create .prc files for deployment to Palm OS from any of the UltraLite utilities, including the Schema Painter, ulxml, and ulinit.

    You must supply a schema or database using the correct creator ID, so that it can be located by your application. The Database On Palm and Schema On Palm connection parameters use the creator ID to find the schema or database.

    See Database On Palm connection parameter, and Schema On Palm connection parameter . For information about using the virtual file system, see VFS On Palm parameter .

  • Deploy the MobiLink synchronization conduit for HotSync.

    This step is required only if the application is synchronizing using HotSync.

    For instructions, see Deploying the MobiLink HotSync conduit.


Maintaining state in UltraLite Palm applications

Palm OS devices run only one application at a time. However, when a user switches from your application to another application, and then returns to your application, it is common to make applications appear as they were simply suspended while the user was working with other applications. To maintain this illusion, the application must save its internal state when the user switches to another application. When the application is launched again, it must restore its internal state.

Saving and restoring state in a database application can be challenging, as the application must re-open result sets and re-position the application within those result sets. UltraLite provides a way for you to save and restore application state.

The state of cursors on result sets is maintained automatically. MobileVB applications that use the table-based API provide a value for the persistent name parameter in the Open method of the ULTable object.


Understanding how state is maintained

For each table whose state is being preserved, UltraLite stores a name for the table as well as enough information to restore the state of the table. The name associated with the table may be, but is not required to be, the name of the table. It is called the persistent name.

UltraLite applications can open more than one instance of the same table at the same time. In this case, the table name is not unique. For example, the following code (using MobileVB) opens the same table twice:

' MobileVB
Set table1 = Connection.GetTable( "ULCustomer" )
table1.Open "", "customer1"
' operations here
Set table2 = Connection.GetTable( "ULCustomer" )
table2.Open "", "customer2"

When opening a table, an applications can optionally provide a persistent name as a parameter. If the state of the persistent name has been saved, the table is opened and positioned to the proper row. If not, the table is opened and positioned before the first row.

When an application terminates, it may or may not explicitly close open tables and close the connection. If it does not close an open table, then UltraLite records the current row of each open table that was supplied with a persistent name. Tables without a persistent name are closed.

Suppose the Connection object is of type ULConnection and a table called ULCustomer exists in the database.

'MobileVB
Dim table As ULTable
Set table = Connection.GetTable( "ULCustomer" )
table.Open "", "customer"

The second line of code gets the table object representing the ULCustomer table. The table has not been opened for reading or writing yet.

In the Open call (the third line of code), the first parameter is the empty string, which indicates that the data will be ordered by the primary key. The second parameter is the persistent name being assigned to the table. If the application terminates while this table is still open, the state PDB will associate customer with the ULCustomer table and save the current position.

Persistent name notes

  • If the persistent name is empty, UltraLite does not store state information for this table, or attempt to look it up when opening the table.

    If you do not need to store the state of your tables, supply an empty persistent name. The state is then not looked up in the state database.

  • HotSync synchronization does not affect the state of your open tables. When a user presses the HotSync button on a device, the operating system closes the application in the same way it closes the application when any other application is started. Consequently, the state of the open tables is recorded in the state PDB and when the user returns to the application and the tables are re-opened, the user is positioned on the expected row. If that row has been deleted as part of the synchronization, the user is positioned on the next row (or after the last row if it was the last row).

  • Applications with auto-commit turned off could terminate with uncommitted transactions. UltraLite maintains these transactions so that when the application restarts, they are not lost.

  • If UltraLite finds a table in the state PDB that matches the persistent name you have provided, it checks that the table and index are the same as the table and index used when the position information was recorded. If they are not, then the call to Open fails.

  • The use of the persistent name is unique to the Palm OS. If you create UltraLite for MobileVB applications for Windows CE, they do not use the persistent name. Applications on Windows CE run more like they do on a desktop machine.


Example: Using the persistent name to maintain state information

The PersistentName example program is a relatively simple program that shows how to use maintained state information. It is available at [external link] http://www.sybase.com/detail?id=1022734. Here are some highlights from the sample:

'MobileVB
CustomerTable.Open
AddRow "John", "Doe", "Atlanta"
AddRow "Mary", "Smith", "Toronto"
AddRow "Jane", "Anderson", "New York"
AddRow "Margaret", "Billington", "Vancouver"
AddRow "Fred", "Jones", "London"
AddRow "Jack", "Frost", "Dublin"
AddRow "David", "Reiser", "Berlin"
AddRow "Kathy", "Stevens", "Waterloo"
AddRow "Rebecca", "Gable", "Paris"
AddRow "George", "Jenkins", "Madrid"
CustomerTable.Close

This code adds ten rows to the ULCustomer table. It calls Open on the table, but in this case a persistent name is not supplied because we are not interested in maintaining the position in the table. Since the code only inserts data, the position in the table is not relevant.

The following line opens the ULCustomer table, ordering rows by the primary key and assigning a persistent name of customer.

CustomerTable.Open "" , "customer"

If the application has been run before, then a lookup is done in the state database for customer. Otherwise, customer is associated with this table.

The customer table is left open for the duration of the running application. If the user switches to another application, UltraLite records the position in the table where the user left off. When the application is started again, the table is opened and UltraLite determines that position information is known for a table with the persistent name customer, so it positions the user back on that row.

When the user clicks the End button, the customer table and the connection are closed before the application disappears. This has the effect of discarding any state information for the customer table, so when the application is restarted, the user is positioned on the first row.


Tutorial: A Sample UltraLite for MobileVB Application

About this chapter

This chapter provides a tutorial to guide you through the process of building an UltraLite for MobileVB application for either a PocketPC or a Palm OS device.


Introduction

This tutorial guides you through the process of building an UltraLite for MobileVB application using the table API. At the end of the tutorial you will have an application and small database on your Windows CE device that synchronizes with a central database.

For more information about the table API, see the UltraLite for MobileVB API Reference.

Timing

The tutorial takes about 30 minutes if you copy and paste the code. If you enter the code yourself, it takes significantly longer.

Competencies and experience

This tutorial assumes:

  • you have MobileVB and Microsoft Visual Basic 6 installed on your computer

  • you can write, test, and troubleshoot a MobileVB application

  • you know how to create an UltraLite schema using the UltraLite Schema Painter

    For more information, see The UltraLite Schema Painter.

  • you have the AppForge Booster installed

    If you are missing Booster, you can get it from [external link] http://www.appforge.com/booster.html.

Note
You can perform most of this tutorial without SQL Anywhere Studio. The synchronization sections of the tutorial require SQL Anywhere Studio.
Goals

The goals for the tutorial are to gain competence and familiarity with the process of developing an UltraLite application.


Lesson 1: Create a project architecture

The first procedure describes how to create an UltraLite database schema. The database schema is a description of the database. It describes the tables, indexes, keys, and publications within the database, and all the relationships between them.

For more information about database schemas, see Creating UltraLite database schema files.

toggle To create an UltraLite database schema

  1. Create a directory for this tutorial.

    This tutorial assumes the directory is c:\Tutorial\mvb. If you create a directory with a different name, use that directory instead of c:\Tutorial\mvb throughout the tutorial.

  2. Create a database schema using the UltraLite Schema Painter.

    For more information about creating a database schema, see the Lesson 1: Create an UltraLite database schema.

    • Schema filename tutcustomer.usm

    • Table name customer

    • Columns in customer

      Column Name | Data Type (Size) | Column allows NULL values? | Default value
      id | integer | No | autoincrement
      fname | char(15) | No | None
      lname | char(20) | No | None
      city | char(20) | Yes | None
      phone | char(12) | Yes | 555-1234

    • Primary key ascending id

  3. If you are using a Palm device, export the schema to Palm with a creator id of Syb3.

    1. From the File menu, choose Export Schema for Palm.

    2. Enter Syb3 as the creator ID.

    3. Save the file as tutcustomer.pdb in your tutorial directory.

    A note on Palm Creator ID's
    A Palm creator ID is assigned to you by Palm. You can use Syb3 as your creator ID when you make sample applications. However, when you create a commercial application, you should use your own creator ID.

Create a MobileVB project


Create a MobileVB project

The following procedure creates a MobileVB project for your application and adds a reference to the UltraLite for MobileVB control.

MobileVB tools appear in addition to the standard Visual Basic tools on the Visual Basic toolbar to the left of the Visual Basic environment.

toggle To add the UltraLite connection parameters control

  1. Start MobileVB.

    • Choose Start > Programs > AppForge MobileVB > Start MobileVB.

    The MobileVB Project Manager appears.

  2. From the Visual Basic menu, choose Project > Components.

  3. Click the Controls tab.

  4. Scroll down the list to select UltraLite Connection Parameters 9.0. Click OK.

    If this item does not appear in the list of available controls, complete the following steps:

    • Close MobileVB and save your project.

    • Open a command prompt at ultralite\UltraLiteforMobileVB\win32 and run the following command:

      ulmvbreg -r

    • Restart MobileVB and open your project.

    • Choose Project > Components.

    • Select UltraLite Connection Parameters 9.0.

    A database icon is added to your toolbar. Double-click this icon to add a ULConnectionParms object to your form.

toggle To create a reference to the UltraLite for MobileVB control

  1. Start MobileVB.

    • Choose Start > Programs > AppForge MobileVB > Start MobileVB.

    The MobileVB Project Manager appears.

  2. Create a new project.

    Click New Project. When asked for the Design Target, choose the appropriate target. This tutorial provides instructions for Palm OS and PocketPC devices.

  3. Create a reference to UltraLite for MobileVB.

    • Choose Project > References

    • Select iAnywhere Solutions, UltraLite for MobileVB 9.0 and click OK.

      If the control does not appear in the list of available references, exit MobileVB and run the following command.

      ulmvbreg -r

  4. Give the Project a name.

    • Click Project > MobileVBProject1 Properties

    • Under Project Name, type UltraLiteTutorial. This is the name of the application as it will appear on your device.

    • Click OK.

  5. Save the Project:

    • Choose File > Save Project.

    • Save the form as c:\tutorial\mvb\Tutorial.frm.

    • Save the project as c:\tutorial\mvb\Tutorial.vbp.


Lesson 2: Create a form

After completing the steps in Lesson 1: Create a project architecture, the project should display a form. The following procedure uses the form to create a user interface. This example uses labels as outputs, and text boxes and buttons as inputs, similar to a real application.

toggle To add controls to your project

  1. Add the controls and properties given in the table below to your form:

    Type | Name | Caption or text
    AFTextBox | txtfname
    AFTextBox | txtlname
    AFTextBox | txtcity
    AFTextBox | txtphone
    AFLabel | lblID
    AFButton | btnInsert | Insert
    AFButton | btnUpdate | Update
    AFButton | btnDelete | Delete
    AFButton | btnNext | Next
    AFButton | btnPrevious | Previous
    AFButton | btnSync | Synchronize
    AFButton | btnDone | End

  2. Check the application.

    • Choose MobileVB > Compile and Validate.

Your form should look like the following screen capture:

The application form, showing the buttons, text boxes, and label.


Lesson 3: Write the sample code

This lesson guides you through the process of writing Visual Basic code to connect to a database, navigate within the database, and manipulate the data in the database.

This lesson also includes instructions for synchronizing your application with an Adaptive Server Anywhere database. This portion of the lesson is optional, and requires SQL Anywhere Studio.


Write code to connect to your database

In this application, you connect to the database during the Form_Load event. You can also connect to a database using the general module.

This example uses a ULConnectionParms object to connect to a database. You can also use a connection string.

For reference information, see ULConnectionParms class.

toggle Write code to connect to the UltraLite database

  1. Double-click the form to open the Code window.

  2. Declare the required UltraLite objects.

    Enter the following code in the declarations area of your form.

    Public DatabaseMgr As New ULDatabaseManager
Public Connection As ULConnection
Public CustomerTable As ULTable

  3. Specify the connection parameters.

    • Add a ULConnectionParms object to your form named ULConnectionParms1. The ULConnectionParms control is a database icon on the toolbox.

    • In the Properties window, specify the ULConnectionParms properties.

      If you are deploying to a Windows CE device, specify the following properties:

      Property | Value
      DatabaseOnDesktop | c:\tutorial\mvb\tutCustomer.udb
      DatabaseOnCE | \tutorial\mvb\tutCustomer.udb
      SchemaOnDesktop | c:\tutorial\mvb\tutCustomer.usm
      SchemaOnCE | \tutorial\mvb\tutCustomer.usm

      If you are deploying to a Palm device, specify the following properties:

      Property | Value
      DatabaseOnDesktop | c:\tutorial\mvb\tutCustomer.pdb
      DatabaseOnPalm | Syb3
      SchemaOnDesktop | c:\tutorial\mvb\tutCustomer.usm
      SchemaOnPalm | tutCustomer

  4. Add code to connect to the database in the Form_Load event.

    The database manager tries to open a connection to the database specified by the ULConnectionParms1 object. If the database does not exist, it creates a new database using the given schema.

    Sub Form_Load()
  ' enable error handling
  On Error Resume Next
  ' try to connect to an existing database
  Set Connection = _
    DatabaseMgr.OpenConnectionWithParms( _
      ULConnectionParms1)
  ' if the database does not exist, create one
  If Err.Number = ULSQLCode.ulSQLE_NOERROR Then
    MsgBox "Connected to an existing database"
  ElseIf Err.Number = _
    ULSQLCode.ulSQLE_ULTRALITE_DATABASE_NOT_FOUND _
  Then
    Err.Clear
    Set Connection = _
    DatabaseMgr.CreateDatabaseWithParms( _
     ULConnectionParms1)
    If Err.Number = ULSQLCode.ulSQLE_NOERROR _
     Then
       MsgBox "Connected to a new database"
     Else
       MsgBox Err.Description
     End If
   Else
    MsgBox Err.Description
   End If
End Sub

  5. Add code to end the application and close the connection when the End button is clicked.

    Sub btnDone_Click()
    Connection.Close
    End
End Sub

  6. Run the application.

    • Choose Run > Execute.

    • After an initial message box, the form loads.

    • To terminate the application, click End.


Write code for navigation and data manipulation

The following procedures implement data manipulation and navigation.

toggle To open the table

  1. Write code to initialize the table and move to the first row.

    This code assigns the customer table in the database to the CustomerTable variable. The call to Open opens the table so that the table data can be read or manipulated. It also positions the application before the first row in the table.

    Add the following code to the Form_Load event, just before the End Sub instruction.

    Set CustomerTable = Connection.GetTable("customer")
CustomerTable.Open
If Err.Number <> ULSQLCode.ulSQLE_NOERROR Then
    MsgBox Err.Description
End If

  2. Create a new procedure called DisplayCurrentRow and implement it as shown below.

    If the table has no rows, the following procedure causes the application to display empty controls. Otherwise, it displays the values stored in each of the columns of the current row of the database.

    Private Sub DisplayCurrentRow()
  If CustomerTable.RowCount = 0 Then
    txtFname.Text = ""
    txtLname.Text = ""
    txtCity.Text = ""
    txtPhone.Text = ""
    lblID.Caption = ""
  Else
    lblID.Caption = _
         CustomerTable.Column("Id").StringValue
    txtFname.Text = _
         CustomerTable.Column("Fname").StringValue
    txtLname.Text = _
         CustomerTable.Column("Lname").StringValue
    If CustomerTable.Column ("City").IsNull Then
      txtCity.text =""
    Else
      txtCity.Text = _
      CustomerTable.Column("City").StringValue
    End If
    If CustomerTable.Column("Phone").IsNull Then
      txtphone.Text = ""
    Else
      txtphone.Text = _
      CustomerTable.Column("Phone").StringValue
    End If
  End If
End Sub

  3. Call DisplayCurrentRow from the Form_Activate procedure. This call ensures that the fields get updated when the application starts.

    Private Sub Form_Activate()
    DisplayCurrentRow
End Sub
toggle To insert rows into the table

  1. Write code to implement the Insert button.

    In the following procedure, the call to InsertBegin puts the application into insert mode and sets all the values in the row to their defaults. For example, the ID column receives the next autoincrement value. The column values are set and then the new row is inserted.

    Add the following procedure to the form.

    Private Sub btnInsert_Click()
    Dim fname As String
    Dim lname As String
    Dim city As String
    Dim phone As String

    fname = txtFname.Text
    lname = txtLname.Text
    city = txtCity.Text
    phone = txtPhone.Text

    On Error GoTo InsertError
    CustomerTable.InsertBegin
    CustomerTable.Column("Fname").StringValue = _
      fname
    CustomerTable.Column("Lname").StringValue = _
      lname
    If Len(city) > 0 Then
        CustomerTable.Column("City").StringValue = _
      city
    End If
    If Len(phone) > 0 Then
       CustomerTable.Column("Phone").StringValue = _
       phone
    End If
    CustomerTable.Insert
    CustomerTable.MoveLast
    DisplayCurrentRow
    Exit Sub

InsertError:
    MsgBox "Error:  " & CStr(Err.Description)
End Sub

  2. Run the application.

    After an initial message box, the form is displayed.

  3. Insert two rows into the database.

    • Enter a first name of Jane in the first text box and a last name of Doe in the second. Click Insert.

      A row is added to the table with these values. The application moves to the last row of the table and displays the row. The label displays the automatically incremented value of the ID column that UltraLite assigned to the row.

    • Enter a first name of John in the first text box and a last name of Smith in the second. Click Insert.

  4. Click End to end the program.

toggle To move through the rows of the table

  1. Write code to implement the Next and Previous buttons.

    Add the following procedures to the form.

    Private Sub btnNext_Click()
    If Not CustomerTable.MoveNext Then
        CustomerTable.MoveLast
    End If
    DisplayCurrentRow
End Sub
Private Sub btnPrevious_Click()
    If Not CustomerTable.MovePrevious Then
        CustomerTable.MoveFirst
    End If
    DisplayCurrentRow
End Sub

  2. Run the application.

    When the form is first displayed, the controls are empty as the current position is before the first row.

    After the form is displayed, click Next and Previous to move through the rows of the table.

toggle To update and delete rows in the table

  1. Write code to implement the Update button.

    In the code below, the call to UpdateBegin puts the application into update mode. The column values are updated and then the row itself is updated with a call to Update.

    Add the following procedure to the form.

    Private Sub btnUpdate_Click()
    Dim fname As String
    Dim lname As String
    Dim city As String
    Dim phone As String

    fname = txtFname.Text
    lname = txtLname.Text
    city = txtCity.Text
    phone = txtPhone.Text
    On Error GoTo UpdateError
    CustomerTable.UpdateBegin
    CustomerTable.Column("Fname").StringValue = fname
    CustomerTable.Column("Lname").StringValue = lname
    If Len(city) > 0 Then
        CustomerTable.Column("City").StringValue = city
    Else
        CustomerTable.Column("City").SetNull
    End If
    If Len(phone) > 0 Then
       CustomerTable.Column("Phone").StringValue = phone
    End If
    CustomerTable.Update
    DisplayCurrentRow
    Exit Sub

UpdateError:
    MsgBox "Error:  " & CStr(Err.Description)
End Sub

  2. Write code to implement the Delete button.

    In the code below, the call to Delete deletes the current row on which the application is positioned.

    Add the following procedure to the form.

    Private Sub btnDelete_Click()
    If CustomerTable.RowCount = 0 Then
        Exit Sub
    End If
    CustomerTable.Delete
    CustomerTable.MoveRelative 0
    DisplayCurrentRow
End Sub

  3. Run the application.


Write code to synchronize

The following procedure implements synchronization. Synchronization requires SQL Anywhere Studio. This portion of the tutorial is optional.

toggle To write code for the synchronize button

  • Write code to implement the Synchronize button.

    In the code below, the ULSyncParms object contains the synchronization parameters. For example, the ULSyncParms.UserName property specifies that when MobiLink is started, it will add a new user. The ULSyncParms.SendColumnNames property specifies that the column names will be sent to MobiLink so it can generate upload and download scripts.

    Add the following procedure to the form.

    Private Sub btnSync_Click()
    With Connection.SyncParms
        .UserName = "afsample"
        .Stream = ULStreamType.ulTCPIP
        .Version = "ul_default"
        .SendColumnNames = True
    End With
    Connection.Synchronize
    DisplayCurrentRow
End Sub


Synchronize your application

The ASA 9.0 Sample database has a Customer table with columns matching those in the customer table in your UltraLite database. The following procedure synchronizes your database with the ASA 9.0 Sample database.

toggle To synchronize your application

  1. From a command prompt, start the MobiLink synchronization server by running the following command line.

    dbmlsrv9 -c "dsn=ASA 9.0 Sample" -v+ -zu+ -za

    The -zu+ and -za command line options provide automatic addition of users and generation of synchronization scripts. For more information about these options, see MobiLink Synchronization Server Options.

  2. Start the UltraLite application.

  3. Delete all the rows in your table.

    Any rows in the table would be uploaded to the Customer table in the ASA 9.0 Sample database.

  4. Synchronize your application.

    Click Synchronize.

    The MobiLink synchronization server window displays the synchronization progress.

  5. When the synchronization is complete, click Next and Previous to move through the rows of the table.


Lesson 4: Deploy to a device

The following procedures deploy your application to either a Palm OS or PocketPC device.

toggle To deploy to a PocketPC device

  1. Configure the application settings.

    • From the MobileVB menu, choose MobileVB Settings. A dialog appears.

    • In the left pane, choose Dependencies and click the User Dependencies tab.

    • Click the Add button and select the c:\tutorial\mvb\tutCustomer.usm. This indicates to MobileVB that the file should be included in the deployment.

    • Choose the PocketPC Settings item in the left pane

    • Enter \tutorial\mvb for the Device Installation Path.

    • Click OK to close the dialog.

  2. From the MobileVB menu, choose Deploy to Device, and select the PocketPC device. If a dialog appears asking if you want to save the project, choose Yes.

  3. If you are running a version of MobileVB that is older than 3.0, you will also need to copy the UltraLite control to the device.

    Copy the file ulmvb9.dll to \Program Files\AppForge on your device. The file is located in one of the following platform-specific subdirectories of your SQL Anywhere 9 installation: \UltraLite\UltraLiteForMobileVB\ce\arm or \UltraLite\UltraLiteForMobileVB\ce\mips. This step only needs to be performed once per device.

  4. On your device, tap Start > Programs.

  5. Tap UltraLiteTutorial to run your application.

toggle To deploy to the Palm device

  1. Configure the application settings.

    • From the MobileVB menu, choose MobileVB Settings.

    • In the dialog that appears, choose Dependencies in the left pane and click the User Dependencies tab.

    • Click the Add button and select c:\tutorial\mvb\tutCustomer.pdb. This indicates to MobileVB that the file should be included in the deployment.

    • Choose the Palm OS Settings item in the left pane and enter Syb3 for the Creator ID. Select a valid HotSync name.

    • Click OK to close the dialog.

  2. From the MobileVB menu, choose Deploy to Device, and select the Palm OS device. If a dialog appears asking if you want to save the project, choose Yes.

  3. HotSync your device and make sure the application gets sent to the device. After the HotSync process is complete, your application files will be extracted on the device.

  4. Click Home on the device and choose UltraLiteTutorial to run your application.


Summary

Learning accomplishments

During this tutorial, you:

  • created a database schema

  • created an UltraLite for MobileVB application

  • synchronized an UltraLite remote database with an Adaptive Server Anywhere consolidated database

  • gained competence with the process of developing an UltraLite for MobileVB application

More samples

You can find more sample applications and utilities at [external link] iAnywhere CodeXchange.


Tutorial: A Sample Application for AppForge Crossfire

About this chapter

This tutorial guides you through the process of using AppForge Crossfire to build an UltraLite application for either a PocketPC or a Palm OS device.

Introduction
Lesson 1: Create a project architecture
Lesson 2: Create the application interface
Lesson 3: Write the sample code
Lesson 4: Deploy to a device
Summary


Introduction

This tutorial describes how to use AppForge Crossfire to build an UltraLite application. At the end of the tutorial you will have an application and small database on your Windows CE device that synchronizes with a central consolidated database.

For more information about the table API, see the UltraLite for MobileVB API Reference.

Timing

The tutorial takes about 30 minutes if you copy and paste the code. If you enter the code yourself, it takes significantly longer.

Prerequisites

This tutorial assumes that you have AppForge Crossfire installed on your computer. It also assumes a basic familiarity with Crossfire development.

The tutorial also assumes that you know how to create an UltraLite schema using the UltraLite Schema Painter. For more information, see The UltraLite Schema Painter.

Note
Crossfire users can perform most of this tutorial without SQL Anywhere Studio. The synchronization sections of the tutorial require SQL Anywhere Studio.

Previous Next


Lesson 1: Create a project architecture

The first procedure describes how to create an UltraLite database schema. The database schema is a description of the database. It describes the tables, indexes, keys, and publications within the database, and all the relationships between them.

For more information about database schemas, see Creating UltraLite database schema files.

toggle To create an UltraLite database schema

  1. Create a directory for this tutorial.

    This tutorial assumes the directory is c:\Tutorial\crossfire. If you create a directory with a different name, use that directory throughout the tutorial.

  2. Create a database schema using the UltraLite Schema Painter.

    For more information about creating a database schema, see the Lesson 1: Create an UltraLite database schema.

    • Schema filename tutcustomer.usm

    • Table name Customer

    • Columns in Customer

      Column Name | Data Type (Size) | Column allows NULL values? | Default value
      ID | integer | No | autoincrement
      FName | char(15) | No | None
      LName | char(20) | No | None
      City | char(20) | Yes | None
      Phone | char(12) | Yes | 555-1234
      In an application with synchronization, it is usual to choose a global autoincrement or UUID data type for primary keys. An autoincrement method is chosen here to make the tutorial quicker.

    • Primary key Ascending ID

  3. Save the database schema.

    If you are developing an application for Windows or Windows CE, choose File > Save and choose tutcustomer.usm in your tutorial directory as the filename.

    If you are developing an application for Palm OS:

    1. From the File menu, choose Export Schema for Palm.

    2. Enter Syb3 as the creator ID.

    3. Save the file as tutcustomer.pdb in your tutorial directory.

    A note on Palm Creator IDs
    The creator ID is assigned to you by Palm. You can use Syb3 as your creator ID when you make sample applications. However, when you create a commercial application, you should use your own creator ID.

Create a Crossfire project


Create a Crossfire project

The following procedure creates an AppForge Crossfire project for your application and adds a reference to the UltraLite control.

AppForge tools appear in addition to the standard Visual Basic tools on the toolbar to the left of the development environment.

toggle To create a Crossfire project for UltraLite

  1. Start Crossfire.

    1. Choose Start > Programs > AppForge > Crossfire. The Crossfire Project Manager appears.

    2. Choose New Project. The Microsoft Development Environment New Project dialog appears.

    3. In the Project Types window open the Visual Basic Projects folder.

    4. In the Templates window, click Crossfire Application.

    5. Leave the project name as CrossfireApp1, and enter your tutorial directory (c:\tutorial\crossfire) as the location. Click OK.

    6. Choose your deployment platform and click OK to create the project.

    You should now see a Crossfire form in the Microsoft Visual Basic .NET Development Environment.

  2. If the Toolbox is not displayed, choose View > Toolbox to open it. Open the AppForge tab.

  3. Scroll down the list of AppForge controls to and double click ULConnectionParms Class.

Troubleshooting

If your Crossfire project does not include a reference to iAnywhere.UltraLiteForAppForge.dll, and if the ULConnectionParms class does not appear in the list of AppForge controls, you need to register UltraLite with Crossfire. This may occur if, for example, you install Crossfire after installing SQL Anywhere.

For instructions on adding UltraLite to Crossfire, see Adding UltraLite to the Crossfire design environment.

What's next

You now have an UltraLite database schema and a Crossfire project with an UltraLite control on a form. The next step is to create the application interface.


Lesson 2: Create the application interface

The following procedure uses the form to create a user interface. This example uses labels as outputs, and text boxes and buttons as inputs, similar to a real application.

toggle To add controls to your project

  1. From the AppForge controls, add the following controls to your form:

    Type | Name | Caption or Text
    TextBox | txtFName
    TextBox | txtLName
    TextBox | txtcity
    TextBox | txtphone
    Label | lblID
    Button | btnInsert | Insert
    Button | btnUpdate | Update
    Button | btnDelete | Delete
    Button | btnNext | Next
    Button | btnPrevious | Previous
    Button | btnSync | Synchronize
    Button | btnDone | End

  2. Check the application.

    • Choose Build > Build Solution.

Your form should look as follows:

The application form, showing the buttons, text boxes, and label.


Lesson 3: Write the sample code

This lesson guides you through writing code to connect to a database, navigate within the database, and manipulate the data in the database.

This lesson also includes instructions for synchronizing your application with an Adaptive Server Anywhere database. This portion of the lesson is optional, and requires SQL Anywhere Studio.


Write code to connect to your database

In this application, you connect to the database during the Form_Load event. You can also connect to a database using the general module.

This example uses a the ULConnectionParms object to connect to your tutcustomer database.

toggle Write code to connect to the UltraLite database

  1. Double-click the form to open the Code window.

  2. Declare the required UltraLite objects.

    Enter the following code immediately after the line Public Class CrossfireForm1 Inherits System.Windows.Forms.Form.

    Public DatabaseMgr As New UltraLiteAFLib.ULDatabaseManager
Public Connection As UltraLiteAFLib.ULConnection
Public CustomerTable As UltraLiteAFLib.ULTable

  3. Specify the connection parameters.

    • Select the ULConnectionParm1 control. In the Properties window, specify connection properties for this database.

      If you are deploying to a Windows CE device, specify the following properties:

      Property | Value
      DatabaseOnCE | \tutorial\crossfire\tutCustomer.udb
      DatabaseOnDesktop | c:\tutorial\crossfire\tutCustomer.udb
      SchemaOnCE | \tutorial\crossfire\tutCustomer.usm
      SchemaOnDesktop | c:\tutorial\crossfire\tutCustomer.usm

      If you are deploying to a Palm device, specify the following properties:

      Property | Value
      DatabaseOnDesktop | c:\tutorial\crossfire\tutCustomer.pdb
      DatabaseOnPalm | Syb3
      SchemaOnDesktop | c:\tutorial\crossfire\tutCustomer.usm
      SchemaOnPalm | tutCustomer

  4. In the Form Load event, add code to connect to the database.

    The standard way of connecting is to try open a connection to the database specified by the connection string. If the database does not exist, create a new database using the schema. In Crossfire, you must use add .GetOcx to the ULConnectionParms1 object.

    Private Sub CrossfireForm1_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs _
) Handles MyBase.Load
   Try
      Connection = _
         DatabaseMgr.OpenConnectionWithParms( _
         ULConnectionParms1.GetOcx)
      ' if the database does not exist, create one
      MsgBox("Connected to an existing database")
   Catch
      If Err.Number = _
         UltraLiteAFLib.ULSQLCode.ulSQLE_ULTRALITE_DATABASE_NOT_FOUND _
      Then
         Err.Clear()
         Connection = _
         DatabaseMgr.CreateDatabaseWithParms( _
            ULConnectionParms1.GetOcx)
         If Err.Number = UltraLiteAFLib.ULSQLCode.ulSQLE_NOERROR _
         Then
            MsgBox("Connected to a new database")
         Else
            MsgBox(Err.Description)
         End If
      Else
         MsgBox(Err.Description)
      End If
   End Try
End Sub

  5. Add the following code to the click event of the End button (btnDone):

    Connection.Close
End

  6. Run the application.

    • Choose Debug > Start.

    • After an initial message box, the form loads.

    • To terminate the application, click End.

    On first connecting to the database, UltraLite creates the database file (tutCustomer.udb) from the schema file. If you run the application again, the message box indicates that the connection is to an existing database.

Troubleshooting

You now have the basic code in place to connect to your database.

If you see a data type conversion error on the attempt to connect, make sure you have supplied the GetOcx method on the ULConnectionParms1 object.

If the schema file is not found, check that the file exists in the location pointed to by the ULConnectionParms1 SchemaOnDesktop setting.


Write code for navigation and data manipulation

The following procedures implement data manipulation and navigation. The code uses the Table API, which provides methods for moving through and changing the rows of a table, one at a time. For more complex applications, UltraLite provides an implementation of SQL.

toggle To open the table

  1. Write code to initialize the table and move to the first row.

    This code assigns the Customer table in the database to the CustomerTable variable. The call to Open opens the table so that the table data can be read or manipulated. It also positions the application before the first row in the table.

    Add the following code to the Form_Load event, just before the End Sub instruction.

    Try
   CustomerTable = Connection.GetTable("Customer")
   CustomerTable.Open()
Catch
   If Err.Number <> UltraLiteAFLib.ULSQLCode.ulSQLE_NOERROR _
   Then
      MsgBox(Err.Description)
   End If
End Try

  2. Create a new procedure called DisplayCurrentRow and implement it as shown below.

    If the table has no rows, the following procedure causes the application to display empty controls. Otherwise, it displays the values stored in each of the columns of the current row of the database.

    Private Sub DisplayCurrentRow()
  If CustomerTable.RowCount = 0 Then
    txtFname.Text = ""
    txtLname.Text = ""
    txtCity.Text = ""
    txtPhone.Text = ""
    lblID.Caption = ""
  Else
    lblID.Caption = _
         CustomerTable.Column("ID").StringValue
    txtFname.Text = _
         CustomerTable.Column("FName").StringValue
    txtLname.Text = _
         CustomerTable.Column("LName").StringValue
    If CustomerTable.Column ("City").IsNull Then
      txtCity.text =""
    Else
      txtCity.Text = _
      CustomerTable.Column("City").StringValue
    End If
    If CustomerTable.Column("Phone").IsNull Then
      txtphone.Text = ""
    Else
      txtphone.Text = _
      CustomerTable.Column("Phone").StringValue
    End If
  End If
End Sub

  3. Call DisplayCurrentRow from the Form's Activated event. This call ensures that the fields get updated when the application starts.

    DisplayCurrentRow
toggle To insert rows into the table

  1. Write code to implement the Insert button.

    In the following procedure, the call to InsertBegin puts the application into insert mode and sets all the values in the row to their defaults. For example, the ID column receives the next autoincrement value. The column values are set and then the new row is inserted.

    Add the following procedure to the Click event of the Insert button (btnInsert).

    Dim fname As String
Dim lname As String
Dim city As String
Dim phone As String

fname = txtFname.Text
lname = txtLname.Text
city = txtCity.Text
phone = txtPhone.Text

Try
    CustomerTable.InsertBegin
    CustomerTable.Column("FName").StringValue = _
      fname
    CustomerTable.Column("LName").StringValue = _
      lname
    If Len(city) > 0 Then
        CustomerTable.Column("City").StringValue = _
      city
    End If
    If Len(phone) > 0 Then
       CustomerTable.Column("Phone").StringValue = _
       phone
    End If
    CustomerTable.Insert
    CustomerTable.MoveLast
    DisplayCurrentRow
    Exit Sub
Catch
    MsgBox "Error:  " & CStr(Err.Description)
End Try

  2. Run the application.

    After an initial message box, the form is displayed.

  3. Insert two rows into the database.

    • Enter a first name of Jane in the first text box and a last name of Doe in the second. Click Insert.

      A row is added to the table with these values. The application moves to the last row of the table and displays the row. The label displays the automatically incremented value of the ID column that UltraLite assigned to the row.

    • Enter a first name of John in the first text box and a last name of Smith in the second. Click Insert.

  4. Click End to end the program.

toggle To move through the rows of the table

  1. Write code to implement the Next and Previous buttons.

    Add the following code to the Click event of the Next button (btnNext).

    If Not CustomerTable.MoveNext Then
    CustomerTable.MoveLast
End If
DisplayCurrentRow

    Add the following code to the Click event of the Previous button (btnPrevious).

    If Not CustomerTable.MovePrevious Then
    CustomerTable.MoveFirst
End If
DisplayCurrentRow

  2. Run the application.

    When the form is first displayed, the controls are empty as the current position is before the first row.

    After the form is displayed, click Next and Previous to move through the rows of the table.

At this stage you can enter data and scroll through the rows of the table.

toggle To update and delete rows in the table

  1. Write code to implement the Update button.

    In the code below, the call to UpdateBegin puts the application into update mode. The column values are updated and then the row itself is updated with a call to Update.

    Add the following code to the Click event of the Update button (btnUpdate):

    Dim fname As String
Dim lname As String
Dim city As String
Dim phone As String

fname = txtFname.Text
lname = txtLname.Text
city = txtCity.Text
phone = txtPhone.Text
Try
    CustomerTable.UpdateBegin
    CustomerTable.Column("FName").StringValue = fname
    CustomerTable.Column("LName").StringValue = lname
    If Len(city) > 0 Then
        CustomerTable.Column("City").StringValue = city
    Else
        CustomerTable.Column("City").SetNull
    End If
    If Len(phone) > 0 Then
       CustomerTable.Column("Phone").StringValue = phone
    End If
    CustomerTable.Update
    DisplayCurrentRow
    Exit Sub
Catch
    MsgBox "Error:  " & CStr(Err.Description)
End Try

  2. Write code to implement the Delete button.

    In the code below, the call to Delete deletes the current row on which the application is positioned.

    Add the following code to the Click event of the Delete button (btnDelete):

    If CustomerTable.RowCount = 0 Then
    Exit Sub
End If
CustomerTable.Delete
CustomerTable.MoveRelative 0
DisplayCurrentRow

  3. Run the application.


Write code to synchronize

The following procedure implements synchronization. Synchronization requires SQL Anywhere Studio.

toggle To write code for the synchronize button

  • Write code to implement the Synchronize button.

    In the code below, the ULSyncParms object contains the synchronization parameters. For example, the ULSyncParms.UserName property specifies that when MobiLink is started, it will add a new user. The ULSyncParms.SendColumnNames property specifies that the column names will be sent to MobiLink so it can generate upload and download scripts.

    Add the following code to the Click event of the Synchronize button (btnSync):

    With Connection.SyncParms
   .UserName = "CrossfireSample"
   .Stream = UltraLiteAFLib.ULStreamType.ulTCPIP
   .Version = "ul_default"
   .SendColumnNames = True
End With
Connection.Synchronize
DisplayCurrentRow


Synchronize your application

The ASA 9.0 Sample database has a Customer table with columns matching those in the customer table in your UltraLite database. The following procedure synchronizes your database with the ASA 9.0 Sample database.

toggle To synchronize your application

  1. From a command prompt, start the MobiLink synchronization server by running the following command line.

    dbmlsrv9 -c "dsn=ASA 9.0 Sample" -v+ -zu+ -za

    The -zu+ and -za command line options provide automatic addition of users and generation of synchronization scripts. For more information about these options, see MobiLink Synchronization Server Options.

  2. Start your UltraLite Crossfire application.

  3. Click Delete repeatedly to delete all the rows in your table.

    Any rows in the table would be uploaded to the Customer table in the ASA 9.0 Sample database.

  4. Synchronize your application.

    Click Synchronize.

    The MobiLink synchronization server window displays the synchronization progress.

  5. When the synchronization is complete, click Next and Previous to move through the rows of the table.


Lesson 4: Deploy to a device

The following procedures deploy your application to either a Palm OS or PocketPC device.

toggle To deploy to a PocketPC device

  1. Configure the application settings.

    • From the AppForge menu, choose Crossfire Settings. A dialog appears.

    • In the left pane, choose Dependencies and click the User Dependencies tab.

    • Click the Add button and select the c:\tutorial\crossfire\tutCustomer.usm. This indicates to Crossfire that the file should be included in the deployment.

    • Choose the PocketPC Settings item in the left pane

    • Enter \tutorial\crossfire for the Device Installation Path.

    • Click OK to close the dialog.

  2. From the AppForge menu, choose Deploy to Device, and select PocketPC/Windows Mobile. If a dialog appears asking if you want to save the project, choose Yes.

  3. On your device, tap Start > Programs.

  4. Tap UltraLiteTutorial to run your application.

toggle To deploy to the Palm device

  1. Configure the application settings.

    • From the AppForge menu, choose Crossfire Settings.

    • In the dialog that appears, choose Dependencies in the left pane and click the User Dependencies tab.

    • Click the Add button and select c:\tutorial\mvb\tutCustomer.pdb. This indicates to Crossfire that the file should be included in the deployment.

    • Choose the Palm OS Settings item in the left pane and enter Syb3 for the Creator ID. Select a valid HotSync name.

    • Click OK to close the dialog.

  2. From the AppForge menu, choose Deploy to Device, and select the Palm OS device. If a dialog appears asking if you want to save the project, choose Yes.

  3. HotSync your device and make sure the application gets sent to the device. After the HotSync process is complete, your application files will be extracted on the device.

  4. Click Home on the device and choose UltraLiteTutorial to run your application.


Summary

Learning accomplishments

During this tutorial, you:

  • created a database schema

  • created an UltraLite application for Crossfire

  • synchronized an UltraLite remote database with an Adaptive Server Anywhere consolidated database

More samples

You can find more sample applications and utilities at [external link] iAnywhere CodeXchange.


UltraLite for MobileVB API Reference

About this chapter

This chapter describes the UltraLite MobileVB API, a set of classes and methods that allow you to write MobileVB code for applications that use UltraLite databases. Each topic contains information about a specific class, method, constant, or enum. The reference is organized by class, with associated methods beneath.

ULAuthStatusCode enumeration
ULColumn class
ULColumnSchema class
ULConnection class
ULConnectionParms class
ULDatabaseManager class
ULDatabaseSchema class
ULIndexSchema class
ULPreparedStatement class
ULPublicationSchema class
ULResultSet class
ULResultSetSchema class
ULSchemaUpgradeState enumeration
ULSQLCode enumeration
ULSQLType enumeration
ULStreamErrorCode enumeration
ULStreamErrorContext enumeration
ULStreamErrorID enumeration
ULStreamType enumeration
ULSyncParms class
ULSyncResult class
ULSyncState enumeration
ULTable class
ULTableSchema class


ULAuthStatusCode enumeration

The ULAuthStatusCode is the auth_status synchronization parameter used in the ULSyncResult object.

Constant | Value
ulAuthStatusUnknown | 0
ulAuthStatusValid | 1000
ulAuthStatusValidButExpiresSoon | 2000
ulAuthStatusExpired | 3000
ulAuthStatusInvalid | 4000
ulAuthStatusInUse | 5000


ULColumn class

The ULColumn object allows you to get and set values from a table in a database. Each column object represents a particular value in a table; the row is determined by the ULTable object.

A note on converting from UltraLite database types to Visual Basic types.
UltraLite attempts to convert from the database column data type to the Visual Basic data type. If a conversion cannot be successfully done, then a ulSQLE_CONVERSION_ERROR is raised.

For information about the table object, see ULTable class.

Properties
AppendByteChunk method
AppendStringChunk method
GetByteChunk method
GetStringChunk method
SetByteChunk method
SetNull method
SetToDefault method


Properties

Prototype | Description
BooleanValue As Boolean | Gets or sets the value of this column for the current row as Boolean.
ByteValue As Byte | Gets or sets the value of this column for the current row as Byte.
DatetimeValue As Date | Gets or sets the value of this column for the current row as Date.
DoubleValue As Double | Gets or sets the value of this column for the current row as Double.
IntegerValue As Integer | Gets or sets the value of this column for the current row as Integer.
IsNull As Boolean (read only) | Indicates whether the column value is NULL.
LongValue As Long | Gets or sets the value of this column for the current row as Long.
RealValue As Single | Gets or sets the value of this column for the current row as Single.
Schema As ULColumnSchema (read only) | Gets the object representing the schema of the column.
StringValue As String | Gets or sets the value of this column for the current row as a String.
UUIDValue As String Gets or sets the value of this column as a UNIQUEIDENTIFIER data type.

When getting this property, UltraLite converts the column value to a string representation of the UUID. If the value is not a valid UUID, a SQLE_CONVERSION_ERROR is raised.

When setting this property, UltraLite converts the string form of the UUID to a binary value before storing it in the database.


AppendByteChunk method

Prototype

AppendByteChunk( _
data As Long, _
data_len As Long _
)
Member of UltraLiteAFLib.ULColumn

Description

Appends bytes to the row's column if the type is ulTypeLongBinary or TypeBinary.

Parameters

data In MobileVB, a pointer to an array of Bytes. To get the pointer to the array of bytes, use the Visual Basic VarPtr() function. In Crossfire, a local variable that is an array of Bytes.

data_len The number of bytes from the array to append.

Errors set

ulSQLE_INVALID_PARAMETER The error occurs if data length is less than 0.

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not LONG BINARY.

Example

The following examples append data to the edata column.

'MobileVB
Dim data (1 to 512) As Byte
' ...
table.Column("edata").AppendByteChunk( _
                  VarPtr(data(1)), 232)
'Crossfire
Dim data (1 to 512) As Byte
' ...
table.Column("edata").AppendByteChunk(data, 232)


AppendStringChunk method

Prototype

AppendStringChunk( chunk As String )
Member of UltraLiteAFLib.ULColumn

Description

Appends the string to the column if the type is TypeLongString or TypeString.

Parameters

data A string to append to the existing string in a table.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not CHAR or LONG VARCHAR.


GetByteChunk method

Prototype

GetByteChunk ( _
offset As Long, _
data As Long, _
data_len As Long, _
filled_len As Long _
) As Boolean
Member of UltraLiteAFLib.ULColumn

Description

Gets data from a TypeBinary or TypeLongBinary column.

Parameters

offset The offset into the underlying array of bytes. The source offset must be greater than or equal to 0, otherwise a ulSQLE_INVALID_PARAMETER error will be raised.

data A pointer to an array of bytes. To get the pointer to the array of bytes, use the Visual Basic VarPtr() function.

data_len The length of the buffer, or array. The data_len must be greater than or equal to 0.

filled_len This is an OUT parameter. After the method is called, it indicates how many bytes were fetched with valid data. If the size of BLOB data is unknown in advance, it is fetched using a fixed-length chunk - one chunk at a time. The last chunk fetched can be smaller than chunk size, so filled_len informs how many bytes of valid data exist in the buffer.

Returns

True if this column value contains more data

False if there is no more data for this column in the database.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type isn't BINARY or LONG BINARY.

ulSQLE_INVALID_PARAMETER The error occurs if the column data type is BINARY and the offset is not 0 or 1, or, the data length is less than 0.

The error also occurs if the column data type is LONG BINARY and the offset is less than 1.

Example

In the following example, edata is a column name.

'MobileVB
Dim filled As Long
Dim more_data As Boolean
Dim data (1 to 512) As Byte
more_data = table.Column("edata").GetByteChunk(0, _
VarPtr(data(1)), 512, filled)
'Crossfire
Dim filled As Long
Dim more_data As Boolean
Dim data (1 to 512) As Byte
more_data = table.Column("edata").GetByteChunk(0, _
data, 512, filled)


GetStringChunk method

Prototype

GetStringChunk( _
offset As Long, _
data As String, _
string_len As Long, _
filled_len As Long _
) As Boolean
Member of UltraLiteAFLib.ULColumn

Description

Gets data from a TypeString or TypeLongString column.

Parameters

offset The character offset into the underlying data from which you start getting the String.

data The variable to receive the string data.

string_length The length of the String you want returned.

filled_len The length of the String fetched.

Returns

True if there is more data to be retrieved from the database.

False if there is no more data.

Errors

ulSQLE_CONVERSION_ERROR The error occurs if the column data type isn't CHAR or LONG VARCHAR.

ulSQLE_INVALID_PARAMETER The error occurs if the column data type is CHAR and the src_offset is greater than 64K.

The error also occurs if src_offset is less than 0 or string length is less than 0.


SetByteChunk method

Prototype

SetByteChunk ( _
data As Long, _
length As Long _
)
Member of UltraLiteAFLib.ULColumn

Description

Sets data in a TypeBinary or TypeLongBinary column.

To append rather than overwriting data, use the AppendByteChunk method.

Parameters

data In MobileVB, a pointer to an array of Bytes. To get the pointer to the array of bytes, use the Visual Basic VarPtr() function. In Crossfire, a local variable that is an array of Bytes.

length The length of the array.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not BINARY or LONG BINARY.

ulSQLE_INVALID_PARAMETER The error occurs if the data length is less than 0 or greater than 64K.

Example

In the following example, edata is a column name and the first 232 bytes of the data variable are stored in the database.

'MobileVB
Dim data (1 to 512) As Byte
' ...
table.Column("edata").SetByteChunk( VarPtr(data(1)), 232)
'Crossfire
Dim data (1 to 512) As Byte
' ...
table.Column("edata").SetByteChunk( data, 232)


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for MobileVB User's Guide

UltraLite for MobileVB API Reference

ULColumn class

SetNull method

Prototype

SetNull( )
Member of UltraLiteAFLib.ULColumn

Description

Sets the column value to null.


SetToDefault method

Prototype

SetToDefault( )
Member of UltraLiteAFLib.ULColumn

Description

Sets the current column to its default value as defined by the database schema. For example, an autoincrement column will be assigned the next available value.


ULColumnSchema class

The ULColumnSchema object allows you to obtain metadata, the attributes of a column, in a table. The attributes are independent of the data in the table.

Properties


Properties

Prototype | Description
AutoIncrement As Boolean (read-only) | Indicates whether this column defaults to an autoincrement value. True if AutoIncrement.
DefaultValue As String (read-only) | Gets the value used if one was not provided when a row was inserted.
GlobalAutoIncrement As Boolean (read-only) | Indicates whether this column defaults to a global autoincrement value.
ID As Integer(read-only) | Gets the ID of the column.
Name As String (read-only) | Gets the column name.
Nullable As Boolean (read-only) | Indicates whether the column permits NULLs.
OptimalIndex As ULIndexSchema (read-only) | Gets the index with this column as its first column.
Precision As Integer (read-only) | Gets the precision value for the column if it is of type ulTypeNumeric.
Scale As Integer (read-only) | Gets the scale value for the column if it is of type ulTypeNumeric.
Size As Long (read-only) | Gets the column size for binary, numeric, and character data types.
SQLType As ULSQLType (read-only) | Gets the SQL type assigned to the column when it was created.


ULConnection class

The ULConnection object represents an UltraLite database connection. It provides methods to get database objects like tables, and to synchronize.

Use WithEvents when receiving synchronization progress
When synchronizing, the ULConnection object can also receive progress information. If you wish to receive this information, you must declare your connection WithEvents. You can perform synchronization without declaring your connection WithEvents; however, your connection object will not receive notification of synchronization progress.
Example

To declare a connection WithEvents, in a MobileVB form, use the following syntax:

Public WithEvents Connection As ULConnection

The addition of WithEvents makes receipt of synchronization progress information possible.

Properties
CancelSynchronize method
ChangeEncryptionKey method
Close method
Commit method
CountUploadRows method
GetNewUUID method
GetTable method
GrantConnectTo method
LastDownloadTime method
OnReceive event
OnSchemaUpgradeProgress event
OnSchemaUpgradeStateChange event
OnSend event
OnStateChange event
OnTableChange event
PrepareStatement method
ResetLastDownloadTime method
RevokeConnectFrom method
Rollback method
RollbackPartialDownload method
StartSynchronizationDelete method
StopSynchronizationDelete method
StringToUUID method
Synchronize method
UUIDToString method


Properties

The following are properties of ULConnection:

Prototype | Description
AutoCommit As Boolean | Indicates the AutoCommit value. If true, all data changes are committed immediately after they are made. Otherwise, changes are not committed to the database until Commit is called. By default, this property is True.
CollationName As String (read-only) | Gets the database character set and sort order.
DatabaseID As Long | Gets or sets the database ID, which determines the starting value for global autoincrement columns. If the database ID has never been set, the value is -1.
DatabaseNew As Boolean (read-only) | Indicates whether the database was newly created for this connection or not.
GlobalAutoIncrementUsage As Integer (read-only) | Gets the percentage of available global autoincrement values that have been used.
IsCaseSensitive As Boolean (read-only) | Indicates whether the database is case sensitive or not.
LastIdentity As Long (read-only) | Gets the most recent value inserted into a column with a default of autoincrement or global autoincrement.
OpenParms As String (read-only) | Gets the string used to open the connection to the database.
Schema As ULDatabaseSchema (read-only) | Gets the ULDatabaseSchema object which represents the definition of the database.
SQLErrorOffset As Integer (read-only) | If PrepareStatement raises an error, indicates the 1-based offset in the SQL statement where the error was noted. If this value is less than or equal to 0, no offset information is available.
SyncParms As ULSyncParms (read-only) | Gets the synchronization parameters object.
SyncResult As ULSyncResult (read-only) | Gets the results of the most recent synchronization.


CancelSynchronize method

Prototype

CancelSynchronize( )
Member of UltraLiteAFLib.ULConnection

Description

When called during synchronization, the method cancels the synchronization. The user can only call this method during one of the synchronization events.

To allow this the ULConnection object must be declared WithEvents.


ChangeEncryptionKey method

Prototype

ChangeEncryptionKey( newkeyAs String )
Member of UltraLiteAFLib.ULConnection

Description

Encrypt the database with the specified key.

Parameters

newkey The new encryption key value for the database.

Example

When you call CreateDatabaseWithParms and pass in the parms object, with a value in place for EncryptionKey, the database is created with encryption. Another way to change the encryption key is by specifying the new encryption key on the ULConnection object. In this example, "apricot" is the key.

Connection.ChangeEncryptionKey( "apricot" )

Connections to the database, such as OpenConnectionWithParms, must, after the database is encrypted, specify apricot as the EncryptionKey property too. Otherwise, the connection will fail.


Close method

Prototype

Close( )
Member of UltraLiteAFLib.ULConnection

Description

Closes the connection to the database. No methods on the ULConnection object or any other database object for this connection should be called after this method is called. If a connection is not explicitly closed, it will be implicitly closed when the application terminates.


Commit method

Prototype

Commit( )
Member of UltraLiteAFLib.ULConnection

Description

Commits outstanding changes to the database. This is only useful if AutoCommit is false.

For more information, see Autocommit under ULConnection Properties


CountUploadRows method

Prototype

CountUploadRows(
[ mask As Long = 0 ], _
[ threshold As Long = -1 ] _
) As Long
Member of UltraLiteAFLib.ULConnection

Description

Returns the number of rows that need to be uploaded when synchronization next takes place.

Parameters

mask An optional, unique identifier that refers to the publications to check. Use 0 for all publications. If not specified, then the value is zero.

threshold An optional parameter representing the maximum number of rows to count. Use -1 to indicate no maximum. If not specified, this value is -1.

Returns

Returns the number of rows that need to be uploaded in next synchronization.


GetNewUUID method

Prototype

GetNewUUID( ) As String
Member of UltraLiteAFLib.ULConnection

Description

Returns a new universally unique identifier. The value is a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, and is typically stored in a column of data type UNIQUEIDENTIFIER.

Returns

Each call returns a new UUID.


GetTable method

Prototype

GetTable( name As String ) As ULTable
Member of UltraLiteAFLib.ULConnection

Description

Returns the ULTable object for the specified table. You must then open the table before data can be read from it.

Parameters

name The name of the table sought.

Returns

Returns the ULTable object.


GrantConnectTo method

Prototype

GrantConnectTo(
userid As String, _
password As String _
)
Member of UltraLiteAFLib.ULConnection

Description

Grants the specified user permission to connect to the database with the given password.

Parameters

userid The user ID being granted authority to connect.

password The password the user ID must specify to connect.


LastDownloadTime method

Prototype

LastDownloadTime( [mask As Long = 0 ] ) As Date
Member of UltraLiteAFLib.ULConnection

Description

Returns the time of last download for the publication(s).

Parameters

mask An optional, unique identifier that refers to the publications to check. Use 0 for all publications. If this parameter is omitted, 0 is used.

Returns

The last download time in the form of a date.


OnReceive event

Prototype

OnReceive(
nBytes As Long, _
nInserts As Long, _
nUpdates As Long, _
nDeletes As Long _
)
Member of UltraLiteAFLib.ULConnection

Description

Reports download information to the application from the consolidated database via MobiLink. This event may be called several times.

Parameters

nBytes Cumulative count of bytes received at the remote application from the consolidated database.

nInserts Cumulative count of inserts received at the remote application from the consolidated database.

nUpdates Cumulative count of updates received at the remote application from the consolidated database.

nDeletes Cumulative count of deletes received at the remote application from the consolidated database.

Example

See the CustDB application for an example of this method.


OnSchemaUpgradeProgress event

Prototype

OnSchemaUpgradeProgress (
nProgress As Long, _
nFinalProgress As Long, _
nOperations As Long _
)
Member of UltraLiteAFLib.ULConnection

Description

Reports the progress of schema upgrades, for display in a status dialog.

Parameters

  • nProgress An approximation of the progress so far. The value is a number between zero and nFinalProgress, enabling you to display a percentage complete value in a dialog box.

  • nFinalProgress The value of the nProgress when the upgrade completes successfully.

  • nOperations An approximation of the amount of work done during the upgrade. The value starts at zero and increases as the upgrade proceeds. It is updated more frequently than nProgress. It can be used as a relative measure to compare against other schema upgrades.

See also
  • Monitoring schema upgrades


OnSchemaUpgradeStateChange event

Prototype

OnSchemaUpgradeStateChange (
newState As ULSchemaUpgradeState, _
oldState As ULSchemaUpgradeState _)

Description

This event is triggered during a database schema upgrade, when the upgrade reaches a new state. The states available are specified in the ULSchemaUpgradeState enumeration.

Parameters

  • newState The state the upgrade is starting.

  • oldState The state just completed.

See also
  • Monitoring schema upgrades
  • ULSchemaUpgradeState enumeration


OnSend event

Prototype

OnSend(
nBytes As Long, _
nInserts As Long, _
nUpdates As Long, _
nDeletes As Long _
)
Member of UltraLiteAFLib.ULConnection

Description

Reports upload information from the remote database via MobiLink to the consolidated database. This event may be called several times.

Parameters

nBytes Cumulative count of bytes sent by the remote application to the consolidated database via MobiLink.

nInserts Cumulative count of inserts sent by the remote application to the consolidated database via MobiLink.

nUpdates Cumulative count of updates sent by the remote application to the consolidated database via MobiLink.

nDeletes Cumulative count of deletes sent by the remote application to the consolidated database via MobiLink.

Example

See the CustDB application for an example of this method.


OnStateChange event

Prototype

OnStateChange(
newState As ULSyncState, _
oldState As ULSyncState _
)
Member of UltraLiteAFLib.ULConnection

Description

This event is called whenever the state of the synchronization changes. For more information, see ULSyncState enumeration.

Parameters

newState The state that the synchronization process is about to enter.

oldState The state that the synchronization process just completed.

Example

See the CustDB application for an example of this method.


OnTableChange event

Prototype

OnTableChange(
newTableIndex As Long, _
numTables As Long _
)
Member of UltraLiteAFLib.ULConnection

Description

This event is called whenever the synchronization process begins synchronizing another table.

Parameters

newTableIndex The index number of the table currently being synchronized. This number is not the same as the table ID, therefore, it cannot be used with the ULDatabaseSchema.GetTableName method.

numTables The number of tables eligible to be synchronized.

Example

See the CustDB application for an example of this method.


PrepareStatement method

Prototype

PrepareStatement(
sqlStatement As String, _
persistent_name As String _
) As ULPreparedStatement
Member of UltraLiteAFLib.ULConnection

Description

Prepares a SQL statement for execution.

Parameters

sqlStatement The SQL statement to prepare.

persistent_name For Palm applications, the persistent name of the statement.

Returns

Returns a ULPreparedStatement. If there was a problem preparing the statement, an error will be raised. The offset into the statement where the error occurred can be determined from the SQLErrorOffset property.


ResetLastDownloadTime method

Prototype

ResetLastDownloadTime( [ mask As Long ] )
Member of UltraLiteAFLib.ULConnection

Description

Resets the time of the most recent download for the publications specified in the mask.

Parameters

mask The mask of the publications to reset. The default is 0, specifying all publications.


RevokeConnectFrom method

Prototype

RevokeConnectFrom( userID As String )
Member of UltraLiteAFLib.ULConnection

Description

Revokes the specified user's ability to connect to the database.

Parameters

userid The user ID whose authority to connect is being revoked.


Rollback method

Prototype

Rollback( )
Member of UltraLiteAFLib.ULConnection

Description

Rolls back outstanding changes to the database. This is only useful if AutoCommit is false.


RollbackPartialDownload method

Roll back the changes from a failed synchronization.

Prototype

RollbackPartialDownload ( )
Member of UltraLiteAFLib.ULConnection

Description

When a communication error occurs during the download phase of synchronization, UltraLite can apply the downloaded changes, so that the synchronization can be resumed from the place it was interrupted. If the download changes are not needed (the user or application does not want to resume the download at this point), RollbackPartialDownload rolls back the failed download transaction.

See also
  • Resuming failed downloads
  • Keep Partial Download synchronization parameter
  • Partial Download Retained synchronization parameter
  • Resume Partial Download synchronization parameter


StartSynchronizationDelete method

Prototype

StartSynchronizationDelete( )
Member of UltraLiteAFLib.ULConnection

Description

Once StartSynchronizationDelete is called, all delete operations are again synchronized.


StopSynchronizationDelete method

Prototype

StopSynchronizationDelete( )
Member of UltraLiteAFLib.ULConnection

Description

Prevents delete operations from being synchronized. This is useful for deleting old information from an UltraLite database to save space, while not deleting this information on the consolidated database.


StringToUUID method

Prototype

StringToUUID(
s_uuid As String, _
buffer_16_bytes As Long _
)
Member of UltraLiteAFLib.ULConnection

Description

Converts a universally unique identifier represented as a String in the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx to a Byte array of 16 bytes. In a MobileVB application, it may be useful to refer to them in their string format. Consequently, the UUIDValue property on the ULColumn object converts from string to binary(16) and vice versa. The StringToUUID function is provided as an easy way to convert a MobileVB String to a Byte array. It does not reference the UltraLite database in any way.

The pointer to the buffer:
The pointer to the buffer must be declared as at least16 bytes. Since Visual Basic does not provide bounds checking, memory could be overwritten if the buffer is too small. In MobileVB, use the VarPtr() function to get the pointer to the buffer. See also ULColumn.UUIDValue property
Not needed in newer databases
In databases created before version 9.0.2, the UNIQUEIDENTIFIER data type is defined as a user-defined data type and functions are needed to convert between binary and string representations of UUID values.

In databases created using version 9.0.2 or later, the UNIQUEIDENTIFIER data type is a native data type and UltraLite carries out conversions as needed. The StringToUUID function is therefore not needed.

For more information, see UNIQUEIDENTIFIER data type [Binary].

Parameters

s_uuid A Universally Unique Identifier passed in as a string. You can obtain a new string UUID using GetNewUUID.

buffer_16_bytes A pointer to a byte array that has at least 16 elements. Use the VarPtr() function to get the pointer value.

Example

The following example will convert the string form of the UUID 0a141e28-323c-4650-5a64-6e78828c96a0 to a binary array:

Dim buff(1 to 16) As Byte
conn.StringToUUID( "0a141e28-323c-4650-5a64-6e78828c96a0", VarPtr(buff(1)) )


Synchronize method

Prototype

Synchronize( )
Member of UltraLiteAFLib.ULConnection

Description

Synchronizes a consolidated database using MobiLink. This function does not return until synchronization is complete, but you can be notified of events if the connection was declared WithEvents.


UUIDToString method

Prototype

UUIDToString( buffer_16_bytes As Long ) As String
Member of UltraLiteAFLib.ULConnection

Description

Converts a UUID from a byte array to a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.

Not needed in newer databases
In databases created before version 9.0.2, the UNIQUEIDENTIFIER data type is defined as a user-defined data type and functions are needed to convert between binary and string representations of UUID values.

In databases created using version 9.0.2 or later, the UNIQUEIDENTIFIER data type is a native data type and UltraLite carries out conversions as needed. The UUIDToString function is therefore not needed.

For more information, see UNIQUEIDENTIFIER data type [Binary].

Parameters

buffer_16_bytes An array of 16 bytes containing a UUID.

Returns

Each call returns a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx


ULConnectionParms class

The ULConnectionParms object allows you to set userID, password, schema file, file on your desktop, and numerous other parameters that specify your connection.

Properties


Properties

The ULConnectionParms class specifies parameters for opening a connection to an UltraLite database.

In UltraLite for MobileVB, ensure you have the ULConnectionParms object on your form and you set connection properties in the ConnectionParms dialog. You use the ULConnectionParms object in conjunction with ULDatabaseManager.CreateDatabaseWithParms and ULDatabaseManager.OpenConnectionWithParms methods.

Note
Databases are created with a single authenticated user, DBA, whose initial password is SQL. By default, connections are opened using the user ID DBA and password SQL.

For more information about the meaning of these parameters, see Connection Parameters.

Prototype | Description
AdditionalParms As String (read-write) Additional parameters specified as name=value pairs separated with semi-colons.

See Additional Parms connection parameter.
CacheSize As Integer (read-write) The size of the cache. CacheSize values are specified in bytes. Use the suffix k or K for kilobytes and use the suffix m or M for megabytes. The default cache size is sixteen pages. Given a default page size of 4 KB, the default cache size is 64 KB.

See Cache Size connection parameter .
ConnectionName As String (read-write) A name for the connection. This is needed only if you create more than one connection to the database.

See Connection Name connection parameter.
DatabaseOnCE As String (read-write) The filename of the database deployed to PocketPC.

See Database On CE connection parameter.
DatabaseOnDesktop As String (read-write) The filename of the database during development.

See Database On Desktop connection parameter.
DatabaseOnPalm As String (read-write) The creator ID for the UltraLite database on the Palm device.

See Database On Palm connection parameter.
EncryptionKey As String (read-write) A key for encrypting the database. OpenConnection and OpenConnectionWithParms must use the same key as specified during database creation. Suggestions for keys are:

  1. Select an arbitrary, lengthy string

  2. Select strings with a variety of numbers, letters and special characters, so as to decrease the chances of key penetration.

See Encryption Key connection parameter .
PageSize As Integer (read-write) The page size for the database.

See Page Size connection parameter .
ParmsUsed As String (read-only) | The parameters used by the ULDatabaseManager. Useful for debugging purposes.
Password As String (read-write) The password for an authenticated user. Databases are initially created with one authenticated user password SQL. Passwords are case-insensitive if the database is case-insensitive and case-sensitive if the database is case-sensitive. The default value is SQL.

See Password connection parameter.
ReserveSize As Integer (read-write) The amount of file system space to reserve for storage of UltraLite persistent data.

See Reserve Size connection parameter .
SchemaOnCE As String (read-write) The schema filename deployed to PocketPC.

See Schema On CE connection parameter .
SchemaOnDesktop As String (read-write) The schema filename during development.

See Schema On Desktop connection parameter .
SchemaOnPalm As String (read-write) The schema PDB on the Palm device.

See Schema On Palm connection parameter .
UserID As String (read-write) The authenticated user for the database. Databases are initially created with one authenticated user DBA. The UserID is case-insensitive if the database is case-insensitive and case-sensitive if the database is case-sensitive. The default value is DBA.

See User ID connection parameter.
VFSOnPalm As Boolean (read-write) Indicates whether the Palm database is on a virtual file system (true) or on the Palm store (false).

See VFS On Palm parameter .


ULDatabaseManager class

The ULDatabaseManager class is used to manage connections and databases. Your application should only have one instance of this object. Creating a database and establishing a connection to it is a necessary first step in using UltraLite. It is suggested that you use CreateDatabaseWithParms, OpenConnectionWithParms and DropDatabaseWithParms, and include checks in your code to ensure that you are connected properly before attempting any DML with the database.

Parms or no parms?
Two types of methods exist for creating, opening and dropping connections to your database: Methods WithParms and methods that do not use the ULConnectionParms object. Methods WithParms allow you to use a ULConnectionParms object to manipulate connection parameters with ease and accuracy. Methods that do not use the ULConnectionParms object require that you can successfully create a connections string and use that connection string in a CreateDatabase, OpenConnection or DropDatabase method.

Properties
CreateDatabase method
CreateDatabaseWithParms method
DropDatabase method
DropDatabaseWithParms method
OpenConnection method
OpenConnectionWithParms method


Properties

The following are properties of ULDatabaseManager:

Prototype | Description
Version As String (read-only) | Gets the version string of the UltraLite component.


CreateDatabase method

CreateDatabase creates a new database and returns a connection to it.

Prototype

CreateDatabase( parms As String ) As ULConnection
Member of UltraLiteAFLib.ULDatabaseManager

Description

Creates a new database and returns a connection to it. It fails if the specified database already exists. A valid schema file must be specified to successfully create a database. To alter the schema of an existing database, use the ULDatabaseSchema ApplyFile method.

Caution
Only one database may be active at a given time. Attempts to create a different database while other connections are open will result in an error.

For more information about ApplyFile, see ULDatabaseSchema class and ApplyFile method.

Parameters

parms A semicolon-separated list of database creation parameters.

Note for VFS card for Palm users
The Palm_fs=vfs parameter needs to be specified both for CreateDatabase and OpenConnection methods if you want to have the database reside on the virtual file system.

For information about connection parameters, see Connection Parameters.

For more information about the Palm_fs parameter, see VFS On Palm parameter .

Returns

Returns a connection to a newly created UltraLite database.

Examples

The following code creates a ULDatabaseManager object. This is the first object you create when writing for UltraLite for MobileVB. Note that CreateDatabase requires that no .udb file exists, and OpenConnection is used when a .udb file already exists.

Dim conn_parms As String
Dim open_parms As String
Dim schema_parms As String

conn_parms = "uid=DBA;pwd=SQL"
open_parms = conn_parms & ";" & _
    "PALM_DB=Syb3;file_name=c:\tutorial\tutCustomer.udb"
schema_parms = open_parms & ";" & _
    "PALM_SCHEMA=tutCustomer;" & _
    "schema_file=c:\tutorial\tutCustomer.usm"

On Error Resume Next

Set Connection = DatabaseMgr.OpenConnection(open_parms)
If Err.Number =  _
    ULSQLCode.ulSQLE_DATABASE_NOT_FOUND _
Then
    Err.Clear
        Set Connection = _
    DatabaseMgr.CreateDatabase(schema_parms)
    If Err.Number <> 0 Then
            MsgBox Err.Description
    End If
End If

For information about connection parameters, see OpenConnection method.


CreateDatabaseWithParms method

CreateDatabaseWithParms creates a new database using a connection parameter object, and returns a connection to it.

Prototype

CreateDatabaseWithParms( parms As ULConnectionParms )
As ULConnection
Member of UltraLiteAFLib.ULDatabaseManager

Description

Creates a new database and returns a connection to it. It fails if the specified database already exists. A valid schema file must be specified to successfully create a database. To alter the schema of an existing database, use the ULDatabaseSchema.ApplyFileWithParms method.

Caution
Only one database may be active at a given time. Attempts to create a different database while other connections are open will result in an error.
Parameters

parms A ULConnectionParms object that holds a set of connection parameters.

Note for VFS card for Palm users
You specify VFSOnPalm in the ULConnectionParms interface.

For more information about the Palm_fs parameter, see VFS On Palm parameter .

Returns

Returns a connection to a newly created UltraLite database. Fails if the specified database already exists.

Examples

The following example assumes you have placed the ULConnectionParms object on your form, named it LoginParms and have specified the database locations and schema locations in the Connection parms properties window.

The following code creates a ULDatabaseManager object. This is the first object you create when writing for UltraLite for MobileVB.

Note that CreateDatabaseWithParms requires that no .udb file exists, and OpenConnectionWithParms is used when a .udb file already exists.

DatabaseMgr.DropDatabaseWithParms LoginParms
Set Connection = DatabaseMgr.CreateDatabaseWithParms(LoginParms)


DropDatabase method

The DropDatabase method deletes a database file.

Prototype

DropDatabase( parms As String )
Member of UltraLiteAFLib.ULDatabaseManager

Description

Deletes the database file. All information in the database file is lost. Fails if the specified database does not exist, or if there exist open connections at the time of DropDatabase is executed.

Parameters

parms The filename for the database.

Example

The following example drops a database:

Dim parms As String
parms = "PALM_DB=Syb1;NT_FILE=c:\temp\ul_CustDB.udb"
DropDatabase(parms)


DropDatabaseWithParms method

The DropDatabaseWithParms method deletes a database file.

Prototype

DropDatabaseWithParms( parms As ULConnectionParms )
Member of

Description

Deletes the database file. All information in the database file is lost.

Parameters

parms The ULConnectionParms object containing vital connection parameters .

Example

The following example assumes you have declared and instantiated a ULConnectionParms object named LoginParms and used it to specify the database location.

DatabaseMgr.DropDatabaseWithParms LoginParms


OpenConnection method

Prototype

OpenConnection( connparms As string ) As ULConnection
Member of UltraLiteAFLib.ULDatabaseManager

Description

If a database exists, use this method to connect to the database. If a database does not exist, or the connection parameters are invalid, the call will fail. Use the error object to determine why the call failed.

The function returns a ULConnection object which provides an open connection to a specified UltraLite database. The database filename is specified using the connparms string. Parameters are specified using a sequence of name=value pairs. If no user ID or password is given, the default is used.

It should contain a value of the form

file_name=UDBFILE
DBF=UDBFILE
palm_db=CreatorID.
Parameters

connparms The parameter used to establish a connection to a database. Parameters are specified as a semicolon separated list of keyword=value pairs. If no user ID or password is given, the default is used.

Note for Palm users
The Palm_fs=vfs parameter needs to be specified both for CreateDatabase and OpenConnection methods when using a database on the Palm virtual file system.
Returns

For more information about the Palm_fs parameter, see VFS On Palm parameter .

The ULConnection object is returned if the connection was successful.

Example

The following example creates a new database connection from the CustDB sample application:

Set Connection = DatabaseMgr.OpenConnection(
"file_name=d:\Dbfile.udb;palm_db=Syb3;CE_file=\myapp\MyDB.udb")


OpenConnectionWithParms method

Prototype

OpenConnectionWithParms( connparms As ULConnectionParms)
As ULConnection
Member of UltraLiteAFLib.ULDatabaseManager

Description

If a database exists, use this method to receive a connection. If a database does not exist, or the connection parameters are invalid, the call will fail. Use the error object to determine why the call failed.

The function returns a ULConnection object which provides an open connection to a specified UltraLite database. The database filename is specified using the connparms object. Parameters are specified using a sequence of name=value pairs. If no user ID or password is given, the default is used.

Parameters

connparms The parameters defining this connection.

Returns

The ULConnection object is returned if the connection was successful.

Example

The following example assumes you have placed the ULConnectionParms object on your form, named it LoginParms and have specified the database locations and schema locations in the ULConnection parms properties window.

Set Connection = DatabaseMgr.OpenConnection(LoginParms)


ULDatabaseSchema class

The ULDatabaseSchema object allows you to obtain the attributes of the database to which you are connected.


Properties

The following are properties of ULDatabaseSchema:

Prototype | Description
DateFormat As String (read-only) | Gets the format for dates retrieved from the database; 'YYYY-MM-DD' is the default. The format of the date retrieved depends on the format used when you created the schema file.
DateOrder As String (read-only) | Indicates the interpretation of date formats; valid values are 'MDY', 'YMD', or 'DMY'.
NearestCentury As String (read-only) | Indicates the interpretation of two-digit years in string-to-date conversions. This is a numeric value that acts as a rollover point. Two digit years less than the value are converted to 20yy, while years greater than or equal to the value are converted to 19yy. The default is 50.
Precision As String (read-only) | Gets the maximum number of digits in the result of any decimal arithmetic.
PublicationCount As Integer (read-only) | Gets the number of publications in the connected database.
Signature As String (read-only) | Gets the database signature, an internal identifier representing the database schema.
TableCount As Integer (read-only) | Gets the number of tables in the connected database.
TimeFormat As String (read-only) | Gets the format for times retrieved from the database.
TimestampFormat As String (read-only) | Gets the format for timestamps retrieved from the database.


ApplyFile method

Prototype

ApplyFile( parms As String )
Member of UltraLiteAFLib.ULDatabaseSchema

Description

Changes the schema of this database. Parms points to the schema file(s) you are applying to the database. This method is only useful on those occasions where you want to modify your existing database structure.

Caution
Although ApplyFile is very safe, ApplyFile can cause data loss under a number of circumstances including (1) if columns are deleted, or (2) if the data type for a column is changed to an incompatible type, or (3) if you upgrade an 8.0.2 database using ApplyFile in UltraLite 9.0.

Parameters

parms The files containing the changes you wish to make to your database schema.

Example
DatabaseSchema.ApplyFile( _
"schema_file=MySchemaFile.usm;palm_schema=MySchema" )


ApplyFileWithParms method

Prototype

ApplyFileWithParms( parms As ULConnectionParms )
Member of UltraLiteAFLib.ULDatabaseSchema

Description

Upgrades the schema of this database using the parameter object Parms, which points to the schema file(s) you are applying to the database. This method is only useful on those occasions where you want to modify your existing database structure.

Caution
Although ApplyFile is very safe, ApplyFileWithParms can cause data loss under a number of circumstances including (1) if columns are deleted, or (2) if the data type for a column is changed to an incompatible type, or (3) if you upgrade an 8.0.2 database using ApplyFile in UltraLite 9.0.
Parameters

parms The object identifying the schema file to apply.


GetPublicationName method

Prototype

GetPublicationName( id As Integer ) As String
Member of UltraLiteAFLib.ULDatabaseSchema

Description

Returns the name of the specified publication. The publication ID can range from 1 to PublicationCount.

Parameters

id The id is the identifier of the publication whose name will be returned.

Returns

Returns the name of a publication in the connected database.

For information about the ULPublicationSchema object, see ULPublicationSchema class.

For more information, see ULDatabaseSchema Properties


GetPublicationSchema method

Prototype

GetPublicationSchema( Name As String ) As ULPublicationSchema
Member of UltraLiteAFLib.ULDatabaseSchema

Description

Use the publication name to retrieve the ULPublicationSchema object.

Parameters

name The name of the publication.

Returns

Returns the ULPublicationSchema object.


GetTableName method

Prototype

GetTableName( id As Integer ) As String
Member of UltraLiteAFLib.ULDatabaseSchema

Description

Returns the name of the table in the connected database that corresponds to the id value you supply. The TableCount property returns the number of tables in the connected database. Each table has a unique number from 1 to the TableCount value, where 1 is the first table in the database, 2 is the second table in the database, and so on. The id for a table my change after a database has had its schema changed.

Parameters

id The id of the table.

Returns

Returns the name of the table for the specified id.


ULIndexSchema class

The ULIndexSchema object allows you to obtain the attributes of an index. An index is an ordered set of columns by which data in a table will be sorted. The primary use of an index is to order the data in a table by one or more columns.

An index can be a foreign key, which is used to maintain referential integrity in a database.


Properties

Prototype | Description
ColumnCount As Integer (read-only) | Gets the number of columns in the index
ForeignKey As Boolean (read-only) | Indicates whether this is a foreign key.
ForeignKeyCheckOnCommit (read-only) | Indicates whether referential integrity is checked only when a commit is done (TRUE) or immediately (FALSE).
ForeignKeyNullable (read-only) | Indicates whether the foreign key columns allow NULL.
Name As String (read-only) | Gets the name of the index
PrimaryKey As Boolean (read-only) | Gets whether this is the primary key for this table.
ReferencedIndexName As String (read-only) | Gets the name of the index referenced by this index if it is a foreign key
ReferencedTableName As String (read-only) | Gets the name of the table referenced by this index if it is a foreign key
UniqueIndex As Boolean (read-only) | Indicates whether values in the index must be unique.
UniqueKey As Boolean (read-only) | Indicates whether the index is a unique constraint on a table. If True, the columns in the index are unique and do not permit NL values


GetColumnName method

Prototype

GetColumnName( col_pos_in_index As Integer ) As String
Member of UltraLiteAFLib.ULIndexSchema

Description

Used to return the names of the columns in the index. The parameter col_pos_in_index must be at least 1 and at most ColumnCount.

Parameters

col_pos_in_index The column position in the index.

Returns

Returns the name of a column in the index.


IsColumnDescending method

Prototype

IsColumnDescending( col_name As String ) As Boolean
Member of UltraLiteAFLib.ULIndexSchema

Description

Indicates whether the specified column in the index is in descending order.

Parameters

col_name The index column name.

Returns

True if the column is descending.

False if the column is ascending.


ULPreparedStatement class

The ULPreparedStatement represents a pre-compiled SQL statement ready for execution. You can use Prepared Statement to run a SQL query. You can also use the ULPreparedStatement to execute the same statement multiple times using numerous input parameters. Since the prepared statement is precompiled, any further additions beyond the first execution take very little extra processing. Use ULPreparedStatement and Dynamic SQL when you want relatively fast DML over multiple rows.

Properties
AppendByteChunkParameter method
AppendStringChunkParameter method
Close method
ExecuteQuery method
ExecuteStatement method
SetBooleanParameter method
SetByteChunkParameter method
SetByteParameter method
SetDatetimeParameter method
SetDoubleParameter method
SetIntegerParameter method
SetLongParameter method
SetNullParameter method
SetRealParameter method
SetStringParameter method


Properties

Prototype | Description
HasResultSet As Boolean (read-only) | Indicates whether the prepared statement generates a result set. True if the statement has a result set, otherwise, false. If true, ExecuteQuery should be called instead of ExecuteStatement.
Plan (read-only) As String | Gets the access plan UltraLite will use to execute a query. This property is intended primarily for use during development.
ResultSetSchema As ULResultSetSchema (read-only) | Gets the schema description for the result set if the statement is for a result set


AppendByteChunkParameter method

Prototype

AppendByteChunkParameter (
param_id As Integer,
data As Long,
data_len As Long)
Member of UltraLiteAFLib.ULPreparedStatement

Description

Appends the buffer of bytes to the row's column if the type is ulTypeLongBinary.

Parameters

parameter_id The 1-based parameter number to set.

data The array of bytes to append.

data_len The number of bytes from the array to append.

Errors set

ulSQLE_INVALID_PARAMETER The error occurs if the data length is less than 0.

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not LONG BINARY.


AppendStringChunkParameter method

Prototype

AppendStringChunkParameter(
param_id As Integer ,
chunk As String )
Member of UltraLiteAFLib.ULPreparedStatement

Description

Appends the string to the column if the type is ulTypeLongString.

Parameters

parameter_id The 1-based parameter number to set.

chunk A string to append to the existing string in a table.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not LONG VARCHAR.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for MobileVB User's Guide

UltraLite for MobileVB API Reference

ULPreparedStatement class

Close method

Prototype

Close( )
Member of UltraLiteAFLib.ULPreparedStatement

Description

Frees resources associated with the ULPreparedStatement.


ExecuteQuery method

Prototype

ExecuteQuery( ) As ULResultSet
Member of UltraLiteAFLib.ULPreparedStatement

Description

Executes the query and returns a result set.

Returns

A ULResultSet object. The ULResultSet is the data you requested in your SELECT statement. To describe the product of your query, see ULResultSetSchema class


ExecuteStatement method

Prototype

ExecuteStatement( ) As Long
Member of UltraLiteAFLib.ULPreparedStatement

Description

Executes the statement.

Returns

The number of rows updated.


SetBooleanParameter method

Prototype

SetBooleanParameter(
param_number As Integer
param_value As Boolean
)
Member of UltraLiteAFLib.ULPreparedStatement

Description

Set the parameter to the Boolean value passed in.

Parameters

param_number The 1-based parameter number to set.

param_value The value the parameter should receive.


SetByteChunkParameter method

Prototype

SetByteChunkParameter(
param_number As Integer,
data As Long,
data_len As Long
)
Member of UltraLiteAFLib.ULPreparedStatement

Description

Sets data in a binary or long binary column.

Parameters

param_number The 1-based parameter number to set.

data An array of bytes.

data_len The number of bytes from the array to set. SetByteChunk writes over the current content. To append to an existing value, see AppendByteChunkParameter method


SetByteParameter method

Prototype

SetByteParameter(
param_number As Integer
param_value As Byte
)
Member of UltraLiteAFLib.ULPreparedStatement

Description

Set the parameter to the Byte value passed in.

Parameters

param_number The 1-based parameter number to set.

param_value The value the parameter should receive.


SetDatetimeParameter method

Prototype

SetDatetimeParameter(
param_number As Integer
param_value As String
)
Member of UltraLiteAFLib.ULPreparedStatement

Description

Set the parameter to the Datetime value passed in.

Parameters

param_number The 1-based parameter number to set.

param_value The value the parameter should receive.


SetDoubleParameter method

Prototype

SetDoubleParameter(
param_number As Integer
param_value As String
)
Member of UltraLiteAFLib.ULPreparedStatement

Description

Set the parameter to the Double value passed in.

Parameters

param_number The 1-based parameter number to set.

param_value The value the parameter should receive.


SetIntegerParameter method

Prototype

SetIntegerParameter(
param_number As Integer
param_value As String
)
Member of UltraLiteAFLib.ULPreparedStatement

Description

Set the parameter to the Integer value passed in.

Parameters

param_number The 1-based parameter number to set.

param_value The value the parameter should receive.


SetLongParameter method

Prototype

SetLongParameter(
param_number As Integer
param_value As String
)
Member of UltraLiteAFLib.ULPreparedStatement

Description

Set the parameter to the Long value passed in.

Parameters

param_number The 1-based parameter number to set.

param_value The value the parameter should receive.


SetNullParameter method

Prototype

SetNullParameter( param_id As Integer )
Member of UltraLiteAFLib.ULPreparedStatement

Description

Set the parameter to NL.

Parameters

parameter_id The 1-based parameter number to set.


SetRealParameter method

Prototype

SetRealParameter(
param_number As Integer
param_value As String
)
Member of UltraLiteAFLib.ULPreparedStatement

Description

Set the parameter to the Long value passed in.

Parameters

param_number The 1-based parameter number to set.

param_value The value the parameter should receive.


SetStringParameter method

Prototype

SetStringParameter(
param_number As Integer
param_value As String
)
Member of UltraLiteAFLib.ULPreparedStatement

Description

Set the parameter to the string passed in.

Parameters

param_number The 1-based parameter number to set.

param_value The value the parameter should receive.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for MobileVB User's Guide

UltraLite for MobileVB API Reference

ULPublicationSchema class

The ULPublicationSchema object allows you to obtain the attributes of a publication.


Properties

Prototype | Description
Mask As Long (read-only) | Gets the mask for the publication
Name As String (read-only) | Gets the name of the publication


ContainsTable method

Prototype

ContainsTable( name As String ) As Boolean
Member of UltraLiteAFLib.ULPublicationSchema

Description

Indicates whether the specified table is part of this publication.

Parameters

name The target table name.

Returns

True if the table is in the publication.

False if the table is not in the publication.


ULResultSet class

The ULResultSet object moves over rows returned by a SQL query. Since the ULResultSet object contains the data returned by a query, you must refresh any query resultset after you have performed DML operations such as INSERT, UPDATE or DELETE. To do this, you should perform ExecuteQuery after you perform ExecuteStatement.

Properties
Close method
GetByteChunk method
GetStringChunk method
MoveAfterLast method
MoveBeforeFirst method
MoveFirst method
MoveLast method
MoveNext method
MovePrevious method
MoveRelative method
IsNull method
GetDatetime method
GetDouble method
GetInteger method
GetLong method
GetReal method
GetString method


Properties

Prototype | Description
BOF As Boolean (read-only) | Indicates whether the current row position is before the first row. Returns True if the current row position is before the first row, otherwise false.
EOF As Boolean (read-only) | Indicates whether the current row position is after the last row. EOF is true if beyond the last row, otherwise false.
RowCount As Long (read-only) | The number of rows in the result set.
Schema As ULResultSetSchema (read-only) | The schema description for this result set.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for MobileVB User's Guide

UltraLite for MobileVB API Reference

ULResultSet class

Close method

Prototype

Close()
Member of UltraLiteAFLib.ULResultSet

Description

Frees all resources associated with this object.


GetByteChunk method

Prototype

GetByteChunk ( _
index As Integer, _
src_offset As Long, _
data As Long, _
data_len As Long, _
filled_len As Long _
) As Boolean
Member of UltraLiteAFLib.ULResultSet

Description

Fills the buffer passed in (which should be an array) with the binary data in the column. Suitable for BLOBS.

Parameters

index The 1-based ordinal of the column containing the binary data.

offset The offset into the underlying array of bytes. The source offset must be greater than or equal to 0, otherwise a SQLE_INVALID_PARAMETER error will be raised. A buffer bigger than 64K is also permissible.

data A pointer to an array of bytes. To get the pointer to the array of bytes, use the Visual Basic VarPtr() function.

data_len The length of the buffer, or array. The data_len must be greater than or equal to 0.

filled_len The number of bytes fetched. Because you don't know how big the BLOB data is in advance, you generally fetch it using a fixed-length chunk, one chunk at a time. The last chunk may be smaller than your chunk size. filled_len reports how many bytes were actually fetched.

Returns

The number of bytes read.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not BINARY or LONG BINARY.

ulSQLE_INVALID_PARAMETER The error occurs if the column data type is BINARY and the offset is not 0 or 1, or, the data length is less than 0.

The error also occurs if the column data type is LONG BINARY and the offset is less than 1.

Example

In the following example, edata is a column name. If the data_len parameter passed in is not sufficiently long, the entire application will terminate.

Dim data (512) As Byte
...
table.Column("edata").GetByteChunk(0,data)


GetStringChunk method

Prototype

GetStringChunk( _
index As Integer, _
offset As Long, _
data As String, _
string_len As Long, _
filled_len As Long _
) As Boolean
Member of UltraLiteAFLib.ULResultSet

Description

Fills the string passed in with the binary data in the column. Suitable for Long Varchars.

Parameters

index The 1-based column ID of the target column.

offset The character offset into the underlying data from which you start getting the string.

data The data string.

string_len The length of the string you want returned.

filled_len The length of the string filled.

Returns

Gets BLOB data from a binary or long binary column.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not CHAR or LONG VARCHAR.

ulSQLE_INVALID_PARAMETER The error occurs if the column data type is CHAR and the src_offset is greater than 64K.

This error also occurs if offset is less than 0 or string length is less than 0.


MoveAfterLast method

Prototype

MoveAfterLast( )
Member of UltraLiteAFLib.ULResultSet

Description

Moves to a position after the last row of the ULResultSet.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for MobileVB User's Guide

UltraLite for MobileVB API Reference

ULResultSet class

MoveBeforeFirst method

Prototype

MoveBeforeFirst( )
Member of UltraLiteAFLib.ULResultSet

Description

Moves to a position before the first row.


MoveFirst method

Prototype

MoveFirst( ) As Boolean
Member of UltraLiteAFLib.ULResultSet

Description

Moves to the first row.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


MoveLast method

Prototype

MoveLast( ) As Boolean
Member of UltraLiteAFLib.ULResultSet

Description

Moves to the last row.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


MoveNext method

Prototype

MoveNext( ) As Boolean
Member of UltraLiteAFLib.ULResultSet

Description

Moves to the next row.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


MovePrevious method

Prototype

MovePrevious( ) As Boolean
Member of UltraLiteAFLib.ULResultSet

Description

Moves to the previous row.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


MoveRelative method

Prototype

MoveRelative( index As Long ) As Boolean
Member of UltraLiteAFLib.ULResultSet

Description

Moves a certain number of rows relative to the current row. Relative to the current position of the cursor in the resultset, positive index values move forward in the resultset, negative index values move backward in the resultset and zero does not move the cursor.

Parameters

index The number of rows to move. The value can be positive, negative, or zero.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


IsNull method

Prototype

IsNull( index As Integer ) As Boolean
Member of UltraLiteAFLib.ULResultSet

Description

Indicates whether this column contains a null value.

Parameters

index The column index value.

Returns

True if the value is Null.


GetDatetime method

Prototype

GetDatetime( index As Integer ) As Date
Member of UltraLiteAFLib.ULResultSet

Description

Gets the column value as an Date.

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a Date.


GetDouble method

Prototype

GetDouble( index As Integer ) As Double
Member of UltraLiteAFLib.ULResultSet

Description

Gets the column value as a Double.

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a Double.


GetInteger method

Prototype

GetInteger( index As Integer ) As Integer
Member of UltraLiteAFLib.ULResultSet

Description

Gets the column value as an Integer.

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as an Integer.


GetLong method

Prototype

GetLong( index As Integer ) As Long
Member of UltraLiteAFLib.ULResultSet

Description

Gets the column value as a Long.

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a Long.


GetReal method

Prototype

GetReal( index As Integer ) As Single
Member of UltraLiteAFLib.ULResultSet

Description

Gets the column value as a Single.

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a Real.


GetString method

Prototype

GetString( index As Integer ) As String
Member of UltraLiteAFLib.ULResultSet

Description

Gets the column value as a String.

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a String.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for MobileVB User's Guide

UltraLite for MobileVB API Reference

ULResultSetSchema class

The ULResultSetSchema provides information about the schema of the result set.

Properties


Properties

Prototype | Description
ColumnCount As Integer (read-only) | Gets the number of columns in the result set
ColumnName As String (read-only) | Gets the name of the column in the result set.
ColumnPrecision As Integer (read-only) | Gets the precision of the datatype for the column if it is numeric.
ColumnScale As Integer (read-only) | Gets the scale of the datatype for the column if it is numeric.
ColumnSize As Integer (read-only) | Gets the size of the datatype for the column.
ColumnSQLType As ULSQLType (read-only) | Gets the ULSQLType of the column.


ULSchemaUpgradeState enumeration

The ULSchemaUpgradeState constants identify states during the upgrade of a database schema.

Constant | Description
ulUpgradeStateStarting | The schema upgrade is starting. This is the only state during which the upgrade may be canceled. If the upgrade is canceled, you receive a second event with state ulUpgradeStateAbort.
ulUpgradeStateUpgrading | The schema upgrade is in progress.
ulUpgradeStateAbort | The schema upgrade has been canceled and the old database is preserved. This state may occur as the result of a recoverable error or user action.
ulUpgradeStateDone | The schema upgrade completed successfully.
ulUpgradeStateError | A critical error occurred and the database is unusable.
See also
  • Upgrading UltraLite database schemas
  • OnSchemaUpgradeProgress event
  • OnSchemaUpgradeStateChange event


ULSQLCode enumeration

The ULSQLCode constants identify SQL codes that may be reported by UltraLite.

For a description of the errors, see the Adaptive Server Anywhere Error Messages book.

Constant | Value
ulSQLE_AGGREGATES_NOT_ALLOWED | -150
ulSQLE_ALIAS_NOT_UNIQUE | -830
ulSQLE_ALIAS_NOT_YET_DEFINED | -831
ulSQLE_BAD_ENCRYPTION_KEY | -840
ulSQLE_BAD_PARAM_INDEX | -689
ulSQLE_CANNOT_ACCESS_FILE | -602
ulSQLE_CANNOT_CHANGE_USER_NAME | -867
ulSQLE_CANNOT_MODIFY | -191
ulSQLE_CANNOT_EXECUTE_STMT | -111
ulSQLE_COLUMN_AMBIGUOUS | -144
ulSQLE_COLUMN_CANNOT_BE_NL | -195
ulSQLE_COLUMN_IN_INDEX | -127
ulSQLE_COLUMN_NOT_FOUND | -143
ulSQLE_COMMUNICATIONS_ERROR | -85
ulSQLE_CONNECTION_NOT_FOUND | -108
ulSQLE_CONVERSION_ERROR | -157
ulSQLE_CURSOROP_NOT_ALLOWED | -187
ulSQLE_CURSOR_ALREADY_OPEN | -172
ulSQLE_CURSOR_NOT_OPEN | -180
ulSQLE_DATABASE_ERROR | -301
ulSQLE_DATABASE_NEW | 123
ulSQLE_DATABASE_NOT_CREATED | -645
ulSQLE_DATABASE_NOT_FOUND | -83
ulSQLE_DATABASE_UPGRADE_FAILED | -672
ulSQLE_DATABASE_UPGRADE_NOT_POSSIBLE | -673
ulSQLE_DATATYPE_NOT_ALLOWED | -624
ulSQLE_DBSPACE_FL | -604
ulSQLE_DIV_ZERO_ERROR | -628
ulSQLE_DOWNLOAD_CONFLICT | -839
ulSQLE_DROP_DATABASE_FAILED | -651
ulSQLE_DYNAMIC_MEMORY_EXHAUSTED | -78
ulSQLE_ENGINE_ALREADY_RUNNING | -96
ulSQLE_ENGINE_NOT_MTIUSER | -89
ulSQLE_ERROR | -300
ulSQLE_ERROR_CALLING_FUNCTION | -622
ulSQLE_EXPRESSION_ERROR | -156
ulSQLE_IDENTIFIER_TOO_LONG | -250
ulSQLE_INDEX_NOT_FOUND | -183
ulSQLE_INDEX_NOT_UNIQUE | -196
ulSQLE_INTERRUPTED | -299
ulSQLE_INVALID_AGGREGATE_PLACEMENT | -862
ulSQLE_INVALID_FOREIGN_KEY | -194
ulSQLE_INVALID_FOREIGN_KEY_DEF | -113
ulSQLE_INVALID_GROUP_SELECT | -149
ulSQLE_INVALID_LOGON | -103
ulSQLE_INVALID_OPTION_SETTING | -201
ulSQLE_INVALID_ORDER | -152
ulSQLE_INVALID_ORDERBY_COLUMN | -854
ulSQLE_INVALID_PARAMETER | -735
ulSQLE_INVALID_SQL_IDENTIFIER | -760
ulSQLE_INVALID_STATEMENT | -130
ulSQLE_LOCKED | -210,
ulSQLE_MEMORY_ERROR | -309
ulSQLE_METHOD_CANNOT_BE_CALLED | -669
ulSQLE_NAME_NOT_UNIQUE | -110
ulSQLE_NOERR | 0
ulSQLE_NOTFOUND | 100
ulSQLE_NOT_IMPLEMENTED | -134
ulSQLE_NO_CURRENT_ROW | -197
ulSQLE_NO_INDICATOR | -181
ulSQLE_OVERFLOW_ERROR | -158
ulSQLE_PERMISSION_DENIED | -121
ulSQLE_PRIMARY_KEY_NOT_UNIQUE | -193
ulSQLE_PRIMARY_KEY_VALUE_REF | -198
ulSQLE_PUBLICATION_NOT_FOUND | -280
ulSQLE_RESOURCE_GOVERNOR_EXCEEDED | -685
ulSQLE_ROW_DROPPED_DURING_SCHEMA_UPGRADE | 130
ulSQLE_SERVER_SYNCHRONIZATION_ERROR | -857
ulSQLE_START_STOP_DATABASE_DENIED | -75
ulSQLE_STATEMENT_ERROR | -132
ulSQLE_SYNTAX_ERROR | -131
ulSQLE_STRING_RIGHT_TRUNCATION | -638
ulSQLE_TABLE_HAS_PUBLICATIONS | -281
ulSQLE_TABLE_IN_USE | -214
ulSQLE_TABLE_NOT_FOUND | -141
ulSQLE_TOO_MANY_CONNECTIONS | -102
ulSQLE_TRALITE_OBJ_CLOSED | -908
ulSQLE_UNABLE_TO_CONNECT_OR_START | -764
ulSQLE_UNABLE_TO_START_DATABASE | -82
ulSQLE_UNCOMMITTED_TRANSACTIONS | -755
ulSQLE_UNKNOWN_FUNC | -148
ulSQLE_UNKNOWN_USERID | -140
ulSQLE_UNSUPPORTED_CHARACTER_SET_ERROR | -869
ulSQLE_UPLOAD_FAILED_AT_SERVER | -794
ulSQLE_WRONG_PARAMETER_COUNT | -154


ULSQLType enumeration

ULSQLType lists the available UltraLite SQL database types used as table column types.

Constant | UltraLite Database Type | Value
ulTypeLong | Integer | 0
ulTypeUnsignedLong | SmallInt | 2
ulTypeShort | UnsignedInteger | 1
ulTypeUnsignedShort | UnsignedSmallInt | 3
ulTypeBig | Big | 4
ulTypeUnsignedBig | UnsignedBig | 5
ulTypeByte | Byte | 6
ulTypeBit | Bit | 7
ulTypeDateTime | Time | 8
ulTypeDate | Date | 9
ulTypeTime | Timestamp | 10
ulTypeDouble | Double | 11
ulTypeReal | Real | 12
ulTypeNumeric | (Var)Binary | 17
ulTypeBinary | LongBinary | 13
ulTypeString | (Var)Char | 15
ulTypeLongString | LongVarchar | 16
ulTypeLongBinary | Numeric | 14
ulTypeUUID | UniqueIdentifier | 18


ULStreamErrorCode enumeration

The ULStreamErrorCode constants identify communications errors during synchronization.

For more information about these errors, see MobiLink Communication Error Messages.

Constant | Value
ulStreamErrorCodeNone | 0
ulStreamErrorCodeParameter | 1
ulStreamErrorCodeParameterNotUint32 | 2
ulStreamErrorCodeParameterNotUint32Range | 3
ulStreamErrorCodeParameterNotBoolean | 4
ulStreamErrorCodeParameterNotHex | 5
ulStreamErrorCodeMemoryAllocation | 6
ulStreamErrorCodeParse | 7
ulStreamErrorCodeRead | 8
ulStreamErrorCodeWrite | 9
ulStreamErrorCodeEndWrite | 10
ulStreamErrorCodeEndRead | 11
ulStreamErrorCodeNotImplemented | 12
ulStreamErrorCodeWouldBlock | 13
ulStreamErrorCodeGenerateRandom | 14
ulStreamErrorCodeInitRandom | 15
ulStreamErrorCodeSeedRandom | 16
ulStreamErrorCodeCreateRandomObject | 17
ulStreamErrorCodeShuttingDown | 18
ulStreamErrorCodeDequeuingConnection | 19
ulStreamErrorCodeSecureCertificateRoot | 20
ulStreamErrorCodeSecureCertificateCompanyName | 21
ulStreamErrorCodeSecureCertificateChainLength | 22
ulStreamErrorCodeSecureCertificateRef | 23
ulStreamErrorCodeSecureCertificateNotTrusted | 24
ulStreamErrorCodeSecureDuplicateContext | 25
ulStreamErrorCodeSecureSetIo | 26
ulStreamErrorCodeSecureSetIoSemantics | 27
ulStreamErrorCodeSecureCertificateChainFunc | 28
ulStreamErrorCodeSecureCertificateChainRef | 29
ulStreamErrorCodeSecureEnableNonBlocking | 30
ulStreamErrorCodeSecureSetCipherSuites | 31
ulStreamErrorCodeSecureSetChainNumber | 32
ulStreamErrorCodeSecureCertificateFileNotFound | 33
ulStreamErrorCodeSecureReadCertificate | 34
ulStreamErrorCodeSecureReadPrivateKey | 35
ulStreamErrorCodeSecureSetPrivateKey | 36
ulStreamErrorCodeSecureCertificateExpiryDate | 37
ulStreamErrorCodeSecureExportCertificate | 38
ulStreamErrorCodeSecureAddCertificate | 39
ulStreamErrorCodeSecureTrustedCertificateFileNotFound | 40
ulStreamErrorCodeSecureTrustedCertificateRead | 41
ulStreamErrorCodeSecureCertificateCount | 42
ulStreamErrorCodeSecureCreateCertificate | 43
ulStreamErrorCodeSecureImportCertificate | 44
ulStreamErrorCodeSecureSetRandomRef | 45
ulStreamErrorCodeSecureSetRandomFunc | 46
ulStreamErrorCodeSecureSetProtocolSide | 47
ulStreamErrorCodeSecureAddTrustedCertificate | 48
ulStreamErrorCodeSecureCreatePrivateKeyObject | 49
ulStreamErrorCodeSecureCertificateExpired | 50
ulStreamErrorCodeSecureCertificateCompanyUnit | 51
ulStreamErrorCodeSecureCertificateCommonName | 52
ulStreamErrorCodeSecureHandshake | 53
ulStreamErrorCodeHttpVersion | 54
ulStreamErrorCodeSecureSetReadFunc | 55
ulStreamErrorCodeSecureSetWriteFunc | 56
ulStreamErrorCodeSocketHostNameNotFound | 57
ulStreamErrorCodeSocketGetHostByAddr | 58
ulStreamErrorCodeSocketLocalhostNameNotFound | 59
ulStreamErrorCodeSocketCreateTcpip | 60
ulStreamErrorCodeSocketCreateUdp | 61
ulStreamErrorCodeSocketBind | 62
ulStreamErrorCodeSocketCleanup | 63
ulStreamErrorCodeSocketClose | 64
ulStreamErrorCodeSocketConnect | 65
ulStreamErrorCodeSocketGetName | 66
ulStreamErrorCodeSocketGetOption | 67
ulStreamErrorCodeSocketSetOption | 68
ulStreamErrorCodeSocketListen | 69
ulStreamErrorCodeSocketShutdown | 70
ulStreamErrorCodeSocketSelect | 71
ulStreamErrorCodeSocketStartup | 72
ulStreamErrorCodeSocketPortOutOfRange | 73
ulStreamErrorCodeLoadNetworkLibrary | 74
ulStreamErrorCodeActsyncNoPort | 75
ulStreamErrorCodeHttpExpectedPost | 89


ULStreamErrorContext enumeration

The ULStreamErrorContext constants identify constants you can use to specify ULStreamErrorContext. The ULStreamErrorContext is the network operation performed when the stream error happens.

Constant | Value
ulStreamErrorContextUnknown | 0
ulStreamErrorContextRegister | 1
ulStreamErrorContextUnregister | 2
ulStreamErrorContextCreate | 3
ulStreamErrorContextDestroy | 4
ulStreamErrorContextOpen | 5
ulStreamErrorContextClose | 6
ulStreamErrorContextRead | 7
ulStreamErrorContextWrite | 8
ulStreamErrorContextWriteFlush | 9
ulStreamErrorContextEndWrite | 10
ulStreamErrorContextEndRead | 11
ulStreamErrorContextYield | 12
ulStreamErrorContextSoftshutdown | 13


ULStreamErrorID enumeration

The ULStreamErrorID is an enumeration of the possible network layers that caused an error in an unsuccessful synchronization.

Constant | Value
ulStreamErrorIDTcpip | 0
ulStreamErrorIDSerial | 1
ulStreamErrorIDFake | 2
ulStreamErrorIDPalmConduit | 3
ulStreamErrorIDPalmSs | 4
ulStreamErrorIDNettech | 5
ulStreamErrorIDRimbb | 6
ulStreamErrorIDHttp | 7
ulStreamErrorIDHttps | 8
ulStreamErrorIDDhCast | 9
ulStreamErrorIDSecure | 10
ulStreamErrorIDCerticom | 11
ulStreamErrorIDJavaCerticom | 12
ulStreamErrorIDCerticomSsl | 13
ulStreamErrorIDCerticomTls | 14
ulStreamErrorIDWirestrm | 15
ulStreamErrorIDWireless | 16
ulStreamErrorIDReplay | 17
ulStreamErrorIDStrm | 18
ulStreamErrorIDUdp | 19
ulStreamErrorIDEmail | 20
ulStreamErrorIDFile | 21
ulStreamErrorIDActivesync | 22
ulStreamErrorIDRsaTls | 23
ulStreamErrorIDJavaRsa | 24


ULStreamType enumeration

The ULStreamType constants identify constants you can use to specify stream type. These represent the types of MobiLink synchronization streams you can use for synchronization.

Constant | Value | Description
ulUnknown | 0 | No stream type has been set. You must set a stream type before synchronization.
ulTCPIP | 1 | TCP/IP stream
ulHTTP | 2 | HTTP stream
ulHTTPS | 3 | HTTPS synchronization
ulPalmConduit | 4 | For HotSync synchronization


ULSyncParms class

The attributes set for the ULSyncParms object determine how the database synchronizes with the consolidated or desktop database. Attributes that are read-only reflect the status of the last synchronization.


Properties

The following are properties of ULSyncParms:

Prototype | Description
CheckpointStore As Boolean | If true, adds checkpoints of the database during synchronization to limit database growth during the synchronization process. This is most useful for large downloads with many updates. See Checkpoint Store synchronization parameter.
DownloadOnly As Boolean | Indicates if a synchronization only downloads data. See Download Only synchronization parameter.
KeepPartialDownload As Boolean | If the synchronisation fails during download because of a communications error, apply those changes that were successfully downloaded, rather than rolling back all the changes. See Keep Partial Download synchronization parameter.
NewPassword As String | Change a user password to this new password string on the next synchronization. See New Password synchronization parameter.
Password As String | The password corresponding to a given user name. See Password synchronization parameter.
PingOnly As Boolean | If true, check the server for liveness, but do not synchronize data. See Ping synchronization parameter.
PublicationMask As Long | Specify the publications to synchronize. The default is to synchronize all data. See Publication synchronization parameter.
ResumePartialDownload As Boolean | Resume a synchronization that failed during download because of a communications error, applying only those changes that were scheduled to be downloaded in the failed synchronization. See Resume Partial Download synchronization parameter.
SendColumnNames As Boolean | If SendColumnNames is true, column names are sent to the MobiLink synchronization server. Column names must be sent to the MobiLink synchronization server for automatic script generation. See Send Column Names synchronization parameter.
SendDownloadAck As Boolean | If SendDownloadAck is true, a download acknowledgement is sent during synchronization. See Send Download Acknowledgement synchronization parameter.
Stream As ULStreamType constants | Set the type of stream to use during synchronization. See Stream Type synchronization parameter.
StreamParms As String | Set network protocol options for the given stream type. See Stream Parameters synchronization parameter and Network protocol options for UltraLite synchronization clients.
UploadOnly As Boolean | Indicates whether a synchronization only uploads data. See Upload Only synchronization parameter.
UserName As String | The MobiLink user name for synchronization. See User Name synchronization parameter.
Version As String | The synchronization script version to run. See Version synchronization parameter.
Examples

The following example sets synchronization parameters for an UltraLite for MobileVB application.

With Connection.SyncParms
    .UserName = "afsample"
    .Stream = ULStreamType.ulTCPIP
    .Version = "ul_default"
    .SendColumnNames = True
End With
Connection.Synchronize


AddAuthenticationParm method

Prototype

AddAuthenticationParm( BSTR parm )
Member of UltraLiteAFLib.ULSyncParms

Description

Adds a parameter to be passed to the authenticate_parms MobiLink synchronization script.

Parameters

parm The parameter being added.

Returns

No return value.

See also

Authentication Parameters synchronization parameter

authenticate_parameters connection event


ClearAuthenticationParms method

Prototype

ClearAuthenticationParms( )
Member of UltraLiteAFLib.ULSyncParms

Description

Clears all parameters that were to be passed to the authenticate_parms MobiLink synchronization script.

Returns

No return value.

See also

Authentication Parameters synchronization parameter

authenticate_parameters connection event


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for MobileVB User's Guide

UltraLite for MobileVB API Reference

ULSyncResult class

The attributes of the ULSyncResult object store the results of the last synchronization.

Properties


Properties

The following are properties of ULSyncResult:

Prototype | Description
AuthStatus As AuthStatusCode (read-only) | Gets the authorization status code for the last synchronization. See Authentication Status synchronization parameter.
PartialDownloadRetained (read-only) | Indicates that the synchronization failed during download, and that a partial download was kept. See Partial Download Retained synchronization parameter.
IgnoredRows As Boolean (read-only) | Indicates whether rows were ignored during the last synchronization. See Ignored Rows synchronization parameter.
StreamErrorCode As ULStreamErrorCode (read-only) | Gets the error code reported by the synchronization stream.
StreamErrorContext As ULStreamErrorContext (read-only) | Gets the basic network operation performed.
StreamErrorID As ULStreamErrorID (read-only) | Gets the network layer reporting the error.
StreamErrorSystem As Long (read-only) | Gets the stream error system-specific code.
UploadOK As Boolean (read-only) | Indicates whether data was uploaded successfully in the last synchronization. See Version synchronization parameter.


ULSyncState enumeration

Constant | Description
ulSyncStateStarting | No synchronization actions have been taken yet.
ulSyncStateConnecting | The synchronization stream has been built, but not yet opened.
ulSyncStateSendingHeader | The synchronization stream has been opened and the header is about to be sent.
ulSyncStateSendingTable | A table is being sent.
ulSyncStateSendingData | Data for the current table is being sent.
ulSyncStateFinishingUpload | The upload is completing. The final count of rows sent is included with this event.
ulSyncStateReceivingUploadAck | An acknowledgement that the upload is complete is being received.
ulSyncStateReceivingTable | A table is being received.
ulSyncStateReceivingData | Data for the current table is being received.
ulSyncStateCommittingDownload | The download is being committed. The final count of rows received is included with this event.
ulSyncStateSendingDownloadAck | An acknowledgement that the download is complete is being sent.
ulSyncStateDisconnecting | The synchronization stream is about to be closed.
ulSyncStateDone | Synchronization has successfully completed. The SyncResult object has been updated.
ulSyncStateError | Synchronization has completed but an error occurred. Check SyncResult and SQLCode for details.
ulSyncStateRollingBackDownload | Synchronization is rolling back the download because an error was encountered during the download. The error will be reported with a subsequent ulSyncStateError progress report.
ulSyncStateCancelled | Synchronization has been canceled.


ULTable class

The ULTable class is used to store, remove, update, and read data from a table.

Before you can work with table data, you must call the Open method. ULTable uses table modes for table operations:

Mode | Description
FindBegin | Begins find mode
InsertBegin | Begins insert mode
LookupBegin | Begins lookup mode
UpdateBegin | Begins update mode

Properties
Close method
Column method
Delete method
DeleteAllRows method
FindBegin method
FindFirst method
FindLast method
FindNext method
FindPrevious method
Insert method
InsertBegin method
LookupBackward method
LookupBegin method
LookupForward method
MoveAfterLast method
MoveBeforeFirst method
MoveFirst method
MoveLast method
MoveNext method
MovePrevious method
MoveRelative method
Open method
Truncate method
Update method
UpdateBegin method


Properties

Prototype | Description
BOF As Boolean (read-only) | Indicates whether the current row position is before the first row. Returns True if the current row position is before the first row, otherwise false.
EOF As Boolean (read-only) | Indicates whether the current row position is after the last row. Returns True if the current row position is before the first row, otherwise false.
IsOpen As Boolean (read-only) | Indicates whether or not the table is currently open.
RowCount As Long (read-only) | Gets the number of rows in the table.
Schema As ULTableSchema (read-only) | Gets information about the table schema.


Close method

Prototype

Close( )
Member of UltraLiteAFLib.ULTable

Description

Frees resources associated with the table. This method should be called after all processing involving the table is complete.

For the Palm OS, if a table is not closed it can be reopened to its current position.


Column method

Column( name As String ) As ULColumn
Member of UltraLiteAFLib.ULTable

Description

Returns the object for the specified column name.

For information about the ULColumn object, see ULColumn class

Parameters

name The name of the column to return.

Returns

Returns a Columns object.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for MobileVB User's Guide

UltraLite for MobileVB API Reference

ULTable class

Delete method

Prototype

Delete( )
Member of UltraLiteAFLib.ULTable

Description

Deletes the current row from the table.


DeleteAllRows method

Prototype

DeleteAllRows( )
Member of UltraLiteAFLib.ULTable

Description

Deletes all rows in the table.

In some applications, it can be useful to delete all rows from tables before downloading a new set of data into the table. Rows can be deleted from the UltraLite database without being deleted from the consolidated database using the ULConnection.StopSynchronizationDelete method or calling Truncate instead of DeleteAllRows.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for MobileVB User's Guide

UltraLite for MobileVB API Reference

ULTable class

FindBegin method

Prototype

FindBegin( )
Member of UltraLiteAFLib.ULTable

Description

Prepares a table for a find.


FindFirst method

Prototype

FindFirst( [num_columns As Long = 32767] ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Move forwards through the table from the beginning, looking for a row that exactly matches a value or set of values in the current index.

The current index is that used to specify the sort order of the table. It is specified when your application calls the Open method. The default index is the primary key.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that exactly matches the index value. On failure the cursor position is after the last row (EOF).

Note : Requires that FindBegin be called prior to using this method.

Parameters

num_columns An optional parameter referring to the number of columns to be used in the FindFirst. For example, if 2 is passed, the first two columns are used for the FindFirst. If num_columns exceeds the number of columns indexed, all columns are used in FindFirst.

Returns

True if successful.

False if unsuccessful.


FindLast method

Prototype

FindLast( [ num_columns As Long = 32767 ] ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Move backwards through the table from the end, looking for a row that matches a value or set of values in the current index.

The current index is used to specify the sort order of the table. It is specified when your application calls the Open method. The default index is the primary key.

For more information, see Open method.

To specify the value to search for, set the column value for each column in the index for which you want to find the value. The cursor is left on the last row found that exactly matches the index value. On failure the cursor position is before the first row (BOF).

Note
Requires that FindBegin be called prior to using this method.
Parameters

num_columns An optional parameter referring to the number of columns to be used in the FindLast. For example, if 2 is passed, the first two columns are used for the FindLast. If num_columns exceeds the number of columns indexed, all columns are used in FindLast.

Returns

True if successful.

False if unsuccessful.


FindNext method

Prototype

FindNext( [ num_columns As Long = 32767 ] ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Move forwards through the table from the current position, looking for the next row that exactly matches a value or set of values in the current index.

The current index is that used to specify the sort order of the table. It is specified when your application calls the Open method. The default index is the primary key.

For more information, see Open method.

The cursor is left on the first row found that exactly matches the index value. On failure, the cursor position is after the last row (EOF).

Note : Must be preceded by FindFirst or FindLast.

Parameters

num_columns An optional parameter referring to the number of columns to be used in the FindNext. For example, if 2 is passed, the first two columns are used for the FindNext. If num_columns exceeds the number of columns indexed, all columns are used in FindNext.

Returns

True if successful.

False if unsuccessful (EOF).


FindPrevious method

Prototype

FindPrevious( [ num_columns As Long = 32767 ] ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Move backwards through the table from the current position, looking for the previous row that exactly matches a value or set of values in the current index.

The current index is that used to specify the sort order of the table. It is specified when your application calls the Open method. The default index is the primary key.

For more information, see Open method.

On failure it is positioned before the first row (BOF).

Parameters

num_columns An optional parameter referring to the number of columns to be used in the FindPrevious. For example, if 2 is passed, the first two columns are used for the FindPrevious. If num_columns exceeds the number of columns indexed, all columns are used in FindPrevious.

Returns

True if successful.

False if unsuccessful (BOF).


Insert method

Prototype

Insert( ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Inserts a row in the table with values specified in previous Set methods. Must be preceded by InsertBegin. Set for each ULColumn object.

Returns

True if successful.

False if unsuccessful (BOF).


InsertBegin method

Prototype

InsertBegin( )
Member of UltraLiteAFLib.ULTable

Description

Prepares a table for inserting a new row, setting column values to their defaults.

Examples

In this example, InsertBegin sets insert mode to allow you to begin assigning data values to CustomerTable columns.

CustomerTable.InsertBegin
CustomerTable.Column("Fname").StringValue = fname
CustomerTable.Column("Lname").StringValue = lname
CustomerTable.Insert
See also

UpdateBegin method


LookupBackward method

Prototype

LookupBackward( [ num_columns As Long = 32767 ] ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Move backwards through the table starting from the end, looking for the first row that matches or is less than a value or set of values in the current index.

The current index is that used to specify the sort order of the table. It is specified when your application calls the Open method. The default index is the primary key.

For more information, see Open method.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the last row that matches or is less than the index value. On failure (that is, if no row is less than the value being looked for), the cursor position is before the first row (BOF).

Parameters

num_columns For composite indexes, the number of columns to use in the lookup.

Returns

True if successful.

False if unsuccessful.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for MobileVB User's Guide

UltraLite for MobileVB API Reference

ULTable class

LookupBegin method

Prototype

LookupBegin( )
Member of UltraLiteAFLib.ULTable

Description

Prepares a table for a lookup.


LookupForward method

Prototype

LookupForward( [num_columns As Long = 32767 ] ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Move forward through the table starting from the beginning, looking for the first row that matches or is greater than a value or set of values in the current index.

The current index is that used to specify the sort order of the table. It is specified when your application calls the Open method. The default index is the primary key.

For more information, see Open method.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is greater than the index value. On failure (that is, if no rows are greater than the value being looked for), the cursor position is after the last row (EOF).

Parameters

num_columns For composite indexes, the number of columns to use in the lookup.

Returns

True if successful.

False if unsuccessful.


MoveAfterLast method

Prototype

MoveAfterLast( ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Moves to a position after the last row.

Returns

True if successful.

False if the operation fails.


MoveBeforeFirst method

Prototype

MoveBeforeFirst( ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Moves to a position before the first row.

Returns

True if successful.

False if the operation fails.


MoveFirst method

Prototype

MoveFirst( ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Moves to the first row.

Returns

True if successful.

False if there is no data in the table.


MoveLast method

Prototype

MoveLast( ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Moves to the last row.

Returns

True if successful.

False if there is no data in the table.


MoveNext method

Prototype

MoveNext( ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Moves to the next row.

Returns

True if successful.

False if there is no more data in the table. For example, MoveNext fails if there are no more rows.


MovePrevious method

Prototype

MovePrevious( ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Moves to the previous row.

Returns

True if successful.

False if there is no more data in the table. For example, MovePrevious fails if there are no rows.


MoveRelative method

Prototype

MoveRelative( index As Long ) As Boolean
Member of UltraLiteAFLib.ULTable

Description

Moves a certain number of rows relative to the current row.

Parameters

index The number of rows to move. The value can be positive, negative, or zero. Zero is useful if you want to repopulate a row buffer.

Returns

True if successful.

False if the move failed, as may happen, for example, if the cursor is positioned beyond the first or last row.


Open method

Prototype

Open(
[ index_name As String ], _
[ persistent_name As String ] _
)
Member of UltraLiteAFLib.ULTable

Description

Opens the table so it can be read or manipulated. By default, the rows are ordered by primary key. By supplying an index name, the rows can be ordered in other ways.

The cursor is positioned before the first row in the table.

Parameters

index_name An optional parameter referring to the name of the index.

persistent_name For Palm Computing Platform applications, an optional parameter referring to the stored name of the table.


Truncate method

Prototype

Truncate( )
Member of UltraLiteAFLib.ULTable

Description

Removes all data from this table. The changes are not synchronized, so that on synchronization, it does not affect the data in the consolidated database.

For more information, see StartSynchronizationDelete method.


Update method

Prototype

Update( )
Member of UltraLiteAFLib.ULTable

Description

Updates a row in the table with values specified in ULColumn methods.

Note : Must be preceded by a call to UpdateBegin.


UpdateBegin method

Prototype

UpdateBegin( )
Member of UltraLiteAFLib.ULTable

Description

Prepares a table for modifying the contents of the current row.

Example
CustomerTable.UpdateBegin
CustomerTable.Column("Fname").StringValue = fname
'...
CustomerTable.Update


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for MobileVB User's Guide

UltraLite for MobileVB API Reference

ULTableSchema class

The ULTableSchema object allows you to obtain the attributes of a table.


Properties

The ULTableSchema represents metadata about the table. The following are properties of the ULTableSchema class:

Prototype | Description
ColumnCount As Integer (read-only) | The number of columns in this table
IndexCount As Integer (read-only) | The number of indexes on this table
Name As String (read-only) | This table's name
NeverSynchronized As Boolean (read-only) | Indicates if the table is always excluded from synchronization.
PrimaryKey As ULIndexSchema (read-only) | The primary key for this table.
UploadUnchangedRows As Boolean (read-only) | Indicates if all rows in the table should be uploaded on synchronization, rather than just the rows changed since the last synchronization.


GetColumnName method

Prototype

GetColumnName( id As Integer ) As String
Member of UltraLiteAFLib.ULTableSchema

Description

Returns the name of the column that corresponds to the id value you supply. The ColumnCount property returns the number of columns in the table. Each column has a unique number from 1 to the ColumnCount value, where 1 is the first column in the table, 2 is the second column in the table, and so on.

Parameters

id The id of the column.

Returns

The name of a column.


GetIndex method

Prototype

GetIndex( name As String ) As ULIndexSchema
Member of UltraLiteAFLib.ULTableSchema

Description

Returns the ULIndexSchema object for the specified index.

For information about the ULIndexSchema object, see ULIndexSchema class.

Parameters

name The name of the index.

Returns

Returns a schema object for a given index on the table.


GetIndexName method

Prototype

GetIndexName( id As Integer ) As String
Member of UltraLiteAFLib.ULTableSchema

Description

Returns the name of the index in the table that corresponds to the id value you supply. The IndexCount property returns the number of indexes in the table. Each index has a unique number from 1 to the IndexCount value, where 1 is the first index in the table, 2 is the second index in the table, and so on.

Parameters

name The id of the index.

Returns

Returns the name of the index.


InPublication method

Prototype

InPublication( publicationName As String ) As Boolean
Member of UltraLiteAFLib.ULTableSchema

Description

Indicates whether this table is part of the specified publication.

Parameters

publicationName The name of the publication you are checking.

Returns

True if the table is part of the publication.

False if the table is not part of the publication.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite ActiveX User's Guide

Version 9.0.2

DC36293-01-0902-01

October 2004

Copyright
About This Manual
Introduction to UltraLite ActiveX
Understanding UltraLite ActiveX Development
Tutorial: A Sample UltraLite ActiveX Application
Tutorial: An UltraLite ActiveX Application for Pocket IE
UltraLite ActiveX API Reference


About This Manual

Subject

This manual describes UltraLite ActiveX. With UltraLite ActiveX you can develop and deploy database applications to handheld, mobile, or embedded devices running Windows CE.

Audience

This manual is intended for eMbedded Visual Basic and JScript application developers who want to take advantage of the performance, resource efficiency, robustness, and security of an UltraLite relational database for data storage and synchronization.

Familiarity with eMbedded Visual Basic or JScript is assumed.


Introduction to UltraLite ActiveX

About this chapter

This chapter introduces UltraLite ActiveX. It assumes that you are familiar with the features of UltraLite, as described in Welcome to UltraLite.


UltraLite ActiveX features

UltraLite ActiveX is a relational data management system for mobile devices. It has the performance, resource efficiency, robustness, and security required by business applications. UltraLite also provides synchronization with enterprise data stores.

System requirements and supported platforms


System requirements and supported platforms

Development platforms

To develop applications using UltraLite ActiveX, you require the following:

  • One of the following:

    • eMbedded Visual Basic 3.0, for development using Visual Basic.

    • Pocket Internet Explorer, for development using JScript.

For more information, see UltraLite development platforms.

Target platforms

UltraLite ActiveX supports the following target platforms:

  • Windows CE 3.0 and higher, with Pocket PC on the ARM and MIPS processors.

For more information, see UltraLite target platforms.


UltraLite ActiveX architecture

The UltraLite programming interface exposes a set of objects for data manipulation using an UltraLite database. The following figure describes the object hierarchy.

The UltraLite ActiveX object hierarchy

The following list describes some of the more commonly-used high level objects.

  • ULDatabaseManager manages connections to UltraLite databases.

    For more information, see ULDatabaseManager class.

  • ULConnectionParms holds a set of connection parameters.

    For more information, see ULConnectionParms class.

  • ULConnection represents a database connection, and governs transactions.

    For more information, see ULConnection class.

  • ULPreparedStatement, ULResultSet, and ULResultSetSchema manage database requests and their results using SQL.

    For more information, see ULPreparedStatement class, ULResultSet class, and ULResultSetSchema class.

  • ULTable and ULColumn manage data using a table-based API.

    For more information, see ULTable class and ULColumn class.

  • ULSyncParms and ULSyncResult manage synchronization through the MobiLink synchronization server.

    For more information about synchronization with MobiLink, see UltraLite Clients.


Understanding UltraLite ActiveX Development

About this chapter

This chapter explains how to develop applications using UltraLite ActiveX.

For a hands-on tutorial, see Tutorial: A Sample UltraLite ActiveX Application or Tutorial: An UltraLite ActiveX Application for Pocket IE

Preparing to use UltraLite ActiveX
Working with the database schema
Connecting to an UltraLite database
Using frames to maintain application state (JScript)
Encryption and obfuscation
Working with data using dynamic SQL
Working with data using the table API
Accessing schema information
Handling errors
Authenticating users
Synchronizing data
Deploying UltraLite applications


Preparing to use UltraLite ActiveX

The following procedures describe the steps you must take before you can build an application using UltraLite ActiveX.

Adding UltraLite ActiveX to the eMbedded Visual Basic design environment
Adding UltraLite ActiveX to a Windows CE device
Deploying a schema file to a Windows CE device
Working with JScript


Adding UltraLite ActiveX to the eMbedded Visual Basic design environment

To access the UltraLite ActiveX control from your eMbedded Visual Basic project, you must add UltraLite ActiveX to the design environment.

The following procedure is only required for eMbedded Visual Basic applications.

toggle To add a reference to UltraLite ActiveX

  1. From the eMbedded Visual Basic menu, choose Project > References.

  2. If iAnywhere Solutions, ActiveX for UltraLite 9.0 is included in the list of available references, select it and click OK.

    If iAnywhere Solutions, ActiveX for UltraLite 9.0 does not appear in the list of available references:

    • Add the control to the list of available references.

      Browse to the UltraLite\UltraLiteActiveX\win32 subdirectory of your SQL Anywhere 9.0 installation. Open uldo9.dll.

    • Select iAnywhere Solutions, ActiveX for UltraLite 9.0 and click OK.


Adding UltraLite ActiveX to a Windows CE device

To debug applications using the emulator, you must add the UltraLite ActiveX control to the emulator. To deploy applications to your Windows CE device, you must add the UltraLite ActiveX control to the device. Both of these tasks can be carried out using the Windows CE Control Manager.

The following procedure applies to both JScript and eMbedded Visual Basic development. If you do not have eMbedded Visual Basic installed on your computer, you can copy the appropriate DLL to the \Windows directory on your device and register it using regsvrce.exe. If you do not have regsvrce.exe on your device, you can copy it to your device from the Microsoft Windows CE SDK.

toggle To add the UltraLite ActiveX control to Windows CE

  1. From the eMbedded Visual Basic menu, choose Tools > Remote Tools > Control Manager.

  2. In the left pane, open the device you are developing for, such as Pocket PC.

  3. Open the device to which you are deploying, such as Pocket PC Emulation.

  4. Choose Control > Add New Control.

  5. Browse to one of the following platform-specific files, located in subdirectories of your SQL Anywhere installation:

    • ARM UltraLite\UltraLiteActiveX\ce\arm\uldo9.dll

    • MIPS UltraLite\UltraLiteActiveX\ce\mips\uldo9.dll

    • Emulator UltraLite\UltraLiteActiveX\ce\emulator30\uldo9.dll

    • Intel 386 UltraLite\UltraLiteActiveX\ce\386\uldo9.dll

  6. Click Open.


Deploying a schema file to a Windows CE device

A schema file is used in the initial creation of an UltraLite database to specify the structure of the database.

The following procedure deploys an UltraLite schema file to a Windows CE device.

For information about creating an UltraLite schema file, see Creating UltraLite database schema files.

toggle To deploy a schema file to Windows CE

  1. From the eMbedded Visual Basic menu, choose Tools > Remote Tools > File Viewer.

  2. If your device does not appear in the left pane, connect to the device:

    • Choose Connection > Add Connection.

    • Select your device from the list and click OK to establish a connection.

  3. Copy the schema file to the device

    • Select a destination directory on the device.

    • Choose File > Export File.

    • Locate the schema (.usm) file.

    • Click OK to export the file to the device.


Working with JScript

The following sections describe how to set up your HTML page in order to optimize the performance of UltraLite ActiveX.

Cached pages

To prevent Pocket IE from using locally cached pages and to ensure all contact is dynamically recalculated, the page expiry should be set to 0. This will cause Pocket IE to always reload the page. Use the following as the first line of your HTML document.

<META HTTP-EQUIV="Expires" CONTENT="0">
Script execution order

To force scripts to run before the page is loaded, for example, to get a database connection which results in dynamic HTML content, place those scripts in the HTML head:

<head> <script>... </script></head>
Pocket Internet Explorer limitations

The JScript language supported by Pocket IE is incompatible with that of Internet Explorer 4 and up, in the following ways:

  • Pocket IE JScript is case insensitive. Scripts written for Pocket IE may not work on IE unless the proper case is used.

  • The BUTTON tag is not supported, but a button can be created using <INPUT TYPE="BUTTON">.

  • HTML tag names are in the same namespace as JScript functions. Ensure that the name of an HTML element does not conflict with any function names in the current document.

    For example, pressing this button will cause an error:

    <SCRIPT>
function b_Done() { ... }
</SCRIPT>
<INPUT NAME="b_Done" TYPE="BUTTON" VALUE="Done" onClick="b_Done()">

  • Dynamic HTML is not supported by Pocket IE. To get dynamic content, you can emit HTML with document.write, or by setting DIV contents.


Changing the schema of a database

To change the schema of an existing database, create a schema file with the new schema and apply this schema to the existing database. In most cases there will be no data loss, but data loss can occur if columns are deleted or if the data type for a column is changed to an incompatible type.

For more information about these methods, see ApplyFile method and ApplyFileWithParms method.

For information about preparing a new schema file for deployment, see Upgrading UltraLite database schemas.

Example

The following code applies a new schema file.

' eMbedded Visual Basic
Dim db As ULDatabaseManager
Dim conn As ULConnection
Set db = CreateObject("UltraLite.ULDatabaseManager")
Set conn = db.OpenConnection("dbf = \My Documents\mydb.udb")
conn.Schema.ApplyFile("\My Documents\myschema.usm")
// JScript
var db;
var conn;
db = new ActiveXObject("UltraLite.ULDatabaseManager");
conn = db.OpenConnection("dbf = \\My Documents\\mydb.udb");
conn.Schema.ApplyFile("\\My Documents\\myschema.usm");


Connecting to an UltraLite database

UltraLite applications must connect to a database before carrying out operations on the data in it. This section describes how to connect to an UltraLite database.

Using the ULConnection object

The following properties of the ULConnection object govern global application behavior.

For more information about the ULConnection object, see ULConnection class.

  • Commit behavior By default, UltraLite applications are in AutoCommit mode. Each insert, update, or delete statement is committed to the database immediately. Set ULConnection.AutoCommit to false to build transactions into your application. Turning AutoCommit off and performing commits directly can improve the performance of your application.

    For more information, see Commit method.

  • User authentication You can change the user ID and password for the application from the default values of DBA and SQL by using the GrantConnectTo and RevokeConnectFrom methods.

    For more information, see Authenticating users.

  • Synchronization A set of objects governing synchronization are accessed from the ULConnection object.

    For more information, see Synchronizing data.

  • Tables UltraLite tables are accessed using the ULConnection.GetTable method.

    For more information, see GetTable method.

Connecting to a database

You can connect to a database using either a ULConnectionParms object or a connection string. Methods that use a ULConnectionParms object allow you to manipulate connection parameters with ease and accuracy. Methods that use a connection string require that you successfully create a connections string.

The following procedure uses a ULConnectionParms object to connect to an UltraLite database.

For more information about connecting to an UltraLite database using a ULConnectionParms object, see CreateDatabaseWithParms method and OpenConnectionWithParms method.

toggle To connect to an UltraLite database using ULConnectionParms

  1. Create a ULDatabaseManager object.

    You should create only one DatabaseManager object per application. This object is at the root of the object hierarchy. For this reason, it is often best to declare the DatabaseManager object as global to the application or as a class-level variable.

    ' eMbedded Visual Basic
Dim DatabaseMgr As ULDatabaseManager
Set DatabaseMgr = CreateObject("UltraLite.ULDatabaseManager")
    // JScript
var DatabaseMgr;
DatabaseMgr = new ActiveXObject( "UltraLite.ULDatabaseManager" );

  2. Declare a ULConnection object.

    Most applications use a single connection to an UltraLite database, and keep the connection open all the time. For this reason, it is often best to declare the ULConnection object as global to the application.

    ' eMbedded Visual Basic
Dim Connection As ULConnection
    // JScript
var Connection;

  3. Create a ULConnectionParms object.

    ' eMbedded Visual Basic
Dim LoginParms As ULConnectionParms
Set LoginParms = CreateObject("UltraLite.ULConnectionParms")
    // JScript
var LoginParms;
LoginParms = new ActiveXObject("UltraLite.ULConnectionParms");

  4. Set the required properties of the ULConnectionParms object.

    For example, the following code specifies the location of the database on the Windows CE device as \tutorial\tutorial.udb.

    ' eMbedded Visual Basic
LoginParms.DatabaseOnCE = "\tutorial\tutorial.udb"
    // JScript
LoginParms.DatabaseOnCE = "\\tutorial\\tutorial.udb";

    Using the following properties, you must specify a schema file for CreateDatabaseWithParms or a database file for OpenConnectionWithParms. For information about additional properties, see Properties.

    Keyword | Description
    DatabaseOnCE | The path and filename of the UltraLite database on Windows CE.
    DatabaseOnDesktop | The path and filename of the UltraLite database on the desktop machine
    SchemaOnCE | The path and filename of the UltraLite schema on Windows CE.
    SchemaOnDesktop | The path and filename of the UltraLite schema on the desktop machine.

  5. Open a connection to the database.

    CreateDatabaseWithParms and OpenConnectionWithParms return an open connection as a ULConnection object. Each method takes a single ULConnectionParms object as its argument.

    The following code attempts to connect to an existing database. If the database does not exist, the OpenConnectionWithParms method returns an error. This causes CreateDatabaseWithParms to create a database using the specified schema file.

    In Crossfire, be sure to include the GetOcx method on the ULConnectionParms object.

    ' eMbedded Visual Basic
On Error Resume Next
Set Connection = DatabaseMgr.OpenConnectionWithParms( LoginParms )
if Err.Number <> ULSQLCode.ulSQLE_NOERROR Then
  Set Connection = DatabaseMgr.CreateDatabaseWithParms( LoginParms )
End If
    // JScript
DatabaseMgr.ErrorResume = true;
Connection = DatabaseMgr.OpenConnectionWithParms( LoginParms );
if ( DatabaseMgr.LastErrorCode != ULSQLCode.ulSQLE_NOERROR ) {
  Connection = DatabaseMgr.CreateDatabaseWithParms( LoginParms );
}


Using frames to maintain application state (JScript)

In Pocket IE, UltraLite ActiveX is accessed using JScript embedded on an HTML page.

In the following code, a ULDatabaseManager object is created. When a page containing this script is loaded, a new ULDatabaseManager object is created. When the browser moves to another page, that object is discarded. If a database connection was obtained on one page, it is lost when that page is unloaded.

<SCRIPT LANGUAGE="JScript">
var DatabaseMgr;
DatabaseMgr = new ActiveXObject( "UltraLite.ULDatabaseManager" );
</SCRIPT>

Losing application state, including database connections, whenever a form changes, is slow and expensive. To avoid this, Pocket IE applications can use HTML frames to maintain application state. The database connection can be kept by the frameset document. Pocket IE requires at least two frames within a frameset, and draws a three-pixel border between the frames.

Note
Support for frames is not included in versions of Pocket IE prior to 1.1.

The following code defines two frames.

// JScript
<frameset rows="5%,*" BORDER=0>
<frame SRC="topline.htm" NAME="TopLine" MARGINWIDTH=0 MARGINHEIGHT=0>
<frame SRC="connect.htm" NAME="Connect" MARGINWIDTH=0 MARGINHEIGHT=0>
</frameset>
<SCRIPT LANGUAGE="JScript">
var Connection;      // UltraLite Connection
var DatabaseMgr;  // UltraLite Database Manager
</SCRIPT>

In the CustDB example, the minimal frame defined in topline.htm is a placeholder that displays the application name at the top of the screen. The rest of the screen is used to display the other pages of the application. The HTML and JScript in connect.htm provide the initial form for the application. Since all these forms will be swapped into the same frameset, they can access their parent frameset objects using window.topwindow.

The following code creates a new variable, conn, and assigns the connection created in the top frame to it. If you are in top, referencing the connection as top.Connection is optional.

// JScript
<SCRIPT>
function usingConnection() {
  if ( top.Connection == null ) {
    return;     // not yet connected..
  }
  var conn = top.Connection;
  ...
}
</SCRIPT>

To swap forms in and out of the frameset, a JScript function can use the document.location.replace method. The following code closes the current connection and returns to the connect form.

// JScript
<SCRIPT>
function exitApp() {
  if ( top.Connection != null ) {
    top.Connection.Close();
  }
  document.location.replace("connect.htm");
}
</SCRIPT>
<INPUT NAME="b_Done" TYPE="BUTTON" VALUE="Done" onClick="exitApp()">


Encryption and obfuscation

You can encrypt or obfuscate your UltraLite database using UltraLite ActiveX.

Encryption

To create a database with encryption, set the ULConnectionParms.EncryptionKey property. When you call CreateDatabaseWithParms and pass in the ConnectionParms object, the database created and encrypted with the specified key.

For more information about the EncryptionKey property, see Encryption Key connection parameter and ChangeEncryptionKey method.

Example

You can change the encryption key by specifying the new encryption key on the Connection object. In this example, "apricot" is the encryption key.

Connection.ChangeEncryptionKey("apricot")

After the database is encrypted, connections to the database must specify the correct encryption key. Otherwise, the connection fails.

Obfuscation

To obfuscate the database, specify obfuscate=1 as a creation parameter.

For more information about database encryption, see Encrypting UltraLite databases.

Example

The following code obfuscates a new database.

' eMbedded Visual Basic
open_parms = "ce_file=\tutorial.udb;ce_schema=\tutorial.usm;obfuscate=1"
Set Connection = DatabaseMgr.CreateDatabase( open_parms )
// JScript
open_parms = "ce_file=\\tutorial.udb;ce_schema=\\tutorial.usm;obfuscate=1";
Connection = DatabaseMgr.CreateDatabase( open_parms );


Data manipulation: INSERT, UPDATE and DELETE

With UltraLite, you can perform SQL Data Manipulation Language operations. These operations are performed using the ExecuteStatement method, a member of the ULPreparedStatement class.

For more information the ULPreparedStatement class, see ULPreparedStatement class.

Using parameters in your prepared statements
Placeholders for parameters are supplied using the ? character. For any INSERT, UPDATE or DELETE, each ? is referenced according to its ordinal position in the prepared statement. For example, the first ? is referred to as 1, and the second as 2.
toggle To INSERT a row

  1. Declare a ULPreparedStatement object.

    ' eMbedded Visual Basic
Dim PrepStmt As ULPreparedStatement
    // JScript
var PrepStmt;

  2. Assign an INSERT statement to your prepared statement object. In the following code, TableName and ColumnName are the names of a table and column.

    ' eMbedded Visual Basic
Set PrepStmt = Connection.PrepareStatement( _
    "INSERT into TableName(ColumnName) VALUES (?)")
    // JScript
PrepStmt = Connection.PrepareStatement(
    "INSERT into TableName(ColumnName) VALUES (?)");

  3. Assign parameter values for the statement.

    ' eMbedded Visual Basic
Dim NewValue As String
NewValue = "Bob"
PrepStmt.SetStringParameter 1, NewValue
    // JScript
var NewValue;
NewValue = "Bob";
PS.SetStringParameter(1, NewValue);

  4. Execute the statement.

    ' eMbedded Visual Basic
PrepStmt.ExecuteStatement
    // JScript
PrepStmt.ExecuteStatement();
toggle To UPDATE a row

  1. Declare a ULPreparedStatement object.

    ' eMbedded Visual Basic
Dim PrepStmt As ULPreparedStatement
    // JScript
var PrepStmt;

  2. Assign an UPDATE statement to your prepared statement object. In the following code, TableName and ColumnName are the names of a table and column.

    ' eMbedded Visual Basic
Set PrepStmt = Connection.PrepareStatement( _
    "UPDATE TableName SET ColumnName = ? WHERE ID = ?")
    // JScript
PrepStmt = Connection.PrepareStatement(
    "UPDATE TableName SET ColumnName = ? WHERE ID = ?");

  3. Assign parameter values for the statement.

    ' eMbedded Visual Basic
Dim NewValue As String
NewValue = "Bob"
PrepStmt.SetParameter 1, NewValue
PrepStmt.SetParameter 2, "6"
    // JScript
var NewValue;
NewValue = "Bob";
PrepStmt.SetParameter(1, NewValue);
PrepStmt.SetParameter(2, "6");

  4. Execute the statement

    ' eMbedded Visual Basic
PrepStmt.ExecuteStatement
    // JScript
PrepStmt.ExecuteStatement();
toggle To DELETE a row

  1. Declare a ULPreparedStatement object.

    ' eMbedded Visual Basic
Dim PrepStmt As ULPreparedStatement
    // JScript
var PrepStmt;

  2. Assign a DELETE statement to your prepared statement object.

    ' eMbedded Visual Basic
Set PrepStmt = Connection.PrepareStatement( _
    "DELETE FROM customer WHERE ID = ?")
    // JScript
PrepStmt = Connection.PrepareStatement( _
    "DELETE FROM customer WHERE ID = ?");

  3. Assign parameter values for the statement.

    ' eMbedded Visual Basic
Dim IDValue As String
IDValue = "6"
PrepStmt.SetParameter 1, IDValue
    // JScript
var IDValue;
IDValue = "6";
PrepStmt.SetParameter( 1, IDValue );

  4. Execute the statement.

    'eMbedded Visual Basic
PrepStmt.ExecuteStatement
    // JScript
PrepStmt.ExecuteStatement();


Data retrieval: SELECT

When you execute a SELECT statement, the ULPreparedStatement.ExecuteQuery method returns a ULResultSet object.

The ULResultSet class contains methods for navigating within a result set. The values are then accessed using the ULResultSet Value property.

For more information about ULResultSet objects, see ULResultSet class.

Example

In the following code, the results of a SELECT query are accessed through a ULResultSet. When first assigned, the ULResultSet is positioned before the first row. The ULResultSet.MoveFirst method is then called to navigate to the first record in the result set.

For more information about navigating a result set, see Navigation with dynamic SQL.

' eMbedded Visual Basic
Dim MyResultSet As ULResultSet
Dim PrepStmt As ULPreparedStatement
Set PrepStmt = Connection.PrepareStatement( _
    "SELECT ID, Name FROM customer")
Set MyResultSet = PrepStmt.ExecuteQuery
MyResultSet.MoveFirst
// JScript
var MyResultSet;
var PrepStmt;
PrepStmt = Connection.PrepareStatement( _
    "SELECT ID, Name FROM customer");
MyResultSet = PrepStmt.ExecuteQuery();
MyResultSet.MoveFirst();
Example

The following code demonstrates how to use the Value property to obtain the column values for the current row. It uses the Value property access both Integer and String values. UltraLite ActiveX uses a variant data type to achieve this flexibility.

The Value property uses the following syntax, where Index is the ordinal position of the column name in your SELECT statement.

MyResultSetName.Value(Index)

The MoveRelative( 0 ) method is called to refresh the contents of the current buffer from the result set, so that the effects of any data modification are included.

' eMbedded Visual Basic
If MyResultSet.RowCount = 0 Then
  lblID.Caption = ""
  txtName.Text = ""
Else
  lblID.Caption = MyResultSet.Value(1)
  txtName.Text = MyResultSet.Value(2)
  MyResultSet.MoveRelative(0)
End If
// JScript
If ( MyResultSet.RowCount == 0 ) {
  lblID.Caption = "";
  txtName.Text = "";
} Else {
  lblID.Caption = MyResultSet.Value(1);
  lblID.Text = MyResultSet.Value(2);
  MyResultSet.MoveRelative(0);
}

The following procedure uses a SELECT statement to retrieve information from the database. The results of the query are assigned to a ULResultSet object.

toggle To perform a SELECT statement

  1. Declare a ULPreparedStatement object.

    ' eMbedded Visual Basic
Dim PrepStmt As ULPreparedStatement
    // JScript
var PrepStmt;

  2. Assign a prepared statement to your ULPreparedStatement object. In the following code, TableName and ColumnName are the names of a table and column.

    ' eMbedded Visual Basic
Set PrepStmt = Connection.PrepareStatement( _
    "SELECT ColumnName FROM TableName")
    // JScript
PrepStmt = Connection.PrepareStatement(
    "SELECT ColumnName FROM TableName")

  3. Execute the query.

    In the eMbedded Visual Basic code below, a listbox captures the result of the SELECT query.

    ' eMbedded Visual Basic
Dim MyResultSet As ULResultSet
Set MyResultSet = PrepStmt.ExecuteQuery
While MyResultSet.MoveNext
  listbox.AddItem y.Value(1)
Wend

    In the JScript code below, an string captures the result of the SELECT query as an HTML table.

    // JScript
var MyResultSet;
var resultTable;
MyResultSet = PrepStmt.ExecuteQuery();
var ncols = MyResultSet.Schema.ColumnCount;
var fld, line, nrows;
resultTable = "<html><table cellpadding=0 cellspacing=0><tr>";
resultTable = resultTable + "<th>" + "ColumnName" + "</th>";
resultTable = resultTable + "</tr><tr>";
nrows = 0;
while ( MyResultSet.MoveNext() ) {
  line = "<tr>";
    nrows++;
  if ( MyResultSet.IsNull(1) ) {
        fld = "(null)";
      } else {
        fld = MyResultSet.Value(1);
      }
      line = line + "<td>" + fld + "</td>";
    resultTable = resultTable + line + "</tr>";
}
resultTable = resultTable + _
    "</table><B>#Rows=" + nrows + "</B></html>";


Navigation with dynamic SQL

UltraLite ActiveX provides you with a number of methods to navigate a result set in order to perform a wide range of navigation tasks.

The following methods of the ULResultSet object allow you to navigate your result set:

  • MoveAfterLast moves to a position after the last row.

  • MoveBeforeFirst moves to a position before the first row.

  • MoveFirst moves to the first row.

  • MoveLast moves to the last row.

  • MoveNext moves to the next row.

  • MovePrevious moves to the previous row.

  • MoveRelative moves a certain number of rows relative to the current row. Positive index values move forward in the result set, negative index values move backward in the result set, and zero does not move the cursor. Zero is useful if you want to repopulate a row buffer.

Example

The following code demonstrates how to use the MoveFirst method to navigate within a result set.

' eMbedded Visual Basic
Set PrepStmt = Connection.PrepareStatement( _
    "SELECT ID, Name FROM customer")
Set MyResultSet = PrepStmt.ExecuteQuery
MyResultSet.MoveFirst
// JScript
PrepStmt = Connection.PrepareStatement(
    "SELECT ID, Name FROM customer");
MyResultSet = PrepStmt.ExecuteQuery();
MyResultSet.MoveFirst();

The same technique is used for all of the Move methods.

For more information about these navigational methods, see ULResultSet class.


ULResultSet schema property

The ULResultSet.Schema property allows you to retrieve information about the columns in the query. The properties of this ULResultSetSchema object include ColumnName, ColumnCount, ColumnPrecision, ColumnScale, ColumnSize, and ColumnSQLType.

Example

The following example demonstrates how to use ULResultSet.Schema to capture schema information.

' eMbedded Visual Basic
Dim i As Integer
Dim MySchema as ULResultSetSchema
Set MySchema = MyResultSet.Schema
For i = 1 To MySchema.ColumnCount
  cn = MySchema.ColumnName(i)
  ct = MySchema.ColumnSQLType(i)
  MsgBox cn, ct
Next i
// JScript
var i;
var MySchema;
For ( i = 1; i <= MySchema.ColumnCount; i++) {
  cn = MySchema.ColumnName(i);
  ct = MySchema.ColumnSQLType(i);
  alert ( cn + " " + ct );
}


Navigation with the Table API

UltraLite ActiveX provides you with a number of methods to navigate a table in order to perform a wide range of navigation tasks.

The following methods of the ULTable object allow you to navigate your result set:

  • MoveAfterLast moves to a position after the last row.

  • MoveBeforeFirst moves to a position before the first row.

  • MoveFirst moves to the first row.

  • MoveLast moves to the last row.

  • MoveNext moves to the next row.

  • MovePrevious moves to the previous row.

  • MoveRelative moves a certain number of rows relative to the current row. Positive index values move forward in the table, negative index values move backward in the table, and zero does not move the cursor. Zero is useful if you want to repopulate a row buffer.

Example

The following code opens the customer table and scrolls through its rows. It then displays a message box or alert with the last name of each customer.

' eMbedded Visual Basic
Dim tCustomer as ULTable
Set tCustomer = Connection.GetTable( "customer" )
tCustomer.Open
' the third column contains the last name of the customer
Set colLastName = tCustomer.Columns.Item(3)
tCustomer.MoveBeforeFirst
While tCustomer.MoveNext
    MsgBox colLastName.Value
Wend
// JScript
var tCustomer;
tCustomer = Connection.GetTable( "customer" );
tCustomer.Open();
// the third column contains the last name of the customer
colLastName = tCustomer.Columns.Item(3);
tCustomer.MoveBeforeFirst();
While (tCustomer.MoveNext()) {
  alert( colLastName.Value );
}
The Columns collection

The columns of a table are contained in a Columns collection. You can address columns by index number according to the order in which they were created in the schema file or by name.

For more information, see IULColumns collection.

Example

The following code accesses the LastName column.

' eMbedded Visual Basic
Set colLastName = tCustomer.Columns.( LastName )
// JScript
colLastName = tCustomer.Columns.( LastName );
Specifying an index

You expose the rows of the table to the application when you open the table object. By default, the rows are exposed in order by primary key value, but you can specify an index to access the rows in a particular order.

Example

The following code moves to the first row of the customer table as ordered by the ix_name index.

' eMbedded Visual Basic
Set tCustomer = Connection.GetTable("customer")
tCustomer.Open "ix_name"
tCustomer.MoveFirst
// JScript
tCustomer = Connection.GetTable("customer");
tCustomer.Open("ix_name");
tCustomer.MoveFirst();


Accessing the values of the current row

At any time, a ULTable object is positioned at one of the following places.

  • Before the first row of the table.

  • On a row of the table.

  • After the last row of the table.

If the ULTable object is positioned on a row, you can use the ULColumn.Value property to get the value of that column for the current row.

Example

The following code retrieves the value of three columns from the tCustomer ULTable object, and displays them in text boxes.

' eMbedded Visual Basic
Dim colID, colFirstName, colLastName As ULColumn
Set colID = tCustomer.Columns.Item(1)
Set colFirstName = tCustomer.Columns.Item(2)
Set colLastName = tCustomer.Columns.Item(3)
txtID.Text = colID.Value
txtFirstName.Text = colFirstName.Value
txtLastName.Text = colLastName.Value
// JScript
var colID, colFirstName, colLastName;
colID = tCustomer.Columns.Item(1);
colFirstName = tCustomer.Columns.Item(2);
colLastName = tCustomer.Columns.Item(3);
txtID.Text = colID.Value;
txtFirstName.value = colFirstName.Value;
txtLastName.value = colLastName.Value;

You can also use the Value property to set values.

' eMbedded Visual Basic
colLastName.Value = "Kaminski"
// JScript
colLastName.Value = "Kaminski";

By assigning values to these properties you do not alter the value of the data in the database.

You can assign values to the properties even if you are before the first row or after the last row of the table. You cannot, however, get values from the column. For example, the following code generates an error.

' This eMbedded Visual Basic code is incorrect
tCustomer.MoveBeforeFirst
id = colID.Value
// This JScript code is incorrect
tCustomer.MoveBeforeFirst();
id = colID.Value();
Casting values

As the Value method returns a variant, you can use it to access columns of any data type.


Searching rows with find and lookup

UltraLite has several modes of operation for working with data. Two of these modes, the find and lookup modes, are used for searching. The ULTable object has methods corresponding to these modes for locating particular rows in a table.

Note
The columns searched using Find and Lookup methods must be in the index used to open the table.

  • Find methods move to the first row that exactly matches a specified search value, under the sort order specified when the ULTable object was opened.

    For more information about find methods, see FindBegin method.

  • Lookup methods move to the first row that matches or is greater than a specified search value, under the sort order specified when the ULTable object was opened.

    For more information about lookup methods, see LookupBackward method.

toggle To search for a row

  1. Enter find or lookup mode.

    Call the FindBegin or LookupBegin method. For example, the following code calls ULTable.FindBegin.

    ' eMbedded Visual Basic
tCustomer.FindBegin
    // JScript
tCustomer.FindBegin();

  2. Set the search values.

    You do this by setting values in the current row. Setting these values affects the buffer, not the database. For example, the following code sets the last name column in the buffer to Kaminski.

    ' eMbedded Visual Basic
tCustomer.Columns.Item(3).Value = "Kaminski"
    // JScript
tCustomer.Columns.Item(3).Value = "Kaminski";

    For multi-column indexes, a value for the first column is required, but you can omit the other columns.

  3. Search for the row.

    Use the appropriate method to carry out the search. For example, the following instruction looks for the first row that exactly matches the specified value in the current index.

    ' eMbedded Visual Basic
tCustomer.FindFirst
    // JScript
tCustomer.FindFirst();


Inserting, updating, and deleting rows

UltraLite exposes the rows in a table to your application one at a time. The ULTable object has a current position, which may be on a row, before the first row, or after the last row of the table.

When your application changes location, UltraLite makes a copy of the row in a buffer. Any operations to get or set values affect only the copy of data in this buffer. They do not affect the data in the database.

Example

The following statement changes the value of the ID column in the buffer to 3.

' eMbedded Visual Basic
colID.Value = 3
// JScript
colID.Value = 3;
Using UltraLite modes

The UltraLite mode determines the purpose for which the values in the buffer will be used. UltraLite has the following four modes of operation, in addition to a default mode.

  • Insert mode The data in the buffer is added to the table as a new row when the ULTable.Insert method is called.

  • Update mode The data in the buffer replaces the current row when the ULTable.Update method is called.

  • Find mode Used to locate a row whose value exactly matches the data in the buffer when one of the ULTable.Find methods is called.

  • Lookup mode Used to locate a row whose value matches or is greater than the data in the buffer when one of the ULTable.Lookup methods is called.

toggle To update a row

  1. Move to the row you wish to update.

    You can move to a row by scrolling through the table or by searching using Find and Lookup methods.

  2. Enter Update mode.

    For example, the following instruction enters Update mode on the table tCustomer.

    ' eMbedded Visual Basic
tCustomer.UpdateBegin
    // JScript
tCustomer.UpdateBegin();

  3. Set the new values for the row to be updated.

    For example, the following instruction sets the new value to Elizabeth.

    ' eMbedded Visual Basic
ColFirstName.Value = "Elizabeth"
    // JScript
ColFirstName.Value = "Elizabeth";

  4. Execute the Update.

    'eMbedded Visual Basic
tCustomer.Update
    // JScript
tCustomer.Update();

After the update operation, the current row is the row that was just updated. If you changed the value of a column in the index specified when the ULTable object was opened, the current position is undefined.

By default, UltraLite operates in AutoCommit mode, so that the update is immediately applied to the row in permanent storage. If you have disabled AutoCommit mode, the update is not applied until you execute a commit operation. For more information, see Transaction processing in UltraLite.

Caution Do not update the primary key of a row: delete the row and add a new row instead.
Inserting rows

The steps to insert a row are similar to those for updating rows, except that there is no need to locate any particular row in the table before carrying out the insert operation. Rows are automatically sorted by the index specified when opening the table.

toggle To insert a row

  1. Enter Insert mode.

    For example, the following instruction enters Insert mode on the table CustomerTable.

    ' eMbedded Visual Basic
CustomerTable.InsertBegin
    // JScript
CustomerTable.InsertBegin();

  2. Set the values for the new row.

    If you do not set a value for one of the columns, and that column has a default, the default value is used. If the column has no default, NULL is used. If the column does not allow NULL, the following defaults are used:

    • For numeric columns, zero.

    • For character columns, an empty string.

    To set a value to NULL explicitly, use the setNull method.

    ' eMbedded Visual Basic
CustomerTable.Columns.Item("Fname").Value = fname
CustomerTable.Columns.Item("Lname").Value = lname
    // JScript
CustomerTable.Columns("Fname").Value = fname;
CustomerTable.Columns("Lname").Value = lname;

  3. Execute the insertion.

    The inserted row is permanently saved to the database when a Commit is carried out. In AutoCommit mode, a Commit is carried out as part of the Insert method.

    'eMbedded Visual Basic
CustomerTable.Insert
    // JScript
CustomerTable.Insert();
Deleting rows

There is no delete mode corresponding to the insert or update modes.

The following procedure deletes a row.

toggle To delete a row

  1. Move to the row you wish to delete.

  2. Execute the deletion.

    'eMbedded Visual Basic
tCustomer.Delete
    // JScript
tCustomer.Delete();


Working with BLOB data

You can fetch BLOB data for columns declared BINARY or LONG BINARY using the GetByteChunk method.

For more information, see GetByteChunk method.

Example

The following code demonstrates how to use the ULColumn.GetByteChunk method to get BLOB data.

' eMbedded Visual Basic
Dim offset As Integer
Dim nBytes As Integer
Dim chunk(1024) As Byte
ll = col.GetByteChunk( 0, chunk, 1024)
If nBytes <> 1024 Then
   ' only got nBytes bytes, expected 1024
Else
   ' have 1024 bytes
End if
// JScript
var offset;
var nBytes;
var chunk = new Array();
nBytes = col.GetByteChunk( 0, chunk, 1024);
if ( nBytes != 1024 ) {
  // only got nBytes bytes, expected 1024
} else {
  // have 1024 bytes
}


Accessing schema information

Each ULConnection, ULTable, and ULColumn object contains a schema property. These schema objects provide information about the tables, columns, indexes, and publications in a database.

Note
You cannot modify the schema through the API. You can only retrieve information about the schema.

For information about modifying the schema, see Changing the schema of a database.

  • ULDatabaseSchema The number and names of the tables in the database, as well as global properties such as the format of dates and times.

    To obtain a ULDatabaseSchema object, access the ULConnection.Schema property.

  • ULTableSchema The number and names of columns in the table, as well as the Indexes collections for the table.

    To obtain a ULTableSchema object, access the ULTable.Schema property.

  • ULColumnSchema Information about an individual column, including its default value, name, and whether it is autoincrement.

    To obtain a ULColumnSchema object, access the ULColumn.Schema property.

  • ULIndexSchema Information about the column, or columns, in the index. As an index has no data directly associated with it, there is no separate ULIndex object, only a ULIndexSchema object.

    The ULIndexSchema objects are available as part of the ULTableSchema.Indexes collection.

  • ULPublicationSchema The numbers and names of tables and columns contained in a publication. Publications are also comprised of schema only, so there is a ULPublicationSchema object but no ULPublication object.

    The ULPublicationSchema objects are available as part of the ULDatabaseSchema.Publications collection.

  • ULResultSetSchema The number and names of the columns in a result set.

    The ULResultSetSchema objects are accessible using the ULPreparedStatement.Schema property.


Handling errors

In normal operation, UltraLite ActiveX can throw errors. Errors are expressed as SQLCODE values, negative numbers indicating the particular kind of error.

For a list of error codes thrown by UltraLite ActiveX, see ULSQLCode enumeration.

UltraLite ActiveX throws errors only from the ULDatabaseManager and ULConnection objects. The following methods of ULDatabaseManager can throw errors.

  • CreateDatabase

  • CreateDatabaseWithParms

  • DropDatabase

  • DropDatabaseWithParms

  • OpenConnection

  • OpenConnectionWithParms

All other errors and exceptions within UltraLite ActiveX are routed through the ULConnection object.

For more information about accessing error numbers from ULDatabaseManager and ULConnection objects, see ULConnection class and ULDatabaseManager class.

The following sections explain how to implement error handling in eMbedded Visual Basic and JScript.


Error handling in eMbedded Visual Basic

You can use the standard eMbedded Visual Basic error-handling features to handle errors. To enable error handling, use the On Error Resume Next statement. On Error Goto 0 causes errors to halt execution of your code.

The Err.Number property holds the SQLCODE value for an error. You can also get the last error using the ULConnection.LastErrorCode property.

One common area where errors need to be caught is in handling missing database files. In the following example, On Error Resume Next is in effect, so control flows to the next statement following the one causing the error. If the specified database does not exist, the Err object is loaded with the error number and description.

' eMbedded Visual Basic
On Error Resume Next
Err.Clear     ' Clear any previous errors
Set Connection = DBMgr.OpenConnection(udb)
If Err.Number <> 0 Then   ' Connection failed, no database?
  Err.Clear
  Set Connection = DBMgr.CreateDatabase(udb & usm)
  If Err.Number <> 0 Then
    MsgBox "Connect with " & udb & usm & " failed: " & Err.Description
    App.End
  End If
End If


Error handling in JScript

There is no error handling in the version of JScript supported by Pocket IE. The default Pocket IE settings cause script errors to be ignored and the script to be silently terminated. When developing new JScript, this makes development difficult.

Set ShowScriptErrors registry key

Using a remote registry editor, such as the one that comes with eMbedded Visual Basic, you should create this key on your CE device:

[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main]ShowScriptErrors=dword:00000001

With this key set, Pocket Internet Explorer will provide error notification messages for JScript code that fails. Note that the line number reported may not be reliable.

Set ErrorResume property

To suppress UltraLite ActiveX errors, the ULDatabaseManager and ULConnection objects provide the following two properties.

  • ErrorResume is set to True to disable throwing subsequent errors.

  • LastErrorCode returns the error code set by the last operation.

One common area where errors need to be caught is in handling missing database files, which are to be created from a schema. In the following example, the ULDatabaseManager.ErrorResume property is True, so control flows to the next statement following the one causing the error. If the specified database does not exist, the LastErrorCode property is loaded with the error number.

// JScript
DBMgr.ErrorResume = true;   // Do not throw errors
Connection = DBMgr.OpenConnection( udb );
if ( DBMgr.LastErrorCode != 0 ) {
  Connection = DBMgr.CreateDatabase( udb + usm );
  if ( DBMgr.LastErrorCode != 0 ) {
    alert("Connect with " + udb + usm + failed: " + DBMgr.LastErrorCode );
  }
}


Authenticating users

New users have to be added from an existing connection. As all UltraLite databases are created with a default user ID and password of DBA and SQL, respectively, you must first connect as this initial user.

You cannot change a user ID: you add a user and delete an existing user. A maximum of four user IDs are permitted for each UltraLite database.

For more information about granting or revoking connection authority, see GrantConnectTo method and RevokeConnectFrom method.

toggle To add a user or change the password for an existing user

  1. Connect to the database as a user with DBA authority.

  2. Grant the user connection authority with the desired password.

    'eMbedded Visual Basic
conn.GrantConnectTo("Robert", "newPassword")
    // JScript
conn.GrantConnectTo("Robert", "newPassword");
toggle To delete an existing user

  1. Connect to the database as a user with DBA authority.

  2. Revoke the user's connection authority as follows.

    'eMbedded Visual Basic
conn.RevokeConnectFrom("Robert")
    // JScript
conn.RevokeConnectFrom("Robert");


Synchronizing data

You can UltraLite applications with a central database. Synchronization requires the MobiLink synchronization server and appropriate licensing.

This section provides a brief introduction to synchronization and describes some features of particular interest to users of UltraLite ActiveX. For a detailed explanation of synchronization, see UltraLite Clients.

You can also find a working example of synchronization in the CustDB sample application. For eMbedded Visual Basic, this sample is described in Tutorial: A Sample UltraLite ActiveX Application. For JScript, this sample is described in Tutorial: An UltraLite ActiveX Application for Pocket IE.

UltraLite ActiveX supports TCP/IP, HTTP, and HTTPS synchronization. Synchronization is initiated by the UltraLite application. In all cases, you use methods and properties of the ULConnection object to control synchronization.

Note
To synchronize using encrypted synchronization (HTTPS) or to use encryption over TCP/IP you must obtain the separately-licensable security option. To order this option, see the card in your SQL Anywhere Studio package or see [external link] http://www.sybase.com/detail?id=1015780.

For more information, see Welcome to SQL Anywhere Studio.

toggle To synchronize over TCP/IP or HTTP

  1. Prepare the synchronization information.

    Assign values to the required properties of the ULConnection.SyncParms object.

    For information about the properties and the values that you should set, see UltraLite Clients.

  2. Synchronize.

    Call the ULConnection.Synchronize method.

Monitoring synchronization progress


Monitoring synchronization progress

This section applies only to eMbedded Visual Basic. You cannot monitor synchronization progress using JScript.

To monitor synchronization progress, you add a synchronization dialog to your project and code accordingly.

The following procedure causes the dialog in ULSyncStatus.ebf to show status messages.

toggle To add a synchronization status dialog to your project (eMbedded Visual Basic)

  1. Browse to the Samples\UltraLiteActiveX\dbview.evb subdirectory of your SQL Anywhere installation.

  2. Copy and add ULSyncStatus.bas and ULSyncStatus.ebf to your project.

  3. Add code to your UltraLite ActiveX project.

    • Instead of using CreateObject to instantiate your ULDatabase Manager, use the following instruction:

      Set DBMgr = CreateObjectWithEvents( _
  "UltraLite.ULDatabaseManager", "UL_")

    • Ensure that your synchronization call accepts callbacks as follows.

      connection.Synchronize(True)

    • Write code that captures event notifications in the Synchronization Progress Dialog.

      The following method shows users insert, update, and delete data when data is sent to the consolidated database.

      Private Sub UL_OnSend(ByVal nBytes As Long, ByVal _
    nInserts As Long, _
    ByVal nUpdates As Long,  _
    ByVal nDeletes As Long)_
    prLine "OnSend " & nBytes & " bytes, " & nInserts &_
        " inserts, " & nUpdates & " updates, " &_
        nDeletes & " deletes"_
End Sub

      The following method shows users insert, update, and delete data when data is received at the consolidated database.

      Private Sub UL_OnReceive(ByVal nBytes As Long, ByVal _
    nInserts As Long, _
    ByVal nUpdates As Long, _
    ByVal nDeletes As Long)
    prLine "OnReceive " & _
       nBytes & " bytes, " & _
       nInserts  & " inserts, " & _
       nUpdates & " updates, " & _
       nDeletes & " deletes"
End Sub

      The following method shows users when synchronization states are changed.

      Private Sub UL_OnStateChange(ByVal newState As Long, _
 ByVal oldState As Long)
    prLine "OnStateChange new:" & _
           newState & ", old: " & oldState
End Sub

      The following method shows users when the currently synchronized table changes.

      Private Sub UL_OnTableChange(ByVal newTableIndex As _
 Long, ByVal numTables As Long)
    prLine "OnTableChange index:" & newTableIndex & _
           ", #tables=" & numTables
End Sub


Deploying UltraLite applications

When you have completed your application or when you wish to test your application, you need to deploy it to a device. This section outlines the steps needed to deploy an UltraLite application to a device.

Deploying UltraLite ActiveX applications to Windows CE


Deploying UltraLite ActiveX applications to Windows CE

You must carry out the following steps to deploy an UltraLite application to Windows CE:

  • Deploy your application and UltraLite component.

  • Deploy an initial copy of the UltraLite database or schema.

    In many situations it is sufficient to deploy an UltraLite schema file only. UltraLite creates a database file from the schema on the first connection attempt. You can then use synchronization to load an initial copy of the data.

    You must place the database or schema file so that it can be located by the application. The Database On CE and Schema On CE connection parameters define the location.

    See Database On CE connection parameter, and Schema On CE connection parameter .

  • Deploy the MobiLink synchronization conduit for ActiveSync.

    This step is required only if the application is synchronizing using ActiveSync.

    For instructions, see Installing the MobiLink provider for ActiveSync


Tutorial: A Sample UltraLite ActiveX Application

About this chapter

This chapter provides a tutorial to guide you through the process of building an UltraLite ActiveX application for a PocketPC device.

This tutorial uses eMbedded Visual Basic. For a sample UltraLite ActiveX application using JScript, see Tutorial: An UltraLite ActiveX Application for Pocket IE.


Introduction

This tutorial guides you through the process of building an UltraLite ActiveX application using the table API. At the end of the tutorial you will have an application and small database on your Windows CE device that synchronizes with a central database.

For more information about the table API, see the UltraLite ActiveX API Reference.

Timing

The tutorial takes about 30 minutes if you copy and paste the code. If you enter the code yourself, it takes significantly longer.

Competencies and experience

This tutorial assumes:

  • you have Microsoft eMbedded Visual Tools installed on your computer

  • you can write, test, and troubleshoot an eMbedded Visual Basic application

  • you know how to create an UltraLite schema using the UltraLite Schema Painter

    For more information, see The UltraLite Schema Painter.

  • you have the AppForge Booster installed

    If you are missing Booster, you can get it from [external link] http://www.appforge.com/booster.html.

Note
You can perform most of this tutorial without SQL Anywhere Studio. The synchronization sections of the tutorial require SQL Anywhere Studio.
Goals

The goals for the tutorial are to gain competence and familiarity with the process of developing an UltraLite application.


Lesson 1: Create a project architecture

The first procedure describes how to create an UltraLite database schema. The database schema is a description of the database. It describes the tables, indexes, keys, and publications within the database, and all the relationships between them.

For more information about database schemas, see Creating UltraLite database schema files.

toggle To create an UltraLite database schema

  1. Create a directory for this tutorial.

    This tutorial assumes the directory is c:\Tutorial\evb. If you create a directory with a different name, use that directory instead of c:\Tutorial\evb throughout the tutorial.

  2. Create a database schema using the UltraLite Schema Painter.

    For more information about creating a database schema, see the Lesson 1: Create an UltraLite database schema.

    • Schema filename tutcustomer.usm

    • Table name customer

    • Columns in customer

      Column Name | Data Type (Size) | Column allows NULL values? | Default value
      id | integer | No | autoincrement
      fname | char(15) | No | None
      lname | char(20) | No | None
      city | char(20) | Yes | None
      phone | char(12) | Yes | 555-1234

    • Primary key ascending id

Create an eMbedded Visual Basic project


Create an eMbedded Visual Basic project

The UltraLite component for eMbedded Visual Basic development is UltraLite ActiveX.

The following procedure creates an eMbedded Visual Basic project for your application and adds a reference to the UltraLite ActiveX control.

toggle To create a reference to the UltraLite ActiveX control

  1. Start eMbedded Visual Basic.

    • Choose Start > Programs > Microsoft eMbedded Visual Tools > eMbedded Visual Basic 3.0.

    The New Project window appears.

  2. Create a new project.

    Choose a design target for your application and click Open. The remainder of the tutorial assumes that you have chosen Windows CE for the PocketPC project.

  3. Create a reference to UltraLite ActiveX.

    • Choose Project > References

    • Select iAnywhere Solutions, ActiveX for UltraLite 9.0 and click OK.

      If the control does not appear in the list of available references, add the control to the list of available references.

      • Browse to the UltraLite\UltraLiteActiveX\win32\ subdirectory of your SQL Anywhere installation.

      • Select uldo9.dll and click OK.

  4. Save the Project:

    • Choose File > Save Project.

    • Save the form as c:\tutorial\evb\Tutorial.ebf.

    • Save the project as c:\tutorial\evb\Tutorial.ebp.


Lesson 2: Create a form

After completing the steps in Lesson 1: Create a project architecture, the project should display a form. The following procedure uses the form to create a user interface. This example uses labels as outputs, and text boxes and buttons as inputs, similar to a real application.

toggle To add controls to your project

  1. Add the controls and properties given in the table below to your form:

    Type Name Caption or text

    TextBox

             txtfname

    TextBox

             txtlname

    TextBox

             txtcity

    TextBox

             txtphone

    Label

             lblID

    Button

             btnInsert Insert

    Button

             btnUpdate Update

    Button

             btnDelete Delete

    Button

             btnNext Next

    Button

             btnPrevious Previous

    Button

             btnSync Synchronize

    Button

             btnDone End

  2. Check the application.

    • Choose Run > Execute.

      The application appears in the Windows CE emulator.

    • To end the application, click OK in the top right corner of the form.

Your form should look like the following screen capture:

The application form, showing the buttons, text boxes, and label.


Configure the emulator to support UltraLite ActiveX

Once you add UltraLite objects to your application, you must add the UltraLite ActiveX control to the emulator in order to debug and test your application.

toggle To add UltraLite ActiveX to the emulator

  1. Start the Control Manager.

    • In eMbedded Visual Basic, select Tools > Remote Tools > Control Manager.

  2. Select the target emulator.

    • In the left pane, open Pocket PC and select Pocket PC Emulation.

  3. Add the UltraLite control.

    • Choose Control > Add New Control.

    • Browse to ultralite\UltraLiteActiveX\ce\emulator30\uldo9.dll, located in your SQL Anywhere directory.

    • Click OK.

      Note that uldo9.dll is an ActiveX file, not a control, so it will not appear in the list of controls on the device.


Deploy the database schema

In addition to the UltraLite control, you must deploy the database schema to the emulator. The following procedure ensures that when your application first connects to a database, it uses the schema to create a database file.

toggle To deploy the database schema file to the emulator

  1. Start the Windows CE File Viewer.

    • From eMbedded Visual Basic, choose Tools > Remote Tools > File Viewer.

    • If the File Viewer does not automatically connect to the emulator, choose Connection > Add Connection and select Pocket PC Emulation.

  2. Create a folder to hold your application.

    • Open the Program Files folder.

    • In File Viewer, choose File > New Folder.

    • Create a folder named tutorial. This folder is used to hold your application files.

    • Click tutorial to navigate to that folder.

  3. Deploy the schema file to the emulator.

    • Choose File > Export File.

    • Browse to c:\tutorial\evb and double-click tutcustomer.usm.


Lesson 3: Write the sample code

This lesson guides you through the process of writing eMbedded Visual Basic code to connect to a database, navigate within the database, and manipulate the data in the database.

This lesson also includes instructions for synchronizing your application with an Adaptive Server Anywhere database. This portion of the lesson is optional, and requires SQL Anywhere Studio.


Write code to connect to your database

In this application, you connect to the database during the Form_Load event. You can also connect to a database using the general module.

This example uses a ULConnectionParms object to connect to a database. You can also use a connection string.

For reference information, see ULConnectionParms class.

toggle Write code to connect to the UltraLite database

  1. Double-click the form to open the Code window.

  2. Declare the required UltraLite objects.

    Enter the following code in the General area of your form.

    Dim DatabaseMgr As ULDatabaseManager
Dim Connection As ULConnection
Dim CustomerTable As ULTable
Dim colID, colFirstName, colLastName As ULColumn

  3. Add code to connect to the database in the Form_Load event.

    In the code below, the CreateObject method is used to create the initial database manager object. The database manager tries to open a connection to the database specified by the ULConnectionParms1 object. If the database does not exist, it creates a new database using the given schema.

    Sub Form_Load()
  ' declare variables
      Dim open_parms As String
  Dim schema_parms As String
  ' enable error handling
  On Error Resume Next
  ' specify the schema and database file
  ' locations
  open_parms = ";ce_file=\Program Files\tutorial\tutCustomer.udb"
  schema_parms = open_parms & ";ce_schema=\Program Files\tutorial\tutCustomer.usm"
  ' create a database manager and try to
  ' connect to an existing database
  Set DatabaseMgr = CreateObject("UltraLite.ULDatabaseManager")
  Set Connection = DatabaseMgr.OpenConnection(open_parms)
  ' if the database does not exist, create one
  If Err.Number = UlSQLCode.ulSQLE_NOERROR Then
    MsgBox "Connected to an existing database."
  ElseIf Err.Number = UlSQLCode.ulSQLE_ULTRALITE_DATABASE_NOT_FOUND Then
    Err.Clear
    Set Connection = DatabaseMgr.CreateDatabase(schema_parms)
    If Err.Number <> 0 Then
      MsgBox Err.Description
    Else
      MsgBox "Connected to a new database"
    End If
  End If
End Sub

  4. Add code to end the application and close the connection when the End button is clicked.

    Sub btnDone_Click()
    Connection.Close
    End
End Sub

  5. Run the application.

    • Choose Run > Execute.

    • After an initial message box, the form loads.

    • To terminate the application, click OK in the top right corner.


Write code for navigation and data manipulation

The following procedures implement data manipulation and navigation.

toggle To open the table

  1. Write code to initialize the table and move to the first row.

    This code assigns the customer table in the database to the CustomerTable variable. The call to Open opens the table so that the table data can be read or manipulated. It also positions the application before the first row in the table.

    Add the following code to the Form_Load event, just before the End Sub instruction.

    Set CustomerTable = Connection.GetTable("customer")
CustomerTable.Open
If Err.Number <> ULSQLCode.ulSQLE_NOERROR Then
    MsgBox Err.Description
End If

  2. Create a new procedure called DisplayCurrentRow and implement it as shown below.

    If the table has no rows, the following procedure causes the application to display empty controls. Otherwise, it displays the values stored in each of the columns of the current row of the database.

    Private Sub DisplayCurrentRow()
  If CustomerTable.RowCount = 0 Then
    txtFname.Text = ""
    txtLname.Text = ""
    txtCity.Text = ""
    txtPhone.Text = ""
    lblID.Caption = ""
  Else
    lblID.Caption = CustomerTable.Columns("ID").Value
    txtFname.Text = CustomerTable.Columns("Fname").Value
    txtLname.Text = CustomerTable.Columns("Lname").Value
    txtCity.Text = CustomerTable.Columns("City").Value
    txtPhone.Text = CustomerTable.Columns("Phone").Value
  End If
End Sub

  3. Call DisplayCurrentRow from the Form_Activate procedure. This call ensures that the fields get updated when the application starts.

    Private Sub Form_Activate()
    DisplayCurrentRow
End Sub
toggle To insert rows into the table

  1. Write code to implement the Insert button.

    In the following procedure, the call to InsertBegin puts the application into insert mode and sets all the values in the row to their defaults. For example, the ID column receives the next autoincrement value. The column values are set and then the new row is inserted.

    Add the following procedure to the form.

    Private Sub btnInsert_Click()
  Dim fname As String
  Dim lname As String
  Dim city As String
  Dim phone As String
  fname = txtFname.Text
  lname = txtLname.Text
  city = txtCity.Text
  phone = txtPhone.Text
  CustomerTable.InsertBegin
  CustomerTable.Columns("Fname").Value = fname
  CustomerTable.Columns("Lname").Value = lname
  If Len(city) > 0 Then
    CustomerTable.Columns("City").Value = city
  End If
  If Len(phone) > 0 Then
     CustomerTable.Columns("Phone").Value = phone
  End If
  CustomerTable.Insert
  CustomerTable.MoveLast
  DisplayCurrentRow
End Sub

  2. Run the application.

    After an initial message box, the form is displayed.

  3. Insert two rows into the database.

    • Enter a first name of Jane in the first text box and a last name of Doe in the second. Click Insert.

      A row is added to the table with these values. The application moves to the last row of the table and displays the row. The label displays the automatically incremented value of the ID column that UltraLite assigned to the row.

    • Enter a first name of John in the first text box and a last name of Smith in the second. Click Insert.

  4. Click OK to end the program.

toggle To move through the rows of the table

  1. Write code to implement the Next and Previous buttons.

    Add the following procedures to the form.

    Private Sub btnNext_Click()
    If Not CustomerTable.MoveNext Then
        CustomerTable.MoveLast
    End If
    DisplayCurrentRow
End Sub
Private Sub btnPrevious_Click()
    If Not CustomerTable.MovePrevious Then
        CustomerTable.MoveFirst
    End If
    DisplayCurrentRow
End Sub

  2. Run the application.

    When the form is first displayed, the controls are empty as the current position is before the first row.

    After the form is displayed, click Next and Previous to move through the rows of the table.

toggle To update and delete rows in the table

  1. Write code to implement the Update button.

    In the code below, the call to UpdateBegin puts the application into update mode. The column values are updated and then the row itself is updated with a call to Update.

    Add the following procedure to the form.

    Private Sub btnUpdate_Click()
    Dim fname As String
    Dim lname As String
    Dim city As String
    Dim phone As String

    fname = txtFname.Text
    lname = txtLname.Text
    city = txtCity.Text
    phone = txtPhone.Text
    CustomerTable.UpdateBegin
    CustomerTable.Columns("Fname").Value = _
        fname
    CustomerTable.Columns("Lname").Value = _
        lname
    If Len(city) > 0 Then
        CustomerTable.Columns("City").Value = _
        city
    End If
    If Len(phone) > 0 Then
       CustomerTable.Columns("Phone").Value = _
        phone
    End If
    CustomerTable.Update
    DisplayCurrentRow
    Exit Sub
End Sub

  2. Write code to implement the Delete button.

    In the code below, the call to Delete deletes the current row on which the application is positioned.

    Add the following procedure to the form.

    Private Sub btnDelete_Click()
    If CustomerTable.RowCount = 0 Then
        Exit Sub
    End If
    CustomerTable.Delete
    CustomerTable.MoveRelative 0
    DisplayCurrentRow
End Sub

  3. Run the application.


Write code to synchronize

The following procedure implements synchronization. Synchronization requires SQL Anywhere Studio. This portion of the tutorial is optional.

toggle To write code for the synchronize button

  • Write code to implement the Synchronize button.

    In the code below, the ULSyncParms object contains the synchronization parameters. For example, the ULSyncParms.UserName property specifies that when MobiLink is started, it will add a new user. The ULSyncParms.SendColumnNames property specifies that the column names will be sent to MobiLink so it can generate upload and download scripts.

    Add the following procedure to the form.

    Private Sub btnSync_Click()
    Dim parms As ULSyncParms
    Dim result As ULSyncResult
    On Error Resume Next
    Set parms = Connection.SyncParms
    Set result = Connection.SyncResult
    parms.UserName = "ULevbUser"
    parms.Stream = ULStreamType.ulTCPIP
    parms.Version = "ul_default"
    parms.SendColumnNames = True
    Connection.Synchronize (False)
    If Err.Number <> UlSQLCode.ulSQLE_NOERROR Then
        MsgBox result.StreamErrorCode
    End If
End Sub


Lesson 4: Deploy to a device

You can deploy your application to a device manually, or using the Application Install Wizard. The following sections describe both procedures.


Deploy to a remote device manually

The following procedures deploy your application to a Windows CE device manually.

toggle To add the UltraLite ActiveX control to your device

  1. Start the Windows CE Control manager.

    Select Tools > Remote Tools > Control Manager.

  2. In the left pane, double-click your device type and select your device. Your device must be connected.

    The right pane shows the controls available on the selected device.

  3. Choose Control > Add New Control.

  4. Browse to the appropriate version of the UltraLite ActiveX control, located in one of the following platform-specific subdirectories of your SQL Anywhere installation:

    • ARM ultralite\UltraLiteActiveX\ce\arm\uldo9.dll

    • MIPS ultralite\UltraLiteActiveX\ce\mips\uldo9.dll

  5. Click OK.

    Alternatively, you can copy the DLL to the \Windows directory on the device and register it using regsvrce.exe.

toggle To deploy the database schema file to your device

  1. Start the Windows CE File Viewer.

    From eMbedded Visual Basic, choose Tools > Remote Tools > File Viewer.

  2. If the File Viewer does not automatically connect to your device, choose Connection > Add Connection and select your device.

  3. Create a folder to hold your application.

    • In the File Viewer, open the Program Files folder.

    • Choose File > New Folder.

    • Create a folder named tutorial. This folder is used to hold your application files.

    • Click tutorial to navigate to that folder.

  4. Deploy the schema file to your device.

    • Choose File > Export File.

    • Browse to c:\tutorial\evb and double-click tutcustomer.usm.

toggle To deploy your application to a remote device

  1. Select File > Make.

  2. Browse to c:\tutorial\evb. Name your project Tutorial. Click OK.

  3. Deploy the .vb file to your device.

    • In the File Viewer, browse to Program Files\tutorial.

    • Choose File > Export File.

    • Browse to c:\tutorial\evb and double-click Tutorial.vb.

You can now launch the sample application on your remote device by browsing to Program Files\tutorial and launching Tutorial.vb.


Deploy to a remote device using the Application Install Wizard

The following procedure deploys your application to a mobile device using the Application Install Wizard. The Application Install Wizard creates an executable file and a cabinet (.cab) file that contains the files necessary for deployment.

toggle To deploy using the Application Install Wizard

  1. Before using the Application Install Wizard, you must complete your project and execute it to ensure that it does not generate run-time errors.

  2. Select File > Make.

  3. Browse to c:\tutorial\evb. Name your project Tutorial. Click OK.

  4. Select Tools > Remote Tools > Application Install Wizard.

    The Application Install Wizard appears. Click Next.

  5. Browse to c:\tutorial\evb\Tutorial.ebp. Click Next.

  6. Browse to c:\tutorial\evb\Tutorial.vb. Click Next.

  7. Browse to c:\tutorial\evb\. Click Next.

  8. Select the processors your application will support. If you select more than one processor, each will be contained in a separate .cab file. Click Next.

  9. Select iAnywhere Solutions, ActiveX for UltraLite. The UltraLite ActiveX control will be registered automatically upon installation of your application. Click Next.

  10. Deploy the schema file to your device.

    • Click Add.

    • Browse to c:\tutorial\tutcustomer.usm.

    • Click Open.

    • If a prompt asks whether it is a system file, click No.

    • Check Include Device Runtimes in Cab file if you want the device runtimes to be included in your installation. The device runtimes are not always required and can make the .cab file very large if included. If the application works with the currently installed runtimes, there is no need to check this option.

    • Click Next.

  11. Enter tutorial in each of the fields. Click Next.

  12. Click Create Install to create the .cab files and setup executable.

    The wizard creates a folder, CD1, in the directory you specified to store the output files. CD1 contains all the files you need to distribute your application.

  13. Click Finish.

  14. Run c:\tutorial\evb\CD1\setup.exe on your desktop computer to install your application to the device attached to it.

You can now launch your application on your device by browsing to Program Files\tutorial and launching Tutorial.vb.


Summary

Learning accomplishments

During this tutorial, you:

  • created a database schema

  • created an UltraLite ActiveX application

  • synchronized an UltraLite remote database with an Adaptive Server Anywhere consolidated database

  • gained competence with the process of developing an UltraLite ActiveX application

More samples

You can find more sample applications and utilities at [external link] iAnywhere CodeXchange.


Tutorial: An UltraLite ActiveX Application for Pocket IE

About this chapter

This chapter provides a tutorial to guide you through the process of building an UltraLite ActiveX application for Pocket Internet Explorer. The application accesses the UltraLite ActiveX package using JScript embedded on an HTML page.

For a sample UltraLite ActiveX application using eMbedded Visual Basic, see Tutorial: A Sample UltraLite ActiveX Application.

Introduction
Lesson 1: Install the UltraLite ActiveX package
Lesson 2: Deploy to a device
Lesson 3: Create and deploy an UltraLite database schema
Lesson 4: Create a form interface
Lesson 5: Write the JScript sample code


Introduction

This tutorial guides you through the process of building an UltraLite ActiveX application. At the end of the tutorial you will have an application and small database on your Windows CE device that synchronizes with a database running on your desktop computer.

This tutorial describes the CustDB sample application. This application demonstrates the capabilities of UltraLite ActiveX used from Pocket Internet Explorer (Pocket IE). It runs on a Windows CE device.

The CustDB sample is fully-functional customer application. The CustDB sample application provides you with examples of how to implement many of the techniques you will need to develop UltraLite ActiveX applications.

The CustDB sample application is written in JScript and HTML. The code for this application is located in the Samples\UltraLiteActiveX\pie subdirectory of your SQL Anywhere 9 installation.

Note
This application uses frames and so will only work on versions of Pocket IE later than 1.1.
Timing

The tutorial takes about 50 minutes.

Competencies and experience

This tutorial assumes:

  • you are familiar with JScript and Pocket Internet Explorer

    • you can write, test, and troubleshoot a JScript application

The synchronization section of this tutorial requires that:

  • you can use command line options and parameters

Goals

The goals for the tutorial are to gain competence and familiarity with the process of developing an UltraLite ActiveX application.


Lesson 1: Install the UltraLite ActiveX package

The UltraLite component for JScript development is UltraLite ActiveX. The following procedure registers the UltraLite ActiveX control on a remote device.

toggle To register the UltraLite ActiveX control

  1. Start eMbedded Visual Basic 3.0.

    Choose Start > Programs > Microsoft eMbedded Visual Tools > eMbedded Visual Basic 3.0.

    The New Project window appears.

  2. Click Cancel.

  3. Choose Tools > Remote Tools > Control Manager.

  4. In the left pane, open the folder corresponding to your device type. Select your device.

    The Control Manager connects to your device.

  5. Choose Control > Add New Control.

  6. Browse to one of the following platform-specific files in subdirectories of your SQL Anywhere 9 installation.

    • ARM UltraLite\UltraLiteActiveX\ce\arm\uldo9.dll

    • MIPS UltraLite\UltraLiteActiveX\ce\mips\uldo9.dll

    • Emulator UltraLite\UltraLiteActiveX\ce\emulator30\uldo9.dll

  7. Click Open.

    The ULConnectionParms class and the ULDatabaseManager class are added to your device.

Alternatively, you can copy the appropriate DLL for your device to \Windows\uldo9.dll and register it using regsvrce.exe. If you do not have regsvrce.exe on your device, you can copy it to your device from the Microsoft Windows CE SDK.


Lesson 2: Deploy to a device

The following procedure copies the HTML files containing embedded JScript to your remote device. Alternatively, you can access the files remotely from your hard drive or server using a web server and an internet connection.

toggle To copy the HTML files to your device

  1. Start the File Viewer.

    From eMbedded Visual Basic 3.0, choose Tools > Remote Tools > File Viewer.

  2. In the left pane, open the folder corresponding to your device type. Select your device.

    The File Viewer connects to your device.

  3. Choose File > New Folder. Create a folder named pie in the root of your device.

  4. Choose File > Export File.

    Copy the contents of the Samples\UltraLiteActiveX\pie subdirectory of your SQL Anywhere 9 installation to the pie directory on your device.


Lesson 3: Create and deploy an UltraLite database schema

The database schema is a description of the database. It describes the tables, indexes, keys, and publications within the database, and all the relationships between them.

A database schema may be created using the UltraLite Schema Painter or the ulinit utility. The following procedure uses ulinit to create a database schema based on an Adaptive Server Anywhere database.

toggle To create the database schema

  1. Create a directory on your computer for this tutorial.

    The remainder of the tutorial assumes that this directory is c:\tutorial\pie. If you create a directory with a different name, use that directory instead of c:\tutorial\pie throughout the tutorial.

  2. Copy the contents of the Samples\UltraLiteActiveX\pie subdirectory of your SQL Anywhere 9 installation to c:\tutorial\pie.

  3. Create the consolidated database.

    Open a command prompt and navigate to c:\tutorial\pie. Run the following command:

    dbinit custdbsrv.db

  4. Start the MobiLink synchronization server.

    Run the following command:

    runml.bat

  5. Create the UltraLite schema using the ulinit utility.

    For more information about the ulinit utility, see The ulinit utility.

    Run the following command:

    makeschemas.bat
toggle To deploy the database schema to your device

  1. Start the File Viewer.

    From eMbedded Visual Basic 3.0, choose Tools > Remote Tools > File Viewer.

  2. The File Viewer connects to your device.

    • Choose Connection > Add New Connection.

    • Open the folder corresponding to your device type.

    • Select your device.

  3. Choose File > New Folder. Create a folder named UltraLiteDB.

  4. Choose File > Export File.

  5. Browse to c:\tutorial\pie\ul_custdb.usm. Click Open to export the file to your device.


Lesson 4: Create a form interface

The form interface consists of the visual elements of your application. The following procedure explains the form interface in main.htm. You can optionally create a new text file and create the form interface yourself.

toggle To add controls to your project

  1. Open c:\tutorial\pie\main.htm in a text editor.

  2. Scroll down to the following lines in main.htm.

    <br>
Customer: <INPUT TYPE="text" NAME="txt_Custname" SIZE=15 MAXLENGTH=40>

    These lines create the text boxes given in the table below.

    Caption INPUT TYPE NAME
    Customer: Text txt_Custname
    Product: Text txt_Prodname
    Quantity: Text txt_Quant
    Prince: Text txt_Price
    Discount: Text txt_Discount
    Status: Text txt_Status
    Notes: Text txt_Notes

  3. Scroll down to the following lines in main.htm.

    <br>
<INPUT NAME="b_Previous" TYPE="BUTTON" VALUE=" <Back " onClick="MoveBack()">

    These lines create the buttons given in the table below.

    INPUT TYPE | NAME | VALUE | OnClick
    Button | b_Previous | < Back | MoveBack()
    Button | b_Next | Next > | MoveForward()
    Button | b_Approve | Approve... | ApproveOrder()
    Button | b_Deny | Deny... | DenyOrder()
    Button | b_Add | Add... | addNewOrder()
    Button | b_Delete | Delete | deleteOrder()
    Button | b_Synchronize | Synchronize | syncData()


Lesson 5: Write the JScript sample code

This lesson guides you through the process of writing JScript code to connect to a database, navigate within the database, and manipulate the data in the database.

The synchronization portion of this lesson require SQL Anywhere Studio.

Write code to connect to an UltraLite database
Write code to synchronize the database
Write code to display order information
Write code for navigation and data manipulation


Write code to connect to an UltraLite database

In Pocket IE, UltraLite ActiveX is accessed using JScript embedded on an HTML page. When a page containing a connection script is loaded, a new database connection is created. When the browser moves to another page, all of the objects created on the previous page are discarded. The database connection is thus lost when the page is unloaded.

Losing application state, including database connections, whenever a form changes, is slow and expensive. To avoid this, it is recommended that Pocket IE applications use HTML frames to maintain application state. The database connection can be kept by the frameset document. Pocket IE requires at least two frames within a frameset, and draws a three (3) pixel border between the frames.

In the CustDB sample, the minimal frame defined in topline.htm is a placeholder that displays the application name at the top of the screen. The rest of the screen is used to display the other pages of the application.

To swap forms in and out of the frameset, a JScript function can use the document.location.replace method. For example, the following code fragment closes the current connection and returns to the connect form.

<SCRIPT>
function exitApp() {
  if ( top.Connection != null ) {
    top.Connection.Close();
  }
  document.location.replace("connect.htm");
}
</SCRIPT>
<INPUT NAME="b_Done" TYPE="BUTTON" VALUE="Done" onClick="exitApp()">

The following procedure connects to an UltraLite database. For more information about connecting to an UltraLite database, see Connecting to an UltraLite database.

toggle To connect to the UltraLite database

  1. Start Pocket Internet Explorer.

  2. Open login.htm.

  3. Tap the hyperlink.

    The hyperlink links to frames.htm.

    The code in frames.htm creates a new database manager object and uses it to open a connection to the database specified by a connection string. If the database does not exist, it creates a new one.

    For more information, see Connecting to an UltraLite database.

    <SCRIPT LANGUAGE="JScript">
var Connection;      // UltraLite Connection
var DatabaseMgr;  // UltraLite Database Manager
var CS;        // Current State object

// Initialize connection. Create database if not already present.
function initDatabase() {
  var udb, usm;
  udb = "file_name=\\UltraLiteDB\\ul_custapi.udb";
  usm = ";schema_file=\\UltraLiteDB\\ul_custdb.usm";
  CS = new CurrState( 0 );
  DatabaseMgr = new ActiveXObject( "UltraLite.ULDatabaseManager" );
  var bval = DatabaseMgr.ErrorResume;
  DatabaseMgr.ErrorResume = true;
  Connection = DatabaseMgr.OpenConnection( udb );
  if ( DatabaseMgr.LastErrorCode != 0 ) {
      Connection = DatabaseMgr.CreateDatabase( udb + usm );
  }
}
// Initialize the database.
initDatabase();
</SCRIPT>

  4. A script prompts you to enter an employee ID. Accept the default value of 50.


Write code to synchronize the database

You must synchronize the database in order to obtain the list of products (which cannot be modified at the remote database) and an initial list of orders.

The following procedure synchronizes the database.

toggle To synchronize the sample database

  1. Tap Synchronize.

    The code below runs.

    The ULConnection.Synchronize method takes a single parameter, show-progress. In JScript applications, show-progress is set to false because Pocket Internet Explorer does not allow messages to be displayed.

    For more information about synchronizing an UltraLite database, see Synchronizing data.

    function syncData() {
  var conn = top.Connection;
  var parms = conn.SyncParms;
  // Set Sync Params
  parms.Stream = 2;  // ulTCPIP = 2, ulHTTP = 1, ulHTTPS = 3
  parms.StreamParams = "";
  parms.UserName = "50";      // m_EmpIDStr;
  parms.Version = "custdb 9.0";
  conn.ErrorResume = true;
  conn.Synchronize(false);
  conn.ErrorResume = false;
  if ( conn.LastErrorCode != 0 ) {
      SetStatus("Sync failed: " + conn.LastErrorDescription );
      return;
  }
  conn.Commit();        // Save updates.
  SetStatus("Synchronized");
  SkipToValidOrder();
  SetOrderData();
}

  2. When synchronization is complete, the word Synchronized appears at the bottom of the screen.


Write code to display order information

When main.htm loads, the following functions run to obtain and display the order information.

For more information about the GetTable method, see GetTable method.

function OpenGetOrder() {
 var conn = top.Connection;
 var cs = top.CS;
 var empid;
 if ( conn == null ) {
    alert("Not yet connected!");
  return;
 }
 conn.AutoCommit = false;
 var table = conn.GetTable("ULIdentifyEmployee_nosync");
 table.Open();
 if ( table.RowCount == 0 ) {
    empid = window.prompt("Enter employee ID #: ", "50");
   table.InsertBegin();
    table.Columns("emp_id").value = empid;
   table.Insert();
    conn.Commit();
 }
table.MoveFirst();
 cs.SetEmployeeID( table.Columns("emp_id").value );
 table.Close();
 ProductList = conn.GetTable("ULProduct");
 ProductList.Open();
 CustomerList = conn.GetTable("ULCustomer");
 CustomerList.Open();
 OrderList = conn.GetTable("ULOrder");
 OrderList.Open();
 SetOrderData();
 SkipToValidOrder();
}
function UpdateForm() {
 var cs = top.CS;
 if ( cs.GetNoOrder() ) {
    txt_Custname.value = "";
    txt_Prodname.value = "";
    txt_Quant.value = "";
    txt_Price.value = "";
    txt_Discount.value = "";
    txt_Status.value = "";
    txt_Notes.value = "";
  return;
 }
txt_Custname.value = cs.GetCustName();
 txt_Prodname.value = cs.GetProdName();
 txt_Quant.value = cs.GetQuantity();
 txt_Price.value = cs.GetPrice();
 txt_Discount.value = cs.GetDiscount();
 txt_Status.value = cs.GetStatus();
 txt_Notes.value = cs.GetNotes();
 if ( cs.FirstOrder() == cs.GetOrderID() ) {
    SetStatus("First Order");
 } else if ( cs.LastOrder() == cs.GetOrderID() ) {
    SetStatus("Last Order");
 }
}


Write code for navigation and data manipulation

The following procedures implement data manipulation and navigation.

toggle To scroll through the list of orders

  • Tap Back or Next.

    One of the following functions runs:

    function MoveBack() {
  var cs = top.CS;
  var posn = cs.GetBookmark();
  if ( MoveOrder( -1 ) ) {
      cs.SetBookmark(posn - 1);
      UpdateForm();
  }
}
function MoveNext() {
  var cs = top.CS;
  var posn = cs.GetBookmark();
  if ( MoveOrder(1) ) {
    cs.SetBookmark(posn + 1);
    UpdateForm();
  }
}
toggle To add an order to the database

  1. Tap Add.

    The following script runs, replacing main.htm with add.htm in the frame.

    function addNewOrder() {
    document.location.replace("add.htm");
}

  2. Fill in the form with the desired values. Click OK.

    The following script runs:

    For more information about inserting rows, see Inserting, updating, and deleting rows.

    function addCustomer() {
  var custName = window.prompt("Enter new customer name: ", "");
  if ( custName == "" ) return;
  var conn = top.Connection;
  var custlist = conn.GetTable( "ULCustomer" )
  custlist.Open("ULCustomerName");
  custlist.FindBegin();
  custlist.Columns("cust_name").value = custName;
  if ( custlist.FindFirst() ) {  // already present. Done.
    custlist.Close();
      return;
  }
    var custid = NextCustomerID();
  if ( custid == -1 ) {
      alert("No more customer IDs, cannot add. Replenish ULCustomerIDPool");
      custlist.Close();
      return;
  }
  custlist.InsertBegin();
  custlist.Columns("cust_id").value = custid;
  custlist.Columns("cust_name").Value = custName;
  custlist.Insert();
  custlist.Close();
  conn.Commit();
  // Only way to show new customer is to reload this form!
  document.location.reload();
}
toggle To approve or deny an order

  1. Click Approve or Deny.

    One of the following scripts runs, loading approve.htm or deny.htm in the frame.

    function ApproveOrder() {
  var cs = top.CS;
  document.location.replace("approve.htm");
}
function DenyOrder() {
  document.location.replace("deny.htm");
}

  2. Enter a note and click OK.

    If you are approving an order, the following code runs. If you are denying an order, the code is the same but the status is instead set to Denied.

    For more information about updating rows, see Inserting, updating, and deleting rows.

    function OK_Approve() {
  var cs = top.CS;
  var conn = top.Connection;
  var notes = txt_Notes.value;
  var order = conn.GetTable("ULOrder");
  order.Open();
  order.FindBegin();
  order.Columns("order_id").value = cs.GetOrderID();
  if ( order.FindFirst() ) {
    order.UpdateBegin();
    order.Columns("status").value = "Approved";
    order.Columns("notes").value = notes;
    order.Update();
    if (conn.LastErrorCode != 0 ) {
      alert("Failed: " + conn.LastErrorDescription );
    }
    conn.Commit();
  } else {
    alert("Cannot find order " + cs.GetOrderID() );
  }
  order.Close();
  document.location.replace("main.htm");
}


UltraLite ActiveX API Reference

About this chapter

This chapter describes the UltraLite ActiveX API, a set of classes and methods that allow you to write eMbedded Visual Basic or JScript code for applications that use UltraLite databases. Each topic contains information about a specific class, method, constant, or enum. The reference is organized by class, with associated methods beneath.

IULColumns collection
IULIndexSchemas collection
IULPublicationSchemas collection
ULAuthStatusCode enumeration
ULColumn class
ULColumnSchema class
ULConnection class
ULConnectionParms class
ULDatabaseManager class
ULDatabaseSchema class
ULIndexSchema class
ULPreparedStatement class
ULPublicationSchema class
ULResultSet class
ULResultSetSchema class
ULSQLCode enumeration
ULSQLType enumeration
ULStreamErrorCode enumeration
ULStreamErrorContext enumeration
ULStreamErrorID enumeration
ULStreamType enumeration
ULSyncParms class
ULSyncResult class
ULSyncState enumeration
ULTable class
ULTableSchema class


IULColumns collection

A collection of ULColumn objects that provides you with metadata about the column.

Properties


Properties

Prototype | Description
Count as long (read-only) | Gets the number of columns in the collection.
Item (Index) as ULColumn (read-only) | Gets a value from the collection. Index can be a number from 1 to count, or the name of a column.
Example

You can enumerate the columns in a IULColumns collection using the For Each statement in eMbedded Visual Basic or the for ... in statement in JScript.

' eMbedded Visual Basic
Dim col As ULColumn
For Each col In table.Columns
    If col.IsNull Then
    MsgBox col.Schema.Name & "is null"
    End If
Next
// JScript
var col : UltraLite.ULColumn;
var collection = table.Columns;
for ( col in collection ) {
  if ( col.IsNull ) {
    alert ( col.Schema.Name + "is null" );
  }
}


IULIndexSchemas collection

A collection of ULIndexSchema objects that provides you with ULIndexSchema information.

Properties


Properties

Prototype | Description
Count as long (read-only) | Gets the number of indexes in the collection.
Item (Index) as ULIndexSchema (read-only) | Gets an index from the collection. Items are indexed using 1-origin indexing. Index can be a number from 1 to count.
Example

You can enumerate the indexes on a table using the For Each statement in eMbedded Visual Basic or the for ... in statement in JScript.

' eMbedded Visual Basic
Dim index As ULIndexSchema
For Each index In TableSchema.Indexes
    'use index
Next
// JScript
var index : UltraLite.ULIndexSchema;
var collection = TableSchema.Indexes;
for ( index in collection ) {
  ' use index
}


IULPublicationSchemas collection

A collection of ULPublicationSchema objects that provides you with information about ULPublicationSchema.

Properties


Properties

Prototype | Description
Count as long (read-only) | Gets the number of publications in the collection.
Item (Index) as ULPublicationSchema (read-only) | Gets a publication from the collection.
Example

You can enumerate all the publications using the For Each statement in eMbedded Visual Basic or the for ... in statement in JScript.

' eMbedded Visual Basic
Dim pub As ULPublicationSchema
For Each pub In connection.schema.publications
    'use pub
Next
// JScript
var ps : UltraLite.ULPublicationSchema;
var collection = connection.schema.publications;
for ( pub in collection ) {
  ' use pub
}


ULAuthStatusCode enumeration

The ULAuthStatusCode is the auth_status synchronization parameter used in the ULSyncResult object.

Constant | Value
ulAuthUnknown | 0
ulAuthValid | 1000
ulAuthValidButExpiresSoon | 2000
ulAuthExpired | 3000
ulAuthInvalid | 4000
ulAuthInUse | 5000


ULColumn class

The ULColumn object allows you to get and set values from a table in a database. Each column object represents a particular value in a table; the row is determined by the ULTable object.

A note on converting from UltraLite database types to Visual Basic types.
UltraLite attempts to convert from the database column data type to the Visual Basic data type. If a conversion cannot be successfully done, then a ulSQLE_CONVERSION_ERROR is raised.

For information about the table object, see ULTable class.


Properties

Prototype | Description
IsNull As Boolean (read only) | Indicates whether the column value is NULL.
Schema As ULColumnSchema (read only) | Gets the object representing the schema of the column.
Value As Variant | Gets or sets the data value of this column in the current row as Variant.


AppendByteChunk method

Prototype

AppendByteChunk( _
byteArray, _
[ chunkSize ] _
) As Boolean
Member of UltraliteActiveX.ULColumn

Description

Appends bytes to the row's column if the type is ulTypeLongBinary or TypeBinary.

Parameters

byteArray The array of bytes to be appended.

chunkSize The number of bytes to be appended. If not provided, the length of byteArray is used.

Returns

True if successful.

False if unsuccessful.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not LONG BINARY or BINARY.

Example

The following examples append data to the edata column.

' eMbedded Visual Basic
Dim data (512) As Byte
' ...
table.Columns("edata").AppendByteChunk(data)
// JScript
var data = new Array();
// ...
table.Columns("edata").AppendByteChunk(data);


AppendStringChunk method

Prototype

AppendStringChunk( chunk )
Member of UltraLiteActiveX.ULColumn

Description

Appends the string to the column if the type is TypeLongString or TypeString.

Parameters

data A string to append to the existing string in a table.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not VARCHAR.


GetByteChunk method

Prototype

GetByteChunk (_
offset As Long, _
pByteArray, _
[ chunkSize ] _
) As Long
Member of UltraliteActiveX.ULColumn

Description

Fills the buffer passed in, which should be an array, with the binary data in the column. Suitable for BLOBS.

Parameters

offset The offset into the underlying array of bytes. The source offset must be greater than or equal to 0, otherwise a ulSQLE_INVALID_PARAMETER error will be raised.

pByteArray A variant. Array data is passed by reference as array.

chunkSize An optional parameter representing an array of bytes expressed as Long type.

Returns

The number of bytes read.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type isn't BINARY or LONG BINARY.

ulSQLE_INVALID_PARAMETER The error occurs if the column data type is BINARY and the offset is not 0 or 1, or, the data length is less than 0.

The error also occurs if the column data type is LONG BINARY and the offset is less than 1 or, the data length is less than 0.

Example

In the following example, edata is a column name.

' eMbedded Visual Basic
Dim data (512) As Byte
' ...
table.Columns.Item("edata").GetByteChunk(0,data)
// JScript
var data = new Array();
// ...
table.Columns.Item("edata").GetByteChunk(0, data);


GetStringChunk method

Prototype

GetStringChunk( _
offset As Long, _
pStringObj, _
[ chunkSize ] _
) As Long
Member of UltraliteActiveX.ULColumn

Description

Fills the string passed in with the binary data from the column. Suitable for LONG VARCHAR columns.

Parameters

offset The character offset into the underlying data from which you start getting the String.

pStringObj The string array you want filled. This variant is passed by reference.

chunkSize An optional parameter representing the number of characters to retrieve.

Returns

The number of characters copied. Room is left for a null termination character and the length does not include that character.

Errors

ulSQLE_CONVERSION_ERROR The error occurs if the column data type isn't TypeString or TypeLongString.

ulSQLE_INVALID_PARAMETER The error occurs if the column data type is CHAR and the src_offset is greater than 64K.

The error also occurs if src_offset is less than 1 or string length is less than 0.

Example
' eMbedded Visual Basic
Dim cd As ULColumn
Dim S As Strong
Dim l, offset As Long
S=String(512, vbNulChar)
offset=0
Do
    l=cd.GetStringChunk(offset, S, 512)
    If l=0 then Exit Do
    'use string ins
Loop
// JScript
var cd;
var s;
var l, offset;
l = 0;
While (!l) {
  l = cd.GetStringChunk(offset, s, 512);
}


SetByteChunk method

Prototype

SetByteChunk ( _
ByteArray, _
[ length ] _
) As Boolean
Member of UltraliteActiveX.ULColumn

Description

Sets the value of the column in the database to the array of bytes in the data field.

Parameters

ByteArray An array of bytes of type Variant.

length The length of the array.

Returns

True if successful.

False if unsuccessful.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not BINARY or LONG BINARY.

ulSQLE_INVALID_PARAMETER The error occurs if the data length is less than 0 or greater than 64K.

Example

In the following example, edata is a column name and the first 232 bytes of the data variable are stored in the database.

' eMbedded Visual Basic
Dim data (1 to 512) As Byte
' ...
table.Columns.Item("edata").SetByteChunk(data,232)
// JScript
var data = new Array();
// ...
table.Columns.Item("edata").SetByteChunk(data,232);


SetToDefault method

Prototype

SetToDefault( )
Member of UltraliteActiveX.IColumn

Description

Sets the current column to its default value as defined by the database schema. For example, an autoincrement column will be assigned the next available value.


Properties

Prototype | Description
AutoIncrement As Boolean (read-only) | Indicates whether this column defaults to an autoincrement value. True if AutoIncrement.
DefaultValue As String (read-only) | Gets the value used if one was not provided when a row was inserted.
GlobalAutoIncrement As Boolean (read-only) | Indicates whether this column defaults to a global autoincrement value.
ID As Long(read-only) | Gets the ID of the column.
Name As String (read-only) | Gets the column name.
Nullable As Boolean (read-only) | Indicates whether the column permits NULLs.
OptimalIndex As ULIndexSchema (read-only) | Gets the index with this column as its first column.
Precision As Integer (read-only) | Gets the precision value for the column if it is of type ulTypeNumeric.
Scale As Long (read-only) | Gets the scale value for the column .
Size As Long (read-only) | Gets the column size for binary, numeric, and character data types.
SQLType As ULSQLType (read-only) | Gets the SQL type assigned to the column when it was created.


ULConnection class

The ULConnection object represents an UltraLite database connection. It provides methods to get database objects like tables, and to synchronize.

Properties
CancelSynchronize method
ChangeEncryptionKey method
Close method
Commit method
CountUploadRows method
GetNewUUID method
GetTable method
GrantConnectTo method
LastDownloadTime method
PrepareStatement method
ResetLastDownloadTime method
RevokeConnectFrom method
Rollback method
RollbackPartialDownload method
StartSynchronizationDelete method
StopSynchronizationDelete method
StringToUUID method
Synchronize method
UUIDToString method


Properties

The following are properties of ULConnection:

Prototype | Description
AutoCommit As Boolean | Indicates the AutoCommit value. If true, all data changes are committed immediately after they are made. Otherwise, changes are not committed to the database until Commit is called. By default, this property is True.
CollationName As String (read-only) | Gets the database character set and sort order.
DatabaseID As Long | Gets or sets the database ID, which determines the starting value for global autoincrement columns. If the database ID has never been set, the value is -1.
DatabaseManager As ULDatabaseManager (read-only) | Gets the owning database manager object.
DatabaseNew As Boolean (read-only) | Indicates whether the database was newly created for this connection or not.
ErrorResume As Boolean | Indicates the error handling method.
GlobalAutoIncrementUsage As Long (read-only) | Gets the percentage of available global autoincrement values that have been used.
IsCaseSensitive As Boolean (read-only) | Indicates whether the database is case sensitive or not.
LastErrorCode As SQLCodeConstants | Gets the last error number, and allows you to clear the previous error code.
LastErrorDescription As String (read-only) | Gets the last error description.
LastIdentity As Long (read-only) | Gets the most recent value inserted into a column with a default of autoincrement or global autoincrement.
OpenParms As String (read-only) | Gets the string used to open the connection to the database.
Schema As ULDatabaseSchema (read-only) | Gets the ULDatabaseSchema object which represents the definition of the database.
SQLErrorOffset As Integer (read-only) | If PrepareStatement raises an error, indicates the 1-based offset in the SQL statement where the error was noted. If this value is less than or equal to 0, no offset information is available.
SyncParms As ULSyncParms (read-only) | Gets the synchronization parameters object.
SyncResult As ULSyncResult (read-only) | Gets the results of the most recent synchronization.


CancelSynchronize method

Prototype

CancelSynchronize( )
Member of UltraliteActiveX.ULConnection

Description

When called during synchronization, the method cancels the synchronization. The user can only call this method during one of the synchronization events.


ChangeEncryptionKey method

Prototype

ChangeEncryptionKey( newkeyAs String )
Member of UltraliteActiveX.ULConnection

Description

Encrypt the database with the specified key.

Parameters

newkey The new encryption key value for the database.

Example

When you call CreateDatabaseWithParms and pass in the parms object, with a value in place for EncryptionKey, the database is created with encryption. Another way to change the encryption key is by specifying the new encryption key on the ULConnection object. In this example, "apricot" is the key.

Connection.ChangeEncryptionKey( "apricot" )

Connections to the database, such as OpenConnectionWithParms, must, after the database is encrypted, specify apricot as the EncryptionKey property too. Otherwise, the connection will fail.


Close method

Prototype

Close( )
Member of UltraliteActiveX.ULConnection

Description

Closes the connection to the database. No methods on the ULConnection object or any other database object for this connection should be called after this method is called. If a connection is not explicitly closed, it will be implicitly closed when the application terminates.


Commit method

Prototype

Commit( )
Member of UltraliteActiveX.ULConnection

Description

Commits outstanding changes to the database. This is only useful if AutoCommit is false.

For more information, see Autocommit under ULConnection Properties


CountUploadRows method

Prototype

CountUploadRows(
[ mask As Long = 0 ], _
[ threshold As Long = -1 ] _
) As Long
Member of UltraliteActiveX.ULConnection

Description

Returns the number of rows that need to be uploaded when synchronization next takes place.

Parameters

mask An optional, unique identifier that refers to the publications to check. Use 0 for all publications. If not specified, then the value is zero.

threshold An optional parameter representing the maximum number of rows to count. Use -1 to indicate no maximum. If not specified, this value is -1.

Returns

Returns the number of rows that need to be uploaded in next synchronization.


GetNewUUID method

Prototype

GetNewUUID( ) As String
Member of UltraliteActiveX.ULConnection

Description

Returns a new universally unique identifier. The value is a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, and is typically stored in a column of data type UNIQUEIDENTIFIER.

Returns

Each call returns a new UUID.


GetTable method

Prototype

GetTable( name As String ) As ULTable
Member of UltraliteActiveX.ULConnection

Description

Returns the ULTable object for the specified table. You must then open the table before data can be read from it.

Parameters

name The name of the table sought.

Returns

Returns the ULTable object.


GrantConnectTo method

Prototype

GrantConnectTo(
userid As String, _
password As String _
)
Member of UltraliteActiveX.ULConnection

Description

Grants the specified user permission to connect to the database with the given password.

Parameters

userid The user ID being granted authority to connect.

password The password the user ID must specify to connect.


LastDownloadTime method

Prototype

LastDownloadTime( [mask As Long = 0 ] As Date
Member of UltraliteActiveX.ULConnection

Description

Returns the time of last download for the publication(s).

Parameters

mask An optional, unique identifier that refers to the publications to check. Use 0 for all publications. If this parameter is omitted, 0 is used.

Returns

The last download time in the form of a date.


PrepareStatement method

Prototype

PrepareStatement( sqlStatement As String ) As ULPreparedStatement
Member of UltraliteActiveX.ULConnection

Description

Prepares a SQL statement for execution.

Parameters

sqlStatement The SQL statement to prepare.

Returns

Returns a ULPreparedStatement. If there was a problem preparing the statement, an error will be raised. The offset into the statement where the error occurred can be determined from the SQLErrorOffset property.


ResetLastDownloadTime method

Prototype

ResetLastDownloadTime( [ mask As Long ] )
Member of UltraliteActiveX.ULConnection

Description

Resets the time of the most recent download for the publications specified in the mask.

Parameters

mask The mask of the publications to reset. The default is 0, specifying all publications.


RevokeConnectFrom method

Prototype

RevokeConnectFrom( userID As String )
Member of UltraliteActiveX.ULConnection

Description

Revokes the specified user's ability to connect to the database.

Parameters

userid The user ID whose authority to connect is being revoked.


Rollback method

Prototype

Rollback( )
Member of UltraliteActiveX.ULConnection

Description

Rolls back outstanding changes to the database. This is only useful if AutoCommit is false.


RollbackPartialDownload method

Roll back the changes from a failed synchronization.

Prototype

RollbackPartialDownload ( )
Member of UltraliteActiveX.ULConnection

Description

When a communication error occurs during the download phase of synchronization, UltraLite can apply the downloaded changes, so that the synchronization can be resumed from the place it was interrupted. If the download changes are not needed (the user or application does not want to resume the download at this point), RollbackPartialDownload rolls back the failed download transaction.

See also
  • Resuming failed downloads
  • Keep Partial Download synchronization parameter
  • Partial Download Retained synchronization parameter
  • Resume Partial Download synchronization parameter


StartSynchronizationDelete method

Prototype

StartSynchronizationDelete( )
Member of UltraliteActiveX.ULConnection

Description

Once StartSynchronizationDelete is called, all delete operations are again synchronized.


StopSynchronizationDelete method

Prototype

StopSynchronizationDelete( )
Member of UltraliteActiveX.ULConnection

Description

Prevents delete operations from being synchronized. This is useful for deleting old information from an UltraLite database to save space, while not deleting this information on the consolidated database.


StringToUUID method

Prototype

StringToUUID( s_uuid As String )
Member of UltraliteActiveX.ULConnection

Description

Converts a universally unique identifier represented as a String in the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx to a Byte array of 16 bytes.

Not needed in newer databases
In databases created before version 9.0.2, the UNIQUEIDENTIFIER data type is defined as a user-defined data type and functions are needed to convert between binary and string representations of UUID values.

In databases created using version 9.0.2 or later, the UNIQUEIDENTIFIER data type is a native data type and UltraLite carries out conversions as needed. The StringToUUID function is therefore not needed.

For more information, see UNIQUEIDENTIFIER data type [Binary].

Parameters

s_uuid A Universally Unique Identifier passed in as a string. You can obtain a new string UUID using GetNewUUID.

Example

The following example will convert the string form of the UUID 0a141e28-323c-4650-5a64-6e78828c96a0 to a binary array:

' eMbedded Visual Basic
Dim buff(1 to 16) As Byte
conn.StringToUUID( "0a141e28-323c-4650-5a64-6e78828c96a0", VarPtr(buff(1)) )


Synchronize method

Prototype

Synchronize( [show-progress As Boolean ] )
Member of UltraliteActiveX.ULConnection

Description

Synchronizes a consolidated database using MobiLink. This function does not return until synchronization is complete, but you can be notified of events if the connection was declared WithEvents.

Parameters

show-progress An optional parameter whose value may be true or false. Set this to true to show the progress of synchronization as it happens. Default is false.


UUIDToString method

Prototype

UUIDToString( buffer_16_bytes ) As String
Member of UltraliteActiveX.ULConnection

Description

Expects a VarPtr to a buffer of 16 bytes. Converts this buffer to a string in the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. The buffer must be declared (1 to 16) As Byte (that is, an array of 16 bytes). Visual Basic is unable to check the bounds for this buffer so if it is not big enough, the application could overwrite memory.

Not needed in newer databases
In databases created before version 9.0.2, the UNIQUEIDENTIFIER data type is defined as a user-defined data type and functions are needed to convert between binary and string representations of UUID values.

In databases created using version 9.0.2 or later, the UNIQUEIDENTIFIER data type is a native data type and UltraLite carries out conversions as needed. The UUIDToString function is therefore not needed.

For more information, see UNIQUEIDENTIFIER data type [Binary].

Parameters

buffer_16_bytes An array of 16 bytes containing a UUID.

Returns

Each call returns a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx


Properties

The ULConnectionParms class specifies parameters for opening a connection to an UltraLite database.

In UltraLite ActiveX, you can use the ULConnectionParms object and set your connection properties in your code. You use the ULConnectionParms object in conjunction with the ULDatabaseManager.CreateDatabaseWithParms and ULDatabaseManager.OpenConnectionWithParms methods.

Note
Databases are created with a single authenticated user, DBA, whose initial password is SQL. By default, connections are opened using the user ID DBA and password SQL.

For more information about the meaning of these parameters, see Connection Parameters.

Prototype | Description
AdditionalParms As String (read-write) Additional parameters specified as name=value pairs separated with semi-colons.

See Additional Parms connection parameter.
CacheSize As String (read-write) The size of the cache. CacheSize values are specified in bytes. Use the suffix k or K for kilobytes and use the suffix m or M for megabytes. The default cache size is sixteen pages. Given a default page size of 4 KB, the default cache size is 64 KB.

See Cache Size connection parameter .
ConnectionName As String (read-write) A name for the connection. This is needed only if you create more than one connection to the database.

See Connection Name connection parameter.
DatabaseOnCE As String (read-write) The filename of the database deployed to PocketPC.

See Database On CE connection parameter.
DatabaseOnDesktop As String (read-write) The filename of the database during development.

See Database On Desktop connection parameter.
EncryptionKey As String (read-write) A key for encrypting the database. OpenConnection and OpenConnectionWithParms must use the same key as specified during database creation. Suggestions for keys are:

  1. Select an arbitrary, lengthy string

  2. Select strings with a variety of numbers, letters and special characters, so as to decrease the chances of key penetration.

See Encryption Key connection parameter .
ParmsUsed As String (read-only) | The parameters used by the ULDatabaseManager. Useful for debugging purposes.
Password As String (read-write) The password for an authenticated user. Databases are initially created with one authenticated user password SQL. Passwords are case-insensitive if the database is case-insensitive and case-sensitive if the database is case-sensitive. The default value is SQL.

See Password connection parameter.
ReserveSize As Integer (read-write) The amount of file system space to reserve for storage of UltraLite persistent data.

See Reserve Size connection parameter .
SchemaOnCE As String (read-write) The schema filename deployed to PocketPC.

See Schema On CE connection parameter .
SchemaOnDesktop As String (read-write) The schema filename during development.

See Schema On Desktop connection parameter .
UserID As String (read-write) The authenticated user for the database. Databases are initially created with one authenticated user DBA. The UserID is case-insensitive if the database is case-insensitive and case-sensitive if the database is case-sensitive. The default value is DBA.

See User ID connection parameter.


ULDatabaseManager class

The ULDatabaseManager class is used to manage connections and databases. Your application should only have one instance of this object. Creating a database and establishing a connection to it is a necessary first step in using UltraLite. It is suggested that you use CreateDatabaseWithParms, OpenConnectionWithParms and DropDatabaseWithParms, and include checks in your code to ensure that you are connected properly before attempting any DML with the database.

Parms or no parms?
Two types of methods exist for creating, opening and dropping connections to your database: Methods WithParms and methods that do not use the ULConnectionParms object. Methods WithParms allow you to use a ULConnectionParms object to manipulate connection parameters with ease and accuracy. Methods that do not use the ULConnectionParms object require that you can successfully create a connections string and use that connection string in a CreateDatabase, OpenConnection or DropDatabase method.

Properties
CreateDatabase method
CreateDatabaseWithParms method
DropDatabase method
DropDatabaseWithParms method
OnReceive event
OnSend event
OnStateChange event
OnTableChange event
OpenConnection method
OpenConnectionWithParms method


Properties

The following are properties of ULDatabaseManager:

Prototype | Description
ErrorResume As Boolean | The error handling method. The default is false. If set to true, an error will not be raised when ULDatabaseManager methods fail.
LastErrorCode As SQLCodeConstants | Gets the last error number, and allows you to clear the previous error code.
Version As String (read-only) | Gets the version string of the UltraLite component.


CreateDatabase method

CreateDatabase creates a new database and returns a connection to it.

Prototype

CreateDatabase( parms As String ) As ULConnection
Member of UltraliteActiveX.ULDatabaseManager

Description

Creates a new database and returns a connection to it. It fails if the specified database already exists. A valid schema file must be specified to successfully create a database. To alter the schema of an existing database, use the ULDatabaseSchema ApplyFile method.

Caution
Only one database may be active at a given time. Attempts to create a different database while other connections are open will result in an error.

For more information about ApplyFile, see ULDatabaseSchema class and ApplyFile method.

Parameters

parms A semicolon-separated list of database creation parameters.

For information about connection parameters, see Connection Parameters.

Returns

Returns a connection to a newly created UltraLite database.

Examples

The example below uses CreateObject to create and open a new database.

' eMbedded Visual Basic
open_parms = "file_name=\tutCustomer.udb"
schema_parms = open_parms & ";" & "schema_name=\tutCustomer.usm"
Set DatabaseMgr = CreateObject("UltraLite.ULDatabaseManager")
Set Connection = DatabaseMgr.CreateDatabase(schema_parms)
// JScript
open_parms = "file_name=\\tutCustomer.udb";
schema parms = open_parms + ";" + "schema_name=\\tutCustomer.usm"
DatabaseMgr = new ActiveXObject("UltraLite.ULDatabaseManager")
Set Connection = DatabaseMgr.CreateDatabase(schema_parms);

The example below shows how you can create a ULDatabaseManager with events. This tactic is used for showing synchronization progress.

This functionality is only available with eMbedded Visual Basic.

For more information about showing synchronization progress, see Monitoring synchronization progress.

'eMbedded Visual Basic
Set DBMgr = CreateObjectWithEvents("UltraLite.ULDatabaseManager", "UL_")

For information about connection parameters, see OpenConnection method.


CreateDatabaseWithParms method

CreateDatabaseWithParms creates a new database using a connection parameter object, and returns a connection to it.

Prototype

CreateDatabaseWithParms( parms As ULConnectionParms )
As ULConnection
Member of UltraliteActiveX.ULDatabaseManager

Description

Creates a new database and returns a connection to it. It fails if the specified database already exists. A valid schema file must be specified to successfully create a database. To alter the schema of an existing database, use the ULDatabaseSchema.ApplyFileWithParms method.

Caution
Only one database may be active at a given time. Attempts to create a different database while other connections are open will result in an error.
Parameters

parms A ULConnectionParms object that holds a set of connection parameters.

Returns

Returns a connection to a newly created UltraLite database. Fails if the specified database already exists.

Examples

The following example assumes you have placed the ULConnectionParms object on your form, named it LoginParms and have specified the database locations and schema locations in the Connection parms properties window.

The example below uses CreateDatabaseWithParms to create and open a new database.

' eMbedded Visual Basic
' Use CreateObject in to get an instance of the ULDatabaseManager object
Set DatabaseMgr = CreateObject("UltraLite.ULDatabaseManager")
' Use CreateObject to get an instance of the ULConnectionParms object
Dim LoginParms As ULConnectionParms
Set LoginParms = CreateObject("UltraLite.ULConnectionParms")
LoginParms.DatabaseOnCE = "/tutorial/tutorial.udb"
LoginParms.SchemaOnCE = "/tutorial/tutorial.usm"
' Drop the existing database and create a new database
Call DatabaseMgr.DropDatabaseWithParms( LoginParms )
Set Connection = DatabaseMgr.CreateDatabaseWithParms(LoginParms)
// JScript
' get an instance of the ULDatabaseManager object
DatabaseMgr = new ActiveXObject("UltraLite.ULDatabaseManager");
var LoginParms;
LoginParms = new ActiveXObject("UltraLite.ULConnectionParms");
LoginParms.DatabaseOnCE = "//tutorial//tutorial.udb";
LoginParms.SchemaOnCE = "//tutorial//tutorial.usm";
' Drop the existing database and create a new database
DatabaseMgr.DropDatabaseWithParms( LoginParms );
Connection = DatabaseMgr.CreateDatabaseWithParms( LoginParms );


DropDatabase method

The DropDatabase method deletes a database file.

Prototype

DropDatabase( parms As String )
Member of UltraliteActiveX.ULDatabaseManager

Description

Deletes the database file. All information in the database file is lost. Fails if the specified database does not exist, or if there exist open connections at the time of DropDatabase is executed.

Parameters

parms The filename for the database.

Example

The following example drops a database:

' eMbedded Visual Basic
open_parms = "ce_file=\tutCustomer.udb"
DropDatabase(open_parms)
// JScript
open_parms = "ce_file=\\tutCustomer.udb";
DropDatabase( open_parms );


DropDatabaseWithParms method

The DropDatabaseWithParms method deletes a database file.

Prototype

DropDatabaseWithParms( parms As ULConnectionParms )
Member of UltraliteActiveX.ULDatabaseManager

Description

Deletes the database file. All information in the database file is lost.

Parameters

parms The ULConnectionParms object containing vital connection parameters .

Example

The following example assumes you have declared and instantiated a ULConnectionParms object named LoginParms and used it to specify the database location.

' eMbedded Visual Basic
Call DatabaseMgr.DropDatabaseWithParms( LoginParms )
// JScript
DatabaseMgr.DropDatabseWithParms( LoginParms );


OnReceive event

Prototype

OnReceive(
nBytes As Long, _
nInserts As Long, _
nUpdates As Long, _
nDeletes As Long _
)
Member of UltraliteActiveX.ULDatabaseManager

Description

Reports download information to the application from the consolidated database via MobiLink. This event may be called several times.

Parameters

nBytes Cumulative count of bytes received.

nInserts Cumulative count of inserts received at the remote application from the consolidated database.

nUpdates Cumulative count of updates received at the remote application from the consolidated database.

nDeletes Cumulative count of deletes received at the remote application from the consolidated database.

Example
'eMbedded Visual Basic
Private Sub OnReceive(ByVal nBytes As Long, ByVal nInserts As Long, ByVal nUpdates As Long, ByVal nDeletes As Long)
    prLine "OnReceive " & nBytes & " bytes, " & Inserts & " inserts, " & nUpdates & " updates, " & nDeletes & " deletes"
End Sub


OnSend event

Prototype

OnSend(
nBytes As Long,
nInserts As Long,
nUpdates As Long,
nDeletes As Long
)
Member of UltraliteActiveX.ULDatabaseManager

Description

Reports upload information from the remote database via MobiLink to the consolidated database. This event may be called several times.

Parameters

nBytes Cumulative count of bytes sent by the remote application to the consolidated database via MobiLink.

nInserts Cumulative count of inserts sent by the remote application to the consolidated database via MobiLink.

nUpdates Cumulative count of updates sent by the remote application to the consolidated database via MobiLink.

nDeletes Cumulative count of deletes sent by the remote application to the consolidated database via MobiLink.

Example
' eMbedded Visual Basic
Private Sub Connection_OnSend(ByVal nBytes As Long, _
    ByVal nInserts As Long, ByVal nUpdates As Long,  _
    ByVal nDeletes As Long)
  send_count = send_count + nBytes
  DisplaySyncStatus
End Sub


OnStateChange event

Prototype

OnStateChange(
newState As ULSyncState, _
oldState As ULSyncState _
)
Member of UltraliteActiveX.ULDatabaseManager

Description

This event is called whenever the state of the synchronization changes.

Parameters

newState The state that the synchronization process is about to enter.

oldState The state that the synchronization process just completed.

Example
' eMbedded Visual Basic
Private Sub _OnStateChange(ByVal newState As Long, ByVal oldState As Long)
    prLine "OnStateChange new:" & newState & ", old: " & oldState
End Sub


OnTableChange event

Prototype

OnTableChange(
newTableIndex As Long, _
numTables As Long _
)
Member of UltraliteActiveX.ULDatabaseManager

Description

This event is called whenever the synchronization process begins synchronizing another table.

Parameters

newTableIndex The index number of the table currently being synchronized. This number is not the same as the table ID, and so it cannot be used with the ULDatabaseSchema.GetTableName method.

numTables The number of tables eligible to be synchronized.

Example
' eMbedded Visual Basic
Private Sub _OnTableChange(ByVal newTableIndex As Long, ByVal numTables As Long)
    prLine "OnTableChange index:" & newTableIndex & ", #tables=" & numTables
End Sub


OpenConnection method

Prototype

OpenConnection( connparms As string ) As ULConnection
Member of UltraliteActiveX.ULDatabaseManager

Description

If a database exists, use this method to connect to the database. If a database does not exist, or the connection parameters are invalid, the call will fail. Use the error object to determine why the call failed.

The function returns a ULConnection object which provides an open connection to a specified UltraLite database. The database filename is specified using the connparms string. Parameters are specified using a sequence of name=value pairs. If no user ID or password is given, the default is used.

Parameters

connparms The parameter used to establish a connection to a database. Parameters are specified as a semicolon separated list of keyword=value pairs. If no user ID or password is given, the default is used.

Returns

The ULConnection object is returned if the connection was successful.

Example

The example below shows how to use connection parameters in the OpenConnection method.

' eMbedded Visual Basic
open_parms = "ce_file = \tutCustomer.udb"
Set DatabaseMgr = CreateObject("UltraLite.ULDatabaseManager")
Set Connection = DatabaseMgr.OpenConnection(open_parms)
// JScript
open_parms = "ce_file = \\tutCustomer.udb";
DatabaseMgr = new ActiveXObject("UltraLite.ULDatabaseManager");
Connection = DatabaseMgr.OpenConnection(open_parms);


OpenConnectionWithParms method

Prototype

OpenConnectionWithParms( connparms As ULConnectionParms)
As ULConnection
Member of UltraliteActiveX.ULDatabaseManager

Description

If a database exists, use this method to receive a connection. If a database does not exist, or the connection parameters are invalid, the call will fail. Use the error object to determine why the call failed.

The function returns a ULConnection object which provides an open connection to a specified UltraLite database. The database filename is specified using the connparms object. Parameters are specified using a sequence of name=value pairs. If no user ID or password is given, the default is used.

Parameters

connparms The parameters defining this connection.

Returns

The ULConnection object is returned if the connection was successful.

Example

The following example assumes you have created a ULConnectionParms object LoginParms and have specified the database locations and schema locations.

' eMbedded Visual Basic
Set DatabaseMgr = CreateObject("UltraLite.ULDatabaseManager")
Set Connection = DatabaseMgr.OpenConnection(LoginParms)
// JScript
DatabaseMgr = new ActiveXObject("UltraLite.ULDatabaseManager");
Connection = DatabaseMgr.OpenConnection(LoginParms);


Properties

The following are properties of ULDatabaseSchema:

Prototype | Description
DateFormat As String (read-only) | Gets the format for dates retrieved from the database; 'YYYY-MM-DD' is the default. The format of the date retrieved depends on the format used when you created the schema file.
DateOrder As String (read-only) | Indicates the interpretation of date formats; valid values are 'MDY', 'YMD', or 'DMY'.
NearestCentury As String (read-only) | Indicates the interpretation of two-digit years in string-to-date conversions. This is a numeric value that acts as a rollover point. Two digit years less than the value are converted to 20yy, while years greater than or equal to the value are converted to 19yy. The default is 50.
Precision As String (read-only) | Gets the maximum number of digits in the result of any decimal arithmetic.
Publications As IPublicationSchemas(read-only) | Gets a collection of publication schema objects.
Scale (read-only) | Gets the database numeric scale.
Signature As Variant (read-only) | Gets the database signature, an internal identifier representing the database schema.
TableCount As Long (read-only) | Gets the number of tables in the connected database.
TimeFormat As String (read-only) | Gets the format for times retrieved from the database.
TimestampFormat As String (read-only) | Gets the format for timestamps retrieved from the database.
TimestampIncrement (read-only) | Gets the database timestamp increment.


ApplyFile method

Prototype

ApplyFile( parms As String ) As Boolean
Member of UltraliteActiveX.ULDatabaseSchema

Description

Changes the schema of this database. Parms points to the schema file(s) you are applying to the database. This method is only useful on those occasions where you want to modify your existing database structure.

Caution
Although ApplyFile is very safe, ApplyFile can cause data loss under a number of circumstances including (1) if columns are deleted, or (2) if the data type for a column is changed to an incompatible type, or (3) if you upgrade an 8.0.2 database using ApplyFile in UltraLite 9.0.

Parameters

parms The files containing the changes you wish to make to your database schema.

Returns

True if successful.

False if unsuccessful.

Example
DatabaseSchema.ApplyFile( _
"schema_file=MySchemaFile.usm;palm_schema=MySchema" )


ApplyFileWithParms method

Prototype

ApplyFileWithParms( parms As ULConnectionParms ) As Boolean
Member of UltraliteActiveX.ULDatabaseSchema

Description

Upgrades the schema of this database using the parameter object Parms, which points to the schema file(s) you are applying to the database. This method is only useful on those occasions where you want to modify your existing database structure.

Caution
Although ApplyFile is very safe, ApplyFileWithParms can cause data loss under a number of circumstances including (1) if columns are deleted, or (2) if the data type for a column is changed to an incompatible type, or (3) if you upgrade an 8.0.2 database using ApplyFile in UltraLite 9.0.
Parameters

parms The object identifying the schema file to apply.

Returns

True if successful.

False if unsuccessful.


ULIndexSchema class

The ULIndexSchema object allows you to obtain the attributes of an index. An index is an ordered set of columns by which data in a table will be sorted. The primary use of an index is to order the data in a table by one or more columns.

An index can be a foreign key, which is used to maintain referential integrity in a database.

Properties


Properties

Prototype | Description
ColumnCount As Long (read-only) | Gets the number of columns in the index
ColumnName (position As Long) As String (read-only) | Gets the column name in position of index.
ForeignKey As Boolean (read-only) | Indicates whether this is a foreign key.
IsColumnDescending( position As Long) As Boolean (read-only) | Indicates whether a column is sorted descending. False if ascending.
Name As String (read-only) | Gets the name of the index
PrimaryKey As Boolean (read-only) | Gets whether this is the primary key for this table.
ReferencedIndexName As String (read-only) | Gets the name of the index referenced by this index if it is a foreign key
ReferencedTableName As String (read-only) | Gets the name of the table referenced by this index if it is a foreign key
UniqueIndex As Boolean (read-only) | Indicates whether values in the index must be unique.
UniqueKey As Boolean (read-only) | Indicates whether the index is a unique constraint on a table. If True, the columns in the index are unique and do not permit NL values


ULPreparedStatement class

The ULPreparedStatement represents a pre-compiled SQL statement ready for execution. You can use Prepared Statement to run a SQL query. You can also use the ULPreparedStatement to execute the same statement multiple times using numerous input parameters. Since the prepared statement is precompiled, any further additions beyond the first execution take very little extra processing. Use ULPreparedStatement and Dynamic SQL when you want relatively fast DML over multiple rows.

Properties
AppendByteChunk method
AppendStringChunk method
Close method
ExecuteQuery method
ExecuteStatement method
SetNullParameter method
SetParameter method


Properties

Prototype | Description
HasResultSet As Boolean (read-only) | Indicates whether the prepared statement generates a result set. True if the statement has a result set, otherwise, false. If true, ExecuteQuery should be called instead of ExecuteStatement.
Schema As ULResultSetSchema (read-only) | Gets the schema describing results of statement.


AppendByteChunk method

Prototype

AppendByteChunk( _
parameter_id As Long, _
Array, _
[ chunkSize ] _
) As Boolean
Member of UltraliteActiveX.ULPreparedStatement

Description

Appends the buffer of bytes to the row's column if the type is ulTypeLongBinary.

Parameters

parameter_id The 1-based parameter number to set.

data The array of bytes to append.

chunkSize The number of bytes to append. If not provided, the length of byteArray is used.

Returns

True if successful.

False if unsuccessful.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not LONG BINARY or BINARY.


AppendStringChunk method

Prototype

AppendStringChunk(
parameter_id As Long ,
chunk )
Member of UltraLiteActiveX.ULPreparedStatement

Description

Appends the string to the column if the type is ulTypeLongString.

Parameters

parameter_id The 1-based parameter number to set.

chunk A string to append to the existing string in a table.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not VARCHAR.


Close method

Prototype

Close( )
Member of UltraLiteActiveX.ULPreparedStatement

Description

Frees resources associated with the ULPreparedStatement.


ExecuteQuery method

Prototype

ExecuteQuery( ) As ULResultSet
Member of UltraliteActiveX.ULPreparedStatement

Description

Executes the query and returns a result set.

Returns

A ULResultSet object. The ULResultSet is the data you requested in your SELECT statement. To describe the product of your query, see ULResultSetSchema class


ExecuteStatement method

Prototype

ExecuteStatement( ) As Long
Member of UltraliteActiveX.ULPreparedStatement

Description

Executes the statement.

Returns

The number of rows updated.


SetNullParameter method

Prototype

SetNullParameter( parameter_id As Long )
Member of UltraliteActiveX.ULPreparedStatement

Description

Set the parameter to NL.

Parameters

parameter_id The 1-based parameter number to set.


SetParameter method

Prototype

SetParameter(
parameter_id As Long
val
)
Member of UltraliteActiveX.ULPreparedStatement

Description

Set execution parameter to the value passed in.

Parameters

parameter_id The 1-based parameter number to set.

val The value you want for the execution parameter.


ULPublicationSchema class

The ULPublicationSchema object allows you to obtain the attributes of a publication.

Properties


ULResultSet class

The ULResultSet object moves over rows returned by a SQL query. Since the ULResultSet object contains the data returned by a query, you must refresh any query resultset after you have performed DML operations such as INSERT, UPDATE or DELETE. To do this, you should perform ExecuteQuery after you perform ExecuteStatement.

Properties
Close method
GetByteChunk method
GetStringChunk method
MoveAfterLast method
MoveBeforeFirst method
MoveFirst method
MoveLast method
MoveNext method
MovePrevious method
MoveRelative method
IsNull method


Properties

Prototype | Description
BOF As Boolean (read-only) | Indicates whether the current row position is before the first row. Returns True if the current row position is before the first row, otherwise false.
EOF As Boolean (read-only) | Indicates whether the current row position is after the last row. EOF is true if beyond the last row, otherwise false.
IsNull (columnID As Long) As Boolean (read-only) | Indicates whether the value from the specified column is SQL NULL. True if the column is null, else, IsNull is false.
RowCount As Long (read-only) | The number of rows in the result set.
Schema As ULResultSetSchema (read-only) | The schema description for this result set.
Value(columnID As Long) (read-only) | The value of the given column


Web Links Browse Collapse Expand PDF Previous Next

UltraLite ActiveX User's Guide

UltraLite ActiveX API Reference

ULResultSet class

Close method

Prototype

Close()
Member of UltraliteActiveX.ULResultSet

Description

Frees all resources associated with this object.


GetByteChunk method

Prototype

GetByteChunk(
index As Long, _
offset As Long, _
data, _
[ data_len As Long ] _
) As Long
Member of UltraliteActiveX.ULResultSet

Description

Fills the buffer passed in (which should be an array) with the binary data in the column. Suitable for BLOBS.

Parameters

index The 1-based ordinal of the column containing the binary data.

offset The offset into the underlying array of bytes. The source offset must be greater than or equal to 0, otherwise a SQLE_INVALID_PARAMETER error will be raised. A buffer bigger than 64K is also permissible.

data A pointer to an array of bytes.

data_len The length of the buffer, or array. The data_len must be greater than or equal to 0.

Returns

The number of bytes read.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not BINARY or LONG BINARY.

ulSQLE_INVALID_PARAMETER The error occurs if the column data type is BINARY and the offset is not 0 or 1, or, the data length is less than 0.

The error also occurs if the column data type is LONG BINARY and the offset is less than 1.

Example

In the following example, edata is a column name.

' eMbedded Visual Basic
Dim data (512) As Byte
...
table.Columns.Item("edata").GetByteChunk(0,data)
// JScript
var data = new Array();
// ...
table.Columns.Item("edata").GetByteChunk(0,data);


GetStringChunk method

Prototype

GetStringChunk(
index As Long, _
offset As Long, _
pStringObj, _
[ chunkSize ] ) As Long
Member of UltraliteActiveX.ULResultSet

Description

Fills the string passed in with the binary data in the column. Suitable for Long Varchars.

Parameters

index The 1-based column ID of the target column.

offset The character offset into the underlying data from which you start getting the string.

pStringObj The string you want returned. This variant is passed by reference.

chunkSize An optional parameter representing the number of characters to retrieve.

Returns

The number of characters copied. Room is left for a null termination character and the length does not include that character.

Gets BLOB data from a binary or long binary column.

Errors set

ulSQLE_CONVERSION_ERROR The error occurs if the column data type is not CHAR or LONG VARCHAR.

ulSQLE_INVALID_PARAMETER The error occurs if the column data type is CHAR and the src_offset is greater than 64K.

The error occurs if offset is less than 1 or string length is less than 0.


MoveAfterLast method

Prototype

MoveAfterLast( )
Member of UltraliteActiveX.ULResultSet

Description

Moves to a position after the last row of the ULResultSet.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


MoveBeforeFirst method

Prototype

MoveBeforeFirst( )
Member of UltraliteActiveX.ULResultSet

Description

Moves to a position before the first row.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


MoveFirst method

Prototype

MoveFirst( ) As Boolean
Member of UltraliteActiveX.ULResultSet

Description

Moves to the first row.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


MoveLast method

Prototype

MoveLast( )
Member of UltraliteActiveX.ULResultSet

Description

Moves to the last row.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


MoveNext method

Prototype

MoveNext( ) As Boolean
Member of UltraliteActiveX.ULResultSet

Description

Moves to the next row.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


MovePrevious method

Prototype

MovePrevious( ) As Boolean
Member of UltraliteActiveX.ULResultSet

Description

Moves to the previous row.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


MoveRelative method

Prototype

MoveRelative( index As Long ) As Boolean
Member of UltraliteActiveX.ULResultSet

Description

Moves a certain number of rows relative to the current row. Relative to the current position of the cursor in the resultset, positive index values move forward in the resultset, negative index values move backward in the resultset and zero does not move the cursor.

Parameters

index The number of rows to move. The value can be positive, negative, or zero.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


IsNull method

Prototype

IsNull( index As Integer ) As Boolean
Member of UltraliteActiveX.ULResultSet

Description

Indicates whether this column contains a null value.

Parameters

index The column index value.

Returns

True if the value is Null.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite ActiveX User's Guide

UltraLite ActiveX API Reference

ULResultSetSchema class

The ULResultSetSchema provides information about the schema of the result set.


Properties

Prototype | Description
ColumnCount As Long(read-only) | Gets the number of columns in the result set
ColumnName As String (read-only) | Gets the name of the column in the result set.
ColumnPrecision As Integer (read-only) | Gets the precision of the datatype for the column if it is numeric.
ColumnScale As Integer (read-only) | Gets the scale of the datatype for the column if it is numeric.
ColumnSize As Integer (read-only) | Gets the size of the datatype for the column.
ColumnSQLType As ULSQLType (read-only) | Gets the ULSQLType of the column.
Name (column_id As Long) as String (read-only) | Gets the name of the publicationgiven the column name from the ordinal ID
Precision(columnID As Long) As Long (read-only) | Gets the numeric precision of the column.


GetColumnID method

Prototype

GetColumnID( col_name As String ) As Long
Member of UltraliteActiveX.ULResultSetSchema

Description

Get the column id for a named column.

Parameters

col_name The column name for which an id is sought.

Returns

GetColumnID returns the column ID for the named column.


ULSQLType enumeration

ULSQLType lists the available UltraLite SQL database types used as table column types.

Constant | UltraLite Database Type | Value
ulTypeLong | Integer | 1
ulTypeUnsignedLong | SmallInt | 2
ulTypeShort | UnsignedInteger | 3
ulTypeUnsignedShort | UnsignedSmallInt | 4
ulTypeBig | Big | 5
ulTypeUnsignedBig | UnsignedBig | 6
ulTypeByte | Byte | 7
ulTypeBit | Bit | 8
ulTypeDateTime | Time | 9
ulTypeDate | Date | 10
ulTypeTime | Timestamp | 11
ulTypeDouble | Double | 12
ulTypeReal | Real | 13
ulTypeNumeric | (Var)Binary | 14
ulTypeBinary | LongBinary | 15
ulTypeString | (Var)Char | 16
ulTypeLongString | LongVarchar | 17
ulTypeLongBinary | Numeric | 18


ULStreamErrorID enumeration

The ULStreamErrorID is an enumeration of the possible network layers that caused an error in an unsuccessful synchronization.

Constant | Value
ulStreamErrorIDTcpip | 0
ulStreamErrorIDSerial | 1
ulStreamErrorIDFake | 2
ulStreamErrorIDNettech | 5
ulStreamErrorIDRimbb | 6
ulStreamErrorIDHttp | 7
ulStreamErrorIDHttps | 8
ulStreamErrorIDDhCast | 9
ulStreamErrorIDSecure | 10
ulStreamErrorIDCerticom | 11
ulStreamErrorIDJavaCerticom | 12
ulStreamErrorIDCerticomSsl | 13
ulStreamErrorIDCerticomTls | 14
ulStreamErrorIDWirestrm | 15
ulStreamErrorIDWireless | 16
ulStreamErrorIDReplay | 17
ulStreamErrorIDStrm | 18
ulStreamErrorIDUdp | 19
ulStreamErrorIDEmail | 20
ulStreamErrorIDFile | 21
ulStreamErrorIDActivesync | 22
ulStreamErrorIDRsaTls | 23
ulStreamErrorIDJavaRsa | 24


ULStreamType enumeration

The ULStreamType constants identify constants you can use to specify stream type. These represent the types of MobiLink synchronization streams you can use for synchronization.

Constant | Value | Description
ulTCPIP | 1 | TCP/IP stream
ulHTTP | 2 | HTTP stream
ulHTTPS | 3 | HTTPS synchronization


Properties

The following are properties of ULSyncParms:

Prototype | Description
CheckpointStore As Boolean | If true, adds checkpoints of the database during synchronization to limit database growth during the synchronization process. This is most useful for large downloads with many updates. See Checkpoint Store synchronization parameter.
DownloadOnly As Boolean | Indicates if a synchronization only downloads data. See Download Only synchronization parameter.
KeepPartialDownload As Boolean | If the synchronisation fails during download because of a communications error, apply those changes that were successfully downloaded, rather than rolling back all the changes. See Keep Partial Download synchronization parameter.
NewPassword As String | Change a user password to this new password string on the next synchronization. See New Password synchronization parameter.
Password As String | The password corresponding to a given user name. See Password synchronization parameter.
PublicationMask As Long | Specify the publications to synchronize. The default is to synchronize all data. See Publication synchronization parameter.
ResumePartialDownload As Boolean | Resume a synchronization that failed during download because of a communications error, applying only those changes that were scheduled to be downloaded in the failed synchronization. See Resume Partial Download synchronization parameter.
SendColumnNames As Boolean | If SendColumnNames is true, column names are sent to the MobiLink synchronization server. Column names must be sent to the MobiLink synchronization server for automatic script generation. See Send Column Names synchronization parameter.
SendDownloadAck As Boolean | If SendDownloadAck is true, a download acknowledgement is sent during synchronization. See Send Download Acknowledgement synchronization parameter.
Stream As ULStreamType constants | Set the type of stream to use during synchronization. See Stream Type synchronization parameter.
StreamParms As String | Set network protocol options for the given stream type. See Stream Parameters synchronization parameter and Network protocol options for UltraLite synchronization clients.
UploadOnly As Boolean | Indicates whether a synchronization only uploads data. See Upload Only synchronization parameter.
UserName As String | The MobiLink user name for synchronization. See User Name synchronization parameter.
Version As String | The synchronization script version to run. See Version synchronization parameter.


AddAuthenticationParm method

Prototype

AddAuthenticationParm( BSTR parm )
Member of UltraliteActiveX.ULSyncParms

Description

Adds a parameter to be passed to the authenticate_parms MobiLink synchronization script.

Parameters

parm The parameter being added.

Returns

No return value.

See also

Authentication Parameters synchronization parameter

authenticate_parameters connection event


ClearAuthenticationParms method

Prototype

ClearAuthenticationParms( )
Member of UltraliteActiveX.ULSyncParms

Description

Clears all parameters that were to be passed to the authenticate_parms MobiLink synchronization script.

Returns

No return value.

See also

Authentication Parameters synchronization parameter

authenticate_parameters connection event


ULSyncResult class

The attributes of the ULSyncResult object store the results of the last synchronization.

Properties


Properties

The following are properties of ULSyncResult:

Prototype | Description
AuthStatus As AuthStatusCode (read-only) | Gets the authorization status code for the last synchronization. See Authentication Status synchronization parameter.
AuthValue As Long (read-only) | Gets the MobiLink authentication value. See Authentication Value synchronization parameter.
PartialDownloadRetained (read-only) | Indicates that the synchronization failed during download, and that a partial download was kept. See Partial Download Retained synchronization parameter.
IgnoredRows As Boolean (read-only) | Indicates whether rows were ignored during the last synchronization. See Ignored Rows synchronization parameter.
StreamErrorCode As ULStreamErrorCode (read-only) | Gets the error code reported by the synchronization stream.
StreamErrorContext As ULStreamErrorContext (read-only) | Gets the basic network operation performed.
StreamErrorID As ULStreamErrorID (read-only) | Gets the network layer reporting the error.
StreamErrorSystem As Long (read-only) | Gets the stream error system-specific code.
Timestamp as Variant (read-only) | Gets the timestamp of the last synchronization.
UploadOK As Boolean (read-only) | Indicates whether data was uploaded successfully in the last synchronization. See Version synchronization parameter.


ULTable class

The ULTable class is used to store, remove, update, and read data from a table.

Before you can work with table data, you must call the Open method. ULTable uses table modes for table operations:

Mode | Description
FindBegin | Begins find mode
InsertBegin | Begins insert mode
LookupBegin | Begins lookup mode
UpdateBegin | Begins update mode

Properties
Close method
Delete method
DeleteAllRows method
FindBegin method
FindFirst method
FindLast method
FindNext method
FindPrevious method
Insert method
InsertBegin method
LookupBackward method
LookupBegin method
LookupForward method
MoveAfterLast method
MoveBeforeFirst method
MoveFirst method
MoveLast method
MoveNext method
MovePrevious method
MoveRelative method
Open method
Truncate method
Update method
UpdateBegin method


Properties

Prototype | Description
BOF As Boolean (read-only) | Indicates whether the current row position is before the first row. Returns True if the current row position is before the first row, otherwise false.
Columns As IColumns (read-only) | Gets a collection of column objects
EOF As Boolean (read-only) | Indicates whether the current row position is after the last row. Returns True if the current row position is before the first row, otherwise false.
IsOpen As Boolean (read-only) | Indicates whether or not the table is currently open.
RowCount As Long (read-only) | Gets the number of rows in the table.
Schema As ULTableSchema (read-only) | Gets information about the table schema.


Close method

Prototype

Close( )
Member of UltraliteActiveX.ULTable

Description

Frees resources associated with the table. This method should be called after all processing involving the table is complete.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite ActiveX User's Guide

UltraLite ActiveX API Reference

ULTable class

Delete method

Prototype

Delete( )
Member of UltraliteActiveX.ULTable

Description

Deletes the current row from the table.


DeleteAllRows method

Prototype

DeleteAllRows( )
Member of UltraliteActiveX.ULTable

Description

Deletes all rows in the table.

In some applications, it can be useful to delete all rows from tables before downloading a new set of data into the table. Rows can be deleted from the UltraLite database without being deleted from the consolidated database using the ULConnection.StopSynchronizationDelete method or calling Truncate instead of DeleteAllRows.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite ActiveX User's Guide

UltraLite ActiveX API Reference

ULTable class

FindBegin method

Prototype

FindBegin( )
Member of UltraliteActiveX.ULTable

Description

Prepares a table for a find.


FindFirst method

Prototype

FindFirst( [num_columns As Long = 32767] ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Move forwards through the table from the beginning, looking for a row that exactly matches a value or set of values in the current index.

The current index is that used to specify the sort order of the table. It is specified when your application calls the Open method. The default index is the primary key.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that exactly matches the index value. On failure the cursor position is after the last row (EOF).

Note : Requires that FindBegin be called prior to using this method.

Parameters

num_columns An optional parameter referring to the number of columns to be used in the FindFirst. For example, if 2 is passed, the first two columns are used for the FindFirst. If num_columns exceeds the number of columns indexed, all columns are used in FindFirst.

Returns

True if successful.

False if unsuccessful.


FindLast method

Prototype

FindLast( [ num_columns As Long = 32767 ] ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Move backwards through the table from the end, looking for a row that matches a value or set of values in the current index.

The current index is used to specify the sort order of the table. It is specified when your application calls the Open method. The default index is the primary key.

For more information, see Open method.

To specify the value to search for, set the column value for each column in the index for which you want to find the value. The cursor is left on the last row found that exactly matches the index value. On failure the cursor position is before the first row (BOF).

Note
Requires that FindBegin be called prior to using this method.
Parameters

num_columns An optional parameter referring to the number of columns to be used in the FindLast. For example, if 2 is passed, the first two columns are used for the FindLast. If num_columns exceeds the number of columns indexed, all columns are used in FindLast.

Returns

True if successful.

False if unsuccessful.


FindNext method

Prototype

FindNext( [ num_columns As Long = 32767 ] ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Move forwards through the table from the current position, looking for the next row that exactly matches a value or set of values in the current index.

The current index is that used to specify the sort order of the table. It is specified when your application calls the Open method. The default index is the primary key.

For more information, see Open method.

The cursor is left on the first row found that exactly matches the index value. On failure, the cursor position is after the last row (EOF).

Note : Must be preceded by FindFirst or FindLast.

Parameters

num_columns An optional parameter referring to the number of columns to be used in the FindNext. For example, if 2 is passed, the first two columns are used for the FindNext. If num_columns exceeds the number of columns indexed, all columns are used in FindNext.

Returns

True if successful.

False if unsuccessful (EOF).


FindPrevious method

Prototype

FindPrevious( [ num_columns As Long = 32767 ] ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Move backwards through the table from the current position, looking for the previous row that exactly matches a value or set of values in the current index.

The current index is that used to specify the sort order of the table. It is specified when your application calls the Open method. The default index is the primary key.

For more information, see Open method.

On failure it is positioned before the first row (BOF).

Parameters

num_columns An optional parameter referring to the number of columns to be used in the FindPrevious. For example, if 2 is passed, the first two columns are used for the FindPrevious. If num_columns exceeds the number of columns indexed, all columns are used in FindPrevious.

Returns

True if successful.

False if unsuccessful (BOF).


Insert method

Prototype

Insert( ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Inserts a row in the table with values specified in previous Set methods. Must be preceded by InsertBegin. Set for each ULColumn object.

Returns

True if successful.

False if unsuccessful (BOF).


InsertBegin method

Prototype

InsertBegin( )
Member of UltraliteActiveX.ULTable

Description

Prepares a table for inserting a new row, setting column values to their defaults.

Examples

In this example, InsertBegin sets insert mode to allow you to begin assigning data values to CustomerTable columns.

' eMbedded Visual Basic
CustomerTable.InsertBegin
CustomerTable.Columns("Fname").Value = fname
CustomerTable.Columns("Lname").Value = lname
If Len(city) > 0 Then
  CustomerTable.Columns("City").Value = city
End If
If Len(phone) > 0 Then
  CustomerTable.Columns("phone").Value = phone
End If
CustomerTable.Insert
// JScript
CustomerTable.InsertBegin();
CustomerTable.Columns("Fname").Value = fname;
CustomerTable.Columns("Lname").Value = lname;
If ( Len(city) > 0 ) {
  CustomerTable.Columns("City").Value = city;
}
If ( Len(phone) > 0 ) {
  CustomerTable.Columns("phone").Value = phone;
}
CustomerTable.Insert();
See also

UpdateBegin method


LookupBackward method

Prototype

LookupBackward( [ num_columns As Long = 32767 ] ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Move backwards through the table starting from the end, looking for the first row that matches or is less than a value or set of values in the current index.

The current index is that used to specify the sort order of the table. It is specified when your application calls the Open method. The default index is the primary key.

For more information, see Open method.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the last row that matches or is less than the index value. On failure (that is, if no row is less than the value being looked for), the cursor position is before the first row (BOF).

Parameters

num_columns For composite indexes, the number of columns to use in the lookup.

Returns

True if successful.

False if unsuccessful.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite ActiveX User's Guide

UltraLite ActiveX API Reference

ULTable class

LookupBegin method

Prototype

LookupBegin( )
Member of UltraliteActiveX.ULTable

Description

Prepares a table for a lookup.


LookupForward method

Prototype

LookupForward( [num_columns As Long = 32767 ] ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Move forward through the table starting from the beginning, looking for the first row that matches or is greater than a value or set of values in the current index.

The current index is that used to specify the sort order of the table. It is specified when your application calls the Open method. The default index is the primary key.

For more information, see Open method.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is greater than the index value. On failure (that is, if no rows are greater than the value being looked for), the cursor position is after the last row (EOF).

Parameters

num_columns For composite indexes, the number of columns to use in the lookup.

Returns

True if successful.

False if unsuccessful.


MoveAfterLast method

Prototype

MoveAfterLast( ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Moves to a position after the last row.

Returns

True if successful.

False if the operation fails.


MoveBeforeFirst method

Prototype

MoveBeforeFirst( ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Moves to a position before the first row.

Returns

True if successful.

False if the operation fails.


MoveFirst method

Prototype

MoveFirst( ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Moves to the first row.

Returns

True if successful.

False if there is no data in the table.


MoveLast method

Prototype

MoveLast( ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Moves to the last row.

Returns

True if successful.

False if there is no data in the table.


MoveNext method

Prototype

MoveNext( ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Moves to the next row.

Returns

True if successful.

False if there is no more data in the table. For example, MoveNext fails if there are no more rows.


MovePrevious method

Prototype

MovePrevious( ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Moves to the previous row.

Returns

True if successful.

False if there is no more data in the table. For example, MovePrevious fails if there are no rows.


MoveRelative method

Prototype

MoveRelative( index As Long ) As Boolean
Member of UltraliteActiveX.ULTable

Description

Moves a certain number of rows relative to the current row.

Parameters

index The number of rows to move. The value can be positive, negative, or zero. Zero is useful if you want to repopulate a row buffer.

Returns

True if successful.

False if the move failed, as may happen, for example, if the cursor is positioned beyond the first or last row.


Open method

Prototype

Open(
[ index_id ], _)
Member of UltraliteActiveX.ULTable

Description

Opens the table so it can be read or manipulated. By default, the rows are ordered by primary key. By supplying an index , the rows can be ordered in other ways.

The cursor is positioned before the first row in the table.

Parameters

indexID An optional parameter referring to the ID of the index.


Truncate method

Prototype

Truncate( )
Member of UltraliteActiveX.ULTable

Description

Removes all data from this table. The changes are not synchronized, so that on synchronization, it does not affect the data in the consolidated database.

For more information, see StartSynchronizationDelete method.


Update method

Prototype

Update( )
Member of UltraliteActiveX.ULTable

Description

Updates a row in the table with values specified in ULColumn methods.

Note : Must be preceded by a call to UpdateBegin.


UpdateBegin method

Prototype

UpdateBegin( )
Member of UltraliteActiveX.ULTable

Description

Prepares a table for modifying the contents of the current row.

Example
' eMbedded Visual Basic
Table.UpdateBegin
Table.Columns( "ColName" ).Value = "New Value"
Table.Update
// JScript
Table.UpdateBegin();
Table.Columns("ColName").Values = "NewValue";
Table.Update();


Web Links Browse Collapse Expand PDF Previous Next

UltraLite ActiveX User's Guide

UltraLite ActiveX API Reference

ULTableSchema class

The ULTableSchema object allows you to obtain the attributes of a table.


Properties

The ULTableSchema represents metadata about the table. The following are properties of the ULTableSchema class:

Prototype | Description
ColumnCount As Integer (read-only) | The number of columns in this table
Indexes As IIndexSchemas | The number of indexes on this table
Name As String (read-only) | This table's name
NeverSynchronized As Boolean (read-only) | Indicates if the table is always excluded from synchronization.
PrimaryKey As ULIndexSchema (read-only) | The primary key for this table.
UploadUnchangedRows As Boolean (read-only) | Indicates if all rows in the table should be uploaded on synchronization, rather than just the rows changed since the last synchronization.


InPublication method

Prototype

InPublication( publicationName ) As Boolean
Member of UltraliteActiveX.ULTableSchema

Description

Indicates whether this table is part of the specified publication.

Parameters

publicationName The name of the publication you are checking.

Returns

True if the table is part of the publication.

False if the table is not part of the publication.


Web Links Browse Collapse Expand PDF Previous Next

Native UltraLite for Java User's Guide

Version 9.0.2

DC36294-01-0902-01

October 2004

Copyright
About This Manual
Introduction to Native UltraLite for Java
Tutorial: Build a Native UltraLite for Java Application
Tutorial: The CustDB Sample Application
Understanding Native UltraLite for Java Development
Native UltraLite for Java API Reference


About This Manual

Subject

This manual describes Native UltraLite for Java. With Native UltraLite for Java you can develop and deploy database applications to Windows CE devices running the Jeode or CrEme VMs.

Audience

This manual is intended for Java application developers who wish to take advantage of the performance, resource efficiency, robustness, and security of an UltraLite relational database for data storage and synchronization.


Introduction to Native UltraLite for Java

About this chapter

This chapter introduces you to Native UltraLite for Java. It assumes that you are familiar with the features of UltraLite, as described in Welcome to UltraLite.

For more information about creating applications using Native UltraLite for Java, see Understanding Native UltraLite for Java Development.

For a hands-on tutorial introducing Native UltraLite for Java, see Tutorial: Build a Native UltraLite for Java Application or Tutorial: The CustDB Sample Application.


UltraLite and Java

Java developers wishing to take advantage of UltraLite database features have two options:

  • The Static Java API is a pure Java UltraLite technology described in UltraLite Static Java User's Guide.

  • Native UltraLite for Java (documented in the current book) provides a Native UltraLite for Java package, together with a native (C++) UltraLite runtime library. This combines the benefits of Java development with the performance of native applications and access to operating system-specific features such as ActiveSync synchronization.

Native UltraLite for Java differs from UltraLite for Java in the following ways:

  • Native components The UltraLite runtime for Native UltraLite for Java uses native methods. That is, it is not written in Java but in C++, and compiled into binary form specific to the underlying CPU and operating system. In contrast, the UltraLite runtime for the Static Java API is a pure Java implementation.

  • Component API Native UltraLite for Java shares API features and structure with the other members of the UltraLite Component Suite. The Static Java API uses JDBC as the programming interface.

  • Windows CE deployment Native UltraLite for Java offers Windows CE as a deployment target. It supports the Jeode VM provided with many Windows CE devices and the CrEme VM. It also supports ActiveSync synchronization.

    For details of platform support, see UltraLite target platforms.

For more information about the features of UltraLite databases, see UltraLite Databases.


System requirements and supported platforms

Development platforms

To develop applications using Native UltraLite for Java, you require the following.

  • Microsoft Windows NT/2000/XP.

  • JDK 1.1.8 or Personal Java 1.2 is recommended for Native UltraLite for Java application development. Borland JBuilder 7 and 8 integration is provided.

Target platforms

Native UltraLite for Java supports the following target platforms:

  • Windows CE 3.0 or higher on devices using the ARM processor, including the Compaq iPaq and NEC MobilePro P300, and a Jeode Personal Java 1.2 compatible VM.

  • Windows NT/2000/XP with JRE 1.1.8 or later.

For more information, see UltraLite development platforms and UltraLite target platforms.


Native UltraLite for Java architecture

The Native UltraLite for Java package is named ianywhere.native_ultralite.

The following list describes some of the more commonly-used high level classes.

  • DatabaseManager You create one DatabaseManager object for each application.

  • Connection Each Connection object represents a connection to an UltraLite database. You can create one or more Connection objects.

  • Table The Table object provides access to the data in the database.

  • PreparedStatement, ResultSet, and ResultSetSchema These dynamic SQL objects allow you to create Dynamic SQL statements, make queries and execute INSERT, UPDATE and DELETE statements, and attain programmatic control over database result sets.

  • SyncParms You use the SyncParms object to synchronize your UltraLite database with a MobiLink synchronization server.

The API Reference is supplied in Javadoc format in the UltraLite\NativeUltraLiteForJava\doc subdirectory of your SQL Anywhere installation. For more information about accessing the API reference, see Native UltraLite for Java API Reference.


Tutorial: Build a Native UltraLite for Java Application

About this chapter

This chapter provides a tutorial to guide you through the process of building a sample Native UltraLite for Java application.

Introduction
Lesson 1: Connect to the database
Lesson 2: Insert data into the database
Lesson 3: Select the rows from the table
Lesson 4: Deploy your application to a Windows CE device
Lesson 5: Add synchronization to your application
Summary


Introduction

This tutorial guides you through the process of building a Native UltraLite for Java application.

This tutorial uses a text editor to edit the Java files. You can also use Native UltraLite for Java in the Borland JBuilder development environment.

For more information, see Developing applications with Borland JBuilder.

Timing

This tutorial takes about 30 minutes if you copy and paste the code. If you enter the code yourself, it takes significantly longer.

Competencies and experience

This tutorial assumes:

  • you are familiar with the Java programming language

  • you have JDK 1.1.8 or Personal Java 1.2 installed on your computer

  • you know how to create an UltraLite schema using the UltraLite Schema Painter

    For more information, see Lesson 1: Create an UltraLite database schema.

Note
The synchronization portion of this tutorial requires SQL Anywhere Studio.
Goals

The goals for this tutorial are to gain competence and familiarity with the process of developing a Native UltraLite for Java application.


Lesson 1: Connect to the database

In the first procedure, you create a database schema. You then write, compile, and run a Java application that creates a database using the schema you have created, or connects to an existing database.

toggle To create a database schema

  1. Create a directory to hold the files you create in this tutorial.

    This tutorial assumes the directory is c:\tutorial\java. If you create a directory with a different name, use that directory instead of c:\tutorial\java throughout the tutorial.

  2. Create a database schema with the following characteristics using the UltraLite Schema Painter.

    For more information, see the Lesson 1: Create an UltraLite database schema.

    Schema file name: tutcustomer.usm

    Table name: Customer

    Columns in Customer:

    Column Name | Data Type (Size) | Column allows NULL values? | Default value
    ID | integer | No | autoincrement
    FName | char(15) | No | None
    LName | char(20) | No | None
    City | char(20) | Yes | None
    Phone | char(12) | Yes | 555-1234

    Primary key: ascending ID

toggle To connect to an UltraLite database

  1. In your tutorial directory, create a file named Customer.java.

  2. Copy the code below into Customer.java.

    This code carries out the following tasks:

    • Imports the UltraLite library and the JDBC SQLException class.

    • Declares a class named Customer.

    • Declares a static variable to hold the database connection object. This object will be shared among several methods later in the tutorial.

    • Invokes the class constructor.

    • If an error occurs, prints the error code and a stack trace.

      For more information about the error code, see ASA Error Messages.

    import ianywhere.native_ultralite.*;
import java.sql.SQLException;

public class Customer {
  static Connection conn;
  public static void main( String args[] ) {
    try {
      Customer cust = new Customer();
      // Clean up
      conn.close();
    } catch( SQLException e ) {
      System.out.println(
        "Exception: " + e.getMessage() +
        " sqlcode=" + e.getErrorCode()
          );
      e.printStackTrace();
    }
  }
}

  3. Add a constructor to the class.

    Copy the code below into your file. This code carries out the following tasks.

    • Instantiates a new DatabaseManager object. All UltraLite objects are created from the DatabaseManager object.

    • Instantiates and defines a new CreateParms object. CreateParms stores the parameters necessary to connect to or create a database. Here, the parameters are the location of the database file and the schema file on the desktop.

      In this example, the locations are hard coded for convenience. In a real application, they would not be hard coded. In addition, these parameters are sufficient only for connections in the development environment; additional parameters are needed for the application to run on a Windows CE device. These additional parameters are described later in the tutorial.

    • If the database file does not exist, a SQLException is thrown. The code that catches this exception uses the schema file to create a new database and establish a connection to it.

    • If the database file does exist, a connection is established.

    public Customer() throws SQLException
{
  // Connect
  DatabaseManager dbMgr = new DatabaseManager();
  CreateParms parms = new CreateParms();
  parms.databaseOnDesktop = "c:\\tutorial\\java\\tutcustomer.udb";
  parms.schema.schemaOnDesktop = "c:\\tutorial\\java\\tutcustomer.usm";
  try {
    conn = dbMgr.openConnection( parms );
    System.out.println(
            "Connected to an existing database." );
  } catch( SQLException econn ) {
    if( econn.getErrorCode() ==
        SQLCode.SQLE_ULTRALITE_DATABASE_NOT_FOUND ){
      conn = dbMgr.createDatabase( parms );
      System.out.println(
            "Connected to a new database." );
    } else {
      throw econn;
    }
  }
}

  4. Compile the Customer class.

    It is recommended that you use Sun JDK 1.1.8 or Personal Java 1.2 to compile the class. In addition, you must add the UltraLite library jul9.jar to your classpath. This library is in the ultralite\NativeUltraLiteForJava subdirectory of your SQL Anywhere installation.

    Enter the following command on a single line at a command prompt.

    javac -classpath
"%ASANY9%\ultralite\NativeUltraLiteForJava\jul9.jar;%classpath%"
Customer.java

  5. Run the application.

    The classpath must include the UltraLite library jul9.jar, as in the previous step.

    The application must also be able to load the DLL that holds UltraLite native methods. The DLL is jul9.dll in the ultralite\NativeUltraLiteForJava\win32 subdirectory of your SQL Anywhere 9 installation. This DLL can be in your system path or you can specify it on the java command line, as follows:

    java -classpath
".;%ASANY9%\ultralite\NativeUltraLiteForJava\jul9.jar"
-Djul.library.dir=
"%ASANY9%\ultralite\NativeUltraLiteForJava\win32" Customer

    This command must be all on one line, with no spaces inside the individual arguments.


Lesson 2: Insert data into the database

The following procedure demonstrates how to add data to the database.

toggle To add rows to your database

  1. Add the method below to the Customer.java file.

    This method carries out the following tasks:

    • Opens the table. You must open a Table object to carry out any operations on the table. To obtain a Table object, use the connection.getTable() method.

    • Obtains identifiers for some of the columns of the table. The other columns in the table can accept NULL values or have a default value. In this tutorial only required values are specified.

    • If the table is empty, adds two rows. To insert each row, the code sets the mode to insert mode using InsertBegin, sets values for each required column, and executes an insert to add the rows to the database.

      The commit method is not strictly needed here, as the default mode for applications is to commit operations after each insert. It has been added to the code to emphasize that if you turn off autocommit behavior you must commit a change for it to be permanent.

    • If the table is not empty, reports the number of rows in the table.

    • Closes the Table object.

    private void insert() throws SQLException
{
  // Open the Customer table
  Table t = conn.getTable( "Customer" );
  t.open();

  short id = t.schema.getColumnID( "ID" );
  short fname = t.schema.getColumnID( "FName" );
  short lname = t.schema.getColumnID( "LName" );

  // Insert two rows if the table is empty
  if( t.getRowCount() == 0 ) {

      t.insertBegin();
      t.setString( fname, "Gene" );
      t.setString( lname, "Poole" );
      t.insert();

      t.insertBegin();
      t.setString( fname, "Penny" );
      t.setString( lname, "Stamp" );
      t.insert();

      conn.commit();
      System.out.println( "Two rows inserted." );
  } else {
      System.out.println( "The table has " +
      t.getRowCount() + " rows." );
  }
  t.close();
}

  2. Call the insert method you have created.

    Add the following line to the main() method, immediately after the call to the Customer constructor.

    cust.insert();

  3. Compile and run your application, as in Lesson 1: Connect to the database.


Lesson 3: Select the rows from the table

The following procedure demonstrates how to loop over the rows of a table. It retrieves rows from the table, and prints them on the command line.

toggle To list the rows in the table

  1. Add the following method to the Customer.java file.

    This method carries out the following tasks.

    • Opens the Table object.

    • Retrieves the column identifiers.

    • Sets the current position before the first row of the table.

      Any operations on a table are carried out at the current position. The position may be before the first row, on one of the rows of the table, or after the last row. By default, as in this case, the rows are ordered by their primary key value (id). To order rows in a different way, you can add a new index to the database and open a table using that index.

    • For each row, the id and name are written out. The loop carries on until moveNext returns false, which happens after the final row.

    • Closes the Table object.

    private void select() throws SQLException
{
  // Fetch rows
  // Open the Customer table
  Table t = conn.getTable( "Customer" );
  t.open();
  short id = t.schema.getColumnID( "ID" );
  short fname = t.schema.getColumnID( "FName" );
  short lname = t.schema.getColumnID( "LName" );
  t.moveBeforeFirst();
  while( t.moveNext() ) {
      System.out.println(
        "id= " + t.getInt( id )
        + ", name= " + t.getString( fname )
        + " " + t.getString( lname )
        );
  }
  t.close();
}

  2. Call the select function you have created.

    Add the following line to the main() method, immediately after the call to the insert method.

    cust.select();

  3. Compile and run your application, as in Lesson 1: Connect to the database.


Lesson 4: Deploy your application to a Windows CE device

Running the sample application on Windows CE requires that the a supported Java VM be installed on your device.

The Jeode Runtime (Java VM) is packaged with some devices, including the HP/Compaq iPAQ and NEC MobilePro P300. CrEme Plus is also available and includes CrEme bundled with Symbol value-add capabilities. Both VMs can be purchased for other devices.

toggle To confirm that the Jeode VM is installed on your Windows CE device

  • Choose Start > Programs.

    If the Jeode VM is installed, a Jeode folder appears in the Programs folder.

toggle To prepare your application to run on a Windows CE device

  1. Specify the location of your database file and schema file by specifying the schemaOnCE and databaseOnCE parameters.

    In the Customer constructor, alter the CreateParms object to read as follows.

    CreateParms parms = new CreateParms();
parms.databaseOnDesktop = "c:\\tutorial\\java\\tutcustomer.udb";
parms.databaseOnCE = "\\UltraLite\\tutorial\\tutcustomer.udb";
parms.schema.schemaOnDesktop = "c:\\tutorial\\java\\tutcustomer.usm";
parms.schema.schemaOnCE = "\\UltraLite\\tutorial\\tutcustomer.usm"";

  2. Compile your application as in Lesson 1: Build the CustDB application.

  3. Run your application to check that no errors were introduced. The schemaOnCE and databaseOnCE parameters have no effect when running in a desktop environment.

  4. Prepare a shortcut to run the application.

    A shortcut is a text file with .lnk extension, which contains a command line to run the application. In the next procedure, you copy this shortcut file to a location on the device.

    Using a text editor, create a file named tutorial.lnk in your tutorial directory with the following content, which should all be on a single line.

    18#"\Windows\evm.exe"
-Djeode.evm.console.local.keep=TRUE
-Djeode.evm.console.local.paging=TRUE
-Djul.library.dir=\UltraLite\lib
-cp \UltraLite\tutorial;\UltraLite\lib\jul9.jar
Customer

    The meaning of the elements in this command are as follows.

    • The first line starts the Jeode VM executable.

    • The -Djeode options control the display of the text console that is used for output from the application.

    • The -Djul.library.dir option directs the VM to the UltraLite native interface runtime library (jul9.dll).

    • The -cp option provides the classpath for the VM. It indicates the location of the application and the UltraLite runtime library.

    • The final argument is the class, which in this case is Customer.

The following procedure copies the files to your device. You must copy both UltraLite runtime files and application-specific files.

toggle To deploy the UltraLite runtime to the Windows CE device

  1. Start Windows Explorer on your Windows CE device.

    • Ensure that your device is connected to your desktop computer.

    • In the ActiveSync window, click Explore. An Explorer window opens.

  2. Create directories to hold the UltraLite runtime and application.

    • In the Explorer window, click My Pocket PC to access the root directory.

    • Create a directory named UltraLite.

    • Open the UltraLite directory and create subdirectories named lib and tutorial. The directory path \UltraLite\lib is the location for the UltraLite runtime files, and the path \UltraLite\tutorial is the location for the application. These directories match the options in the shortcut file described above.

  3. Copy the UltraLite runtime files to the Windows CE device.

    • Start a separate Explorer window and navigate to the SQL Anywhere installation directory on our desktop machine.

    • Drag the following files from the desktop to the device

    Desktop location relative to your SQL Anywhere directory | Windows CE location
    UltraLite\NativeUltraLiteForJava\jul9.jar | \UltraLite\lib\jul9.jar
    UltraLite\NativeUltraLiteForJava \ce\arm\jul9.dll | \UltraLite\lib\jul9.dll

    As an alternative, you can deploy the UltraLite engine, an executable that permits concurrent multi-process access to UltraLite databases. If you use the UltraLite engine, you must deploy the appropriate version of the component (julclient9.dll) and you must specify the Runtime Type property in the Database Manager.

  4. Copy the application files to the Windows CE device.

    • In your Explorer window, navigate to the tutorial directory.

    • Drag the following files from the desktop to the device

    Desktop location | Windows CE location
    Customer.class | \UltraLite\tutorial
    tutcustomer.usm | \UltraLite\tutorial

    In this tutorial, you do not copy the database file to the Windows CE device. Instead, you copy a schema file to the device and the application creates a database based on the schema file.

  5. If you are running the CrEme VM and wish to use ActiveSync, add \Windows\CrEme\lib\crmex.jar to your classpath.

  6. Copy the shortcut file to the Windows CE device.

    • Drag the following file from the desktop to the device.

    Desktop location | Windows CE location
    tutorial.lnk | \Windows\Start Menu

The following procedure runs the application

toggle To run the application

  1. On the Windows CE device, choose Start > tutorial.

    This shortcut is the tutorial.lnk file that you copied onto the device.

    • The Jeode VM loads and the console is displayed.

    • The following messages are printed onto the console.

      Connected to a new database.
Two rows inserted.
id= 1, name= Gene Poole
id= 2, name= Penny Stamp
Application finished. Please close console

    • Close the console.

  2. On the Windows CE device, choose Start > tutorial again.

    This time the first two messages are as follows.

    Connected to an existing database.
The table has 2 rows.

  3. Close the console.


Lesson 5: Add synchronization to your application

The following procedures add synchronization code to your application, starts the MobiLink synchronization server, and runs your application to synchronize.

Note
This lesson uses MobiLink synchronization, which is part of SQL Anywhere Studio. You must have SQL Anywhere Studio installed on your computer to carry out this lesson.

Synchronization is carried out with the ASA 9.0 Sample database. The ASA 9.0 Sample database has a Customer table whose columns match those in the customer table of your UltraLite database. During synchronization the data in that table is downloaded to your UltraLite application.

This lesson assumes some familiarity with MobiLink synchronization.

toggle To add synchronization to your application

  1. Add the method below to Customer.java.

    This code carries out the following tasks.

    • Sets the synchronization stream to TCP/IP. Synchronization can also be carried out over HTTP, ActiveSync, or HTTPS. HTTPS synchronization requires that you obtain the separately licensable SQL Anywhere Studio security option.

      For more information, see ianywhere.native_ultralite.StreamType and ianywhere.native_ultralite.Connection in the Native UltraLite for Java API Reference.

      The syncParms field of the Connection object provides convenient access to a SyncParms object. For more information, see ianywhere.native_ultralite.SyncParms in the Native UltraLite for Java API Reference.

    • MobiLink synchronization is controlled by scripts at the MobiLink synchronization server. The script version identifies which set of scripts to use. The setSendColumnNames method together with an option on the MobiLink synchronization server causes the scripts to be generated automatically.

      For more information, see Generating scripts automatically.

    • Sets the MobiLink user name. This value is used for authentication at the MobiLink synchronization server, and is different from the UltraLite database user ID, although in some applications you may wish to make the values the same.

    • Sets the synchronization to only download data. By default, MobiLink synchronization is two-way. Here, we use download-only synchronization so that the rows in your table do not get uploaded to the sample database.

    private void sync() throws SQLException {
  conn.syncParms.setStream( StreamType.TCPIP );
  conn.syncParms.setVersion( "ul_default" );
  conn.syncParms.setUserName( "sample" );
  conn.syncParms.setSendColumnNames( true );
  conn.syncParms.setDownloadOnly( true );
  conn.synchronize();
}

  2. Call your sync method.

    Add the following line to the main() method, immediately after the call to the insert method and before the call to the select method.

    cust.sync();

  3. Compile your application, as in Lesson 1: Connect to the database. Do not run the application.

toggle To synchronize your data

  1. Start the MobiLink synchronization server.

    From a command prompt, run the MobiLink following command line.

    dbmlsrv9 -c "dsn=ASA 9.0 Sample" -v+ -zu+ -za

    The ASA 9.0 Sample database has a Customer table that matches the columns in the UltraLite database you have created. You can synchronize your UltraLite application with the ASA 9.0 Sample database.

    The -zu+ and -za command line options provide automatic addition of users and generation of synchronization scripts.

    For more information about these options, see the MobiLink Synchronization Server Options.

  2. Run your application, as in Lesson 1: Connect to the database.

    The MobiLink synchronization server window displays status messages indicating the synchronization progress. The final message displays Synchronization complete.


Summary

Learning accomplishments

During this tutorial, you:

  • created a database schema

  • created a Native UltraLite for Java application

  • synchronized an UltraLite remote database with an Adaptive Server Anywhere consolidated database

  • gained competence with the process of developing a Native UltraLite for Java application

Samples

  • For more code samples, see Samples\NativeUltraLiteForJava\Simple\Simple.java.


Tutorial: The CustDB Sample Application

About this chapter

This chapter provides a tutorial to guide you through the process of building and deploying a multi-table application using Native UltraLite for Java.

This tutorial also demonstrates synchronization between an UltraLite remote database and a consolidated database. The synchronization portion of this tutorial requires SQL Anywhere Studio.


Introduction

This tutorial guides you through the process of compiling, running, and deploying the CustDB sample application. It demonstrates how to implement several common tasks using Native UltraLite for Java.

Source code for CustDB is supplied in the Samples\NativeUltraLiteForJava\CustDB subdirectory of your SQL Anywhere installation.

Timing

The tutorial takes about 30 minutes if you copy and paste the code. If you enter the code yourself, it takes significantly longer.

Competencies and experience

This tutorial assumes:

  • you have access a Windows CE device running the Jeode VM

  • you have a Java development kit installed on your computer. JDK 1.1.8 or Personal Java 1.2 is recommended, as it is compatible with the Jeode VM used for deployment

  • you know how to create an UltraLite schema using the UltraLite Schema Painter

    For more information, see Lesson 1: Create an UltraLite database schema.

Note
The synchronization portion of this tutorial requires SQL Anywhere Studio.
Goals

The goals for this tutorial are to gain competence and familiarity with developing Native UltraLite for Java applications.


Lesson 1: Build the CustDB application

The following procedure uses the build.bat script, located in the Samples\NativeUltraLiteForJava\CustDB subdirectory of your installation, to build the CustDB sample from the source java files.

A clean.bat script is also provided for removing the results of the build.

toggle To build the sample

  1. Open a command prompt and navigate to the Samples\NativeUltraLiteForJava\CustDB subdirectory of your SQL Anywhere installation.

    You should leave this command prompt open for the entire tutorial.

  2. Set the required environment variables.

    Ensure the environment variables ASANY9 and JAVA_HOME are properly defined.

    • ASANY9 is set by the setup program to the location of your SQL Anywhere installation.

    • Set the JAVA_HOME environment variable to the location of a JDK on your computer. JDK 1.1.8 or Personal Java 1.2 is recommended, as it is compatible with the Jeode VM used for deployment.

      For example, if the JDK is version 1.1.8 in c:\jdk1.1.8 run the following command.

      set JAVA_HOME=c:\jdk1.1.8

  3. Build the application.

    At the command prompt, run the following command:

    build

    The build batch file carries out the following operations.

    • Compiles the CustDB sample code.

      The compiled classes are stored in the builddir subdirectory.

    • Puts the compiled classes into a JAR file.

      The JAR file is stored in the CustDB directory.

    • Creates a database schema file using the ulinit command line utility.

      The schema file is created from the Adaptive Server Anywhere UltraLite 9.0 Sample database.

      For more information about the ulinit tool, see The ulinit utility.

The sample code


The sample code

The sample code files are given below together with a brief description.

File | Description
Application.java | The main user interface frame, event processing, and ActiveSync support.
CustDB.java | The main interface to the database. Most of the database processing is in this file.
DialogDelOrder.java | The delete confirmation dialog.
DialogNewOrder.java | The new order entry form which shows populating a list box with data from the database.
Dialogs.java | The common base class for dialogs.
DialogSyncHost.java | This prompts for synchronization host name.
DialogUserID.java | This prompts for the Employee ID.
GetOrder.java | This is a class representing order data. It shows how to do a key join.
GetOrderData.java | This computes min and max order ID. Equivalent to SELECT max( order_id ), min( order_id ) FROM ULOrder.


Lesson 2: Run the CustDB application

The following procedure demonstrates how to run the CustDB sample on Windows. Deployment to a Windows CE device is described in Lesson 3: Deploy CustDB to a Windows CE device. This lesson uses MobiLink synchronization, and so requires SQL Anywhere Studio.

toggle To run the sample on Windows

  1. From the same command prompt as in the previous lesson, type win32\run.bat.

    This command carries out the following operations.

    • Starts the MobiLink synchronization server.

      The server connects to the UltraLite 9.0 Sample database, which is used as a consolidated database for the CustDB application.

    • Starts the CustDB sample.

      The first time you run it, the application starts with no UltraLite database (.udb file) and so it creates this file from the UltraLite schema.

    • Displays a logon window.

      The window appears in the middle of the screen, but may be behind other windows. You may have to move other windows to locate the logon window.

  2. Logon to the application.

    Click OK to logon as a user with MobiLink user name 50. The application synchronizes and synchronization progress information is displayed. After a pause, a window with a single order is displayed.

  3. Explore the application.

    You can move through the rows in the database, approve and deny orders, and synchronize. When you quit the application, the batch file shuts down the MobiLink synchronization server.


Lesson 3: Deploy CustDB to a Windows CE device

The following procedure deploys your application to a Windows CE device. Deployment requires the Jeode Runtime (Java VM).

toggle To deploy the application to a Windows CE device

  1. Start Windows Explorer on your Windows CE device.

    • Ensure that your device is connected to your desktop computer.

    • In the ActiveSync window, click Explore.

      An Explorer window opens.

  2. Create directories to hold the UltraLite runtime and application.

    If you have completed the previous tutorial, some of these directories may already exist.

    • In the Explorer window, click My Pocket PC. This is the root directory, and has a path of \.

    • Create a directory named UltraLite.

    • Open the UltraLite directory and create subdirectories named lib and CustDB.

      \UltraLite\lib is the location for the UltraLite runtime files, and \UltraLite\CustDB is the location for the application. These directories match the options in the shortcut file provided in the ce subdirectory.

  3. Copy the UltraLite runtime files to the Windows CE device.

    If you have completed the previous tutorial, you may have already carried out this operation. You do not need to repeat the step.

    • Start a separate Explorer window and navigate to the SQL Anywhere installation directory on your desktop machine.

    • Drag the following files from the desktop to the device.

    Desktop location relative to your SQL Anywhere directory | Windows CE location
    UltraLite\NativeUltraLiteForJava\jul9.jar | \UltraLite\lib
    UltraLite\NativeUltraLiteForJava\ce\arm\jul9.dll | \UltraLite\lib

  4. Copy the application files to the Windows CE device.

    • In your Explorer window, navigate to the Samples\NativeUltraLiteForJava\CustDB directory.

    • Drag the following files from the desktop to the device.

    Desktop location | Windows CE location
    custdb.jar | \UltraLite\CustDB
    ul_custapi.usm | \UltraLite\CustDB

    In this tutorial, you do not copy the database file to the Windows CE device. Instead, you deploy a schema file to the device and the application creates a database.

  5. Copy the shortcut file to the Windows CE device.

    • Drag the following file from the desktop to the device.

    Desktop location relative to your SQL Anywhere directory | Windows CE location
    ce\CustDB.lnk | \Windows\Start Menu

  6. Install the ActiveSync provider.

    The ActiveSync provider is required for synchronization.

    For instructions, see ActiveSync provider installation utility.

  7. Register the application for use with ActiveSync.

    When registering CustDB, use the following properties.

    Property | Value
    Name | JULCustDB
    Class Name | JULCustDB
    File Location | \Windows\evm.exe
    Arguments | -Djeode.evm.console.local.keep=TRUE -Djul.library.dir=\UltraLite\lib -cp \UltraLite\CustDB\custdb.jar;\UltraLite\lib\jul9.jar custdb.Application ACTIVE_SYNC_LAUNCH

    You can run the batch file Samples\NativeUltraLiteForJava\CustDB\ce\as_register.bat to carry out this operation.

    SQL Anywhere Studio users
    For the setup steps for ActiveSync synchronization, see ActiveSync provider installation utility.
toggle To run the application

  1. Start the MobiLink synchronization server.

    Run the startdb.bat batch file, located in the Samples\NativeUltraLiteForJava\CustDB\ce\ subdirectory of your SQL Anywhere installation.

  2. On the CE device, run the CustDB application from the Start menu.


Summary

During this tutorial, you:

  • Built and ran the CustDB sample on your desktop computer.

  • Deployed a Native UltraLite for Java application to a Windows CE device.


Understanding Native UltraLite for Java Development

About this chapter

This chapter explains how to develop applications using Native UltraLite for Java.

For hands-on tutorials, see Tutorial: Build a Native UltraLite for Java Application or Tutorial: The CustDB Sample Application.

UltraLite database schemas
Connecting to a database
Encryption and obfuscation
Accessing and manipulating data using dynamic SQL
Accessing and manipulating data with the Table API
Transaction processing in UltraLite
Accessing schema information
Error handling
User authentication
Synchronizing UltraLite applications
Developing applications with Borland JBuilder


UltraLite database schemas

The database schema is a description of the database. It is the collection of tables, indexes, keys, and publications within the database, and all the relationships between them.

You do not alter the schema of an UltraLite database directly. Instead, you create a schema (.usm) file and upgrade the database schema from that file by calling a built-in UltraLite function in your application.

A schema file is also used in the initial creation of a database to specify the structure of the database.


Upgrading your database schema

To modify your existing database structure, use the DatabaseSchema.applyFile method. In most cases there will be no data loss, however, data loss can occur if columns are deleted or if the data type for a column is changed to an incompatible type.

For more information, see DatabaseSchema.ApplyFile in the Native UltraLite for Java API Reference.

Example

The following code applies a new schema file using the ApplyFile method. It assumes that you have already connected to the database as shown in Connecting to a database.

DatabaseSchema schema = conn.schema;
SchemaParms parms = new SchemaParms();
parms.schemaOnDesktop = "c:\tutorial\tutcustomer.usm";
try {
  schema.applyFile(parms );
} catch {
  // handle any errors
}


Connecting to a database

UltraLite applications must connect to a database before carrying out operations on the data in it. This section describes how to connect to an UltraLite database.

Using the Connection object

The following properties of the Connection object govern global application behavior.

  • Commit behavior By default, Native UltraLite for Java applications are in autocommit mode. Each insert, update, or delete statement is committed to the database immediately. You can also set Connection.autoCommit to false to build transactions into your application.

    For more information, see Transaction processing in UltraLite.

  • User authentication You can change the user ID and password for the application from the default values of DBA and SQL by using methods to Grant and Revoke connection permissions. Each application can have a maximum of four user IDs.

    For more information, see User authentication.

  • Synchronization A set of objects governing synchronization is accessed from the Connection object.

    For more information, see Synchronizing UltraLite applications.

  • Tables UltraLite tables are accessed using methods of the Connection object.

    For more information, see Accessing and manipulating data with the Table API.

  • Prepared statements A set of objects is provided to handle the execution of dynamic SQL statements and to navigate result sets.

    For more information, see Accessing and manipulating data using dynamic SQL.

For more information, see ianywhere.native_ultralite.Connection in the Native UltraLite for Java API Reference

Multi-threaded applications

Each Connection and all objects created from it should be used on a single thread. If your application requires multiple threads accessing the UltraLite database, each thread requires a separate connection.

toggle To connect to an UltraLite database

  1. Create and initialize a DatabaseManager object.

    The DatabaseManager object is at the root of the object hierarchy. You create only one DatabaseManager object per application. It is often best to declare the DatabaseManager object as global to the application.

    DatabaseManager dbMgr = new DatabaseManager();

    For more information, see ianywhere.native_ultralite.DatabaseManager in the Native UltraLite for Java API Reference.

  2. Declare a Connection object.

    Most applications use a single connection to an UltraLite database and leave the connection open. Multiple connections are only required for multi-threaded data access. For this reason, it is often best to declare the Connection object as global to the application.

    static Connection conn;

  3. Open a connection to an existing database, or create a new database if the specified database file does not exist.

    Most UltraLite applications deploy a schema file rather than a database file, and let UltraLite create the database file on the first connection attempt. Thus, the following code attempts to connect to an existing database. If the database file does not exist, the application creates a database file.

    ConnectionParms parms = new ConnectionParms();
// specify the location of the database file
parms.databaseOnDesktop = "mydata.udb";
try {
  conn = dbMgr.openConnection( parms );
} catch( SQLException econn ) {
  if( econn.getErrorCode() ==
    SQLCode.SQLE_ULTRALITE_DATABASE_NOT_FOUND ){
    CreateParms parms = new CreateParms();
    parms.databaseOnDesktop = "mydata.udb";
    parms.schema.schemaOnDesktop = "mydata.usm";
    try {
      conn = dbMgr.createDatabase( parms );
  }
}
Example

The following code opens a connection to an UltraLite database named mydata.udb. If the database does not exist, it is created using the UltraLite schema file named mydata.usm.

For more information, see the code in Samples\NativeUltraLiteForJava\Simple\Simple.java.

CreateParms parms = new CreateParms();
parms.databaseOnDesktop = "mydata.udb";
parms.schema.schemaOnDesktop = "mydata.usm";
try {
  conn = dbMgr.openConnection( parms );
  System.out.println(
    "Connected to an existing database." );
}
catch( SQLException econn ) {
  if( econn.getErrorCode() ==
      SQLCode.SQLE_ULTRALITE_DATABASE_NOT_FOUND ){
    conn = dbMgr.createDatabase( parms );
    System.out.println(
    "Connected to a new database." );
  } else {
    throw econn;
  }
}


Encryption and obfuscation

You can encrypt or obfuscate your UltraLite database using Native UltraLite for Java.

Encryption

To create a database with encryption, specify an encryption key using the ianywhere.native_ultralite.ConnectionParms.EncryptionKey property, then call the createDatabase method. When you call the createDatabase method, the database is created and encrypted with the specified key.

For more information, see Encryption Key connection parameter .

You can change the encryption key by specifying the new encryption key with the ianywhere.native_ultralite.Connection.changeEncryptionKey method.

For more information, see ianywhere.native_ultralite.Connection in the Native UltraLite for Java API Reference.

After the database is encrypted, connections to the database must specify the correct encryption key. Otherwise, the connection fails.

Obfuscation

To obfuscate the database, specify obfuscate=1 as a creation parameter.

For more information about database encryption, see Encrypting UltraLite databases.


Accessing and manipulating data using dynamic SQL

UltraLite applications can access table data using dynamic SQL or the Table API. This section describes data access using dynamic SQL.

For information about using the Table API, see Accessing and manipulating data with the Table API.

This section explains how to perform the following tasks using dynamic SQL.

  • Inserting, deleting, and updating rows.

  • Retrieving rows to a result set.

  • Scrolling through the rows of a result set.

This section does not describe the SQL language itself. For information about dynamic SQL features, see Dynamic SQL.

For an overview of the sequence of operations required for any SQL operation, see Using dynamic SQL.


Data manipulation: INSERT, UPDATE and DELETE

With UltraLite, you can perform SQL Data Manipulation Language operations. These operations are performed using the PreparedStatement.executeStatement method.

For more information, see ianywhere.native_ultralite.PreparedStatement in the Native UltraLite for Java API Reference.

Using parameters in your prepared statements
Placeholders for parameters in SQL statements are indicated the ? character. For any INSERT, UPDATE or DELETE, each ? is referenced according to its ordinal position in the prepared statement. For example, the first ? is referred to as 1, and the second as 2.
toggle To INSERT a row

  1. Declare a PreparedStatement.

    PreparedStatement prepStmt;

  2. Assign a SQL statement to the PreparedStatement object.

    prepStmt = conn.prepareStatement(
   "INSERT INTO MyTable(MyColumn) values (?)");

  3. Assign input parameter values for the statement.

    The following code shows a string parameter.

    String newValue;
// assign value
prepStmt.setStringParameter(1, newValue);

  4. Execute the statement.

    The return value indicates the number of rows affected by the statement.

    long rowsInserted = prepStmt.executeStatement();

  5. If you have disabled autoCommit, commit the change.

    conn.commit();
toggle To UPDATE a row

  1. Declare a PreparedStatement.

    PreparedStatement prepStmt;

  2. Assign a statement to the PreparedStatement object.

    prepStmt = conn.prepareStatement(
   "UPDATE MyTable SET MyColumn1 = ? WHERE MyColumn2 = ?");

  3. Assign input parameter values for the statement.

    String newValue;
String oldValue;
// assign values
prepStmt.setStringParameter( 1, newValue );
prepStmt.setStringParameter( 2, oldValue );

  4. Execute the statement.

    long rowsUpdated = prepStmt.executeStatement();

  5. If you have disabled autoCommit, commit the change.

    conn.commit();
toggle To DELETE a row

  1. Declare a PreparedStatement.

    PreparedStatement prepStmt;

  2. Assign a statement to the PreparedStatement object.

    prepStmt = conn.prepareStatement(
   "DELETE FROM MyTable WHERE MyColumn = ?");

  3. Assign input parameter values for the statement.

    String deleteValue;
prepStmt.setStringParameter(1, deleteValue);

  4. Execute the statement.

    long rowsDeleted = prepStmt.executeStatement();

  5. If you have disabled autoCommit, commit the change.

    conn.commit();


Data retrieval: SELECT

The SELECT statement allows you to retrieve information from the database. This section describes how to execute a SELECT statement and how to handle the result set it returns.

toggle To execute a SELECT statement

  1. Declare a PreparedStatement object, which holds the query.

    PreparedStatement prepStmt;

  2. Assign a statement to the object.

    prepStmt = conn.prepareStatement(
"SELECT MyColumn FROM MyTable");

  3. Execute the statement.

    In the following code, the result of the SELECT query contain a string, which is output to a command prompt.

    ResultSet customerNames = prepStmt.executeQuery();
customerNames.moveBeforeFirst();
while( customerNames.moveNext() ) {
   for ( int i = 1;
         i <= customerNames.schema.getColumnCount();
         i++ ) {
      System.out.print(
        customerNames.getString( i ) + " "
        );

  }
  System.out.println();
}


Navigating dynamic SQL result sets

You can navigate through a result set using methods associated with the ResultSet object.

The result set object provides you with the following methods to navigate a result set.

  • moveAfterLast() moves to a position after the last row.

  • moveBeforeFirst() moves to a position before the first row.

  • moveFirst() moves to the first row.

  • moveLast() moves to the last row.

  • moveNext() moves to the next row.

  • movePrevious() moves to the previous row.

  • moveRelative( offset ) moves a certain number of rows relative to the current row, as specified by the offset. Positive offset values move forward in the result set, relative to the current position of the cursor in the result set, and negative offset values move backward in the result set. An offset value of zero does not move the cursor, but allows you to repopulate the row buffer.


Result set schema description

The ResultSet.schema property allows you to retrieve information about a result set, such as column names, total number of columns, column scales, column sizes and column SQL types.

Example

The following example demonstrates how to use the ResultSet.schema property to display schema information in a console window.

for ( int i = 1;
      i <= MyResultSet.schema.getColumnCount();
      i++ ) {
   System.out.println(
      MyResultSet.schema.getColumnName(i) + " " +
      MyResultSet.schema.getColumnSQLType(i)
   );
}


Accessing and manipulating data with the Table API

UltraLite applications can access table data using dynamic SQL or the Table API. This section describes data access using the Table API.

For information about dynamic SQL, see Accessing and manipulating data using dynamic SQL.

This section explains how to perform the following tasks using the Table API.

  • Scrolling through the rows of a table.

  • Accessing the values of the current row.

  • Using find and lookup methods to locate rows in a table.

  • Inserting, deleting, and updating rows.

Navigating the rows of a table
Using UltraLite modes
Accessing the values of the current row
Searching rows with find and lookup
Updating rows
Inserting rows
Deleting rows


Navigating the rows of a table

Native UltraLite for Java provides you with a number of methods to navigate a table in order to perform a wide range of navigation tasks.

The table object provides you with the following methods to navigate a table.

  • moveAfterLast() moves to a position after the last row.

  • moveBeforeFirst() moves to a position before the first row.

  • moveFirst() moves to the first row.

  • moveLast() moves to the last row.

  • moveNext() moves to the next row.

  • movePrevious() moves to the previous row.

  • moveRelative( offset ) moves a certain number of rows relative to the current row, as specified by the offset. Positive offset values move forward in the table, relative to the current position of the cursor in the table, and negative offset values move backward in the table. An offset value of zero does not move the cursor, but allows you to repopulate the row buffer.

Example

The following code opens the MyTable table and displays the value of the MyColumn column for each row.

Table t = conn.getTable( "MyTable" );
short colID = t.schema.getColumnID( "MyColumn" );
t.open();
t.moveBeforeFirst();
while ( t.moveNext() ){
   System.out.println( t.getString( colID ) );
}

You expose the rows of the table to the application when you open the table object. By default, the rows are ordered by primary key value, but you can specify an index when opening a table to access the rows in a particular order.

Example

The following code moves to the first row of the MyTable table as ordered by the ix_col index.

Table t = conn.getTable( "MyTable" );
t.open( "ix_col" );
t.moveFirst();

For more information, see ianywhere.native_ultralite.Table and ianywhere.native_ultralite.TableSchema in the Native UltraLite for Java API Reference.


Using UltraLite modes

UltraLite mode determines the purpose for which the values in the buffer will be used. UltraLite has the following four modes of operation, in addition to a default mode.

  • Insert mode The data in the buffer is added to the table as a new row when the insert method is called.

  • Update mode The data in the buffer replaces the current row when the update method is called.

  • Find mode Used to locate a row whose value exactly matches the data in the buffer when one of the find methods is called.

  • Lookup mode Used to locate a row whose value matches or is greater than the data in the buffer when one of the lookup methods is called.


Accessing the values of the current row

A Table object is always located at one of the following positions.

  • Before the first row of the table.

  • On a row of the table.

  • After the last row of the table.

If the Table object is positioned on a row, you can use one of a set of methods appropriate for the data type to retrieve or modify the value of each column.

Retrieving column values

The Table object provides a set of methods for retrieving column values. These methods take the column ID as argument.

Example

The following code retrieves the value of the lname column, which is a character string.

short lname = t.schema.getColumnID( "lname" );
String lastname = t.getString( lname );

The following code retrieves the value of the cust_id column, which is an integer.

short cust_id = t.schema.getColumnID( "cust_id" );
int id = t.getInt( cust_id );
Modifying column values

In addition to the methods for retrieving values, there are methods for setting values. These methods take the column ID and the value as arguments.

Example

For example, the following code sets the value of the lname column to Kaminski.

t.setString( lname, "Kaminski" );

By assigning values to these properties you do not alter the value of the data in the database. You can assign values to the properties even if you are before the first row or after the last row of the table, but it is an error to try to access data when the current row is at one of these positions, for example by assigning the property to a variable.

// This code is incorrect
tCustomer.moveBeforeFirst();
id = tCustomer.getInt( cust_id );
Casting values

The method you choose must match the data type you wish to assign. UltraLite automatically casts database data types where they are compatible, so that you could use the getString method to fetch an integer value into a string variable, and so on.


Searching rows with find and lookup

UltraLite has several modes of operation for working with data. Two of these modes, the find and lookup modes, are used for searching. The Table object has methods corresponding to these modes for locating particular rows in a table.

Note
The columns searched using Find and Lookup methods must be in the index used to open the table.

  • Find methods move to the first row that exactly matches specified search values, under the sort order specified when the Table object was opened. If the search values cannot be found, the application is positioned before the first or after the last row.

  • Lookup methods move to the first row that matches or is greater than a specified search value, under the sort order specified when the Table object was opened.

toggle To search for a row

  1. Enter find or lookup mode.

    The mode is entered by calling a method on the table object. For example, the following code enters find mode.

    t.findBegin();

  2. Set the search values.

    You do this by setting values in the current row. Setting these values affects the buffer holding the current row only, not the database. For example, the following code sets the value in the buffer to Kaminski.

    short lname = t.schema.getColumnID( "lname" );
t.setString( lname, "Kaminski" );

  3. Search for the row.

    Use the appropriate method to carry out the search. For example, the following instruction looks for the first row that exactly matches the specified value in the current index.

    For multi-column indexes, a value for the first column is always used, but you can omit the other columns.

    tCustomer.findFirst();

  4. Search for the next instance of the row.

    Use the appropriate method to carry out the search. For a find operation, findNext() locates the next instance of the parameters in the index. For a lookup, moveNext() locates the next instance.

For more information, see ianywhere.native_ultralite.Table in the Native UltraLite for Java API Reference.


Updating rows

The following procedure updates a row.

toggle To update a row

  1. Move to the row you wish to update.

    You can move to a row by scrolling through the table or by searching the table using find and lookup methods.

  2. Enter update mode.

    For example, the following instruction enters update mode on t.

    t.beginUpdate();

  3. Set the new values for the row to be updated. For example, the following instruction sets the id column in the buffer to 3.

    t.setInt( id , 3);

  4. Execute the Update.

    t.update();

After the update operation the current row is the row that has been updated. If you changed the value of a column in the index specified when the Table object was opened, the current row is undefined.

By default, Native UltraLite for Java operates in autocommit mode, so that the update is immediately applied to the row in permanent storage. If you have disabled autocommit mode, the update is not applied until you execute a commit operation. For more information, see Transaction processing in UltraLite.

Caution You cannot update the primary key of a row: delete the row and add a new row instead.


Inserting rows

The steps to insert a row are very similar to those for updating rows, except that there is no need to locate a row in the table before carrying out the insert operation. The order of row insertion into the table has no significance.

Example

The following code inserts a new row.

t.insertBegin();
t.setInt( id, 3 );
t.setString( lname, "Carlo" );
t.insert();

If you do not set a value for one of the columns, and that column has a default, the default value is used. If the column has no default, one of the following entries is used.

  • For nullable columns, NULL.

  • For numeric columns that disallow NULL, zero.

  • For character columns that disallow NULL, an empty string.

  • To explicitly set a value to NULL, use the setNull method.

For update operations, an insert is applied to the database in permanent storage when a commit is carried out. In autoCommit mode, a commit is carried out as part of the insert method.


Deleting rows

The steps to delete a row are simpler than to insert or update rows. There is no delete mode corresponding to the insert or update modes.

The following procedure deletes a row.

toggle To delete a row

  1. Move to the row you wish to delete.

  2. Execute the Table.delete() method.

    t.delete();


Transaction processing in UltraLite

UltraLite provides transaction processing to ensure the integrity of the data in your database. A transaction is a logical unit of work. Either an entire transaction is executed or none of the statements in the transaction are executed.

By default, Native UltraLite for Java operates in autocommit mode, so that each insert, update, or delete is executed as a separate transaction. Once the operation is complete, the change is made to the database.

If you set the Connection.autoCommit property to false, you can use multi-statement transactions. For example, if your application transfers money between two accounts, either both the deduction from the source account and the addition to the destination account must be completed, or neither statement must be completed.

If autoCommit is set to false, you must execute a Connection.commit() statement to complete a transaction and make changes to your database permanent, or you must execute a Connection.rollback() statement to cancel all the operations of a transaction.

For more information, see the ianywhere.native_ultralite.Connection class in the Native UltraLite for Java API Reference.


Accessing schema information

The objects in the API represent tables, columns, indexes, and synchronization publications. Each object has a schema property that provides access to information about the structure of that object.

You cannot modify the schema through the API. You can only retrieve information about the schema.

For information about modifying the schema, see Upgrading your database schema.

You can access the following schema objects and information.

  • DatabaseSchema exposes the number and names of the tables in the database, as well as global properties such as the format of dates and times.

    To obtain a DatabaseSchema object, access Connection.schema.

    For more information, see ianywhere.native_ultralite.Connection in the Native UltraLite for Java API Reference.

  • TableSchema The number and names of the columns and indexes for this table.

    To obtain a TableSchema object, access Table.schema.

  • IndexSchema Information about the column in the index. As an index has no data directly associated with it there is no separate Index class, just an IndexSchema class.

    To obtain an IndexSchema object, call the TableSchema.getIndex, the TableSchema.getOptimalIndex, or the TableSchema.getPrimaryKey method.

  • PublicationSchema A list of the tables and columns contained in a publication. Publications are also comprised of schema only, and so there is no Publication object.

    To obtain a PublicationSchema object, call the DatabaseSchema.getPublicationSchema method.

For more information, see ianywhere.native_ultralite.TableSchema in the Native UltraLite for Java API Reference.


Error handling

You can use the standard Java error-handling features to handle errors. Most methods throw java.sql.SQLException errors. You can use SQLException.getErrorCode() to retrieve the SQLCode value assigned to this error. SQLCode errors are negative numbers indicating the error type.

For a list of error codes, see ASA Error Messages.

After synchronization, you can use the SyncResult property of the connection to obtain more detailed error information.

For more information, see the following:

  • ianywhere.native_ultralite.SyncResult in the Native UltraLite for Java API Reference


User authentication

New users have to be added from an existing connection. As all UltraLite databases are created with a default user ID and password of DBA and SQL, respectively, you must first connect as this initial user.

You cannot change a user ID. Instead, you add a user and delete an existing user. A maximum of four user IDs are permitted for each UltraLite database.

For more information, see User authentication in UltraLite.

toggle To add a user or change a password for an existing user

  1. Connect to the database as a user with DBA authority.

  2. Grant the user access to the database with the desired password using the Connection.grantConnectTo method.

    This procedure is the same whether you are adding a new user or changing the password of an existing user.

    For more information, see ianywhere.native_ultralite.Connection in the Native UltraLite for Java API Reference.

toggle To delete an existing user

  1. Connect to the database as a user with DBA authority.

  2. Revoke the user's connection authority using the Connection.revokeConnectFrom method.


Synchronizing UltraLite applications

You synchronize UltraLite applications with a central consolidated database. Synchronization requires the MobiLink synchronization software included with SQL Anywhere Studio.

This section provides a brief introduction to synchronization and describes some features of particular interest to users of Native UltraLite for Java.

For a more detailed explanation of synchronization, see UltraLite Clients.

You can also find a working example of synchronization in the CustDB sample application. For more information, see the Samples\Ultralite\NativeUltraLiteForJava\CustDB subdirectory of your SQL Anywhere 9 installation.

Native UltraLite for Java supports TCP/IP, HTTP, and HTTPS synchronization. Synchronization is initiated by the UltraLite application. In all cases, you use properties of the SyncParms object to control synchronization.

Note
To synchronize using HTTPS you must obtain the separately-licensable security option. To order this option, see the card in your SQL Anywhere Studio package or see [external link] http://www.sybase.com/detail?id=1015780.

For more information, see Welcome to SQL Anywhere Studio.

Adding ActiveSync synchronization to your application


Adding ActiveSync synchronization to your application

This section explains how to add ActiveSync to a Native UltraLite for Java application, and how to register your application for use with ActiveSync on your end users' computers. ActiveSync is available on Windows CE devices through the Jeode and CrEme Java VMs.

If you are using the CrEme VM and wish to use ActiveSync, you must add \Windows\CrEme\lib\crmex.jar to your classpath.

Synchronization requires SQL Anywhere Studio. For general information about setting up ActiveSync synchronization, see Deploying applications that use ActiveSync. For general information on adding synchronization to an application, see UltraLite Clients.

ActiveSync synchronization can only be initiated by ActiveSync. ActiveSync initiates a synchronization when the device is placed in the cradle or when the Synchronization command is selected from the ActiveSync window.

When ActiveSync initiates synchronization, the MobiLink ActiveSync provider starts the UltraLite application, if it is not already running, and sends a message to it. Your application must implement an ActiveSyncListener to receive and process messages from the MobiLink provider. Your application must specify the listener object using the setActiveSyncListener method, where MyAppClassName is a unique Windows class name for the application..

dbMgr.setActiveSyncListener(
   listener, "MyAppClassName" );

For more information, see anywhere.native_ultralite.DatabaseManager in the Native UltraLite for Java API Reference.

When UltraLite receives an ActiveSync message, it invokes the specified listener's activeSyncInvoked( boolean ) method on a different thread. To avoid multi-threading issues, your activeSyncInvoked( boolean ) method should post an event to the user interface.

If your application is multi-threaded, use a separate connection and use the Java synchronized keyword to access any objects shared with the rest of the application. The activeSyncInvoked() method should specify a StreamType.ACTIVE_SYNC for its connection's syncInfo stream and then call Connection.synchronize().

When registering your application, set the following parameters.

  • Class Name The same class name the application used with the Connection.setActiveSyncListener method.

  • Path The path to the Jeode VM (\Windows\evm.exe).

  • Arguments Includes the classpath (-cp) and other Jeode command line arguments, the application name and applications arguments.

    If you specify unique arguments to indicate ActiveSync activation, your application can carry out a special startup sequence knowing that it is to close upon the completion of ActiveSync synchronization.

CustDB and ActiveSync


CustDB and ActiveSync

The Native UltraLite for Java version of the CustDB sample provides examples of synchronization through an application menu using a socket and through ActiveSync.

You can find source code for this sample in Samples\NativeUltraLiteForJava\CustDB\Application.java, located under your SQL Anywhere directory. This section describes the code in that sample.

  • CustDB parses its arguments to check for a special flag used to indicate it was launched by the MobiLink provider for ActiveSync. This allows it to streamline initialization (such as avoiding form population), since applications launched for ActiveSync are expected to shut down once they have synchronized.

    // Normal versus Active sync launch
boolean isNormalLaunch = true;
int alen = args.length;
if( alen > 0 ) {
  String asflag = args[ alen - 1 ].toUpperCase();
  if( asflag.compareTo( "ACTIVE_SYNC_LAUNCH" ) == 0) {
    isNormalLaunch = false;
    --alen;
  }

  • For normal launches (that is, non-ActiveSync launches), CustDB performs the connection initialization and determines the employee ID. It then initializes for ActiveSync by specifying a listener and loads its main form. For ActiveSync launches, CustDB performs the ActiveSync synchronization then shuts down.

    if( isNormalLaunch ) {
  db.initActiveSync( "JULCustDB", main );
  db.getOrder( 1 );
} else {
  // ActiveSync launch
  db.activeSync( false );
  main.quit();
}
public void initActiveSync(
   String appName, ActiveSyncListener listener )
{
  DEBUG( "initActiveSync" );
  _conn.setActiveSyncListener( appName, listener );
}
public void activeSync( boolean useDialog )
{
  try {
    // Change stream
    _conn.syncInfo.setStream(
                      StreamType.ACTIVE_SYNC );
    // since if "stream=" not in parms,
    //it defaults to tcpip, no
    // need to change stream parms
    _conn.synchronize( useDialog );
    freeLists();
    allocateLists();
    skipToValidOrder();
  } catch( SQLException e ) {
    System.out.println(
    "Can't synchronize, sql code=" +
    e.getErrorCode()
      );
  }
}

  • The Application class implements the ActiveSyncListener interface so the running application can be notified to perform an ActiveSync synchronization.

    public class Application
extends Frame
implements ActionListener,
// ActiveSyncListener functional only on CE devices
ActiveSyncListener

  • When activeSyncInvoked() is invoked, it posts a message to the UI thread.

    static final int ACTIVE_SYNC_EVENT_MASK =
   AWTEvent.RESERVED_ID_MAX + 1;
static class ActiveSyncEvent extends AWTEvent {
   ActiveSyncEvent( Object source ) {
      super( source, ACTIVE_SYNC_EVENT_MASK );
   }

/** Process ActiveSync message
*/
public void activeSyncInvoked(
        boolean launchedByProvider ) {
  // This method is invoked on a special thread.
  // Post an event so that active sync
  // takes places on the same thread
  // as the rest of the application.
  DEBUG( "activeSyncInvoked()" );
  getToolkit().getSystemEventQueue().postEvent(
            new ActiveSyncEvent( this )
  );
  DEBUG( "ActiveSync Event posted" );
}

  • The UI thread catches the message by overriding processEvent

    /** Intercept my special action events
 *    for ActiveSync
 */
protected void processEvent( AWTEvent e ) {
  if( e instanceof ActiveSyncEvent ) {
    _db.activeSync( true );
    refresh();
  } else {
    super.processEvent( e );
  }
}

    However, for the application to receive the event, it must be enabled. This is done in Application's constructor.

    // ActiveSync support
enableEvents( ACTIVE_SYNC_EVENT_MASK );


Developing applications with Borland JBuilder

Borland JBuilder is a development environment for Java applications. Native UltraLite for Java includes integration with JBuilder 7 and JBuilder 8. This section describes how to use Native UltraLite for Java within the JBuilder environment.

Preparing to use Native UltraLite for Java with JBuilder
Using the Native UltraLite for Java setup
Using Native UltraLite for Java templates
Accessing Native UltraLite for Java utilities from JBuilder


Preparing to use Native UltraLite for Java with JBuilder

If JBuilder is installed, the UltraLite setup program enables JBuilder integration. If JBuilder is installed after the UltraLite, re-run the UltraLite setup program to enable JBuilder integration.

Setting the JDK

You should use JDK 1.1.8 or Personal Java 1.2 when developing Native UltraLite for Java applications, for compatibility with the Jeode VM on Windows CE devices.

JBuilder SE and Enterprise fully support JDK switching, while JBuilder Personal allows you to edit a single JDK.

toggle To set the JDK version

  1. In JBuilder Personal, click Tools > Configure JDKs and edit the JDK.

  2. In JBuilder SE and Enterprise, right-click the project file in the project pane and choose Properties. On the Paths tab, click JDK and browse to your desired JDK location.


Using the Native UltraLite for Java setup

The Native UltraLite for Java setup can be used with existing projects or with new projects.

toggle To add UltraLite features to a JBuilder project

  1. Open a JBuilder project.

  2. Add the Native UltraLite for Java setup.

    • Choose File > New. The Object Gallery appears.

    • On the General tab, select Native UltraLite Setup and click OK.

    • Choose a database name and deployment directories on the Windows CE device. Click Next.

    • Add names for the Windows CE shortcut (which will be displayed on the Start menu), the JAR name, and the main class. Click Finish.

    A link file is added to your project. This link file is used to run the application on the Windows CE device.

The Native UltraLite for Java setup makes the following changes to your JBuilder project.

  • Adds Native UltraLite for Java in the list of available libraries.

  • Adds project properties for code insight templates.

  • Modifies the runtime configurations to locate jul9.dll when you run the application from within the development environment.


Using Native UltraLite for Java templates

During development, you can use Native UltraLite for Java code templates for some of the standard parts of your code. To use a template, type the template name at the appropriate place in your .java file and type Ctrl+J to expand the template.

The following templates are provided.

  • julimp Adds a line to import the Native UltraLite for Java package. Use this template in the imports section of your files.

  • juldb Adds code to declare a DatabaseManager object.

  • julconn Adds code to connect to to a database.

  • julskel Adds both the juldb and julconn code, as a main method.


Accessing Native UltraLite for Java utilities from JBuilder

You can access the following Native UltraLite for Java utilities from the JBuilder interface.

  • Schema Painter The UltraLite schema painter is a tool for creating and editing database definitions.

    To open the schema painter, choose Tools > UltraLite Schema Painter.

  • Online help This documentation is available from the interface.

    To open the online help, choose Help > Native UltraLite Reference.


Native UltraLite for Java API Reference

About this chapter

The Native UltraLite for Java package is named ianywhere.native_ultralite. The Native UltraLite for Java API reference is supplied in Javadoc format in the docs\javadocs\NativeUltraLiteForJava subdirectory of your SQL Anywhere 9 installation.

For more information, see the following classes:

  • ianywhere.native_ultralite.ActiveSyncListener
  • ianywhere.native_ultralite.AuthStatusCode
  • ianywhere.native_ultralite.Connection
  • ianywhere.native_ultralite.ConnectionParms
  • ianywhere.native_ultralite.CreateParms
  • ianywhere.native_ultralite.Cursor
  • ianywhere.native_ultralite.CursorSchema
  • ianywhere.native_ultralite.DatabaseManager
  • ianywhere.native_ultralite.DatabaseNameParms
  • ianywhere.native_ultralite.DatabaseSchema
  • ianywhere.native_ultralite.IndexSchema
  • ianywhere.native_ultralite.PreparedStatement
  • ianywhere.native_ultralite.ResultSet
  • ianywhere.native_ultralite.ResultSetSchema
  • ianywhere.native_ultralite.SchemaParms
  • ianywhere.native_ultralite.SchemaUpgradeData
  • ianywhere.native_ultralite.SchemaUpgradeListener
  • ianywhere.native_ultralite.SQLCode
  • ianywhere.native_ultralite.SQLType
  • ianywhere.native_ultralite.StreamErrorCode
  • ianywhere.native_ultralite.StreamErrorID
  • ianywhere.native_ultralite.StreamType
  • ianywhere.native_ultralite.SyncParms
  • ianywhere.native_ultralite.SyncProgressData
  • ianywhere.native_ultralite.SyncProgressDialog
  • ianywhere.native_ultralite.SyncProgressListener
  • ianywhere.native_ultralite.SyncResult
  • ianywhere.native_ultralite.Table
  • ianywhere.native_ultralite.TableSchema
  • ianywhere.native_ultralite.UUID


Web Links Browse Collapse Expand PDF Previous Next

UltraLite.NET User's Guide

Version 9.0.2

DC50043-01-0902-01

October 2004

Copyright
About This Manual
Introduction to UltraLite.NET
Tutorial: Build an UltraLite.NET Application
Understanding UltraLite.NET Development
iAnywhere.Data.UltraLite namespace
iAnywhere.UltraLite namespace


About This Manual

Subject

This manual describes UltraLite.NET. With UltraLite.NET you can develop and deploy database applications to computers, or handheld, mobile, or embedded devices.

Audience

This manual is intended for .NET application developers who wish to take advantage of the performance, resource efficiency, robustness, and security of an UltraLite relational database for data storage and synchronization.


Introduction to UltraLite.NET

About this chapter

This chapter introduces you to UltraLite.NET. It assumes that you are familiar with the features of UltraLite, as described in Welcome to UltraLite.

For more information about creating applications using UltraLite.NET, see Understanding UltraLite.NET Development.

For a hands-on tutorial introducing UltraLite.NET, see Tutorial: Build an UltraLite.NET Application.


UltraLite and .NET

The .NET Compact Framework is the Microsoft .NET runtime component for Windows CE. It supports several programming languages. You can use either Visual Basic.NET or C# to build applications using UltraLite.NET.

UltraLite.NET provides the following namespaces:

  • iAnywhere.Data.UltraLite This namespace provides an ADO.NET interface to UltraLite. It has the virtues of being built on an industry-standard model and of providing a migration path to the Adaptive Server Anywhere ADO.NET interface, which is very similar.

  • iAnywhere.UltraLite This namespace is the original UltraLite.NET namespace. It is deprecated in release 9.0.2, and will not be available in the next major release of SQL Anywhere.

The UltraLite.NET runtime supports both these namespaces.

UltraLite.NET applications can be deployed to Windows CE and Windows XP. If deploying to Windows CE, UltraLite.NET requires the .NET Compact Framework. If deploying to Windows XP, it requires the .NET Framework. It also supports ActiveSync sychronization.


System requirements and supported platforms

Development platforms

To develop applications using UltraLite.NET, you require the following.

  • Microsoft Windows NT/2000/XP.

  • Visual Studio.NET or Visual Studio.NET 2003.

  • For Windows CE devices, .NET Compact Framework version 1.0.5000 or later.

Target platforms

UltraLite.NET supports the following target platforms:

  • Microsoft .NET Compact Framework 1.0.3705 or later on Windows CE 3.0 and higher, with Pocket PC on Arm or MIPS processors. The Pocket PC 2002 emulator is also supported.

  • Microsoft .NET Compact Framework version 1.0.5000 or later on Windows XP.

In addition to your application code and the .NET Compact Framework, you must deploy the following files to your Windows CE device or computer running Windows XP:

  • iAnywhere.Data.UltraLite.dll An assembly containing the iAnywhere.Data.UltraLite ADO.NET namespace. This file is required only if your application uses the iAnywhere.Data.UltraLite namespace.

  • iAnywhere.Data.UltraLite.resources.dll The resources needed by the iAnywhere.Data.UltraLite ADO.NET namespace. This file is required only if your application uses the iAnywhere.Data.UltraLite namespace.

  • iAnywhere.UltraLite.dll An assembly containing the iAnywhere.UltraLite namespace. This file is required only if your application uses the iAnywhere.UltraLite namespace.

  • iAnywhere.UltraLite.resources.dll The resources needed by the iAnywhere.UltraLite namespace. This file is required only if your application uses the iAnywhere.UltraLite namespace.

  • ulnet9.dll This file contains the UltraLite runtime. A separate version of the runtime is provided for each target platform.

  • UltraLite schema file The UltraLite runtime library uses the information in the schema file to set the database schema. Once a database file is created, the schema file is no longer required.

For more information, see UltraLite development platforms and UltraLite target platforms.


UltraLite.NET architecture

The UltraLite.NET namespaces are named iAnywhere.Data.UltraLite (ADO.NET interface) and iAnywhere.UltraLite. It is recommended that new applications use the iAnywhere.Data.UltraLite namespace.

The following list describes some of the more commonly-used high level classes for the iAnywhere.Data.UltraLite ADO.NET namespace:

  • ULConnection Each ULConnection object represents a connection to an UltraLite database. You can create one or more ULConnection objects.

  • ULTable Each ULTable object provides access to the data in a single table.

  • ULCommand object Each ULCommand object holds a SQL statement to be executed against the database.

  • ULDataReader object Each ULDataReader object holds the result set for a single query.

  • ULSyncParms You use the ULSyncParms object to synchronize your UltraLite database with a MobiLink synchronization server.

The following list describes some of the more commonly-used high level classes for the iAnywhere.UltraLite namespace:

  • DatabaseManager You create one DatabaseManager object for each application.

  • Connection Each Connection object represents a connection to an UltraLite database. You can create one or more Connection objects.

  • Table The Table object provides access to the data in the database.

  • PreparedStatement, ResultSet, and ResultSetSchema These dynamic SQL objects allow you to create Dynamic SQL statements, make queries and execute INSERT, UPDATE and DELETE statements, and attain programmatic control over database result sets.

  • SyncParms You use the SyncParms object to synchronize your UltraLite database with a MobiLink synchronization server.

For more information, see iAnywhere.Data.UltraLite namespace for the ADO.NET interface and iAnywhere.UltraLite namespace for the component interface.


Tutorial: Build an UltraLite.NET Application

About this chapter

This chapter provides a tutorial to guide you through the process of building an UltraLite.NET application in Visual Studio .NET 2003.

Introduction
Lesson 1: Create a Visual Studio project
Lesson 2: Create an UltraLite schema file
Lesson 3: Connect to the database
Lesson 4: Insert, update, and delete data
Lesson 5: Build and deploy your application


Introduction

This tutorial guides you through the process of building an UltraLite.NET application in Visual Studio. It uses the ADO.NET interface provided by the iAnywhere.Data.UltraLite namespace.

This tutorial contains code for a Visual Basic .NET application and a Visual C# application.

Timing

The tutorial takes about thirty minutes if you cut and paste the code. It takes significantly longer if you type the code yourself.

Competencies and experience

This tutorial assumes the following:

  • You are familiar with the C# programming language or the Visual Basic .NET programming language.

  • You have Microsoft Visual Studio .NET 2003 installed on your computer.

  • You know how to create an UltraLite schema using the UltraLite Schema Painter.

    For more information, see Lesson 1: Create an UltraLite database schema.

Goals

The goals for the tutorial are to gain competence and familiarity with the process of developing UltraLite.NET applications in the Visual Studio environment.


Lesson 1: Create a Visual Studio project

The following procedure creates and configures a new Visual Studio application. You can choose whether to use Visual Basic.NET or C# as your programming language.

toggle To create a Visual Studio project

  1. Create a Visual Studio project .

    • From the Visual Studio .NET 2003 File menu, choose New > Project to create a new project.

      The New Project window appears.

    • In the left pane, select either the Visual Basic Projects folder or the Visual C# Projects folder.

    • In the right pane, select a Smart Device Application and name your project VBApp or CSApp, depending on whether you choose Visual Basic or C# for the programming language.

    • Enter a Location of c:\tutorial\uldotnet and click OK.

      The Smart Device Application Wizard appears.

    • Choose Pocket PC as the target platform, and select Windows Application as the project type. Click OK.

      A Design workspace appears, displaying a form.

  2. Add references to your project.

    • Add the iAnywhere.Data.UltraLite assembly and the associated resources to your project.

      1. From the Project menu, choose Add Reference.

        The Add Reference window appears.

      2. Select iAnywhere.Data.UltraLite (CE) from the list of available references. Click Select to add it to the list of selected components.

        If this reference does not appear in the list, click Browse and locate it in the ultralite\UltraLite.NET\ce subdirectory of your SQL Anywhere installation. Select iAnywhere.Data.UltraLite.dll and click Open.

      3. Select iAnywhere.Data.UltraLite (CE) EN from the list of available references. Click Select to add it to the list of selected components.

        If this reference does not appear in the list, click Browse and locate it in the ultralite\UltraLite.NET\ce\xx subdirectory of your SQL Anywhere installation, where xx is a two-letter abbreviation for the language. Select iAnywhere.Data.UltraLite.resources.dll and click Open.

      4. Click OK to add the assembly and resources to your project.

    • Link the UltraLite component to your project.

      In this step, ensure that you add a link to the component, and that you do not Open the component.

      1. From the Project menu, choose Add Existing Item and browse to the ultralite\UltraLite.NET\ce subdirectory of your SQL Anywhere installation.

      2. Set the Files of Type drop down to All Files so that DLL files are displayed.

      3. Open the folder corresponding to the processor of the CE device you are using (for the Pocket PC emulator, open the x86 folder) and select ulnet9.dll. Do not click Open.

      4. Click the arrow on the Open button and select Link File to link it to your project.

  3. Create a form for your application.

    Add the following visual components to the form.

    Type | Name | Text
    Button | btnInsert | Insert
    Button | btnUpdate | Update
    Button | btnDelete | Delete
    TextBox | txtName
    ListBox | lbNames
    Label | laName | Name

    Your form should look like the following figure.

    The Visual Studio form, showing the Insert, Update, and Delete buttons as well as a text box, list box, and label.

  4. Build and deploy your solution.

    Building and deploying the solution confirms that you have configured your Visual Studio.NET project properly.

    1. From the Build menu, choose Build Solution. Confirm that the project builds successfully.

    2. From the Debug menu, choose Start. This action deploys your application to the device or emulator, and starts it. The application is deployed to \Program Files\VBApp or \Program Files\CSApp depending on your project name.

      The deployment may take some time.

    3. Confirm that the application deploys to the emulator or your target device.

    4. From the Debug menu, choose Stop Debugging to close the application.


Lesson 2: Create an UltraLite schema file

The following procedure creates an UltraLite database schema using the UltraLite Schema Painter.

For information on using the Schema Painter, see Lesson 1: Create an UltraLite database schema.

toggle To create a schema file

  1. Start the UltraLite Schema Painter:

    From the Start menu, choose Programs > SQL Anywhere 9 > UltraLite > UltraLite Schema Painter.

  2. Use the UltraLite Schema Painter to create a database schema in the same directory as your application with the following characteristics.

    • Schema file name vbapp.usm or csapp.usm, depending on your application.

    • Collation sequence Default

    • Case sensitivity Leave unchecked

    • Table name Names

    • Columns Create columns in the Names table with the following attributes:

      Column Name | Data Type (Size) | Allow NULL? | Default value
      ID | integer | No | global autoincrement
      Name | char(30) | No | None

    • Primary key Ascending ID

  3. Link the schema file to your application.

    • From the Visual Studio .NET 2003 interface, choose Project > Add Existing Item.

    • Browse to your tutorial directory and select csapp.usm or vbapp.usm, as appropriate. Do not click Open.

    • Click the arrow on the Open button and choose Link File.

    • In the Solution Explorer, right click your schema file and select Properties. In the properties pane, set the Build Action property to Content.


Lesson 3: Connect to the database

The following procedure adds a control to your UltraLite.NET application that establishes a connection to an UltraLite database.

If an UltraLite application attempts to connect to a database that does not exist, it uses the schema file to create the database.

This tutorial assumes that if you are designing a C# application, your files are in the directory c:\tutorial\uldotnet\CSApp and that if you are designing a Visual Basic application, your files are in the directory c:\tutorial\uldotnet\VBApp. If you created a directory with a different name, use that directory throughout the tutorial.

toggle To add an UltraLite connection to your application

  1. Add the ConnectionParms control to your form.

    From the UltraLite.NET CF tab in the toolbox, choose ULConnectionParms and add it to your form. The control is named UlConnectionParms1 (Visual Basic) or ulConnectionParms1 (C#).

    If you have not rebooted since installing SQL Anywhere Studio, you may get an error message at this point. Reboot your machine to solve this problem.

  2. Specify the connection parameters.

    Ensure the following properties are set:

    • DatabaseOnCE \Program Files\CSApp\CSApp.udb for a Visual C# application, or \Program Files\VBApp\VBApp.udb for a Visual Basic application.

    • SchemaOnCE \Program Files\CSApp\CSApp.usm for a Visual C# application, or \Program Files\VBApp\VBApp.usm for a Visual Basic application.

  3. Open the source code for the form.

    Double-click the form to open the source file.

  4. Import the iAnywhere.Data.UltraLite namespace.

    Add the following statement as the very first line of the file.

    //Visual C#
using iAnywhere.Data.UltraLite;
    'Visual Basic
Imports iAnywhere.Data.UltraLite

  5. Add global variables to the form declaration.

    For a Visual C# application, add the following code after the code describing the form components and before the first method declaration.

    //Visual C#
private ULConnection Conn;
private int[] ids;

    For a Visual Basic project, add the following code after the declaration of the form components (FriendsWithEvents declarations) and before the first method declaration.

    'Visual Basic
Dim Conn As ULConnection
Dim ids() As Integer

    These variables are used as follows:

    • ULConnection A Connection object is the root object for all actions executed on a connection to a database.

    • ids The ids array is used to hold the ID column values returned after executing a query.

      Although the ListBox control itself allows you access to sequential numbers, those numbers differ from the value of the ID column once a row has been deleted. For this reason, the ID column values must be stored separately.

  6. Double-click a blank area of your form to create a Form1_Load method.

    This method performs the following tasks.

    • Opens a connection to the database using the connection parameters set in the ULConnectionParms1 control.

    • Calls the RefreshListBox method, which you will define later in this tutorial.

    • If an error occurs, prints the error message. For SQL errors, the code also prints the error code. For more information about the error code, see ASA Error Messages.

    For C#, add the following code to the method.

    //Visual C#
try {
    Conn = new ULConnection(
        ulConnectionParms1.ToString() );
    Conn.OpenWithCreate();
    Conn.DatabaseID = 1;
    RefreshListBox();
}
catch ( System.Exception t ) {
    MessageBox.Show( "Exception: " + t.Message);
}

    For Visual Basic , add the following code to the method.

    'Visual Basic
Try
    Conn = New ULConnection( _
        UlConnectionParms1.ToString())
    Conn.OpenWithCreate()
    Conn.DatabaseID = 1
    RefreshListBox()
Catch
    MsgBox("Exception: " + err.Description)
End Try

  7. Build the project.

    From the Build menu choose Build Solution. At this stage, you should get a single error reported, which is that the Name RefreshListBox is not declared. You will fix this error by adding the function in the next lesson.

    If you get other errors, fix them. Check for common errors, such as case inconsistencies in C#. For example, UltraLite and ULConnection must match case exactly.


Lesson 4: Insert, update, and delete data

In this lesson you add code to your application to modify the data in your database. The following procedures use Dynamic SQL. The same techniques can be performed using the Table API.

For more information, see Choosing between components and static interfaces or Accessing and manipulating data with the Table API.

The following procedure creates a supporting method to maintain the list box. This method is required for data manipulation methods created in the remaining procedures.

toggle To add code to maintain the listbox

  1. Right-click the form and select View Code.

  2. Add a method of the Form1 class to update and populate the listbox. This method carries out the following tasks.

    • Clears the listbox.

    • Instantiates a ULCommand object and assigns it a SELECT query that returns the Names table in the database.

    • Executes the query, returning a result set as a ULDataReader.

    • Instantiates an integer array with length equal to the number of rows in the result set.

    • Populates the listbox with the names returned in the ULDataReader and populates the integer array with the ids returned in the ULDataReader.

    • Closes the ULDataReader.

    • If an error occurs, prints the error message. For SQL errors, the code also prints the error code. For more information about the error code, see ASA Error Messages.

    For C#, add the following code to your application as a method of the Form1 class.

    //Visual C#
private void RefreshListBox(){
    try{
        long NumRows;
        int i = 0;
        lbNames.Items.Clear();
        using( ULCommand cmd = Conn.CreateCommand() ){
            cmd.CommandText = "SELECT ID, Name FROM Names";
            using( ULDataReader dr = cmd.ExecuteReader()){
                dr.MoveBeforeFirst();
                NumRows = dr.RowCount;
                ids = new int[ NumRows ];
                while (dr.MoveNext())
                {
                    lbNames.Items.Add(
                    dr.GetString(1));
                    ids[ i ] = dr.GetInt32(0);
                    i++;
                }
            }
        }
    }
    catch( Exception err ){
        MessageBox.Show(
        "Exception in RefreshListBox: " + err.Message );
    }
}

    For Visual Basic, add the following code to your application as a method of the Form1 class.

    'Visual Basic
Private Sub RefreshListBox()
    Try
        Dim cmd As ULCommand = Conn.CreateCommand()
        Dim i As Integer = 0
        lbNames.Items.Clear()
        cmd.CommandText = "SELECT ID, Name FROM Names"
        Dim dr As ULDataReader = cmd.ExecuteReader()
        ReDim ids(dr.RowCount)
        While (dr.MoveNext)
            lbNames.Items.Add(dr.GetString(1))
            ids(i) = dr.GetInt32(0)
            i = i + 1
        End While
        dr.Close()
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

  3. Build the project.

    Building the project should result in no errors.

toggle To implement INSERT, UPDATE and DELETE

  1. Double-click the Insert button to create a btnInsert_Click method. This method carries out the following tasks.

    • Instantiates a ULCommand object and assigns it an INSERT statement that inserts the value in the textbox into the database.

    • Executes the statement.

    • Disposes of the ULCommand object.

    • Refreshes the listbox.

    • If an error occurs, prints the error message. For SQL errors, the code also prints the error code. For more information about the error code, see ASA Error Messages.

    For C#, add the following code to the method.

    //Visual C#
try {
    long RowsInserted;
    using( ULCommand cmd = Conn.CreateCommand() ) {
        cmd.CommandText =
            "INSERT INTO Names(name) VALUES (?)";
        cmd.Parameters.Add("", txtName.Text);
        RowsInserted = cmd.ExecuteNonQuery();
    }
    RefreshListBox();
}
catch( Exception err ) {
    MessageBox.Show("Exception: " + err.Message );
}

    For Visual Basic, add the following code to the method.

    'Visual Basic
Try
    Dim RowsInserted As Long
    Dim cmd As ULCommand = Conn.CreateCommand()
    cmd.CommandText = "INSERT INTO Names(name) VALUES (?)"
    cmd.Parameters.Add("", txtName.Text)
    RowsInserted = cmd.ExecuteNonQuery()
    cmd.Dispose()
    RefreshListBox()
Catch
    MsgBox("Exception: " + Err.Description)
End Try

  2. Double-click the Update button to create a btnUpdate_Click method. This method carries out the following tasks.

    • Instantiates a ULCommand object and assigns it an UPDATE statement that inserts the value in the textbox into the database based on the associated id.

    • Executes the statement.

    • Disposes of the ULCommand object.

    • Refreshes the listbox.

    • If an error occurs, prints the error message. For SQL errors, the code also prints the error code. For more information about the error code, see ASA Error Messages.

    For C#, add the following code to the method.

    //Visual C#
try {
    long RowsUpdated;
    int updateID = ids[ lbNames.SelectedIndex ];
    using( ULCommand cmd = Conn.CreateCommand() ){
        cmd.CommandText =
            "UPDATE Names SET name = ? WHERE id = ?" ;
        cmd.Parameters.Add("", txtName.Text );
        cmd.Parameters.Add("", updateID);
        RowsUpdated = cmd.ExecuteNonQuery();
    }
    RefreshListBox();
}
catch( Exception err ) {
    MessageBox.Show(
        "Exception: " + err.Message);
}

    For Visual Basic, add the following code to the method.

    'Visual Basic
Try
    Dim RowsUpdated As Long
    Dim updateID As Integer = ids(lbNames.SelectedIndex)
    Dim cmd As ULCommand = Conn.CreateCommand()
    cmd.CommandText = "UPDATE Names SET name = ? WHERE id = ?"
    cmd.Parameters.Add("", txtName.Text)
    cmd.Parameters.Add("", updateID)
    RowsUpdated = cmd.ExecuteNonQuery()
    cmd.Dispose()
    RefreshListBox()
Catch
    MsgBox("Exception: " + Err.Description)
End Try

  3. Double-click the Delete button to create a btnDelete_Click method. Add code to carry out the following tasks.

    • Instantiates a ULCommand object and assigns it a DELETE statement. The DELETE statement deletes the selected row from the database, based on the associated id from the integer array ids.

    • Executes the statement.

    • Disposes of the ULCommand object.

    • Refreshes the listbox.

    • If an error occurs, prints the error message. For SQL errors, the code also prints the error code. For more information about the error code, see ASA Error Messages.

    For C#, add the following code to the method.

    //Visual C#
try{
    int deleteID = ids[lbNames.SelectedIndex];
    long RowsDeleted;
    using( ULCommand cmd = Conn.CreateCommand() ){
        cmd.CommandText =
            "DELETE From Names WHERE id = ?" ;
        cmd.Parameters.Add("", deleteID);
        RowsDeleted = cmd.ExecuteNonQuery ();
    }
    RefreshListBox();
}
catch( Exception err ) {
    MessageBox.Show("Exception: " + err.Message );
}

    For Visual Basic, add the following code to the method.

    'Visual Basic
Try
    Dim deleteID As Integer = ids(lbNames.SelectedIndex)
    Dim RowsDeleted As Long
    Dim cmd As ULCommand = Conn.CreateCommand()
    cmd.CommandText = "DELETE From Names WHERE id = ?"
    cmd.Parameters.Add("", deleteID)
    RowsDeleted = cmd.ExecuteNonQuery()
    cmd.Dispose()
    RefreshListBox()
Catch
    MsgBox("Exception: " + Err.Description)
End Try

  4. Build your application to confirm that it compiles properly.


Lesson 5: Build and deploy your application

In the following procedure, you build your application and deploy it to a remote device.

toggle To deploy your application

  1. Build the solution.

    Ensure that your application builds without errors.

  2. Select Debug > Start.

    This builds an executable file containing your application and deploys it to the Pocket PC emulator. The process may take some time, especially if it must deploy the .NET Compact Framework before running the application.

Deployment troubleshooting checklist

If errors are reported, you may wish to check that your deployment was completed successfully using the following checklist.

  • Confirm that the application is deployed into \Program Files\appname, where appname is the name you gave your application in Lesson 1 (CSApp or VBApp).

  • Confirm that the schema file is located in the same directory as the application.

  • Confirm that the path to the schema file in your application code is correct. For more information, see Lesson 3: Connect to the database.

  • Confirm that you chose Link File when adding the schema file to the project and that you set the Build Action to Content. If you did not, the files will not be deployed to the device.

  • Ensure that you added a reference to the correct version of ulnet9.dll for your target platform, or ran the Windows CE installer. If you switch between the emulator and a real device, you must change the version of this library that you use. For more information, see Lesson 1: Create a Visual Studio project.

  • You may wish to exit the emulator, without saving state. Redeploying copies all required files to the emulator, and ensures there are no version problems.

toggle To test your application

  1. Insert data into the database.

    Enter a name in the text box and click Insert. The name should now appear in the listbox.

  2. Update data in the database.

    Select a name from the listbox. Enter a new name in the text box. Click Update. The new name should now appear in place of the old name in the listbox.

  3. Delete data from the database.

    Select a name from the listbox. Click Delete. The name should no longer appear in the listbox.

This completes the tutorial.


Understanding UltraLite.NET Development

About this chapter

This chapter explains how to develop applications using UltraLite.NET.

For hands-on tutorials, see Tutorial: Build an UltraLite.NET Application.

Code samples in C#
The code samples in this chapter are in Microsoft C#. If you are using one of the other supported development tools you must modify the instructions appropriately.

UltraLite database schemas
Connecting to a database
Encryption and obfuscation
Accessing and manipulating data using dynamic SQL
Accessing and manipulating data with the Table API
Transaction processing in UltraLite
Accessing schema information
Error handling
User authentication
Synchronizing UltraLite applications


Upgrading your database schema

To modify your existing database structure, use the ULDatabaseSchema.ApplyFile method. In most cases there will be no data loss, however, data loss can occur if columns are deleted or if the data type for a column is changed to an incompatible type.

For more information, see ULDatabaseSchema members (iAnywhere.Data.UltraLite namespace) or DatabaseSchema members (iAnywhere.UltraLite namespace).

Example

The following code applies a new schema file using the ApplyFile method. It assumes that you have already connected to the database as shown in Connecting to a database.

// iAnywhere.Data.UltraLite namespace
ULDatabaseSchema schema = conn.Schema;
ULConnectionParms parms = new ULConnectionParms();
parms.SchemaOnDesktop = @"c:\tutorial\tutcustomer.usm";
try {
  schema.ApplyFile(parms );
} catch {
  // handle error
}
// iAnywhere.UltraLite namespace
DatabaseSchema schema = conn.Schema;
SchemaParms parms = new SchemaParms();
parms.SchemaOnDesktop = @"c:\tutorial\tutcustomer.usm";
try {
  schema.ApplyFile( parms );
} catch {
  // handle error
}


Connecting to a database

UltraLite applications must connect to a database before carrying out operations on the data in it. This section describes how to connect to an UltraLite database.

Using the Connection object

The following properties of the Connection object govern global application behavior.

  • Commit behavior By default, UltraLite.NET applications are in autocommit mode. Each insert, update, or delete statement is committed to the database immediately. You can use ULConnection.BeginTransaction() to build transactions into your application.

    For more information, see Transaction processing in UltraLite.

  • User authentication You can change the user ID and password for the application from the default values of DBA and SQL by using methods to Grant and Revoke connection permissions. Each application can have a maximum of four user IDs.

    For more information, see User authentication.

  • Synchronization A set of objects governing synchronization is accessed from the Connection object.

    For more information, see Synchronizing UltraLite applications.

  • Tables UltraLite tables are accessed using methods of the Connection object.

    For more information, see Accessing and manipulating data with the Table API.

  • Commands A set of objects is provided to handle the execution of dynamic SQL statements and to navigate result sets.

    For more information, see Accessing and manipulating data using dynamic SQL.

For more information, see ULConnection class (iAnywhere.Data.UltraLite namespace) or Connection class (iAnywhere.UltraLite namespace).

Multi-threaded applications

Each Connection and all objects created from it should be used on a single thread. If your application requires multiple threads accessing the UltraLite database, each thread requires a separate connection.

toggle To connect to an UltraLite database

  1. Create and initialize a DatabaseManager object.

    This step is not required if using the iAnywhere.Data.UltraLite namespace.

    The DatabaseManager object is at the root of the object hierarchy. You create only one DatabaseManager object per application. It is often best to declare the DatabaseManager object as global to the application.

    // iAnywhere.UltraLite namespace
DatabaseManager dbMgr = new DatabaseManager();

    For more information, see DatabaseManager class (iAnywhere.UltraLite namespace).

  2. Declare a Connection object.

    Most applications use a single connection to an UltraLite database and leave the connection open. Multiple connections are only required for multi-threaded data access. For this reason, it is often best to declare the Connection object as global to the application.

    // iAnywhere.Data.UltraLite namespace
ULConnection conn;
    // iAnywhere.UltraLite namespace
Connection conn;

  3. Open a connection to an existing database, or create a new database if the specified database file does not exist.

    Most UltraLite applications deploy a schema file rather than a database file, and let UltraLite create the database file on the first connection attempt. Thus, the following code attempts to connect to an existing database. If the database file does not exist, the application creates a database file.

    // iAnywhere.Data.UltraLite namespace
ULConnectionParms parms = new ULConnectionParms();
// specify the location of the database file
parms.DatabaseOnDesktop = "mydata.udb";
// specify the location of the schema file
parms.SchemaOnDesktop = "mydata.usm";
conn = new ULConnection( parms.ToString() );
conn.OpenWithCreate();
    // iAnywhere.UltraLite namespace
ConnectionParms parms = new ConnectionParms();
// specify the location of the database file
parms.DatabaseOnDesktop = "mydata.udb";
try {
  conn = dbMgr.OpenConnection( parms );
} catch( SQLException econn ) {
  if( econn.GetErrorCode() ==
    SQLCode.SQLE_ULTRALITE_DATABASE_NOT_FOUND ){
    CreateParms parms = new CreateParms();
    parms.DatabaseOnDesktop = "mydata.udb";
    parms.Schema.SchemaOnDesktop = "mydata.usm";
    try {
      conn = dbMgr.CreateDatabase( parms );
  }
}
Example

The following code opens a connection to an UltraLite database named mydata.udb. If the database does not exist, it is created using the UltraLite schema file named mydata.usm.

// iAnywhere.Data.UltraLite namespace
ULConnectionParms parms = new ULConnectionParms();
parms.DatabaseOnDesktop = "mydata.udb";
parms.SchemaOnDesktop = "mydata.usm";
conn = new ULConnection( parms.ToString() );
conn.InfoMessage += new ULInfoMessageEventHandler(
    InfoMessageEventHandler );
conn.OpenWithCreate();
// iAnywhere.UltraLite namespace
CreateParms parms = new CreateParms();
parms.DatabaseOnDesktop = "mydata.udb";
parms.Schema.SchemaOnDesktop = "mydata.usm";
try {
  conn = dbMgr.OpenConnection( parms );
  System.Console.WriteLine(
    "Connected to an existing database." );
}
catch( SQLException econn ) {
  if( econn.GetErrorCode() ==
      SQLCode.SQLE_ULTRALITE_DATABASE_NOT_FOUND ){
    conn = dbMgr.CreateDatabase( parms );
    System.Console.WriteLine(
      "Connected to a new database." );
  } else {
    throw econn;
  }
}

The above code uses the InfoMessage handler defined below to detect if the database is new.

// iAnywhere.Data.UltraLite namespace
protected void InfoMessageHandler(
    object obj, ULInfoMessageEventArgs args )
{
  if( args.NativeError == ULSQLCode.SQLE_DATABASE_CREATED ){
    System.Console.WriteLine( args.Message );
  }
}


Encryption and obfuscation

You can encrypt or obfuscate your UltraLite database using UltraLite.NET.

Encryption

To create a database with encryption, specify an encryption key using the ULConnectionParms.EncryptionKey property, then call the OpenWithCreate method. When you call the OpenWithCreate method, the database is created and encrypted with the specified key.

For more information, see Encryption Key connection parameter .

You can change the encryption key by specifying the new encryption key with the Connection.ChangeEncryptionKey method.

For more information, see ULConnection class and ULConnectionParms class (iAnywhere.Data.UltraLite namespace) or Connection class (iAnywhere.UltraLite namespace).

After the database is encrypted, connections to the database must specify the correct encryption key. Otherwise, the connection fails.

Obfuscation

To obfuscate the database, specify obfuscate=1 as a creation parameter.

For more information about database encryption, see Encrypting UltraLite databases.


Data manipulation: INSERT, UPDATE and DELETE

With UltraLite, you can perform SQL Data Manipulation Language operations. These operations are performed using the ULCommand.ExecuteNonQuery method (iAnywhere.Data.UltraLite namespace) or the PreparedStatement.executeStatement method (iAnywhere.UltraLite namespace).

For more information, see ULCommand class (iAnywhere.Data.UltraLite namespace) or PreparedStatement class (iAnywhere.UltraLite namespace).

Using parameters with your iAnywhere.Data.UltraLite commands
Placeholders for parameters in SQL statements are indicated the ? character. For any INSERT, UPDATE or DELETE, each ? is referenced according to its ordinal position in the command's Parameters collection. For example, the first ? is referred to as 0, and the second as 1.
Using parameters in your iAnywhere.UltraLite prepared statements
Placeholders for parameters in SQL statements are indicated the ? character. For any INSERT, UPDATE or DELETE, each ? is referenced according to its ordinal position in the prepared statement. For example, the first ? is referred to as 1, and the second as 2.
toggle To INSERT a row

  1. Declare a ULCommand.

    // iAnywhere.Data.UltraLite namespace
ULCommand cmd;

// iAnywhere.UltraLite namespace
PreparedStatement prepStmt;

  2. Assign a SQL statement to the ULCommand object.

    // iAnywhere.Data.UltraLite namespace
cmd = conn.CreateCommand();
cmd.Command =
   "INSERT INTO MyTable(MyColumn) values (?)";
    // iAnywhere.UltraLite namespace
prepStmt = conn.PrepareStatement(
   "INSERT INTO MyTable(MyColumn) values (?)");

  3. Assign input parameter values for the statement.

    The following code shows a string parameter.

    // iAnywhere.Data.UltraLite namespace
String newValue;
// assign value
cmd.add("", newValue);
    // iAnywhere.UltraLite namespace
String newValue;
// assign value
prepStmt.SetStringParameter(1, newValue);

  4. Execute the statement.

    The return value indicates the number of rows affected by the statement.

    // iAnywhere.Data.UltraLite namespace
int rowsInserted = cmd.ExecuteNonQuery();

// iAnywhere.UltraLite namespace
long rowsInserted = prepStmt.ExecuteStatement();

  5. If you are using transactions (AutoCommit false in the iAnywhere.UltraLite namespace), commit the change.

    // iAnywhere.Data.UltraLite namespace
cmd.Transaction.Commit();
    // iAnywhere.UltraLite namespace
conn.Commit();
toggle To UPDATE a row

  1. Declare a ULCommand.

    // iAnywhere.Data.UltraLite namespace
ULCommand cmd;

// iAnywhere.UltraLite namespace
PreparedStatement prepStmt;

  2. Assign a statement to the ULCommand object.

    // iAnywhere.Data.UltraLite namespace
cmd = conn.CreateCommand();
cmd.Command =
   "UPDATE MyTable SET MyColumn1 = ? WHERE MyColumn2 = ?";
    // iAnywhere.UltraLite namespace
prepStmt = conn.PrepareStatement(
   "UPDATE MyTable SET MyColumn1 = ? WHERE MyColumn2 = ?");

  3. Assign input parameter values for the statement.

    // iAnywhere.Data.UltraLite namespace
String newValue;
String oldValue;
// assign values
cmd.add("", newValue);
cmd.add("", oldValue);
    // iAnywhere.UltraLite namespace
String newValue;
String oldValue;
// assign values
prepStmt.SetStringParameter(1, newValue);
prepStmt.SetStringParameter(2, oldValue);

  4. Execute the statement.

    // iAnywhere.Data.UltraLite namespace
int rowsUpdated = cmd.ExecuteNonQuery();
    // iAnywhere.UltraLite namespace
long rowsUpdated = prepStmt.ExecuteStatement();

  5. If you are using transactions (AutoCommit false in the iAnywhere.UltraLite namespace), commit the change.

    // iAnywhere.Data.UltraLite namespace
cmd.Transaction.Commit();
    // iAnywhere.UltraLite namespace
conn.Commit();
toggle To DELETE a row

  1. Declare a ULCommand.

    // iAnywhere.Data.UltraLite namespace
ULCommand cmd;
    // iAnywhere.UltraLite namespace
PreparedStatement prepStmt;

  2. Assign a statement to the ULCommand object.

    // iAnywhere.Data.UltraLite namespace
cmd = conn.CreateCommand();
cmd.Command =
   "DELETE FROM MyTable WHERE MyColumn = ?";
    // iAnywhere.UltraLite namespace
prepStmt = conn.PrepareStatement(
   "DELETE FROM MyTable WHERE MyColumn = ?");

  3. Assign input parameter values for the statement.

    // iAnywhere.Data.UltraLite namespace
String deleteValue;
// assign value
cmd.add("", deleteValue);
    // iAnywhere.UltraLite namespace
String deleteValue;
prepStmt.SetStringParameter(1, deleteValue);

  4. Execute the statement.

    // iAnywhere.Data.UltraLite namespace
int rowsDeleted = cmd.ExecuteNonQuery();
    // iAnywhere.UltraLite namespace
long rowsDeleted = prepStmt.ExecuteStatement();

  5. If you are using transactions (AutoCommit false in the iAnywhere.UltraLite namespace), commit the change.

    // iAnywhere.Data.UltraLite namespace
cmd.Transaction.Commit();
    // iAnywhere.UltraLite namespace
conn.Commit();


Data retrieval: SELECT

The SELECT statement allows you to retrieve information from the database. This section describes how to execute a SELECT statement and how to handle the result set it returns.

toggle To execute a SELECT statement

  1. Declare a ULCommand object, which holds the query.

    // iAnywhere.Data.UltraLite namespace
ULCommand cmd;
    // iAnywhere.UltraLite namespace
PreparedStatement prepStmt;

  2. Assign a statement to the object.

    // iAnywhere.Data.UltraLite namespace
cmd = conn.CreateCommand();
cmd.Command =
   "SELECT MyColumn FROM MyTable";
    // iAnywhere.UltraLite namespace
prepStmt = conn.PrepareStatement(
"SELECT MyColumn FROM MyTable");

  3. Execute the statement.

    In the following code, the result of the SELECT query contain a string, which is output to a command prompt.

    // iAnywhere.Data.UltraLite namespace
ULDataReader customerNames = prepStmt.ExecuteReader();
while( customerNames.MoveNext() ) {
  for ( int i = 0;
    i < customerNames.GetFieldCount();
    i++ ) {
    System.Console.Write(
    customerNames.GetString( i ) + " " );
  }
  System.Console.WriteLine();
}
    // iAnywhere.UltraLite namespace
ResultSet customerNames = prepStmt.ExecuteQuery();
customerNames.MoveBeforeFirst();
while( customerNames.MoveNext() ) {
  for ( int i = 1;
    i <= customerNames.Schema.GetColumnCount();
    i++ ) {
    System.Console.Write(
    customerNames.GetString( i ) + " " );
  }
  System.Console.WriteLine();
}


Navigating dynamic SQL result sets

You can navigate through a result set using methods associated with the ULDataReader (iAnywhere.Data.UltraLite namespace) or ResultSet (iAnywhere.UltraLite namespace) object.

The result set object provides you with the following methods to navigate a result set.

  • MoveAfterLast() moves to a position after the last row.

  • MoveBeforeFirst() moves to a position before the first row.

  • MoveFirst() moves to the first row.

  • MoveLast() moves to the last row.

  • MoveNext() moves to the next row.

  • MovePrevious() moves to the previous row.

  • MoveRelative( offset ) moves a certain number of rows relative to the current row, as specified by the offset. Positive offset values move forward in the result set, relative to the current position of the cursor in the result set, and negative offset values move backward in the result set. An offset value of zero does not move the cursor, but allows you to repopulate the row buffer.


Result set schema description

The ULDataReader.GetSchemaTable method and ULDataReader.Schema property (iAnywhere.Data.UltraLite namespace), or the ResultSet.Schema property (iAnywhere.UltraLite namespace) allows you to retrieve information about a result set, such as column names, total number of columns, column scales, column sizes and column SQL types.

Example

The following example demonstrates how to use the ULDataReader.Schema and ResultSet.Schema properties to display schema information in a console window.

// iAnywhere.Data.UltraLite namespace
for ( int i = 0;
      i < MyResultSet.Schema.GetColumnCount();
      i++ ) {
   System.Console.WriteLine(
      MyResultSet.Schema.GetColumnName(i) + " " +
      MyResultSet.Schema.GetColumnSQLType(i)
   );
}
// iAnywhere.UltraLite namespace
for ( int i = 1;
      i <= MyResultSet.Schema.GetColumnCount();
      i++ ) {
   System.Console.WriteLine(
      MyResultSet.Schema.GetColumnName(i) + " " +
      MyResultSet.Schema.GetColumnSQLType(i)
   );
}


Navigating the rows of a table

UltraLite.NET provides you with a number of methods to navigate a table in order to perform a wide range of navigation tasks.

The table object provides you with the following methods to navigate a table.

  • MoveAfterLast() moves to a position after the last row.

  • MoveBeforeFirst() moves to a position before the first row.

  • MoveFirst() moves to the first row.

  • MoveLast() moves to the last row.

  • MoveNext() moves to the next row.

  • MovePrevious() moves to the previous row.

  • MoveRelative( offset ) moves a certain number of rows relative to the current row, as specified by the offset. Positive offset values move forward in the table, relative to the current position of the cursor in the table, and negative offset values move backward in the table. An offset value of zero does not move the cursor, but allows you to repopulate the row buffer.

Example

The following code opens the MyTable table and displays the value of the MyColumn column for each row.

// iAnywhere.Data.UltraLite namespace
ULTable t = conn.ExecuteTable( "MyTable" );
int colID = t.GetOrdinal( "MyColumn" );
while ( t.MoveNext() ){
   System.Console.WriteLine( t.GetString( colID ) );
}
// iAnywhere.UltraLite namespace
Table t = conn.GetTable( "MyTable" );
short colID = t.Schema.GetColumnID( "MyColumn" );
t.Open();
t.MoveBeforeFirst();
while ( t.MoveNext() ){
   System.Console.WriteLine( t.GetString( colID ) );
}

You expose the rows of the table to the application when you open the table object. By default, the rows are ordered by primary key value, but you can specify an index when opening a table to access the rows in a particular order.

Example

The following code moves to the first row of the MyTable table as ordered by the ix_col index.

// iAnywhere.Data.UltraLite namespace
ULTable t = conn.ExecuteTable( "MyTable", "ix_col" );
t.MoveFirst();

// iAnywhere.UltraLite namespace
Table t = conn.GetTable( "MyTable" );
t.Open( "ix_col" );
t.MoveFirst();

For more information, see ULTable class and ULTableSchema class and (iAnywhere.Data.UltraLite namespace) or Table class and TableSchema class (iAnywhere.UltraLite namespace).


Accessing the values of the current row

A Table object is always located at one of the following positions.

  • Before the first row of the table.

  • On a row of the table.

  • After the last row of the table.

If the Table object is positioned on a row, you can use one of a set of methods appropriate for the data type to retrieve or modify the value of each column.

Retrieving column values

The Table object provides a set of methods for retrieving column values. These methods take the column ID as argument.

Example

The following code retrieves the value of the lname column, which is a character string.

// iAnywhere.Data.UltraLite namespace
int lname = t.GetOrdinal( "lname" );
string lastname = t.GetString( lname );
// iAnywhere.UltraLite namespace
short lname = t.Schema.GetColumnID( "lname" );
string lastname = t.GetString( lname );

The following code retrieves the value of the cust_id column, which is an integer.

// iAnywhere.Data.UltraLite namespace
int cust_id = t.GetOrdinal( "cust_id" );
int id = t.GetInt( cust_id );
// iAnywhere.UltraLite namespace
short cust_id = t.Schema.GetColumnID( "cust_id" );
int id = t.GetInt( cust_id );
Modifying column values

In addition to the methods for retrieving values, there are methods for setting values. These methods take the column ID and the value as arguments.

Example

For example, the following code sets the value of the lname column to Kaminski.

t.SetString( lname, "Kaminski" );

By assigning values to these properties you do not alter the value of the data in the database. You can assign values to the properties even if you are before the first row or after the last row of the table, but it is an error to try to access data when the current row is at one of these positions, for example by assigning the property to a variable.

// This code is incorrect
t.MoveBeforeFirst();
id = t.GetInt( cust_id );
Casting values

The method you choose must match the data type you wish to assign. UltraLite automatically casts database data types where they are compatible, so that you could use the getString method to fetch an integer value into a string variable, and so on.


Searching rows with find and lookup

UltraLite has several modes of operation for working with data. Two of these modes, the find and lookup modes, are used for searching. The Table object has methods corresponding to these modes for locating particular rows in a table.

Note
The columns searched using Find and Lookup methods must be in the index used to open the table.

  • Find methods move to the first row that exactly matches specified search values, under the sort order specified when the Table object was opened. If the search values cannot be found, the application is positioned before the first or after the last row.

  • Lookup methods move to the first row that matches or is greater than a specified search value, under the sort order specified when the Table object was opened.

toggle To search for a row

  1. Enter find or lookup mode.

    The mode is entered by calling a method on the table object. For example, the following code enters find mode.

    t.FindBegin();

  2. Set the search values.

    You do this by setting values in the current row. Setting these values affects the buffer holding the current row only, not the database. For example, the following code sets the value in the buffer to Kaminski.

    // iAnywhere.Data.UltraLite namespace
int lname = t.GetOrdinal( "lname" );
t.SetString( lname, "Kaminski" );
    // iAnywhere.UltraLite namespace
short lname = t.Schema.GetColumnID( "lname" );
t.SetString( lname, "Kaminski" );

  3. Search for the row.

    Use the appropriate method to carry out the search. For example, the following instruction looks for the first row that exactly matches the specified value in the current index.

    For multi-column indexes, a value for the first column is always used, but you can omit the other columns.

    tCustomer.FindFirst();

  4. Search for the next instance of the row.

    Use the appropriate method to carry out the search. For a find operation, FindNext() locates the next instance of the parameters in the index. For a lookup, MoveNext() locates the next instance.

For more information, see ULTable class (iAnywhere.Data.UltraLite namespace) or Table class (iAnywhere.UltraLite namespace).


Updating rows

The following procedure updates a row.

toggle To update a row

  1. Move to the row you wish to update.

    You can move to a row by scrolling through the table or by searching the table using find and lookup methods.

  2. Enter update mode.

    For example, the following instruction enters update mode on t.

    t.BeginUpdate();

  3. Set the new values for the row to be updated. For example, the following instruction sets the id column in the buffer to 3.

    t.SetInt( id , 3);

  4. Execute the Update.

    t.Update();

After the update operation the current row is the row that has been updated. If you changed the value of a column in the index specified when the Table object was opened, the current row is undefined.

By default, UltraLite.NET operates in autocommit mode, so that the update is immediately applied to the row in permanent storage. If you have disabled autocommit mode, the update is not applied until you execute a commit operation. For more information, see Transaction processing in UltraLite.

Caution You cannot update the primary key of a row: delete the row and add a new row instead.


Inserting rows

The steps to insert a row are very similar to those for updating rows, except that there is no need to locate a row in the table before carrying out the insert operation. The order of row insertion into the table has no significance.

Example

The following code inserts a new row.

t.InsertBegin();
t.SetInt( id, 3 );
t.SetString( lname, "Carlo" );
t.Insert();

If you do not set a value for one of the columns, and that column has a default, the default value is used. If the column has no default, one of the following entries is used.

  • For nullable columns, NULL.

  • For numeric columns that disallow NULL, zero.

  • For character columns that disallow NULL, an empty string.

  • To explicitly set a value to NULL, use the setNull method.

For update operations, an insert is applied to the database in permanent storage when a commit is carried out. In AutoCommit mode, a commit is carried out as part of the insert method.


Deleting rows

The steps to delete a row are simpler than to insert or update rows. There is no delete mode corresponding to the insert or update modes.

The following procedure deletes a row.

toggle To delete a row

  1. Move to the row you wish to delete.

  2. Execute the Table.Delete() method.

    t.Delete();


Transaction processing in UltraLite

UltraLite provides transaction processing to ensure the integrity of the data in your database. A transaction is a logical unit of work. Either an entire transaction is executed or none of the statements in the transaction are executed.

By default, UltraLite.NET operates in autocommit mode, so that each insert, update, or delete is executed as a separate transaction. Once the operation is complete, the change is made to the database.

To use multi-statement transactions, you must create a ULTransaction class object by calling ULConnection.BeginTransaction(). For example, if your application transfers money between two accounts, either both the deduction from the source account and the addition to the destination account must be completed, or neither statement must be completed.

If the connection has a valid transaction, you must execute a ULTransaction.Commit() statement to complete the transaction and make changes to your database permanent, or you must execute a ULTransaction.Rollback() statement to cancel all the operations of the transaction. Once a transaction has been commited or rolled back, the connection will revert to autocommit mode until the next call to ULConnection.BeginTransaction().

For more information, see ULConnection class and ULTransaction class (iAnywhere.Data.UltraLite namespace) or Connection class (iAnywhere.UltraLite namespace).


Accessing schema information

The objects in the API represent tables, columns, indexes, and synchronization publications. Each object has a Schema property that provides access to information about the structure of that object.

You cannot modify the schema through the API. You can only retrieve information about the schema.

For information about modifying the schema, see Upgrading your database schema.

You can access the following schema objects and information.

  • DatabaseSchema exposes the number and names of the tables in the database, as well as global properties such as the format of dates and times.

    To obtain a ULDatabaseSchema object, access ULConnection.Schema (iAnywhere.Data.UltraLite namespace) or Connection.Schema (iAnywhere.UltraLite namespace).

    For more information, see ULConnection class (iAnywhere.Data.UltraLite namespace) or Connection class (iAnywhere.UltraLite namespace).

  • TableSchema The number and names of the columns and indexes for this table.

    To obtain a ULTableSchema object, access ULTable.Schema (iAnywhere.Data.UltraLite namespace) or Table.Schema (iAnywhere.UltraLite namespace).

  • IndexSchema Information about the column in the index. As an index has no data directly associated with it there is no separate Index class, just a ULIndexSchema class.

    To obtain a ULIndexSchema object, call the ULTableSchema.GetIndex, the ULTableSchema.GetOptimalIndex, or the ULTableSchema.GetPrimaryKey method.

  • PublicationSchema A list of the tables and columns contained in a publication. Publications are also comprised of schema only, and so there is no Publication object.

    To obtain a ULPublicationSchema object, call the ULDatabaseSchema.GetPublicationSchema method.

For more information, see ULTableSchema class (iAnywhere.Data.UltraLite namespace) or TableSchema class (iAnywhere.UltraLite namespace).


Error handling

You can use the standard .NET error-handling features to handle errors. Most iAnywhere.Data.UltraLite namespace methods throw ULException errors. You can use ULException.NativeError to retrieve the ULSQLCode value assigned to this error. Most iAnywhere.UltraLite namespace methods throw SQLException errors. You can use SQLException.ErrorCode to retrieve the SQLCode value assigned to this error. Both ULException and SQLException have a Message property which you can use to obtain a descriptive text of the error. ULSQLCode and SQLCode errors are negative numbers indicating the error type.

For a list of error codes, see ASA Error Messages.

After synchronization, you can use the SyncResult property of the connection to obtain more detailed error information.

For more information, see the following:

  • ULSyncProgressListener interface (iAnywhere.Data.UltraLite namespace) or SyncProgressListener interface (iAnywhere.UltraLite namespace).

  • ULSyncResult class (iAnywhere.Data.UltraLite namespace) or SyncResult class (iAnywhere.UltraLite namespace).


User authentication

New users have to be added from an existing connection. As all UltraLite databases are created with a default user ID and password of DBA and SQL, respectively, you must first connect as this initial user.

You cannot change a user ID. Instead, you add a user and delete an existing user. A maximum of four user IDs are permitted for each UltraLite database.

For more information, see User authentication in UltraLite.

toggle To add a user or change a password for an existing user

  1. Connect to the database as a user with DBA authority.

  2. Grant the user access to the database with the desired password using the ULConnection.GrantConnectTo method.

    This procedure is the same whether you are adding a new user or changing the password of an existing user.

    For more information, see ULConnection class (iAnywhere.Data.UltraLite namespace) or Connection class (iAnywhere.UltraLite namespace).

toggle To delete an existing user

  1. Connect to the database as a user with DBA authority.

  2. Revoke the user's connection authority using the Connection.RevokeConnectFrom method.


Synchronizing UltraLite applications

You synchronize UltraLite applications with a central consolidated database. Synchronization requires the MobiLink synchronization software included with SQL Anywhere Studio.

This section provides a brief introduction to synchronization and describes some features of particular interest to users of UltraLite.NET.

For a more detailed explanation of synchronization, see UltraLite Clients.

You can also find a working example of synchronization in the CustDB sample application. For more information, see the Samples\UltraLite.NET\CustDB subdirectory of your SQL Anywhere 9 installation.

UltraLite.NET supports TCP/IP, HTTP, and HTTPS synchronization. Synchronization is initiated by the UltraLite application. In all cases, you use properties of the SyncParms object to control synchronization.

Note
To synchronize using HTTPS you must obtain the separately-licensable security option. To order this option, see the card in your SQL Anywhere Studio package or see [external link] http://www.sybase.com/detail?id=1015780.

For more information, see Welcome to SQL Anywhere Studio.

Adding ActiveSync synchronization to your application


Adding ActiveSync synchronization to your application

This section describes how to add ActiveSync synchronization to an UltraLite.NET application, and how to register your application for use with ActiveSync on your end users' computers.

For general information about setting up ActiveSync synchronization, see Deploying applications that use ActiveSync. For general information about adding synchronization to an application, see UltraLite Clients.

ActiveSync synchronization can only be initiated by ActiveSync. ActiveSync initiates synchronization when the device is placed in the cradle or when the Synchronization command is selected from the ActiveSync window.

When ActiveSync initiates synchronization, the MobiLink ActiveSync provider starts the UltraLite application, if it is not already running, and sends a message to it. Your application must implement a ULActiveSyncListener to receive and process messages from the MobiLink provider. Your application must specify the listener object using the SetActiveSyncListener method, where MyAppClassName is a unique Windows class name for the application.

dbMgr.SetActiveSyncListener(
   "MyAppClassName", listener );

For more information, including sample code, see the ULActiveSyncListener interface (iAnywhere.Data.UltraLite namespace) or ActiveSyncListener interface (iAnywhere.UltraLite namespace).

When UltraLite receives an ActiveSync message, it invokes the specified listener's ActiveSyncInvoked() method on a different thread. To avoid multi-threading issues, your ActiveSyncInvoked() method should post an event to the user interface.

If your application is multi-threaded, use a separate connection and use the lock keyword in C# or SyncLock keyword in Visual Basic .NET to access any objects shared with the rest of the application. The ActiveSyncInvoked() method should specify a ULStreamType.ACTIVE_SYNC for its connection's SyncParms.Stream and then call ULConnection.Synchronize().

When registering your application, set the following parameter.

  • Class Name The same class name the application used with the Connection.SetActiveSyncListener method.


iAnywhere.Data.UltraLite namespace

About this chapter

The iAnywhere.Data.UltraLite namespace contains the classes, interfaces, and enumerations of the UltraLite.NET Data Provider for ADO.NET.

UltraLite.NET allows you to write C# or Visual Basic .NET code to develop UltraLite database applications using the ADO.NET standard and provides a migration path to Adaptive Server Anywhere. If you are undecided as to whether to use UltraLite or Adaptive Server Anywhere, start with the iAnywhere.Data.UltraLite namespace and switch to Adaptive Server Anywhere (iAnywhere.Data.AsaClient namespace) if you determine that more advanced Adaptive Server Anywhere features are required. If you may be moving to Adaptive Server Anywhere, avoid as much as possible the few UltraLite-only extensions that are in the iAnywhere.Data.UltraLite namespace.

UltraLite.NET extensions that are not available in Adaptive Server Anywhere's Data Provider for ADO.NET are denoted in this API reference with "UL Ext.:".

To use the UltraLite Engine runtime of UltraLite.NET, set RuntimeType property to the appropriate value prior to using any other UltraLite.NET API.

Applications must open a connection to perform operations on a database. Connections are opened using the ULConnection class class.

The iAnywhere.Data.UltraLite assembly uses a satellite resource assembly called iAnywhere.Data.UltraLite.resources. The main assembly searches for this resource assembly by culture, using the following order: System.Globalization.CultureInfo.CurrentUICulture, then System.Globalization.CultureInfo.CurrentCulture, and finally culture "EN".

ULActiveSyncListener interface
ULAuthStatusCode enumeration
ULCommand class
ULConnection class
ULConnectionParms class
ULConnectionParms.UnusedEventHandler delegate
ULCursorSchema class
ULDataAdapter class
ULDatabaseManager class
ULDatabaseSchema class
ULDataReader class
ULDbType enumeration
ULException class
ULIndexSchema class
ULInfoMessageEventArgs class
ULInfoMessageEventHandler delegate
ULParameter class
ULParameterCollection class
ULPublicationSchema class
ULResultSetSchema class
ULRowUpdatedEventArgs class
ULRowUpdatedEventHandler delegate
ULRowUpdatingEventArgs class
ULRowUpdatingEventHandler delegate
ULRuntimeType enumeration
ULSchemaUpgradeData class
ULSchemaUpgradeListener interface
ULSchemaUpgradeState enumeration
ULServerSyncListener interface
ULSQLCode enumeration
ULStreamErrorCode enumeration
ULStreamErrorContext enumeration
ULStreamErrorID enumeration
ULStreamType enumeration
ULSyncParms class
ULSyncProgressData class
ULSyncProgressListener interface
ULSyncProgressState enumeration
ULSyncResult class
ULTable class
ULTableSchema class
ULTransaction class


ULActiveSyncListener interface

UL Ext.: The listener interface for receiving ActiveSync events.

Prototypes

' Visual Basic
Public Interface ULActiveSyncListener

// C#
public interface ULActiveSyncListener


ULActiveSyncListener members

Public instance methods
Member | Description
ActiveSyncInvoked method | Invoked when the MobiLink provider for ActiveSync calls the application to perform synchronization.


ActiveSyncInvoked method

Invoked when the MobiLink provider for ActiveSync calls the application to perform synchronization.

Prototypes

' Visual Basic
Public Sub ActiveSyncInvoked( _
ByVal launchedByProvider As Boolean _
)

// C#
public void ActiveSyncInvoked(
bool launchedByProvider
);

Parameters

  • launchedByProvider True if the application was launched by the MobiLink provider to perform ActiveSync synchronization. The application must then shut itself down after it has finished synchronizing. False if the application was already running when called by the MobiLink provider for ActiveSync.

Remarks

This method is invoked by a separate thread. To avoid multi-threading issues, it should post an event to the UI. If you are using multi-threading, it is recommended that you use a separate connection and use the lock keyword to access any objects shared with the rest of the application. The synchronization resulting from a call to ActiveSyncInvoked must specify the ULStreamType enumeration value for its connection's Stream property property.

Example

The following code fragments demonstrate how to receive an ActiveSync request and perform a synchronization in the UI thread.

' Visual Basic
Imports iAnywhere.Data.UltraLite

Public Class MainWindow
  Inherits System.Windows.Forms.Form
  Implements ULActiveSyncListener
  Private conn As ULConnection
  Public Sub New(ByVal args() As String)

    MyBase.New()

    'This call is required by the Windows Form Designer.
    InitializeComponent()

    'Add any initialization after the InitializeComponent() call
    ULConnection.DatabaseManager.SetActiveSyncListener( _
        "myCompany.myapp", Me _
      )
    'Create Connection
    ...
  End Sub
  Protected Overrides Sub OnClosing( _
        ByVal e As System.ComponentModel.CancelEventArgs _
      )
    ULConnection.DatabaseManager.SetActiveSyncListener( _
        Nothing, Nothing _
      )
    MyBase.OnClosing(e)
  End Sub
  Public Sub ActiveSyncInvoked( _
        ByVal launchedByProvider As Boolean _
      ) Implements ULActiveSyncListener.ActiveSyncInvoked
    Me.Invoke(New EventHandler(AddressOf Me.ActiveSyncAction))
  End Sub
  Public Sub ActiveSyncAction( _
        ByVal sender As Object, ByVal e As EventArgs _
      )
    ' Do active sync
    conn.SyncParms.Stream = ULStreamType.ACTIVE_SYNC
    conn.Synchronize()
  End Sub
End Class
// C#
using iAnywhere.Data.UltraLite;
public class Form1 : System.Windows.Forms.Form, ULActiveSyncListener
{
  private System.Windows.Forms.MainMenu mainMenu1;
  private ULConnection conn;
  public Form1()
  {
    //
    // Required for Windows Form Designer support
    //
    InitializeComponent();

    //
    // TODO: Add any constructor code after
    // InitializeComponent call
    //
    ULConnection.DatabaseManager.SetActiveSyncListener(
        "myCompany.myapp", this
      );
    // Create connection
    ...
  }
  protected override void Dispose( bool disposing )
  {
    base.Dispose( disposing );
  }
  protected override void OnClosing(
      System.ComponentModel.CancelEventArgs e
    )
  {
    ULConnection.DatabaseManager.SetActiveSyncListener(
        null, null
      );
    base.OnClosing(e);
  }
  public void ActiveSyncInvoked(bool launchedByProvider)
  {
    this.Invoke( new EventHandler( ActiveSyncHandler ) );
  }
  internal void ActiveSyncHandler(object sender, EventArgs e)
  {
    conn.SyncParms.Stream = ULStreamType.ACTIVE_SYNC;
    conn.Synchronize();
  }
}


ULAuthStatusCode enumeration

UL Ext.: Enumerates the status codes that may be reported during MobiLink user authentication.

Prototypes

' Visual Basic
Public Enum ULAuthStatusCode

// C#
public enum ULAuthStatusCode

Members
Member | Description
EXPIRED | User ID or password has expired - authorization failed (EXPIRED = 3000).
IN_USE | User ID is already in use - authorization failed (IN_USE = 5000).
INVALID | Bad user ID or password - authorization failed (INVALID = 4000).
UNKNOWN | Authorization status is unknown, possibly because the connection has not yet performed a synchronization (UNKNOWN = 0).
VALID | User ID and password were valid at time of synchronization (VALID = 1000).
VALID_BUT_EXPIRES_SOON | User ID and password were valid at time of synchronization, but will expire soon (VALID_BUT_EXPIRES_SOON = 2000).
See also
  • AuthStatus property


ULCommand class

Represents a pre-compiled SQL statement or query, with or without IN parameters. This object can be used to efficiently execute a statement or query multiple times.

Prototypes

' Visual Basic
NotInheritable Public Class ULCommand
Inherits Component, IDbCommand

// C#
public sealed class ULCommand :
Component,
IDbCommand

Remarks

ULCommand objects can be created directly, or with the CreateCommand method method. This method ensures that the command has the correct transaction for executing statements on the given connection.

The Transaction property property must be reset after the current transaction is committed or rolled back.

ULCommand features the following methods for executing commands on an UltraLite.NET database:

Method | Description
ExecuteNonQuery method | Executes a statement that does not return a result set, such as a SQL INSERT, DELETE, or UPDATE statement.
ExecuteReader method | Executes a SQL SELECT statement and returns the result set in a ULDataReader class.
ExecuteScalar method | Executes a SQL SELECT statement and returns a single value.
ExecuteTable method | UL Ext.: Retrieves a database table in a ULTable class for direct manipulation. The CommandText property is interpreted as the name of the table and IndexName property can be used to specify a table sorting order. CommandType property must be CommandType.TableDirect.

You can reset most properties, including the CommandText property property, and reuse the ULCommand object.

For resource management reasons, it is recommended that you explicitly close commands when you are done with them.

Implements: IDbCommand, IDisposable

ULCommand members
ULCommand constructor
ULCommand constructor
ULCommand constructor
ULCommand constructor
CommandText property
CommandTimeout property
CommandType property
Connection property
IndexName property
Parameters property
Plan property
Transaction property
UpdatedRowSource property
Cancel method
CreateParameter method
Dispose method
ExecuteNonQuery method
ExecuteReader method
ExecuteReader method
ExecuteScalar method
ExecuteTable method
ExecuteTable method
Prepare method


ULCommand members

Public instance constructors
Member | Description
ULCommand constructor | Initializes a ULCommand object.
ULCommand constructor | Initializes a ULCommand object with the specified command text.
ULCommand constructor | Initializes a ULCommand object with the specified command text and connection.
ULCommand constructor | Initializes a ULCommand object with the specified command text, connection, and transaction.
Public instance properties
Member | Description
CommandText property | Specifies the text of the SQL statement or the name of the table when the CommandType property is CommandType.TableDirect. For parameterized statements, use a question mark (?) placeholder to pass parameters.
CommandTimeout property | This feature is not supported by UltraLite.NET.
CommandType property | Specifies the type of command to be executed.
Connection property | The connection object on which to execute the ULCommand object.
IndexName property | UL Ext.: Specifies the name of the index to open (sort) the table with when the CommandType property is CommandType.TableDirect.
Parameters property | Specifies the parameters for the current statement.
Plan property | UL Ext.: Returns the access plan UltraLite.NET will use to execute a query. This property is intended primarily for use during development.
Transaction property | Specifies the ULTransaction class in which the ULCommand executes.
UpdatedRowSource property | Specifies how command results are applied to the DataRow when used by the Update method of the ULDataAdapter.
Public instance methods
Member | Description
Cancel method | This method is not supported in UltraLite.NET.
CreateParameter method | Provides a ULParameter class object for supplying parameters to ULCommand objects.
ExecuteNonQuery method | Executes a statement that does not return a result set, such as a SQL INSERT, DELETE, or UPDATE statement.
ExecuteReader method | Executes a SQL SELECT statement and returns the result set.
ExecuteReader method | Executes a SQL SELECT statement with the specified command behavior and returns the result set.
ExecuteScalar method | Executes a SQL SELECT statement and returns a single value.
ExecuteTable method | UL Ext.: Retrieves in a ULTable class a database table for direct manipulation. The CommandText property is interpreted as the name of the table and IndexName property can be used to specify a table sorting order.
ExecuteTable method | UL Ext.: Retrieves, with the specified command behavior, a database table for direct manipulation. The CommandText property is interpreted as the name of the table and IndexName property can be used to specify a table sorting order.
Prepare method | Pre-compiles and stores the SQL statement of this command.
Protected instance methods
Member | Description
Dispose method | Releases the unmanaged resources used by the ULCommand and optionally releases the managed resources.


ULCommand constructor

Initializes a ULCommand object.

Prototypes

' Visual Basic
Overloads Public Sub New()

// C#
public ULCommand();

Remarks

The ULCommand object needs to have the CommandText property, Connection property, and Transaction property properties set before a statement can be executed.

See also
  • ULCommand class
  • ULCommand members
  • CreateCommand method
  • ULCommand constructor
  • ULCommand constructor
  • ULCommand constructor


ULCommand constructor

Initializes a ULCommand object with the specified command text.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal cmdText As String _
)

// C#
public ULCommand(
string cmdText
);

Parameters

  • cmdText The text of the SQL statement or name of the table when the CommandType property is CommandType.TableDirect. For parameterized statements, use a question mark (?) placeholder to pass parameters.

Remarks

The ULCommand object needs to have the Connection property and Transaction property properties set before a statement can be executed.

See also
  • ULCommand class
  • ULCommand members
  • CreateCommand method
  • ULCommand constructor
  • ULCommand constructor
  • ULCommand constructor


ULCommand constructor

Initializes a ULCommand object with the specified command text and connection.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal cmdText As String, _
ByVal connection As ULConnection _
)

// C#
public ULCommand(
string cmdText,
ULConnection connection
);

Parameters

  • cmdText The text of the SQL statement or name of the table when the CommandType property is CommandType.TableDirect. For parameterized statements, use a question mark (?) placeholder to pass parameters.

  • connection The current connection.

Remarks

The ULCommand object may need to have the Transaction property property set before a statement can be executed.

See also
  • ULCommand class
  • ULCommand members
  • CreateCommand method
  • ULCommand constructor
  • ULCommand constructor
  • ULCommand constructor


ULCommand constructor

Initializes a ULCommand object with the specified command text, connection, and transaction.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal cmdText As String, _
ByVal connection As ULConnection, _
ByVal transaction As ULTransaction _
)

// C#
public ULCommand(
string cmdText,
ULConnection connection,
ULTransaction transaction
);

Parameters

  • cmdText The text of the SQL statement or name of the table when the CommandType property is CommandType.TableDirect. For parameterized statements, use a question mark (?) placeholder to pass parameters.

  • connection The current connection.

  • transaction The ULTransaction class in which the ULCommand executes.

See also
  • ULCommand class
  • ULCommand members
  • CreateCommand method
  • ULCommand constructor
  • ULCommand constructor
  • ULCommand constructor


CommandText property

Specifies the text of the SQL statement or the name of the table when the CommandType property is CommandType.TableDirect. For parameterized statements, use a question mark (?) placeholder to pass parameters.

Prototypes

' Visual Basic
NotOverridable Public Property CommandText As String _
Implements IDbCommand.CommandText

// C#
public string CommandText {get;set;}

Property value

A string specifying the text of the SQL statement or the name of the table. The default is an empty string (invalid command).

Implements

IDbCommand.CommandText

Example

The following example demonstrates the use of the parameterized placeholder:

' Visual Basic
myCmd.CommandText = "SELECT * FROM Customers WHERE CustomerID = ?"

// C#
myCmd.CommandText = "SELECT * FROM Customers WHERE CustomerID = ?";
See also
  • ULCommand class
  • ULCommand members
  • ExecuteNonQuery method
  • ExecuteReader method
  • ExecuteScalar method
  • ExecuteTable method


CommandTimeout property

This feature is not supported by UltraLite.NET.

Prototypes

' Visual Basic
NotOverridable Public Property CommandTimeout As Integer _
Implements IDbCommand.CommandTimeout

// C#
public int CommandTimeout {get;set;}

Property value

The value is always zero.

Exceptions

  • ULException class - Setting the value is not supported in UltraLite.NET.

Implements

IDbCommand.CommandTimeout


CommandType property

Specifies the type of command to be executed.

Prototypes

' Visual Basic
NotOverridable Public Property CommandType As CommandType _
Implements IDbCommand.CommandType

// C#
public CommandType CommandType {get;set;}

Property value

One of the CommandType values. The default is CommandType.Text.

Remarks

Supported command types are as follows:

  • CommandType.TableDirect - UL Ext.: When you specify this CommandType, the CommandText property must be the name of a database table. You can also specify the index used to open (sort) the table with IndexName property. Use ExecuteTable method or ExecuteReader method to access the table.
  • CommandType.Text - When you specify this CommandType, the CommandText property must be a SQL statement or query. Use ExecuteNonQuery method to execute a non-query SQL statement and use either ExecuteReader method or ExecuteScalar method to execute a query.
Exceptions

  • ArgumentException - CommandType.StoredProcedure is not supported in UltraLite.NET.

Implements

IDbCommand.CommandType


Connection property

The connection object on which to execute the ULCommand object.

Prototypes

' Visual Basic
Public Property Connection As ULConnection

// C#
public ULConnection Connection {get;set;}

Property value

The ULConnection class object on which to execute the command.

Remarks

ULCommand objects must have an open connection before they can be executed.

The default is a null reference (Nothing in Visual Basic).

This is the strongly typed version of IDbCommand.Connection.


IndexName property

UL Ext.: Specifies the name of the index to open (sort) the table with when the CommandType property is CommandType.TableDirect.

Prototypes

' Visual Basic
Public Property IndexName As String

// C#
public string IndexName {get;set;}

Property value

A string specifying the name of the index. The default is a null reference (Nothing in Visual Basic), meaning the table is opened with its primary key.

See also
  • ULCommand class
  • ULCommand members
  • ExecuteTable method
  • ExecuteReader method


Parameters property

Specifies the parameters for the current statement.

Prototypes

' Visual Basic
Public Readonly Property Parameters As ULParameterCollection

// C#
public ULParameterCollection Parameters {get;}

Property value

A ULParameterCollection class holding the parameters of the SQL statement. The default value is the empty collection.

Remarks

Use question marks in the CommandText property to indicate parameters. The parameters in the collection are specified in the same order as the question mark placeholders. For example, the first parameter in the collection corresponds to the first question mark in the SQL statement, the second parameter in the collection corresponds to the second question mark in the SQL statement, and so on. There must be at least as many question marks in the CommandText property as there are parameters in this collection.

This is the strongly typed version of IDbCommand.Parameters.


Plan property

UL Ext.: Returns the access plan UltraLite.NET will use to execute a query. This property is intended primarily for use during development.

Prototypes

' Visual Basic
Public Readonly Property Plan As String

// C#
public string Plan {get;}

Property value

A string containing the text-based description of the query execution plan.

Exceptions

  • ULException class - A SQL error occurred.


Transaction property

Specifies the ULTransaction class in which the ULCommand executes.

Prototypes

' Visual Basic
Public Property Transaction As ULTransaction

// C#
public ULTransaction Transaction {get;set;}

Property value

The ULTransaction class in which the ULCommand executes. This should be the current transaction of the connection specified by the Connection property property. The default is a null reference (Nothing in Visual Basic).

Remarks

If a command is reused after a transaction has been committed or rolled back, this property needs to be reset.

This is the strongly typed version of IDbCommand.Transaction.

See also
  • ULCommand class
  • ULCommand members
  • BeginTransaction method


UpdatedRowSource property

Specifies how command results are applied to the DataRow when used by the Update method of the ULDataAdapter.

Prototypes

' Visual Basic
NotOverridable Public Property UpdatedRowSource As UpdateRowSource _
Implements IDbCommand.UpdatedRowSource

// C#
public UpdateRowSource UpdatedRowSource {get;set;}

Property value

One of the UpdateRowSource values. The default value is UpdateRowSource.Both.

Implements

IDbCommand.UpdatedRowSource


Cancel method

This method is not supported in UltraLite.NET.

Prototypes

' Visual Basic
NotOverridable Public Sub Cancel() _
Implements IDbCommand.Cancel

// C#
public void Cancel();

Remarks

This method does nothing. UltraLite.NET commands cannot be interrupted while they are executing.

Implements

IDbCommand.Cancel


CreateParameter method

Provides a ULParameter class object for supplying parameters to ULCommand objects.

Prototypes

' Visual Basic
Public Function CreateParameter() As ULParameter

// C#
public ULParameter CreateParameter();

Return value

A new parameter, as a ULParameter class object.

Remarks

Some SQL statements can take parameters, indicated in the text of a statement by a question mark (?). The CreateParameter method provides a ULParameter class object. You can set properties on the ULParameter to specify the value for the parameter.

This is the strongly typed version of IDbCommand.CreateParameter.


Dispose method

Releases the unmanaged resources used by the ULCommand and optionally releases the managed resources.

Prototypes

' Visual Basic
Overloads Overrides Protected Sub Dispose( _
ByVal disposing As Boolean _
)

// C#
protected override void Dispose(
bool disposing
);

Parameters

  • disposing When true, disposes of both the managed and unmanaged resources. When false, disposes of only the unmanaged resources.


ExecuteNonQuery method

Executes a statement that does not return a result set, such as a SQL INSERT, DELETE, or UPDATE statement.

Prototypes

' Visual Basic
NotOverridable Public Function ExecuteNonQuery() As Integer _
Implements IDbCommand.ExecuteNonQuery

// C#
public int ExecuteNonQuery();

Return value

The number of rows affected.

Remarks

The statement is the current ULCommand object, with the CommandText property and Parameters property as needed.

For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command. For all other types of statements, and for rollbacks, the return value is -1.

The CommandType property property cannot be CommandType.TableDirect.

Exceptions

  • ULException class - A SQL error occurred.

  • InvalidOperationException - The command is in an invalid state. Either the Connection property is missing or closed, the Transaction property value does not match the current transaction state of the connection, or the CommandText property is invalid.

Implements

IDbCommand.ExecuteNonQuery


ExecuteReader method

Executes a SQL SELECT statement and returns the result set.

Prototypes

' Visual Basic
Overloads Public Function ExecuteReader() As ULDataReader

// C#
public ULDataReader ExecuteReader();

Return value

The result set as a ULDataReader class object.

Remarks

The statement is the current ULCommand object, with the CommandText property and Parameters property as needed. The ULDataReader class object is a read-only result set. For editable result sets, use ExecuteTable method or a ULDataAdapter class.

If the CommandType property is CommandType.TableDirect, ExecuteReader performs an ExecuteTable method and returns a ULTable class downcast as a ULDataReader class.

This is the strongly typed version of IDbCommand.ExecuteReader.

Exceptions

  • ULException class - A SQL error occurred.

  • InvalidOperationException - The command is in an invalid state. Either the Connection property is missing or closed, the Transaction property value does not match the current transaction state of the connection, or the CommandText property is invalid.

See also
  • ULCommand class
  • ULCommand members
  • ExecuteReader method


ExecuteReader method

Executes a SQL SELECT statement with the specified command behavior and returns the result set.

Prototypes

' Visual Basic
Overloads Public Function ExecuteReader( _
ByVal cmdBehavior As CommandBehavior _
) As ULDataReader

// C#
public ULDataReader ExecuteReader(
CommandBehavior cmdBehavior
);

Parameters

  • cmdBehavior A bitwise combination of CommandBehavior flags describing the results of the query and its effect on the connection. UltraLite.NET respects only the CommandBehavior.Default, CommandBehavior.CloseConnection, and CommandBehavior.SchemaOnly flags.

Return value

The result set as a ULDataReader class object.

Remarks

The statement is the current ULCommand object, with the CommandText property and Parameters property as needed. The ULDataReader class object is a read-only result set. For editable result sets, use ExecuteTable method or a ULDataAdapter class.

If the CommandType property is CommandType.TableDirect, ExecuteReader performs an ExecuteTable method and returns a ULTable class downcast as a ULDataReader class.

This is the strongly typed version of IDbCommand.ExecuteReader.

Exceptions

  • ULException class - A SQL error occurred.

  • InvalidOperationException - The command is in an invalid state. Either the Connection property is missing or closed, the Transaction property value does not match the current transaction state of the connection, or the CommandText property is invalid.

See also
  • ULCommand class
  • ULCommand members
  • ExecuteReader method


ExecuteScalar method

Executes a SQL SELECT statement and returns a single value.

Prototypes

' Visual Basic
NotOverridable Public Function ExecuteScalar() As Object _
Implements IDbCommand.ExecuteScalar

// C#
public object ExecuteScalar();

Return value

The first column of the first row in the result set, or a null reference (Nothing in Visual Basic) if the result set is empty.

Remarks

The statement is the current ULCommand object, with the CommandText property and Parameters property as needed.

If this method is called on a query that returns multiple rows and columns, only the first column of the first row is returned.

If the CommandType property is CommandType.TableDirect, ExecuteScalar performs an ExecuteTable method and returns the first column of the first row.

Exceptions

  • ULException class - A SQL error occurred.

  • InvalidOperationException - The command is in an invalid state. Either the Connection property is missing or closed, the Transaction property value does not match the current transaction state of the connection, or the CommandText property is invalid.

Implements

IDbCommand.ExecuteScalar


ExecuteTable method

UL Ext.: Retrieves in a ULTable class a database table for direct manipulation. The CommandText property is interpreted as the name of the table and IndexName property can be used to specify a table sorting order.

Prototypes

' Visual Basic
Overloads Public Function ExecuteTable() As ULTable

// C#
public ULTable ExecuteTable();

Return value

The table as a ULTable class object.

Remarks

The CommandType property property must be set to CommandType.TableDirect.

If the IndexName property property is a null reference (Nothing in Visual Basic), the primary key is used to open the table. Otherwise, the table is opened using the IndexName property value as the name of the index to sort by.

Exceptions

  • ULException class - A SQL error occurred.

  • InvalidOperationException - The command is in an invalid state. Either the Connection property is missing or closed, the Transaction property value does not match the current transaction state of the connection, or the CommandText property is invalid.

See also
  • ULCommand class
  • ULCommand members
  • ExecuteTable method


ExecuteTable method

UL Ext.: Retrieves, with the specified command behavior, a database table for direct manipulation. The CommandText property is interpreted as the name of the table and IndexName property can be used to specify a table sorting order.

Prototypes

' Visual Basic
Overloads Public Function ExecuteTable( _
ByVal cmdBehavior As CommandBehavior _
) As ULTable

// C#
public ULTable ExecuteTable(
CommandBehavior cmdBehavior
);

Parameters

  • cmdBehavior A bitwise combination of CommandBehavior flags describing the results of the query and its effect on the connection. UltraLite.NET respects only the CommandBehavior.Default, CommandBehavior.CloseConnection, and CommandBehavior.SchemaOnly flags.

Return value

The table as a ULTable class object.

Remarks

The CommandType property property must be set to CommandType.TableDirect.

If the IndexName property property is a null reference (Nothing in Visual Basic), the primary key is used to open the table. Otherwise, the table is opened using the IndexName property value as the name of the index to sort by.

Exceptions

  • ULException class - A SQL error occurred.

  • InvalidOperationException - The command is in an invalid state. Either the Connection property is missing or closed, the Transaction property value does not match the current transaction state of the connection, or the CommandText property is invalid.

See also
  • ULCommand class
  • ULCommand members
  • ExecuteTable method


Prepare method

Pre-compiles and stores the SQL statement of this command.

Prototypes

' Visual Basic
NotOverridable Public Sub Prepare() _
Implements IDbCommand.Prepare

// C#
public void Prepare();

Remarks

Pre-compiling statements allows for the efficient re-use of statements when just the parameter values are changed. Changing any other property on this command unprepares the statement.

UltraLite.NET does not require you to explicitly prepare statements as all unprepared commands are prepared on calls to the various Execute methods.

Exceptions

  • ULException class - A SQL error occurred.

  • InvalidOperationException - The command is in an invalid state. Either the Connection property is missing or closed, the Transaction property value does not match the current transaction state of the connection, or the CommandText property is invalid.

Implements

IDbCommand.Prepare


ULConnection class

Represents a connection to an UltraLite.NET database.

Prototypes

' Visual Basic
NotInheritable Public Class ULConnection
Inherits Component, IDbConnection

// C#
public sealed class ULConnection :
Component,
IDbConnection

Remarks

To use the UltraLite Engine runtime of UltraLite.NET, set RuntimeType property to the appropriate value before using any other UltraLite.NET API.

A connection to an existing database is opened using the Open method method. You can create a new database and connect to it using the OpenWithCreate method method.

You must open a connection before carrying out any other operation, and you must close the connection after you have finished all operations on the connection and before your application terminates. In addition, you must close all result sets and tables opened on a connection before closing the connection.

The schema of the database can be accessed using an open connection's Schema property property.

Implements: IDbConnection, IDisposable

ULConnection members
ULConnection constructor
ULConnection constructor
INVALID_DATABASE_ID field
ConnectionString property
ConnectionTimeout property
Database property
DatabaseID property
DatabaseManager property
GlobalAutoIncrementUsage property
LastIdentity property
Schema property
State property
SyncParms property
SyncResult property
BeginTransaction method
BeginTransaction method
ChangeDatabase method
ChangeEncryptionKey method
Close method
CountUploadRows method
CountUploadRows method
CreateCommand method
Dispose method
ExecuteTable method
ExecuteTable method
ExecuteTable method
Finalize method
GetLastDownloadTime method
GetNewUUID method
GrantConnectTo method
Open method
OpenWithCreate method
ResetLastDownloadTime method
RevokeConnectFrom method
RollbackPartialDownload method
StartSynchronizationDelete method
StopSynchronizationDelete method
Synchronize method
Synchronize method
InfoMessage event
StateChange event


ULConnection members

Public static fields (Shared)
Member | Description
INVALID_DATABASE_ID field | UL Ext.: A database ID constant indicating that the DatabaseID property has not been set.
Public static properties (Shared)
Member | Description
DatabaseManager property | UL Ext.: Provides access to the singleton ULDatabaseManager class object.
Public instance constructors
Member | Description
ULConnection constructor | Initializes a ULConnection object. The connection must be opened before you can perform any operations against the database.
ULConnection constructor | Initializes a ULConnection object with the specified connection string. The connection must be opened before you can perform any operations against the database.
Public instance properties
Member | Description
ConnectionString property | Specifies the parameters to use for opening a connection to an UltraLite.NET database. The connection string can be supplied using a ULConnectionParms class object.
ConnectionTimeout property | This feature is not supported by UltraLite.NET.
Database property | Returns the name of the database that the connection will be opened to.
DatabaseID property | UL Ext.: Specifies the Database ID value to be used for global autoincrement columns.
GlobalAutoIncrementUsage property | UL Ext.: Returns the percentage of available global autoincrement values that have been used.
LastIdentity property | UL Ext.: Returns the most recent identity value used.
Schema property | UL Ext.: Provides access to the schema of the current database associated with this connection.
State property | Returns the current state of the connection.
SyncParms property | UL Ext.: Specifies the synchronization settings for this connection.
SyncResult property | UL Ext.: Returns the results of the last synchronization for this connection.
Public instance methods
Member | Description
BeginTransaction method | Returns a transaction object. Commands associated with a transaction object are executed as a single transaction. The transaction is terminated with a Commit method or Rollback method.
BeginTransaction method | Returns a transaction object with the specified isolation level. Commands associated with a transaction object are executed as a single transaction. The transaction is terminated with a Commit method or Rollback method.
ChangeDatabase method | Changes the current database for an open ULConnection.
ChangeEncryptionKey method | UL Ext.: Changes the database's encryption key to the specified new key.
Close method | Closes the database connection.
CountUploadRows method | UL Ext.: Returns the number of rows that need to be uploaded when the next synchronization takes place.
CountUploadRows method | UL Ext.: Returns the number of rows that need to be uploaded when the next synchronization takes place.
CreateCommand method | Creates and initializes a ULCommand class object associated with this connection and its current transaction. You can use the properties of the ULCommand to control its behavior.
ExecuteTable method | UL Ext.: Retrieves in a ULTable class a database table for direct manipulation. The table is opened (sorted) using the table's primary key.
ExecuteTable method | UL Ext.: Retrieves in a ULTable class a database table for direct manipulation. The table is opened (sorted) using the specified index.
ExecuteTable method | UL Ext.: Retrieves, with the specified command behavior, a database table for direct manipulation. The table is opened (sorted) using the specified index.
GetLastDownloadTime method | UL Ext.: Returns the time of the most recent download of the specified publication.
GetNewUUID method | UL Ext.: Generates a new UUID (Guid).
GrantConnectTo method | UL Ext.: Grants access to an UltraLite database for a user ID with a specified password.
Open method | Opens a connection to a database using the previously-specified connection string.
OpenWithCreate method | UL Ext.: Opens a connection to a database using the previously-specified connection string. If the database does not exist, a new database is created.
ResetLastDownloadTime method | UL Ext.: Resets the time of the most recent download.
RevokeConnectFrom method | UL Ext.: Revokes access to an UltraLite database from the specified user ID.
RollbackPartialDownload method | UL Ext.: Rolls back outstanding changes to the database from a partial download.
StartSynchronizationDelete method | UL Ext.: Marks all subsequent deletes made by this connection for synchronization.
StopSynchronizationDelete method | UL Ext.: Prevents delete operations from being synchronized.
Synchronize method | UL Ext.: Synchronize the database using the current SyncParms property.
Synchronize method | UL Ext.: Synchronize the database using the current SyncParms property with progress events posted to the specified listener.
Public instance events
Member | Description
InfoMessage event | Occurs when UltraLite.NET sends a warning or an informational message on this connection.
StateChange event | Occurs when this connection changes state.
Protected instance methods
Member | Description
Dispose method | Releases the unmanaged resources used by the ULCommand class and optionally releases the managed resources.
Finalize method | Releases unmanaged resources and performs other cleanup operations before the ULConnection is reclaimed by garbage collection.


ULConnection constructor

Initializes a ULConnection object. The connection must be opened before you can perform any operations against the database.

Prototypes

' Visual Basic
Overloads Public Sub New()

// C#
public ULConnection();

Remarks

To use the UltraLite Engine runtime of UltraLite.NET, set RuntimeType property to the appropriate value before using any other UltraLite.NET API.

The ULConnection object needs to have the ConnectionString property property set before it can be opened.

See also
  • ULConnection class
  • ULConnection members
  • Open method
  • OpenWithCreate method
  • ULConnection constructor


ULConnection constructor

Initializes a ULConnection object with the specified connection string. The connection must be opened before you can perform any operations against the database.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal connectionString As String _
)

// C#
public ULConnection(
string connectionString
);

Parameters

  • connectionString An UltraLite.NET connection string. A connection string is a semicolon-separated list of keyword-value pairs.

    For a list of parameters, see the ConnectionString property property.

Remarks

To use the UltraLite Engine runtime of UltraLite.NET, set RuntimeType property to the appropriate value before using any other UltraLite.NET API.

The connection string can be supplied using a ULConnectionParms class object.

Exceptions

  • ArgumentException - The supplied connection string is invalid.

Example

The following code creates and opens a connection to the existing database \UltraLite\MyDatabase.udb on a Windows CE device.

' Visual Basic
Dim openParms As ULConnectionParms = New ULConnectionParms
openParms.DatabaseOnCE = "\UltraLite\MyDatabase.udb"
Dim conn As ULConnection = _
  New ULConnection( openParms.ToString() )
conn.Open()

// C#
ULConnectionParms openParms = new ULConnectionParms();
openParms.DatabaseOnCE = @"\UltraLite\MyDatabase.udb";
ULConnection conn = new ULConnection( openParms.ToString() );
conn.Open();
See also
  • ULConnection class
  • ULConnection members
  • Open method
  • OpenWithCreate method
  • ULConnection constructor


INVALID_DATABASE_ID field

UL Ext.: A database ID constant indicating that the DatabaseID property has not been set.

Prototypes

' Visual Basic
Public Shared INVALID_DATABASE_ID As Long

// C#
public const long INVALID_DATABASE_ID;


ConnectionString property

Specifies the parameters to use for opening a connection to an UltraLite.NET database. The connection string can be supplied using a ULConnectionParms class object.

Prototypes

' Visual Basic
NotOverridable Public Property ConnectionString As String _
Implements IDbConnection.ConnectionString

// C#
public string ConnectionString {get;set;}

Property value

The parameters used to open this connection in the form of a semicolon-separated list of keyword-value pairs. The default is an empty string (an invalid connection string).

Remarks

UL Ext.: The parameters used by UltraLite.NET are specific to UltraLite databases and therefore the connection string is not compatible with Adaptive Server Anywhere connection strings. For a list of parameters, see Connection Parameters.

Exceptions

  • ArgumentException - The supplied connection string is invalid.

  • InvalidOperationException - The value cannot be set while the connection is open.

Implements

IDbConnection.ConnectionString

Example

The following code creates and opens a connection to the existing database \UltraLite\MyDatabase.udb on a Windows CE device.

' Visual Basic
Dim openParms As ULConnectionParms = New ULConnectionParms
openParms.DatabaseOnCE = "\UltraLite\MyDatabase.udb"
Dim conn As ULConnection = New ULConnection
conn.ConnectionString = openParms.ToString()
conn.Open()

// C#
ULConnectionParms openParms = new ULConnectionParms();
openParms.DatabaseOnCE = @"\UltraLite\MyDatabase.udb";
ULConnection conn = new ULConnection();
conn.ConnectionString = openParms.ToString();
conn.Open();
See also
  • ULConnection class
  • ULConnection members
  • Open method
  • OpenWithCreate method


ConnectionTimeout property

This feature is not supported by UltraLite.NET.

Prototypes

' Visual Basic
NotOverridable Public Readonly Property ConnectionTimeout As Integer _
Implements IDbConnection.ConnectionTimeout

// C#
public int ConnectionTimeout {get;}

Property value

The value is always zero.

Exceptions

  • ULException class - Setting the value is not supported in UltraLite.NET.

Implements

IDbConnection.ConnectionTimeout


Database property

Returns the name of the database that the connection will be opened to.

Prototypes

' Visual Basic
NotOverridable Public Readonly Property Database As String _
Implements IDbConnection.Database

// C#
public string Database {get;}

Property value

A string containing the name of the database.

Remarks

On Windows CE devices, ULConnection looks in the connection string in the following order: dbn, ce_file.

On desktop machines, ULConnection looks in the connection string in the following order: dbn, nt_file.

Implements

IDbConnection.Database


DatabaseID property

UL Ext.: Specifies the Database ID value to be used for global autoincrement columns.

Prototypes

' Visual Basic
Public Property DatabaseID As Long

// C#
public long DatabaseID {get;set;}

Property value

The Database ID value of the current database.

Remarks

The database ID value must be in the range [0,UInt32.MaxValue]. A value of INVALID_DATABASE_ID field is used to indicate that the database ID has not been set for the current database.

Exceptions

  • ULException class - The specified new database ID is invalid.


DatabaseManager property

UL Ext.: Provides access to the singleton ULDatabaseManager class object.

Prototypes

' Visual Basic
Public Shared Readonly Property DatabaseManager As ULDatabaseManager

// C#
public const ULDatabaseManager DatabaseManager {get;}

Property value

A reference to the singleton ULDatabaseManager class object.


GlobalAutoIncrementUsage property

UL Ext.: Returns the percentage of available global autoincrement values that have been used.

Prototypes

' Visual Basic
Public Readonly Property GlobalAutoIncrementUsage As Short

// C#
public short GlobalAutoIncrementUsage {get;}

Property value

The percentage of available global autoincrement values that have been used. It is an integer in the range [0-100], inclusive.

Remarks

If the percentage approaches 100, your application should set a new value for the global database ID using DatabaseID property.

Exceptions

  • ULException class - A SQL error occurred.


LastIdentity property

UL Ext.: Returns the most recent identity value used.

Prototypes

' Visual Basic
Public Readonly Property LastIdentity As UInt64

// C#
public ulong LastIdentity {get;}

Property value

The most recently-used identity value as an unsigned long.

Remarks

The most recent identity value used. This property is equivalent to the Adaptive Server Anywhere SQL statement:

SELECT @@identity

LastIdentity is particularly useful in the context of global autoincrement columns.

Since this property only allows you to determine the most recently assigned default value, you should retrieve this value soon after executing the insert statement to avoid spurious results.

Occasionally, a single insert statement may include more than one column of type global autoincrement. In this case, LastIdentity is one of the generated default values, but there is no reliable means to determine which column the value is from. For this reason, you should design your database and write your insert statements so as to avoid this situation.

Exceptions

  • ULException class - A SQL error occurred.


Schema property

UL Ext.: Provides access to the schema of the current database associated with this connection.

Prototypes

' Visual Basic
Public Readonly Property Schema As ULDatabaseSchema

// C#
public ULDatabaseSchema Schema {get;}

Property value

A reference to the ULDatabaseSchema class object representing the schema of the database that this connection is opened on.

Remarks

This property is only valid while its connection is open.


State property

Returns the current state of the connection.

Prototypes

' Visual Basic
NotOverridable Public Readonly Property State As ConnectionState _
Implements IDbConnection.State

// C#
public ConnectionState State {get;}

Property value

ConnectionState.Open if the connection is open, ConnectionState.Closed if the connection is closed.

Implements

IDbConnection.State

See also
  • ULConnection class
  • ULConnection members
  • StateChange event


SyncParms property

UL Ext.: Specifies the synchronization settings for this connection.

Prototypes

' Visual Basic
Public Readonly Property SyncParms As ULSyncParms

// C#
public ULSyncParms SyncParms {get;}

Property value

A reference to the parameters used for synchronization by this connection. Modifications to the parameters affect the next synchronization made over this connection.

See also
  • ULConnection class
  • ULConnection members
  • Synchronize method
  • SyncResult property


SyncResult property

UL Ext.: Returns the results of the last synchronization for this connection.

Prototypes

' Visual Basic
Public Readonly Property SyncResult As ULSyncResult

// C#
public ULSyncResult SyncResult {get;}

Property value

A reference to the results of the last synchronization for this connection.

See also
  • ULConnection class
  • ULConnection members
  • Synchronize method
  • SyncParms property


BeginTransaction method

Returns a transaction object. Commands associated with a transaction object are executed as a single transaction. The transaction is terminated with a Commit method or Rollback method.

Prototypes

' Visual Basic
Overloads Public Function BeginTransaction() As ULTransaction

// C#
public ULTransaction BeginTransaction();

Return value

A ULTransaction class object representing the new transaction.

Remarks

To associate a command with a transaction object, use the Transaction property property. The current transaction is automatically associated to commands created by CreateCommand method.

By default, the connection does not use transactions and all commands are automatically committed as they are executed. Once the current transaction is committed or rolled back, the connection reverts to auto commit mode until the next call to BeginTransaction.

This is the strongly typed version of IDbConnection.BeginTransaction.

Exceptions

  • ULException class - The connection is closed.

  • InvalidOperationException - ULConnection does not support parallel transactions.

See also
  • ULConnection class
  • ULConnection members
  • BeginTransaction method


BeginTransaction method

Returns a transaction object with the specified isolation level. Commands associated with a transaction object are executed as a single transaction. The transaction is terminated with a Commit method or Rollback method.

Prototypes

' Visual Basic
Overloads Public Function BeginTransaction( _
ByVal isolationLevel As IsolationLevel _
) As ULTransaction

// C#
public ULTransaction BeginTransaction(
IsolationLevel isolationLevel
);

Parameters

  • isolationLevel The required isolation level for the transaction. UltraLite.NET only supports IsolationLevel.ReadUncommitted.

Return value

A ULTransaction class object representing the new transaction.

Remarks

To associate a command with a transaction object, use the Transaction property property. The current transaction is automatically associated to commands created by CreateCommand method.

By default, the connection does not use transactions and all commands are automatically committed as they are executed. Once the current transaction is committed or rolled back, the connection reverts to auto commit mode until the next call to BeginTransaction.

This is the strongly typed version of IDbConnection.BeginTransaction.

Exceptions

  • ULException class - The connection is closed or an unsupported isolation level was specified.

  • InvalidOperationException - ULConnection does not support parallel transactions.

See also
  • ULConnection class
  • ULConnection members
  • BeginTransaction method


ChangeDatabase method

Changes the current database for an open ULConnection.

Prototypes

' Visual Basic
NotOverridable Public Sub ChangeDatabase( _
ByVal connectionString As String _
) _
Implements IDbConnection.ChangeDatabase

// C#
public void ChangeDatabase(
string connectionString
);

Parameters

  • connectionString A complete connection string to open the connection to a new database.

Remarks

The connection to the current database is closed even if there are parameter errors.

UL Ext.: connectionString is a full connection string, not a dbn or dbf.

Implements

IDbConnection.ChangeDatabase

See also
  • ULConnection class
  • ULConnection members
  • ConnectionString property


ChangeEncryptionKey method

UL Ext.: Changes the database's encryption key to the specified new key.

Prototypes

' Visual Basic
Public Sub ChangeEncryptionKey( _
ByVal newKey As String _
)

// C#
public void ChangeEncryptionKey(
string newKey
);

Parameters

  • newKey The new encryption key for the database.

Remarks

If the encryption key is lost, it is not possible to open the database.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULConnection class
  • ULConnection members
  • EncryptionKey property


Close method

Closes the database connection.

Prototypes

' Visual Basic
NotOverridable Public Sub Close() _
Implements IDbConnection.Close

// C#
public void Close();

Remarks

The Close method rolls back any pending transactions and then closes the connection. An application can call Close multiple times.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDbConnection.Close


CountUploadRows method

UL Ext.: Returns the number of rows that need to be uploaded when the next synchronization takes place.

Prototypes

' Visual Basic
Overloads Public Function CountUploadRows( _
ByVal mask As Integer, _
ByVal threshold As UInt32 _
) As UInt32

// C#
public uint CountUploadRows(
int mask,
uint threshold
);

Parameters

  • mask The set of publications to check for rows. See the ULPublicationSchema class class for more information.

  • threshold The maximum number of rows to count, limiting the amount of time taken by CountUploadRows. A value of 0 corresponds to the maximum limit. A value of 1 determines if any rows need to be synchronized.

Return value

The number of rows that need to be uploaded from the specified publication(s).

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULConnection class
  • ULConnection members
  • CountUploadRows method


CountUploadRows method

UL Ext.: Returns the number of rows that need to be uploaded when the next synchronization takes place.

Prototypes

' Visual Basic
Overloads Public Function CountUploadRows( _
ByVal mask As Integer, _
ByVal threshold As Long _
) As Long

// C#
public long CountUploadRows(
int mask,
long threshold
);

Parameters

  • mask The set of publications to check for rows. See the ULPublicationSchema class class for more information.

  • threshold The maximum number of rows to count, limiting the amount of time taken by CountUploadRows. A value of 0 corresponds to the maximum limit. A value of 1 determines if any rows need to be synchronized. The threshold value must be in the range [0,0x0ffffffff].

Return value

The number of rows that need to be uploaded from the specified publication(s).

Remarks

This method is provided for languages that do not support the System.UInt32 type natively. Use the other form of this method if your application supports it.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULConnection class
  • ULConnection members
  • CountUploadRows method


CreateCommand method

Creates and initializes a ULCommand class object associated with this connection and its current transaction. You can use the properties of the ULCommand to control its behavior.

Prototypes

' Visual Basic
Public Function CreateCommand() As ULCommand

// C#
public ULCommand CreateCommand();

Return value

A new ULCommand class object.

Remarks

You must set the CommandText property property before the command can be executed.

This is the strongly typed version of IDbConnection.CreateCommand.


Dispose method

Releases the unmanaged resources used by the ULCommand class and optionally releases the managed resources.

Prototypes

' Visual Basic
Overloads Overrides Protected Sub Dispose( _
ByVal disposing As Boolean _
)

// C#
protected override void Dispose(
bool disposing
);

Parameters

  • disposing When true, dispose of both managed and unmanaged resources. When false, dispose of only the unmanaged resources.


ExecuteTable method

UL Ext.: Retrieves in a ULTable class a database table for direct manipulation. The table is opened (sorted) using the table's primary key.

Prototypes

' Visual Basic
Overloads Public Function ExecuteTable( _
ByVal tableName As String _
) As ULTable

// C#
public ULTable ExecuteTable(
string tableName
);

Parameters

  • tableName The name of the table to open.

Return value

The table as a ULTable class object.

Remarks

This method is a shortcut for the ExecuteTable method method that does not require a ULCommand class instance. It is provided to help users porting from earlier versions of UltraLite.NET (it replaces iAnywhere.UltraLite.Connection.GetTable() and iAnywhere.UltraLite.Table.Open()).

Exceptions

  • ULException class - A SQL error occurred.

  • InvalidOperationException - The tableName is invalid.

Example

The following code opens the table named MyTable using the table's primary key. It assumes an open ULConnection instance called conn.

' Visual Basic
Dim t As ULTable = conn.ExecuteTable("MyTable")
' The line above is equivalent to
' Dim cmd As ULCommand = conn.CreateCommand()
' cmd.CommandText = "MyTable"
' cmd.CommandType = CommandType.TableDirect
' Dim t As ULTable = cmd.ExecuteTable()
' cmd.Dispose()
// C#
ULTable t = conn.ExecuteTable("MyTable");
// The line above is equivalent to
// ULTable t;
// using(ULCommand cmd = conn.CreateCommand())
// {
//     cmd.CommandText = "MyTable";
//     cmd.CommandType = CommandType.TableDirect;
//     t = cmd.ExecuteTable();
// }
See also
  • ULConnection class
  • ULConnection members
  • ExecuteTable method
  • ExecuteTable method


ExecuteTable method

UL Ext.: Retrieves in a ULTable class a database table for direct manipulation. The table is opened (sorted) using the specified index.

Prototypes

' Visual Basic
Overloads Public Function ExecuteTable( _
ByVal tableName As String, _
ByVal indexName As String _
) As ULTable

// C#
public ULTable ExecuteTable(
string tableName,
string indexName
);

Parameters

  • tableName The name of the table to open.

  • indexName The name of the index to open (sort) the table with.

Return value

The table as a ULTable class object.

Remarks

This method is a shortcut for the ExecuteTable method method that does not require a ULCommand class instance. It is provided to help users porting from earlier versions of UltraLite.NET (it replaces iAnywhere.UltraLite.Connection.GetTable() and iAnywhere.UltraLite.Table.Open()).

Exceptions

  • ULException class - A SQL error occurred.

  • InvalidOperationException - The tableName is invalid.

Example

The following code opens the table named MyTable using the index named MyIndex. It assumes an open ULConnection instance called conn.

' Visual Basic
Dim t As ULTable = conn.ExecuteTable("MyTable", "MyIndex")
' The line above is equivalent to
' Dim cmd As ULCommand = conn.CreateCommand()
' cmd.CommandText = "MyTable"
' cmd.IndexName = "MyIndex"
' cmd.CommandType = CommandType.TableDirect
' Dim t As ULTable = cmd.ExecuteTable()
' cmd.Dispose()
// C#
ULTable t = conn.ExecuteTable("MyTable", "MyIndex");
// The line above is equivalent to
// ULTable t;
// using(ULCommand cmd = conn.CreateCommand())
// {
//     cmd.CommandText = "MyTable";
//     cmd.IndexName = "MyIndex";
//     cmd.CommandType = CommandType.TableDirect;
//     t = cmd.ExecuteTable();
// }
See also
  • ULConnection class
  • ULConnection members
  • ExecuteTable method
  • ExecuteTable method


ExecuteTable method

UL Ext.: Retrieves, with the specified command behavior, a database table for direct manipulation. The table is opened (sorted) using the specified index.

Prototypes

' Visual Basic
Overloads Public Function ExecuteTable( _
ByVal tableName As String, _
ByVal indexName As String, _
ByVal cmdBehavior As CommandBehavior _
) As ULTable

// C#
public ULTable ExecuteTable(
string tableName,
string indexName,
CommandBehavior cmdBehavior
);

Parameters

  • tableName The name of the table to open.

  • indexName The name of the index to open (sort) the table with.

  • cmdBehavior A bitwise combination of CommandBehavior flags describing the results of the query and its effect on the connection. UltraLite.NET respects only the CommandBehavior.Default, CommandBehavior.CloseConnection, and CommandBehavior.SchemaOnly flags.

Return value

The table as a ULTable class object.

Remarks

This method is a shortcut for the ExecuteTable method method that does not require a ULCommand class instance. It is provided to help users porting from earlier versions of UltraLite.NET (it replaces iAnywhere.UltraLite.Connection.GetTable() and iAnywhere.UltraLite.Table.Open()).

Exceptions

  • ULException class - A SQL error occurred.

  • InvalidOperationException - The tableName is invalid.

Example

The following code opens the table named MyTable using the index named MyIndex. It assumes an open ULConnection instance called conn.

' Visual Basic
Dim t As ULTable = conn.ExecuteTable( _
    "MyTable", "MyIndex", CommandBehavior.Default _
  )
' The line above is equivalent to
' Dim cmd As ULCommand = conn.CreateCommand()
' cmd.CommandText = "MyTable"
' cmd.IndexName = "MyIndex"
' cmd.CommandType = CommandType.TableDirect
' Dim t As ULTable = cmd.ExecuteTable(CommandBehavior.Default)
' cmd.Dispose()
// C#
ULTable t = conn.ExecuteTable(
    "MyTable", "MyIndex", CommandBehavior.Default
  );
// The line above is equivalent to
// ULTable t;
// using(ULCommand cmd = conn.CreateCommand())
// {
//     cmd.CommandText = "MyTable";
//     cmd.IndexName = "MyIndex";
//     cmd.CommandType = CommandType.TableDirect;
//     t = cmd.ExecuteTable(CommandBehavior.Default);
// }
See also
  • ULConnection class
  • ULConnection members
  • ExecuteTable method
  • ExecuteTable method


Finalize method

Releases unmanaged resources and performs other cleanup operations before the ULConnection is reclaimed by garbage collection.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


GetLastDownloadTime method

UL Ext.: Returns the time of the most recent download of the specified publication.

Prototypes

' Visual Basic
Public Function GetLastDownloadTime( _
ByVal mask As Integer _
) As Date

// C#
public DateTime GetLastDownloadTime(
int mask
);

Parameters

  • mask The mask of the publication to check. See the ULPublicationSchema class class for more information.

Return value

The timestamp of the last download.

Remarks

The parameter mask must reference a single publication or be the special constant SYNC_ALL_DB field for the time of the last download of the full database.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULConnection class
  • ULConnection members
  • ResetLastDownloadTime method


GetNewUUID method

UL Ext.: Generates a new UUID (Guid).

Prototypes

' Visual Basic
Public Function GetNewUUID() As Guid

// C#
public Guid GetNewUUID();

Return value

A new UUID as a Guid.

Remarks

This method is provided here as it is not included in the .NET Compact Framework.

Exceptions

  • ULException class - A SQL error occurred.


GrantConnectTo method

UL Ext.: Grants access to an UltraLite database for a user ID with a specified password.

Prototypes

' Visual Basic
Public Sub GrantConnectTo( _
ByVal uid As String, _
ByVal pwd As String _
)

// C#
public void GrantConnectTo(
string uid,
string pwd
);

Parameters

  • uid The user ID to receive access to the database. The maximum length of the user ID is 16 characters.

  • pwd The password to be associated with the user ID. The maximum length is 16 characters.

Remarks

If an existing user ID is specified, this function updates the password for the user. UltraLite supports a maximum of 4 users. This method is enabled only if user authentication was enabled when the connection was opened.

See also
  • ULConnection class
  • ULConnection members
  • UserID property
  • Password property
  • ConnectionString property


Open method

Opens a connection to a database using the previously-specified connection string.

Prototypes

' Visual Basic
NotOverridable Public Sub Open() _
Implements IDbConnection.Open

// C#
public void Open();

Remarks

You should explicitly close or dispose of the connection when you are done with it.

Exceptions

  • ULException class - A SQL error occurred while attempting to open the database.

  • InvalidOperationException - The connection is already open or the connection string is not specified in the ConnectionString property property.

Implements

IDbConnection.Open

See also
  • ULConnection class
  • ULConnection members
  • ConnectionString property
  • OpenWithCreate method
  • State property


OpenWithCreate method

UL Ext.: Opens a connection to a database using the previously-specified connection string. If the database does not exist, a new database is created.

Prototypes

' Visual Basic
Public Sub OpenWithCreate()

// C#
public void OpenWithCreate();

Remarks

To create a new database, the connection string must contain the location of the new database's schema file.

You should explicitly close or dispose of the connection when you are done with it.

Exceptions

  • ULException class - A SQL error occurred while attempting to open or create the database.

  • InvalidOperationException - The connection is already open or the connection string is not specified in the ConnectionString property property.

See also
  • ULConnection class
  • ULConnection members
  • ConnectionString property
  • SchemaOnCE property
  • SchemaOnDesktop property
  • Open method
  • State property
  • DropDatabase method


ResetLastDownloadTime method

UL Ext.: Resets the time of the most recent download.

Prototypes

' Visual Basic
Public Sub ResetLastDownloadTime( _
ByVal mask As Integer _
)

// C#
public void ResetLastDownloadTime(
int mask
);

Parameters

  • mask The set of publications to reset. See ULPublicationSchema class class for more information.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULConnection class
  • ULConnection members
  • GetLastDownloadTime method


RevokeConnectFrom method

UL Ext.: Revokes access to an UltraLite database from the specified user ID.

Prototypes

' Visual Basic
Public Sub RevokeConnectFrom( _
ByVal uid As String _
)

// C#
public void RevokeConnectFrom(
string uid
);

Parameters

  • uid The user ID whose access to the database is being revoked.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULConnection class
  • ULConnection members
  • GrantConnectTo method


RollbackPartialDownload method

UL Ext.: Rolls back outstanding changes to the database from a partial download.

Prototypes

' Visual Basic
Public Sub RollbackPartialDownload()

// C#
public void RollbackPartialDownload();

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULConnection class
  • ULConnection members
  • KeepPartialDownload property
  • ResumePartialDownload property


StartSynchronizationDelete method

UL Ext.: Marks all subsequent deletes made by this connection for synchronization.

Prototypes

' Visual Basic
Public Sub StartSynchronizationDelete()

// C#
public void StartSynchronizationDelete();

Remarks

Once this function is called, all delete operations are again synchronized, causing the rows deleted from the UltraLite database to be removed from the consolidated database as well.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULConnection class
  • ULConnection members
  • StopSynchronizationDelete method
  • Truncate method


StopSynchronizationDelete method

UL Ext.: Prevents delete operations from being synchronized.

Prototypes

' Visual Basic
Public Sub StopSynchronizationDelete()

// C#
public void StopSynchronizationDelete();

Remarks

This method is useful for deleting old information on an UltraLite database to save space, while not deleting this information on the consolidated database.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULConnection class
  • ULConnection members
  • StartSynchronizationDelete method


Synchronize method

UL Ext.: Synchronize the database using the current SyncParms property.

Prototypes

' Visual Basic
Overloads Public Sub Synchronize()

// C#
public void Synchronize();

Remarks

A detailed result status is reported in this connection's SyncResult property property.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULConnection class
  • ULConnection members
  • Synchronize method


Synchronize method

UL Ext.: Synchronize the database using the current SyncParms property with progress events posted to the specified listener.

Prototypes

' Visual Basic
Overloads Public Sub Synchronize( _
ByVal listener As ULSyncProgressListener _
)

// C#
public void Synchronize(
ULSyncProgressListener listener
);

Parameters

  • listener The object that will receive synchronization progress events.

Remarks

The last event posted to the listener will have a state of ULSyncProgressState enumeration.

Errors during synchronization will be posted as ULSyncProgressState enumeration events and then thrown as ULException classs.

A detailed result status will be reported in this connection's SyncResult property property.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULConnection class
  • ULConnection members
  • ULSyncProgressListener interface
  • Synchronize method


InfoMessage event

Occurs when UltraLite.NET sends a warning or an informational message on this connection.

Prototypes

' Visual Basic
Public Event InfoMessage As ULInfoMessageEventHandler

// C#
public event ULInfoMessageEventHandler InfoMessage;

Remarks

To process UltraLite.NET warnings or informational messages, you must create a ULInfoMessageEventHandler delegate delegate and attach it to this event.

Example

The following code defines an informational message event handler.

' Visual Basic
Private Sub MyInfoMessageHandler( _
      obj As Object, args As ULInfoMessageEventArgs _
    )
  System.Console.WriteLine( _
      "InfoMesageHandler: " + args.NativeError + ", " _
      + args.Message _
    )
End Sub

// C#
private void MyInfoMessageHandler(
      object obj, ULInfoMessageEventArgs args
    )
{
  System.Console.WriteLine(
      "InfoMesageHandler: " + args.NativeError + ", "
      + args.Message
    );
}

The following code adds the MyInfoMessageHandler to the connection named conn.

' Visual Basic
AddHandler conn.InfoMessage, AddressOf MyInfoMessageHandler

// C#
conn.InfoMessage +=
  new ULInfoMessageEventHandler(MyInfoMessageHandler);


StateChange event

Occurs when this connection changes state.

Prototypes

' Visual Basic
Public Event StateChange As StateChangeEventHandler

// C#
public event StateChangeEventHandler StateChange;

Remarks

To process state change messages, you must create a StateChangeEventHandler delegate and attach it to this event.

Example

The following code defines a state change event handler.

' Visual Basic
Private Sub MyStateHandler( _
      obj As Object, args As StateChangeEventArgs _
    )
  System.Console.WriteLine( _
      "StateHandler: " + args.OriginalState + " to " _
      + args.CurrentState _
    )
End Sub

// C#
private void MyStateHandler(
      object obj, StateChangeEventArgs args
    )
{
  System.Console.WriteLine(
      "StateHandler: " + args.OriginalState + " to "
      + args.CurrentState
    );
}

The following code adds the MyStateHandler to the connection named conn.

' Visual Basic
AddHandler conn.StateChange, AddressOf MyStateHandler

// C#
conn.StateChange += new StateChangeEventHandler(MyStateHandler);


ULConnectionParms class

UL Ext.: Builds a connection string for opening a connection to an UltraLite database. The frequently-used connection parameters are individual properties on the ULConnectionParms object.

Prototypes

' Visual Basic
Public Class ULConnectionParms
Inherits Component

// C#
public class ULConnectionParms :
Component

Remarks

A ULConnectionParms object is used to specify the parameters for opening a connection (Open method), creating a database (OpenWithCreate method), dropping a database (DropDatabase method), or specifying a schema file (ApplyFile method).

Leading and trailing spaces are ignored and values must not contain semicolons (;), parentheses (), or curly braces {}. For future compatibility it is strongly recommended that values do not contain single (') or double (") quotes.

When building a connection string, you need to identify the database, specify any optional connection settings, and specify the database schema file if you wish to create the database with OpenWithCreate method. Once you have supplied all the connection parameters by setting the appropriate properties on a ULConnectionParms object, you create a connection string using the ToString method method. The resulting string is used to create a new ULConnection class with the ULConnection constructor constructor or set the ConnectionString property property of an existing ULConnection class object.

Identifying the database

Each instance contains platform-specific paths to the database. Only the value corresponding to the executing platform is used. For example, in the code below the path \UltraLite\mydb1.udb would be used on Windows CE, while mydb2.db would be used on other platforms.

' Visual Basic
Dim dbName As ULConnectionParms = new ULConnectionParms
dbName.DatabaseOnCE = "\UltraLite\mydb1.udb"
dbName.DatabaseOnDesktop = "mydb2.udb"

// C#
ULConnectionParms dbName = new ULConnectionParms();
dbName.DatabaseOnCE = "\\UltraLite\\mydb1.udb";
dbName.DatabaseOnDesktop = "mydb2.udb";

The recommended extension for UltraLite database files is .udb. On Windows CE devices, the default database is \UltraLiteDB\ulstore.udb. On other Windows platforms, the default database is ulstore.udb. In C#, you must escape any backslash characters in paths or use @-quoted string literals.

If you are using multiple databases, you should specify a database name for each database. See the AdditionalParms property property for more information.

Optional connection settings

Depending on your application's needs and how the database was created, you may need to supply a non-default UserID property and Password property, a database EncryptionKey property, and the connection CacheSize property. If your application is using multiple connections, you should provide a unique ConnectionName property for each connection.

Databases are created with a single authenticated user, DBA, whose initial password is SQL. By default, connections are opened using the user ID DBA and password SQL. To disable the default user, use the RevokeConnectFrom method method. To add a user or change a user's password, use the GrantConnectTo method method.

If an encryption key was supplied when the database was created, all subsequent connections to the database must use the same encryption key. To change a database's encryption key, use the ChangeEncryptionKey method method.

Identifying the schema

When creating a database, you must supply a schema. The path to the schema file is specified using the platform-specific properties SchemaOnCE property and SchemaOnDesktop property. Only the value corresponding to the executing platform is used.

For more information, see Connection Parameters.

ULConnectionParms members
ULConnectionParms constructor
AdditionalParms property
CacheSize property
ConnectionName property
DatabaseOnCE property
DatabaseOnDesktop property
EncryptionKey property
Password property
SchemaOnCE property
SchemaOnDesktop property
UserID property
ToString method
UnusedEvent event


ULConnectionParms members

Public instance constructors
Member | Description
ULConnectionParms constructor | Initializes a ULConnectionParms instance with its default values.
Public instance properties
Member | Description
AdditionalParms property | Specifies additional parameters as a semicolon-separated list of name=value pairs. These are less commonly used parameters.
CacheSize property | Specifies the size of the cache.
ConnectionName property | Specifies a name for the connection. This is only needed if you create more than one connection to the database.
DatabaseOnCE property | Specifies the path and filename of the UltraLite database on Windows CE.
DatabaseOnDesktop property | Specifies the path and filename of the UltraLite database on Windows desktop platforms.
EncryptionKey property | Specifies a key for encrypting the database.
Password property | Specifies the password for the authenticated user.
SchemaOnCE property | Specifies the path and filename of the UltraLite schema on Windows CE.
SchemaOnDesktop property | Specifies the path and filename of the UltraLite schema on Windows desktop platforms.
UserID property | Specifies an authenticated user for the database.
Public instance methods
Member | Description
ToString method | Returns the string representation of this instance.
Public instance events
Member | Description
UnusedEvent event | Unused.


ULConnectionParms constructor

Initializes a ULConnectionParms instance with its default values.

Prototypes

' Visual Basic
Public Sub New()

// C#
public ULConnectionParms();


AdditionalParms property

Specifies additional parameters as a semicolon-separated list of name=value pairs. These are less commonly used parameters.

Prototypes

' Visual Basic
Public Property AdditionalParms As String

// C#
public string AdditionalParms {get;set;}

Property value

A semicolon-separated list of keyword=value additional parameters. The default is a null reference (Nothing in Visual Basic).

Remarks

The values for the page size and reserve size parameters are specified in units of bytes. Use the suffix k or K to indicate units of kilobytes and the suffix m or M to indicate megabytes.

Additional parameters are:

Keyword Description
dbn Identifies a loaded database to which a connection needs to be made.

When a database is started, it is assigned a database name, either explicitly with the dbn parameter, or by UltraLite using the base of the filename with the extension and path removed.

When opening connections, UltraLite first searches for a running database with a matching dbn. If one is not found, UltraLite starts a new database using the appropriate database filename parameter (DatabaseOnCE property or DatabaseOnDesktop property).

This parameter is required if the application (or UltraLite engine) needs to access two different databases that have the same base filename.

This parameter is only used when opening a connection with Open method or OpenWithCreate method.
obfuscate When set to one (1), specifies that the database is to be created with obfuscation. For example:
 createParms.AdditionalParms = "obfuscate=1"
Obfuscation provides security against straightforward attempts to view data in the database directly using a viewing tool. It is not proof against skilled and determined attempts to gain access to the data. Obfuscation has little or no performance impact.

This parameter is only used when creating a new database with OpenWithCreate method.

page_size UltraLite databases are stored in pages. I/O operations are carried out one page at a time. The default page size for UltraLite databases is 4 KB. You can specify 2 KB pages using the following storage parameters string:
 connParms.AdditionalParms = "page_size=2k"
Setting a page size of 2 KB reduces the maximum number of tables to approximately 500.

This parameter is only used when creating a new database with OpenWithCreate method.
reserve_size Reserves file system space for storage of UltraLite persistent data.

The reserve_size parameter allows you to pre-allocate the file system space required for your UltraLite database without inserting any data. Reserving file system space can improve performance slightly and also prevent out of memory failures. By default, the persistent storage file only grows when required as the application updates the database.

Note that reserve_size reserves file system space, which includes the metadata in the persistent store file, and not just the raw data. The metadata overhead, as well as data compression, must be considered when deriving the required file system space from the amount of database data. Running the database with test data and observing the persistent store file size is recommended.

The reserve_size parameter reserves space by growing the persistent store file to the given reserve size on startup, regardless of whether the file previously existed. The file is never truncated.

The following parameter string ensures that the persistent store file is at least 2 MB upon startup.

 createParms.AdditionalParms = "reserve_size=2m"
This parameter is only used when opening a connection with Open method or OpenWithCreate method.
Exceptions

  • ArgumentException - The value contained parentheses () or curly braces {}.


CacheSize property

Specifies the size of the cache.

Prototypes

' Visual Basic
Public Property CacheSize As String

// C#
public string CacheSize {get;set;}

Property value

A string specifying the cache size. The default is a null reference (Nothing in Visual Basic) meaning the default of 16 pages is used.

Remarks

The values for the cache size are specified in units of bytes. Use the suffix k or K to indicate units of kilobytes and the suffix of m or M to indicate megabytes.

For example, the following sets the cache size to 128 KB.

connParms.CacheSize = "128k"

The default cache size is sixteen pages. Using the default page size of 4 KB, the default cache size is therefore 64 KB. The minimum cache size is platform dependent.

The default cache size is conservative. If your testing shows the need for better performance, you should increase the cache size.

Increasing the cache size beyond the size of the database itself provides no performance improvement and large cache sizes may interfere with the number of other applications you can use.

If the cache size is unspecified or improperly specified, the default size is used.

Exceptions

  • ArgumentException - The value contained a semi-colon (;), parentheses () or curly braces {}.


ConnectionName property

Specifies a name for the connection. This is only needed if you create more than one connection to the database.

Prototypes

' Visual Basic
Public Property ConnectionName As String

// C#
public string ConnectionName {get;set;}

Property value

A string specifying the name of the connection. The default is a null reference (Nothing in Visual Basic).

Exceptions

  • ArgumentException - The value contained a semi-colon (;), parentheses () or curly braces {}.


DatabaseOnCE property

Specifies the path and filename of the UltraLite database on Windows CE.

Prototypes

' Visual Basic
Public Property DatabaseOnCE As String

// C#
public string DatabaseOnCE {get;set;}

Property value

A string specifying the full path to the database. If the value is a null reference (Nothing in Visual Basic), the default database \UltraLiteDB\ulstore.udb is used. In C#, you must escape any backslash characters in paths or use @-quoted string literals.

Exceptions

  • ArgumentException - The value contained a semicolon (;), parentheses (), or curly braces {}.


DatabaseOnDesktop property

Specifies the path and filename of the UltraLite database on Windows desktop platforms.

Prototypes

' Visual Basic
Public Property DatabaseOnDesktop As String

// C#
public string DatabaseOnDesktop {get;set;}

Property value

A string specifying the absolute or relative path to the database. If the value is a null reference (Nothing in Visual Basic), the default database ulstore.udb is used. In C#, you must escape any backslash characters in paths or use @-quoted string literals.

Exceptions

  • ArgumentException - The value contained a semi-colon (;), parentheses () or curly braces {}.


EncryptionKey property

Specifies a key for encrypting the database.

Prototypes

' Visual Basic
Public Property EncryptionKey As String

// C#
public string EncryptionKey {get;set;}

Property value

A string specifying the encryption key. The default is a null reference (Nothing in Visual Basic) meaning no encryption.

Remarks

All connections must use the same key as was specified when the database was created. Lost or forgotten keys result in completely inaccessible databases.

As with all passwords, it is best to choose a key value that cannot be easily guessed. The key can be of arbitrary length, but generally the longer the key, the better, because a shorter key is easier to guess than a longer one. As well, including a combination of numbers, letters, and special characters decreases the chances of someone guessing the key.

Exceptions

  • ArgumentException - The value contained a semi-colon (;), parentheses () or curly braces {}.

See also
  • ULConnectionParms class
  • ULConnectionParms members
  • ChangeEncryptionKey method


Password property

Specifies the password for the authenticated user.

Prototypes

' Visual Basic
Public Property Password As String

// C#
public string Password {get;set;}

Property value

A string specifying a database user ID. The default is SQL.

Remarks

When a database is created, the password for the DBA user ID is set to SQL. Passwords are case-insensitive if the database is case-insensitive and case-sensitive if the database is case-sensitive.

Exceptions

  • ArgumentException - The value contained a semi-colon (;), parentheses () or curly braces {}.

See also
  • ULConnectionParms class
  • ULConnectionParms members
  • UserID property


SchemaOnCE property

Specifies the path and filename of the UltraLite schema on Windows CE.

Prototypes

' Visual Basic
Public Property SchemaOnCE As String

// C#
public string SchemaOnCE {get;set;}

Property value

A string specifying the full path to the schema file. The default is a null reference (Nothing in Visual Basic) meaning no schema file is specified for this platform.

Exceptions

  • ArgumentException - The value contained a semi-colon (;), parentheses () or curly braces {}.


SchemaOnDesktop property

Specifies the path and filename of the UltraLite schema on Windows desktop platforms.

Prototypes

' Visual Basic
Public Property SchemaOnDesktop As String

// C#
public string SchemaOnDesktop {get;set;}

Property value

A string specifying the absolute or relative path to the schema file. The default is a null reference (Nothing in Visual Basic) meaning no schema file is specified for this platform.

Exceptions

  • ArgumentException - The value contained a semi-colon (;), parentheses () or curly braces {}.


UserID property

Specifies an authenticated user for the database.

Prototypes

' Visual Basic
Public Property UserID As String

// C#
public string UserID {get;set;}

Property value

A string specifying a database user ID. The default value is DBA.

Remarks

Databases are initially created with a single authenticated user named DBA. User IDs are case-insensitive if the database is case-insensitive and case-sensitive if the database is case-sensitive.

Exceptions

  • ArgumentException - The value contained a semi-colon (;), parentheses () or curly-braces {}.

See also
  • ULConnectionParms class
  • ULConnectionParms members
  • Password property
  • GrantConnectTo method
  • RevokeConnectFrom method
  • IsCaseSensitive property


ToString method

Returns the string representation of this instance.

Prototypes

' Visual Basic
Overrides Public Function ToString() As String

// C#
public override string ToString();

Return value

The string representation of this instance as a semicolon-separated list keyword=value pairs.


UnusedEvent event

Unused.

Prototypes

' Visual Basic
Public Event UnusedEvent As ULConnectionParms.UnusedEventHandler

// C#
public event ULConnectionParms.UnusedEventHandler UnusedEvent;

Remarks

This public Event is provided to fix a Visual Studio .NET bug relating to the integration of this class in Visual Basic .NET projects. It has no functional use.


ULConnectionParms.UnusedEventHandler delegate

UL Ext.: Unused.

Prototypes

' Visual Basic
 Delegate Sub ULConnectionParms.UnusedEventHandler( _
ByVal sender As Object, _
ByVal args As System.EventArgs _
)

// C#
 delegate void ULConnectionParms.UnusedEventHandler(
object sender,
System.EventArgs args
);

Parameters

  • sender Object that is the sender.

  • args Event arguments.

Remarks

This public Delegate is provided to fix a Visual Studio .NET bug relating to the integration of this class in Visual Basic .NET projects. It has no functional use.


ULCursorSchema class

UL Ext.: Represents the schema of an UltraLite.NET cursor.

Prototypes

' Visual Basic
MustInherit Public Class ULCursorSchema

// C#
public abstract class ULCursorSchema

Remarks

This class is an abstract base class of the ULTableSchema class and ULResultSetSchema class classes.

Note to users porting from the iAnywhere.UltraLite namespace: Column IDs are 0-based, not 1-based as they are in the iAnywhere.UltraLite namespace.

ULCursorSchema members
ColumnCount property
IsOpen property
Name property
Finalize method
GetColumnID method
GetColumnName method
GetColumnPrecision method
GetColumnScale method
GetColumnSize method
GetColumnULDbType method
GetSchemaTable method


ULCursorSchema members

Public instance properties
Member | Description
ColumnCount property | Returns the number of columns in the cursor.
IsOpen property | Checks whether the cursor schema is currently open.
Name property | Returns the name of the cursor.
Public instance methods
Member | Description
GetColumnID method | Returns the column ID of the named column.
GetColumnName method | Returns the name of the column identified by the specified column ID.
GetColumnPrecision method | Returns the precision of the column identified by the specified column ID if the column is a numeric column (SQL type NUMERIC).
GetColumnScale method | Returns the scale of the column identified by the specified column ID if the column is a numeric column (SQL type NUMERIC).
GetColumnSize method | Returns the size of the column identified by the specified column ID if the column is a sized column (SQL type BINARY or CHAR).
GetColumnULDbType method | Returns the UltraLite.NET data type of the column identified by the specified column ID.
GetSchemaTable method | Returns a DataTable that describes the column schema of the ULDataReader class.
Protected instance methods
Member | Description
Finalize method | Releases the unmanaged resources used by the ULCursorSchema.


ColumnCount property

Returns the number of columns in the cursor.

Prototypes

' Visual Basic
Public Readonly Property ColumnCount As Short

// C#
public short ColumnCount {get;}

Property value

The number of columns in the cursor or 0 if the cursor schema is closed.

Remarks

Column IDs range from 0 to ColumnCount-1, inclusively.

Column IDs and count may change during a schema upgrade. To correctly identify a column, access it by name or refresh the cached IDs and counts after a schema upgrade.


IsOpen property

Checks whether the cursor schema is currently open.

Prototypes

' Visual Basic
Public Readonly Property IsOpen As Boolean

// C#
public bool IsOpen {get;}

Property value

True if the cursor schema is currently open, false if the cursor schema is closed.


Name property

Returns the name of the cursor.

Prototypes

' Visual Basic
Public Readonly Property Name As String

// C#
public string Name {get;}

Property value

The name of the cursor as a string.


Finalize method

Releases the unmanaged resources used by the ULCursorSchema.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


GetColumnID method

Returns the column ID of the named column.

Prototypes

' Visual Basic
Public Function GetColumnID( _
ByVal name As String _
) As Short

// C#
public short GetColumnID(
string name
);

Parameters

  • name The name of the column.

Return value

The column ID of the named column.

Remarks

Column IDs range from 0 to ColumnCount property -1, inclusively.

Note that in result sets, not all columns have names and not all column names are unique. If you are not using aliases, the name of a non-computed column is prefixed with the name of the table the column is from. For example, MyTable.ID is the name of the only column in the result set for the query "SELECT ID FROM MyTable".

Column IDs and counts may change during a schema upgrade. To correctly identify a column, access it by name or refresh the cached IDs and counts after a schema upgrade.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULCursorSchema class
  • ULCursorSchema members
  • ColumnCount property


GetColumnName method

Returns the name of the column identified by the specified column ID.

Prototypes

' Visual Basic
Public Function GetColumnName( _
ByVal columnID As Integer _
) As String

// C#
public string GetColumnName(
int columnID
);

Parameters

  • columnID ID of the column. The value must be in the range [0,ColumnCount property -1].

Return value

The name of the column or a null reference (Nothing in Visual Basic) if the column has no name. If the column is aliased in the SQL query, the alias is returned.

Remarks

Note that in result sets, not all columns have names and not all column names are unique. If you are not using aliases, the name of a non-computed column is prefixed with the name of the table the column is from. For example, MyTable.ID is the name of the only column in the result set for the query "SELECT ID FROM MyTable".

Column IDs and count may change during a schema upgrade. To correctly identify a column, access it by name or refresh the cached IDs and counts after a schema upgrade.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULCursorSchema class
  • ULCursorSchema members
  • ColumnCount property


GetColumnPrecision method

Returns the precision of the column identified by the specified column ID if the column is a numeric column (SQL type NUMERIC).

Prototypes

' Visual Basic
Public Function GetColumnPrecision( _
ByVal columnID As Integer _
) As Integer

// C#
public int GetColumnPrecision(
int columnID
);

Parameters

  • columnID ID of the column. The value must be in the range [0,ColumnCount property -1].

Return value

The precision of the specified numeric column.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULCursorSchema class
  • ULCursorSchema members
  • GetColumnULDbType method


GetColumnScale method

Returns the scale of the column identified by the specified column ID if the column is a numeric column (SQL type NUMERIC).

Prototypes

' Visual Basic
Public Function GetColumnScale( _
ByVal columnID As Integer _
) As Integer

// C#
public int GetColumnScale(
int columnID
);

Parameters

  • columnID ID of the column. The value must be in the range [0,ColumnCount property -1].

Return value

The scale of the specified numeric column.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULCursorSchema class
  • ULCursorSchema members
  • GetColumnULDbType method


GetColumnSize method

Returns the size of the column identified by the specified column ID if the column is a sized column (SQL type BINARY or CHAR).

Prototypes

' Visual Basic
Public Function GetColumnSize( _
ByVal columnID As Integer _
) As Integer

// C#
public int GetColumnSize(
int columnID
);

Parameters

  • columnID ID of the column. The value must be in the range [0,ColumnCount property -1].

Return value

The size of the specified sized column.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULCursorSchema class
  • ULCursorSchema members
  • GetColumnULDbType method


GetColumnULDbType method

Returns the UltraLite.NET data type of the column identified by the specified column ID.

Prototypes

' Visual Basic
Public Function GetColumnULDbType( _
ByVal columnID As Integer _
) As ULDbType

// C#
public ULDbType GetColumnULDbType(
int columnID
);

Parameters

  • columnID ID of the column. The value must be in the range [0,ColumnCount property -1].

Return value

A ULDbType enumerated integer.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULCursorSchema class
  • ULCursorSchema members
  • ULDbType enumeration
  • ColumnCount property


GetSchemaTable method

Returns a DataTable that describes the column schema of the ULDataReader class.

Prototypes

' Visual Basic
Public Function GetSchemaTable() As DataTable

// C#
public DataTable GetSchemaTable();

Return value

A DataTable that describes the column schema.

Remarks

For more information see GetSchemaTable method.


ULDataAdapter class

Represents a set of commands and a database connection used to fill a DataSet and to update a database.

Prototypes

' Visual Basic
NotInheritable Public Class ULDataAdapter
Implements IDbDataAdapter, IDataAdapter, IDisposable

// C#
public sealed class ULDataAdapter :
IDbDataAdapter, IDataAdapter,
IDisposable

Remarks

The DataSet provides a way to work with data offline; that is, away from your UltraLite database. The ULDataAdapter provides methods to associate a DataSet with a set of SQL statements.

Since UltraLite is a local database and MobiLink has conflict resolution, the use of the ULDataAdapter is limitted. For most purposes, the ULDataReader class or ULTable class classes provide more efficient access to data.

Inherits: DbDataAdapter

Implements: IDbDataAdapter, IDataAdapter, IDisposable

ULDataAdapter members
ULDataAdapter constructor
ULDataAdapter constructor
ULDataAdapter constructor
ULDataAdapter constructor
AcceptChangesDuringFill property
ContinueUpdateOnError property
DeleteCommand property
InsertCommand property
MissingMappingAction property
MissingSchemaAction property
SelectCommand property
TableMappings property
UpdateCommand property
Dispose method
Fill method
Fill method
Fill method
Fill method
FillSchema method
FillSchema method
FillSchema method
GetFillParameters method
Update method
Update method
Update method
Update method
FillError event
RowUpdated event
RowUpdating event


ULDataAdapter members

Public instance constructors
Member | Description
ULDataAdapter constructor | Initializes a ULDataAdapter object.
ULDataAdapter constructor | Initializes a ULDataAdapter object with the specified SELECT statement.
ULDataAdapter constructor | Initializes a ULDataAdapter object with the specified SELECT statement and connection.
ULDataAdapter constructor | Initializes a ULDataAdapter object with the specified SELECT statement and connection string.
Public instance properties
Member | Description
AcceptChangesDuringFill property | Specifies whether DataRow.AcceptChanges is called on a DataRow after it is added to the DataTable.
ContinueUpdateOnError property | Specifies whether to generate an exception when an error is encountered during a row update.
DeleteCommand property | Specifies a ULCommand class object that is executed against the database when DbDataAdapter.Update is called to delete rows in the database that correspond to deleted rows in the DataSet.
InsertCommand property | Specifies a ULCommand class object that is executed against the database when DbDataAdapter.Update is called to insert rows in the database that correspond to inserted rows in the DataSet.
MissingMappingAction property | Determines the action to take when incoming data does not have a matching table or column.
MissingSchemaAction property | Determines the action to take when the existing DataSet schema does not match incoming data.
SelectCommand property | Specifies a ULCommand class that is used during Fill method or FillSchema method to obtain a result set from the database for copying into a DataSet.
TableMappings property | Returns a collection that provides the master mapping between a source table and a DataTable
UpdateCommand property | Specifies a ULCommand class object that is executed against the database when Update method is called to update rows in the database that correspond to updated rows in the DataSet.
Public instance methods
Member | Description
Dispose method | Releases the unmanaged resources used by the ULDataAdapter and optionally releases the managed resources.
Fill method | Adds or refreshes rows into the DataTable named "Table" of the specified DataSet. The DataTable named "Table" is created and added to the DataSet if necessary.
Fill method | Adds or refreshes rows into the named DataTable of the specified DataSet. The DataTable named is created and added to the DataSet if neccessary.
Fill method | Adds or refreshes the specified range of rows into the named DataTable of the specified DataSet. The DataTable named is created and added to the DataSet if neccessary.
Fill method | Adds or refreshes rows into the specified DataTable.
FillSchema method | Adds a DataTable named "Table" to a DataSet and configures the schema to match the schema in the data source.
FillSchema method | Adds a DataTable named "Table" to a DataSet and configures the schema to match the schema in the data source.
FillSchema method | Configures the schema of a DataTable to match the schema in the data source.
GetFillParameters method | Returns the parameters set by the user when executing a SELECT statement.
Update method | Updates the rows in the database with the changes made to the DataTable named "Table" of the specified DataSet.
Update method | Updates the rows in the database with the changes made to the named DataTable of the specified DataSet.
Update method | Updates the rows in the database with the changes made to the specified DataTable.
Update method | Updates the rows in the database with the changes made to the specified DataRow array.
Public instance events
Member | Description
FillError event | Occurs when an error is detected during a fill operation.
RowUpdated event | Occurs during an update after a command is executed against the data source. When an attempt to update is made, the event fires.
RowUpdating event | Occurs during an update before a command is executed against the data source. When an attempt to update is made, the event fires.


ULDataAdapter constructor

Initializes a ULDataAdapter object.

Prototypes

' Visual Basic
Overloads Public Sub New()

// C#
public ULDataAdapter();

See also
  • ULDataAdapter class
  • ULDataAdapter members
  • ULDataAdapter constructor
  • ULDataAdapter constructor
  • ULDataAdapter constructor


ULDataAdapter constructor

Initializes a ULDataAdapter object with the specified SELECT statement.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal selectCommand As ULCommand _
)

// C#
public ULDataAdapter(
ULCommand selectCommand
);

Parameters

  • selectCommand A ULCommand class object that is used during DbDataAdapter.Fill to select records from the data source for placement in the DataSet.

See also
  • ULDataAdapter class
  • ULDataAdapter members
  • ULDataAdapter constructor
  • ULDataAdapter constructor
  • ULDataAdapter constructor


ULDataAdapter constructor

Initializes a ULDataAdapter object with the specified SELECT statement and connection.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal selectCommandText As String, _
ByVal selectConnection As ULConnection _
)

// C#
public ULDataAdapter(
string selectCommandText,
ULConnection selectConnection
);

Parameters

  • selectCommandText A SELECT statement to be used by the SelectCommand property property of the ULDataAdapter.

  • selectConnection A ULConnection class object that defines a connection to a database.

See also
  • ULDataAdapter class
  • ULDataAdapter members
  • ULDataAdapter constructor
  • ULDataAdapter constructor
  • ULDataAdapter constructor


ULDataAdapter constructor

Initializes a ULDataAdapter object with the specified SELECT statement and connection string.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal selectCommandText As String, _
ByVal selectConnectionString As String _
)

// C#
public ULDataAdapter(
string selectCommandText,
string selectConnectionString
);

Parameters

  • selectCommandText A SELECT statement to be used by the SelectCommand property property of the ULDataAdapter.

  • selectConnectionString A connection string for an UltraLite.NET database.

See also
  • ULDataAdapter class
  • ULDataAdapter members
  • ULDataAdapter constructor
  • ULDataAdapter constructor
  • ULDataAdapter constructor


AcceptChangesDuringFill property

Specifies whether DataRow.AcceptChanges is called on a DataRow after it is added to the DataTable.

Prototypes

' Visual Basic
Public Property AcceptChangesDuringFill As Boolean

// C#
public bool AcceptChangesDuringFill {get;set;}

Property value

True to specify that the ULDataAdapter should call the DataRow.AcceptChanges function on the DataRow; false if AcceptChanges is not to be called, and the newly added rows are treated as inserted rows. The default is true.


ContinueUpdateOnError property

Specifies whether to generate an exception when an error is encountered during a row update.

Prototypes

' Visual Basic
Public Property ContinueUpdateOnError As Boolean

// C#
public bool ContinueUpdateOnError {get;set;}

Property value

True to continue the update without generating an exception, false to generate an exception. The default is false.

Remarks

If ContinueUpdateOnError is true, no exception is thrown when an error occurs during the update of a row. The update of the row is skipped and the error information is placed in the DataRow.RowError property of the row. The ULDataAdapter continues to update subsequent rows.

If ContinueUpdateOnError is false, an exception is thrown when an error occurs.


DeleteCommand property

Specifies a ULCommand class object that is executed against the database when DbDataAdapter.Update is called to delete rows in the database that correspond to deleted rows in the DataSet.

Prototypes

' Visual Basic
Public Property DeleteCommand As ULCommand

// C#
public ULCommand DeleteCommand {get;set;}

Property value

A ULCommand class object that is executed to delete rows in the database that correspond to deleted rows in the DataSet.

Remarks

When DeleteCommand is assigned to an existing ULCommand class object, the ULCommand class object is not cloned. The DeleteCommand maintains a reference to the existing ULCommand class.

This is the strongly typed version of IDbDataAdapter.DeleteCommand.


InsertCommand property

Specifies a ULCommand class object that is executed against the database when DbDataAdapter.Update is called to insert rows in the database that correspond to inserted rows in the DataSet.

Prototypes

' Visual Basic
Public Property InsertCommand As ULCommand

// C#
public ULCommand InsertCommand {get;set;}

Property value

A ULCommand class object that is executed to insert rows in the database that correspond to inserted rows in the DataSet.

Remarks

When InsertCommand is assigned to an existing ULCommand class object, the ULCommand class object is not cloned. The InsertCommand maintains a reference to the existing ULCommand class.

This is the strongly typed version of IDbDataAdapter.InsertCommand.


MissingMappingAction property

Determines the action to take when incoming data does not have a matching table or column.

Prototypes

' Visual Basic
NotOverridable Public Property MissingMappingAction As MissingMappingAction _
Implements IDataAdapter.MissingMappingAction

// C#
public MissingMappingAction MissingMappingAction {get;set;}

Property value

One of the MissingMappingAction values. The default is MissingMappingAction.Passthrough.

Implements

IDataAdapter.MissingMappingAction


MissingSchemaAction property

Determines the action to take when the existing DataSet schema does not match incoming data.

Prototypes

' Visual Basic
NotOverridable Public Property MissingSchemaAction As MissingSchemaAction _
Implements IDataAdapter.MissingSchemaAction

// C#
public MissingSchemaAction MissingSchemaAction {get;set;}

Property value

One of the MissingSchemaAction values. The default is MissingSchemaAction.Add.

Implements

IDataAdapter.MissingSchemaAction


SelectCommand property

Specifies a ULCommand class that is used during Fill method or FillSchema method to obtain a result set from the database for copying into a DataSet.

Prototypes

' Visual Basic
Public Property SelectCommand As ULCommand

// C#
public ULCommand SelectCommand {get;set;}

Property value

A ULCommand class object that is executed to fill the DataSet.

Remarks

When SelectCommand is assigned to an existing ULCommand class object, the ULCommand class object is not cloned. The SelectCommand maintains a reference to the existing ULCommand class.

If the SelectCommand does not return any rows, no tables are added to the DataSet, and no exception is raised. The SELECT statement can also be specified in the ULDataAdapter constructor, ULDataAdapter constructor, or ULDataAdapter constructor constructors.

This is the strongly typed version of IDbDataAdapter.SelectCommand.


TableMappings property

Returns a collection that provides the master mapping between a source table and a DataTable

Prototypes

' Visual Basic
Public Readonly Property TableMappings As DataTableMappingCollection

// C#
public DataTableMappingCollection TableMappings {get;}

Property value

A collection of DataTableMapping objects providing the master mapping between source tables and DataTables. The default value is an empty collection.

Remarks

When reconciling changes, the ULDataAdapter uses the DataTableMappingCollection collection to associate the column names used by the data source with the column names used by the DataSet.

This is the strongly typed version of IDataAdapter.TableMappings.


UpdateCommand property

Specifies a ULCommand class object that is executed against the database when Update method is called to update rows in the database that correspond to updated rows in the DataSet.

Prototypes

' Visual Basic
Public Property UpdateCommand As ULCommand

// C#
public ULCommand UpdateCommand {get;set;}

Property value

A ULCommand class object that is executed to update rows in the database that correspond to updated rows in the DataSet.

Remarks

When UpdateCommand is assigned to an existing ULCommand class object, the ULCommand class object is not cloned. The UpdateCommand maintains a reference to the existing ULCommand class.

If execution of this command returns rows, these rows may be merged with the DataSet depending on how you set the UpdatedRowSource property property of the ULCommand class object.

This is the strongly typed version of IDbDataAdapter.UpdateCommand.


Dispose method

Releases the unmanaged resources used by the ULDataAdapter and optionally releases the managed resources.

Prototypes

' Visual Basic
Overloads NotOverridable Public Sub Dispose() _
Implements IDisposable.Dispose

// C#
public void Dispose();

Implements

IDisposable.Dispose


Fill method

Adds or refreshes rows into the DataTable named "Table" of the specified DataSet. The DataTable named "Table" is created and added to the DataSet if necessary.

Prototypes

' Visual Basic
Overloads NotOverridable Public Function Fill( _
ByVal dataSet As DataSet _
) As Integer _
Implements IDataAdapter.Fill

// C#
public int Fill(
DataSet dataSet
);

Parameters

  • dataSet A DataSet to fill with records and optionally schema.

Return value

The number of rows successfully added or refreshed in the DataSet.

Remarks

For large result sets, this can have a significant performance impact. An alternative is to use a ULDataReader class when a read-only result set is sufficient, perhaps with SQL statements (ExecuteNonQuery) to carry out modifications. Another alternative is to use a ULTable class that allows read-write access to the database.

If SelectCommand property does not return any rows, no tables are added to the DataSet and no exception is raised.

For more information, see IDataAdapter.Fill.

Exceptions

  • System.ArgumentNullException - The dataSet parameter is invalid.

  • InvalidOperationException - The SelectCommand property property is invalid or, the table mapping is missing and MissingMappingAction property is set to MissingMappingAction.Error or, the DataTable is missing from the DataSet and MissingSchemaAction property is set to MissingSchemaAction.Error.

Implements

IDataAdapter.Fill


Fill method

Adds or refreshes rows into the named DataTable of the specified DataSet. The DataTable named is created and added to the DataSet if neccessary.

Prototypes

' Visual Basic
Overloads Public Function Fill( _
ByVal dataSet As DataSet, _
ByVal srcTable As String _
) As Integer

// C#
public int Fill(
DataSet dataSet,
string srcTable
);

Parameters

  • dataSet A DataSet to fill with records and optionally schema.

  • srcTable The name of the source table to use for table mapping.

Return value

The number of rows successfully added or refreshed in the DataSet.

Remarks

For large result sets, this can have a significant performance impact. An alternative is to use an ULDataReader class when a read-only result set is sufficient, perhaps with SQL statements (ExecuteNonQuery) to carry out modifications. Another alternative is to use a ULTable class that allows read-write access to the database.

If SelectCommand property does not return any rows, no tables are added to the DataSet and no exception is raised.

For more information, see IDataAdapter.Fill.

Exceptions

  • System.ArgumentNullException - The dataSet or srcTable parameter is invalid.

  • InvalidOperationException - The SelectCommand property property is invalid or, the table mapping is missing and MissingMappingAction property is set to MissingMappingAction.Error or, the DataTable is missing from the DataSet and MissingSchemaAction property is set to MissingSchemaAction.Error.


Fill method

Adds or refreshes the specified range of rows into the named DataTable of the specified DataSet. The DataTable named is created and added to the DataSet if neccessary.

Prototypes

' Visual Basic
Overloads Public Function Fill( _
ByVal dataSet As DataSet, _
ByVal startRecord As Integer, _
ByVal maxRecords As Integer, _
ByVal srcTable As String _
) As Integer

// C#
public int Fill(
DataSet dataSet,
int startRecord,
int maxRecords,
string srcTable
);

Parameters

  • dataSet A DataSet to fill with records and optionally schema.

  • startRecord The zero-based record number to start with.

  • maxRecords The maximum number of records to be read into the DataSet. A value of 0 gets all records found after the start record.

  • srcTable The name of the source table to use for table mapping.

Return value

The number of rows successfully added or refreshed in the DataSet.

Remarks

Even if you use the startRecord argument to limit the number of records that are copied to the DataSet, all records in the ULDataAdapter query are fetched from the database to the client. For large result sets, this can have a significant performance impact. An alternative is to use an ULDataReader class when a read-only result set is sufficient, perhaps with SQL statements (ExecuteNonQuery) to carry out modifications. Another alternative is to use a ULTable class that allows read-write access to the database.

If SelectCommand property does not return any rows, no tables are added to the DataSet and no exception is raised.

For more information, see IDataAdapter.Fill.

Exceptions

  • ArgumentException - The startRecord or maxRecords parameter was less than zero.

  • System.ArgumentNullException - The dataSet or srcTable parameter is invalid.

  • InvalidOperationException - The SelectCommand property property is invalid or, the table mapping is missing and MissingMappingAction property is set to MissingMappingAction.Error or, the DataTable is missing from the DataSet and MissingSchemaAction property is set to MissingSchemaAction.Error.


Fill method

Adds or refreshes rows into the specified DataTable.

Prototypes

' Visual Basic
Overloads Public Function Fill( _
ByVal dataTable As DataTable _
) As Integer

// C#
public int Fill(
DataTable dataTable
);

Parameters

  • dataTable A DataTable to fill with records and optionally schema.

Return value

The number of rows successfully added or refreshed in the DataTable.

Remarks

For large result sets, this can have a significant performance impact. An alternative is to use an ULDataReader class when a read-only result set is sufficient, perhaps with SQL statements (ExecuteNonQuery) to carry out modifications. Another alternative is to use a ULTable class that allows read-write access to the database.

If SelectCommand property does not return any rows, no tables are added to the and no exception is raised.

For more information, see IDataAdapter.Fill.

Exceptions

  • System.ArgumentNullException - The dataTable parameter is invalid.

  • InvalidOperationException - The SelectCommand property property is invalid or, the table mapping is missing and MissingMappingAction property is set to MissingMappingAction.Error.


FillSchema method

Adds a DataTable named "Table" to a DataSet and configures the schema to match the schema in the data source.

Prototypes

' Visual Basic
Overloads NotOverridable Public Function FillSchema( _
ByVal dataSet As DataSet, _
ByVal schemaType As SchemaType _
) As DataTable() _
Implements IDataAdapter.FillSchema

// C#
public DataTable[] FillSchema(
DataSet dataSet,
SchemaType schemaType
);

Parameters

  • dataSet A DataSet to fill with the schema.

  • schemaType One of the SchemaType values that specify how to insert the schema.

Return value

A reference to a collection of DataTable objects that were added to the DataSet.

Remarks

For more information, see IDataAdapter.FillSchema.

Exceptions

  • System.ArgumentNullException - The dataSet parameter is invalid.

  • InvalidOperationException - The SelectCommand property property is invalid or, the table mapping is missing and MissingMappingAction property is set to MissingMappingAction.Error.

Implements

IDataAdapter.FillSchema


FillSchema method

Adds a DataTable named "Table" to a DataSet and configures the schema to match the schema in the data source.

Prototypes

' Visual Basic
Overloads Public Function FillSchema( _
ByVal dataSet As DataSet, _
ByVal schemaType As SchemaType, _
ByVal srcTable As String _
) As DataTable()

// C#
public DataTable[] FillSchema(
DataSet dataSet,
SchemaType schemaType,
string srcTable
);

Parameters

  • dataSet A DataSet to fill with the schema.

  • schemaType One of the SchemaType values that specify how to insert the schema.

  • srcTable The name of the source table to use for table mapping.

Return value

A reference to a collection of DataTable objects that were added to the DataSet.

Remarks

For more information, see DbDataAdapter.FillSchema.

Exceptions

  • System.ArgumentNullException - The dataSet or srcTable parameter is invalid.

  • InvalidOperationException - The SelectCommand property property is invalid or, the table mapping is missing and MissingMappingAction property is set to MissingMappingAction.Error.


FillSchema method

Configures the schema of a DataTable to match the schema in the data source.

Prototypes

' Visual Basic
Overloads Public Function FillSchema( _
ByVal dataTable As DataTable, _
ByVal schemaType As SchemaType _
) As DataTable

// C#
public DataTable FillSchema(
DataTable dataTable,
SchemaType schemaType
);

Parameters

  • dataTable A DataTable to fill with the schema.

  • schemaType One of the SchemaType values that specify how to insert the schema.

Return value

A reference to the DataTable object that contains the schema.

Remarks

For more information, see DbDataAdapter.FillSchema.

Exceptions

  • System.ArgumentNullException - The dataTable parameter is invalid.

  • InvalidOperationException - The SelectCommand property property is invalid.


GetFillParameters method

Returns the parameters set by the user when executing a SELECT statement.

Prototypes

' Visual Basic
Public Function GetFillParameters() As ULParameter()

// C#
public ULParameter[] GetFillParameters();

Return value

An array of ULParameter class objects that contains the parameters set by the user.


Update method

Updates the rows in the database with the changes made to the DataTable named "Table" of the specified DataSet.

Prototypes

' Visual Basic
Overloads NotOverridable Public Function Update( _
ByVal dataSet As DataSet _
) As Integer _
Implements IDataAdapter.Update

// C#
public int Update(
DataSet dataSet
);

Parameters

  • dataSet A DataSet to update with records from.

Return value

The number of rows successfully updated from the DataSet.

Remarks

For more information, see IDataAdapter.Update.

Exceptions

  • System.ArgumentNullException - The dataSet parameter is invalid.

  • InvalidOperationException - The SelectCommand property property is invalid or, the table mapping is missing and MissingMappingAction property is set to MissingMappingAction.Error or, the DataTable is missing from the DataSet.

Implements

IDataAdapter.Update


Update method

Updates the rows in the database with the changes made to the named DataTable of the specified DataSet.

Prototypes

' Visual Basic
Overloads Public Function Update( _
ByVal dataSet As DataSet, _
ByVal srcTable As String _
) As Integer

// C#
public int Update(
DataSet dataSet,
string srcTable
);

Parameters

  • dataSet A DataSet to update with records from.

  • srcTable The name of the source table to use for table mapping.

Return value

The number of rows successfully updated from the DataSet.

Remarks

For more information, see DbDataAdapter.Update.

Exceptions

  • System.ArgumentNullException - The dataSet or srcTable parameter is invalid.

  • InvalidOperationException - The SelectCommand property property is invalid or, the table mapping is missing and MissingMappingAction property is set to MissingMappingAction.Error or, the DataTable is missing from the DataSet.


Update method

Updates the rows in the database with the changes made to the specified DataTable.

Prototypes

' Visual Basic
Overloads Public Function Update( _
ByVal dataTable As DataTable _
) As Integer

// C#
public int Update(
DataTable dataTable
);

Parameters

  • dataTable A DataTable to update from.

Return value

The number of rows successfully updated from the DataTable.

Remarks

For more information, see DbDataAdapter.Update.

Exceptions

  • System.ArgumentNullException - The dataTable parameter is invalid.

  • InvalidOperationException - The SelectCommand property property is invalid or, the table mapping is missing and MissingMappingAction property is set to MissingMappingAction.Error.


Update method

Updates the rows in the database with the changes made to the specified DataRow array.

Prototypes

' Visual Basic
Overloads Public Function Update( _
ByVal dataRows As DataRow() _
) As Integer

// C#
public int Update(
DataRow[] dataRows
);

Parameters

  • dataRows An array of DataRow to update from.

Return value

The number of rows successfully updated from the DataRow array.

Remarks

For more information, see DbDataAdapter.Update.

Exceptions

  • System.ArgumentNullException - The dataRows parameter is invalid.

  • InvalidOperationException - The SelectCommand property property is invalid or, the table mapping is missing and MissingMappingAction property is set to MissingMappingAction.Error.


FillError event

Occurs when an error is detected during a fill operation.

Prototypes

' Visual Basic
Public Event FillError As FillErrorEventHandler

// C#
public event FillErrorEventHandler FillError;

Remarks

The FillError event allows you to determine whether or not the fill operation should continue after the error occurs.

Examples of when the FillError event might occur are:

  • The data being added to a DataSet cannot be converted to a common language runtime type without losing precision.
  • The row being added contains data that violates a Constraint that must be enforced on a DataColumn in the DataSet.

To process row fill error events, you must create a FillErrorEventHandler delegate and attach it to this event.


RowUpdated event

Occurs during an update after a command is executed against the data source. When an attempt to update is made, the event fires.

Prototypes

' Visual Basic
Public Event RowUpdated As ULRowUpdatedEventHandler

// C#
public event ULRowUpdatedEventHandler RowUpdated;

Remarks

To process row updated events, you must create a ULRowUpdatedEventHandler delegate delegate and attach it to this event.


RowUpdating event

Occurs during an update before a command is executed against the data source. When an attempt to update is made, the event fires.

Prototypes

' Visual Basic
Public Event RowUpdating As ULRowUpdatingEventHandler

// C#
public event ULRowUpdatingEventHandler RowUpdating;

Remarks

To process row updating events, you must create a ULRowUpdatingEventHandler delegate delegate and attach it to this event.


ULDatabaseManager class

UL Ext.: Manages synchronization listeners and the UltraLite.NET runtime type. The ULDatabaseManager class also allows you to drop (delete) UltraLite.NET databases.

Prototypes

' Visual Basic
NotInheritable Public Class ULDatabaseManager

// C#
public sealed class ULDatabaseManager

Remarks

This class is a singleton class whose only instance is accessible only through the static (Shared in Visual Basic) DatabaseManager property property.

To use the UltraLite Engine runtime of UltraLite.NET, set RuntimeType property to the appropriate value before using any other UltraLite.NET API.


ULDatabaseManager members

Public static properties (Shared)
Member | Description
RuntimeType property | Specifies the UltraLite.NET runtime type. The runtime type must be selected before using any other UltraLite.NET API.
Public instance methods
Member | Description
DropDatabase method | Deletes the specified database. You cannot drop a database that has open connections.
SetActiveSyncListener method | Specifies the listener object used to process ActiveSync calls from the MobiLink provider for ActiveSync.
SetServerSyncListener method | Specifies the listener object used to process the specified server synchronization message.
Protected instance methods
Member | Description
Finalize method | Releases the unmanaged resources used by the ULDatabaseManager.


RuntimeType property

Specifies the UltraLite.NET runtime type. The runtime type must be selected before using any other UltraLite.NET API.

Prototypes

' Visual Basic
Public Shared Property RuntimeType As ULRuntimeType

// C#
public const ULRuntimeType RuntimeType {get;set;}

Property value

A ULRuntimeType enumeration value identifying the type of the unmanaged UltraLite.NET runtime.

Example

The following example selects the UltraLite Engine runtime and creates a connection.

' Visual Basic
ULDatabaseManager.RuntimeType = ULRuntimeType.UL_ENGINE_CLIENT
Dim conn As ULConnection = new ULConnection
' The RuntimeType is now locked

// C#
ULDatabaseManager.RuntimeType = ULRuntimeType.UL_ENGINE_CLIENT;
ULConnection conn = new ULConnection();
// The RuntimeType is now locked


DropDatabase method

Deletes the specified database.

You cannot drop a database that has open connections.

Prototypes

' Visual Basic
Public Sub DropDatabase( _
ByVal parms As ULConnectionParms _
)

// C#
public void DropDatabase(
ULConnectionParms parms
);

Parameters

  • parms The parameters for identifying a database. See ULConnectionParms class for more information.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULDatabaseManager class
  • ULDatabaseManager members
  • OpenWithCreate method


Finalize method

Releases the unmanaged resources used by the ULDatabaseManager.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


SetActiveSyncListener method

Specifies the listener object used to process ActiveSync calls from the MobiLink provider for ActiveSync.

Prototypes

' Visual Basic
Public Sub SetActiveSyncListener( _
ByVal appClassName As String, _
ByVal listener As ULActiveSyncListener _
)

// C#
public void SetActiveSyncListener(
string appClassName,
ULActiveSyncListener listener
);

Parameters

  • appClassName The unique class name for the application. This is the class name used when the application is registered for use with ActiveSync.

  • listener The ULActiveSyncListener interface object. Use null (Nothing in Visual Basic) to remove the previous listener.

Remarks

The parameter appClassName is the unique identifier used to identify the application. The application can only use one appClassName at a time. While a listener is registered with a particular appClassName, calls to SetServerSyncListener method or SetActiveSyncListener method with a different appClassName fail.

To remove the ActiveSync listener, call SetActiveSyncListener method with a null reference (Nothing in Visual Basic) as the listener parameter.

To remove all listeners, call SetServerSyncListener method with a null reference (Nothing in Visual Basic) for all parameters.

Applications should remove all listeners prior to exiting.

Exceptions

  • ULException class - A SQL error occurred.

Example

Refer to the ActiveSyncInvoked method documentation for an example of SetActiveSyncListener method.

See also
  • ULDatabaseManager class
  • ULDatabaseManager members
  • ColumnCount property


SetServerSyncListener method

Specifies the listener object used to process the specified server synchronization message.

Prototypes

' Visual Basic
Public Sub SetServerSyncListener( _
ByVal messageName As String, _
ByVal appClassName As String, _
ByVal listener As ULServerSyncListener _
)

// C#
public void SetServerSyncListener(
string messageName,
string appClassName,
ULServerSyncListener listener
);

Parameters

  • messageName The name of the message.

  • appClassName The unique class name for the application. This is a unique identifier used to identify the application.

  • listener The ULServerSyncListener interface object. Use null (Nothing in Visual Basic) to remove the previous listener.

Remarks

The parameter appClassName is the unique identifier used to identify the application. The application may only use one appClassName at a time. While a listener is registered with a particular appClassName, calls to SetServerSyncListener method or SetActiveSyncListener method with a different appClassName fail.

To remove the listener for a particular message, call SetServerSyncListener method with a null reference (Nothing in Visual Basic) as the listener parameter.

To remove all listeners, call SetServerSyncListener method with a null reference (Nothing in Visual Basic) for all parameters.

Applications should remove all listeners before exiting.

Exceptions

  • ULException class - A SQL error occurred.

Example

Refer to the ServerSyncInvoked method documentation for an example of SetServerSyncListener method.


ULDatabaseSchema class

UL Ext.: Represents the schema of an UltraLite.NET database.

Prototypes

' Visual Basic
NotInheritable Public Class ULDatabaseSchema

// C#
public sealed class ULDatabaseSchema

Remarks

This class cannot be directly instantiated. A ULDatabaseSchema class object is attached to a connection as its Schema property property and is only valid while that connection is open.

ULDatabaseSchema members
CollationName property
IsCaseSensitive property
IsOpen property
PublicationCount property
Signature property
TableCount property
ApplyFile method
ApplyFile method
GetDatabaseProperty method
GetPublicationName method
GetPublicationSchema method
GetTableCountInPublications method
GetTableName method


ULDatabaseSchema members

Public instance properties
Member | Description
CollationName property | The name of the database's collation sequence.
IsCaseSensitive property | Checks whether the database is case sensitive.
IsOpen property | Whether or not the database schema is open.
PublicationCount property | The number of publications in the database.
Signature property | The signature of this database.
TableCount property | The number of tables in the database.
Public instance methods
Member | Description
ApplyFile method | Applies a database schema file to the database while allowing a listener to monitor the progress.
ApplyFile method | Applies a database schema file to the database.
GetDatabaseProperty method | Returns the value of the specified database property.
GetPublicationName method | Returns the name of the publication identified by the specified publication ID. Publication IDs are not publication masks.
GetPublicationSchema method | Returns the publication schema corresponding to the named publication.
GetTableCountInPublications method | Returns the number of tables included in the specified publication mask.
GetTableName method | Returns the name of the table identified by the specified table ID.


CollationName property

The name of the database's collation sequence.

Prototypes

' Visual Basic
Public Readonly Property CollationName As String

// C#
public string CollationName {get;}

Property value

A string representing the database's collation sequence.

Remarks

The database collation sequence affects how indexes on tables and result sets are sorted.

Exceptions

  • ULException class - A SQL error occurred.


IsCaseSensitive property

Checks whether the database is case sensitive.

Prototypes

' Visual Basic
Public Readonly Property IsCaseSensitive As Boolean

// C#
public bool IsCaseSensitive {get;}

Property value

True if the database is case sensitive, and false if the database is case insensitive.

Remarks

Database case sensitivity affects how indexes on tables and result sets are sorted. Case sensitivity also affects how UserID property and Password property are verified.

Exceptions

  • ULException class - A SQL error occurred.


IsOpen property

Whether or not the database schema is open.

Prototypes

' Visual Basic
Public Readonly Property IsOpen As Boolean

// C#
public bool IsOpen {get;}

Property value

True if this database schema is currently open, false if this database schema is currently closed.

Remarks

A ULDatabaseSchema object is open only if the connection it is attached to is open.


PublicationCount property

The number of publications in the database.

Prototypes

' Visual Basic
Public Readonly Property PublicationCount As Integer

// C#
public int PublicationCount {get;}

Property value

The numberof publications in the database or zero if the connection is not open.

Remarks

Publication IDs range from 1 to PublicationCount, inclusively. Publication IDs are not publication masks.

Note: Publication IDs, masks, and counts may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached IDs, masks, and counts after a schema upgrade.

See also
  • ULDatabaseSchema class
  • ULDatabaseSchema members
  • GetPublicationName method


Signature property

The signature of this database.

Prototypes

' Visual Basic
Public Readonly Property Signature As String

// C#
public string Signature {get;}

Property value

A string representing the signature of the currently opened database.

Exceptions

  • ULException class - A SQL error occurred.


TableCount property

The number of tables in the database.

Prototypes

' Visual Basic
Public Readonly Property TableCount As Integer

// C#
public int TableCount {get;}

Property value

The number of tables in the database or zero if the connection is not open.

Remarks

Table IDs range from 1 to TableCount, inclusively.

Note: Table IDs and counts may change during a schema upgrade. To correctly identify a table, access it by name or refresh the cached IDs and counts after a schema upgrade.


ApplyFile method

Applies a database schema file to the database while allowing a listener to monitor the progress.

Prototypes

' Visual Basic
Overloads Public Sub ApplyFile( _
ByVal parms As ULConnectionParms, _
ByVal listener As ULSchemaUpgradeListener _
)

// C#
public void ApplyFile(
ULConnectionParms parms,
ULSchemaUpgradeListener listener
);

Parameters

  • parms Parameters for specifying the schema to be applied to the database. See ULConnectionParms class for more information.

  • listener The ULSchemaUpgradeListener interface object to receive schema upgrade progress events.

Remarks

All instances of ULResultSetSchema class, ULTableSchema class, ULIndexSchema class, and ULPublicationSchema class will be invalidated and will need to be replaced.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULDatabaseSchema class
  • ULDatabaseSchema members
  • ApplyFile method
  • ULConnectionParms class


ApplyFile method

Applies a database schema file to the database.

Prototypes

' Visual Basic
Overloads Public Sub ApplyFile( _
ByVal parms As ULConnectionParms _
)

// C#
public void ApplyFile(
ULConnectionParms parms
);

Parameters

  • parms Parameters for specifying the schema to be applied to the database. See ULConnectionParms class for more information.

Remarks

All instances of ULResultSetSchema class, ULTableSchema class, ULIndexSchema class, and ULPublicationSchema class will be invalidated and will need to be replaced.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULDatabaseSchema class
  • ULDatabaseSchema members
  • ApplyFile method
  • ULConnectionParms class


GetDatabaseProperty method

Returns the value of the specified database property.

Prototypes

' Visual Basic
Public Function GetDatabaseProperty( _
ByVal name As String _
) As String

// C#
public string GetDatabaseProperty(
string name
);

Parameters

  • name The name of the database property to inquire about.

Return value

The value of the property as a string.

Remarks

Recognized properties are:

  • "DATE_FORMAT" The date format used for string conversions by the database.

    This format is not necessarily the same as the one used by DateTime.

  • "DATE_ORDER" The date order used for string conversions by the database.

  • "NEAREST_CENTURY" The nearest century used for string conversions by the database.

  • "PRECISION" The floating point precision used for string conversions by the database.

  • "SCALE" The minimum number of digits after the decimal point when an arithmetic result is truncated to the maximum PRECISION during string conversions by the database.

  • "TIME_FORMAT" The time format used for string conversions by the database.

    This format is not necessarily the same as the one used by TimeSpan.

  • "TIMESTAMP_FORMAT" The timestamp format used for string conversions by the database.

    This format is not necessarily the same as the one used by DateTime.

  • "TIMESTAMP_INCREMENT" The minimum difference between two unique timestamps, in nanoseconds (1,000,000th of a second).

Exceptions

  • ULException class - A SQL error occurred.


GetPublicationName method

Returns the name of the publication identified by the specified publication ID. Publication IDs are not publication masks.

Prototypes

' Visual Basic
Public Function GetPublicationName( _
ByVal pubID As Integer _
) As String

// C#
public string GetPublicationName(
int pubID
);

Parameters

  • pubID The ID of the publication. The value must be in the range [1,PublicationCount property].

Return value

The publication name as a string.

Remarks

Note: Publication IDs, masks, and counts may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached IDs, masks, and counts after a schema upgrade.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULDatabaseSchema class
  • ULDatabaseSchema members
  • PublicationCount property


GetPublicationSchema method

Returns the publication schema corresponding to the named publication.

Prototypes

' Visual Basic
Public Function GetPublicationSchema( _
ByVal name As String _
) As ULPublicationSchema

// C#
public ULPublicationSchema GetPublicationSchema(
string name
);

Parameters

  • name The name of the publication.

Return value

The ULPublicationSchema class object representing the named publication.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULDatabaseSchema class
  • ULDatabaseSchema members
  • GetPublicationName method
  • ULPublicationSchema class


GetTableCountInPublications method

Returns the number of tables included in the specified publication mask.

Prototypes

' Visual Basic
Public Function GetTableCountInPublications( _
ByVal mask As Integer _
) As Integer

// C#
public int GetTableCountInPublications(
int mask
);

Parameters

  • mask The set of publications to check. See ULPublicationSchema class for information on building publication masks.

Return value

The number of tables included in set of publications.

Remarks

The count will not include tables whose names end in _nosync.

Note: Publication IDs, masks, and counts may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached IDs, masks, and counts after a schema upgrade.

Exceptions

  • ULException class - A SQL error occurred.


GetTableName method

Returns the name of the table identified by the specified table ID.

Prototypes

' Visual Basic
Public Function GetTableName( _
ByVal tableID As Integer _
) As String

// C#
public string GetTableName(
int tableID
);

Parameters

  • tableID The ID of the table. The value must be in range [1,TableCount].

Return value

The table name as a string.

Remarks

Table IDs may change during a schema upgrade. To correctly identify a table, access it by name or refresh the cached IDs after a schema upgrade.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULDatabaseSchema class
  • ULDatabaseSchema members
  • TableCount property


ULDataReader class

Represents a read-only bi-directional cursor in an UltraLite database. Cursors are sets of rows from either a table or the result set from a query.

Prototypes

' Visual Basic
Public Class ULDataReader
Inherits MarshalByRefObject
Implements IDataReader, IDisposable, IDataRecord,
IEnumerable

// C#
public class ULDataReader :
MarshalByRefobject, IDataReader, IDisposable,
IDataRecord, IEnumerable

Remarks

There is no constructor for ULDataReader. To get a ULDataReader object, execute a ULCommand class:

' Visual Basic
Dim cmd As ULCommand = new ULCommand( _
    "SELECT emp_id FROM employee", conn _
  )
Dim reader As ULDataReader = cmd.ExecuteReader()

// C#
ULCommand cmd = new ULCommand(
    "SELECT emp_id FROM employee", conn
  );
ULDataReader reader = cmd.ExecuteReader();

UL Ext.: The ADO.NET standard only requires forward-only motion through the result set, but ULDataReader is bi-directional. ULDataReader's Move methods provide you with full flexibility when moving through results.

ULDataReader is a read-only result set. If you need a more flexible object to manipulate results, use a ULDataAdapter class. The ULDataReader retrieves rows as needed, whereas the ULDataAdapter class must retrieve all rows of a result set before you can carry out any action on the object. For large result sets, this difference gives the ULDataReader a much faster response time.

UL Ext.: All columns of a ULDataReader may be retrieved using GetString method.

Implements: IDataReader, IDataRecord, IDisposable

ULDataReader members
Depth property
FieldCount property
IsBOF property
IsClosed property
IsEOF property
Item property
Item property
RecordsAffected property
RowCount property
Schema property
Close method
Dispose method
Finalize method
GetBoolean method
GetByte method
GetBytes method
GetBytes method
GetChar method
GetChars method
GetData method
GetDataTypeName method
GetDateTime method
GetDecimal method
GetDouble method
GetFieldType method
GetFloat method
GetGuid method
GetInt16 method
GetInt32 method
GetInt64 method
GetName method
GetOrdinal method
GetSchemaTable method
GetString method
GetTimeSpan method
GetUInt16 method
GetUInt32 method
GetUInt64 method
GetValue method
GetValues method
IsDBNull method
MoveAfterLast method
MoveBeforeFirst method
MoveFirst method
MoveLast method
MoveNext method
MovePrevious method
MoveRelative method
NextResult method
Read method


ULDataReader members

Public instance properties
Member | Description
Depth property | Returns the depth of nesting for the current row. The outermost table has a depth of zero.
FieldCount property | Returns the number of columns in the cursor.
IsBOF property | UL Ext.: Checks whether the current row position is before the first row or not.
IsClosed property | Checks whether the cursor is currently open.
IsEOF property | UL Ext.: Checks whether the current row position is after the last row or not.
Item property | Returns the value of the specified column in its native format. In C#, this property is the indexer for the ULDataReader class.
Item property | Returns the value of the specified named column in its native format. In C#, this property is the indexer for the ULDataReader class.
RecordsAffected property | Returns the number of rows changed, inserted, or deleted by execution of the SQL statement. For SELECT statements or CommandType.TableDirect tables, this value is -1.
RowCount property | UL Ext.: Returns the number of rows in the cursor.
Schema property | UL Ext.: Holds the schema of this cursor.
Public instance methods
Member | Description
Close method | Closes the cursor.
Dispose method | Releases the unmanaged resources used by the ULDataReader and optionally releases the managed resources.
GetBoolean method | Returns the value for the specified column as a Boolean.
GetByte method | Returns the value for the specified column as an unsigned 8-bit value (Byte).
GetBytes method | Copies a subset of the value for the specified ULDbType enumeration column, beginning at the specified offset, to the specified offset of the destination Byte array.
GetBytes method | UL Ext.: Returns the value for the specified column as an array of Bytes. Only valid for columns of type ULDbType enumeration, ULDbType enumeration, or ULDbType enumeration.
GetChar method | This method is not supported in UltraLite.NET.
GetChars method | Copies a subset of the value for the specified ULDbType enumeration column, beginning at the specified offset, to the specified offset of the destination System.Char array.
GetData method | This method is not supported in UltraLite.NET.
GetDataTypeName method | Returns the name of the specified column's provider data type.
GetDateTime method | Returns the value for the specified column as a DateTime with millisecond accuracy.
GetDecimal method | Returns the value for the specified column as a Decimal.
GetDouble method | Returns the value for the specified column as a Double.
GetFieldType method | Returns the Type most appropriate for the specified column.
GetFloat method | Returns the value for the specified column as a Single.
GetGuid method | Returns the value for the specified column as a UUID (Guid).
GetInt16 method | Returns the value for the specified column as an Int16.
GetInt32 method | Returns the value for the specified column as an Int32.
GetInt64 method | Returns the value for the specified column as an Int64.
GetName method | Returns the name of the specified column.
GetOrdinal method | Returns the column ID of the named column.
GetSchemaTable method | Returns a DataTable that describes the column metadata of the ULDataReader.
GetString method | Returns the value for the specified column as a String.
GetTimeSpan method | Returns the value for the specified column as a TimeSpan with millisecond accuracy.
GetUInt16 method | Returns the value for the specified column as a UInt16.
GetUInt32 method | Returns the value for the specified column as a UInt32.
GetUInt64 method | Returns the value for the specified column as a UInt64.
GetValue method | Returns the value of the specified column in its native format.
GetValues method | Returns all the column values for the current row.
IsDBNull method | Checks whether the value from the specified column is NULL.
MoveAfterLast method | UL Ext.: Positions the cursor to after the last row of the cursor.
MoveBeforeFirst method | UL Ext.: Positions the cursor to before the first row of the cursor.
MoveFirst method | UL Ext.: Positions the cursor to the first row of the cursor.
MoveLast method | UL Ext.: Positions the cursor to the last row of the cursor.
MoveNext method | UL Ext.: Positions the cursor to the next row or after the last row if the cursor was already on the last row.
MovePrevious method | UL Ext.: Positions the cursor to the previous row or before the first row.
MoveRelative method | UL Ext.: Positions the cursor relative to the current row.
NextResult method | Advances the ULDataReader to the next result when reading the results of batch SQL statements.
Read method | Positions the cursor to the next row, or after the last row if the cursor was already on the last row.
Protected instance methods
Member | Description
Finalize method | Releases the unmanaged resources used by the ULDataReader.


Depth property

Returns the depth of nesting for the current row. The outermost table has a depth of zero.

Prototypes

' Visual Basic
NotOverridable Public Readonly Property Depth As Integer _
Implements IDataReader.Depth

// C#
public int Depth {get;}

Property value

All UltraLite.NET result sets have a depth of zero.

Exceptions

  • ULException class - The ULDataReader is not opened.

Implements

IDataReader.Depth


FieldCount property

Returns the number of columns in the cursor.

Prototypes

' Visual Basic
NotOverridable Public Readonly Property FieldCount As Integer _
Implements IDataRecord.FieldCount

// C#
public int FieldCount {get;}

Return value

The number of columns in the cursor as an integer. Returns 0 if the cursor is closed.

Remarks

This method is identical to the ColumnCount property property.

Implements

IDataRecord.FieldCount


IsBOF property

UL Ext.: Checks whether the current row position is before the first row or not.

Prototypes

' Visual Basic
Public Readonly Property IsBOF As Boolean

// C#
public bool IsBOF {get;}

Property value

True if the current row position is before the first row, false otherwise.

Exceptions

  • ULException class - A SQL error occurred.


IsClosed property

Checks whether the cursor is currently open.

Prototypes

' Visual Basic
NotOverridable Public Readonly Property IsClosed As Boolean _
Implements IDataReader.IsClosed

// C#
public bool IsClosed {get;}

Property value

True if the cursor is currently open, false if the cursor is closed.

Implements

IDataReader.IsClosed


IsEOF property

UL Ext.: Checks whether the current row position is after the last row or not.

Prototypes

' Visual Basic
Public Readonly Property IsEOF As Boolean

// C#
public bool IsEOF {get;}

Property value

True if the current row position is after the last row, false otherwise.

Exceptions

  • ULException class - A SQL error occurred.


Item property

Returns the value of the specified column in its native format. In C#, this property is the indexer for the ULDataReader class.

Prototypes

' Visual Basic
NotOverridable Public Readonly Property Item As Object _
Implements IDataRecord.Item

// C#
public object Item {get;}

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as the .NET type most appropriate for the column or DBNull if column is NULL.

Remarks

This method is identical in functionality to the GetValue method method.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.Item

See also
  • ULDataReader class
  • ULDataReader members
  • GetFieldType method
  • Item property


Item property

Returns the value of the specified named column in its native format. In C#, this property is the indexer for the ULDataReader class.

Prototypes

' Visual Basic
NotOverridable Public Readonly Property Item As Object _
Implements IDataRecord.Item

// C#
public object Item {get;}

Parameters

  • name The name of the column.

Return value

The column value as the .NET type most appropriate for the column or DBNull if column is NULL.

Remarks

Note that in result sets, not all columns have names and not all column names are unique. If you are not using aliases, the name of a non-computed column is prefixed with the name of the table the column is from. For example, MyTable.ID is the name of the only column in the result set for the query "SELECT ID FROM MyTable".

When accessing columns multiple times, it is more efficient to access columns by column ID than by name.

This method is equivalent to:

dataReader.GetValue( dataReader.GetOrdinal( name ) )
Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.Item

See also
  • ULDataReader class
  • ULDataReader members
  • Item property
  • GetOrdinal method
  • GetValue method
  • GetFieldType method


RecordsAffected property

Returns the number of rows changed, inserted, or deleted by execution of the SQL statement. For SELECT statements or CommandType.TableDirect tables, this value is -1.

Prototypes

' Visual Basic
NotOverridable Public Readonly Property RecordsAffected As Integer _
Implements IDataReader.RecordsAffected

// C#
public int RecordsAffected {get;}

Property value

The number of rows changed, inserted, or deleted by execution of the SQL statement.

Implements

IDataReader.RecordsAffected


RowCount property

UL Ext.: Returns the number of rows in the cursor.

Prototypes

' Visual Basic
Public Readonly Property RowCount As Integer

// C#
public int RowCount {get;}

Property value

The number of rows in the cursor.

Remarks

One use for RowCount is to decide when to delete old rows to save space. Old rows can be deleted from the UltraLite database without being deleted from the consolidated database using the StopSynchronizationDelete method method.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULDataReader class
  • ULDataReader members
  • StartSynchronizationDelete method
  • StopSynchronizationDelete method


Schema property

UL Ext.: Holds the schema of this cursor.

Prototypes

' Visual Basic
Public Readonly Property Schema As ULCursorSchema

// C#
public ULCursorSchema Schema {get;}

Property value

For result sets, the ULResultSetSchema class object representing the schema of the result set. For tables, the ULTableSchema class object representing the schema of the table.

Remarks

This property represents the complete schema of the cursor, including UltraLite.NET extended information which is not represented in the results from GetSchemaTable method.


Close method

Closes the cursor.

Prototypes

' Visual Basic
NotOverridable Public Sub Close() _
Implements IDataReader.Close

// C#
public void Close();

Remarks

It is not an error to close a cursor that is already closed.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataReader.Close


Dispose method

Releases the unmanaged resources used by the ULDataReader and optionally releases the managed resources.

Prototypes

' Visual Basic
Overloads NotOverridable Public Sub Dispose() _
Implements IDisposable.Dispose

// C#
public void Dispose();

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDisposable.Dispose


Finalize method

Releases the unmanaged resources used by the ULDataReader.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


GetBoolean method

Returns the value for the specified column as a Boolean.

Prototypes

' Visual Basic
NotOverridable Public Function GetBoolean( _
ByVal columnID As Integer _
) As Boolean _
Implements IDataRecord.GetBoolean

// C#
public bool GetBoolean(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as a Boolean.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetBoolean

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetByte method

Returns the value for the specified column as an unsigned 8-bit value (Byte).

Prototypes

' Visual Basic
NotOverridable Public Function GetByte( _
ByVal columnID As Integer _
) As Byte _
Implements IDataRecord.GetByte

// C#
public byte GetByte(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as a Byte.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetByte

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetBytes method

Copies a subset of the value for the specified ULDbType enumeration column, beginning at the specified offset, to the specified offset of the destination Byte array.

Prototypes

' Visual Basic
Overloads NotOverridable Public Function GetBytes( _
ByVal columnID As Integer, _
ByVal srcOffset As Long, _
ByVal dst As Byte(), _
ByVal dstOffset As Integer, _
ByVal count As Integer _
) As Long _
Implements IDataRecord.GetBytes

// C#
public long GetBytes(
int columnID,
long srcOffset,
byte[] dst,
int dstOffset,
int count
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • srcOffset The start position in the column value. Zero is the beginning of the value.

  • dst The destination array.

  • dstOffset The start position in the destination array.

  • count The number of bytes to be copied.

Return value

The actual number of bytes copied.

Remarks

If you pass a dst buffer that is a null reference (Nothing in Visual Basic), GetBytes returns the length of the field in bytes.

The bytes at position srcOffset through srcOffset+count-1 of the value are copied into positions dstOffset through dstOffset+count-1, respectively, of the destination array. If the end of the value is encountered before count bytes are copied, the remainder of the destination array is left unchanged.

If any of the following is true, a ULException class with code ULSQLCode enumeration is thrown and the destination is not modified:

  • srcOffset is negative.
  • dstOffset is negative.
  • count is negative.
  • dstOffset+count is greater than dst.Length.

For other errors, a ULException class with the appropriate error code is thrown.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetBytes

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method
  • GetBytes method


GetBytes method

UL Ext.: Returns the value for the specified column as an array of Bytes. Only valid for columns of type ULDbType enumeration, ULDbType enumeration, or ULDbType enumeration.

Prototypes

' Visual Basic
Overloads Public Function GetBytes( _
ByVal columnID As Integer _
) As Byte()

// C#
public byte[] GetBytes(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as an array of Bytes.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method
  • GetBytes method


GetChar method

This method is not supported in UltraLite.NET.

Prototypes

' Visual Basic
NotOverridable Public Function GetChar( _
ByVal columnID As Integer _
) As Char _
Implements IDataRecord.GetChar

// C#
public char GetChar(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

This method is not supported in UltraLite.NET.

Exceptions

  • ULException class - This method is not supported in UltraLite.NET.

Implements

IDataRecord.GetChar

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method
  • GetString method


GetChars method

Copies a subset of the value for the specified ULDbType enumeration column, beginning at the specified offset, to the specified offset of the destination System.Char array.

Prototypes

' Visual Basic
NotOverridable Public Function GetChars( _
ByVal columnID As Integer, _
ByVal srcOffset As Long, _
ByVal dst As Char(), _
ByVal dstOffset As Integer, _
ByVal count As Integer _
) As Long _
Implements IDataRecord.GetChars

// C#
public long GetChars(
int columnID,
long srcOffset,
char[] dst,
int dstOffset,
int count
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • srcOffset The start position in the column value. Zero is the beginning of the value.

  • dst The destination array.

  • dstOffset The start position in the destination array.

  • count The number of characters to be copied.

Return value

The actual number of characters copied.

Remarks

If you pass a dst buffer that is a null reference (Nothing in Visual Basic), GetChars returns the length of the field in characters.

The characters at position srcOffset through srcOffset+count-1 of the value are copied into positions dstOffset through dstOffset+count-1, respectively, of the destination array. If the end of the value is encountered before count characters are copied, the remainder of the destination array is left unchanged.

If any of the following is true, a ULException class with code ULSQLCode enumeration is thrown and the destination is not modified:

  • srcOffset is negative.
  • dstOffset is negative.
  • count is negative.
  • dstOffset+count is greater than dst.Length.

For other errors, a ULException class with the appropriate error code is thrown.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetChars

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetData method

This method is not supported in UltraLite.NET.

Prototypes

' Visual Basic
NotOverridable Public Function GetData( _
ByVal i As Integer _
) As IDataReader _
Implements IDataRecord.GetData

// C#
public IDataReader GetData(
int i
);

Parameters

  • i An integer value.

Return value

This method is not supported in UltraLite.NET.

Exceptions

  • ULException class - This method is not supported in UltraLite.NET.

Implements

IDataRecord.GetData


GetDataTypeName method

Returns the name of the specified column's provider data type.

Prototypes

' Visual Basic
NotOverridable Public Function GetDataTypeName( _
ByVal columnID As Integer _
) As String _
Implements IDataRecord.GetDataTypeName

// C#
public string GetDataTypeName(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

A string corresponding to the column's ULDbType enumeration.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetDataTypeName

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetColumnULDbType method


GetDateTime method

Returns the value for the specified column as a DateTime with millisecond accuracy.

Prototypes

' Visual Basic
NotOverridable Public Function GetDateTime( _
ByVal columnID As Integer _
) As Date _
Implements IDataRecord.GetDate

// C#
public DateTime GetDateTime(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as a DateTime.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetDateTime

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetDecimal method

Returns the value for the specified column as a Decimal.

Prototypes

' Visual Basic
NotOverridable Public Function GetDecimal( _
ByVal columnID As Integer _
) As Decimal _
Implements IDataRecord.GetDecimal

// C#
public decimal GetDecimal(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as a Decimal.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetDecimal

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetDouble method

Returns the value for the specified column as a Double.

Prototypes

' Visual Basic
NotOverridable Public Function GetDouble( _
ByVal columnID As Integer _
) As Double _
Implements IDataRecord.GetDouble

// C#
public double GetDouble(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as a Double.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetDouble

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetFieldType method

Returns the Type most appropriate for the specified column.

Prototypes

' Visual Basic
NotOverridable Public Function GetFieldType( _
ByVal columnID As Integer _
) As Type _
Implements IDataRecord.GetFieldType

// C#
public Type GetFieldType(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

A Type value for the column.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetFieldType

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetDataTypeName method
  • GetColumnULDbType method


GetFloat method

Returns the value for the specified column as a Single.

Prototypes

' Visual Basic
NotOverridable Public Function GetFloat( _
ByVal columnID As Integer _
) As Single _
Implements IDataRecord.GetFloat

// C#
public float GetFloat(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as a Single.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetFloat

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetGuid method

Returns the value for the specified column as a UUID (Guid).

Prototypes

' Visual Basic
NotOverridable Public Function GetGuid( _
ByVal columnID As Integer _
) As Guid _
Implements IDataRecord.GetGuid

// C#
public Guid GetGuid(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as a Guid.

Remarks

This method is only valid for columns of type ULDbType enumeration or for columns of type ULDbType enumeration with length 16.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetGuid

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method
  • GetColumnULDbType method
  • GetColumnSize method


GetInt16 method

Returns the value for the specified column as an Int16.

Prototypes

' Visual Basic
NotOverridable Public Function GetInt16( _
ByVal columnID As Integer _
) As Short _
Implements IDataRecord.GetShort

// C#
public short GetInt16(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as an Int16.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetInt16

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetInt32 method

Returns the value for the specified column as an Int32.

Prototypes

' Visual Basic
NotOverridable Public Function GetInt32( _
ByVal columnID As Integer _
) As Integer _
Implements IDataRecord.GetInteger

// C#
public int GetInt32(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as an Int32.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetInt32

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetInt64 method

Returns the value for the specified column as an Int64.

Prototypes

' Visual Basic
NotOverridable Public Function GetInt64( _
ByVal columnID As Integer _
) As Long _
Implements IDataRecord.GetLong

// C#
public long GetInt64(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as an Int64

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetInt64

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetName method

Returns the name of the specified column.

Prototypes

' Visual Basic
NotOverridable Public Function GetName( _
ByVal columnID As Integer _
) As String _
Implements IDataRecord.GetName

// C#
public string GetName(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The name of the column or a null reference (Nothing in Visual Basic) if the column has no name. If the column is aliased in the SQL query, the alias is returned.

Remarks

Note that in result sets, not all columns have names and not all column names are unique. If you are not using aliases, the name of a non-computed column is prefixed with the name of the table the column is from. For example, MyTable.ID is the name of the only column in the result set for the query "SELECT ID FROM MyTable".

This method is identical to the GetColumnName method method.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetName

See also
  • ULDataReader class
  • ULDataReader members
  • FieldCount property
  • GetSchemaTable method


GetOrdinal method

Returns the column ID of the named column.

Prototypes

' Visual Basic
NotOverridable Public Function GetOrdinal( _
ByVal columnName As String _
) As Integer _
Implements IDataRecord.GetOrdinal

// C#
public int GetOrdinal(
string columnName
);

Parameters

  • columnName The name of the column.

Return value

The column ID of the named column.

Remarks

Column IDs range from 0 to FieldCount property -1, inclusively.

Note that in result sets, not all columns have names and not all column names are unique. If you are not using aliases, the name of a non-computed column is prefixed with the name of the table the column is from. For example, MyTable.ID is the name of the only column in the result set for the query "SELECT ID FROM MyTable".

Column IDs and counts may change during a schema upgrade. To correctly identify a column, access it by name or refresh the cached IDs and counts after a schema upgrade.

This method is identical to the GetColumnID method method.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetOrdinal

See also
  • ULDataReader class
  • ULDataReader members
  • GetSchemaTable method


GetSchemaTable method

Returns a DataTable that describes the column metadata of the ULDataReader.

Prototypes

' Visual Basic
NotOverridable Public Function GetSchemaTable() As DataTable _
Implements IDataReader.GetSchemaTable

// C#
public DataTable GetSchemaTable();

Return value

A DataTable describing the schema of each column in the ULDataReader.

Remarks

The GetSchemaTable method returns metadata about each column in the following order:

DataTable Column | Description
ColumnName | The name of the column or a null reference (Nothing in Visual Basic) if the column has no name. If the column is aliased in the SQL query, the alias is returned. Note that in result sets, not all columns have names and not all column names are unique.
ColumnOrdinal | The ID of the column. The value is in the range [0,FieldCount property -1].
ColumnSize | For sized columns, the maximum length of a value in the column. For other columns, this is the size in bytes of the data type.
NumericPrecision | The precision of a numeric column (ProviderType ULDbType enumeration or ULDbType enumeration) or DBNull if the column is not numeric.
NumericScale | The scale of a numeric column (ProviderType ULDbType enumeration or ULDbType enumeration) or DBNull if the column is not numeric.
IsUnique | True if the column is a non-computed unique column in the table (BaseTableName) it is taken from.
IsKey | True if the column is one of a set of columns in the result set that taken together from a unique key for the result set. The set of columns with IsKey set to true does not need to be the minimal set that uniquely identifies a row in the result set.
BaseCatalogName | The name of the catalog in the database that contains the column. For UltraLite.NET, this value is always DBNull.
BaseColumnName | The original name of the column in the table BaseTableName of the database or DBNull if the column is computed or if this information cannot be determined.
BaseSchemaName | The name of the schema in the database that contains the column. For UltraLite.NET, this value is always DBNull.
BaseTableName | The name of the table in the database that contains the column, or DBNull if column is computed or if this information cannot be determined.
DataType | The .NET data type that is most appropriate for this type of column.
AllowDBNull | True if the column is nullable, false if the column is not nullable or if this information can not be determined.
ProviderType | The ULDbType enumeration of the column.
IsIdentity | True if the column is an identity column, false if it is not an identity column. For UltraLite.NET, this value is always false.
IsAutoIncrement | True if the column is an autoincrement or global autoincrement column, false otherwise (or if this information can not be determined).
IsRowVersion | True if the column contains a persistent row identifier that cannot be written to, and has no meaningful value except to identity the row. For UltraLite.NET, this value is always false.
IsLong | True if the column is a ULDbType enumeration or a ULDbType enumeration column, false otherwise.
IsReadOnly | True if the column is read-only, false if the column is modifiable or if its access cannot be determined.
Implements

IDataReader.GetSchemaTable

See also
  • ULDataReader class
  • ULDataReader members
  • Schema property


GetString method

Returns the value for the specified column as a String.

Prototypes

' Visual Basic
NotOverridable Public Function GetString( _
ByVal columnID As Integer _
) As String _
Implements IDataRecord.GetString

// C#
public string GetString(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as a String.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetString

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetTimeSpan method

Returns the value for the specified column as a TimeSpan with millisecond accuracy.

Prototypes

' Visual Basic
Public Function GetTimeSpan( _
ByVal columnID As Integer _
) As TimeSpan

// C#
public TimeSpan GetTimeSpan(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as a TimeSpan.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetUInt16 method

Returns the value for the specified column as a UInt16.

Prototypes

' Visual Basic
Public Function GetUInt16( _
ByVal columnID As Integer _
) As UInt16

// C#
public ushort GetUInt16(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as an UInt16.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetUInt32 method

Returns the value for the specified column as a UInt32.

Prototypes

' Visual Basic
Public Function GetUInt32( _
ByVal columnID As Integer _
) As UInt32

// C#
public uint GetUInt32(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as an UInt32.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetUInt64 method

Returns the value for the specified column as a UInt64.

Prototypes

' Visual Basic
Public Function GetUInt64( _
ByVal columnID As Integer _
) As UInt64

// C#
public ulong GetUInt64(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as a UInt64

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetValue method

Returns the value of the specified column in its native format.

Prototypes

' Visual Basic
NotOverridable Public Function GetValue( _
ByVal columnID As Integer _
) As Object _
Implements IDataRecord.GetValue

// C#
public object GetValue(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

The column value as the .NET type most appropriate for the column or DBNull if column is NULL.

Remarks

This method is identical in functionality to the Item property property.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.GetValue

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


GetValues method

Returns all the column values for the current row.

Prototypes

' Visual Basic
NotOverridable Public Function GetValues( _
ByVal values As Object() _
) As Integer _
Implements IDataRecord.GetValues

// C#
public int GetValues(
object[] values
);

Parameters

  • values The array of Objects to hold the entire row.

Return value

The number of column values retrieved. If the length of the array is greater than the number of columns (FieldCount property), only FieldCount items are retrieved and the rest of the array is left unchanged.

Remarks

For most applications, the GetValues method provides an efficient means for retrieving all columns, rather than retrieving each column individually.

You can pass an Object array that contains fewer than the number of columns contained in the resulting row. Only the amount of data the Object array holds is copied to the array. You can also pass an Object array whose length is more than the number of columns contained in the resulting row.

This method returns DBNull for NULL database columns. For other columns, it returns the value of the column in its native format.

Exceptions

  • ULException class - A SQL error occurred.

  • System.ArgumentNullException - The values array is NULL or has zero length.

Implements

IDataRecord.GetValues

See also
  • ULDataReader class
  • ULDataReader members
  • FieldCount property
  • GetFieldType method
  • GetValue method


IsDBNull method

Checks whether the value from the specified column is NULL.

Prototypes

' Visual Basic
NotOverridable Public Function IsDBNull( _
ByVal columnID As Integer _
) As Boolean _
Implements IDataRecord.IsDBNull

// C#
public bool IsDBNull(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Return value

True if value is NULL, false if value is not NULL.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataRecord.IsDBNull

See also
  • ULDataReader class
  • ULDataReader members
  • GetOrdinal method
  • GetFieldType method


MoveAfterLast method

UL Ext.: Positions the cursor to after the last row of the cursor.

Prototypes

' Visual Basic
Public Sub MoveAfterLast()

// C#
public void MoveAfterLast();

Exceptions

  • ULException class - A SQL error occurred.


MoveBeforeFirst method

UL Ext.: Positions the cursor to before the first row of the cursor.

Prototypes

' Visual Basic
Public Sub MoveBeforeFirst()

// C#
public void MoveBeforeFirst();

Exceptions

  • ULException class - A SQL error occurred.


MoveFirst method

UL Ext.: Positions the cursor to the first row of the cursor.

Prototypes

' Visual Basic
Public Function MoveFirst() As Boolean

// C#
public bool MoveFirst();

Return value

True if successful, false otherwise. For example, the method fails if there are no rows.

Exceptions

  • ULException class - A SQL error occurred.


MoveLast method

UL Ext.: Positions the cursor to the last row of the cursor.

Prototypes

' Visual Basic
Public Function MoveLast() As Boolean

// C#
public bool MoveLast();

Return value

True if successful, false otherwise. For example, the method fails if there are no rows.

Exceptions

  • ULException class - A SQL error occurred.


MoveNext method

UL Ext.: Positions the cursor to the next row or after the last row if the cursor was already on the last row.

Prototypes

' Visual Basic
Public Function MoveNext() As Boolean

// C#
public bool MoveNext();

Return value

True if successful, false otherwise. For example, the method fails if there are no more rows.

Remarks

This method is identical to the Read method method.

Exceptions

  • ULException class - A SQL error occurred.


MovePrevious method

UL Ext.: Positions the cursor to the previous row or before the first row.

Prototypes

' Visual Basic
Public Function MovePrevious() As Boolean

// C#
public bool MovePrevious();

Return value

True if successful, false otherwise. For example, the method fails if there are no more rows.

Exceptions

  • ULException class - A SQL error occurred.


MoveRelative method

UL Ext.: Positions the cursor relative to the current row.

Prototypes

' Visual Basic
Public Function MoveRelative( _
ByVal offset As Integer _
) As Boolean

// C#
public bool MoveRelative(
int offset
);

Parameters

  • offset The number of rows to move. Negative values correspond to moving backwards.

Return value

True if successful, false otherwise. For example, the method fails if it positions beyond the first or last row.

Remarks

If the row does not exist, the method returns false, and the cursor position is after the last row (IsEOF property) if offset is positive, and before the first row (IsBOF property) if the offset is negative.

Exceptions

  • ULException class - A SQL error occurred.


NextResult method

Advances the ULDataReader to the next result when reading the results of batch SQL statements.

Prototypes

' Visual Basic
NotOverridable Public Function NextResult() As Boolean _
Implements IDataReader.NextResult

// C#
public bool NextResult();

Return value

True if there are more result sets, false otherwise. For UltraLite.NET, always returns false.

Remarks

UL Ext.: UltraLite.NET does not support batches of SQL statements, hence the ULDataReader is always positioned on the first and only result set. Calling NextResult has no effect.

Exceptions

  • ULException class - The ULDataReader is not opened.

Implements

IDataReader.NextResult


Read method

Positions the cursor to the next row, or after the last row if the cursor was already on the last row.

Prototypes

' Visual Basic
NotOverridable Public Function Read() As Boolean _
Implements IDataReader.Read

// C#
public bool Read();

Return value

True if successful, false otherwise. For example, the method fails if there are no more rows.

Remarks

This method is identical to the MoveNext method method.

Exceptions

  • ULException class - A SQL error occurred.

Implements

IDataReader.Read


ULDbType enumeration

Enumerates the UltraLite.NET database data types.

Prototypes

' Visual Basic
Public Enum ULDbType

// C#
public enum ULDbType

Remarks

The table below lists which .NET types are compatible with each ULDbType. In the case of integral types, table columns can always be set using smaller integer types, but can also be set using larger types as long as the actual value is within the range of the type.

ULDbType | Compatible .NET type | C# built-in type | Visual Basic built-in type
Binary, VarBinary | System.Byte[], or System.Guid if size is 16 | byte[] | Byte()
Bit | System.Boolean | bool | Boolean
Char, VarChar | System.String | String | String
Date | System.DateTime | DateTime No built-in type. | Date
Double | System.Double | double | Double
LongBinary | System.Byte[] | byte[] | Byte()
LongVarchar | System.String | String | String
Decimal, Numeric | System.String | decimal | Decimal
Float, Real | System.Single | float | Single
BigInt | System.Int64 | long | Long
Integer | System.Int32 | int | Integer
SmallInt | System.Int16 | short | Short
Time | System.TimeSpan | TimeSpan No built-in type. | TimeSpan No built-in type.
DateTime, TimeStamp | System.DateTime | DateTime No built-in type. | Date
TinyInt | System.Byte | byte | Byte
UnsignedBigInt | System.UInt64 | ulong | UInt64 No built-in type.
UnsignedInt | System.UInt32 | uint | UInt32 No built-in type.
UnsignedSmallInt | System.UInt16 | ushort | UInt16 No built-in type.
UniqueIdentifier | System.Guid | Guid No built-in type. | Guid No built-in type.

Binary columns of length 16 are fully compatible with the UniqueIdentifier type.

Members
Member | Description
BigInt | Signed 64-bit integer.
Binary | Binary data, with a specified maximum length. The enumeration values Binary and VarBinary are aliases of each other.
Bit | 1-bit flag.
Char | Character data, with a specified length. In UltraLite.NET, this type always supports Unicode characters. The types Char and VarChar are fully compatible.
Date | Date information.
DateTime | Timestamp information (date, time). The enumeration values DateTime and TimeStamp are aliases of each other.
Decimal | Exact numerical data, with a specified precision and scale. The enumeration values Decimal and Numeric are aliases of each other.
Double | Double precision floating point number (8 bytes).
Float | Single precision floating point number (4 bytes). The enumeration values Float and Real are aliases of each other.
Integer | Unsigned 32-bit integer.
LongBinary | Binary data, with variable length.
LongVarchar | Character data, with variable length. In UltraLite.NET, this type always supports Unicode characters.
Numeric | Exact numerical data, with a specified precision and scale. The enumeration values Decimal and Numeric are aliases of each other.
Real | Single precision floating point number (4 bytes). The enumeration values Float and Real are aliases of each other.
SmallInt | Signed 16-bit integer.
Time | Time information.
TimeStamp | Timestamp information (date, time). The enumeration values DateTime and TimeStamp are aliases of each other.
TinyInt | Unsigned 8-bit integer.
UniqueIdentifier | Universally Unique Identifier (UUID/GUID).
UnsignedBigInt | Unsigned 64-bit integer.
UnsignedInt | Unsigned 32-bit integer.
UnsignedSmallInt | Unsigned 16-bit integer.
VarBinary | Binary data, with a specified maximum length. The enumeration values Binary and VarBinary are aliases of each other.
VarChar | Character data, with a specified maximum length. In UltraLite.NET, this type always supports Unicode characters. The types Char and VarChar are fully compatible.
See also
  • GetFieldType method
  • GetDataTypeName method
  • GetColumnULDbType method


ULException class

Represents a SQL error returned by the UltraLite.NET database.

Prototypes

' Visual Basic
Public Class ULException
Inherits ApplicationException

// C#
public class ULException :
ApplicationException

Remarks

This class is not serializable under the .NET Compact Framework.


ULException members

Public instance constructors
Member | Description
ULException constructor | Creates a ULException with the given error code.
Public instance properties
Member | Description
HelpLink (inherited from Exception) | Gets or sets a link to the help file associated with this exception.
InnerException (inherited from Exception) | Gets the System.Exception instance that caused the current exception.
Message (inherited from Exception) | Gets a message that describes the current exception.
NativeError property | Returns the SQL code returned by the database.
Source property | Returns the name of the provider that generated the error.
StackTrace (inherited from Exception) | Gets a string representation of the frames on the call stack at the time the current exception was thrown.
TargetSite (inherited from Exception) | Gets the method that throws the current exception.
Public instance methods
Member | Description
GetBaseException (inherited from Exception) | When overridden in a derived class, returns the System.Exception that is the root cause of one or more subsequent exceptions.
GetObjectData method | Populates a SerializationInfo with the data needed to serialize this ULException.
ToString (inherited from Exception) | Creates and returns a string representation of the current exception.
Protected instance properties
Member | Description
HResult (inherited from Exception) | Gets or sets HRESULT, a coded numerical value that is assigned to a specific exception.


ULException constructor

Creates a ULException with the given error code.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal code As ULSQLCode, _
ByVal s1 As String, _
ByVal s2 As String, _
ByVal s3 As String _
)

// C#
public ULException(
ULSQLCode code,
string s1,
string s2,
string s3
);

Parameters

  • code The code of the exception.

  • s1 The first string for the formatted message.

  • s2 The second string for the formatted message.

  • s3 The third string for the formatted message.

Remarks

The message string corresponding to the specified ULSQLCode enumeration is retrieved from the iAnywhere.Data.UltraLite.resources assembly. Resources are searched for, by culture, using the following order: System.Globalization.CultureInfo.CurrentUICulture, then System.Globalization.CultureInfo.CurrentCulture, and finally culture "EN".


NativeError property

Returns the SQL code returned by the database.

Prototypes

' Visual Basic
Public Readonly Property NativeError As ULSQLCode

// C#
public ULSQLCode NativeError {get;}

Property value

The ULSQLCode enumeration value returned by the database.


Source property

Returns the name of the provider that generated the error.

Prototypes

' Visual Basic
Public Readonly Property Source As String

// C#
public string Source {get;}

Property value

The string value identifying UltraLite.NET as the provider.


GetObjectData method

Populates a SerializationInfo with the data needed to serialize this ULException.

Prototypes

' Visual Basic
Overrides Public Sub GetObjectData( _
ByVal info As System.Runtime.Serialization.SerializationInfo, _
ByVal context As System.Runtime.Serialization.StreamingContext _
) _
Implements ISerializable.GetObjectData

// C#
public override void GetObjectData(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context
);

Parameters

  • info The SerializationInfo to populate with data.

  • context The destination for this serialization.

Remarks

This method is not supported under the .NET Compact Framework.

Implements

ISerializable.GetObjectData


ULIndexSchema class

UL Ext.: Represents the schema of an UltraLite table index.

Prototypes

' Visual Basic
NotInheritable Public Class ULIndexSchema

// C#
public sealed class ULIndexSchema

Remarks

This class cannot be directly instantiated. Index schemas are created using the PrimaryKey property, GetIndex method, and GetOptimalIndex method methods of the ULTableSchema class class.

ULIndexSchema members
ColumnCount property
IsForeignKey property
IsForeignKeyCheckOnCommit property
IsForeignKeyNullable property
IsOpen property
IsPrimaryKey property
IsUniqueIndex property
IsUniqueKey property
Name property
ReferencedIndexName property
ReferencedTableName property
Finalize method
GetColumnName method
IsColumnDescending method


ULIndexSchema members

Public instance properties
Member | Description
ColumnCount property | Returns the number of columns in the index.
IsForeignKey property | Checks whether the index is a foreign key.
IsForeignKeyCheckOnCommit property | Checks whether referential integrity for the foreign key is performed on commits or on inserts and updates.
IsForeignKeyNullable property | Checks whether the foreign key is nullable.
IsOpen property | Determines whether the index schema is open or closed.
IsPrimaryKey property | Checks whether the index is the primary key.
IsUniqueIndex property | Checks whether the index is unique.
IsUniqueKey property | Checks whether the index is a unique key.
Name property | Returns the name of the index.
ReferencedIndexName property | The name of the referenced primary index if the index is a foreign key.
ReferencedTableName property | The name of the referenced primary table if the index is a foreign key.
Public instance methods
Member | Description
GetColumnName method | Returns the name of the colOrdinalInIndex'th column in this index.
IsColumnDescending method | Checks whether the named column is used in descending order by the index.
Protected instance methods
Member | Description
Finalize method | Releases the unmanaged resources used by ULIndexSchema.


ColumnCount property

Returns the number of columns in the index.

Prototypes

' Visual Basic
Public Readonly Property ColumnCount As Short

// C#
public short ColumnCount {get;}

Property value

The number of columns in the index.

Remarks

Column ordinals in indexes range from 1 to ColumnCount, inclusively.

Column ordinals and count may change during a schema upgrade. Column ordinals from an index are different than the column IDs in a table or another index, even if they refer to the same physical column in a particular table.


IsForeignKey property

Checks whether the index is a foreign key.

Prototypes

' Visual Basic
Public Readonly Property IsForeignKey As Boolean

// C#
public bool IsForeignKey {get;}

Property value

True if the index is the foreign key, false if the index is not the foreign key.

Remarks

Columns in a foreign key may reference another table's non-null, unique index.

Exceptions

  • ULException class - A SQL error occurred.


IsForeignKeyCheckOnCommit property

Checks whether referential integrity for the foreign key is performed on commits or on inserts and updates.

Prototypes

' Visual Basic
Public Readonly Property IsForeignKeyCheckOnCommit As Boolean

// C#
public bool IsForeignKeyCheckOnCommit {get;}

Property value

True if referential integrity is checked on commits, false if it is checked on inserts and updates.

Exceptions

  • ULException class - A SQL error occurred (including index is not a foreign key).

See also
  • ULIndexSchema class
  • ULIndexSchema members
  • IsForeignKey property


IsForeignKeyNullable property

Checks whether the foreign key is nullable.

Prototypes

' Visual Basic
Public Readonly Property IsForeignKeyNullable As Boolean

// C#
public bool IsForeignKeyNullable {get;}

Property value

True if the foreign key is nullable, false if the foreign key is not nullable.

Exceptions

  • ULException class - A SQL error occurred (including index is not a foreign key).

See also
  • ULIndexSchema class
  • ULIndexSchema members
  • IsForeignKey property


IsOpen property

Determines whether the index schema is open or closed.

Prototypes

' Visual Basic
Public Readonly Property IsOpen As Boolean

// C#
public bool IsOpen {get;}

Property value

True if the index schema is open, otherwise false.


IsPrimaryKey property

Checks whether the index is the primary key.

Prototypes

' Visual Basic
Public Readonly Property IsPrimaryKey As Boolean

// C#
public bool IsPrimaryKey {get;}

Property value

True if the index is the primary key, false if the index is not the primary key.

Remarks

Columns in the primary key may not be null.

Exceptions

  • ULException class - A SQL error occurred.


IsUniqueIndex property

Checks whether the index is unique.

Prototypes

' Visual Basic
Public Readonly Property IsUniqueIndex As Boolean

// C#
public bool IsUniqueIndex {get;}

Property value

True if the index is unique, false if the index is not unique.

Remarks

Columns in a unique index may be null.

Exceptions

  • ULException class - A SQL error occurred.


IsUniqueKey property

Checks whether the index is a unique key.

Prototypes

' Visual Basic
Public Readonly Property IsUniqueKey As Boolean

// C#
public bool IsUniqueKey {get;}

Property value

True if the index is a unique key, false if the index is not a unique key.

Remarks

Columns in a unique key may not be null.

Exceptions

  • ULException class - A SQL error occurred.


Name property

Returns the name of the index.

Prototypes

' Visual Basic
Public Readonly Property Name As String

// C#
public string Name {get;}

Property value

A string specifying the name of the index.

Exceptions

  • ULException class - A SQL error occurred.


ReferencedIndexName property

The name of the referenced primary index if the index is a foreign key.

Prototypes

' Visual Basic
Public Readonly Property ReferencedIndexName As String

// C#
public string ReferencedIndexName {get;}

Property value

A string specifying the name of the referenced primary index.

Exceptions

  • ULException class - A SQL error occurred (including index is not a foreign key).

See also
  • ULIndexSchema class
  • ULIndexSchema members
  • IsForeignKey property


ReferencedTableName property

The name of the referenced primary table if the index is a foreign key.

Prototypes

' Visual Basic
Public Readonly Property ReferencedTableName As String

// C#
public string ReferencedTableName {get;}

Property value

A string specifying the name of the referenced primary table.

Exceptions

  • ULException class - A SQL error occurred (including index is not a foreign key).

See also
  • ULIndexSchema class
  • ULIndexSchema members
  • IsForeignKey property


Finalize method

Releases the unmanaged resources used by ULIndexSchema.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


GetColumnName method

Returns the name of the colOrdinalInIndex'th column in this index.

Prototypes

' Visual Basic
Public Function GetColumnName( _
ByVal colOrdinalInIndex As Short _
) As String

// C#
public string GetColumnName(
short colOrdinalInIndex
);

Parameters

  • colOrdinalInIndex The ordinal of the desired column in the index. The value must be in the range [1,ColumnCount property].

Return value

The name of the column.

Remarks

Column ordinals and count may change during a schema upgrade. Column ordinals from an index are different than the column IDs in a table or another index, even if they refer to the same physical column in a particular table.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULIndexSchema class
  • ULIndexSchema members
  • ColumnCount property


IsColumnDescending method

Checks whether the named column is used in descending order by the index.

Prototypes

' Visual Basic
Public Function IsColumnDescending( _
ByVal name As String _
) As Boolean

// C#
public bool IsColumnDescending(
string name
);

Parameters

  • name The name of the column.

Return value

True if the column is used in descending order, false if the column is used in ascending order.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULIndexSchema class
  • ULIndexSchema members
  • GetColumnName method
  • ColumnCount property


ULInfoMessageEventArgs class

Provides data for the InfoMessage event event.

Prototypes

' Visual Basic
NotInheritable Public Class ULInfoMessageEventArgs
Inherits EventArgs

// C#
public sealed class ULInfoMessageEventArgs :
EventArgs


ULInfoMessageEventArgs members

Public instance properties
Member | Description
Message property | The informational or warning message string returned by the database.
NativeError property | The SQL code corresponding to the informational message or warning returned by the database.
Source property | The name of the ADO.NET data provider returning the message.
Public instance methods
Member | Description
ToString method | Returns the string representation of the InfoMessage event event.


Message property

The informational or warning message string returned by the database.

Prototypes

' Visual Basic
Public Readonly Property Message As String

// C#
public string Message {get;}

Property value

A string containing the informational or warning message.


NativeError property

The SQL code corresponding to the informational message or warning returned by the database.

Prototypes

' Visual Basic
Public Readonly Property NativeError As ULSQLCode

// C#
public ULSQLCode NativeError {get;}

Property value

An informational or warning ULSQLCode enumeration value.


Source property

The name of the ADO.NET data provider returning the message.

Prototypes

' Visual Basic
Public Readonly Property Source As String

// C#
public string Source {get;}

Property value

The string "UltraLite.NET Data Provider".


ToString method

Returns the string representation of the InfoMessage event event.

Prototypes

' Visual Basic
Overrides Public Function ToString() As String

// C#
public override string ToString();

Property value

The string "UltraLite.NET Data Provider".

Return value

The informational or warning message string.


ULInfoMessageEventHandler delegate

Represents the method that will handle the InfoMessage event event.

Prototypes

' Visual Basic
Public Delegate Sub ULInfoMessageEventHandler( _
ByVal obj As Object, _
ByVal args As ULInfoMessageEventArgs _
)

// C#
public delegate void ULInfoMessageEventHandler(
object obj,
ULInfoMessageEventArgs args
);

Parameters

  • obj The connection sending the event.

  • args The ULInfoMessageEventArgs class object that contains the event data.


ULParameter class

Represents a parameter to a ULCommand class.

Prototypes

' Visual Basic
NotInheritable Public Class ULParameter
Inherits MarshalByRefObject
Implements IDbDataParameter, IDataParameter

// C#
public sealed class ULParameter :
MarshalByRefobject, IDbDataParameter, IDataParameter

Remarks

A ULParameter object can be created directly using one of its many constructors, or using the CreateParameter method method. Because of the special treatment of the 0 and 0.0 constants and the way overloaded methods are resolved, it is highly recommended that you explicitly cast constant values to type object when using the ULParameter constructor constructor. For example:

' Visual Basic
Dim p As ULParameter = New ULParameter( "", CType( 0, Object ) )

// C#
ULParameter p = new ULParameter( "", (object)0 );

Parameters (including those created by CreateParameter method) must be added to a Parameters property collection to be used. All parameters are treated as positional parameters and are used by a command in the order that they were added.

In UltraLite.NET, parameters can only be used as IN parameters and all mapping information is ignored. Only the Value property property is important.

Implements: IDbDataParameter, IDataParameter

ULParameter members
ULParameter constructor
ULParameter constructor
ULParameter constructor
ULParameter constructor
ULParameter constructor
ULParameter constructor
DbType property
Direction property
IsNullable property
Offset property
ParameterName property
Precision property
Scale property
Size property
SourceColumn property
SourceVersion property
ULDbType property
Value property
ToString method


ULParameter members

Public instance constructors
Member | Description
ULParameter constructor | Initializes a ULParameter object with null (Nothing in Visual Basic) as its value.
ULParameter constructor | Initializes a ULParameter object with the specified parameter name and value.
ULParameter constructor | Initializes a ULParameter object with the specified parameter name and data type. This constructor is not recommended; it is provided for compatibility with other data providers.
ULParameter constructor | Initializes a ULParameter object with the specified parameter name and data type. This constructor is not recommended; it is provided for compatibility with other data providers.
ULParameter constructor | Initializes a ULParameter object with the specified parameter name, data type, and length. This constructor is not recommended; it is provided for compatibility with other data providers.
ULParameter constructor | Initializes a ULParameter object with the specified parameter name, data type, length, direction, nullability, numeric precision, numeric scale, source column, source version, and value. This constructor is not recommended; it is provided for compatibility with other data providers.
Public instance properties
Member | Description
DbType property | Specifies the DbType of the parameter
Direction property | A value indicating whether the parameter is input-only, output-only, bidirectional, or a stored procedure return value parameter.
IsNullable property | Specifies whether the parameter accepts null values.
Offset property | Specifies the offset to the Value property property.
ParameterName property | Specifies the name of the parameter.
Precision property | Specifies the maximum number of digits used to represent the Value property property.
Scale property | Specifies the number of decimal places to which Value property is resolved.
Size property | Specifies the maximum size of the data within the column.
SourceColumn property | Specifies the name of the source column mapped to the DataSet and used for loading or returning the value.
SourceVersion property | The DataRowVersion to use when loading Value property.
ULDbType property | Specifies the ULDbType enumeration of the parameter
Value property | Specifies the value of the parameter.
Public instance methods
Member | Description
ToString method | Returns the string representation of this instance.


ULParameter constructor

Initializes a ULParameter object with null (Nothing in Visual Basic) as its value.

Prototypes

' Visual Basic
Overloads Public Sub New()

// C#
public ULParameter();

Example

The following code creates a ULParameter with the value 3 and adds it to a ULCommand class called cmd.

' Visual Basic
Dim p As ULParameter = New ULParameter
p.Value = 3
cmd.Parameters.Add( p )

// C#
ULParameter p = new ULParameter();
p.Value = 3;
cmd.Parameters.Add( p );
See also
  • ULParameter class
  • ULParameter members
  • Value property
  • ULParameter constructor


ULParameter constructor

Initializes a ULParameter object with the specified parameter name and value.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal parameterName As String, _
ByVal value As Object _
)

// C#
public ULParameter(
string parameterName,
object value
);

Parameters

  • parameterName The name of the parameter. For unnamed parameters, use an empty string ("") or a null reference (Nothing in Visual Basic) for this value. In UltraLite.NET, parameter names are not used by ULCommand class.

  • value An Object that is to be the value of the parameter.

Remarks

Because of the special treatment of the 0 and 0.0 constants and the way overloaded methods are resolved, it is highly recommended that you explicitly cast constant values to type object when using this constructor.

Example

The following code creates a ULParameter with the value 0 and adds it to a ULCommand class called cmd.

' Visual Basic
cmd.Parameters.Add( New ULParameter( "", CType( 0, Object ) ) )

// C#
cmd.Parameters.Add( new ULParameter( "", (object)0 ) );
See also
  • ULParameter class
  • ULParameter members
  • ULParameter constructor


ULParameter constructor

Initializes a ULParameter object with the specified parameter name and data type. This constructor is not recommended; it is provided for compatibility with other data providers.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal parameterName As String, _
ByVal dbType As ULDbType _
)

// C#
public ULParameter(
string parameterName,
ULDbType dbType
);

Parameters

  • parameterName The name of the parameter. For unnamed parameters, use an empty string ("") or a null reference (Nothing in Visual Basic) for this value. In UltraLite.NET, parameter names are not used by ULCommand class.

  • dbType One of the ULDbType enumeration values.

Remarks

In UltraLite.NET parameters can only be used as IN parameters and all mapping information is ignored. Only the Value property property is important.

See also
  • ULParameter class
  • ULParameter members
  • ULParameter constructor
  • ULParameter constructor


ULParameter constructor

Initializes a ULParameter object with the specified parameter name and data type. This constructor is not recommended; it is provided for compatibility with other data providers.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal parameterName As String, _
ByVal dbType As ULDbType, _
ByVal size As Integer _
)

// C#
public ULParameter(
string parameterName,
ULDbType dbType,
int size
);

Parameters

  • parameterName The name of the parameter. For unnamed parameters, use an empty string ("") or a null reference (Nothing in Visual Basic) for this value. In UltraLite.NET, parameter names are not used by ULCommand class.

  • dbType One of the ULDbType enumeration values.

  • size The length of the parameter.

Remarks

In UltraLite.NET parameters can only be used as IN parameters and all mapping information is ignored. Only the Value property property is important.

See also
  • ULParameter class
  • ULParameter members
  • ULParameter constructor
  • ULParameter constructor


ULParameter constructor

Initializes a ULParameter object with the specified parameter name, data type, and length. This constructor is not recommended; it is provided for compatibility with other data providers.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal parameterName As String, _
ByVal dbType As ULDbType, _
ByVal size As Integer, _
ByVal sourceColumn As String _
)

// C#
public ULParameter(
string parameterName,
ULDbType dbType,
int size,
string sourceColumn
);

Parameters

  • parameterName The name of the parameter. For unnamed parameters, use an empty string ("") or a null reference (Nothing in Visual Basic) for this value. In UltraLite.NET, parameter names are not used by ULCommand class.

  • dbType One of the ULDbType enumeration values.

  • size The length of the parameter.

  • sourceColumn The name of the source column to map.

Remarks

In UltraLite.NET parameters can only be used as IN parameters and all mapping information is ignored. Only the Value property property is important.

See also
  • ULParameter class
  • ULParameter members
  • ULParameter constructor
  • ULParameter constructor


ULParameter constructor

Initializes a ULParameter object with the specified parameter name, data type, length, direction, nullability, numeric precision, numeric scale, source column, source version, and value. This constructor is not recommended; it is provided for compatibility with other data providers.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal parameterName As String, _
ByVal dbType As ULDbType, _
ByVal size As Integer, _
ByVal direction As ParameterDirection, _
ByVal isNullable As Boolean, _
ByVal precision As Byte, _
ByVal scale As Byte, _
ByVal sourceColumn As String, _
ByVal sourceVersion As DataRowVersion, _
ByVal value As Object _
)

// C#
public ULParameter(
string parameterName,
ULDbType dbType,
int size,
ParameterDirection direction,
bool isNullable,
byte precision,
byte scale,
string sourceColumn,
DataRowVersion sourceVersion,
object value
);

Parameters

  • parameterName The name of the parameter. For unnamed parameters, use an empty string ("") or a null reference (Nothing in Visual Basic) for this value. In UltraLite.NET, parameter names are not used by ULCommand class.

  • dbType One of the ULDbType enumeration values.

  • size The length of the parameter.

  • direction One of the ParameterDirection values.

  • isNullable True if the value of the field can be null; otherwise, false.

  • precision The total number of digits to the left and right of the decimal point to which Value is resolved.

  • scale The total number of decimal places to which Value is resolved.

  • sourceColumn The name of the source column to map.

  • sourceVersion One of the DataRowVersion values.

  • value An Object that is to be the value of the parameter.

Exceptions

  • ULException class - Only the ParameterDirection.Input direction is supported in UltraLite.NET.

See also
  • ULParameter class
  • ULParameter members
  • ULParameter constructor
  • ULParameter constructor


DbType property

Specifies the DbType of the parameter

Prototypes

' Visual Basic
NotOverridable Public Property DbType As DbType _
Implements IDataParameter.DbType

// C#
public DbType DbType {get;set;}

Property value

One of the DbType values.

Remarks

The ULDbType property and DbType properties are linked. Therefore, setting the DbType changes the ULDbType property to a supporting ULDbType enumeration.

Exceptions

  • ArgumentException - There is no mapping from the specified value to a ULDbType enumeration, hence, the specified value is not supported.

Implements

IDataParameter.DbType


Direction property

A value indicating whether the parameter is input-only, output-only, bidirectional, or a stored procedure return value parameter.

Prototypes

' Visual Basic
NotOverridable Public Property Direction As ParameterDirection _
Implements IDataParameter.Direction

// C#
public ParameterDirection Direction {get;set;}

Property value

One of the ParameterDirection values.

Remarks

In UltraLite.NET, parameters can only be used as IN parameters and all mapping information is ignored. Only the Value property property is important.

Exceptions

  • ULException class - Only the ParameterDirection.Input direction is supported in UltraLite.NET.

Implements

IDataParameter.Direction


IsNullable property

Specifies whether the parameter accepts null values.

Prototypes

' Visual Basic
Public Property IsNullable As Boolean _
Implements IDataParameter.IsNullable

// C#
public bool IsNullable {get;set;}

Property value

True if null values are accepted, false otherwise. The default is false. Null values are handled using the DBNull class.

Remarks

In UltraLite.NET, parameters can only be used as IN parameters and all mapping information is ignored. Only the Value property property is important.

Implements

IDataParameter.IsNullable


Offset property

Specifies the offset to the Value property property.

Prototypes

' Visual Basic
Public Property Offset As Integer

// C#
public int Offset {get;set;}

Property value

The offset to the value. The default is 0.

Remarks

In UltraLite.NET parameters can only be used as IN parameters and all mapping information is ignored. Only the Value property property is important.


ParameterName property

Specifies the name of the parameter.

Prototypes

' Visual Basic
NotOverridable Public Property ParameterName As String _
Implements IDataParameter.ParameterName

// C#
public string ParameterName {get;set;}

Property value

A string representing the name of the parameter, or an empty string ("') for unnamed parameters. Specifying a null reference (Nothing in Visual Basic) results in an empty string being used.

Remarks

In UltraLite.NET, parameter names are not used by ULCommand class. All parameters are treated as positional parameters and are used by a command in the order that they were added.

Implements

IDataParameter.ParameterName


Precision property

Specifies the maximum number of digits used to represent the Value property property.

Prototypes

' Visual Basic
NotOverridable Public Property Precision As Byte _
Implements IDbDataParameter.Precision

// C#
public byte Precision {get;set;}

Property value

The maximum number of digits used to represent the Value property property. The default value is 0, which indicates that the data provider sets the precision for the Value property property.

Remarks

In UltraLite.NET, parameters can only be used as IN parameters and all mapping information is ignored. Only the Value property property is important.

Exceptions

  • ArgumentException - The value is greater then 38.

Implements

IDbDataParameter.Precision


Scale property

Specifies the number of decimal places to which Value property is resolved.

Prototypes

' Visual Basic
NotOverridable Public Property Scale As Byte _
Implements IDbDataParameter.Scale

// C#
public byte Scale {get;set;}

Property value

The number of decimal places to which Value property is resolved. The default is 0.

Remarks

In UltraLite.NET, parameters can only be used as IN parameters and all mapping information is ignored. Only the Value property property is important.

Implements

IDbDataParameter.Scale


Size property

Specifies the maximum size of the data within the column.

Prototypes

' Visual Basic
NotOverridable Public Property Size As Integer _
Implements IDbDataParameter.Size

// C#
public int Size {get;set;}

Property value

The maximum size of the data within the column. The default value is inferred from the parameter value. The Size property is used for binary and string types.

Remarks

In UltraLite.NET, parameters can only be used as IN parameters and all mapping information is ignored. Only the Value property property is important.

Implements

IDbDataParameter.Size


SourceColumn property

Specifies the name of the source column mapped to the DataSet and used for loading or returning the value.

Prototypes

' Visual Basic
NotOverridable Public Property SourceColumn As String _
Implements IDataParameter.SourceColumn

// C#
public string SourceColumn {get;set;}

Property value

A string specifying the name of the source column mapped to the DataSet and used for loading or returning the value.

Remarks

In UltraLite.NET, parameters can only be used as IN parameters and all mapping information is ignored. Only the Value property property is important.

Implements

IDataParameter.SourceColumn


SourceVersion property

The DataRowVersion to use when loading Value property.

Prototypes

' Visual Basic
NotOverridable Public Property SourceVersion As DataRowVersion _
Implements IDataParameter.SourceVersion

// C#
public DataRowVersion SourceVersion {get;set;}

Implements

IDataParameter.SourceVersion


ULDbType property

Specifies the ULDbType enumeration of the parameter

Prototypes

' Visual Basic
Public Property ULDbType As ULDbType

// C#
public ULDbType ULDbType {get;set;}

Property value

One of the ULDbType enumeration values.

Remarks

The ULDbType and DbType property properties are linked. Therefore, setting the ULDbType changes the DbType property to a supporting DbType.

In UltraLite.NET, parameters can only be used as IN parameters and all mapping information is ignored. Only the Value property property is important.


Value property

Specifies the value of the parameter.

Prototypes

' Visual Basic
NotOverridable Public Property Value As Object _
Implements IDataParameter.Value

// C#
public object Value {get;set;}

Property value

An Object that specifies the value of the parameter.

Remarks

The value is sent as-is to the data provider without any type conversion or mapping. When the command is executed, the command attempts to convert the value to the required type, signaling a ULException class with ULSQLCode enumeration if it cannot convert the value.

Implements

IDataParameter.Value


ToString method

Returns the string representation of this instance.

Prototypes

' Visual Basic
Overrides Public Function ToString() As String

// C#
public override string ToString();

Return value

The name of the parameter.


ULParameterCollection class

Represents all parameters to a ULCommand class.

Prototypes

' Visual Basic
NotInheritable Public Class ULParameterCollection
Implements IDataParameterCollection, IList, ICollection,
IEnumerable

// C#
public sealed class ULParameterCollection :
IDataParameterCollection, IList,
ICollection, IEnumerable

Remarks

All parameters in the collection are treated as positional parameters and are specified in the same order as the question mark placeholders in the CommandText property. For example, the first parameter in the collection corresponds to the first question mark in the SQL statement, the second parameter in the collection corresponds to the second question mark in the SQL statement, and so on. There must be at least as many question marks in the CommandText property as there are parameters in the collection. Nulls are substituted for missing parameters.

There is no constructor for ULParameterCollection. You obtain a ULParameterCollection from the Parameters property property.

Implements: IDataParameterCollection

ULParameterCollection members
Count property
Item property
Item property
Add method
Add method
Add method
Add method
Add method
Add method
Clear method
Contains method
Contains method
CopyTo method
GetEnumerator method
IndexOf method
IndexOf method
Insert method
Remove method
RemoveAt method
RemoveAt method


ULParameterCollection members

Public instance properties
Member | Description
Count property | Returns the number of ULParameter class objects in the collection.
Item property | Returns the ULParameter class at the specified index. In C#, this property is the indexer for the ULParameterCollection class.
Item property | Returns the ULParameter class with the specified name. In C#, this property is the indexer for the ULParameterCollection class.
Public instance methods
Member | Description
Add method | Adds a ULParameter class to the collection.
Add method | Adds a ULParameter class to the collection.
Add method | Adds a new ULParameter class, created using the specified parameter name and value, to the collection.
Add method | Adds a new ULParameter class, created using the specified parameter name and data type, to the collection.
Add method | Adds a new ULParameter class, created using the specified parameter name, data type, and length, to the collection.
Add method | Adds a new ULParameter class, created using the specified parameter name, data type, length, and source column name, to the collection.
Clear method | Removes all the parameters from the collection.
Contains method | Checks whether a ULParameter class exists in the collection.
Contains method | Checks whether a ULParameter class with the specified name exists in the collection.
CopyTo method | Copies ULParameter class objects from the ULParameterCollection to the specified array.
GetEnumerator method | Returns an enumerator for the collection.
IndexOf method | Returns the location of the ULParameter class in the collection.
IndexOf method | Returns the location of the ULParameter class with the specified name in the collection.
Insert method | Inserts an ULParameter class in the collection at the specified index.
Remove method | Removes an ULParameter class from the collection.
RemoveAt method | Removes the parameter at the specified index in the collection.
RemoveAt method | Removes the parameter with the specified name from the collection.


Count property

Returns the number of ULParameter class objects in the collection.

Prototypes

' Visual Basic
NotOverridable Public Readonly Property Count As Integer _
Implements ICollection.Count

// C#
public int Count {get;}

Property value

The number of ULParameter class objects in the collection.

Implements

ICollection.Count


Item property

Returns the ULParameter class at the specified index. In C#, this property is the indexer for the ULParameterCollection class.

Prototypes

' Visual Basic
Public Property Item As ULParameter

// C#
public ULParameter Item {get;set;}

Parameters

  • index The zero-based index of the parameter to retrieve. The value must be in the range [0,Count property -1]. The first parameter in the collection has an index value of zero.

Return value

The ULParameter class at the specified index.

Exceptions

  • System.IndexOutOfRangeException - The index is invalid.


Item property

Returns the ULParameter class with the specified name. In C#, this property is the indexer for the ULParameterCollection class.

Prototypes

' Visual Basic
Public Property Item As ULParameter

// C#
public ULParameter Item {get;set;}

Parameters

  • parameterName The name of the parameter to retrieve.

Return value

The ULParameter class with the specified name.

Exceptions

  • System.ArgumentNullException - You cannot set a parameter using a null (Nothing in Visual Basic) parameter name.

  • System.IndexOutOfRangeException - There is no parameter with the specified name.

See also
  • ULParameterCollection class
  • ULParameterCollection members
  • Item property
  • GetOrdinal method
  • GetValue method
  • GetFieldType method


Add method

Adds a ULParameter class to the collection.

Prototypes

' Visual Basic
Overloads NotOverridable Public Function Add( _
ByVal value As Object _
) As Integer _
Implements IList.Add

// C#
public int Add(
object value
);

Parameters

  • value The ULParameter class object to add to the collection.

Return value

The index of the new ULParameter class object.

Remarks

All parameters in the collection are treated as positional parameters and must be added to the collection in the same order as the corresponding question mark placeholders in the CommandText property. For example, the first parameter in the collection corresponds to the first question mark in the SQL statement, the second parameter in the collection corresponds to the second question mark in the SQL statement, and so on. There must be at least as many question marks in the CommandText property as there are parameters in the collection. Nulls are substituted for missing parameters.

Exceptions

  • ArgumentException - The ULParameter class object can only be added to the collection once.

  • System.ArgumentNullException - The value cannot be null (Nothing in Visual Basic).

  • System.InvalidCastException - The value specified must be a ULParameter class.

Implements

IList.Add

See also
  • ULParameterCollection class
  • ULParameterCollection members
  • Add method
  • Add method


Add method

Adds a ULParameter class to the collection.

Prototypes

' Visual Basic
Overloads Public Function Add( _
ByVal value As ULParameter _
) As ULParameter

// C#
public ULParameter Add(
ULParameter value
);

Parameters

  • value The ULParameter class object to add to the collection.

Return value

The new ULParameter class object.

Remarks

All parameters in the collection are treated as positional parameters and must be added to the collection in the same order as the corresponding question mark placeholders in the CommandText property. For example, the first parameter in the collection corresponds to the first question mark in the SQL statement, the second parameter in the collection corresponds to the second question mark in the SQL statement, and so on. There must be at least as many question marks in the CommandText property as there are parameters in the collection. Nulls are substituted for missing parameters.

Exceptions

  • ArgumentException - The ULParameter class object can only be added to the collection once.

  • System.ArgumentNullException - The value cannot be null (Nothing in Visual Basic).

See also
  • ULParameterCollection class
  • ULParameterCollection members
  • Add method


Add method

Adds a new ULParameter class, created using the specified parameter name and value, to the collection.

Prototypes

' Visual Basic
Overloads Public Function Add( _
ByVal parameterName As String, _
ByVal value As Object _
) As ULParameter

// C#
public ULParameter Add(
string parameterName,
object value
);

Parameters

  • parameterName The name of the parameter. For unnamed parameters, use an empty string ("") or a null reference (Nothing in Visual Basic) for this value. In UltraLite.NET, parameter names are not used by ULCommand class.

  • value An Object that is to be the value of the parameter.

Return value

The new ULParameter class object.

Remarks

All parameters in the collection are treated as positional parameters and must be added to the collection in the same order as the corresponding question mark placeholders in the CommandText property. For example, the first parameter in the collection corresponds to the first question mark in the SQL statement, the second parameter in the collection corresponds to the second question mark in the SQL statement, and so on. There must be at least as many question marks in the CommandText property as there are parameters in the collection. Nulls are substituted for missing parameters.

Because of the special treatment of the 0 and 0.0 constants and the way overloaded methods are resolved, it is highly recommended that you explicitly cast constant values to type object when using this method.

Example

The following code adds a ULParameter with the value 0 to a ULCommand class called cmd.

' Visual Basic
cmd.Parameters.Add( "", CType( 0, Object ) )

// C#
cmd.Parameters.Add( "", (object)0 );
See also
  • ULParameterCollection class
  • ULParameterCollection members
  • Add method


Add method

Adds a new ULParameter class, created using the specified parameter name and data type, to the collection.

Prototypes

' Visual Basic
Overloads Public Function Add( _
ByVal parameterName As String, _
ByVal ulDbType As ULDbType _
) As ULParameter

// C#
public ULParameter Add(
string parameterName,
ULDbType ulDbType
);

Parameters

  • parameterName The name of the parameter. For unnamed parameters, use an empty string ("") or a null reference (Nothing in Visual Basic) for this value. In UltraLite.NET, parameter names are not used by ULCommand class.

  • ulDbType One of the ULDbType enumeration values.

Return value

The new ULParameter class object.

Remarks

All parameters in the collection are treated as positional parameters and must be added to the collection in the same order as the corresponding question mark placeholders in the CommandText property. For example, the first parameter in the collection corresponds to the first question mark in the SQL statement, the second parameter in the collection corresponds to the second question mark in the SQL statement, and so on. There must be at least as many question marks in the CommandText property as there are parameters in the collection. Nulls are substituted for missing parameters.

See also
  • ULParameterCollection class
  • ULParameterCollection members
  • Add method
  • Add method


Add method

Adds a new ULParameter class, created using the specified parameter name, data type, and length, to the collection.

Prototypes

' Visual Basic
Overloads Public Function Add( _
ByVal parameterName As String, _
ByVal ulDbType As ULDbType, _
ByVal size As Integer _
) As ULParameter

// C#
public ULParameter Add(
string parameterName,
ULDbType ulDbType,
int size
);

Parameters

  • parameterName The name of the parameter. For unnamed parameters, use an empty string ("") or a null reference (Nothing in Visual Basic) for this value. In UltraLite.NET, parameter names are not used by ULCommand class.

  • ulDbType One of the ULDbType enumeration values.

  • size The length of the parameter.

Return value

The new ULParameter class object.

Remarks

All parameters in the collection are treated as positional parameters and must be added to the collection in the same order as the corresponding question mark placeholders in the CommandText property. For example, the first parameter in the collection corresponds to the first question mark in the SQL statement, the second parameter in the collection corresponds to the second question mark in the SQL statement, and so on. There must be at least as many question marks in the CommandText property as there are parameters in the collection. Nulls are substituted for missing parameters.

See also
  • ULParameterCollection class
  • ULParameterCollection members
  • Add method
  • Add method


Add method

Adds a new ULParameter class, created using the specified parameter name, data type, length, and source column name, to the collection.

Prototypes

' Visual Basic
Overloads Public Function Add( _
ByVal parameterName As String, _
ByVal ulDbType As ULDbType, _
ByVal size As Integer, _
ByVal sourceColumn As String _
) As ULParameter

// C#
public ULParameter Add(
string parameterName,
ULDbType ulDbType,
int size,
string sourceColumn
);

Parameters

  • parameterName The name of the parameter. For unnamed parameters, use an empty string ("") or a null reference (Nothing in Visual Basic) for this value. In UltraLite.NET, parameter names are not used by ULCommand class.

  • ulDbType One of the ULDbType enumeration values.

  • size The length of the parameter.

  • sourceColumn The name of the source column to map.

Return value

The new ULParameter class object.

Remarks

All parameters in the collection are treated as positional parameters and must be added to the collection in the same order as the corresponding question mark placeholders in the CommandText property. For example, the first parameter in the collection corresponds to the first question mark in the SQL statement, the second parameter in the collection corresponds to the second question mark in the SQL statement, and so on. There must be at least as many question marks in the CommandText property as there are parameters in the collection. Nulls are substituted for missing parameters.

See also
  • ULParameterCollection class
  • ULParameterCollection members
  • Add method
  • Add method


Clear method

Removes all the parameters from the collection.

Prototypes

' Visual Basic
NotOverridable Public Sub Clear() _
Implements IList.Clear

// C#
public void Clear();

Implements

IList.Clear


Contains method

Checks whether a ULParameter class exists in the collection.

Prototypes

' Visual Basic
Overloads NotOverridable Public Function Contains( _
ByVal value As Object _
) As Boolean _
Implements IList.Contains

// C#
public bool Contains(
object value
);

Parameters

  • value The ULParameter class object to check for.

Return value

True if the collection contains the ULParameter class, false otherwise.

Implements

IList.Contains

See also
  • ULParameterCollection class
  • ULParameterCollection members
  • Contains method


Contains method

Checks whether a ULParameter class with the specified name exists in the collection.

Prototypes

' Visual Basic
Overloads NotOverridable Public Function Contains( _
ByVal value As String _
) As Boolean _
Implements IDataParameterCollection.Contains

// C#
public bool Contains(
string value
);

Parameters

  • value The name of the parameter to search for.

Return value

True if the collection contains the ULParameter class, false otherwise.

Implements

IDataParameterCollection.Contains

See also
  • ULParameterCollection class
  • ULParameterCollection members
  • Contains method


CopyTo method

Copies ULParameter class objects from the ULParameterCollection to the specified array.

Prototypes

' Visual Basic
NotOverridable Public Sub CopyTo( _
ByVal array As System.Array, _
ByVal index As Integer _
) _
Implements ICollection.CopyTo

// C#
public void CopyTo(
System.Array array,
int index
);

Parameters

  • array The array into which to copy the ULParameter class objects.

  • index The starting index of the array.

Implements

ICollection.CopyTo


GetEnumerator method

Returns an enumerator for the collection.

Prototypes

' Visual Basic
NotOverridable Public Function GetEnumerator() As System.Collections.IEnumerator _
Implements IEnumerable.GetEnumerator

// C#
public System.Collections.IEnumerator GetEnumerator();

Return value

An ArrayList enumerator enumerating the parameters in the collection.

Implements

IEnumerable.GetEnumerator


IndexOf method

Returns the location of the ULParameter class in the collection.

Prototypes

' Visual Basic
Overloads NotOverridable Public Function IndexOf( _
ByVal value As Object _
) As Integer _
Implements IList.IndexOf

// C#
public int IndexOf(
object value
);

Parameters

  • value The ULParameter class object to locate.

Return value

The zero-based index of the ULParameter class in the collection or -1 if the parameter is not found.

Exceptions

  • System.InvalidCastException - The value specified must be a ULParameter class.

Implements

IList.IndexOf

See also
  • ULParameterCollection class
  • ULParameterCollection members
  • IndexOf method


IndexOf method

Returns the location of the ULParameter class with the specified name in the collection.

Prototypes

' Visual Basic
Overloads NotOverridable Public Function IndexOf( _
ByVal parameterName As String _
) As Integer _
Implements IDataParameterCollection.IndexOf

// C#
public int IndexOf(
string parameterName
);

Parameters

  • parameterName The name of the parameter to locate.

Return value

The zero-based index of the ULParameter class in the collection or -1 if the parameter is not found.

Implements

IDataParameterCollection.IndexOf

See also
  • ULParameterCollection class
  • ULParameterCollection members
  • IndexOf method


Insert method

Inserts an ULParameter class in the collection at the specified index.

Prototypes

' Visual Basic
NotOverridable Public Sub Insert( _
ByVal index As Integer, _
ByVal value As Object _
) _
Implements IList.Insert

// C#
public void Insert(
int index,
object value
);

Parameters

  • index The zero-based index where the parameter is to be inserted within the collection.

  • value The ULParameter class object to insert.

Exceptions

  • System.ArgumentNullException - You cannot set a parameter using a null reference (Nothing in Visual Basic).

  • System.IndexOutOfRangeException - The index is invalid.

  • System.InvalidCastException - The value specified must be a ULParameter class.

Implements

IList.Insert


Remove method

Removes an ULParameter class from the collection.

Prototypes

' Visual Basic
NotOverridable Public Sub Remove( _
ByVal value As Object _
) _
Implements IList.Remove

// C#
public void Remove(
object value
);

Parameters

  • value The ULParameter class object to insert.

Exceptions

  • ArgumentException - The collection does not contain the specified parameter.

  • System.ArgumentNullException - You cannot set a parameter using a null reference (Nothing in Visual Basic).

  • System.InvalidCastException - The value specified must be a ULParameter class.

Implements

IList.Remove


RemoveAt method

Removes the parameter at the specified index in the collection.

Prototypes

' Visual Basic
Overloads NotOverridable Public Sub RemoveAt( _
ByVal index As Integer _
) _
Implements IList.RemoveAt

// C#
public void RemoveAt(
int index
);

Parameters

  • index The zero-based index of the parameter to remove. The value must be in the range [0,Count property -1]. The first parameter in the collection has an index value of zero.

Exceptions

  • System.IndexOutOfRangeException - The index is invalid.

Implements

IList.RemoveAt

See also
  • ULParameterCollection class
  • ULParameterCollection members
  • RemoveAt method


RemoveAt method

Removes the parameter with the specified name from the collection.

Prototypes

' Visual Basic
Overloads NotOverridable Public Sub RemoveAt( _
ByVal parameterName As String _
) _
Implements IDataParameterCollection.RemoveAt

// C#
public void RemoveAt(
string parameterName
);

Parameters

  • parameterName The name of the parameter to retrieve.

Exceptions

  • System.IndexOutOfRangeException - There is no parameter with the specified name.

Implements

IDataParameterCollection.RemoveAt

See also
  • ULParameterCollection class
  • ULParameterCollection members
  • RemoveAt method


ULPublicationSchema class

UL Ext.: Represents the schema of an UltraLite publication.

Prototypes

' Visual Basic
NotInheritable Public Class ULPublicationSchema

// C#
public sealed class ULPublicationSchema

Remarks

This class cannot be directly instantiated. Publication schemas are created using the GetPublicationSchema method method of the ULDatabaseSchema class class.

UltraLite methods requiring a publication mask actually require a set of publications to check. A set is formed by or'ing the publication masks of individual publications. For example:

' Visual Basic
Dim mask As Integer = pub1.Mask Or pub2.Mask

// C#
int mask = pub1.Mask | pub2.Mask;

Two special mask values are also provided by this class. SYNC_ALL_DB field corresponds to the entire database. SYNC_ALL_PUBS field corresponds to all publications.

Note: Publication masks may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached masks after a schema upgrade.

See also
  • ULPublicationSchema members
  • Mask property
  • GetLastDownloadTime method
  • CountUploadRows method
  • Schema property


ULPublicationSchema members

Public static fields (Shared)
Member | Description
SYNC_ALL_DB field | Publication mask corresponding to the entire database.
SYNC_ALL_PUBS field | Publication mask corresponding to all publications.
Public instance properties
Member | Description
IsOpen property | Determines whether the publication schema is open or closed.
Mask property | Returns the publication mask of the publication.
Name property | Returns the name of this publication.


SYNC_ALL_DB field

Publication mask corresponding to the entire database.

Prototypes

' Visual Basic
Public Shared SYNC_ALL_DB As Integer

// C#
public const int SYNC_ALL_DB;


SYNC_ALL_PUBS field

Publication mask corresponding to all publications.

Prototypes

' Visual Basic
Public Shared SYNC_ALL_PUBS As Integer

// C#
public const int SYNC_ALL_PUBS;


IsOpen property

Determines whether the publication schema is open or closed.

Prototypes

' Visual Basic
Public Readonly Property IsOpen As Boolean

// C#
public bool IsOpen {get;}

Property value

True if the publication schema is open, false if the publication schema closed.


Mask property

Returns the publication mask of the publication.

Prototypes

' Visual Basic
Public Readonly Property Mask As Integer

// C#
public int Mask {get;}

Property value

The publication mask of the publication.

Remarks

Publication IDs, masks, and counts may change during a schema upgrade. To correctly identify a publication, access it by name, or refresh the cached masks and counts after a schema upgrade.

Exceptions

  • ULException class - If a SQL error exception occurs. PUBLICATION_NOT_FOUND is issued if a schema upgrade has deleted or renamed this publication.


Name property

Returns the name of this publication.

Prototypes

' Visual Basic
Public Readonly Property Name As String

// C#
public string Name {get;}

Property value

A string specifying the name of the publication.

Exceptions

  • ULException class - A SQL error occurred. PUBLICATION_NOT_FOUND is issued if a schema upgrade has deleted or renamed the publication.


ULResultSetSchema class

UL Ext.: Represents the schema of an UltraLite result set.

Prototypes

' Visual Basic
NotInheritable Public Class ULResultSetSchema
Inherits ULCursorSchema

// C#
public sealed class ULResultSetSchema :
ULCursorSchema

Remarks

This class cannot be directly instantiated. A ULResultSetSchema class object is attached to a result set as its Schema property property.

A result set schema is only valid while the data reader is open.

See also
  • ULResultSetSchema members
  • ULCommand class
  • ULDataReader class


ULResultSetSchema members

Public instance properties
Member | Description
ColumnCount property (inherited from ULCursorSchema) | Returns the number of columns in the cursor.
IsOpen property (inherited from ULCursorSchema) | Checks whether the cursor schema is currently open.
Name property | Returns the name of the cursor.
Public instance methods
Member | Description
GetColumnID method (inherited from ULCursorSchema) | Returns the column ID of the named column.
GetColumnName method (inherited from ULCursorSchema) | Returns the name of the column identified by the specified column ID.
GetColumnPrecision method (inherited from ULCursorSchema) | Returns the precision of the column identified by the specified column ID if the column is a numeric column (SQL type NUMERIC).
GetColumnScale method (inherited from ULCursorSchema) | Returns the scale of the column identified by the specified column ID if the column is a numeric column (SQL type NUMERIC).
GetColumnSize method (inherited from ULCursorSchema) | Returns the size of the column identified by the specified column ID if the column is a sized column (SQL type BINARY or CHAR).
GetColumnULDbType method (inherited from ULCursorSchema) | Returns the UltraLite.NET data type of the column identified by the specified column ID.
GetSchemaTable method (inherited from ULCursorSchema) | Returns a DataTable that describes the column schema of the ULDataReader class.
Protected instance methods
Member | Description
Finalize method | Releases the unmanaged resources used by the ULResultSetSchema.


Name property

Returns the name of the cursor.

Prototypes

' Visual Basic
Public Readonly Property Name As String

// C#
public string Name {get;}

Property value

The SQL statement that generated the ULResultSetSchema.


Finalize method

Releases the unmanaged resources used by the ULResultSetSchema.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


ULRowUpdatedEventArgs class

Provides data for the RowUpdated event event.

Prototypes

' Visual Basic
NotInheritable Public Class ULRowUpdatedEventArgs
Inherits RowUpdatedEventArgs

// C#
public sealed class ULRowUpdatedEventArgs :
RowUpdatedEventArgs


ULRowUpdatedEventArgs members

Public instance constructors
Member | Description
ULRowUpdatedEventArgs constructor | Initializes a new instance of the ULRowUpdatedEventArgs class.
Public instance properties
Member | Description
Command property | Returns the ULCommand class executed when DbDataAdapter.Update is called.
Errors (inherited from RowUpdatedEventArgs) | Gets any errors generated by the .NET Framework data provider when the RowUpdatedEventArgs.Command was executed.
RecordsAffected property | Returns the number of rows changed, inserted, or deleted by the execution of the SQL statement. For SELECT statements this value is -1.
Row (inherited from RowUpdatedEventArgs) | Gets the DataRow sent through an DbDataAdapter.Update .
StatementType (inherited from RowUpdatedEventArgs) | Gets the type of SQL statement executed.
Status (inherited from RowUpdatedEventArgs) | Gets the UpdateStatus of the RowUpdatedEventArgs.Command property.
TableMapping (inherited from RowUpdatedEventArgs) | Gets the DataTableMapping sent through an DbDataAdapter.Update.


ULRowUpdatedEventArgs constructor

Initializes a new instance of the ULRowUpdatedEventArgs class.

Prototypes

' Visual Basic
Public Sub New( _
ByVal row As DataRow, _
ByVal command As IDbCommand, _
ByVal statementType As StatementType, _
ByVal tableMapping As DataTableMapping _
)

// C#
public ULRowUpdatedEventArgs(
DataRow row,
IDbCommand command,
StatementType statementType,
DataTableMapping tableMapping
);

Parameters

  • row The DataRow sent through an DbDataAdapter.Update.

  • command The IDbCommand executed when DbDataAdapter.Update is called.

  • statementType One of the StatementType values that specifies the type of query executed.

  • tableMapping The DataTableMapping sent through an DbDataAdapter.Update.


Command property

Returns the ULCommand class executed when DbDataAdapter.Update is called.

Prototypes

' Visual Basic
Public Readonly Property Command As ULCommand

// C#
public ULCommand Command {get;}

Property value

The ULCommand class object executed by the update.

Remarks

This is the strongly typed version of RowUpdatedEventArgs.Command.


RecordsAffected property

Returns the number of rows changed, inserted, or deleted by the execution of the SQL statement. For SELECT statements this value is -1.

Prototypes

' Visual Basic
Public Readonly Property RecordsAffected As Integer

// C#
public int RecordsAffected {get;}

Property value

The number of rows changed, inserted, or deleted; 0 if no rows were affected or the statement failed; and -1 for SELECT statements.


ULRowUpdatedEventHandler delegate

Represents the method that will handle the RowUpdated event event.

Prototypes

' Visual Basic
Public Delegate Sub ULRowUpdatedEventHandler( _
ByVal sender As Object, _
ByVal e As ULRowUpdatedEventArgs _
)

// C#
public delegate void ULRowUpdatedEventHandler(
object sender,
ULRowUpdatedEventArgs e
);

Parameters

  • sender The connection sending the event.

  • e The ULRowUpdatedEventArgs class object that contains the event data.


ULRowUpdatingEventArgs class

Provides data for the RowUpdating event event.

Prototypes

' Visual Basic
NotInheritable Public Class ULRowUpdatingEventArgs
Inherits RowUpdatingEventArgs

// C#
public sealed class ULRowUpdatingEventArgs :
RowUpdatingEventArgs


ULRowUpdatingEventArgs members

Public instance constructors
Member | Description
ULRowUpdatingEventArgs constructor | Initializes a new instance of the ULRowUpdatingEventArgs class.
Public instance properties
Member | Description
Command property | Specifies the ULCommand class to execute when performing the DbDataAdapter.Update.
Errors (inherited from RowUpdatingEventArgs) | Gets any errors generated by the .NET Framework data provider when the RowUpdatedEventArgs.Command executes.
Row (inherited from RowUpdatingEventArgs) | Gets the DataRow to send through an DbDataAdapter.Update .
StatementType (inherited from RowUpdatingEventArgs) | Gets the type of SQL statement to execute.
Status (inherited from RowUpdatingEventArgs) | Gets the UpdateStatus of the RowUpdatedEventArgs.Command property.
TableMapping (inherited from RowUpdatingEventArgs) | Gets the DataTableMapping to send through the DbDataAdapter.Update.


ULRowUpdatingEventArgs constructor

Initializes a new instance of the ULRowUpdatingEventArgs class.

Prototypes

' Visual Basic
Public Sub New( _
ByVal row As DataRow, _
ByVal command As IDbCommand, _
ByVal statementType As StatementType, _
ByVal tableMapping As DataTableMapping _
)

// C#
public ULRowUpdatingEventArgs(
DataRow row,
IDbCommand command,
StatementType statementType,
DataTableMapping tableMapping
);

Parameters

  • row The DataRow to update.

  • command The IDbCommand to execute during the update.

  • statementType One of the StatementType values that specifies the type of query executed.

  • tableMapping The DataTableMapping sent through an DbDataAdapter.Update.


Command property

Specifies the ULCommand class to execute when performing the DbDataAdapter.Update.

Prototypes

' Visual Basic
Public Property Command As ULCommand

// C#
public ULCommand Command {get;set;}

Property value

The ULCommand class object to execute when updating.

Remarks

This is the strongly typed version of RowUpdatingEventArgs.Command.


ULRowUpdatingEventHandler delegate

Represents the method that will handle the RowUpdating event event.

Prototypes

' Visual Basic
Public Delegate Sub ULRowUpdatingEventHandler( _
ByVal sender As Object, _
ByVal e As ULRowUpdatingEventArgs _
)

// C#
public delegate void ULRowUpdatingEventHandler(
object sender,
ULRowUpdatingEventArgs e
);

Parameters

  • sender The connection sending the event.

  • e The ULRowUpdatingEventArgs class object that contains the event data.


ULRuntimeType enumeration

UL Ext.: Enumerates the types of UltraLite.NET runtimes.

Prototypes

' Visual Basic
Public Enum ULRuntimeType

// C#
public enum ULRuntimeType

Members
Member | Description
STANDALONE_UL | Selects the standalone UltraLite.NET runtime. The standalone runtime accesses databases directly. Databases are accessed more quickly this way, but cannot be shared.
UL_ENGINE_CLIENT | Selects the UltraLite engine runtime. The UltraLite.NET engine client communicates with the UltraLite engine to access databases. This means that databases can be shared by different applications.
See also
  • RuntimeType property


ULSchemaUpgradeData class

UL Ext.: Returns schema upgrade monitoring data.

Prototypes

' Visual Basic
Public Class ULSchemaUpgradeData

// C#
public class ULSchemaUpgradeData

See also
  • ULSchemaUpgradeData members
  • ULSchemaUpgradeListener interface


ULSchemaUpgradeData members

Public instance properties
Member | Description
FinalProgressCount property | Returns an estimate of the final progress count.
ProgressCounter property | Returns the schema upgrade progress counter. This number is an approximation of the progress so far.
State property | Returns the current schema upgrade state.
UpgradeOperations property | Returns the number of schema upgrade operations performed.


FinalProgressCount property

Returns an estimate of the final progress count.

Prototypes

' Visual Basic
Public Readonly Property FinalProgressCount As Long

// C#
public long FinalProgressCount {get;}

Property value

The estimated final progress count.

See also
  • ULSchemaUpgradeData class
  • ULSchemaUpgradeData members
  • ULSchemaUpgradeState enumeration
  • ProgressCounter property


ProgressCounter property

Returns the schema upgrade progress counter. This number is an approximation of the progress so far.

Prototypes

' Visual Basic
Public Readonly Property ProgressCounter As Long

// C#
public long ProgressCounter {get;}

Property value

The schema upgrade progress counter as a number between 0 and FinalProgressCount property.

See also
  • ULSchemaUpgradeData class
  • ULSchemaUpgradeData members
  • ULSchemaUpgradeState enumeration


State property

Returns the current schema upgrade state.

Prototypes

' Visual Basic
Public Readonly Property State As ULSchemaUpgradeState

// C#
public ULSchemaUpgradeState State {get;}

Property value

One of the ULSchemaUpgradeState enumeration values.


UpgradeOperations property

Returns the number of schema upgrade operations performed.

Prototypes

' Visual Basic
Public Readonly Property UpgradeOperations As Long

// C#
public long UpgradeOperations {get;}

Property value

The number of schema operations performed so far.

Remarks

This number is an approximation of the amount of work done during the schema upgrade. This number starts at zero and increases as the update proceeds. This number is updated more frequently than the progress counter and can be used as a relative measure to compare against other schema upgrades.

See also
  • ULSchemaUpgradeData class
  • ULSchemaUpgradeData members
  • ULSchemaUpgradeState enumeration


ULSchemaUpgradeListener interface

UL Ext.: The listener interface for receiving schema upgrade progress events.

Prototypes

' Visual Basic
Public Interface ULSchemaUpgradeListener

// C#
public interface ULSchemaUpgradeListener

See also
  • ULSchemaUpgradeListener members
  • ApplyFile method


ULSchemaUpgradeListener members

Public instance methods
Member | Description
SchemaUpgrading method | Invoked during schema upgrade to inform the user of progress. When the state is ULSchemaUpgradeState enumeration, this method should return true to cancel the schema upgrade or return false to continue. For other states, this method's return value is ignored.


SchemaUpgrading method

Invoked during schema upgrade to inform the user of progress. When the state is ULSchemaUpgradeState enumeration, this method should return true to cancel the schema upgrade or return false to continue. For other states, this method's return value is ignored.

Prototypes

' Visual Basic
Public Function SchemaUpgrading( _
ByVal data As ULSchemaUpgradeData _
) As Boolean

// C#
public bool SchemaUpgrading(
ULSchemaUpgradeData data
);

Parameters

  • data A ULSchemaUpgradeData class object containing the latest schema upgrade progress data.

Return value

This method should return false to continue or true to cancel the schema upgrade (the state must be ULSchemaUpgradeState enumeration to cancel).

Remarks

No UltraLite.NET API methods should be invoked during a SchemaUpgrading call.


ULSchemaUpgradeState enumeration

UL Ext.: Enumerates all the states that can occur while upgrading a schema.

Prototypes

' Visual Basic
Public Enum ULSchemaUpgradeState

// C#
public enum ULSchemaUpgradeState

Remarks

STATE_STARTING is the only state during which the upgrade may be cancelled. If the upgrade is cancelled, you will receive a second event with state STATE_ERROR.

Members
Member | Description
STATE_ABORT | The schema upgrade has been aborted and the old database is preserved. This state may occur as the result of a recoverable error or user abort.
STATE_DONE | The schema upgrade completed successfully.
STATE_ERROR | A critical error occurred and the database is unusable.
STATE_LAST | Internally used state not sent to SchemaUpgrading method.
STATE_STARTING | The schema upgrade is starting. This is the only state during which the upgrade may be cancelled. If the upgrade is cancelled, you will receive a second event with state STATE_ABORT.
STATE_UPGRADING | The schema upgrade is in progress.
See also
  • ULSchemaUpgradeData class


ULServerSyncListener interface

UL Ext.: The listener interface for receiving server synchronization messages.

Prototypes

' Visual Basic
Public Interface ULServerSyncListener

// C#
public interface ULServerSyncListener


ULServerSyncListener members

Public instance methods
Member | Description
ServerSyncInvoked method | Invoked when the MobiLink Listener for server-initiated synchronizations calls the application to perform synchronization.


ServerSyncInvoked method

Invoked when the MobiLink Listener for server-initiated synchronizations calls the application to perform synchronization.

Prototypes

' Visual Basic
Public Sub ServerSyncInvoked( _
ByVal messageName As String _
)

// C#
public void ServerSyncInvoked(
string messageName
);

Parameters

  • messageName The name of the message sent to the application.

Remarks

This method is invoked by a separate thread. To avoid multi-threading issues, it should post an event to the UI. If you are using multi-threading, it is recommended that you use a separate connection and use the lock keyword to access any objects shared with the rest of the application.

Example

The following code fragments demonstrate how to receive a server synchronization request and perform a synchronization in the UI thread.

' Visual Basic
Imports iAnywhere.Data.UltraLite

Public Class MainWindow
  Inherits System.Windows.Forms.Form
  Implements ULServerSyncListener
  Private conn As ULConnection
  Public Sub New(ByVal args() As String)

    MyBase.New()

    'This call is required by the Windows Form Designer.
    InitializeComponent()

    'Add any initialization after the InitializeComponent() call
    ULConnection.DatabaseManager.SetServerSyncListener( _
        "myCompany.mymsg", "myCompany.myapp", Me _
      )
    'Create Connection
    ...
  End Sub
  Protected Overrides Sub OnClosing( _
        ByVal e As System.ComponentModel.CancelEventArgs _
      )
    ULConnection.DatabaseManager.SetServerSyncListener( _
        Nothing, Nothing, Nothing _
      )
    MyBase.OnClosing(e)
  End Sub
  Public Sub ServerSyncInvoked(ByVal messageName As String) _
      Implements ULServerSyncListener.ServerSyncInvoked
    Me.Invoke(New EventHandler(AddressOf Me.ServerSyncAction))
  End Sub
  Public Sub ServerSyncAction( _
        ByVal sender As Object, ByVal e As EventArgs _
      )
    ' Do Server sync
    conn.Synchronize()
  End Sub
End Class
// C#
using iAnywhere.Data.UltraLite;
public class Form1 : System.Windows.Forms.Form, ULServerSyncListener
{
  private System.Windows.Forms.MainMenu mainMenu1;
  private ULConnection conn;
  public Form1()
  {
    //
    // Required for Windows Form Designer support
    //
    InitializeComponent();

    //
    // TODO: Add any constructor code after
    // InitializeComponent call
    //
    ULConnection.DatabaseManager.SetServerSyncListener(
        "myCompnay.mymsg", "myCompany.myapp", this
      );
    // Create connection
    ...
  }
  protected override void Dispose( bool disposing )
  {
    base.Dispose( disposing );
  }
  protected override void OnClosing(
      System.ComponentModel.CancelEventArgs e
    )
  {
    ULConnection.DatabaseManager.SetServerSyncListener(
        null, null, null
      );
    base.OnClosing(e);
  }
  public void ServerSyncInvoked( string messageName )
  {
    this.Invoke( new EventHandler( ServerSyncHandler ) );
  }
  internal void ServerSyncHandler(object sender, EventArgs e)
  {
    conn.Synchronize();
  }
}


ULSQLCode enumeration

UL Ext.: Enumerates the SQL codes that may be reported by UltraLite.NET.

Prototypes

' Visual Basic
Public Enum ULSQLCode

// C#
public enum ULSQLCode

Members
Member | Description
SQLE_AGGREGATES_NOT_ALLOWED | See Invalid use of an aggregate function.
SQLE_ALIAS_NOT_UNIQUE | See Alias '%1' is not unique.
SQLE_ALIAS_NOT_YET_DEFINED | See Definition for alias '%1' must appear before its first reference.
SQLE_AMBIGUOUS_INDEX_NAME | See Index name '%1' is ambiguous.
SQLE_ARGUMENT_CANNOT_BE_NULL | See Argument %1 of procedure '%2' cannot be null.
SQLE_BAD_ENCRYPTION_KEY | See Incorrect or missing encryption key.
SQLE_BAD_PARAM_INDEX | See Input parameter index out of range.
SQLE_CANNOT_ACCESS_FILE | See Cannot access file '%1' -- %2.
SQLE_CANNOT_ACCESS_SCHEMA_FILE | See Cannot access schema file '%1'.
SQLE_CANNOT_CHANGE_USER_NAME | See Cannot change synchronization user_name when status of the last upload is unknown..
SQLE_CANNOT_EXECUTE_STMT | See Statement cannot be executed.
SQLE_CANNOT_MODIFY | See Cannot modify column '%1' in table '%2'.
SQLE_CANNOT_REGISTER_LISTENER | See The specified listener could not be registered.
SQLE_COLUMN_AMBIGUOUS | See Column '%1' found in more than one table -- need a correlation name.
SQLE_COLUMN_CANNOT_BE_NULL | See Column '%1' in table '%2' cannot be NULL.
SQLE_COLUMN_IN_INDEX | See Cannot alter a column in an index.
SQLE_COLUMN_NOT_FOUND | See Column '%1' not found.
SQLE_COLUMN_NOT_FOUND_IN_TABLE | See Column '%1' not found in table '%2'.
SQLE_COMMUNICATIONS_ERROR | See Communication error.
SQLE_CONNECTION_ALREADY_EXISTS | See This connection already exists.
SQLE_CONNECTION_NOT_FOUND | See Connection not found.
SQLE_CONNECTION_RESTORED | See UltraLite connection was restored.
SQLE_CONVERSION_ERROR | See Cannot convert %1 to a %2.
SQLE_CORRELATION_NAME_NOT_FOUND | See Correlation name '%1' not found.
SQLE_COULD_NOT_FIND_FUNCTION | See Could not find '%1' in dynamic library '%2'.
SQLE_COULD_NOT_LOAD_LIBRARY | See Could not load dynamic library '%1'.
SQLE_CURSOR_ALREADY_OPEN | See Cursor already open.
SQLE_CURSOR_NOT_OPEN | See Cursor not open.
SQLE_CURSOR_RESTORED | See UltraLite cursor (or result set or table) was restored.
SQLE_CURSOROP_NOT_ALLOWED | See Illegal cursor operation attempt.
SQLE_DATABASE_CREATED | See The database was created..
SQLE_DATABASE_ERROR | See Internal database error %1 -- transaction rolled back.
SQLE_DATABASE_NAME_REQUIRED | See Database name required to start server.
SQLE_DATABASE_NEW | See Database created without any schema.
SQLE_DATABASE_NOT_CREATED | See Database creation failed: %1.
SQLE_DATABASE_UPGRADE_NOT_POSSIBLE | See Database upgrade not possible.
SQLE_DATATYPE_NOT_ALLOWED | See Expression has unsupported data type.
SQLE_DBSPACE_FULL | See A dbspace has reached its maximum file size.
SQLE_DEVICE_IO_FAILED | See File I/O failed for '%1'.
SQLE_DIV_ZERO_ERROR | See Division by zero.
SQLE_DOWNLOAD_CONFLICT | See Download failed because of conflicts with existing rows..
SQLE_DROP_DATABASE_FAILED | See An attempt to delete database '%1' failed.
SQLE_DUPLICATE_FOREIGN_KEY | See Foreign key '%1' for table '%2' duplicates an existing foreign key.
SQLE_DYNAMIC_MEMORY_EXHAUSTED | See Dynamic memory exhausted.
SQLE_ENGINE_ALREADY_RUNNING | See Database server already running.
SQLE_ENGINE_NOT_MULTIUSER | See Database server not running in multi-user mode.
SQLE_ERROR | See Run time SQL error -- %1.
SQLE_ERROR_CALLING_FUNCTION | See Could not allocate resources to call external function.
SQLE_EXPRESSION_ERROR | See Invalid expression near '%1'.
SQLE_FOREIGN_KEY_NAME_NOT_FOUND | See Foreign key name '%1' not found.
SQLE_IDENTIFIER_TOO_LONG | See Identifier '%1' too long.
SQLE_INCORRECT_VOLUME_ID | See Incorrect volume ID for '%1'.
SQLE_INDEX_NAME_NOT_UNIQUE | See Index name '%1' not unique.
SQLE_INDEX_NOT_FOUND | See Cannot find index named '%1'.
SQLE_INDEX_NOT_UNIQUE | See Index '%1' for table '%2' would not be unique.
SQLE_INTERRUPTED | See Statement interrupted by user.
SQLE_INVALID_DATABASE | See Specified database is invalid.
SQLE_INVALID_FOREIGN_KEY | See No primary key value for foreign key '%1' in table '%2'.
SQLE_INVALID_FOREIGN_KEY_DEF | See Column '%1' in foreign key has a different definition than primary key.
SQLE_INVALID_GROUP_SELECT | See Function or column reference to '%1' must also appear in a GROUP BY.
SQLE_INVALID_OPTION_SETTING | See Invalid setting for option '%1'.
SQLE_INVALID_ORDER | See Invalid ORDER BY specification.
SQLE_INVALID_PARAMETER | See Invalid parameter.
SQLE_INVALID_PARSE_PARAMETER | See Parse error: %1.
SQLE_INVALID_PASSWORD | See Invalid user ID or password.
SQLE_INVALID_SQL_IDENTIFIER | See Invalid SQL identifier.
SQLE_LOCKED | See User '%1' has the row in '%2' locked.
SQLE_MEMORY_ERROR | See Memory error -- transaction rolled back.
SQLE_METHOD_CANNOT_BE_CALLED | See Method '%1' cannot be called at this time.
SQLE_NAME_NOT_UNIQUE | See Item '%1' already exists.
SQLE_NO_COLUMN_NAME | See Derived table '%1' has no name for column %2.
SQLE_NO_CURRENT_ROW | See No current row of cursor.
SQLE_NO_INDICATOR | See No indicator variable provided for NULL result.
SQLE_NO_MATCHING_SELECT_ITEM | See The Select list for the derived table '%1' has no expression to match '%2'.
SQLE_NO_PRIMARY_KEY | See Table '%1' has no primary key.
SQLE_NOERROR | SQLE_NOERROR(0) - This code indicates that there was no error or warning.
SQLE_NOT_IMPLEMENTED | See Feature '%1' not implemented.
SQLE_NOT_SUPPORTED_IN_ULTRALITE | See Feature not available with UltraLite.
SQLE_NOTFOUND | See Row not found.
SQLE_OVERFLOW_ERROR | See Value %1 out of range for destination.
SQLE_PAGE_SIZE_INVALID | See Invalid database page size.
SQLE_PERMISSION_DENIED | See Permission denied: %1.
SQLE_PRIMARY_KEY_NOT_UNIQUE | See Primary key for table '%1' is not unique.
SQLE_PRIMARY_KEY_TWICE | See Table cannot have two primary keys.
SQLE_PRIMARY_KEY_VALUE_REF | See Primary key for row in table '%1' is referenced by foreign key '%2' in table '%3'.
SQLE_PUBLICATION_NOT_FOUND | See Publication '%1' not found.
SQLE_RESOURCE_GOVERNOR_EXCEEDED | See Resource governor for '%1' exceeded.
SQLE_ROW_DELETED_TO_MAINTAIN_REFERENTIAL_INTEGRITY | See Row was dropped from table %1 to maintain referential integrity.
SQLE_ROW_DROPPED_DURING_SCHEMA_UPGRADE | See A row could not be converted to the new schema format.
SQLE_SCHEMA_UPGRADE_NOT_ALLOWED | See A schema upgrade is not currently allowed.
SQLE_SERVER_SYNCHRONIZATION_ERROR | See Synchronization failed due to an error on the server: %1.
SQLE_START_STOP_DATABASE_DENIED | See Request to start/stop database denied.
SQLE_STRING_RIGHT_TRUNCATION | See Right truncation of string data.
SQLE_SUBQUERY_SELECT_LIST | See Subquery allowed only one select list item.
SQLE_SYNC_INFO_INVALID | See Information for synchronization is incomplete or invalid, check '%1'.
SQLE_SYNC_STATUS_UNKNOWN | See The status of the last synchronization upload is unknown.
SQLE_SYNCHRONIZATION_NOT_FOUND | See Cannot find synchronization subscription with the name '%1'.
SQLE_SYNTAX_ERROR | See Syntax error near '%1' %2.
SQLE_TABLE_HAS_PUBLICATIONS | See Table '%1' has publications.
SQLE_TABLE_IN_USE | See Table in use.
SQLE_TABLE_NOT_FOUND | See Table '%1' not found.
SQLE_TOO_MANY_CONNECTIONS | See Database server connection limit exceeded.
SQLE_TOO_MANY_TEMP_TABLES | See too many temporary tables in connection.
SQLE_ULTRALITE_DATABASE_NOT_FOUND | See The database '%1' was not found.
SQLE_ULTRALITE_OBJ_CLOSED | See Invalid operation on a closed '%1'.
SQLE_ULTRALITE_RUNTIME_LIBRARY_MISMATCH | See UltraLite runtime library is incompatible with the database file.
SQLE_UNABLE_TO_CONNECT | See Database cannot be started -- %1.
SQLE_UNABLE_TO_START_DATABASE | See Unable to start specified database: %1.
SQLE_UNABLE_TO_START_DATABASE_VER_NEWER | See Unable to start specified database: Server must be upgraded to start database %1.
SQLE_UNCOMMITTED_TRANSACTIONS | See You cannot synchronize or upgrade with uncommitted transactions.
SQLE_UNKNOWN_FUNC | See Unknown function '%1'.
SQLE_UNKNOWN_USERID | See User ID '%1' does not exist.
SQLE_UNRECOGNIZED_OPTION | See The option '%1' is not recognized..
SQLE_UNSUPPORTED_CHARACTER_SET_ERROR | See Database server cannot convert data from/to character set '%1'.
SQLE_UPLOAD_FAILED_AT_SERVER | See Synchronization server failed to commit the upload.
SQLE_WRONG_NUM_OF_INSERT_COLS | See Wrong number of values for INSERT.
SQLE_WRONG_PARAMETER_COUNT | See Wrong number of parameters to function '%1'.


ULStreamErrorCode enumeration

UL Ext.: Enumerates the error codes that may be reported by streams during synchronization.

Prototypes

' Visual Basic
Public Enum ULStreamErrorCode

// C#
public enum ULStreamErrorCode

Members
Member | Description
ACTSYNC_NO_PORT | ACTSYNC_NO_PORT(75)
ACTSYNC_NOT_INSTALLED | ACTSYNC_NOT_INSTALLED(76)
CREATE_RANDOM_OBJECT | CREATE_RANDOM_OBJECT(17)
DEQUEUING_CONNECTION | DEQUEUING_CONNECTION(19)
END_READ | END_READ(11)
END_WRITE | END_WRITE(10)
GENERATE_RANDOM | GENERATE_RANDOM(14)
HTTP_BAD_STATUS_CODE | HTTP_BAD_STATUS_CODE(86)
HTTP_BUFFER_SIZE_OUT_OF_RANGE | HTTP_BUFFER_SIZE_OUT_OF_RANGE(79)
HTTP_CHUNK_LEN_BAD_CHARACTER | HTTP_CHUNK_LEN_BAD_CHARACTER(85)
HTTP_CHUNK_LEN_ENCODED_MISSING | HTTP_CHUNK_LEN_ENCODED_MISSING(84)
HTTP_CLIENT_ID_NOT_SET | HTTP_CLIENT_ID_NOT_SET(78)
HTTP_CONTENT_TYPE_NOT_SPECIFIED | HTTP_CONTENT_TYPE_NOT_SPECIFIED(77)
HTTP_CRLF_ENCODED_MISSING | HTTP_CRLF_ENCODED_MISSING(81)
HTTP_CRLF_MISSING | HTTP_CRLF_MISSING(82)
HTTP_EXPECTED_POST | HTTP_EXPECTED_POST(89)
HTTP_EXTRA_DATA_END_READ | HTTP_EXTRA_DATA_END_READ(80)
HTTP_NO_CONTD_CONNECTION | HTTP_NO_CONTD_CONNECTION(83)
HTTP_UNABLE_TO_PARSE_COOKIE | HTTP_UNABLE_TO_PARSE_COOKIE(88)
HTTP_UNKNOWN_TRANSFER_ENCODING | HTTP_UNKNOWN_TRANSFER_ENCODING(87)
HTTP_VERSION | HTTP_VERSION(54)
INIT_RANDOM | INIT_RANDOM(15)
LOAD_NETWORK_LIBRARY | LOAD_NETWORK_LIBRARY(74)
MEMORY_ALLOCATION | MEMORY_ALLOCATION(6)
NONE | NONE(0)
NOT_IMPLEMENTED | NOT_IMPLEMENTED(12)
PARAMETER | PARAMETER(1)
PARAMETER_NOT_BOOLEAN | PARAMETER_NOT_BOOLEAN(4)
PARAMETER_NOT_HEX | PARAMETER_NOT_HEX(5)
PARAMETER_NOT_UINT32 | PARAMETER_NOT_UINT32(2)
PARAMETER_NOT_UINT32_RANGE | PARAMETER_NOT_UINT32_RANGE(3)
PARSE | PARSE(7)
READ | READ(8)
SECURE_ADD_CERTIFICATE | SECURE_ADD_CERTIFICATE(39)
SECURE_ADD_TRUSTED_CERTIFICATE | SECURE_ADD_TRUSTED_CERTIFICATE(48)
SECURE_CERTIFICATE_CHAIN_FUNC | SECURE_CERTIFICATE_CHAIN_FUNC(28)
SECURE_CERTIFICATE_CHAIN_LENGTH | SECURE_CERTIFICATE_CHAIN_LENGTH(22)
SECURE_CERTIFICATE_CHAIN_REF | SECURE_CERTIFICATE_CHAIN_REF(29)
SECURE_CERTIFICATE_COMMON_NAME | SECURE_CERTIFICATE_COMMON_NAME(52)
SECURE_CERTIFICATE_COMPANY_NAME | SECURE_CERTIFICATE_COMPANY_NAME(21)
SECURE_CERTIFICATE_COMPANY_UNIT | SECURE_CERTIFICATE_COMPANY_UNIT(51)
SECURE_CERTIFICATE_COUNT | SECURE_CERTIFICATE_COUNT(42)
SECURE_CERTIFICATE_EXPIRED | SECURE_CERTIFICATE_EXPIRED(50)
SECURE_CERTIFICATE_EXPIRY_DATE | SECURE_CERTIFICATE_EXPIRY_DATE(37)
SECURE_CERTIFICATE_FILE_NOT_FOUND | SECURE_CERTIFICATE_FILE_NOT_FOUND(33)
SECURE_CERTIFICATE_NOT_TRUSTED | SECURE_CERTIFICATE_NOT_TRUSTED(24)
SECURE_CERTIFICATE_REF | SECURE_CERTIFICATE_REF(23)
SECURE_CERTIFICATE_ROOT | SECURE_CERTIFICATE_ROOT(20)
SECURE_CREATE_CERTIFICATE | SECURE_CREATE_CERTIFICATE(43)
SECURE_CREATE_PRIVATE_KEY_OBJECT | SECURE_CREATE_PRIVATE_KEY_OBJECT(49)
SECURE_DUPLICATE_CONTEXT | SECURE_DUPLICATE_CONTEXT(25)
SECURE_ENABLE_NON_BLOCKING | SECURE_ENABLE_NON_BLOCKING(30)
SECURE_EXPORT_CERTIFICATE | SECURE_EXPORT_CERTIFICATE(38)
SECURE_HANDSHAKE | SECURE_HANDSHAKE(53)
SECURE_IMPORT_CERTIFICATE | SECURE_IMPORT_CERTIFICATE(44)
SECURE_READ_CERTIFICATE | SECURE_READ_CERTIFICATE(34)
SECURE_READ_PRIVATE_KEY | SECURE_READ_PRIVATE_KEY(35)
SECURE_SET_CHAIN_NUMBER | SECURE_SET_CHAIN_NUMBER(32)
SECURE_SET_CIPHER_SUITES | SECURE_SET_CIPHER_SUITES(31)
SECURE_SET_IO | SECURE_SET_IO(26)
SECURE_SET_IO_SEMANTICS | SECURE_SET_IO_SEMANTICS(27)
SECURE_SET_PRIVATE_KEY | SECURE_SET_PRIVATE_KEY(36)
SECURE_SET_PROTOCOL_SIDE | SECURE_SET_PROTOCOL_SIDE(47)
SECURE_SET_RANDOM_FUNC | SECURE_SET_RANDOM_FUNC(46)
SECURE_SET_RANDOM_REF | SECURE_SET_RANDOM_REF(45)
SECURE_SET_READ_FUNC | SECURE_SET_READ_FUNC(55)
SECURE_SET_WRITE_FUNC | SECURE_SET_WRITE_FUNC(56)
SECURE_TRUSTED_CERTIFICATE_FILE_NOT_FOUND | SECURE_TRUSTED_CERTIFICATE_FILE_NOT_FOUND(40)
SECURE_TRUSTED_CERTIFICATE_READ | SECURE_TRUSTED_CERTIFICATE_READ(41)
SEED_RANDOM | SEED_RANDOM(16)
SHUTTING_DOWN | SHUTTING_DOWN(18)
SOCKET_BIND | SOCKET_BIND(62)
SOCKET_CLEANUP | SOCKET_CLEANUP(63)
SOCKET_CLOSE | SOCKET_CLOSE(64)
SOCKET_CONNECT | SOCKET_CONNECT(65)
SOCKET_CREATE_TCPIP | SOCKET_CREATE_TCPIP(60)
SOCKET_CREATE_UDP | SOCKET_CREATE_UDP(61)
SOCKET_GET_HOST_BY_ADDR | SOCKET_GET_HOST_BY_ADDR(58)
SOCKET_GET_NAME | SOCKET_GET_NAME(66)
SOCKET_GET_OPTION | SOCKET_GET_OPTION(67)
SOCKET_HOST_NAME_NOT_FOUND | SOCKET_HOST_NAME_NOT_FOUND(57)
SOCKET_LISTEN | SOCKET_LISTEN(69)
SOCKET_LOCALHOST_NAME_NOT_FOUND | SOCKET_LOCALHOST_NAME_NOT_FOUND(59)
SOCKET_PORT_OUT_OF_RANGE | SOCKET_PORT_OUT_OF_RANGE(73)
SOCKET_SELECT | SOCKET_SELECT(71)
SOCKET_SET_OPTION | SOCKET_SET_OPTION(68)
SOCKET_SHUTDOWN | SOCKET_SHUTDOWN(70)
SOCKET_STARTUP | SOCKET_STARTUP(72)
WOULD_BLOCK | WOULD_BLOCK(13)
WRITE | WRITE(9)
See also
  • StreamErrorCode property


ULStreamErrorContext enumeration

UL Ext.: Enumerates the basic network operation being performed when the stream errors occured.

Prototypes

' Visual Basic
Public Enum ULStreamErrorContext

// C#
public enum ULStreamErrorContext

Members
Member | Description
CLOSE | CLOSE(6)
CREATE | CREATE(3)
DESTROY | DESTROY(4)
END_READ | END_READ(11)
END_WRITE | END_WRITE(10)
GETVALUE | GETVALUE(14)
OPEN | OPEN(5)
READ | READ(7)
REGISTER | REGISTER(1)
SOFTSHUTDOWN | SOFTSHUTDOWN(13)
UNKNOWN | UNKNOWN(0)
UNREGISTER | UNREGISTER(2)
WRITE | WRITE(8)
WRITE_FLUSH | WRITE_FLUSH(9)
YIELD | YIELD(12)
See also
  • StreamErrorContext property


ULStreamErrorID enumeration

UL Ext.: Enumerates the network layers that may report errors during synchronization.

Prototypes

' Visual Basic
Public Enum ULStreamErrorID

// C#
public enum ULStreamErrorID

Members
Member | Description
ACTIVESYNC | ACTIVESYNC(22)
CERTICOM | CERTICOM(11)
CERTICOM_SSL | CERTICOM_SSL(13)
CERTICOM_TLS | CERTICOM_TLS(14)
DH_CAST | DH_CAST(9)
EMAIL | EMAIL(20)
FAKE | FAKE(2)
FILE | FILE(21)
HTTP | HTTP(7)
HTTPS | HTTPS(8)
JAVA_CERTICOM | JAVA_CERTICOM(12)
JAVA_RSA | JAVA_RSA(24)
NETTECH | NETTECH(5)
PALM_CONDUIT | PALM_CONDUIT(3)
PALM_SS | PALM_SS(4)
REPLAY | REPLAY(17)
RIMBB | RIMBB(6)
RSA_TLS | RSA_TLS(23)
SECURE | SECURE(10)
SERIAL | SERIAL(1)
STRM | STRM(18)
TCPIP | TCPIP(0)
UDP | UDP(19)
WIRELESS | WIRELESS(16)
WIRESTRM | WIRESTRM(15)
See also
  • StreamErrorID property


ULStreamType enumeration

UL Ext.: Enumerates the types of MobiLink synchronization streams to use for synchronization.

Prototypes

' Visual Basic
Public Enum ULStreamType

// C#
public enum ULStreamType

Remarks

For information on configuring specific stream types, refer to Network protocol options for UltraLite synchronization clients.

Members
Member | Description
ACTIVE_SYNC | ActiveSync synchronization (Windows CE only). UltraLite applications should only use ActiveSync synchronization when notified to do so by the MobiLink provider for ActiveSync. An application can listen for such notification by implementing a ULActiveSyncListener interface and calling SetActiveSyncListener method.
HTTP | Synchronize via HTTP. The HTTP stream uses TCP/IP as its underlying transport. UltraLite applications act as Web browsers and the MobiLink synchronization server acts as a Web server. UltraLite applications send POST requests to send data to the server and GET requests to read data from the server.
HTTPS | Synchronize via HTTPS (HTTP with RSA transport-layer security). Transport-layer security is a separately-licensable component and must be ordered before you can install it. To order this component, see the card in your SQL Anywhere Studio package, or see [external link] http://www.sybase.com/detail?id=1015780.
TCPIP | Synchronize via TCP/IP.
UNKNOWN | Unknown or no synchronization stream. The user has not set the stream type.
See also
  • Stream property


ULSyncParms class

UL Ext.: Represents synchronization parameters that define how to synchronize an UltraLite database.

Prototypes

' Visual Basic
NotInheritable Public Class ULSyncParms

// C#
public sealed class ULSyncParms

Remarks

This class cannot be directly instantiated. Each connection has its own ULSyncParms instance, attached as its SyncParms property property.

At most, only one synchronization command (DownloadOnly property, PingOnly property, ResumePartialDownload property, or UploadOnly property) may be specified at a time. If more than one of these parameters is set to true, a ULSQLCode enumeration SQLException is thrown by Synchronize method.

Other sources of ULSQLCode enumeration errors include not specifying a Stream property value or a Version property value.

See also
  • ULSyncParms members
  • ULConnection class
  • SyncParms property
  • Synchronize method

ULSyncParms members
AuthenticationParms property
CheckpointStore property
DisableConcurrency property
DownloadOnly property
KeepPartialDownload property
NewPassword property
Password property
PingOnly property
PublicationMask property
ResumePartialDownload property
SendColumnNames property
SendDownloadAck property
Stream property
StreamParms property
UploadOnly property
UserName property
Version property
CopyFrom method
Finalize method


ULSyncParms members

Public instance properties
Member | Description
AuthenticationParms property | Specifies parameters for a custom user authentication script (MobiLink authenticate_parameters connection event).
CheckpointStore property | Specifies whether the client should perform extra store checkpoints to control the growth of the database store during synchronization.
DisableConcurrency property | Specifies whether concurrent access to UltraLite while performing a synchronization.
DownloadOnly property | Specifies whether to disable or enable uploads when synchronizing.
KeepPartialDownload property | Specifies whether to disable or enable partial downloads when synchronizing.
NewPassword property | Specifies a new MobiLink password for the user specified with UserName.
Password property | The MobiLink password for the user specified by UserName.
PingOnly property | Specifies whether the client should only ping the MobiLink synchronization server instead of performing a real synchronization.
PublicationMask property | Specifies the publications to be synchronized.
ResumePartialDownload property | Specifies whether to resume or discard a previous partial download.
SendColumnNames property | Specifies whether the client should send column names to the MobiLink synchronization server during synchronization.
SendDownloadAck property | Specifies whether the client should send a download acknowledgement to the MobiLink synchronization server during synchronization.
Stream property | Specifies the MobiLink synchronization stream to use for synchronization.
StreamParms property | Specifies the parameters to configure the synchronization stream.
UploadOnly property | Specifies whether to disable or enable downloads when synchronizing.
UserName property | The user name that uniquely identifies the MobiLink client to the MobiLink synchronization server.
Version property | Specifies which synchronization script to use.
Public instance methods
Member | Description
CopyFrom method | Copies the properties of the specified ULSyncParms class object to this ULSyncParms class object.
Protected instance methods
Member | Description
Finalize method | Releases unmanaged resources and performs other cleanup operations before the ULSyncParms is reclaimed by garbage collection.


AuthenticationParms property

Specifies parameters for a custom user authentication script (MobiLink authenticate_parameters connection event).

Prototypes

' Visual Basic
Public Property AuthenticationParms As String()

// C#
public string [] AuthenticationParms {get;set;}

Property value

An array of strings, each containing an authentication parameter (null array entries result in a synchronization error). The default is a null reference (Nothing in Visual Basic), meaning no authentication parameters.

Remarks

Only the first 255 strings are used and each string should be no longer than 128 characters (longer strings are truncated when sent to the MobiLink synchronization server).


CheckpointStore property

Specifies whether the client should perform extra store checkpoints to control the growth of the database store during synchronization.

Prototypes

' Visual Basic
Public Property CheckpointStore As Boolean

// C#
public bool CheckpointStore {get;set;}

Property value

True to specify that the client should perform extra store checkpoints. The default is false, meaning only required checkpointing is done.

Remarks

The checkpoint operation adds I/O operations for the application, and so slows synchronization. This option is most useful for large downloads with many updates. Devices with slow flash memory may not want to pay the performance penalty associated with additional checkpoints.


DisableConcurrency property

Specifies whether concurrent access to UltraLite while performing a synchronization.

Prototypes

' Visual Basic
Public Property DisableConcurrency As Boolean

// C#
public bool DisableConcurrency {get;set;}

Property value

True to disable concurrent access to UltraLite while performing a synchronization, false to enable concurrent access. The default is false.

Remarks

By default, other threads may perform UltraLite operations while a thread is synchronizing. When concurrent synchronization is disabled, other threads will block on UltraLite calls until synchronization completes.


DownloadOnly property

Specifies whether to disable or enable uploads when synchronizing.

Prototypes

' Visual Basic
Public Property DownloadOnly As Boolean

// C#
public bool DownloadOnly {get;set;}

Property value

True to disable uploads when synchronizing, false to enable uploads. The default is false.

Remarks

At most, only one synchronization command (DownloadOnly property, PingOnly property, ResumePartialDownload property, or UploadOnly property) may be specified at a time. If more than one of these parameters is set to true, a ULSQLCode enumeration SQLException is thrown by Synchronize method.

See also
  • ULSyncParms class
  • ULSyncParms members
  • UploadOnly property


KeepPartialDownload property

Specifies whether to disable or enable partial downloads when synchronizing.

Prototypes

' Visual Basic
Public Property KeepPartialDownload As Boolean

// C#
public bool KeepPartialDownload {get;set;}

Property value

True to enable partial downloads when synchronizing, false to disable partial downloads. The default is false.

Remarks

UltraLite.NET has the ability to restart downloads that fail because of communication errors or user aborts through the ULSyncProgressListener. UltraLite.NET processes the download as it is received. If a download is interrupted, then the partial download transaction remains in the database and can be resumed during the next synchronization.

To indicate that UltraLite.NET should save partial downloads, specify connection.SyncParms.KeepPartialDownload=true; otherwise the download is rolled back if an error occurs.

If a partial download was kept, then the output field connection.SyncResult.PartialDownloadRetained property is set to true when connection.Synchronize() exits.

If PartialDownloadRetained is set, then you can resume a download. To do this, call connection.Synchronize() with connection.SyncParms.ResumePartialDownload property set to true. It is recommended that you keep KeepPartialDownload set to true as well in case another communications error occurs. No upload is done if a download is skipped.

The download you receive during a resumed download will be as old as when the download originally began. If you need the most up to date data, then you can do another download immediately after the special resumed download completes.

When resuming a download, many of the ULSyncParms fields are not relevant. For example, the PublicationMask field is not used. You will receive the publications that you requested on the initial download. The only fields that need to be set are ResumePartialDownload property and UserName property. The fields KeepPartialDownload and DisableConcurrency property may be set if desired and will function as normal.

If you have a partial download and it is no longer needed, then you can call RollbackPartialDownload method to roll back the failed download transaction. Also, if you attempt to synchronize again and do not specify ResumePartialDownload, then the partial download is rolled back before the next synchronization begins.

For more information, refer to the Resuming failed downloads.

See also
  • ULSyncParms class
  • ULSyncParms members
  • PartialDownloadRetained property
  • ResumePartialDownload property
  • RollbackPartialDownload method


NewPassword property

Specifies a new MobiLink password for the user specified with UserName.

Prototypes

' Visual Basic
Public Property NewPassword As String

// C#
public string NewPassword {get;set;}

Property value

A string specifying a new MobiLink password. The default is a null reference (Nothing in Visual Basic), meaning the password is not changed.

Remarks

A new password takes effect after the next synchronization.

See also
  • ULSyncParms class
  • ULSyncParms members
  • UserName property


Password property

The MobiLink password for the user specified by UserName.

Prototypes

' Visual Basic
Public Property Password As String

// C#
public string Password {get;set;}

Property value

A string specifying the MobiLink password. The default is a null reference (Nothing in Visual Basic), meaning no password is specified.

Remarks

The MobiLink user name and password are separate from any database user ID and password, and serve to identify and authenticate the application to the MobiLink synchronization server.

See also
  • ULSyncParms class
  • ULSyncParms members
  • NewPassword property
  • UserName property


PingOnly property

Specifies whether the client should only ping the MobiLink synchronization server instead of performing a real synchronization.

Prototypes

' Visual Basic
Public Property PingOnly As Boolean

// C#
public bool PingOnly {get;set;}

Property value

True to specify that the client should only ping the MobiLink synchronization server, false to specify the client should perform a real synchronization. The default is false.

Remarks

At most, only one synchronization command (DownloadOnly property, PingOnly property, ResumePartialDownload property, or UploadOnly property) may be specified at a time. If more than one of these parameters is set to true, a ULSQLCode enumeration SQLException is thrown by Synchronize method.


PublicationMask property

Specifies the publications to be synchronized.

Prototypes

' Visual Basic
Public Property PublicationMask As Integer

// C#
public int PublicationMask {get;set;}

Property value

A bitwise combination of publication masks, the special value SYNC_ALL_PUBS field, or the special value SYNC_ALL_DB field. The default is SYNC_ALL_DB field. See ULPublicationSchema class for more information on publication masks.

See also
  • ULSyncParms class
  • ULSyncParms members
  • Mask property


ResumePartialDownload property

Specifies whether to resume or discard a previous partial download.

Prototypes

' Visual Basic
Public Property ResumePartialDownload As Boolean

// C#
public bool ResumePartialDownload {get;set;}

Property value

True to resume a previous partial download, false to discard a previous partial download. The default is false.

Remarks

Only at most one synchronization command (DownloadOnly property, PingOnly property, ResumePartialDownload property, or UploadOnly property) may be specified at a time. If more than one of these parameters is set to true, a ULSQLCode enumeration SQLException is thrown by Synchronize method.

For more information on partial downloads, see KeepPartialDownload property.

See also
  • ULSyncParms class
  • ULSyncParms members
  • PartialDownloadRetained property


SendColumnNames property

Specifies whether the client should send column names to the MobiLink synchronization server during synchronization.

Prototypes

' Visual Basic
Public Property SendColumnNames As Boolean

// C#
public bool SendColumnNames {get;set;}

Property value

True to specify that the client should send column names to the MobiLink synchronization server, false to specify that column names are not sent. The default is false.

Remarks

This parameter is typically used together with the -za or -ze option on the MobiLink synchronization server for automatically generating synchronization scripts.


SendDownloadAck property

Specifies whether the client should send a download acknowledgement to the MobiLink synchronization server during synchronization.

Prototypes

' Visual Basic
Public Property SendDownloadAck As Boolean

// C#
public bool SendDownloadAck {get;set;}

Property value

True to specify that the client should send a download acknowledgement to the MobiLink synchronization server, false to specify that no download acknowledgement is sent. The default is false.

Remarks

If the client sends a download acknowledgement, the MobiLink synchronization server worker thread must wait for the client to apply the download. If the client does not sent a download acknowledgement, the MobiLink synchronization server is freed up sooner for its next synchronization.


Stream property

Specifies the MobiLink synchronization stream to use for synchronization.

Prototypes

' Visual Basic
Public Property Stream As ULStreamType

// C#
public ULStreamType Stream {get;set;}

Property value

One of the ULStreamType enumeration values specifying the type of synchronization stream to use. This parameter has no default value, and must be explicitly set.

Remarks

Most synchronization streams require parameters to identify the MobiLink synchronization server address and control other behavior. These parameters are supplied by the StreamParms property property.

If the stream type is set to a value that is invalid for the platform, the stream type will be set to ULStreamType enumeration.

See also
  • ULSyncParms class
  • ULSyncParms members
  • ULStreamType enumeration
  • StreamParms property


StreamParms property

Specifies the parameters to configure the synchronization stream.

Prototypes

' Visual Basic
Public Property StreamParms As String

// C#
public string StreamParms {get;set;}

Property value

A string, in the form of a semicolon-separated list of keyword-value pairs, specifying the parameters for the stream. The default is a null reference (Nothing in Visual Basic).

Remarks

For information on configuring specific stream types, refer to Network protocol options for UltraLite synchronization clients.

StreamParms is a string containing all the parameters used for synchronization streams. Parameters are specified as a semicolon-separated list of name=value pairs ("param1=value1;param2=value2").

See also
  • ULSyncParms class
  • ULSyncParms members
  • Stream property
  • ULStreamType enumeration


UploadOnly property

Specifies whether to disable or enable downloads when synchronizing.

Prototypes

' Visual Basic
Public Property UploadOnly As Boolean

// C#
public bool UploadOnly {get;set;}

Property value

True to disable downloads, false to enable downloads. The default is false.

Remarks

At most, only one synchronization command (DownloadOnly property, PingOnly property, ResumePartialDownload property, or UploadOnly property) may be specified at a time. If more than one of these parameters is set to true, a ULSQLCode enumeration SQLException is thrown by Synchronize method.

See also
  • ULSyncParms class
  • ULSyncParms members
  • DownloadOnly property


UserName property

The user name that uniquely identifies the MobiLink client to the MobiLink synchronization server.

Prototypes

' Visual Basic
Public Property UserName As String

// C#
public string UserName {get;set;}

Property value

A string specifying the user name. This parameter has no default value, and must be explicitly set.

Remarks

MobiLink uses this value to determine the download content, to record the synchronization state, and to recover from interruptions during synchronization. This user name and password are separate from any database user ID and password, and serve to identify and authenticate the application to the MobiLink synchronization server.

See also
  • ULSyncParms class
  • ULSyncParms members
  • Password property


Version property

Specifies which synchronization script to use.

Prototypes

' Visual Basic
Public Property Version As String

// C#
public string Version {get;set;}

Property value

A string specifying the version of the synchronization script to use. This parameter has no default value, and must be explicitly set.

Remarks

Each synchronization script in the consolidated database is marked with a version string. For example, there may be two different download_cursor scripts, with each one identified by different a version string. The version string allows an UltraLite application to choose from a set of synchronization scripts.


CopyFrom method

Copies the properties of the specified ULSyncParms class object to this ULSyncParms class object.

Prototypes

' Visual Basic
Public Sub CopyFrom( _
ByVal src As ULSyncParms _
)

// C#
public void CopyFrom(
ULSyncParms src
);

Parameters

  • src The object to copy from.


Finalize method

Releases unmanaged resources and performs other cleanup operations before the ULSyncParms is reclaimed by garbage collection.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


ULSyncProgressData class

UL Ext.: Returns synchronization progress monitoring data.

Prototypes

' Visual Basic
Public Class ULSyncProgressData

// C#
public class ULSyncProgressData

See also
  • ULSyncProgressData members
  • ULSyncProgressListener interface

ULSyncProgressData members
ErrorMessage property
ReceivedBytes property
ReceivedDeletes property
ReceivedInserts property
ReceivedUpdates property
SentBytes property
SentDeletes property
SentInserts property
SentUpdates property
SQLCode property
State property
SyncParms property
SyncResult property
TableCount property
TableIndex property
TableTotal property


ULSyncProgressData members

Public instance properties
Member | Description
ErrorMessage property | Returns the error message describing the error that occurred during synchronization.
ReceivedBytes property | Returns the number of bytes received so far. This information is updated for all states.
ReceivedDeletes property | Returns the number of deleted rows received so far.
ReceivedInserts property | Returns the number of inserted rows received so far.
ReceivedUpdates property | Returns the number of updated rows received so far.
SentBytes property | Returns the number of bytes sent so far. This information is updated for all states.
SentDeletes property | Returns the number of deleted rows sent so far.
SentInserts property | Returns the number of inserted rows sent so far.
SentUpdates property | Returns the number of updated rows sent so far.
SQLCode property | Returns the SQL code for synchronization.
State property | Returns the current synchronization state.
SyncParms property | Returns a reference to the connection's SyncParms object.
SyncResult property | Returns a reference to the connection's SyncResult object. This object is only updated with ULSyncProgressState enumeration and ULSyncProgressState enumeration events.
TableCount property | A count of the tables sent or received (TableCount of TableTotal) so far.
TableIndex property | Returns the index of the table currently being synchronized (tables are numbered 1 to DatabaseSchema.TableCount).
TableTotal property | Returns the number of tables being synchronized.


ErrorMessage property

Returns the error message describing the error that occurred during synchronization.

Prototypes

' Visual Basic
Public Readonly Property ErrorMessage As String

// C#
public string ErrorMessage {get;}

Property value

A string describing the error that occurred during synchronization.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration


ReceivedBytes property

Returns the number of bytes received so far. This information is updated for all states.

Prototypes

' Visual Basic
Public Readonly Property ReceivedBytes As Long

// C#
public long ReceivedBytes {get;}

Property value

The number of bytes received so far.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration


ReceivedDeletes property

Returns the number of deleted rows received so far.

Prototypes

' Visual Basic
Public Readonly Property ReceivedDeletes As Integer

// C#
public int ReceivedDeletes {get;}

Property value

The number of deleted rows received so far.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration


ReceivedInserts property

Returns the number of inserted rows received so far.

Prototypes

' Visual Basic
Public Readonly Property ReceivedInserts As Integer

// C#
public int ReceivedInserts {get;}

Property value

The number of inserted rows received so far.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration


ReceivedUpdates property

Returns the number of updated rows received so far.

Prototypes

' Visual Basic
Public Readonly Property ReceivedUpdates As Integer

// C#
public int ReceivedUpdates {get;}

Property value

The number of updated rows received so far.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration


SentBytes property

Returns the number of bytes sent so far. This information is updated for all states.

Prototypes

' Visual Basic
Public Readonly Property SentBytes As Long

// C#
public long SentBytes {get;}

Property value

The number of bytes sent so far.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration


SentDeletes property

Returns the number of deleted rows sent so far.

Prototypes

' Visual Basic
Public Readonly Property SentDeletes As Integer

// C#
public int SentDeletes {get;}

Property value

The number of deleted rows sent so far.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration


SentInserts property

Returns the number of inserted rows sent so far.

Prototypes

' Visual Basic
Public Readonly Property SentInserts As Integer

// C#
public int SentInserts {get;}

Property value

The number of inserted rows sent so far.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration


SentUpdates property

Returns the number of updated rows sent so far.

Prototypes

' Visual Basic
Public Readonly Property SentUpdates As Integer

// C#
public int SentUpdates {get;}

Property value

The number of updated rows sent so far.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration


SQLCode property

Returns the SQL code for synchronization.

Prototypes

' Visual Basic
Public Readonly Property SQLCode As ULSQLCode

// C#
public ULSQLCode SQLCode {get;}

Property value

The ULSQLCode enumeration value for any synchronization error.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration


State property

Returns the current synchronization state.

Prototypes

' Visual Basic
Public Readonly Property State As ULSyncProgressState

// C#
public ULSyncProgressState State {get;}

Property value

One of the ULSyncProgressState enumeration values specifying the current synchronization state.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration


SyncParms property

Returns a reference to the connection's SyncParms object.

Prototypes

' Visual Basic
Public Readonly Property SyncParms As ULSyncParms

// C#
public ULSyncParms SyncParms {get;}

Property value

A reference to the SyncParms property object.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration
  • SyncParms property


SyncResult property

Returns a reference to the connection's SyncResult object. This object is only updated with ULSyncProgressState enumeration and ULSyncProgressState enumeration events.

Prototypes

' Visual Basic
Public Readonly Property SyncResult As ULSyncResult

// C#
public ULSyncResult SyncResult {get;}

Property value

A reference to the SyncResult property object.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration


TableCount property

A count of the tables sent or received (TableCount of TableTotal) so far.

Prototypes

' Visual Basic
Public Readonly Property TableCount As Integer

// C#
public int TableCount {get;}

Property value

The count of tables sent or received.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration


TableIndex property

Returns the index of the table currently being synchronized (tables are numbered 1 to DatabaseSchema.TableCount).

Prototypes

' Visual Basic
Public Readonly Property TableIndex As Integer

// C#
public int TableIndex {get;}

Property value

The index of the table currently being synchronized. Tables are numbered 1 to TableCount property.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration


TableTotal property

Returns the number of tables being synchronized.

Prototypes

' Visual Basic
Public Readonly Property TableTotal As Integer

// C#
public int TableTotal {get;}

Property value

The number of tables being synchronized.

See also
  • ULSyncProgressData class
  • ULSyncProgressData members
  • ULSyncProgressState enumeration
  • ULSyncProgressState enumeration


ULSyncProgressListener interface

UL Ext.: The listener interface for receiving synchronization progress events.

Prototypes

' Visual Basic
Public Interface ULSyncProgressListener

// C#
public interface ULSyncProgressListener

See also
  • ULSyncProgressListener members
  • Synchronize method


ULSyncProgressListener members

Public instance methods
Member | Description
SyncProgressed method | Invoked during synchronization to inform the user of progress. This method should return true to cancel synchronization or return false to continue.


SyncProgressed method

Invoked during synchronization to inform the user of progress. This method should return true to cancel synchronization or return false to continue.

Prototypes

' Visual Basic
Public Function SyncProgressed( _
ByVal data As ULSyncProgressData _
) As Boolean

// C#
public bool SyncProgressed(
ULSyncProgressData data
);

Parameters

  • data A ULSyncProgressData class object containing the latest synchronization progress data.

Return value

This method should return true to cancel synchronization or return false to continue.

Remarks

No UltraLite.NET API methods should be invoked during a SyncProgressed call.


ULSyncProgressState enumeration

UL Ext.: Enumerates all the states that can occur while synchronizing.

Prototypes

' Visual Basic
Public Enum ULSyncProgressState

// C#
public enum ULSyncProgressState

Members
Member | Description
STATE_CANCELLED | Synchronization has been cancelled.
STATE_COMMITTING_DOWNLOAD | The download is being committed. The final count of rows received is included with this event. See ReceivedBytes property, ReceivedInserts property, ReceivedUpdates property, and ReceivedDeletes property.
STATE_CONNECTING | The synchronization stream has been built, but is not yet opened.
STATE_DISCONNECTING | The synchronization stream is about to be closed.
STATE_DONE | Synchronization has successfully completed. The connection's SyncResult property object has been updated.
STATE_ERROR | Synchronization has completed, but an error occurred. Check SyncResult property, ErrorMessage property, and SQLCode property for details.
STATE_FINISHING_UPLOAD | The upload is completing. The final count of rows sent is included with this event. See SentBytes property, SentInserts property, SentUpdates property, and SentDeletes property.
STATE_LAST | The last state entered by synchronization. This state is always entered and always after any other state. Other ULSyncProgressData fields may not contain valid data.
STATE_RECEIVING_DATA | Data for the current table is being received. ReceivedBytes property, ReceivedInserts property, ReceivedUpdates property, and ReceivedDeletes property have been updated.
STATE_RECEIVING_TABLE | A table is being received. Progress can be monitored using TableIndex property and TableCount property.
STATE_RECEIVING_UPLOAD_ACK | An acknowledgement that the upload is complete is being received.
STATE_ROLLING_BACK_DOWNLOAD | Synchronization is rolling back the download because an error was encountered during the download. The error will be reported with a subsequent STATE_ERROR progress report.
STATE_SENDING_DATA | Data for the current table is being sent. SentBytes property, SentInserts property, SentUpdates property, and SentDeletes property have been updated.
STATE_SENDING_DOWNLOAD_ACK | An acknowledgement that the download is complete is being sent.
STATE_SENDING_HEADER | The synchronization stream has been opened and the header is about to be sent.
STATE_SENDING_TABLE | A table is being sent. Progress can be monitored using TableIndex property and TableCount property.
STATE_STARTING | No synchronization actions have been taken yet.
See also
  • ULSyncProgressData class


ULSyncResult class

UL Ext.: Represents the status of the last synchronization.

Prototypes

' Visual Basic
Public Class ULSyncResult

// C#
public class ULSyncResult

Remarks

This class cannot be directly instantiated. Each connection has its own ULSyncResult instance, attached as its SyncResult property property. A ULSyncResult instance is only valid while that connection is open.

See also
  • ULSyncResult members
  • SyncResult property
  • Synchronize method

ULSyncResult members
AuthStatus property
AuthValue property
IgnoredRows property
PartialDownloadRetained property
StreamErrorCode property
StreamErrorContext property
StreamErrorID property
StreamErrorSystem property
Timestamp property
UploadOK property
Finalize method


ULSyncResult members

Public instance properties
Member | Description
AuthStatus property | Returns the authorization status code for the last synchronization attempt.
AuthValue property | Returns the return value from custom user authentication synchronization scripts.
IgnoredRows property | Checks whether any uploaded rows were ignored or not during the last synchronization.
PartialDownloadRetained property | Checks whether a partial download was retained or not during the last synchronization.
StreamErrorCode property | Returns the error reported by the stream itself.
StreamErrorContext property | Returns the basic network operation being performed when the stream error occurred.
StreamErrorID property | Returns the ID of the network layer reporting an error.
StreamErrorSystem property | Returns the stream error system-specific code.
Timestamp property | Returns the timestamp of the last synchronization.
UploadOK property | Checks whether the last upload synchronization was successful or not.
Protected instance methods
Member | Description
Finalize method | Releases unmanaged resources and performs other cleanup operations before the ULSyncResult is reclaimed by garbage collection.


AuthStatus property

Returns the authorization status code for the last synchronization attempt.

Prototypes

' Visual Basic
Public Readonly Property AuthStatus As ULAuthStatusCode

// C#
public ULAuthStatusCode AuthStatus {get;}

Property value

One of the ULAuthStatusCode enumeration values denoting the authorization status for the last synchronization attempt.


AuthValue property

Returns the return value from custom user authentication synchronization scripts.

Prototypes

' Visual Basic
Public Readonly Property AuthValue As Long

// C#
public long AuthValue {get;}

Property value

A long integer returned from custom user authentication synchronization scripts.


IgnoredRows property

Checks whether any uploaded rows were ignored or not during the last synchronization.

Prototypes

' Visual Basic
Public Readonly Property IgnoredRows As Boolean

// C#
public bool IgnoredRows {get;}

Property value

True if any uploaded rows were ignored during the last synchronization, false if no rows were ignored.

See also
  • ULSyncResult class
  • ULSyncResult members
  • DownloadOnly property


PartialDownloadRetained property

Checks whether a partial download was retained or not during the last synchronization.

Prototypes

' Visual Basic
Public Readonly Property PartialDownloadRetained As Boolean

// C#
public bool PartialDownloadRetained {get;}

Property value

True if a download was interrupted and the partial download was retained, false if the download was not interrupted or if the partial download was rolled back.

See also
  • ULSyncResult class
  • ULSyncResult members
  • KeepPartialDownload property


StreamErrorCode property

Returns the error reported by the stream itself.

Prototypes

' Visual Basic
Public Readonly Property StreamErrorCode As ULStreamErrorCode

// C#
public ULStreamErrorCode StreamErrorCode {get;}

Property value

One of the ULStreamErrorCode enumeration values denoting the error reported by the stream itself, ULStreamErrorCode enumeration if no error occurred.


StreamErrorContext property

Returns the basic network operation being performed when the stream error occurred.

Prototypes

' Visual Basic
Public Readonly Property StreamErrorContext As ULStreamErrorContext

// C#
public ULStreamErrorContext StreamErrorContext {get;}

Property value

One of the ULStreamErrorContext enumeration values denoting which basic network operation was being performed when the stream error occurred.


StreamErrorID property

Returns the ID of the network layer reporting an error.

Prototypes

' Visual Basic
Public Readonly Property StreamErrorID As ULStreamErrorID

// C#
public ULStreamErrorID StreamErrorID {get;}

Property value

One of the ULStreamErrorID enumeration values denoting the ID of the network layer reporting an error.


StreamErrorSystem property

Returns the stream error system-specific code.

Prototypes

' Visual Basic
Public Readonly Property StreamErrorSystem As Integer

// C#
public int StreamErrorSystem {get;}

Property value

An integer denoting the stream error system-specific code.


Timestamp property

Returns the timestamp of the last synchronization.

Prototypes

' Visual Basic
Public Readonly Property Timestamp As Date

// C#
public DateTime Timestamp {get;}

Property value

A DateTime specifying the timestamp of the last synchronization.


UploadOK property

Checks whether the last upload synchronization was successful or not.

Prototypes

' Visual Basic
Public Readonly Property UploadOK As Boolean

// C#
public bool UploadOK {get;}

Property value

True if the last upload synchronization was successful, false if the last upload synchronization was unsuccessful.


Finalize method

Releases unmanaged resources and performs other cleanup operations before the ULSyncResult is reclaimed by garbage collection.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


ULTable class

UL Ext.: Represents a table in an UltraLite database.

Prototypes

' Visual Basic
Public Class ULTable
Inherits ULDataReader

// C#
public class ULTable :
ULDataReader

Remarks

This class cannot be directly instantiated. Tables are created using the ExecuteTable method method of the ULCommand class class.

ULTable members
Schema property
AppendBytes method
AppendChars method
Delete method
DeleteAllRows method
Finalize method
FindBegin method
FindFirst method
FindFirst method
FindLast method
FindLast method
FindNext method
FindNext method
FindPrevious method
FindPrevious method
Insert method
InsertBegin method
LookupBackward method
LookupBackward method
LookupBegin method
LookupForward method
LookupForward method
SetBoolean method
SetByte method
SetBytes method
SetDateTime method
SetDBNull method
SetDecimal method
SetDouble method
SetFloat method
SetGuid method
SetInt16 method
SetInt32 method
SetInt64 method
SetString method
SetTimeSpan method
SetToDefault method
SetUInt16 method
SetUInt32 method
SetUInt64 method
Truncate method
Update method
UpdateBegin method


ULTable members

Public instance properties
Member | Description
Depth property (inherited from ULDataReader) | Returns the depth of nesting for the current row. The outermost table has a depth of zero.
FieldCount property (inherited from ULDataReader) | Returns the number of columns in the cursor.
IsBOF property (inherited from ULDataReader) | UL Ext.: Checks whether the current row position is before the first row or not.
IsClosed property (inherited from ULDataReader) | Checks whether the cursor is currently open.
IsEOF property (inherited from ULDataReader) | UL Ext.: Checks whether the current row position is after the last row or not.
Item property (inherited from ULDataReader) | Returns the value of the specified column in its native format. In C#, this property is the indexer for the ULDataReader class.
Item property (inherited from ULDataReader) | Returns the value of the specified named column in its native format. In C#, this property is the indexer for the ULDataReader class.
RecordsAffected property (inherited from ULDataReader) | Returns the number of rows changed, inserted, or deleted by execution of the SQL statement. For SELECT statements or CommandType.TableDirect tables, this value is -1.
RowCount property (inherited from ULDataReader) | UL Ext.: Returns the number of rows in the cursor.
Schema property | Holds the table schema. This property is only valid while its connection is open.
Public instance methods
Member | Description
AppendBytes method | Appends the specified subset of the specified array of Bytes to the new value for the specified ULDbType enumeration column.
AppendChars method | Appends the specified subset of the specified array of System.Chars to the new value for the specified ULDbType enumeration column.
Close method (inherited from ULDataReader) | Closes the cursor.
Delete method | Deletes the current row.
DeleteAllRows method | Deletes all rows in the table.
Dispose method (inherited from ULDataReader) | Releases the unmanaged resources used by the ULDataReader and optionally releases the managed resources.
FindBegin method | Prepares to perform a new Find on a table.
FindFirst method | Moves forwards through the table from the beginning, looking for a row that exactly matches a value or full set of values in the current index.
FindFirst method | Moves forwards through the table from the beginning, looking for a row that exactly matches a value or partial set of values in the current index.
FindLast method | Moves backwards through the table from the end, looking for a row that exactly matches a value or full set of values in the current index.
FindLast method | Moves backwards through the table from the end, looking for a row that exactly matches a value or partial set of values in the current index.
FindNext method | Continues a FindFirst method search by moving forward through the table from the current position, looking to see if the next row exactly matches a value or full set of values in the current index.
FindNext method | Continues a FindFirst method search by moving forward through the table from the current position, looking to see if the next row exactly matches a value or partial set of values in the current index.
FindPrevious method | Continues a FindLast method search by moving backward through the table from the current position, looking to see if the previous row exactly matches a value or full set of values in the current index.
FindPrevious method | Continues a FindLast method search by moving backward through the table from the current position, looking to see if the previous row exactly matches a value or partial set of values in the current index.
GetBoolean method (inherited from ULDataReader) | Returns the value for the specified column as a Boolean.
GetByte method (inherited from ULDataReader) | Returns the value for the specified column as an unsigned 8-bit value (Byte).
GetBytes method (inherited from ULDataReader) | Copies a subset of the value for the specified ULDbType enumeration column, beginning at the specified offset, to the specified offset of the destination Byte array.
GetBytes method (inherited from ULDataReader) | UL Ext.: Returns the value for the specified column as an array of Bytes. Only valid for columns of type ULDbType enumeration, ULDbType enumeration, or ULDbType enumeration.
GetChar method (inherited from ULDataReader) | This method is not supported in UltraLite.NET.
GetChars method (inherited from ULDataReader) | Copies a subset of the value for the specified ULDbType enumeration column, beginning at the specified offset, to the specified offset of the destination System.Char array.
GetData method (inherited from ULDataReader) | This method is not supported in UltraLite.NET.
GetDataTypeName method (inherited from ULDataReader) | Returns the name of the specified column's provider data type.
GetDateTime method (inherited from ULDataReader) | Returns the value for the specified column as a DateTime with millisecond accuracy.
GetDecimal method (inherited from ULDataReader) | Returns the value for the specified column as a Decimal.
GetDouble method (inherited from ULDataReader) | Returns the value for the specified column as a Double.
GetFieldType method (inherited from ULDataReader) | Returns the Type most appropriate for the specified column.
GetFloat method (inherited from ULDataReader) | Returns the value for the specified column as a Single.
GetGuid method (inherited from ULDataReader) | Returns the value for the specified column as a UUID (Guid).
GetInt16 method (inherited from ULDataReader) | Returns the value for the specified column as an Int16.
GetInt32 method (inherited from ULDataReader) | Returns the value for the specified column as an Int32.
GetInt64 method (inherited from ULDataReader) | Returns the value for the specified column as an Int64.
GetName method (inherited from ULDataReader) | Returns the name of the specified column.
GetOrdinal method (inherited from ULDataReader) | Returns the column ID of the named column.
GetSchemaTable method (inherited from ULDataReader) | Returns a DataTable that describes the column metadata of the ULDataReader.
GetString method (inherited from ULDataReader) | Returns the value for the specified column as a String.
GetTimeSpan method (inherited from ULDataReader) | Returns the value for the specified column as a TimeSpan with millisecond accuracy.
GetUInt16 method (inherited from ULDataReader) | Returns the value for the specified column as a UInt16.
GetUInt32 method (inherited from ULDataReader) | Returns the value for the specified column as a UInt32.
GetUInt64 method (inherited from ULDataReader) | Returns the value for the specified column as a UInt64.
GetValue method (inherited from ULDataReader) | Returns the value of the specified column in its native format.
GetValues method (inherited from ULDataReader) | Returns all the column values for the current row.
Insert method | Inserts a new row with the current column values (specified using the set methods). Each insert must be preceded by a call to InsertBegin method.
InsertBegin method | Prepares to insert a new row into the table by setting all current column values to their default values.
IsDBNull method (inherited from ULDataReader) | Checks whether the value from the specified column is NULL.
LookupBackward method | Moves backwards through the table from the end, looking for a row that matches or is less than a value or full set of values in the current index.
LookupBackward method | Moves backwards through the table from the beginning, looking for a row that matches or is less than a value or partial set of values in the current index.
LookupBegin method | Prepares to perform a new lookup on the table. The value(s) to search for are specified by calling the appropriate setType method(s) on the columns in the index the table was opened with.
LookupForward method | Moves forwards through the table from the beginning, looking for a row that matches or is greater than a value or full set of values in the current index.
LookupForward method | Moves forwards through the table from the beginning, looking for a row that matches or is greater than a value or partial set of values in the current index.
MoveAfterLast method (inherited from ULDataReader) | UL Ext.: Positions the cursor to after the last row of the cursor.
MoveBeforeFirst method (inherited from ULDataReader) | UL Ext.: Positions the cursor to before the first row of the cursor.
MoveFirst method (inherited from ULDataReader) | UL Ext.: Positions the cursor to the first row of the cursor.
MoveLast method (inherited from ULDataReader) | UL Ext.: Positions the cursor to the last row of the cursor.
MoveNext method (inherited from ULDataReader) | UL Ext.: Positions the cursor to the next row or after the last row if the cursor was already on the last row.
MovePrevious method (inherited from ULDataReader) | UL Ext.: Positions the cursor to the previous row or before the first row.
MoveRelative method (inherited from ULDataReader) | UL Ext.: Positions the cursor relative to the current row.
NextResult method (inherited from ULDataReader) | Advances the ULDataReader to the next result when reading the results of batch SQL statements.
Read method (inherited from ULDataReader) | Positions the cursor to the next row, or after the last row if the cursor was already on the last row.
SetBoolean method | Sets the value for the specified column using a Boolean.
SetByte method | Sets the value for the specified column using a Byte (unsigned 8-bit integer).
SetBytes method | Sets the value for the specified column using an array of Bytes.
SetDateTime method | Sets the value for the specified column using a DateTime.
SetDBNull method | Sets a column to NULL.
SetDecimal method | Sets the value for the specified column using a Decimal.
SetDouble method | Sets the value for the specified column using a Double.
SetFloat method | Sets the value for the specified column using a Single.
SetGuid method | Sets the value for the specified column using a Guid.
SetInt16 method | Sets the value for the specified column using an Int16.
SetInt32 method | Sets the value for the specified column using an Int32.
SetInt64 method | Sets the value for the specified column using an Int64.
SetString method | Sets the value for the specified column using a String.
SetTimeSpan method | Sets the value for the specified column using a TimeSpan.
SetToDefault method | Sets the value for the specified column to its default value.
SetUInt16 method | Sets the value for the specified column using a UInt16.
SetUInt32 method | Sets the value for the specified column using an UInt32.
SetUInt64 method | Sets the value for the specified column using a UInt64.
Truncate method | Deletes all rows in the table while temporarily activating a stop synchronization delete.
Update method | Updates the current row with the current column values (specified using the set methods). Each update must be preceded by a call to UpdateBegin method.
UpdateBegin method | Prepares to update the current row in the table.
Protected instance methods
Member | Description
Finalize method | Releases unmanaged resources and performs other cleanup operations before the ULTable is reclaimed by garbage collection.


Schema property

Holds the table schema. This property is only valid while its connection is open.

Prototypes

' Visual Basic
Public Readonly Property Schema As ULTableSchema

// C#
public ULTableSchema Schema {get;}

Property value

The ULTableSchema class object representing the table schema.

Remarks

This property represents the complete schema of the table, including UltraLite.NET extended information which is not represented in the results from GetSchemaTable method.


AppendBytes method

Appends the specified subset of the specified array of Bytes to the new value for the specified ULDbType enumeration column.

Prototypes

' Visual Basic
Public Sub AppendBytes( _
ByVal columnID As Integer, _
ByVal val As Byte(), _
ByVal srcOffset As Integer, _
ByVal count As Integer _
)

// C#
public void AppendBytes(
int columnID,
byte[] val,
int srcOffset,
int count
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The value to append to the current new value for the column.

  • srcOffset The start position in the source array.

  • count The number of bytes to be copied.

Remarks

The bytes at position srcOffset (starting from 0) through srcOffset+count-1 of the array val are appended to the value for the specified column.

When inserting, InsertBegin method initializes the new value to the column's default value. The data in the row is not actually changed until you execute an Insert method, and that change is not made permanent until it is committed.

When updating, the first append on a column will clear the current value prior to appending the new value.

If any of the following are true, a ULException class with code ULSQLCode enumeration is thrown and the destination is not modified:

  • val is null.
  • srcOffset is negative.
  • count is negative.
  • srcOffset+count is greater than val.Length.

For other errors, a ULException class with the appropriate error code is thrown.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


AppendChars method

Appends the specified subset of the specified array of System.Chars to the new value for the specified ULDbType enumeration column.

Prototypes

' Visual Basic
Public Sub AppendChars( _
ByVal columnID As Integer, _
ByVal val As Char(), _
ByVal srcOffset As Integer, _
ByVal count As Integer _
)

// C#
public void AppendChars(
int columnID,
char[] val,
int srcOffset,
int count
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The value to append to the current new value for the column.

  • srcOffset The start position in the source array.

  • count The number of bytes to be copied.

Remarks

The characters at position srcOffset (starting from 0) through srcOffset+count-1 of the array val are appended to the value for the specified column. When inserting, InsertBegin method initializes the new value to the column's default value. The data in the row is not actually changed until you execute an Insert method, and that change is not made permanent until it is committed.

When updating, the first append on a column clears the current value prior to appending the new value.

If any of the following is true, a ULException class with code ULSQLCode enumeration is thrown and the destination is not modified:

  • val is null.
  • srcOffset is negative.
  • count is negative.
  • srcOffset+count is greater than value.Length.

For other errors, a ULException class with the appropriate error code is thrown.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


Delete method

Deletes the current row.

Prototypes

' Visual Basic
Public Sub Delete()

// C#
public void Delete();

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • StartSynchronizationDelete method
  • StopSynchronizationDelete method


DeleteAllRows method

Deletes all rows in the table.

Prototypes

' Visual Basic
Public Sub DeleteAllRows()

// C#
public void DeleteAllRows();

Remarks

In some applications, it can be useful to delete all rows from a table before downloading a new set of data into the table. Rows can be deleted from the UltraLite database without being deleted from the consolidated database using StopSynchronizationDelete method.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • Truncate method


Finalize method

Releases unmanaged resources and performs other cleanup operations before the ULTable is reclaimed by garbage collection.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


FindBegin method

Prepares to perform a new Find on a table.

Prototypes

' Visual Basic
Public Sub FindBegin()

// C#
public void FindBegin();

Remarks

The value(s) to search for are specified by calling the appropriate setType method(s) on the columns in the index the table was opened with.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • FindFirst method
  • FindFirst method
  • FindLast method
  • FindLast method


FindFirst method

Moves forwards through the table from the beginning, looking for a row that exactly matches a value or full set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindFirst() As Boolean

// C#
public bool FindFirst();

Return value

True if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that exactly matches the index value. On failure, the cursor position is after the last row (IsEOF property).

Each search must be preceded by a call to FindBegin method.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • FindBegin method
  • FindNext method
  • FindPrevious method
  • FindFirst method


FindFirst method

Moves forwards through the table from the beginning, looking for a row that exactly matches a value or partial set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindFirst( _
ByVal numColumns As Short _
) As Boolean

// C#
public bool FindFirst(
short numColumns
);

Parameters

  • numColumns For composite indexes, the number of columns to use in the find. For example, if you have a three column index and you want to look up a value that matches based on the first column only, you should set the value for the first column, and then supply a value of 1.

Return value

True if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that exactly matches the index value. On failure, the cursor position is after the last row (IsEOF property).

Each search must be preceded by a call to FindBegin method.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • FindBegin method
  • FindNext method
  • FindPrevious method
  • FindFirst method


FindLast method

Moves backwards through the table from the end, looking for a row that exactly matches a value or full set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindLast() As Boolean

// C#
public bool FindLast();

Return value

True if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row found that exactly matches the index value. On failure, the cursor position is before the first row (IsBOF property).

Each search must be preceded by a call to FindBegin method.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • FindBegin method
  • FindNext method
  • FindPrevious method
  • FindLast method


FindLast method

Moves backwards through the table from the end, looking for a row that exactly matches a value or partial set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindLast( _
ByVal numColumns As Short _
) As Boolean

// C#
public bool FindLast(
short numColumns
);

Parameters

  • numColumns For composite indexes, the number of columns to use in the find. For example, if you have a three column index and you want to find a value that matches based on the first column only, you should set the value for the first column, then supply a value of 1.

Return value

True if successful, false otherwise

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row found that exactly matches the index value. On failure, the cursor position is before the first row (IsBOF property).

Each search must be preceded by a call to FindBegin method.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • FindBegin method
  • FindNext method
  • FindPrevious method
  • FindLast method


FindNext method

Continues a FindFirst method search by moving forward through the table from the current position, looking to see if the next row exactly matches a value or full set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindNext() As Boolean

// C#
public bool FindNext();

Return value

True if successful, false otherwise.

Remarks

The cursor is left on the next row if it exactly matches the index value. On failure, the cursor position is after the last row (IsEOF property).

FindNext behavior is undefined if the column values being searched for are modified during a row update.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • FindFirst method
  • FindNext method


FindNext method

Continues a FindFirst method search by moving forward through the table from the current position, looking to see if the next row exactly matches a value or partial set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindNext( _
ByVal numColumns As Short _
) As Boolean

// C#
public bool FindNext(
short numColumns
);

Parameters

  • numColumns For composite indexes, the number of columns to use in the find. For example, if you have a three column index, and you want to find a value that matches based on the first column only, you should set the value for the first column, and then supply a value of 1.

Return value

True if successful, false otherwise.

Remarks

The cursor is left on the next row if it exactly matches the index value. On failure, the cursor position is after the last row (IsEOF property).

FindNext behavior is undefined if the column values being searched for are modified during a row update.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • FindFirst method
  • FindNext method


FindPrevious method

Continues a FindLast method search by moving backward through the table from the current position, looking to see if the previous row exactly matches a value or full set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindPrevious() As Boolean

// C#
public bool FindPrevious();

Return value

True if successful, false otherwise.

Remarks

The cursor is left on the previous row if it exactly matches the index value. On failure, the cursor position is before the first row (IsBOF property).

FindPrevious behavior is undefined if the column values being searched for are modified during a row update.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • FindLast method
  • FindPrevious method


FindPrevious method

Continues a FindLast method search by moving backward through the table from the current position, looking to see if the previous row exactly matches a value or partial set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindPrevious( _
ByVal numColumns As Short _
) As Boolean

// C#
public bool FindPrevious(
short numColumns
);

Parameters

  • numColumns For composite indexes, the number of columns to use in the find. For example, if you have a three column index and you want to look up a value that matches based on the first column only, you should set the value for the first column, then supply a value of 1.

Return value

True if successful, false otherwise.

Remarks

The cursor is left on the previous row if it exactly matches the index value. On failure, the cursor position is before the first row (IsBOF property).

FindPrevious behavior is undefined if the column values being searched for are modified during a row update.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • FindLast method
  • FindPrevious method


Insert method

Inserts a new row with the current column values (specified using the set methods).

Each insert must be preceded by a call to InsertBegin method.

Prototypes

' Visual Basic
Public Sub Insert()

// C#
public void Insert();

Exceptions

  • ULException class - A SQL error occurred.


InsertBegin method

Prepares to insert a new row into the table by setting all current column values to their default values.

Prototypes

' Visual Basic
Public Sub InsertBegin()

// C#
public void InsertBegin();

Remarks

Call the appropriate SetType or AppendType method(s) to specify the non-default values that are to be inserted.

The row is not actually inserted and the data in the row is not actually changed until you execute the Insert method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • Insert method


LookupBackward method

Moves backwards through the table from the end, looking for a row that matches or is less than a value or full set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function LookupBackward() As Boolean

// C#
public bool LookupBackward();

Return value

True if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is less than the index value. On failure, (no rows less than the value being looked for) the cursor position is before the first row (IsBOF property).

Each search must be preceded by a call to LookupBegin method.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • LookupBegin method
  • LookupBackward method


LookupBackward method

Moves backwards through the table from the beginning, looking for a row that matches or is less than a value or partial set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function LookupBackward( _
ByVal numColumns As Short _
) As Boolean

// C#
public bool LookupBackward(
short numColumns
);

Parameters

  • numColumns For composite indexes, the number of columns to use in the lookup. For example, if you have a three column index, and you want to look up a value that matches based on the first column only, you should set the value for the first column, and then supply a value of 1.

Return value

True if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is less than the index value. On failure, (no rows less than the value being looked for) the cursor position is before the first row (IsBOF property).

Each search must be preceded by a call to LookupBegin method.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • LookupBegin method
  • LookupBackward method


LookupBegin method

Prepares to perform a new lookup on the table. The value(s) to search for are specified by calling the appropriate setType method(s) on the columns in the index the table was opened with.

Prototypes

' Visual Basic
Public Sub LookupBegin()

// C#
public void LookupBegin();

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • LookupForward method
  • LookupForward method
  • LookupBackward method
  • LookupBackward method


LookupForward method

Moves forwards through the table from the beginning, looking for a row that matches or is greater than a value or full set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function LookupForward() As Boolean

// C#
public bool LookupForward();

Return value

True if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is greater than the index value. On failure, (no rows greater than the value being looked for) the cursor position is after the last row (IsEOF property).

Each search must be preceded by a call to LookupBegin method.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • LookupBegin method
  • LookupForward method


LookupForward method

Moves forwards through the table from the beginning, looking for a row that matches or is greater than a value or partial set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function LookupForward( _
ByVal numColumns As Short _
) As Boolean

// C#
public bool LookupForward(
short numColumns
);

Parameters

  • numColumns For composite indexes, the number of columns to use in the lookup. For example, if you have a three column index and you want to look up a value that matches based on the first column only, you should set the value for the first column, and then supply a value of 1.

Return value

True if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is greater than the index value. On failure, (no rows greater than the value being looked for) the cursor position is after the last row (IsEOF property).

Each search must be preceded by a call to LookupBegin method.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • LookupBegin method
  • LookupForward method


SetBoolean method

Sets the value for the specified column using a Boolean.

Prototypes

' Visual Basic
Public Sub SetBoolean( _
ByVal columnID As Integer, _
ByVal val As Boolean _
)

// C#
public void SetBoolean(
int columnID,
bool val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetByte method

Sets the value for the specified column using a Byte (unsigned 8-bit integer).

Prototypes

' Visual Basic
Public Sub SetByte( _
ByVal columnID As Integer, _
ByVal val As Byte _
)

// C#
public void SetByte(
int columnID,
byte val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetBytes method

Sets the value for the specified column using an array of Bytes.

Prototypes

' Visual Basic
Public Sub SetBytes( _
ByVal columnID As Integer, _
ByVal val As Byte() _
)

// C#
public void SetBytes(
int columnID,
byte[] val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

Only suitable for columns of type ULDbType enumeration or ULDbType enumeration, or for columns of type ULDbType enumeration when val is of length 16. The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetDateTime method

Sets the value for the specified column using a DateTime.

Prototypes

' Visual Basic
Public Sub SetDateTime( _
ByVal columnID As Integer, _
ByVal val As Date _
)

// C#
public void SetDateTime(
int columnID,
DateTime val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The set value is accurate to the millisecond. The data in the row is not actually changed until you execute an Insert method or Update method, and that change is made not permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetDBNull method

Sets a column to NULL.

Prototypes

' Visual Basic
Public Sub SetDBNull( _
ByVal columnID As Integer _
)

// C#
public void SetDBNull(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Remarks

The data is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • IsColumnNullable method


SetDecimal method

Sets the value for the specified column using a Decimal.

Prototypes

' Visual Basic
Public Sub SetDecimal( _
ByVal columnID As Integer, _
ByVal val As Decimal _
)

// C#
public void SetDecimal(
int columnID,
decimal val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetDouble method

Sets the value for the specified column using a Double.

Prototypes

' Visual Basic
Public Sub SetDouble( _
ByVal columnID As Integer, _
ByVal val As Double _
)

// C#
public void SetDouble(
int columnID,
double val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetFloat method

Sets the value for the specified column using a Single.

Prototypes

' Visual Basic
Public Sub SetFloat( _
ByVal columnID As Integer, _
ByVal val As Single _
)

// C#
public void SetFloat(
int columnID,
float val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetGuid method

Sets the value for the specified column using a Guid.

Prototypes

' Visual Basic
Public Sub SetGuid( _
ByVal columnID As Integer, _
ByVal val As Guid _
)

// C#
public void SetGuid(
int columnID,
Guid val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed. Only valid for columns of type ULDbType enumeration or for columns of type ULDbType enumeration with length 16.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetNewUUID method
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method
  • GetColumnSize method


SetInt16 method

Sets the value for the specified column using an Int16.

Prototypes

' Visual Basic
Public Sub SetInt16( _
ByVal columnID As Integer, _
ByVal val As Short _
)

// C#
public void SetInt16(
int columnID,
short val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetInt32 method

Sets the value for the specified column using an Int32.

Prototypes

' Visual Basic
Public Sub SetInt32( _
ByVal columnID As Integer, _
ByVal val As Integer _
)

// C#
public void SetInt32(
int columnID,
int val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetInt64 method

Sets the value for the specified column using an Int64.

Prototypes

' Visual Basic
Public Sub SetInt64( _
ByVal columnID As Integer, _
ByVal val As Long _
)

// C#
public void SetInt64(
int columnID,
long val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetString method

Sets the value for the specified column using a String.

Prototypes

' Visual Basic
Public Sub SetString( _
ByVal columnID As Integer, _
ByVal val As String _
)

// C#
public void SetString(
int columnID,
string val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetTimeSpan method

Sets the value for the specified column using a TimeSpan.

Prototypes

' Visual Basic
Public Sub SetTimeSpan( _
ByVal columnID As Integer, _
ByVal val As TimeSpan _
)

// C#
public void SetTimeSpan(
int columnID,
TimeSpan val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The set value is accurate to the millisecond and is normalized to a nonnegative value between 0 and 24 hours. The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetToDefault method

Sets the value for the specified column to its default value.

Prototypes

' Visual Basic
Public Sub SetToDefault( _
ByVal columnID As Integer _
)

// C#
public void SetToDefault(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method
  • GetColumnDefaultValue method


SetUInt16 method

Sets the value for the specified column using a UInt16.

Prototypes

' Visual Basic
Public Sub SetUInt16( _
ByVal columnID As Integer, _
ByVal val As UInt16 _
)

// C#
public void SetUInt16(
int columnID,
ushort val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetUInt32 method

Sets the value for the specified column using an UInt32.

Prototypes

' Visual Basic
Public Sub SetUInt32( _
ByVal columnID As Integer, _
ByVal val As UInt32 _
)

// C#
public void SetUInt32(
int columnID,
uint val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


SetUInt64 method

Sets the value for the specified column using a UInt64.

Prototypes

' Visual Basic
Public Sub SetUInt64( _
ByVal columnID As Integer, _
ByVal val As UInt64 _
)

// C#
public void SetUInt64(
int columnID,
ulong val
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,FieldCount property -1]. The first column in the cursor has an ID value of zero.

  • val The new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not made permanent until it is committed.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • GetOrdinal method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetFieldType method


Truncate method

Deletes all rows in the table while temporarily activating a stop synchronization delete.

Prototypes

' Visual Basic
Public Sub Truncate()

// C#
public void Truncate();

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTable class
  • ULTable members
  • DeleteAllRows method


Update method

Updates the current row with the current column values (specified using the set methods).

Each update must be preceded by a call to UpdateBegin method.

Prototypes

' Visual Basic
Public Sub Update()

// C#
public void Update();

Exceptions

  • ULException class - A SQL error occurred.


UpdateBegin method

Prepares to update the current row in the table.

Prototypes

' Visual Basic
Public Sub UpdateBegin()

// C#
public void UpdateBegin();

Remarks

Column values are modified by calling the appropriate setType or AppendType method(s). The first append on a column clears the current column value prior to appending the new value.

The data in the row is not actually changed until you call Update method, and that change is not made permanent until it is committed.

Modifying columns in the index used to open the table affects any active searches in unpredictable ways. Columns in the primary key of the table can not be updated.

Exceptions

  • ULException class - A SQL error occurred.


ULTableSchema class

UL Ext.: Represents the schema of an UltraLite table.

Prototypes

' Visual Basic
NotInheritable Public Class ULTableSchema
Inherits ULCursorSchema

// C#
public sealed class ULTableSchema :
ULCursorSchema

Remarks

This class cannot be directly instantiated. A ULTableSchema class object is attached to a table as its Schema property property.

ULTableSchema members
IndexCount property
IsNeverSynchronized property
Name property
PrimaryKey property
UploadUnchangedRows property
Finalize method
GetColumnDefaultValue method
GetColumnPartitionSize method
GetIndex method
GetIndexName method
GetOptimalIndex method
IsColumnAutoIncrement method
IsColumnCurrentDate method
IsColumnCurrentTime method
IsColumnCurrentTimestamp method
IsColumnGlobalAutoIncrement method
IsColumnNewUUID method
IsColumnNullable method
IsInPublication method


ULTableSchema members

Public instance properties
Member | Description
ColumnCount property (inherited from ULCursorSchema) | Returns the number of columns in the cursor.
IndexCount property | Returns the number of indexes on the table.
IsNeverSynchronized property | Checks whether the table is marked as never being synchronized.
IsOpen property (inherited from ULCursorSchema) | Checks whether the cursor schema is currently open.
Name property | Returns the name of the table.
PrimaryKey property | Returns the index schema of the primary key for the table.
UploadUnchangedRows property | Checks whether the database will upload rows that have not changed.
Public instance methods
Member | Description
GetColumnDefaultValue method | Returns the default value of the specified column.
GetColumnID method (inherited from ULCursorSchema) | Returns the column ID of the named column.
GetColumnName method (inherited from ULCursorSchema) | Returns the name of the column identified by the specified column ID.
GetColumnPartitionSize method | Returns the global autoincrement partition size assigned to the specified column.
GetColumnPrecision method (inherited from ULCursorSchema) | Returns the precision of the column identified by the specified column ID if the column is a numeric column (SQL type NUMERIC).
GetColumnScale method (inherited from ULCursorSchema) | Returns the scale of the column identified by the specified column ID if the column is a numeric column (SQL type NUMERIC).
GetColumnSize method (inherited from ULCursorSchema) | Returns the size of the column identified by the specified column ID if the column is a sized column (SQL type BINARY or CHAR).
GetColumnULDbType method (inherited from ULCursorSchema) | Returns the UltraLite.NET data type of the column identified by the specified column ID.
GetIndex method | Returns the index schema of the named index.
GetIndexName method | Returns the name of the index identified by the specified index ID.
GetOptimalIndex method | The optimal index for searching a table using the specified column.
GetSchemaTable method (inherited from ULCursorSchema) | Returns a DataTable that describes the column schema of the ULDataReader class.
IsColumnAutoIncrement method | Checks whether the specified column's default is set to autoincrement.
IsColumnCurrentDate method | Checks whether the specified column's default is set to the current date (ULDbType enumeration).
IsColumnCurrentTime method | Checks whether the specified column's default is set to the current time (ULDbType enumeration).
IsColumnCurrentTimestamp method | Checks whether the specified column's default is set to the current timestamp (ULDbType enumeration).
IsColumnGlobalAutoIncrement method | Checks whether the specified column's default is set to global autoincrement.
IsColumnNewUUID method | Checks whether the specified column's default is set to a new UUID (Guid).
IsColumnNullable method | Checks whether the specified column is nullable.
IsInPublication method | Checks whether the table is contained in the named publication.
Protected instance methods
Member | Description
Finalize method | Releases unmanaged resources and performs other cleanup operations before the ULTableSchema is reclaimed by garbage collection.


IndexCount property

Returns the number of indexes on the table.

Prototypes

' Visual Basic
Public Readonly Property IndexCount As Integer

// C#
public int IndexCount {get;}

Property value

The number of indexes on the table or 0 if the table schema is closed.

Remarks

Index IDs range from 1 to IndexCount, inclusively.

Note: Index IDs and count may change during a schema upgrade. To correctly identify an index, access it by name or refresh the cached IDs and counts after a schema upgrade.


IsNeverSynchronized property

Checks whether the table is marked as never being synchronized.

Prototypes

' Visual Basic
Public Readonly Property IsNeverSynchronized As Boolean

// C#
public bool IsNeverSynchronized {get;}

Property value

True if the table is marked as never being synchronized, false otherwise.

Remarks

Tables marked as never being synchronized are never synchronized, even if they are included in a publication. These tables are sometimes referred to as "no sync" tables.

Exceptions

  • ULException class - A SQL error occurred.


Name property

Returns the name of the table.

Prototypes

' Visual Basic
Public Readonly Property Name As String

// C#
public string Name {get;}

Property value

The name of the table as a string.

Exceptions

  • ULException class - A SQL error occurred.


PrimaryKey property

Returns the index schema of the primary key for the table.

Prototypes

' Visual Basic
Public Readonly Property PrimaryKey As ULIndexSchema

// C#
public ULIndexSchema PrimaryKey {get;}

Property value

A ULIndexSchema class object representing the primary key for the table.

Exceptions

  • ULException class - A SQL error occurred.


UploadUnchangedRows property

Checks whether the database will upload rows that have not changed.

Prototypes

' Visual Basic
Public Readonly Property UploadUnchangedRows As Boolean

// C#
public bool UploadUnchangedRows {get;}

Property value

True if the table is marked to always upload all rows during synchronization, false if the table is marked to upload only changed rows.

Remarks

Tables marked as such upload unchanged rows, as well as changed rows, when the table is synchronized. These tables are sometimes referred to as "all sync" tables.

Exceptions

  • ULException class - A SQL error occurred.


Finalize method

Releases unmanaged resources and performs other cleanup operations before the ULTableSchema is reclaimed by garbage collection.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


GetColumnDefaultValue method

Returns the default value of the specified column.

Prototypes

' Visual Basic
Public Function GetColumnDefaultValue( _
ByVal columnID As Integer _
) As String

// C#
public string GetColumnDefaultValue(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,ColumnCount property -1]. The first column in a table has an ID value of zero.

Return value

The default value of the specified column as a string or a null reference (Nothing in Visual Basic) if the default value is null.

Exceptions

  • ULException class - A SQL error occurred.


GetColumnPartitionSize method

Returns the global autoincrement partition size assigned to the specified column.

Prototypes

' Visual Basic
Public Function GetColumnPartitionSize( _
ByVal columnID As Integer _
) As UInt64

// C#
public ulong GetColumnPartitionSize(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,ColumnCount property -1]. The first column in the table has an ID value of zero.

Return value

The column's global autoincrement partition size as a UInt64.

Remarks

All global autoincrement columns in a given table share the same global autoincrement partition.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTableSchema class
  • ULTableSchema members
  • IsColumnGlobalAutoIncrement method


GetIndex method

Returns the index schema of the named index.

Prototypes

' Visual Basic
Public Function GetIndex( _
ByVal name As String _
) As ULIndexSchema

// C#
public ULIndexSchema GetIndex(
string name
);

Parameters

  • name The name of the index.

Return value

A ULIndexSchema class object representing the named index.

Exceptions

  • ULException class - A SQL error occurred.


GetIndexName method

Returns the name of the index identified by the specified index ID.

Prototypes

' Visual Basic
Public Function GetIndexName( _
ByVal indexID As Integer _
) As String

// C#
public string GetIndexName(
int indexID
);

Parameters

  • indexID The ID of the index. The value must be in the range [1,IndexCount property].

Return value

The name of the index as a string.

Remarks

Index IDs and counts may change during a schema upgrade. To correctly identify an index, access it by name or refresh the cached IDs and counts after a schema upgrade.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTableSchema class
  • ULTableSchema members
  • IndexCount property


GetOptimalIndex method

The optimal index for searching a table using the specified column.

Prototypes

' Visual Basic
Public Function GetOptimalIndex( _
ByVal columnID As Integer _
) As ULIndexSchema

// C#
public ULIndexSchema GetOptimalIndex(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,ColumnCount property -1]. The first column in the table has an ID value of zero.

Return value

A ULIndexSchema class object representing the optimal index for the specified column.

Remarks

The specified column is the first column in the index, but the index may have more than one column.

Exceptions

  • ULException class - A SQL error occurred.


IsColumnAutoIncrement method

Checks whether the specified column's default is set to autoincrement.

Prototypes

' Visual Basic
Public Function IsColumnAutoIncrement( _
ByVal columnID As Integer _
) As Boolean

// C#
public bool IsColumnAutoIncrement(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,ColumnCount property -1]. The first column in the table has an ID value of zero.

Return value

True if the column is autoincrementing, false if it is not autoincrementing.

Exceptions

  • ULException class - A SQL error occurred.


IsColumnCurrentDate method

Checks whether the specified column's default is set to the current date (ULDbType enumeration).

Prototypes

' Visual Basic
Public Function IsColumnCurrentDate( _
ByVal columnID As Integer _
) As Boolean

// C#
public bool IsColumnCurrentDate(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,ColumnCount property -1]. The first column in the table has an ID value of zero.

Return value

True if the column defaults to the current date, false if the column does not default to the current date.

Exceptions

  • ULException class - A SQL error occurred.


IsColumnCurrentTime method

Checks whether the specified column's default is set to the current time (ULDbType enumeration).

Prototypes

' Visual Basic
Public Function IsColumnCurrentTime( _
ByVal columnID As Integer _
) As Boolean

// C#
public bool IsColumnCurrentTime(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,ColumnCount property -1]. The first column in the table has an ID value of zero.

Return value

True if the column defaults to the current time, false if the column does not default to the current time.

Exceptions

  • ULException class - A SQL error occurred.


IsColumnCurrentTimestamp method

Checks whether the specified column's default is set to the current timestamp (ULDbType enumeration).

Prototypes

' Visual Basic
Public Function IsColumnCurrentTimestamp( _
ByVal columnID As Integer _
) As Boolean

// C#
public bool IsColumnCurrentTimestamp(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,ColumnCount property -1]. The first column in the table has an ID value of zero.

Return value

True if the column defaults to the current timestamp, false if the column does not default to the current timestamp.

Exceptions

  • ULException class - A SQL error occurred.


IsColumnGlobalAutoIncrement method

Checks whether the specified column's default is set to global autoincrement.

Prototypes

' Visual Basic
Public Function IsColumnGlobalAutoIncrement( _
ByVal columnID As Integer _
) As Boolean

// C#
public bool IsColumnGlobalAutoIncrement(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,ColumnCount property -1]. The first column in the table has an ID value of zero.

Return value

True if the column is global autoincrementing, false if it is not global autoincrementing.

Exceptions

  • ULException class - A SQL error occurred.

See also
  • ULTableSchema class
  • ULTableSchema members
  • GetColumnPartitionSize method
  • DatabaseID property


IsColumnNewUUID method

Checks whether the specified column's default is set to a new UUID (Guid).

Prototypes

' Visual Basic
Public Function IsColumnNewUUID( _
ByVal columnID As Integer _
) As Boolean

// C#
public bool IsColumnNewUUID(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,ColumnCount property -1]. The first column in the table has an ID value of zero.

Return value

True if the column defaults to a new UUID, false if the column does not default to a new UUID.

Exceptions

  • ULException class - A SQL error occurred.


IsColumnNullable method

Checks whether the specified column is nullable.

Prototypes

' Visual Basic
Public Function IsColumnNullable( _
ByVal columnID As Integer _
) As Boolean

// C#
public bool IsColumnNullable(
int columnID
);

Parameters

  • columnID The ID number of the column. The value must be in the range [0,ColumnCount property -1]. The first column in the table has an ID value of zero.

Return value

True if the column is nullable, false if it is not nullable.

Exceptions

  • ULException class - A SQL error occurred.


IsInPublication method

Checks whether the table is contained in the named publication.

Prototypes

' Visual Basic
Public Function IsInPublication( _
ByVal pubName As String _
) As Boolean

// C#
public bool IsInPublication(
string pubName
);

Parameters

  • pubName The name of the publication.

Return value

True if the table is in the publication, false if the table is not in the publication.

Exceptions

  • ULException class - A SQL error occurred.


ULTransaction class

Represents a SQL transaction.

Prototypes

' Visual Basic
NotInheritable Public Class ULTransaction
Implements IDbTransaction, IDisposable

// C#
public sealed class ULTransaction :
IDbTransaction, IDisposable

Remarks

There is no constructor for ULTransaction. To obtain a ULTransaction object, use the BeginTransaction method method. To associate a command with a transaction, use the Transaction property property.

Once a transaction has been committed or rolled back, the connection reverts to automatically committing all operations as they are executed. To group more operations together, a new transaction must be created.

Implements: IDbTransaction, IDisposable


ULTransaction members

Public instance properties
Member | Description
Connection property | Returns the connection associated with the transaction.
IsolationLevel property | Returns the isolation level for the transaction.
Public instance methods
Member | Description
Commit method | Commits the database transaction.
Dispose method | Releases the resources used by the ULTransaction and rolls back any uncommitted commands.
Rollback method | Rolls back the transaction's outstanding changes to the database.
Protected instance methods
Member | Description
Finalize method | Releases unmanaged resources and performs other cleanup operations before the ULTransaction is reclaimed by garbage collection.


Connection property

Returns the connection associated with the transaction.

Prototypes

' Visual Basic
Public Readonly Property Connection As ULConnection

// C#
public ULConnection Connection {get;}

Property value

The ULConnection class object associated with the transaction, or a null reference (Nothing in Visual Basic) if the transaction is no longer valid.

Remarks

This is the strongly typed version of IDbTransaction.Connection.

See also
  • ULTransaction class
  • ULTransaction members
  • BeginTransaction method


IsolationLevel property

Returns the isolation level for the transaction.

Prototypes

' Visual Basic
NotOverridable Public Readonly Property IsolationLevel As IsolationLevel _
Implements IDbTransaction.IsolationLevel

// C#
public IsolationLevel IsolationLevel {get;}

Property value

One of the IsolationLevel values. UltraLite.NET only supports IsolationLevel.ReadUncommitted.

Implements

IDbTransaction.IsolationLevel

See also
  • ULTransaction class
  • ULTransaction members
  • BeginTransaction method


Commit method

Commits the database transaction.

Prototypes

' Visual Basic
NotOverridable Public Sub Commit() _
Implements IDbTransaction.Commit

// C#
public void Commit();

Remarks

Once a transaction has been committed or rolled back, the connection reverts to automatically committing all operations as they are executed. To group more operations together, a new transaction must be created.

Implements

IDbTransaction.Commit

See also
  • ULTransaction class
  • ULTransaction members
  • Rollback method


Dispose method

Releases the resources used by the ULTransaction and rolls back any uncommitted commands.

Prototypes

' Visual Basic
Overloads NotOverridable Public Sub Dispose() _
Implements IDisposable.Dispose

// C#
public void Dispose();

Implements

IDisposable.Dispose


Finalize method

Releases unmanaged resources and performs other cleanup operations before the ULTransaction is reclaimed by garbage collection.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


Rollback method

Rolls back the transaction's outstanding changes to the database.

Prototypes

' Visual Basic
NotOverridable Public Sub Rollback() _
Implements IDbTransaction.Rollback

// C#
public void Rollback();

Remarks

Once a transaction has been committed or rolled back, the connection reverts to automatically committing all operations as they are executed. To group more operations together, a new transaction must be created.

Implements

IDbTransaction.Rollback

See also
  • ULTransaction class
  • ULTransaction members
  • Commit method


iAnywhere.UltraLite namespace

About this chapter

The iAnywhere.UltraLite namespace is deprecated in release 9.0.2, and will not be available in the next major release of SQL Anywhere. See @olink targetdoc="uldotnet" targetptr="ianywhere-data-ultralite"@iAnywhere.Data.UltraLite namespace@/olink@ for more information.

The iAnywhere.UltraLite namespace contains UltraLite.NET classes, interfaces, and enumerations that allow you to write C# or Visual Basic .NET code for applications that use UltraLite databases.

This API Reference for UltraLite.NET provides a complete reference of the features supported. Each topic contains information about a specific class, interface, or enumeration.

Application programs must first instantiate an instance of DatabaseManager class before using any other UltraLite.NET class.

The iAnywhere.UltraLite assembly uses a satellite resource assembly called iAnywhere.UltraLite.resources. The main assembly searches for this resource assembly by culture, using the following order: System.Globalization.CultureInfo.CurrentUICulture, then System.Globalization.CultureInfo.CurrentCulture, and finally culture "EN".

ActiveSyncListener interface
AuthStatusCode enumeration
Connection class
ConnectionParms class
CreateParms class
Cursor class
CursorSchema class
DatabaseManager class
DatabaseNameParms class
DatabaseNameParms.UnusedEventHandler delegate
DatabaseSchema class
IndexSchema class
PreparedStatement class
PublicationSchema class
ResultSet class
ResultSetSchema class
RuntimeType enumeration
SchemaParms class
SchemaUpgradeData class
SchemaUpgradeListener interface
SchemaUpgradeState enumeration
ServerSyncListener interface
SQLCode enumeration
SQLException class
SQLType enumeration
StreamErrorCode enumeration
StreamErrorContext enumeration
StreamErrorID enumeration
StreamType enumeration
SyncParms class
SyncProgressData class
SyncProgressDialog class
SyncProgressListener interface
SyncProgressState enumeration
SyncResult class
Table class
TableSchema class


ActiveSyncListener interface

The listener interface for receiving ActiveSync events.

Prototypes

' Visual Basic
Public Interface ActiveSyncListener

// C#
public interface ActiveSyncListener


ActiveSyncListener members

Public instance methods
Member | Description
ActiveSyncInvoked method | Invoked when the MobiLink provider for ActiveSync calls the application to perform synchronization.


ActiveSyncInvoked method

Invoked when the MobiLink provider for ActiveSync calls the application to perform synchronization.

Prototypes

' Visual Basic
Public Sub ActiveSyncInvoked( _
ByVal launchedByProvider As Boolean _
)

// C#
public void ActiveSyncInvoked(
bool launchedByProvider
);

Parameters

  • launchedByProvider true if the application was launched by the MobiLink provider to perform ActiveSync synchronization. The application must then shut itself down after it has finished synchronizing. False if the application was already running when called by the MobiLink provider for ActiveSync.

Remarks

This method is invoked by a separate thread. To avoid multi-threading issues, it should post an event to the UI. If you are using multi-threading, it is recommended that you use a separate connection and use the lock keyword to access any objects shared with the rest of the application. The synchronization resulting from a call to ActiveSyncInvoked must specify a StreamType.ACTIVE_SYNC for its connection's SyncInfo stream.

Example

The following code fragments demonstrate how to receive an ActiveSync request and perform a synchronization in the UI thread.

            [Visual Basic]
            Imports iAnywhere.UltraLite

            Public Class MainWindow
              Inherits System.Windows.Forms.Form
              Implements ActiveSyncListener
              Private dbMgr As DatabaseManager
              Private conn As Connection

              Public Sub New(ByVal args() As String)

                MyBase.New()

                'This call is required by the Windows Form Designer.
                InitializeComponent()

                'Add any initialization after the InitializeComponent() call
                dbMgr = New DatabaseManager
                dbMgr.SetActiveSyncListener( "myCompany.myapp", Me )
                'Create Connection
                ...
              End Sub

              Protected Overrides Sub OnClosing(ByVal e As System.ComponentModel.CancelEventArgs)
                If Not (dbMgr Is Nothing) Then
                  dbMgr.SetActiveSyncListener(Nothing, Nothing)
                  dbMgr = Nothing
                End If
              End Sub

              Public Sub ActiveSyncInvoked(ByVal launchedByProvider As Boolean) Implements iAnywhere.UltraLite.ActiveSyncListener.ActiveSyncInvoked
                Me.Invoke(New EventHandler(AddressOf Me.ActiveSyncAction))
              End Sub

              Public Sub ActiveSyncAction(ByVal sender As Object, ByVal e As EventArgs)
                ' Do active sync
                conn.SyncParms.Stream = StreamType.ACTIVE_SYNC
                conn.Synchronize()
              End Sub
            End Class

            [C#]
            using iAnywhere.UltraLite;
            public class Form1 : System.Windows.Forms.Form, ActiveSyncListener
            {
              private System.Windows.Forms.MainMenu mainMenu1;
              private DatabaseManager dbMgr;
              private Connection conn;

              public Form1()
              {
                //
                // Required for Windows Form Designer support
                //
                InitializeComponent();

                //
                // TODO: Add any constructor code after InitializeComponent call
                //
                dbMgr = new DatabaseManager();
                dbMgr.SetActiveSyncListener( "myCompany.myapp", this );
                // Create connection
                ...
              }

              protected override void Dispose( bool disposing )
              {
                base.Dispose( disposing );
              }

              protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
              {
                if( dbMgr != null ) {
                  dbMgr.SetActiveSyncListener( null, null );
                  dbMgr = null;
                }
                base.OnClosing (e);
              }

              public void ActiveSyncInvoked(bool launchedByProvider)
              {
                this.Invoke( new EventHandler( ActiveSyncHandler ) );
              }

              internal void ActiveSyncHandler(object sender, EventArgs e)
              {
                conn.SyncParms.Stream = StreamType.ACTIVE_SYNC;
                conn.Synchronize();
              }
            }


AuthStatusCode enumeration

Enumerates the status codes that may be reported during MobiLink user authentication.

Prototypes

' Visual Basic
Public Enum AuthStatusCode

// C#
public enum AuthStatusCode

Members
Member | Description
EXPIRED | User ID or password has expired - authorization failed (EXPIRED = 3000).
IN_USE | User ID is already in use - authorization failed (IN_USE = 5000).
INVALID | Bad user ID or password - authorization failed (INVALID = 4000).
UNKNOWN | Authorization status is unknown, possibly because the connection has not yet performed a synchronization (UNKNOWN = 0).
VALID | User ID and password were valid at time of synchronization (VALID = 1000).
VALID_BUT_EXPIRES_SOON | User ID and password were valid at time of synchronization but will expire soon (VALID_BUT_EXPIRES_SOON = 2000).
See also
  • AuthStatus property


Connection class

Represents a connection to an UltraLite database.

Prototypes

' Visual Basic
NotInheritable Public Class Connection

// C#
public sealed class Connection

Remarks

This class cannot be directly instantiated. Connections are instantiated and opened using OpenConnection method or if the database does not yet exist, CreateDatabase method.

You must open a connection before carrying out any other operation, and you must close the connection after you have finished all operations on the connection and before your application terminates. You must close all tables opened on a connection before closing the connection.

When a SQLException is thrown, the error code in the exception supercedes the error code in LastSQLCode property or the values of IsLastFetchOK property and IsLastCodeOK property.

Connection members
AutoCommit field
INVALID_DATABASE_ID field
ConnectionOpenParms property
DatabaseID property
GlobalAutoIncrementUsage property
IsDatabaseNew property
IsLastCodeOK property
IsLastFetchOK property
IsOpen property
LastIdentity property
LastSQLCode property
Schema property
SyncParms property
SyncResult property
ChangeEncryptionKey method
Close method
Commit method
CountUploadRows method
CountUploadRows method
Finalize method
GetLastDownloadTime method
GetNewUUID method
GetTable method
GrantConnectTo method
PrepareStatement method
ResetLastDownloadTime method
RevokeConnectFrom method
Rollback method
RollbackPartialDownload method
StartSynchronizationDelete method
StopSynchronizationDelete method
Synchronize method
Synchronize method


Connection members

Public static fields (Shared)
Member | Description
AutoCommit field | Controls whether a commit is performed after each insert, update or delete statement.
INVALID_DATABASE_ID field | Database ID constant indicating that the DatabaseID property has not been set.
Public instance fields
Member | Description
AutoCommit field | Controls whether a commit is performed after each insert, update or delete statement.
Public instance properties
Member | Description
ConnectionOpenParms property | The parameters used to open this connection.
DatabaseID property | Database ID value to be used for global autoincrement columns.
GlobalAutoIncrementUsage property | The percentage of available global autoincrement values that have been used.
IsDatabaseNew property | Checks whether the database was new when this connection was opened.
IsLastCodeOK property | Classifies the last SQL code as successful or unsuccessful.
IsLastFetchOK property | Provides a convenient way of checking that the most recent fetch of a row succeeded or failed.
IsOpen property | Determines whether the connection is open or closed.
LastIdentity property | The most recent identity value used.
LastSQLCode property | The SQL code value for the success or failure of the last database operation.
Schema property | The database schema associated with the connection.
SyncParms property | The synchronization settings for this connection.
SyncResult property | The results of the last synchronization for this connection.
Public instance methods
Member | Description
ChangeEncryptionKey method | Changes the database's encryption key to the specified new key.
Close method | Closes this connection.
Commit method | Commits outstanding changes to the database.
CountUploadRows method | Returns the number of rows that need to be uploaded when the next synchronization takes place.
CountUploadRows method | Returns the number of rows that need to be uploaded when the next synchronization takes place.
GetLastDownloadTime method | Returns the time of the most recent download of the specified publication.
GetNewUUID method | Generates a new UUID (Guid).
GetTable method | Creates and returns a reference to the requested table in the database.
GrantConnectTo method | Grants access to an UltraLite database for a user ID with a specified password.
PrepareStatement method | Pre-compiles and stores into a PreparedStatement object a SQL statement with or without IN parameters.
ResetLastDownloadTime method | Resets the time of the most recent download.
RevokeConnectFrom method | Revokes access to an UltraLite database from the specified user ID.
Rollback method | Rolls back outstanding changes to the database.
RollbackPartialDownload method | Rolls back outstanding changes to the database from a partial download.
StartSynchronizationDelete method | Marks all subsequent deletes made by this connection for synchronization.
StopSynchronizationDelete method | Prevents delete operations from being synchronized.
Synchronize method | Synchronize the database using the current SyncParms property.
Synchronize method | Synchronize the database using the current SyncParms property with progress events posted to the specified listener.
Protected instance methods
Member | Description
Finalize method | Cleans up the associated native object.


AutoCommit field

Controls whether a commit is performed after each insert, update or delete statement.

Prototypes

' Visual Basic
PublicAutoCommit As Boolean

// C#
public bool AutoCommit;

Remarks

If AutoCommit is false, a commit or rollback is performed only when the user invokes the Commit method or Rollback method methods.

By default, a database commit is performed after each successful statement. If the commit fails, you have the option to execute additional SQL statements and perform the commit again, or execute a rollback statement.

See also
  • Connection class
  • Connection members
  • Commit method
  • Rollback method


INVALID_DATABASE_ID field

Database ID constant indicating that the DatabaseID property has not been set.

Prototypes

' Visual Basic
Public Shared INVALID_DATABASE_ID As Long

// C#
public const long INVALID_DATABASE_ID;


ConnectionOpenParms property

The parameters used to open this connection.

Prototypes

' Visual Basic
Public Readonly Property ConnectionOpenParms As ConnectionParms

// C#
public ConnectionParms ConnectionOpenParms {get;}

Property value

The parameters used to open this connection in a read-only ConnectionParms class instance.

Remarks

This property can be used after the connection is closed.

See also
  • Connection class
  • Connection members
  • ConnectionParms class
  • CreateDatabase method
  • OpenConnection method


DatabaseID property

Database ID value to be used for global autoincrement columns.

Prototypes

' Visual Basic
Public Property DatabaseID As Long

// C#
public long DatabaseID {get;set;}

Property value

Database ID value must be in range [0,UInt32.MaxValue]. A value of INVALID_DATABASE_ID field is used to indicate that the database ID has not been set.

Exceptions

  • SQLException class - If the new ID is invalid.


GlobalAutoIncrementUsage property

The percentage of available global autoincrement values that have been used.

Prototypes

' Visual Basic
Public Readonly Property GlobalAutoIncrementUsage As Short

// C#
public short GlobalAutoIncrementUsage {get;}

Property value

The percentage of available global autoincrement values that have been used. It is an integer in the range [0-100] inclusive.

Remarks

If the percentage approaches 100, your application should set a new value for the global database ID using DatabaseID property.

Exceptions

  • SQLException class - A SQL error occurred.


IsDatabaseNew property

Checks whether the database was new when this connection was opened.

Prototypes

' Visual Basic
Public Readonly Property IsDatabaseNew As Boolean

// C#
public bool IsDatabaseNew {get;}

Property value

True if the database was new when this connection was opened, false if the database already existed when this connection was opened.

See also
  • Connection class
  • Connection members
  • CreateDatabase method
  • OpenConnection method


IsLastCodeOK property

Classifies the last SQL code as successful or unsuccessful.

Prototypes

' Visual Basic
Public Readonly Property IsLastCodeOK As Boolean

// C#
public bool IsLastCodeOK {get;}

Property value

True if the most recent SQL code represents a warning or success, and false if the most recent SQL code represents an error. For example, SQLCode enumeration is not an error.

See also
  • Connection class
  • Connection members
  • LastSQLCode property
  • SQLCode enumeration


IsLastFetchOK property

Provides a convenient way of checking that the most recent fetch of a row succeeded or failed.

Prototypes

' Visual Basic
Public Readonly Property IsLastFetchOK As Boolean

// C#
public bool IsLastFetchOK {get;}

Property value

True if the last fetch succeeded, false otherwise.

Remarks

When a SQLException is thrown, the error code in the exception supercedes the error code in LastSQLCode property or the values of IsLastFetchOK property and IsLastCodeOK property.

See also
  • Connection class
  • Connection members
  • LastSQLCode property


IsOpen property

Determines whether the connection is open or closed.

Prototypes

' Visual Basic
Public Readonly Property IsOpen As Boolean

// C#
public bool IsOpen {get;}

Property value

True if the connection is open, false otherwise.


LastIdentity property

The most recent identity value used.

Prototypes

' Visual Basic
Public Readonly Property LastIdentity As UInt64

// C#
public ulong LastIdentity {get;}

Property value

The most recent identity value used. This property is equivalent to the SQL statement:

SELECT @@identity

LastIdentity is particularly useful in the context of global autoincrement columns.

Remarks

Since this property only allows you to determine the most recently assigned default value, you should retrieve this value soon after executing the insert statement to avoid spurious results.

Occasionally, a single insert statement may include more than one column of type global autoincrement. In this case, LastIdentity is one of the generated default values, but there is no reliable means to determine which one. For this reason, you should design your database and write your insert statements so as to avoid this situation.

Exceptions

  • SQLException class - A SQL error occurred.


LastSQLCode property

The SQL code value for the success or failure of the last database operation.

Prototypes

' Visual Basic
Public Readonly Property LastSQLCode As SQLCode

// C#
public SQLCode LastSQLCode {get;}

Remarks

The SQL code is a standard Adaptive Server Anywhere code and is reset by any subsequent UltraLite database operation on this connection.

When a SQLException is thrown, the error code in the exception supercedes the error code returned by LastSQLCode property or the results from IsLastFetchOK property and IsLastCodeOK property.


Schema property

The database schema associated with the connection.

Prototypes

' Visual Basic
Public Readonly Property Schema As DatabaseSchema

// C#
public DatabaseSchema Schema {get;}

Property value

A reference to the schema of the database referenced by the connection.

Remarks

This property is only valid while its connection is open.

See also
  • Connection class
  • Connection members
  • DatabaseSchema class


SyncParms property

The synchronization settings for this connection.

Prototypes

' Visual Basic
Public Readonly Property SyncParms As SyncParms

// C#
public SyncParms SyncParms {get;}

Property value

A reference to the parameters used for synchronization by the connection. Modifications to the parameters will affect the next synchronization made over the connection.

See also
  • Connection class
  • Connection members
  • SyncParms property
  • SyncResult property


SyncResult property

The results of the last synchronization for this connection.

Prototypes

' Visual Basic
Public Readonly Property SyncResult As SyncResult

// C#
public SyncResult SyncResult {get;}

Property value

A reference to the results of the last synchronization for this connection.

See also
  • Connection class
  • Connection members
  • SyncResult property
  • SyncParms property


ChangeEncryptionKey method

Changes the database's encryption key to the specified new key.

Prototypes

' Visual Basic
Public Sub ChangeEncryptionKey( _
ByVal newKey As String _
)

// C#
public void ChangeEncryptionKey(
string newKey
);

Parameters

  • newKey The new encryption key for the database.

Remarks

If the encryption key is lost, it will not be possible to open the database.

Exceptions

  • SQLException class - A SQL error occurred.


Close method

Closes this connection.

Prototypes

' Visual Basic
Public Sub Close()

// C#
public void Close();

Remarks

Once a connection is closed, it cannot be reopened. To reopen a connection, a new Connection object must be created and opened.

It is an error to use any object (table, schema, etc.) associated with a closed connection.

Exceptions

  • SQLException class - A SQL error occurred.


Commit method

Commits outstanding changes to the database.

Prototypes

' Visual Basic
Public Sub Commit()

// C#
public void Commit();

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Connection class
  • Connection members
  • Commit method
  • Rollback method


CountUploadRows method

Returns the number of rows that need to be uploaded when the next synchronization takes place.

Prototypes

' Visual Basic
Overloads Public Function CountUploadRows( _
ByVal mask As Integer, _
ByVal threshold As UInt32 _
) As UInt32

// C#
public uint CountUploadRows(
int mask,
uint threshold
);

Parameters

  • mask The set of publications to check for rows. See the PublicationSchema class class for more information.

  • threshold The maximum number of rows to count, limiting the amount of time taken by CountUploadRows. A value of 0 corresponds to the maximum limit. A value of 1 determines if any rows need to be synchronized.

Return value

The number of rows that need to be uploaded from the specified publication(s).

Exceptions

  • SQLException class - A SQL error occurred.


CountUploadRows method

Returns the number of rows that need to be uploaded when the next synchronization takes place.

Prototypes

' Visual Basic
Overloads Public Function CountUploadRows( _
ByVal mask As Integer, _
ByVal threshold As Long _
) As Long

// C#
public long CountUploadRows(
int mask,
long threshold
);

Parameters

  • mask The set of publications to check for rows. See the PublicationSchema class class for more information.

  • threshold The maximum number of rows to count, and so limits the amount of time taken by CountUploadRows. A value of 0 corresponds to the maximum limit. A value of 1 determines if any rows need to be synchronized. threshold must be in range [0,0x0ffffffff].

Return value

The number of rows that need to be uploaded from the specified publication(s).

Remarks

This method is provided for languages that do not support the System.UInt32 type natively. Use the other form of this method if your application supports it.

Exceptions

  • SQLException class - A SQL error occurred.


Finalize method

Cleans up the associated native object.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


GetLastDownloadTime method

Returns the time of the most recent download of the specified publication.

Prototypes

' Visual Basic
Public Function GetLastDownloadTime( _
ByVal mask As Integer _
) As Date

// C#
public DateTime GetLastDownloadTime(
int mask
);

Parameters

  • mask The mask of the publication to check. See the PublicationSchema class class for more information.

Return value

The timestamp of the last download.

Remarks

The parameter mask must reference a single publication or be the special constant SYNC_ALL_DB field for the time of the last download of the full database.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Connection class
  • Connection members
  • ResetLastDownloadTime method


GetNewUUID method

Generates a new UUID (Guid).

Prototypes

' Visual Basic
Public Function GetNewUUID() As Guid

// C#
public Guid GetNewUUID();

Return value

A new UUID as a Guid.

Remarks

Provided here as it is not included in the .NET Compact Framework.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Connection class
  • Connection members
  • SetUUID method
  • GetUUID method


GetTable method

Creates and returns a reference to the requested table in the database.

Prototypes

' Visual Basic
Public Function GetTable( _
ByVal name As String _
) As Table

// C#
public Table GetTable(
string name
);

Parameters

  • name The name of the table to fetch.

Return value

An instance of the Table class object representing the desired table.

Exceptions

  • SQLException class - A SQL error occurred.


GrantConnectTo method

Grants access to an UltraLite database for a user ID with a specified password.

Prototypes

' Visual Basic
Public Sub GrantConnectTo( _
ByVal uid As String, _
ByVal pwd As String _
)

// C#
public void GrantConnectTo(
string uid,
string pwd
);

Parameters

  • uid The user ID to receive access to the database. The maximum length of the ID is 16 characters.

  • pwd The password to be associated with the ID. The maximum length is 16 characters.

Remarks

If an existing user ID is specified, this function updates the password for the user. UltraLite supports a maximum of 4 users. This method is enabled only if user authentication was enabled when the connection was opened.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Connection class
  • Connection members
  • OpenConnection method


PrepareStatement method

Pre-compiles and stores into a PreparedStatement object a SQL statement with or without IN parameters.

Prototypes

' Visual Basic
Public Function PrepareStatement( _
ByVal sql As String _
) As PreparedStatement

// C#
public PreparedStatement PrepareStatement(
string sql
);

Parameters

  • sql a SQL statement that may contain one or more '?' IN parameter placeholders.

Return value

a new PreparedStatement object containing the pre-compiled statement.

Remarks

The prepared statement object can be used to efficiently execute this statement multiple times.

Exceptions

  • SQLException class - A SQL error occurred.


ResetLastDownloadTime method

Resets the time of the most recent download.

Prototypes

' Visual Basic
Public Sub ResetLastDownloadTime( _
ByVal mask As Integer _
)

// C#
public void ResetLastDownloadTime(
int mask
);

Parameters

  • mask The set of publications to reset. See PublicationSchema class class for more information.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Connection class
  • Connection members
  • GetLastDownloadTime method


RevokeConnectFrom method

Revokes access to an UltraLite database from the specified user ID.

Prototypes

' Visual Basic
Public Sub RevokeConnectFrom( _
ByVal uid As String _
)

// C#
public void RevokeConnectFrom(
string uid
);

Parameters

  • uid The user ID for which database access is to be revoked. The maximum length of a user ID is 16 characters.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Connection class
  • Connection members
  • GrantConnectTo method


Rollback method

Rolls back outstanding changes to the database.

Prototypes

' Visual Basic
Public Sub Rollback()

// C#
public void Rollback();

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Connection class
  • Connection members
  • Commit method
  • AutoCommit field


RollbackPartialDownload method

Rolls back outstanding changes to the database from a partial download.

Prototypes

' Visual Basic
Public Sub RollbackPartialDownload()

// C#
public void RollbackPartialDownload();

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Connection class
  • Connection members
  • KeepPartialDownload property
  • ResumePartialDownload property


StartSynchronizationDelete method

Marks all subsequent deletes made by this connection for synchronization.

Prototypes

' Visual Basic
Public Sub StartSynchronizationDelete()

// C#
public void StartSynchronizationDelete();

Remarks

Once this function is called, all delete operations are again synchronized, causing the deleted rows to also be removed from the consolidated database.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Connection class
  • Connection members
  • StopSynchronizationDelete method


StopSynchronizationDelete method

Prevents delete operations from being synchronized.

Prototypes

' Visual Basic
Public Sub StopSynchronizationDelete()

// C#
public void StopSynchronizationDelete();

Remarks

This method is useful for deleting old information from an UltraLite database to save space, while not deleting this information on the consolidated database.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Connection class
  • Connection members
  • StartSynchronizationDelete method


Synchronize method

Synchronize the database using the current SyncParms property.

Prototypes

' Visual Basic
Overloads Public Sub Synchronize()

// C#
public void Synchronize();

Remarks

A detailed result status will be reported in this connection's SyncResult property object.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Connection class
  • Connection members
  • SyncParms property
  • SyncResult property


Synchronize method

Synchronize the database using the current SyncParms property with progress events posted to the specified listener.

Prototypes

' Visual Basic
Overloads Public Sub Synchronize( _
ByVal listener As SyncProgressListener _
)

// C#
public void Synchronize(
SyncProgressListener listener
);

Parameters

  • listener The object that will receive synchronization progress events.

Remarks

The last event posted to the listener will have a state of SyncProgressState enumeration.

Errors during synchronization will be posted as SyncProgressState enumeration events and then thrown as SQLException classs.

A detailed result status will be reported in this connection's SyncResult property object.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Connection class
  • Connection members
  • SyncParms property
  • SyncResult property
  • SyncProgressListener interface


ConnectionParms class

Specifies parameters for opening a connection to an UltraLite database.

Prototypes

' Visual Basic
Public Class ConnectionParms
Inherits DatabaseNameParms

// C#
public class ConnectionParms :
DatabaseNameParms

Remarks

Databases are created with a single authenticated user, DBA, whose initial password is SQL. By default, connections are opened using the user ID DBA and password SQL. To disable the default user, use RevokeConnectFrom method. To add a user or change a user's password, use GrantConnectTo method.

If multiple connections are created, each one must be given a unique name using ConnectionName="name";.

See also
  • ConnectionParms members
  • AdditionalParms property

ConnectionParms members
ConnectionParms constructor
CacheSize property
ConnectionName property
EncryptionKey property
Password property
UserID property


ConnectionParms members

Public instance constructors
Member | Description
ConnectionParms constructor | Initializes a ConnectionParms instance with its default values.
Public instance properties
Member | Description
AdditionalParms property (inherited from DatabaseNameParms) | Specifies additional parameters as a semicolon-separated list of name=value pairs. These are less commonly used parameters.
CacheSize property | Specifies the size of the cache.
ConnectionName property | Specifies a name for the connection. This is only needed if you create more than one connection to the database.
DatabaseOnCE property (inherited from DatabaseNameParms) | Specifies the path and filename of the UltraLite database on Windows CE.
DatabaseOnDesktop property (inherited from DatabaseNameParms) | Specifies the path and filename of the UltraLite database on Windows desktop platforms.
EncryptionKey property | Specifies a key for encrypting the database.
ParmsUsed property (inherited from DatabaseNameParms) | Returns the parameters actually used by the last DatabaseManager method to use this instance.
Password property | Specifies the password for the authenticated user.
UserID property | Specifies an authenticated user for the database.
Public instance methods
Member | Description
ToString method (inherited from DatabaseNameParms) | Returns the string representation of this instance.
Public instance events
Member | Description
UnusedEvent event (inherited from DatabaseNameParms) | Unused.
Protected instance methods
Member | Description
Dispose method (inherited from DatabaseNameParms) | Releases the resources used by this object.


ConnectionParms constructor

Initializes a ConnectionParms instance with its default values.

Prototypes

' Visual Basic
Overloads Public Sub New()

// C#
public ConnectionParms();

Exceptions

  • SQLException class - A SQL error occurred.


CacheSize property

Specifies the size of the cache.

Prototypes

' Visual Basic
Public Property CacheSize As String

// C#
public string CacheSize {get;set;}

Remarks

The values for the cache size are specified in units of bytes. Use the suffix k or K to indicate units of kilobytes and use the suffix of m or M to indicate megabytes.

For example, the following sets the cache size to 128 KB.

connParms.CacheSize = "128k";

The default cache size is sixteen pages. Using the default page size of 4 KB, the default cache size is therefore 64 KB. The minimum cache size is platform dependent.

The default cache size is conservative. If your testing shows the need for better performance, you should increase the cache size.

Increasing the cache size beyond the size of the database itself provides no performance improvement. Also, large cache sizes may interfere with the number of other applications you can use.

If the cache size is unspecified or improperly specified, the default size is used.


ConnectionName property

Specifies a name for the connection. This is only needed if you create more than one connection to the database.

Prototypes

' Visual Basic
Public Property ConnectionName As String

// C#
public string ConnectionName {get;set;}


EncryptionKey property

Specifies a key for encrypting the database.

Prototypes

' Visual Basic
Public Property EncryptionKey As String

// C#
public string EncryptionKey {get;set;}

Remarks

All openConnection calls must use the same key as was specified when the database was created. Lost or forgotten keys result in completely inaccessible databases.

As with all passwords, it is best to choose a key value that cannot be easily guessed. The key can be of arbitrary length, but generally the longer the key, the better, because a shorter key is easier to guess than a longer one. As well, including a combination of numbers, letters, and special characters decreases the chances of someone guessing the key.

See also
  • ConnectionParms class
  • ConnectionParms members
  • ChangeEncryptionKey method


Password property

Specifies the password for the authenticated user.

Prototypes

' Visual Basic
Public Property Password As String

// C#
public string Password {get;set;}

Remarks

When a database is created, the password for the DBA user ID is set to SQL. Passwords are case-insensitive if the database is case-insensitive and case-sensitive if the database is case-sensitive. The default value is SQL.

See also
  • ConnectionParms class
  • ConnectionParms members
  • UserID property


UserID property

Specifies an authenticated user for the database.

Prototypes

' Visual Basic
Public Property UserID As String

// C#
public string UserID {get;set;}

Remarks

Databases are initially created with a single authenticated user named DBA. User IDs are case-insensitive if the database is case-insensitive and case-sensitive if the database is case-sensitive. The default value is DBA.

See also
  • ConnectionParms class
  • ConnectionParms members
  • Password property
  • GrantConnectTo method
  • RevokeConnectFrom method
  • IsCaseSensitive property


CreateParms class

Specifies parameters for creating an UltraLite database and opening a connection to it.

Prototypes

' Visual Basic
NotInheritable Public Class CreateParms
Inherits ConnectionParms

// C#
public sealed class CreateParms :
ConnectionParms

Remarks

NOTE: Only one database may be active at a given time. Attempts to create a different database while other connections are open will result in an error.

A valid schema file must be specified to successfully create a database.

See also
  • CreateParms members
  • AdditionalParms property


CreateParms members

Public instance constructors
Member | Description
CreateParms constructor | Initializes a CreateParms instance with its default values.
Public instance properties
Member | Description
AdditionalParms property (inherited from DatabaseNameParms) | Specifies additional parameters as a semicolon-separated list of name=value pairs. These are less commonly used parameters.
CacheSize property (inherited from ConnectionParms) | Specifies the size of the cache.
ConnectionName property (inherited from ConnectionParms) | Specifies a name for the connection. This is only needed if you create more than one connection to the database.
DatabaseOnCE property (inherited from DatabaseNameParms) | Specifies the path and filename of the UltraLite database on Windows CE.
DatabaseOnDesktop property (inherited from DatabaseNameParms) | Specifies the path and filename of the UltraLite database on Windows desktop platforms.
EncryptionKey property (inherited from ConnectionParms) | Specifies a key for encrypting the database.
ParmsUsed property (inherited from DatabaseNameParms) | Returns the parameters actually used by the last DatabaseManager method to use this instance.
Password property (inherited from ConnectionParms) | Specifies the password for the authenticated user.
Schema property | Specifies the schema for an UltraLite database.
UserID property (inherited from ConnectionParms) | Specifies an authenticated user for the database.
Public instance methods
Member | Description
ToString method (inherited from DatabaseNameParms) | Returns the string representation of this instance.
Public instance events
Member | Description
UnusedEvent event (inherited from DatabaseNameParms) | Unused.
Protected instance methods
Member | Description
Dispose method (inherited from DatabaseNameParms) | Releases the resources used by this object.


CreateParms constructor

Initializes a CreateParms instance with its default values.

Prototypes

' Visual Basic
Public Sub New()

// C#
public CreateParms();

Exceptions

  • SQLException class - A SQL error occurred.


Schema property

Specifies the schema for an UltraLite database.

Prototypes

' Visual Basic
Public Property Schema As SchemaParms

// C#
public SchemaParms Schema {get;set;}

See also
  • CreateParms class
  • CreateParms members
  • SchemaParms class


Cursor class

Represents a cursor in an UltraLite database. Cursors are sets of rows from either a table or a result set.

Prototypes

' Visual Basic
MustInherit Public Class Cursor

// C#
public abstract class Cursor

Remarks

This class is an abstract base class of the Table class and ResultSet class classes.

Derived classes have a Schema property through which the description of the rows may be accessed.

Cursor members
IsBOF property
IsEOF property
IsOpen property
RowCount property
Close method
Fill method
Finalize method
GetBoolean method
GetBytes method
GetBytes method
GetChars method
GetDouble method
GetFloat method
GetInt method
GetLong method
GetShort method
GetString method
GetTime method
GetTimestamp method
GetUInt method
GetULong method
GetUShort method
GetUUID method
IsNull method
MoveAfterLast method
MoveBeforeFirst method
MoveFirst method
MoveLast method
MoveNext method
MovePrevious method
MoveRelative method


Cursor members

Public instance properties
Member | Description
IsBOF property | Returns true if the current row position is before the first row.
IsEOF property | Returns true if the current row position is after the last row.
IsOpen property | Checks whether this cursor is currently open.
RowCount property | Returns the number of rows in the cursor.
Public instance methods
Member | Description
Close method | Closes the cursor.
Fill method | Fills a ADO .NET DataTable object with the rows in the cursor.
GetBoolean method | Returns the value for the specified column as a Boolean.
GetBytes method | Returns the value for the specified column as an array of Bytes. Only valid for columns of type SQLType enumeration, SQLType enumeration, or SQLType enumeration.
GetBytes method | Copies a subset of the value for the specified SQLType enumeration column, beginning at the specified offset, to the specified offset of the destination Byte array.
GetChars method | Copies a subset of the value for the specified SQLType enumeration column, beginning at the specified offset, to the specified offset of the destination System.Char array.
GetDouble method | Returns the value for the specified column as a Double.
GetFloat method | Returns the value for the specified column as a Single.
GetInt method | Returns the value for the specified column as an Int32.
GetLong method | Returns the value for the specified column as an Int64.
GetShort method | Returns the value for the specified column as an Int16.
GetString method | Returns the value for the specified column as a String.
GetTime method | Returns the value for the specified column as a TimeSpan with millisecond accuracy.
GetTimestamp method | Returns the value for the specified column as a DateTime with millisecond accuracy.
GetUInt method | Returns the value for the specified column as a UInt32.
GetULong method | Returns the value for the specified column as a UInt64.
GetUShort method | Returns the value for the specified column as a UInt16.
GetUUID method | Returns the value for the specified column as a UUID (Guid).
IsNull method | Checks whether the value from the specified column is NULL.
MoveAfterLast method | Position to after the last row of the cursor.
MoveBeforeFirst method | Position to before the first row of the cursor.
MoveFirst method | Position to the first row of the cursor.
MoveLast method | Position to the last row of the cursor.
MoveNext method | Position to the next row or after last.
MovePrevious method | Position to the previous row or before first.
MoveRelative method | Position relative to the current row.
Protected instance methods
Member | Description
Finalize method | Finalize method


IsBOF property

Returns true if the current row position is before the first row.

Prototypes

' Visual Basic
Public Readonly Property IsBOF As Boolean

// C#
public bool IsBOF {get;}

Exceptions

  • SQLException class - A SQL error occurred.


IsEOF property

Returns true if the current row position is after the last row.

Prototypes

' Visual Basic
Public Readonly Property IsEOF As Boolean

// C#
public bool IsEOF {get;}

Exceptions

  • SQLException class - A SQL error occurred.


IsOpen property

Checks whether this cursor is currently open.

Prototypes

' Visual Basic
Public Readonly Property IsOpen As Boolean

// C#
public bool IsOpen {get;}

Return value

True if this cursor is currently open, false if the cursor is closed.


RowCount property

Returns the number of rows in the cursor.

Prototypes

' Visual Basic
Public Readonly Property RowCount As Integer

// C#
public int RowCount {get;}

Remarks

One use for RowCount is to decide when to delete old rows to save space. Old rows can be deleted from the UltraLite database without being deleted from the consolidated database using the StopSynchronizationDelete method method.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • StartSynchronizationDelete method
  • StopSynchronizationDelete method


Close method

Closes the cursor.

Prototypes

' Visual Basic
Public Sub Close()

// C#
public void Close();

Remarks

It is not an error to close a cursor that is already closed.

Exceptions

  • SQLException class - A SQL error occurred.


Fill method

Fills a ADO .NET DataTable object with the rows in the cursor.

Prototypes

' Visual Basic
Public Function Fill( _
ByVal dt As DataTable _
) As Integer

// C#
public int Fill(
DataTable dt
);

Parameters

  • dt the ADO .NET DataTable object to fill.

Return value

the number of rows that were filled.


Finalize method

Finalize method

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


GetBoolean method

Returns the value for the specified column as a Boolean.

Prototypes

' Visual Basic
Public Function GetBoolean( _
ByVal columnID As Short _
) As Boolean

// C#
public bool GetBoolean(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

column value as a Boolean.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetBytes method

Returns the value for the specified column as an array of Bytes. Only valid for columns of type SQLType enumeration, SQLType enumeration, or SQLType enumeration.

Prototypes

' Visual Basic
Overloads Public Function GetBytes( _
ByVal columnID As Short _
) As Byte()

// C#
public byte[] GetBytes(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

column value as an array of Bytes.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBoolean method
  • GetBytes method
  • GetChars method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetBytes method

Copies a subset of the value for the specified SQLType enumeration column, beginning at the specified offset, to the specified offset of the destination Byte array.

Prototypes

' Visual Basic
Overloads Public Function GetBytes( _
ByVal columnID As Short, _
ByVal srcOffset As Integer, _
ByVal dst As Byte(), _
ByVal dstOffset As Integer, _
ByVal count As Integer _
) As Integer

// C#
public int GetBytes(
short columnID,
int srcOffset,
byte[] dst,
int dstOffset,
int count
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

  • srcOffset start position in the column value. Zero is the beginning of the value.

  • dst the destination array.

  • dstOffset start position in the destination array.

  • count the number of bytes to be copied.

Return value

the actual number of bytes copied.

Remarks

The bytes at position srcOffset through srcOffset+count-1 of the value are copied into positions dstOffset through dstOffset+count-1, respectively, of the destination array. If the end of the value is encountered before count bytes are copied, the remainder of the destination array is left unchanged.

If any of the following are true, a SQLException class with code SQLCode enumeration is thrown and the destination is not modified: For other errors, a SQLException class with the appropriate error code is thrown.

  • dst is null.
  • srcOffset is negative.
  • dstOffset is negative.
  • count is negative.
  • dstOffset+count is greater than dst.Length.
Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBoolean method
  • GetBytes method
  • GetChars method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetChars method

Copies a subset of the value for the specified SQLType enumeration column, beginning at the specified offset, to the specified offset of the destination System.Char array.

Prototypes

' Visual Basic
Public Function GetChars( _
ByVal columnID As Short, _
ByVal srcOffset As Integer, _
ByVal dst As Char(), _
ByVal dstOffset As Integer, _
ByVal count As Integer _
) As Integer

// C#
public int GetChars(
short columnID,
int srcOffset,
char[] dst,
int dstOffset,
int count
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

  • srcOffset start position in the column value. Zero is the beginning of the value.

  • dst the destination array.

  • dstOffset start position in the destination array.

  • count the number of characters to be copied.

Return value

the actual number of characters copied.

Remarks

The characters at position srcOffset through srcOffset+count-1 of the value are copied into positions dstOffset through dstOffset+count-1, respectively, of the destination array. If the end of the value is encountered before count characters are copied, the remainder of the destination array is left unchanged.

If any of the following is true, a SQLException class with code SQLCode enumeration is thrown and the destination is not modified: For other errors, a SQLException class with the appropriate error code is thrown.

  • dst is null.
  • srcOffset is negative.
  • dstOffset is negative.
  • count is negative.
  • dstOffset+count is greater than dst.Length.
Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBoolean method
  • GetBytes method
  • GetBytes method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetDouble method

Returns the value for the specified column as a Double.

Prototypes

' Visual Basic
Public Function GetDouble( _
ByVal columnID As Short _
) As Double

// C#
public double GetDouble(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

column value as a Double.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetBoolean method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetFloat method

Returns the value for the specified column as a Single.

Prototypes

' Visual Basic
Public Function GetFloat( _
ByVal columnID As Short _
) As Single

// C#
public float GetFloat(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

column value as a Single.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetBoolean method
  • GetDouble method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetInt method

Returns the value for the specified column as an Int32.

Prototypes

' Visual Basic
Public Function GetInt( _
ByVal columnID As Short _
) As Integer

// C#
public int GetInt(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

column value as an Int32.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetBoolean method
  • GetDouble method
  • GetFloat method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetLong method

Returns the value for the specified column as an Int64.

Prototypes

' Visual Basic
Public Function GetLong( _
ByVal columnID As Short _
) As Long

// C#
public long GetLong(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

column value as an Int64

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetBoolean method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetShort method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetShort method

Returns the value for the specified column as an Int16.

Prototypes

' Visual Basic
Public Function GetShort( _
ByVal columnID As Short _
) As Short

// C#
public short GetShort(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

column value as an Int16.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetBoolean method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetString method

Returns the value for the specified column as a String.

Prototypes

' Visual Basic
Public Function GetString( _
ByVal columnID As Short _
) As String

// C#
public string GetString(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

column value as a String.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetBoolean method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetTime method

Returns the value for the specified column as a TimeSpan with millisecond accuracy.

Prototypes

' Visual Basic
Public Function GetTime( _
ByVal columnID As Short _
) As TimeSpan

// C#
public TimeSpan GetTime(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

Column value as a TimeSpan.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetBoolean method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetTimestamp method

Returns the value for the specified column as a DateTime with millisecond accuracy.

Prototypes

' Visual Basic
Public Function GetTimestamp( _
ByVal columnID As Short _
) As Date

// C#
public DateTime GetTimestamp(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

column value as a DateTime.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • DateTime
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetBoolean method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTime method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetUInt method

Returns the value for the specified column as a UInt32.

Prototypes

' Visual Basic
Public Function GetUInt( _
ByVal columnID As Short _
) As UInt32

// C#
public uint GetUInt(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

column value as an UInt32.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetBoolean method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetULong method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetULong method

Returns the value for the specified column as a UInt64.

Prototypes

' Visual Basic
Public Function GetULong( _
ByVal columnID As Short _
) As UInt64

// C#
public ulong GetULong(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

column value as a UInt64

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetBoolean method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetUShort method
  • GetUUID method
  • GetColumnSQLType method


GetUShort method

Returns the value for the specified column as a UInt16.

Prototypes

' Visual Basic
Public Function GetUShort( _
ByVal columnID As Short _
) As UInt16

// C#
public ushort GetUShort(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

column value as an UInt16.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetBoolean method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUUID method
  • GetColumnSQLType method


GetUUID method

Returns the value for the specified column as a UUID (Guid).

Prototypes

' Visual Basic
Public Function GetUUID( _
ByVal columnID As Short _
) As Guid

// C#
public Guid GetUUID(
short columnID
);

Parameters

  • columnID The ID number of the column. The first column in the cursor has an ID value of one.

Return value

Column value as a Guid.

Remarks

Only valid for columns of type SQLType enumeration or for columns of type SQLType enumeration with length 16.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • IsNull method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetBoolean method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetColumnSQLType method
  • GetColumnSize method


IsNull method

Checks whether the value from the specified column is NULL.

Prototypes

' Visual Basic
Public Function IsNull( _
ByVal columnID As Short _
) As Boolean

// C#
public bool IsNull(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the cursor has an ID value of one.

Return value

true if value is NULL, false if value is not NULL.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Cursor class
  • Cursor members
  • GetColumnID method
  • GetBoolean method
  • GetBytes method
  • GetBytes method
  • GetChars method
  • GetDouble method
  • GetFloat method
  • GetInt method
  • GetLong method
  • GetShort method
  • GetString method
  • GetTime method
  • GetTimestamp method
  • GetUInt method
  • GetULong method
  • GetUShort method
  • GetUUID method


MoveAfterLast method

Position to after the last row of the cursor.

Prototypes

' Visual Basic
Public Sub MoveAfterLast()

// C#
public void MoveAfterLast();

Exceptions

  • SQLException class - A SQL error occurred.


MoveBeforeFirst method

Position to before the first row of the cursor.

Prototypes

' Visual Basic
Public Sub MoveBeforeFirst()

// C#
public void MoveBeforeFirst();

Exceptions

  • SQLException class - A SQL error occurred.


MoveFirst method

Position to the first row of the cursor.

Prototypes

' Visual Basic
Public Function MoveFirst() As Boolean

// C#
public bool MoveFirst();

Return value

true if successful, false otherwise. For example, the method fails if there are no rows.

Exceptions

  • SQLException class - A SQL error occurred.


MoveLast method

Position to the last row of the cursor.

Prototypes

' Visual Basic
Public Function MoveLast() As Boolean

// C#
public bool MoveLast();

Return value

true if successful, false otherwise. For example, the method fails if there are no rows.

Exceptions

  • SQLException class - A SQL error occurred.


MoveNext method

Position to the next row or after last.

Prototypes

' Visual Basic
Public Function MoveNext() As Boolean

// C#
public bool MoveNext();

Return value

true if successful, false otherwise. For example, the method fails if there are no more rows.

Exceptions

  • SQLException class - A SQL error occurred.


MovePrevious method

Position to the previous row or before first.

Prototypes

' Visual Basic
Public Function MovePrevious() As Boolean

// C#
public bool MovePrevious();

Return value

true if successful, false otherwise. For example, the method fails if there are no more rows.

Exceptions

  • SQLException class - A SQL error occurred.


MoveRelative method

Position relative to the current row.

Prototypes

' Visual Basic
Public Function MoveRelative( _
ByVal offset As Integer _
) As Boolean

// C#
public bool MoveRelative(
int offset
);

Parameters

  • offset The number of rows to move. Negative values correspond to moving backwards.

Return value

true if successful, false otherwise. For example, the method fails if it positions beyond the first or last row.

Remarks

If the row does not exist, the method returns false, and the cursor position is after the last row (isEOF()) if offset is positive, and before the first row (isBOF()) if the offset is negative.

Exceptions

  • SQLException class - A SQL error occurred.


CursorSchema class

Represents the schema of an UltraLite cursor.

Prototypes

' Visual Basic
MustInherit Public Class CursorSchema

// C#
public abstract class CursorSchema

Remarks

This class is an abstract base class of the TableSchema class and ResultSetSchema class classes.

CursorSchema members
ColumnCount property
IsOpen property
Name property
Finalize method
GetColumnID method
GetColumnName method
GetColumnPrecision method
GetColumnScale method
GetColumnSize method
GetColumnSQLType method


CursorSchema members

Public instance properties
Member | Description
ColumnCount property | Returns the number of columns in this cursor.
IsOpen property | Checks whether this cursor schema is currently open.
Name property | The name of this cursor.
Public instance methods
Member | Description
GetColumnID method | Returns the column ID of the named column.
GetColumnName method | Returns the name of column identified by the specified column ID.
GetColumnPrecision method | Returns the precision of the named column if the column is a numeric column (SQL type NUMERIC).
GetColumnScale method | Returns the scale of the named column if the column is a numeric column (SQL type NUMERIC).
GetColumnSize method | Returns the size of the named column if the column is a sized column (SQL type BINARY or CHAR).
GetColumnSQLType method | Gets the SQL data type of the named column.
Protected instance methods
Member | Description
Finalize method | Destructor that cleans up the associated native object.


ColumnCount property

Returns the number of columns in this cursor.

Prototypes

' Visual Basic
Public Readonly Property ColumnCount As Short

// C#
public short ColumnCount {get;}

Remarks

Column IDs range from 1 to ColumnCount, inclusively.

Column IDs and count may change during a schema upgrade. To correctly identify a column, access it by name or refresh the cached IDs and counts after a schema upgrade.


IsOpen property

Checks whether this cursor schema is currently open.

Prototypes

' Visual Basic
Public Readonly Property IsOpen As Boolean

// C#
public bool IsOpen {get;}

Return value

True if this cursor schema is currently open, false if the cursor schema is closed.


Name property

The name of this cursor.

Prototypes

' Visual Basic
Public Readonly Property Name As String

// C#
public string Name {get;}


Finalize method

Destructor that cleans up the associated native object.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


GetColumnID method

Returns the column ID of the named column.

Prototypes

' Visual Basic
Public Function GetColumnID( _
ByVal name As String _
) As Short

// C#
public short GetColumnID(
string name
);

Parameters

  • name name of the column.

Return value

column ID.

Remarks

Column IDs range from 1 to ColumnCount property, inclusively.

Column IDs and counts may change during a schema upgrade. To correctly identify a column, access it by name or refresh the cached IDs and counts after a schema upgrade.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • CursorSchema class
  • CursorSchema members
  • ColumnCount property


GetColumnName method

Returns the name of column identified by the specified column ID.

Prototypes

' Visual Basic
Public Function GetColumnName( _
ByVal columnID As Short _
) As String

// C#
public string GetColumnName(
short columnID
);

Parameters

  • columnID ID of the column. columnID must be in the range [1,CursorSchema.ColumnCount].

Return value

name of the column.

Remarks

Column IDs and count may change during a schema upgrade. To correctly identify a column, access it by name or refresh the cached IDs and counts after a schema upgrade.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • CursorSchema class
  • CursorSchema members
  • ColumnCount property


GetColumnPrecision method

Returns the precision of the named column if the column is a numeric column (SQL type NUMERIC).

Prototypes

' Visual Basic
Public Function GetColumnPrecision( _
ByVal name As String _
) As Integer

// C#
public int GetColumnPrecision(
string name
);

Parameters

  • name name of the column.

Return value

precision of the numeric column.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • CursorSchema class
  • CursorSchema members
  • GetColumnSQLType method


GetColumnScale method

Returns the scale of the named column if the column is a numeric column (SQL type NUMERIC).

Prototypes

' Visual Basic
Public Function GetColumnScale( _
ByVal name As String _
) As Integer

// C#
public int GetColumnScale(
string name
);

Parameters

  • name name of the column.

Return value

scale of the numeric column.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • CursorSchema class
  • CursorSchema members
  • GetColumnSQLType method


GetColumnSize method

Returns the size of the named column if the column is a sized column (SQL type BINARY or CHAR).

Prototypes

' Visual Basic
Public Function GetColumnSize( _
ByVal name As String _
) As Integer

// C#
public int GetColumnSize(
string name
);

Parameters

  • name name of the column.

Return value

size of the sized column.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • CursorSchema class
  • CursorSchema members
  • GetColumnSQLType method


GetColumnSQLType method

Gets the SQL data type of the named column.

Prototypes

' Visual Basic
Public Function GetColumnSQLType( _
ByVal name As String _
) As SQLType

// C#
public SQLType GetColumnSQLType(
string name
);

Parameters

  • name name of the column.

Return value

a SQLType enumerated integer.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • CursorSchema class
  • CursorSchema members
  • SQLType enumeration
  • ColumnCount property


DatabaseManager class

Manages connections to an UltraLite database. May not be instantiated more than once.

Prototypes

' Visual Basic
NotInheritable Public Class DatabaseManager

// C#
public sealed class DatabaseManager

Remarks

You must open a connection before carrying out any other operation, and you must close the connection after you have finished all operations on the connection, and before your application terminates. You must close all tables opened on a connection before closing the connection.

The constructor is not thread-safe. All other methods on this class are thread-safe.

DatabaseManager members
DatabaseManager constructor
DatabaseManager constructor
RuntimeType property
CreateDatabase method
DropDatabase method
Finalize method
OpenConnection method
SetActiveSyncListener method
SetServerSyncListener method


DatabaseManager members

Public instance constructors
Member | Description
DatabaseManager constructor | Initializes the iAnywhere.UltraLite assembly using the standalone runtime. Only one instance of DatabaseManager can be created per application.
DatabaseManager constructor | Initializes the iAnywhere.UltraLite assembly specifying the type of runtime. Only one instance of DatabaseManager can be created per application.
Public instance properties
Member | Description
RuntimeType property | Specifies the type of the UltraLite.NET runtime.
Public instance methods
Member | Description
CreateDatabase method | Creates a database and opens a connection to the database as specified by parms.
DropDatabase method | Deletes the specified database. You cannot drop a database that has open connections.
OpenConnection method | Opens a connection to the database specified by parms. If the database does not exist, a SQLException class with the value SQLCode enumeration is thrown.
SetActiveSyncListener method | Specifies the listener object to process ActiveSync calls from the MobiLink provider for ActiveSync.
SetServerSyncListener method | Specifies the listener object used to process the specified server sync message.
Protected instance methods
Member | Description
Finalize method | Destructor that cleans up the associated native state.


DatabaseManager constructor

Initializes the iAnywhere.UltraLite assembly using the standalone runtime. Only one instance of DatabaseManager can be created per application.

Prototypes

' Visual Basic
Overloads Public Sub New()

// C#
public DatabaseManager();

Exceptions

  • SQLException class - if called more than once per application.

See also
  • DatabaseManager class
  • DatabaseManager members
  • RuntimeType property


DatabaseManager constructor

Initializes the iAnywhere.UltraLite assembly specifying the type of runtime. Only one instance of DatabaseManager can be created per application.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal ulType As RuntimeType _
)

// C#
public DatabaseManager(
RuntimeType ulType
);

Parameters

  • ulType specifies the type of UltraLite.NET runtime to use.

Exceptions

  • SQLException class - if called more than once per application.

See also
  • DatabaseManager class
  • DatabaseManager members
  • RuntimeType property


RuntimeType property

Specifies the type of the UltraLite.NET runtime.

Prototypes

' Visual Basic
Public Readonly Property RuntimeType As RuntimeType

// C#
public RuntimeType RuntimeType {get;}

Property value

A RuntimeType enumeration enumerated value representing the type of the unmanaged UltraLite.NET runtime.


CreateDatabase method

Creates a database and opens a connection to the database as specified by parms.

Prototypes

' Visual Basic
Public Function CreateDatabase( _
ByVal parms As CreateParms _
) As Connection

// C#
public Connection CreateDatabase(
CreateParms parms
);

Parameters

  • parms parameters for creating the database and opening a connection to it. See CreateParms class for more information.

Return value

opened Connection.

Remarks

If the database already exists, a SQLException class with code SQLCode enumeration is thrown.

IsDatabaseNew property on the connection is set to true to indicate that the database was created when the connection was opened.

You must close the connection after you have finished all operations on the connection, and before your application terminates. You must close all tables opened on a connection before closing the connection.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • DatabaseManager class
  • DatabaseManager members
  • CreateParms class
  • OpenConnection method
  • IsDatabaseNew property
  • Close method
  • GrantConnectTo method
  • RevokeConnectFrom method


DropDatabase method

Deletes the specified database.

You cannot drop a database that has open connections.

Prototypes

' Visual Basic
Public Sub DropDatabase( _
ByVal parms As DatabaseNameParms _
)

// C#
public void DropDatabase(
DatabaseNameParms parms
);

Parameters

  • parms parameters for identifying a database. See DatabaseNameParms class for more information.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • DatabaseManager class
  • DatabaseManager members
  • DatabaseNameParms class
  • CreateDatabase method
  • OpenConnection method


Finalize method

Destructor that cleans up the associated native state.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


OpenConnection method

Opens a connection to the database specified by parms. If the database does not exist, a SQLException class with the value SQLCode enumeration is thrown.

Prototypes

' Visual Basic
Public Function OpenConnection( _
ByVal parms As ConnectionParms _
) As Connection

// C#
public Connection OpenConnection(
ConnectionParms parms
);

Parameters

  • parms parameters for opening a connection. See ConnectionParms class for more information.

Return value

opened Connection.

Remarks

IsDatabaseNew property is set to false to indicate that the database was not created when the connection was opened.

You must close the connection after you have finished all operations on the connection, and before your application terminates. You must close all tables opened on a connection before closing the connection.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • DatabaseManager class
  • DatabaseManager members
  • ConnectionParms class
  • CreateDatabase method
  • IsDatabaseNew property
  • Close method
  • GrantConnectTo method
  • RevokeConnectFrom method


SetActiveSyncListener method

Specifies the listener object to process ActiveSync calls from the MobiLink provider for ActiveSync.

Prototypes

' Visual Basic
Public Sub SetActiveSyncListener( _
ByVal appClassName As String, _
ByVal listener As ActiveSyncListener _
)

// C#
public void SetActiveSyncListener(
string appClassName,
ActiveSyncListener listener
);

Parameters

  • appClassName unique class name for the application. This is the class name used when the application is registered for use with ActiveSync.

  • listener listener object. Use null to remove previous listener.

Remarks

The parameter appClassName is the unique identifier used to identify the application. The application may only use one appClassName at a time. While a listener is registered with a particular appClassName, calls to SetServerSyncListener method or SetActiveSyncListener method with a different appClassName will fail.

To remove the ActiveSync listener, call SetActiveSyncListener method with null as the listener parameter.

To remove all listeners, call SetServerSyncListener method will null for all parameters.

Applications should remove all listeners prior to exiting.

Exceptions

  • SQLException class - A SQL error occurred.

Example

Refer to the ActiveSyncInvoked method

documentation for an example of SetActiveSyncListener method

.


SetServerSyncListener method

Specifies the listener object used to process the specified server sync message.

Prototypes

' Visual Basic
Public Sub SetServerSyncListener( _
ByVal messageName As String, _
ByVal appClassName As String, _
ByVal listener As ServerSyncListener _
)

// C#
public void SetServerSyncListener(
string messageName,
string appClassName,
ServerSyncListener listener
);

Parameters

  • messageName name of the message.

  • appClassName unique class name for the application. This is a unique identifier used to identify the application.

  • listener listener object. Use null to remove previous listener.

Remarks

The parameter appClassName is the unique identifier used to identify the application. The application may only use one appClassName at a time. While a listener is registered with a particular appClassName, calls to SetServerSyncListener method or SetActiveSyncListener method with a different appClassName will fail.

To remove the listener for a particular message, call SetServerSyncListener method with null as the listener parameter.

To remove all listeners, call SetServerSyncListener method will null for all parameters.

Applications should remove all listeners prior to exiting.

Exceptions

  • SQLException class - A SQL error occurred.

Example

Refer to the ServerSyncInvoked method

documentation for an example of SetServerSyncListener method

.


DatabaseNameParms class

Identifies an UltraLite database.

Prototypes

' Visual Basic
Public Class DatabaseNameParms
Inherits Component

// C#
public class DatabaseNameParms :
Component

Remarks

Each instance contains platform-specific and generic paths to the database. Only one value is used with the platform-specific path taking precedence over the generic path. For example, with

[Visual Basic]
  dbName.DatabaseOnCE="\UltraLite\mydb1.udb";
  dbName.DatabaseOnDesktop="mydb2.udb";
[C#]
  dbName.DatabaseOnCE="\\UltraLite\\mydb1.udb";
  dbName.DatabaseOnDesktop="mydb2.udb";

the path \UltraLite\mydb1.udb would be used on Windows CE while mydb2.udb would be used on other platforms.

After an instance is passed to an UltraLite method, the property ParmsUsed returns the parameters actually used by the UltraLite method.

The recommended extension for UltraLite database files is .udb. On Windows CE devices, the default database is \UltraLiteDB\ulstore.udb. On other Windows platforms, the default database is ulstore.udb. In C#, you must escape any backslash characters in paths.

DatabaseNameParms members
DatabaseNameParms constructor
AdditionalParms property
DatabaseOnCE property
DatabaseOnDesktop property
ParmsUsed property
Dispose method
ToString method
UnusedEvent event


DatabaseNameParms members

Public instance constructors
Member | Description
DatabaseNameParms constructor | Initializes a DatabaseNameParms instance with its default values.
Public instance properties
Member | Description
AdditionalParms property | Specifies additional parameters as a semicolon-separated list of name=value pairs. These are less commonly used parameters.
DatabaseOnCE property | Specifies the path and filename of the UltraLite database on Windows CE.
DatabaseOnDesktop property | Specifies the path and filename of the UltraLite database on Windows desktop platforms.
ParmsUsed property | Returns the parameters actually used by the last DatabaseManager method to use this instance.
Public instance methods
Member | Description
ToString method | Returns the string representation of this instance.
Public instance events
Member | Description
UnusedEvent event | Unused.
Protected instance methods
Member | Description
Dispose method | Releases the resources used by this object.


DatabaseNameParms constructor

Initializes a DatabaseNameParms instance with its default values.

Prototypes

' Visual Basic
Overloads Public Sub New()

// C#
public DatabaseNameParms();

Exceptions

  • SQLException class - A SQL error occurred.


AdditionalParms property

Specifies additional parameters as a semicolon-separated list of name=value pairs. These are less commonly used parameters.

Prototypes

' Visual Basic
Public Property AdditionalParms As String

// C#
public string AdditionalParms {get;set;}

Remarks

The values for the page size and reserve size parameters are specified in units of bytes. Use the suffix k or K to indicate units of kilobytes and use the suffix m or M to indicate megabytes.

Additional parameters are:

Keyword Description
dbn Identifies a loaded database to which a connection needs to be made.

When a database is started, it is assigned a database name, either explicitly with the dbn parameter, or by UltraLite using the base of the filename with the extension and path removed.

When opening connections, UltraLite will first search for a running database with a matching dbn. If one is not found, UltraLite will start a new database using the appropriate database filename parameter (DatabaseOnCE property or DatabaseOnDesktop property).

This parameter is required if the application (or UltraLite engine) needs to access two different databases that have the same base filename.

This parameter is only used when opening a connection with OpenConnection method or CreateDatabase method.

obfuscate When set to one (1), specifies that the database is to be created with obfuscation. For example:
 createParms.AdditionalParms = "obfuscate=1";
Obfuscating databases provides security against straightforward attempts to view data in the database directly using a viewing tool. It is not proof against skilled and determined attempts to gain access to the data. Obfuscation has little or no performance impact.

This parameter is only used when creating a new database with CreateDatabase method.

page_size UltraLite databases are stored in pages. I/O operations are carried out one page at a time. The default page size for UltraLite databases is 4 KB. You can specify 2 KB pages using the following storage parameters string:
 connParms.AdditionalParms = "page_size=2k";
Setting a page size of 2 KB reduces the maximum number of tables to approximately 500.

This parameter is only used when creating a new database with CreateDatabase method.

reserve_size Reserves file system space for storage of UltraLite persistent data.

The reserve_size parameter allows you to pre-allocate the file system space required for your UltraLite database without actually inserting any data. Reserving file system space can improve performance slightly and also prevent out of memory failures. By default, the persistent storage file only grows when required as the application updates the database.

Note that reserve_size reserves file system space, which includes the metadata in the persistent store file, and not just the raw data. The metadata overhead, as well as data compression, must be considered when deriving the required file system space from the amount of database data. Running the database with test data and observing the persistent store file size is recommended.

The reserve_size parameter reserves space by growing the persistent store file to the given reserve size on startup, regardless of whether the file previously existed. The file is never truncated.

The following parameter string ensures that the persistent store file is at least 2 MB upon startup.

 createParms.AdditionalParms = "reserve_size=2m";
This parameter is only used when opening a connection with OpenConnection method or CreateDatabase method.


DatabaseOnCE property

Specifies the path and filename of the UltraLite database on Windows CE.

Prototypes

' Visual Basic
Public Property DatabaseOnCE As String

// C#
public string DatabaseOnCE {get;set;}

Remarks

If the value is null, the default database \UltraLiteDB\ulstore.udb is used. In C#, you must escape any backslash characters in paths.


DatabaseOnDesktop property

Specifies the path and filename of the UltraLite database on Windows desktop platforms.

Prototypes

' Visual Basic
Public Property DatabaseOnDesktop As String

// C#
public string DatabaseOnDesktop {get;set;}

Remarks

If the value is null, the default database ulstore.udb is used. In C#, you must escape any backslash characters in paths.


ParmsUsed property

Returns the parameters actually used by the last DatabaseManager method to use this instance.

Prototypes

' Visual Basic
Public Readonly Property ParmsUsed As String

// C#
public string ParmsUsed {get;}

See also
  • DatabaseNameParms class
  • DatabaseNameParms members
  • CreateDatabase method
  • DropDatabase method
  • OpenConnection method


Dispose method

Releases the resources used by this object.

Prototypes

' Visual Basic
Overloads Overrides Protected Sub Dispose( _
ByVal disposing As Boolean _
)

// C#
protected override void Dispose(
bool disposing
);

Parameters

  • disposing true to release both managed and unmanaged resources; false to release only unmanaged resources.


ToString method

Returns the string representation of this instance.

Prototypes

' Visual Basic
Overrides Public Function ToString() As String

// C#
public override string ToString();

Return value

string representation of this instance.


UnusedEvent event

Unused.

Prototypes

' Visual Basic
Public Event UnusedEvent As DatabaseNameParms.UnusedEventHandler

// C#
public event DatabaseNameParms.UnusedEventHandler UnusedEvent;

Remarks

This public Event is added to fix a Visual Studio .NET bug relating to the integration of this class in Visual Basic .NET projects. It has no functional use.


DatabaseNameParms.UnusedEventHandler delegate

Unused.

Prototypes

' Visual Basic
 Delegate Sub DatabaseNameParms.UnusedEventHandler( _
ByVal sender As Object, _
ByVal args As System.EventArgs _
)

// C#
 delegate void DatabaseNameParms.UnusedEventHandler(
object sender,
System.EventArgs args
);

Parameters

  • sender Object that is the sender

  • args Event arguments

Remarks

This public Delegate is added to fix a Visual Studio .NET bug relating to the integration of this class in Visual Basic .NET projects. It has no functional use.


DatabaseSchema class

Represents the schema of an UltraLite database.

Prototypes

' Visual Basic
NotInheritable Public Class DatabaseSchema

// C#
public sealed class DatabaseSchema

Remarks

This class cannot be directly instantiated. A DatabaseSchema class object is attached to a connection as its Schema property property and is only valid while that connection is open.

DatabaseSchema members
CollationName property
IsCaseSensitive property
IsOpen property
PublicationCount property
Signature property
TableCount property
ApplyFile method
ApplyFile method
GetDatabaseProperty method
GetPublicationName method
GetPublicationSchema method
GetTableCountInPublications method
GetTableName method


DatabaseSchema members

Public instance properties
Member | Description
CollationName property | The name of the database's collation sequence.
IsCaseSensitive property | Checks whether the database is case sensitive.
IsOpen property | Whether or not the database schema is open.
PublicationCount property | The number of publications in the database.
Signature property | The signature of this database.
TableCount property | The number of tables in the database.
Public instance methods
Member | Description
ApplyFile method | Applies a database schema file to the database while allowing a listener to monitor the progress.
ApplyFile method | Applies a database schema file to the database.
GetDatabaseProperty method | Returns the value of the specified database property.
GetPublicationName method | Returns the name of the publication identified by the specified publication ID. Publication IDs are not publication masks.
GetPublicationSchema method | Returns the publication schema corresponding to the named publication.
GetTableCountInPublications method | Returns the number of tables included in the specified publication mask.
GetTableName method | Returns the name of the table identified by the specified table ID.


CollationName property

The name of the database's collation sequence.

Prototypes

' Visual Basic
Public Readonly Property CollationName As String

// C#
public string CollationName {get;}

Remarks

The database collation sequence affects how indexes on tables and result sets are sorted.


IsCaseSensitive property

Checks whether the database is case sensitive.

Prototypes

' Visual Basic
Public Readonly Property IsCaseSensitive As Boolean

// C#
public bool IsCaseSensitive {get;}

Property value

true if the database is case sensitive, and false if the database is case insensitive.

Remarks

Database case sensitivity affects how indexes on tables and result sets are sorted. Case sensitivity also affects how UserID property and Password property are verified.


IsOpen property

Whether or not the database schema is open.

Prototypes

' Visual Basic
Public Readonly Property IsOpen As Boolean

// C#
public bool IsOpen {get;}

Property value

True if this database schema is currently open.


PublicationCount property

The number of publications in the database.

Prototypes

' Visual Basic
Public Readonly Property PublicationCount As Integer

// C#
public int PublicationCount {get;}

Remarks

Publication IDs range from 1 to PublicationCount, inclusively. Publication IDs are not publication masks. If the database is not open then PublicationCount has the value 0.

Note: Publication IDs, masks, and counts may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached IDs, masks, and counts after a schema upgrade.

See also
  • DatabaseSchema class
  • DatabaseSchema members
  • GetPublicationName method


Signature property

The signature of this database.

Prototypes

' Visual Basic
Public Readonly Property Signature As String

// C#
public string Signature {get;}

Exceptions

  • SQLException class - A SQL error occurred.


TableCount property

The number of tables in the database.

Prototypes

' Visual Basic
Public Readonly Property TableCount As Integer

// C#
public int TableCount {get;}

Remarks

Table IDs range from 1 to TableCount, inclusively. TableCount has the value 0 if the connection is not open.

Note: Table IDs and counts may change during a schema upgrade. To correctly identify a table, access it by name or refresh the cached IDs and counts after a schema upgrade.


ApplyFile method

Applies a database schema file to the database while allowing a listener to monitor the progress.

Prototypes

' Visual Basic
Overloads Public Sub ApplyFile( _
ByVal parms As SchemaParms, _
ByVal listener As SchemaUpgradeListener _
)

// C#
public void ApplyFile(
SchemaParms parms,
SchemaUpgradeListener listener
);

Parameters

  • parms Parameters for specifying the schema to be applied to the database. See SchemaParms class for more information.

  • listener The listener to receive schema upgrade progress events.

Remarks

All instances of TableSchema class, IndexSchema class, and PublicationSchema class will be invalidated and will need to be replaced.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • DatabaseSchema class
  • DatabaseSchema members
  • ApplyFile method
  • SchemaParms class


ApplyFile method

Applies a database schema file to the database.

Prototypes

' Visual Basic
Overloads Public Sub ApplyFile( _
ByVal parms As SchemaParms _
)

// C#
public void ApplyFile(
SchemaParms parms
);

Parameters

  • parms Parameters for specifying the schema to be applied to the database. See SchemaParms class for more information.

Remarks

All instances of TableSchema class, IndexSchema class, and PublicationSchema class will be invalidated and will need to be replaced.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • DatabaseSchema class
  • DatabaseSchema members
  • ApplyFile method
  • SchemaParms class


GetDatabaseProperty method

Returns the value of the specified database property.

Prototypes

' Visual Basic
Public Function GetDatabaseProperty( _
ByVal name As String _
) As String

// C#
public string GetDatabaseProperty(
string name
);

Parameters

  • name Name of the database property.

Return value

Value of the property as a string.

Remarks

Recognized properties are:

  • "DATE_FORMAT" The date format used for string conversions by the database.

    This format is not necessarily the same as the one used by DateTime.

  • "DATE_ORDER" The date order used for string conversions by the database.

  • "NEAREST_CENTURY" The nearest century used for string conversions by the database.

  • "PRECISION" The floating point precision used for string conversions by the database.

  • "SCALE" The minimum number of digits after the decimal point when an arithmetic result is truncated to the maximum PRECISION during string conversions by the database.

  • "TIME_FORMAT" The time format used for string conversions by the database.

    This format is not necessarily the same as the one used by TimeSpan.

  • "TIMESTAMP_FORMAT" The timestamp format used for string conversions by the database.

    This format is not necessarily the same as the one used by DateTime.

  • "TIMESTAMP_INCREMENT" The minimum difference between two unique timestamps, in nanoseconds (1,000,000th of a second).

Exceptions

  • SQLException class - A SQL error occurred.


GetPublicationName method

Returns the name of the publication identified by the specified publication ID. Publication IDs are not publication masks.

Prototypes

' Visual Basic
Public Function GetPublicationName( _
ByVal pubID As Integer _
) As String

// C#
public string GetPublicationName(
int pubID
);

Parameters

  • pubID ID of the publication. pubID must be in the range [1,DatabaseSchema.PublicationCount].

Return value

publication name

Remarks

Note: Publication IDs, masks, and counts may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached IDs, masks, and counts after a schema upgrade.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • DatabaseSchema class
  • DatabaseSchema members
  • PublicationCount property


GetPublicationSchema method

Returns the publication schema corresponding to the named publication.

Prototypes

' Visual Basic
Public Function GetPublicationSchema( _
ByVal name As String _
) As PublicationSchema

// C#
public PublicationSchema GetPublicationSchema(
string name
);

Parameters

  • name name of the publication.

Return value

publication schema of the named publication.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • DatabaseSchema class
  • DatabaseSchema members
  • GetPublicationName method
  • PublicationSchema class


GetTableCountInPublications method

Returns the number of tables included in the specified publication mask.

Prototypes

' Visual Basic
Public Function GetTableCountInPublications( _
ByVal mask As Integer _
) As Integer

// C#
public int GetTableCountInPublications(
int mask
);

Parameters

  • mask set of publications to check.

Return value

number of tables included in set of publications.

Remarks

The count will not include tables whose names end in _nosync.

Note: Publication IDs, masks, and counts may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached IDs, masks, and counts after a schema upgrade.

Exceptions

  • SQLException class - A SQL error occurred.


GetTableName method

Returns the name of the table identified by the specified table ID.

Prototypes

' Visual Basic
Public Function GetTableName( _
ByVal tableID As Integer _
) As String

// C#
public string GetTableName(
int tableID
);

Parameters

  • tableID ID of the table. tableID must be in range [1,TableCount].

Return value

table name

Remarks

Table IDs may change during a schema upgrade. To correctly identify a table, access it by name or refresh the cached IDs after a schema upgrade.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • DatabaseSchema class
  • DatabaseSchema members
  • TableCount property


IndexSchema class

Represents the schema of an UltraLite table index.

Prototypes

' Visual Basic
NotInheritable Public Class IndexSchema

// C#
public sealed class IndexSchema

Remarks

This class cannot be directly instantiated. Index schemas are created using the PrimaryKey property, GetIndex method, and GetOptimalIndex method methods of the TableSchema class class.

IndexSchema members
ColumnCount property
IsForeignKey property
IsForeignKeyCheckOnCommit property
IsForeignKeyNullable property
IsOpen property
IsPrimaryKey property
IsUniqueIndex property
IsUniqueKey property
Name property
ReferencedIndexName property
ReferencedTableName property
Finalize method
GetColumnName method
IsColumnDescending method


IndexSchema members

Public instance properties
Member | Description
ColumnCount property | The number of columns in this index.
IsForeignKey property | Checks whether the index is a foreign key.
IsForeignKeyCheckOnCommit property | Checks whether referential integrity for this foreign key is performed on commits or on inserts and updates.
IsForeignKeyNullable property | Checks whether this foreign key is nullable.
IsOpen property | Determines whether the index schema is open or closed.
IsPrimaryKey property | Checks whether the index is the primary key.
IsUniqueIndex property | Checks whether the index is unique.
IsUniqueKey property | Checks whether the index is a unique key.
Name property | The name of this index.
ReferencedIndexName property | The name of the referenced primary index if this index is a foreign key.
ReferencedTableName property | The name of the referenced primary table if index is a foreign key.
Public instance methods
Member | Description
GetColumnName method | Returns the name of the colIDInIndex'th column in this index.
IsColumnDescending method | Checks whether the named column is used in descending order by this index.
Protected instance methods
Member | Description
Finalize method | Cleans up the associated native object.


ColumnCount property

The number of columns in this index.

Prototypes

' Visual Basic
Public Readonly Property ColumnCount As Short

// C#
public short ColumnCount {get;}

Remarks

Column IDs in indexes range from 1 to ColumnCount, inclusively.

Column IDs and count may change during a schema upgrade. Column IDs from an index are different than the column IDs in a table or another index.


IsForeignKey property

Checks whether the index is a foreign key.

Prototypes

' Visual Basic
Public Readonly Property IsForeignKey As Boolean

// C#
public bool IsForeignKey {get;}

Property value

true if index is the foreign key, false if index is not the foreign key.

Remarks

Columns in a foreign key may reference a non-null unique index of another table.

Exceptions

  • SQLException class - A SQL error occurred.


IsForeignKeyCheckOnCommit property

Checks whether referential integrity for this foreign key is performed on commits or on inserts and updates.

Prototypes

' Visual Basic
Public Readonly Property IsForeignKeyCheckOnCommit As Boolean

// C#
public bool IsForeignKeyCheckOnCommit {get;}

Property value

true if referential integrity is checked on commits, false if it is checked on inserts and updates.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • IndexSchema class
  • IndexSchema members
  • IsForeignKey property


IsForeignKeyNullable property

Checks whether this foreign key is nullable.

Prototypes

' Visual Basic
Public Readonly Property IsForeignKeyNullable As Boolean

// C#
public bool IsForeignKeyNullable {get;}

Property value

true if this foreign key is nullable, false if this foreign key is not nullable.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • IndexSchema class
  • IndexSchema members
  • IsForeignKey property


IsOpen property

Determines whether the index schema is open or closed.

Prototypes

' Visual Basic
Public Readonly Property IsOpen As Boolean

// C#
public bool IsOpen {get;}

Property value

true if the index schema is open, otherwise closed.


IsPrimaryKey property

Checks whether the index is the primary key.

Prototypes

' Visual Basic
Public Readonly Property IsPrimaryKey As Boolean

// C#
public bool IsPrimaryKey {get;}

Property value

true if index is the primary key, false if index is not the primary key.

Remarks

Columns in the primary key may not be null.

Exceptions

  • SQLException class - A SQL error occurred.


IsUniqueIndex property

Checks whether the index is unique.

Prototypes

' Visual Basic
Public Readonly Property IsUniqueIndex As Boolean

// C#
public bool IsUniqueIndex {get;}

Property value

true if index is unique, false if index is not unique.

Remarks

Columns in a unique index may be null.

Exceptions

  • SQLException class - A SQL error occurred.


IsUniqueKey property

Checks whether the index is a unique key.

Prototypes

' Visual Basic
Public Readonly Property IsUniqueKey As Boolean

// C#
public bool IsUniqueKey {get;}

Property value

true if index is a unique key, false if index is not a unique key.

Remarks

Columns in a unique key may not be null.

Exceptions

  • SQLException class - A SQL error occurred.


Name property

The name of this index.

Prototypes

' Visual Basic
Public Readonly Property Name As String

// C#
public string Name {get;}

Exceptions

  • SQLException class - A SQL error occurred.


ReferencedIndexName property

The name of the referenced primary index if this index is a foreign key.

Prototypes

' Visual Basic
Public Readonly Property ReferencedIndexName As String

// C#
public string ReferencedIndexName {get;}

Exceptions

  • SQLException class - A SQL error occurred.


ReferencedTableName property

The name of the referenced primary table if index is a foreign key.

Prototypes

' Visual Basic
Public Readonly Property ReferencedTableName As String

// C#
public string ReferencedTableName {get;}

Exceptions

  • SQLException class - A SQL error occurred.


GetColumnName method

Returns the name of the colIDInIndex'th column in this index.

Prototypes

' Visual Basic
Public Function GetColumnName( _
ByVal colIDInIndex As Short _
) As String

// C#
public string GetColumnName(
short colIDInIndex
);

Parameters

  • colIDInIndex ID in this index of the column. colIDInIndex must be in the range [1,IndexSchema.ColumnCount].

Return value

name of the column.

Remarks

Column IDs and count may change during a schema upgrade. Column IDs from an index are different than the column IDs in a table or another index.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • IndexSchema class
  • IndexSchema members
  • ColumnCount property


IsColumnDescending method

Checks whether the named column is used in descending order by this index.

Prototypes

' Visual Basic
Public Function IsColumnDescending( _
ByVal name As String _
) As Boolean

// C#
public bool IsColumnDescending(
string name
);

Parameters

  • name name of the column.

Return value

true if the column is used in descending order, false if the column is used in ascending order.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • IndexSchema class
  • IndexSchema members
  • ColumnCount property


PreparedStatement class

Represents a pre-compiled SQL statement with or without IN parameters.

Prototypes

' Visual Basic
Public Class PreparedStatement

// C#
public class PreparedStatement

Remarks

This class cannot be directly instantiated. Prepared statements are created using the PrepareStatement method method of the Connection class class. This object can then be used to efficiently execute this statement multiple times.

When a prepared statement is closed, all ResultSet and ResultSetSchema objects associated with it are also closed. PreparedStatement objects are closed when they are garbage collected. However, since all ResultSet and ResultSetSchema objects reference their prepared statement, the prepared statement will not be garbage collected until all its open ResultSet and ResultSetSchema objects are ready for garbage collection.

For resource management reasons, it is recommended that you explicitly close prepared statements when you are done with them.

PreparedStatement members
HasResultSet property
IsOpen property
Plan property
ResultSetSchema property
AppendBytesParameter method
AppendCharsParameter method
Close method
ExecuteQuery method
ExecuteStatement method
Finalize method
SetBoolParameter method
SetBytesParameter method
SetDateTimeParameter method
SetDoubleParameter method
SetFloatParameter method
SetIntParameter method
SetLongParameter method
SetNullParameter method
SetShortParameter method
SetStringParameter method
SetTimeSpanParameter method
SetUIntParameter method
SetULongParameter method
SetUShortParameter method
SetUUIDParameter method


PreparedStatement members

Public instance properties
Member | Description
HasResultSet property | Indicates whether the prepared statement generates a result set or not.
IsOpen property | Checks whether this prepared statement is currently open.
Plan property | Returns the access plan UltraLite will use to execute a query. This property is intended primarily for use during development.
ResultSetSchema property | Holds the schema describing the result set of this query statement.
Public instance methods
Member | Description
AppendBytesParameter method | Appends the specified subset of the specified array of Bytes (byte[] in C#, Byte() in Visual Basic) to the new value for the specified SQLType enumeration parameter.
AppendCharsParameter method | Appends the specified subset of the specified array of System.Chars (char[] in C#, Char() in Visual Basic) to the new value for the specified SQLType enumeration parameter.
Close method | Closes the prepared statement.
ExecuteQuery method | Executes a SQL SELECT statement and returns the result set.
ExecuteStatement method | Executes a statement that does not return a result set, such as a SQL INSERT, DELETE, or UPDATE statement.
SetBoolParameter method | Sets the value for the specified parameter using a Boolean (bool in C#).
SetBytesParameter method | Sets the value for the specified parameter using an array of Bytes (byte[] in C#, Byte() in Visual Basic).
SetDateTimeParameter method | Sets the value for the specified parameter using a DateTime (Date in Visual Basic).
SetDoubleParameter method | Sets the value for the specified parameter using a Double (double in C#).
SetFloatParameter method | Sets the value for the specified parameter using a Single (float in C#).
SetIntParameter method | Sets the value for the specified parameter using an Int32 (long in C#, Long in Visual Basic).
SetLongParameter method | Sets the value for the specified parameter using an Int64.
SetNullParameter method | Sets a parameter to NULL.
SetShortParameter method | Sets the value for the specified parameter using an Int16 (short in C#, Short in Visual Basic).
SetStringParameter method | Sets the value for the specified parameter using a String.
SetTimeSpanParameter method | Sets the value for the specified parameter using a TimeSpan.
SetUIntParameter method | Sets the value for the specified parameter using a UInt32 (uint in C#).
SetULongParameter method | Sets the value for the specified parameter using a UInt64 (ulong in C#).
SetUShortParameter method | Sets the value for the specified parameter using a UInt16 (ushort in C#).
SetUUIDParameter method | Sets the value for the specified parameter using a UUID (Guid).
Protected instance methods
Member | Description
Finalize method | Finalize method


HasResultSet property

Indicates whether the prepared statement generates a result set or not.

Prototypes

' Visual Basic
Public Readonly Property HasResultSet As Boolean

// C#
public bool HasResultSet {get;}

Remarks

True if a result set is generated when this statement is executed, false if no result set is generated.

Exceptions

  • SQLException class - A SQL error occurred.


IsOpen property

Checks whether this prepared statement is currently open.

Prototypes

' Visual Basic
Public Readonly Property IsOpen As Boolean

// C#
public bool IsOpen {get;}

Return value

True if this prepared statement is currently open, false if the prepared statement is closed.


Plan property

Returns the access plan UltraLite will use to execute a query. This property is intended primarily for use during development.

Prototypes

' Visual Basic
Public Readonly Property Plan As String

// C#
public string Plan {get;}

Return value

text-based description of the query execution plan.

Exceptions

  • SQLException class - A SQL error occurred.


ResultSetSchema property

Holds the schema describing the result set of this query statement.

Prototypes

' Visual Basic
Public Readonly Property ResultSetSchema As ResultSetSchema

// C#
public ResultSetSchema ResultSetSchema {get;}

Return value

schema of this statement's result set.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • HasResultSet property
  • ExecuteQuery method


AppendBytesParameter method

Appends the specified subset of the specified array of Bytes (byte[] in C#, Byte() in Visual Basic) to the new value for the specified SQLType enumeration parameter.

Prototypes

' Visual Basic
Public Sub AppendBytesParameter( _
ByVal parameterID As Short, _
ByVal val As Byte(), _
ByVal srcOffset As Integer, _
ByVal count As Integer _
)

// C#
public void AppendBytesParameter(
short parameterID,
byte[] val,
int srcOffset,
int count
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the value to append to the current new value for the parameter.

  • srcOffset start position in the source array.

  • count the number of bytes to be copied.

Remarks

The bytes at position srcOffset (starting from 0) through srcOffset+count-1 of the array val are appended to the value for the specified parameter.

When specifying parameters, the first append to a parameter after an execute clears the current value before appending the new value.

If any of the following are true, a SQLException class with code SQLCode enumeration is thrown and the destination is not modified: For other errors, a SQLException class with the appropriate error code is thrown.

  • val is null.
  • srcOffset is negative.
  • count is negative.
  • srcOffset+count is greater than val.Length.
Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


AppendCharsParameter method

Appends the specified subset of the specified array of System.Chars (char[] in C#, Char() in Visual Basic) to the new value for the specified SQLType enumeration parameter.

Prototypes

' Visual Basic
Public Sub AppendCharsParameter( _
ByVal parameterID As Short, _
ByVal val As Char(), _
ByVal srcOffset As Integer, _
ByVal count As Integer _
)

// C#
public void AppendCharsParameter(
short parameterID,
char[] val,
int srcOffset,
int count
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the value to append to the current value for the parameter.

  • srcOffset start position in the source array.

  • count the number of bytes to be copied.

Remarks

The characters at position srcOffset (starting from 0) through srcOffset+count-1 of the array val are appended to the value for the specified parameter.

When specifying parameters, the first append to a parameter after an execute clears the current value before appending the new value.

If any of the following are true, a SQLException class with code SQLCode enumeration is thrown and the destination is not modified: For other errors, a SQLException class with the appropriate error code is thrown.

  • val is null.
  • srcOffset is negative.
  • count is negative.
  • srcOffset+count is greater than value.Length.
Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


Close method

Closes the prepared statement.

Prototypes

' Visual Basic
Public Sub Close()

// C#
public void Close();

Remarks

When a prepared statement is closed, all ResultSet and ResultSetSchema objects associated with it are also closed.

Exceptions

  • SQLException class - A SQL error occurred.


ExecuteQuery method

Executes a SQL SELECT statement and returns the result set.

Prototypes

' Visual Basic
Public Function ExecuteQuery() As ResultSet

// C#
public ResultSet ExecuteQuery();

Return value

the resulting set of rows from the statement.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • HasResultSet property
  • ExecuteStatement method


ExecuteStatement method

Executes a statement that does not return a result set, such as a SQL INSERT, DELETE, or UPDATE statement.

Prototypes

' Visual Basic
Public Function ExecuteStatement() As Long

// C#
public long ExecuteStatement();

Return value

number of rows affected by the statement.

Remarks

If AutoCommit field is true, the statement will be committed only if one or more rows are affected by the statement.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • HasResultSet property
  • ExecuteQuery method


Web Links Browse Collapse Expand PDF Previous Next

UltraLite.NET User's Guide

iAnywhere.UltraLite namespace

PreparedStatement class

Finalize method

Finalize method

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


SetBoolParameter method

Sets the value for the specified parameter using a Boolean (bool in C#).

Prototypes

' Visual Basic
Public Sub SetBoolParameter( _
ByVal parameterID As Short, _
ByVal val As Boolean _
)

// C#
public void SetBoolParameter(
short parameterID,
bool val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetBytesParameter method

Sets the value for the specified parameter using an array of Bytes (byte[] in C#, Byte() in Visual Basic).

Prototypes

' Visual Basic
Public Sub SetBytesParameter( _
ByVal parameterID As Short, _
ByVal val As Byte() _
)

// C#
public void SetBytesParameter(
short parameterID,
byte[] val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Remarks

Suitable for parameters of type SQLType enumeration or SQLType enumeration only.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetDateTimeParameter method

Sets the value for the specified parameter using a DateTime (Date in Visual Basic).

Prototypes

' Visual Basic
Public Sub SetDateTimeParameter( _
ByVal parameterID As Short, _
ByVal val As Date _
)

// C#
public void SetDateTimeParameter(
short parameterID,
DateTime val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Remarks

The set value is accurate to the millisecond.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetDoubleParameter method

Sets the value for the specified parameter using a Double (double in C#).

Prototypes

' Visual Basic
Public Sub SetDoubleParameter( _
ByVal parameterID As Short, _
ByVal val As Double _
)

// C#
public void SetDoubleParameter(
short parameterID,
double val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetFloatParameter method

Sets the value for the specified parameter using a Single (float in C#).

Prototypes

' Visual Basic
Public Sub SetFloatParameter( _
ByVal parameterID As Short, _
ByVal val As Single _
)

// C#
public void SetFloatParameter(
short parameterID,
float val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetIntParameter method

Sets the value for the specified parameter using an Int32 (long in C#, Long in Visual Basic).

Prototypes

' Visual Basic
Public Sub SetIntParameter( _
ByVal parameterID As Short, _
ByVal val As Integer _
)

// C#
public void SetIntParameter(
short parameterID,
int val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetLongParameter method

Sets the value for the specified parameter using an Int64.

Prototypes

' Visual Basic
Public Sub SetLongParameter( _
ByVal parameterID As Short, _
ByVal val As Long _
)

// C#
public void SetLongParameter(
short parameterID,
long val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetNullParameter method

Sets a parameter to NULL.

Prototypes

' Visual Basic
Public Sub SetNullParameter( _
ByVal parameterID As Short _
)

// C#
public void SetNullParameter(
short parameterID
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetShortParameter method

Sets the value for the specified parameter using an Int16 (short in C#, Short in Visual Basic).

Prototypes

' Visual Basic
Public Sub SetShortParameter( _
ByVal parameterID As Short, _
ByVal val As Short _
)

// C#
public void SetShortParameter(
short parameterID,
short val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetStringParameter method

Sets the value for the specified parameter using a String.

Prototypes

' Visual Basic
Public Sub SetStringParameter( _
ByVal parameterID As Short, _
ByVal val As String _
)

// C#
public void SetStringParameter(
short parameterID,
string val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetTimeSpanParameter method

Sets the value for the specified parameter using a TimeSpan.

Prototypes

' Visual Basic
Public Sub SetTimeSpanParameter( _
ByVal parameterID As Short, _
ByVal val As TimeSpan _
)

// C#
public void SetTimeSpanParameter(
short parameterID,
TimeSpan val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Remarks

The set value is accurate to the millisecond and is normalized to a nonnegative value between 0 and 24 hours.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetUIntParameter method

Sets the value for the specified parameter using a UInt32 (uint in C#).

Prototypes

' Visual Basic
Public Sub SetUIntParameter( _
ByVal parameterID As Short, _
ByVal val As UInt32 _
)

// C#
public void SetUIntParameter(
short parameterID,
uint val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetULongParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetULongParameter method

Sets the value for the specified parameter using a UInt64 (ulong in C#).

Prototypes

' Visual Basic
Public Sub SetULongParameter( _
ByVal parameterID As Short, _
ByVal val As UInt64 _
)

// C#
public void SetULongParameter(
short parameterID,
ulong val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetUShortParameter method
  • SetUUIDParameter method


SetUShortParameter method

Sets the value for the specified parameter using a UInt16 (ushort in C#).

Prototypes

' Visual Basic
Public Sub SetUShortParameter( _
ByVal parameterID As Short, _
ByVal val As UInt16 _
)

// C#
public void SetUShortParameter(
short parameterID,
ushort val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetStringParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUUIDParameter method


SetUUIDParameter method

Sets the value for the specified parameter using a UUID (Guid).

Prototypes

' Visual Basic
Public Sub SetUUIDParameter( _
ByVal parameterID As Short, _
ByVal val As Guid _
)

// C#
public void SetUUIDParameter(
short parameterID,
Guid val
);

Parameters

  • parameterID the ID number of the parameter. The first parameter in the statement has an ID value of one.

  • val the new value for the parameter.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • PreparedStatement class
  • PreparedStatement members
  • GetNewUUID method
  • SetNullParameter method
  • AppendBytesParameter method
  • AppendCharsParameter method
  • SetBytesParameter method
  • SetBoolParameter method
  • SetDoubleParameter method
  • SetFloatParameter method
  • SetIntParameter method
  • SetLongParameter method
  • SetShortParameter method
  • SetTimeSpanParameter method
  • SetDateTimeParameter method
  • SetUIntParameter method
  • SetULongParameter method
  • SetUShortParameter method


PublicationSchema class

Represents the schema of an UltraLite publication.

Prototypes

' Visual Basic
NotInheritable Public Class PublicationSchema

// C#
public sealed class PublicationSchema

Remarks

This class cannot be directly instantiated. Publication schemas are created using the GetPublicationSchema method method of the DatabaseSchema class class.

UltraLite methods requiring a publication mask actually require a set of publications to check. A set is formed by or'ing the publication masks of individual publications. For example:

pub1.Mask | pub2.Mask

Two special mask values are also provided by this class. SYNC_ALL_DB field corresponds to the entire database. SYNC_ALL_PUBS field corresponds to all publications.

Note: Publication masks may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached masks after a schema upgrade.

See also
  • PublicationSchema members
  • Mask property
  • GetLastDownloadTime method
  • CountUploadRows method
  • Schema property


PublicationSchema members

Public static fields (Shared)
Member | Description
SYNC_ALL_DB field | Publication mask corresponding to the entire database.
SYNC_ALL_PUBS field | Publication mask corresponding to all publications.
Public instance properties
Member | Description
IsOpen property | Determines whether the publication schema is open or closed.
Mask property | The publication mask of this publication.
Name property | The name of this publication.


IsOpen property

Determines whether the publication schema is open or closed.

Prototypes

' Visual Basic
Public Readonly Property IsOpen As Boolean

// C#
public bool IsOpen {get;}

Property value

True if the publication schema is open, otherwise closed.


Mask property

The publication mask of this publication.

Prototypes

' Visual Basic
Public Readonly Property Mask As Integer

// C#
public int Mask {get;}

Remarks

Publication IDs, masks, and counts may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached masks, and counts after a schema upgrade.

Exceptions

  • SQLException class - If a SQL error exception occurs. PUBLICATION_NOT_FOUND is issued if a schema upgrade has deleted or renamed this publication.


Name property

The name of this publication.

Prototypes

' Visual Basic
Public Readonly Property Name As String

// C#
public string Name {get;}

Exceptions

  • SQLException class - A SQL error occurred. PUBLICATION_NOT_FOUND is issued if a schema upgrade has deleted or renamed this publication.


ResultSet class

Represents a result set in an UltraLite database. Created at runtime using ExecuteQuery method.

Prototypes

' Visual Basic
Public Class ResultSet
Inherits Cursor

// C#
public class ResultSet :
Cursor

Remarks

This class cannot be directly instantiated. Result sets are created using the ExecuteQuery method method of the PreparedStatement class class.

A result set is only valid while the prepared statement is open.


ResultSet members

Public instance properties
Member | Description
IsBOF property (inherited from Cursor) | Returns true if the current row position is before the first row.
IsEOF property (inherited from Cursor) | Returns true if the current row position is after the last row.
IsOpen property (inherited from Cursor) | Checks whether this cursor is currently open.
RowCount property (inherited from Cursor) | Returns the number of rows in the cursor.
Schema property | Holds the schema of this result set. This property is only valid while its prepared statement is open.
Public instance methods
Member | Description
Close method | Closes the result set.
Fill method (inherited from Cursor) | Fills a ADO .NET DataTable object with the rows in the cursor.
GetBoolean method (inherited from Cursor) | Returns the value for the specified column as a Boolean.
GetBytes method (inherited from Cursor) | Returns the value for the specified column as an array of Bytes. Only valid for columns of type SQLType enumeration, SQLType enumeration, or SQLType enumeration.
GetBytes method (inherited from Cursor) | Copies a subset of the value for the specified SQLType enumeration column, beginning at the specified offset, to the specified offset of the destination Byte array.
GetChars method (inherited from Cursor) | Copies a subset of the value for the specified SQLType enumeration column, beginning at the specified offset, to the specified offset of the destination System.Char array.
GetDouble method (inherited from Cursor) | Returns the value for the specified column as a Double.
GetFloat method (inherited from Cursor) | Returns the value for the specified column as a Single.
GetInt method (inherited from Cursor) | Returns the value for the specified column as an Int32.
GetLong method (inherited from Cursor) | Returns the value for the specified column as an Int64.
GetShort method (inherited from Cursor) | Returns the value for the specified column as an Int16.
GetString method (inherited from Cursor) | Returns the value for the specified column as a String.
GetTime method (inherited from Cursor) | Returns the value for the specified column as a TimeSpan with millisecond accuracy.
GetTimestamp method (inherited from Cursor) | Returns the value for the specified column as a DateTime with millisecond accuracy.
GetUInt method (inherited from Cursor) | Returns the value for the specified column as a UInt32.
GetULong method (inherited from Cursor) | Returns the value for the specified column as a UInt64.
GetUShort method (inherited from Cursor) | Returns the value for the specified column as a UInt16.
GetUUID method (inherited from Cursor) | Returns the value for the specified column as a UUID (Guid).
IsNull method (inherited from Cursor) | Checks whether the value from the specified column is NULL.
MoveAfterLast method (inherited from Cursor) | Position to after the last row of the cursor.
MoveBeforeFirst method (inherited from Cursor) | Position to before the first row of the cursor.
MoveFirst method (inherited from Cursor) | Position to the first row of the cursor.
MoveLast method (inherited from Cursor) | Position to the last row of the cursor.
MoveNext method (inherited from Cursor) | Position to the next row or after last.
MovePrevious method (inherited from Cursor) | Position to the previous row or before first.
MoveRelative method (inherited from Cursor) | Position relative to the current row.
Protected instance methods
Member | Description
Finalize method | Finalize method


Schema property

Holds the schema of this result set. This property is only valid while its prepared statement is open.

Prototypes

' Visual Basic
Public Readonly Property Schema As ResultSetSchema

// C#
public ResultSetSchema Schema {get;}

See also
  • ResultSet class
  • ResultSet members
  • ResultSetSchema class


Close method

Closes the result set.

Prototypes

' Visual Basic
NotOverridable Public Sub Close()

// C#
public void Close();

Remarks

It is not an error to close a result set that is already closed.

Exceptions

  • SQLException class - A SQL error occurred.


ResultSetSchema class

Represents the schema of an UltraLite result set.

Prototypes

' Visual Basic
NotInheritable Public Class ResultSetSchema
Inherits CursorSchema

// C#
public sealed class ResultSetSchema :
CursorSchema

Remarks

This class cannot be directly instantiated. A ResultSetSchema class object is attached to a result set as its Schema property property. A result set schema is also attached to a prepared statement as its ResultSetSchema property property if the prepared statement represents a query (when the prepared statement's HasResultSet property property is true).

A result set schema is only valid while the prepared statement is open.

See also
  • ResultSetSchema members
  • PreparedStatement class
  • ResultSet class


ResultSetSchema members

Public instance properties
Member | Description
ColumnCount property (inherited from CursorSchema) | Returns the number of columns in this cursor.
IsOpen property (inherited from CursorSchema) | Checks whether this cursor schema is currently open.
Name property | The name of this cursor.
Public instance methods
Member | Description
GetColumnID method (inherited from CursorSchema) | Returns the column ID of the named column.
GetColumnName method (inherited from CursorSchema) | Returns the name of column identified by the specified column ID.
GetColumnPrecision method (inherited from CursorSchema) | Returns the precision of the named column if the column is a numeric column (SQL type NUMERIC).
GetColumnScale method (inherited from CursorSchema) | Returns the scale of the named column if the column is a numeric column (SQL type NUMERIC).
GetColumnSize method (inherited from CursorSchema) | Returns the size of the named column if the column is a sized column (SQL type BINARY or CHAR).
GetColumnSQLType method (inherited from CursorSchema) | Gets the SQL data type of the named column.
Protected instance methods
Member | Description
Finalize method | Destructor which cleans up the associated native object.


Name property

The name of this cursor.

Prototypes

' Visual Basic
Public Readonly Property Name As String

// C#
public string Name {get;}

Return value

Sql statement that generated this ResultSetSchema.


Finalize method

Destructor which cleans up the associated native object.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


RuntimeType enumeration

Enumerates the types of UltraLite.NET runtimes.

Prototypes

' Visual Basic
Public Enum RuntimeType

// C#
public enum RuntimeType

Members
Member | Description
STANDALONE_UL | Selects the standalone UltraLite.NET runtime. The standalone runtime accesses databases directly. Databases are accessed more quickly but cannot be shared.
UL_ENGINE_CLIENT | Selects to use the UltraLite engine. The UltraLite.NET engine client communicates with the UltraLite engine to access databases. This means that databases can be shared by different applications.
See also
  • DatabaseManager constructor


SchemaParms class

Specifies the schema for an UltraLite database.

Prototypes

' Visual Basic
NotInheritable Public Class SchemaParms
Inherits Component

// C#
public sealed class SchemaParms :
Component

Remarks

Each instance contains platform-specific and generic paths to a schema file. Only one file value is used with the platform-specific keyword taking precedence over the generic keyword. For example, with schemaParms.SchemaOnCE="\\s1.usm"; and schemaParms.SchemaOnDesktop="s2.usm";, the path \s1.usm would be used on Windows CE while s2.usm would be used on other platforms.

After an instance is passed to an UltraLite method, the property ParmsUsed returns the parameters actually used by the UltraLite method.

The recommended extension for UltraLite schema files is .usm. You must escape any backslash characters in paths.

SchemaParms members
SchemaParms constructor
SchemaParms constructor
AdditionalParms property
ParmsUsed property
SchemaOnCE property
SchemaOnDesktop property
Finalize method
ToString method


SchemaParms members

Public instance constructors
Member | Description
SchemaParms constructor | Initializes a SchemaParms instance with its default values.
SchemaParms constructor | Initializes a SchemaParms instance with the specified values.
Public instance properties
Member | Description
AdditionalParms property | Specifies additional parameters as a semicolon-separated list of name=value pairs. This is reserved for future use.
ParmsUsed property | Returns the parameters actually used by the last DatabaseSchema method to use this instance.
SchemaOnCE property | Specifies the path and filename of the UltraLite schema on Windows CE.
SchemaOnDesktop property | Specifies the path and filename of the UltraLite schema on Windows desktop platforms.
Public instance methods
Member | Description
ToString method | Returns the string representation of this instance.
Protected instance methods
Member | Description
Finalize method | Cleans up the associated native object.


SchemaParms constructor

Initializes a SchemaParms instance with its default values.

Prototypes

' Visual Basic
Overloads Public Sub New()

// C#
public SchemaParms();

Exceptions

  • SQLException class - A SQL error occurred.


SchemaParms constructor

Initializes a SchemaParms instance with the specified values.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal schemaOnCE As String, _
ByVal schemaOnDesktop As String, _
ByVal additionalParms As String _
)

// C#
public SchemaParms(
string schemaOnCE,
string schemaOnDesktop,
string additionalParms
);

Parameters

  • schemaOnCE value for SchemaOnCE property.

  • schemaOnDesktop value for SchemaOnDesktop property.

  • additionalParms value for AdditionalParms property.

Exceptions

  • SQLException class - A SQL error occurred.


AdditionalParms property

Specifies additional parameters as a semicolon-separated list of name=value pairs. This is reserved for future use.

Prototypes

' Visual Basic
Public Property AdditionalParms As String

// C#
public string AdditionalParms {get;set;}


ParmsUsed property

Returns the parameters actually used by the last DatabaseSchema method to use this instance.

Prototypes

' Visual Basic
Public Readonly Property ParmsUsed As String

// C#
public string ParmsUsed {get;}

See also
  • SchemaParms class
  • SchemaParms members
  • ApplyFile method


SchemaOnCE property

Specifies the path and filename of the UltraLite schema on Windows CE.

Prototypes

' Visual Basic
Public Property SchemaOnCE As String

// C#
public string SchemaOnCE {get;set;}


SchemaOnDesktop property

Specifies the path and filename of the UltraLite schema on Windows desktop platforms.

Prototypes

' Visual Basic
Public Property SchemaOnDesktop As String

// C#
public string SchemaOnDesktop {get;set;}


SchemaUpgradeData class

Returns schema upgrade monitoring data.

Prototypes

' Visual Basic
Public Class SchemaUpgradeData

// C#
public class SchemaUpgradeData

See also
  • SchemaUpgradeData members
  • SchemaUpgradeListener interface


SchemaUpgradeData members

Public instance properties
Member | Description
FinalProgressCount property | Estimate of the final progress count.
ProgressCounter property | The schema upgrade progress counter. This number is an approximation of the progess so far.
State property | The current schema upgrade state.
UpgradeOperations property | Number of schema upgrade operations performed.


FinalProgressCount property

Estimate of the final progress count.

Prototypes

' Visual Basic
Public Readonly Property FinalProgressCount As Long

// C#
public long FinalProgressCount {get;}

Return value

estimated final progress count.

See also
  • SchemaUpgradeData class
  • SchemaUpgradeData members
  • SchemaUpgradeState enumeration
  • ProgressCounter property


ProgressCounter property

The schema upgrade progress counter. This number is an approximation of the progess so far.

Prototypes

' Visual Basic
Public Readonly Property ProgressCounter As Long

// C#
public long ProgressCounter {get;}

Return value

schema upgrade progress counter as a number between 0 and FinalProgressCount property.

See also
  • SchemaUpgradeData class
  • SchemaUpgradeData members
  • SchemaUpgradeState enumeration


State property

The current schema upgrade state.

Prototypes

' Visual Basic
Public Readonly Property State As SchemaUpgradeState

// C#
public SchemaUpgradeState State {get;}

See also
  • SchemaUpgradeData class
  • SchemaUpgradeData members
  • SchemaUpgradeState enumeration


UpgradeOperations property

Number of schema upgrade operations performed.

Prototypes

' Visual Basic
Public Readonly Property UpgradeOperations As Long

// C#
public long UpgradeOperations {get;}

Remarks

This number is an approximation of the amount of work done during the schema upgrade. This number starts at zero and increases as the update proceeds. This number is updated more frequently than the progress counter and can be used as a relative measure to compare against other schema upgrades.

See also
  • SchemaUpgradeData class
  • SchemaUpgradeData members
  • SchemaUpgradeState enumeration


SchemaUpgradeListener interface

The listener interface for receiving schema upgrade progress events.

Prototypes

' Visual Basic
Public Interface SchemaUpgradeListener

// C#
public interface SchemaUpgradeListener

See also
  • SchemaUpgradeListener members
  • ApplyFile method


SchemaUpgradeListener members

Public instance methods
Member | Description
SchemaUpgrading method | Invoked during schema upgrade to inform the user of progress. When the state is SchemaUpgradeState enumeration, this method should return true to cancel the schema upgrade or return false to continue. For other states, this method's return value is ignored.


SchemaUpgrading method

Invoked during schema upgrade to inform the user of progress. When the state is SchemaUpgradeState enumeration, this method should return true to cancel the schema upgrade or return false to continue. For other states, this method's return value is ignored.

Prototypes

' Visual Basic
Public Function SchemaUpgrading( _
ByVal data As SchemaUpgradeData _
) As Boolean

// C#
public bool SchemaUpgrading(
SchemaUpgradeData data
);

Parameters

  • data object containing the latest schema upgrade progress data.

Return value

This method should return false to continue or true to cancel the schema upgrade (state must be SchemaUpgradeState enumeration to cancel).

Remarks

No UltraLite.NET API methods should be invoked during a SchemaUpgrading call.


SchemaUpgradeState enumeration

Enumerates all the states that can occur while upgrading a schema.

Prototypes

' Visual Basic
Public Enum SchemaUpgradeState

// C#
public enum SchemaUpgradeState

Remarks

STATE_STARTING is the only state during which the upgrade may be cancelled. If the upgrade is cancelled, you will receive a second event with state STATE_ERROR.

Members
Member | Description
STATE_ABORT | The schema upgrade has been aborted and the old database is preserved. This state may occur as the result of a recoverable error or user abort.
STATE_DONE | The schema upgrade completed successfully.
STATE_ERROR | A critial error occured and the database is unusable.
STATE_LAST | Internally used state not sent to SchemaUpgrading method.
STATE_STARTING | The schema upgrade is starting. This is the only state during which the upgrade may be cancelled. If the upgrade is cancelled, you will receive a second event with state STATE_ABORT.
STATE_UPGRADING | The schema upgrade is in progress.
See also
  • State property
  • ProgressCounter property
  • FinalProgressCount property
  • UpgradeOperations property


ServerSyncListener interface

The listener interface for receiving server synchronization messages.

Prototypes

' Visual Basic
Public Interface ServerSyncListener

// C#
public interface ServerSyncListener


ServerSyncListener members

Public instance methods
Member | Description
ServerSyncInvoked method | Invoked when the MobiLink Listener for server-initiated synchronizations calls the application to perform synchronization.


ServerSyncInvoked method

Invoked when the MobiLink Listener for server-initiated synchronizations calls the application to perform synchronization.

Prototypes

' Visual Basic
Public Sub ServerSyncInvoked( _
ByVal messageName As String _
)

// C#
public void ServerSyncInvoked(
string messageName
);

Parameters

  • messageName name of the message sent to the application.

Remarks

This method is invoked by a separate thread. To avoid multi-threading issues, it should post an event to the UI. If you are using multi-threading, it is recommended that you use a separate connection and use the lock keyword to access any objects shared with the rest of the application.

Example

The following code fragments demonstrate how to receive a server synchronization request and perform a synchronization in the UI thread.

            [Visual Basic]
            Imports iAnywhere.UltraLite

            Public Class MainWindow
              Inherits System.Windows.Forms.Form
              Implements ServerSyncListener
              Private dbMgr As DatabaseManager
              Private conn As Connection

              Public Sub New(ByVal args() As String)

                MyBase.New()

                'This call is required by the Windows Form Designer.
                InitializeComponent()

                'Add any initialization after the InitializeComponent() call
                dbMgr = New DatabaseManager
                dbMgr.SetServerSyncListener( "myCompany.mymsg", "myCompany.myapp", Me )
                'Create Connection
                ...
              End Sub

              Protected Overrides Sub OnClosing(ByVal e As System.ComponentModel.CancelEventArgs)
                If Not (dbMgr Is Nothing) Then
                  dbMgr.SetServerSyncListener(Nothing, Nothing, Nothing)
                  dbMgr = Nothing
                End If
              End Sub

              Public Sub ServerSyncInvoked(ByVal messageName As String) Implements iAnywhere.UltraLite.ServerSyncListener.ServerSyncInvoked
                Me.Invoke(New EventHandler(AddressOf Me.ServerSyncAction))
              End Sub

              Public Sub ServerSyncAction(ByVal sender As Object, ByVal e As EventArgs)
                ' Do Server sync
                conn.Synchronize()
              End Sub
            End Class

            [C#]
            using iAnywhere.UltraLite;
            public class Form1 : System.Windows.Forms.Form, ServerSyncListener
            {
              private System.Windows.Forms.MainMenu mainMenu1;
              private DatabaseManager dbMgr;
              private Connection conn;

              public Form1()
              {
                //
                // Required for Windows Form Designer support
                //
                InitializeComponent();

                //
                // TODO: Add any constructor code after InitializeComponent call
                //
                dbMgr = new DatabaseManager();
                dbMgr.SetServerSyncListener( "myCompnay.mymsg", "myCompany.myapp", this );
                // Create connection
                ...
              }

              protected override void Dispose( bool disposing )
              {
                base.Dispose( disposing );
              }

              protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
              {
                if( dbMgr != null ) {
                  dbMgr.SetServerSyncListener( null, null, null );
                  dbMgr = null;
                }
                base.OnClosing (e);
              }

              public void ServerSyncInvoked( string messageName )
              {
                this.Invoke( new EventHandler( ServerSyncHandler ) );
              }

              internal void ServerSyncHandler(object sender, EventArgs e)
              {
                conn.Synchronize();
              }
            }


SQLCode enumeration

Enumerates the SQL codes that may be reported by UltraLite.NET.

Prototypes

' Visual Basic
Public Enum SQLCode

// C#
public enum SQLCode

Members
Member | Description
SQLE_AGGREGATES_NOT_ALLOWED | SQLE_AGGREGATES_NOT_ALLOWED(-150)
SQLE_ALIAS_NOT_UNIQUE | SQLE_ALIAS_NOT_UNIQUE(-830)
SQLE_ALIAS_NOT_YET_DEFINED | SQLE_ALIAS_NOT_YET_DEFINED(-831)
SQLE_AMBIGUOUS_INDEX_NAME | SQLE_AMBIGUOUS_INDEX_NAME(-678)
SQLE_ARGUMENT_CANNOT_BE_NULL | SQLE_ARGUMENT_CANNOT_BE_NULL(-90)
SQLE_BAD_ENCRYPTION_KEY | SQLE_BAD_ENCRYPTION_KEY(-840)
SQLE_BAD_PARAM_INDEX | SQLE_BAD_PARAM_INDEX(-689)
SQLE_CANNOT_ACCESS_FILE | SQLE_CANNOT_ACCESS_FILE(-602)
SQLE_CANNOT_ACCESS_SCHEMA_FILE | SQLE_CANNOT_ACCESS_SCHEMA_FILE(-951)
SQLE_CANNOT_CHANGE_USER_NAME | SQLE_CANNOT_CHANGE_USER_NAME(-867)
SQLE_CANNOT_EXECUTE_STMT | SQLE_CANNOT_EXECUTE_STMT(111)
SQLE_CANNOT_MODIFY | SQLE_CANNOT_MODIFY(-191)
SQLE_CANNOT_REGISTER_LISTENER | SQLE_CANNOT_REGISTER_LISTENER(-992)
SQLE_COLUMN_AMBIGUOUS | SQLE_COLUMN_AMBIGUOUS(-144)
SQLE_COLUMN_CANNOT_BE_NULL | SQLE_COLUMN_CANNOT_BE_NULL(-195)
SQLE_COLUMN_IN_INDEX | SQLE_COLUMN_IN_INDEX(-127)
SQLE_COLUMN_NOT_FOUND | SQLE_COLUMN_NOT_FOUND(-143)
SQLE_COLUMN_NOT_FOUND_IN_TABLE | SQLE_COLUMN_NOT_FOUND_IN_TABLE(-834)
SQLE_COMMUNICATIONS_ERROR | SQLE_COMMUNICATIONS_ERROR(-85)
SQLE_CONNECTION_ALREADY_EXISTS | SQLE_CONNECTION_ALREADY_EXISTS(-955)
SQLE_CONNECTION_NOT_FOUND | SQLE_CONNECTION_NOT_FOUND(-108)
SQLE_CONNECTION_RESTORED | SQLE_CONNECTION_RESTORED(133)
SQLE_CONVERSION_ERROR | SQLE_CONVERSION_ERROR(-157)
SQLE_CORRELATION_NAME_NOT_FOUND | SQLE_CORRELATION_NAME_NOT_FOUND(-142)
SQLE_COULD_NOT_FIND_FUNCTION | SQLE_COULD_NOT_FIND_FUNCTION(-621)
SQLE_COULD_NOT_LOAD_LIBRARY | SQLE_COULD_NOT_LOAD_LIBRARY(-620)
SQLE_CURSOR_ALREADY_OPEN | SQLE_CURSOR_ALREADY_OPEN(-172)
SQLE_CURSOR_NOT_OPEN | SQLE_CURSOR_NOT_OPEN(-180)
SQLE_CURSOR_RESTORED | SQLE_CURSOR_RESTORED(134)
SQLE_CURSOROP_NOT_ALLOWED | SQLE_CURSOROP_NOT_ALLOWED(-187)
SQLE_DATABASE_CREATED | SQLE_DATABASE_CREATED(136)
SQLE_DATABASE_ERROR | SQLE_DATABASE_ERROR(-301)
SQLE_DATABASE_NAME_REQUIRED | SQLE_DATABASE_NAME_REQUIRED(-87)
SQLE_DATABASE_NEW | SQLE_DATABASE_NEW(123)
SQLE_DATABASE_NOT_CREATED | SQLE_DATABASE_NOT_CREATED(-645)
SQLE_DATABASE_UPGRADE_NOT_POSSIBLE | SQLE_DATABASE_UPGRADE_NOT_POSSIBLE(-673)
SQLE_DATATYPE_NOT_ALLOWED | SQLE_DATATYPE_NOT_ALLOWED(-624)
SQLE_DBSPACE_FULL | SQLE_DBSPACE_FULL(-604)
SQLE_DEVICE_IO_FAILED | SQLE_DEVICE_IO_FAILED(-974)
SQLE_DIV_ZERO_ERROR | SQLE_DIV_ZERO_ERROR(-628)
SQLE_DOWNLOAD_CONFLICT | SQLE_DOWNLOAD_CONFLICT(-839)
SQLE_DROP_DATABASE_FAILED | SQLE_DROP_DATABASE_FAILED(-651)
SQLE_DYNAMIC_MEMORY_EXHAUSTED | SQLE_DYNAMIC_MEMORY_EXHAUSTED(-78)
SQLE_ENGINE_ALREADY_RUNNING | SQLE_ENGINE_ALREADY_RUNNING(-96)
SQLE_ENGINE_NOT_MULTIUSER | SQLE_ENGINE_NOT_MULTIUSER(-89)
SQLE_ERROR | SQLE_ERROR(-300)
SQLE_ERROR_CALLING_FUNCTION | SQLE_ERROR_CALLING_FUNCTION(-622)
SQLE_EXPRESSION_ERROR | SQLE_EXPRESSION_ERROR(-156)
SQLE_FOREIGN_KEY_NAME_NOT_FOUND | SQLE_FOREIGN_KEY_NAME_NOT_FOUND(-145)
SQLE_IDENTIFIER_TOO_LONG | SQLE_IDENTIFIER_TOO_LONG(-250)
SQLE_INCORRECT_VOLUME_ID | SQLE_INCORRECT_VOLUME_ID(-975)
SQLE_INDEX_NAME_NOT_UNIQUE | SQLE_INDEX_NAME_NOT_UNIQUE(-111)
SQLE_INDEX_NOT_FOUND | SQLE_INDEX_NOT_FOUND(-183)
SQLE_INDEX_NOT_UNIQUE | SQLE_INDEX_NOT_UNIQUE(-196)
SQLE_INTERRUPTED | SQLE_INTERRUPTED(-299)
SQLE_INVALID_DATABASE | SQLE_INVALID_DATABASE(-84)
SQLE_INVALID_FOREIGN_KEY | SQLE_INVALID_FOREIGN_KEY(-194)
SQLE_INVALID_FOREIGN_KEY_DEF | SQLE_INVALID_FOREIGN_KEY_DEF(-113)
SQLE_INVALID_GROUP_SELECT | SQLE_INVALID_GROUP_SELECT(-149)
SQLE_INVALID_LOGON | SQLE_INVALID_LOGON(-103)
SQLE_INVALID_OPTION_SETTING | SQLE_INVALID_OPTION_SETTING(-201)
SQLE_INVALID_ORDER | SQLE_INVALID_ORDER(-152)
SQLE_INVALID_PARAMETER | SQLE_INVALID_PARAMETER(-735)
SQLE_INVALID_PARSE_PARAMETER | SQLE_INVALID_PARSE_PARAMETER(-95)
SQLE_INVALID_SQL_IDENTIFIER | SQLE_INVALID_SQL_IDENTIFIER(-760)
SQLE_LOCKED | SQLE_LOCKED(-210)
SQLE_MEMORY_ERROR | SQLE_MEMORY_ERROR(-309)
SQLE_METHOD_CANNOT_BE_CALLED | SQLE_METHOD_CANNOT_BE_CALLED(-669)
SQLE_NAME_NOT_UNIQUE | SQLE_NAME_NOT_UNIQUE(-110)
SQLE_NO_COLUMN_NAME | SQLE_NO_COLUMN_NAME(-163)
SQLE_NO_CURRENT_ROW | SQLE_NO_CURRENT_ROW(-197)
SQLE_NO_INDICATOR | SQLE_NO_INDICATOR(-181)
SQLE_NO_MATCHING_SELECT_ITEM | SQLE_NO_MATCHING_SELECT_ITEM(-812)
SQLE_NO_PRIMARY_KEY | SQLE_NO_PRIMARY_KEY(-118)
SQLE_NOERROR | SQLE_NOERROR(0)
SQLE_NOT_IMPLEMENTED | SQLE_NOT_IMPLEMENTED(-134)
SQLE_NOT_SUPPORTED_IN_ULTRALITE | SQLE_NOT_SUPPORTED_IN_ULTRALITE(-749)
SQLE_NOTFOUND | SQLE_NOTFOUND(100)
SQLE_OVERFLOW_ERROR | SQLE_OVERFLOW_ERROR(-158)
SQLE_PAGE_SIZE_INVALID | SQLE_PAGE_SIZE_INVALID(-644)
SQLE_PERMISSION_DENIED | SQLE_PERMISSION_DENIED(-121)
SQLE_PRIMARY_KEY_NOT_UNIQUE | SQLE_PRIMARY_KEY_NOT_UNIQUE(-193)
SQLE_PRIMARY_KEY_TWICE | SQLE_PRIMARY_KEY_TWICE(-126)
SQLE_PRIMARY_KEY_VALUE_REF | SQLE_PRIMARY_KEY_VALUE_REF(-198)
SQLE_PUBLICATION_NOT_FOUND | SQLE_PUBLICATION_NOT_FOUND(-280)
SQLE_RESOURCE_GOVERNOR_EXCEEDED | SQLE_RESOURCE_GOVERNOR_EXCEEDED(-685)
SQLE_ROW_DELETED_TO_MAINTAIN_REFERENTIAL_INTEGRITY | SQLE_ROW_DELETED_TO_MAINTAIN_REFERENTIAL_INTEGRITY(137)
SQLE_ROW_DROPPED_DURING_SCHEMA_UPGRADE | SQLE_ROW_DROPPED_DURING_SCHEMA_UPGRADE(130)
SQLE_SCHEMA_UPGRADE_NOT_ALLOWED | SQLE_SCHEMA_UPGRADE_NOT_ALLOWED(-953)
SQLE_SERVER_SYNCHRONIZATION_ERROR | SQLE_SERVER_SYNCHRONIZATION_ERROR(-857)
SQLE_START_STOP_DATABASE_DENIED | SQLE_START_STOP_DATABASE_DENIED(-75)
SQLE_STRING_RIGHT_TRUNCATION | SQLE_STRING_RIGHT_TRUNCATION(-638)
SQLE_SUBQUERY_SELECT_LIST | SQLE_SUBQUERY_SELECT_LIST(-151)
SQLE_SYNC_INFO_INVALID | SQLE_SYNC_INFO_INVALID(-956)
SQLE_SYNC_STATUS_UNKNOWN | SQLE_SYNC_STATUS_UNKNOWN(-952)
SQLE_SYNCHRONIZATION_NOT_FOUND | SQLE_SYNCHRONIZATION_NOT_FOUND(-767)
SQLE_SYNTAX_ERROR | SQLE_SYNTAX_ERROR(-131)
SQLE_TABLE_HAS_PUBLICATIONS | SQLE_TABLE_HAS_PUBLICATIONS(-281)
SQLE_TABLE_IN_USE | SQLE_TABLE_IN_USE(-214)
SQLE_TABLE_NOT_FOUND | SQLE_TABLE_NOT_FOUND(-141)
SQLE_TOO_MANY_CONNECTIONS | SQLE_TOO_MANY_CONNECTIONS(-102)
SQLE_TOO_MANY_TEMP_TABLES | SQLE_TOO_MANY_TEMP_TABLES(-817)
SQLE_ULTRALITE_DATABASE_NOT_FOUND | SQLE_ULTRALITE_DATABASE_NOT_FOUND(-954)
SQLE_ULTRALITE_OBJ_CLOSED | SQLE_ULTRALITE_OBJ_CLOSED(-908)
SQLE_ULTRALITE_RUNTIME_LIBRARY_MISMATCH | SQLE_ULTRALITE_RUNTIME_LIBRARY_MISMATCH(-977)
SQLE_UNABLE_TO_CONNECT | SQLE_UNABLE_TO_CONNECT(-105)
SQLE_UNABLE_TO_START_DATABASE | SQLE_UNABLE_TO_START_DATABASE(-82)
SQLE_UNABLE_TO_START_DATABASE_VER_NEWER | SQLE_UNABLE_TO_START_DATABASE_VER_NEWER(-934)
SQLE_UNCOMMITTED_TRANSACTIONS | SQLE_UNCOMMITTED_TRANSACTIONS(-755)
SQLE_UNKNOWN_FUNC | SQLE_UNKNOWN_FUNC(-148)
SQLE_UNKNOWN_USERID | SQLE_UNKNOWN_USERID(-140)
SQLE_UNRECOGNIZED_OPTION | SQLE_UNRECOGNIZED_OPTION(-1002)
SQLE_UNSUPPORTED_CHARACTER_SET_ERROR | SQLE_UNSUPPORTED_CHARACTER_SET_ERROR(-869)
SQLE_UPLOAD_FAILED_AT_SERVER | SQLE_UPLOAD_FAILED_AT_SERVER(-794)
SQLE_WRONG_NUM_OF_INSERT_COLS | SQLE_WRONG_NUM_OF_INSERT_COLS(-207)
SQLE_WRONG_PARAMETER_COUNT | SQLE_WRONG_PARAMETER_COUNT(-154)


SQLException class

Represents a SQL error returned by the UltraLite database.

Prototypes

' Visual Basic
Public Class SQLException
Inherits ApplicationException

// C#
public class SQLException :
ApplicationException

Remarks

This class is not serializable under the .NET Compact Framework.


SQLException members

Public instance constructors
Member | Description
SQLException constructor | Creates a SQLException with the given error code.
Public instance properties
Member | Description
ErrorCode property | The SQL code returned by the database.
HelpLink (inherited from Exception) | Gets or sets a link to the help file associated with this exception.
InnerException (inherited from Exception) | Gets the System.Exception instance that caused the current exception.
Message (inherited from Exception) | Gets a message that describes the current exception.
Source (inherited from Exception) | Gets or sets the name of the application or the object that causes the error.
StackTrace (inherited from Exception) | Gets a string representation of the frames on the call stack at the time the current exception was thrown.
TargetSite (inherited from Exception) | Gets the method that throws the current exception.
Public instance methods
Member | Description
GetBaseException (inherited from Exception) | When overridden in a derived class, returns the System.Exception that is the root cause of one or more subsequent exceptions.
GetObjectData method | Populates a SerializationInfo with the data needed to serializes this SQLException.
ToString (inherited from Exception) | Creates and returns a string representation of the current exception.
Protected instance properties
Member | Description
HResult (inherited from Exception) | Gets or sets HRESULT, a coded numerical value that is assigned to a specific exception.


SQLException constructor

Creates a SQLException with the given error code.

Prototypes

' Visual Basic
Overloads Public Sub New( _
ByVal code As SQLCode, _
ByVal s1 As String, _
ByVal s2 As String, _
ByVal s3 As String _
)

// C#
public SQLException(
SQLCode code,
string s1,
string s2,
string s3
);

Parameters

  • code the code of the exception.

  • s1 first string for formatted message.

  • s2 second string for formatted message.

  • s3 third string for formatted message.

Remarks

The message string corresponding to the specified SQLCode enumeration is retrieved from the iAnywhere.UltraLite.resources assembly. Resources are searched for, by culture, using the following order: System.Globalization.CultureInfo.CurrentUICulture, then System.Globalization.CultureInfo.CurrentCulture, and finally culture "EN".


ErrorCode property

The SQL code returned by the database.

Prototypes

' Visual Basic
Public Readonly Property ErrorCode As SQLCode

// C#
public SQLCode ErrorCode {get;}


GetObjectData method

Populates a SerializationInfo with the data needed to serializes this SQLException.

Prototypes

' Visual Basic
Overrides Public Sub GetObjectData( _
ByVal info As System.Runtime.Serialization.SerializationInfo, _
ByVal context As System.Runtime.Serialization.StreamingContext _
) _
Implements ISerializable.GetObjectData

// C#
public override void GetObjectData(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context
);

Parameters

  • info the SerializationInfo to populate with data.

  • context the destination for this serialization.

Remarks

This method is not supported under the .NET Compact Framework.

Implements

ISerializable.GetObjectData


SQLType enumeration

Enumerates the available UltraLite SQL database types used as table column types.

Prototypes

' Visual Basic
Public Enum SQLType

// C#
public enum SQLType

Remarks

The table below lists which .NET types are compatible with each SQL type. In the case of integral types, table columns can always be set using smaller integer types and can be set using larger types as long as the actual value is within the range of the SQL type. For example:

            [Visual Basic]
            Dim t as iAnywhere.UltraLite.Table
            Dim s as Short
            ...
            ' Column 1 is of type S_LONG (Equivalent to a .NET 'System.Int32')
            t.SetShort( 1, s )  ' will succeed for all values in s
            t.SetLong( 1, 10 )  ' (long)10 is ok
            t.SetLong( 1, Int32.MaxValue + 1 )  ' throws SQLException

            ' Column 2 is of type U_SHORT
            Dim i as Integer = t.GetInt( 2 )  ' will succeed for all column values
            t.SetInt( 2, 0x0ffff )  ' largest valid 'int' column can be set with
            t.SetInt( 2, -1 )  ' SQLException

            [C#]
            Table t;
            short s;
            ...
            // Column 1 is of type S_LONG (Equivalent to a .NET 'System.Int32')
            t.SetShort( 1, s );  // will succeed for all values in s
            t.SetLong( 1, 10 );  // (long)10 is ok
            t.SetLong( 1, Int32.MaxValue + 1 );  // throws SQLException

            // Column 2 is of type U_SHORT
            int i = t.GetInt( 2 );  // will succeed for all column values
            t.SetInt( 2, 0x0ffff );  // largest valid 'int' column can be set with
            t.SetInt( 2, -1 );  // SQLException

SQL Type | Compatible .NET Type | C# Built-in Type | Visual Basic Built-in Type
BINARY | System.Byte[], or System.Guid if size is 16 | byte[] | Byte()
BIT | System.Boolean | bool | Boolean
CHAR | System.String | String | String
DATE | System.DateTime | DateTime No built-in type. | Date
DOUBLE | System.Double | double | Double
LONGBINARY | System.Byte[] | byte[] | Byte()
LONGVARCHAR | System.String | String | String
NUMERIC | System.String | String | String
REAL | System.Single | float | Single
S_BIG | System.Int64 | long | Long
S_LONG | System.Int32 | int | Integer
S_SHORT | System.Int16 | short | Short
TIME | System.TimeSpan | TimeSpan No built-in type. | TimeSpan No built-in type.
TIMESTAMP | System.DateTime | DateTime No built-in type. | Date
TINY | System.Byte | byte | Byte
U_BIG | System.UInt64 | ulong | UInt64 No built-in type.
U_LONG | System.UInt32 | uint | UInt32 No built-in type.
U_SHORT | System.UInt16 | ushort | UInt16 No built-in type.
UUID | System.Guid | Guid No built-in type. | Guid No built-in type.

BINARY columns of length 16 are sometimes referred to as UUID columns.

Members
Member | Description
BAD_INDEX | Column type returned if bad column indentifier is passed to GetColumnSQLType method.
BINARY | Binary data, with a specified length.
BIT | 1-bit flag.
CHAR | Character data, with a specified length.
DATE | Date information.
DOUBLE | Double precision floating point number (8 bytes).
LONGBINARY | Binary data, with variable length.
LONGVARCHAR | Character data, with variable length.
NUMERIC | Exact numerical data, with a specified precision and scale.
REAL | Single precision floating point number (4 bytes).
S_BIG | Signed 64-bit integer.
S_LONG | Signed 32-bit integer.
S_SHORT | Signed 16-bit integer.
TIME | Time information.
TIMESTAMP | Timestamp information (date, time).
TINY | Unsigned 8-bit integer.
U_BIG | Unsigned 64-bit integer.
U_LONG | Unsigned 32-bit integer.
U_SHORT | Unsigned 16-bit integer.
UUID | Universally Unique Identifer.


StreamErrorCode enumeration

Enumerates the error codes that may be reported by streams during synchronization.

Prototypes

' Visual Basic
Public Enum StreamErrorCode

// C#
public enum StreamErrorCode

Members
Member | Description
ACTSYNC_NO_PORT | ACTSYNC_NO_PORT(75)
ACTSYNC_NOT_INSTALLED | ACTSYNC_NOT_INSTALLED(76)
CREATE_RANDOM_OBJECT | CREATE_RANDOM_OBJECT(17)
DEQUEUING_CONNECTION | DEQUEUING_CONNECTION(19)
END_READ | END_READ(11)
END_WRITE | END_WRITE(10)
GENERATE_RANDOM | GENERATE_RANDOM(14)
HTTP_BAD_STATUS_CODE | HTTP_BAD_STATUS_CODE(86)
HTTP_BUFFER_SIZE_OUT_OF_RANGE | HTTP_BUFFER_SIZE_OUT_OF_RANGE(79)
HTTP_CHUNK_LEN_BAD_CHARACTER | HTTP_CHUNK_LEN_BAD_CHARACTER(85)
HTTP_CHUNK_LEN_ENCODED_MISSING | HTTP_CHUNK_LEN_ENCODED_MISSING(84)
HTTP_CLIENT_ID_NOT_SET | HTTP_CLIENT_ID_NOT_SET(78)
HTTP_CONTENT_TYPE_NOT_SPECIFIED | HTTP_CONTENT_TYPE_NOT_SPECIFIED(77)
HTTP_CRLF_ENCODED_MISSING | HTTP_CRLF_ENCODED_MISSING(81)
HTTP_CRLF_MISSING | HTTP_CRLF_MISSING(82)
HTTP_EXPECTED_POST | HTTP_EXPECTED_POST(89)
HTTP_EXTRA_DATA_END_READ | HTTP_EXTRA_DATA_END_READ(80)
HTTP_NO_CONTD_CONNECTION | HTTP_NO_CONTD_CONNECTION(83)
HTTP_UNABLE_TO_PARSE_COOKIE | HTTP_UNABLE_TO_PARSE_COOKIE(88)
HTTP_UNKNOWN_TRANSFER_ENCODING | HTTP_UNKNOWN_TRANSFER_ENCODING(87)
HTTP_VERSION | HTTP_VERSION(54)
INIT_RANDOM | INIT_RANDOM(15)
LOAD_NETWORK_LIBRARY | LOAD_NETWORK_LIBRARY(74)
MEMORY_ALLOCATION | MEMORY_ALLOCATION(6)
NONE | NONE(0)
NOT_IMPLEMENTED | NOT_IMPLEMENTED(12)
PARAMETER | PARAMETER(1)
PARAMETER_NOT_BOOLEAN | PARAMETER_NOT_BOOLEAN(4)
PARAMETER_NOT_HEX | PARAMETER_NOT_HEX(5)
PARAMETER_NOT_UINT32 | PARAMETER_NOT_UINT32(2)
PARAMETER_NOT_UINT32_RANGE | PARAMETER_NOT_UINT32_RANGE(3)
PARSE | PARSE(7)
READ | READ(8)
SECURE_ADD_CERTIFICATE | SECURE_ADD_CERTIFICATE(39)
SECURE_ADD_TRUSTED_CERTIFICATE | SECURE_ADD_TRUSTED_CERTIFICATE(48)
SECURE_CERTIFICATE_CHAIN_FUNC | SECURE_CERTIFICATE_CHAIN_FUNC(28)
SECURE_CERTIFICATE_CHAIN_LENGTH | SECURE_CERTIFICATE_CHAIN_LENGTH(22)
SECURE_CERTIFICATE_CHAIN_REF | SECURE_CERTIFICATE_CHAIN_REF(29)
SECURE_CERTIFICATE_COMMON_NAME | SECURE_CERTIFICATE_COMMON_NAME(52)
SECURE_CERTIFICATE_COMPANY_NAME | SECURE_CERTIFICATE_COMPANY_NAME(21)
SECURE_CERTIFICATE_COMPANY_UNIT | SECURE_CERTIFICATE_COMPANY_UNIT(51)
SECURE_CERTIFICATE_COUNT | SECURE_CERTIFICATE_COUNT(42)
SECURE_CERTIFICATE_EXPIRED | SECURE_CERTIFICATE_EXPIRED(50)
SECURE_CERTIFICATE_EXPIRY_DATE | SECURE_CERTIFICATE_EXPIRY_DATE(37)
SECURE_CERTIFICATE_FILE_NOT_FOUND | SECURE_CERTIFICATE_FILE_NOT_FOUND(33)
SECURE_CERTIFICATE_NOT_TRUSTED | SECURE_CERTIFICATE_NOT_TRUSTED(24)
SECURE_CERTIFICATE_REF | SECURE_CERTIFICATE_REF(23)
SECURE_CERTIFICATE_ROOT | SECURE_CERTIFICATE_ROOT(20)
SECURE_CREATE_CERTIFICATE | SECURE_CREATE_CERTIFICATE(43)
SECURE_CREATE_PRIVATE_KEY_OBJECT | SECURE_CREATE_PRIVATE_KEY_OBJECT(49)
SECURE_DUPLICATE_CONTEXT | SECURE_DUPLICATE_CONTEXT(25)
SECURE_ENABLE_NON_BLOCKING | SECURE_ENABLE_NON_BLOCKING(30)
SECURE_EXPORT_CERTIFICATE | SECURE_EXPORT_CERTIFICATE(38)
SECURE_HANDSHAKE | SECURE_HANDSHAKE(53)
SECURE_IMPORT_CERTIFICATE | SECURE_IMPORT_CERTIFICATE(44)
SECURE_READ_CERTIFICATE | SECURE_READ_CERTIFICATE(34)
SECURE_READ_PRIVATE_KEY | SECURE_READ_PRIVATE_KEY(35)
SECURE_SET_CHAIN_NUMBER | SECURE_SET_CHAIN_NUMBER(32)
SECURE_SET_CIPHER_SUITES | SECURE_SET_CIPHER_SUITES(31)
SECURE_SET_IO | SECURE_SET_IO(26)
SECURE_SET_IO_SEMANTICS | SECURE_SET_IO_SEMANTICS(27)
SECURE_SET_PRIVATE_KEY | SECURE_SET_PRIVATE_KEY(36)
SECURE_SET_PROTOCOL_SIDE | SECURE_SET_PROTOCOL_SIDE(47)
SECURE_SET_RANDOM_FUNC | SECURE_SET_RANDOM_FUNC(46)
SECURE_SET_RANDOM_REF | SECURE_SET_RANDOM_REF(45)
SECURE_SET_READ_FUNC | SECURE_SET_READ_FUNC(55)
SECURE_SET_WRITE_FUNC | SECURE_SET_WRITE_FUNC(56)
SECURE_TRUSTED_CERTIFICATE_FILE_NOT_FOUND | SECURE_TRUSTED_CERTIFICATE_FILE_NOT_FOUND(40)
SECURE_TRUSTED_CERTIFICATE_READ | SECURE_TRUSTED_CERTIFICATE_READ(41)
SEED_RANDOM | SEED_RANDOM(16)
SHUTTING_DOWN | SHUTTING_DOWN(18)
SOCKET_BIND | SOCKET_BIND(62)
SOCKET_CLEANUP | SOCKET_CLEANUP(63)
SOCKET_CLOSE | SOCKET_CLOSE(64)
SOCKET_CONNECT | SOCKET_CONNECT(65)
SOCKET_CREATE_TCPIP | SOCKET_CREATE_TCPIP(60)
SOCKET_CREATE_UDP | SOCKET_CREATE_UDP(61)
SOCKET_GET_HOST_BY_ADDR | SOCKET_GET_HOST_BY_ADDR(58)
SOCKET_GET_NAME | SOCKET_GET_NAME(66)
SOCKET_GET_OPTION | SOCKET_GET_OPTION(67)
SOCKET_HOST_NAME_NOT_FOUND | SOCKET_HOST_NAME_NOT_FOUND(57)
SOCKET_LISTEN | SOCKET_LISTEN(69)
SOCKET_LOCALHOST_NAME_NOT_FOUND | SOCKET_LOCALHOST_NAME_NOT_FOUND(59)
SOCKET_PORT_OUT_OF_RANGE | SOCKET_PORT_OUT_OF_RANGE(73)
SOCKET_SELECT | SOCKET_SELECT(71)
SOCKET_SET_OPTION | SOCKET_SET_OPTION(68)
SOCKET_SHUTDOWN | SOCKET_SHUTDOWN(70)
SOCKET_STARTUP | SOCKET_STARTUP(72)
WOULD_BLOCK | WOULD_BLOCK(13)
WRITE | WRITE(9)
See also
  • StreamErrorCode property


StreamErrorContext enumeration

Enumerates the basic network operation being performed when the stream errors occured.

Prototypes

' Visual Basic
Public Enum StreamErrorContext

// C#
public enum StreamErrorContext

Members
Member | Description
CLOSE | CLOSE(6)
CREATE | CREATE(3)
DESTROY | DESTROY(4)
END_READ | END_READ(11)
END_WRITE | END_WRITE(10)
GETVALUE | GETVALUE(14)
OPEN | OPEN(5)
READ | READ(7)
REGISTER | REGISTER(1)
SOFTSHUTDOWN | SOFTSHUTDOWN(13)
UNKNOWN | UNKNOWN(0)
UNREGISTER | UNREGISTER(2)
WRITE | WRITE(8)
WRITE_FLUSH | WRITE_FLUSH(9)
YIELD | YIELD(12)
See also
  • StreamErrorContext property


StreamErrorID enumeration

Enumerates the network layers that may report errors during synchronization.

Prototypes

' Visual Basic
Public Enum StreamErrorID

// C#
public enum StreamErrorID

Members
Member | Description
ACTIVESYNC | ACTIVESYNC(22)
CERTICOM | CERTICOM(11)
CERTICOM_SSL | CERTICOM_SSL(13)
CERTICOM_TLS | CERTICOM_TLS(14)
DH_CAST | DH_CAST(9)
EMAIL | EMAIL(20)
FAKE | FAKE(2)
FILE | FILE(21)
HTTP | HTTP(7)
HTTPS | HTTPS(8)
JAVA_CERTICOM | JAVA_CERTICOM(12)
JAVA_RSA | JAVA_RSA(24)
NETTECH | NETTECH(5)
PALM_CONDUIT | PALM_CONDUIT(3)
PALM_SS | PALM_SS(4)
REPLAY | REPLAY(17)
RIMBB | RIMBB(6)
RSA_TLS | RSA_TLS(23)
SECURE | SECURE(10)
SERIAL | SERIAL(1)
STRM | STRM(18)
TCPIP | TCPIP(0)
UDP | UDP(19)
WIRELESS | WIRELESS(16)
WIRESTRM | WIRESTRM(15)
See also
  • StreamErrorID property


StreamType enumeration

Enumerates the types of MobiLink synchronization streams to use for synchronization.

Prototypes

' Visual Basic
Public Enum StreamType

// C#
public enum StreamType

Remarks

For information on configuring specific stream types, refer to the Synchronization Stream Parameters Reference section of the UltraLite Database User's Guide online book.

Members
Member | Description
ACTIVE_SYNC | ActiveSync synchronization (Windows CE only). UltraLite applications should only use ActiveSync synchronization when notified to do so by the MobiLink provider for ActiveSync. An application can listen for such notification by implementing an ActiveSyncListener interface and calling SetActiveSyncListener method.
HTTP | Synchronize via HTTP. The HTTP stream uses TCP/IP as its underlying transport. UltraLite applications act as Web browsers and the MobiLink synchronization server acts as a Web server. UltraLite applications send POST requests to send data to the server and GET requests to read data from the server.
HTTPS | Synchronize via HTTPS (HTTP with RSA transport-layer security). Transport-layer security is a separately-licensable component and must be ordered before you can install it. To order this component, see the card in your SQL Anywhere Studio package, or see [external link] http://www.sybase.com/detail?id=1015780.
TCPIP | Synchronize via TCP/IP.
UNKNOWN | Unknown or no synchronization stream. The user has not set the stream type.
See also
  • Stream property


SyncParms class

Represents synchronization parameters that define how to synchronize an UltraLite database.

Prototypes

' Visual Basic
NotInheritable Public Class SyncParms

// C#
public sealed class SyncParms

Remarks

This class cannot be directly instantiated. Each connection has its own SyncParms instance, attached as its SyncParms property property.

Only one synchronization command (DownloadOnly property, PingOnly property, ResumePartialDownload property, or UploadOnly property) may be specified at a time. If more than one of these parameters is set to true, a SQLCode enumeration SQLException will be thrown by Synchronize method.

Other sources of SQLCode enumeration errors include not specifying a Stream property value or a Version property value.

See also
  • SyncParms members
  • Connection class
  • SyncParms property
  • Synchronize method

SyncParms members
AuthenticationParms property
CheckpointStore property
DisableConcurrency property
DownloadOnly property
KeepPartialDownload property
NewPassword property
Password property
PingOnly property
PublicationMask property
ResumePartialDownload property
SendColumnNames property
SendDownloadAck property
Stream property
StreamParms property
UploadOnly property
UserName property
Version property
CopyFrom method
Finalize method


SyncParms members

Public instance properties
Member | Description
AuthenticationParms property | Specifies parameters for a custom user authentication script (MobiLink authenticate_parameters connection event).
CheckpointStore property | Specifies whether the client should perform extra store checkpoints to control the growth of the database store during synchronization.
DisableConcurrency property | Specifies whether to disable or enable concurrent access to UltraLite while performing a synchronization.
DownloadOnly property | Specifies whether to disable or enable uploads when synchronizing.
KeepPartialDownload property | Specifies whether to disable or enable partial downloads when synchronizing.
NewPassword property | Specifies a new MobiLink password for the user specified with UserName.
Password property | The MobiLink password for the user specified by UserName.
PingOnly property | Specifies whether the client should only ping the MobiLink synchronization server instead of performing a real synchronization.
PublicationMask property | Specifies the publications to be synchronized.
ResumePartialDownload property | Specifies whether to resume or discard a previous partial download.
SendColumnNames property | Specifies whether the client should send column names to the MobiLink synchronization server during synchronization.
SendDownloadAck property | Specifies whether the client should send a download acknowledgement to the MobiLink synchronization server during synchronization.
Stream property | Specifies the MobiLink synchronization stream to use for synchronization.
StreamParms property | Specifies the parameters to configure the synchronization stream.
UploadOnly property | Specifies whether to disable or enable downloads when synchronizing.
UserName property | The user name that uniquely identifies the MobiLink client to the MobiLink synchronization server.
Version property | Specifies which synchronization script to use.
Public instance methods
Member | Description
CopyFrom method | Copies the properties of the specified SyncParms class object to this SyncParms class object.
Protected instance methods
Member | Description
Finalize method | Destructor which cleans up the associated JNI state.


AuthenticationParms property

Specifies parameters for a custom user authentication script (MobiLink authenticate_parameters connection event).

Prototypes

' Visual Basic
Public Property AuthenticationParms As String()

// C#
public string [] AuthenticationParms {get;set;}

Remarks

Specified as an array of strings, each containing an authentication parameter (null array entries will result in a synchronization error).

Only the first 255 strings are used and each string should be no longer than 128 characters (longer strings will be truncated when sent to MobiLink).

The default is no authentication parms.


CheckpointStore property

Specifies whether the client should perform extra store checkpoints to control the growth of the database store during synchronization.

Prototypes

' Visual Basic
Public Property CheckpointStore As Boolean

// C#
public bool CheckpointStore {get;set;}

Remarks

The checkpoint operation adds I/O operations for the application, and so slows synchronization. This option is most useful for large downloads with many updates. Devices with slow flash memory may not want to pay the performance penalty.

The default is false (only required checkpointing is done).


DisableConcurrency property

Specifies whether to disable or enable concurrent access to UltraLite while performing a synchronization.

Prototypes

' Visual Basic
Public Property DisableConcurrency As Boolean

// C#
public bool DisableConcurrency {get;set;}

Remarks

By default, other threads may perform UltraLite operations while a thread is synchronizing. When concurrent synchronization is disabled, other threads will block on UltraLite calls until the synchronization has completed.


DownloadOnly property

Specifies whether to disable or enable uploads when synchronizing.

Prototypes

' Visual Basic
Public Property DownloadOnly As Boolean

// C#
public bool DownloadOnly {get;set;}

Remarks

Only one synchronization command (DownloadOnly property, PingOnly property, ResumePartialDownload property, or UploadOnly property) may be specified at a time. If more than one of these parameters is set to true, a SQLCode enumeration SQLException will be thrown by Synchronize method.

The default is false.

See also
  • SyncParms class
  • SyncParms members
  • UploadOnly property


KeepPartialDownload property

Specifies whether to disable or enable partial downloads when synchronizing.

Prototypes

' Visual Basic
Public Property KeepPartialDownload As Boolean

// C#
public bool KeepPartialDownload {get;set;}

Remarks

UltraLite.NET has the ability to restart downloads that fail because of communication errors or user aborts through the SyncProgressListener. UltraLite.NET processes the download as it is received. If a download is interrupted, then the partial download transaction will remain in the database and can be resumed during the next synchronization.

To indicate that UltraLite.NET should save partial downloads, specify connection.SyncParms.KeepPartialDownload=true; otherwise the download will be rolled back if an error occurs.

If a partial download was kept, then the output field connection.SyncResult.SyncResult.PartialDownloadRetained will be set to true when connection.Synchronize() exits.

If PartialDownloadRetained is set, then you can resume a download. To do this, call connection.Synchronize() with connection.SyncParms.SyncParms.ResumePartialDownload set to true. You'll likely still want KeepPartialDownload set to true as well in case another communications error occurs. No upload is done if a download is skipped.

The download you receive during a resumed download will be as old as when the download originally began. If you need the most up to date data, then you can do another download immediately after the special resumed download completes.

When resuming a download, many of the SyncParms fields are not relevant. For example, the PublicationMask field is not used. You will receive the publications that you requested on the initial download. The only fields that need to be set are ResumePartialDownload property and UserName property. The fields KeepPartialDownload and DisableConcurrency property may be set if desired and will function as normal.

If you have a partial download and it is no longer needed, then you can call RollbackPartialDownload method to roll back the failed download transaction. Also if you attempt to synchronize again and do not specify ResumePartialDownload, then the partial download will be rolled back before the next synchronization begins.

For more information, refer to the Restartable downloads section of the MobiLink Synchronization User's Guide.

The default is false.

See also
  • SyncParms class
  • SyncParms members
  • PartialDownloadRetained property
  • ResumePartialDownload property
  • RollbackPartialDownload method


NewPassword property

Specifies a new MobiLink password for the user specified with UserName.

Prototypes

' Visual Basic
Public Property NewPassword As String

// C#
public string NewPassword {get;set;}

Remarks

A new password will take effect after the next synchronization.

The default is null (password not replaced).

See also
  • SyncParms class
  • SyncParms members
  • UserName property


Password property

The MobiLink password for the user specified by UserName.

Prototypes

' Visual Basic
Public Property Password As String

// C#
public string Password {get;set;}

Remarks

The MobiLink user name and password are separate from any database user ID and password, and serve to identify and authenticate the application to the MobiLink synchronization server.

The default is null (no password).

See also
  • SyncParms class
  • SyncParms members
  • NewPassword property
  • UserName property


PingOnly property

Specifies whether the client should only ping the MobiLink synchronization server instead of performing a real synchronization.

Prototypes

' Visual Basic
Public Property PingOnly As Boolean

// C#
public bool PingOnly {get;set;}

Remarks

Only one synchronization command (DownloadOnly property, PingOnly property, ResumePartialDownload property, or UploadOnly property) may be specified at a time. If more than one of these parameters is set to true, a SQLCode enumeration SQLException will be thrown by Synchronize method.

The default is false.


PublicationMask property

Specifies the publications to be synchronized.

Prototypes

' Visual Basic
Public Property PublicationMask As Integer

// C#
public int PublicationMask {get;set;}

Remarks

The default is SYNC_ALL_DB field.

See also
  • SyncParms class
  • SyncParms members
  • PublicationSchema class


ResumePartialDownload property

Specifies whether to resume or discard a previous partial download.

Prototypes

' Visual Basic
Public Property ResumePartialDownload As Boolean

// C#
public bool ResumePartialDownload {get;set;}

Remarks

Only one synchronization command (DownloadOnly property, PingOnly property, ResumePartialDownload property, or UploadOnly property) may be specified at a time. If more than one of these parameters is set to true, a SQLCode enumeration SQLException will be thrown by Synchronize method.

The default is false.

See also
  • SyncParms class
  • SyncParms members
  • KeepPartialDownload property
  • PartialDownloadRetained property


SendColumnNames property

Specifies whether the client should send column names to the MobiLink synchronization server during synchronization.

Prototypes

' Visual Basic
Public Property SendColumnNames As Boolean

// C#
public bool SendColumnNames {get;set;}

Remarks

This parameter is typically used together with the -za or -ze option on the MobiLink synchronization server for automatically generating synchronization scripts.

The default is false (column names are not sent).


SendDownloadAck property

Specifies whether the client should send a download acknowledgement to the MobiLink synchronization server during synchronization.

Prototypes

' Visual Basic
Public Property SendDownloadAck As Boolean

// C#
public bool SendDownloadAck {get;set;}

Remarks

If the client does send a download acknowledgement, the MobiLink synchronization server worker thread must wait for the client to apply the download. If the client does not sent a download acknowledgement, the MobiLink synchronization server is freed up sooner for its next synchronization.

The default is false (no download acknowledgement is sent).


Stream property

Specifies the MobiLink synchronization stream to use for synchronization.

Prototypes

' Visual Basic
Public Property Stream As StreamType

// C#
public StreamType Stream {get;set;}

Remarks

Most synchronization streams require parameters to identify the MobiLink synchronization server address and control other behavior. These parameters are supplied by the StreamParms property property.

If the stream type is set to a value that is invalid for the platform, the stream type will be set to StreamType enumeration.

This parameter has no default value, and must be explicitly set.

See also
  • SyncParms class
  • SyncParms members
  • StreamType enumeration
  • StreamParms property


StreamParms property

Specifies the parameters to configure the synchronization stream.

Prototypes

' Visual Basic
Public Property StreamParms As String

// C#
public string StreamParms {get;set;}

Remarks

For information on configuring specific stream types, refer to the Synchronization Stream Parameters Reference section of the UltraLite Database User's Guide online book.

StreamParms is a string containing all the parameters used for synchronization streams. Parameters are specified as a semicolon-separated list of name=value pairs ("param1=value1;param2=value2").

The default is null.

See also
  • SyncParms class
  • SyncParms members
  • Stream property
  • StreamType enumeration


UploadOnly property

Specifies whether to disable or enable downloads when synchronizing.

Prototypes

' Visual Basic
Public Property UploadOnly As Boolean

// C#
public bool UploadOnly {get;set;}

Remarks

Only one synchronization command (DownloadOnly property, PingOnly property, ResumePartialDownload property, or UploadOnly property) may be specified at a time. If more than one of these parameters is set to true, a SQLCode enumeration SQLException will be thrown by Synchronize method.

The default is false.

See also
  • SyncParms class
  • SyncParms members
  • DownloadOnly property


UserName property

The user name that uniquely identifies the MobiLink client to the MobiLink synchronization server.

Prototypes

' Visual Basic
Public Property UserName As String

// C#
public string UserName {get;set;}

Remarks

MobiLink uses this value to determine the download content, to record the synchronization state, and to recover from interruptions during synchronization. This user name and password are separate from any database user ID and password, and serve to identify and authenticate the application to the MobiLink synchronization server.

This parameter has no default value, and must be explicitly set.

See also
  • SyncParms class
  • SyncParms members
  • Password property


Version property

Specifies which synchronization script to use.

Prototypes

' Visual Basic
Public Property Version As String

// C#
public string Version {get;set;}

Remarks

Each synchronization script in the consolidated database is marked with a version string. For example, there may be two different download_cursor scripts, with each one identified by different a version string. The version string allows an UltraLite application to choose from a set of synchronization scripts.

This parameter has no default value, and must be explicitly set.


CopyFrom method

Copies the properties of the specified SyncParms class object to this SyncParms class object.

Prototypes

' Visual Basic
Public Sub CopyFrom( _
ByVal src As SyncParms _
)

// C#
public void CopyFrom(
SyncParms src
);

Parameters

  • src object to copy from.


Finalize method

Destructor which cleans up the associated JNI state.

Prototypes

' Visual Basic
Overrides Protected Sub Finalize()

// C#
protected override void Finalize();


SyncProgressData class

Returns synchronization progress monitoring data.

Prototypes

' Visual Basic
Public Class SyncProgressData

// C#
public class SyncProgressData

See also
  • SyncProgressData members
  • SyncProgressListener interface

SyncProgressData members
ErrorMessage property
ReceivedBytes property
ReceivedDeletes property
ReceivedInserts property
ReceivedUpdates property
SentBytes property
SentDeletes property
SentInserts property
SentUpdates property
SQLCode property
State property
SyncParms property
SyncResult property
TableCount property
TableIndex property
TableTotal property


SyncProgressData members

Public instance properties
Member | Description
ErrorMessage property | Error message describing the error that occured during synchronization.
ReceivedBytes property | The number of bytes received so far. This information is updated for all states.
ReceivedDeletes property | The number of deleted rows received so far.
ReceivedInserts property | The number of inserted rows received so far.
ReceivedUpdates property | The number of updated rows received so far.
SentBytes property | The number of bytes sent so far. This information is updated for all states.
SentDeletes property | The number of deleted rows sent so far.
SentInserts property | The number of inserted rows sent so far.
SentUpdates property | The number of updated rows sent so far.
SQLCode property | SQL code for synchronization.
State property | The current synchronization state.
SyncParms property | Reference to the Connection's SyncParms object.
SyncResult property | Reference to the Connection's SyncResult object. This object is only updated with STATE_DONE and STATE_ERROR events.
TableCount property | A count of the tables sent or received (TableCount of TableTotal) so far.
TableIndex property | Index of the table currently being synchronized (tables are numbered 1 to DatabaseSchema.TableCount).
TableTotal property | The number of tables being synchronized.


ErrorMessage property

Error message describing the error that occured during synchronization.

Prototypes

' Visual Basic
Public Readonly Property ErrorMessage As String

// C#
public string ErrorMessage {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration


ReceivedBytes property

The number of bytes received so far. This information is updated for all states.

Prototypes

' Visual Basic
Public Readonly Property ReceivedBytes As Long

// C#
public long ReceivedBytes {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration


ReceivedDeletes property

The number of deleted rows received so far.

Prototypes

' Visual Basic
Public Readonly Property ReceivedDeletes As Integer

// C#
public int ReceivedDeletes {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration


ReceivedInserts property

The number of inserted rows received so far.

Prototypes

' Visual Basic
Public Readonly Property ReceivedInserts As Integer

// C#
public int ReceivedInserts {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration


ReceivedUpdates property

The number of updated rows received so far.

Prototypes

' Visual Basic
Public Readonly Property ReceivedUpdates As Integer

// C#
public int ReceivedUpdates {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration


SentBytes property

The number of bytes sent so far. This information is updated for all states.

Prototypes

' Visual Basic
Public Readonly Property SentBytes As Long

// C#
public long SentBytes {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration


SentDeletes property

The number of deleted rows sent so far.

Prototypes

' Visual Basic
Public Readonly Property SentDeletes As Integer

// C#
public int SentDeletes {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration


SentInserts property

The number of inserted rows sent so far.

Prototypes

' Visual Basic
Public Readonly Property SentInserts As Integer

// C#
public int SentInserts {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration


SentUpdates property

The number of updated rows sent so far.

Prototypes

' Visual Basic
Public Readonly Property SentUpdates As Integer

// C#
public int SentUpdates {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration


SQLCode property

SQL code for synchronization.

Prototypes

' Visual Basic
Public Readonly Property SQLCode As SQLCode

// C#
public SQLCode SQLCode {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration


State property

The current synchronization state.

Prototypes

' Visual Basic
Public Readonly Property State As SyncProgressState

// C#
public SyncProgressState State {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration


SyncParms property

Reference to the Connection's SyncParms object.

Prototypes

' Visual Basic
Public Readonly Property SyncParms As SyncParms

// C#
public SyncParms SyncParms {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration
  • SyncParms property


SyncResult property

Reference to the Connection's SyncResult object. This object is only updated with STATE_DONE and STATE_ERROR events.

Prototypes

' Visual Basic
Public Readonly Property SyncResult As SyncResult

// C#
public SyncResult SyncResult {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration
  • SyncResult property


TableCount property

A count of the tables sent or received (TableCount of TableTotal) so far.

Prototypes

' Visual Basic
Public Readonly Property TableCount As Integer

// C#
public int TableCount {get;}

Return value

count of tables sent or received.

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration


TableIndex property

Index of the table currently being synchronized (tables are numbered 1 to DatabaseSchema.TableCount).

Prototypes

' Visual Basic
Public Readonly Property TableIndex As Integer

// C#
public int TableIndex {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration


TableTotal property

The number of tables being synchronized.

Prototypes

' Visual Basic
Public Readonly Property TableTotal As Integer

// C#
public int TableTotal {get;}

See also
  • SyncProgressData class
  • SyncProgressData members
  • SyncProgressState enumeration
  • SyncProgressState enumeration


SyncProgressDialog class

Displays a synchronization progress monitoring dialog.

Prototypes

' Visual Basic
Public Class SyncProgressDialog
Inherits Form, SyncProgressListener

// C#
public class SyncProgressDialog :
Form,
SyncProgressListener

Remarks

This dialog must be used as a modal, single use dialog. When the application calls the dialog's ShowDialog method method to display the dialog, it blocks the rest of the application until synchronization has completed or the user has clicked the Cancel button.

Note: Methods documented as being "called during synchronization" must not access any connections, schemas, or tables.

See also
  • SyncProgressDialog members
  • Synchronize method

SyncProgressDialog members
SyncProgressDialog constructor
SQLCode property
Dispose method
GetErrorMessage method
GetMessage method
GetString method
OnClosing method
ResetValues method
ShowDialog method
ShowDialog method
SyncProgressed method


SyncProgressDialog members

Public instance constructors
Member | Description
SyncProgressDialog constructor | Construct a SyncProgressDialog instance to synchronize the UltraLite database using the specified connection.
Public instance properties
Member | Description
AcceptButton (inherited from Form) | Gets or sets the button on the form that is clicked when the user presses the ENTER key.
AccessibilityObject (inherited from Control) | Gets the System.Windows.Forms.AccessibleObject assigned to the control.
AccessibleDefaultActionDescription (inherited from Control) | Gets or sets the default action description of the control for use by accessibility client applications.
AccessibleDescription (inherited from Control) | Gets or sets the description of the control used by accessibility client applications.
AccessibleName (inherited from Control) | Gets or sets the name of the control used by accessibility client applications.
AccessibleRole (inherited from Control) | Gets or sets the accessible role of the control
ActiveControl (inherited from ContainerControl) | Gets or sets the active control on the container control.
ActiveMdiChild (inherited from Form) | Gets the currently active multiple document interface (MDI) child window.
AllowDrop (inherited from Control) | Gets or sets a value indicating whether the control can accept data that the user drags onto it.
AllowTransparency (inherited from Form) |
Anchor (inherited from Control) | Gets or sets which edges of the control are anchored to the edges of its container.
AutoScale (inherited from Form) | Gets or sets a value indicating whether the form adjusts its size to fit the height of the font used on the form and scales its controls.
AutoScaleBaseSize (inherited from Form) | Gets or sets the base size used for autoscaling of the form.
AutoScroll (inherited from Form) | Gets or sets a value indicating whether the form enables autoscrolling.
AutoScrollMargin (inherited from ScrollableControl) | Gets or sets the size of the auto-scroll margin.
AutoScrollMinSize (inherited from ScrollableControl) | Gets or sets the minimum size of the auto-scroll.
AutoScrollPosition (inherited from ScrollableControl) | Gets or sets the location of the auto-scroll position.
BackColor (inherited from Form) |
BackgroundImage (inherited from Control) | Gets or sets the background image displayed in the control.
BindingContext (inherited from ContainerControl) |
Bottom (inherited from Control) | Gets the distance between the bottom edge of the control and the top edge of its container's client area.
Bounds (inherited from Control) | Gets or sets the size and location of the control including its nonclient elements.
CancelButton (inherited from Form) | Gets or sets the button control that is clicked when the user presses the ESC key.
CanFocus (inherited from Control) | Gets a value indicating whether the control can receive focus.
CanSelect (inherited from Control) | Gets a value indicating whether the control can be selected.
Capture (inherited from Control) | Gets or sets a value indicating whether the control has captured the mouse.
CausesValidation (inherited from Control) | Gets or sets a value indicating whether the control causes validation to be performed on any controls that require validation when it receives focus.
ClientRectangle (inherited from Control) | Gets the rectangle that represents the client area of the control.
ClientSize (inherited from Form) | Gets or sets the size of the client area of the form.
CompanyName (inherited from Control) | Gets the name of the company or creator of the application containing the control.
ContainsFocus (inherited from Control) | Gets a value indicating whether the control, or one of its child controls, currently has the input focus.
ContextMenu (inherited from Control) | Gets or sets the shortcut menu associated with the control.
ControlBox (inherited from Form) | Gets or sets a value indicating whether a control box is displayed in the caption bar of the form.
Controls (inherited from Control) | Gets the collection of controls contained within the control.
Created (inherited from Control) | Gets a value indicating whether the control has been created.
Cursor (inherited from Control) | Gets or sets the cursor that is displayed when the mouse pointer is over the control.
DataBindings (inherited from Control) | Gets the data bindings for the control.
DesktopBounds (inherited from Form) | Gets or sets the size and location of the form on the Windows desktop.
DesktopLocation (inherited from Form) | Gets or sets the location of the form on the Windows desktop.
DialogResult (inherited from Form) | Gets or sets the dialog result for the form.
DisplayRectangle (inherited from ScrollableControl) |
Disposing (inherited from Control) | Gets a value indicating whether the control is in the process of being disposed of.
Dock (inherited from Control) | Gets or sets which edge of the parent container a control is docked to.
DockPadding (inherited from ScrollableControl) | Gets the dock padding settings for all edges of the control.
Enabled (inherited from Control) | Gets or sets a value indicating whether the control can respond to user interaction.
Focused (inherited from Control) | Gets a value indicating whether the control has input focus.
Font (inherited from Control) | Gets or sets the font of the text displayed by the control.
ForeColor (inherited from Control) | Gets or sets the foreground color of the control.
FormBorderStyle (inherited from Form) | Gets or sets the border style of the form.
Handle (inherited from Control) | Gets the window handle that the control is bound to.
HasChildren (inherited from Control) | Gets a value indicating whether the control contains one or more child controls.
Height (inherited from Control) | Gets or sets the height of the control.
HelpButton (inherited from Form) | Gets or sets a value indicating whether a Help button should be displayed in the caption box of the form.
Icon (inherited from Form) | Gets or sets the icon for the form.
ImeMode (inherited from Control) | Gets or sets the Input Method Editor (IME) mode of the control.
InvokeRequired (inherited from Control) | Gets a value indicating whether the caller must call an invoke method when making method calls to the control because the caller is on a different thread than the one the control was created on.
IsAccessible (inherited from Control) | Gets or sets a value indicating whether the control is visible to accessibility applications.
IsDisposed (inherited from Control) | Gets a value indicating whether the control has been disposed of.
IsHandleCreated (inherited from Control) | Gets a value indicating whether the control has a handle associated with it.
IsMdiChild (inherited from Form) | Gets a value indicating whether the form is a multiple document interface (MDI) child form.
IsMdiContainer (inherited from Form) | Gets or sets a value indicating whether the form is a container for multiple document interface (MDI) child forms.
IsRestrictedWindow (inherited from Form) |
KeyPreview (inherited from Form) | Gets or sets a value indicating whether the form will receive key events before the event is passed to the control that has focus.
Left (inherited from Control) | Gets or sets the x-coordinate of a control's left edge in pixels.
Location (inherited from Control) | Gets or sets the coordinates of the upper-left corner of the control relative to the upper-left corner of its container.
MaximizeBox (inherited from Form) | Gets or sets a value indicating whether the maximize button is displayed in the caption bar of the form.
MaximumSize (inherited from Form) | Gets the maximum size the form can be resized to.
MdiChildren (inherited from Form) | Gets an array of forms that represent the multiple document interface (MDI) child forms that are parented to this form.
MdiParent (inherited from Form) | Gets or sets the current multiple document interface (MDI) parent form of this form.
Menu (inherited from Form) | Gets or sets the System.Windows.Forms.MainMenu that is displayed in the form.
MergedMenu (inherited from Form) | Gets the merged menu for the form.
MinimizeBox (inherited from Form) | Gets or sets a value indicating whether the minimize button is displayed in the caption bar of the form.
MinimumSize (inherited from Form) | Gets or sets the minimum size the form can be resized to.
Modal (inherited from Form) | Gets a value indicating whether this form is displayed modally.
Name (inherited from Control) | Gets or sets the name of the control.
Opacity (inherited from Form) | Gets or sets the opacity level of the form.
OwnedForms (inherited from Form) | Gets an array of System.Windows.Forms.Form objects that represent all forms that are owned by this form.
Owner (inherited from Form) | Gets or sets the form that owns this form.
Parent (inherited from Control) | Gets or sets the parent container of the control.
ParentForm (inherited from ContainerControl) | Gets the form that the container control is assigned to.
ProductName (inherited from Control) | Gets the product name of the assembly containing the control.
ProductVersion (inherited from Control) | Gets the version of the assembly containing the control.
RecreatingHandle (inherited from Control) | Gets a value indicating whether the control is currently re-creating its handle.
Region (inherited from Control) | Gets or sets the window region associated with the control.
Right (inherited from Control) | Gets the distance between the right edge of the control and the left edge of its container.
RightToLeft (inherited from Control) | Gets or sets a value indicating whether control's elements are aligned to support locales using right-to-left fonts.
ShowInTaskbar (inherited from Form) | Gets or sets a value indicating whether the form is displayed in the Windows taskbar.
Site (inherited from Control) | Gets or sets the site of the control.
Size (inherited from Form) | Gets or sets the size of the form.
SizeGripStyle (inherited from Form) | Gets or sets the style of the size grip to display in the lower-right corner of the form.
SQLCode property | The SQL error code from the last synchronization.
StartPosition (inherited from Form) | Gets or sets the starting position of the form at run time.
TabIndex (inherited from Form) |
TabStop (inherited from Control) | Gets or sets a value indicating whether the user can give the focus to this control using the TAB key.
Tag (inherited from Control) | Gets or sets the object that contains data about the control.
Text (inherited from Control) | Gets or sets the text associated with this control.
Top (inherited from Control) | Gets or sets the y-coordinate of the control's top edge in pixels.
TopLevel (inherited from Form) | Gets or sets a value indicating whether to display the form as a top-level window.
TopLevelControl (inherited from Control) | Gets the parent control that is not parented by another Windows Forms control. Typically, this is the outermost System.Windows.Forms.Form that the control is contained in.
TopMost (inherited from Form) | Gets or sets a value indicating whether the form should be displayed as the top-most form of your application.
TransparencyKey (inherited from Form) | Gets or sets the color that will represent transparent areas of the form.
Visible (inherited from Control) | Gets or sets a value indicating whether the control is displayed.
Width (inherited from Control) | Gets or sets the width of the control.
WindowState (inherited from Form) | Gets or sets the form's window state.
WindowTarget (inherited from Control) |
Public instance methods
Member | Description
Activate (inherited from Form) | Activates the form and gives it focus.
AddOwnedForm (inherited from Form) | Adds an owned form to this form.
BeginInvoke (inherited from Control) | Executes the specified delegate asynchronously with the specified arguments, on the thread that the control's underlying handle was created on.
BeginInvoke (inherited from Control) | Executes the specified delegate asynchronously on the thread that the control's underlying handle was created on.
BringToFront (inherited from Control) | Brings the control to the front of the z-order.
Close (inherited from Form) | Closes the form.
Contains (inherited from Control) | Retrieves a value indicating whether the specified control is a child of the control.
CreateControl (inherited from Control) | Forces the creation of the control, including the creation of the handle and any child controls.
CreateGraphics (inherited from Control) | Creates the System.Drawing.Graphics object for the control.
DoDragDrop (inherited from Control) | Begins a drag-and-drop operation.
EndInvoke (inherited from Control) | Retrieves the return value of the asynchronous operation represented by the System.IAsyncResult object passed.
FindForm (inherited from Control) | Retrieves the form that the control is on.
Focus (inherited from Control) | Sets input focus to the control.
GetChildAtPoint (inherited from Control) | Retrieves the child control that is located at the specified coordinates.
GetContainerControl (inherited from Control) | Returns the next System.Windows.Forms.ContainerControl up the control's chain of parent controls.
GetNextControl (inherited from Control) | Retrieves the next control forward or back in the tab order of child controls.
Hide (inherited from Control) | Conceals the control from the user.
Invalidate (inherited from Control) | Invalidates the specified region of the control (adds it to the control's update region, which is the area that will be repainted at the next paint operation), and causes a paint message to be sent to the control.
Invalidate (inherited from Control) | Invalidates the specified region of the control (adds it to the control's update region, which is the area that will be repainted at the next paint operation), and causes a paint message to be sent to the control. Optionally, invalidates the child controls assigned to the control.
Invalidate (inherited from Control) | Invalidates a specific region of the control and causes a paint message to be sent to the control.
Invalidate (inherited from Control) | Invalidates a specific region of the control and causes a paint message to be sent to the control. Optionally, invalidates the child controls assigned to the control.
Invalidate (inherited from Control) | Invalidates the specified region of the control (adds it to the control's update region, which is the area that will be repainted at the next paint operation), and causes a paint message to be sent to the control.
Invalidate (inherited from Control) | Invalidates the specified region of the control (adds it to the control's update region, which is the area that will be repainted at the next paint operation), and causes a paint message to be sent to the control. Optionally, invalidates the child controls assigned to the control.
Invoke (inherited from Control) | Executes the specified delegate, on the thread that owns the control's underlying window handle, with the specified list of arguments.
Invoke (inherited from Control) | Executes the specified delegate on the thread that owns the control's underlying window handle.
LayoutMdi (inherited from Form) | Arranges the multiple document interface (MDI) child forms within the MDI parent form.
PerformLayout (inherited from Control) | Forces the control to apply layout logic to all its child controls.
PerformLayout (inherited from Control) | Forces the control to apply layout logic to all its child controls.
PointToClient (inherited from Control) | Computes the location of the specified screen point into client coordinates.
PointToScreen (inherited from Control) | Computes the location of the specified client point into screen coordinates.
PreProcessMessage (inherited from Control) | Preprocesses input messages within the message loop before they are dispatched.
RectangleToClient (inherited from Control) | Computes the size and location of the specified screen rectangle in client coordinates.
RectangleToScreen (inherited from Control) | Computes the size and location of the specified client rectangle in screen coordinates.
Refresh (inherited from Control) | Forces the control to invalidate its client area and immediately redraw itself and any child controls.
RemoveOwnedForm (inherited from Form) | Removes an owned form from this form.
ResetBackColor (inherited from Control) | Resets the System.Windows.Forms.Control.BackColor property to its default value.
ResetBindings (inherited from Control) | Resets the System.Windows.Forms.Control.DataBindings property to its default value.
ResetCursor (inherited from Control) | Resets the System.Windows.Forms.Control.Cursor property to its default value.
ResetFont (inherited from Control) | Resets the System.Windows.Forms.Control.Fontproperty to its default value.
ResetForeColor (inherited from Control) | Resets the System.Windows.Forms.Control.ForeColor property to its default value.
ResetImeMode (inherited from Control) | Resets the System.Windows.Forms.Control.ImeMode property to its default value.
ResetRightToLeft (inherited from Control) | Resets the System.Windows.Forms.Control.RightToLeft property to its default value.
ResetText (inherited from Control) | Resets the System.Windows.Forms.Control.Text property to its default value.
ResumeLayout (inherited from Control) | Resumes normal layout logic.
ResumeLayout (inherited from Control) | Resumes normal layout logic. Optionally forces an immediate layout of pending layout requests.
Scale (inherited from Control) | Scales the control and any child controls to the specified ratio.
Scale (inherited from Control) | Scales the control and any child controls by the specified horizontal and vertical ratios.
ScrollControlIntoView (inherited from ScrollableControl)
Select (inherited from Control) | Activates the control.
SelectNextControl (inherited from Control) | Activates the next control.
SendToBack (inherited from Control) | Sends the control to the back of the z-order.
SetAutoScrollMargin (inherited from ScrollableControl) | Sets the size of the auto-scroll margins.
SetBounds (inherited from Control) | Sets the bounds of the control to the specified location and size.
SetBounds (inherited from Control) | Sets the specified bounds of the control to the specified location and size.
SetDesktopBounds (inherited from Form) | Sets the bounds of the form in desktop coordinates.
SetDesktopLocation (inherited from Form) | Sets the location of the form in desktop coordinates.
Show (inherited from Control) | Displays the control to the user.
ShowDialog method | Shows the form as a modal dialog with the specified parent and performs synchronization. The dialog will close when synchronization has completed.
ShowDialog method | Shows the form as a modal dialog with no parent window and performs synchronization. The dialog will close when synchronization has completed.
ShowDialog (inherited from Form) | Shows the form as a modal dialog with the specified owner.
SuspendLayout (inherited from Control) | Temporarily suspends the layout logic for the control.
SyncProgressed method Invoked during synchronization to inform the user of progress. This method should return true to cancel synchronization or return false to continue.

For most event states (SyncProgressData.getState()), getMessage is invoked to formulate the message to be displayed, and the sent and received byte counts are updated. The appropriate row counts are updated for the STATE_SENDING_DATA and STATE_RECEIVED_DATA events.

If a STATE_DONE or STATE_CANCELLED event is received, the dialog will be hidden after a brief pause.

If a STATE_ERROR event is received, GetErrorMessage is invoked to formulate the error message, the Cancel button is changed to a Dismiss button, and the dialog is not hidden until the user clicks on the button.

NOTE: The only safe UltraLite .NET API calls are schema inquiry API calls (DatabaseSchema, TableSchema, PublicationSchema, IndexSchema).

ToString (inherited from Form)
Update (inherited from Control) | Causes the control to redraw the invalidated regions within its client area.
Validate (inherited from ContainerControl) | Validates the last invalidated control and its ancestors up through, but not including, the current control.
Public instance events
Member | Description
Activated (inherited from Form) | Occurs when the form is activated in code or by the user.
BackColorChanged (inherited from Control) | Occurs when the value of the System.Windows.Forms.Control.BackColor property changes.
BackgroundImageChanged (inherited from Control) | Occurs when the value of the System.Windows.Forms.Control.BackgroundImage property changes.
BindingContextChanged (inherited from Control) | Occurs when the value of the System.Windows.Forms.BindingContext property changes.
CausesValidationChanged (inherited from Control) | Occurs when the value of the System.Windows.Forms.Control.CausesValidation property changes.
ChangeUICues (inherited from Control) | Occurs when the focus or keyboard user interface (UI) cues change.
Click (inherited from Control) | Occurs when the control is clicked.
Closed (inherited from Form) | Occurs when the form is closed.
Closing (inherited from Form) | Occurs when the form is closing.
ContextMenuChanged (inherited from Control) | Occurs when the value of the System.Windows.Forms.Control.ContextMenu property changes.
ControlAdded (inherited from Control) | Occurs when a new control is added to the System.Windows.Forms.Control.ControlCollection .
ControlRemoved (inherited from Control) | Occurs when a control is removed from the System.Windows.Forms.Control.ControlCollection .
CursorChanged (inherited from Control) | Occurs when the value of the System.Windows.Forms.Control.Cursor property changes.
Deactivate (inherited from Form) | Occurs when the form loses focus and is not the active form.
DockChanged (inherited from Control) | Occurs when the value of the System.Windows.Forms.Control.Dock property changes.
DoubleClick (inherited from Control) | Occurs when the control is double-clicked.
DragDrop (inherited from Control) | Occurs when a drag-and-drop operation is completed.
DragEnter (inherited from Control) | Occurs when an object is dragged into the control's bounds.
DragLeave (inherited from Control) | Occurs when an object is dragged out of the control's bounds.
DragOver (inherited from Control) | Occurs when an object is dragged over the control's bounds.
EnabledChanged (inherited from Control) | Occurs when the System.Windows.Forms.Control.Enabled property value has changed.
Enter (inherited from Control) | Occurs when the control is entered.
FontChanged (inherited from Control) | Occurs when the System.Windows.Forms.Control.Font property value changes.
ForeColorChanged (inherited from Control) | Occurs when the System.Windows.Forms.Control.ForeColor property value changes.
GiveFeedback (inherited from Control) | Occurs during a drag operation.
GotFocus (inherited from Control) | Occurs when the control receives focus.
HandleCreated (inherited from Control) | Occurs when a handle is created for the control.
HandleDestroyed (inherited from Control) | Occurs when the control's handle is in the process of being destroyed.
HelpRequested (inherited from Control) | Occurs when the user requests help for a control.
ImeModeChanged (inherited from Control) | Occurs when the System.Windows.Forms.Control.ImeMode property has changed.
InputLanguageChanged (inherited from Form) | Occurs after the input language of the form has changed.
InputLanguageChanging (inherited from Form) | Occurs when the user attempts to change the input language for the form.
Invalidated (inherited from Control) | Occurs when a control's display requires redrawing.
KeyDown (inherited from Control) | Occurs when a key is pressed while the control has focus.
KeyPress (inherited from Control) | Occurs when a key is pressed while the control has focus.
KeyUp (inherited from Control) | Occurs when a key is released while the control has focus.
Layout (inherited from Control) | Occurs when a control should reposition its child controls.
Leave (inherited from Control) | Occurs when the input focus leaves the control.
Load (inherited from Form) | Occurs before a form is displayed for the first time.
LocationChanged (inherited from Control) | Occurs when the System.Windows.Forms.Control.Location property value has changed.
LostFocus (inherited from Control) | Occurs when the control loses focus.
MaximizedBoundsChanged (inherited from Form) | Occurs when the value of the System.Windows.Forms.Form.MaximizedBounds property has changed.
MaximumSizeChanged (inherited from Form) | Occurs when the value of the System.Windows.Forms.Form.MaximumSize property has changed.
MdiChildActivate (inherited from Form) | Occurs when a multiple document interface (MDI) child form is activated or closed within an MDI application.
MenuComplete (inherited from Form) | Occurs when the menu of a form loses focus.
MenuStart (inherited from Form) | Occurs when the menu of a form receives focus.
MinimumSizeChanged (inherited from Form) | Occurs when the value of the System.Windows.Forms.Form.MinimumSize property has changed.
MouseDown (inherited from Control) | Occurs when the mouse pointer is over the control and a mouse button is pressed.
MouseEnter (inherited from Control) | Occurs when the mouse pointer enters the control.
MouseHover (inherited from Control) | Occurs when the mouse pointer hovers over the control.
MouseLeave (inherited from Control) | Occurs when the mouse pointer leaves the control.
MouseMove (inherited from Control) | Occurs when the mouse pointer is moved over the control.
MouseUp (inherited from Control) | Occurs when the mouse pointer is over the control and a mouse button is released.
MouseWheel (inherited from Control) | Occurs when the mouse wheel moves while the control has focus.
Move (inherited from Control) | Occurs when the control is moved.
Paint (inherited from Control) | Occurs when the control is redrawn.
ParentChanged (inherited from Control) | Occurs when the System.Windows.Forms.Control.Parent property value changes.
QueryAccessibilityHelp (inherited from Control) | Occurs when System.Windows.Forms.AccessibleObject is providing help to accessibility applications.
QueryContinueDrag (inherited from Control) | Occurs during a drag-and-drop operation and allows the drag source to determine whether the drag-and-drop operation should be canceled.
Resize (inherited from Control) | Occurs when the control is resized.
RightToLeftChanged (inherited from Control) | Occurs when the System.Windows.Forms.Control.RightToLeft property value changes.
SizeChanged (inherited from Control) | Occurs when the System.Windows.Forms.Control.Size property value changes.
StyleChanged (inherited from Control) | Occurs when the control style changes.
SystemColorsChanged (inherited from Control) | Occurs when the system colors change.
TabIndexChanged (inherited from Form) |
TabStopChanged (inherited from Control) | Occurs when the System.Windows.Forms.Control.TabStop property value changes.
TextChanged (inherited from Control) | Occurs when the System.Windows.Forms.Control.Text property value changes.
Validated (inherited from Control) | Occurs when the control is finished validating.
Validating (inherited from Control) | Occurs when the control is validating.
VisibleChanged (inherited from Control) | Occurs when the System.Windows.Forms.Control.Visible property value changes.
Protected instance properties
Member | Description
CreateParams (inherited from Form) |
DefaultImeMode (inherited from Form) | Gets the default Input Method Editor (IME) mode supported by the control.
DefaultSize (inherited from Form) |
FontHeight (inherited from Control) | Gets or sets the height of the font of the control.
HScroll (inherited from ScrollableControl) | Gets or sets a value indicating whether the horizontal scroll bar is visible.
MaximizedBounds (inherited from Form) | Gets and sets the size of the form when it is maximized.
RenderRightToLeft (inherited from Control) |
ResizeRedraw (inherited from Control) | Gets or sets a value indicating whether the control redraws itself when resized.
ShowFocusCues (inherited from Control) | Gets a value indicating whether the control should display focus rectangles.
ShowKeyboardCues (inherited from Control) | Gets a value indicating whether the control should display keyboard shortcuts.
VScroll (inherited from ScrollableControl) | Gets or sets a value indicating whether the vertical scroll bar is visible.
Protected instance methods
Member | Description
AccessibilityNotifyClients (inherited from Control) | Notifies the accessibility client applications of the specified System.Windows.Forms.AccessibleEvents for the specified child control.
ActivateMdiChild (inherited from Form) |
AdjustFormScrollbars (inherited from Form) |
ApplyAutoScaling (inherited from Form) |
CenterToParent (inherited from Form) |
CenterToScreen (inherited from Form) |
CreateAccessibilityInstance (inherited from Control) | Creates a new accessibility object for the control.
CreateControlsInstance (inherited from Form) |
CreateHandle (inherited from Form) |
DefWndProc (inherited from Form) |
DestroyHandle (inherited from Control) | Destroys the handle associated with the control.
Dispose method | Clean up any resources being used.
GetErrorMessage method | Returns a message for the STATE_ERROR event state. The message is formatted with the SQL code of the error. This method is called during synchronization.
GetMessage method | Returns a message for the event state. The message is formatted with data.GetTableIndex(), data.GetTableCount(), and data.GetTableTotal(). This method is called during synchronization.
GetScrollState (inherited from ScrollableControl) |
GetString method | Returns localized string (in languages supported by UltraLite.NET).
GetStyle (inherited from Control) | Retrieves the value of the specified control style bit for the control.
GetTopLevel (inherited from Control) | Determines if the control is a top-level control.
InitLayout (inherited from Control) | Called after the control has been added to another container.
InvokeGotFocus (inherited from Control) | Raises the System.Windows.Forms.Control.GotFocus event for the specified control.
InvokeLostFocus (inherited from Control) | Raises the System.Windows.Forms.Control.LostFocus event for the specified control.
InvokeOnClick (inherited from Control) | Raises the System.Windows.Forms.Control.Click event for the specified control.
InvokePaint (inherited from Control) | Raises the System.Windows.Forms.Control.Paint event for the specified control.
InvokePaintBackground (inherited from Control) | Raises the event for the specified control.
IsInputChar (inherited from Control) | Determines if a character is an input character that the control recognizes.
IsInputKey (inherited from Control) | Determines whether the specified key is a regular input key or a special key that requires preprocessing.
NotifyInvalidate (inherited from Control) |
OnActivated (inherited from Form) | Raises the System.Windows.Forms.Form.Activated event.
OnBackColorChanged (inherited from Control) | Raises the System.Windows.Forms.Control.BackColorChanged event.
OnBackgroundImageChanged (inherited from Control) | Raises the System.Windows.Forms.Control.BackgroundImageChanged event.
OnBindingContextChanged (inherited from Control) | Raises the System.Windows.Forms.Control.BindingContextChangedevent.
OnCausesValidationChanged (inherited from Control) | Raises the System.Windows.Forms.Control.CausesValidationChangedevent.
OnChangeUICues (inherited from Control) | Raises the System.Windows.Forms.Control.ChangeUICues event.
OnClick (inherited from Control) | Raises the System.Windows.Forms.Control.Click event.
OnClosed (inherited from Form) | Raises the System.Windows.Forms.Form.Closed event.
OnClosing method | Overide closing behavior to cancel synchronization and not close until synchronization has processed the cancel request.
OnContextMenuChanged (inherited from Control) | Raises the System.Windows.Forms.Control.ContextMenuChangedevent.
OnControlAdded (inherited from Control) | Raises the System.Windows.Forms.Control.ControlAdded event.
OnControlRemoved (inherited from ContainerControl) |
OnCreateControl (inherited from Form) |
OnCursorChanged (inherited from Control) | Raises the System.Windows.Forms.Control.CursorChangedevent.
OnDeactivate (inherited from Form) | Raises the System.Windows.Forms.Form.Deactivate event.
OnDockChanged (inherited from Control) | Raises the System.Windows.Forms.Control.DockChangedevent.
OnDoubleClick (inherited from Control) | Raises the System.Windows.Forms.Control.DoubleClick event.
OnDragDrop (inherited from Control) | Raises the System.Windows.Forms.Control.DragDrop event.
OnDragEnter (inherited from Control) | Raises the System.Windows.Forms.Control.DragEnter event.
OnDragLeave (inherited from Control) | Raises the System.Windows.Forms.Control.DragLeave event.
OnDragOver (inherited from Control) | Raises the System.Windows.Forms.Control.DragOver event.
OnEnabledChanged (inherited from Control) | Raises the System.Windows.Forms.Control.EnabledChanged event.
OnEnter (inherited from Control) | Raises the System.Windows.Forms.Control.Enter event.
OnFontChanged (inherited from Form) |
OnForeColorChanged (inherited from Control) | Raises the System.Windows.Forms.Control.ForeColorChangedevent.
OnGiveFeedback (inherited from Control) | Raises the System.Windows.Forms.Control.GiveFeedback event.
OnGotFocus (inherited from Control) | Raises the System.Windows.Forms.Control.GotFocus event.
OnHandleCreated (inherited from Form) |
OnHandleDestroyed (inherited from Form) |
OnHelpRequested (inherited from Control) | Raises the System.Windows.Forms.Control.HelpRequested event.
OnImeModeChanged (inherited from Control) | Raises the System.Windows.Forms.Control.ImeModeChanged event.
OnInputLanguageChanged (inherited from Form) | Raises the System.Windows.Forms.Form.InputLanguageChanged event.
OnInputLanguageChanging (inherited from Form) | Raises the System.Windows.Forms.Form.InputLanguageChanging event.
OnInvalidated (inherited from Control) | Raises the System.Windows.Forms.Control.Invalidated event.
OnKeyDown (inherited from Control) | Raises the System.Windows.Forms.Control.KeyDown event.
OnKeyPress (inherited from Control) | Raises the System.Windows.Forms.Control.KeyPress event.
OnKeyUp (inherited from Control) | Raises the System.Windows.Forms.Control.KeyUp event.
OnLayout (inherited from ScrollableControl) |
OnLeave (inherited from Control) | Raises the System.Windows.Forms.Control.Leave event.
OnLoad (inherited from Form) | Raises the System.Windows.Forms.Form.Load event.
OnLocationChanged (inherited from Control) | Raises the System.Windows.Forms.Control.LocationChanged event.
OnLostFocus (inherited from Control) | Raises the System.Windows.Forms.Control.LostFocus event.
OnMaximizedBoundsChanged (inherited from Form) | Raises the System.Windows.Forms.Form.MaximizedBoundsChanged event.
OnMaximumSizeChanged (inherited from Form) | Raises the System.Windows.Forms.Form.MaximumSizeChanged event.
OnMdiChildActivate (inherited from Form) | Raises the System.Windows.Forms.Form.MdiChildActivate event.
OnMenuComplete (inherited from Form) | Raises the System.Windows.Forms.Form.MenuComplete event.
OnMenuStart (inherited from Form) | Raises the System.Windows.Forms.Form.MenuStart event.
OnMinimumSizeChanged (inherited from Form) | Raises the System.Windows.Forms.Form.MinimumSizeChanged event.
OnMouseDown (inherited from Control) | Raises the System.Windows.Forms.Control.MouseDown event.
OnMouseEnter (inherited from Control) | Raises the System.Windows.Forms.Control.MouseEnter event.
OnMouseHover (inherited from Control) | Raises the System.Windows.Forms.Control.MouseHover event.
OnMouseLeave (inherited from Control) | Raises the System.Windows.Forms.Control.MouseLeave event.
OnMouseMove (inherited from Control) | Raises the System.Windows.Forms.Control.MouseMove event.
OnMouseUp (inherited from Control) | Raises the System.Windows.Forms.Control.MouseUp event.
OnMouseWheel (inherited from ScrollableControl) |
OnMove (inherited from Control) | Raises the System.Windows.Forms.Control.Move event.
OnNotifyMessage (inherited from Control) | Notifies the control of Windows messages.
OnPaint (inherited from Form) |
OnPaintBackground (inherited from Control) | Paints the background of the control.
OnParentBackColorChanged (inherited from Control) | Raises the System.Windows.Forms.Control.BackColorChanged event when the System.Windows.Forms.Control.BackColor property value of the control's container changes.
OnParentBackgroundImageChanged (inherited from Control) | Raises the System.Windows.Forms.Control.BackgroundImageChanged event when the System.Windows.Forms.Control.BackgroundImage property value of the control's container changes.
OnParentBindingContextChanged (inherited from Control) | Raises the System.Windows.Forms.Control.BindingContextChanged event when the System.Windows.Forms.Control.BindingContext property value of the control's container changes.
OnParentChanged (inherited from Control) | Raises the System.Windows.Forms.Control.ParentChanged event.
OnParentEnabledChanged (inherited from Control) | Raises the System.Windows.Forms.Control.EnabledChanged event when the System.Windows.Forms.Control.Enabled property value of the control's container changes.
OnParentFontChanged (inherited from Control) | Raises the System.Windows.Forms.Control.FontChanged event when the System.Windows.Forms.Control.Font property value of the control's container changes.
OnParentForeColorChanged (inherited from Control) | Raises the System.Windows.Forms.Control.ForeColorChanged event when the System.Windows.Forms.Control.ForeColor property value of the control's container changes.
OnParentRightToLeftChanged (inherited from Control) | Raises the System.Windows.Forms.Control.RightToLeftChanged event when the System.Windows.Forms.Control.RightToLeft property value of the control's container changes.
OnParentVisibleChanged (inherited from Control) | Raises the System.Windows.Forms.Control.VisibleChanged event when the System.Windows.Forms.Control.Visible property value of the control's container changes.
OnQueryContinueDrag (inherited from Control) | Raises the System.Windows.Forms.Control.QueryContinueDrag event.
OnResize (inherited from Form) |
OnRightToLeftChanged (inherited from Control) | Raises the System.Windows.Forms.Control.RightToLeftChangedevent.
OnSizeChanged (inherited from Control) | Raises the System.Windows.Forms.Control.SizeChanged event.
OnStyleChanged (inherited from Form) |
OnSystemColorsChanged (inherited from Control) | Raises the System.Windows.Forms.Control.SystemColorsChanged event.
OnTabIndexChanged (inherited from Control) | Raises the System.Windows.Forms.Control.TabIndexChanged event.
OnTabStopChanged (inherited from Control) | Raises the System.Windows.Forms.Control.TabStopChanged event.
OnTextChanged (inherited from Form) |
OnValidated (inherited from Control) | Raises the System.Windows.Forms.Control.Validated event.
OnValidating (inherited from Control) | Raises the System.Windows.Forms.Control.Validating event.
OnVisibleChanged (inherited from Form) |
ProcessCmdKey (inherited from Form) |
ProcessDialogChar (inherited from ContainerControl) |
ProcessDialogKey (inherited from Form) |
ProcessKeyEventArgs (inherited from Control) | Processes a key message and generates the appropriate control events.
ProcessKeyPreview (inherited from Form) |
ProcessMnemonic (inherited from ContainerControl) |
ProcessTabKey (inherited from Form) |
RaiseDragEvent (inherited from Control) |
RaiseKeyEvent (inherited from Control) |
RaiseMouseEvent (inherited from Control) |
RaisePaintEvent (inherited from Control) |
RecreateHandle (inherited from Control) | Forces the re-creation of the handle for the control.
ResetMouseEventArgs (inherited from Control) |
ResetValues method | Initializes displayed values of this dialog.
RtlTranslateAlignment (inherited from Control) | Converts the specified System.Windows.Forms.HorizontalAlignment to the appropriate System.Windows.Forms.HorizontalAlignment to support right-to-left text.
RtlTranslateAlignment (inherited from Control) | Converts the specified System.Windows.Forms.LeftRightAlignment to the appropriate System.Windows.Forms.LeftRightAlignment to support right-to-left text.
RtlTranslateAlignment (inherited from Control) | Converts the specified System.Drawing.ContentAlignment to the appropriate System.Drawing.ContentAlignment to support right-to-left text.
RtlTranslateContent (inherited from Control) | Converts the specified System.Drawing.ContentAlignment to the appropriate System.Drawing.ContentAlignment to support right-to-left text.
RtlTranslateHorizontal (inherited from Control) | Converts the specified System.Windows.Forms.HorizontalAlignment to the appropriate System.Windows.Forms.HorizontalAlignment to support right-to-left text.
RtlTranslateLeftRight (inherited from Control) | Converts the specified System.Windows.Forms.LeftRightAlignment to the appropriate System.Windows.Forms.LeftRightAlignment to support right-to-left text.
ScaleCore (inherited from Form) |
Select (inherited from Form) |
SetBoundsCore (inherited from Form) |
SetClientSizeCore (inherited from Form) |
SetDisplayRectLocation (inherited from ScrollableControl) |
SetScrollState (inherited from ScrollableControl) |
SetStyle (inherited from Control) | Sets the specified style bit to the specified value.
SetTopLevel (inherited from Control) | Sets the control as the top-level control.
SetVisibleCore (inherited from Form) |
UpdateBounds (inherited from Control) | Updates the bounds of the control with the current size and location.
UpdateBounds (inherited from Control) | Updates the bounds of the control with the specified size and location.
UpdateBounds (inherited from Control) | Updates the bounds of the control with the specified size, location, and client size.
UpdateDefaultButton (inherited from Form) |
UpdateStyles (inherited from Control) | Forces the assigned styles to be reapplied to the control.
UpdateZOrder (inherited from Control) | Updates the control in its parent's z-order.
WndProc (inherited from Form) |


SyncProgressDialog constructor

Construct a SyncProgressDialog instance to synchronize the UltraLite database using the specified connection.

Prototypes

' Visual Basic
Public Sub New( _
ByVal dbMgr As DatabaseManager, _
ByVal conn As Connection _
)

// C#
public SyncProgressDialog(
DatabaseManager dbMgr,
Connection conn
);

Parameters

  • dbMgr application's DatabaseManager.

  • conn connection on which to synchronize.

Remarks

This dialog should be shown as a modal dialog using ShowDialog method.


SQLCode property

The SQL error code from the last synchronization.

Prototypes

' Visual Basic
Public Readonly Property SQLCode As SQLCode

// C#
public SQLCode SQLCode {get;}

Property value

SQL error code

See also
  • SyncProgressDialog class
  • SyncProgressDialog members
  • SQLCode property


GetErrorMessage method

Returns a message for the STATE_ERROR event state. The message is formatted with the SQL code of the error.

This method is called during synchronization.

Prototypes

' Visual Basic
Protected Function GetErrorMessage( _
ByVal sqlCode As SQLCode, _
ByVal errMsg As String, _
ByVal uploadOK As Boolean _
) As String

// C#
protected string GetErrorMessage(
SQLCode sqlCode,
string errMsg,
bool uploadOK
);

Parameters

  • sqlCode SQL code of the error.

  • errMsg error message associated with the SQL code.

  • uploadOK status of upload.

Return value

message for event.

See also
  • SyncProgressDialog class
  • SyncProgressDialog members
  • SQLCode property
  • SyncResult property


GetMessage method

Returns a message for the event state. The message is formatted with data.GetTableIndex(), data.GetTableCount(), and data.GetTableTotal().

This method is called during synchronization.

Prototypes

' Visual Basic
Protected Function GetMessage( _
ByVal progress As SyncProgressData _
) As String

// C#
protected string GetMessage(
SyncProgressData progress
);

Parameters

  • progress synchronization progress data.

Return value

message for event.


GetString method

Returns localized string (in languages supported by UltraLite.NET).

Prototypes

' Visual Basic
Protected Function GetString( _
ByVal name As String _
) As String

// C#
protected string GetString(
string name
);

Parameters

  • name name of string.

Return value

localized string.


OnClosing method

Overide closing behavior to cancel synchronization and not close until synchronization has processed the cancel request.

Prototypes

' Visual Basic
Overrides Protected Sub OnClosing( _
ByVal e As System.ComponentModel.CancelEventArgs _
)

// C#
protected override void OnClosing(
System.ComponentModel.CancelEventArgs e
);

Parameters

  • e a CancelEventArgs that contains the event data.


ResetValues method

Initializes displayed values of this dialog.

Prototypes

' Visual Basic
Protected Sub ResetValues()

// C#
protected void ResetValues();


ShowDialog method

Shows the form as a modal dialog with the specified parent and performs synchronization. The dialog will close when synchronization has completed.

Prototypes

' Visual Basic
Overloads Public Function ShowDialog( _
ByVal parent As System.Windows.Forms.Form _
) As System.Windows.Forms.DialogResult

// C#
public System.Windows.Forms.DialogResult ShowDialog(
System.Windows.Forms.Form parent
);

Parameters

  • parent any System.Windows.Forms.Form object that represents the top-level window that will own the modal dialog.

Return value

System.Windows.Forms.DialogResult.OK if synchronization completed successfully, System.Windows.Forms.DialogResult.Cancel if synchronization was cancelled by the user, and System.Windows.Forms.DialogResult.Abort if an error occurred during synchronization (see SQLCode property for more specific error reporting).

Remarks

This method is recommended over ShowDialog().

The parent will be disabled while this dialog is active.


ShowDialog method

Shows the form as a modal dialog with no parent window and performs synchronization. The dialog will close when synchronization has completed.

Prototypes

' Visual Basic
Overloads Public Function ShowDialog() As System.Windows.Forms.DialogResult

// C#
public System.Windows.Forms.DialogResult ShowDialog();

Return value

System.Windows.Forms.DialogResult.OK if synchronization completed successfully, System.Windows.Forms.DialogResult.Cancel if synchronization was cancelled by the user, and System.Windows.Forms.DialogResult.Abort if an error occurred during synchronization (see SQLCode property for more specific error reporting).

Remarks

ShowDialog method is recommended over this method.


SyncProgressed method

Invoked during synchronization to inform the user of progress. This method should return true to cancel synchronization or return false to continue.

For most event states (SyncProgressData.getState()), getMessage is invoked to formulate the message to be displayed, and the sent and received byte counts are updated. The appropriate row counts are updated for the STATE_SENDING_DATA and STATE_RECEIVED_DATA events.

If a STATE_DONE or STATE_CANCELLED event is received, the dialog will be hidden after a brief pause.

If a STATE_ERROR event is received, GetErrorMessage is invoked to formulate the error message, the Cancel button is changed to a Dismiss button, and the dialog is not hidden until the user clicks on the button.

NOTE: The only safe UltraLite .NET API calls are schema inquiry API calls (DatabaseSchema, TableSchema, PublicationSchema, IndexSchema).

Prototypes

' Visual Basic
Public Function SyncProgressed( _
ByVal data As SyncProgressData _
) As Boolean _
Implements SyncProgressListener.SyncProgressed

// C#
public bool SyncProgressed(
SyncProgressData data
);

Parameters

  • data object containing latest synchronization progress data.

Return value

true to cancel synchronization, or false to continue.

Implements

SyncProgressListener interface


SyncProgressListener interface

The listener interface for receiving synchronization progress events.

Prototypes

' Visual Basic
Public Interface SyncProgressListener

// C#
public interface SyncProgressListener

See also
  • SyncProgressListener members
  • Synchronize method


SyncProgressListener members

Public instance methods
Member | Description
SyncProgressed method | Invoked during synchronization to inform the user of progress. This method should return true to cancel synchronization or return false to continue.


SyncProgressed method

Invoked during synchronization to inform the user of progress. This method should return true to cancel synchronization or return false to continue.

Prototypes

' Visual Basic
Public Function SyncProgressed( _
ByVal data As SyncProgressData _
) As Boolean

// C#
public bool SyncProgressed(
SyncProgressData data
);

Parameters

  • data object containing the latest synchronization progress data.

Return value

This method should return true to cancel synchronization or return false to continue.

Remarks

No UltraLite.NET API methods should be invoked during a SyncProgressed call.


SyncProgressState enumeration

Enumerates all the states that can occur while synchronizing.

Prototypes

' Visual Basic
Public Enum SyncProgressState

// C#
public enum SyncProgressState

Members
Member | Description
STATE_CANCELLED | Synchronization has been cancelled.
STATE_COMMITTING_DOWNLOAD | The download is being committed. The final count of rows received is included with this event. See ReceivedBytes property, ReceivedInserts property, ReceivedUpdates property, and ReceivedDeletes property.
STATE_CONNECTING | The synchronization stream has been built, but not yet opened.
STATE_DISCONNECTING | The synchronization stream is about to be closed.
STATE_DONE | Synchronization has successfully completed. The connection's SyncResult property object has been updated.
STATE_ERROR | Synchronization has completed, but an error occurred. Check SyncResult property, ErrorMessage property, and SQLCode property for details.
STATE_FINISHING_UPLOAD | The upload is completing. The final count of rows sent is included with this event. See SentBytes property, SentInserts property, SentUpdates property, and SentDeletes property.
STATE_LAST | Last state entered by synchronization. This state will always be entered and always after any other state. Other SyncProgressData fields may not contain valid data.
STATE_RECEIVING_DATA | Data for the current table is being received. ReceivedBytes property, ReceivedInserts property, ReceivedUpdates property, and ReceivedDeletes property have been updated.
STATE_RECEIVING_TABLE | A table is being received. Progress can be monitored using TableIndex property and TableCount property.
STATE_RECEIVING_UPLOAD_ACK | An acknowledgement that the upload is complete is being received.
STATE_ROLLING_BACK_DOWNLOAD | Synchronization is rolling back the download because an error was encountered during the download. The error will be reported with a subsequent STATE_ERROR progress report.
STATE_SENDING_DATA | Data for the current table is being sent. SentBytes property, SentInserts property, SentUpdates property, and SentDeletes property have been updated.
STATE_SENDING_DOWNLOAD_ACK | An acknowledgement that the download is complete is being sent.
STATE_SENDING_HEADER | The synchronization stream has been opened and the header is about to be sent.
STATE_SENDING_TABLE | A table is being sent. Progress can be monitored using TableIndex property and TableCount property.
STATE_STARTING | No synchronization actions have been taken yet.
See also
  • SyncProgressData class


SyncResult class

Represents the status of the last synchronization.

Prototypes

' Visual Basic
Public Class SyncResult

// C#
public class SyncResult

Remarks

This class cannot be directly instantiated. Each connection has its own SyncResult instance, attached as its SyncResult property property. A SyncResult instance is only valid while that connection is open.

See also
  • SyncResult members
  • SyncResult property
  • Synchronize method

SyncResult members
AuthStatus property
AuthValue property
IgnoredRows property
PartialDownloadRetained property
StreamErrorCode property
StreamErrorContext property
StreamErrorID property
StreamErrorSystem property
Timestamp property
UploadOK property
Finalize method


SyncResult members

Public instance properties
Member | Description
AuthStatus property | The authorization status code for the last synchronization attempt. See AuthStatusCode enumeration for possible values.
AuthValue property | The return value from custom user authentication synchronization scripts.
IgnoredRows property | True if any uploaded rows were ignored during the last synchronization, false if no rows were ignored.
PartialDownloadRetained property | True if a download was interrupted and the partial download was retained. False if the download was not interrupted or if the partial download was rolled back.
StreamErrorCode property | Returns the error reported by the stream itself. See StreamErrorCode property for a list of known codes.
StreamErrorContext property | The basic network operation being performed when the stream error occurred. See StreamErrorContext property for a list of known contexts.
StreamErrorID property | ID of network layer reporting an error. See StreamErrorID property for a list of known IDs.
StreamErrorSystem property | The stream error system-specific code.
Timestamp property | The timestamp of the last synchronization.
UploadOK property | True if the last upload synchronization was successful, false if the last upload synchronization was unsuccessful.
Protected instance methods
Member | Description
Finalize method | Destructor which cleans up the associated JNI state.


AuthStatus property

The authorization status code for the last synchronization attempt. See AuthStatusCode enumeration for possible values.

Prototypes

' Visual Basic
Public Readonly Property AuthStatus As AuthStatusCode

// C#
public AuthStatusCode AuthStatus {get;}


AuthValue property

The return value from custom user authentication synchronization scripts.

Prototypes

' Visual Basic
Public Readonly Property AuthValue As Long

// C#
public long AuthValue {get;}


IgnoredRows property

True if any uploaded rows were ignored during the last synchronization, false if no rows were ignored.

Prototypes

' Visual Basic
Public Readonly Property IgnoredRows As Boolean

// C#
public bool IgnoredRows {get;}

See also
  • SyncResult class
  • SyncResult members
  • DownloadOnly property


PartialDownloadRetained property

True if a download was interrupted and the partial download was retained. False if the download was not interrupted or if the partial download was rolled back.

Prototypes

' Visual Basic
Public Readonly Property PartialDownloadRetained As Boolean

// C#
public bool PartialDownloadRetained {get;}

See also
  • SyncResult class
  • SyncResult members
  • KeepPartialDownload property


StreamErrorCode property

Returns the error reported by the stream itself. See StreamErrorCode property for a list of known codes.

Prototypes

' Visual Basic
Public Readonly Property StreamErrorCode As StreamErrorCode

// C#
public StreamErrorCode StreamErrorCode {get;}


StreamErrorContext property

The basic network operation being performed when the stream error occurred. See StreamErrorContext property for a list of known contexts.

Prototypes

' Visual Basic
Public Readonly Property StreamErrorContext As StreamErrorContext

// C#
public StreamErrorContext StreamErrorContext {get;}


StreamErrorID property

ID of network layer reporting an error. See StreamErrorID property for a list of known IDs.

Prototypes

' Visual Basic
Public Readonly Property StreamErrorID As StreamErrorID

// C#
public StreamErrorID StreamErrorID {get;}


StreamErrorSystem property

The stream error system-specific code.

Prototypes

' Visual Basic
Public Readonly Property StreamErrorSystem As Integer

// C#
public int StreamErrorSystem {get;}


Timestamp property

The timestamp of the last synchronization.

Prototypes

' Visual Basic
Public Readonly Property Timestamp As Date

// C#
public DateTime Timestamp {get;}


UploadOK property

True if the last upload synchronization was successful, false if the last upload synchronization was unsuccessful.

Prototypes

' Visual Basic
Public Readonly Property UploadOK As Boolean

// C#
public bool UploadOK {get;}


Table class

Represents a table in an UltraLite database.

Prototypes

' Visual Basic
Public Class Table
Inherits Cursor

// C#
public class Table :
Cursor

Remarks

This class cannot be directly instantiated. Tables are created using the GetTable method method of the Connection class class.

Table members
Schema property
AppendBytes method
AppendChars method
Delete method
DeleteAllRows method
Finalize method
FindBegin method
FindFirst method
FindFirst method
FindLast method
FindLast method
FindNext method
FindNext method
FindPrevious method
FindPrevious method
Insert method
InsertBegin method
LookupBackward method
LookupBackward method
LookupBegin method
LookupForward method
LookupForward method
Open method
Open method
SetBoolean method
SetBytes method
SetDouble method
SetFloat method
SetInt method
SetLong method
SetNull method
SetShort method
SetString method
SetTime method
SetTimestamp method
SetToDefault method
SetUInt method
SetULong method
SetUShort method
SetUUID method
Truncate method
Update method
UpdateBegin method


Table members

Public instance properties
Member | Description
IsBOF property (inherited from Cursor) | Returns true if the current row position is before the first row.
IsEOF property (inherited from Cursor) | Returns true if the current row position is after the last row.
IsOpen property (inherited from Cursor) | Checks whether this cursor is currently open.
RowCount property (inherited from Cursor) | Returns the number of rows in the cursor.
Schema property | Holds the schema of this table. This property is only valid while its connection is open.
Public instance methods
Member | Description
AppendBytes method | Appends the specified subset of the specified array of Bytes to the new value for the specified SQLType enumeration column.
AppendChars method | Appends the specified subset of the specified array of System.Chars to the new value for the specified SQLType enumeration column.
Close method (inherited from Cursor) | Closes the cursor.
Delete method | Deletes the current row.
DeleteAllRows method | Deletes all rows in the table.
Fill method (inherited from Cursor) | Fills a ADO .NET DataTable object with the rows in the cursor.
FindBegin method | Prepares to perform a new Find on this table.
FindFirst method | Move forwards through the table from the beginning, looking for a row that exactly matches a value or full set of values in the current index.
FindFirst method | Move forwards through the table from the beginning, looking for a row that exactly matches a value or partial set of values in the current index.
FindLast method | Move backwards through the table from the end, looking for a row that exactly matches a value or full set of values in the current index.
FindLast method | Move backwards through the table from the end, looking for a row that exactly matches a value or partial set of values in the current index.
FindNext method | Continues a FindFirst method search by moving forward through the table from the current position, looking to see if the next row exactly matches a value or full set of values in the current index.
FindNext method | Continues a FindFirst method search by moving forward through the table from the current position, looking to see if the next row exactly matches a value or partial set of values in the current index.
FindPrevious method | Continues a FindLast method search by moving backward through the table from the current position, looking to see if the previous row exactly matches a value or full set of values in the current index.
FindPrevious method | Continues a FindLast method search by moving backward through the table from the current position, looking to see if the previous row exactly matches a value or partial set of values in the current index.
GetBoolean method (inherited from Cursor) | Returns the value for the specified column as a Boolean.
GetBytes method (inherited from Cursor) | Returns the value for the specified column as an array of Bytes. Only valid for columns of type SQLType enumeration, SQLType enumeration, or SQLType enumeration.
GetBytes method (inherited from Cursor) | Copies a subset of the value for the specified SQLType enumeration column, beginning at the specified offset, to the specified offset of the destination Byte array.
GetChars method (inherited from Cursor) | Copies a subset of the value for the specified SQLType enumeration column, beginning at the specified offset, to the specified offset of the destination System.Char array.
GetDouble method (inherited from Cursor) | Returns the value for the specified column as a Double.
GetFloat method (inherited from Cursor) | Returns the value for the specified column as a Single.
GetInt method (inherited from Cursor) | Returns the value for the specified column as an Int32.
GetLong method (inherited from Cursor) | Returns the value for the specified column as an Int64.
GetShort method (inherited from Cursor) | Returns the value for the specified column as an Int16.
GetString method (inherited from Cursor) | Returns the value for the specified column as a String.
GetTime method (inherited from Cursor) | Returns the value for the specified column as a TimeSpan with millisecond accuracy.
GetTimestamp method (inherited from Cursor) | Returns the value for the specified column as a DateTime with millisecond accuracy.
GetUInt method (inherited from Cursor) | Returns the value for the specified column as a UInt32.
GetULong method (inherited from Cursor) | Returns the value for the specified column as a UInt64.
GetUShort method (inherited from Cursor) | Returns the value for the specified column as a UInt16.
GetUUID method (inherited from Cursor) | Returns the value for the specified column as a UUID (Guid).
Insert method | Inserts a new row with the current column values (specified using the set methods). Each insert must be preceded by a call to InsertBegin method.
InsertBegin method | Prepares to insert a new row into this table by setting all current column values to their default values.
IsNull method (inherited from Cursor) | Checks whether the value from the specified column is NULL.
LookupBackward method | Move backwards through the table from the end, looking for a row that matches or is less than a value or full set of values in the current index.
LookupBackward method | Move backwards through the table from the beginning, looking for a row that matches or is less than a value or partial set of values in the current index.
LookupBegin method | Prepares to perform a new lookup on this table. The value(s) to search for are specified by calling the appropriate setType method(s) on the columns in the index this table was opened with.
LookupForward method | Move forwards through the table from the beginning, looking for a row that matches or is greater than a value or full set of values in the current index.
LookupForward method | Move forwards through the table from the beginning, looking for a row that matches or is greater than a value or partial set of values in the current index.
MoveAfterLast method (inherited from Cursor) | Position to after the last row of the cursor.
MoveBeforeFirst method (inherited from Cursor) | Position to before the first row of the cursor.
MoveFirst method (inherited from Cursor) | Position to the first row of the cursor.
MoveLast method (inherited from Cursor) | Position to the last row of the cursor.
MoveNext method (inherited from Cursor) | Position to the next row or after last.
MovePrevious method (inherited from Cursor) | Position to the previous row or before first.
MoveRelative method (inherited from Cursor) | Position relative to the current row.
Open method | Opens this table for data access using its primary key.
Open method | Opens this table for data access using the specified index.
SetBoolean method | Sets the value for the specified column using a Boolean.
SetBytes method | Sets the value for the specified column using an array of Bytes.
SetDouble method | Sets the value for the specified column using a Double.
SetFloat method | Sets the value for the specified column using a Single.
SetInt method | Sets the value for the specified column using an Int32.
SetLong method | Sets the value for the specified column using an Int64.
SetNull method | Sets a column to NULL.
SetShort method | Sets the value for the specified column using an Int16.
SetString method | Sets the value for the specified column using a String.
SetTime method | Sets the value for the specified column using a TimeSpan.
SetTimestamp method | Sets the value for the specified column using a DateTime.
SetToDefault method | Sets the value for the specified column to its default value.
SetUInt method | Sets the value for the specified column using an UInt32.
SetULong method | Sets the value for the specified column using a UInt64.
SetUShort method | Sets the value for the specified column using a UInt16.
SetUUID method | Sets the value for the specified column using a Guid.
Truncate method | Deletes all rows in the table while temporarily activating a stop synchronization delete.
Update method | Updates the current row with the current column values (specified using the set methods). Each update must be preceded by a call to UpdateBegin method.
UpdateBegin method | Prepares to update the current row in this table.
Protected instance methods
Member | Description
Finalize method | Finalize method


Schema property

Holds the schema of this table. This property is only valid while its connection is open.

Prototypes

' Visual Basic
Public Readonly Property Schema As TableSchema

// C#
public TableSchema Schema {get;}

See also
  • Table class
  • Table members
  • TableSchema class


AppendBytes method

Appends the specified subset of the specified array of Bytes to the new value for the specified SQLType enumeration column.

Prototypes

' Visual Basic
Public Sub AppendBytes( _
ByVal columnID As Short, _
ByVal val As Byte(), _
ByVal srcOffset As Integer, _
ByVal count As Integer _
)

// C#
public void AppendBytes(
short columnID,
byte[] val,
int srcOffset,
int count
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the value to append to the current new value for the column.

  • srcOffset start position in the source array.

  • count the number of bytes to be copied.

Remarks

The bytes at position srcOffset (starting from 0) through srcOffset+count-1 of the array val are appended to the value for the specified column.

When inserting, InsertBegin method initializes the new value to the column's default value. The data in the row is not actually changed until you execute an Insert method, and that change is not permanent until it is committed.

When updating, the first append on a column will clear the current value prior to appending the new value.

If any of the following are true, a SQLException class with code SQLCode enumeration is thrown and the destination is not modified: For other errors, a SQLException class with the appropriate error code is thrown.

  • val is null.
  • srcOffset is negative.
  • count is negative.
  • srcOffset+count is greater than val.Length.
Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


AppendChars method

Appends the specified subset of the specified array of System.Chars to the new value for the specified SQLType enumeration column.

Prototypes

' Visual Basic
Public Sub AppendChars( _
ByVal columnID As Short, _
ByVal val As Char(), _
ByVal srcOffset As Integer, _
ByVal count As Integer _
)

// C#
public void AppendChars(
short columnID,
char[] val,
int srcOffset,
int count
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val The value to append to the current new value for the column.

  • srcOffset start position in the source array.

  • count the number of bytes to be copied.

Remarks

The characters at position srcOffset (starting from 0) through srcOffset+count-1 of the array val are appended to the value for the specified column. When inserting, InsertBegin method initializes the new value to the column's default value. The data in the row is not actually changed until you execute an Insert method, and that change is not permanent until it is committed.

When updating, the first append on a column will clear the current value prior to appending the new value.

If any of the following is true, a SQLException class with code SQLCode enumeration is thrown and the destination is not modified: For other errors, a SQLException class with the appropriate error code is thrown.

  • val is null.
  • srcOffset is negative.
  • count is negative.
  • srcOffset+count is greater than value.Length.
Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


Delete method

Deletes the current row.

Prototypes

' Visual Basic
Public Sub Delete()

// C#
public void Delete();

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • StartSynchronizationDelete method
  • StopSynchronizationDelete method
  • AutoCommit field


DeleteAllRows method

Deletes all rows in the table.

Prototypes

' Visual Basic
Public Sub DeleteAllRows()

// C#
public void DeleteAllRows();

Remarks

In some applications, it can be useful to delete all rows from a table before downloading a new set of data into the table. Rows can be deleted from the UltraLite database without being deleted from the consolidated database using StopSynchronizationDelete method.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • Truncate method
  • AutoCommit field


FindBegin method

Prepares to perform a new Find on this table.

Prototypes

' Visual Basic
Public Sub FindBegin()

// C#
public void FindBegin();

Remarks

The value(s) to search for are specified by calling the appropriate setType method(s) on the columns in the index this table was opened with.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • FindFirst method
  • FindFirst method
  • FindLast method
  • FindLast method


FindFirst method

Move forwards through the table from the beginning, looking for a row that exactly matches a value or full set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindFirst() As Boolean

// C#
public bool FindFirst();

Return value

true if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that exactly matches the index value. On failure the cursor position is after the last row (IsEOF property).

Each search must be preceded by a call to FindBegin method.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • FindBegin method
  • FindNext method
  • FindPrevious method


FindFirst method

Move forwards through the table from the beginning, looking for a row that exactly matches a value or partial set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindFirst( _
ByVal numColumns As Short _
) As Boolean

// C#
public bool FindFirst(
short numColumns
);

Parameters

  • numColumns for composite indexes, the number of columns to use in the find. For example, if you have a three column index, and you want to look up a value that matches based on the first column only, you should set the value for the first column, and then supply a numColumns value of 1.

Return value

true if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that exactly matches the index value. On failure the cursor position is after the last row (IsEOF property).

Each search must be preceded by a call to FindBegin method.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • FindBegin method
  • FindNext method
  • FindPrevious method


FindLast method

Move backwards through the table from the end, looking for a row that exactly matches a value or full set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindLast() As Boolean

// C#
public bool FindLast();

Return value

true if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row found that exactly matches the index value. On failure the cursor position is before the first row (IsBOF property).

Each search must be preceded by a call to FindBegin method.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • FindBegin method
  • FindNext method
  • FindPrevious method


FindLast method

Move backwards through the table from the end, looking for a row that exactly matches a value or partial set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindLast( _
ByVal numColumns As Short _
) As Boolean

// C#
public bool FindLast(
short numColumns
);

Parameters

  • numColumns for composite indexes, the number of columns to use in the find. For example, if you have a three column index, and you want to find a value that matches based on the first column only, you should set the value for the first column, then supply a numColumns value of 1.

Return value

true if successful, false otherwise

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row found that exactly matches the index value. On failure the cursor position is before the first row (IsBOF property).

Each search must be preceded by a call to FindBegin method.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • FindBegin method
  • FindNext method
  • FindPrevious method


FindNext method

Continues a FindFirst method search by moving forward through the table from the current position, looking to see if the next row exactly matches a value or full set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindNext() As Boolean

// C#
public bool FindNext();

Return value

true if successful, false otherwise.

Remarks

The cursor is left on the next row if it exactly matches the index value. On failure the cursor position is after the last row (IsEOF property).

FindNext behavior is undefined if the column values being searched for are modified during a row update.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • FindFirst method


FindNext method

Continues a FindFirst method search by moving forward through the table from the current position, looking to see if the next row exactly matches a value or partial set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindNext( _
ByVal numColumns As Short _
) As Boolean

// C#
public bool FindNext(
short numColumns
);

Parameters

  • numColumns for composite indexes, the number of columns to use in the find. For example, if you have a three column index, and you want to find a value that matches based on the first column only, you should set the value for the first column, and then supply a numColumns value of 1.

Return value

true if successful, false otherwise.

Remarks

The cursor is left on the next row if it exactly matches the index value. On failure the cursor position is after the last row (IsEOF property).

FindNext behavior is undefined if the column values being searched for are modified during a row update.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • FindFirst method


FindPrevious method

Continues a FindLast method search by moving backward through the table from the current position, looking to see if the previous row exactly matches a value or full set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindPrevious() As Boolean

// C#
public bool FindPrevious();

Return value

true if successful, false otherwise.

Remarks

The cursor is left on the previous row if it exactly matches the index value. On failure the cursor position is before the first row (IsBOF property).

FindPrevious behavior is undefined if the column values being searched for are modified during a row update.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • FindLast method


FindPrevious method

Continues a FindLast method search by moving backward through the table from the current position, looking to see if the previous row exactly matches a value or partial set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function FindPrevious( _
ByVal numColumns As Short _
) As Boolean

// C#
public bool FindPrevious(
short numColumns
);

Parameters

  • numColumns for composite indexes, the number of columns to use in the find. For example, if you have a three column index, and you want to look up a value that matches based on the first column only, you should set the value for the first column, then supply a numColumns value of 1.

Return value

true if successful, false otherwise.

Remarks

The cursor is left on the previous row if it exactly matches the index value. On failure the cursor position is before the first row (IsBOF property).

FindPrevious behavior is undefined if the column values being searched for are modified during a row update.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • FindLast method


Insert method

Inserts a new row with the current column values (specified using the set methods).

Each insert must be preceded by a call to InsertBegin method.

Prototypes

' Visual Basic
Public Sub Insert()

// C#
public void Insert();

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • AutoCommit field


InsertBegin method

Prepares to insert a new row into this table by setting all current column values to their default values.

Prototypes

' Visual Basic
Public Sub InsertBegin()

// C#
public void InsertBegin();

Remarks

Call the appropriate SetType or AppendType method(s) to specify the non-default values that are to be inserted.

The row is not actually inserted and the data in the row is not actually changed until you execute the Insert method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • Insert method


LookupBackward method

Move backwards through the table from the end, looking for a row that matches or is less than a value or full set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function LookupBackward() As Boolean

// C#
public bool LookupBackward();

Return value

true if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is less than the index value. On failure (no rows less than the value being looked for) the cursor position is before the first row (IsBOF property).

Each search must be preceded by a call to LookupBegin method.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • LookupBegin method


LookupBackward method

Move backwards through the table from the beginning, looking for a row that matches or is less than a value or partial set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function LookupBackward( _
ByVal numColumns As Short _
) As Boolean

// C#
public bool LookupBackward(
short numColumns
);

Parameters

  • numColumns for composite indexes, the number of columns to use in the lookup. For example, if you have a three column index, and you want to look up a value that matches based on the first column only, you should set the value for the first column, and then supply a numColumns value of 1.

Return value

true if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is less than the index value. On failure (no rows less than the value being looked for) the cursor position is before the first row (IsBOF property).

Each search must be preceded by a call to LookupBegin method.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • LookupBegin method


LookupBegin method

Prepares to perform a new lookup on this table. The value(s) to search for are specified by calling the appropriate setType method(s) on the columns in the index this table was opened with.

Prototypes

' Visual Basic
Public Sub LookupBegin()

// C#
public void LookupBegin();

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • LookupForward method
  • LookupForward method
  • LookupBackward method
  • LookupBackward method


LookupForward method

Move forwards through the table from the beginning, looking for a row that matches or is greater than a value or full set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function LookupForward() As Boolean

// C#
public bool LookupForward();

Return value

true if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is greater than the index value. On failure (no rows greater than the value being looked for) the cursor position is after the last row (IsEOF property).

Each search must be preceded by a call to LookupBegin method.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • LookupBegin method


LookupForward method

Move forwards through the table from the beginning, looking for a row that matches or is greater than a value or partial set of values in the current index.

Prototypes

' Visual Basic
Overloads Public Function LookupForward( _
ByVal numColumns As Short _
) As Boolean

// C#
public bool LookupForward(
short numColumns
);

Parameters

  • numColumns for composite indexes, the number of columns to use in the lookup. For example, if you have a three column index, and you want to look up a value that matches based on the first column only, you should set the value for the first column, and then supply a numColumns value of 1.

Return value

true if successful, false otherwise.

Remarks

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is greater than the index value. On failure (no rows greater than the value being looked for) the cursor position is after the last row (IsEOF property).

Each search must be preceded by a call to LookupBegin method.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • LookupBegin method


Open method

Opens this table for data access using its primary key.

Prototypes

' Visual Basic
Overloads Public Sub Open()

// C#
public void Open();

Exceptions

  • SQLException class - A SQL error occurred.


Open method

Opens this table for data access using the specified index.

Prototypes

' Visual Basic
Overloads Public Sub Open( _
ByVal index As String _
)

// C#
public void Open(
string index
);

Parameters

  • index name of index to open the table with. If null, the primary key is used.

Exceptions

  • SQLException class - A SQL error occurred.


SetBoolean method

Sets the value for the specified column using a Boolean.

Prototypes

' Visual Basic
Public Sub SetBoolean( _
ByVal columnID As Short, _
ByVal val As Boolean _
)

// C#
public void SetBoolean(
short columnID,
bool val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetBytes method

Sets the value for the specified column using an array of Bytes.

Prototypes

' Visual Basic
Public Sub SetBytes( _
ByVal columnID As Short, _
ByVal val As Byte() _
)

// C#
public void SetBytes(
short columnID,
byte[] val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

Only suitable for columns of type SQLType enumeration or SQLType enumeration, or for columns of type SQLType enumeration when val is of length 16. The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetDouble method

Sets the value for the specified column using a Double.

Prototypes

' Visual Basic
Public Sub SetDouble( _
ByVal columnID As Short, _
ByVal val As Double _
)

// C#
public void SetDouble(
short columnID,
double val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetFloat method

Sets the value for the specified column using a Single.

Prototypes

' Visual Basic
Public Sub SetFloat( _
ByVal columnID As Short, _
ByVal val As Single _
)

// C#
public void SetFloat(
short columnID,
float val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetInt method

Sets the value for the specified column using an Int32.

Prototypes

' Visual Basic
Public Sub SetInt( _
ByVal columnID As Short, _
ByVal val As Integer _
)

// C#
public void SetInt(
short columnID,
int val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetLong method

Sets the value for the specified column using an Int64.

Prototypes

' Visual Basic
Public Sub SetLong( _
ByVal columnID As Short, _
ByVal val As Long _
)

// C#
public void SetLong(
short columnID,
long val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetShort method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetNull method

Sets a column to NULL.

Prototypes

' Visual Basic
Public Sub SetNull( _
ByVal columnID As Short _
)

// C#
public void SetNull(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

Remarks

The data is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • IsColumnNullable method


SetShort method

Sets the value for the specified column using an Int16.

Prototypes

' Visual Basic
Public Sub SetShort( _
ByVal columnID As Short, _
ByVal val As Short _
)

// C#
public void SetShort(
short columnID,
short val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetString method

Sets the value for the specified column using a String.

Prototypes

' Visual Basic
Public Sub SetString( _
ByVal columnID As Short, _
ByVal val As String _
)

// C#
public void SetString(
short columnID,
string val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetTime method

Sets the value for the specified column using a TimeSpan.

Prototypes

' Visual Basic
Public Sub SetTime( _
ByVal columnID As Short, _
ByVal val As TimeSpan _
)

// C#
public void SetTime(
short columnID,
TimeSpan val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

The set value is accurate to the millisecond and is normalized to a nonnegative value between 0 and 24 hours. The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetTimestamp method

Sets the value for the specified column using a DateTime.

Prototypes

' Visual Basic
Public Sub SetTimestamp( _
ByVal columnID As Short, _
ByVal val As Date _
)

// C#
public void SetTimestamp(
short columnID,
DateTime val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

The set value is accurate to the millisecond. The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetToDefault method

Sets the value for the specified column to its default value.

Prototypes

' Visual Basic
Public Sub SetToDefault( _
ByVal columnID As Short _
)

// C#
public void SetToDefault(
short columnID
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetNull method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method
  • GetColumnDefaultValue method


SetUInt method

Sets the value for the specified column using an UInt32.

Prototypes

' Visual Basic
Public Sub SetUInt( _
ByVal columnID As Short, _
ByVal val As UInt32 _
)

// C#
public void SetUInt(
short columnID,
uint val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetULong method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetULong method

Sets the value for the specified column using a UInt64.

Prototypes

' Visual Basic
Public Sub SetULong( _
ByVal columnID As Short, _
ByVal val As UInt64 _
)

// C#
public void SetULong(
short columnID,
ulong val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetUShort method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetUShort method

Sets the value for the specified column using a UInt16.

Prototypes

' Visual Basic
Public Sub SetUShort( _
ByVal columnID As Short, _
ByVal val As UInt16 _
)

// C#
public void SetUShort(
short columnID,
ushort val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetString method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUUID method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method


SetUUID method

Sets the value for the specified column using a Guid.

Prototypes

' Visual Basic
Public Sub SetUUID( _
ByVal columnID As Short, _
ByVal val As Guid _
)

// C#
public void SetUUID(
short columnID,
Guid val
);

Parameters

  • columnID the ID number of the column. The first column in the table has an ID value of one.

  • val the new value for the column.

Remarks

The data in the row is not actually changed until you execute an Insert method or Update method, and that change is not permanent until it is committed. Only valid for columns of type SQLType enumeration or for columns of type SQLType enumeration with length 16.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • GetNewUUID method
  • GetColumnID method
  • SetToDefault method
  • SetNull method
  • AppendBytes method
  • AppendChars method
  • SetBytes method
  • SetBoolean method
  • SetDouble method
  • SetFloat method
  • SetInt method
  • SetLong method
  • SetShort method
  • SetTime method
  • SetTimestamp method
  • SetUInt method
  • SetULong method
  • SetUShort method
  • FindBegin method
  • LookupBegin method
  • InsertBegin method
  • UpdateBegin method
  • Schema property
  • GetColumnSQLType method
  • GetColumnSize method


Truncate method

Deletes all rows in the table while temporarily activating a stop synchronization delete.

Prototypes

' Visual Basic
Public Sub Truncate()

// C#
public void Truncate();

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • DeleteAllRows method
  • AutoCommit field


Update method

Updates the current row with the current column values (specified using the set methods).

Each update must be preceded by a call to UpdateBegin method.

Prototypes

' Visual Basic
Public Sub Update()

// C#
public void Update();

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • Table class
  • Table members
  • AutoCommit field


UpdateBegin method

Prepares to update the current row in this table.

Prototypes

' Visual Basic
Public Sub UpdateBegin()

// C#
public void UpdateBegin();

Remarks

Column values are modified by calling the appropriate setType or AppendType method(s). The first append on a column will clear the current column value prior to appending the new value.

The data in the row is not actually changed until you call Update method, and that change is not permanent until it is committed.

Modifying columns in the index used to open the table will affect any active searches in unpredictable ways. Columns in the primary key of the table can not be updated.

Exceptions

  • SQLException class - A SQL error occurred.


TableSchema class

Represents the schema of an UltraLite table.

Prototypes

' Visual Basic
NotInheritable Public Class TableSchema
Inherits CursorSchema

// C#
public sealed class TableSchema :
CursorSchema

Remarks

This class cannot be directly instantiated. A TableSchema class object is attached to a table as its Schema property property.

TableSchema members
IndexCount property
IsNeverSynchronized property
Name property
PrimaryKey property
UploadsUnchangedRows property
Finalize method
GetColumnDefaultValue method
GetColumnPartitionSize method
GetIndex method
GetIndexName method
GetOptimalIndex method
IsColumnAutoIncrement method
IsColumnCurrentDate method
IsColumnCurrentTime method
IsColumnCurrentTimestamp method
IsColumnGlobalAutoIncrement method
IsColumnNewUUID method
IsColumnNullable method
IsInPublication method


TableSchema members

Public instance properties
Member | Description
ColumnCount property (inherited from CursorSchema) | Returns the number of columns in this cursor.
IndexCount property | The number of indexes on this table.
IsNeverSynchronized property | Whether this table is marked as never being synchronized.
IsOpen property (inherited from CursorSchema) | Checks whether this cursor schema is currently open.
Name property | The name of this table.
PrimaryKey property | The index schema of the primary key for this table.
UploadsUnchangedRows property | Whether the database will upload rows which have not changed.
Public instance methods
Member | Description
GetColumnDefaultValue method | The default value of the named column.
GetColumnID method (inherited from CursorSchema) | Returns the column ID of the named column.
GetColumnName method (inherited from CursorSchema) | Returns the name of column identified by the specified column ID.
GetColumnPartitionSize method | Returns the global autoincrement partition size assigned to the named column.
GetColumnPrecision method (inherited from CursorSchema) | Returns the precision of the named column if the column is a numeric column (SQL type NUMERIC).
GetColumnScale method (inherited from CursorSchema) | Returns the scale of the named column if the column is a numeric column (SQL type NUMERIC).
GetColumnSize method (inherited from CursorSchema) | Returns the size of the named column if the column is a sized column (SQL type BINARY or CHAR).
GetColumnSQLType method (inherited from CursorSchema) | Gets the SQL data type of the named column.
GetIndex method | Returns the index schema of the named index.
GetIndexName method | Returns the name of the index identified by the specified index ID.
GetOptimalIndex method | The optimal index for searching a table using the named column.
IsColumnAutoIncrement method | Checks whether the named column's default is set to autoincrement.
IsColumnCurrentDate method | Checks whether the named column's default is set to the current date (SQLType.DATE).
IsColumnCurrentTime method | Checks whether the named column's default is set to the current time (SQLType.TIME).
IsColumnCurrentTimestamp method | Checks whether the named column's default is set to the current timestamp (SQLType.TIMESTAMP).
IsColumnGlobalAutoIncrement method | Checks whether the named column's default is set to global autoincrement.
IsColumnNewUUID method | Checks whether the named column's default is set to a new UUID (Guid).
IsColumnNullable method | Checks whether the named column is nullable.
IsInPublication method | Checks whether this table is contained in the named publication.
Protected instance methods
Member | Description
Finalize method | Destructor which cleans up the associated native object.


IndexCount property

The number of indexes on this table.

Prototypes

' Visual Basic
Public Readonly Property IndexCount As Integer

// C#
public int IndexCount {get;}

Remarks

Index IDs range from 1 to IndexCount, inclusively.

Note: Index IDs and count may change during a schema upgrade. To correctly identify an index, access it by name or refresh the cached IDs and counts after a schema upgrade.


IsNeverSynchronized property

Whether this table is marked as never being synchronized.

Prototypes

' Visual Basic
Public Readonly Property IsNeverSynchronized As Boolean

// C#
public bool IsNeverSynchronized {get;}

Property value

true if this table is marked as never being synchronized.

Remarks

Tables marked as never being synchronized are never synchronized, even if they are included in a publication. These tables are sometimes referred to as "no sync" tables.

Exceptions

  • SQLException class - A SQL error occurred.


Name property

The name of this table.

Prototypes

' Visual Basic
Public Readonly Property Name As String

// C#
public string Name {get;}

Exceptions

  • SQLException class - A SQL error occurred.


PrimaryKey property

The index schema of the primary key for this table.

Prototypes

' Visual Basic
Public Readonly Property PrimaryKey As IndexSchema

// C#
public IndexSchema PrimaryKey {get;}

Exceptions

  • SQLException class - A SQL error occurred.


UploadsUnchangedRows property

Whether the database will upload rows which have not changed.

Prototypes

' Visual Basic
Public Readonly Property UploadsUnchangedRows As Boolean

// C#
public bool UploadsUnchangedRows {get;}

Property value

true if this table is marked to always upload all rows during synchronization.

Remarks

Tables marked as such will upload unchanged rows, as well as changed rows, when the table is synchronized. These tables are sometimes referred to as "all sync" tables.

Exceptions

  • SQLException class - A SQL error occurred.


GetColumnDefaultValue method

The default value of the named column.

Prototypes

' Visual Basic
Public Function GetColumnDefaultValue( _
ByVal name As String _
) As String

// C#
public string GetColumnDefaultValue(
string name
);

Parameters

  • name the name of the column.

Return value

The default value of the named column as a string or null if the default value is null.

Exceptions

  • SQLException class - A SQL error occurred.


GetColumnPartitionSize method

Returns the global autoincrement partition size assigned to the named column.

Prototypes

' Visual Basic
Public Function GetColumnPartitionSize( _
ByVal name As String _
) As UInt64

// C#
public ulong GetColumnPartitionSize(
string name
);

Parameters

  • name name of the column.

Return value

Column's global autoincrement partition size.

Remarks

All global autoincrement columns in a given table share the same global autoincrement partition.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • TableSchema class
  • TableSchema members
  • IsColumnGlobalAutoIncrement method


GetIndex method

Returns the index schema of the named index.

Prototypes

' Visual Basic
Public Function GetIndex( _
ByVal name As String _
) As IndexSchema

// C#
public IndexSchema GetIndex(
string name
);

Parameters

  • name name of the index.

Return value

index schema of the named index.

Exceptions

  • SQLException class - A SQL error occurred.


GetIndexName method

Returns the name of the index identified by the specified index ID.

Prototypes

' Visual Basic
Public Function GetIndexName( _
ByVal indexID As Integer _
) As String

// C#
public string GetIndexName(
int indexID
);

Parameters

  • indexID ID of the index. indexID must be in the range [1,TableSchema.IndexCount].

Return value

name of the index.

Remarks

Index IDs and counts may change during a schema upgrade. To correctly identify an index, access it by name or refresh the cached IDs and counts after a schema upgrade.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • TableSchema class
  • TableSchema members
  • IndexCount property


GetOptimalIndex method

The optimal index for searching a table using the named column.

Prototypes

' Visual Basic
Public Function GetOptimalIndex( _
ByVal name As String _
) As IndexSchema

// C#
public IndexSchema GetOptimalIndex(
string name
);

Parameters

  • name name of the column.

Return value

index for the named column.

Remarks

The named column will be the first column in the index, but the index may have more than one column.

Exceptions

  • SQLException class - A SQL error occurred.


IsColumnAutoIncrement method

Checks whether the named column's default is set to autoincrement.

Prototypes

' Visual Basic
Public Function IsColumnAutoIncrement( _
ByVal name As String _
) As Boolean

// C#
public bool IsColumnAutoIncrement(
string name
);

Parameters

  • name name of the column.

Return value

true if the column is autoincrementing, false if it is not autoincrementing.

Exceptions

  • SQLException class - A SQL error occurred.


IsColumnCurrentDate method

Checks whether the named column's default is set to the current date (SQLType.DATE).

Prototypes

' Visual Basic
Public Function IsColumnCurrentDate( _
ByVal name As String _
) As Boolean

// C#
public bool IsColumnCurrentDate(
string name
);

Parameters

  • name name of the column.

Return value

True if the column defaults to the current date, false if the column does not default to the current date.

Exceptions

  • SQLException class - A SQL error occurred.


IsColumnCurrentTime method

Checks whether the named column's default is set to the current time (SQLType.TIME).

Prototypes

' Visual Basic
Public Function IsColumnCurrentTime( _
ByVal name As String _
) As Boolean

// C#
public bool IsColumnCurrentTime(
string name
);

Parameters

  • name name of the column.

Return value

True if the column defaults to the current time, false if the column does not default to the current time.

Exceptions

  • SQLException class - A SQL error occurred.


IsColumnCurrentTimestamp method

Checks whether the named column's default is set to the current timestamp (SQLType.TIMESTAMP).

Prototypes

' Visual Basic
Public Function IsColumnCurrentTimestamp( _
ByVal name As String _
) As Boolean

// C#
public bool IsColumnCurrentTimestamp(
string name
);

Parameters

  • name name of the column.

Return value

True if the column defaults to the current timestamp, false if the column does not default to the current timestamp.

Exceptions

  • SQLException class - A SQL error occurred.


IsColumnGlobalAutoIncrement method

Checks whether the named column's default is set to global autoincrement.

Prototypes

' Visual Basic
Public Function IsColumnGlobalAutoIncrement( _
ByVal name As String _
) As Boolean

// C#
public bool IsColumnGlobalAutoIncrement(
string name
);

Parameters

  • name name of the column.

Return value

true if the column is global autoincrementing, false if it is not global autoincrementing.

Exceptions

  • SQLException class - A SQL error occurred.

See also
  • TableSchema class
  • TableSchema members
  • GetColumnPartitionSize method
  • DatabaseID property


IsColumnNewUUID method

Checks whether the named column's default is set to a new UUID (Guid).

Prototypes

' Visual Basic
Public Function IsColumnNewUUID( _
ByVal name As String _
) As Boolean

// C#
public bool IsColumnNewUUID(
string name
);

Parameters

  • name name of the column.

Return value

True if the column defaults to a new UUID, false if the column does not default to a new UUID.

Exceptions

  • SQLException class - A SQL error occurred.


IsColumnNullable method

Checks whether the named column is nullable.

Prototypes

' Visual Basic
Public Function IsColumnNullable( _
ByVal name As String _
) As Boolean

// C#
public bool IsColumnNullable(
string name
);

Parameters

  • name name of the column.

Return value

true if the column is nullable, false if not nullable.

Exceptions

  • SQLException class - A SQL error occurred.


IsInPublication method

Checks whether this table is contained in the named publication.

Prototypes

' Visual Basic
Public Function IsInPublication( _
ByVal pubName As String _
) As Boolean

// C#
public bool IsInPublication(
string pubName
);

Parameters

  • pubName name of the publication.

Return value

true if the table is in the publication, false if the table is not in the publication.

Exceptions

  • SQLException class - A SQL error occurred.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

Version 9.0.2

DC20093-01-0902-01

October 2004

Copyright
About This Manual
Introduction to UltraLite for M-Business Anywhere
Understanding UltraLite for M-Business Anywhere Development
Tutorial: A Sample Application for M-Business Anywhere
UltraLite for M-Business Anywhere API Reference


About This Manual

Subject

This manual describes UltraLite for M-Business Anywhere. With UltraLite for M-Business Anywhere you can develop and deploy web-based database applications to handheld, mobile, or embedded devices, running Palm OS, Windows CE, or Windows XP.

M-Business Anywhere is iAnywhere's platform for developing and deploying mobile web-based applications. The previous name for the product was AvantGo M-Business Server.

Audience

This manual is intended for application developers who wish to take advantage of the performance, resource efficiency, robustness, and security of an UltraLite relational database for data storage and synchronization.


Introduction to UltraLite for M-Business Anywhere

About this chapter

This chapter introduces UltraLite for M-Business Anywhere. It assumes that you are familiar with the features of UltraLite, as described in Welcome to UltraLite.


UltraLite for M-Business Anywhere features

UltraLite for M-Business Anywhere is a relational data management system for mobile devices. It has the performance, resource efficiency, robustness, and security required by business applications. UltraLite also provides synchronization with enterprise data stores.

System requirements and supported platforms


System requirements and supported platforms

Development platforms

To develop applications using UltraLite for M-Business Anywhere, you require the following:

  • M-Business Anywhere is the new name for AvantGo M-Business Server. This software requires M-Business Server 5.3 or later, and the corresponding M-Business Anywhere client.

For more information, see UltraLite development platforms.

Target platforms

UltraLite for M-Business Anywhere supports the following target platforms:

  • Windows CE 3.0 and higher, with Pocket PC on the ARM processor.

  • Palm OS version 5.0 and higher.

  • Windows 2000 and Windows XP, starting with M-Business Anywhere 5.5.

For more information, see UltraLite target platforms.


UltraLite for M-Business Anywhere architecture

The UltraLite programming interface exposes a set of objects for data manipulation using an UltraLite database. The following figure describes the object hierarchy.

The UltraLite for M-Business Anywhere objects

The following list describes some of the more commonly-used high level objects.

  • DatabaseManager manages connections to UltraLite databases.

    For more information, see Class DatabaseManager.

  • ConnectionParms holds a set of connection parameters.

    For more information, see Class ConnectionParms.

  • Connection represents a database connection, and governs transactions.

    For more information, see Class Connection.

  • PreparedStatement, ResultSet, and ResultSetSchema manage database requests and their results using SQL.

    For more information, see Class PreparedStatement, Class ResultSet, and Class ResultSetSchema.

  • Table manages data using a table-based API.

    For more information, see Class ULTable.

  • SyncParms and SyncResult manage synchronization through the MobiLink synchronization server.

    For more information about synchronization with MobiLink, see UltraLite Clients.


Understanding UltraLite for M-Business Anywhere Development

About this chapter

This chapter describes application development using UltraLite for M-Business Anywhere.

UltraLite for M-Business Anywhere Quick Start
Working with the database schema
Connecting to an UltraLite database
Maintaining connections and application state across pages
Encryption and obfuscation
Working with data using dynamic SQL
Working with data using the table API
Accessing schema information
Handling errors
Authenticating users
Synchronizing data
Deploying UltraLite for M-Business Anywhere applications


UltraLite for M-Business Anywhere Quick Start

The following procedures describe how to run the supplied CustDB and Simple sample applications.

Before you start, ensure that you have M-Business Anywhere 5.3 or later installed and running, and that you have administrative privileges on the server. You must also have a supported handheld device.

toggle To install and run M-Business Anywhere samples

  1. Copy the UltraLite for M-Business Anywhere sample files to your installation directory for deployment.

    1. Open a command prompt and change directory to the Samples\UltraLiteForMBusinessAnywhere\custdb subdirectory of your SQL Anywhere installation.

    2. Run the following command:

      build.bat install-dir

      where install-dir is the directory to which the CustDB and UltraLite files should be deployed.

      The batch file copies the required files into the location you specify. To see what files are being copied, open Samples\UltraLiteForMBusinessAnywhere\custdb\build.bat in a text editor.

  2. Create a virtual directory in your web server that points to the install directory install-dir specified in step 1. The following instructions are for Microsoft IIS:

    1. Open the IIS management tool.

    2. Right-click your web site and choose New Virtual Directory. Name this virtual directory CustDB and point it at your install directory install-dir. Leave the other settings at their default values.

    3. Right-click the new virtual directory and choose Properties. In the HTTP Headers tab, click File Types and register the following file extensions as the type application/octet-stream:

      • dll
      • usm
      • cab
      • pdb
      • prc

    4. Make a note of the URL that accesses the file main.htm in this virtual directory. In a default installation this would be http://localhost/CustDB/main.htm.

  3. Add users to M-Business Anywhere.

    There are three ways to add new users to M-Business Anywhere: by creating new user profiles, by allowing users to self-register, and by importing a CSV file. These instructions describe how to create a new user profile. For more information, see the M-Business Anywhere documentation.

    1. Log in to M-Business Anywhere as an administrator.

      The default administrator account settings are a user ID of Admin and an empty password.

    2. Click the Users button.

    3. Click the New User link. The Create New User page appears.

    4. Type a unique user name in the User Name field.

    5. Type the same password in the Password and the Confirm Password fields.

    6. Click Create to add the user, or click Create and Edit to create the user and edit the user's details.

  4. Deploy the M-Business Anywhere Client to a handheld device or PC.

    1. Click the Download Client Software Only link on the M-Business Anywhere login page.

    2. On the handheld device or PC, configure AvantGo Connect to synchronize with the M-Business Anywhere server.

      Enter the user ID and password of the new M-Business user account you created.

    3. Synchronize to the M-Business Anywhere server at least once to install the client onto the device.

      If you have connection problems at this stage, specify the IP number rather than the host name as the host to avoid name resolution issues with some versions of ActiveSync.

    For more information, see your M-Business Anywhere documentation.

  5. Add a group to M-Business Anywhere.

    The group will be used to test UltraLite for M-Business Anywhere.

    1. From a web browser, connect to M-Business Anywhere.

      The default URL is http://localhost or http://localhost:8092.

    2. Log in using the administrator account.

    3. Click the Groups tab, and click New Group.

    4. Name your group UltraLite Samples.

  6. Configure the M-Business Anywhere channel settings.

    1. Add the user you created in step 3 to the new group UltraLite Samples.

    2. User the group's "web" tab, create the following channel.

      Setting | Value
      Channel Name | CustDB
      Location | http://localhost/CustDB/main.htm or the URL from step 2.
      Size | 1000
      Link depth | 3
      Allow binary distribution | Yes (checked)
      Hidden | No (unchecked)

      After setting the Location value, click View to confirm that you have entered the value correctly.

  7. Synchronize your client.

    The initial synchronization downloads the UltraLite for M-Business Anywhere files onto your handheld device.

toggle To verify your setup

  1. Check that the required files are present.

    • On Pocket PC, after you have synchronized the device, check that the following files are in the \Program Files\AvantGo\Pods folder:

      • ulpod9.dll
      • ul_custdb.usm

      If any of these files are missing, you may have to manually copy them over to the device.

    • On Palm OS, after you have synchronized your device, check Palm OS App Info for the presence of the following:

      • ulpod
      • ul_custdb

      If any of these are missing, you may have to use the Palm install utility to install the UltraLite for M-Business Anywhere runtime .prc and sample schemas .pdb to the device.

    • On Windows, after you have synchronized your device, check that the following files are in the AvantGo\Pods subdirectory of your AvantGo Connect folder:

      • ulpod9.dll
      • ul_custdb.usm

      If any of these files are missing, you may have to manually copy them over to the device.

  2. Launch M-Business Client.

    On your handheld device or PC, check that the About screen displays the UltraLite for M-Business Anywhere version number. This confirms that UltraLite for M-Business Anywhere is successfully installed.

  3. Run the CustDB sample application.

    1. Start the MobiLink synchronization server on your desktop.

      From the Start menu, choose Programs > SQL Anywhere 9 > MobiLink > Synchronization Server Sample.

    2. Start the CustDB application on your AvantGo Client.

      The CustDB application is a link on your AvantGo home page.

    3. Enter your user ID.

      The default value is 50.

    4. Synchronize.

      Either answer Yes to the prompt "Do you have a network connection now?" or, in the CustDB application, click Synchronize. This synchronizes data with MobiLink, and is a separate operation from synchronizing with M-Business Anywhere.

      You should now see data in the CustDB fields. You can now explore the CustDB application.

    For information about the CustDB sample application, see The CustDB Sample Application.

HotSync with multiple databases

Each UltraLite database on a Palm OS device must have a distinct creator ID to work properly with HotSync. In addition, an application with that creator ID must exist on the Palm OS device.

The HotSync Manager uses each application's creator ID as an identifier to handle synchronization. It hands each properly configured UltraLite application to the MobiLink conduit for synchronization. The conduit searches for and synchronizes a database with the same creator ID as the application.

For information about configuring the conduit, see Understanding HotSync synchronization.

All UltraLite for M-Business Anywhere applications inherit the creator ID of the AvantGo client, which is AvGo. This inheritance means that only one UltraLite database with creator ID AvGo can be synchronized, and that if you assign a distinct creator ID to your database, HotSync will not find it because there is no application with a corresponding creator ID.

This limitation is not an issue for the two sample applications (CustDB and Simple), as they share a common database schema. The only side effect is that when you synchronize the CustDB database, the Simple sample is also synchronized.

For information on resolving this problem, see Understanding the Palm Creator ID.


Working with the database schema

The schema is the structure of a database. It is the collection of table definitions, index definitions, and publication definitions within the database, and all the relationships between them.

You create UltraLite databases by creating an UltraLite database schema file and apply that file to a database by calling a function in your application.


Changing the schema of a database

To change the schema of an existing database, create a schema file with the new schema and apply this schema to the existing database. In most cases there will be no data loss, but data loss can occur if columns are deleted or if the data type for a column is changed to an incompatible type.

For more information about these methods, see Method applyFileWithParms and Method applyFile.

You can also change the schema by executing the following SQL statements:

  • CREATE INDEX statement
  • CREATE TABLE statement
  • DROP INDEX statement


Connecting to an UltraLite database

UltraLite applications must connect to a database before carrying out operations on the data in it. This section describes how to connect to an UltraLite database.

Using the Connection object

The following properties of the Connection object govern global application behavior.

For more information about the Connection object, see Class Connection.

  • Commit behavior By default, UltraLite applications are in AutoCommit mode. Each insert, update, or delete statement is committed to the database immediately. Set Connection.autoCommit to false to build transactions into your application. Turning autoCommit off and performing commits directly can improve the performance of your application.

    For more information, see Method commit.

  • User authentication You can change the user ID and password for the application from the default values of DBA and SQL by using the grantConnectTo and revokeConnectFrom methods.

    For more information, see Authenticating users.

  • Synchronization A set of objects governing synchronization are accessed from the Connection object.

    For more information, see Synchronizing data.

  • Tables UltraLite tables are accessed using the Connection.getTable method.

    For more information, see Method getTable.

Connecting to a database

You can connect to a database using either a ConnectionParms object or a connection string. Methods that use a ConnectionParms object allow you to manipulate connection parameters with ease and accuracy. Methods that use a connection string require that you successfully create a connection string.

Using ConnectionParms to connect to a database


Using ConnectionParms to connect to a database

The following procedure uses a ConnectionParms object to connect to an UltraLite database.

toggle To connect to an UltraLite database using ConnectionParms

  1. Create a DatabaseManager object.

    You should create only one DatabaseManager object per application. This object is at the root of the object hierarchy. For this reason, it is often best to declare the DatabaseManager object as global to the application.

    dbMgr = CreateObject( "iAnywhere.UltraLite.DatabaseManager.myDB" );
if ( dbMgr == null || dbMgr.sqlCode < 0 ) {
    alert(
    "Fatal Error! Cannot create database manager object: "
    + dbMgr.sqlCode );
}

  2. Declare a ConnectionParms object and locate the directory where M-Business Anywhere places the downloaded files.

    For example:

    var parm = dbMgr.createConnectionParms();
var dir = dbMgr.directory;

  3. Set the required properties of the ConnectionParms object.

    For example:

    parm.connectionName = "simpleCon";

parm.schemaOnPalm = "ul_custapi";
parm.databaseOnPalm = "AvGo";
parm.databaseOnCE = dir + "\\ul_custapi.udb";
parm.schemaOnCE = dir + "\\ul_custapi.usm";

  4. Open a connection to the database.

    CreateDatabaseWithParms and OpenConnectionWithParms return an open connection as a Connection object. Each method takes a single ConnectionParms object as its argument.

    For example:

    try {
  Connection = dbMgr.reOpenConnection( "custdb" );
  if ( Connection == null ) {
    Connection = dbMgr.openConnectionWithParms( parm );
  }
} catch ( ex ) {
  if ( DatabaseMgr.sqlCode !=
       DatabaseMgr.SQLError.SQLE_ULTRALITE_DATABASE_NOT_FOUND ) {
    alert( "Database Error! " + ex.getMessage() );
    return;
  }
}

    For more information, see Method createDatabaseWithParms and Method openConnectionWithParms.


Maintaining connections and application state across pages

The scope of a JavaScript variable is limited to one web page. Most web applications require multiple pages, and so a mechanism is needed for making some objects persistent across the pages of an application.

UltraLite for M-Business Anywhere provides persistence for the ULTable, ResultSet, and PreparedStatement objects. To make one of these objects persist across pages, supply a persistent name as a parameter when creating the object. You can use the persistent name on subsequent pages.

To carry a connection object from page to page, you reopen the connection on each page. One way to do this is to use the reOpen method. Another is to supply an open method on each page, perhaps by including a JavaScript file on each web page to initialize the settings. For examples of how to do this, see the sample files Samples\UltraLiteForMBusinessAnywhere\CustDB\main.htm and Samples\UltraLiteForMBusinessAnywhere\Simple\main_page.htm.

The requirement to reopen connections across pages provides a security feature for UltraLite applications. You can use it to require that the user confirm some information, perhaps the password, on moving from page to page.

See also
  • Method reOpenConnection
  • Class PreparedStatement
  • Class ResultSet
  • Class ULTable
  • Class PreparedStatement


Encryption and obfuscation

You can encrypt or obfuscate your UltraLite database using UltraLite for M-Business Anywhere.

For more information about database encryption, see Encrypting UltraLite databases.

Encryption

To create a database with encryption, set the ConnectionParms.encryptionKey property. When you call CreateDatabaseWithParms and pass in the ConnectionParms object, the database created and encrypted with the specified key.

For more information about the EncryptionKey property, see Encryption Key connection parameter and Method changeEncryptionKey.

Example

You can change the encryption key by specifying the new encryption key on the Connection object. In this example, "apricot" is the encryption key.

conn.changeEncryptionKey("apricot")

After the database is encrypted, connections to the database must specify the correct encryption key. Otherwise, the connection fails.

Obfuscation

To obfuscate the database, specify obfuscate=1 in the ConnectionParms.additionalParms string. For example:

var open_parms = dbMgr.createConnectionParms();
open_parms.additionalParms = "obfuscate=1";
Connection = dbMgr.createDatabase( open_parms );

For more information, see Properties.


Working with data using dynamic SQL

UltraLite applications can access table data using dynamic SQL or the Table API. This section describes data access using dynamic SQL.

For information about the Table API, see Working with data using the table API.

This section explains how to perform the following tasks using dynamic SQL.

  • Inserting, deleting, and updating rows.

  • Executing a query.

  • Scrolling through the rows of a result set.

This section does not describe the SQL language itself. For information about dynamic SQL features, see Dynamic SQL.

The sequence of operations required is similar for any SQL operation. For an overview, see Using dynamic SQL.


Data manipulation: INSERT, UPDATE and DELETE

With UltraLite, you can perform SQL Data Manipulation Language operations. These operations are performed using the ExecuteStatement method, a member of the PreparedStatement class.

For more information the PreparedStatement class, see Class PreparedStatement.

Parameter markers in prepared statements
UltraLite handles variable values using the ? parameter marker. For any INSERT, UPDATE or DELETE, each ? is referenced according to its ordinal position in the prepared statement. For example, the first ? is referred to as 1, and the second as 2.
toggle To INSERT a row

  1. Declare a PreparedStatement object.

    var PrepStmt;

  2. Assign an INSERT statement to your prepared statement object. In the following, TableName and ColumnName are the names of a table and column.

    PrepStmt = conn.prepareStatement(
    "INSERT into TableName(ColumnName) values (?)", null );

    The null parameter indicates that the statement has no persistent name.

  3. Assign parameter values to the statement.

    var NewValue;
NewValue = "Bob";
PrepStmt.setStringParameter(1, NewValue);

  4. Execute the statement.

    PrepStmt.executeStatement( null );
toggle To UPDATE a row

  1. Declare a PreparedStatement object.

    var PrepStmt;

  2. Assign an UPDATE statement to your prepared statement object. In the following, TableName and ColumnName are the names of a table and column.

    PrepStmt = conn.prepareStatement(
  "UPDATE TableName SET ColumnName = ? WHERE ID = ?", null);

    The null parameter indicates that the statement has no persistent name.

  3. Assign parameter values to the statement using methods appropriate for the data type.

    var NewValue;
NewValue = "Bob";
PrepStmt.setStringParameter(1, NewValue);
PrepStmt.setIntParameter(2, 6);

  4. Execute the statement

    PrepStmt.executeStatement( );
toggle To DELETE a row

  1. Declare a PreparedStatement object.

    var PrepStmt;

  2. Assign a DELETE statement to your prepared statement object.

    PrepStmt = conn.prepareStatement(
    "DELETE FROM customer WHERE ID = ?", null );

    The null parameter indicates that the statement has no persistent name.

  3. Assign parameter values for the statement.

    var IDValue;
IDValue = 6;
PrepStmt.setIntParameter( 1, IDValue );

  4. Execute the statement.

    PrepStmt.executeStatement( );


Data retrieval: SELECT

When you execute a SELECT statement, the PreparedStatement.executeQuery method returns a ResultSet object. The ResultSet class contains methods for navigating within a result set.

For more information about ResultSet objects, see Class ResultSet.

Example

In the following code, the results of a query are accessed as a ResultSet. When first assigned, the ResultSet is positioned before the first row. The ResultSet.moveFirst method is then called to navigate to the first record in the result set.

var MyResultSet;
var PrepStmt;
PrepStmt = conn.prepareStatement( _
    "SELECT ID, Name FROM customer", null );
MyResultSet = PrepStmt.executeQuery( null );
MyResultSet.moveFirst();
Example

The following code demonstrates how to obtain column values for the current row. The example uses character data; similar methods are available for other data types.

The getString method uses the following syntax: MyResultSetName.getString( Index ) where Index is the ordinal position of the column name in your SELECT statement.

if ( MyResultSet.getRowCount() == 0 ) {
} else {
  alert( MyResultSet.getString(1) );
  alert( MyResultSet.getString(2) );
  MyResultSet.moveRelative(0);
}

For more information about navigating a result set, see Navigation with dynamic SQL.

The following procedure uses a SELECT statement to retrieve information from the database. The results of the query are assigned to a ResultSet object.

toggle To perform a SELECT statement

  1. Declare a PreparedStatement object.

    var OrderStmt;

  2. Assign a prepared statement to your PreparedStatement object.

    OrderStmt = Connection.prepareStatement(
"SELECT order_id, disc, quant, notes, status, c.cust_id,
   cust_name, p.prod_id, prod_name, price
  FROM ULOrder o, ULCustomer c, ULProduct p
  WHERE o.cust_id = c.cust_id
  AND o.prod_id = p.prod_id
  ORDER BY der_id", "order_query_stmt" );

    The second parameter is a persistent name that provides cross-page JavaScript object persistence.

  3. Execute the query.

    OrderResultSet = OrderStmt.executeQuery( "order_query" );

For more information on how to use queries, see the CustDB sample code in Samples\UltraLiteForMBusinessAnywhere\CustDB\custdb.js.


Navigation with dynamic SQL

UltraLite for M-Business Anywhere provides you with a number of methods to navigate a result set in order to perform a wide range of navigation tasks.

The following methods of the ResultSet object allow you to navigate your result set:

  • moveAfterLast moves to a position after the last row.

  • moveBeforeFirst moves to a position before the first row.

  • moveFirst moves to the first row.

  • moveLast moves to the last row.

  • moveNext moves to the next row.

  • movePrevious moves to the previous row.

  • moveRelative moves a certain number of rows relative to the current row. Positive index values move forward in the result set, negative index values move backward in the result set, and zero does not move the cursor. Zero is useful if you want to repopulate a row buffer.

Example

The following code fragment demonstrates how to use the MoveFirst method to navigate within a result set.

PrepStmt = conn.prepareStatement(
    "SELECT ID, Name FROM customer", null );
MyResultSet = PrepStmt.executeQuery( null );
MyResultSet.moveFirst();

The same technique is used for all of the move methods.

For more information about these navigational methods, see Class ResultSet.


The ResultSetSchema object

The ResultSet.schema property allows you to retrieve information about the columns in the query.

The following example demonstrates how to use ResultSetSchema to capture schema information.

var i;
var MySchema = rs.schema ;
for ( i = 1; i <= MySchema.columnCount; i++) {
  colname = MySchema.getColumnName(i);
  coltype = MySchema.getColumnSQLType(colname).toString();
  alert ( colname + " " + coltype );
}


Navigation with the Table API

UltraLite for M-Business Anywhere provides you with a number of methods to navigate a table in order to perform a wide range of navigation tasks.

The following methods of the ULTable object allow you to navigate your result set:

  • moveAfterLast moves to a position after the last row.

  • moveBeforeFirst moves to a position before the first row.

  • moveFirst moves to the first row.

  • moveLast moves to the last row.

  • moveNext moves to the next row.

  • movePrevious moves to the previous row.

  • moveRelative moves a certain number of rows relative to the current row. Positive index values move forward in the table, negative index values move backward in the table, and zero does not move the cursor. Zero is useful if you want to repopulate a row buffer.

Example

The following code opens the customer table and scrolls through its rows. It then displays an alert with the last name of each customer.

var tCustomer;
tCustomer = conn.getTable( "customer", null );
tCustomer.open();
tCustomer.moveBeforeFirst();
While (tCustomer.moveNext()) {
  alert( tCustomer.getString(3) );
}
Specifying an index

You expose the rows of the table to the application when you open the table object. By default, the rows are exposed in order by primary key value, but you can specify an index to access the rows in a particular order.

Example

The following code moves to the first row of the customer table as ordered by the ix_name index.

tCustomer = conn.getTable("customer", null );
tCustomer.openWithIndex("ix_name");
tCustomer.moveFirst();


Accessing the values of the current row

At any time, a ULTable object is positioned at one of the following places.

  • Before the first row of the table.

  • On a row of the table.

  • After the last row of the table.

If the ULTable object is positioned on a row, you can use one of the ULTable get methods to get the value of each column for the current row.

Example

The following code fragment retrieves the value of three columns from the tCustomer ULTable object, and displays them in text boxes.

var colID, colFirstName, colLastName;
colID = tCustomer.schema.getColumnID( "id" );
colFirstName = tCustomer.schema.getColumnID( "fname" );
colLastName = tCustomer.schema.getColumnID( "lname" );
alert( tCustomer.getInt( colID ) );
alert( tCustomer.getString( colFirstName ) );
alert( tCustomer.getString( colLastName ) );

You can also use methods of ULTable to set values.

tCustomer.setString( colLastName, "Kaminski" );

By assigning values to these properties you do not alter the value of the data in the database.

You can assign values to the properties even if you are before the first row or after the last row of the table. You cannot, however, get values from the column. For example, the following code fragment generates an error.

tCustomer.moveBeforeFirst();
id = tCustomer.getInt( colID );


Searching rows with find and lookup

UltraLite has several modes of operation for working with data. Two of these modes, the find and lookup modes, are used for searching. The ULTable object has methods corresponding to these modes for locating particular rows in a table.

Note
The columns searched using Find and Lookup methods must be in the index used to open the table.

  • Find methods move to the first row that exactly matches a specified search value, under the sort order specified when the ULTable object was opened.

    For more information about find methods, see Class ULTable.

  • Lookup methods move to the first row that matches or is greater than a specified search value, under the sort order specified when the ULTable object was opened.

    For more information about lookup methods, see Class ULTable.

toggle To search for a row

  1. Enter find or lookup mode.

    Call the FindBegin or LookupBegin method. For example, the following code fragment calls ULTable.findBegin.

    tCustomer.findBegin();

  2. Set the search values.

    You do this by setting values in the current row. Setting these values affects the buffer, not the database. For example, the following code fragment sets the last name column in the buffer to Kaminski.

    tCustomer.setString(3, "Kaminski" );

    For multi-column indexes, a value for the first column is required, but you can omit the other columns.

  3. Search for the row.

    Use the appropriate method to carry out the search. For example, the following instruction looks for the first row that exactly matches the specified value in the current index.

    tCustomer.findFirst();


Inserting, updating, and deleting rows

UltraLite exposes the rows in a table to your application one at a time. The ULTable object has a current position, which may be on a row, before the first row, or after the last row of the table.

When your application changes location, UltraLite makes a copy of the row in a buffer. Any operations to get or set values affect only the copy of data in this buffer. They do not affect the data in the database.

Example

The following statement changes the value of the first column in the buffer to 3.

tCustomer.setInt( 1 , 3 );
Using UltraLite modes

The UltraLite mode determines the purpose for which the values in the buffer will be used. UltraLite has the following four modes of operation, in addition to a default mode.

  • Insert mode The data in the buffer is added to the table as a new row when the ULTable.insert method is called.

  • Update mode The data in the buffer replaces the current row when the ULTable.update method is called.

  • Find mode Used to locate a row whose value exactly matches the data in the buffer when one of the ULTable.find methods is called.

  • Lookup mode Used to locate a row whose value matches or is greater than the data in the buffer when one of the ULTable.lookup methods is called.

toggle To update a row

  1. Move to the row you wish to update.

    You can move to a row by scrolling through the table or by searching using Find and Lookup methods.

  2. Enter Update mode.

    For example, the following instruction enters Update mode on the table tCustomer.

    tCustomer.updateBegin();

  3. Set the new values for the row to be updated.

    For example, the following instruction sets the new value to Elizabeth.

    tCustomer.setString( 2, "Elizabeth" );

  4. Execute the Update.

    tCustomer.update();

After the update operation, the current row is the row that was just updated. If you changed the value of a column in the index specified when the ULTable object was opened, the current position is undefined.

By default, UltraLite operates in AutoCommit mode, so that the update is immediately applied to the row in permanent storage. If you have disabled AutoCommit mode, the update is not applied until you execute a commit operation. For more information, see Transaction processing in UltraLite.

Caution Do not update the primary key of a row: delete the row and add a new row instead.
Inserting rows

The steps to insert a row are similar to those for updating rows, except that there is no need to locate any particular row in the table before carrying out the insert operation. Rows are automatically sorted by the index specified when opening the table.

toggle To insert a row

  1. Enter Insert mode.

    For example, the following instruction enters Insert mode on the table CustomerTable.

    tCustomer.insertBegin();

  2. Set the values for the new row.

    If you do not set a value for one of the columns, and that column has a default, the default value is used. If the column has no default, NULL is used. If the column does not allow NULL, the following defaults are used:

    • For numeric columns, zero.

    • For character columns, an empty string.

    To set a value to NULL explicitly, use the setNull method.

    colID = tCustomer.schema.getColumnID( "id" );
colFirstName = tCustomer.schema.getColumnID( "fname" );
colLastName = tCustomer.schema.getColumnID( "lname" );
tCustomer.setInt( colID, 42 );
tCustomer.setString( colFirstName, "Mitch" );
tCustomer.setString( colLastName, "McLeod" );

  3. Execute the insertion.

    The inserted row is permanently saved to the database when a Commit is carried out. In AutoCommit mode, a Commit is carried out as part of the Insert method.

    tCustomer.insert();
Deleting rows

There is no delete mode corresponding to the insert or update modes.

The following procedure deletes a row.

toggle To delete a row

  1. Move to the row you wish to delete.

  2. Execute the delete:

    tCustomer.deleteRow();


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

Understanding UltraLite for M-Business Anywhere Development

Working with data using the table API

Working with BLOB data

You can fetch BLOB data for columns declared BINARY or LONG BINARY using the GetByteChunk method.

For more information, see Method getStringChunk.


Transaction processing in UltraLite

UltraLite provides transaction processing to ensure the integrity of the data in your database. A transaction is a logical unit of work. Either the entire transaction is executed, or none of the statements in the transaction are executed.

By default, UltraLite operates in AutoCommit mode. In AutoCommit mode, each insert, update, or delete is executed as a separate transaction. Once the operation is completed, the change is made to the database.

If you set the Connection.autoCommit property to false, you can use multi-statement transactions. For example, if your application transfers money between two accounts, the deduction from the source account and the addition to the destination account constitute a single transaction.

If AutoCommit is false, you must execute a Connection.commit statement to complete a transaction and make changes to your database permanent, or you may execute a Connection. Rollback statement to cancel all the operations of a transaction. Turning AutoCommit off improves performance.

Note
Synchronization causes a Commit even if you have AutoCommit set to False.

Previous Next


Accessing schema information

Each Connection, ULTable, and ResultSet object contains a schema property. These schema objects provide information about the tables, columns, indexes, and publications in a database.

For information about modifying the schema, see Changing the schema of a database.

  • DatabaseSchema The number and names of the tables in the database, as well as global properties such as the format of dates and times.

    To obtain a DatabaseSchema object, access the Connection.databaseSchema property.

  • TableSchema The number and names of columns in the table, as well as the Indexes collections for the table.

    To obtain a TableSchema object, access the ULTable.schema property.

  • IndexSchema Information about the column, or columns, in the index. As an index has no data directly associated with it, there is no separate Index object, only a IndexSchema object.

    The IndexSchema objects are accessed using the TableSchema.getIndex method.

  • PublicationSchema The numbers and names of tables and columns contained in a publication. Publications are also comprised of schema only, so there is a PublicationSchema object but no Publication object.

    The PublicationSchema objects are accessible using the DatabaseSchema.getPublicationSchema method.

  • ResultSetSchema The number and names of the columns in a result set.

    The ResultSetSchema objects are accessible using the PreparedStatement.getResultSetSchema method or the ResultSet.schema property.


Handling errors

In normal operation, UltraLite for M-Business Anywhere can throw errors that are intended to be caught and handled in the script environment. Errors are expressed as SQLCODE values, negative numbers indicating the particular kind of error.

For a list of error codes thrown by UltraLite for M-Business Anywhere, see Class SQLError.

UltraLite for M-Business Anywhere throws errors only from the DatabaseManager and Connection objects. The following methods of DatabaseManager can throw errors.

  • createDatabase
  • createDatabaseWithParms
  • dropDatabase
  • dropDatabaseWithParms
  • openConnection
  • openConnectionWithParms

All other errors and exceptions within UltraLite for M-Business Anywhere are routed through the Connection object.

For more information about accessing error numbers from DatabaseManager and Connection objects, see Class Connection and Class DatabaseManager.


Authenticating users

New users have to be added from an existing connection. As all UltraLite databases are created with a default user ID and password of DBA and SQL, respectively, you must first connect as this initial user.

You cannot change a user ID: you add a user and delete an existing user. A maximum of four user IDs are permitted for each UltraLite database.

For more information about granting or revoking connection authority, see Method grantConnectTo and Method revokeConnectFrom.

toggle To add a user or change the password for an existing user

  1. Connect to the database as a user with DBA authority.

  2. Grant the user connection authority with the desired password.

    conn.grantConnectTo("Robert", "newPassword");
toggle To delete an existing user

  1. Connect to the database as a user with DBA authority.

  2. Revoke the user's connection authority as follows.

    conn.revokeConnectFrom("Robert");


Synchronizing data

UltraLite for M-Business Anywhere applications typically involve two kinds of synchronization:

  • Web content synchronization Web content, including HTML pages that define the application itself, is synchronized through M-Business Anywhere.

  • Data synchronization The UltraLite database is synchronized with a MobiLink synchronization server.

Although these two kinds of synchronization are distinct, you can initiate them together in a technique called one-button synchronization. One-button synchronization is the recommended model for most applications, but as there may be cases where it is necessary to keep synchronization of data and web content entirely separate, that technique is discussed below.


One-button synchronization

One-button synchronization is a technique for initiating web content synchronization (using M-Business Anywhere) and UltraLite data synchronization (using MobiLink) in a single operation. It is available on Windows CE and Windows XP only. The architecture of one-button synchronization is as follows:

Architecture for one-button synchronization, showing web content synchronization with M-Business Anywhere and data synchronization with MobiLink

The sequence of events in one button synchronization is as follows:

  1. The user synchronizes their web application, perhaps by placing it in the cradle.

  2. The M-Business Client synchronizes the web content.

  3. The MBConnect component of M-Business Client calls the ulconnect.exe application.

  4. ulconnect.exe initiates synchronization of the UltraLite database.

  5. Data is synchronized with MobiLink.

To implement one-button synchronization you must carry out the following steps:

  1. In your application, set the synchronization parameters for MobiLink synchronization.

    If you are synchronizing through M-Business Anywhere you can use the SyncParms.setMBAServer method to set the host and port synchronization parameters. For more information, see Method setMBAServer.

    Otherwise, use the standard methods to set synchronization parameters. For more information, see Class SyncParms.

  2. Save the synchronization parameters so that they can be read by ulconnect.exe.

    Call the Connection.SaveSyncParms method to save the synchronization parameters. For more information, see Method saveSyncParms.


Synchronizing data

Synchronizing data

For most users it is useful to use one-button synchronization, which initiates both data synchronization and web content synchronization. For more information, see One-button synchronization.

This section is for those users who wish to synchronize data separately from web content synchronization.

Synchronization requires the MobiLink synchronization server and appropriate licensing. You can find a working example of synchronization in the CustDB sample application.

UltraLite for M-Business Anywhere supports TCP/IP, HTTP, HTTPS, and HotSync synchronization. Synchronization is initiated by the UltraLite application. In all cases, you use methods and properties of the Connection object to control synchronization.

Note
To synchronize using encrypted synchronization (HTTPS) or to use encryption over TCP/IP you must obtain the separately-licensable security option. To order this option, see the card in your SQL Anywhere Studio package or see [external link] http://www.sybase.com/detail?id=1015780.

For more information, see Welcome to SQL Anywhere Studio.

toggle To synchronize over TCP/IP or HTTP

  1. Prepare the synchronization information.

    Assign values to the required properties of the Connection.syncParms object.

    For information about the properties and the values that you should set, see UltraLite Clients.

  2. Synchronize.

    Call the Connection.synchronize method.


Synchronizing data via M-Business Anywhere

Whether you use one-button synchronization or separate data synchronization, you can use a MobiLink Redirector to configure your M-Business Anywhere server to route data to and from a MobiLink synchronization server. For synchronization from outside the firewall, this reduces the number of ports that need to be externally accessible.

The following diagram illustrates the architecture for the case of one-button synchronization.

Architecture for data synchronization via M-Business Anywhere, using a MobiLink Redirector.
toggle To synchronize data via M-Business Anywhere

  1. At the server side, set up a MobiLink Redirector to route data between M-Business Anywhere and your MobiLink synchronization server.

    For information on the MobiLink Redirector for M-Business Anywhere, see M-Business Anywhere Redirector.

  2. In your client, set synchronization parameters so that UltraLite synchronization is directed to the host and port number of M-Business Anywhere. You can use the SyncParms.setMBAServer method to carry out this task.

    For more information, see Method setMBAServer.

  3. From a client application, initiate synchronization using either one-button synchronization or separate data synchronization.

    For more information, see One-button synchronization, and Synchronizing data.


Deploying UltraLite for M-Business Anywhere applications

When you have completed your application or when you wish to test your application, you need to deploy it to a device. This section outlines the steps needed to deploy an UltraLite application to a device.


Deploying applications to Windows CE and Windows XP

You must carry out the following steps to deploy an UltraLite application to a Windows CE device:

  • Deploy your application and UltraLite component.

    For instructions, see UltraLite for M-Business Anywhere Quick Start.

  • Deploy an initial copy of the UltraLite database or schema.

    For instructions, see UltraLite for M-Business Anywhere Quick Start.

    In many situations it is sufficient to deploy an UltraLite schema file only. UltraLite creates a database file from the schema on the first connection attempt. You can then use synchronization to load an initial copy of the data.

    You must place the database or schema file so that it can be located by the application. The Database On CE and Schema On CE connection parameters define the location for Windows CE. The Database on Desktop and Schema on Desktop define the location for Windows XP.

    See Database On CE connection parameter, Schema On CE connection parameter , Database On Desktop connection parameter, and Schema On Desktop connection parameter .

Deploying applications that use one-button synchronization

One-button synchronization requires a set of files, including ulconnect.exe and ulconnect.usm. These files are packaged together in the file ultralite\UltraLiteForMBusinessAnywhere\ulpod.cab. When you deploy the cab file to a Windows CE device, it installs its contents in the proper locations automatically. For Windows XP, you must deploy the files manually.


Deploying applications to Palm OS

You must carry out the following steps to deploy an UltraLite application to a Palm OS device:

  • Deploy your application and UltraLite component.

    For instructions, see UltraLite for M-Business Anywhere Quick Start.

  • Deploy an initial copy of the UltraLite database or schema.

    For instructions, see UltraLite for M-Business Anywhere Quick Start.

    In many situations it is sufficient to deploy an UltraLite schema file only. UltraLite creates a database file from the schema on the first connection attempt. You can then use synchronization to load an initial copy of the data.

    You can create .pdb files for deployment to Palm OS from any of the UltraLite utilities, including the Schema Painter, ulxml, and ulinit.

    You must supply a schema or database using the correct creator ID, so that it can be located by your application. The Database On Palm connection parameter uses the creator ID to find the database.

    See Database On Palm connection parameter, and Schema On Palm connection parameter . For information about using the virtual file system, see VFS On Palm parameter .

  • Deploy the MobiLink synchronization conduit for HotSync.

    This step is required only if the application is synchronizing using HotSync.

    For instructions, see Deploying the MobiLink HotSync conduit.


Tutorial: A Sample Application for M-Business Anywhere

About this chapter

This tutorial guides you through the process of building an UltraLite application for M-Business Anywhere.

Introduction
Lesson 1: Create a project architecture
Lesson 2: Create the application files
Lesson 3: Set up the M-Business Anywhere Server and Client
Lesson 4: Add startup code to your application
Lesson 5: Add inserts to your application
Lesson 6: Add navigation to your application
Lesson 7: Add updates and deletes to your application
Lesson 8: Add synchronization to your application


Introduction

This tutorial describes how to build a cross-platform UltraLite application. At the end of the tutorial you will have an application and small database that synchronizes with a central consolidated database.

Timing

The tutorial takes about 30 minutes if you copy and paste the code. If you enter the code yourself, it takes significantly longer.

Prerequisites

This tutorial assumes that you have M-Business Anywhere installed on your computer and that your machine has a web server that you can use to deliver files.

You must also have access to an M-Business Client in order to test and run the application.

The tutorial assumes a basic familiarity with JavaScript programming language and M-Business Anywhere application development.

The tutorial also assumes that you know how to create an UltraLite schema using the UltraLite Schema Painter. For more information, see The UltraLite Schema Painter.


Lesson 1: Create a project architecture

The first procedure describes how to create an UltraLite database schema. The database schema is a description of the database. It describes the tables, indexes, keys, and publications within the database, and all the relationships between them.

For more information about database schemas, see Creating UltraLite database schema files.

toggle To create an UltraLite database schema

  1. Create a directory for this tutorial.

    This tutorial assumes the directory is c:\Tutorial\mbus. If you create a directory with a different name, use that directory throughout the tutorial.

    Create the following subdirectories for platform-specific files:

    • c:\Tutorial\mbus\PALM_OS
    • c:\Tutorial\mbus\WIN32_OS
    • c:\Tutorial\mbus\WINCE_OS
    • c:\Tutorial\mbus\WINCE_OS\arm

  2. Configure your web server.

    1. Map a virtual directory named tutorial on your web server to c:\Tutorial\mbus. The URL to access this directory will be http://localhost/tutorial.

      For Microsoft IIS, you can make these changes from the management tool.

      For Apache, make a symbolic link named tutorial from your document root to the c:\Tutorial\mbus directory, or copy the tutorial files into your Apache document root.

    2. Ensure that your web server delivers the following files with MIME type application/octet-stream:

      • dll
      • usm
      • prc
      • pdb

      For Microsoft IIS, you can make these changes from the management tool. Go to the virtual directory properties and make the changes under HTTP Headers and File Types.

      For Apache, edit the file mime.types in your conf directory.

  3. Create a database schema using the UltraLite Schema Painter.

    For more information about creating a database schema, see the Lesson 1: Create an UltraLite database schema.

    • Schema filename tutcustomer.usm.

    • Table name Customer

    • Columns in Customer

      Column Name | Data Type (Size) | Column allows NULL values? | Default value
      ID | integer | No | autoincrement
      FName | char(15) | No | None
      LName | char(20) | No | None
      City | char(20) | Yes | None
      Phone | char(12) | Yes | 555-1234
      It is usually better to use global autoincrement or UUID values for primary keys in a synchronizing environment. The autoincrement default is used here to keep the tutorial shorter.

    • Primary key Ascending ID

  4. Save the database schema.

    If you are developing an application for Windows or Windows CE, choose File > Save and choose tutcustomer.usm in the WINCE_OS or the WIN32_OS subdirectory of your tutorial directory as the filename.

    If you are developing an application for Palm OS:

    1. From the File menu, choose Export Schema for Palm.

    2. Enter Syb3 as the creator ID.

    3. Save the file as tutcustomer.pdb in the PALM_OS subdirectory of your tutorial directory.

    A note on Palm Creator IDs
    The creator ID is assigned to you by Palm. You can use Syb3 as your creator ID when you make sample applications. However, when you create a commercial application, you should use your own creator ID.

    If you are developing a cross-platform application, save the schema file in all the above locations.


Lesson 2: Create the application files

The following procedure uses the form to create a user interface. This example uses text boxes for input and output.

toggle Create the application files

  1. Create the file c:\Tutorial\mbus\main.html.

    This file will be the main file of the application. Later in the tutorial, you will add content to the file. For now, you just set it up to include a platform-specific file ul_deps.html. Add the following content to the file:

    <html>
<body>
<a href="AG_DEVICEOS/ul_deps.html"></a>
</body>
</html>

  2. Create the platform-specific files.

    Each of these files references the appropriate UltraLite runtime library and database schema file. Create a file ul_deps.html in each of the operating system subdirectories of your tutorial directory, as follows:

    <!-- PALM_OS\ul_deps.html -->
<html>
  <a href="ulpod9.prc"></a>
  <a href="tutCustomer.pdb"></a>
</html>
    <!-- WINCE_OS\ul_deps.html -->
<html>
  <a href="AG_DEVICEPROCESSOR/ulpod9.dll"></a>
  <a href="tutCustomer.usm"></a>
</html>
    <!-- WIN32_OS\ul_deps.html -->
<html>
  <a href="ulpod9.dll"></a>
  <a href="tutCustomer.usm"></a>
</html>

  3. Copy the UltraLite runtime files to the tutorial directory.

    The ul_deps.html files require that the UltraLite runtime library and database schema be in the proper location relative to the tutorial directory. The schema file is already in place from earlier in the tutorial. You must now copy the UltraLite runtime library into place.

    In the following instructions, paths for the source files are relative to your SQL Anywhere installation.

    • For the Palm OS, copy ulpod9.prc from UltraLite\UltraLiteForMBusinessAnywhere\palm\68k to c:\Tutorial\mbus\PALM_OS.

    • For Windows CE, copy ulpod9.dll from UltraLite\UltraLiteForMBusinessAnywhere\ce\arm to c:\Tutorial\mbus\WINCE_OS\arm.

    • For Windows CP, copy ulpod9.dll from UltraLite\UltraLiteForMBusinessAnywhere\win32\386 to c:\Tutorial\mbus\WIN32_OS.

    All application files are now in place.


Lesson 3: Set up the M-Business Anywhere Server and Client

In this lesson you create an M-Business Anywhere user, group, and channel for your application.

toggle Configure M-Business Anywhere

  1. Open the M-Business Anywhere administration console and login as the admin user.

    The default user ID is admin, with a blank password.

  2. Create a new user.

    Later in this tutorial, you will use the user name and password you create in this step to synchronize from an M-Business client. If you already have an M-Business client set up for this server, you may wish to use a user name that already exists.

    1. Click the Users heading and click New User.

    2. Enter a User Name and Password. The other fields are optional. Click Create.

  3. Create a group and a channel:

    1. Click the Groups heading and click New Group.

    2. Name the new group UltraLite and click Create and Edit.

    3. Under the Web tab, click New Group Channel.

    4. Use the following settings for the channel. Make sure to substitute the correct URL for your web server:

      • Title UltraLite Tutorial

      • Location http://host:port/tutorial/main.html.

        The location is the URL of the tutorial main.html page, as served by your web server.

      • Channel Size Limit 1000 KB

      • Link Depth 2

      • Allow Binary Distribution Yes (checked).

  4. Add the user to the group:

    1. Click the Users heading and find the user you created in step 2.

    2. Click the User Name to show the user's properties.

    3. Click Add/Remove Groups.

    4. Check the UltraLite group and click Update to add the user to this group.

The user, group, and channel are now all set up on M-Business Anywhere. The next step is to synchronize the content of this channel to an M-Business client. You can do this from whichever platform you wish to use.

The next procedure assumes that you have an M-Business client installed. It is recommended that you click Tools > Options and set the client options to Show JavaScript Errors. This setting allows easier debugging of any errors in your application.

toggle Synchronize the channel for your device

  • Synchronize your M-Business client with the UltraLite channel on the M-Business Anywhere Server.

    At this stage there is no content for your application, so the page appears blank.


Lesson 4: Add startup code to your application

In this lesson you add startup code to your application that connects to an UltraLite database. This requires adding HTML to the main page, and adding JavaScript logic to control the application.

toggle Add content to your application

  1. Add content to main.html.

    Add the following form to your application's main page, c:\Tutorial\mbus\main.html, immediately after the <a> tag:

    <form name="custForm">
<input type="text" name="fname" size="15"><br>
<input type="text" name="lname" size="20"><br>
<input type="text" name="city" size="20"><br>
<input type="text" name="phone" size="12"><br>
<input type="text" name="custid" size="10"><br>
<br><br>
    <table>
   <tr>
  <td><input type="button"
       value="Insert" onclick="ClickInsert();">
  </td>
  <td><input type="button"
       value="Update" onclick="ClickUpdate();">
  </td>
  <td>
           <input type="button"
      value="Delete" onclick="ClickDelete();">
  </td>
   </tr>
     <tr>
  <td>
    <input type="button"
     value="Next" onclick="ClickNext();">
  </td>
  <td>
    <input type="button"
     value="Prev" onclick="ClickPrev();">
  </td>
  <td></td>
   </tr>
     <tr>
   <td colspan=3>
        <input type="button"
     value="Synchronize" onclick="ClickSync();">
   </td>
   </tr>
</table>
</form>

  2. Create a JavaScript file c:\Tutorial\mbus\tutorial.js that provides application logic.

  3. Add content to the JavaScript file:

    Add the following code to the top of the file to declare the required UltraLite objects:

    var DatabaseMgr;
var Connection;
var CustomerTable;

    Add connection code:

    function Connect()
{
  DatabaseMgr = CreateObject( "iAnywhere.UltraLite.DatabaseManager.Tutorial" );
  if( DatabaseMgr == null ) {
    alert( "Error, make sure POD is on device" );
    return;
  }

  var connParms = DatabaseMgr.createConnectionParms();
  var dir = DatabaseMgr.directory;

  connParms.schemaOnPalm = "tutCustomer";
  connParms.databaseOnPalm = "Syb3";

  connParms.databaseOnCE = dir + "\\tutCustomer.udb";
  connParms.schemaOnCE = dir + "\\tutCustomer.usm";

  connParms.schemaOnDesktop = dir + "\\tutCustomer.usm";
  connParms.databaseOnDesktop = dir + "\\tutCustomer.udb";

  connParms.userID = "dba";
  connParms.password = "sql";
      try {
    // try to connect to an existing database
    Connection = DatabaseMgr.openConnectionWithParms( connParms );
    alert("Connected to an existing database");
  } catch( ex ) {
    if( DatabaseMgr.sqlCode != DatabaseMgr.SQLError.SQLE_ULTRALITE_DATABASE_NOT_FOUND ) {
      alert( ex.getMessage() );
      return;
    } else {
      try {
        // the database does not exist, create one
        Connection = DatabaseMgr.createDatabaseWithParms( connParms );
        alert("Created a new database");
      } catch( ex2 ) {
        alert( ex2.getMessage() );
        return;
      }
    }
  }
}

  4. Use the onload event handler to connect to the database when the application is started:

    1. Import tutorial.js into main.html by adding the following line immediately before the <body> tag:

      <script src="tutorial.js"></script>

    2. Edit main.html and change the <body> tag to the following:

      <body onload="Connect();">

  5. Test your application.

    Synchronize your M-Business Client and start the application. A message box appears when your application creates the UltraLite database. Once this is working properly, you can continue to the next lesson.


Lesson 5: Add inserts to your application

This lesson shows how to fill out your application with data manipulation and navigation logic.

toggle Open the table

  1. Write code to initialize the CustomerTable that represents the Customer table in your database.

    Add the following code to the end of the Connect() function in tutorial.js:

    try {
  CustomerTable = Connection.getTable( "customer", null );
  CustomerTable.open();
} catch( ex3 ) {
  alert("Error: " + ex3.getMessage() );
}

  2. Add variables to move data between the database and the web form.

    Add the following declarations to the top of tutorial.js, before the Connect() function.

    var Cust_FName = "";
var Cust_LName = "";
var Cust_City = "";
var Cust_Phone = "";
var Cust_Id = "";

  3. Create procedures to fetch and display customer data.

    Add the following function to tutorial.js, immediately after the Connect() function. It fetches the current row of the customer and also ensures that NULL columns display as empty strings:

    function FetchCurrentRow()
{
  var id;
  if( CustomerTable.getRowCount() == 0 ) {
    Cust_FName = "";
    Cust_LName = "";
    Cust_City = "";
    Cust_Phone = "";
    Cust_Id = "";
  } else {
    id = CustomerTable.schema.getColumnID("FName");
    Cust_FName = CustomerTable.getString(id);
    id = CustomerTable.schema.getColumnID("LName");
    Cust_LName = CustomerTable.getString(id);
    id = CustomerTable.schema.getColumnID("city");
    if( CustomerTable.isNull(id) ) {
      Cust_City = "";
    } else {
      Cust_City = CustomerTable.getString(id);
    }
    id = CustomerTable.schema.getColumnID("phone");
    if( CustomerTable.isNull(id) ) {
      Cust_Phone = "";
    } else {
      Cust_Phone = CustomerTable.getString(id);
    }

    id = CustomerTable.schema.getColumnID("id");
    Cust_Id = CustomerTable.getString(id);
  }
}

    Add the following JavaScript to main.html, immediately before the closing </body> tag. DisplayCurrentRow takes the values from the database and displays them in the web form. FetchForm takes the current values in the web form and makes them available to the database code.

    <script>
function DisplayCurrentRow()
{
  FetchCurrentRow();
  document.custForm.fname.value = Cust_FName;
  document.custForm.lname.value = Cust_LName;
  document.custForm.city.value = Cust_City;
  document.custForm.phone.value = Cust_Phone;
  document.custForm.custid.value = Cust_Id;
}
    function FetchForm()
{
  Cust_FName = document.custForm.fname.value;
  Cust_LName = document.custForm.lname.value;
  Cust_City = document.custForm.city.value;
  Cust_Phone = document.custForm.phone.value;
}
</script>

  4. Call DisplayCurrentRow when the application is loaded.

    Modify the <body> tag at the top of main.html as follows:

    <body onload="Connect(); DisplayCurrentRow();">

Although there is no data in your database, so that no rows are displayed, this is a good place to synchronize M-Business Client to ensure that you have not introduced bugs.

toggle Add code to insert rows

  • Write code to implement the Insert button.

    In the following procedure, the call to InsertBegin puts the application into insert mode and sets all values in the current row to their defaults. For example, the ID column receives the next autoincrement value. The column values are set and the new row is inserted.

    Add the following function to tutorial.js, immediately after FetchCurrentRow():

    function Insert()
{
  var id;

  try {
    CustomerTable.insertBegin();
    id = CustomerTable.schema.getColumnID("FName");
    CustomerTable.setString(id, Cust_FName);
    id = CustomerTable.schema.getColumnID("LName");
    CustomerTable.setString(id, Cust_LName);
    id = CustomerTable.schema.getColumnID("city");
    if( Cust_City.length > 0 ) {
      CustomerTable.setString(id, Cust_City);
    }
    id = CustomerTable.schema.getColumnID("phone");
    if( Cust_Phone.length > 0 ) {
      CustomerTable.setString(id, Cust_Phone);
    }
    CustomerTable.insert();
    CustomerTable.moveLast();
  } catch( ex ) {
    alert( "Insert error: " + ex.getMessage() );
  }
}

    Add the following function to main.html, immediately after the FetchForm() function:

    function ClickInsert()
{
  FetchForm();
  Insert();
  DisplayCurrentRow();
}

You can now test your application.

toggle Test your application

  1. Synchronize your M-Business Client.

  2. Run the application.

    After an initial message box, the form is displayed.

  3. Insert two rows into the table:

    1. Enter a first name of Jane in the first text box and a last name of Doe in the second text box. Click Insert.

      A row is added to the table with these values. The application moves to the last row of the table and displays the row. The label displays the automatically incremented value of the ID column that UltraLite assigned to the row.

    2. Enter a first name of John in the first text box and a last name of Smith in the second. Click Insert.

The next step is to add navigation buttons


Lesson 6: Add navigation to your application

This lesson describes code for scrolling forwards and backwards through the rows of a result set.

toggle Add navigation code to your application

  1. Add the MoveNext function to tutorial.js, immediately after the Insert() function:

    function MoveNext()
{
  if( ! CustomerTable.moveNext() ) {
    CustomerTable.moveLast();
  }
}

  2. Add the MovePrev function to tutorial.js, immediately after the MoveNext() function:

    function MovePrev()
{
  if( ! CustomerTable.movePrevious() ) {
    CustomerTable.moveFirst();
  }
}

  3. Add the following procedures to main.html:

    function ClickNext()
{
  MoveNext();
  DisplayCurrentRow();
}
    function ClickPrev()
{
  MovePrev();
  DisplayCurrentRow();
}

  4. Synchronize your application and test the navigation buttons.

    When the form is first displayed, the controls are empty as the current position is before the first row. After the form is displayed, click Next and Previous to move through the rows of the table.


Lesson 7: Add updates and deletes to your application

This lesson describes code for updating and deleting rows.

toggle Add update and delete functions to your application

  1. Add the Update function to tutorial.js:

    function Update()
{
  var id;
  try {
    CustomerTable.updateBegin();

    id = CustomerTable.schema.getColumnID("fname");
    CustomerTable.setString(id, Cust_FName);
    id = CustomerTable.schema.getColumnID("lname");
    CustomerTable.setString(id, Cust_LName);
    id = CustomerTable.schema.getColumnID("city");
    if( Cust_City.length > 0 ) {
      CustomerTable.setString(id, Cust_City);
    } else {
      CustomerTable.setNull(id);
    }
    id = CustomerTable.schema.getColumnID("phone");
    if( Cust_Phone.length > 0 ) {
      CustomerTable.setString(id, Cust_Phone);
    } else {
      CustomerTable.setNull(id);
    }
    CustomerTable.update();
  } catch( ex ) {
    alert( "Update error: " + ex.getMessage() );
  }
}

  2. Add the Delete function to tutorial.js:

    function Delete()
{
  if( CustomerTable.getRowCount() == 0 ) {
    return;
  }
  CustomerTable.deleteRow();
  CustomerTable.moveRelative(0);
}

  3. Add the following functions to main.html:

    function ClickUpdate()
{
  FetchForm();
  Update();
  DisplayCurrentRow();
}
    function ClickDelete()
{
  Delete();
  DisplayCurrentRow();
}

  4. Synchronize your M-Business Client and run the application.


Lesson 8: Add synchronization to your application

The following procedure implements synchronization.

toggle Add a synchronization function to your application

  1. Add the Synchronize() function to tutorial.js:

    The synchronization parameters are stored in the ULSyncParms object. For example, the ULSyncParms.UserName property specifies the user name that MobiLink looks for. The ULSyncParms.SendColumnNames property specifies that the column names will be sent to MobiLink so it can generate upload and download scripts.

    This function uses a TCP/IP synchronization stream and the default network communication options (stream parameters). These default options assume that you are synchronizing from either a Windows CE client connected to the computer running the MobiLink server via ActiveSync, or from a Windows XP client running on the same computer as MobiLink. If this is not the case, change the synchronization stream type and set the network communication options to the appropriate values.

    For more information, see Method setStream and Method setStreamParms

    function Synchronize()
{
  var SyncParms = Connection.syncParms;

  SyncParms.setUserName("user-name");
  SyncParms.setStream(SyncParms.STREAM_TYPE_TCPIP);
  SyncParms.setVersion("ul_default");
  SyncParms.setSendColumnNames(true);

  try {
    Connection.synchronize();
  } catch( ex ) {
    alert( "Sync error: " + ex.getMessage() );
  }
}

  2. Add the following function to main.html:

    function ClickSync()
{
  window.showBusy = true;
  Synchronize();
  window.showBusy = false;
  DisplayCurrentRow();
}

  3. Synchronize your M-Business Client.

    This synchronization downloads the latest version of the application. It does not synchronize your database.

The final step in this tutorial is to synchronize your UltraLite database. The ASA 9.0 Sample database has a Customer table with columns matching those in the Customer table in your UltraLite database. The following procedure synchronizes your database with the ASA 9.0 Sample database.

toggle To synchronize your application

  1. From a command prompt, start the MobiLink synchronization server by running the following command line.

    dbmlsrv9 -c "dsn=ASA 9.0 Sample" -v+ -zu+ -za

    The -zu+ and -za command line options provide automatic addition of users and generation of synchronization scripts. For more information about these options, see MobiLink Synchronization Server Options.

  2. In M-Business Client, click Delete repeatedly to delete all the rows in your table.

    Any rows in the table would be uploaded to the Customer table in the ASA 9.0 Sample database.

  3. Synchronize your application.

    Click Synchronize. The MobiLink synchronization server window displays the synchronization progress.

  4. When the synchronization is complete, click Next and Previous to move through the rows of the table.

This completes the tutorial.


UltraLite for M-Business Anywhere API Reference

About this chapter

This chapter describes the UltraLite for M-Business Anywhere API, a set of classes and methods that allow you to write code for applications that use UltraLite databases. Each topic contains information about a specific class, method, constant, or enum. The reference is organized by class, with associated methods beneath.

Data types in UltraLite for M-Business Anywhere
Class AuthStatusCode
Class Connection
Class ConnectionParms
Class DatabaseManager
Class DatabaseSchema
Class IndexSchema
Class PreparedStatement
Class PublicationSchema
Class ResultSet
Class ResultSetSchema
Class SQLError
Class SQLType
Class SyncParms
Class SyncResult
Class TableSchema
Class ULTable
Class UUID


Data types in UltraLite for M-Business Anywhere

JavaScript has only one numeric data type and only one Date data type.

The prototypes in this API Reference include a variety of other data types in the method and property descriptions. These types are internal M-Business Anywhere data types. Distinct numeric data types such as UInt32 (unsigned 32-bit integer) are reported here to give an idea of the size and precision of data that may be supplied. Distinct time-related data types (Date, Time, Timestamp) are reported so that you can write code to extract the required information from the supplied data if necessary.


Class AuthStatusCode

Enumerates the status codes that may be reported during MobiLink user authentication.

This object can be obtained from DatabaseManager as follows:

var authStatus = dbMgr.AuthStatusCode;


Properties

The following constants are properties of AuthStatusCode

Constant | Value | Description
UNKNOWN | 0 | Authorization status is unknown, possibly because the connection has not yet performed a synchronization.
VALID | 1000 | User ID and password were valid at time of synchronization.
VALID_BUT_EXPIRES_SOON | 2000 | User ID and password were valid at time of synchronization but will expire soon.
EXPIRED | 3000 | User ID or password has expired; authorization failed.
INVALID | 4000 | Bad user ID or password; authorization failed.
IN_USE | 5000 | User ID is already in use; authorization failed.


Method toString

Prototype

String toString();

Returns

The name of the code or unknown if not a recognized code.

Remarks

Generates the string name of the authorization status code constant.


Class Connection

Represents a connection to an UltraLite database.

Connections are instantiated using one of the following methods:

  • DatabaseManager.openConnection
  • DatabaseManager.openConnectionWithParms
  • DatabaseManager.createDatabase
  • DatabaseManager.createDatabaseWithParms

You must open a connection before carrying out any other operation, and you must close the connection after you have finished all operations on the connection and before your application terminates.

You must close all tables opened on a connection before closing the connection.

When a JavaScript Error is thrown because of a failed UltraLite database operation, the SQL error code is set on the sqlCode field of the Connection object.

Properties
Method changeEncryptionKey
Method close
Method commit
Method countUploadRow
Method getDatabaseID
Method getGlobalAutoIncrementUsage
Method getLastDownloadTime
Method getLastIdentity
Method getNewUUID
Method getTable
Method grantConnectTo
Method isOpen
Method prepareStatement
Method resetLastDownloadTime
Method revokeConnectFrom
Method rollback
Method rollbackPartialDownload
Method setDatabaseID
Method saveSyncParms
Method startSynchronizationDelete
Method stopSynchronizationDelete
Method synchronize
Method synchronizeWithParm


Properties

Prototype | Description
Boolean autoCommit Controls whether a commit is performed after each statement (insert, update or delete).

If autoCommit is false, a commit or rollback is performed only when the user invokes the commit() or rollback() method.

By default, a database commit is performed after each successful statement. If the commit fails, you have the option to execute additional SQL statements and perform the commit again, or execute a rollback statement.

Boolean databaseNew (read-only) | Indicates if the database was new when this connection was opened (true), or if the database already existed when this connection was opened (false).
String openParms (read-only) Gets the open parameters string as a semicolon-separated list of name=value pairs.

See Connection Parameters.
DatabaseSchema databaseSchema (read-only) | Gets the database schema. This property is valid only while its connection is open.
Boolean skipMBASync (read-write) Controls whether the database should be synchronized during one-button synchronization (false) or whether it should be skipped (true).

See One-button synchronization.
Int32 sqlCode (read-only) Gets the SQL Code of the last operation on this connection.

The SQL Code is the standard Adaptive Server Anywhere code and is reset by any subsequent UltraLite database operation on this connection.
SyncParms syncParms (read-only) Gets synchronization settings for this connection.

See Synchronization parameters.
SyncResult syncResult (read-only) Gets the results of the most recent synchronization for this connection.

See Synchronization parameters.
INVALID_DATABASE_ID (read-only) | A constant indicating an invalid database.


Method changeEncryptionKey

Prototype

changeEncryptionKey(String newKey)

Parameters

  • newKey The new encryption key for the database.

Remarks

Changes the database's encryption key to the specified new key.

If the encryption key is lost, it is not possible to open the database.


Method close

Prototype

close()

Remarks

Closes this connection.

Once a connection is closed, it can not be reopened. To reopen a connection, a new connection object must be created and opened.

It is an error to use any object (table, schema, etc.) associated with a closed connection.

In JavaScript, the closed connection object is not set to NULL automatically after it is closed. It is recommended that you explicitly set the connection object to NULL after closing the connection.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class Connection

Method commit

Prototype

commit()

Remarks

Commits outstanding changes to the database.


Method countUploadRow

Prototype

UInt32 countUploadRow( UInt32 mask, UInt32 threshold)

Parameters

  • mask set of publications to check. See PublicationSchema class for more information.

  • threshold value that determines the maximum number of rows to count, and so limits the amount of time taken by the call. A value of 0 corresponds to the maximum limit. A value of 1 determines if any rows need to be synchronized. threshold must be in range [0,0x0ffffffff].

Returns

The number of rows to be uploaded when the next synchronization takes place.


Method getDatabaseID

Prototype

UInt32 getDatabaseID( )

Remarks

Gets the current Database ID value, as set by setDatabaseID().

If the value has not been set, the constant Connection.INVALID_DATABASE_ID is returned.


Method getGlobalAutoIncrementUsage

Prototype

UInt16 getGlobalAutoIncrementUsage( )

Returns

The percentage of available global increment values used so far.

Remarks

Returns the percentage of available global autoincrement values that have been used.

If the percentage approaches 100, your application should set a new value for the global database ID using the setDatabaseID.


Method getLastDownloadTime

Prototype

Date getLastDownloadTime( UInt32 mask )

Parameters

  • mask A set of publications to check.

Returns

The timestamp of the most recent download.

Remarks

The parameter mask must reference a single publication or be the special constant PublicationSchema.SYNC_ALL_DB for the time of the last download of the full database.

See also
  • Class PublicationSchema


Method getLastIdentity

Prototype

UInt64 getLastIdentity()

Returns

The most recent identity value used.

Remarks

This function is equivalent to the following SQL statement:

  SELECT @@identity

The function is particularly useful in the context of global autoincrement columns. The returned value is an unsigned 64-bit integer, database data type UNSIGNED BIGINT. Since this statement only allows you to determine the most recently assigned default value, you should retrieve this value soon after executing the insert statement to avoid spurious results.

Occasionally, a single insert statement may include more than one column of type global autoincrement. In this case, the return value is one of the generated default values, but there is no reliable means to determine which one. For this reason, you should design your database and write your insert statements so as to avoid this situation.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class Connection

Method getNewUUID

Prototype

UUID getNewUUID()

Returns

A new UUID value.


Method getTable

Prototype

Table getTable(String name, String persistName )

Parameters

  • name name of the table to fetch.

  • persistName The name for cross-page JavaScript object persistence. Set to null if no persistence is required (for example, if the application has only a single HTML page).

Remarks

Creates and returns a reference to the requested table in the database.


Method grantConnectTo

Prototype

grantConnectTo(String uid, String pwd)

Parameters

  • uid user ID to grant access to. The maximum length is 16 characters.

  • pwd The password for the user ID.

Remarks

Grants access to an UltraLite database for a user ID with a specified password. If an existing user ID is specified, this function updates the password for the user. UltraLite supports a maximum of 4 users. This method is enabled only if user authentication was enabled when the connection was opened.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class Connection

Method isOpen

Prototype

Boolean isOpen();

Returns

true if the connection is open, false otherwise.

Remarks

Checks whether this connection is currently open.


Method prepareStatement

Prototype

PreparedStatement prepareStatement(String sql, String persistName)

Parameters

  • sql a SQL statement that may contain one or more '?' IN parameter placeholder.

  • persistName The name for cross-page JavaScript object persistence. Set to null if no persistence is required (for example, if the application has only a single HTML page).

Remarks

Pre-compiles and stores into a PreparedStatement object a SQL statement with or without IN parameters. This object can then be used to efficiently execute this statement multiple times.


Method resetLastDownloadTime

Prototype

resetLastDownloadTime(UInt32 mask)

Parameters

  • mask set of publications to reset.

Remarks

Resets the time of the most recent download.


Method revokeConnectFrom

Prototype

revokeConnectFrom(String uid )

Parameters

  • uid user ID to be excluded from database access. The maximum length is 16 characters.

Remarks

Revokes access from an UltraLite database for a user ID.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class Connection

Method rollback

Prototype

rollback( )

Remarks

Rolls back outstanding changes to the database.


Method rollbackPartialDownload

Prototype

rollbackPartialDownload( )

Remarks

Roll back the changes from a failed synchronization.

When a communication error occurs during the download phase of synchronization, UltraLite can apply the downloaded changes, so that the synchronization can be resumed from the place it was interrupted. If the download changes are not needed (the user or application does not want to resume the download at this point), RollbackPartialDownload rolls back the failed download transaction.


Method setDatabaseID

Prototype

setDatabaseID( UInt32 value )

Parameters

  • value database ID value. value must be in range [0,0x0ffffffff].

Remarks

Sets the database ID value to be used for global autoincrement columns.


Method saveSyncParms

Prototype

saveSyncParms( )

Remarks

Saves the synchronization parameters for use by HotSync or for use during one-button synchronization.

Do not confuse the saveSyncParms method with the Connection.SyncParms property. The SyncParms property is used to define the synchronization parameters for this connection. The setSyncParms method just saves these parameters so that HotSync can use them.

See also
  • One-button synchronization


Method startSynchronizationDelete

Prototype

startSynchronizationDelete( )

Remarks

Mark for synchronization all subsequent deletes made by this connection. Once this function is called, all delete operations are again synchronized.


Method stopSynchronizationDelete

Prototype

stopSynchronizationDelete( )

Remarks

Prevents delete operations from being synchronized. This is useful for deleting old information from an UltraLite database to save space, while not deleting this information on the consolidated database.


Method synchronize

Prototype

synchronize( )

Remarks

Synchronize the database using the current SyncParms object. A detailed result status is reported in this connection's SyncResult object. The synchronization is carried out using the synchronization properties defined in the Connection.SyncParms object for this connection.


Method synchronizeWithParm

Prototype

synchronizeWithParm( SyncParms parms)

Parameters

  • parms The SyncParms object to use for this synchronization.

Remarks

Synchronize the database using the specified SyncParms object. This method makes it possible to share synchronization parameters among connections.

A detailed result status is reported in this connection's SyncResult object.


Class ConnectionParms

Specifies parameters for opening a connection to an UltraLite database.

Databases are created with a single authenticated user, DBA, whose initial password is SQL. By default, connections are opened using the user ID DBA and password SQL. To disable the default user, use Connection.revokeConnectFrom. To add a user or change a user's password, use Connection.grantConnectTo.

Currently, only one connection can be opened at any time. Only one database may be active at a given time. Attempts to open a connection to a different database while other connections are open result in an error.

Properties


Properties

The properties of the class are listed here.

Prototype | Description
String additionalParms (read-write) Additional parameters specified as name=value pairs separated with semi-colons.

See Additional Parms connection parameter.
String cacheSize (read-write) The size of the cache. CacheSize values are specified in bytes. Use the suffix k or K for kilobytes and use the suffix m or M for megabytes. The default cache size is sixteen pages. Given a default page size of 4 KB, the default cache size is 64 KB.

See Cache Size connection parameter .
String connectionName (read-write) A name for the connection. The connection name is used to share a single connection across multiple web pages.

See Connection Name connection parameter, and Maintaining connections and application state across pages.
String databaseOnCE (read-write) The filename of the database deployed to PocketPC.

See Database On CE connection parameter.
String databaseOnDesktop (read-write) The filename of the database deployed to Windows XP.

See Database On Desktop connection parameter.
String databaseOnPalm (read-write) The UltraLite database creator ID on the Palm device.

See Database On Palm connection parameter.
String encryptionKey (read-write) A key for encrypting the database. OpenConnection and OpenConnectionWithParms must use the same key as specified during database creation. Suggestions for keys are:

  1. Select an arbitrary, lengthy string

  2. Select strings with a variety of numbers, letters and special characters, so as to decrease the chances of key penetration.

See Encryption Key connection parameter .
String parmsUsed (read-only) | The connection parameters used by the DatabaseManager. Useful for debugging purposes.
String password (read-write) The password for an authenticated user. Databases are initially created with one authenticated user password SQL. Passwords are case-insensitive if the database is case-insensitive and case-sensitive if the database is case-sensitive. The default value is SQL.

See Password connection parameter.
String schemaOnCE (read-write) The schema filename deployed to PocketPC.

See Schema On CE connection parameter .
String schemaOnDesktop (read-write) The schema filename deployed to Windows XP.

See Schema On Desktop connection parameter .
String schemaOnPalm (read-write) The schema PDB on the Palm device.

See Schema On Palm connection parameter .
String userID (read-write) The authenticated user for the database. Databases are initially created with one authenticated user DBA. The UserID is case-insensitive if the database is case-insensitive and case-sensitive if the database is case-sensitive. The default value is DBA.

See User ID connection parameter.
Boolean VFSOnPalm (read-write) Indicates whether the Palm database is on a virtual file system (true) or on the Palm store (false).

See VFS On Palm parameter .


Class DatabaseManager

Manages connections to an UltraLite database.

You must open a connection before carrying out any other operation, and you must close the connection after you have finished all operations on the connection, and before your application terminates. You must close all tables opened on a connection before closing the connection.

Properties
Method createDatabase
Method createDatabaseWithParms
Method dropDatabase
Method dropDatabaseWithParms
Method openConnection
Method openConnectionWithParms
Method reOpenConnection


Properties

The properties of the class are listed here.

Property | Description
AuthStatusCode AuthStatusCode (read-only) | Gets the AuthStatusCode object associated with the most recent synchronization.
String directory (read-only) The directory in which M-Business Anywhere is running. This directory is where M-Business Anywhere places the downloaded schema file.

On Palm OS, this property is NULL.
UInt32 runtimeType Set the runtime type to be either the UltraLite runtime library or the UltraLite database engine. The value is an enum, and is one of the following:
  • DatabaseManager.UL_STANDALONE
  • DatabaseManager.UL_ENGINE_CLIENT
Int32 sqlCode (read-only) | Gets the SQL Code value associated with the most recent operation.
SQLError SQLError (read-only) | Gets the SQLError object for the most recent operation.
SQLType SQLType (read-only) | Gets the SQLType object for the most recent operation.
PODSUInt32 UL_STANDALONE (read only) | A constant indicating that the runtime type is the UltraLite runtime library.
PODSUInt32 UL_ENGINE_CLIENT (read-only) | A constant indicating that the runtime type is the UltraLite database engine.


Method createDatabase

Prototype

Connection createDatabase( String parms )

Parameters

  • parms parameters for creating the database and opening a connection to it. Parameter keywords are case-insensitive, and most values are case-sensitive. parms is used to create the database, specify the schema for the newly-created database, and open the connection.

Returns

An opened Connection object.

Remarks

Creates a database and opens a connection to the database as specified by parms. If the database already exists, a SQLE_DATABASE_NOT_CREATED exception is thrown.

Only one database may be active at a given time. Attempts to open a connection to a database result in an error if there are connections open to a different database.

Connection.databaseNew is set to true to indicate that the database was created when the connection was opened. You must close the connection after you have finished all operations on the connection, and before your application terminates. You must close all tables opened on a connection before closing the connection.


Method createDatabaseWithParms

Prototype

Connection createDatabaseWithParms( ConnectionParms parms)

Parameters

  • parms A ConnectionParms object holding parameters for creating the database and opening a connection to it.

Returns

An opened connection object

Remarks

Creates a database and opens a connection to the database as specified by parms. If the database already exists, an error is thrown. You can check Connection.sqlCode within the error catching code to identify the cause of the error.

Only one database may be active at a given time. Attempts to open a connection to a database will result in an error if there are connections open to a different database.

Connection.databaseNew is set to true to indicate that the database was created when the connection was opened. You must close the connection after you have finished all operations on the connection, and before your application terminates. You must close all tables opened on a connection before closing the connection.


Method dropDatabase

Prototype

dropDatabase(String parms)

Parameters

  • parms parameters for identifying a database.

Remarks

Deletes the specified database.

parms is a semicolon-separated list of keyword=value pairs ("param1=value1;param2=value2"). Parameter keywords are case-insensitive, and most values are case-sensitive.

You can not drop a database that has open connections.


Method dropDatabaseWithParms

Prototype

dropDatabaseWithParms( ConnectionParms parms)

Parameters

  • parms parameters for identifying a database. For more information see Class ConnectionParms.

Remarks

Deletes the specified database file.

You can not drop a database that has open connections.


Method openConnection

Prototype

Connection openConnection( String parms)

Parameters

  • parms A String holding the parameters for opening a connection as a set of keyword=value pairs. Parameter keywords are case-insensitive, and most values are case-sensitive.

Returns

An opened connection.

Remarks

Opens a connection to the database specified by parms. If the database does not exist, an error is thrown. You can check Connection.sqlCode within the error catching code to identify the cause of the error.

Only one database may be active at a given time. Attempts to open a connection to different database while other connections are open will result in an error.

Connection.databaseNew is set to false to indicate that the database was not created when the connection was opened. You must close the connection after you have finished all operations on the connection, and before your application terminates. You must close all tables opened on a connection before closing the connection.


Method openConnectionWithParms

Prototype

Connection openConnectionWithParms( ConnectionParms parms )

Parameters

  • parms A ConnectionParms object holding the parameters for opening a connection.

Returns

An opened Connection object.

Remarks

Opens a connection to the database specified by parms. If the database does not exist, an exception is thrown. You can check Connection.sqlCode to find out more about the cause of the error.

Only one database may be active at a given time. Attempts to open a connection to different database while other connections are open will result in an error.

Connection.databaseNew is set to false to indicate that the database was not created when the connection was opened. You must close the connection after you have finished all operations on the connection, and before your application terminates. You must close all tables opened on a connection before closing the connection.


Method reOpenConnection

Prototype

Connection reOpenConnection( String connectionName )

Parameters

  • persistName The name of the connection to be reopened, as specified in the Connection.connectionName property.

Returns

An opened Connection object. The method is used to maintain connections across multiple web pages.


Class DatabaseSchema

Represents the schema of an UltraLite database. A DatabaseSchema object is attached to a connection and is only valid while that connection is open.

Constants
Method applyFile
Method applyFileWithParms
Method getCollationName
Method getDatabaseProperty
Method getDateFormat
Method getDateOrder
Method getNearestCentury
Method getPrecision
Method getPublicationCount
Method getPublicationName
Method getPublicationSchema
Method getSignature
Method getTableCount
Method getTableCountInPublications
Method getTableName
Method getTimeFormat
Method getTimestampFormat
Method isCaseSensitive
Method isOpen


Constants

Constant | Description
SYNC_ALL_DB | Synchronize all tables in the database.
SYNC_ALL_PUBS | Synchronize all publications in the database.

The members of the class are listed here.


Method applyFile

Prototype

applyFile(String parms)

Parameters

  • parms parameters for specifying the schema to be applied to the database.

Remarks

Applies a database schema file to the database. All instances of TableSchema, IndexSchema, and PublicationSchema will be invalidated and will need to be replaced.

parms is a semicolon-separated list of keyword=value pairs ("param1=value1;param2=value2"). Parameter keywords are case-insensitive, and most values are case-sensitive.


Method applyFileWithParms

Prototype

applyFileWithParms( ConnectionParms parms)

Parameters

  • parms A ConnectionParms object holding parameters for specifying the schema to be applied to the database.

Remarks

Applies a database schema file to the database. All instances of TableSchema, IndexSchema, and PublicationSchema will be invalidated and will need to be replaced.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class DatabaseSchema

Method getCollationName

Prototype

String getCollationName()

Returns

A string identifying the character set and sort order used in this database.


Method getDatabaseProperty

Prototype

String getDatabaseProperty(String name)

Parameters

  • name name of the database property.

Returns

Returns the value of the specified database property. Recognized properties are:

  • "DATE_FORMAT" The date format used for string conversions by the database.

  • "DATE_ORDER" The date order used for string conversions by the database.

  • "NEAREST_CENTURY" The nearest century used for string conversions by the database.

  • "PRECISION" The floating point precision used for string conversions by the database.

  • "SCALE" The minimum number of digits after the decimal point when an arithmetic result is truncated to the maximum PRECISION during string conversions by the database.

  • "TIME_FORMAT" The time format used for string conversions by the database.

  • "TIMESTAMP_FORMAT" The timestamp format used for string conversions by the database.

  • "TIMESTAMP_INCREMENT" The minimum difference between two unique timestamps, in nanoseconds (1,000,000th of a second).


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class DatabaseSchema

Method getDateFormat

Prototype

String getDateFormat()

Returns

The date format used for string conversions.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class DatabaseSchema

Method getDateOrder

Prototype

String getDateOrder()

Returns

The date order used for string conversions.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class DatabaseSchema

Method getNearestCentury

Prototype

String getNearestCentury()

Returns

The nearest century used for string conversions.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class DatabaseSchema

Method getPrecision

Prototype

String getPrecision( )

Returns

The floating point precision used for string conversions.


Method getPublicationCount

Prototype

UInt16 getPublicationCount( )

Returns

The number of publications in the database.

Remarks

Publication IDs range from 1 to getPublicationCount(), inclusively. Publication IDs are not publication masks.

Note: Publication IDs, masks, and count may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached IDs, masks, and counts after a schema upgrade.


Method getPublicationName

Prototype

String getPublicationName( UInt16 pubID )

Parameters

  • pubID ID of the publication. pubID must be in range [1,getPublicationCount().

Returns

The name of the publication identified by the specified publication ID. Publication IDs are not publication masks.

Remarks

Note: Publication IDs, masks, and count may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached IDs, masks, and counts after a schema upgrade.


Method getPublicationSchema

Prototype

PublicationSchema getPublicationSchema( String name )

Parameters

  • name name of the publication.

Returns

The publication schema corresponding to the named publication.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class DatabaseSchema

Method getSignature

Prototype

String getSignature( )

Returns

The signature of this database.


Method getTableCount

Prototype

UInt16 getTableCount( )

Returns

The number of tables, or 0 if the connection is not open.

Remarks

Returns the number of tables in the database. Table IDs range from 1 to getTableCount(), inclusively.

Note: Table IDs and count may change during a schema upgrade. To correctly identify a table, access it by name or refresh the cached IDs and counts after a schema upgrade.


Method getTableCountInPublications

Prototype

UInt16 getTableCountInPublications( UInt32 mask )

Parameters

  • mask set of publications to check.

Returns

The number of tables included in the specified publication mask. The count does not include tables whose names end in _nosync.

Remarks

Note: Publication IDs, masks, and count may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached IDs, masks, and counts after a schema upgrade.


Method getTableName

Prototype

String getTableName( UInt16 tableID )

Parameters

  • tableID ID of the table. tableID must be in range [1,getTableCount()].

Returns

The name of the table identified by the specified table ID.

Remarks

Note: Table IDs may change during a schema upgrade. To correctly identify a table, access it by name or refresh the cached IDs after a schema upgrade.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class DatabaseSchema

Method getTimeFormat

Prototype

String getTimeFormat()

Returns

The time format used for string conversions.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class DatabaseSchema

Method getTimestampFormat

Prototype

String getTimestampFormat()

Remarks

The timestamp format used for string conversions.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class DatabaseSchema

Method isCaseSensitive

Prototype

Boolean isCaseSensitive()

Returns

True if the database is case sensitive, false otherwise.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class DatabaseSchema

Method isOpen

Prototype

Boolean isOpen()

Returns

True if the database schema is open, false otherwise.

Remarks

Checks whether this database schema is currently open.


Class IndexSchema

Represents the schema of an UltraLite table index.

This object cannot be directly instantiated. Index schemas are created using the TableSchema.getPrimaryKey, TableSchema.getIndex and TableSchema.getOptimalIndex methods.

Method getColumnCount
Method getColumnName
Method getName
Method getReferencedIndexName
Method getReferencedTableName
Method isColumnDescending
Method isForeignKey
Method isForeignKeyCheckOnCommit
Method isForeignKeyNullable
Method isPrimaryKey
Method isUniqueIndex
Method isUniqueKey


Method getColumnCount

Prototype

UInt16 getColumnCount( )

Returns

The number of columns in this index. Column IDs in indexes range from 1 to getColumnCount(), inclusively.

Column IDs and count may change during a schema upgrade. Column IDs from an index are different than the column IDs in a table or another index.


Method getColumnName

Prototype

String getColumnName(UInt16 colIDInIndex )

Parameters

  • colIDInIndex ID in this index of the column. colIDInIndex must be in range [1, getColumnCount()].

Returns

The name of the colIDInIndex'th column in this index.

Column IDs and count may change during a schema upgrade. Column IDs from an index are different than the column IDs in a table or another index.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class IndexSchema

Method getName

Prototype

String getName()

Returns

The name of this index.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class IndexSchema

Method getReferencedIndexName

Prototype

String getReferencedIndexName()

Returns

The name of the referenced primary index if this index is a foreign key.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class IndexSchema

Method getReferencedTableName

Prototype

String getReferencedTableName()

Returns

The name of the referenced primary table if index is a foreign key.


Method isColumnDescending

Prototype

Boolean isColumnDescending(String name)

Parameters

  • name name of the column.

Returns

True if column is used in descending order, false if column is used in ascending order.


Method isForeignKey

Prototype

Boolean isForeignKey()

Returns

True if index is the foreign key, false if index is not the foreign key.

Remarks

Columns in a foreign key may reference a non-null unique index of another table.


Method isForeignKeyCheckOnCommit

Prototype

Boolean isForeignKeyCheckOnCommit()

Returns

true if referential integrity is checked on commits, false if it is checked on inserts and updates.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class IndexSchema

Method isForeignKeyNullable

Prototype

Boolean isForeignKeyNullable()

Returns

true if this foreign key is nullable, false if this foreign key is not nullable.


Method isPrimaryKey

Prototype

Boolean isPrimaryKey()

Returns

True if index is the primary key, false if index is not the primary key.

Remarks

Columns in the primary key may not be null.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class IndexSchema

Method isUniqueIndex

Prototype

Boolean isUniqueIndex()

Returns

True if the index is unique, false otherwise.

Remarks

Columns in a unique index may be null.


Method isUniqueKey

Prototype

Boolean isUniqueKey()

Returns

True if index is unique key, false if index is not unique key.

Remarks

Columns in a unique key may not be null.


Class PreparedStatement

Represents a pre-compiled SQL statement with or without IN parameters. Created at runtime using Connection.prepareStatement.

This object can then be used to efficiently execute this statements multiple times.

When a prepared statement is closed, all ResultSet and ResultSetSchema objects associated with it are also closed. For resource management reasons, it is preferred that you explicitly close prepared statements when you are done with them.

Method appendBytesParameter
Method appendStringChunkParameter
Method close
Method executeQuery
Method executeStatement
Method getPlan
Method getResultSetSchema
Method hasResultSet
Method isOpen
Method setBooleanParameter
Method setBytesParameter
Method setDateParameter
Method setDoubleParameter
Method setFloatParameter
Method setIntParameter
Method setLongParameter
Method setNullParameter
Method setShortParameter
Method setStringParameter
Method setTimeParameter
Method setTimestampParameter
Method setULongParameter
Method setUUIDParameter


Method appendBytesParameter

Prototype

appendBytesParameter(
UInt16 parameterID,
Array value,
UInt32 srcOffset,
UInt32 count
)

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the value to append to the current new value for the parameter.

  • srcOffset start position in the source array.

  • count the number of bytes to be copied.

Remarks

Appends the specified subset of the specified array of bytes to the new value for the specified SQLType.LONGBINARY column. The bytes at position srcOffset (starting from 0) through srcOffset+count-1 of the array value are appended to the value for the specified parameter. When inserting, insertBegin initializes the new value to the parameter.'s default value.

If any of the following is true, an Error with code SQLError.SQLE_INVALID_PARAMETER is thrown and the destination is not modified:

  • The value argument is null.

  • The srcOffset argument is negative.

  • The count argument is negative.

  • srcOffset+count is greater than value.length, the length of the source array.


Method appendStringChunkParameter

Prototype

appendStringChunkParameter(
UInt16 parameterID,
String value,
)

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the value to append to the current new value for the parameter.

Remarks

Appends the String to the new value for the specified SQLType.LONGVARCHAR.

Example

The following statement appends one hundred instances of the string XYZ to the first parameter:

for ( i = 0; i < 100; i++ ){
  stmt.appendStringChunkParameter( 1, "XYZ" );
}


Method close

Prototype

close( )

Remarks

Close the prepared statement.

When a prepared statement is closed, all ResultSet and ResultSetSchema objects associated with it are also closed.

It is recommended that you set the preparedStatement object to null immediately after you close it.


Method executeQuery

Prototype

ResultSet executeQuery( String persistName )

Parameter

  • persistName The name for cross-page JavaScript object persistence. Set to null if no persistence is required (for example, if the application has only a single HTML page).

Returns

The result set of the query, as a set of rows.

Remarks

Executes a SQL SELECT statement and returns the result set.


Method executeStatement

Prototype

Int32 executeStatement( )

Returns

The number of rows affected by the statement.

Remarks

Executes a statement that does not return a result set, such as a SQL INSERT, DELETE or UPDATE statement.

If Connection.autoCommit is true, the statement will be committed only if one or more rows is affected by the statement.


Method getPlan

Prototype

String getPlan( )

Returns

A string describing the access plan UltraLite will use to execute a query. This method is intended primarily for use during development.

See also
  • Query optimization.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class PreparedStatement

Method getResultSetSchema

Prototype

ResultSetSchema getResultSetSchema()

Returns

The schema describing the result set of this query statement.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class PreparedStatement

Method hasResultSet

Prototype

Boolean hasResultSet( )

Returns

true if a result set is generated when this statement is executed, false if no result set is generated.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class PreparedStatement

Method isOpen

Prototype

Boolean isOpen( )

Returns

true if the prepared statement is open, false otherwise.


Method setBooleanParameter

Prototype

setBooleanParameter( UInt16 parameterID, Boolean value )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter.

Remarks

Sets the value for the specified parameter using a Boolean.

Example

The following statement sets a value for the first parameter:

stmt.setBooleanParameter(1, false);


Method setBytesParameter

Prototype

setBytesParameter( UInt16 parameterID, Array value )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter.

Remarks

Sets the value for the specified parameter using an array of bytes. Suitable for columns of type SQLType.BINARY or SQLType.LONGBINARY only.

Example

The following statement sets a value for the first parameter:

var blob = new Array( 3 );
blob[ 0 ] = 78;
blob[ 1 ] = 0;
blob[ 2 ] = 68;
stmt.setBytesParameter( 1, blob );


Method setDateParameter

Prototype

setDateParameter( UInt16 parameterID, Date value )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter.

Remarks

Sets the value for the specified SQLType.DATE type parameter using a date. Only the year, month, and day fields of the Date object are relevant.

Example

The following statement sets a value for the first parameter to 2004/10/27:

stmt.setDateParameter(
    1, new Date( 2004,9,27,0,0,0,0 )
);


Method setDoubleParameter

Prototype

setDoubleParameter( UInt16 parameterID, Double value )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter.

Remarks

Sets the value for the specified parameter using a double.

Example

The following statement sets a value for the first parameter:

stmt.setDoubleParameter( 1, Number.MAX_VALUE );


Method setFloatParameter

Prototype

setFloatParameter( UInt16 parameterID, Float value )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter.

Remarks

Sets the value for the specified SQLType.REAL parameter.

Example

The following statement sets a floating point value for the first parameter:

stmt.setFloatParameter( 1,
    (2 - Math.pow(2,-23)) * Math.pow(2,127)
);


Method setIntParameter

Prototype

setUInt16Parameter( UInt16 parameterID, UInt16 value )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter.

Remarks

Sets the value for the specified parameter using a Uint16.

Example

The following statement sets the value for the first parameter to 2147483647:

stmt.setIntParameter( 1, 2147483647 );


Method setLongParameter

Prototype

setLongParameter( UInt16 parameterID, Int64 value )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter.

Remarks

Sets the value for the specified parameter.

Example

The following statement sets the value for the first parameter to 9223372036854770000:

stmt.setLongParameter( 1, 9223372036854770000 );


Method setNullParameter

Prototype

setNullParameter( UInt16 parameterID )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

Remarks

Sets the specified parameter to the SQL NULL value.


Method setShortParameter

Prototype

setUInt16Parameter( UInt16 parameterID, UInt16 value )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter.

Remarks

Sets the value for the specified parameter.

Example

The following statement sets the value for the first parameter to 32767:

stmt.setShortParameter( 1, 32767 );


Method setStringParameter

Prototype

setStringParameter( UInt16 parameterID, String value )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter.

Remarks

Sets the value for the specified parameter.

Example

The following statement sets the value for the first parameter to ABC:

stmt.setStringParameter( 1, "ABC" );


Method setTimeParameter

Prototype

setTimeParameter( UInt16 parameterID, Date value )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter.

Remarks

Sets the value for the specified SQLType.TIME type parameter using a date. Only the hour, minute, and second fields of the Date object are relevant.

Example

The following statement sets a value for the first parameter to 18:02:13:0000:

stmt.setTimeParameter(
    1, new Date( 1966,4,1,18,2,13,0 )
);


Method setTimestampParameter

Prototype

setTimestampParameter( UInt16 parameterID, Date value )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter.

Remarks

Sets the value for the specified parameter using a Timestamp.

Example

The following statement sets a value for the first parameter to 1966/05/01 18:02:13:0000:

stmt.setTimestampParameter(
    1, new Date( 1966,4,1,18,2,13,0 )
);


Method setULongParameter

Prototype

setULongParameter( UInt16 parameterID, UInt64 value )

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter. Uses a Double to represent the value of an unsigned 64-bit integer.

Remarks

Sets the value for the specified parameter using a Double treated as an unsigned value. See class Unsigned64 for more information.

Example

The following statement sets the value for the first parameter:

stmt.setLongParameter( 1, 9223372036854770000 * 4096 );


Method setUUIDParameter

Prototype

setUUIDParameter(UInt16 parameterID, UUID value)

Parameters

  • parameterID the ID number of the parameter. The first parameter in the result set has an ID value of one.

  • value the new value for the parameter.

Remarks

Sets the value for the specified parameter using a UUID.


Class PublicationSchema

Represents the schema of an UltraLite publication.

This class cannot be directly instantiated. Publication schemas are created using the DatabaseSchema.getPublicationSchema method.

UltraLite methods requiring a publication mask actually require a set of publications to check. A set is formed by or'ing the publication masks of individual publications. For example:

pub1.getMask() | pub2.getMask()

Two special mask values are provided by DatabaseSchema object. SYNC_ALL_DB corresponds to the entire database. SYNC_ALL_PUBS corresponds to all publications.

Publication masks may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached masks after a schema upgrade.


Method getMask

Prototype

UInt32 getMask()

Returns

The publication mask of this publication.

Note: Publication IDs, masks, and count may change during a schema upgrade. To correctly identify a publication, access it by name or refresh the cached masks, and counts after a schema upgrade.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class PublicationSchema

Method getName

Prototype

String getName()

Returns

The name of this publication.


Class ResultSet

Represents a result set in an UltraLite database. Created at runtime using PreparedStatement.executeQuery.

Properties
Method close
Method getBoolean
Method getBytes
Method getBytesSection
Method getDate
Method getDouble
Method getFloat
Method getInteger
Method getLong
Method getRowCount
Method getShort
Method getString
Method getStringChunk
Method getTime
Method getTimestamp
Method getULong
Method getUUID
Method isBOF
Method isEOF
Method isNull
Method isOpen
Method moveAfterLast
Method moveBeforeFirst
Method moveFirst
Method moveLast
Method moveNext
Method movePrevious
Method moveRelative


Properties

The properties of the class are listed here.

Property | Description
ResultSetSchema schema (read-only) | The schema of this result set. This property is only valid while its prepared statement is open.
NULL_TIMESTAMP_VAL | A constant indicating that a timestamp value is NULL.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method close

Prototype

close()

Remarks

Frees all resources associated with this object.


Method getBoolean

Prototype

Boolean getBoolean( UInt16 index )

Parameters

  • index The ID number of the column. The first column in the result set has an ID of one.

Returns

The value for the specified column as a Boolean.


Method getBytes

Prototype

Array getBytes( UInt16 index )

Parameters

  • index The ID number of the column. The first column in the result set has an ID of one.

Returns

The value for the specified column as an array of bytes.

Remarks

Only valid for columns of type SQLType.BINARY or SQLType.LONGBINARY.


Method getBytesSection

Prototype

UInt32 getBytesSection(
UInt16 index
UInt32 srcOffset,
Array dst,
UInt32 dstOffset,
UInt32 count
)

Parameters

index The 1-based ordinal of the column containing the binary data.

offset The offset into the underlying array of bytes. The source offset must be greater than or equal to 0, otherwise a SQLE_INVALID_PARAMETER error will be raised. A buffer bigger than 64K is also permissible.

data An array of bytes.

data_len The length of the buffer, or array. The data_len must be greater than or equal to 0.

Returns

The number of bytes read.

Remarks

Copies a subset of the value for the specified SQLType.LONGBINARY column, beginning at the specified offset, to the specified offset of the destination byte array.

The bytes at position srcOffset (starting from 0) through srcOffset+count-1 of the value are copied into positions dstOffset through dstOffset+count-1, respectively, of the destination array. If the end of the value is encountered before count bytes are copied, the remainder of the destination array is left unchanged.

If any of the following is true, an error is thrown, SQLError code SQLCode.SQLE_INVALID_PARAMETER is set, and the destination is not modified:

  • The dst argument is null
  • The srcOffset argument is negative
  • The dstOffset argument is negative
  • The count argument is negative
  • dstOffset + count is greater than the length of the destination array, dst.length.
Errors set

SQLE_CONVERSION_ERROR The error occurs if the column data type is not BINARY or LONG BINARY.

SQLE_INVALID_PARAMETER The error occurs if the column data type is BINARY and the offset is not 0 or 1, or, the data length is less than 0.

The error also occurs if the column data type is LONG BINARY and the offset is less than 1.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method getDate

Prototype

Date getDate( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a Date.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method getDouble

Prototype

Double getDouble( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a Double.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method getFloat

Prototype

Float getFloat( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value for the specified column.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method getInteger

Prototype

UInt32 getInt( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value for the specified column.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method getLong

Prototype

Int64 getLong( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value for the specified column.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method getRowCount

Prototype

UInt32 getRowCount( )

Returns

The number of rows in the result set.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method getShort

Prototype

Int16 getShort( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as an Int16.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method getString

Prototype

String getString( UInt32 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a String.


Method getStringChunk

Prototype

String getStringChunk(
UInt16 index,
UInt32 srcOffset,
UInt32 count
)

Parameters

  • index The 1-based ordinal in the result set to get

  • srcOffset The o-based start position in the string value.

  • count The number of characters to be copied.

Returns

The string, with specified characters copied.

Remarks

Copies a subset of the value for the specified SQLType.LONGVARCHAR column, starting at the specified offset, to the String object.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method getTime

Prototype

Date getTime( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a Date.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method getTimestamp

Prototype

Date getTimestamp( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a Date.


Method getULong

Prototype

UInt64 getULong( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as an unsigned 64-bit integer.


Method getUUID

Prototype

UUID getUUID( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value of the column as a UUID. The column must be of type SQLType.BINARY with length 16.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method isBOF

Prototype

Boolean isBOF( )

Returns

true if the current row position is before first row.

false otherwise


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method isEOF

Prototype

Boolean isEOF( )

Returns

true if the current row position if after the last row.

false otherwise.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method isNull

Prototype

Boolean isNull( Uint16 index )

Parameters

index The column index value.

Returns

true if the value is null.

false otherwise.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSet

Method isOpen

Prototype

Boolean isOpen( )

Returns

true if the ResultSet is open, false otherwise.


Method moveAfterLast

Prototype

Boolean moveAfterLast( )

Remarks

Moves to a position after the last row of the ULResultSet.

Returns

true if successful.

false if unsuccessful. The method fails, for example, if there are no rows.


Method moveBeforeFirst

Prototype

Boolean moveBeforeFirst( )

Remarks

Moves to a position before the first row.

Returns

true if successful.

false if unsuccessful. The method fails, for example, if there are no rows.


Method moveFirst

Prototype

Boolean moveFirst( )

Remarks

Moves to the first row.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


Method moveLast

Prototype

Boolean moveLast( )

Remarks

Moves to the last row.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


Method moveNext

Prototype

Boolean moveNext( )

Remarks

Moves to the next row.

Returns

True if successful.

False if unsuccessful. The method fails, for example, if there are no rows.


Method movePrevious

Prototype

Boolean movePrevious( )

Remarks

Moves to the previous row.

Returns

true if successful.

false if unsuccessful. The method fails, for example, if there are no rows.


Method moveRelative

Prototype

Boolean moveRelative( Int32 index )

Remarks

Moves a certain number of rows relative to the current row. Relative to the current position of the cursor in the resultset, positive index values move forward in the resultset, negative index values move backward in the resultset and zero does not move the cursor.

Parameters

index The number of rows to move. The value can be positive, negative, or zero.

Returns

true if successful.

false if unsuccessful. The method fails, for example, if there are no rows.


Class ResultSetSchema

Represents the schema of an UltraLite result set.

Method getColumnCount
Method getColumnID
Method getColumnName
Method getColumnPrecision
Method getColumnPrecisionByColID
Method getColumnScale
Method getColumnScaleByColID
Method getColumnSize
Method getColumnSizeByColID
Method getColumnSQLType
Method getColumnSQLTypeByColID
Method isOpen


Method getColumnCount

Prototype

UInt16 getColumnCount();

Returns

The number of columns in this cursor. Column IDs range from 1 to getColumnCount() inclusively.

Remarks

Column IDs and count may change during a schema upgrade. To correctly identify a column, access it by name or refresh the cached IDs and counts after a schema upgrade.


Method getColumnID

Prototype

UInt16 getColumnID(String name)

Parameters

  • name name of the column.

Returns

The column ID of the named column. Column IDs range from 1 to getColumnCount(), inclusively.

Remarks

Column IDs and count may change during a schema upgrade. To correctly identify a column, access it by name or refresh the cached IDs and counts after a schema upgrade.


Method getColumnName

Prototype

String getColumnName(UInt16 columnID)

Parameters

  • columnID ID of the column. columnID must be in the range [1,getColumnCount()].

Returns

The name of column identified by the specified column ID.

Remarks

Column IDs and count may change during a schema upgrade. To correctly identify a column, access it by name or refresh the cached IDs and counts after a schema upgrade.


Method getColumnPrecision

Prototype

Int32 getColumnPrecision(String name)

Parameters

  • name name of the column.

Returns

The precision of the named column. The column must be of type SQLType.NUMERIC.


Method getColumnPrecisionByColID

Prototype

Int32 getColumnPrecisionByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the result set has an ID value of one.

Returns

The precision of the column. The column must be of type SQLType.NUMERIC.


Method getColumnScale

Prototype

Int32 getColumnScale(String name)

Parameters

  • name name of the column.

Returns

The scale of the column. The column must be of type SQLType.NUMERIC.


Method getColumnScaleByColID

Prototype

Int32 getColumnScaleByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the result set has an ID value of one.

Returns

The scale of the column. The column must be of type SQLType.NUMERIC.


Method getColumnSize

Prototype

UInt32 getColumnSize(String name)

Parameters

  • name name of the column.

Returns

The size of the named column. The column must be of type SQLType.NUMERIC.


Method getColumnSizeByColID

Prototype

UInt32 getColumnSizeByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the result set has an ID value of one.

Returns

The size of the column. The column must be of type SQLType.NUMERIC.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSetSchema

Method getColumnSQLType

Prototype

UInt16 getColumnSQLType(String name)

Parameters

  • name name of the column.

Remarks

The code for the SQL data type of the named column.


Method getColumnSQLTypeByColID

Prototype

UInt16 getColumnSQLTypeByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the result set has an ID value of one.

Returns

The SQLType of the column, in a SQLType enumerated integer.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ResultSetSchema

Method isOpen

Prototype

Boolean isOpen();

Returns

true if the result set is open, false otherwise.


Class SQLError

Enumerates the SQL codes that may be reported by UltraLite for M-Business Anywhere. This class provides static constants and can not be directly instantiated.

For more information about the meaning of these constants, see MobiLink Communication Error Messages.

Constant | Value
SQLE_AGGREGATES_NOT_ALLOWED | -150
SQLE_ALIAS_NOT_UNIQUE | -830
SQLE_ALIAS_NOT_YET_DEFINED | -831
SQLE_BAD_ENCRYPTION_KEY | -840
SQLE_BAD_PARAM_INDEX | -689
SQLE_CANNOT_ACCESS_FILE | -602
SQLE_CANNOT_CHANGE_USER_NAME | -867
SQLE_CANNOT_MODIFY | -191
SQLE_CANNOT_EXECUTE_STMT | -111
SQLE_COLUMN_AMBIGUOUS | -144
SQLE_COLUMN_CANNOT_BE_NL | -195
SQLE_COLUMN_IN_INDEX | -127
SQLE_COLUMN_NOT_FOUND | -143
SQLE_COMMUNICATIONS_ERROR | -85
SQLE_CONNECTION_NOT_FOUND | -108
SQLE_CONVERSION_ERROR | -157
SQLE_CURSOROP_NOT_ALLOWED | -187
SQLE_CURSOR_ALREADY_OPEN | -172
SQLE_CURSOR_NOT_OPEN | -180
SQLE_DATABASE_ERROR | -301
SQLE_DATABASE_NEW | 123
SQLE_DATABASE_NOT_CREATED | -645
SQLE_DATABASE_NOT_FOUND | -83
SQLE_DATABASE_UPGRADE_FAILED | -672
SQLE_DATABASE_UPGRADE_NOT_POSSIBLE | -673
SQLE_DATATYPE_NOT_ALLOWED | -624
SQLE_DBSPACE_FL | -604
SQLE_DIV_ZERO_ERROR | -628
SQLE_DOWNLOAD_CONFLICT | -839
SQLE_DROP_DATABASE_FAILED | -651
SQLE_DYNAMIC_MEMORY_EXHAUSTED | -78
SQLE_ENGINE_ALREADY_RUNNING | -96
SQLE_ENGINE_NOT_MTIUSER | -89
SQLE_ERROR | -300
SQLE_ERROR_CALLING_FUNCTION | -622
SQLE_EXPRESSION_ERROR | -156
SQLE_IDENTIFIER_TOO_LONG | -250
SQLE_INDEX_NOT_FOUND | -183
SQLE_INDEX_NOT_UNIQUE | -196
SQLE_INTERRUPTED | -299
SQLE_INVALID_AGGREGATE_PLACEMENT | -862
SQLE_INVALID_FOREIGN_KEY | -194
SQLE_INVALID_FOREIGN_KEY_DEF | -113
SQLE_INVALID_GROUP_SELECT | -149
SQLE_INVALID_LOGON | -103
SQLE_INVALID_OPTION_SETTING | -201
SQLE_INVALID_ORDER | -152
SQLE_INVALID_ORDERBY_COLUMN | -854
SQLE_INVALID_paraMETER | -735
SQLE_INVALID_SQL_IDENTIFIER | -760
SQLE_INVALID_STATEMENT | -130
SQLE_LOCKED | -210,
SQLE_MEMORY_ERROR | -309
SQLE_METHOD_CANNOT_BE_CALLED | -669
SQLE_NAME_NOT_UNIQUE | -110
SQLE_NOERR | 0
SQLE_NOTFOUND | 100
SQLE_NOT_IMPLEMENTED | -134
SQLE_NO_CURRENT_ROW | -197
SQLE_NO_INDICATOR | -181
SQLE_OVERFLOW_ERROR | -158
SQLE_PERMISSION_DENIED | -121
SQLE_PRIMARY_KEY_NOT_UNIQUE | -193
SQLE_PRIMARY_KEY_VALUE_REF | -198
SQLE_PUBLICATION_NOT_FOUND | -280
SQLE_RESOURCE_GOVERNOR_EXCEEDED | -685
SQLE_ROW_DROPPED_DURING_SCHEMA_UPGRADE | 130
SQLE_SERVER_SYNCHRONIZATION_ERROR | -857
SQLE_START_STOP_DATABASE_DENIED | -75
SQLE_STATEMENT_ERROR | -132
SQLE_SYNTAX_ERROR | -131
SQLE_STRING_RIGHT_TRUNCATION | -638
SQLE_TABLE_HAS_PUBLICATIONS | -281
SQLE_TABLE_IN_USE | -214
SQLE_TABLE_NOT_FOUND | -141
SQLE_TOO_MANY_CONNECTIONS | -102
SQLE_UTRALITE_OBJ_CLOSED | -908
SQLE_UNABLE_TO_CONNECT_OR_START | -764
SQLE_UNABLE_TO_START_DATABASE | -82
SQLE_UNCOMMITTED_TRANSACTIONS | -755
SQLE_UNKNOWN_FUNC | -148
SQLE_UNKNOWN_USERID | -140
SQLE_UNSUPPORTED_CHARACTER_SET_ERROR | -869
SQLE_UPLOAD_FAILED_AT_SERVER | -794
SQLE_WRONG_PARAMETER_COUNT | -154


Class SQLType

This enumeration lists as constants the available UltraLite SQL database types used as table column types.

Constant | UltraLite Database Type
BAD_INDEX |
S_LONG | INT
U_LONG | UNSIGNED INT
S_SHORT | SMALLINT
U_SHORT | UNSIGNED SMALLINT
S_BIG | BIGINT
U_BIG | UNSIGNED BIGINT
TINY | TYNY INT
BIT | BIT
TIMESTAMP | TIMESTAMP
DATE | DATE
TIME | TIMESTAMP
DOUBLE | DOUBLE
REAL | REAL
NUMERIC | NUMERIC
BINARY | BINARY
CHAR | CHAR or VARCHAR
LONGVARCHAR | LONG VARCHAR
LONGBINARY | LONG BINARY
MAX_INDEX |

Method toString


Method toString

Prototype

String toString(UInt16 code)

Parameters

  • code The SQL column type constant.

Returns

The string name of the specified SQL column type constant or BAD_SQL_TYPE if not a a recognized type.


Class SyncParms

Represents synchronization parameters that define how to synchronize an UltraLite database. Each connection has its own SyncParms instance.

Constants
Method getAuthenticationParms
Method getCheckpointStore
Method getDisableConcurrency
Method getDownloadOnly
Method getKeepPartialDownload
Method getNewPassword
Method getPartialDownloadRetained
Method getPassword
Method getPingOnly
Method getPublicationMask
Method getResumePartialDownload
Method getSendColumnNames
Method getSendDownloadAck
Method getStream
Method getStreamParms
Method getUploadOnly
Method getUserName
Method getVersion
Method setAuthenticationParms
Method setCheckpointStore
Method setDisableConcurrency
Method setDownloadOnly
Method setMBAServer
Method setNewPassword
Method setPassword
Method setPingOnly
Method setPublicationMask
Method setSendColumnNames
Method setSendDownloadAck
Method setStream
Method setStreamParms
Method setUploadOnly
Method setUserName
Method setVersion


Constants

Constant | Value | Description
STREAM_TYPE_UNKNOWN | 0 | No stream type has been set. You must set a stream type before synchronization.
STREAM_TYPE_TCPIP | 1 | TCP/IP stream
STREAM_TYPE_HTTP | 2 | HTTP stream
STREAM_TYPE_HTTPS | 3 | HTTPS synchronization
STREAM_TYPE_HOTSYNC | 4 | For HotSync synchronization


Method getAuthenticationParms

Prototype

Array getAuthenticationParms()

Returns

Parameters provided to a custom user authentication script or null if no parameters are specified.


Method getCheckpointStore

Prototype

Boolean getCheckpointStore()

Returns

true if the client will perform extra checkpoints, false if the client will only perform required checkpoints.


Method getDisableConcurrency

Prototype

Boolean getDisableConcurrency()

Returns

true if concurrent synchronization is disabled, false if concurrent synchronization is enabled.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class SyncParms

Method getDownloadOnly

Prototype

Boolean getDownloadOnly()

Returns

true if uploads are disabled, false if uploads are enabled.


Method getKeepPartialDownload

Prototype

Boolean getKeepPartialDownload()

Returns

true if partial downloads are to be kept, false if partial downloads should be rolled back.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class SyncParms

Method getNewPassword

Prototype

String getNewPassword()

Returns

The new password that will be associated with the MobiLink user after the next synchronization.


Method getPartialDownloadRetained

Prototype

Boolean getPartialDownloadRetained( )

Returns

true if a download failed because of a communications error and the partial download was retained, false if the download was not interrupted, or if the partial download was rolled back.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class SyncParms

Method getPassword

Prototype

String getPassword();

Returns

The MobiLink password for the user specified with setUserName.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class SyncParms

Method getPingOnly

Prototype

Boolean getPingOnly()

Returns

true if client will only ping the server, false if client will perform a synchronization.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class SyncParms

Method getPublicationMask

Prototype

UInt32 getPublicationMask();

Returns

The publications to be synchronized. See PublicationSchema class for more information.


Method getResumePartialDownload

Prototype

Boolean getResumePartialDownload( )

Returns

true if the previous partial download is to be resumed, false if the previous partial download is to be rolled back.


Method getSendColumnNames

Prototype

Boolean getSendColumnNames()

Returns

true if client will send column names to the MobiLink synchronization server during synchronization, false if client will not send column names.


Method getSendDownloadAck

Prototype

Boolean getSendDownloadAck()

Returns

true if client will provide a download acknowledgement to the MobiLink server, false if the client will not provide a download acknowledgement.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class SyncParms

Method getStream

Prototype

UInt16 getStream();

Returns

The type of MobiLink synchronization stream to use for synchronization.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class SyncParms

Method getStreamParms

Prototype

String getStreamParms();

Remarks

A string containing all the network protocol options used for synchronization streams.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class SyncParms

Method getUploadOnly

Prototype

Boolean getUploadOnly()

Remarks

true if downloads are disabled, false if downloads are enabled.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class SyncParms

Method getUserName

Prototype

String getUserName()

Returns

The MobiLink user name.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class SyncParms

Method getVersion

Prototype

String getVersion()

Remarks

The version string that indicates which synchronization scripts are to be used.


Method setAuthenticationParms

Prototype

setAuthenticationParms( Array value )

Parameters

  • value an array of strings, each containing an authentication parameter (null array entries will result in a synchronization error).

Remarks

Specifies parameters for a custom user authentication script (MobiLink authenticate_parameters connection event).

Only the first 255 strings are used and each string should be no longer than 128 characters (longer strings will be truncated when sent to MobiLink).


Method setCheckpointStore

Prototype

setCheckpoint16Store( Boolean value )

Parameters

  • value set to true to perform extra checkpoints, or set to false to only perform the required checkpoints.

Remarks

Specifies whether the client should perform extra store checkpoints to control the growth of the database store during synchronization.

The checkpoint operation adds I/O operations for the application, and so slows synchronization. This option is most useful for large downloads with many updates. Devices with slow flash memory may not want to pay the performance penalty.


Method setDisableConcurrency

Prototype

setDisableConcurrency( Boolean value );

Parameters

  • value set to true to disable concurrent synchronization, or set to false to enable concurrent synchronization.

Remarks

Specifies whether to disable or enable concurrent access to UltraLite while performing a synchronization.

By default, other threads may perform UltraLite operations while a thread is synchronizing. When concurrent synchronization is disabled, other threads will block on UltraLite calls until the synchronization has completed.


Method setDownloadOnly

Prototype

setDownloadOnly( Boolean value )

Parameters

  • value set to true to disable uploads, or set to false to enable uploads.

Remarks

Specifies whether to disable or enable uploads when synchronizing.


Method setMBAServer

Prototype

setMBAServer( String host, String port, String url_suffix )

Parameters

  • host The host or IP value of the M-Business Anywhere server. If host is null, UltraLite sets it to the current M-Business Anywhere host.

  • port The port on which the M-Business Anywhere server is listening. If port is null, UltraLite sets it to the current M-Business Anywhere port value.

  • url_suffix This corresponds to the url_suffix parameter set in the sync.conf file of M-Business Anywhere.

Remarks

Provides a quick way to set the synchronization parameters for the MobiLink host and port to those of the M-Business Anywhere server used by the M-Business client. You should use the MobiLink redirector for M-Business Anywhere to route data to and from the MobiLink synchronization server.

If you are using one-button synchronization, you must save the synchronization parameters using Connection.saveSyncParms.

For information about configuring M-Business Server to route HTTP database traffic through the M-Business Anywhere Redirector, see M-Business Anywhere Redirector.


Method setNewPassword

Prototype

setNewPassword( String value )

Parameters

  • value new password for MobiLink user.

Remarks

Sets a new MobiLink password for the user specified with setUserName. The new password will take effect after the next synchronization.


Method setPassword

Prototype

setPassword( String value )

Parameters

  • value password for MobiLink user.

Remarks

Sets the MobiLink password for the user specified with setUserName. This user name and password are separate from any database user ID and password, and serves to identify and authenticate the application to the MobiLink synchronization server.


Method setPingOnly

Prototype

setPingOnly( Boolean value );

Parameters

  • value set to true to only ping the MobiLink synchronization server, or to false to perform a synchronization.

Remarks

Specifies whether the client should only ping the MobiLink synchronization server instead of performing a real synchronization.


Method setPublicationMask

Prototype

setPublicationMask( UInt16 mask )

Parameters

  • mask set of publications to synchronize.

Remarks

Specifies the publications to be synchronized. See PublicationSchema class for more information.


Method setSendColumnNames

Prototype

setSendColumnNames( Boolean value )

Parameters

  • value set to true to send column names, or set to false to not send column names.

Remarks

Specifies whether the client should send column names to the MobiLink synchronization server during synchronization.

This parameter is typically used together with the -za or -ze switch on the MobiLink synchronization server for automatically generating synchronization scripts.


Method setSendDownloadAck

Prototype

setSendDownloadAck( Boolean value )

Parameters

  • value set to true to send a download acknowledgement, to false to tell the server that no download acknowledgement will be sent.

Remarks

Specifies whether the client should send a download acknowledgement to the MobiLink synchronization server during synchronization.

If the client does send a download acknowledgement, the MobiLink synchronization server worker thread must wait for the client to apply the download. If the client does not sent a download acknowledgement, the MobiLink synchronization server is freed up sooner for its next synchronization.


Method setStream

Prototype

setStream( UInt16 value )

Parameters

  • value type of MobiLink synchronization stream to use for synchronization. Valid choices are listed in

    For a list of valid choices, see Constants.

Remarks

Sets the MobiLink synchronization stream to use for synchronization. Most synchronization streams require parameters to identify the MobiLink synchronization server address and control other behavior. These parameters are supplied with the setStreamParms() method.

If the specified stream type is invalid for the platform, the stream type will be set to UNKNOWN.


Method setStreamParms

Prototype

setStreamParms( String value )

Parameters

  • value string containing all the network protocol oiptions used for synchronization streams. Options are specified as a semicolon-separated list of name=value pairs ("param1=value1;param2=value2").

Remarks

Sets the parameters to configure the synchronization stream. For information on configuring specific stream types, refer to the Synchronization Stream Parameters Reference section of the UltraLite Database User's Guide online book.


Method setUploadOnly

Prototype

setUploadOnly( Boolean value )

Parameters

  • value set to true to disable downloads, or set to false to enable downloads.

Remarks

Specifies whether to disable or enable downloads when synchronizing.


Method setUserName

Prototype

setUserName( String value )

Parameters

  • value MobiLink user name.

Remarks

Sets the user name that uniquely identifies the MobiLink client to the MobiLink synchronization server. MobiLink uses this value to determine the download content, to record the synchronization state, and to recover from interruptions during synchronization. This user name and password are separate from any database user ID and password, and serve to identify and authenticate the application to the MobiLink synchronization server.


Method setVersion

Prototype

setVersion( String value )

Parameters

  • value script version string.

Remarks

Specifies which synchronization script version to use. Each synchronization script in the consolidated database is marked with a version string. For example, there may be two different download_cursor scripts, and each one is identified by different version strings. The version string allows an UltraLite application to choose from a set of synchronization scripts.


Class SyncResult

Represents the status of the last synchronization. Each connection has its own SyncResult instance.

This class can not be directly instantiated.

Method getAuthStatus
Method getIgnoredRows
Method getPartialDownloadRetained
Method getStreamErrorCode
Method getStreamErrorContext
Method getStreamErrorID
Method getStreamErrorSystem
Method getTimestamp
Method getUploadOK


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class SyncResult

Method getAuthStatus

Prototype

UInt16 getAuthStatus()

Remarks

Returns the authorization status code for the last synchronization attempt.


Method getIgnoredRows

Prototype

Boolean getIgnoredRows()

Parameters

  • return true if any uploaded rows were ignored, false if no uploaded rows were not ignored.

Returns

true if any uploaded rows were ignored during the most recent synchronization, false if no uploaded rows were ignored.


Method getPartialDownloadRetained

Prototype

Boolean getPartialDownloadRetained()

Returns

true if a download was interrupted and the partial download was retained, false if the download was not interrupted or the partial download was rolled back.


Method getStreamErrorCode

Prototype

UInt16 getStreamErrorCode( )

Parameters

  • return error code reported by the synchronization stream.

Returns

An integer representing the error reported by the stream itself. The following table gives a brief description of the error codes. For more complete descriptions, see MobiLink Communication Error Messages

Value | Description
0 | None
1 | Parameter
2 | Parameter not uint32
3 | Parameter not uint32 range
4 | Parameter not boolean
5 | Parameter not hex
6 | Memory allocation
7 | Parse
8 | Read
9 | Write
10 | End write
11 | End read
12 | Not implemented
13 | Would block
14 | Generate random
15 | Init random
16 | Seed random
17 | Create random object
18 | Shutting down
19 | Dequeuing connection
20 | Secure certificate root
21 | Secure certificate company name
22 | Secure certificate chain length
23 | Secure certificate ref
24 | Secure certificate not trusted
25 | Secure duplicate context
26 | Secure set io
27 | Secure set io semantics
28 | Secure certificate chain func
29 | Secure certificate chain ref
30 | Secure enable non blocking
31 | Secure set cipher suites
32 | Secure set chain number
33 | Secure certificate file not found
34 | Secure read certificate
35 | Secure read private key
36 | Secure set private key
37 | Secure certificate expiry date
38 | Secure export certificate
39 | Secure add certificate
40 | Secure trusted certificate file not found
41 | Secure trusted certificate read
42 | Secure certificate count
43 | Secure create certificate
44 | Secure import certificate
45 | Secure set random ref
46 | Secure set random func
47 | Secure set protocol side
48 | Secure add trusted certificate
49 | Secure create private key object
50 | Secure certificate expired
51 | Secure certificate company unit
52 | Secure certificate common name
53 | Secure handshake
54 | HTTP version
55 | Secure set read func
56 | Secure set write func
57 | Socket host name not found
58 | Socket get host by addr
59 | Socket localhost name not found
60 | Socket create TCP/IP
61 | Socket create UDP
62 | Socket bind
63 | Socket cleanup
64 | Socket close
65 | Socket connect
66 | Socket get name
67 | Socket get option
68 | Socket set option
69 | Socket listen
70 | Socket shutdown
71 | Socket select
72 | Socket startup
73 | Socket port out of range
74 | Load network library
75 | ActiveSync no port
89 | HTTP expected post


Method getStreamErrorContext

Prototype

UInt16 getStreamErrorContext( )

Remarks

The basic network operation being performed when the stream error occurred. The known contexts are as follows:

Value | Context
0 | Unknown
1 | Register
2 | Unregister
3 | Create
4 | Destroy
5 | Open
6 | Close
7 | Read
8 | Write
9 | WriteFlush
10 | EndWrite
11 | EndRead
12 | Yield
13 | Softshutdown


Method getStreamErrorID

Prototype

UInt32 getStreamErrorID( )

Returns

The network layer reporting the error. The value is the ID of network layer.

The known IDs are as follows:

Value | Description
0 | TCP/IP stream
7 | HTTP stream
8 | HTTPS synchronization
3 | For HotSync synchronization


Method getStreamErrorSystem

Prototype

UInt16 getStreamErrorSystem( )

Parameters

  • return a system-specific error code.

Remarks

Returns the stream error system-specific code.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class SyncResult

Method getTimestamp

Prototype

Date getTimestamp( )

Returns

The timestamp of the most recent synchronization.


Method getUploadOK

Prototype

Boolean getUploadOK()

Remarks

true if last upload synchronization was successful, false if last upload synchronization was unsuccessful.


Class TableSchema

Represents the schema of an UltraLite table.

Method getColumnCount
Method getColumnDefaultValue
Method getColumnDefaultValueByColID
Method getColumnID
Method getColumName
Method getColumnPartitionSize
Method getColumnPartitionSizeByColID
Method getColumnPrecision
Method getColumnPrecisionByColID
Method getColumnScale
Method getColumnScaleByColID
Method getColumnSize
Method getColumnSizeByColID
Method getColumnSQLType
Method getColumnSQLTypeByColID
Method getIndex
Method getIndexCount
Method getIndexName
Method getName
Method getOptimalIndex
Method getPrimaryKey
Method getUploadUnchangedRows
Method isColumnAutoIncrement
Method isColumnAutoIncrementByColID
Method isColumnCurrentDate
Method isColumnCurrentDateByColID
Method isColumnCurrentTime
Method isColumnCurrentTimeByColID
Method isColumnCurrentTimestamp
Method isColumnCurrentTimestampByColID
Method isColumnGlobalAutoIncrement
Method isColumnGlobalAutoincrementByColID
Method isColumnNewUUID
Method isColumnNewUUIDByColID
Method isColumnNullable
Method isColumnNullableByColID
Method isInPublication
Method isNeverSynchronized


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class TableSchema

Method getColumnCount

Prototype

UInt16 getColumnCount( )

Returns

The 1-based number of columns in this table. Column IDs range from 1 to getColumnCount().


Method getColumnDefaultValue

Prototype

String getColumnDefaultValue( String name )

Parameters

  • name name of the column.

Remarks

The default value of the named column or null if the default value is null.


Method getColumnDefaultValueByColID

Prototype

String getColumnDefaultValueByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

The default value of the column or null if the default value is null.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class TableSchema

Method getColumnID

Prototype

UInt16 getColumnID( String name )

Parameters

  • name name of the column.

Returns

The 1-based ID of the specified column.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class TableSchema

Method getColumName

Prototype

String getColumnName( UInt16 colID )

Parameters

  • colID The 1-based column ID of the column.

Returns

The name of the specified column.


Method getColumnPartitionSize

Prototype

UInt64 getColumnPartitionSize( String name )

Parameters

  • name name of the column.

Returns

The column's global autoincrement partition size as an unsigned 64-bit number represented by a Double. All global autoincrement columns in a given table share the same global autoincrement partition.


Method getColumnPartitionSizeByColID

Prototype

UInt64 getColumnPartitionSizeByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

The column's global autoincrement partition size as an unsigned 64-bit number represented by a Double. All global autoincrement columns in a given table share the same global autoincrement partition.


Method getColumnPrecision

Prototype

Int32 getColumnPrecision( String name )

Parameters

  • name name of the column.

Returns

The precision of the column. The column must be of type SQLType.NUMERIC.


Method getColumnPrecisionByColID

Prototype

Int32 getColumnPrecisionByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

The precision of the column. The column must be of type SQLType.NUMERIC


Method getColumnScale

Prototype

Int32 getColumnScale( String name )

Parameters

  • name name of the column.

Returns

The scale of the column. The column must be of type SQLType.NUMERIC.


Method getColumnScaleByColID

Prototype

Int32 getColumnScaleByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

The scale of the column. The column must be of type SQLType.NUMERIC.


Method getColumnSize

Prototype

UInt32 getColumnSize( String name )

Parameters

  • name name of the column.

Returns

The size of the column. The column must be of type SQLType.BINARY or SQLType.CHAR.


Method getColumnSizeByColID

Prototype

UInt32 getColumnSizeByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

The size of the column. The column must be of type SQLType.BINARY or SQLType.CHAR.


Method getColumnSQLType

Prototype

Int16 getColumnSQLType( String name )

Parameters

  • name name of the column.

Returns

The SQLType of the column, in a SQLType enumerated integer.


Method getColumnSQLTypeByColID

Prototype

Int16 getColumnSQLTypeByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

The SQLType of the column, in a SQLType enumerated integer.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class TableSchema

Method getIndex

Prototype

IndexSchema getIndex( String name )

Parameters

  • name name of the index.

Returns

The index schema of the named index.


Method getIndexCount

Prototype

UInt16 getIndexCount( )

Returns

The number of indexes on this table. Index IDs range from 1 to getIndexCount(), inclusively.

Remarks

Note: Index IDs and count may change during a schema upgrade. To correctly identify an index, access it by name or refresh the cached IDs and counts after a schema upgrade.


Method getIndexName

Prototype

String getIndexName( UInt16 indexID )

Parameters

  • indexID ID of the index. indexID must be in the range [1,getIndexCount()].

Returns

The name of the index identified by the specified index ID.

Remarks

Note: Index IDs and count may change during a schema upgrade. To correctly identify an index, access it by name or refresh the cached IDs and counts after a schema upgrade.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class TableSchema

Method getName

Prototype

String getName( )

Returns

The name of this table.


Method getOptimalIndex

Prototype

IndexSchema getOptimalIndex( String name )

Parameters

  • name name of the column.

Returns

The optimal index for searching a table using the named column. The named column will be the first column in the index but the index may have more than one column.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class TableSchema

Method getPrimaryKey

Prototype

IndexSchema getPrimaryKey( )

Returns

The index schema of the primary key for this table.


Method getUploadUnchangedRows

Prototype

Boolean getUploadUnchangedRows( )

Returns

true if the table is marked to upload all rows, false if the table is not marked to upload all rows.

Remarks

Tables for which this method returns true always upload unchanged rows, as well as changed rows, when the table is synchronized. These tables are sometimes referred to as "all sync" tables.


Method isColumnAutoIncrement

Prototype

Boolean isColumnAutoIncrement( String name )

Parameters

  • name name of the column.

Returns

true if the column is autoincrementing, false otherwise.


Method isColumnAutoIncrementByColID

Prototype

Boolean isColumnAutoIncrementByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

true if the column is autoincrementing, false otherwise.


Method isColumnCurrentDate

Prototype

Boolean isColumnCurrentDate( String name )

Parameters

  • name name of the column.

Returns

true if the column defaults to the current date, false otherwise.

Remarks

The column must be of type SQLType.DATE.


Method isColumnCurrentDateByColID

Prototype

Boolean isColumnCurrentDateByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

true if the column defaults to the current date, false otherwise.

Remarks

The column must be of type SQLType.DATE.


Method isColumnCurrentTime

Prototype

Boolean isColumnCurrentTime( String name )

Parameters

  • name name of the column.

Returns

true if the column defaults to the current time, false otherwise.

Remarks

The column must be of type SQLType.TIME.


Method isColumnCurrentTimeByColID

Prototype

Boolean isColumnCurrentTimeByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

true if the column defaults to the current time, false otherwise.

Remarks

The column must be of type SQLType.TIME.


Method isColumnCurrentTimestamp

Prototype

Boolean isColumnCurrentTimestamp( String name )

Parameters

  • name name of the column.

Returns

true if the column defaults to the current timestamp, false otherwise.

Remarks

The column must be of type SQLType.TIMESTAMP.


Method isColumnCurrentTimestampByColID

Prototype

Boolean isColumnCurrentTimestampByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

true if the column defaults to the current timestamp, false otherwise.

Remarks

The column must be of type SQLType.TIME.


Method isColumnGlobalAutoIncrement

Prototype

Boolean isColumnGlobalAutoIncrement( String name )

Parameters

  • name name of the column.

  • return true if the column is global autoincrementing, false if not global autoincrementing.

Returns

true if the column defaults to global autoincrement, false otherwise.


Method isColumnGlobalAutoincrementByColID

Prototype

Boolean isColumnGlobalAutoincrementByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

true if the column defaults to global autoincrement, false otherwise.


Method isColumnNewUUID

Prototype

Boolean isColumnNewUUID( String name )

Parameters

  • name name of the column.

Returns

true if the column defaults to a new UUID, false otherwise.


Method isColumnNewUUIDByColID

Prototype

Boolean isColumnNewUUIDByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

true if the column defaults to a new UUID, false otherwise.


Method isColumnNullable

Prototype

Boolean isColumnNullable( String name )

Parameters

  • name name of the column.

Returns

true if the column is nullable, false otherwise.


Method isColumnNullableByColID

Prototype

Boolean isColumnNullableByColID( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Returns

true if the column defaults to a new UUID, false otherwise.


Method isInPublication

Prototype

Boolean isInPublication( String pubName )

Parameters

  • pubName name of the publication.

Returns

true if table in publication, false if table not in publication.


Method isNeverSynchronized

Prototype

Boolean isNeverSynchronized( )

Returns

true if the table is marked as never synchronized, false if the table is not marked as never synchronized.

Remarks

Tables for which this method returns true are never synchronized, even if they are included in a publication. These tables are sometimes referred to as "no sync" tables.


Class ULTable

Represents an UltraLite table.

Properties
Method appendBytes
Method appendStringChunk
Method deleteRow
Method deleteAllRows
Method findBegin
Method findFirst
Method findFirstForColumns
Method findLast
Method findLastForColumns
Method findNext
Method findNextForColumns
Method findPrevious
Method findPreviousForColumns
Method getBoolean
Method getBytes
Method getBytesSection
Method getDate
Method getDouble
Method getFloat
Method getInt
Method getLong
Method getRowCount
Method getShort
Method getString
Method getStringChunk
Method getTime
Method getTimestamp
Method getULong
Method getUUID
Method insert
Method insertBegin
Method lookupBackward
Method lookupBackwardForColumns
Method lookupBegin
Method lookupForward
Method lookupForwardForColumns
Method isBOF
Method isEOF
Method isNull
Method isOpen
Method moveAfterLast
Method moveBeforeFirst
Method moveFirst
Method moveLast
Method moveNext
Method movePrevious
Method moveRelative
Method open
Method openWithIndex
Method setBoolean
Method setBytes
Method setDate
Method setDouble
Method setFloat
Method setInt
Method setLong
Method setNull
Method setShort
Method setString
Method setTime
Method setTimestamp
Method setToDefault
Method setULong
Method setUUID
Method truncate
Method update
Method updateBegin


Properties

The properties of the class are listed here.

Property | Description
TableSchema schema (read-only) | The schema of this result set. This property is only valid while its prepared statement is open.
NULL_TIMESTAMP_VAL | A constant indicating that a timestamp value is NULL.


Method appendBytes

Prototype

appendBytes(
UInt16 columnID,
Array value,
UInt32 srcOffset,
UInt32 count
)

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

  • srcOffset The value to append to the current new value for the column.

  • count The number of bytes to be copied.

Remarks

Appends the specified subset of the specified array of bytes to the new value for the specified SQLType.LONGBINARY column. The bytes at position srcOffset (starting from 0) through srcOffset+count-1 of the array value are appended to the value for the specified column. When inserting, insertBegin initializes the new value to the column's default value. The data in the row is not actually changed until you execute an insert, and that change is not permanent until it is committed.

If any of the following is true, an Error with code SQLCode.SQLE_INVALID_PARAMETER is thrown and the destination is not modified:

  • The value argument is null.

  • The srcOffset argument is negative.

  • The count argument is negative.

  • srcOffset+count is greater than value.length, the length of the source array.

For other errors, a SQLException with the appropriate error code is thrown.


Method appendStringChunk

Prototype

appendChars(
UInt16 columnID,
String value
)

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Appends the specified string to the new value for the specified SQLType.LONGVARCHAR column.

Example

The following statements append one hundred instances of the string XYZ to the value in the first column:

for ( i = 0; i < 100; i++ ){
  t.appendStringChunk( 1, "XYZ" );
}


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method deleteRow

Prototype

deleteRow( )

Remarks

Deletes the current row.


Method deleteAllRows

Prototype

deleteAllRows( )

Remarks

Deletes all rows in the table.

In some applications, it can be useful to delete all rows from a table before downloading a new set of data into the table. Rows can be deleted from the UltraLite database without being deleted from the consolidated database using the Connection.startSynchronizationDelete method.


Method findBegin

Prototype

findBegin( )

Remarks

Prepares to perform a new find on this table. The value(s) to search for are specified by calling the appropriate setType method(s) on the columns in the index this table was opened with.


Method findFirst

Prototype

Boolean findFirst( )

Returns

true if successful, false otherwise

Remarks

Move forwards through the table from the beginning, looking for a row that exactly matches a value or full set of values in the current index.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that exactly matches the index value. On failure the cursor position is after the last row (isEOF()).

Each search must be preceded by a call to findBegin().


Method findFirstForColumns

Prototype

Boolean findFirstForColumns(
UInt16 numColumns
)

Parameters

  • numColumns For composite indexes, the number of columns to use in the lookup. For example, if you have a three column index, and you want to look up a value that matches based on the first column only, you should set the value for the first column, and then supply a numColumns value of 1.

Returns

true if successful, false otherwise

Remarks

Move forwards through the table from the beginning, looking for a row that exactly matches a value or partial set of values in the current index.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that exactly matches the index value. On failure the cursor position is after the last row (isEOF()).

Each search must be preceded by a call to findBegin().


Method findLast

Prototype

Boolean findLast( )

Returns

true if successful, false otherwise.

Remarks

Move backwards through the table from the end, looking for a row that exactly matches a value or full set of values in the current index.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row found that exactly matches the index value. On failure the cursor position is before the first row (isBOF()).

Each search must be preceded by a call to findBegin().


Method findLastForColumns

Prototype

Boolean findLastForColumns( UInt16 numColumns )

Parameters

  • numColumns For composite indexes, the number of columns to use in the lookup. For example, if you have a three column index, and you want to look up a value that matches based on the first column only, you should set the value for the first column, and then supply a numColumns value of 1.

Returns

true if successful, false otherwise.

Remarks

Move backwards through the table from the end, looking for a row that exactly matches a value or partial set of values in the current index.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row found that exactly matches the index value. On failure the cursor position is before the first row (isBOF()).

Each search must be preceded by a call to findBegin().


Method findNext

Prototype

Boolean findNext( )

Returns

true if successful, false otherwise.

Remarks

Continues a findFirst() search by moving forward through the table from the current position, looking to see if the next row exactly matches a value or full set of values in the current index.

The cursor is left on the next row if it exactly matches the index value. On failure the cursor position is after the last row (isEOF()).

findNext behavior is undefined if the column values being searched for are modified during a row update.


Method findNextForColumns

Prototype

Boolean findNextForColumns( UInt16 numColumns)

Parameters

  • numColumns For composite indexes, the number of columns to use in the lookup. For example, if you have a three column index, and you want to look up a value that matches based on the first column only, you should set the value for the first column, and then supply a numColumns value of 1.

Returns

true if successful, false otherwise.

Remarks

Continues a findFirst search by moving forward through the table from the current position, looking to see if the next row exactly matches a value or partial set of values in the current index.

The cursor is left on the next row if it exactly matches the index value. On failure the cursor position is after the last row (isEOF()).

findNext behavior is undefined if the column values being searched for are modified during a row update.


Method findPrevious

Prototype

Boolean findPrevious( )

Returns

true if successful, false otherwise.

Remarks

Continues a findLast() search by moving backward through the table from the current position, looking to see if the previous row exactly matches a value or full set of values in the current index.

The cursor is left on the previous row if it exactly matches the index value. On failure the cursor position is before the first row (isBOF()).

findPrevious behavior is undefined if the column values being searched for are modified during a row update.


Method findPreviousForColumns

Prototype

Boolean findPreviousForColumns(
UInt16 numColumns
)

Parameters

  • numColumns For composite indexes, the number of columns to use in the lookup. For example, if you have a three column index, and you want to look up a value that matches based on the first column only, you should set the value for the first column, and then supply a numColumns value of 1.

Returns

true if successful, false otherwise.

Remarks

Continues a findLast search by moving backward through the table from the current position, looking to see if the previous row exactly matches a value or partial set of values in the current index.

The cursor is left on the previous row if it exactly matches the index value. On failure the cursor position is before the first row (isBOF()).

findPrevious behavior is undefined if the column values being searched for are modified during a row update.


Method getBytesSection

Prototype

UInt32 getBytesSection(
UInt16 index
UInt32 srcOffset,
Array dst,
UInt32 dstOffset,
UInt32 count
)

Parameters

index The 1-based ordinal of the column containing the binary data.

srcOffset The start position in the column value. Zero is the beginning of the value.

dst The destination array.

dstOffset The start position in the destination array.

count The number of bytes to be copied

Returns

The number of bytes read.

Remarks

Copies a subset of the value for the specified SQLType.LONGBINARY column, beginning at the specified offset, to the specified offset of the destination byte array.

The bytes at position srcOffset (starting from 0) through srcOffset+count-1 of the value are copied into positions dstOffset through dstOffset+count-1, respectively, of the destination array. If the end of the value is encountered before count bytes are copied, the remainder of the destination array is left unchanged.

If any of the following is true, an Error is thrown, Connection.sqlCode set to SQLError.SQLE_INVALID_PARAMETER and the destination is not modified:

  • The dst argument is null
  • The srcOffset argument is negative
  • The dstOffset argument is negative
  • The count argument is negative
  • dstOffset + count is greater than dst.length, the length of the destination array.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method getDate

Prototype

Date getDate( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a Date.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method getDouble

Prototype

Double getDouble( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a Double.


Method getFloat

Prototype

Float getFloat( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value for the specified column.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method getInt

Prototype

Int32 getInt( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value for the specified column.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method getLong

Prototype

Int64 getLong( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value for the specified column.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method getRowCount

Prototype

UInt32 getRowCount( )

Returns

The number of rows in the result set.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method getShort

Prototype

Int16 getShort( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as an Int16.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method getString

Prototype

String getString( UInt32 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a String.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method getTime

Prototype

Date getTime( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a Date.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method getTimestamp

Prototype

Date getTimestamp( UInt16 index )

Parameters

index The 1-based ordinal in the result set to get.

Returns

The value as a Date.


Method insert

Prototype

insert()

Remarks

Inserts a new row with the current column values (specified using the set methods).

Each insert must be preceded by a call to insertBegin.


Method insertBegin

Prototype

insertBegin( )

Remarks

Prepares to insert a new row into this table by setting all current column values to their default values. Call the appropriate setType method(s) to specify the non-default values that are to be inserted.

The row is not actually inserted and the data in the row is not actually changed until you execute the insert(), and that change is not permanent until it is committed.


Method lookupBackward

Prototype

Boolean lookupBackward( )

Returns

true if successful, false otherwise.

Remarks

Move backwards through the table from the end, looking for a row that matches or is less than a value or full set of values in the current index.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is less than the index value. On failure (no rows less than the value being looked for) the cursor position is before the first row (isBOF()).

Each search must be preceded by a call to lookupBegin().


Method lookupBackwardForColumns

Prototype

Boolean lookupBackwardForColumns( UInt16 numColumns )

Parameters

  • numColumns For composite indexes, the number of columns to use in the lookup. For example, if you have a three column index, and you want to look up a value that matches based on the first column only, you should set the value for the first column, and then supply a numColumns value of 1.

Returns

true if successful, false otherwise.

Remarks

Move backwards through the table from the beginning, looking for a row that matches or is less than a value or partial set of values in the current index.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is less than the index value. On failure (no rows less than the value being looked for) the cursor position is before the first row (isBOF()).

Each search must be preceded by a call to lookupBegin().


Method lookupBegin

Prototype

lookupBegin( )

Remarks

Prepares to perform a new lookup on this table. The value(s) to search for are specified by calling the appropriate setType method(s) on the columns in the index this table was opened with.


Method lookupForward

Prototype

Boolean lookupForward( )

Returns

true if successful, false otherwise.

Remarks

Move forwards through the table from the beginning, looking for a row that matches or is greater than a value or full set of values in the current index.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is greater than the index value. On failure (no rows greater than the value being looked for) the cursor position is after the last row (isEOF()).

Each search must be preceded by a call to lookupBegin().


Method lookupForwardForColumns

Prototype

Boolean lookupForwardForColumns( UInt16 numColumns )

Parameters

  • numColumns For composite indexes, the number of columns to use in the lookup. For example, if you have a three column index, and you want to look up a value that matches based on the first column only, you should set the value for the first column, and then supply a numColumns value of 1.

Returns

true if successful, false otherwise.

Remarks

Move forwards through the table from the beginning, looking for a row that matches or is greater than a value or partial set of values in the current index.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is greater than the index value. On failure (no rows greater than the value being looked for) the cursor position is after the last row (isEOF()).

Each search must be preceded by a call to lookupBegin().


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method isBOF

Prototype

Boolean isBOF( )

Returns

true if successful, false otherwise.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method isEOF

Prototype

Boolean isEOF( )

Returns

true if successful, false otherwise.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method isNull

Prototype

Boolean isNull( Uint16 index )

Parameters

index The column index value.

Returns

true if the value is null.

false otherwise.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method isOpen

Prototype

Boolean isOpen( )

Returns

true if the ResultSet is open, false otherwise.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method open

Prototype

open()

Remarks

Opens this table for data access using its primary key.


Method openWithIndex

Prototype

openWithIndex( String index)

Parameters

  • index The name of the index with which to open the table. If null, the primary key is used.

Remarks

Opens this table for data access using the specified index.


Method setBoolean

Prototype

setBoolean(short columnID, boolean value)

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using a boolean. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.

Example

The following statement sets the value for the first column to false:

t.setBoolean( 1, false );


Method setBytes

Prototype

setBytes( UInt16 columnID, Array value )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using an array of bytes. Suitable for columns of type SQLType.BINARY or SQLType.LONGBINARY only. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.

Example

The following statements set the value of the first column:

var blob = new Array( 3 );
blob[ 0 ] = 78;
blob[ 1 ] = 0'
blob[ 2 ] = 68;
t.setBytes( 1, blob );


Method setDate

Prototype

setDate( UInt16 columnID, Date value)

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using a Date. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.

Example

The following statement sets the value of the first column to 2004/10/27:

t.setDate(
  1, new Date( 2002,9,27,0,0,0,0 )
);


Method setDouble

Prototype

setDouble( UInt16 columnID, Double value )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using a double. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.

Example

The following example sets the value of the first column:

t.setDouble( 1, Number.MAX_VALUE );


Method setFloat

Prototype

setFloat( UInt16 columnID, Float value)

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using a Float. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.

Example

The following statement sets the value of the first column:

t.setFloat(
   1,
   (2 - Math.pow(2,-23)) * Math.pow(2,127)
);


Method setInt

Prototype

setInt( UInt16 columnID, Int32 value )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using an Integer. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.

Example

The following statement sets the value of the first column to 2147483647:

t.setInt( 1, 2147483647 );


Method setLong

Prototype

setLong( UInt16 columnID, Int64 value )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using an Int64. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.

Example

The following statement sets the value of the first column to 9223372036854770000:

t.setLong( 1, 9223372036854770000 );


Method setNull

Prototype

setNull( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Remarks

Sets a column to the SQL NULL. The data is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.


Method setShort

Prototype

setShort( UInt16 columnID, Int16 value )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using a UInt16. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.

Example

The following statement sets the value of the first column to 32767:

t.setShort( 1, 32767 );


Method setString

Prototype

setString( UInt16 columnID, String value )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using a String. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.

Example

The following statement sets the value of the first column to abc.

t.setString( 1, "abc" );


Method setTime

Prototype

setTime( UInt16 columnID, Date value )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using a Date. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.

Example

The following statement sets the value for the first column to 18:02:13:0000:

t.setTime(
  1, new Date( 1966,4,1,18,2,13,0 )
);


Method setTimestamp

Prototype

setTimestamp( UInt16 columnID, Date value )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using a Date. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.

Example

The following statement sets the value of the first column to 1966/05/01 18:02:13:0000:

t.setTimestamp(
  1, new Date( 1966,4,1,18,2,13,0 )
);


Method setToDefault

Prototype

setToDefault( UInt16 columnID )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

Remarks

Sets the value for the specified column to its default value. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.


Method setULong

Prototype

setULong( UInt16 columnID, UInt64 value )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using a 64-bit integer treated as an unsigned value. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed.

Example

The following statement sets the value for the first column:

t.setULong(
  1, 9223372036854770000 * 4096
);


Method setUUID

Prototype

setUUID( UInt16 columnID, UUID value )

Parameters

  • columnID The ID number of the column. The first column in the table has an ID value of one.

  • value The new value for the column.

Remarks

Sets the value for the specified column using a UUID. The data in the row is not actually changed until you execute an insert or update, and that change is not permanent until it is committed. Only valid for columns of type SQLType.BINARY and length 16.

Example

The following statement sets a new UUID value for the first column in the table:

t.setUUID( 1, conn.getNewUUID(); );
See also
  • Maintaining unique primary keys using UUIDs


Web Links Browse Collapse Expand PDF Previous Next

UltraLite for M-Business Anywhere User's Guide

UltraLite for M-Business Anywhere API Reference

Class ULTable

Method truncate

Prototype

truncate()

Remarks

Deletes all rows in the table while temporarily activating stop synchronization delete.


Method update

Prototype

update()

Remarks

Updates the current row with the current column values (specified using the set methods).

Each update must be preceded by a call to updateBegin.


Method updateBegin

Prototype

updateBegin()

Remarks

Prepares to update the current row in this table. Column values are modified by calling the appropriate setType method or methods.

The data in the row is not actually changed until you execute the update, and that change is not permanent until it is committed.

Modifying columns in the index used to open the table will affect any active searches in unpredictable ways. Columns in the primary key of the table can not be updated.


Class UUID

Represents a UUID. A UUID (Universally Unique Identifer) or GUID (Globally Unique Identifier) is a generated value guaranteed to be unique across all computers and databases. UUIDs are stored as SQLType.BINARY(16) values in UltraLite databases and can be used to uniquely identify rows. The UUID class stores immutable UUIDs.

A UUID is associated with the Connection that created it and can no longer be converted to a string after the connection is closed.


Method equals

Prototype

Boolean equals( UUID other)

Parameters

  • other UUID with which to compare.

Returns

true if this UUID is the same as the other argument, false otherwise.


Method toString

Prototype

String toString()

Returns

A string representation of this UUID.

Remarks

The string is of the format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, where X is a hexadecimal digit or null if the Connection associated with the UUID is closed.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

Version 9.0.2

DC50023-01-0902-01

October 2004

Copyright
About This Manual
Introduction to UltraLite for C/C++ Developers
Developing Applications Using the UltraLite C++ Component
Developing Applications Using the Static C++ API
Developing Applications Using Embedded SQL
Common Features of UltraLite C/C++ Interfaces
Developing UltraLite Applications for the Palm Computing Platform
Developing UltraLite Applications for Windows CE
Tutorial: Build an Application Using the C++ Component
Tutorial: Build an Application Using the Static C++ API
Tutorial: Build an Application Using Embedded SQL
Tutorial: Build an Application Using ODBC
UltraLite C/C++ Common API Reference
UltraLite C++ Component API Reference
UltraLite Static C++ API Reference
Embedded SQL API Reference
UltraLite ODBC API Reference
Synchronization Parameters Reference


About This Manual

Subject

This manual describes UltraLite C and C++ programming interfaces. With UltraLite you can develop and deploy database applications to handheld, mobile, or embedded devices.

Audience

This manual is intended for C and C++ application developers who wish to take advantage of the performance, resource efficiency, robustness, and security of an UltraLite relational database for data storage and synchronization.


Introduction to UltraLite for C/C++ Developers

About this chapter

This chapter introduces you to UltraLite for C/C++. It assumes that you are familiar with the features of UltraLite, as described in Welcome to UltraLite.

For more information about creating applications using UltraLite for C/C++, see Common Features of UltraLite C/C++ Interfaces.

For a hands-on tutorial introducing UltraLite for C/C++, see Tutorial: Build an Application Using the C++ Component.


UltraLite and the C/C++ programming languages

C and C++ provides the following benefits for UltraLite developers targeting small devices:

  • a robust relational database store

  • the power, efficiency, and flexibility of C or C++

  • deployment on the Windows CE, Palm OS, and Windows XP platforms

For more information about the features of UltraLite databases, see UltraLite Databases.

UltraLite programming interfaces are either static or dynamic. Static and dynamic interfaces have different benefits and limitations. They also have a different development model.

UltraLite developers using C++ have several options available:

  • The UltraLite C++ Component.

  • Embedded SQL (static interface).

  • The Static C++ API (static interface).

  • The ODBC programming interface (component interface).

UltraLite developers using C must use embedded SQL or ODBC.

For more information, see Choosing between components and static interfaces.

Benefits and limitations of the C++ Component
Benefits and limitations of the Static C++ API
Developing Static C++ applications
Benefits and limitations of embedded SQL
Developing embedded SQL applications


Benefits and limitations of the C++ Component

The benefits and disadvantages of the UltraLite C++ Component are as follows:

  • Dynamic SQL The UltraLite C++ Component broadens the scope of the applications you can build by providing access to dynamic SQL. Dynamic SQL permits SQL statements to be defined at runtime. By contrast, the static interfaces, such as embedded SQL and the Static C++ API, require all SQL statements to be specified at compile time.

  • Development model You can use the UltraLite Schema Painter to create an UltraLite database when you use the UltraLite C++ Component. Also, no preprocessing is required. By contrast, the embedded SQL and Static C++ API interfaces require a preprocessing step before compiling your application. They also require that you construct an Adaptive Server Anywhere reference database.

  • Efficiency For databases with few tables, applications built with the static interfaces provide a smaller footprint than those built using the component interfaces. For databases with more complex schemas, this advantage of the static interfaces is lost.

  • Multi-process support The UltraLite C++ Component provides a version of the UltraLite runtime engine that supports connections from multiple applications.

Advanced developers can combine features of the UltraLite C++ Component API with those of the Static C++ API and even embedded SQL.

For more information, see Combining UltraLite C/C++ interfaces.


Benefits and limitations of the Static C++ API

UltraLite provides several programming interfaces, including both static development models (of which the Static C++ interface is one) and UltraLite components. Many of the benefits and disadvantages of the Static C++ API are shared with the embedded SQL.

The Static C++ API has the following advantages:

  • Small footprint database As the Static C++ API uses an UltraLite database engine compiled specifically for each application, the footprint is generally smaller than when using an UltraLite component, especially for a small number of tables. For a large number of tables, this benefit is lost.

  • High performance Combining the high performance of C and C++ applications with the optimization of the generated code, including data access plans, makes the Static C++ API a good choice for high-performance application development.

  • Extensive SQL support With the Static C++ API you can use a wide range of SQL in your applications.

The Static C++ API has the following disadvantages:

  • Knowledge of C or C++ required If you are not familiar with C or C++ programming, you may wish to use one of the other UltraLite interfaces. UltraLite components provide interfaces from several popular programming languages and tools.

  • Complex development model The use of a reference database to hold the UltraLite database schema, together with the need to generate the API for your specific application, makes the Static C++ API development process complex. The UltraLite components provide a much simpler development process.

  • SQL must be specified at design time Only SQL statements defined at compile time can be included in your application. The UltraLite components allow dynamic use of SQL statements.

The choice of development model is guided by the needs of your particular project, and by the programming skills and experience available.


Developing Static C++ applications

When developing Static C++ UltraLite applications, you use a programming interface that is generated from a reference database. In order to develop these applications you should be familiar with the C or C++ programming language.

The development process for Static C++ UltraLite applications is as follows:

  1. Design your database.

    Prepare an Adaptive Server Anywhere reference database that contains the tables and indexes you wish to include in your UltraLite database.

  2. Add SQL statements to the database.

    The SQL Statements you wish to use in your application must be added to the reference database.

  3. Generate the API for your application.

    The UltraLite generator provides an API for your specific application.

  4. Write your application.

    Data access features in your application code use function calls from the generated API.

  5. Compile your .cpp files.

    You can compile the generated .cpp files just as you compile other .cpp files.

  6. Link the .cpp files.

    You must link the files against the UltraLite runtime library.

For a full description of the development process, see Building Static C++ API applications.


Benefits and limitations of embedded SQL

UltraLite provides several programming interfaces, including both static development models (of which embedded SQL is one) and UltraLite components. Many of the benefits and disadvantages of embedded SQL are shared with the UltraLite Static C++ API.

Embedded SQL has the following advantages:

  • Small footprint database As embedded SQL uses an UltraLite database engine compiled specifically for each application, the footprint is generally smaller than when using an UltraLite component, especially for a small number of tables. For a large number of tables, this benefit is lost.

  • High performance Combining the high performance of C and C++ applications with the optimization of the generated code, including data access plans, makes embedded SQL a good choice for high-performance application development.

  • Extensive SQL support With embedded SQL you can use a wide range of SQL in your applications.

Embedded SQL has the following disadvantages:

  • Knowledge of C or C++ required If you are not familiar with C or C++ programming, you may wish to use one of the other UltraLite interfaces. UltraLite components provide interfaces from several popular programming languages and tools.

  • Complex development model The use of a reference database to hold the UltraLite database schema, together with the need to preprocess your source code files, makes the embedded SQL development process complex. The UltraLite components provide a much simpler development process.

  • SQL must be specified at design time Only SQL statements defined at compile time can be included in your application. The UltraLite components allow dynamic use of SQL statements.

The choice of development model is guided by the needs of your particular project, and by the programming skills and experience available.


Developing embedded SQL applications

When developing embedded SQL applications, you mix SQL statements in with standard C or C++ source code. In order to develop embedded SQL applications you should be familiar with the C or C++ programming language.

The development process for embedded SQL applications is as follows:

  1. Design your database.

    Prepare an Adaptive Server Anywhere reference database that contains the tables and indexes you wish to include in your UltraLite database.

  2. Write your source code in an embedded SQL source file, which typically has extension .sqc.

    When you need data access in your source code, use the SQL statement you wish to execute, prefixed by the EXEC SQL keywords. For example:

    EXEC SQL SELECT price, prod_name
         INTO :cost, :pname
         FROM ULProduct
         WHERE prod_id= :pid;
if((SQLCODE==SQLE_NOTFOUND)||(SQLCODE<0)) {
      return(-1);
}

  3. Preprocess the .sqc files.

    SQL Anywhere Studio includes a SQL preprocessor (sqlpp), which reads the .sqc files, accesses an Adaptive Server Anywhere reference database, and generates .c or .cpp files. These files hold function calls to the UltraLite runtime library.

  4. Compile your .c or .cpp files.

    You can compile the generated .c or .cpp files just as you compile other .c or .cpp files.

  5. Link the .c or .cpp files.

    You must link the files against the UltraLite runtime library.

For a full description of the embedded SQL development process, see Building embedded SQL applications.


System requirements and supported platforms

Development platforms

To develop applications using UltraLite C++, you require the following.

  • Microsoft Windows NT/2000/XP.

  • A supported C/C++ compiler.

Target platforms

UltraLite C/C++ supports the following target platforms:

  • Windows CE 3.0 and higher, or Palm OS 3.5 or later.

For more information, see UltraLite development platforms and UltraLite target platforms.


UltraLite C++ Component architecture

The UltraLite C++ Component interface is defined in the uliface.h header file.

  • DatabaseManager You create one DatabaseManager object for each application.

  • Connection Each Connection object represents a connection to an UltraLite database. You can create one or more Connection objects.

  • Table The Table object provides access to the data in the database.

  • PreparedStatement, ResultSet, and ResultSetSchema These dynamic SQL objects allow you to create Dynamic SQL statements, make queries and execute INSERT, UPDATE and DELETE statements, and attain programmatic control over database result sets.

  • SyncParms You use the SyncParms object to synchronize your UltraLite database with a MobiLink synchronization server.

The API Reference is supplied in the online books. For more information about accessing the API reference, see UltraLite C++ Component API Reference.


Developing Applications Using the UltraLite C++ Component

About this chapter

This chapter explains how to develop applications using the UltraLite C++ component.

For hands-on tutorials, see Tutorial: Build an Application Using the C++ Component.

Using the UltraLite namespace
UltraLite database schemas
Connecting to a database
Accessing data using dynamic SQL
Accessing data with the Table API
Managing transactions
Accessing schema information
Handling errors
Authenticating users
Encrypting data
Synchronizing data
Compiling and linking your application


Using the UltraLite namespace

The UltraLite C++ Component interface provides a set of classes with names prefixed by UltraLite_, such as the UltraLite_Connection and UltraLite_DatabaseManager class. Most of the functions for each of these classes implement a function from an underlying interface with the string _iface appended to it. For example, the UltraLite_Connection class implements functions from UltraLite_Connection_iface.

When you explicitly use the UltraLite namespace, you can use a shorter name to refer to each class. Instead of declaring a connection as an UltraLite_Connection object, you can declare it as a Connection object if you are using the UltraLite namespace:

using namespace UltraLite;
ULSqlca sqlca;
sqlca.Initialize();
DatabaseManager * dbMgr = ULInitDatabaseManager(sqlca);
Connection *  conn = UL_NULL;

As a result of this architecture, code samples in this chapter use types such as DatabaseManager, Connection, and TableSchema, but links for more information direct you to UltraLite_DatabaseManager_iface, UltraLite_Connection_iface, and UltraLite_TableSchema_iface, respectively.


Upgrading your database schema

To modify your existing database structure, use the UpgradeSchemaFromFile method. In most cases there will be no data loss, however, data loss can occur if columns are deleted or if the data type for a column is changed to an incompatible type.

Example

The following code applies a new schema file.

// issue a commit before applying a new schema
// if there are any uncommitted transactions
conn->Commit();
conn->UpgradeSchemaFromFile(
  UL_TEXT("schema_file=genup01b.usm") ) );

For more information, see UpgradeSchemaFromFile Function.


Connecting to a database

UltraLite applications must connect to a database before carrying out operations on the data in it. This section describes how to connect to an UltraLite database. You can find sample code in Samples\UltraLite\CustDB.

Using the Connection object

The following properties of the Connection object govern global application behavior.

  • Commit behavior In the UltraLite C++ component, there is no autocommit mode. Each transaction must be followed by a Connection.Commit statement.

    For more information, see Managing transactions.

  • User authentication You can change the user ID and password for the application from the default values of DBA and SQL by using methods to Grant and Revoke connection permissions. Each application can have a maximum of four user IDs.

    For more information, see User authentication in UltraLite and Authenticating users.

  • Synchronization A set of objects governing synchronization is accessed from the Connection object.

    For more information, see Synchronizing data.

  • Tables UltraLite tables are accessed using methods of the Connection object.

    For more information, see Accessing data with the Table API.

  • Prepared statements A set of objects is provided to handle the execution of dynamic SQL statements and to navigate result sets.

    For more information, see Accessing data using dynamic SQL.

For more information about the Connection object, see Class UltraLite_Connection.

toggle To connect to an UltraLite database

  1. Use the UltraLite namespace.

    Using the UltraLite namespace allows you to use simple names for classes in the C++ Component interface.

    using namespace UltraLite;

  2. Create and initialize a DatabaseManager object and an UltraLite SQL communications area (ULSqlca). The ULSqlca is a structure that handles communication between the application and the database.

    The DatabaseManager object is at the root of the object hierarchy. You create only one DatabaseManager object per application. It is often best to declare the DatabaseManager object as global to the application.

    ULSqlca sqlca;
sqlca.Initialize();
DatabaseManager * dbMgr = ULInitDatabaseManager(sqlca);

    For more information, see Class UltraLite_DatabaseManager_iface.

    On the Palm OS, you should precede the call to ULInitDatabaseManager by a call to ULEnableFileDB or ULEnablePalmRecordDB. This sets the database store to use the Palm data store or the virtual file system. For more details, see ULEnablePalmRecordDB function and ULEnableFileDB function.

  3. Declare a Connection object.

    Most applications use a single connection to an UltraLite database and leave the connection open. Multiple connections are only required for multi-threaded data access. For this reason, it is often best to declare the Connection object as global to the application.

    Connection *  conn = UL_NULL;

    For more information, see Class UltraLite_Connection_iface

  4. Open a connection to an existing database, or create a new database if the specified database file does not exist.

    Most UltraLite applications deploy a schema file rather than a database file, and let UltraLite create the database file on the first connection attempt. Thus, the following code attempts to connect to an existing database. If the database file does not exist, the application creates a database file.

    // specify the location of the database file
static ul_char * parms = "file_name=mydata.udb";
ULValue lp( parms );
conn = dbMgr->OpenConnection( sqlca, lp );
if( sqlca.GetSQLCode() ==
  SQLE_ULTRALITE_DATABASE_NOT_FOUND ) {
  static ul_char * parms = UL_TEXT("schema_file=mydata.usm")
  UL_TEXT(";file_name=mydata.udb");
  ULValue lp( parms );
  conn = dm->CreateAndOpenDatabase( sqlca, lp );
  if( sqlca.GetSQLCode() < SQLE_NOERROR ){
    printf( "Open failed with sql code: %d.\n" ,
    sqlca.GetSQLCode() );
  }
}

    For more information, see OpenConnection Function and CreateAndOpenDatabase Function.

Example

The following code opens a connection to an UltraLite database named mydata.udb.

#include "uliface.h"
using namespace UltraLite;
static ul_char *  parms =
UL_TEXT( ";file_name=tutcustomer.udb"  )
UL_TEXT( ";schema_file=tutcustomer.usm" );
ULSqlca sqlca;
DatabaseManager * dm   = UL_NULL;
Connection *   conn   = UL_NULL;
sqlca.Initialize();
dm = ULInitDatabaseManager( sqlca );
if( dm == UL_NULL ){
   // You may have mismatched UNICODE vs. ANSI runtimes.
   return 1;
}
ULValue  lp( parms );
conn = dm->OpenConnection( sqlca, lp );
if( sqlca.GetSQLCode() ==
    SQLE_ULTRALITE_DATABASE_NOT_FOUND ) {
   conn = dm->CreateAndOpenDatabase( sqlca, lp );
   if( sqlca.GetSQLCode() < SQLE_NOERROR ) {
      printf( "Open failed with sql code: %d.\n" ,
      sqlca.GetSQLCode() );
      return NULL;
   }  else {
      printf( "Connected to a new database.\n" );
   }
} else {
   printf( "Connected to an existing database.\n" );
}
return( conn );
Multi-threaded applications

Each Connection and all objects created from it should be used on a single thread. If your application requires multiple threads accessing the UltraLite database, each thread requires a separate connection.


Accessing data using dynamic SQL

UltraLite applications can access table data using dynamic SQL or the Table API. This section describes data access using dynamic SQL.

For information about using the Table API, see Accessing data with the Table API.

This section explains how to perform the following tasks using dynamic SQL.

  • Inserting, deleting, and updating rows.

  • Retrieving rows to a result set.

  • Scrolling through the rows of a result set.

This section does not describe the SQL language itself. For information about dynamic SQL features, see Dynamic SQL.

For an overview of the sequence of operations required for any SQL operation, see Using dynamic SQL.


Data manipulation: INSERT, UPDATE and DELETE

With UltraLite, you can perform SQL Data Manipulation Language operations. These operations are performed using the ExecuteStatement method, a member of the PreparedStatement class.

For more information, see the Class UltraLite_PreparedStatement.

Using parameters in your prepared statements
UltraLite indicates query parameters using the ? character. For any INSERT, UPDATE or DELETE, each ? is referenced according to its ordinal position in the prepared statement. For example, the first ? is referred to as 1, and the second as 2.
toggle To INSERT a row

  1. Declare a PreparedStatement.

    PreparedStatement * prepStmt;

    For more information, see PrepareStatement Function.

  2. Assign a SQL statement to the PreparedStatement object.

    ULValue sqltext(
    "INSERT INTO MyTable(MyColumn) values (?)" );
prepStmt = conn->PrepareStatement( sqltext );

  3. Assign input parameter values for the statement.

    The following code shows a string parameter.

    ULValue newValue( "string-value" );
prepStmt->SetParameter( 1, newValue );

  4. Execute the statement.

    The return value indicates the number of rows affected by the statement.

    ul_s_long rowsInserted;
rowsInserted = prepStmt->ExecuteStatement();

  5. Commit the change.

    conn->Commit();
toggle To UPDATE a row

  1. Declare a PreparedStatement.

    PreparedStatement * prepStmt;

  2. Assign a statement to the PreparedStatement object.

    ULValue sqltext(
   "UPDATE MyTable SET MyColumn1 = ? WHERE MyColumn2 = ?" );
prepStmt = conn->PrepareStatement( sqltext );

  3. Assign input parameter values for the statement.

    ULValue newValue( new-value );
ULValue oldValue( old-value );
stmt->SetParameter( 1, newValue );
stmt->SetParameter( 2, oldValue );

  4. Execute the statement.

    long rowsUpdated = prepStmt->ExecuteStatement();

  5. Commit the change.

    conn->Commit();
toggle To DELETE a row

  1. Declare a PreparedStatement.

    PreparedStatement * prepStmt;

  2. Assign a statement to the PreparedStatement object.

    ULValue sqltext(
   "DELETE FROM MyTable WHERE MyColumn = ?" );
prepStmt = conn->PrepareStatement( sqltext );

  3. Assign input parameter values for the statement.

    ULValue deleteValue( old-value );
prepStmt->SetParameter( 1, deleteValue );

  4. Execute the statement.

    long rowsDeleted = prepStmt->ExecuteStatement();

  5. Commit the change.

    conn->Commit();


Data retrieval: SELECT

The SELECT statement allows you to retrieve information from the database. When you execute a SELECT statement, the PreparedStatement.ExecuteQuery method returns a ResultSet object.

For more information, see Class UltraLite_PreparedStatement_iface.

toggle To execute a SELECT statement

  1. Create a new prepared statement and result set.

    PreparedStatement * prepStmt;

  2. Assign a prepared statement to your newly created PreparedStatement object.

    ULValue sqltext( "SELECT MyColumn FROM MyTable" );
prepStmt = conn->PrepareStatement( sqltext );

  3. Execute the statement.

    In the following code, the result of the SELECT query contain a string, which is output to a command prompt.

    #define MAX_NAME_LEN     100
ULValue mycol;
ResultSet * rs = stmt->ExecuteQuery();
rs->BeforeFirst();
while( rs->Next() ){
   char mycol[ MAX_NAME_LEN ];
   val = rs->Get( 1 );
   val.GetString( mycol, MAX_NAME_LEN );
   printf( "mycol= %s\n", mycol );
}


Navigating dynamic SQL result sets

You can navigate through a result set using methods associated with the ResultSet object.

The result set object provides you with the following methods to navigate a result set.

  • AfterLast() moves to a position after the last row.

  • BeforeFirst() moves to a position before the first row.

  • First() moves to the first row.

  • Last() moves to the last row.

  • Next() moves to the next row.

  • Previous() moves to the previous row.

  • Relative( offset ) moves a certain number of rows relative to the current row, as specified by the offset. Positive offset values move forward in the result set, relative to the current position of the cursor in the result set, and negative offset values move backward in the result set. An offset value of zero does not move the cursor, but allows you to repopulate the row buffer.

For more information, see Class UltraLite_ResultSet_iface.


Result set schema description

The ResultSet.GetSchema method allows you to retrieve information about a result set, such as column names, total number of columns, column scales, column sizes and column SQL types.

Example

The following example demonstrates how to use the ResultSet.GetSchema method to display schema information in a console window.

ResultSetSchema * rss = rs->GetSchema();
ULValue val;
char name[ MAX_NAME_LEN ];
for( int i = 1;
     i <= rss->GetColumnCount();
     i++ ){
   val = rss->GetColumnName( i );
   val.GetString( name, MAX_NAME_LEN );
   printf( "id= %d, name= %s \n", i, name );
}

For more information, see GetSchema Function.


Accessing data with the Table API

UltraLite applications can access table data using dynamic SQL or the Table API. This section describes data access using the Table API.

For information about dynamic SQL, see Accessing data using dynamic SQL.

This section explains how to perform the following tasks using the Table API.

  • Scrolling through the rows of a table.

  • Accessing the values of the current row.

  • Using find and lookup methods to locate rows in a table.

  • Inserting, deleting, and updating rows.

Navigating the rows of a table
Using UltraLite modes
Accessing the values of the current row
Searching rows with find and lookup
Updating rows
Inserting rows
Deleting rows


Navigating the rows of a table

UltraLite C++ component provides you with a number of methods to navigate a table in order to perform a wide range of navigation tasks.

The table object provides you with the following methods to navigate a table.

  • AfterLast() moves to a position after the last row.

  • BeforeFirst() moves to a position before the first row.

  • First() moves to the first row.

  • Last() moves to the last row.

  • Next() moves to the next row.

  • Previous() moves to the previous row.

  • Relative( offset ) moves a certain number of rows relative to the current row, as specified by the offset. Positive offset values move forward in the table, relative to the current position of the cursor in the table, and negative offset values move backward in the table. An offset value of zero does not move the cursor, but allows you to repopulate the row buffer.

For more information, see Class UltraLite_Table_iface.

Example

The following code opens the MyTable table and displays the value of the MyColumn column for each row.

Table * t = conn->openTable( "MyTable" );
ul_column_num colValue =
   t->GetSchema()->GetColumnID( "MyColumn" );
while ( t->Next() ){
   char lname[ MAX_NAME_LEN ];
   printf( "%s\n", colValue );
}

You expose the rows of the table to the application when you open the table object. By default, the rows are ordered by primary key value, but you can specify an index when opening a table to access the rows in a particular order.

Example

The following code fragment moves to the first row of the MyTable table as ordered by the ix_col index.

ULValue table_name( "MyTable" )
ULValue index_name( "ix_col" )
Table * t =
   conn->OpenTableWithIndex( table_name, index_name );
t.moveFirst();

For more information, see Class UltraLite_Table_iface.


Using UltraLite modes

UltraLite mode determines the purpose for which the values in the buffer will be used. UltraLite has the following four modes of operation, in addition to a default mode.

  • Insert mode The data in the buffer is added to the table as a new row when the insert method is called.

  • Update mode The data in the buffer replaces the current row when the update method is called.

  • Find mode Used to locate a row whose value exactly matches the data in the buffer when when one of the find methods is called.

  • Lookup mode Used to locate a row whose value matches or is greater than the data in the buffer when one of the lookup methods is called.


Accessing the values of the current row

A Table object is always located at one of the following positions.

  • Before the first row of the table.

  • On a row of the table.

  • After the last row of the table.

If the Table object is positioned on a row, you can use one of a set of methods appropriate for the data type to retrieve or modify the value of each column.

Retrieving column values

The Table object provides a set of methods for retrieving column values. These methods take the column ID as argument.

Example

The following code fragment retrieves the value of the lname column, which is a character string.

ULValue val;
char lname[ MAX_NAME_LEN ];
val = t->Get( lname_col_id );
val.GetString( lname, MAX_NAME_LEN );

The following code retrieves the value of the cust_id column, which is an integer.

int id = (int)(t->Get( id_col_id );
Modifying column values

In addition to the methods for retrieving values, there are methods for setting values. These methods take the column ID and the value as arguments.

Example

For example, the following code sets the value of the lname column to Kaminski.

ULValue lname_col( "fname" );
ULValue v_lname( "Kaminski" );
t->Set( lname_col, v_lname );

By assigning values to these properties you do not alter the value of the data in the database. You can assign values to the properties even if you are before the first row or after the last row of the table, but it is an error to try to access data when the current row is at one of these positions, for example by assigning the property to a variable.

// This code is incorrect
t.BeforeFirst();
id = t.Get( cust_id );
Casting values

The method you choose must match the data type you wish to assign. UltraLite automatically casts database data types where they are compatible, so that you could use the getString method to fetch an integer value into a string variable, and so on.


Searching rows with find and lookup

UltraLite has several modes of operation for working with data. Two of these modes, the find and lookup modes, are used for searching. The Table object has methods corresponding to these modes for locating particular rows in a table.

Note
The columns searched using Find and Lookup methods must be in the index used to open the table.

  • Find methods move to the first row that exactly matches specified search values, under the sort order specified when the Table object was opened. If the search values cannot be found, the application is positioned before the first or after the last row.

  • Lookup methods move to the first row that matches or is greater than a specified search value, under the sort order specified when the Table object was opened.

toggle To search for a row

  1. Enter find or lookup mode.

    The mode is entered by calling a method on the table object. For example, the following code enters find mode.

    t.FindBegin();

  2. Set the search values.

    You do this by setting values in the current row. Setting these values affects the buffer holding the current row only, not the database. For example, the following code fragment sets the value in the buffer to Kaminski.

    ULValue lname_col = t->GetSchema()->GetColumnID( "lname" );
ULValie v_lname( "Kaminski" );
t.Set( lname_col, v_lname );

  3. Search for the row.

    Use the appropriate method to carry out the search. For example, the following instruction looks for the first row that exactly matches the specified value in the current index.

    For multi-column indexes, a value for the first column is always used, but you can omit the other columns.

    tCustomer.FindFirst();

  4. Search for the next instance of the row.

    Use the appropriate method to carry out the search. For a find operation, FindNext() locates the next instance of the parameters in the index. For a lookup, MoveNext() locates the next instance.

For more information, see Class UltraLite_Table_iface.


Updating rows

The following procedure updates a row.

toggle To update a row

  1. Move to the row you wish to update.

    You can move to a row by scrolling through the table or by searching the table using find and lookup methods.

  2. Enter update mode.

    For example, the following instruction enters update mode on t.

    t.BeginUpdate();

  3. Set the new values for the row to be updated. For example, the following instruction sets the id column in the buffer to 3.

    t.SetInt( id, 3 );

  4. Execute the Update.

    t.Update();

After the update operation the current row is the row that has been updated. If you changed the value of a column in the index specified when the Table object was opened, the current row is undefined.

UltraLite C++ component does not commit changes to the database until you commit them using conn->Commit(). For more information, see Managing transactions.

Caution Do not update the primary key of a row: delete the row and add a new row instead.


Inserting rows

The steps to insert a row are very similar to those for updating rows, except that there is no need to locate a row in the table before carrying out the insert operation. The order of row insertion into the table has no significance.

Example

The following code fragment inserts a new row.

t.InsertBegin();
t.SetInt( id, 3 );
t.SetString( lname, "Carlo" );
t.Insert();
t.Commit();

If you do not set a value for one of the columns, and that column has a default, the default value is used. If the column has no default, one of the following entries is used.

  • For nullable columns, NULL.

  • For numeric columns that disallow NULL, zero.

  • For character columns that disallow NULL, an empty string.

  • To explicitly set a value to NULL, use the setNull method.

For update operations, an insert is applied to the database in permanent storage when a commit is carried out. In AutoCommit mode, a commit is carried out as part of the insert method.


Managing transactions

For background information about transaction management in UltraLite, see Transaction processing, recovery, and backup.

The UltraLite C++ component does not support an autocommit model. It requires that transactions be explicitly completed.

toggle To commit a transaction

  • Execute a Connection.Commit() statement.

toggle To roll back a transaction

  • Execute a Connection.Rollback() statement.

For more information, see Class UltraLite_Connection_iface.


Accessing schema information

The objects in the API represent tables, columns, indexes, and synchronization publications. Each object has a GetSchema method that provides access to information about the structure of that object.

You cannot modify the schema through the API. You can only retrieve information about the schema.

For information about modifying the schema, see Upgrading your database schema.

You can access the following schema objects and information.

  • DatabaseSchema exposes the number and names of the tables in the database, as well as global properties such as the format of dates and times.

    To obtain a DatabaseSchema object, use Connection.GetSchema.

    For more information, see GetSchema Function.

  • TableSchema The number and names of the columns and indexes for this table.

    To obtain a TableSchema object, use Table.GetSchema.

    For more information , see GetSchema Function.

  • IndexSchema Information about the column in the index. As an index has no data directly associated with it there is no separate Index class, just a IndexSchema class.

    To obtain a IndexSchema object, call the TableSchema.GetIndex, the TableSchema.GetOptimalIndex, or the TableSchema.GetPrimaryKey method.

    For more information, see Class UltraLite_Table_iface.

  • PublicationSchema A list of the tables and columns contained in a publication. Publications are also comprised of schema only, and so there is no Publication object.

    To obtain a PublicationSchema object, call the DatabaseSchema.TableSchema.GetPublicationSchema method.

    For more information, see GetSchema Function.


Handling errors

You should check for errors after each database operation. You do so by using methods of the ULSqlca object. For example, LastCodeOK() checks if the operation was successful, while GetSQLCode() returns the numerical value of the SQLCode. You can look up the meaning of these values in Error messages indexed by Adaptive Server Anywhere SQLCODE.

In addition to explicit error handling, UltraLite supports an error callback function. If you register a callback function, then UltraLite calls the function each time an error occurs. The callback function does not control application flow, but does provide you with the ability to be notified of all errors, which is particularly helpful during application development. Use of the callback is illustrated in the tutorial: Tutorial: Build an Application Using the C++ Component.

For a sample callback function, see Callback function for ULRegisterErrorCallback and ULRegisterErrorCallback function.

For a list of error codes thrown by the UltraLite C++ component, see Error messages indexed by Adaptive Server Anywhere SQLCODE.

For more information, see Class ULSqlca.


Authenticating users

New users have to be added from an existing connection. As all UltraLite databases are created with a default user ID and password of DBA and SQL, respectively, you must first connect as this initial user.

You cannot change a user ID. Instead, you add a user and delete an existing user. A maximum of four user IDs are permitted for each UltraLite database.

For more information, see User authentication in UltraLite.

toggle To add a user or change a password for an existing user

  1. Connect to the database as a user with DBA authority.

  2. Grant the user connection authority with the desired password using the Connection.GrantConnectTo method.

    This procedure is the same whether you are adding a new user or changing the password of an existing user.

    For more information, see Class UltraLite_Connection_iface.

toggle To delete an existing user

  1. Connect to the database as a user with DBA authority.

  2. Revoke the user's connection authority using the Connection.RevokeConnectFrom method.


Encrypting data

You can encrypt or obfuscate your UltraLite database using the UltraLite C++ component.

For background information, see Encrypting UltraLite databases,

Encryption

To create a database with encryption, specify an encryption key by specifying the key connection parameter in the connection string. When you call the CreateAndOpenDatabase method, the database is created and encrypted with the specified key.

For more information, see Encryption Key connection parameter .

You can change the encryption key by specifying the new encryption key with the UltraLite_Connection.ChangeEncryptionKey method.

For more information, see Class UltraLite_Connection_iface.

After the database is encrypted, connections to the database must specify the correct encryption key. Otherwise, the connection fails.

Obfuscation

To obfuscate the database, specify obfuscate=1 as a creation parameter.

For more information about database encryption, see Encrypting UltraLite databases.


Synchronizing data

Users of SQL Anywhere Studio 9.0 can synchronize UltraLite applications with a central database. Synchronization requires the MobiLink synchronization software included with SQL Anywhere Studio.

This section provides a brief introduction to synchronization and describes some features of particular interest to users of the UltraLite C++ component.

For a more detailed explanation of synchronization, see UltraLite Clients and UltraLite Synchronization Parameters.

UltraLite C++ component supports TCP/IP, HTTP, and HTTPS synchronization. Synchronization is initiated by the UltraLite application. In all cases, you use methods and properties of the connection object to control synchronization.

Note
To synchronize using HTTPS or encryption over TCP/IP you must obtain the separately-licensable security option. To order this option, see the card in your SQL Anywhere Studio package or see [external link] http://www.sybase.com/detail?id=1015780.

For more information, see Welcome to SQL Anywhere Studio.


Compiling and linking your application

A set of runtime libraries is available for some platforms when using the UltraLite C++ component. These include, for Windows CE and Windows XP, a database engine that permits multi-process access to the same database.

The runtime libraries are provided in the UltraLite\palm, UltraLite\ce, and UltraLite\win32 subdirectories of your SQL Anywhere installation.

The runtime library for Palm OS is as follows:

  • ulrt.lib A static library. This is located in UltraLite\palm\68k\lib\cw.

The Windows CE libraries are in the UltraLite\ce\<platform> directories, where platform may be one of arm, 386, mips, or emulator. Both static and dynamic libraries are provided for Windows CE:

  • ulrt9.dll A Unicode character set dynamic link library. To use this library, link your application against the import library, UltraLite\ce\<platform>\lib\ulimp.lib.

    When linking against this library, be sure to specify the following compilation options:

    /DUNICODE /DUL_USE_DLL

  • ulrt.lib A Unicode character set static library. This is located in UltraLite\ce\<platform>\lib\.

    When linking against this library, be sure to specify the following compilation option:

    /DUNICODE

  • ulrtc.lib A Unicode character set static library for use with the UltraLite engine for multi-process access to an UltraLite database. This is located in UltraLite\ce\<platform>\lib\.

    When linking against this library, be sure to specify the following compilation option:

    /DUNICODE
Runtime libraries for Windows XP

The UltraLite\win32\386 directory contains libraries for Windows operating systems other than Windows CE. These include the following:

  • ulrt9.dll An ANSI character set dynamic link library. To use this library, link your application against the import library, UltraLite\win32\386\ulimp.lib. Databases created using this library cannot be deployed to Windows CE devices, as Windows CE uses Unicode.

    When linking against this library, be sure to specify the following compilation option:

    /DUL_USE_DLL

  • ulrtw9.dll A Unicode character set dynamic link library. To use this library, link your application against the import library, UltraLite\win32\386\ulimpw.lib.

    When linking against this library, specify the following compilation options:

    /DUNICODE /DUL_USE_DLL

  • ulrtcw9.dll A Unicode character set dynamic link library for use with the UltraLite engine for multi-process access to an UltraLite database. To use this library, link your application against the import library, UltraLite\win32\386\ulimpcw.lib. Databases created using this library require distribution of the UltraLite engine, as well as the DLL.

    When linking against this library, be sure to specify the following compilation options:

    /DUNICODE /DUL_USE_DLL

    For information about the UltraLite engine, see Using the UltraLite engine.


Developing Applications Using the Static C++ API

About this chapter

This chapter describes how to develop applications using the UltraLite Static C++ API. This interface represents predefined queries or tables in your UltraLite database as objects, and provides methods that enable you to manipulate them from your application without using SQL.

Introduction
Defining features for your application
Connecting to a database
Accessing data
Authenticating users
Encrypting data
Synchronizing data
Building Static C++ API applications


Introduction

This chapter provides notes for developers who are writing and building UltraLite applications using the Static C++ API.

What's in this chapter?

The chapter includes the following information:

  • Information about how to define the data access features to be used in your application.

    See Defining features for your application.

  • Information on generating C++ API classes from your reference database.

    See Generating UltraLite C++ classes.

  • Notes on compiling and linking UltraLite C++ API applications.

    See Compiling and linking your application.

Before you begin

The development process for the C++ API is similar to that for other UltraLite development models. This chapter assumes a familiarity with that process.

For more information, see Using UltraLite Static Interfaces.


Defining features for your application

The SQL statements to be included in the UltraLite application, and the structure of the UltraLite database itself, are defined by adding the SQL statements to the reference database for your application.

Defining projects
Adding statements to a project
Defining UltraLite tables
Tables or queries?
Defining database features for Static C++ API applications


Defining projects

When you run the UltraLite generator, it writes out class definitions for all the SQL statements in a given project. A project is a name defined in the reference database, which groups the SQL statements for an application. You can store SQL statements for multiple applications in a single reference database by defining multiple projects.

For information on creating projects, see Creating an UltraLite project.

You can use the ul_delete_project stored procedure to remove a project definition.


Adding statements to a project

For information on adding SQL statements to an UltraLite project, see Adding SQL statements to an UltraLite project.

For information on using placeholders, and other aspects of writing SQL statements for UltraLite, see Writing UltraLite SQL statements.


Defining UltraLite tables

If you do not intend to carry out joins, and if you have strong constraints on your application executable size, you can define tables instead of queries for your UltraLite application.

You define a subset of a database for use in a Static C++ API application by creating a publication in the reference database. A publication defines the set of tables, and columns in those tables, that you want to include in your UltraLite application. The use of a publication is purely a convenience for UltraLite, and does not imply any connection with SQL Remote or MobiLink synchronization.

Publications allow you to qualify which rows any user receives using subqueries and parameters. You cannot use these devices when creating publications for use with UltraLite: only the set of tables and columns within those tables is used for defining the UltraLite classes.


Tables or queries?

Table definitions and query definitions provide alternative ways of defining the data that is to be included in your UltraLite database, and the range of operations you can carry out on that data.

Using SQL statements and projects provides a more general approach to defining applications, and are most likely to be used in larger enterprise applications. Table definitions may be useful as a convenient device in the following cases:

  • Your application needs to access data only one table at a time. You cannot define joins using table definitions.

  • You are severely constrained for memory use. The code generated for table definitions is smaller than that for queries, because of their simpler structure.


Defining database features for Static C++ API applications

Static C++ API applications use some functions that are not part of the class hierarchy. These functions control features such as database storage and access configuration. They are as follows:

  • ULEnableFileDB function

  • ULRegisterSchemaUpgradeObserver function

  • ULEnablePalmRecordDB function

  • ULEnableStrongEncryption function

  • ULEnableUserAuthentication function.

Other aspects of database storage are configured using the UL_STORE_PARMS macro. For more information, see UL_STORE_PARMS macro.


Connecting to a database

The ULData object makes the data in the database object available to your application. You need to call ULData::Open() before you can connect to the UltraLite database or carry out any operations on the data.

The ULData::Open() method can be called with parameters that define the storage and access parameters for the database (file name, cache size, reserved size).

Once the ULData object is opened, you can open a connection on the database. You do that using the ULConnection::Open() method, supplying a reference to the ULData object and a set of connection parameters to establish the connection. You can use multiple connections on a single database. Once the connection is established, you can open the generated ULStatement, ULResultSet or ULTable objects that define the tables or statements used in your application, and use these objects to manipulate the data.

The ULConnection object defines the general characteristics of how you interact with the data.

Synchronization is carried out using the ULConnection object. The Synchronize method carries out synchronization of the data with a MobiLink server.


Accessing data

Each table or query is represented by a class. The API for accessing and modifying the rows in the table or query is based on a SQL cursor: a pointer to a position in the table or query.

The cursor can have the following positions:

  • Before the first row This position has value 0. This is the position of the cursor when the table or query is opened.

  • On a row If a table or query has n rows, positions 1 to n for the cursor correspond to the rows.

  • After the last row This position has value (n+ 1)

You can move through the rows of the object using methods of the object, including Next() and Previous().

Palm Computing Platform developers

If you are developing an application for the Palm Computing Platform, there are some extra considerations for how to use these objects.

For more information, see Selecting a network protocol.

Row ordering


Row ordering

The order of the rows in the object is determined when it is opened. By default, tables are ordered by primary key. The UltraLite generator adds an enumeration for the object definition, with a member for each index on the table in the reference database (the primary key is named Primary), and by specifying a member of this enumeration, you can control the ordering of the rows in the object.

If you update a row so that it no longer belongs in the current position the current row of the cursor moves to that row.

For example, consider a single-column object with the values A, B, C, and E.

  • If a cursor is sitting on row B (position 2) and modifies the value to D, then the row is moved to sit between C and E (becoming position 3) and the current row of the cursor changes to position 3.

If you insert a row, the current position does not move to that row.


Authenticating users

New users have to be added from an existing connection. As all UltraLite databases are created with a default user ID and password of DBA and SQL, respectively, you must first connect as this initial user.

You cannot change a user ID. Instead, you add a user and delete an existing user. A maximum of four user IDs are permitted for each UltraLite database.

For more information, see User authentication in UltraLite.

toggle To enable user authentication (Static C++ API)

  1. Define the compiler directive UL_ENABLE_USER_AUTH when compiling ulapi.cpp.

  2. Call ULEnableUserAuthentication before opening the database. For example:

    ULData db;
...
ULEnableUserAuthentication( &sqlca );
db.open();
...

The following code fragment performs user management and authentication for a Static C++ API UltraLite application.

A complete sample can be found in the Samples\UltraLite\apiauth subdirectory of your SQL Anywhere directory. The code below is taken from Samples\UltraLite\apiauth\sample.cpp.

ULEnableUserAuthentication( &sqlca );
db.Open() ;
   if( conn.Open( &db,
                  UL_TEXT( "dba" ),
                  UL_TEXT( "sql" ) ) ){
      // prompt for new user ID and password
      printf("Enter new user ID and password\n" );
      scanf( "%s %s", uid, pwd );
      if( conn.GrantConnectTo( uid, pwd ) ){
         // new user added, remove dba
         conn.RevokeConnectFrom( UL_TEXT("dba") );
      }
      conn.Close();
   }
   // regular connection
   printf("Enter user ID and password\n" );
   scanf( "%s %s", uid, pwd );
   if( conn.Open( &db, uid, pwd )){
   ...

The code carries out the following tasks:

  1. Initiate database functionality by opening the database object.

  2. Attempt to connect using the default user ID and password.

  3. If the connection attempt is successful, add a new user.

  4. If the new user is successfully added, delete the DBA user from the UltraLite database.

  5. Disconnect. An updated user ID and password is now added to the database.

  6. Connect using the updated user ID and password.

For more information, see GrantConnectTo method, and RevokeConnectFrom method.


Encrypting data

You can encrypt or obfuscate your UltraLite database using the UltraLite Static C++ API.

For background information, see Encrypting UltraLite databases,

Encryption

UltraLite databases are created on the first connection attempt. To encrypt an UltraLite database, you supply an encryption key before that connection attempt. On the first attempt, the supplied key is used to encrypt the database. On subsequent attempts, the supplied key is checked against the encryption key, and connection fails unless the key matches.

toggle To strongly encrypt an UltraLite database

  1. Load the encryption module.

    Call ULEnableStrongEncryption before opening the database.

    You open a database by calling ULData::Open.

  2. Specify the encryption key.

    Define the UL_STORE_PARMS macro with the parameter name key.

    #define UL_STORE_PARMS "key=a secret key"

    As with most passwords, it is best to choose a key value that cannot be easily guessed. The key can be of arbitrary length, but generally the longer the key, the better because a shorter key is easier to guess than a longer one. As well, including a combination of numbers, letters, and special characters decreases the chances of someone guessing the key.

    Do not include semicolons in your key. Do not put the key itself in quotes, or the quotes will be considered part of the key.

    You must supply this key each time you want to start the database. Lost or forgotten keys result in completely inaccessible databases.

    For more information, see UL_STORE_PARMS macro.

  3. Handle attempts to open an encrypted database with the wrong key.

    If an attempt is made to open an encrypted database and the wrong key is passed in, db_init returns ul_false and SQLCODE -840 is set.

Changing the encryption key

You can change the encryption key for a database. The application must already be connected to the database using the existing key before the change can be made.

toggle To change the encryption key on an UltraLite database

  • Call the ULChangeEncryptionKey function, supplying the new key as an argument.

    The application must already be connected to the database using the old key before this function is called.

    For more information, see ULChangeEncryptionKey function.

Obfuscation
toggle To obfuscate an UltraLite database

  • Define the UL_ENABLE_OBFUSCATION compiler directive when compiling the generated database.

    For more information, see UL_ENABLE_OBFUSCATION macro.


Synchronizing data

Synchronization is a key feature of many UltraLite applications. This section describes how to add synchronization to your application.

The synchronization logic that keeps UltraLite applications up to date with the consolidated database is not held in the application itself. Synchronization scripts stored in the consolidated database, together with the MobiLink synchronization server and the UltraLite runtime library, control how changes are processed when they are uploaded and determines which changes are to be downloaded.

Overview

The specifics of each synchronization is controlled by a set of synchronization parameters. These parameters are gathered into a structure C/C++, which is then supplied as an argument in a function call to synchronize. The outline of the method is the same in each development model.

toggle To add synchronization to your application

  1. Initialize the synchronization structure.

    For information, see Initializing the synchronization parameters.

  2. Assign the parameter values for your application.

    For information, see Network protocol options for UltraLite synchronization clients.

  3. Call the synchronization function, supplying the structure or object as argument.

    For information, see Invoking synchronization.

You must ensure that there are no uncommitted changes when you synchronize. For more information, see Commit all changes before synchronizing.

Synchronization parameters

Synchronization specifics are controlled through a set of synchronization parameters. For information on these parameters, see Network protocol options for UltraLite synchronization clients.

Initializing the synchronization parameters
Setting synchronization parameters
Invoking synchronization
Commit all changes before synchronizing
Adding initial data to your application
Monitoring and canceling synchronization


Initializing the synchronization parameters

The synchronization parameters are stored in a C/C++ structure.

In C/C++ the members of the structure may not be well-defined on initialization. You must set your parameters to their initial values with a call to a special function. The synchronization parameters are defined in a structure declared in the UltraLite header file ulglobal.h.

For a complete list of synchronization parameters, see UltraLite Synchronization Parameters.

toggle To initialize the synchronization parameters (Static C++ API)

  • Call the InitSynchInfo() method on the Connection object. For example:

    auto ul_synch_info synch_info;
conn.InitSynchInfo( &synch_info );


Setting synchronization parameters

The following code initiates TCP/IP synchronization. The MobiLink user name is 50, with an empty password, the script version is custdb, and the MobiLink synchronization server is running on the same machine as the application (localhost), on the default port (2439):

auto ul_synch_info synch_info;
conn.InitSynchInfo( &synch_info );
synch_info.user_name = UL_TEXT( "50" );
synch_info.version = UL_TEXT( "custdb" );
synch_info.stream = ULSocketStream();
synch_info.stream_parms =
   UL_TEXT("host=localhost");
conn.Synchronize( &synch_info );


Invoking synchronization

The details of how to invoke synchronization depends on your target platform and on the synchronization stream.

The synchronization process can only work if the device running the UltraLite application is able to communicate with the synchronization server. For some platforms, this means that the device needs to be physically connected by placing it in its cradle or by attaching it to a server computer using a cable. You need to add error handling code to your application in case the synchronization cannot be carried out.

toggle To invoke synchronization (TCP/IP, HTTP, or HTTPS streams)

  • Call Connection.InitSynchInfo() to initialize the synchronization parameters, and call Connection.Synchronize() to synchronize. See Synchronize method.

toggle To invoke synchronization (HotSync)

  • Call Connection.InitSynchInfo to initialize the synchronization parameters and ULSetSynchInfo to manage synchronization before exiting the application.

    For more information, see ULSetSynchInfo function.

    HotSync synchronization is managed outside the application.

The synchronization call requires a structure that holds a set of parameters describing the specifics of the synchronization. The particular parameters used depend on the stream.


Commit all changes before synchronizing

An UltraLite database cannot have uncommitted changes when it is synchronized. If you attempt to synchronize an UltraLite database when any connection has an uncommitted transaction, the synchronization fails, an exception is thrown and the SQLE_UNCOMMITTED_TRANSACTIONS error is set. This error code also appears in the MobiLink synchronization server log.

For more information on download-only synchronizations, see Download Only synchronization parameter.


Adding initial data to your application

Many UltraLite application need data in order to start working. You can download data into your application by synchronizing. You may want to add logic to your application to ensure that, the first time it is run, it downloads all necessary data before any other actions are carried out.

Development tip
It is easier to locate errors if you develop an application in stages. When developing a prototype, temporarily code INSERT statements in your application to provide data for testing and demonstration purposes. Once your prototype is working correctly, enable synchronization and discard the temporary INSERT statements.

For more synchronization development tips, see Development tips.


Monitoring and canceling synchronization

This section describes how to monitor and cancel synchronization from UltraLite applications.

  • An API for monitoring synchronization progress and for canceling synchronization.

  • A progress indicator component that implements the interface, which you can add to your application.

Monitoring synchronization

  • Specify the name of your callback function in the observer member of the synchronization structure (ul_synch_info).

  • Call the synchronization function or method to start synchronization.

  • UltraLite calls your callback function called whenever the synchronization state changes. The following section describes the synchronization state.

Handling synchronization status information


Handling synchronization status information

The callback function that monitors synchronization takes a ul_synch_status structure as parameter.

The ul_synch_status structure has the following members:

ul_synch_state    state;
ul_u_short        tableCount;
ul_u_short        tableIndex;
   struct {
      ul_u_long   bytes;
      ul_u_short  inserts;
      ul_u_short  updates;
      ul_u_short  deletes;
    }       sent;
    struct {
      ul_u_long   bytes;
      ul_u_short  inserts;
      ul_u_short  updates;
      ul_u_short  deletes;
    }       received;
p_ul_synch_info   info;
ul_bool           stop;

  • state One of the following states:

    • UL_SYNCH_STATE_STARTING No synchronization actions have yet been taken.

    • UL_SYNCH_STATE_CONNECTING The synchronization stream has been built, but not yet opened.

    • UL_SYNCH_STATE_SENDING_HEADER The synchronization stream has been opened, and the header is about to be sent.

    • UL_SYNCH_STATE_SENDING_TABLE A table is being sent.

    • UL_SYNCH_STATE_SENDING_DATA Schema information or data is being sent.

    • UL_SYNCH_STATE_FINISHING_UPLOAD The upload stage is completed and a commit is being carried out.

    • UL_SYNCH_STATE_RECEIVING_UPLOAD_ACK An acknowledgement that the upload is complete is being received.

    • UL_SYNCH_STATE_RECEIVING_TABLE A table is being received.

    • UL_SYNCH_STATE_RECEIVING_DATA Schema information or data is being received.

    • UL_SYNCH_STATE_COMMITTING_DOWNLOAD The download stage is completed and a commit is being carried out.

    • UL_SYNCH_STATE_SENDING_DOWNLOAD_ACK An acknowledgement that download is complete is being sent.

    • UL_SYNCH_STATE_DISCONNECTING The synchronization stream is about to be closed.

    • UL_SYNCH_STATE_DONE Synchronization has completed successfully.

    • UL_SYNCH_STATE_ERROR Synchronization has completed, but with an error.

      For a description of the synchronization process, see The synchronization process.

  • tableCount Returns the number of tables being synchronized. For each table there is a sending and receiving phase, so this number may be more than the number of tables being synchronized.

  • tableIndex The current table which is being uploaded or downloaded, starting at 0. This number may skip values when not all tables are being synchronized.

  • info A pointer to the ul_synch_info structure.

  • sent.inserts The number of inserted rows that have been uploaded so far.

  • sent.updates The number of updated rows that have been uploaded so far.

  • sent.deletes The number of deleted rows that have been uploaded so far.

  • sent.bytes The number of bytes that have been uploaded so far.

  • received.inserts The number of inserted rows that have been downloaded so far.

  • received.updates The number of updated rows that have been downloaded so far.

  • received.deletes The number of deleted rows that have been downloaded so far.

  • received.bytes The number of bytes that have been downloaded so far.

  • stops Set this member to true to interrupt the synchronization. The SQL exception SQLE_INTERRUPTED is set, and the synchronization stops as if a communications error had occurred. The observer is always called with either the DONE or ERROR state so that it can do proper cleanup.

  • getUserData Returns the user data object.

  • getStatement Returns the statement that called the synchronization. The statement is an internal UltraLite statement, and this method is unlikely to be of practical use, but is included for completion.

  • getErrorCode When the synchronization state is set to ERROR, this method returns a diagnostic error code.

  • isOKToContinue This is set to false when cancelSynchronization is called. Otherwise, it is true.

Example

The following code illustrates a very simple observer function:

extern void __stdcall ObserverFunc(
    p_ul_synch_status status )
{
    printf( "UL_SYNCH_STATE is %d: ",
            status->state );
    switch( status->state ) {
        case UL_SYNCH_STATE_STARTING:
        printf( "Starting\n");
        break;
    case UL_SYNCH_STATE_CONNECTING:
        printf( "Connecting\n"  );
        break;
    case UL_SYNCH_STATE_SENDING_HEADER:
        printf( "Sending Header\n" );
        break;
    case UL_SYNCH_STATE_SENDING_TABLE:
        printf( "Sending Table %d of %d\n",
                status->tableIndex + 1,
                status->tableCount );
        break;
...

This observer produces the following output when synchronizing two tables:

UL_SYNCH_STATE is 0: Starting
UL_SYNCH_STATE is 1: Connecting
UL_SYNCH_STATE is 2: Sending Header
UL_SYNCH_STATE is 3: Sending Table 1 of 2
UL_SYNCH_STATE is 3: Sending Table 2 of 2
UL_SYNCH_STATE is 4: Receiving Upload Ack
UL_SYNCH_STATE is 5: Receiving Table 1 of 2
UL_SYNCH_STATE is 5: Receiving Table 2 of 2
UL_SYNCH_STATE is 6: Sending Download Ack
UL_SYNCH_STATE is 7: Disconnecting
UL_SYNCH_STATE is 8: Done
CustDB example

An example of an observer function is included in the CustDB sample application. The implementation in CustDB provides a dialog that displays synchronization progress and allows the user to cancel synchronization. The user-interface component makes the observer function platform specific.

The CustDB sample code is in the Samples\UltraLite\CustDB subdirectory of your SQL Anywhere directory. The observer function is contained in the platform-specific subdirectories of the CustDB directory.


Building Static C++ API applications

This section covers the following subjects:

  • Generating UltraLite C++ classes.

  • Compiling and linking your application.

Some small sample applications are provided that include makefiles for compilation. These applications can be found in subdirectories of the Samples\UltraLite directory.


Generating UltraLite C++ classes

The generator generates table classes from publications in the database, and query classes from any SQL statements added with the ul_add_statement stored procedure, writing the output to the following files:

  • filename.hpp This file contains the prototypes for the generated interface. You should inspect this file to determine the API you can use in your application.

  • filename.cpp This file contains the interface source. You do not need to look at this file.

  • filename.h This file contains internal definitions required by UltraLite. You do not need to look at this file.

  • Here, filename is the name supplied on the ulgen command line.

Whether you use queries in a project, publications, or a mix to define the classes in your application, you must generate all the code in a single run of the UltraLite generator.

toggle To generate UltraLite code for a publication

  • Run the UltraLite generator specifying the publication name with the -u command-line switch. For example:

    ulgen -c "uid=dba;pwd=sql" –t c++ -u pubName -f filename
toggle To generate UltraLite code for a UltraLite project

  • Run the UltraLite generator, specifying the project name with the –j command-line switch. For example:

    ulgen -c "uid=dba;pwd=sql" –t c++ -j projectname -f filename
toggle To generate UltraLite code for both a project and a publication

  • Run the UltraLite generator, specifying the project name and the publication name. For example:

    ulgen -c "uid=dba;pwd=sql" –t c++ -j projectname –u pubname -f filename

For more information on the UltraLite generator, see The UltraLite Generator.


Compiling and linking your application

When you compile your UltraLite application, you must ensure that the compiler can locate all the required files.

  • Generated source files You must included the generated files describing the API in your project. This includes the generated .cpp file, .h file, and .hpp file.

  • UltraLite header files You must configure your compiler so that it can locate the UltraLite header files.

    These header files are installed into the h directory under your Adaptive Server Anywhere installation directory.

  • UltraLite c file You must configure your linker so that it can locate the UltraLite API file ulapi.cpp.

    This file is installed into the src subdirectory of your Adaptive Server Anywhere installation directory.

  • Library or import library You must configure your compiler so that it can locate the UltraLite runtime library for your target platform or, in the case that you are using the UltraLite runtime DLL, the UltraLite imports library.

    These files are installed under the UltraLite subdirectory of your Adaptive Server Anywhere installation directory. Each target platform has a separated directory, and if there are different processors for a platform, each has its own subdirectory.

For a sample application that includes compilation options, see the files in Samples\UltraLite\apitutorial.


Developing Applications Using Embedded SQL

About this chapter

This chapter describes how to write data access code for embedded SQL UltraLite applications.

Before you begin

This chapter assumes an elementary familiarity with the UltraLite development process. For an overview, see Using UltraLite Static Interfaces.

For reference information, see Embedded SQL API Reference.

For detailed information about the SQL preprocessor, see The SQL preprocessor.

Introduction
Initializing the SQL Communications Area
Connecting to a database
Using host variables
Fetching data
Authenticating users
Encrypting data
Adding synchronization to your application
Building embedded SQL applications


Introduction

The following is a very simple embedded SQL program. It updates the surname of employee 195 and commits the change.

#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;
   EXEC SQL DISCONNECT;
   db_fini( &sqlca );
   return( 0 );
   error:
      printf( "update unsuccessful: sqlcode = %ld\n",
         sqlca.sqlcode );
      return( -1 );
}

Although too simple to be useful, this example demonstrates the following aspects common to all embedded SQL applications:

  • Each SQL statement is prefixed with the keywords EXEC SQL.

  • Each SQL statement ends with a semicolon.

  • Some embedded SQL statements are not found in standard SQL. The INCLUDE SQLCA statement is one example.

  • Embedded SQL provides library functions to perform some specific tasks. The functions db_init and db_fini are examples.

Before working with data

The above example demonstrates the necessary initialization statements. You must include these before working with the data in any database.

  1. You must define the SQL communications area, sqlca, using the following command.

    EXEC SQL INCLUDE SQLCA;

    This definition must be your first embedded SQL statement, so a natural place for it is the end of your include list.

    If you have multiple .sqc files in your application, each file must have this line.

  2. Your first executable database action must be a call to an embedded SQL library function named db_init. This function initializes the UltraLite runtime library. Only embedded SQL definition statements can be executed before this call.

    For more information, see db_init function.

  3. You must use the CONNECT statement to connect to your database.

Preparing to exit

This example also demonstrates the sequence of calls you must make when preparing to exit.

  1. Commit or rollback any outstanding changes.

  2. Disconnect from the database.

  3. End your SQL work with a call to a library function named db_fini.

If you leave changes to the database uncommitted when you exit, any uncommitted operations are automatically rolled back.

Error handling

There is virtually no interaction between the SQL and C code in this example. The C code only controls flow. The WHENEVER statement is used for error checking. The error action, GOTO in this example, is executed after any SQL statement causes an error.

Structure of embedded SQL programs


Structure of embedded SQL programs

All embedded SQL statements start with the words EXEC SQL and end with a semicolon (;). Normal C-language comments are allowed in the middle of embedded SQL statements.

Every C program using embedded SQL must contain the following statement before any other embedded SQL statements in the source file.

EXEC SQL INCLUDE SQLCA;

The first embedded SQL executable statement executed in any program must be a CONNECT statement. If you are not including UltraLite user authentication in your application, this CONNECT statement is ignored.

For information about UltraLite user authentication in embedded SQL applications, see Authenticating users, and User authentication in UltraLite.

Some embedded SQL commands do not generate any executable C code, or do not involve communication with the database. Only these commands are allowed before the CONNECT statement. Most notable are the INCLUDE statement and the WHENEVER statement for specifying error processing.


Initializing the SQL Communications Area

The SQL Communication Area (SQLCA) is an area of memory that is used for communicating statistics and errors from the application to the database and back to the application. The SQLCA is used as a handle for the application-to-database communication link. It is passed explicitly to all database library functions that communicate with the database. It is implicitly passed in all embedded SQL statements.

UltraLite defines a global SQLCA variable for you in the generated code. The preprocessor generates an external reference for the global SQLCA variable. The external reference is named sqlca and is of type SQLCA. The actual global variable is declared in the imports library.

The SQLCA type is defined by the sqlca.h header file, which is located in the h subdirectory of your installation directory.

After declaring the SQLCA (EXEC SQL INCLUDE SQLCA;) but before your application can carry out any operations on a database, it must initialize the communications area by calling db_init and passing it the SQLCA:

db_init( &sqlca );
SQLCA provides error codes

You reference the SQLCA to test for a particular error code. The sqlcode field contains an error code when a database request causes an error (see below). Some C macros are defined for referencing the sqlcode field and some other fields.

SQLCA fields


SQLCA fields

The fields in the SQLCA have the following meanings:

  • sqlcaid An 8-byte character field that contains the string SQLCA as an identification of the SQLCA structure. This field helps in debugging when you are looking at memory contents.

  • sqlcabc A long integer that contains the length of the SQLCA structure (136 bytes).

  • sqlcode A long integer that specifies the error code when the database detects an error on a request. Definitions for the error codes can be found in the header file sqlerr.h. The error code is 0 (zero) for a successful operation, positive for a warning and negative for an error.

    You can access this field directly using the SQLCODE macro.

    For a list of error codes, see ASA Error Messages.

  • sqlerrml The length of the information in the sqlerrmc field.

    UltraLite applications do not use this field.

  • sqlerrmc May contain one or more character strings to be inserted into an error message. Some error messages contain a placeholder string (%1) which is replaced with the text in this field.

    UltraLite applications do not use this field.

  • sqlerrp Reserved.

  • sqlerrd A utility array of long integers.

  • sqlwarn Reserved.

    UltraLite applications do not use this field.

  • sqlstate The SQLSTATE status value.

    UltraLite applications do not use this field.


Connecting to a database

To connect to an UltraLite database from an embedded SQL application, include the EXEC SQL CONNECT statement in your code after initializing the SQLCA.

The CONNECT statement takes one of the following two forms:

EXEC SQL CONNECT "user-name" IDENTIFIED BY "password";

EXEC SQL CONNECT
USING "uid=user-name;pwd=password;dbf=database-filename";

The first syntax assumes that the startup parameters are supplied in UL_STORE_PARMS. For more information, see UL_STORE_PARMS macro.

The second syntax ignores settings in UL_STORE_PARMS and supplies the database startup parameters explicitly (specifically the filename).

For more information on the CONNECT statement, see CONNECT statement [ESQL] [Interactive SQL].

Managing multiple connections


Managing multiple connections

If you want more than one database connection in your application, you can either use multiple SQLCAs or you can use a single SQLCA to manage the connections.

toggle To manage multiple SQLCAs in your application

  1. Each SQLCA used in your program must be initialized with a call to db_init and cleaned up at the end with a call to db_fini.

    For more information, see db_init function.

  2. The embedded SQL statement SET SQLCA is used to tell the SQL preprocessor to use a different SQLCA for database requests. Usually, a statement such as the following:

    EXEC SQL SET SQLCA 'task_data->sqlca';

    is used at the top of your program or in a header file to set the SQLCA reference to point at task specific data. This statement does not generate any code and thus has no performance impact. It changes the state within the preprocessor so that any reference to the SQLCA will use the given string.

    For information about creating SQLCAs, see SET SQLCA statement [ESQL].

Using a single SQLCA

As an alternative to using multiple SQLCAs, you can use a single SQLCA to manage more than one connection to a database.

Each SQLCA has a single active or current connection, but that connection can be changed. Before executing a command, use the SET CONNECTION statement to specify the connection on which the command should be executed.

For more information, see SET CONNECTION statement [Interactive SQL] [ESQL].


Using host variables

Embedded SQL applications use host variables to send values to the database or receive values from the database. Host variables are C variables that are identified to the SQL preprocessor.

Declaring host variables
Data types in embedded SQL
Host variable usage
The scope of host variables
Using expressions as host variables
Using host variables in C++
Using indicator variables


Declaring host variables

You can define host variables by placing them within a declaration section. Host variables are declared by surrounding the normal C variable declarations with BEGIN DECLARE SECTION and END DECLARE SECTION statements.

Whenever you use a host variable in a SQL statement, you must prefix the variable name with a colon (:) so that the SQL preprocessor can distinguish it from other identifiers allowed in the statement.

You can use host variables in place of value constants in any SQL statement. When the database server executes the command, the value of the host variable is read from or written to each host variable. Host variables cannot be used in place of table or column names.

The SQL preprocessor does not scan C language code except inside a declaration section. Initializers for variables are allowed inside a declaration section, while typedef types and structures are not permitted.

Example

The following sample code illustrates the use of host variables with an INSERT command. The variables are filled in by the program and then inserted into the database:

/* Declare fields for personal data. */
EXEC SQL BEGIN DECLARE SECTION;
   long employee_number = 0;
   char employee_name[50];
   char employee_initials[8];
   char employee_phone[15];
EXEC SQL END DECLARE SECTION;
/* Fill variables with appropriate values. */
/* Insert a row in the database. */
EXEC SQL INSERT INTO Employee
   VALUES (:employee_number, :employee_name,
      :employee_initials, :employee_phone );


Data types in embedded SQL

To transfer information between a program and the database server, every piece of data must have a data type. You can create a host variable with any one of the supported types.

Only a limited number of C data types are supported as host variables. Also, certain host variable types do not have a corresponding C type.

Macros defined in the sqlca.h header file can be used to declare a host variable of type VARCHAR, FIXCHAR, BINARY, DECIMAL, or SQLDATETIME. These macros are used as follows:

EXEC SQL BEGIN DECLARE SECTION;
   DECL_VARCHAR( 10 ) v_varchar;
   DECL_FIXCHAR( 10 ) v_fixchar;
   DECL_BINARY( 4000 ) v_binary;
   DECL_DECIMAL( 10, 2 ) v_packed_decimal;
   DECL_DATETIME v_datetime;
EXEC SQL END DECLARE SECTION;

The preprocessor recognizes these macros within a declaration section and treats the variable as the appropriate type.

The following data types are supported by the embedded SQL programming interface:

  • 16-bit signed integer.

    short int i;
unsigned short int i;

  • 32-bit signed integer.

    long int l;
unsigned long int l;

  • 4-byte floating point number.

    float f;

  • 8-byte floating point number.

    double d;

  • Packed decimal number.

    DECL_DECIMAL(p,s)
typedef struct TYPE_DECIMAL {
   char array[1];
} TYPE_DECIMAL;

  • NULL-terminated blank-padded character string.

    char a[n]; /* n > 1 */
char *a; /* n = 2049 */

    Because the C-language array must also hold the NULL terminator, a char a[n] data type maps to a CHAR(n – 1) SQL data type, which can hold n – 1 characters.

    Pointers to char, WCHAR, TCHAR
    The SQL preprocessor assumes that a pointer to char points to a character array of size 2049 bytes and that this array can safely hold 2048 characters, plus the NULL terminator. In other words, a char* data type maps to a CHAR(2048) SQL type. If that is not the case, your application may corrupt memory. If you are using a 16-bit compiler, requiring 2049 bytes can make the program stack overflow. Instead, use a declared array, even as a parameter to a function, to let the SQL preprocessor know the size of the array. WCHAR and TCHAR behave similarly to char.

  • NULL terminated UNICODE or wide character string.

    Each character occupies two bytes of space and so may contain UNICODE characters.

    WCHAR a[n]; /* n > 1 */

  • NULL terminated system-dependent character string.

    A TCHAR is equivalent to a WCHAR for systems that use UNICODE (for example, Windows CE) for their character set; otherwise, a TCHAR is equivalent to a char. The TCHAR data type is designed to support character strings in either kind of system automatically.

    TCHAR a[n]; /* n > 1 */

  • Fixed-length blank padded character string.

    char a; /* n  = 1 */
DECL_FIXCHAR(n) a; /* n >= 1 */

  • Variable-length character string with a two-byte length field.

    When supplying information to the database server, you must set the length field. When fetching information from the database server, the server sets the length field (not padded).

    DECL_VARCHAR(n) a; /* n >= 1 */
typedef struct VARCHAR {
   unsigned short int len;
   TCHAR array[1];
} VARCHAR;

  • Variable-length binary data with a two-byte length field.

    When supplying information to the database server, you must set the length field. When fetching information from the database server, the server sets the length field.

    DECL_BINARY(n) a; /* n >= 1 */
typedef struct BINARY {
   unsigned short int len;
   unsigned char array[1];
} BINARY;

  • SQLDATETIME structure with fields for each part of a timestamp.

    DECL_DATETIME a;
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;

    The SQLDATETIME structure can be used to retrieve fields of DATE, TIME, and TIMESTAMP type (or anything that can be converted to one of these). Often, applications have their own formats and date manipulation code. Fetching data in this structure makes it easier for a programmer to manipulate this data. Note that DATE, TIME and TIMESTAMP fields can also be fetched and updated with any character type.

    If you use a SQLDATETIME structure to enter a date, time, or timestamp into the database via, the day_of_year and day_of_week members are ignored.

    For more information, see the DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT, and DATE_ORDER database options in Database Options. While these options cannot be set during execution of an UltraLite program, their values are identical to the settings in the reference database used to generate the program.

  • DT_LONGVARCHAR Long varying length character data. The macro defines a structure, as follows:

    #define DECL_LONGVARCHAR( size )         \
  struct { a_sql_uint32    array_len;    \
           a_sql_uint32    stored_len;   \
           a_sql_uint32    untrunc_len;  \
           char            array[size+1];\
         }

    The DECL_LONGVARCHAR struct may be used with more than 32K of data. Large data may be fetched all at once, or in pieces using the GET DATA statement. Large data may be supplied to the server all at once, or in pieces by appending to a database variable using the SET statement. The data is not null terminated.

    typedef struct BINARY {
  unsigned short int len;
  char array[1];
} BINARY;

  • DT_LONGBINARY Long binary data. The macro defines a structure, as follows:

    #define DECL_LONGBINARY( size )          \
  struct { a_sql_uint32    array_len;    \
           a_sql_uint32    stored_len;   \
           a_sql_uint32    untrunc_len;  \
           char            array[size];  \
         }

    The DECL_LONGBINARY struct may be used with more than 32K of data. Large data may be fetched all at once, or in pieces using the GET DATA statement. Large data may be supplied to the server all at once, or in pieces by appending to a database variable using the SET statement.

The structures are defined in the sqlca.h file. The VARCHAR, BINARY, and TYPE_DECIMAL types contain a one-character array and are thus not useful for declaring host variables, but they are useful for allocating variables dynamically or typecasting other variables.

DATE and TIME database types

There are no corresponding embedded SQL interface data types for the various DATE and TIME database types. These database types are fetched and updated either using the SQLDATETIME structure or using character strings.

There are no embedded SQL interface data types for LONG VARCHAR and LONG BINARY database types.


Host variable usage

Host variables can be used in the following circumstances:

  • In a SELECT, INSERT, UPDATE, or DELETE statement in any place where a number or string constant is allowed.

  • In the INTO clause of a SELECT or FETCH statement.

  • In CONNECT, DISCONNECT, and SET CONNECT statements, a host variable can be used in place of a user ID, password, connection name, or database environment name.

Host variables can never be used in place of a table name or a column name.


The scope of host variables

A host-variable declaration section can appear anywhere that C variables can normally be declared, including the parameter declaration section of a C function. The C variables have their normal scope (available within the block in which they are defined). However, since the SQL preprocessor does not scan C code, it does not respect C blocks.

The preprocessor assumes all host variables are global

As far as the SQL preprocessor is concerned, host variables are globally known in the source module following their declaration. Two host variables cannot have the same name. The only exception to this rule is that two host variables can have the same name if they have identical types (including any necessary lengths).

The best practice is to give each host variable a unique name.

Examples

  • Because the SQL preprocessor can not parse C code, it assumes that all host variables, no matter where they are declared, are known globally following their declaration.

    // Example demonstrating poor coding
EXEC SQL BEGIN DECLARE SECTION;
   long emp_id;
EXEC SQL END DECLARE SECTION;
long getManagerID( void )
{
   EXEC SQL BEGIN DECLARE SECTION;
      long manager_id = 0;
   EXEC SQL END DECLARE SECTION;
   EXEC SQL SELECT manager_id
            INTO :manager_id
            FROM employee
            WHERE emp_number = :emp_id;
   return( manager_number );
}
void setManagerID( long manager_id )
{
   EXEC SQL UPDATE employee
            SET manager_number = :manager_id
            WHERE emp_number = :emp_id;
}

Although it works, the above code is confusing because the SQL preprocessor relies on the declaration inside getManagerID when processing the statement within setManagerID. You should rewrite this code as follows.

// Rewritten example
#if 0
   // Declarations for the SQL preprocessor
   EXEC SQL BEGIN DECLARE SECTION;
      long emp_id;
      long manager_id;
   EXEC SQL END DECLARE SECTION;
#endif
long getManagerID( long emp_id )
{
   long manager_id = 0;
   EXEC SQL SELECT manager_id
            INTO :manager_id
            FROM employee
            WHERE emp_number = :emp_id;
   return( manager_number );
}
void setManagerID( long emp_id, long manager_id )
{
   EXEC SQL UPDATE employee
            SET manager_number = :manager_id
            WHERE emp_number = :emp_id;
}

The SQL preprocessor sees the declaration of the host variables contained within the #if directive because it ignores these directives. On the other hand, it ignores the declarations within the procedures because they are not inside a DECLARE SECTION. Conversely, the C compiler ignores the declarations within the #if directive and uses those within the procedures.

These declarations work only because variables having the same name are declared to have exactly the same type.


Using expressions as host variables

Because host variables must be simple names, the SQL preprocessor does not recognize pointer or reference expressions. For example, the following statement does not work because the SQL preprocessor does not understand the dot operator. The same syntax has a different meaning in SQL.

// Incorrect statement:
EXEC SQL SELECT LAST sales_id INTO :mystruct.mymember;

Although the above syntax is not allowed, you can still use an expression with the following technique:

  • Wrap the SQL declaration section in an #if 0 preprocessor directive. The SQL preprocessor will read the declarations and use them for the rest of the module because it ignores preprocessor directives.

  • Define a macro with the same name as the host variable. Since the SQL declaration section is not seen by the C compiler because of the #if directive, no conflict will arise. Ensure that the macro evaluates to the same type host variable.

The following code demonstrates this technique to hide the host_value expression from the SQL preprocessor.

EXEC SQL INCLUDE SQLCA;
#include <sqlerr.h>
#include <stdio.h>
typedef struct my_struct {
   long     host_field;
} my_struct;
#if 0
   // Because it ignores #if preprocessing directives,
   // SQLPP reads the following declaration.
   EXEC SQL BEGIN DECLARE SECTION;
      long    host_value;
   EXEC SQL END DECLARE SECTION;
#endif
// Make C/C++ recognize the 'host_value' identifier
// as a macro that expands to a struct field.
#define host_value my_s.host_field

Since the SQLPP processor ignores directives for conditional compilation, host_value is treated as a long host variable and will emit that name when it is subsequently used as a host variable. The C/C++ compiler processes the emitted file and will substitute my_s.host_field for all such uses of that name.

With the above declarations in place, you can proceed to access host_field as follows.

void main( void )
{
   my_struct      my_s;
   db_init( &sqlca );
   EXEC SQL CONNECT "DBA" IDENTIFIED BY "SQL";
   EXEC SQL DECLARE my_table_cursor CURSOR FOR
      SELECT int_col FROM my_table order by int_col;
   EXEC SQL OPEN my_table_cursor;
   for( ; ; ) {
      // :host_value references my_s.host_field
      EXEC SQL FETCH NEXT AllRows INTO :host_value;
      if( SQLCODE == SQLE_NOTFOUND ) {
         break;
      }
      printf( "%ld\n", my_s.host_field );
   }
   EXEC SQL CLOSE my_table_cursor;
   EXEC SQL DISCONNECT;
   db_fini( &sqlca );
}

You can use the same technique to use other lvalues as host variables.

  • pointer indirections

    *ptr
p_struct->ptr
(*pp_struct)->ptr

  • array references

    my_array[ i ]

  • arbitrarily complex lvalues


Using host variables in C++

A similar situation arises when using host variables within C++ classes. It is frequently convenient to declare your class in a separate header file. This header file might contain, for example, the following declaration of my_class.

typedef short a_bool;
#define  TRUE  ((a_bool)(1==1))
#define  FALSE ((a_bool)(0==1))
public class {
   long  host_member;
   my_class();    // Constructor
   ~my_class();      // Destructor
   a_bool FetchNextRow( void );
      // Fetch the next row into host_member
} my_class;

In this example, each method is implemented in an embedded SQL source file. Only simple variables can be used as host variables. The technique introduced in the preceding section can be used to access a data member of a class.

EXEC SQL INCLUDE SQLCA;
#include "my_class.hpp"
#if 0
   // Because it ignores #if preprocessing directives,
   // SQLPP reads the following declaration.
   EXEC SQL BEGIN DECLARE SECTION;
      long  this_host_member;
   EXEC SQL END DECLARE SECTION;
#endif
// Macro used by the C++ compiler only.
#define this_host_member this->host_member
my_class::my_class()
{
   EXEC SQL DECLARE my_table_cursor CURSOR FOR
      SELECT int_col FROM my_table order by int_col;
   EXEC SQL OPEN my_table_cursor;
}
my_class::~my_class()
{
   EXEC SQL CLOSE my_table_cursor;
}
a_bool my_class::FetchNextRow( void )
{
   // :this_host_member references this->host_member
   EXEC SQL FETCH NEXT AllRows INTO :this_host_member;
   return( SQLCODE != SQLE_NOTFOUND );
}
void main( void )
{
   db_init( &sqlca );
   EXEC SQL CONNECT "DBA" IDENTIFIED BY "SQL";
   {
      my_class mc; // Created after connecting.
      while( mc.FetchNextRow() ) {
         printf( "%ld\n", mc.host_member );
      }
   }
   EXEC SQL DISCONNECT;
   db_fini( &sqlca );
}

The above example declares this_host_member for the SQL preprocessor, but the macro causes C++ to convert it to this->host_member. The preprocessor would otherwise not know the type of this variable. Many C/C++ compilers do not tolerate duplicate declarations. The #if directive hides the second declaration from the compiler, but leaves it visible to the SQL preprocessor.

While multiple declarations can be useful, you must ensure that each declaration assigns the same variable name to the same type. The preprocessor assumes that each host variable is globally known following its declaration because it can not fully parse the C language.


Using indicator variables

An indicator variable is a C variable that holds supplementary information about a particular host variable. You can use a host variable when fetching or putting data. Use indicator variables to handle NULL values.

An indicator variable is a host variable of type short int. To detect or specify a NULL value, place the indicator variable immediately following a regular host variable in a SQL statement.

Example

  • For example, in the following INSERT statement, :ind_phone is an indicator variable.

    EXEC SQL INSERT INTO Employee
   VALUES (:employee_number, :employee_name,
   :employee_initials, :employee_phone:ind_phone );
Indicator variable values

The following table provides a summary of indicator variable usage.

Indicator Value | Supplying Value to database | Receiving value from database
0 | Host variable value | Fetched a non-NULL value.
–1 | NULL value | Fetched a NULL value

Using indicator variables to handle NULL


Using indicator variables to handle NULL

Do not confuse the SQL concept of NULL with the C-language constant of the same name. In the SQL language, NULL represents either an unknown attribute or inapplicable information. The C-language constant represents a pointer value which does not point to a memory location.

When NULL is used in the Adaptive Server Anywhere documentation, it refers to the SQL database meaning given above. The C language constant is referred to as the null pointer (lower case).

NULL is not the same as any value of the column's defined type. Thus, in order to pass NULL values to the database or receive NULL results back, you require something beyond regular host variables. Indicator variables serve this purpose.

Using indicator variables when inserting NULL

An INSERT statement can include an indicator variable as follows:

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;
/* set values of empnum, empname,
   initials, and homephone */
if( /* phone number is known */ ) {
   ind_phone =  0;
} else {
   ind_phone = -1; /* NULL */
}
EXEC SQL INSERT INTO Employee
   VALUES (:employee_number, :employee_name,
   :employee_initials, :employee_phone:ind_phone );

If the indicator variable has a value of –1, a NULL is written. If it has a value of 0, the actual value of employee_phone is written.

Using indicator variables when fetching NULL

Indicator variables are also used when receiving data from the database. They are used to indicate that a NULL value was fetched (indicator is negative). If a NULL value is fetched from the database and an indicator variable is not supplied, the SQLE_NO_INDICATOR error is generated.

Errors and warnings are returned in the SQLCA structure, as described in Initializing the SQL Communications Area.


Fetching data

Fetching data in embedded SQL is done using the SELECT statement. There are two cases:

  1. The SELECT statement returns at most one row.

  2. The SELECT statement may return multiple rows.


Fetching one row

A single row query retrieves at most one row from the database. A single-row query SELECT statement may have an INTO clause following the select list and before the FROM clause. The INTO clause contains a list of host variables to receive the value for each select list item. There must be the same number of host variables as there are select list items. The host variables may be accompanied by indicator variables to indicate NULL results.

When the SELECT statement is executed, the database server retrieves the results and places them in the host variables.

  • If the query selects more than one row, the database server returns the SQLE_TOO_MANY_RECORDS error.

  • If the query selects no rows, the SQLE_NOTFOUND warning is returned.

Errors and warnings are returned in the SQLCA structure, as described in Initializing the SQL Communications Area.

Example

For example, the following code fragment returns 1 if a row from the employee table is successfully fetched, 0 if the row doesn't exist, and –1 if an error occurs.

EXEC SQL BEGIN DECLARE SECTION;
   long int    emp_id;
   char        name[41];
   char        sex;
   char        birthdate[15];
   short int   ind_birthdate;
EXEC SQL END DECLARE SECTION;
int find_employee( long employee )
{
   emp_id = employee;
   EXEC SQL SELECT emp_fname || ' ' || emp_lname,
         sex, birth_date
      INTO :name, :sex, birthdate:ind_birthdate
      FROM "DBA".employee
      WHERE emp_id = :emp_id;
   if( SQLCODE == SQLE_NOTFOUND ) {
      return( 0 ); /* employee not found */
   } else if( SQLCODE < 0 ) {
      return( -1 ); /* error */
   } else {
      return( 1 ); /* found */
   }
}


Fetching multiple rows

You use a cursor to retrieve rows from a query that has multiple rows in its result set. A cursor is a handle or an identifier for the SQL query result set and a position within that result set.

For an introduction to cursors, see Working with cursors.

toggle To manage a cursor in embedded SQL

  1. Declare a cursor for a particular SELECT statement, using the DECLARE statement.

  2. Open the cursor using the OPEN statement.

  3. Retrieve rows from the cursor one at a time using the FETCH statement.

    • Fetch rows until the SQLE_NOTFOUND warning is returned.

      Error and warning codes are returned in the variable SQLCODE, defined in the SQL communications area structure.

  4. Close the cursor, using the CLOSE statement.

Cursors in UltraLite applications are always opened using the WITH HOLD option. They are never closed automatically. You must close each cursor explicitly using the CLOSE statement.

The following is a simple example of cursor usage:

void print_employees( void )
{
   int status;
   EXEC SQL BEGIN DECLARE SECTION;
   char name[50];
   char sex;
   char birthdate[15];
   short int ind_birthdate;
   EXEC SQL END DECLARE SECTION;
   /* 1. Declare the cursor. */
   EXEC SQL DECLARE C1 CURSOR FOR
      SELECT emp_fname || ' ' || emp_lname,
               sex, birth_date
      FROM "DBA".employee
      ORDER BY emp_fname, emp_lname;
   /* 2. Open the cursor. */
   EXEC SQL OPEN C1;
   /* 3. Fetch each row from the cursor. */
   for( ;; ) {
      EXEC SQL FETCH C1 INTO :name, :sex,
            :birthdate:ind_birthdate;
      if( SQLCODE == SQLE_NOTFOUND ) {
         break; /* no more rows */
      } else if( SQLCODE < 0 ) {
         break; /* the FETCH caused an error */
      }
      if( ind_birthdate < 0 ) {
         strcpy( birthdate, "UNKNOWN" );
      }
      printf( "Name: %s Sex: %c Birthdate:
               %s\n",name, sex, birthdate );
   }
   /* 4. Close the cursor. */
   EXEC SQL CLOSE C1;
}

For details of the FETCH statement, see FETCH statement [ESQL] [SP].

Cursor positioning

A cursor is positioned in one of three places:

  • On a row

  • Before the first row

  • After the last row

Cursors can be positioned before the first row, after the last row, or on a row. When counting from the start, position 0 is before the first row. When counting from the end, position 0 is after the last row.
Order of the rows in a cursor

You control the order of rows in a cursor by including an ORDER BY clause in the SELECT statements that defines that cursor. If you omit this clause, the order of the rows is unpredictable.

If you don't explicitly define an order, your only guarantee is that fetching repeatedly will return each row in the result set once and only once before SQLE_NOTFOUND is returned.

Order of rows in a cursor
If the cursor must have a specific order, include an ORDER BY clause in the SELECT statement in the cursor definition. Without this clause, the ordering is unpredictable and can vary from one time to the next.
Repositioning a cursor

When you open a cursor, it is positioned before the first row. The FETCH statement automatically advances the cursor position. An attempt to FETCH beyond the last row results in an SQLE_NOTFOUND error, which can be used as a convenient signal to complete sequential processing of the rows.

You can also reposition the cursor to an absolute position relative to the start or the end of the query results, or move it relative to the current cursor position. There are special positioned versions of the UPDATE and DELETE statements that can be used to update or delete the row at the current position of the cursor. If the cursor is positioned before the first row or after the last row, an SQLE_NOTFOUND error is returned.

To avoid unpredictable results when using explicit positioning, you can include an ORDER BY clause in the SELECT statement that defines the cursor.

You can use the PUT statement to insert a row into a cursor.

Cursor positioning after updates

After updating any information that is being accessed by an open cursor, it is best to fetch and display the rows again. If the cursor is being used to display a single row, FETCH RELATIVE 0 will re-fetch the current row. When the current row has been deleted, the next row will be fetched from the cursor (or SQLE_NOTFOUND is returned if there are no more rows).

When a temporary table is used for the cursor, inserted rows in the underlying tables do not appear at all until that cursor is closed and reopened. It is difficult for most programmers to detect whether or not a temporary table is involved in a SELECT statement without examining the code generated by the SQL preprocessor or by becoming knowledgeable about the conditions under which temporary tables are used. Temporary tables can usually be avoided by having an index on the columns used in the ORDER BY clause.

For more information about temporary tables, see Use of work tables in query processing.

Inserts, updates and deletes to non-temporary tables may affect the cursor positioning. Because UltraLite materializes cursor rows one at a time (when temporary tables are not used), the data from a freshly inserted row (or the absence of data from a freshly deleted row) may affect subsequent FETCH operations. In the simple case where (parts of) rows are being selected from a single table, an inserted or updated row will appear in the result set for the cursor when it satisfies the selection criteria of the SELECT statement. Similarly, a freshly deleted row that previously contributed to the result set will no longer be within it.


Authenticating users

New users have to be added from an existing connection. As all UltraLite databases are created with a default user ID and password of DBA and SQL, respectively, you must first connect as this initial user.

You cannot change a user ID. Instead, you add a user and delete an existing user. A maximum of four user IDs are permitted for each UltraLite database.

For more information, see User authentication in UltraLite.

For the static interfaces, you must enable the user authentication feature before you can add or delete users or change passwords. On Palm OS, if you wish to authenticate users whenever they return to an application from some other application, you must include the prompt for user and password information in your PilotMain routine.

toggle To enable user authentication (embedded SQL)

  • Call ULEnableUserAuthentication before calling db_init. For example:

    app(){
   ...
   ULEnableUserAuthentication( &sqlca );
   db_init( &sqlca );
   ...

    The call to db_init precedes all other database activity in the application.

The following code performs user management and authentication for an embedded SQL UltraLite application.

User authentication example

A complete sample can be found in the Samples\UltraLite\esqlauth subdirectory of your SQL Anywhere directory. The code below is taken from Samples\UltraLite\esqlauth\sample.sqc.

//Embedded SQL
app() {
   ...
/* Declare fields */
   EXEC SQL BEGIN DECLARE SECTION;
      char uid[31];
      char pwd[31];
   EXEC SQL END DECLARE SECTION;
   ULEnableUserAuthentication( &sqlca );
   db_init( &sqlca );
   ...
   EXEC SQL CONNECT "DBA" IDENTIFIED BY "SQL";
   if( SQLCODE == SQLE_NOERROR ) {
      printf("Enter new user ID and password\n" );
      scanf( "%s %s", uid, pwd );
      ULGrantConnectTo( &sqlca,
         UL_TEXT( uid ), UL_TEXT( pwd ) );
      if( SQLCODE == SQLE_NOERROR ) {
         // new user added: remove DBA
         ULRevokeConnectFrom( &sqlca, UL_TEXT("DBA") );
      }
      EXEC SQL DISCONNECT;
   }
   // Prompt for password
    printf("Enter user ID and password\n" );
    scanf( "%s %s", uid, pwd );
    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;

The code carries out the following tasks:

  1. Enable user authentication by calling ULEnableUserAuthentication.

  2. Initiate database functionality by calling db_init.

  3. Attempt to connect using the default user ID and password.

  4. If the connection attempt is successful, add a new user.

  5. If the new user is successfully added, delete the DBA user from the UltraLite database.

  6. Disconnect. An updated user ID and password is now added to the database.

  7. Connect using the updated user ID and password.

For more information, see ULGrantConnectTo function, and ULRevokeConnectFrom function.


Encrypting data

You can encrypt or obfuscate your UltraLite database using the UltraLite embedded SQL.

For background information, see Encrypting UltraLite databases,

Encryption

UltraLite databases are created on the first connection attempt. To encrypt an UltraLite database, you supply an encryption key before that connection attempt. On the first attempt, the supplied key is used to encrypt the database. On subsequent attempts, the supplied key is checked against the encryption key, and connection fails unless the key matches.

toggle To strongly encrypt an UltraLite database

  1. Load the encryption module.

    Call ULEnableStrongEncryption before opening the database.

    You open a database by calling db_init.

  2. Specify the encryption key.

    Define the UL_STORE_PARMS macro with the parameter name key.

    #define UL_STORE_PARMS "key=a secret key"

    As with most passwords, it is best to choose a key value that cannot be easily guessed. The key can be of arbitrary length, but generally the longer the key, the better because a shorter key is easier to guess than a longer one. As well, including a combination of numbers, letters, and special characters decreases the chances of someone guessing the key.

    Do not include semicolons in your key. Do not put the key itself in quotes, or the quotes will be considered part of the key.

    You must supply this key each time you want to start the database. Lost or forgotten keys result in completely inaccessible databases.

    For more information, see .

  3. Handle attempts to open an encrypted database with the wrong key.

    If an attempt is made to open an encrypted database and the wrong key is passed in, db_init returns ul_false and SQLCODE -840 is set.

Changing the encryption key

You can change the encryption key for a database. The application must already be connected to the database using the existing key before the change can be made.

toggle To change the encryption key on an UltraLite database

  • Call the ULChangeEncryptionKey function, supplying the new key as an argument.

    The application must already be connected to the database using the old key before this function is called.

    For more information, see ULChangeEncryptionKey function.

Obfuscation
toggle To obfuscate an UltraLite database

  • Define the UL_ENABLE_OBFUSCATION compiler directive when compiling the generated database.

    For more information, see UL_ENABLE_OBFUSCATION macro.


Adding synchronization to your application

Synchronization is a key feature of many UltraLite applications. This section describes how to add synchronization to your application.

The synchronization logic that keeps UltraLite applications up to date with the consolidated database is not held in the application itself. Synchronization scripts stored in the consolidated database, together with the MobiLink synchronization server and the UltraLite runtime library, control how changes are processed when they are uploaded and determines which changes are to be downloaded.

Overview

The specifics of each synchronization is controlled by a set of synchronization parameters. These parameters are gathered into a structure, which is then supplied as an argument in a function call to synchronize. The outline of the method is the same in each development model.

toggle To add synchronization to your application

  1. Initialize the structure that holds the synchronization parameters.

    For information, see Initializing the synchronization parameters.

  2. Assign the parameter values for your application.

    For information, see Network protocol options for UltraLite synchronization clients.

  3. Call the synchronization function, supplying the structure or object as argument.

    For information, see Invoking synchronization.

You must ensure that there are no uncommitted changes when you synchronize. For more information, see Commit all changes before synchronizing.

Synchronization parameters

Synchronization specifics are controlled through a set of synchronization parameters. For information on these parameters, see Network protocol options for UltraLite synchronization clients.

Initializing the synchronization parameters
Setting synchronization parameters
Invoking synchronization
Commit all changes before synchronizing
Adding initial data to your application
Handling synchronization communications errors
Monitoring and canceling synchronization


Initializing the synchronization parameters

The synchronization parameters are stored in a structure.

The members of the structure may not be well-defined on initialization. You must set your parameters to their initial values with a call to a special function. The synchronization parameters are defined in a structure declared in the UltraLite header file ulglobal.h.

For a complete list of synchronization parameters, see Synchronization parameters.

toggle To initialize the synchronization parameters (embedded SQL)

  • Call the ULInitSynchInfo function. For example:

    auto ul_synch_info synch_info;
ULInitSynchInfo( &synch_info );


Setting synchronization parameters

The following code initiates TCP/IP synchronization. The MobiLink user name is Betty Best, with password TwentyFour, the script version is default, and the MobiLink synchronization server is running on the host machine test.internal, on port 2439:

auto ul_synch_info synch_info;
ULInitSynchInfo( &synch_info );
synch_info.user_name = UL_TEXT("Betty Best");
synch_info.password = UL_TEXT("TwentyFour");
synch_info.version = UL_TEXT("default");
synch_info.stream = ULSocketStream();
synch_info.stream_parms =
   UL_TEXT("host=test.internal;port=2439");
ULSynchronize( &sqlca, &synch_info );

The following code for an application on the Palm Computing Platform is called when the user exits the application. It allows HotSync synchronization to take place, with a MobiLink user name of 50, an empty password, a script version of custdb. The HotSync conduit communicates over TCP/IP with a MobiLink synchronization server running on the same machine as the conduit (localhost), on the default port (2439):

auto ul_synch_info synch_info;
ULInitSynchInfo( &synch_info );
synch_info.name = UL_TEXT("Betty Best");
synch_info.version = UL_TEXT("default");
synch_info.stream = ULConduitStream();
synch_info.stream_parms =
   UL_TEXT("stream=tcpip;host=localhost");
ULSetSynchInfo( &sqlca, &synch_info );


Invoking synchronization

The details of how to invoke synchronization depends on your target platform and on the synchronization stream.

The synchronization process can only work if the device running the UltraLite application is able to communicate with the synchronization server. For some platforms, this means that the device needs to be physically connected by placing it in its cradle or by attaching it to a server computer using a cable. You need to add error handling code to your application in case the synchronization cannot be carried out.

toggle To invoke synchronization (TCP/IP, HTTP, or HTTPS streams)

  • Call ULInitSynchInfo to initialize the synchronization parameters, and call ULSynchronize to synchronize.

toggle To invoke synchronization (HotSync)

  • Call ULInitSynchInfo to initialize the synchronization parameters, and call ULSetSynchInfo to manage synchronization before exiting the application.

    For more information, see ULSetSynchInfo function.

The synchronization call requires a structure that holds a set of parameters describing the specifics of the synchronization. The particular parameters used depend on the stream.


Handling synchronization communications errors

The following code illustrates how to handle communications errors from embedded SQL applications:

 if( psqlca->sqlcode == SQLE_COMMUNICATIONS_ERROR ) {
     printf( "  Stream error information:\n"
             "    stream_id         = %d\t(ss_stream_id)\n"
             "    stream_context    = %d\t(ss_stream_context)\n"
             "    stream_error_code = %ld\t(ss_error_code)\n"
             "    error_string      = \"%s\"\n"
             "    system_error_code = %ld\n",
     (int)info.stream_error.stream_id,
     (int)info.stream_error.stream_context,
     (long)info.stream_error.stream_error_code,
     info.stream_error.error_string,
     (long)info.stream_error.system_error_code );

SQLE_COMMUNICATIONS_ERROR is the general error code for communications errors. More information about the specific error is supplied to your application in the members of the stream_error synchronization parameter.

To keep UltraLite small, the runtime reports numbers rather than messages. For information on what the numbers mean, see stream_error synchronization parameter.


Monitoring and canceling synchronization

This section describes how to monitor and cancel synchronization from UltraLite applications.

  • An API for monitoring synchronization progress and for canceling synchronization.

  • A progress indicator component that implements the interface, which you can add to your application.

Monitoring synchronization

  • Specify the name of your callback function in the observer member of the synchronization structure (ul_synch_info).

  • Call the synchronization function or method to start synchronization.

  • UltraLite calls your callback function called whenever the synchronization state changes. The following section describes the synchronization state.

The following code shows how this sequence of tasks can be implemented in an embedded SQL application:

ULInitSynchInfo( &info );
info.user_name = m_EmpIDStr;
...
//The info parameter of ULSynchronize() contains
// a pointer to the observer function
info.observer = ObserverFunc;
ULSynchronize( &sqlca, &info );

Handling synchronization status information


Handling synchronization status information

The callback function that monitors synchronization takes a ul_synch_status structure as parameter.

The ul_synch_status structure has the following members:

ul_synch_state    state;
ul_u_short        tableCount;
ul_u_short        tableIndex;
   struct {
      ul_u_long   bytes;
      ul_u_short  inserts;
      ul_u_short  updates;
      ul_u_short  deletes;
    }       sent;
    struct {
      ul_u_long   bytes;
      ul_u_short  inserts;
      ul_u_short  updates;
      ul_u_short  deletes;
    }       received;
p_ul_synch_info   info;
ul_bool           stop;

  • state One of the following states:

    • UL_SYNCH_STATE_STARTING No synchronization actions have yet been taken.

    • UL_SYNCH_STATE_CONNECTING The synchronization stream has been built, but not yet opened.

    • UL_SYNCH_STATE_SENDING_HEADER The synchronization stream has been opened, and the header is about to be sent.

    • UL_SYNCH_STATE_SENDING_TABLE A table is being sent.

    • UL_SYNCH_STATE_SENDING_DATA Schema information or data is being sent.

    • UL_SYNCH_STATE_FINISHING_UPLOAD The upload stage is completed and a commit is being carried out.

    • UL_SYNCH_STATE_RECEIVING_UPLOAD_ACK An acknowledgement that the upload is complete is being received.

    • UL_SYNCH_STATE_RECEIVING_TABLE A table is being received.

    • UL_SYNCH_STATE_SENDING_DATA Schema information or data is being received.

    • UL_SYNCH_STATE_COMMITTING_DOWNLOAD The download stage is completed and a commit is being carried out.

    • UL_SYNCH_STATE_SENDING_DOWNLOAD_ACK An acknowledgement that download is complete is being sent.

    • UL_SYNCH_STATE_DISCONNECTING The synchronization stream is about to be closed.

    • UL_SYNCH_STATE_DONE Synchronization has completed successfully.

    • UL_SYNCH_STATE_ERROR Synchronization has completed, but with an error.

      For a description of the synchronization process, see The synchronization process.

  • tableCount Returns the number of tables being synchronized. For each table there is a sending and receiving phase, so this number may be more than the number of tables being synchronized.

  • tableIndex The current table which is being uploaded or downloaded, starting at 0. This number may skip values when not all tables are being synchronized.

  • info A pointer to the ul_synch_info structure.

  • sent.inserts The number of inserted rows that have been uploaded so far.

  • sent.updates The number of updated rows that have been uploaded so far.

  • sent.deletes The number of deleted rows that have been uploaded so far.

  • sent.bytes The number of bytes that have been uploaded so far.

  • received.inserts The number of inserted rows that have been downloaded so far.

  • received.updates The number of updated rows that have been downloaded so far.

  • received.deletes The number of deleted rows that have been downloaded so far.

  • received.bytes The number of bytes that have been downloaded so far.

  • stop Set this member to true to interrupt the synchronization. The SQL exception SQLE_INTERRUPTED is set, and the synchronization stops as if a communications error had occurred. The observer is always called with either the DONE or ERROR state so that it can do proper cleanup.

  • getUserData Returns the user data object.

  • getStatement Returns the statement that called the synchronization. The statement is an internal UltraLite statement, and this method is unlikely to be of practical use, but is included for completion.

  • getErrorCode When the synchronization state is set to ERROR, this method returns a diagnostic error code.

  • isOKToContinue This is set to false when cancelSynchronization is called. Otherwise, it is true.

Example

The following code illustrates a very simple observer function:

extern void __stdcall ObserverFunc(
    p_ul_synch_status status )
{
    printf( "UL_SYNCH_STATE is %d: ",
            status->state );
    switch( status->state ) {
        case UL_SYNCH_STATE_STARTING:
        printf( "Starting\n");
        break;
    case UL_SYNCH_STATE_CONNECTING:
        printf( "Connecting\n"  );
        break;
    case UL_SYNCH_STATE_SENDING_HEADER:
        printf( "Sending Header\n" );
        break;
    case UL_SYNCH_STATE_SENDING_TABLE:
        printf( "Sending Table %d of %d\n",
                status->tableIndex + 1,
                status->tableCount );
        break;
...

This observer produces the following output when synchronizing two tables:

UL_SYNCH_STATE is 0: Starting
UL_SYNCH_STATE is 1: Connecting
UL_SYNCH_STATE is 2: Sending Header
UL_SYNCH_STATE is 3: Sending Table 1 of 2
UL_SYNCH_STATE is 3: Sending Table 2 of 2
UL_SYNCH_STATE is 4: Receiving Upload Ack
UL_SYNCH_STATE is 5: Receiving Table 1 of 2
UL_SYNCH_STATE is 5: Receiving Table 2 of 2
UL_SYNCH_STATE is 6: Sending Download Ack
UL_SYNCH_STATE is 7: Disconnecting
UL_SYNCH_STATE is 8: Done
CustDB example

An example of an observer function is included in the CustDB sample application. The implementation in CustDB provides a dialog that displays synchronization progress and allows the user to cancel synchronization. The user-interface component makes the observer function platform specific.

The CustDB sample code is in the Samples\UltraLite\CustDB subdirectory of your SQL Anywhere directory. The observer function is contained in the platform-specific subdirectories of the CustDB directory.


Building embedded SQL applications

This section describes a general build procedure for UltraLite embedded SQL applications. You can use a simpler modification if your application uses only a single .sqc file. For more information, see Single-file build procedure.

This section assumes a familiarity with the overall embedded SQL development model. For more information, see Using UltraLite Static Interfaces.

There are two build processes, depending on whether you have a single embedded SQL file or multiple embedded SQL files.


General build procedure

Sample code

You can find a makefile that uses this process in the Samples\UltraLite\ESQLSecurity directory. You require the separately-licensable transport-layer security option to build that sample.

For information on obtaining the transport-layer security option, see the card in your SQL Anywhere package or see [external link] http://www.sybase.com/detail?id=1015780.

Procedure

The following diagram depicts the procedure for building an UltraLite embedded SQL application. In addition to your source files, you need a reference database that contains the tables and indexes you wish to use in your application.

The UltraLite development process with multiple embedded SQL files
toggle To build an UltraLite embedded SQL application

  1. Start the Adaptive Server Anywhere personal database server, specifying your reference database.

  2. Run the SQL preprocessor on each embedded SQL source file.

    The SQL preprocessor is the sqlpp command-line utility. It carries out two functions in an UltraLite development project:

    • It preprocesses the embedded SQL files, producing C files to be compiled into your application.

    • It adds the SQL statements to the reference database, for use by the UltraLite generator.

    Caution sqlpp overwrites the output file without regard to its contents. Ensure that the output file name does not match the name of any of your source files. By default, sqlpp constructs the output file name by changing the suffix of your source file to .c. When in doubt, specify the output file name explicitly, following the name of the source file.

    Use the sqlpp -c command-line option to connect to the reference database and the -p command-line option to specify a project name. Use the same project name for each embedded SQL file in your project.

    For detailed information about the SQL preprocessor, see The SQL Preprocessor.

    For information about projects, see Creating an UltraLite project.

  3. Run the UltraLite generator.

    The generator analyzes information collected while pre-processing your embedded SQL files. It prepares extra code and writes out a new C source file. This step also relies on your reference database.

    Enter the following command at a command-prompt:

    ulgen -"c "connection-string" options

    where options depend on the specifics of your project.

    The UltraLite generator command line customizes its behavior. The following command-line switches are particularly important:

    • -c You must supply a connection string, to connect to the reference database.

      For information on Adaptive Server Anywhere connection strings, see Connection parameters.

    • -f Specify the output file name.

    • -j Specify the UltraLite project name.

    For more information on UltraLite generator options, see The UltraLite Generator.

  4. Compile each C or C++ source file for the target platform of your choice. Include

    • each C files generated by the SQL preprocessor,

    • the C file made by the UltraLite generator,

    • any additional C or C++ source files that comprise your application.

  5. Link all these object files, together with the UltraLite runtime library.

Example

  • Suppose that your project contains two embedded SQL source files, called store.sqc and display.sqc. You could give your project the name salesdb and process these two commands using the following commands. (Each command should be entered on a single line.)

    sqlpp -c "uid=dba;pwd=sql" -p salesdb store.sqc
sqlpp -c "uid=dba;pwd=sql" -p salesdb display.sqc

    These two commands generate the files store.c and display.c, respectively. In addition, they store information in the reference database for the UltraLite analyzer.


Single-file build procedure

This section assumes a familiarity with the overall embedded SQL development model. For more information, see Using UltraLite Static Interfaces.

You can use a simpler single-file build procedure if the following requirements are also met:

  • You are not using transport-layer security.

  • You do not wish to use publications for synchronization.

  • You do not need to specify an UltraLite project name.

  • You have more than one embedded SQL source file.

If these requirements are not all met, you must use the general build process. For instructions, see Building embedded SQL applications .

The following diagram depicts the single-file build procedure for UltraLite database applications. In addition to your source files, you need a reference database that contains the tables and indexes you wish to use in your application.

The UltraLite development process for embedded SQL applications.
toggle To build an UltraLite application (one embedded SQL file only)

  1. Start the Adaptive Server Anywhere personal database server, specifying your reference database.

  2. Preprocess the embedded SQL source file using the SQL preprocessor.

    The SQL preprocessor is the sqlpp command-line utility. The SQL preprocessor runs the UltraLite generator automatically and appends additional code to the generated C/C++ source file. This step relies on your reference database and on the database server.

    Use the sqlpp -c command-line option to connect to the reference database. In the single-file build procedure, do not specify a project on the SQL preprocessor command line.

    For a list of the parameters to sqlpp, see The SQL preprocessor.

  3. Compile the C or C++ source file for the target platform of your choice. Include

    • the C file generated by the SQL preprocessor,

    • any additional C/C++ source files that comprise your application.

  4. Link all these object files, together with the UltraLite runtime library.

Example

  • Your application contains only one embedded SQL source file, called store.sqc. You can process this file using the following command. Do not specify a project name. This command causes the SQL preprocessor to write the file store.c.

    sqlpp -c "uid=dba;pwd=sql" store.sqc

    In addition, the preprocessor automatically runs the UltraLite generator, which generates more C/C++ code to implement your application database. This code is automatically appended to the file store.c.


Configuring development tools for embedded SQL development

Many development tools use a dependency model, sometimes expressed as a makefile, in which the timestamp on each source file is compared with that on the target file (object file, in most cases) to decide whether the target file needs to be regenerated.

With UltraLite development, a change to any SQL statement in a development project means that the generated code needs to be regenerated. Changes are not reflected in the timestamp on any individual source file because the SQL statements are stored in the reference database,.

This section describes how to incorporate UltraLite application development, specifically the SQL preprocessor and the UltraLite generator, into a dependency-based build environment. The specific instructions provided are for Visual C++, and you may need to modify them for your own development tool.

The UltraLite plug-in for Metrowerks CodeWarrior automatically provides Palm Computing platform developers with the techniques described here. For information on this plug-in, see Developing UltraLite applications with Metrowerks CodeWarrior.

or a tutorial describing details for a very simple project, see Tutorial: Build an Application Using Embedded SQL.

SQL preprocessing

The first set of instructions describes how to add instructions to run the SQL preprocessor to your development tool.

toggle To add embedded SQL preprocessing into a dependency-based development tool

  1. Add the .sqc files to your development project.

    The development project is defined in your development tool. It is separate from the UltraLite project name used by the UltraLite generator.

  2. Add a custom build rule for each .sqc file.

    • The custom build rule should run the SQL preprocessor. In Visual C++, the build rule should have the following command (entered on a single line):

      "%asany9%\win32\sqlpp.exe" -q -o WINNT
        -c connection-string -p project-name
        $(InputPath) $(InputName).c

      where asany9 is an environment variable that points to your SQL Anywhere installation directory, connection-string provides the connection to the reference database, and project-name is the name of your UltraLite project.

      If you are generating an executable for a non-Windows platform, choose the appropriate setting instead of WINNT.

      For a full description of the SQL preprocessor command line, see The SQL preprocessor.

    • Set the output for the command to $(InputName).c.

  3. Compile the .sqc files, and add the generated .c files to your development project.

    You need to add the generated files to your project even though they are not source files, so that you can set up dependencies and build options.

  4. For each generated .c file, set the preprocessor definitions.

    • Under General or Preprocessor, add UL_USE_DLL to the Preprocessor definitions.

    • Under Preprocessor, add $(asany9)\h and any other include folders you require to your include path, as a comma-separated list.

UltraLite code generation

The following set of instructions describes how to add UltraLite code generation to your development tool.

toggle To add UltraLite code generation into a dependency-based development environment

  1. Add a dummy file to your development project.

    Add a file named, for example, uldatabase.ulg, in the same directory as your generated files.

  2. Set the build rules for this file to be the UltraLite generator command line.

    In Visual C++, use a command of the following form (which should be all on one line):

    "%asany9%\win32\ulgen.exe" -q -c "connection-string" $(InputName) $(InputName).c

    where asany9 is an environment variable that points to your SQL Anywhere installation directory, connection-string is a connection to your reference database, and InputName is the UltraLite project name, and should match the root of the text file name. The output is $(InputName).c.

  3. Set the dummy file to depend on the output files from the preprocessor.

    In Visual C++, click Dependencies on the custom build page, and enter the names of the generated .c files produced by the SQL preprocessor.

    This instructs Visual C++ to run the UltraLite generator after all the necessary embedded SQL files have been preprocessed.

  4. Compile your dummy file to generate the .c file that implements the UltraLite database.

  5. Add the generated UltraLite database file to your project and change its C/C++ settings.

  6. Add the UltraLite imports library to your object/libraries modules list.

    In Visual C++, go to the project settings, choose the Link tab, and add the following to the Object/libraries module list for Windows development.

    $(asany9)\ultralite\win32\386\lib\ulimp.lib

    For other targets, choose the appropriate import library.

  7. When you alter any SQL statements in the reference database, touch the dummy file, to update its timestamp and force the UltraLite generator to be run.


Common Features of UltraLite C/C++ Interfaces

About this chapter

This chapter addresses development issues that are common to the UltraLite C/C++ interfaces. It also describes how to mix the interfaces in the same application.


Understanding the SQL Communications Area

All UltraLite C/C++ interfaces address the same UltraLite runtime engine. They each provide access to the same underlying functionality.

All UltraLite C/C++ interfaces also share the same basic data structure for marshaling data between the UltraLite runtime and your application. This data structure is the SQL Communications Area or SQLCA. Each SQLCA has a current connection, and separate threads cannot share a common SQLCA.

Your code must carry out the following tasks before connecting to a database:

  • Initialize a SQLCA. This prepares your application for communication with the UltraLite runtime.

  • Set any data store characteristics and register your error callback function. For a list of functions, see UltraLite C/C++ Common API Reference.

  • Start a database. This operation may be carried out as part of opening the connection.

The following functions are equivalent ways of carrying out these tasks.

Task | Interface | Function
Initialize SQLCA | Embedded SQL | db_init
 | Static C++ API | ULData::Initialize
 | C++ Component | ULSqlca::Initialize
Initialize SQLCA and start database | Embedded SQL | db_init db_start_database
 | Static C++ API | ULData::Open
 | C++ Component | The database is started as part of the connection function in UltraLite_DatabaseManager

Creating databases


Creating databases

To create a database, UltraLite requires a schema definition. In static interfaces that use generated code, the schema definition is held in the generated code. In the UltraLite C++ component, the schema definition is held externally in a schema file.

The following connection primitives know about the generated code database schema, and create a database that matches that schema.

  • db_start_database (embedded SQL)

  • ULData::Open (static C++ API)

  • EXEC SQL CONNECT statement (embedded SQL)

The C++ component does not require any generated code and does not reference the generated code database schema. If you add C++ component code to a static application, you must use one of the primitives that know about the generated code database schema to start the database. You cannot start a database without an external schema file using the C++ component DatabaseManager::CreateAndOpenDatabase() method.

Name the database explicitly

The different interfaces use different default filenames for the database. If you are mixing the interfaces, it is therefore best to always name the database explicitly when creating or connecting. You can do this using a DBN connection parameter.


Combining UltraLite C/C++ interfaces

You can combine the use of separate C/C++ interfaces in a single application. There are several reasons you may wish to do this. For example:

  • You may wish to add features from the new UltraLite C++ Component to an existing static interface application.

  • You may wish to include dynamic SQL features together with SQL statements that are supported only in static interfaces.

Use a generated database schema

When combining interfaces, the database schema must be defined by the generated code of a static interface because the static code has no way of accessing a database schema held in an external file. This means that if you are mixing C++ Component features with static interface features, you must start the database using the static interface. That is, you must start the database using ULData::StartDatabase (static C++ API) or db_start_database (embedded SQL).

Simple mixing

The simplest way to add dynamic SQL or other C++ Component features to a static interface application is to use a separate SQLCA and a separate connection for the two feature sets. One SQLCA and connection can use C++ Component code and execute dynamic SQL queries, while the other SQLCA and connection can use static interface features. In this approach, no coordination between the static interface code and the C++ Component is required. The overhead for the separate connection is minimal.

The only restriction to this method of mixing interfaces is that the dynamic SQL and static statements cannot be part of the same transaction.

Sharing a SQLCA

If you wish statements from static and dynamic SQL to be part of the same transaction, you must share a single connection among the interfaces. Sharing a SQLCA is a prerequisite to sharing connections. It is also possible to write your application to share a SQLCA but have different connections.

toggle To share a single SQLCA

  1. Declare the SQLCA using the UltraLite C++ Component ULSqlca object.

    //Declare a SQLCA using C++ Component
ULSqlca    MySqlca;

  2. Set the static interface to use this object.

    For embedded SQL:

    //Set the embedded SQL SQLCA
EXEC SQL SET SQLCA "MySqlca.GetCA()";

    For the static C++ API:

    ULData MyData
MyData.Initialize( MySqlca.GetCA() );

  3. Initialize the SQLCA once only.

    Use either the UltraLite C++ Component ULSqlca::Initialize() method or db_init. The following example uses C++ component initialization.

    //Initialize the SQLCA
MySqlca.Initialize();

  4. Start the database.

    You must start the database from the static component, so that the internal generated schema can be used to create the database on the first connection.

    For embedded SQL:

    db_start_database( );

    For the static C++ API:

    MyData.StartDatabase( );

You can now use separate connections from the C++ Component and the static interface, and these connections will share the same SQLCA. If you wish to share a single connection, there is another step to carry out.

toggle To share a single connection

  1. Ensure that your application is sharing a single SQLCA, as described in the previous procedure.

  2. Manage the connection using the UltraLite C++ Component.

    Use the DatabaseManager::OpenConnection and Connection::Release methods to open and close connections. Do not use the static interface connection mechanisms.

    Once OpenConnection returns, the connection is current for the SQLCA and is used for any subsequent embedded SQL or static C++ API statements.


Defragmenting UltraLite databases

The UltraLite store is designed to efficiently reuse free space, so explicit defragmentation is not required under normal circumstances. This section describes a technique to explicitly defragment UltraLite databases, for use by applications with extremely strict space requirements.

UltraLite provides a defragmentation step function, which defragments a small part of the database. To defragment the entire database at once, call the defragmentation step function in a loop until it returns ul_true. This can be an expensive operation, and SQLCODE must also be checked to detect errors (an error here usually indicates a file I/O error).

Explicit defragmentation occurs incrementally under application control during idle time. Each step is a small operation.

For more information, see ULStoreDefragFini function, ULStoreDefragInit function, and ULStoreDefragStep function.

toggle To defragment an UltraLite database

  1. Obtain a p_ul_store_defrag_info information block. For example,

    p_ul_store_defrag_info     DefragInfo;
//...
db_init( &sqlca );
DefragInfo = ULStoreDefragInit( &sqlca );

  2. During idle time, call UlStoreDefragStep to defragment a piece of the database. For example,

    ULStoreDefragStep( &sqlca, DefragInfo );

  3. When complete, dispose of the defragmentation block. For example,

    ULStoreDefragFini( &sqlca, DefragInfo );
Example

In this embedded SQL sample, defragmentation occurs incrementally under application control during idle time. Each defragmentation step is a small operation.

p_ul_store_defrag_info     DefragInfo;

idle()
{
   for( i = 0; i < DEFRAG_IDLE_STEPS; i++ ){
      ULStoreDefragStep( &sqlca, DefragInfo );
      if( SQLCODE != SQLE_NOERROR ) break;
   }
}

main()
{
   db_init( &sqlca );
   DefragInfo = ULStoreDefragInit( &sqlca );
   //
   // main application code,
   // calls idle() when appropriate...
   //
   ULStoreDefragFini( &sqlca, DefragInfo );
   db_fini( &sqlca );
}

To defragment the entire store at once, you can call ULStoreDefragStep in a loop until it returns ul_true. This can be an expensive operation, and you must check SQLCODE to detect errors such as file I/O errors.


Developing UltraLite Applications for the Palm Computing Platform

About this chapter

This chapter describes details of development, deployment and synchronization that are specific to developing applications for the Palm Computing Platform.

Introduction
Developing UltraLite applications with Metrowerks CodeWarrior
Saving state in UltraLite Palm applications
Building multi-segment applications
Adding HotSync synchronization to Palm applications
Adding TCP/IP, HTTP, or HTTPS synchronization to Palm applications
Deploying Palm applications


Introduction

This chapter describes features of UltraLite development specific to the Palm Computing Platform.

Development environments

You can use one of the following development environments to build UltraLite Palm applications:

  • Metrowerks CodeWarrior, version 8 or 9, using embedded SQL, the static C++ API, or the UltraLite C++ component.

    See Developing UltraLite applications with Metrowerks CodeWarrior.

    CodeWarrior includes a version of the Palm SDK. Depending on the particular devices you are targeting, you may want to upgrade your Palm SDK to a more recent version than that included in the development tool.

    For a list of supported platforms, see UltraLite development platforms and UltraLite target platforms.

  • AppForge MobileVB, using the UltraLite MobileVB component.

    See UltraLite for MobileVB User's Guide.

Target platforms

For a list of supported target operating systems, see UltraLite target platforms.

See also

For general information on development environments for the Palm, including more information on each of the supported host platforms, see the [external link] Palm Computing Platform Development Zone Web site.

For information on supported development environments, see UltraLite development platforms.


Developing UltraLite applications with Metrowerks CodeWarrior

Metrowerks CodeWarrior versions 8 and 9 are supported platforms for developing Palm Computing Platform applications using the UltraLite C++ component, the static C++ API and embedded SQL.

A CodeWarrior plug-in is supplied to make building UltraLite applications easier. This plug-in is supplied in the UltraLite\Palm\68k\cwplugin directory.

This section describes how to develop UltraLite applications using CodeWarrior. It assumes a familiarity with CodeWarrior programming for the Palm Computing Platform.

Installing the UltraLite plug-in for CodeWarrior
Creating UltraLite projects in CodeWarrior
Converting an existing CodeWarrior project to an UltraLite application
Using the UltraLite plug-in for CodeWarrior
Building the CustDB sample application from CodeWarrior
Building Expanded Mode applications


Installing the UltraLite plug-in for CodeWarrior

The files for the UltraLite plug-in for CodeWarrior are placed on your disk during UltraLite installation, but the plug-in is not available for use without an additional installation step.

toggle To install the UltraLite plug-in for CodeWarrior

  1. Ensure that you are running CodeWarrior version 8 or CodeWarrior version 9. You can obtain patches for CodeWarrior from the Metrowerks Web site.

  2. From a command prompt, change to the UltraLite\palm\68k\cwplugin subdirectory of your SQL Anywhere directory.

  3. Run install.bat to copy the appropriate files into your CodeWarrior installation directory: The install.bat file takes two arguments:

    • Your CodeWarrior directory

    • Your CodeWarrior version.

    For example, the following command (which should be entered on one line) installs the plug-in for CodeWarrior 9 in the default CodeWarrior installation directory.

    install "c:\Program Files\Metrowerks\CodeWarrior for Palm OS Platform 9.0" r9

    You only need double quotes around the directory if the path has spaces.

Uninstalling the CodeWarrior plug-in

There is also a file uninstall.bat, that you can use in the same way as install.bat to uninstall the UltraLite Plug-in from CodeWarrior.


Creating UltraLite projects in CodeWarrior

toggle To create an UltraLite project in CodeWarrior

  1. Start CodeWarrior.

  2. Create a new project.

    1. From the CodeWarrior menu, choose File > New. A tabbed dialog appears.

    2. On the Projects tab, choose Palm OS Application Stationery.

    3. Also on the Projects tab, choose a name and location for the project. Click OK.

  3. Choose an UltraLite stationery.

    The UltraLite plug-in adds the following choices to the stationery list:

    • Palm OS UltraLite C++ API App
    • Palm OS UltraLite C++ Component App
    • Palm OS UltraLite ESQL App

    Choose the development model you want to use and click OK to create the project.

    The stationery is standard C stationery for embedded SQL, and standard C++ stationery for the static C++ API and C++ component. It contains almost-empty source files.

  4. If you are using embedded SQL or the static C++ API, configure the target settings for your project.

    If you are using the C++ component, these settings are ignored.

    1. On your project window (.mcp), choose the Targets tab, and click the Settings icon on the toolbar. The Project Settings window opens.

    2. In the tree on the left pane, choose Target > UltraLite preprocessor. You can enter the settings for your project, such as which reference database to use.

Preprocessing

When you build an embedded SQL project, the UltraLite project calls sqlpp and ulgen utilities to convert any .sqc files into .c or .cpp files and to generate the database code.

When you build a C++ API project, the UltraLite plugin calls ulgen to generate the UltraLite API files and the database code.

There is no preprocessing required for C++ component, which is why the target settings are ignored.

For embedded SQL and the static C++ API, plugin also adds paths to required UltraLite files, such as headers and runtime library, to the search paths.


Converting an existing CodeWarrior project to an UltraLite application

If you install the UltraLite plug-in into CodeWarrior, you will be asked to convert each existing project when you open it. In this conversion, CodeWarrior sets the default SQL preprocessor settings and saves them in the project file. This causes no disruption to projects that do not use the SQL preprocessor. If you want to further convert a project to invoke the SQL preprocessor automatically, you need to do the following:

  1. Add a file mapping entry for .sqc and .ulg files to the File Mappings panel of the Target settings.

    These files are of file type TEXT and the Compiler is UltraLite Preprocessor. All flags for these files should be unchecked.

  2. For embedded SQL applications, remove all .cpp files generated by the SQL preprocessor from the Files view. These files are automatically generated and re-added when the .sqc files are built.

  3. For static C++ API applications, mark the .ulg dummy file dirty and remove the UltraLite Files folder.


Using the UltraLite plug-in for CodeWarrior

For embedded SQL and the static C++ API, the UltraLite plug-in for CodeWarrior integrates the UltraLite preprocessing steps (running the UltraLite generator and, for embedded SQL applications, running the SQL preprocessor) into the CodeWarrior compilation model. It ensures that the SQL preprocessor and UltraLite generator run when required.

If you change the UltraLite project name, or if you change the generated database name, you should delete the UltraLite Files folder. This forces regeneration of the generated files. To avoid filename collisions, do not use a generated database name that is the same as the .sqc file name.

If you change a SQL statement in a static C++ API UltraLite project, or if you alter a publication used in a static C++ API project, you must manually touch the dummy.ulg file to prompt the UltraLite generator to run.

For an overview of the tasks the plug-in carries out, see Configuring development tools for static UltraLite development.

Using prefix files

A prefix file is a header file that all source files in a Metrowerks CodeWarrior project must include. You should use ulpalmos.h from the h subdirectory of your SQL Anywhere Studio installation as your prefix file. The CodeWarrior plug-in sets this for you automatically.

If you have your own prefix file, it must include ulpalmos.h. The ulpalmos.h file defines macros required by UltraLite Palm applications and also sets CodeWarrior compiler options required by UltraLite.

Notes

Although the UltraLite plug-in does not configure your development environment for expanded mode, you can build expanded mode applications. For more information, see Building Expanded Mode applications.

If you are using either the ULSecureCerticomTLSStream or ULSecureRSATLSStream functions to implement encrypted synchronization, you must add ulrsa.lib or ulecc.lib to your CodeWarrior projects.


Building the CustDB sample application from CodeWarrior

CustDB is a simple sales-status application.

For a diagram of the sample database schema, see The CustDB sample database.

Files for the application are located in the Samples\UltraLite\CustDB subdirectory of your SQL Anywhere directory. Generic files are located in the CustDB directory. Files specific to CodeWarrior for the Palm Computing Platform are in the following locations:

  • cwcommon Files common to all versions of CodeWarrior.

  • cw8 Files for CodeWarrior 8 or CodeWarrior 9.

The instructions in this section describe how to build the CustDB application using CodeWarrior 9. The process is very similar for CodeWarrior 8.

toggle To build the CustDB sample application using CodeWarrior

  1. Start the CodeWarrior IDE.

  2. Open the CustDB project file:

    • Choose File > Open.

    • Open the project file Samples\UltraLite\custdb\cw8\custdb.mcp under your SQL Anywhere directory.

  3. To build the target application (custdb.prc), choose Project > Make.

You can use the UltraLite plug-in to customize settings for your own application. For more information, see Developing UltraLite applications with Metrowerks CodeWarrior.


Building Expanded Mode applications

CodeWarrior supports a code generation mode called expanded mode, which improves memory use for global data. If you are using CodeWarrior version 9 you can now use expanded mode with an A5-based jump table. To do so, you must specify a specific version of the UltraLite runtime library. For expanded mode, specify the following runtime library:

ultralite\palm\68k\lib\cw9_a4a5jt\ulrt.lib

Expanded mode may be helpful for large applications that would otherwise exceed the 64 KB global data limit. A limitation of expanded mode is that encrypted synchronization can be used only via HotSync, as the synchronization security libraries for UltraLite do not use expanded mode.

Using the UltraLite plug-in

The UltraLite plug-in for CodeWarrior does not add the expanded mode library to applications.

The easiest way to build expanded mode applications from the UltraLite plug-in is to copy the expanded mode runtime library over the normal runtime library.

toggle To use the expanded mode runtime library from the UltraLite plug-in

  1. Back up the standard runtime library.

    Copy the file ultralite\palm\68k\lib\cw\ulrt.lib to a safe location.

  2. Copy the expanded mode runtime library over the normal runtime library.

    Copy ultralite\palm\68k\lib\cw9_a4a5jt\ulrt.lib over ultralite\palm\68k\lib\cw\ulrt.lib.

    The UltraLite plug-in should then add the required paths, headers, and runtime library to the CW project.

  3. Repeat the process if you install updated UltraLite software.

    Installing updates to the UltraLite software will copy the new standard mode library over your expanded mode runtime library. Be sure to repeat the earlier steps in the procedure to use the expanded mode runtime library.


Saving state in UltraLite Palm applications

You can save the state of tables and cursors when an application is closed by suspending the connection instead of closing it.

The current state is only stored for tables that are not closed, and when the connection object is not closed. This means that, to maintain state, the application should terminate without ever closing the connection object; or exiting the routine that defined the connection object; or assigning the variable for the connection object to nothing or null.

Whenever your UltraLite application is closed, and the user switches to another application, UltraLite saves the state of any open cursors and tables.

  1. When the user returns to the application, call the appropriate open methods:

    • For the Static C++ API, call the following functions:

      • ULData::Open,
      • ULEnablePalmRecordDB or ULEnableFileDB,
      • ULConnection::Open.

    • For embedded SQL, call the following functions:

      • db_init,
      • ULEnablePalmRecordDB or ULEnableFileDB,
      • EXEC SQL CONNECT.

    • For the C++ Component, call the following functions:

      • ULSqlca.Initialize,
      • ULInitDatabaseManager,
      • ULEnablePalmRecordDB or ULEnableFileDB,
      • OpenDatabase.

  2. Confirm that the connection was restored properly by checking that the SQLCODE is SQLE_CONNECTION_RESTORED.

  3. For cursor objects, including instances of generated result set classes, you can do either of the following:

    • Ensure that the object is closed when the user switches away from the application, and call Open when you next need the object. If you choose this option, the current position is not restored.

    • Do not close the object when the user switches away, and call Reopen when you next need to access the object. The current position is then maintained, but the application takes more memory in the Palm when the user is using other applications.

  4. For table objects, including instances of generated table classes, you cannot save a position. You must close table objects before a user moves away from the application, and Open them when the user needs them again. Do not use Reopen on table objects.

Closing a connection rolls back any uncommitted transactions. By not closing connection objects, any outstanding transactions are saved (not committed), so that when the application restarts, those transactions will appear and can be committed or rolled back. Also, uncommitted changes are not synchronized.

Restoring state in UltraLite Palm applications


Restoring state in UltraLite Palm applications

When an application restarts on the Palm OS, UltraLite restores the state of any cursors or tables that were not explicitly closed when the application was most recently shut down.


Building multi-segment applications

Application code for the Palm Computing Platform must be divided into segments. For CodeWarrior, these segments are at most 64 KB in size. This section describes how to manage the assignment of code into segments.

UltraLite applications include the following types of code:

  • User-defined code Application code, including the .cpp file generated by the SQL Preprocessor.

  • Generated code for SQL statements Code generated by the UltraLite Analyzer to execute SQL statements.

  • Generated code for the database schema Code generated by the UltraLite Analyzer to represent the database tables.

  • Runtime library The UltraLite runtime library is compiled as multi-segment code. Segment names of the form ULRTn and ULRTnn are reserved for the UltraLite runtime libraries.

Building multi-segment applications is a general feature of application development for the Palm Computing Platform, whether or not you are using UltraLite. Some familiarity with building multi-segment applications using your development tool is assumed. User-defined code is no different to other standard Palm applications. For a reminder about assigning user-defined code to segments, see Assigning user-defined code to segments.

You can partition generated code into segments in the following ways:

  • Enable multi-segment code generation, but let the UltraLite Analyzer assign segments in a default manner.

    For more information, see Enabling multi-segment code generation.

  • Enable multi-segment code-generation and explicitly assign segments yourself.

    For more information, see Explicitly assigning segments.


Enabling multi-segment code generation

This section describes how to instruct the UltraLite Analyzer to generate multi-segment code using its default scheme. If you wish to customize the assignment of code to segments by explicitly assigning functions to segments, you can do so. For more information, see Explicitly assigning segments.

You enable generated code segments by defining macros.

toggle To enable multi-segment code generation

  1. Define a prefix file for your CodeWarrior project with the following contents:

    #define UL_ENABLE_SEGMENTS
#include "ulpalmos.h"

    For more information, see UL_ENABLE_SEGMENTS macro.

Notes

When multi-segment code generation is enabled, the default behavior of the UltraLite Analyzer is as follows:

  • The generated schema code fits into a single segment and is assigned to a segment named ULSEGDB.

  • For the C++ API, the generated statement code is assigned to a segment named ULSEGDEF.

  • For embedded SQL, the generated statement code is assigned to a segment with a generated name based on the .sqc file. All the code for a single .sqc file goes into a single segment.


Explicitly assigning segments

This section describes how to explicitly assign the generated code for SQL statements to segments. You must first enable multi-segment code generation as described in Enabling multi-segment code generation.

Explicit segment assignment requires a database upgraded to version 8 or later standards.

toggle To explicitly assign generated statement code to segments (embedded SQL)

  • Split your .sqc files into separate files. The generated code for the statements in each .sqc file is placed into a separate segment.

toggle To explicitly assign generated statement code to segments (static C++ API)

  • Do one of the following:

    • Call the ul_set_codesegment procedure for each SQL statement, providing the name of the segment to which the statement should be assigned.

      For example, the following statement assigns the statement mystmt, in the project myproject, to the segment MYSEG1.

      call ul_set_codesegment(
     'myproject', 'mystmt', 'MYSEG1' )

      For more information, see ul_set_codesegment system procedure.

    • From Sybase Central, open the UltraLite Project folder. Right click the statement and choose Properties from the popup menu. Enter a code segment name in the box.


Assigning user-defined code to segments

Assigning user-defined code to segments is a standard part of programming applications for the Palm Computing Platform. This section is intended as a reminder for Palm programmers.

toggle To assign user-defined code to segments (CodeWarrior)

  1. Add the following line at various places in your .sqc file or .cpp file:

    #pragma segment segment-name

    where segment-name is a unique name for the segment This forces code after each #pragma line to be in a separate segment.

The first segment

You must ensure that PilotMain and all functions called in PilotMain are in the first segment.

If necessary, you can add a line of the following form before your startup code:

#pragma segment segment-name

where segment-name is the name of your first segment.

For more information on prefix files and segments, see your Palm developer documentation.


Adding HotSync synchronization to Palm applications

HotSync synchronization takes place when your UltraLite application is closed. It is initiated by the HotSync.

If you use HotSync, then you synchronize by calling ULSetSynchInfo before closing the application. Do not use ULSynchronize or ULConnection.Synchronize for HotSync synchronization.

To call HotSync synchronization from your application you must add code for the following steps:

  1. Prepare a ul_synch_info structure.

  2. Call the ULSetSynchInfo function, supplying the ul_synch_info structure as an argument.

    This function is called when the user switches away from the UltraLite application. You must ensure that all outstanding operations are committed before calling db_fini or ULData.Close. The ul_synch_info.stream parameter is ignored, and so does not need to be set.

    For example:

    //Static C++ API
ul_synch_info info;
ULInitSynchInfo( &info );
info.stream_parms =
  UL_TEXT( "stream=tcpip;host=localhost" );
info.user_name = UL_TEXT( "50" );
info.version = UL_TEXT( "custdb" );

ULSetSynchInfo( &sqlca, &info );

if( !db.Close( ) ) {
  return( false );
}

  3. Call db_fini or ULData.Close.

For more information, see Saving state in UltraLite Palm applications, and Synchronization parameters.

A MobiLink HotSync conduit is required for HotSync synchronization of UltraLite applications. If there are uncommitted transactions when you close your Palm application, and if you synchronize, the conduit reports that synchronization fails because of uncommitted changes in the database.

Specifying the stream parameters

The synchronization stream parameters in the ul_synch_info structure control communication with the MobiLink synchronization server. For HotSync synchronization, the UltraLite application does not communicate directly with a MobiLink synchronization server; it is the HotSync conduit instead.

You can supply synchronization stream parameters to govern the behavior of the MobiLink conduit in one of the following ways:

  • Supply the required information in the stream_parms member of ul_synch_info passed to ULSetSynchInfo.

    For a list of available values, see Network protocol options for UltraLite synchronization clients.

  • Supply a null value for the stream_parms member. The MobiLink conduit then searches in the ClientParms registry entry on the machine where it is running for information on how to connect to the MobiLink synchronization server.

    The stream and stream parameters in the registry entry are specified in the same format as in the ul_synch_info structure stream_parms field.

    For more information, see HotSync configuration overview.

See also

For information about configuring HotSync, including a description of how to set up your MobiLink HotSync conduit, see Configuring the MobiLink HotSync conduit.


Adding TCP/IP, HTTP, or HTTPS synchronization to Palm applications

This section describes how to add TCP/IP, HTTP, or HTTPS synchronization to your Palm application.

For a general description of how to add synchronization to UltraLite applications, see Synchronizing data.

Transport layer security on the Palm Computing Platform

You can use transport-layer security with Palm applications built with Metrowerks CodeWarrior.

For information on transport-layer security, see MobiLink Transport-Layer Security.

Palm devices can synchronize using TCP/IP, HTTP, or HTTPS communication by setting the stream member of the ul_synch_info structure to the appropriate stream, and calling ULSynchronize or ULConnection.Synchronize to carry out the synchronization.

When using TCP/IP, HTTP, or HTTPS synchronization, db_init or ULData.Initialize and db_fini or ULData.Close save and restore the state of the application on exiting and activating the application, but do not participate in synchronization.

Before closing the application, set the synchronization information using ULSetSynchInfo, providing ul_synch_info structure as an argument.

When using TCP/IP, HTTP, or HTTPS synchronization from a Palm device, you must specify an explicit host name or IP number in the stream_parms member of the ul_synch_info structure. Specifying NULL defaults to localhost, which represents the device, not the host.

For information on the ul_synch_info structure, see Network protocol options for UltraLite synchronization clients.


Deploying Palm applications

This section describes the following aspects of deploying Palm applications:

  • Deploying the application.

    See Deploying the application

  • Deploying the MobiLink synchronization conduit for HotSync.

    See Deploying the MobiLink synchronization conduit.

  • Deploying an initial copy of the UltraLite database.

    See Deploying UltraLite databases.

Install your UltraLite application on your Palm device as you would any other Palm Computing Platform application.

Deploying the application
toggle To install an application on a Palm device

  1. Open the Install Tool, included with your Palm Desktop Organizer Software.

  2. Choose Add and locate your compiled application (.prc file).

  3. Close the Install Tool.

  4. HotSync to copy the application to your Palm device.

Deploying the MobiLink synchronization conduit

For applications using HotSync synchronization, each end user must have the MobiLink synchronization conduit installed on their desktop.

For more information about installing the MobiLink synchronization conduit, see Deploying the MobiLink HotSync conduit.

Deploying UltraLite databases

If you deploy your application without a database, the database is created the first time it is accessed from the application. The user must then download an initial copy of data on the first synchronization. You can use the ULUtil utility to back up the UltraLite database to the PC. To deploy many UltraLite databases with an initial database including data, you can perform an initial synchronization and then back up the UltraLite database. The database can be deployed on other devices so they do not need to perform an initial synchronization.

For more information, see The ULUtil utility.

If you are using HotSync synchronization, each of your end users must also install the synchronization conduit onto their desktop machine.

For information on installing the synchronization conduit, see Configuring the MobiLink HotSync conduit.

If you deploy a database using HotSync, HotSync sets a backup bit on the database. When this backup bit is set, the entire database is backed up to the desktop machine on each synchronization. This behavior is generally not appropriate for UltraLite databases. When an UltraLite application is launched, the Palm data store is checked to see if its backup bit is set to true. If it is set, it is cleared. If it is not set, there is no change.

If you wish the backup bit to remain set to true, you can set the store parameter palm_allow_backup in UL_STORE_PARMS.

For more information, see UL_STORE_PARMS macro.


Developing UltraLite Applications for Windows CE

About this chapter

This chapter describes details of development, deployment and synchronization that are specific to Windows CE. These instructions assume familiarity with the general development process. They assist in building the CustDB sample application, included with your UltraLite software, on each of these platforms.


Introduction

This section contains instructions pertaining to building UltraLite applications for use under Microsoft Windows CE.

For a list of supported host platforms and development tools for Windows CE development, and for a list of supported target Windows CE platforms, see UltraLite development platforms, and UltraLite target platforms.

You can test your applications under an emulator on most Windows CE target platforms.

Preparing for Windows CE development

The recommended development environment for Windows CE at the time of writing is Microsoft eMbedded Visual C++ 3.0. This development environment is available from Microsoft as part of eMbedded Visual Tools.

You can download eMbedded Visual C++ from the Microsoft Developer Network at [external link] http://msdn.microsoft.com/.

A first application

A sample eMbedded Visual C++ project is provided in the Samples\UltraLite\CEStarter directory under your SQL Anywhere directory. The workspace file is Samples\UltraLite\CEStarter\ul_wceapplication.vcw.

When preparing to use eMbedded Visual C++ for UltraLite applications, you should make the following changes to the project settings. The CEStarter application has these changes made.

  • Compiler settings:

    • Add $(ASANY9)\h to the include path.

    • Define appropriate compiler directives. For example, the UNDER_CE macro should be defined for eMbedded Visual C++ projects.

  • Linker settings:

    • Add "$(ASANY9)\ultralite\ce\processor\lib\ulrt.lib"

      where processor is the target processor for your application.

    • Add winsock.lib.

  • The .sqc file (embedded SQL only):

    • Add ul_database.sqc and ul_database.cpp to the project

    • Add the following custom build step for the .sqc file:

      "$(ASANY9)\win32\sqlpp" -q -c "dsn=UltraLite 9.0 Sample" $(InputPath) ul_database.cpp

    • Set the output file to ul_database.cpp.

    • Disable the use of precompiled headers for ul_database.cpp.

Choosing how to link the runtime library


Choosing how to link the runtime library

Windows CE supports dynamic link libraries. At link time, you have the option of linking your UltraLite application to the runtime DLL using an imports library, or statically linking your application using the UltraLite runtime library.

If you have a single UltraLite application on your target device, a statically linked library uses less memory. If you have multiple UltraLite applications on your target device, using the DLL may be more economical in memory use.

If you are repeatedly downloading UltraLite applications to a device, over a slow link, then you may want to use the DLL in order to minimize the size of the downloaded executable, after the initial download.

toggle To build and deploy an application using the UltraLite runtime DLL

  1. Preprocess your code, then compile the output with UL_USE_DLL.

  2. Link your application using the UltraLite imports library.

  3. Copy both your application executable and the UltraLite runtime DLL to your target device.


Building the CustDB sample application

CustDB is a simple sales-status application. It is located in the UltraLite samples directory of your Adaptive Server Anywhere installation. Generic files are located in the CustDB directory. Files specific to Windows CE are located in the ce subdirectory of CustDB.

The CustDB application is provided as an eMbedded Visual C++ 3.0 project.

For a diagram of the sample database schema, see The CustDB sample database.

toggle To build the CustDB sample application

  1. Start eMbedded Visual C++.

  2. Open the project file that corresponds to your version of eMbedded Visual C++:

    • Samples\UltraLite\CustDB\EVC\EVCCustDB.vcp for eVC 3.0.

    • Samples\UltraLite\CustDB\EVC40\EVCCustDB.vcp for eVC 4.0.

  3. Choose Build > Set Active Platform to set the target platform.

    • Set a platform of your choice.

  4. Choose Build->Set Active Configuration to select the configuration.

    • Set an active configuration of your choice.

  5. If you are building CustDB for the Pocket PC x86em emulator platform only:

    • Choose Project > Settings. The Project Settings dialog appears.

    • On the Link tab, in the Object/library modules box, change the UltraLite runtime library entry to the emulator30 directory rather than the emulator directory.

  6. Build the application:

    • Press F7 or select Build > Build EVCCustDB.exe to build CustDB.

      When eMbedded Visual C++ has finished building the application, it automatically attempts to upload it to the remote device.

  7. Start the synchronization server:

    • To start the MobiLink synchronization server, select Programs > Sybase SQL Anywhere 9 > MobiLink > Synchronization Server Sample.

  8. Run the CustDB application:

    Press Ctrl+F5 or select Build > Execute CustDB.exe

Folder locations and environment variables
The sample project uses environment variables wherever possible. It may be necessary to adjust the project in order for the application to build properly. If you experience problems, try searching for missing files in the MS VC++ folder and adding the appropriate directory settings.

For embedded SQL, the build process uses the SQL preprocessor, sqlpp, to preprocess the file CustDB.sqc into the file CustDB.c. This one-step process is useful in smaller UltraLite applications where all the embedded SQL can be confined to one source module. In larger UltraLite applications, you need to use multiple sqlpp invocations followed by one ulgen command to create the customized remote database.

For more information, see Building embedded SQL applications.


Storing persistent data

The UltraLite database is stored in the Windows CE file system. The default file is \UltraLiteDB\ul_<project>.udb, with project being truncated to eight characters. You can override this choice using the file_name parameter which specifies the full path name of the file-based persistent store.

The UltraLite runtime carries out no substitutions on the file_name parameter. If a directory has to be created in order for the file name to be valid, the application must ensure that any directories are created before calling db_init.

As an example, you could make use of a flash memory storage card by scanning for storage cards and prefixing a name by the appropriate directory name for the storage card. For example,

file_name = "\\Storage Card\\My Documents\\flash.udb"
Example

The following sample embedded SQL code sets the file_name parameter:

#undef UL_STORE_PARMS
#define UL_STORE_PARMS UL_TEXT(
   "file_name=\\uldb\\my own name.udb;cache_size=128k" )
...
db_init( &sqlca );


Deploying Windows CE applications

When compiling UltraLite applications for Windows CE, you can link the UltraLite runtime library either statically or dynamically. If you link it dynamically, you must copy the UltraLite runtime library for your platform to the target device.

toggle To build and deploy an application using the UltraLite runtime DLL

  1. Preprocess your code, then compile the output with UL_USE_DLL.

  2. Link your application using the UltraLite imports library.

  3. Copy both your application executable and the UltraLite runtime DLL to your target device.

    The UltraLite runtime DLL is in chip-specific directories under the UltraLite\ce subdirectory of your SQL Anywhere directory.

To deploy the UltraLite runtime DLL for the Windows CE emulator, place the DLL in the appropriate subdirectory of your Windows CE tools directory. The following directory is the default setting for the Pocket PC emulator:

C:\Program Files\Windows CE Tools\wce300\MS Pocket PC\
emulation\palm300\windows


Deploying applications that use ActiveSync

Applications that use ActiveSync synchronization must be registered with ActiveSync and copied to the device. The MobiLink provider for ActiveSync must also be installed.

For more information, see Deploying applications that use ActiveSync, Installing the MobiLink provider for ActiveSync and Registering applications for use with ActiveSync.


Assigning class names for applications

When registering applications for use with ActiveSync you must supply a window class name. Assigning class names is carried out at development time and your application development tool documentation is the primary source of information on the topic.

Microsoft Foundation Classes (MFC) dialog boxes are given a generic class name of Dialog, which is shared by all dialogs in the system. This section describes how to assign a distinct class name for your application if you are using MFC and eMbedded Visual C++.

toggle To assign a window class name for MFC applications using eMbedded Visual C++

  1. Create and register a custom window class for dialog boxes, based on the default class.

    Add the following code to your application's startup code. The code must be executed before any dialogs get created:

    WNDCLASS wc;
if( ! GetClassInfo( NULL, L"Dialog", &wc ) ) {
   AfxMessageBox( L"Error getting class info" );
}
wc.lpszClassName = L"MY_APP_CLASS";
if( ! AfxRegisterClass( &wc ) ) {
   AfxMessageBox( L"Error registering class" );
}

    where MY_APP_CLASS is the unique class name for your application.

  2. Determine which dialog is the main dialog for your application.

    If your project was created with the MFC Application Wizard, this is likely to be a dialog named CMyAppDlg.

  3. Find and record the resource ID for the main dialog.

    The resource ID is a constant of the same general form as IDD_MYAPP_DIALOG.

  4. Ensure that the main dialog remains open any time your application is running.

    Add the following line to your application's InitInstance function. The line ensures that if the main dialog dlg is closed, the application also closes.

    m_pMainWnd = &dlg;

    For more information see the Microsoft documentation for CWinThread::m_pMainWnd.

    If the dialog does not remain open for the duration of your application, you must change the window class of other dialogs as well.

  5. Save your changes.

    If eMbedded Visual C++ is open, save your changes and close your project and workspace.

  6. Modify the resource file for your project.

    • Open your resource file (which has an extension of .rc) in a text editor such as Notepad.

    Locate the resource ID of your main dialog.

    • Change the main dialog's definition to use the new window class as in the following example. The only change that you should make is the addition of the CLASS line:

      IDD_MYAPP_DIALOG DIALOG DISCARDABLE  0, 0, 139, 103
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION
EXSTYLE WS_EX_APPWINDOW | WS_EX_CAPTIONOKBTN
CAPTION "MyApp"
FONT 8, "System"
CLASS "MY_APP_CLASS"
BEGIN
       LTEXT   "TODO: Place dialog controls here.",IDC_STATIC,13,33,112,17
END

      where MY_APP_CLASS is the name of the window class you used earlier.

    • Save the .rc file.

  7. Reopen eMbedded Visual C++ and load your project.

  8. Add code to catch the synchronization message.

    For information, see Adding ActiveSync synchronization (MFC).


Synchronization on Windows CE

UltraLite applications on Windows CE can synchronize through the following streams:

  • ActiveSync See Adding ActiveSync synchronization to your application

  • TCP/IP See TCP/IP, HTTP, or HTTPS synchronization from Windows CE.

  • HTTP See TCP/IP, HTTP, or HTTPS synchronization from Windows CE.

The user_name and stream_parms parameters must be surrounded by the UL_TEXT() macro for Windows CE when initializing, since the compilation environment is Unicode wide characters.

For information on adding synchronization to your application, see Synchronizing data. For detailed information on synchronization parameters, see Synchronization parameters.


Adding ActiveSync synchronization to your application

ActiveSync is synchronization software for Microsoft Windows CE handheld devices. UltraLite supports ActiveSync versions 3.1 and 3.5.

This section describes how to add ActiveSync to your application, and how to register your application for use with ActiveSync on your end users' machines.

If you use ActiveSync, synchronization can be initiated only by ActiveSync itself. ActiveSync automatically initiates a synchronization when the device is placed in the cradle or when the Synchronization command is selected from the ActiveSync window. The MobiLink provider starts the application, if it is not already running, and sends a message to the application.

For information on setting up ActiveSync synchronization, see Deploying applications that use ActiveSync.

The ActiveSync provider uses the wParam parameter. A wParam value of 1 indicates that the MobiLink provider for ActiveSync launched the application. The application must then shut itself down after it has finished synchronizing. If the application was already running when called by the MobiLink provider for ActiveSync, wParam is 0. The application can ignore the wParam parameter if it wants to keep running.

Adding synchronization depends on whether you are addressing the Windows API directly or whether you are using the Microsoft Foundation Classes. Both development models are described here.


Adding ActiveSync synchronization (Windows API)

If you are programming directly to the Windows API, you must handle the message from the MobiLink provider in your application's WindowProc function, using the ULIsSynchronizeMessage function to determine if it has received the message.

Here is an example of how to handle the message:

LRESULT CALLBACK WindowProc( HWND hwnd,
         UINT uMsg,
         WPARAM wParam,
         LPARAM lParam )
{
  if( ULIsSynchronizeMessage( uMsg ) ) {
    DoSync();
    if( wParam == 1 ) DestroyWindow( hWnd );
    return 0;
  }
  switch( uMsg ) {
  // code to handle other windows messages
  default:
    return DefWindowProc( hwnd, uMsg, wParam, lParam );
  }
  return 0;
}

where DoSync is the function that actually calls ULSynchronize.

For more information, see ULIsSynchronizeMessage function.


Adding ActiveSync synchronization (MFC)

If you are using Microsoft Foundation Classes to develop your application, you can catch the synchronization message in the main dialog class or in your application class. Both methods are described here.

Your application must create and register a custom window class name for notification. See Assigning class names for applications.

toggle To add ActiveSync synchronization in the main dialog class

  1. Add a registered message and declare a message handler.

    Find the message map in the source file for your main dialog ( the name is of the same form as CMyAppDlg.cpp). Add a registered message using the static and declare a message handler using ON_REGISTERED_MESSAGE as in the following example:

    static UINT WM_ULTRALITE_SYNC_MESSAGE =
   ::RegisterWindowMessage( UL_AS_SYNCHRONIZE );
BEGIN_MESSAGE_MAP(CMyAppDlg, CDialog)
      //{{AFX_MSG_MAP(CMyAppDlg)
      //}}AFX_MSG_MAP
   ON_REGISTERED_MESSAGE( WM_ULTRALITE_SYNC_MESSAGE,
      OnDoUltraLiteSync )
END_MESSAGE_MAP()

  2. Implement the message handler.

    Add a method to the main dialog class with the following signature. This method is automatically executed any time the MobiLink provider for ActiveSync requests that your application synchronize. The method should call ULSynchronize.

    LRESULT CMyAppDlg::OnDoUltraLiteSync(
   WPARAM wParam,
   LPARAM lParam
);

    The return value of this function should be 0.

    For information on handling the synchronization message, see ULIsSynchronizeMessage function.

toggle To add ActiveSync synchronization in the Application class

  1. Open up the Class Wizard for the application class.

  2. In the Messages list, highlight PreTranslateMessage and then click the Add Function button.

  3. Click the Edit Code button. The PreTranslateMessage function appears. Change it to read as follows:

    BOOL CMyApp::PreTranslateMessage(MSG* pMsg)
{
   if( ULIsSynchronizeMessage(pMsg->message) ) {
      DoSync();
      // close application if launched by provider
      if( pMsg->wParam == 1 ) {
         ASSERT( AfxGetMainWnd() != NULL );
         AfxGetMainWnd()->SendMessage( WM_CLOSE );
      }
      return TRUE;   // message has been processed
   }
   return CWinApp::PreTranslateMessage(pMsg);
}

    where DoSync is the function that actually calls ULSynchronize.

    For information on handling the synchronization message, see ULIsSynchronizeMessage function.


TCP/IP, HTTP, or HTTPS synchronization from Windows CE

For TCP/IP, HTTP, or HTTPS synchronization, the application controls when synchronization occurs. Your application will usually provide a menu item or user interface control so that the user can request synchronization.

For more information, see Synchronizing data.


Tutorial: Build an Application Using the C++ Component

About this chapter

This chapter provides a tutorial to guide you through the process of building a simple UltraLite C++ Component application.

Introduction
Lesson 1: Connect to the database
Lesson 2: Insert data into the database
Lesson 3: Select the rows from the table
Lesson 4: Add synchronization to your application
Lesson 5: Deploy to a Windows CE device


Introduction

This tutorial guides you through the process of building an UltraLite C++ application. The application is built for Windows operating systems, and runs at a command prompt.

This tutorial uses a text editor to edit the C++ files. You can also use any C++ development environment, such as Microsoft Visual Studio.

Timing

The tutorial takes about 30 minutes if you copy and paste the code. If you enter the code yourself, it takes significantly longer.

Competencies and experience

This tutorial assumes:

  • you are familiar with the C++ programming language

  • you have a C++ compiler installed on your computer

  • you know how to create an UltraLite schema using the UltraLite Schema Painter

    For more information, see Lesson 1: Create an UltraLite database schema.

Note
The synchronization portion of this tutorial requires SQL Anywhere Studio.
Goals

The goals for the tutorial are to gain competence and familiarity with the process of developing an UltraLite C++ Component application.


Lesson 1: Connect to the database

In the first procedure, you create a database schema. You then write, compile, and run a C++ application that creates a database using the schema you have created.

toggle To create a database schema

  1. Create a directory to hold the files you create in this tutorial.

    The remainder of this tutorial assumes that this directory is c:\tutorial\cpp. If you create a directory with a different name, use that directory instead of c:\tutorial\cpp throughout the tutorial.

  2. Using the UltraLite Schema Painter, create a database schema in your new directory with the following characteristics.

    For more information about using the UltraLite Schema painter, see Lesson 1: Create an UltraLite database schema.

    Schema file name: tutcustomer.usm

    Table name: customer

    Columns in customer:

    Column Name | Data Type (Size) | Column allows NULL values? | Default value
    id | integer | No | autoincrement
    fname | char(15) | No | None
    lname | char(20) | No | None
    city | char(20) | Yes | None
    phone | char(12) | Yes | 555-1234

    Primary key: ascending id

toggle To connect to an UltraLite database

  1. In Microsoft Visual C++, choose File > New.

  2. On the Files tab, choose C++ Source File.

  3. Save the file as customer.cpp in your tutorial directory.

  4. Import the UltraLite libraries and use the UltraLite namespace.

    Copy the code below into customer.cpp.

    #include "uliface.h"
#include <stdio.h>
#include <tchar.h>
#include <assert.h>
using namespace UltraLite;
#define MAX_NAME_LEN 100
ULSqlca Sqlca;

    For information about how using the UltraLite namespace makes class declarations simpler, see Using the UltraLite namespace.

  5. Define connection parameters to connect to the database. In this example, the parameters are the location of the database and schema files.

    In the following code, these locations are hard coded. In a real application, the locations would be specified at runtime. In addition, these connection parameters are sufficient only for connections in the development environment; additional parameters are needed for the application to run on a Windows CE device.

    Copy the code below into customer.cpp.

    static ul_char const * ConnectionParms =
  UL_TEXT( "UID=DBA;PWD=SQL" )
  UL_TEXT( ";DBF=tutcustomer.udb" )
  UL_TEXT( ";schema_file=tutcustomer.usm" );

    For more information about connection parameters, see Class UltraLite_Connection_iface.

  6. Define a method for error handling.

    UltraLite provides a callback mechanism to notify the application of errors.

    This is a sample callback function.

    ul_error_action UL_GENNED_FN_MOD MyErrorCallBack(
   SQLCA *    sqlca,
   ul_error_kind   kind,
   ul_void *   user_data,
   ul_char *   message_parameter )
{
    ul_error_action rc;

    (void) user_data;
    switch( kind ) {
   case UL_ERROR_KIND_MEDIA_REMOVED:
       // Not handled in this sample: Prompt user to re-insert media
       // (message_parameter contains the filename).
       rc = UL_ERROR_ACTION_ABORT;
      // use UL_ERROR_ACTION_RETRY to retry
       break;

   case UL_ERROR_KIND_SQLCODE:
       switch( sqlca->sqlcode ){
       // The following errors are used for flow control, and we don't want to
       // report them here:
       case SQLE_NOTFOUND:
       case SQLE_ULTRALITE_DATABASE_NOT_FOUND:
      break;
       case SQLE_CANNOT_ACCESS_SCHEMA_FILE:
      _tprintf( _TEXT(
         "Error %ld: UltraLite schema file %s not found\n" ), sqlca->sqlcode, message_parameter );
      break;
       case SQLE_COMMUNICATIONS_ERROR:
      _tprintf( _TEXT(
         "Error %ld: Communications error\n" ), sqlca->sqlcode );
      break;
       default:
      _tprintf( _TEXT(
         "Error %ld: %s\n" ), sqlca->sqlcode, message_parameter );
      break;
       }
       rc = UL_ERROR_ACTION_ABORT; // N/A for SQLCODE kind, return ABORT
       break;

   default:
       // future error kinds
       assert( 0 );
       rc = UL_ERROR_ACTION_ABORT; // default action
       break;
    }
    return rc;
}

    In UltraLite, two errors are used to control application flow. The SQLE_ULTRALITE_DATABASE_NOT_FOUND error is signaled on the first connection attempt (when only the schema file is present), and is used to prompt the application to create a database from the schema file. The SQLE_NOTFOUND error marks the end of a loop over a result set.

    For more information about error handling, see Handling errors.

  7. Define a method to open a connection to a database.

    If the database file does not exist, a SQLException is thrown. The schema file is used to create a new database and establish a connection to it.

    If the database file exists, a connection is established.

    Connection * open_conn( DatabaseManager * dm ) {
  Connection * conn;
  conn = dm->OpenConnection( Sqlca, ConnectionParms );
  if( conn == NULL ) {
   if( Sqlca.GetSQLCode() == SQLE_ULTRALITE_DATABASE_NOT_FOUND ) {
    // The database doesn't exist yet -- create it using the schema file.
     conn = dm->CreateAndOpenDatabase( Sqlca, ConnectionParms );
     if( conn == NULL ) {
      handle_error( _TEXT("create database") );
     } else {
         _tprintf( _TEXT("Connected to a new database.\n") );
     }
   } else {
     handle_error( _TEXT("open database") );
   }
  } else {
   _tprintf( _TEXT("Connected to an existing database.\n") );
  }
  return conn;
}

  8. Implement the main() method.

    The main method carries out the following tasks.

    • Instantiates a DatabaseManager object. All UltraLite objects are created from the DatabaseManager object.

    • Registers the error handling function.

    • Opens a connection to the database.

    • Closes the connection and shuts down the database manager.

    int main() {
  ul_char buffer[ 100 ];
  DatabaseManager * dm;
  Connection * conn;
  Sqlca.Initialize();
  ULRegisterErrorCallback(
    Sqlca.GetCA(), MyErrorCallBack,
    UL_NULL, buffer, 100 );
  dm = ULInitDatabaseManager( Sqlca );
  if( dm == UL_NULL ){
    //  You  may  have  mismatched  UNICODE  vs.  ANSI  runtimes.
    Sqlca.Finalize();
    return 1;
  }
  conn = open_conn( dm );
  if( conn == UL_NULL ){
    dm->Shutdown( Sqlca );
    Sqlca.Finalize();
    return 1;
  }
  dm->Shutdown( Sqlca );
  Sqlca.Finalize();
  return 0;
}

  9. Compile and link the Customer class.

    The method you use to compile the class depends on your compiler. The following instructions are for the Microsoft Visual C++ command line compiler using a makefile.

    • From a command prompt, browse to your tutorial directory.

    • Create a makefile named makefile.

    • In the makefile, add directories to your include path as follows.

      IncludeFolders= \
/I"$(ASANY9)\h"

    • In the makefile, add directories to your libraries path as follows.

      LibraryFolders= \
/LIBPATH:"$(ASANY9)\ultralite\win32\386\lib"

    • In the makefile, add libraries to your linker command line options as follows.

      Libraries= \
ulimp.lib

      The UltraLite runtime library, ulimp.lib, is an ASCII version of the library. If you choose the Unicode version, ulimpw.lib, you should add /DUNICODE to the compiler options.

    • In the makefile, set the following compiler options all on one line.

      CompileOptions=/c /nologo /W3 /Od /Zi /DWIN32 /DUL_USE_DLL

    • In the makefile, add an instruction for linking the application.

      customer.exe: customer.obj
   link /NOLOGO /DEBUG customer.obj $(LibraryFolders) $(Libraries)

    • In the makefile, add an instruction for compiling the application.

      customer.obj: customer.cpp
   cl $(CompileOptions) $(IncludeFolders) customer.cpp

    • Add an instruction to create a preprocessed version of the file. This step is included for debugging purposes.

      customer.i: customer.cpp
   cl $(CompileOptions) $(IncludeFolders) customer.cpp -P

    • Run the makefile as follows:

      nmake

      An executable named customer.exe is created.

  10. Run the application.

    At the command prompt, enter customer.


Lesson 2: Insert data into the database

The following procedures demonstrate how to add data to a database.

toggle To add rows to your database

  1. Add procedure below to customer.cpp, immediately before the main method.

    This procedure carries out the following tasks.

    • Opens the table using the connection->OpenTable() method. You must open a Table object to carry out operations on the table.

    • Obtains identifiers for the required columns of the table. The other columns in the table can accept NULL values or have a default value.

    • If the table is empty, adds two rows. To insert each row, the code changes to insert mode using the InsertBegin method, sets values for each required column, and executes an insert to add the rows to the database.

      The commit method is only required when you turn off autocommit. By default, autocommit is enabled but it may be disabled for better performance, or for multi-operation transactions.

    • If the table is not empty, reports the number of rows in the table.

    • Closes the Table object.

    • Returns a boolean indicating whether the operation was completed.

    bool do_insert( Connection * conn ) {
  Table * table = conn->OpenTable( UL_TEXT("customer") );
  if( table == NULL ) {
  return  false;
  }
  if( table->GetRowCount() == 0 ) {
  _tprintf( UL_TEXT("Inserting two rows.\n") );
     table->InsertBegin();
     table->Set( UL_TEXT("fname"), UL_TEXT("Penny") );
     table->Set( UL_TEXT("lname"), UL_TEXT("Stamp") );
     table->Insert();
     CHECK_ERROR();
  table->InsertBegin();
     table->Set( UL_TEXT("fname"), UL_TEXT("Gene") );
     table->Set( UL_TEXT("lname"), UL_TEXT("Poole") );
     table->Insert();
     CHECK_ERROR();
  conn->Commit();
     CHECK_ERROR();
  } else {
    _tprintf( UL_TEXT("The table has %lu rows\n"),
  table->GetRowCount() );
  }
  table->Release();
  return true;
}

  2. Call the do_insert method you have created.

    Add the following line to the main() method, immediately after the call to open_conn.

    do_insert(conn);

  3. Compile your application by running nmake.

  4. Run your application by typing customer at the command prompt.


Lesson 3: Select the rows from the table

The following procedure retrieves rows from the table and prints them on the command line.

toggle To list the rows in the table

  1. Add the method below to customer.cpp. This method carries out the following tasks.

    • Opens the Table object.

    • Retrieves the column identifiers.

    • Sets the current position before the first row of the table.

      Any operations on a table are carried out at the current position. The position may be before the first row, on one of the rows of the table, or after the last row. By default, as in this case, the rows are ordered by their primary key value (id). To order rows in a different way, you can add an index to an UltraLite database and open a table using that index.

    • For each row, the id and name are written out. The loop carries on until the Next method returns false, which occurs after the final row.

    • Closes the Table object.

    bool do_select( Connection * conn ) {
  Table * table = conn->OpenTable( UL_TEXT("customer") );
  if( table == NULL ) {
  return false;
  }
  TableSchema * schema = table->GetSchema();
  if( schema == NULL ) {
    table->Release();
    return false;
  }
  ul_column_num id_cid = schema->GetColumnID( UL_TEXT("id") );
  ul_column_num fname_cid = schema->GetColumnID( UL_TEXT("fname") );
  ul_column_num lname_cid = schema->GetColumnID( UL_TEXT("lname") );
  schema->Release();
  while( table->Next() ) {
    ul_char fname[ MAX_NAME_LEN ];
    ul_char lname[ MAX_NAME_LEN ];
    table->Get( fname_cid ).GetString( fname, MAX_NAME_LEN );
    table->Get( lname_cid ).GetString( lname,  MAX_NAME_LEN );
    _tprintf( "id=%d, name=%s %s\n", (int)table->Get( id_cid ), fname, lname );
  }
  table->Release();
  return true;
}

  2. Add the following line to the main() method, immediately after the call to the insert method:

    do_select(conn);

  3. Compile your application by running nmake.

  4. Run your application by typing customer at the command prompt.


Lesson 4: Add synchronization to your application

This lesson synchronizes your application with a consolidated database running on your computer.

The following procedures add synchronization code to your application, start the MobiLink synchronization server, and run your application to synchronize.

Note
This lesson uses MobiLink synchronization, which is part of SQL Anywhere Studio. You must have SQL Anywhere Studio installed on your computer to carry out this lesson.

The UltraLite database you created in the previous lessons synchronizes with the UltraLite 9.0 Sample database. The UltraLite 9.0 sample database has a ULCustomer table whose columns match those in the customer table of your UltraLite database.

This lesson assumes that you are familiar with MobiLink synchronization.

toggle To add synchronization to your application

  1. Add the method below to customer.cpp. This method carries out the following tasks.

    • Sets the synchronization stream to TCP/IP. Synchronization can also be carried out over HTTP, ActiveSync, or HTTPS. For more information, see UltraLite Clients.

    • Sets the script version. MobiLink synchronization is controlled by scripts stored in the consolidated database. The script version identifies which set of scripts to use.

    • Sets sendColumnNames to true so the MobiLink synchronization server can generate synchronization scripts automatically.

      For more information, see Generating scripts automatically.

    • Sets the MobiLink user name. This value is used for authentication at the MobiLink synchronization server. It is distinct from the UltraLite database user ID, although in some applications you may wish to give them the same value.

    • Sets the download_only parameter to true. By default, MobiLink synchronization is two-way. This application uses download-only synchronization so that the rows in your table do not get uploaded to the sample database.

    bool do_sync( Connection * conn ) {
  ul_synch_info info;
  conn->InitSynchInfo( &info );
  info.stream = ULSocketStream();
  info.version = UL_TEXT( "ul_default" );
  info.user_name = UL_TEXT( "sample" );
  info.send_column_names = true;
  info.download_only = true;
  if( !conn->Synchronize( &info ) ) {
  handle_error( _TEXT("synchronize") );
  return false;
  }
  return true;
}

  2. Add the following line to the main() method, immediately after the call to the insert method and before the call to the select method.

    do_sync(conn);

  3. Compile your application by running nmake.

toggle To synchronize your data

  1. Start the MobiLink synchronization server.

    From a command prompt, run the following command.

    dbmlsrv9 -c "dsn=UltraLite 9.0 Sample" -v+ -zu+ -za

    The -zu+ and -za command line options provide automatic addition of users and generation of synchronization scripts.

    For more information about these options, see the MobiLink Synchronization Server Options.

  2. Run your application by typing customer at the command prompt.

    The MobiLink synchronization server window displays status messages indicating the synchronization progress. If synchronization is successful, the final message displays Synchronization complete.


Lesson 5: Deploy to a Windows CE device

The following procedure demonstrates how to deploy an UltraLite C++ Component application to a Windows CE device.

toggle To deploy to a Windows CE device

  1. Ensure that your device is connected to your computer.

  2. Start File Explorer on your device.

    Choose Start > Programs > File Explorer.

  3. Create directories to hold the UltraLite runtime and application.

    • Navigate to the root of the device. The root may be named My Device or My Pocket PC.

    • Create a directory named UltraLite.

    • Open the UltraLite directory and create subdirectories named lib and CustDB.

      \UltraLite\lib is the location for the UltraLite runtime files, and \UltraLite\CustDB is the location for the application.

  4. Copy the UltraLite runtime files to the Windows CE device.

    You can now run the application on your Windows CE device. This completes the tutorial.


Tutorial: Build an Application Using the Static C++ API

About this chapter

This chapter provides a tutorial to guide you through the process of developing a UltraLite application using the static + API. It describes how to build a very simple application, and how to add synchronization to your application.

Introduction to the UltraLite static C++ API
Lesson 1: Getting started
Lesson 2: Create an UltraLite database template
Lesson 3: Run the UltraLite generator
Lesson 4: Write the application source code
Lesson 5: Build and run your application
Lesson 6: Add synchronization to your application
Restore the sample database


Introduction to the UltraLite static C++ API

You can use the UltraLite static C++ API to develop UltraLite C/C++ programs using an API instead of embedded SQL. It provides an equivalent functionality to embedded SQL, but in the form of a C++ interface.

Base classes

The UltraLite C++ API starts with a set of base classes that represent the basic components of an UltraLite application. These are:

  • ULData Represents an UltraLite database.

  • ULConnection Represents a connection to an UltraLite database, and also handles synchronization.

  • ULCursor Provides methods used by generated table or result set objects, for accessing and modifying the data.

  • ULTable Provides methods used by generated table objects, but not by generated result set objects. This class inherits from ULCursor.

  • ULResultSet Provides methods used by generated result set objects, but not by generated table objects. This class inherits from ULCursor, and is not documented separately as it contains only methods that are in ULCursor.

  • ULStatement Represents a statement that does not return a result set, such as an INSERT or UPDATE statement. All methods of this class are generated.

Generated classes

For each application, the UltraLite generator writes out a set of classes that describe your particular UltraLite database.

  • Generated result set classes Individual SQL statements that return result sets are represented by a class, with methods for traversing the result set, and for modifying the underlying data.

  • Generated table classes Each table in the application is represented by a class, and methods on that table allow the rows of the table to be modified.

    For example, for a table named Employee, the UltraLite generator generates a class named Employee.

  • Generated statement classes Individual SQL statements that do not return result sets are represented by a simple class with an Execute method.

You use these classes in your application to access and modify data, and to synchronize with consolidated databases.

Overview


Overview

This tutorial describes how to construct a simple application using the UltraLite static C++ API. The application is a Windows console application, developed using Microsoft Visual C++, which queries data in the ULProduct table of the UltraLite 9.0 Sample database.

The tutorial takes you through configuration of Visual C++, in such a way that users of other development platforms should be able to identify the steps required. These steps are supplied so that you can start development of your own applications.

In the tutorial, you write and build an application that carries out the following tasks.

  1. Connects to an UltraLite database, consisting of a single table. The table is a subset of the ULProduct table of the UltraLite Sample database.

  2. Inserts rows into the table. Initial data is usually added to an UltraLite application by synchronizing with a consolidated database. Synchronization is added later in the chapter.

  3. Writes the first row of the table to standard output.

In order to build the application, you must carry out the following steps:

  1. Design the UltraLite database in an Adaptive Server Anywhere reference database.

    Here we use a single table from the UltraLite sample database (CustDB).

  2. Run the UltraLite generator to generate the API for this UltraLite database.

    The generator writes out a C++ file and a header file.

  3. Write source code that implements the logic of the application.

    Here, the source code is main.cpp.

  4. Compile, link, and run the application.

You then add synchronization to your application.


Lesson 1: Getting started

In this tutorial, you will create a set of files, including source files and executable files. You should make a directory to hold these files. In addition, you should make a copy of the UltraLite sample database so that you can work on it, and be sure you still have the original sample database for other projects.

Copies of the files used in this tutorial can be found in the Samples\UltraLite\APITutorial subdirectory of your SQL Anywhere directory.

toggle To prepare a tutorial directory

  • Create a directory to hold the files you will create. The remainder of the tutorial assumes that this directory is c:\APITutorial.

toggle To copy the sample database

  • Make a backup copy of the UltraLite 9.0 Sample database into the tutorial directory. The UltraLite 9.0 Sample database is the file custdb.db, in the Samples\UltraLite\CustDB subdirectory of your SQL Anywhere installation directory. In this tutorial, we use the original UltraLite 9.0 Sample database, and at the end of the tutorial you can copy the untouched version from the APITutorial directory back into place.


Lesson 2: Create an UltraLite database template

In this tutorial, you use the original copy of the UltraLite 9.0 Sample database (CustDB) as a reference database. The copy you placed in the APITutorial directory serves as a backup.

An UltraLite database template is a set of tables, and columns within tables, that are to be included in your UltraLite database. You create an UltraLite database template by creating a publication in the reference database. The publication is simply a convenient device for assembling tables and column-based subsets of tables: there is no direct connection to SQL Remote or MobiLink synchronization.

You can also define your UltraLite database by adding SQL statements to the reference database. SQL statements allow you to include joins and more advanced features in your UltraLite application. Here, we build an UltraLite database template by defining tables, as it is more simple.

The tutorial uses SQL statements to define the UltraLite database.

For an example of how to add SQL statements to a database, see Lesson 1: Getting started.

toggle To create the UltraLite database template

  1. Start Sybase Central.

  2. Connect to the UltraLite 9.0 Sample database.

    • Choose Tools > Connect.

    • If a list of plugins is displayed, choose Adaptive Server Anywhere 9.

    • In the Connect dialog, choose the UltraLite 9.0 Sample ODBC data source.

    • Click OK to connect.

  3. Create a publication that describes the data you wish to include in your UltraLite database.

    • In Sybase Central, open the custdb database.

    • Open the Publications folder. Choose File > New > Publication.

      The Publication Creation wizard appears.

    • Name the publication ProductPub.

    • Add the ULProduct table to the publication, including all columns in the publication.

    • Click Finish to create the publication.

You have now finished designing the UltraLite database template. Leave Sybase Central and the database server running for the next lesson.


Lesson 3: Run the UltraLite generator

The UltraLite generator writes a C++ file and a header file that define an interface to the UltraLite database, as specified in the UltraLite database template.

toggle To generate the UltraLite interface code

  1. From a command prompt, change directory to your APITutorial directory.

  2. Run the UltraLite generator with the following arguments (all on one line):

    ulgen -c "dsn=UltraLite 9.0 Sample" –t c++ -u ProductPub -f ProductPubAPI

    The generator writes out the following files:

    • ProductPubAPI.hpp This file contains prototypes for the generated API. You should inspect this file to determine the API you can use in your application .

    • ProductPubAPI.cpp This file contains the interface source. You do not need to look at this file.

    • ProductPubAPI.h This file contains internal definitions required by UltraLite. You do not need to look at this file.


Lesson 4: Write the application source code

The following procedure creates a C++ source file containing the application source code. This code does not contain error checking or other features that you would require in a complete application. It is provided as a simplified application, for illustrative purposes only.

You can find the source code in Samples\UltraLite\APITutorial\sample.cpp, although you may have to edit the file to uncomment the inserts.

toggle To write the application source code

  1. In Microsoft Visual C++, choose File > New.

  2. On the Files tab, choose C++ Source File. Click OK.

  3. Copy and paste the following source code into a file named sample.cpp in your APItutorial directory.

    // (1) include headers
#include <stdio.h>
#include "ProductPubAPI.hpp"

void main() {
   // (2) declare variables
   long price;
   ULData db;
   ULConnection conn;
   ULProduct productTable;

   // (3) connect to the UltraLite database
   db.Open() ;
       conn.Open( &db, "dba", "sql" );
   productTable.Open( &conn );

   // (4) insert sample data
   productTable.SetProd_id( 1 );
   productTable.SetPrice( 400 );
   productTable.SetProd_name( "4x8 Drywall x100" );
   productTable.Insert();

   productTable.SetProd_id( 2 );
   productTable.SetPrice( 3000 );
   productTable.SetProd_name( "8' 2x4 Studs x1000" );
   productTable.Insert();

   // (5) Write out the price of the items
   productTable.BeforeFirst();
   while( productTable.Next() ) {
      productTable.GetPrice( price );
      printf("Price: %d\n", price );
   }

   // (6) close the objects to finish
   productTable.Close();
   conn.Close();
   db.Close();
}
Explanation

The numbered comments in the code indicate the main tasks this routine carries out:

  1. Include headers.

    In addition to stdio.h, you need to include the generated header file ProductPubAPI.hpp to include the generated classes describing the Product table. This file includes the UltraLite header file ulapi.h.

  2. Declare variables.

    The UltraLite database is declared as an instance of class ULData, and the connection to the database is an instance of class ULConnection. These classes are included from ulapi.h.

    The table is declared as an instance of class ULProduct, a generated name derived from the name of the table in the reference database.

  3. Connect to the database.

    Opening each of the declared objects establishes access to the data. Opening the database requires no arguments; opening a connection requires a user ID and password, and also the name of the database. Opening the table requires the name of the connection.

  4. Insert sample data.

    In a production application, data is entered into the database by synchronizing. It is a useful practice to insert some sample data during the initial stages of development, and include synchronization at a later stage.

    The method names in the ULProduct class are unique names that reflect the columns of the table in the reference database.

    Synchronization is added to this routine in Lesson 6: Add synchronization to your application.

  5. Write out the price of each item.

    The price is retrieved and written out for each row in the table.

  6. Close the objects.

    Closing the objects used in the program frees the memory associated with them.


Lesson 5: Build and run your application

You can compile and link your application in the development tool of your choice. In this section, we describe how to compile and link using Visual C++; if you are using one of the other supported development tools, modify the instructions to fit your tool.

  1. Start Microsoft Visual C++ from your desktop in the standard fashion.

  2. Configure Visual C++ to search the appropriate directories for UltraLite header files and library files.

    Select Tools > Options and click on the Directories tab. In the Show Directories For dropdown list, choose Include Files. Include the following directory, so that the header files can be accessed.

    C:\Program Files\Sybase\SQL Anywhere 9\h

    On the same tab, select Library Files under the Show Directories For dropdown menu. Include the following directory so that the UltraLite library files can be accessed.

    C:\Program Files\Sybase\SQL Anywhere 9\ultralite\win32\386\lib

    Click OK to submit the changes.

  3. Create a project named APITutorial (it should have the same name as the directory you have used to hold your files).

    • Select File > New. The New dialog is displayed.

    • On the Projects tab choose Win32 Console Application.

    • Specify a project name of APITutorial.

    • Specify the APITutorial directory as its location.

    • Select Create a New Workspace and click OK.

    • Choose to create An Empty Project and click Finish.

    • On the Workspace window, click the FileView tab. The workspace tutorial consists of just the APITutorial project. Double-click APITutorial files to display the three folders: Source Files, Header Files, Resource Files.

  4. Configure the project settings.

    • Right-click APITutorial files and select Settings.

      The Project Settings dialog is displayed.

    • From the Settings For dropdown menu, choose All Configurations.

    • Click the Link tab. Add the following runtime library to the Object/Library Modules box.

      ulimp.lib

    • Click the C/C++ tab. From the Category dropdown menu, choose General. Add the following to the Preprocessor definitions list:

      __NT__,UL_USE_DLL

      Here, __NT__ has two underscores either side of NT.

    • Click OK to finish.

  5. Add sample.cpp and ProductPubAPI.cpp to the project.

    • Right-click the Source Files folder and select Add Files to Folder. Locate sample.cpp and click OK. Open the Source Files folder to verify that it contains sample.cpp.

    • Repeat to add the generated ProductPubAPI.cpp file to the project.

  6. Add the file containing the base classes for the UltraLite API to the project.

    • Right-click the Source Files folder and choose Add Files to Folder. Browse to ulapi.cpp, located in the src subdirectory of your SQL Anywhere installation. Click OK.

  7. Compile and link the application.

    • Select Build > Build APITutorial.exe to compile and link the executable. Depending on your settings, the APITutorial.exe executable may be created in a Debug directory within your APITutorial directory.

  8. Run the application.

    • Select Build > Execute APITutorial.exe.

    A command prompt window appears and displays the prices of the products in the product table.

You have now built and run a simple UltraLite application. The next step is to add synchronization to your application.


Lesson 6: Add synchronization to your application

UltraLite applications exchange data with a consolidated database. In this lesson, you add synchronization to the simple application you created in the previous section. In addition, you change the output to verify that synchronization has taken place.

Adding synchronization actually simplifies the code. Your initial version of main.cpp has the following lines, that insert data into your UltraLite database.

productTable.SetProd_id( 1 );
productTable.SetPrice( 400 );
productTable.SetProd_name( "4x8 Drywall x100" );
productTable.Insert();

productTable.SetProd_id( 2 );
productTable.SetPrice( 3000 );
productTable.SetProd_name( "8' 2x4 Studs x1000" );
productTable.Insert();

This code is included to provide an initial set of data for your application. In a production application, you would usually not insert an initial copy of your data from source code, but instead carry out a synchronization.

toggle To add synchronization to your application

  1. Add a synchronization information structure to your code.

    • Add the following line immediately after the line that says // (2) declare variables.

      auto ul_synch_info synch_info;

      This structure holds the parameters that control the synchronization.

  2. Replace the explicit inserts with a synchronization call.

    • Delete the productTable methods listed above.

    • Add the following lines in their place:

      conn.InitSynchInfo( &synch_info );
synch_info.user_name = UL_TEXT( "50" );
synch_info.version = UL_TEXT( "custdb 9.0" );
synch_info.stream = ULSocketStream();
synch_info.stream_parms =
   UL_TEXT("host=localhost");
conn.Synchronize( &synch_info );

      The value of 50 is the MobiLink user name.

      The string custdb instructs MobiLink to use the default script version for synchronization.

      ULSocketStream() instructs the application to synchronize over TCP/IP, and host=localhost specifies the host name of the MobiLink server, which in this case is the current machine.

  3. Compile and link your application.

    • Select Build > Build APITutorial.exe to compile and link the executable. Depending on your settings, the APITutorial.exe executable may be created in a Debug directory within your APITutorial directory.

  4. Start the MobiLink server running against the sample database.

    From a command prompt in your APITutorial directory, enter the following command:

    start dbmlsrv9 -c "dsn=UltraLite 9.0 Sample"

  5. Run your application.

    From the Build menu, choose Execute APITutorial.exe.

    The application connects, synchronizes to receive data, and writes out information to the command prompt window. The output is as follows:

    The ULData object is open
Price: 400
Price: 3000
Price: 40
Price: 75
Price: 100
Price: 400
Price: 3000
Price: 75
Price: 40
Price: 100


Restore the sample database

Now that you have completed the tutorial, you should restore the sample database so that it can be used again. You created a copy of the UltraLite 9.0 Sample database in Lesson 1: Getting started. You can now replace the version of custdb.db that you just changed with the copy.

toggle To restore the sample database

  1. Copy the custdb.db file from your tutorial directory to the UltraLite\Samples\CustDB subdirectory of your SQL Anywhere directory.

  2. In the same directory, delete the transaction log file custdb.log.

Your sample database is now restored to its original state.


Tutorial: Build an Application Using Embedded SQL

About this chapter

This chapter provides a tutorial to guide you through the process of developing an embedded SQL UltraLite application using eMbedded Visual C++.

For an overview of the development process and background information on the UltraLite database, see Developing embedded SQL applications.

For information on developing embedded SQL UltraLite Applications, see Developing Applications Using Embedded SQL.

For a description of embedded SQL, see Embedded SQL API Reference.

Introduction
Lesson 1: Configure eMbedded Visual C++
Lesson 2: Write an embedded SQL source file
Lesson 3: Build the sample embedded SQL UltraLite application
Lesson 4: Add synchronization to your application


Introduction

In this tutorial, you create an embedded SQL source file and use it to build a simple UltraLite application. This UltraLite application can be executed on a remote device.

This tutorial assumes that you have UltraLite and Microsoft eMbedded Visual Tools installed on your computer. If you use a different C/C++ development tool, you will have to translate the eMbedded Visual C++ instructions into their equivalent for your development tool.

toggle To prepare for the tutorial

  • Create a directory to hold the files you will create.

    The remainder of the tutorial assumes that this directory is c:\tutorial\.


Lesson 1: Configure eMbedded Visual C++

The following procedure configures eMbedded Visual C++ for UltraLite development. You may need to add additional library and include paths.

toggle To configure eMbedded Visual C++ for UltraLite development

  1. Start Microsoft eMbedded Visual C++ 3.0.

    From the Start menu, choose Programs > Microsoft Visual Tools > eMbedded Visual C++ 3.0

  2. Configure eMbedded Visual C++ to search the appropriate directories for embedded SQL header files and UltraLite library files.

    1. Select Tools > Options.

      The Options dialog is displayed.

    2. Click the Directories tab

    3. For each target platform and CPU combination,

      • Choose Include Files under the Show Directories For dropdown menu. Include the following directory, so that the embedded SQL header files are accessible.

        C:\Program Files\Sybase\SQL Anywhere 9\h

        If you have installed SQL Anywhere to a directory other than the default, substitute the \h subdirectory of your installation.

      • Choose Library Files under the Show Directories For dropdown menu. Include the UltraLite \lib directory, located in a platform-specific directory. For example, for the Pocket PC emulator, choose the following:

        C:\Program Files\Sybase\SQL Anywhere 9\UltraLite\ce\emulator30\lib

    4. Click OK.


Lesson 2: Write an embedded SQL source file

The following procedure creates a sample program that establishes a connection with the UltraLite CustDB sample database and executes a query.

toggle To build the sample embedded SQL UltraLite application

  1. Start Microsoft eMbedded Visual C++.

    Choose Start > Programs > Microsoft eMbedded Visual Tools > eMbedded Visual C++.

  2. Create a new workspace named UltraLite:

    • Select File > New.

    • Click the Workspaces tab.

    • Choose Blank Workspace. Specify a workspace name UltraLite and specify C:\tutorial as the location to save this workspace. Click OK.

      The UltraLite workspace is added to the Workspace window.

  3. Create a new project named esql and add it to the UltraLite workspace.

    • Select File > New.

    • Click the Projects tab.

    • Choose WCE Pocket PC 2002 Application. Specify a project name esql and select Add To Current Workspace. Select the applicable CPUs. Click OK.

    • Choose Create An Empty Project and click Finish.

      The project is saved in the c:\tutorial\esql folder.

  4. Create the sample.sqc source file.

    • Choose File > New.

    • Click the Files tab.

    • Select C++ Source File.

    • Select Add to Project and select esql from the dropdown list.

    • Name the file sample.sqc. Click OK.

    • Copy the following source code into the file:

      #include <stdio.h>
#include <wingdi.h>
#include <winuser.h>
#include <string.h>
#include "uliface.h"
EXEC SQL INCLUDE SQLCA;
int WINAPI WinMain( HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nShowCmd)
{
   /* Declare fields */
   EXEC SQL BEGIN DECLARE SECTION;
      long pid=1;
      long cost;
      char pname[31];
   EXEC SQL END DECLARE SECTION;
   /* Before working with data*/
   db_init(&sqlca);
   /* Connect to database */
   EXEC SQL CONNECT "DBA" IDENTIFIED BY "SQL";
   /* Fill table with data first */
   EXEC SQL INSERT INTO ULProduct(
         prod_id, price, prod_name)
      VALUES (1, 400, '4x8 Drywall x100');
   EXEC SQL INSERT INTO ULProduct (
         prod_id, price, prod_name)
      VALUES (2, 3000, '8''2x4 Studs x1000');
   EXEC SQL COMMIT;
   /* Fetch row from database */
   EXEC SQL SELECT price, prod_name
         INTO :cost, :pname
         FROM ULProduct
         WHERE prod_id= :pid;
   /* Error handling.  If the row does not exist,
      or if    an error occurs, -1 is returned */
   if((SQLCODE==SQLE_NOTFOUND)||(SQLCODE<0)) {
      return(-1);
   }
      /* Print query results */
   wchar_t query[100];
   wchar_t result[10];
   wchar_t wpname[31];
   mbstowcs(wpname, pname, 31);
   wcscpy(query, L"Product id: ");
   _ltow(pid, result, 10);
   wcscat(query, result);
   wcscat(query, L" Price: ");
   _ltow(cost, result, 10);
   wcscat(query, result);
   wcscat(query, L" Product name: ");
   wcscat(query, wpname);
   wcscpy(result, L"Result");
   MessageBox(NULL, query, result, MB_OK);
   /* Preparing to exit:
   rollback any outstanding changes and disconnect */
   EXEC SQL DISCONNECT;
   db_fini(&sqlca);
   return(0);
}

    • Save the file.

  5. Configure the sample.sqc source file settings to invoke the SQL preprocessor to preprocess the source file:

    • Right-click sample.sqc in the Workspace window and select Settings.

      The Project Settings dialog appears.

    • From the Settings For drop down menu, choose All Configurations.

    • In the Custom Build tab, enter the following statement in the Commands box. Ensure that the statement is entered all on one line.

      The following statement runs the SQL preprocessor sqlpp on the sample.sqc file, and writes the processed output in a file named sample.cpp. The SQL preprocessor translates SQL statements in the source file into C/C++.

      "%asany9%\win32\sqlpp.exe" -q -o WINDOWS -c  "dsn=Ultralite 9.0 Sample" $(InputPath) sample.cpp

      For more information about the SQL preprocessor, see The SQL preprocessor.

    • Specify sample.cpp in the Outputs box.

    • Click OK to submit the changes.

  6. Start the Adaptive Server Anywhere personal database server.

    By starting the database server, both the SQL preprocessor and the UltraLite analyzer will have access to your reference database. The sample application uses the CustDB sample database custdb.db as a reference database and as consolidated database.

    Start the database server at the command line from the Samples\UltraLite\CusDB directory containing custdb.db as follows:

    dbeng9 custdb.db

    Alternatively, you can start the database server by selecting Start > Programs > SQL Anywhere 9 > UltraLite > Personal Server Sample for UltraLite.

  7. Preprocess the sample.sqc file.

    Because the sample application consists of only one source file, the preprocessor automatically runs the UltraLite analyzer as well and appends extra C/C++ code to the generated source file.

    • Select sample.sqc in the Workspace window. Choose Build > Compile sample.sqc. A sample.cpp file will be created and saved in the tutorial\esql folder.

  8. Add sample.cpp to the project:

    • Right-click the Source Files folder in the Workspace window and select Add Files to Folder.

    • Browse to c:\tutorial\esql\sample.cpp and click OK.

      The sample.cpp file appears inside the Source Files folder.

Explanation of the sample program


Explanation of the sample program

Although the sample program is simple, it contains elements that must be present in every embedded SQL source file used for database access.

The following list describes the key elements in the sample program. Use these steps as a guide when creating your own embedded SQL UltraLite application.

  1. Include the appropriate header files.

    The sample program uses standard I/O, therefore the stdio.h header file has been included.

  2. Define the SQL communications area, sqlca.

    Use the following command:

    EXEC SQL INCLUDE SQLCA;

    This definition must be your first embedded SQL statement, so place it at the end of your include list.

    Prefix SQL statements
    All SQL statements must be prefixed with the keywords EXEC SQL and must end with a semicolon.

  3. Define host variables by creating a declaration section.

    Host variables are used to send values to the database server or receive values from the database server. Create a declaration section as follows:

    EXEC SQL BEGIN DECLARE SECTION;
   long pid=1;
   long cost;
   char pname[31];
EXEC SQL END DECLARE SECTION;

    For information about host variables, see Using host variables.

  4. Call the embedded SQL library function db_init to initialize the UltraLite runtime library.

    Call this function as follows:

    db_init(&sqlca);

  5. Connect to the database using the CONNECT statement.

    To connect to the UltraLite sample database, you must supply the login user ID and password. Connect as user DBA with password SQL as follows:

    EXEC SQL CONNECT "DBA" IDENTIFIED BY "SQL";

  6. Insert data into database tables.

    When an application is first started, its database tables are empty. When you synchronize the remote database with the consolidated database, the tables are filled with values so that you may execute select, update or delete commands.

    Rather than using synchronization, this sample code directly inserts data into the tables. Directly inserting data is a useful technique during the early stages of UltraLite development.

    If you use synchronization and your application fails to execute a query, it can be due to a problem in the synchronization process or due to a mistake in your program. To locate the source of failure may be difficult. If you directly fill tables with data in your source code rather than perform synchronization, then, if your application fails, you will know automatically that the failure is due to a mistake in your program.

    After you have tested that there are no mistakes in your program, remove the insert statements and replace them with a call to the ULSynchronize function to synchronize the remote database with the consolidated database.

    For information on adding synchronization to an UltraLite application, see Lesson 4: Add synchronization to your application.

  7. Execute your SQL query.

    The sample program executes a select query that returns one row of results. The results are stored in the previously defined host variables cost and pname.

  8. Perform error handling.

    The sample program executes a select request that returns an error code, sqlcode. This code is negative if an error occurs; SQL_NOTFOUND is returned if there are no query results. The sample program handles these errors by returning –1.

  9. Disconnect from the database.

    You should rollback or commit any outstanding changes before disconnecting.

    To disconnect, use the DISCONNECT statement as follows:

    EXEC SQL DISCONNECT;

  10. End your SQL work with a call to the library function db_fini:

    db_fini(&sqlca);


Lesson 3: Build the sample embedded SQL UltraLite application

The following procedure uses the source file generated in the previous lesson, sample.cpp, to create the sample embedded SQL UltraLite application.

toggle To build the sample embedded SQL UltraLite application

  1. Ensure that the Adaptive Server Anywhere personal database server is still running.

  2. Configure the project settings:

    • Right-click esql and select Settings.

      The Project Settings dialog appears.

    • Select All Configurations under the Settings For drop down menu.

    • Click the Link tab and add the following runtime library to the Object/Library Modules box.

      ulimp.lib

    • Click the C/C++ tab. Select Preprocessor from the Category drop-down menu. Ensure that the following are included in the Preprocessor definitions:

      __NT__

    • Click OK to close the dialog.

  3. Build the executable:

    • Select Build > Build esql.exe.

      The esql executable is created. Depending on your settings, the executable may be created in a Debug directory within your tutorial directory.

  4. Run the application:

    • Select Build > Execute esql.exe.

      A screen appears and displays the first row of the product table.


Lesson 4: Add synchronization to your application

Once you have tested that your program is functioning properly, you can replace the code that manually insert data into the ULProduct table with instructions to synchronize the remote database with the consolidated database. Synchronization will fill the tables with data and you can subsequently execute a select query.


Synchronization via TCP/IP

You can synchronize the remote database with the consolidated database using a TCP/IP socket connection. Call ULSynchronize with the ULSocketStream() stream.

In order to synchronize with the CustDB consolidated database, the employee ID must be supplied. This ID identifies an instance of an application to the MobiLink server. You may choose a value of 50, 51, 52, or 53. The MobiLink server uses this value to determine the download content, to record the synchronization state, and to recover from interruptions during synchronization.

For more information about the ULSynchronize function, see ULSynchronize function.


Running the sample application with synchronization

After you have made changes to sample.sqc, you must preprocess sample.sqc and rebuild esql.exe.

toggle To synchronize your application

  1. Ensure that the Adaptive Server Anywhere database server is still running.

  2. Delete the INSERT commands and add the following code. Replace your-pc with the name of your computer.

    auto ul_synch_info synch_info;
ULInitSynchInfo( &synch_info );
synch_info.user_name = UL_TEXT("50");
synch_info.version = UL_TEXT("custdb 9.0");
synch_info.stream = ULSocketStream();
synch_info.send_column_names = ul_true;
synch_info.stream_parms = UL_TEXT("host=your-pc;port=2439");
ULSynchronize( &sqlca, &synch_info );

  3. Preprocess sample.sqc.

    Choose Build > Compile sample.sqc to recompile the altered file. When prompted, choose to reload sample.cpp.

  4. Build the executable.

    Select Build > Build esql.exe to build the sample executable.

  5. Start the MobiLink synchronization server.

    At a command prompt, execute the following command on a single line:

    dbmlsrv9 –c "DSN=UltraLite 9.0 Sample" –o ulsync.mls –vcr –x tcpip -za

  6. Run the application:

    • Select Build > Execute esql.exe to run the sample application.

      The remote database will be synchronized with the consolidated database, filling the tables in the remote database with data. The select query in the sample application will be processed, and a row of query results will appear on the screen.


Tutorial: Build an Application Using ODBC

About this chapter

This chapter walks you through the creation of an UltraLite ODBC application.

Introduction to UltraLite ODBC
Lesson 1: Getting started
Lesson 2: Create an UltraLite database schema file
Lesson 3: Connect to the database
Lesson 4: Insert data into the database
Lesson 5: Query the database


Introduction to UltraLite ODBC

ODBC is a standard database programming interface. UltraLite supports a subset of the ODBC interface, together with extensions to permit synchronization. For a listing of the functions UltraLite supports, see UltraLite ODBC API Reference.

This section walks you through the creation of a simple UltraLite ODBC application. It does not provide an extensive guide to ODBC programming, as the main reference for ODBC is the Microsoft [external link] ODBC SDK documentation.

UltraLite ODBC does not share some features with other C/C++ interfaces. In particular, the functions listed in UltraLite C/C++ Common API Reference cannot be used from UltraLite ODBC.


Lesson 1: Getting started

In this tutorial, you will create a set of files, including source files and executable files. You should make a directory to hold these files. In the remainder of the tutorial, it is assumed the directory is c:\tutorial\ulodbc. If you choose a different name, use that name throughout.

The ODBC interface does not depend on any particular C/C++ compiler or development environment. The tutorial uses a makefile with Microsoft's nmake syntax. If you are using a different development environment, make the appropriate substitutions.

toggle Create and test your build environment

  1. Add the following code to a file called makefile in your tutorial directory:

    IncludeFolders= /I"$(ASANY9)\h"

CompileOptions=/c /nologo /W3 /Od /Zi /DWIN32 /DUL_USE_DLL

LibraryFolders= \
/LIBPATH:"$(ASANY9)\ultralite\win32\386\lib"

Libraries= ulimp.lib

LinkOptions=/NOLOGO /DEBUG

sample.exe: sample.obj
   link $(LinkOptions) sample.obj $(LibraryFolders) $(Libraries)

sample.obj: sample.cpp
   cl $(CompileOptions) $(IncludeFolders) sample.cpp

    These options compile a source file called sample.cpp into an executable sample.exe, using the UltraLite import library for Windows (ulimp.lib). They rely on the environment variable ASANY9, which is defined as your SQL Anywhere installation directory.

  2. Add the following code to a file called sample.cpp in your tutorial directory:

    #include "ulodbc.h"
#include <stdio.h>
#include <tchar.h>
int main() {
    return 0;
}

    This application simply returns 0 to the calling environment.

  3. Compile and link sample.cpp.

    If you are using the Microsoft compiler, type nmake at a command prompt to compile and link your application. Otherwise, use the command appropriate for your development environment.

    Compiling and linking the application confirms that your build environment is set up properly. You are now ready for the rest of the tutorial.


Lesson 2: Create an UltraLite database schema file

The database schema holds the table definitions. This tutorial uses a simple one-table database. It is the same schema as used in other UltraLite component tutorials.

This section assumes you can use the UltraLite Schema Painter to create a schema file.

For more information about creating a database schema, see the Lesson 1: Create an UltraLite database schema.

toggle Create a database schema

  • Create a database schema using the UltraLite Schema Painter.

    To start the UltraLite Schema Painter, choose Start > Programs > SQL Anywhere Studio 9 > UltraLite > UltraLite Schema Painter.

    Create your schema as follows:

    • Schema filename c:\tutorial\ulodbc\customer.usm

    • Table name customer

    • Columns in customer

      Column Name | Data Type (Size) | Column allows NULL values? | Default value
      id | integer | No | autoincrement
      fname | char(15) | No | None
      lname | char(20) | No | None
      city | char(20) | Yes | None
      phone | char(12) | Yes | 555-1234

    • Primary key ascending id


Lesson 3: Connect to the database

UltraLite uses standard ODBC programming methods to connect to a database. Each application requires an environment handle to manage the communication with UltraLite and a connection handle for a specific connection.

toggle Write code to allocate an environment handle

  1. Add functions opendb and closedb to sample.cpp:

    static SQLHANDLE opendb( void ){
    SQLRETURN retn;
    SQLHANDLE henv;
    retn = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv );
    if( retn == SQL_SUCCESS ){
        _tprintf( "success in opendb: %d.\n", retn );
        return henv;
    } else {
        _tprintf( "error in opendb: %d.\n", retn );
        return henv;
    }
}

static void closedb( SQLHANDLE henv ){
    SQLRETURN retn;
    retn = SQLFreeHandle( SQL_HANDLE_ENV, henv );
}

    These functions do not connect to the database, they simply allocate the environment handle henv that manages UltraLite features.

  2. Call opendb and closedb from the main() function.

    Alter your main() function in sample.cpp so that it reads as follows:

    int main() {
    SQLHANDLE henv;
    henv = opendb();
    closedb( henv );
    return 0;
}

  3. Compile, link, and run your application to confirm that the application builds properly.

For more information about the functions called in this procedure, see SQLAllocHandle function, and SQLFreeHandle function.

The next step is to connect to the UltraLite database

toggle Write code to connect to your database

  1. Add functions connect and disconnect to sample.cpp:

    static SQLHANDLE connect ( SQLHANDLE henv ){
    SQLRETURN retn;
    SQLHANDLE hcon;
    retn = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hcon );
    retn = SQLConnect( hcon
     , (SQLTCHAR*)UL_TEXT(
         "schema_file=customer.usm;dbf=customer.udb" )
     , SQL_NTS
     , (SQLTCHAR*)UL_TEXT( "dba" )
     , SQL_NTS
     , (SQLTCHAR*)UL_TEXT( "sql" )
     , SQL_NTS );
    if( retn == SQL_SUCCESS ){
        _tprintf( "success in connect: %d.\n", retn );
        return hcon;
    } else {
        _tprintf( "error in connect: %d.\n", retn );
        return hcon;
    }
}

static void disconnect( SQLHANDLE hcon, SQLHANDLE henv ){
    SQLRETURN retn;
    retn = SQLDisconnect( hcon );
    retn = SQLFreeHandle( SQL_HANDLE_DBC, hcon );
}

  2. Call connect and disconnect from the main() function.

    Alter your main() function in sample.cpp so that it reads as follows:

    int main() {
    SQLHANDLE henv;
    SQLHANDLE hcon;
    henv = opendb();
    hcon = connect( henv );
    disconnect( hcon, henv );
    closedb( henv );
    return 0;
}

  3. Compile, link, and run your application to confirm that the application builds properly.

    You should see that the application creates an UltraLite database file customer.udb together with a temporary file customer.~db.

For more information about the functions called in this procedure, see SQLConnect function, and SQLDisconnect function.

You now have an application that connects to and disconnects from a database. The next step is to add some data to the database.


Lesson 4: Insert data into the database

ODBC provides a set of functions to carry out operations on the database. In this lesson we use the simplest statement, SQLExecDirect.

toggle Write code to insert data into the database

  1. Add a function insert to sample.cpp:

    static ul_bool insert( SQLHANDLE hcon )
{
    SQLRETURN retn;
    SQLHANDLE hstmt;
    retn = SQLAllocHandle( SQL_HANDLE_STMT, hcon, &hstmt );
    static const ul_char * sql = UL_TEXT(
     "INSERT customer( id, fname, lname ) VALUES ( 42, 'jane', 'doe' )" );
    retn = SQLExecDirect( hstmt, (SQLTCHAR*)sql, SQL_NTS );
    if( retn == SQL_SUCCESS ) {
        _tprintf( "success in insert.\n" );
    } else {
        _tprintf( "error in insert: %d.\n", retn );
    retn = SQLFreeHandle( SQL_HANDLE_STMT, hstmt );
    hstmt = 0;
    }
    return retn == SQL_SUCCESS;
}

  2. Call insert from the main() function.

    Alter your main() function in sample.cpp so that it reads as follows:

    int main() {
    SQLHANDLE henv;
    SQLHANDLE hcon;
    henv = opendb();
    hcon = connect( henv );
    insert( hcon );
    disconnect( hcon, henv );
    closedb( henv );
    return 0;
}

  3. Compile, link, and run your application to confirm that the application builds properly.

    You should see that the application reports success on inserting the data.

For more information about the function called in this procedure, see SQLExecDirect function.


Lesson 5: Query the database

In order to process query result sets, ODBC requires that statements be prepared before they are executed. In this lesson you prepare and execute a statement, and print out the results.

toggle Write code to query the database

  1. Add functions prepare, execute, and fetch to sample.cpp:

    static SQLHANDLE prepare( SQLHANDLE hcon ){
    SQLRETURN retn;
    SQLHANDLE hstmt;
    static const ul_char * sql =
        UL_TEXT( "SELECT id, fname, lname FROM customer" );
    retn = SQLAllocHandle( SQL_HANDLE_STMT, hcon, &hstmt );
    retn = SQLPrepare( hstmt, (SQLTCHAR*)sql, SQL_NTS );
    if( retn == SQL_SUCCESS ) {
        _tprintf( "success in prepare.\n" );
    } else {
        _tprintf( "error in prepare: %d.\n", retn );
        retn = SQLFreeHandle( SQL_HANDLE_STMT, hstmt );
        hstmt = 0;
    }
    return hstmt;
}

    The prepare function does not execute the SQL statement.

    static ul_bool execute( SQLHANDLE hstmt )
{
    SQLRETURN retn;
    retn = SQLExecute( hstmt );
    if( retn == SQL_SUCCESS ) {
        _tprintf( "success in execute.\n" );
    } else {
        _tprintf( "error in execute: %d.\n", retn );
    retn = SQLFreeHandle( SQL_HANDLE_STMT, hstmt );
    hstmt = 0;
    }
    return retn == SQL_SUCCESS;
}

    The execute function executes the query, but does not make the result set directly available to the client application. Your application must explicitly fetch the rows it needs from the result set.

    static ul_bool fetch( SQLHANDLE hstmt )
{
#define NAME_LEN 20
    SQLCHAR      fName[NAME_LEN], lName[NAME_LEN];
    SQLINTEGER   id;
    SQLINTEGER     cbID = 0, cbFName = SQL_NTS, cbLName = SQL_NTS;
    SQLRETURN    retn;

    SQLBindCol( hstmt, 1, SQL_C_ULONG, &id, 0, &cbID );
    SQLBindCol( hstmt, 2, SQL_C_CHAR,
                fName, sizeof(fName), &cbFName );
    SQLBindCol( hstmt, 3, SQL_C_CHAR,
                lName, sizeof(lName), &cbLName );
    while ( ( retn = SQLFetch( hstmt ) ) != SQL_NO_DATA ){
        if (retn == SQL_SUCCESS || retn == SQL_SUCCESS_WITH_INFO){
            fName[ cbFName ] = '\0';
            lName[ cbLName ] = '\0';
            _tprintf( "%20s %d %20s\n", fName, id, lName );
        } else {
            _tprintf ( "error while fetching: %d.\n", retn );
            break;
        }
    }
    return retn == SQL_SUCCESS;
}

    The values are fetched into variables that have been bound to the column. String variables are not returned with a null terminator, and so the null terminator is added for printing purposes. The length of the actual string that was returned is available in the final parameter of SQLBindCol.

  2. Call prepare, execute, and fetch from the main() function.

    Alter your main() function in sample.cpp so that it reads as follows:

    int main() {
    SQLHANDLE henv;
    SQLHANDLE hcon;
    SQLHANDLE hstmt;

    henv = opendb();
    hcon = connect( henv );
    insert( hcon );
    hstmt = prepare( hcon );
    execute( hstmt );
    fetch( hstmt );
    SQLFreeHandle( SQL_HANDLE_STMT, hstmt );
    disconnect( hcon );
    closedb( henv );
    return 0;
}

  3. Compile, link, and run your application to confirm that the application builds properly.

    You should see that the application prints out the row you inserted.

For more information about the functions called in this procedure, see SQLPrepare function, SQLExecute function, SQLBindCol function, and SQLFetch function.

This completes the tutorial.


UltraLite C/C++ Common API Reference

About this chapter

This chapter lists functions and macros that are for use from any of the embedded SQL, static C++ API, or C++ Component interfaces. They cannot be used from ODBC.

The functions in this chapter all require a SQL Communications Area. For more information, see Common Features of UltraLite C/C++ Interfaces.

Callback function for ULRegisterErrorCallback
Callback function for ULRegisterSchemaUpgradeObserver
ULEnableFileDB function
ULEnableGenericSchema function (deprecated)
ULEnablePalmRecordDB function
ULEnableStrongEncryption function
ULEnableUserAuthentication function
ULRegisterErrorCallback function
ULRegisterSchemaUpgradeObserver function
ULStoreDefragFini function
ULStoreDefragInit function
ULStoreDefragStep function
Macros and compiler directives for UltraLite C/C++ applications


Callback function for ULRegisterErrorCallback

Handle errors that the UltraLite runtime signals to your application.

Prototype

ul_error_action UL_GENNED_FN_MOD error-callback-function(
SQLCA * sqlca,
ul_error_kind kind,
ul_void * user_data,
ul_char * buffer
)

Parameters

  • error-callback-function The name of your function. You must supply the name to ULRegisterErrorCallback. See ULRegisterErrorCallback function.

  • sqlca A pointer to the SQL communications area (SQLCA).

    The SQLCA contains the SQL code in sqlca->sqlcode. Any error parameters have already been retrieved from the SQLCA and stored in buffer.

    This sqlca pointer does not necessarily point to the SQLCA in your application, and cannot be used to call back to UltraLite. It is used only to communicate the SQL code to the callback.

    In the static C++ API the SQLCA is declared in the header file as sqlca. In the C++ Component use the Sqlca.GetCA() method.

  • kind The kind of error that UltraLite is signaling. One of the following constants:

    • UL_ERROR_KIND_MEDIA_REMOVED The media card containing the database has been removed and must be re-inserted for the current I/O operation to succeed.

      A common action to take for this kind of error is to prompt the user to insert the media card.

      For this kind of error, the buffer holds the database filename.

    • UL_ERROR_KIND_SQLCODE A SQL error. The SQLCA contains the SQL code in sqlca->sqlcode. SQL codes and their meanings are listed in Error messages indexed by Adaptive Server Anywhere SQLCODE. The returned error action is ignored for this kind of error; the operation is always canceled.

  • user_data The user data supplied to ULRegisterErrorCallback. UltraLite does not change this data in any way. As the callback function may be signaled anywhere in your application, the user_data argument is an alternative to creating a global variable.

  • buffer The buffer supplied when the callback function was registered. UltraLite fills the buffer with a string holding any substitution parameters for the error message. To keep UltraLite as small as possible, UltraLite does not supply error messages themselves. The substitution parameters depend on the specific error. You can look up the error parameters for SQL errors in Database Error Messages.

Return value

Returns one of the following actions:

  • UL_ERROR_ACTION_CANCEL Cancel the operation that raised the error.

  • UL_ERROR_ACTION_CONTINUE Continue execution, ignoring the operation that raised the error.

  • UL_ERROR_ACTION_DEFAULT Behave as if there is no error callback. This value is particularly appropriate for UL_ERROR_KIND_SQLCODE.

  • UL_ERROR_ACTION_TRY_AGAIN Try the operation again that raised the error.

Description

For a description of error handling using this technique, see ULRegisterErrorCallback function.

See also
  • ULRegisterErrorCallback function
  • Error messages indexed by Adaptive Server Anywhere SQLCODE


Callback function for ULRegisterSchemaUpgradeObserver

Enables applications to display progress during UltraLite database schema upgrades.

Prototype

ul_ret_void UL_GENNED_FN_MOD upgrade-callback-function(
p_ul_schema_upgrade_status status
)

Parameters

  • upgrade-callback-function The name of your function. You must supply the name to ULRegisterSchemaUpgradeObserver.

  • status A pointer to a schema upgrade structure, which has the following definition:

    typedef struct {
  ul_schema_upgrade_state state;
  ul_u_long               progress_counter;
  ul_u_long               final_progress_count;
  ul_u_long               upgrade_operations;
  ul_bool                 stop;
  ul_void *               user_data;
}

The status fields are as follows:

  • state One of the following:

    • UL_UPGRADE_STATE_STARTING The upgrade is starting. The user can safely cancel the operation at this stage.

    • UL_UPGRADE_STATE_UPGRADING The upgrade is in progress.

    • UL_UPGRADE_STATE_ABORT The schema upgrade is canceled as a result of a recoverable error or as a result of user action. The old database is preserved.

    • UL_UPGRADE_STATE_ERROR A critical error occurred. The database is unusable.

    • UL_UPGRADE_STATE_DONE The upgrade completed successfully.

  • progress_counter An approximation of the progress so far. The value is a number between zero and final_progress_count, enabling you to display a percentage complete value in a dialog box.

  • final_progress_count The value of the progress_counter when the upgrade completes successfully.

  • upgrade_operations An approximation of the amount of work done during the upgrade. The value starts at zero and increases as the upgrade proceeds. It is updated more frequently than progress_counter. It can be used as a relative measure to compare against other schema upgrades.

  • stop To cancel the schema upgrade, set this value to ul_true when the state is UL_UPGRADE_STATE_STARTING. Your application will receive a second callback with UL_UPGRADE_STATUS_ABORT.

    In embedded SQL and the Static C++ API, the connect operation fails with SQLCODE SQLE_SCHEMA_UPGRADE_NOT_ALLOWED. In the C++ Component, the UpgradeSchemaFromFile call returns false and the SQLCODE is set to SQLE_SCHEMA_UPGRADE_NOT_ALLOWED.

    The stop value is ignored if you set stop to ul_true when the state is not UL_UPGRADE_STATE_STARTING.

  • user_data This is identical to the user_data parameter passed to ULRegisterSchemaUpgradeObserver or UpgradeSchemaFromFile.


ULEnableFileDB function

Use a file-based data store on a device operating the Palm Computing Platform version 4.0 or later.

Prototype

void ULEnableFileDB( SQLCA * sqlca );

Parameters

sqlca A pointer to the SQLCA. This argument is supplied even in C++ Component and static C++ API applications.

In the static C++ API the SQLCA is declared in the header file as sqlca. In the C++ Component use the Sqlca.GetCA() method.

Description

To use the file-based data store on a Palm expansion card, an UltraLite application must call ULEnableFileDB to load the persistent storage file-I/O modules before connecting to the database.

Examples

The following embedded SQL code illustrates the use of ULEnableFileDB.

db_init( & sqlca );
ULEnablePalmRecordDB( &sqlca );
// connection code here
if( SQLCODE == SQLE_CONNECTION_RESTORED ){
    // connection was restored
    // cursor is already open
} else {
    // open cursor
}
See also

ULEnablePalmRecordDB function


ULEnableGenericSchema function (deprecated)

Upgrade the database schema when deploying a new version of an application.

Deprecated feature
This statement is deprecated. Use ULRegisterSchemaUpgradeObserver instead.
Prototype

void ULEnableGenericSchema( SQLCA * sqlca );

Parameters

sqlca A pointer to the SQLCA. This argument is supplied even in C++ API applications.

In the static C++ API the SQLCA is declared in the header file as sqlca. In the C++ Component use the Sqlca.GetCA() method.

Description

When a new UltraLite application is deployed to a device, UltraLite by default re-creates an empty database, losing any data that was in the database before the new application was deployed. If you call ULEnableGenericSchema, the existing database is instead upgraded to the schema of the new application.

This function can be used by C++ API applications as well as embedded SQL applications. It must be called before db_init or ULData.Open(). An exception is the Palm Computing Platform, where there is no need to close all cursors before upgrading. Immediately following an upgrade on the Palm Computing Platform the LAUNCH_SUCCESS_FIRST launch code is returned.

Backup before upgrading
It is strongly recommended that you backup your data before attempting an upgrade, either by copying the database file or by synchronizing.

For more information about the schema upgrade process, see How schema upgrade works.


ULEnablePalmRecordDB function

Use a standard record-based data store on a device operating the Palm Computing Platform.

Prototype

void ULEnablePalmRecordDB( SQLCA * sqlca );

Parameters

sqlca A pointer to the SQLCA. This argument is supplied even in C++ Component and C++ API applications.

In the static C++ API the SQLCA is declared in the header file as sqlca. In the C++ Component use the Sqlca.GetCA() method.

Description

This function can be used by C++ Component and C++ API applications as well as embedded SQL applications.

Examples

The following embedded SQL code illustrates the use of ULEnablePalmRecordDB.

db_init( & sqlca );
ULEnablePalmRecordDB( &sqlca );
// connection code here
if( SQLCODE == SQLE_CONNECTION_RESTORED ){
    // connection was restored
    // cursor is already open
} else {
    // open cursor
}
See also

ULEnableFileDB function


ULEnableStrongEncryption function

Strongly encrypt an UltraLite database.

Prototype

void ULEnableStrongEncryption( SQLCA * sqlca )

Parameters

sqlca A pointer to the SQLCA. This argument is supplied even in C++ Component and C++ API applications.

In the static C++ API the SQLCA is declared in the header file as sqlca. In the C++ Component use the Sqlca.GetCA() method.

Description

This function can be used by C++ API applications as well as embedded SQL applications. It must be called before db_init() or ULData.Open().

See also

Encrypting data


ULEnableUserAuthentication function

Enable user authentication in the UltraLite application.

Prototype

void ULEnableUserAuthentication( SQLCA * sqlca );

Parameters

sqlca A pointer to the SQLCA. This argument is supplied even in C++ Component and C++ API applications.

In the static C++ API the SQLCA is declared in the header file as sqlca. In the C++ Component use the Sqlca.GetCA() method.

Description

If you do not call this function, no user ID or password is required to access an UltraLite database. With this function, your application must supply a valid user ID and password. UltraLite databases are created with a single authenticated user ID DBA which has initial password SQL.

This function can be used by C++ API applications as well as embedded SQL applications. It must be called before a connection is opened.

See also

User authentication in UltraLite


ULRegisterErrorCallback function

Register a callback function that handles errors.

Prototype

void ULRegisterErrorCallback (
SQLCA * sqlca,
ul_error_callback_fn callback,
ul_void * user_data,
ul_char * buffer,
size_t len
)

Parameters

  • sqlca A pointer to the SQL Communications Area.

    In the static C++ API the SQLCA is declared in the header file as sqlca. In the C++ Component use the Sqlca.GetCA() method.

  • callback The name of your callback function. For information about the prototype of the function, see Callback function for ULRegisterErrorCallback.

    A callback value of UL_NULL disables any previously registered callback function.

  • user_data As the callback function may be called from any location in your application, any context information you wish it to access would have to be globally accessible. As an alternative to global variables, use this field to supply any context information you wish your function to have access to.

    UltraLite does not modify the supplied data, it simply passes it to your callback function when it is invoked.

    You can declare any data type here and cast it into the correct type in your callback function. For example, you could include a line of the following form in your callback function:

    MyContextType * context = (MyContextType *)user_data;

  • buffer A character array holding the substitution parameters for the error message, including a null terminator. To keep UltraLite as small as possible, UltraLite does not supply error messages. The substitution parameters depend on the specific error. You can look up the error parameters for SQL errors in Database Error Messages.

    The buffer must exist as long as UltraLite is active. Supply UL_NULL if you do not want to receive parameter information.

  • len The length of the buffer, in ul_char characters. A value of 100 is large enough to hold most error parameters. If the buffer is too small, the parameters are truncated safely.

Description

Once this function has been called, the user-supplied callback function is called whenever UltraLite signals an error. You should therefore call ULRegisterErrorCallback immediately after initializing the SQL Communications Area.

Error handling using this callback technique is particularly helpful during development, as it ensures that your application is notified of any and all errors that occur. However, the callback function does not control execution flow, so the callback function does not replace other error handling code.

Example

The following code registers a callback function for an UltraLite C++ Component application:

int main(){
    ul_char buffer[100];
    DatabaseManager * dm;
    Connection * conn;
    Sqlca.Initialize();
    ULRegisterErrorCallback(
        Sqlca.GetCA(),
        MyErrorCallBack,
        UL_NULL,
        buffer,
        100 );
    dm = ULInitDatabaseManager( Sqlca );
    ...

The following is a sample callback function:

ul_error_action UL_GENNED_FN_MOD MyErrorCallBack(
   SQLCA *    sqlca,
   ul_error_kind   kind,
   ul_void *   user_data,
   ul_char *   message_parameter ){
    ul_error_action rc;
    (void) user_data;
    switch( kind ) {
    case UL_ERROR_KIND_MEDIA_REMOVED:
        // TODO: Prompt user to re-insert media
        // (message_parameter contains the filename).
        rc = UL_ERROR_ACTION_ABORT; // use UL_ERROR_ACTION_RETRY to retry
        break;
    case UL_ERROR_KIND_SQLCODE:
        switch( sqlca->sqlcode ){
        // The following errors are used for flow control, and we don't want to
        // report them here:
        case SQLE_NOTFOUND:
        case SQLE_ULTRALITE_DATABASE_NOT_FOUND:
            break;
        case SQLE_CANNOT_ACCESS_SCHEMA_FILE:
          _tprintf(
           _TEXT( "Error %ld: UltraLite schema file %s not found\n" ),
           sqlca->sqlcode,
           message_parameter );
           break;
        case SQLE_COMMUNICATIONS_ERROR:
          _tprintf(
           _TEXT( "Error %ld: Communications error\n" ),
           sqlca->sqlcode );
           break;
        default:
           _tprintf(
             _TEXT( "Error %ld: %s\n" ),
             sqlca->sqlcode,
             message_parameter );
             break;
        }
        rc = UL_ERROR_ACTION_ABORT; // ignored for SQL kind
        break;
    default:
        // future error kinds
        assert( 0 );
        rc = UL_ERROR_ACTION_ABORT; // default action
        break;
    }
    return rc;
}
See also
  • Error messages indexed by Adaptive Server Anywhere SQLCODE
  • Callback function for ULRegisterErrorCallback


ULRegisterSchemaUpgradeObserver function

Prototype

ul_ret_void ULRegisterSchemaUpgradeObserver (
SQLCA * sqlca,
ul_schema_upgrade_observer_fn callback,
ul_void * user_data
);

Parameters

  • sqlca A pointer to the SQL Communications Area.

    In the static C++ API the SQLCA is declared in the header file as sqlca. In the C++ Component use the Sqlca.GetCA() method.

  • callback The name of your callback function. For information about the prototype of the function, see Callback function for ULRegisterErrorCallback.

    A callback value of UL_NULL disables any previously registered callback function.

  • user_data As the callback function may be called from any location in your application, any context information you wish it to access would have to be globally accessible. As an alternative to global variables, use this field to supply any context information you wish your function to have access to.

    UltraLite does not modify the supplied data, it simply passes it to your callback function when it is invoked.

    You can declare any data type here and cast it into the correct type in your callback function. For example, you could include a line of the following form in your callback function:

    MyContextType * context = (MyContextType *)user_data;
Description

The schema upgrade process can be time consuming. You can use an observer callback to monitor the upgrade process and provide feedback to your end user. For example, you can use this feature to provide a dialog box that displays percentage progress to the user.

Call ULRegisterSchemaUpgradeObserver after the call to db_init (embedded SQL) or ULData::Open (Static C++ API), but before connecting to the database. The upgrade takes place during the connect operation, at which time callbacks are made to your registered callback function.

Although you can call ULRegisterSchemaUpgradeObserver from the C++ Component, you can also use the Connection.UpgradeSchemaFromFile method to carry out the same action. If your application calls both, ULRegisterSchemaUpgradeObserver is used.

You must call ULRegisterSchemaUpgradeObserver in applications that upgrade the database schema. If you do not wish to provide feedback to the user, pass UL_NULL as the callback function. If your application does not upgrade a database schema, you may wish to omit the call to ULRegisterSchemaUpgradeObserver, as it can add significantly to application size.

See also

Upgrading UltraLite database schemas


ULStoreDefragFini function

Prototype

ul_ret_void ULStoreDefragFini(
SQLCA * sqlca,
p_ul_store_defrag_info dfi );

Description

This function disposes of the defragmentation information block returned by ULStoreDefragInit.

Parameters

sqlca A pointer to the SQLCA.

dfi A defragmentation information block.

See also

Defragmenting UltraLite databases

ULStoreDefragInit function


ULStoreDefragInit function

Prototype

p_ul_store_defrag_info ULStoreDefragInit( SQLCA * sqlca );

Description

This function initializes and returns a defragmentation information block to maintain the defragmentation state of the database.

Parameters

sqlca A pointer to the SQLCA.

Returns

If successful, returns a defragmentation information block p_ul_store_defrag_info. If unsuccessful, for example if there is not enough memory, returns UL_NULL.

See also

Defragmenting UltraLite databases

ULStoreDefragFini function


ULStoreDefragStep function

Prototype

ul_bool ULStoreDefragStep(
SQLCA * sqlca
p_ul_store_defrag_info dfi );

Description

This function defragments a piece of the database.

Parameters

sqlca A pointer to the SQLCA.

dfi A defragmentation information block.

Returns

If the entire store has been defragmented, returns ul_true.

If the entire store is not defragmented, returns ul_false.

If an error occurs, SQLCODE is set.

See also

Defragmenting UltraLite databases

ULStoreDefragFini function

ULStoreDefragInit function


Macros and compiler directives for UltraLite C/C++ applications

This section describes compiler directives to supply for UltraLite C/C++ applications. Unless stated otherwise, directives apply to both embedded SQL and C++ API applications.

Compiler directives can be supplied on your compiler command line or in the compiler settings dialog box of your user interface. Alternatively, they can be defined in source code.

On the compiler command line, a compiler directive is commonly set by using the /D command-line option. For example, to compile an UltraLite application with user authentication, a makefile for the Microsoft Visual C++ compiler may look as follows:

CompileOptions=/c /DPRWIN32 /Od /Zi /DWIN32
/D__NT__ /DUL_USE_DLL /DULB_USE_BIGINT_TYPES
/DULB_USE_FLOAT_TYPES /DUL_ENABLE_USER_AUTH

IncludeFolders= \
/I"$(VCDIR)\include" \
/I"$(ASANY9)\h"

sample.obj: sample.cpp
   cl $(CompileOptions) $(IncludeFolders) sample.cpp

where VCDIR is your Visual C++ directory and ASANY9 is your SQL Anywhere directory.

In source code, directives are supplied using the #define statement.

UL_AS_SYNCHRONIZE macro
UL_ENABLE_OBFUSCATION macro
UL_ENABLE_USER_AUTH macro
UL_ENABLE_SEGMENTS macro
UL_OMIT_COLUMN_INFO macro
UL_STORE_PARMS macro
UL_SYNC_ALL macro
UL_SYNC_ALL_PUBS macro
UL_TEXT macro
UL_USE_DLL macro
UNDER_CE macro
UNDER_PALM_OS macro


UL_AS_SYNCHRONIZE macro

Function

Provides the name of the callback message used to indicate an ActiveSync synchronization.

Applies to

Windows CE applications using ActiveSync only.

See also

Adding ActiveSync synchronization to your application

Adding ActiveSync synchronization to your application


UL_ENABLE_OBFUSCATION macro

Function

By default, obfuscation is disabled. To enable obfuscation, define UL_ENABLE_OBFUSCATION when compiling the generated database.

Applies to

The generated database code.

See also

Encrypting data


UL_ENABLE_USER_AUTH macro

Function

For C++ API applications only, define this directive to enable user authentication. Without this directive, there is no user authentication on C++ API UltraLite applications.

Applies to

The ulapi.cpp file.

See also

Authenticating users


UL_ENABLE_SEGMENTS macro

Function

Instructs the compiler to generate multi-segment code for Palm Computing Platform applications.

Applies to

The generated database code.

See also

Enabling multi-segment code generation

Enabling multi-segment code generation


UL_OMIT_COLUMN_INFO macro

Function

Reduce the number of Palm OS data segments required by the generated code.

Usage

Define the preprocessor symbol UL_OMIT_COLUMN_INFO before compiling generated files. In CodeWarrior, you can do this by adding the #define to your prefix file.

The macro decreases the number of segments required by the generated code. To accomplish the reduction, it omits extended schema information that the UltraLite generator would otherwise write. As a result, when this macro is defined, you cannot upgrade a database schema, and you cannot use the send_column_names synchronization parameter.


UL_STORE_PARMS macro

Function

Supply a set of keyword-value pairs to configure database storage.

Syntax

#define UL_STORE_PARMS UL_TEXT( "keyword=value;..." )

All spaces in the keyword-value list are significant, except spaces at the start of the string and any spaces that immediately follow a semicolon.

Usage

Define the UL_STORE_PARMS macro in the header of your application source code so that it is visible to all db_init() calls.

Parameters

Keywords are case insensitive. The case sensitivity of the values depends on the application interpreting it. For example, the case sensitivity of the filename depends on the operating system.

For a list of available parameters, see Database Schema parameters, and Additional connection parameters.

Examples

The following statements set the cache size to 128 kb.

#undef  UL_STORE_PARMS
#define UL_STORE_PARMS  UL_TEXT("cache_size=128k")
   . . .
db_init( &sqlca );

You can set UL_STORE_PARMS to a string, then set the value of that string programmatically before calling db_init, as in the following example. The UL_TEXT macro and the _stprintf function are used to achieve proper character encoding.

char store_parms[32];
#undef  UL_STORE_PARMS
#define UL_STORE_PARMS  store_parms
...
   /* Set cache_size to the correct number of bytes. */
...
_stprintf( store_parms, UL_TEXT("cache_size=%lu"),
   cache_size );
db_init( &sqlca );

Here is a similar example that uses the password as an encryption key, and which sets the location and file name of the UltraLite database file. The code assumes that the variable filename already contains the desired path and filename. The code must be executed before calling db_init:

TCHAR store_parms[100];
#undef  UL_STORE_PARMS
#define UL_STORE_PARMS  store_parms
//put the password in UL_STORE_PARMS to be used as encryption key
my_sprintf( store_parms, UL_TEXT("key=%s"), app_pword );

#ifdef UNDER_CE
if( filename != NULL ) {
    my_strcat( store_parms, _T(";file_name=") );
    my_strcat( store_parms, filename );
}
#endif
See also

Database Schema parameters

Additional connection parameters

Creating UltraLite database schema files

Encrypting data


UL_SYNC_ALL macro

Function

Provides a publication mask that refers to all tables in the database, including those not in publications.

See also

publication synchronization parameter

ULGetLastDownloadTime function

ULCountUploadRows function

UL_SYNC_ALL_PUBS macro


UL_SYNC_ALL_PUBS macro

Function

Provides a publication mask that refers to all tables in the database that are in publications.

See also

publication synchronization parameter

ULGetLastDownloadTime function

ULCountUploadRows function

UL_SYNC_ALL macro


UL_TEXT macro

Function

Prepares constant strings to be compiled as single-byte strings or wide-character strings. In embedded SQL and C++ API applications, use this macro to enclose all constant strings so that the compiler handles these parameters correctly.


UL_USE_DLL macro

Function

For Windows CE and Windows applications only, define this directive to use the runtime library DLL, rather than a static runtime library.

Applies to

The generated database code.


UNDER_CE macro

Function

Use this macro when compiling UltraLite applications for Windows CE only.

By default, this macro is defined in all new eMbedded Visual C++ projects.

See also

Developing UltraLite Applications for Windows CE.


UNDER_PALM_OS macro

Function

Use this macro when compiling UltraLite applications for Palm OS only.

This macro is defined in the ulpalmXX.h header file included in UltraLite Palm OS applications by the UltraLite plugin. For more information, see Using the UltraLite plug-in for CodeWarrior.

See also

Developing UltraLite Applications for the Palm Computing Platform.


UltraLite C++ Component API Reference

About this chapter

This chapter describes the UltraLite C++ Component API.

Class ULSqlca
Class ULSqlcaBase
Class ULSqlcaWrap
Class UltraLite_Connection
Class UltraLite_Connection_iface
Class UltraLite_Cursor_iface
Class UltraLite_DatabaseManager
Class UltraLite_DatabaseManager_iface
Class UltraLite_DatabaseSchema
Class UltraLite_DatabaseSchema_iface
Class UltraLite_IndexSchema
Class UltraLite_IndexSchema_iface
Class UltraLite_PreparedStatement
Class UltraLite_PreparedStatement_iface
Class UltraLite_ResultSet
Class UltraLite_ResultSet_iface
Class UltraLite_ResultSetSchema
Class UltraLite_RowSchema_iface
Class UltraLite_SQLObject_iface
Class UltraLite_StreamReader
Class UltraLite_StreamReader_iface
Class UltraLite_StreamWriter
Class UltraLite_Table
Class UltraLite_Table_iface
Class UltraLite_TableSchema
Class UltraLite_TableSchema_iface
Class ULValue


Class ULSqlca

Synopsis

public ULSqlca

Base classes
  • Class ULSqlcaBase
Remarks

Class ULSqlcaBase subclass which contains a SQLCA structure so an external one is not required.

This is used in most C++ Component applications. The communication area must be initialized before any other functions are called. Each thread requires its own communication area.

Members

All members of ULSqlca, including all inherited members.

  • Finalize Function
  • GetCA Function
  • GetParameter Function
  • GetParameterCount Function
  • GetSQLCode Function
  • GetSQLCount Function
  • GetSQLErrorOffset Function
  • Initialize Function
  • LastCodeOK Function
  • LastFetchOK Function
  • ULSqlca Function
  • ~ULSqlca Function


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULSqlca

ULSqlca Function

Synopsis

ULSqlca::ULSqlca()

Remarks

Constructor.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULSqlca

~ULSqlca Function

Synopsis

ULSqlca::~ULSqlca()

Remarks

Destructor.


Class ULSqlcaBase

Synopsis

public ULSqlcaBase

Derived classes
  • Class ULSqlca
  • Class ULSqlcaWrap
Remarks

Provides a communication area.

ULSqlcaBase defines the communication area between the interface library and the application. Use a subclass of this class (typically Class ULSqlca) to create your communication area. There is always an underlying SQLCA object required. The communication area must be initialized before any other functions are called. Each thread requires its own communication area.

Members

All members of ULSqlcaBase, including all inherited members.

  • Finalize Function
  • GetCA Function
  • GetParameter Function
  • GetParameterCount Function
  • GetSQLCode Function
  • GetSQLCount Function
  • GetSQLErrorOffset Function
  • Initialize Function
  • LastCodeOK Function
  • LastFetchOK Function

Finalize Function
GetCA Function
GetParameter Function
GetParameterCount Function
GetSQLCode Function
GetSQLCount Function
GetSQLErrorOffset Function
Initialize Function
LastCodeOK Function
LastFetchOK Function


Finalize Function

Synopsis

void ULSqlcaBase::Finalize()

Remarks

Finalizes this communication area.

Until the communication area is initialized again, it cannot be used.


GetCA Function

Synopsis

SQLCA * ULSqlcaBase::GetCA()

Remarks

Gets the SQLCA structure for direct access to additional fields.

Returns

Raw sqlca structure.


GetParameter Function

Synopsis

size_t ULSqlcaBase::GetParameter(
ul_u_long parm_num
ul_char * buffer
size_t size
)

Parameters

  • parm_num A 1-based parameter number.

  • buffer The buffer to receive parameter string.

  • size The size, in ul_chars, of the buffer.

Remarks

Gets the error parameter string.

The output parameter string is always null-terminated, even if the buffer is too small and the parameter is truncated. The parameter number is 1-based.

Returns

If the function succeeds, the return value is the buffer size required to hold the entire parameter string (number of ul_chars, including the null terminator). If the function fails, the return value is zero. The function fails if an invalid (out of range) parameter number is given.


GetParameterCount Function

Synopsis

ul_u_long ULSqlcaBase::GetParameterCount()

Remarks

Gets the error parameter count for last operation.

Returns

The number of parameters for the current error.


GetSQLCode Function

Synopsis

an_sql_code ULSqlcaBase::GetSQLCode()

Remarks

Gets the error code (SQLCODE) for last operation.

Returns

The sqlcode value


GetSQLCount Function

Synopsis

an_sql_code ULSqlcaBase::GetSQLCount()

Remarks

Gets the sql count variable (SQLCOUNT) for the last operation.

This indicates the number of rows affected by an INSERT, DELETE, or UPDATE operation, and is zero otherwise.


GetSQLErrorOffset Function

Synopsis

ul_s_long ULSqlcaBase::GetSQLErrorOffset()

Remarks

Gets the error offset in dynamic SQL statement.

Returns

When applicable, the return value is the offset into the associated dynamic SQL statement (passed to the PrepareStatement function) corresponding to the current error. When not applicable, the return value is -1.


Initialize Function

Synopsis

bool ULSqlcaBase::Initialize()

Remarks

Initializes this communication area.

You must initialize the communications area before any other operations occur.

Returns

On success, true, otherwise false. This method can fail if basic interface library initialization fails, which could occur if system resources are depleted.


LastCodeOK Function

Synopsis

bool ULSqlcaBase::LastCodeOK()

Remarks

Tests the error code for the last operation.

Returns

true if the sqlcode is SQLE_NOERROR or a warning; false if it indicates an error.


LastFetchOK Function

Synopsis

bool ULSqlcaBase::LastFetchOK()

Remarks

Tests the error code for last fetch operation.

Use this function only immediately after performing a fetch operation.

Returns

true if the sqlcode indicates that a row was fetched successfully by the last operation.


Class ULSqlcaWrap

Synopsis

public ULSqlcaWrap

Base classes
  • Class ULSqlcaBase
Remarks

Class ULSqlcaBase subclass which attaches to an existing SQLCA object.

This can be used with a previously-initialized SQLCA object (in which case, you would NOT call Initialize again). The communication area must be initialized before any other functions are called. Each thread requires its own communication area.

Members

All members of ULSqlcaWrap, including all inherited members.

  • Finalize Function
  • GetCA Function
  • GetParameter Function
  • GetParameterCount Function
  • GetSQLCode Function
  • GetSQLCount Function
  • GetSQLErrorOffset Function
  • Initialize Function
  • LastCodeOK Function
  • LastFetchOK Function
  • ULSqlcaWrap Function
  • ~ULSqlcaWrap Function


ULSqlcaWrap Function

Synopsis

ULSqlcaWrap::ULSqlcaWrap(
SQLCA * sqlca
)

Parameters

  • sqlca The SQLCA object to use.

Remarks

Constructor.

You may initialize the given SQLCA object before creating this object. In this case, don't call Initialize Function again.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULSqlcaWrap

~ULSqlcaWrap Function

Synopsis

ULSqlcaWrap::~ULSqlcaWrap()

Remarks

Destructor.


Class UltraLite_Connection

Synopsis

public UltraLite_Connection

Base classes
  • Class UltraLite_SQLObject_iface
  • Class UltraLite_Connection_iface
Remarks

Connection class.

Members

All members of UltraLite_Connection, including all inherited members.

  • AddRef Function
  • ChangeEncryptionKey Function
  • Commit Function
  • CountUploadRows Function
  • GetConnection Function
  • GetConnectionNum Function
  • GetDatabaseID Function
  • GetDatabaseProperty Function
  • GetIFace Function
  • GetLastDownloadTime Function
  • GetLastIdentity Function
  • GetNewUUID Function
  • GetPublicationMask Function
  • GetSchema Function
  • GetSqlca Function
  • GetSuspend Function
  • GetSynchResult Function
  • GetUtilityULValue Function
  • GlobalAutoincUsage Function
  • GrantConnectTo Function
  • InitSynchInfo Function
  • OpenTable Function
  • OpenTableWithIndex Function
  • PrepareStatement Function
  • Release Function
  • ResetLastDownloadTime Function
  • RevokeConnectFrom Function
  • Rollback Function
  • RollbackPartialDownload Function
  • SetDatabaseID Function
  • SetSuspend Function
  • SetSynchInfo Function
  • Shutdown Function
  • StartSynchronizationDelete Function
  • StopSynchronizationDelete Function
  • StrToUUID Function
  • Synchronize Function
  • UpgradeSchemaFromFile Function
  • UpgradeSchemaFromFile Function
  • UUIDToStr Function
  • UUIDToStr Function


Class UltraLite_Connection_iface

Synopsis

public UltraLite_Connection_iface

Derived classes
  • Class UltraLite_Connection
Remarks

Connection interface.

Members

All members of UltraLite_Connection_iface, including all inherited members.

  • ChangeEncryptionKey Function
  • Commit Function
  • CountUploadRows Function
  • GetConnectionNum Function
  • GetDatabaseID Function
  • GetDatabaseProperty Function
  • GetLastDownloadTime Function
  • GetLastIdentity Function
  • GetNewUUID Function
  • GetPublicationMask Function
  • GetSchema Function
  • GetSqlca Function
  • GetSuspend Function
  • GetSynchResult Function
  • GetUtilityULValue Function
  • GlobalAutoincUsage Function
  • GrantConnectTo Function
  • InitSynchInfo Function
  • OpenTable Function
  • OpenTableWithIndex Function
  • PrepareStatement Function
  • ResetLastDownloadTime Function
  • RevokeConnectFrom Function
  • Rollback Function
  • RollbackPartialDownload Function
  • SetDatabaseID Function
  • SetSuspend Function
  • SetSynchInfo Function
  • Shutdown Function
  • StartSynchronizationDelete Function
  • StopSynchronizationDelete Function
  • StrToUUID Function
  • Synchronize Function
  • UpgradeSchemaFromFile Function
  • UpgradeSchemaFromFile Function
  • UUIDToStr Function
  • UUIDToStr Function

ChangeEncryptionKey Function
Commit Function
CountUploadRows Function
GetConnectionNum Function
GetDatabaseID Function
GetDatabaseProperty Function
GetLastDownloadTime Function
GetLastIdentity Function
GetNewUUID Function
GetPublicationMask Function
GetSchema Function
GetSqlca Function
GetSuspend Function
GetSynchResult Function
GetUtilityULValue Function
GlobalAutoincUsage Function
GrantConnectTo Function
InitSynchInfo Function
OpenTable Function
OpenTableWithIndex Function
PrepareStatement Function
ResetLastDownloadTime Function
RevokeConnectFrom Function
Rollback Function
RollbackPartialDownload Function
SetDatabaseID Function
SetSuspend Function
SetSynchInfo Function
Shutdown Function
StartSynchronizationDelete Function
StopSynchronizationDelete Function
StrToUUID Function
Synchronize Function
UUIDToStr Function
UUIDToStr Function
UpgradeSchemaFromFile Function
UpgradeSchemaFromFile Function


ChangeEncryptionKey Function

Synopsis

virtual bool UltraLite_Connection_iface::ChangeEncryptionKey(
const ULValue & new_key
)

Parameters

  • new_key The new encryption key value for the database.

Remarks

Changes the encryption key.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_Connection_iface

Commit Function

Synopsis

virtual bool UltraLite_Connection_iface::Commit()

Remarks

Commits the current transaction.


CountUploadRows Function

Synopsis

virtual ul_u_long UltraLite_Connection_iface::CountUploadRows(
ul_publication_mask mask
ul_u_long threshold
)

Parameters

  • mask The set of publications to consider.

  • threshold The limit on the number of rows to count.

Remarks

Determines the number of rows that need to be uploaded.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_Connection_iface

GetConnectionNum Function

Synopsis

virtual ul_connection_num UltraLite_Connection_iface::GetConnectionNum()

Remarks

Gets the connection number.


GetDatabaseID Function

Synopsis

virtual ul_u_long UltraLite_Connection_iface::GetDatabaseID()

Remarks

Gets the database ID used for global autoincrement columns.


GetDatabaseProperty Function

Synopsis

virtual ULValue UltraLite_Connection_iface::GetDatabaseProperty(
ul_database_property_id id
)

Parameters

  • id The ID of the property being requested.

Remarks

Gets the Database Property.

Returns

The value of the requested property.


GetLastDownloadTime Function

Synopsis

virtual bool UltraLite_Connection_iface::GetLastDownloadTime(
ul_publication_mask mask
DECL_DATETIME * value
)

Parameters

  • mask The publication mask.

  • value output: the last download time.

Remarks

Gets the time of the last download.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_Connection_iface

GetLastIdentity Function

Synopsis

virtual ul_u_big UltraLite_Connection_iface::GetLastIdentity()

Remarks

Gets the @@identity value.


GetNewUUID Function

Synopsis

virtual bool UltraLite_Connection_iface::GetNewUUID(
p_ul_binary uuid
)

Parameters

  • uuid The new UUID value.

Remarks

Creates a new UUID.


GetPublicationMask Function

Synopsis

virtual ul_publication_mask UltraLite_Connection_iface::GetPublicationMask(
const ULValue & pub_id
)

Parameters

  • pub_id The publication name or ordinal.

Remarks

Gets the publication mask for a given publication name.

Publication masks are not publication IDs. 0 is returned if the publication is not found.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_Connection_iface

GetSchema Function

Synopsis

virtual UltraLite_DatabaseSchema * UltraLite_Connection_iface::GetSchema()

Remarks

Gets the database schema.


GetSqlca Function

Synopsis

virtual ULSqlcaBase const & UltraLite_Connection_iface::GetSqlca()

Remarks

Gets the communication area associated with this connection.


GetSuspend Function

Synopsis

virtual bool UltraLite_Connection_iface::GetSuspend()

Remarks

Gets the Suspend property.

Returns

true if this connection is suspended, false otherwise.


GetSynchResult Function

Synopsis

virtual bool UltraLite_Connection_iface::GetSynchResult(
p_ul_synch_result synch_result
)

Parameters

  • synch_result A pointer to the ul_synch_result structure that holds the synchronization results.

Remarks

Gets the result of the last synchronization.


GetUtilityULValue Function

Synopsis

virtual ULValue UltraLite_Connection_iface::GetUtilityULValue()

Remarks

Gets a new Class ULValue.

A Class ULValue object must be bound to a connection in order for many of its methods to succeed.


GlobalAutoincUsage Function

Synopsis

virtual ul_u_short UltraLite_Connection_iface::GlobalAutoincUsage()

Remarks

Gets the percent usage of the global autoincrement counter.


GrantConnectTo Function

Synopsis

virtual bool UltraLite_Connection_iface::GrantConnectTo(
const ULValue & uid
const ULValue & pwd
)

Parameters

  • uid The user ID being granted authority to connect.

  • pwd The password the user ID must specify to connect.

Remarks

Adds a new user or changes an existing user's password.


InitSynchInfo Function

Synopsis

virtual void UltraLite_Connection_iface::InitSynchInfo(
p_ul_synch_info info
)

Parameters

  • info A pointer to the ul_synch_info structure that holds the synchronization parameters.

Remarks

Initializes the synchronization information structure.


OpenTable Function

Synopsis

virtual UltraLite_Table * UltraLite_Connection_iface::OpenTable(
const ULValue & table_id
const ULValue & persistent_name
)

Parameters

  • table_id The table name or ordinal.

  • persistent_name The instance name used for suspending.

Remarks

Opens a table.

When a table is first opened, the cursor position is BeforeFirst()


OpenTableWithIndex Function

Synopsis

virtual UltraLite_Table * UltraLite_Connection_iface::OpenTableWithIndex(
const ULValue & table_id
const ULValue & index_id
const ULValue & persistent_name
)

Parameters

  • table_id The table name or ordinal.

  • index_id The index name or ordinal.

  • persistent_name The instance name used for suspending.

Remarks

Opens a table, using a specified index to order the rows.

When a table is first opened, the cursor position is BeforeFirst()


PrepareStatement Function

Synopsis

virtual UltraLite_PreparedStatement * UltraLite_Connection_iface::PrepareStatement(
const ULValue & sql
const ULValue & persistent_name
)

Parameters

  • sql The SQL statement as a string.

  • persistent_name The instance name used for suspending.

Remarks

Prepares a SQL statement.


ResetLastDownloadTime Function

Synopsis

virtual bool UltraLite_Connection_iface::ResetLastDownloadTime(
ul_publication_mask mask
)

Parameters

  • mask The set of publications to reset.

Remarks

Resets the time of the last download.


RevokeConnectFrom Function

Synopsis

virtual bool UltraLite_Connection_iface::RevokeConnectFrom(
const ULValue & uid
)

Parameters

  • uid The user ID whose authority to connect is being revoked.

Remarks

Deletes an existing user.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_Connection_iface

Rollback Function

Synopsis

virtual bool UltraLite_Connection_iface::Rollback()

Remarks

Rolls back the current transaction.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_Connection_iface

RollbackPartialDownload Function

Synopsis

virtual bool UltraLite_Connection_iface::RollbackPartialDownload()

Remarks

Rollback a partial download.


SetDatabaseID Function

Synopsis

virtual bool UltraLite_Connection_iface::SetDatabaseID(
ul_u_long value
)

Parameters

  • value The database ID, which determines the starting value for global autoincrement columns.

Remarks

Sets the database ID used for global autoincrement columns.


SetSuspend Function

Synopsis

virtual void UltraLite_Connection_iface::SetSuspend(
bool suspend
)

Parameters

  • suspend Set to true to suspend the connection so that its state can be restored when the database is reopened.

Remarks

Sets the Suspend property.

If true, this connection is suspended and restored when the database is reopened. The connection name (or lack of one) is used to identifiy suspended connetions.


SetSynchInfo Function

Synopsis

virtual bool UltraLite_Connection_iface::SetSynchInfo(
p_ul_synch_info info
)

Parameters

  • info A pointer to the ul_synch_info structure that holds the synchronization parameters.

Remarks

Attaches a ul_synch_info struct to the current database.


Shutdown Function

Synopsis

virtual void UltraLite_Connection_iface::Shutdown()

Remarks

Destroys this connection and any remaining associated objects.

If not set to suspend, this connection is rolled back.


StartSynchronizationDelete Function

Synopsis

virtual bool UltraLite_Connection_iface::StartSynchronizationDelete()

Remarks

START SYNCHRONIZATION DELETE for this connection.


StopSynchronizationDelete Function

Synopsis

virtual bool UltraLite_Connection_iface::StopSynchronizationDelete()

Remarks

STOP SYNCHRONIZATION DELETE for this connection.


StrToUUID Function

Synopsis

virtual bool UltraLite_Connection_iface::StrToUUID(
p_ul_binary dst
size_t len
const ULValue & src
)

Parameters

  • dst The UUID value being returned.

  • len The length of the ul_binary array.

  • src A string holding the UUID value to be converted.

Remarks

Converts a string to a UUID.


Synchronize Function

Synopsis

virtual bool UltraLite_Connection_iface::Synchronize(
p_ul_synch_info info
)

Parameters

  • info A pointer to the ul_synch_info structure that holds the synchronization parameters.

Remarks

Synchronizes the database.

Example:

ul_synch_info info;
conn.InitSynchInfo( &info );
info.user_name = UL_TEXT( "user_name" );
info.version = UL_TEXT( "test" );
conn.Synchronize( &info );

Or

ul_synch_info info;
conn.InitSynchInfo( &info );
info.user_name = UL_TEXT( "user_name" );
info.version = UL_TEXT( "test" );
conn.SetSynchInfo( &info );
conn.Synchronize();


UUIDToStr Function

Synopsis

virtual bool UltraLite_Connection_iface::UUIDToStr(
char * dst
size_t len
p_ul_binary src
)

Parameters

  • dst The string being returned.

  • len The length of the ul_binary array.

  • src The UUID value to be converted to a string.

Remarks

Converts a UUID to an ANSI string.


UUIDToStr Function

Synopsis

virtual bool UltraLite_Connection_iface::UUIDToStr(
ul_wchar * dst
size_t len
p_ul_binary src
)

Parameters

  • dst The Unicode string being returned.

  • len The length of the ul_binary array.

  • src The UUID value to be converted to a string.

Remarks

Converts a UUID to a Unicode string.


UpgradeSchemaFromFile Function

Synopsis

virtual bool UltraLite_Connection_iface::UpgradeSchemaFromFile(
const ULValue & options
)

Parameters

  • options A semicolon-delimited list of upgrade options.

Remarks

Upgrades to a new schema using an external schema definition file.

options is a semicolon-delimited list of upgrade options.


UpgradeSchemaFromFile Function

Synopsis

virtual bool UltraLite_Connection_iface::UpgradeSchemaFromFile(
const ULValue & options
ul_schema_upgrade_observer_fn callback
ul_void * user_data
)

Parameters

  • options A list of options.

  • callback The upgrade observer callback function.

  • user_data User data passed to the callback function.

Remarks

Upgrades to a new schema using an external schema definition file.

options is a semi-colon delimited list of upgrade options.


Class UltraLite_Cursor_iface

Synopsis

public UltraLite_Cursor_iface

Derived classes
  • Class UltraLite_ResultSet
  • Class UltraLite_Table
Remarks

Cursor interface.

Members

All members of UltraLite_Cursor_iface, including all inherited members.

  • AfterLast Function
  • BeforeFirst Function
  • First Function
  • Get Function
  • GetRowCount Function
  • GetState Function
  • GetStreamReader Function
  • GetSuspend Function
  • IsNull Function
  • Last Function
  • Next Function
  • Previous Function
  • Relative Function
  • SetSuspend Function

AfterLast Function
BeforeFirst Function
First Function
Get Function
GetRowCount Function
GetState Function
GetStreamReader Function
GetSuspend Function
IsNull Function
Last Function
Next Function
Previous Function
Relative Function
SetSuspend Function


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_Cursor_iface

AfterLast Function

Synopsis

virtual bool UltraLite_Cursor_iface::AfterLast()

Remarks

Moves the cursor after the last row.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_Cursor_iface

BeforeFirst Function

Synopsis

virtual bool UltraLite_Cursor_iface::BeforeFirst()

Remarks

Moves the cursor before the first row.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_Cursor_iface

First Function

Synopsis

virtual bool UltraLite_Cursor_iface::First()

Remarks

Moves the cursor to the first row.


Get Function

Synopsis

virtual ULValue UltraLite_Cursor_iface::Get(
const ULValue & column_id
)

Parameters

  • column_id The name or ordinal of the column.

Remarks

Fetches a value from a column.


GetRowCount Function

Synopsis

virtual ul_u_long UltraLite_Cursor_iface::GetRowCount()

Remarks

Gets the number of rows in the table.

Calling this method is equivalent to executing "select count(*) from table"


GetState Function

Synopsis

virtual UL_RS_STATE UltraLite_Cursor_iface::GetState()

Remarks

Gets the internal state of the cursor.

See enum UL_RS_STATE in ulglobal.h


GetStreamReader Function

Synopsis

virtual UltraLite_StreamReader * UltraLite_Cursor_iface::GetStreamReader(
const ULValue & id
)

Parameters

  • id A column identifier, which may be either a 1-based ordinal number or a column name.

Remarks

Gets a stream reader object for reading string or binary column data in chunks.


GetSuspend Function

Synopsis

virtual bool UltraLite_Cursor_iface::GetSuspend()

Remarks

Gets the value of the Suspend property.

Returns

true if this cursor is suspended, false otherwise.


IsNull Function

Synopsis

virtual bool UltraLite_Cursor_iface::IsNull(
const ULValue & column_id
)

Parameters

  • column_id The name or ordinal of the column.

Remarks

Checks if a column is NULL.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_Cursor_iface

Last Function

Synopsis

virtual bool UltraLite_Cursor_iface::Last()

Remarks

Moves the cursor to the last row.


Next Function

Synopsis

virtual bool UltraLite_Cursor_iface::Next()

Remarks

Moves the cursor forward one row.

On failure there is no next row, the resulting cursor position is AfterLast Function


Previous Function

Synopsis

virtual bool UltraLite_Cursor_iface::Previous()

Remarks

Moves the cursor back one row.

On failure, the resulting cursor position is BeforeFirst Function


Relative Function

Synopsis

virtual bool UltraLite_Cursor_iface::Relative(
ul_fetch_offset offset
)

Parameters

  • offset The number of rows to move.

Remarks

Moves the cursor by offset rows from the current cursor position.


SetSuspend Function

Synopsis

virtual void UltraLite_Cursor_iface::SetSuspend(
bool suspend
)

Parameters

  • suspend Set to true to suspend the connection so that its state can be restored when the database is reopened.

Remarks

Sets the value of the Suspend property.

If true, this cursor is suspended and restored when the database is reopened. Use the persistent name parameter when opening the associated object to identify suspended cursors. If a persistent name parameter was not supplied for this cursor, it cannot be suspended.


Class UltraLite_DatabaseManager

Synopsis

public UltraLite_DatabaseManager

Base classes
  • Class UltraLite_DatabaseManager_iface
Remarks

DatabaseManager class.

Members

All members of UltraLite_DatabaseManager, including all inherited members.

  • CreateAndOpenDatabase Function
  • DropDatabase Function
  • OpenConnection Function
  • Shutdown Function


Class UltraLite_DatabaseManager_iface

Synopsis

public UltraLite_DatabaseManager_iface

Derived classes
  • Class UltraLite_DatabaseManager
Remarks

DatabaseManager interface.

Members

All members of UltraLite_DatabaseManager_iface, including all inherited members.

  • CreateAndOpenDatabase Function
  • DropDatabase Function
  • OpenConnection Function
  • Shutdown Function


CreateAndOpenDatabase Function

Synopsis

virtual UltraLite_Connection * UltraLite_DatabaseManager_iface::CreateAndOpenDatabase(
ULSqlcaBase & sqlca
ULValue const & parms_string
)

Parameters

  • sqlca The initialized sqlca to associate with new connection.

  • parms_string The creation and connection parameters.

Remarks

Creates a new database and connects to it.

The given sqlca is associated with the new connection. If the database already exists, this function fails.

Returns

If the function succeeds, a new connection object is returned. If the function fails, NULL is returned.


DropDatabase Function

Synopsis

virtual bool UltraLite_DatabaseManager_iface::DropDatabase(
ULSqlcaBase & sqlca
const ULValue & parms_string
)

Parameters

  • sqlca The initialized sqlca.

  • parms_string The database identification parameters.

Remarks

Erases an existing database.

In order to be erased, the database must be stopped.


OpenConnection Function

Synopsis

virtual UltraLite_Connection * UltraLite_DatabaseManager_iface::OpenConnection(
ULSqlcaBase & sqlca
ULValue const & parms_string
)

Parameters

  • sqlca The initialized sqlca to associate with the new connection.

  • parms_string The connection string.

Remarks

Opens a new connection to an existing database.

The given sqlca is associated with the new connection.

  • SQLE_CONNECTION_ALREADY_EXISTS - You are already connected using these parameters (specifically the sqlca and connection name, CON).

  • SQLE_INVALID_LOGON - The userid you supplied does not exist or the password is incorrect. User authentication is only enabled if you have called the ULEnableUserAuthentication function before connecting.

  • SQLE_INVALID_SQL_IDENTIFIER - The userid or password you supplied was not legal, or no userid was supplied at all (use UID=user;PWD=password).

  • SQLE_TOO_MANY_CONNECTIONS - You have opened too many connections and attempted to exceed the (concurrent) connection limit.

To get error information, use the associated Class ULSqlca object. Possible errors include:

Returns

If the function succeeds, a new connection object is returned. If the function fails, NULL is returned.


Shutdown Function

Synopsis

virtual void UltraLite_DatabaseManager_iface::Shutdown(
ULSqlcaBase & sqlca
)

Parameters

  • sqlca The initialized sqlca.

Remarks

Closes all databases and releases the database manager.

Any remaining associated objects are destroyed. After calling this function, the database manager can no longer be used (nor can any other previously obtained objects).


Class UltraLite_DatabaseSchema

Synopsis

public UltraLite_DatabaseSchema

Base classes
  • Class UltraLite_SQLObject_iface
  • Class UltraLite_DatabaseSchema_iface
Remarks

DatabaseSchema class.

Members

All members of UltraLite_DatabaseSchema, including all inherited members.

  • AddRef Function
  • GetCollationName Function
  • GetConnection Function
  • GetIFace Function
  • GetPublicationCount Function
  • GetPublicationID Function
  • GetPublicationMask Function
  • GetPublicationName Function
  • GetSignature Function
  • GetTableCount Function
  • GetTableName Function
  • GetTableSchema Function
  • IsCaseSensitive Function
  • Release Function


Class UltraLite_DatabaseSchema_iface

Synopsis

public UltraLite_DatabaseSchema_iface

Derived classes
  • Class UltraLite_DatabaseSchema
Remarks

DatabaseSchema interface.

Members

All members of UltraLite_DatabaseSchema_iface, including all inherited members.

  • GetCollationName Function
  • GetPublicationCount Function
  • GetPublicationID Function
  • GetPublicationMask Function
  • GetPublicationName Function
  • GetSignature Function
  • GetTableCount Function
  • GetTableName Function
  • GetTableSchema Function
  • IsCaseSensitive Function

GetCollationName Function
GetPublicationCount Function
GetPublicationID Function
GetPublicationMask Function
GetPublicationName Function
GetSignature Function
GetTableCount Function
GetTableName Function
GetTableSchema Function
IsCaseSensitive Function


GetCollationName Function

Synopsis

virtual ULValue UltraLite_DatabaseSchema_iface::GetCollationName()

Remarks

Gets the name of the current collation sequence.

Returns

A Class ULValue containing a string is returned.


GetPublicationCount Function

Synopsis

virtual ul_publication_count UltraLite_DatabaseSchema_iface::GetPublicationCount()

Remarks

Gets the number of publications in the database.

Publication IDs range from 1 to GetPublicationCount Function


GetPublicationID Function

Synopsis

virtual ul_u_short UltraLite_DatabaseSchema_iface::GetPublicationID(
const ULValue & pub_id
)

Parameters

  • pub_id A 1-based ordinal number.

Remarks

Gets a 1-based id for the publication given its name.


GetPublicationMask Function

Synopsis

virtual ul_publication_mask UltraLite_DatabaseSchema_iface::GetPublicationMask(
const ULValue & pub_id
)

Parameters

  • pub_id A 1-based ordinal number.

Remarks

Gets the publication mask for a given publication name Publication masks are not publication IDs.

0 is returned if the publication is not found


GetPublicationName Function

Synopsis

virtual ULValue UltraLite_DatabaseSchema_iface::GetPublicationName(
const ULValue & pub_id
)

Parameters

  • pub_id A 1-based ordinal number.

Remarks

Gets the name of a publication given its 1-based index ID.

Publication masks are not publication IDs.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_DatabaseSchema_iface

GetSignature Function

Synopsis

virtual ULValue UltraLite_DatabaseSchema_iface::GetSignature()

Remarks

Gets the database signature.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_DatabaseSchema_iface

GetTableCount Function

Synopsis

virtual ul_table_num UltraLite_DatabaseSchema_iface::GetTableCount()

Remarks

Gets the number of tables.


GetTableName Function

Synopsis

virtual ULValue UltraLite_DatabaseSchema_iface::GetTableName(
ul_table_num tableID
)

Parameters

  • tableID A 1-based ordinal number.

Remarks

Gets the name of a table given its 1-based table ID.

The Class ULValue object returned is empty if the table does not exist.


GetTableSchema Function

Synopsis

virtual UltraLite_TableSchema * UltraLite_DatabaseSchema_iface::GetTableSchema(
const ULValue & table_id
)

Parameters

  • table_id A 1-based ordinal number.

Remarks

Gets a TableSchema object given a 1-based table ID or name UL_NULL is returned if the table does not exist.


IsCaseSensitive Function

Synopsis

virtual bool UltraLite_DatabaseSchema_iface::IsCaseSensitive()

Remarks

Gets the case sensitivity of the database.

Returns

true is returned if the database is case sensitive.


Class UltraLite_IndexSchema

Synopsis

public UltraLite_IndexSchema

Base classes
  • Class UltraLite_SQLObject_iface
  • Class UltraLite_IndexSchema_iface
Remarks

IndexSchema class.

Members

All members of UltraLite_IndexSchema, including all inherited members.

  • AddRef Function
  • GetColumnCount Function
  • GetColumnName Function
  • GetConnection Function
  • GetID Function
  • GetIFace Function
  • GetName Function
  • GetReferencedIndexName Function
  • GetReferencedTableName Function
  • GetTableName Function
  • IsColumnDescending Function
  • IsForeignKey Function
  • IsForeignKeyCheckOnCommit Function
  • IsForeignKeyNullable Function
  • IsPrimaryKey Function
  • IsUniqueIndex Function
  • IsUniqueKey Function
  • Release Function


Class UltraLite_IndexSchema_iface

Synopsis

public UltraLite_IndexSchema_iface

Derived classes
  • Class UltraLite_IndexSchema
Remarks

IndexSchema interface.

Members

All members of UltraLite_IndexSchema_iface, including all inherited members.

  • GetColumnCount Function
  • GetColumnName Function
  • GetID Function
  • GetName Function
  • GetReferencedIndexName Function
  • GetReferencedTableName Function
  • GetTableName Function
  • IsColumnDescending Function
  • IsForeignKey Function
  • IsForeignKeyCheckOnCommit Function
  • IsForeignKeyNullable Function
  • IsPrimaryKey Function
  • IsUniqueIndex Function
  • IsUniqueKey Function

GetColumnCount Function
GetColumnName Function
GetID Function
GetName Function
GetReferencedIndexName Function
GetReferencedTableName Function
GetTableName Function
IsColumnDescending Function
IsForeignKey Function
IsForeignKeyCheckOnCommit Function
IsForeignKeyNullable Function
IsPrimaryKey Function
IsUniqueIndex Function
IsUniqueKey Function


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_IndexSchema_iface

GetColumnCount Function

Synopsis

virtual ul_column_num UltraLite_IndexSchema_iface::GetColumnCount()

Remarks

Gets the number of columns in the index.


GetColumnName Function

Synopsis

virtual ULValue UltraLite_IndexSchema_iface::GetColumnName(
ul_column_num col_id_in_index
)

Parameters

  • col_id_in_index The 1-based ordinal number indicating the position of the column in the index.

Remarks

Gets the name of the column given the position of the column in the index.

Class ULValue object returned is empty if the column does not exist. SQLE_COLUMN_NOT_FOUND is returned if the column name does not exist.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_IndexSchema_iface

GetID Function

Synopsis

virtual ul_index_num UltraLite_IndexSchema_iface::GetID()

Remarks

Gets the index Id.

Returns

The id of this index.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_IndexSchema_iface

GetName Function

Synopsis

virtual ULValue UltraLite_IndexSchema_iface::GetName()

Remarks

Gets the name of the index.


GetReferencedIndexName Function

Synopsis

virtual ULValue UltraLite_IndexSchema_iface::GetReferencedIndexName()

Remarks

Gets the associated primary index name.

This method is for foreign keys only. The Class ULValue object returned is empty if the index is not a foreign key.


GetReferencedTableName Function

Synopsis

virtual ULValue UltraLite_IndexSchema_iface::GetReferencedTableName()

Remarks

Gets the associated primary table name.

This method is for foreign keys The Class ULValue object returned is empty if the index is not a foreign key


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_IndexSchema_iface

GetTableName Function

Synopsis

virtual ULValue UltraLite_IndexSchema_iface::GetTableName()

Remarks

Gets the name of the table containing the index.


IsColumnDescending Function

Synopsis

virtual bool UltraLite_IndexSchema_iface::IsColumnDescending(
const ULValue & column_name
)

Parameters

  • column_name The column name.

Remarks

Returns true if the column is set to descending order.

SQLE_COLUMN_NOT_FOUND is set if the column name does not exist.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_IndexSchema_iface

IsForeignKey Function

Synopsis

virtual bool UltraLite_IndexSchema_iface::IsForeignKey()

Remarks

Returns true if the index is a foreign key.


IsForeignKeyCheckOnCommit Function

Synopsis

virtual bool UltraLite_IndexSchema_iface::IsForeignKeyCheckOnCommit()

Remarks

Returns true if this foreign key checks referential integrity on commit.

Otherwise RI is checked on insert


IsForeignKeyNullable Function

Synopsis

virtual bool UltraLite_IndexSchema_iface::IsForeignKeyNullable()

Remarks

Returns true if the index is a unique foreign key constraint.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_IndexSchema_iface

IsPrimaryKey Function

Synopsis

virtual bool UltraLite_IndexSchema_iface::IsPrimaryKey()

Remarks

Returns true if the index is the primary key.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_IndexSchema_iface

IsUniqueIndex Function

Synopsis

virtual bool UltraLite_IndexSchema_iface::IsUniqueIndex()

Remarks

Returns true if the index is a unique index.


IsUniqueKey Function

Synopsis

virtual bool UltraLite_IndexSchema_iface::IsUniqueKey()

Remarks

Returns true if the index is a primary key or a unique constraint.


Class UltraLite_PreparedStatement

Synopsis

public UltraLite_PreparedStatement

Base classes
  • Class UltraLite_SQLObject_iface
  • Class UltraLite_PreparedStatement_iface
Remarks

PreparedStatement class.

Members

All members of UltraLite_PreparedStatement, including all inherited members.

  • AddRef Function
  • ExecuteQuery Function
  • ExecuteStatement Function
  • GetConnection Function
  • GetIFace Function
  • GetPlan Function
  • GetSchema Function
  • GetStreamWriter Function
  • HasResultSet Function
  • Release Function
  • SetParameter Function
  • SetParameterNull Function


Class UltraLite_PreparedStatement_iface

Synopsis

public UltraLite_PreparedStatement_iface

Derived classes
  • Class UltraLite_PreparedStatement
Remarks

PreparedStatement interface.

Members

All members of UltraLite_PreparedStatement_iface, including all inherited members.

  • ExecuteQuery Function
  • ExecuteStatement Function
  • GetPlan Function
  • GetSchema Function
  • GetStreamWriter Function
  • HasResultSet Function
  • SetParameter Function
  • SetParameterNull Function

ExecuteQuery Function
ExecuteStatement Function
GetPlan Function
GetSchema Function
GetStreamWriter Function
HasResultSet Function
SetParameter Function
SetParameterNull Function


ExecuteQuery Function

Synopsis

virtual UltraLite_ResultSet * UltraLite_PreparedStatement_iface::ExecuteQuery()

Remarks

Executes a SQL query.

A ResultSet object is returned.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_PreparedStatement_iface

ExecuteStatement Function

Synopsis

virtual ul_s_long UltraLite_PreparedStatement_iface::ExecuteStatement()

Remarks

Executes a SQL statement.


GetPlan Function

Synopsis

virtual size_t UltraLite_PreparedStatement_iface::GetPlan(
ul_char * buffer
size_t size
)

Parameters

  • buffer The buffer to receive the plan description.

  • size The size, in ul_chars, of the buffer.

Remarks

Gets a text-based description of query execution plan.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_PreparedStatement_iface

GetSchema Function

Synopsis

virtual UltraLite_ResultSetSchema * UltraLite_PreparedStatement_iface::GetSchema()

Remarks

Gets the schema for the result set.


GetStreamWriter Function

Synopsis

virtual UltraLite_StreamWriter * UltraLite_PreparedStatement_iface::GetStreamWriter(
ul_column_num parameter_id
)

Parameters

  • parameter_id A column identifier, which may be either a 1-based ordinal number or a column name.

Remarks

Gets a stream writer for streaming string/binary data into a parameter.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_PreparedStatement_iface

HasResultSet Function

Synopsis

virtual bool UltraLite_PreparedStatement_iface::HasResultSet()

Remarks

Determines if this SQL statement has a result set.


SetParameter Function

Synopsis

virtual void UltraLite_PreparedStatement_iface::SetParameter(
ul_column_num parameter_id
ULValue const & value
)

Parameters

  • parameter_id The 1-based ordinal of the parameter.

  • value The value to set the parameter.

Remarks

Sets a parameter for the SQL statement.


SetParameterNull Function

Synopsis

virtual void UltraLite_PreparedStatement_iface::SetParameterNull(
ul_column_num parameter_id
)

Parameters

  • parameter_id The 1-based ordinal of the parameter.

Remarks

Sets a parameter to null.


Class UltraLite_ResultSet

Synopsis

public UltraLite_ResultSet

Base classes
  • Class UltraLite_SQLObject_iface
  • Class UltraLite_ResultSet_iface
  • Class UltraLite_Cursor_iface
Remarks

ResultSet class.

Members

All members of UltraLite_ResultSet, including all inherited members.

  • AddRef Function
  • AfterLast Function
  • BeforeFirst Function
  • First Function
  • Get Function
  • GetConnection Function
  • GetIFace Function
  • GetRowCount Function
  • GetSchema Function
  • GetState Function
  • GetStreamReader Function
  • GetSuspend Function
  • IsNull Function
  • Last Function
  • Next Function
  • Previous Function
  • Relative Function
  • Release Function
  • SetSuspend Function


Class UltraLite_ResultSet_iface

Synopsis

public UltraLite_ResultSet_iface

Derived classes
  • Class UltraLite_ResultSet
Remarks

ResultSet interface.

Members

All members of UltraLite_ResultSet_iface, including all inherited members.

  • GetSchema Function

GetSchema Function


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_ResultSet_iface

GetSchema Function

Synopsis

virtual UltraLite_ResultSetSchema * UltraLite_ResultSet_iface::GetSchema()

Remarks

Gets the schema for this result set.


Class UltraLite_ResultSetSchema

Synopsis

public UltraLite_ResultSetSchema

Base classes
  • Class UltraLite_SQLObject_iface
  • Class UltraLite_RowSchema_iface
Remarks

ResultSetSchema class.

Members

All members of UltraLite_ResultSetSchema, including all inherited members.

  • AddRef Function
  • GetColumnCount Function
  • GetColumnID Function
  • GetColumnName Function
  • GetColumnPrecision Function
  • GetColumnScale Function
  • GetColumnSize Function
  • GetColumnSQLType Function
  • GetColumnType Function
  • GetConnection Function
  • GetIFace Function
  • Release Function


Class UltraLite_RowSchema_iface

Synopsis

public UltraLite_RowSchema_iface

Derived classes
  • Class UltraLite_ResultSetSchema
  • Class UltraLite_TableSchema
Remarks

RowSchema interface.

Members

All members of UltraLite_RowSchema_iface, including all inherited members.

  • GetColumnCount Function
  • GetColumnID Function
  • GetColumnName Function
  • GetColumnPrecision Function
  • GetColumnScale Function
  • GetColumnSize Function
  • GetColumnSQLType Function
  • GetColumnType Function

GetColumnCount Function
GetColumnID Function
GetColumnName Function
GetColumnPrecision Function
GetColumnSQLType Function
GetColumnScale Function
GetColumnSize Function
GetColumnType Function


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_RowSchema_iface

GetColumnCount Function

Synopsis

virtual ul_column_num UltraLite_RowSchema_iface::GetColumnCount()

Remarks

Gets the number of columns in the table.


GetColumnID Function

Synopsis

virtual ul_column_num UltraLite_RowSchema_iface::GetColumnID(
const ULValue & column_name
)

Parameters

  • column_name The column name.

Remarks

Gets the 1-based column ID 0 is returned if the column does not exist SQLE_COLUMN_NOT_FOUND is set if the column name does not exist.


GetColumnName Function

Synopsis

virtual ULValue UltraLite_RowSchema_iface::GetColumnName(
ul_column_num column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Gets the name of a column given its 1-based ID The Class ULValue object returned is empty if the column does not exist.

SQLE_COLUMN_NOT_FOUND is set if the column name does not exist


GetColumnPrecision Function

Synopsis

virtual size_t UltraLite_RowSchema_iface::GetColumnPrecision(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Gets the precision of a numeric column Same errors as GetColumnScale.


GetColumnSQLType Function

Synopsis

virtual ul_column_sql_type UltraLite_RowSchema_iface::GetColumnSQLType(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Gets the SQL type of a column.

See the ul_column_sql_type in ulprotos.h. UL_SQLTYPE_BAD_INDEX is returned if the column does not exist No SQL error is set


GetColumnScale Function

Synopsis

virtual size_t UltraLite_RowSchema_iface::GetColumnScale(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Gets the scale of a numeric column.

0 is returned if the column is not a numeric type or if the column does not exist. SQLE_COLUMN_NOT_FOUND is set if the column name does not exist SQLE_DATATYPE_NOT_ALLOWED is set if the column type is not a numeric.


GetColumnSize Function

Synopsis

virtual size_t UltraLite_RowSchema_iface::GetColumnSize(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Gets the size of the column.

0 is returned if the column does not exist or if the column type does not have a variable length. SQLE_COLUMN_NOT_FOUND is set if the column name does not exist SQLE_DATATYPE_NOT_ALLOWED is set if the column type is not one of the following: UL_SQLTYPE_CHAR UL_SQLTYPE_BINARY


GetColumnType Function

Synopsis

virtual ul_column_storage_type UltraLite_RowSchema_iface::GetColumnType(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Gets the type of a column.

See the ul_column_storage_type enum in ulprotos.h UL_TYPE_BAD_INDEX is returned if the column does not exist No SQL error is set


Class UltraLite_SQLObject_iface

Synopsis

public UltraLite_SQLObject_iface

Derived classes
  • Class UltraLite_Connection
  • Class UltraLite_DatabaseSchema
  • Class UltraLite_IndexSchema
  • Class UltraLite_PreparedStatement
  • Class UltraLite_ResultSet
  • Class UltraLite_ResultSetSchema
  • Class UltraLite_StreamReader
  • Class UltraLite_StreamWriter
  • Class UltraLite_Table
  • Class UltraLite_TableSchema
Remarks

SQLObject interface.

Members

All members of UltraLite_SQLObject_iface, including all inherited members.

  • AddRef Function
  • GetConnection Function
  • GetIFace Function
  • Release Function


AddRef Function

Synopsis

virtual ul_ret_void UltraLite_SQLObject_iface::AddRef()

Remarks

Increase the internal reference count for an object.

Note that you must match each call to AddRef Function with a call to Release Function in order to free the object.


GetConnection Function

Synopsis

virtual UltraLite_Connection * UltraLite_SQLObject_iface::GetConnection()

Remarks

Gets the Connection object.

Returns

The connection associated with this object.


GetIFace Function

Synopsis

virtual ul_void * UltraLite_SQLObject_iface::GetIFace(
ul_iface_id iface
)

Parameters

  • iface Reserved for future use.

Remarks

Reserved for future use.


Release Function

Synopsis

virtual ul_u_long UltraLite_SQLObject_iface::Release()

Remarks

Release a reference to an object.

The object will be freed once all references have been removed. You must call Release Function at least once and if you use AddRef Function you also need a matching call from each AddRef Function.


Class UltraLite_StreamReader

Synopsis

public UltraLite_StreamReader

Base classes
  • Class UltraLite_SQLObject_iface
  • Class UltraLite_StreamReader_iface
Remarks

StreamReader class.

Members

All members of UltraLite_StreamReader, including all inherited members.

  • AddRef Function
  • GetByteChunk Function
  • GetConnection Function
  • GetIFace Function
  • GetLength Function
  • GetStringChunk Function
  • GetStringChunk Function
  • Release Function
  • SetReadPosition Function


Class UltraLite_StreamReader_iface

Synopsis

public UltraLite_StreamReader_iface

Derived classes
  • Class UltraLite_StreamReader
Remarks

StreamReader interface.

This interface supports reading/retrieving string (varchar) and binary columns.

Members

All members of UltraLite_StreamReader_iface, including all inherited members.

  • GetByteChunk Function
  • GetLength Function
  • GetStringChunk Function
  • GetStringChunk Function
  • SetReadPosition Function


GetByteChunk Function

Synopsis

virtual bool UltraLite_StreamReader_iface::GetByteChunk(
ul_byte * data
size_t buffer_len
size_t * len_retn
bool * morebytes
)

Parameters

  • data A buffer of bytes.

  • buffer_len The length of buffer.

  • len_retn output: the length returned.

  • morebytes output: true if there are more bytes to read.

Remarks

Gets a byte chunk from current StreamReader offset.

Copy buffer_len bytes in to buffer data . bytes are read from where the last read left off unless SetReadPosition Function is used.


GetLength Function

Synopsis

virtual size_t UltraLite_StreamReader_iface::GetLength(
bool fetching_as_wide
)

Parameters

  • fetching_as_wide The indicated fetch string type. Use false for binary.

Remarks

Gets the length of a string/binary value.

For binary and for strings fetched as ANSI (fetch_is_wide = false) the number of bytes is returned. When fetching UNICODE (fetch_is_wide = true) the number of unicode characters is returned.


GetStringChunk Function

Synopsis

virtual bool UltraLite_StreamReader_iface::GetStringChunk(
ul_wchar * str
size_t buffer_len
size_t * len_retn
bool * morebytes
)

Parameters

  • str A buffer of wide characters.

  • buffer_len The length of the buffer.

  • len_retn output: the length returned.

  • morebytes output: true if there are more characters to read.

Remarks

Gets a string chunk from current StreamReader offset.

Copy buffer_len wide characters in to buffer str . Characters are read from where the last read left off unless SetReadPosition Function is used.


GetStringChunk Function

Synopsis

virtual bool UltraLite_StreamReader_iface::GetStringChunk(
char * str
size_t buffer_len
size_t * len_retn
bool * morebytes
)

Parameters

  • str A buffer of characters.

  • buffer_len The length of the buffer.

  • len_retn output: the length returned.

  • morebytes output: true if there are more characters to read.

Remarks

Gets a string chunk from current StreamReader offset.

Copy buffer_len bytes in to buffer str . Characters are read from where the last read left off unless SetReadPosition Function is used.


SetReadPosition Function

Synopsis

virtual bool UltraLite_StreamReader_iface::SetReadPosition(
size_t offset
)

Parameters

  • offset The offset. For strings, the offset is in characters.

Remarks

Sets the offset in the data for the next read.


Class UltraLite_StreamWriter

Synopsis

public UltraLite_StreamWriter

Base classes
  • Class UltraLite_SQLObject_iface
Remarks

StreamWriter class.

Members

All members of UltraLite_StreamWriter, including all inherited members.

  • AddRef Function
  • GetConnection Function
  • GetIFace Function
  • Release Function


Class UltraLite_Table

Synopsis

public UltraLite_Table

Base classes
  • Class UltraLite_SQLObject_iface
  • Class UltraLite_Table_iface
  • Class UltraLite_Cursor_iface
Remarks

Table class.

Members

All members of UltraLite_Table, including all inherited members.

  • AddRef Function
  • AfterLast Function
  • BeforeFirst Function
  • Delete Function
  • DeleteAllRows Function
  • Find Function
  • FindBegin Function
  • FindFirst Function
  • FindLast Function
  • FindNext Function
  • FindPrevious Function
  • First Function
  • Get Function
  • GetConnection Function
  • GetIFace Function
  • GetRowCount Function
  • GetSchema Function
  • GetState Function
  • GetStreamReader Function
  • GetStreamWriter Function
  • GetSuspend Function
  • Insert Function
  • InsertBegin Function
  • IsNull Function
  • Last Function
  • Lookup Function
  • LookupBackward Function
  • LookupBegin Function
  • LookupForward Function
  • Next Function
  • Previous Function
  • Relative Function
  • Release Function
  • Set Function
  • SetDefault Function
  • SetNull Function
  • SetSuspend Function
  • TruncateTable Function
  • Update Function
  • UpdateBegin Function


Class UltraLite_Table_iface

Synopsis

public UltraLite_Table_iface

Derived classes
  • Class UltraLite_Table
Remarks

Table interface.

Members

All members of UltraLite_Table_iface, including all inherited members.

  • Delete Function
  • DeleteAllRows Function
  • Find Function
  • FindBegin Function
  • FindFirst Function
  • FindLast Function
  • FindNext Function
  • FindPrevious Function
  • GetSchema Function
  • GetStreamWriter Function
  • Insert Function
  • InsertBegin Function
  • Lookup Function
  • LookupBackward Function
  • LookupBegin Function
  • LookupForward Function
  • Set Function
  • SetDefault Function
  • SetNull Function
  • TruncateTable Function
  • Update Function
  • UpdateBegin Function

Delete Function
DeleteAllRows Function
Find Function
FindBegin Function
FindFirst Function
FindLast Function
FindNext Function
FindPrevious Function
GetSchema Function
GetStreamWriter Function
Insert Function
InsertBegin Function
Lookup Function
LookupBackward Function
LookupBegin Function
LookupForward Function
Set Function
SetDefault Function
SetNull Function
TruncateTable Function
Update Function
UpdateBegin Function


Delete Function

Synopsis

virtual bool UltraLite_Table_iface::Delete()

Remarks

Deletes the current row.

The cursor position is left on the next valid row.


DeleteAllRows Function

Synopsis

virtual bool UltraLite_Table_iface::DeleteAllRows()

Remarks

Deletes all rows from table.

If the stop sync property is set on the connection, the deleted rows are not synchronized.

Note: Uncommitted inserts from other connections are not deleted, any uncommitted deletes from other connections will not be deleted if the other connection does a rollback after DeleteAllRows Function has been called.

Returns

true on success, false otherwise (table not open, SQL error, etc.).


Find Function

Synopsis

virtual bool UltraLite_Table_iface::Find(
ul_column_num ncols
)

Parameters

  • ncols For composite indexes, the number of columns to use in the lookup.

Remarks

Equivalent to FindFirst.

To specify the value to search for, Set the column value for each column in the index

The cursor is left positioned on the first row that exactly matches the index value

If no row matches the index value, the cursor position is AfterLast() and the function returns false


FindBegin Function

Synopsis

virtual bool UltraLite_Table_iface::FindBegin()

Remarks

Selects find mode for setting columns.

Only columns in the index that the table was opened with may be set.


FindFirst Function

Synopsis

virtual bool UltraLite_Table_iface::FindFirst(
ul_column_num ncols
)

Parameters

  • ncols For composite indexes, the number of columns to use in the lookup.

Remarks

Does an exact match lookup based on the current index scanning forward through the table.

  • To specify the value to search for, Set the column value for each column in the index

  • The cursor is left positioned on the first row that exactly matches the index value

  • If no row matches the index value, the cursor position is AfterLast() and the function returns false


FindLast Function

Synopsis

virtual bool UltraLite_Table_iface::FindLast(
ul_column_num ncols
)

Parameters

  • ncols For composite indexes, the number of columns to use in the lookup.

Remarks

Does an exact match lookup based on the current index scanning backward through the table.

  • To specify the value to search for, Set the column value for each column in the index

  • The cursor is left positioned on the first row that exactly matches the index value

  • If no row matches the index value, the cursor position is BeforeFirst() and the function returns false


FindNext Function

Synopsis

virtual bool UltraLite_Table_iface::FindNext(
ul_column_num ncols
)

Parameters

  • ncols For composite indexes, the number of columns to use in the lookup.

Remarks

Gets the next row (forward) that exactly matches the index.

Returns false if no more rows match the index. In this case the cursor is positioned after the last row.


FindPrevious Function

Synopsis

virtual bool UltraLite_Table_iface::FindPrevious(
ul_column_num ncols
)

Parameters

  • ncols For composite indexes, the number of columns to use in the lookup.

Remarks

Gets the previous row (backward) that exactly matches the index.

Returns false if no more rows match the index. In this case the cursor is positioned before the first row.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_Table_iface

GetSchema Function

Synopsis

virtual UltraLite_TableSchema * UltraLite_Table_iface::GetSchema()

Remarks

Gets a schema object for this table.


GetStreamWriter Function

Synopsis

virtual UltraLite_StreamWriter * UltraLite_Table_iface::GetStreamWriter(
const ULValue & column_id
)

Parameters

  • column_id A column identifier, which may be either a 1-based ordinal number or a column name.

Remarks

Gets a stream writer for streaming string/binary data into a column.


Insert Function

Synopsis

virtual bool UltraLite_Table_iface::Insert()

Remarks

Inserts a new row into the table.

The table must be in insert mode for this operation to succeed. Use InsertBegin Function to switch to insert mode.


InsertBegin Function

Synopsis

virtual bool UltraLite_Table_iface::InsertBegin()

Remarks

Selects insert mode for setting columns.

All columns may be modified in this mode.


Lookup Function

Synopsis

virtual bool UltraLite_Table_iface::Lookup(
ul_column_num ncols
)

Parameters

  • ncols For composite indexes, the number of columns to use in the lookup.

Remarks

Equivalent to LookupForward.

To specify the value to search for, Set the column value for each column in the index

The cursor is left positioned on the first row that matches or is greater than the index value

If the resulting cursor position is AfterLast() the return value is false


LookupBackward Function

Synopsis

virtual bool UltraLite_Table_iface::LookupBackward(
ul_column_num ncols
)

Parameters

  • ncols For composite indexes, the number of columns to use in the lookup.

Remarks

Does a lookup based on the current index scanning backward through the table.

  • To specify the value to search for, Set the column value for each column in the index

  • The cursor is left positioned on the last row that matches or is less than the index value

  • If resulting cursor position is BeforeFirst() the return value is false

  • For composite indexes, ncols specifies the number of columns to use in the lookup


LookupBegin Function

Synopsis

virtual bool UltraLite_Table_iface::LookupBegin()

Remarks

Selects lookup mode for setting columns.

Only columns in the index that the table was opened with may be set.


LookupForward Function

Synopsis

virtual bool UltraLite_Table_iface::LookupForward(
ul_column_num ncols
)

Parameters

  • ncols For composite indexes, the number of columns to use in the lookup.

Remarks

Does a lookup based on the current index scanning forward through the table.

  • To specify the value to search for, Set the column value for each column in the index

  • The cursor is left positioned on the first row that matches or is greater than the index value

  • If the resulting cursor position is AfterLast() the return value is false


Set Function

Synopsis

virtual bool UltraLite_Table_iface::Set(
const ULValue & column_id
const ULValue & value
)

Parameters

  • column_id A 1-based ordinal number identifying the column.

  • value The value to which the column is set.

Remarks

Sets a column value.


SetDefault Function

Synopsis

virtual bool UltraLite_Table_iface::SetDefault(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number identifying the column.

Remarks

Sets column(s) to their default value.


SetNull Function

Synopsis

virtual bool UltraLite_Table_iface::SetNull(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number identifying the column.

Remarks

Sets a column to null.


TruncateTable Function

Synopsis

virtual bool UltraLite_Table_iface::TruncateTable()

Remarks

Truncates the table.

Temporarily activates stop synchronization delete.


Update Function

Synopsis

virtual bool UltraLite_Table_iface::Update()

Remarks

Updates the current row.

The table must be in update mode for this operation to succeed. Use UpdateBegin Function to switch to update mode;


UpdateBegin Function

Synopsis

virtual bool UltraLite_Table_iface::UpdateBegin()

Remarks

Selects update mode for setting columns.

Columns in the primary key may not be modified when in update mode.


Class UltraLite_TableSchema

Synopsis

public UltraLite_TableSchema

Base classes
  • Class UltraLite_SQLObject_iface
  • Class UltraLite_TableSchema_iface
  • Class UltraLite_RowSchema_iface
Remarks

TableSchema class.

Members

All members of UltraLite_TableSchema, including all inherited members.

  • AddRef Function
  • GetColumnCount Function
  • GetColumnDefault Function
  • GetColumnID Function
  • GetColumnName Function
  • GetColumnPrecision Function
  • GetColumnScale Function
  • GetColumnSize Function
  • GetColumnSQLType Function
  • GetColumnType Function
  • GetConnection Function
  • GetGlobalAutoincPartitionSize Function
  • GetID Function
  • GetIFace Function
  • GetIndexCount Function
  • GetIndexName Function
  • GetIndexSchema Function
  • GetName Function
  • GetOptimalIndex Function
  • GetPrimaryKey Function
  • GetUploadUnchangedRows Function
  • InPublication Function
  • IsColumnAutoinc Function
  • IsColumnCurrentDate Function
  • IsColumnCurrentTime Function
  • IsColumnCurrentTimestamp Function
  • IsColumnGlobalAutoinc Function
  • IsColumnInIndex Function
  • IsColumnNewUUID Function
  • IsColumnNullable Function
  • IsNeverSynchronized Function
  • Release Function


Class UltraLite_TableSchema_iface

Synopsis

public UltraLite_TableSchema_iface

Derived classes
  • Class UltraLite_TableSchema
Remarks

TableSchema interface.

Members

All members of UltraLite_TableSchema_iface, including all inherited members.

  • GetColumnDefault Function
  • GetGlobalAutoincPartitionSize Function
  • GetID Function
  • GetIndexCount Function
  • GetIndexName Function
  • GetIndexSchema Function
  • GetName Function
  • GetOptimalIndex Function
  • GetPrimaryKey Function
  • GetUploadUnchangedRows Function
  • InPublication Function
  • IsColumnAutoinc Function
  • IsColumnCurrentDate Function
  • IsColumnCurrentTime Function
  • IsColumnCurrentTimestamp Function
  • IsColumnGlobalAutoinc Function
  • IsColumnInIndex Function
  • IsColumnNewUUID Function
  • IsColumnNullable Function
  • IsNeverSynchronized Function

GetColumnDefault Function
GetGlobalAutoincPartitionSize Function
GetID Function
GetIndexCount Function
GetIndexName Function
GetIndexSchema Function
GetName Function
GetOptimalIndex Function
GetPrimaryKey Function
GetUploadUnchangedRows Function
InPublication Function
IsColumnAutoinc Function
IsColumnCurrentDate Function
IsColumnCurrentTime Function
IsColumnCurrentTimestamp Function
IsColumnGlobalAutoinc Function
IsColumnInIndex Function
IsColumnNewUUID Function
IsColumnNullable Function
IsNeverSynchronized Function


GetColumnDefault Function

Synopsis

virtual ULValue UltraLite_TableSchema_iface::GetColumnDefault(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Gets the default value for the column if it exists The Class ULValue object returned has the default contained as a string.

The Class ULValue object returned is empty if the column does not contain a default value. SQLE_COLUMN_NOT_FOUND is set if the column name does not exist.


GetGlobalAutoincPartitionSize Function

Synopsis

virtual bool UltraLite_TableSchema_iface::GetGlobalAutoincPartitionSize(
const ULValue & column_id
ul_u_big * size
)

Parameters

  • column_id A 1-based ordinal number.

  • size output: The partition size for the column.

Remarks

Returns the partition size for a global autoincrement column.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_TableSchema_iface

GetID Function

Synopsis

virtual ul_table_num UltraLite_TableSchema_iface::GetID()

Remarks

Gets the table ID.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_TableSchema_iface

GetIndexCount Function

Synopsis

virtual ul_index_num UltraLite_TableSchema_iface::GetIndexCount()

Remarks

Returns the number of indexes in the table.


GetIndexName Function

Synopsis

virtual ULValue UltraLite_TableSchema_iface::GetIndexName(
ul_index_num index_id
)

Parameters

  • index_id A 1-based ordinal number.

Remarks

Gets the index name given its 1-based ID.

The Class ULValue object returned is empty if the index does not exist.


GetIndexSchema Function

Synopsis

virtual UltraLite_IndexSchema * UltraLite_TableSchema_iface::GetIndexSchema(
const ULValue & index_id
)

Parameters

  • index_id The name or ID number identifying the index.

Remarks

Gets an IndexSchema object with the given name or id.

UL_NULL is returned if the index does not exist


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_TableSchema_iface

GetName Function

Synopsis

virtual ULValue UltraLite_TableSchema_iface::GetName()

Remarks

Gets the name of the table.


GetOptimalIndex Function

Synopsis

virtual ULValue UltraLite_TableSchema_iface::GetOptimalIndex(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Determine the best index to use for searching for a column value.

Returns the name of the index.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class UltraLite_TableSchema_iface

GetPrimaryKey Function

Synopsis

virtual UltraLite_IndexSchema * UltraLite_TableSchema_iface::GetPrimaryKey()

Remarks

Gets the primary key for the table.


GetUploadUnchangedRows Function

Synopsis

virtual bool UltraLite_TableSchema_iface::GetUploadUnchangedRows()

Remarks

Returns true if the table upload every row.

Rows will be uploaded even if they haven't been modified since the last download


InPublication Function

Synopsis

virtual bool UltraLite_TableSchema_iface::InPublication(
const ULValue & publication_name
)

Parameters

  • publication_name The name of the publication.

Remarks

Returns true if the table is contained in the publication SQLE_PUBLICATION_NOT_FOUND is set if the publication does not exist.


IsColumnAutoinc Function

Synopsis

virtual bool UltraLite_TableSchema_iface::IsColumnAutoinc(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Returns true if the column default is set to be auto increment.

SQLE_COLUMN_NOT_FOUND is set if the column name does not exist


IsColumnCurrentDate Function

Synopsis

virtual bool UltraLite_TableSchema_iface::IsColumnCurrentDate(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Returns true if the column has a current date default.


IsColumnCurrentTime Function

Synopsis

virtual bool UltraLite_TableSchema_iface::IsColumnCurrentTime(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Returns true if the column has a current time default.


IsColumnCurrentTimestamp Function

Synopsis

virtual bool UltraLite_TableSchema_iface::IsColumnCurrentTimestamp(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Returns true if the column has a current timestamp default.


IsColumnGlobalAutoinc Function

Synopsis

virtual bool UltraLite_TableSchema_iface::IsColumnGlobalAutoinc(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Returns true if the column default is set to be auto increment SQLE_COLUMN_NOT_FOUND is set if the column name does not exist.


IsColumnInIndex Function

Synopsis

virtual bool UltraLite_TableSchema_iface::IsColumnInIndex(
const ULValue & column_id
const ULValue & index_id
)

Parameters

  • column_id A 1-based ordinal number identifying the column. You can get the column_id by calling GetColumnCount Function.

  • index_id A 1-based ordinal number identifying the index. You can get the number of indexes in a table by calling GetIndexCount Function.

Remarks

Returns true if the column is contained in the index - id must be 1-based.

SQLE_COLUMN_NOT_FOUND is set if the column name does not exist. SQLE_INDEX_NOT_FOUND is set if the index does not exist.


IsColumnNewUUID Function

Synopsis

virtual bool UltraLite_TableSchema_iface::IsColumnNewUUID(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Returns true if the column has a UUID default.


IsColumnNullable Function

Synopsis

virtual bool UltraLite_TableSchema_iface::IsColumnNullable(
const ULValue & column_id
)

Parameters

  • column_id A 1-based ordinal number.

Remarks

Returns true if the column is nullable SQLE_COLUMN_NOT_FOUND is set if the column name does not exist.


IsNeverSynchronized Function

Synopsis

virtual bool UltraLite_TableSchema_iface::IsNeverSynchronized()

Remarks

Returns true if the table is omitted from syncronization.


Class ULValue

Synopsis

public ULValue

Remarks

ULValue object.

The ULValue class is a wrapper for the data types stored in an UltraLite cursor. This allows you to store data without having to worry about the data type.

ULValue contains many constructors and cast operators so that ULValue can be used seamlessly in most cases without explicitly instantiating a ULValue.

Members

All members of ULValue, including all inherited members.

  • GetBinary Function
  • GetBinary Function
  • GetBinaryLength Function
  • GetString Function
  • GetString Function
  • GetStringLength Function
  • InDatabase Function
  • IsNull Function
  • operator bool Function
  • operator DECL_DATETIME Function
  • operator double Function
  • operator float Function
  • operator int Function
  • operator long Function
  • operator short Function
  • operator ul_s_big Function
  • operator ul_u_big Function
  • operator unsigned char Function
  • operator unsigned int Function
  • operator unsigned long Function
  • operator unsigned short Function
  • operator= Function
  • SetBinary Function
  • SetString Function
  • SetString Function
  • StringCompare Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ULValue Function
  • ~ULValue Function

GetBinary Function
GetBinary Function
GetBinaryLength Function
GetString Function
GetString Function
GetStringLength Function
InDatabase Function
IsNull Function
SetBinary Function
SetString Function
SetString Function
StringCompare Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
ULValue Function
operator DECL_DATETIME Function
operator bool Function
operator double Function
operator float Function
operator int Function
operator long Function
operator short Function
operator ul_s_big Function
operator ul_u_big Function
operator unsigned char Function
operator unsigned int Function
operator unsigned long Function
operator unsigned short Function
operator= Function
~ULValue Function


GetBinary Function

Synopsis

void ULValue::GetBinary(
p_ul_binary bin
size_t len
)

Parameters

  • bin The binary structure to receive bytes.

  • len The length of the buffer.

Remarks

Gets a binary value.

Retrieve the current value into a binary buffer, casting as required If the buffer is too small then the value is truncated. Up to len characters are be copied to the given buffer.


GetBinary Function

Synopsis

void ULValue::GetBinary(
ul_byte * dst
size_t len
size_t * retr_len
)

Parameters

  • dst The buffer to receive bytes.

  • len The length of the buffer.

  • retr_len output: The actual number of bytes returned.

Remarks

Gets a binary value.

Retrieve the current value into a binary buffer, casting as required If the buffer is too small then the value is truncated. Up to len bytes are be copied to the given buffer. The number of bytes actually copied is returned in retr_len .


GetBinaryLength Function

Synopsis

size_t ULValue::GetBinaryLength()

Remarks

Gets the length of a Binary value.

Returns

Number of bytes necessary to hold the binary value returned by GetBinary Function.


GetString Function

Synopsis

void ULValue::GetString(
char * dst
size_t len
)

Parameters

  • dst The buffer to receive string value.

  • len The length, in bytes, of dst .

Remarks

Gets the String value.

Retrieve the current value into a string buffer, casting as required. The output string is always null-terminated, if the buffer is too small then the value is truncated. Up to len characters are be copied to the given buffer, including the null terminator.


GetString Function

Synopsis

void ULValue::GetString(
ul_wchar * dst
size_t len
)

Parameters

  • dst The buffer to receive string value.

  • len The length, in wide chars, of dst .

Remarks

Gets a String value.

Retrieve the current value into a string buffer, casting as required. The output string is always null-terminated, if the buffer is too small then the value is truncated. Up to len characters are be copied to the given buffer, including the null terminator.


GetStringLength Function

Synopsis

size_t ULValue::GetStringLength(
bool fetching_as_wide
)

Parameters

  • fetching_as_wide The indicated fetch string type.

Remarks

Gets the length of a String.

Intended usage is as follows.

          len = v.GetStringLength();
          dst = new char_type[ len ];
          ( dst, len ); GetString

Given this usage, the length may be different for different character types because of multi-element encodings. The fetching_as_wide parmeter is used to indicate what character type is used with the GetString Function call.

Returns

Number of bytes or wide chars required to hold the string returned by one of the GetString Function methods, including the null-terminator. This is not necessarily the number of characters in the string.


InDatabase Function

Synopsis

bool ULValue::InDatabase()

Remarks

Check if value is in the Database.

Returns

Returns true if this object is referencing a cursor field


IsNull Function

Synopsis

bool ULValue::IsNull()

Remarks

Check if NULL.

Returns

Returns true if this object is an empty ULValue object, or if it references a cursor field that is set to NULL.


SetBinary Function

Synopsis

void ULValue::SetBinary(
ul_byte * src
size_t len
)

Parameters

  • src A buffer of bytes.

  • len The length of the buffer.

Remarks

Sets a Binary value.

Set the value to reference the binary buffer provided. No bytes are copied from the provided buffer until the value is used.


SetString Function

Synopsis

void ULValue::SetString(
const char * val
size_t len
)

Parameters

  • val A pointer to the null-terminated string representation of this ULValue.

  • len The length of the string.

Remarks

Cast a ULValue to a string.


SetString Function

Synopsis

void ULValue::SetString(
const ul_wchar * val
size_t len
)

Parameters

  • val A pointer to the null-terminated unicode string representation of this ULValue.

  • len The length of the string.

Remarks

Cast a ULValue to a unicode string.


StringCompare Function

Synopsis

ul_compare ULValue::StringCompare(
const ULValue & value
)

Parameters

  • value The string to compare with.

Remarks

Compare strings.

Compares strings, or string representations of ULValue objects

Returns

  • Returns 0 if the strings are equal.

  • Returns -1 if the current value compares less than value .

  • Returns 1 if the current value compares greater than value .

  • On error returns -3 if the sqlca of either ULValue object is not set or -2 if the string representation of either ULValue object is UL_NULL


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

ULValue Function

Synopsis

ULValue::ULValue()

Remarks

Construct a ULValue.


ULValue Function

Synopsis

ULValue::ULValue(
const ULValue & vSrc
)

Parameters

  • vSrc A value to be treated as a ULValue.

Remarks

Construct a ULValue from a const.


ULValue Function

Synopsis

ULValue::ULValue(
bool val
)

Parameters

  • val A boolean value to be treated as a ULValue.

Remarks

Construct a ULValue from a boool.


ULValue Function

Synopsis

ULValue::ULValue(
short val
)

Parameters

  • val A short value to be treated as a ULValue.

Remarks

Construct a ULValue from a short.


ULValue Function

Synopsis

ULValue::ULValue(
long val
)

Parameters

  • val A long value to be treated as a ULValue.

Remarks

Construct a ULValue from a long.


ULValue Function

Synopsis

ULValue::ULValue(
int val
)

Parameters

  • val An int value to be treated as a ULValue.

Remarks

Construct a ULValue from an int.


ULValue Function

Synopsis

ULValue::ULValue(
unsigned int val
)

Parameters

  • val An unsigned int value to be treated as a ULValue.

Remarks

Construct a ULValue from an unsigned int.


ULValue Function

Synopsis

ULValue::ULValue(
float val
)

Parameters

  • val A float value to be treated as a ULValue.

Remarks

Construct a ULValue from a float.


ULValue Function

Synopsis

ULValue::ULValue(
double val
)

Parameters

  • val A double value to be treated as a ULValue.

Remarks

Construct a ULValue from a double.


ULValue Function

Synopsis

ULValue::ULValue(
unsigned char val
)

Parameters

  • val An unsigned char to be treated as a ULValue.

Remarks

Construct a ULValue from an unsigned char.


ULValue Function

Synopsis

ULValue::ULValue(
unsigned short val
)

Parameters

  • val An unsigned short to be treated as a ULValue.

Remarks

Construct a ULValue from an unsigned short.


ULValue Function

Synopsis

ULValue::ULValue(
unsigned long val
)

Parameters

  • val An unsigned long to be treated as a ULValue.

Remarks

Construct a ULValue from an unsigned long.


ULValue Function

Synopsis

ULValue::ULValue(
const ul_u_big & val
)

Parameters

  • val A ul_u_big value to be treated as a ULValue.

Remarks

Construct a ULValue from a ul_u_big.


ULValue Function

Synopsis

ULValue::ULValue(
const ul_s_big & val
)

Parameters

  • val A ul_s_big value to be treated as a ULValue.

Remarks

Construct a ULValue from a ul_s_big.


ULValue Function

Synopsis

ULValue::ULValue(
const p_ul_binary val
)

Parameters

  • val A ul_binary value to be treated as a ULValue.

Remarks

Construct a ULValue from a ul_binary.


ULValue Function

Synopsis

ULValue::ULValue(
DECL_DATETIME & val
)

Parameters

  • val A datetime value to be treated as a ULValue.

Remarks

Construct a ULValue from a datetime.


ULValue Function

Synopsis

ULValue::ULValue(
const char * val
)

Parameters

  • val A pointer to a string to be treated as a ULValue.

Remarks

Construct a ULValue from a string.


ULValue Function

Synopsis

ULValue::ULValue(
const ul_wchar * val
)

Parameters

  • val A pointer to a unicode string to be treated as a ULValue.

Remarks

Construct a ULValue from a unicode string.


ULValue Function

Synopsis

ULValue::ULValue(
const char * val
size_t len
)

Parameters

  • val A buffer holding the string to be treated as a ULValue.

  • len The length of the buffer.

Remarks

Construct a ULValue from a buffer of characters.


ULValue Function

Synopsis

ULValue::ULValue(
const ul_wchar * val
size_t len
)

Parameters

  • val A buffer holding the string to be treated as a ULValue.

  • len The length of the buffer.

Remarks

Construct a ULValue from a buffer of unicode characters.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator DECL_DATETIME Function

Synopsis

ULValue::operator DECL_DATETIME()

Remarks

Cast a ULValue to a datetime.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator bool Function

Synopsis

ULValue::operator bool()

Remarks

Cast a ULValue to a boolean.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator double Function

Synopsis

ULValue::operator double()

Remarks

Cast a ULValue to a double.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator float Function

Synopsis

ULValue::operator float()

Remarks

Cast a ULValue to a float.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator int Function

Synopsis

ULValue::operator int()

Remarks

Cast a ULValue to an int.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator long Function

Synopsis

ULValue::operator long()

Remarks

Cast a ULValue to a long.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator short Function

Synopsis

ULValue::operator short()

Remarks

Cast a ULValue to a short.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator ul_s_big Function

Synopsis

ULValue::operator ul_s_big()

Remarks

Cast a ULValue to a signed big int.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator ul_u_big Function

Synopsis

ULValue::operator ul_u_big()

Remarks

Cast a ULValue to an unsigned big int.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator unsigned char Function

Synopsis

ULValue::operator unsigned char()

Remarks

Cast a ULValue to a char.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator unsigned int Function

Synopsis

ULValue::operator unsigned int()

Remarks

Cast a ULValue to an unsigned int.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator unsigned long Function

Synopsis

ULValue::operator unsigned long()

Remarks

Cast a ULValue to an unsigned long.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

operator unsigned short Function

Synopsis

ULValue::operator unsigned short()

Remarks

Cast a ULValue to an unsigned short.


operator= Function

Synopsis

ULValue & ULValue::operator=(
const ULValue & other
)

Parameters

  • other The value to be assigned to a ULValue.

Remarks

Override the = operator for ULValues.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite C++ Component API Reference

Class ULValue

~ULValue Function

Synopsis

ULValue::~ULValue()

Remarks

Destructor for ULValue.


UltraLite Static C++ API Reference

About this chapter

This chapter describes the UltraLite Static C++ API.

C++ API class hierarchy
C++ API language elements
ULConnection class
ULCursor class
ULData class
ULResultSet class
ULTable class
Generated result set class
Generated statement class
Generated table class


C++ API class hierarchy

The classes in the C++ API are displayed in the following diagram:

The classes in the C++ API hierarchy.

The classes are described in the following header files:

  • generated-name.hpp The interface generated for a particular set of statements or tables is defined in the generated .hpp file.

  • ulapi.h The base classes are defined in ulapi.h, in the h subdirectory of your SQL Anywhere installation directory.

  • ulglobal.h You may want to look at ulglobal.h, in the h subdirectory of your SQL Anywhere installation directory, for some of the data types and other definitions used in ulapi.h.

Functions available from the Static C++ API

C++ API applications use some functions that are not part of the class hierarchy. These functions are as follows:

  • ULEnableFileDB function.

  • ULEnablePalmRecordDB function.

  • ULEnableStrongEncryption function.

  • ULEnableUserAuthentication function.

  • ULRegisterErrorCallback function.

  • ULRegisterSchemaUpgradeObserver function.


C++ API language elements

The UltraLite API methods and variables are described in terms of a set of UltraLite data types. These data types are described in this section.

UltraLite data types


UltraLite data types

  • an_SQL_code A data type for holding SQL error codes.

  • ul_char A data type representing a character. If the operating system uses Unicode, ul_char uses two bytes per character. For single-byte character sets, ul_char uses a single byte per character.

  • ul_binary A data type representing one byte of binary information.

  • ul_column_num A data type for holding a number indicating a column of a table or query. The first column in the table or query is number one.

  • ul_fetch_offset A data type for holding a relative number in a ULCursor object.

  • ul_length A data type for holding the length of a data type.

  • DECL_DATETIME A type for holding date and time information in a SQLDATETIME structure, which is defined as follows:

    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;

    DECL_DATETIME is also used in embedded SQL programming. Other embedded SQL data types with named DECL_type are not needed in C++ API programming.

  • UL_NULL A constant representing a SQL NULL.


ULConnection class

Object

Represents a database connection.

Description

A ULConnection object represents an UltraLite database connection. It provides methods to open and close a connection, to check whether a connection is open, to synchronize a database on the current connection, and more.

For embedded SQL users, opening a ULConnection object is equivalent to the EXEC SQL CONNECT statement.

Close method
Commit method
CountUploadRows method
GetCA method
GetDatabaseID method
GetLastIdentity method
GetLastDownloadTime method
GetSQLCode method
GetSynchResult method
GlobalAutoincUsage method
GrantConnectTo method
InitSynchInfo method
IsOpen method
LastCodeOK method
LastFetchOK method
Open method
Reopen method (deprecated)
ResetLastDownloadTime method
RevokeConnectFrom method
Rollback method
RollbackPartialDownload method
SetDatabaseID method
StartSynchronizationDelete method
StopSynchronizationDelete method
Synchronize method


Close method

Prototype

bool Close ( )

Description

Disconnects your application from the database, and frees resources associated with the ULConnection object. Once you have closed the ULConnection object, your application is no longer connected to the UltraLite database.

Closing a connection rolls back any outstanding changes.

You should not close a connection object in a Palm Computing Platform application. Instead, use the Reopen method when the application is reactivated. For more information, see Reopen method (deprecated).

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example closes a ULConnection object:

conn.Close();
See also

Open method


Commit method

Prototype

bool Commit( )

Description

Commits outstanding changes to the database.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following code inserts a value to the database, and commits the change.

productTable.Open( &conn );
productTable.SetProd_id( 2 );
productTable.SetPrice( 3000 );
productTable.SetProd_name( "8' 2x4 Studs x1000" );
productTable.Insert();
conn.Commit();
See also

Rollback method


CountUploadRows method

Prototype

ul_u_long CountUploadRows(
ul_publication_mask mask,
ul_u_long threshold )

Description

Returns the number of rows that need to be uploaded when the next synchronization takes place.

You can use this function to determine if a synchronization is needed.

Parameters

publication-mask A set of publications to check. A value of 0 corresponds to the entire database. The set is supplied as a mask. For example, the following mask corresponds to publications PUB1 and PUB2.:

UL_PUB_PUB1 | UL_PUB_PUB2

For more information on publication masks, see publication synchronization parameter.

threshold A value that determines the maximum number of rows to count, and so limits the amount of time taken by the call. A value of 0 corresponds to no limit. A value of 1 determines if any rows need to be synchronized.

Returns

The number of rows to be uploaded.


GetCA method

Prototype

SQLCA *GetCA( )

Description

Retrieves the SQLCA associated with the current connection.

This function is useful if you are combining embedded SQL and the C++ API in a single application.

Returns

A pointer to the SQLCA.

Example
ULConnection conn;
conn.Open();
conn.GetCA();
See also

The SQL Communication Area (SQLCA)


GetDatabaseID method

Prototype

ul_u_long ULGetDatabaseID( )

Description

ULGetDatabaseID returns the current database ID used for global autoincrement. It returns the value set by the last call to SetDatabaseID or UL_INVALID_DATABASE_ID if the ID was never set.


GetLastIdentity method

Prototype

ul_u_big GetLastIdentity( )

Description

Returns the most recent identity value used. This function is equivalent to the following SQL statement:

SELECT @@identity

The function is particularly useful in the context of global autoincrement columns.

Returns

The last identity value.

See also

Determining the most recently assigned value

Declaring default global autoincrement columns


GetLastDownloadTime method

Prototype

bool GetLastDownloadTime(
ul_publication_mask mask,
DECL_DATETIME *value )

Description

Provides the last time a specified publication was downloaded.

Parameters

publication-mask A set of publications for which the last download time is retrieved. A value of 0 corresponds to the entire database. The set is supplied as a mask. For example, the following mask corresponds to publications PUB1 and PUB2.:

UL_PUB_PUB1 | UL_PUB_PUB2

For more information on publication masks, see publication synchronization parameter.

value A pointer to the DECL_DATETIME structure to be populated.

A value of January 1, 1990 indicates that the publication has yet to be synchronized.

Returns

  • true Indicates that value is successfully populated by the last download time of the publication specified by publication-mask.

  • false Indicates that publication-mask specifies more than one publication or that the publication is undefined. If the return value is false, the contents of value are not meaningful.


GetSQLCode method

Prototype

an_SQL_code GetSQLCode( )

Description

Provides error checking capabilities by checking the SQLCODE value for the success or failure of a database operation. The SQLCODE is the standard Adaptive Server Anywhere code.

SQLCODE is reset by any subsequent UltraLite database operation, including those on other connections.

Returns

The SQLCODE value as an integer.

Example

The following code writes out a SQLCODE. If the synchronization call fails, a value of -85 is returned.

conn.Synchronize( &synch_info );
sqlcode = conn.GetSQLCode();
printf("sqlcode: %d\n", sqlcode );
See also

ASA Error Messages


GetSynchResult method

Prototype

bool GetSynchResult( ul_synch_result * synch-result );

Description

Stores the results of the most recent synchronization, so that appropriate action can be taken in the application:

The application must allocate a ul_synch_result object before passing it to GetSynchResult. The function fills the ul_synch_result with the result of the last synchronization. These results are stored persistently in the database.

The function is of particular use when synchronizing applications on the Palm Computing Platform using HotSync, as the synchronization takes place outside the application itself. The SQLCODE value set in the call to ULData.PalmLaunch reflects the ULData.PalmLaunch operation itself. The synchronization status and results are written to the HotSync log only. To obtain extended synchronization result information, call GetSynchResult after a successful ULData.PalmLaunch.

Parameters

synch-result A structure to hold the synchronization result. It is defined in ulglobal.h as follows:.

typedef struct {
an_sql_code sql_code;
ul_stream_error stream_error;
ul_bool upload_ok;
ul_bool ignored_rows;
ul_auth_status auth_status;
ul_s_long auth_value;
SQLDATETIME timestamp;
ul_synch_status status;
} ul_synch_result, * p_ul_synch_result;

where the individual members have the following meanings:

  • sql_code The SQL code from the last synchronization. For a list of SQL codes, see Error messages indexed by Adaptive Server Anywhere SQLCODE.

  • stream_error The communication stream error code from the last synchronization. For a listing, see MobiLink Communication Error Messages.

  • upload_ok Set to true if the upload was successful; false otherwise.

  • ignored_rows Set to true if uploaded rows were ignored; false otherwise.

  • auth_status The synchronization authentication status. For more information, see auth_status parameter.

  • auth_value The value used by the MobiLink synchronization server to determine the auth_status result. For more information, see auth_value synchronization parameter.

  • timestamp The time and date of the last synchronization.

  • status The status information used by the observer function. For more information, see observer synchronization parameter.

Returns

The method returns a boolean value.

true Success.

false Failure.

See also

PalmLaunch method [deprecated]


GlobalAutoincUsage method

Prototype

ul_u_short GlobalAutoincUsage()

Description

Returns the percentage of available global autoincrement values that have been used.

If the percentage approaches 100, your application should set a new value for the global database ID, using the SetDatabaseID.

Returns

The percent usage of the available global autoincrement values.

See also

SetDatabaseID method


GrantConnectTo method

Prototype

bool GrantConnectTo( userid, password )

Parameters

userid Character array holding the user ID. The maximum length is 16 characters.

password Character array holding the password for userid. The maximum length is 16 characters.

Description

Grant access to an UltraLite database for a user ID with a specified password. If an existing user ID is specified, this function updates the password for the user.

See also

User authentication in UltraLite

Authenticating users

RevokeConnectFrom method


InitSynchInfo method

Prototype

an_SQL_code InitSynchInfo( ul_synch_info * synch_info )

Description

Initializes the synch_info structure used for synchronization.

Returns

None

Example

The following code illustrates where the InitSynchInfo method is used in the sequence of calls that synchronize data in a UltraLite application.

auto ul_synch_info synch_info;
conn.InitSynchInfo( &synch_info );
conn.Synchronize( &synch_info );
See also

Synchronize method


IsOpen method

Prototype

bool IsOpen ( )

Description

Checks whether the ULConnection object is currently open.

Returns

true (1) if the ULConnection object is open.

false (0) if the ULConnection object is not open.

Example

The following example checks that an attempt to Open a connection succeeded:

ULConnection conn;
conn.Open();
if( conn.IsOpen() ){
   printf( "Connected to the database.\n" );
}
See also

Open method


LastCodeOK method

Prototype

bool LastCodeOK ( )

Description

Checks the most recent SQLCODE and returns true if the code represents a warning or success. The function returns false if the most recent SQLCODE represents an error.

This method provides a convenient way of checking for the success or potential failure of operations. You can use GetSQLCode to obtain the numerical value.

SQLCODE is reset by any subsequent UltraLite database operation, including those on other connections.

Returns

true (1) if the previous SQLCode was zero or a warning.

false (0) if the previous SQLCode was an error.

Example

The following example checks that an attempt to Open a connection succeeded:

ULConnection conn;
conn.Open();
if( conn.LastCodeOK() ){
   printf( "Connected to the database.\n" );
};
See also

GetSQLCode method


LastFetchOK method

Prototype

bool LastFetchOK( )

Description

Provides a convenient way of checking that the most recent fetch of a row succeeded (true) or failed (false).

The value is reset by any subsequent UltraLite database operation, including those on other connections.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example moves to the last row in a table, fetches a value from the row, and checks for the success of the fetch:

tb.Open( &conn );
tb.Last();
tb.GetID( iVal );
if( tb.LastFetchOK() ){
   ... operations on success...
}
See also

AfterLast method

First method


Open method

Prototype

bool Open ( ULData* db,
ul_char* userid,
ul_char* password,
ul_char* name = SQLNULL )

bool Open ( SQLCA * sqlca, char * start-parms )

Description

Open a connection to a database. The ULData object must be open for this call to succeed.

Parameters

db A pointer to the ULData object on which the connection is made. This argument is usually the address of the ULData object opened prior to making the connection.

userid The user ID argument is a placeholder reserved for possible future use. It is ignored.

For more information on user IDs and UltraLite, see User authentication in UltraLite.

password The password parameter is a placeholder reserved for possible future use. It is ignored.

name An optional name for the connection. This is needed only if you have multiple connections from a single application to the same database.

start-parms A connection string, consisting of a semicolon-separated list of keyword=value pairs.

For information on allowed keywords, see Connection Parameters.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example opens a connection to the UltraLite database.

ULData db;
ULConnection conn;

db.Open();
conn.Open( &db, "dummy", "dummy" );
See also

Close method


Reopen method (deprecated)

Prototype

bool Reopen ( )

bool Reopen( ULData *db, ul_char * name = SQLNULL )

Description
Deprecated feature
The Reopen method is no longer needed and is deprecated. Use ULConnection::Open instead.

This method is available for the Palm Computing Platform only. The ULData object must be reopened for this call to succeed.

When developing Palm applications, you should never close the connection object. Instead, you should call Reopen when the user switches to the UltraLite application. The method prepares the data in use by the database object for use by the application.

db A pointer to the ULData object on which the connection is made. This argument is usually the address of the ULData object opened prior to reopening the connection.

name An optional name for the connection. This is needed only if you have multiple connections from a single application to the same database.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example reopens a database object, and then a connection object:

db.Reopen();
conn.Reopen( &db );
See also

Open method


ResetLastDownloadTime method

Prototype

bool ResetLastDownloadTime( ul_publication_mask publication-mask )

Description

This method can be used to repopulate values and return an application to a known clean state. It resets the last download time so that the application resynchronizes previously downloaded data.

Parameters

publication-mask A set of publications to check. A value of 0 corresponds to the entire database. The set is supplied as a mask. For example, the following mask corresponds to publications PUB1 and PUB2.:

UL_PUB_PUB1 | UL_PUB_PUB2

For more information on publication masks, see publication synchronization parameter.

Example

The following example resets the download time for all tables in the database:

db.Reopen();
conn.ResetLastDownloadTime( UL_SYNC_ALL );
See also

GetLastDownloadTime method

Timestamp-based synchronization


RevokeConnectFrom method

Prototype

bool RevokeConnectFrom( ul_char * userid )

Description

Revoke access from an UltraLite database for a user ID.

Parameters

userid Character array holding the user ID to be excluded from database access. The maximum length is 16 characters.

See also

User authentication in UltraLite

Authenticating users

GrantConnectTo method


Rollback method

Prototype

bool Rollback( )

Description

Rolls back outstanding changes to the database.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following code inserts a value to the database, but then rolls back the change.

productTable.Open( &conn );
productTable.SetProd_id( 2 );
productTable.SetPrice( 3000 );
productTable.SetProd_name( "8' 2x4 Studs x1000" );
productTable.Insert();
conn.Rollback();
See also

Commit method


RollbackPartialDownload method

Roll back the changes from a failed synchronization.

Prototype

bool RollbackPartialDownload ( )

Description

When a communication error occurs during the download phase of synchronization, UltraLite can apply the downloaded changes, so that the synchronization can be resumed from the place it was interrupted. If the download changes are not needed (the user or application does not want to resume the download at this point), RollbackPartialDownload rolls back the failed download transaction.

See also
  • Resuming failed downloads
  • Keep Partial Download synchronization parameter
  • Partial Download Retained synchronization parameter
  • Resume Partial Download synchronization parameter


SetDatabaseID method

Prototype

bool SetDatabaseID( ul_u_long value )

Description

Sets the database ID value to be used for global autoincrement columns

Parameters

value The value to use for generating global autoincrement values.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

GLOBAL_DATABASE_ID option [database]

GlobalAutoincUsage method


StartSynchronizationDelete method

Prototype

bool StartSynchronizationDelete( )

Description

Once this function is called, all delete operations are again synchronized.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

START SYNCHRONIZATION DELETE statement [MobiLink]

StopSynchronizationDelete method


StopSynchronizationDelete method

Prototype

bool StopSynchronizationDelete( )

Description

Prevents delete operations from being synchronized. This is useful for deleting old information from an UltraLite database to save space, while not deleting this information on the consolidated database.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

START SYNCHRONIZATION DELETE statement [MobiLink]

StartSynchronizationDelete method


Synchronize method

Prototype

bool Synchronize ( ul_synch_info * synch_info )

Description

Synchronizes an UltraLite database.

For a detailed description of the members of the synch_info structure, see Synchronization parameters.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following code fragment illustrates how information is provided to the Synchronize method.

auto ul_synch_info synch_info;
conn.InitSynchInfo( &synch_info );
synch_info.user_name = UL_TEXT( "50" );
synch_info.version = UL_TEXT( "custdb" );
synch_info.stream = ULSocketStream();
synch_info.stream_parms =
   UL_TEXT("host=localhost");
conn.Synchronize( &synch_info );
See also

Synchronization parameters


ULCursor class

The ULCursor class contains methods needed by both generated table objects and generated result set objects.

For its position in the API hierarchy, see C++ API class hierarchy.

Data types enumeration
SQL data types enumeration
AfterLast method
BeforeFirst method
Close method
Delete method
First method
Get method
GetColumnCount method
GetColumnSize method
GetColumnType method
GetColumnSQLType method
GetSQLCode method
Insert method
IsOpen method
Last method
LastCodeOK method
LastFetchOK method
Next method
Open method
Previous method
Relative method
Reopen method
Set method
SetColumnNull method
Update method


Data types enumeration

This enumeration lists the available UltraLite data types, as constants. It contains the following members:

Enumeration value | Description
BAD_INDEX | An inappropriate argument was provided
S_LONG | Signed 4-byte integer
S_SHORT | Signed 2-byte integer
LONG | 4-byte integer
SHORT | 2-byte integer
TINY | 1-byte integer
BIT | Bit
TIMESTAMP_STRUCT | Timestamp information as a struct.
DATE | Data and time information as a string
TIME | Time information as a string
S_BIG | Signed 8-byte integer
BIG | 8-byte integer
DOUBLE | Double precision number
REAL | Real number
BINARY | Binary data, with a specified length
TCHAR | Character data, with a specified length
NUMERIC | Exact numerical data, with a specified precision and scale
MAX_INDEX | Reserved

The GetColumnType method returns a value from this enumeration.

See also

GetColumnType method


SQL data types enumeration

This enumeration lists the available UltraLite SQL data types, as constants. It contains the following members:

enum {
       SQL_BAD_INDEX,
       SQL_S_LONG,
       SQL_U_LONG,
       SQL_LONG = SQL_U_LONG,
       SQL_S_SHORT,
       SQL_U_SHORT,
       SQL_SHORT = SQL_U_SHORT,
       SQL_S_BIG,
       SQL_U_BIG,
       SQL_BIG = SQL_U_BIG,
       SQL_TINY,
       SQL_BIT,
       SQL_TIMESTAMP,
       SQL_DATE,
       SQL_TIME,
       SQL_DOUBLE,
       SQL_REAL,
       SQL_NUMERIC,
       SQL_BINARY,
       SQL_CHAR,
       SQL_LONGVARCHAR,
       SQL_LONGBINARY,
       SQL_MAX_INDEX
   };

The GetColumnSQLType method returns a value from this enumeration.

See also

GetColumnSQLType method


AfterLast method

Prototype

bool AfterLast( )

Description

Changes the cursor position to be after the last row in the current table or result set.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example makes the current row the last row of the table tb:

tb.AfterLast();
tb.Previous();
See also

BeforeFirst method

Last method


BeforeFirst method

Prototype

bool BeforeFirst( )

Description

Changes the cursor position to be before the first row in the current table or result set.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example makes the current row the first row of the table tb:

tb.BeforeFirst();
tb.Next();
See also

AfterLast method

First method


Close method

Prototype

bool Close( )

Description

Frees resources associated with the generated object in your application. This method must be called after all processing involving the table is complete, and before the ULConnection and ULData objects are closed.

Any uncommitted operations are rolled back when the Close() method is called.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example closes a generated object for a table named ULProduct:

tb.Close();
See also

Open method


Delete method

Prototype

bool Delete( )

Description

Deletes the current row from the current table or result set.

Returns

true (1) if successful.

false (0) if unsuccessful. For example, if you attempt to use the method on a SQL statement that represents more than one table.

Example

The following example deletes the last row from a table tb:

tb.Open( &conn );
tb.Last();
tb.Delete();
See also

Insert method

Update method


First method

Prototype

bool First( )

Description

Moves the cursor to the first row of the table or result set.

Returns

true (1) if successful.

false (0) if unsuccessful. For example, the method fails if there are no rows.

Example

The following example deletes the first row from a table tb:

tb.Open( &conn );
tb.First();
tb.Delete();
See also

BeforeFirst method

Last method


Get method

Prototype

bool Get( ul_column_num colnum,
value-declaration,
bool* isNull = UL_NULL)

value-declaration:
ul_char * ptr, ul_length length
| p_ul_binary name , ul_length length
| DECL_DATETIME &date-value
| { DECL_BIGINT | DECL_UNSIGNED_BIGINT } &bigint-value
| [ unsigned ] long &integer-value
| unsigned char &char-value
| double & double-value
| float & float-value
| [ unsigned ] short &short-value

Description

Gets a value from the specified column.

colnum A 2-byte integer. The first column is column 1.

value declaration The arguments required to specify the value depend on the data type. Character and binary data must be mapped into buffers, with the buffer name and length specified in the call. For other data types, a pointer to a variable of the proper type is needed. For character data, the length parameter specifies the length of the C array including the space used for the terminator.

isNULL If a value in a column is NULL, isNull is set to true. In this case, the value argument is not meaningful.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

Get generated method

Set method


GetColumnCount method

Prototype

int GetColumnCount( )

Description

Returns the number of columns in the current table or result set.

Returns

Integer number of columns.

Example

The following example opens a table object named tb and places the number of columns in the variable numCol:

tb.Open( &conn );
numCol = tb.GetColumnCount();


GetColumnSize method

Prototype

ul_length GetColumnSize( ul_column_num column-index )

Description

Returns the number of bytes needed to hold the information in the specified column.

Parameters

column-index The number of the column. The first column in the table has a value of one.

Returns

The number of bytes.

Example

The following example gets the number of bytes needed to hold the third column in the table tb:

tb.Open( &conn );
colSize = tb.GetColumnSize( 3 );
See also

GetColumnType method


GetColumnType method

Prototype

int GetColumnType( ul_column_num column-index )

Description

Returns the data type needed to hold the information in the specified column.

Parameters

column-index The number of the column. The first column in the table or result set has a value of one.

Returns

The column type is a member of the UltraLite data types enumeration. For more information, see Data types enumeration:

Example

The following example gets the column type for the third column in the table tb:

tb.Open( &conn );
colType = tb.GetColumnType( 3 );
See also

Data types enumeration

Get generated method

GetColumnSQLType method


GetColumnSQLType method

Prototype

int GetColumnSQLType( ul_column_num column-index )

Description

Returns the SQL data type of the specified column.

Parameters

column-index The number of the column. The first column in the table or result set has a value of one.

Returns

The column type is a member of the UltraLite data types enumeration. For more information, see Data types enumeration:

Example

The following example gets the column type for the third column in the table tb:

tb.Open( &conn );
colType = tb.GetColumnType( 3 );
See also

Data types enumeration

Get generated method

GetColumnType method


GetSQLCode method

This is a convenience method that calls the ULConnection::GetSQLCode method.

For more information see GetSQLCode method.


Insert method

Prototype

bool Insert( )

Description

Inserts a row in the table with values specified in previous Set methods.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example inserts a new row into the table based at the current position:

productTable.SetProd_id( 2 );
productTable.SetPrice( 3000 );
productTable.SetProd_name( "8' 2x4 Studs x1000" );
productTable.Insert();

When inserting a row, you must supply a value for each column in the table.

For information on cursor positioning after inserts, and the position of the inserted row, see Accessing data.

See also

Delete method

Update method


IsOpen method

Prototype

bool IsOpen ( )

Description

Checks whether the ULCursor object is currently open.

Returns

true (1) if the ULCursor object is open.

false (0) if the ULCursor object is not open.

See also

Open method


Last method

Prototype

bool Last( )

Description

Move the cursor to the last row in the table or result set.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example moves to a position after the last row in a table:

tb.Open( &conn );
tb.Last();
tb.Next();
See also

AfterLast method

First method


LastCodeOK method

This is a convenience method that calls the ULConnection::LastCodeOK method.

For more information see LastCodeOK method.


LastFetchOK method

This is a convenience method that calls the ULConnection::LastFetchOK method.

For more information see LastFetchOK method.


Next method

Prototype

bool Next( )

Description

Moves the cursor position to the next row in the table or result set.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example moves the cursor position to the first row in the table:

tb.Open( &conn );
tb.BeforeFirst();
tb.Next();
See also

Previous method

Relative method


Open method

Prototype

bool Open( ULConnection * conn )

Description

Opens a cursor on the specified connection. If the object is a result set with parameters, you must set the parameters before opening the result set.

When using Open from the ULTable subclass of ULCursor, do not open two connections on a ULTable object at one time.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example opens a result set object (which extends the cursor class) and moves the cursor position to the first row:

rs.Open( &conn );
rs.BeforeFirst();
rs.Next();
See also

Close method

Open method


Previous method

Prototype

bool Previous( )

Description

Moves the cursor position to the previous row in the table or result set.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example moves to the last row in a table:

tb.Open( &conn );
tb.AfterLast();
tb.Previous();
See also

Next method

Relative method


Relative method

Prototype

bool Relative( ul_fetch_offset offset )

Description

Moves the cursor position relative to the current position. If the row does not exist, the method returns false, and the cursor is left at AfterLast() if offset is positive, and BeforeFirst() if offset is negative.

offset The number of rows to move. Negative values correspond to moving backwards.

Returns

true (1) if the row exists.

false (0) if the row does not exist.

See also

Next method

Previous method


Reopen method

Prototype

bool Reopen( ULConnection *conn )

Description

This method is available for the Palm Computing Platform only. The ULData and ULConnection objects must already be open for this call to succeed.

When developing Palm applications, you should never close result set objects if you wish to maintain the cursor position. Instead, you should call Reopen when the user switches back to the UltraLite application.

Although the ULTable object inherits from the ULCursor class, you should not use Reopen on table objects. Instead, you should close them on exiting the Palm application and Open them on re-entering. The cursor position is not maintained in ULTable objects.

Parameters

conn A pointer to the ULConnection object on which the cursor is defined.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example reopens a database object, and then a connection object, and then a result set object:

db.Reopen();
conn.Reopen( &db );
rs.Reopen( &conn );
See also

Open method


Set method

Prototype

bool Set( ul_column_num colnum, value )

value:
p_ul_binary buffer-name, ul_length buffer-length
| ul_char * buffer-name, ul_length buffer-length = 0
| DECL_DATETIME date-value
| DECL_UNSIGNED_BIGINT bigint-value
| unsigned char char-value
| double double-value
| float float-value
| [ unsigned ] long long-value
| [ unsigned ] short short-value

Description

Sets a value in the specified column, for the current row.

colnum A 2-byte integer. The first column is column 1.

value For character and binary data you must supply a buffer name and length. For other data types, a value of the proper type is needed. The function fails if the data type is incorrect for the column.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

Get method


SetColumnNull method

Prototype

int SetColumnNull( ul_column_num column-index )

Description

Sets a column to the SQL NULL. The data is not actually changed until you execute an Insert or Update, and that change is not permanent until it is committed.

Parameters

column-index The number of the column. The first column in the table has a value of one.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

SetNull generated method


Update method

Prototype

bool Update( )

Description

Updates a row in the table with values specified in previous Set methods.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example sets a new price on the current row of the productTable object, and then updates the row in the UltraLite database:

productTable.SetPrice( 400 );
productTable.Update();
See also

Delete method

Insert method


ULData class

Object

Represents an UltraLite database.

Prototype

ULData db;
db.Open();

Description

The ULData class represents an UltraLite database to your application. It provides methods to open and close a database, and to check whether a database is open.

You must open a database before connecting to it or carrying out any other operation, and you must close the database after you have finished all operations on the database, and before your application terminates.

For multi-threaded applications, each thread must create its own ULData. Neither the ULData object nor the other objects inherited from it (ULConnection and other classes) can be shared across threads.

For embedded SQL users, opening a ULData object is equivalent to calling db_init.

For its position in the API hierarchy, see C++ API class hierarchy.

Example

The following example declares a ULData object and opens it:

ULData db;
db.Open();

Close method
Drop method
Initialize method
IsOpen method
Open method
PalmExit method [deprecated]
PalmLaunch method [deprecated]
Reopen method [deprecated]
StartDatabase method
StopDatabase method


Close method

Prototype

bool Close ( )

Description

Frees resources associated with a ULData object, before you terminate your application. Once you have closed the ULData object, you cannot execute any other operations on that database using the C++ API without reopening.

Palm Computing Platform
Use ULSetSynchInfo to save the state of the application before calling ULData.Close. Use the Open method when the application is reactivated. For more information, see Open method and ULSetSynchInfo function.
Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example closes a ULData object:

db.Close();
See also

Open method


Drop method

Prototype

bool Drop ( SQLCA * sqlca, ul_char * store-parms )

Description

Delete the UltraLite database file.

Caution This function deletes the database file and all data in it. Use with care.

Do not call this function while a database connection is open. Call this function only after closing the database or before opening the database (C++ API).

On the Palm OS, call this function only when not connected to the database (but after any ULEnable functions have been called)

Parameters

sqlca A pointer to the SQLCA.

store-parms A string of connection parameters, including the file name to delete as a keyword-value pair of the form file_name=file.udb. It is often convenient to use the UL_STORE_PARMS macro as this argument. A value of UL_NULL deletes the default database filename.

For more information, see UL_STORE_PARMS macro.

Returns

  • true Indicates that database files was successfully deleted.

  • false You can obtain detailed error information by using GetSQLCode. The usual reason for failure is that an incorrect filename was supplied or that access to the file was denied, perhaps because it is opened by an application.


Initialize method

Prototype

bool Initialize ( SQLCA * ca )

Description

Initializes UltraLite for communications with a database. The method does not start the database. Typically, applications start the database when connecting (ULConnection::Open).

Use this function before any other data management functions, including ULConnection::Open.

Parameters

Open( ) This prototype can be used by most UltraLite applications. Any persistent storage parameters defined in the UL_STORE_PARMS macro are employed when opening the database.

Open( SQLCA* ca ) Use this prototype if you are using embedded SQL as well as the C++ API in your application, and if you have a SQLCA in use, to access the same data using the C++ API.


IsOpen method

Prototype

bool IsOpen ( )

Description

Checks whether the ULData object is currently open.

Returns

true (1) if the ULData object is open.

false (0) if the ULData object is not open.

Example

The following example declares a ULData object, opens it, and checks that the Open method succeeded:

ULData db;
db.Open();
if( db.IsOpen() ){
   printf( "The ULData object is open\n" );
}
See also

Open method


Open method

Prototype

bool Open ( )

bool Open( SQLCA* ca )

bool Open( ul_char* parms )

bool Open( SQLCA* ca , ul_char* parms )

Description

Prepares your application to work with a database. You must open the ULData object before carrying out any other operations on the database using the C++ API. Exceptions to this rule are as follows:

  • On the Palm Computing Platform, the ULData.PalmLaunch method is called before ULData.Open. The resources that this library requires for your program are allocated and initialized on this call.

    On the Palm Computing Platform, call ULData.Open whenever ULData.PalmLaunch returns LAUNCH_SUCCESS_FIRST. For more information, see PalmLaunch method [deprecated].

  • Functions that configure database storage can be called. These functions have names starting with ULEnable.

    For special purposes, you can specify persistent storage parameters when opening a database to configure caching, encryption, and the database file name. For information on these parameters, see Setting UltraLite database properties.

For multi-threaded applications, each thread must open its own ULData object. Neither the ULData object nor the other objects inherited from it (ULConnection and other classes) can be shared across threads.

Parameters

Open( ) This prototype can be used by most UltraLite applications. Any persistent storage parameters defined in the UL_STORE_PARMS macro are employed when opening the database.

Open( SQLCA* ca ) Use this prototype if you are using embedded SQL as well as the C++ API in your application, and if you have a SQLCA in use, to access the same data using the C++ API.

Open( ul_char* parms ) Persistent storage parameters can be specified using the UL_STORE_PARMS macro. This prototype provides an alternative way of specifying persistent storage parameters. The string is a semicolon-separated list of assignments, of the form parameter=value.

Open( SQLCA *ca, ul_char* parms ) A call specifying both the SQLCA and persistent storage parameters.

For more information on persistent storage parameters, see UL_STORE_PARMS macro.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example declares a ULData object and opens it:

ULData db;
db.Open();
See also

Close method

Setting UltraLite database properties

UL_STORE_PARMS macro


PalmExit method [deprecated]

Prototype

bool PalmExit( SQLCA *ca )

bool PalmExit( ul_synch_info * synch_info )

Description
Deprecated feature
This function is no longer required. Use ULData::Close instead.

Call this method just before your application is closed, to save the state of the application.

For applications using HotSync or Scout Sync synchronization, the method also writes an upload stream. When the user uses HotSync or Scout Sync to synchronize data between their Palm device and a PC, the upload stream is read by the MobiLink HotSync conduit or the MobiLink Scout conduit respectively.

The MobiLink HotSync conduit synchronizes with the MobiLink synchronization server through a TCP/IP or HTTP stream. You can tune the synchronization by specifying a set of stream parameters or network protocol options in the synch_info.stream_parms. Alternatively, you may specify the stream and stream parameters via the ClientParms registry entry. If the ClientParms registry entry does not exist, a default setting of {stream=tcpip;host=localhost} is used.

Parameters

sqlca A pointer to the SQLCA. You do not need to supply this argument unless you are using embedded SQL as well as the C++ API in your application and have used a non-default SQLCA.

synch_info A synchronization structure.

If you are using TCP/IP or HTTP synchronization, supply UL_NULL instead of the ul_synch_info structure. When using these streams, the synchronization information is supplied instead in the call to ULSynchronize.

If you use HotSync or Scout Sync synchronization, supply the synchronization structure. The value of the stream parameter is ignored, and may be UL_NULL.

For information on the members of the synch_info structure, see Synchronization parameters.

Returns

true (1) if successful.

false (0) if unsuccessful


PalmLaunch method [deprecated]

Prototype

UL_PALM_LAUNCH_RET PalmLaunch( );

UL_PALM_LAUNCH_RET PalmLaunch( ul_synch_info * synch_info );

UL_PALM_LAUNCH_RET PalmLaunch( SQLCA* ca );

UL_PALM_LAUNCH_RET PalmLaunch( SQLCA* ca ,
ul_synch_info * synch_info );

typedef enum {
LAUNCH_SUCCESS_FIRST,
LAUNCH_SUCCESS,
LAUNCH_FAIL
} UL_PALM_LAUNCH_RET;

Description
Deprecated feature
This function is no longer required. Use ULData::Initialize instead.

This function restores the application state when the application is activated. For applications using HotSync or Scout Sync synchronization, it carries out the additional task of processing the download stream prepared by the MobiLink HotSync conduit or MobiLink Scout conduit.

If you are using TCP/IP or HTTP synchronization, supply a null value for the stream parameter in the ul_synch_info synchronization structure. This information is supplied instead in the synchronization structure called by the ULConnection.Synchronize method.

Parameters

ca A pointer to the SQLCA. You do not need to supply this argument unless you are using embedded SQL as well as the C++ API in your application and have used a non-default SQLCA.

synch_info A synchronization structure. For information on the members of this structure, see Synchronization parameters.

If you are using TCP/IP or HTTP synchronization, supply a null value for the stream parameter.

Returns

A member of the UL_PALM_LAUNCH_RET enumeration. The return values have the following meanings:

  • LAUNCH_SUCCESS_FIRST This value is returned the first time the application is successfully launched and at any subsequent time the internal state of the UltraLite database needs to be re-established. In general, the state of the database needs to be re-established only after severe failures.

    You should open a ULData object when LAUNCH_SUCCESS_FIRST is returned.

  • LAUNCH_SUCCESS This value is returned when an application is successfully launched, after the Palm user has been using other applications.

  • LAUNCH_FAIL This value is returned when the launch fails.

Examples

A typical C++ API example is

ULData db;
ULEnablePalmRecordDB( & sqlca );
switch( db.PalmLaunch( &synch_info ) ){
case LAUNCH_SUCCESS_FIRST:
   if( !db.Open() ){
      // initialization failed: add error handling here
      break;
   }
   // fall through
case LAUNCH_SUCCESS:
   db.Reopen();
   // do work here
   break;
case LAUNCH_FAIL:
   // error
   break;
}


Reopen method [deprecated]

Prototype

bool Reopen ( )

bool Reopen( SQLCA* ca )

Description
Deprecated feature
This function is no longer required. Use ULData::Open or ULData::Initialize instead.

This method is available for the Palm Computing Platform only.

When developing Palm applications, you should never close the database object. Instead, you should call Reopen when the user switches to the UltraLite application. The method prepares the data in use by the database object for use by the application.

Parameters

Open( ) No arguments are needed if you are not using embedded SQL as well as the C++ API in your application.

Open( SQLCA* ca ) If you are also using embedded SQL in your application, and you have a non-default SQLCA in use, you can use this method to access the same data using the C++ API.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example reopens a database object and a connection object:

db.Reopen();
conn.Reopen( &db );
See also

Open method


StartDatabase method

Prototype

bool StartDatabase ( ul_char const * parms );

Description

Start a database if the database is not already running. This function is required when developing applications that combine the Static C++ API and the C++ Component. See Combining UltraLite C/C++ interfaces.

You must call ULData::Initialize() before calling StartDatabase. If you use the StartDatabase method to start a database, any information in UL_STORE_PARMS is ignored.

The return value is true if the database was already running or successfully started. Error information is returned in the SQLCA.

Parameters

  • parms A connection string identifying the database to start. Typically, this includes only a database file:

    DBF=mydatabase.udb
Returns

true (1) if successful.

false (0) if unsuccessful.


StopDatabase method

Prototype

bool StopDatabase ( ul_char const * parms );

Description

Stop a database. This function is not commonly needed, as UltraLite automatically stops the database when all connections are closed.

This function may be useful when developing applications that combine the Static C++ API and the C++ Component. See Combining UltraLite C/C++ interfaces.

You must call ULData::Close() after calling StartDatabase.

The return value is true if the database was successfully stopped. Error information is returned in the SQLCA.

Parameters

  • parms A connection string identifying the database to stop. Typically, this includes only a database file:

    DBF=mydatabase.udb
Returns

true (1) if successful.

false (0) if unsuccessful.


ULResultSet class

The ULResultSet class extends the ULCursor class, and provides methods needed by all generated result sets.

For more information, see ULCursor class, and Generated result set class.

For its position in the API hierarchy, see C++ API class hierarchy.

SetParameter method


SetParameter method

Prototype

virtual bool SetParameter( int argnum, value-reference )

value-reference:
[ unsigned ] long & value
| p_ul_binary value
| unsigned char & value
| ul_char * value
| double & value
| float & value
| [ unsigned ] short & value
| DECL_DATETIME value
| DECL_BIGINT value
| DECL_UNSIGNED_BIGINT value

Description

The following query defines a result set with a parameter:

SELECT id
FROM mytable
WHERE id < ?

The result set object defined in the C++ API that corresponds to this query has a parameter. You must set the value of the parameter before opening the generated result set object.

Parameters

argnum An identifier for the argument to be set. The first argument is 1, the second 2, and so on.

value-reference A reference to the parameter value. The data type listing above provides the possibilities. As the parameter are passed as pointers, they must remain valid until used. Do not free them until they are used.

Returns

true (1) if successful.

false (0) if unsuccessful. If you supply a parameter of the wrong data type, the method fails.

See also

Open method


ULTable class

The ULTable class extends the ULCursor class, and provides methods needed by all generated table objects.

You cannot have multiple connections to a ULTable object at one time.

For its position in the API hierarchy, see C++ API class hierarchy.

DeleteAllRows method
Find method
FindFirst method
FindLast method
FindNext method
FindPrevious method
Lookup method
GetRowCount method
LookupBackward method
LookupForward method


DeleteAllRows method

Prototype

ul_ret_void DeleteAllRows( )

Description

The function deletes all rows in the table.

In some applications, it can be useful to delete all rows from tables before downloading a new set of data into the table. Rows can be deleted from the UltraLite database without being deleted from the consolidated database using the ULConnection::StopSynchronizationDelete method.

See also

StartSynchronizationDelete method

StopSynchronizationDelete method


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite Static C++ API Reference

ULTable class

Find method

Equivalent to the FindNext method.

See FindNext method.


FindFirst method

Prototype

bool FindFirst( ul_column_num ncols )

Description

Move forwards through the table from the beginning, looking for a row that exactly matches a value or set of values in the current index.

The current index is that used to specify the sort order of the table, It is specified when your application calls the generated table Open method. The default index is the primary key. For more information, see Open method.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that exactly matches the index value. On failure the cursor position is AfterLast().

Parameters

ncols For composite indexes, the number of columns to use in the lookup. For example, if there is a three column index, and you want to lookup a value that matches based on the first column only, you should Set the value for the first column, and then supply an ncols value of 1.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

FindLast method

FindNext method

FindPrevious method

LookupBackward method

LookupForward method


FindLast method

Prototype

bool FindLast( ul_column_num ncols )

Description

Move backwards through the table from the end, looking for a row that matches a value or set of values in the current index.

The current index is that used to specify the sort order of the table, It is specified when your application calls the generated table Open method. The default index is the primary key. For more information, see Open method.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row found that exactly matches the index value. On failure the cursor position is BeforeFirst().

Parameters

ncols For composite indexes, the number of columns to use in the lookup. For example, if there is a three column index, and you want to lookup a value that matches based on the first column only, you should Set the value for the first column, and then supply an ncols value of 1.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

FindFirst method

FindNext method

FindPrevious method

LookupBackward method

LookupForward method


FindNext method

Prototype

bool FindNext( ul_column_num ncols )

Description

Move forwards through the table from the current position, looking for a row that exactly matches a value or set of values in the current index.

The current index is that used to specify the sort order of the table, It is specified when your application calls the generated table Open method. The default index is the primary key. For more information, see Open method.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row found that exactly matches the index value. On failure, the cursor position is AfterLast().

Parameters

ncols For composite indexes, the number of columns to use in the lookup. For example, if there is a three column index, and you want to lookup a value that matches based on the first column only, you should Set the value for the first column, and then supply an ncols value of 1.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

FindFirst method

FindLast method

FindPrevious method

LookupBackward method

LookupForward method


FindPrevious method

Prototype

bool FindPrevious( ul_column_num ncols )

Description

Move backwards through the table from the current position, looking for a row that exactly matches a value or set of values in the current index.

The current index is that used to specify the sort order of the table, It is specified when your application calls the generated table Open method. The default index is the primary key. For more information, see Open method.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row found that exactly matches the index value. On failure the cursor position is BeforeFirst().

Parameters

ncols For composite indexes, the number of columns to use in the lookup. For example, if there is a three column index, and you want to lookup a value that matches based on the first column only, you should Set the value for the first column, and then supply an ncols value of 1.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

FindFirst method

FindLast method

FindNext method

LookupBackward method

LookupForward method


Web Links Browse Collapse Expand PDF Previous Next

UltraLite C/C++ User's Guide

UltraLite Static C++ API Reference

ULTable class

Lookup method

Equivalent to the LookupForward method.

See LookupForward method


GetRowCount method

Prototype

ul_ul_long GetRowCount( )

Description

The function returns the number of rows in the table.

One use for the function is to decide when to delete old rows to save space. Old rows can be deleted from the UltraLite database without being deleted from the consolidated database using the ULConnection::StartSynchronizationDelete method.

Returns

The number of rows in the table.

See also

StartSynchronizationDelete method

StopSynchronizationDelete method


LookupBackward method

Prototype

bool LookupBackward( ul_column_num ncols )

Description

Move backwards through the table starting from the end, looking for the first row that matches or is less than a value or set of values in the current index.

The current index is that used to specify the sort order of the table, It is specified when your application calls the generated table Open method. The default index is the primary key. For more information, see Open method.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is less than the index value. On failure (that is, if no row is less than the value being looked for), the cursor position is BeforeFirst().

Parameters

ncols For composite indexes, the number of columns to use in the lookup. For example, if there is a three column index, and you want to lookup a value that matches based on the first column only, you should Set the value for the first column, and then supply an ncols value of 1.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

FindFirst method

FindLast method

FindNext method

FindPrevious method

LookupForward method


LookupForward method

Prototype

bool LookupForward( ul_column_num ncols )

Description

Move forward through the table starting from the beginning, looking for the first row that matches or is greater than a value or set of values in the current index.

The current index is that used to specify the sort order of the table, It is specified when your application calls the generated table Open method. The default index is the primary key. For more information, see Open method.

To specify the value to search for, set the column value for each column in the index. The cursor is left on the first row that matches or is greater than the index value. On failure (that is, if no rows are greater than the value being looked for), the cursor position is AfterLast().

Parameters

ncols For composite indexes, the number of columns to use in the lookup. For example, if there is a three column index, and you want to lookup a value that matches based on the first column only, you should Set the value for the first column, and then supply an ncols value of 1.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

FindFirst method

FindLast method

FindNext method

FindPrevious method

LookupBackward method


Generated result set class

Object

The generated result set class represents a query result set to your application. The name of the class is generated by the UltraLite generator, based on the name of the statement supplied when it was added to the database.

Prototype

To create a generated result set object, you use the generated name in the declaration

result-set rs;
rs.Open();

result-set: generated name

Description

The UltraLite generator defines a class for each named statement in an UltraLite project that returns a result set. This class inherits methods from ULCursor.

For its position in the API hierarchy, see C++ API class hierarchy.

See also

ULCursor class

ul_add_statement system procedure


Get<Column> generated method

Prototype

bool Get column-name( type* variable, [ ul_length* length, ]
bool* isNull = UL_NULL )

Description

Retrieves a value from column-name. The type specification depends on the column data type.

Parameters

column-name The name of the column.

variable A variable of the proper data type for the column. This data type can be retrieved using GetColumnType.

length For variable length data. For character data, the length parameter specifies the length of the C array including the space used for the terminator.

isNull If the value is NULL, this argument is true.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

Set generated method


Open method

Prototype

bool Open( ULConnection * conn,
datatype value, ... )

Description

The UltraLite generator defines a class for each named statement in an UltraLite project that returns a result set. This class inherits methods from ULCursor.

You must supply a value for each placeholder in the result set.

Parameters

conn The connection on which the result set is to be opened.

value The value for the placeholder in the result set.

Example

The following query contains a single placeholder:

select prod_id, price, prod_name
from "DBA".ulproduct
where price < ?

The generator writes out the following methods for the object (in addition to some others):

bool Open( ULConnection* conn,
    long Price    );
bool Open( ULConnection* conn );
bool SetParameter( int index, long &value );
See also

SetParameter method


Set<Column> generated method

Prototype

bool Set column-name( )

Description

Sets the value of the cursor at the current position. The data in the row is not actually changed until you execute an Insert or Update, and that change is not permanent until it is committed.

Parameters

column-name A generated name derived from the name of the column in the reference database.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

Get generated method

SetNull generated method


SetNull<Column> generated method

Prototype

bool SetNull column-name( )

Description

Sets a column to the SQL NULL. The data is not actually changed until you execute an Insert or Update, and that change is not permanent until it is committed.

Parameters

column-name A generated name derived from the name of the column in the reference database.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

Set generated method


Generated statement class

For each SQL statement that does not return a result set, including inserts, updates, and deletes, the UltraLite generator defines a generated statement class. The name of the class is the name provided in the ul_add_statement stored procedure call that added the statement to the reference database.

The generated statement class inherits from the ULStatement class, which has no methods of its own.

For its position in the API hierarchy, see C++ API class hierarchy.


Execute method

Prototype

bool Execute( ULConnection* conn,
[ datatype column-name,... ] )

Description

Executes a named statement that does not return a result set. Any change made is not permanent until it is committed.

When a statement is defined using ul_add_statement, you supply placeholders for the values, and supply them at run time. The generated prototype has a data type and name for each value.

If the set of parameters is omitted, each value must be set using SetNull or SetParameter before the Execute is called.

Parameters

conn The connection on which the statement is to be executed.

datatype A member of the UltraLite data type enumeration.

column-name The name of the column.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

ul_add_statement system procedure

SetNull method

SetParameter method


SetNull method

Prototype

bool SetNull( ULConnection* conn,
ul_column_num column-index )

Description

Sets the specified column to NULL.

Parameters

conn The connection on which the statement is to be executed.

column-index The number of the column. The first column in the table has a value of one.

Returns

true (1) if successful.

false (0) if unsuccessful.


SetParameter method

Prototype

virtual bool SetParameter( int argnum, value-reference )

value-reference:
[ unsigned ] long & value
| p_ul_binary value
| unsigned char & value
| ul_char * value
| double & value
| float & value
| [ unsigned ] short & value
| DECL_DATETIME value
| DECL_BIGINT value
| DECL_UNSIGNED_BIGINT value

Description

This method sets parameters for statements before the Execute method is called.

To set parameters to NULL, use the SetNull method.

Parameters

argnum An identifier for the argument to be set. The first argument is 1, the second 2, and so on.

value-reference A reference to the parameter value. The data type listing above provides the possibilities. As the parameter are passed as pointers, they must remain valid until used. Do not free them until they are used.

Returns

true (1) if successful.

false (0) if unsuccessful. If you supply a parameter of the wrong data type, the method fails.

See also

Execute method

SetNull method


Generated table class

Object

The generated table class represents a database table to your application. The name of the class is generated by the UltraLite generator, based on the name of the table in the database.

Prototype

Tablename tb;
tb.Open();

Tablename:
generated name

Description

The UltraLite generator defines a class for each table in a named publication. The generated table class inherits from ULTable and ULCursor. The class has a name based on the table or statement name, so that for a table named Product, the generator defines a class named Product.

For its position in the API hierarchy, see C++ API class hierarchy.

See also

ULCursor class

ULTable class

Get generated method
Get<Column> generated method
GetSize<Column> generated method
Open method
Set<Column> generated method
SetNull<Column> generated method
Index enumeration


Get generated method

Prototype

bool Get (
ul_column_num column-index,
value-declaration,
bool* is-null = UL_NULL );

value-declaration:
ul_char * buffer-name, ul_length buffer-length
| p_ul_binary buffer-name, ul_length buffer-length
| DECL_DATETIME & date-value
| { DECL_BIGINT | DECL_UNSIGNED_BIGINT } & bigint-value
| unsigned char & char-value
| double & double-value
| float & float-value
| [ unsigned ] long & integer-value
| [ unsigned ] short & short-value

Description

Gets a value of from a column, specified by index.

Parameters

column-index The number of the column. The first column in the table has a value of one.

value declaration The arguments required to specify the value depend on the data type. Character and binary data must be mapped into buffers, with the buffer name and length specified in the call. For other data types, a pointer to a variable of the proper type is needed. For character data, the length parameter specifies the length of the C array including the space used for the terminator.

isNULL If a value in a column is NULL, isNull is set to true. In this case, the value argument is not meaningful.

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example is part of a switch statement that gets values from rows based on their data type:

switch( tb.GetColumnType( colIndex ) ) {
case tb.S_LONG :
   ret = tb.Get( colIndex, longval );
   printf( "Long column: %d\n", longval );
   break;
...
See also

Data types enumeration

Get method

Get generated method

GetColumnSize method


Get<Column> generated method

Prototype

bool Get column-name( type* variable, [ ul_length* length, ]
bool* isNull = UL_NULL )

Description

Retrieves a value from column-name. The type specification depends on the column data type.

Parameters

column-name The name of the column.

variable A variable of the proper data type for the column. This data type can be retrieved using GetColumnType.

length For variable length data types. For character data, the length parameter specifies the length of the C array including the space used for the terminator.

isNull If the value is NULL, this argument is true.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

Get generated method


GetSize<Column> generated method

Prototype

ul_length GetSize column-name( )

Description

Returns the storage area needed to hold a value from the specified column.

Parameters

column-name A generated name derived from the name of the column in the reference database.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

GetColumnType method


Open method

Prototype

bool Open( ULConnection* conn )

bool Open( ULConnection* conn, ul_index_num index )

Description

Prepares your application to work with the data in a generated table object.

Parameters

conn The address of a ULConnection object. The connection must be open.

index An optional index number, used to order the rows in the table. The index is one of the members of the generated index enumeration. By default, the table is ordered by primary key value.

For more information, see Index enumeration.

When the table is opened, the cursor is positioned before the first row

Returns

true (1) if successful.

false (0) if unsuccessful.

Example

The following example declares a generated object for a table named ULProduct, and opens it:

ULData db;
ULConnection conn;
ULProduct tb;
db.Open();
conn.Open( &db, "DBA", "SQL" );
tb.Open( &conn );
See also

Close method

Index enumeration


Set<Column> generated method

Prototype

bool Set column-name( )

Description

Sets the value of the cursor at the current position. The data in the row is not actually changed until you execute an Insert or Update, and that change is not permanent until it is committed.

Parameters

column-name A generated name derived from the name of the column in the reference database.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

SetColumnNull method


SetNull<Column> generated method

Prototype

bool SetNull column-name( )

Description

Sets a column to the SQL NULL. The data is not actually changed until you execute an Insert or Update, and that change is not permanent until it is committed.

Parameters

column-name A generated name derived from the name of the column in the reference database.

Returns

true (1) if successful.

false (0) if unsuccessful.

See also

SetColumnNull method


Index enumeration

Prototype

enum{ index-name,... }

Description

Each member of the enumeration is an index name in the table being generated. You can use the index name to specify an ordering for the table when it is opened, and thereby control the behavior of the cursor movement methods.

Parameters

index-name The name of an index in the table. The primary key has the name Primary, and other indexes have their name in the database.

See also

Open method


Embedded SQL API Reference

About this chapter

This chapter lists functions that can be used in UltraLite embedded SQL applications. It does not include the embedded SQL EXEC SQL statement and the SQL statements that can be included in your application. For information about these statements, see Developing Applications Using Embedded SQL.

Use the EXEC SQL INCLUDE SQLCA command to include prototypes for the functions in this chapter.

db_fini function
db_init function
db_start_database function
db_stop_database function
ULActiveSyncStream function
ULChangeEncryptionKey function
ULClearEncryptionKey function
ULCountUploadRows function
ULDropDatabase function
ULGetDatabaseID function
ULGetLastDownloadTime function
ULGetSynchResult function
ULGlobalAutoincUsage function
ULGrantConnectTo function
ULHTTPSStream function
ULHTTPStream function
ULIsSynchronizeMessage function
ULPalmDBStream function (deprecated)
ULPalmExit function (deprecated)
ULPalmLaunch function (deprecated)
ULResetLastDownloadTime function
ULRetrieveEncryptionKey function
ULRevokeConnectFrom function
ULRollbackPartialDownload function
ULSaveEncryptionKey function
ULSetDatabaseID function
ULSetSynchInfo function
ULSocketStream function
ULSynchronize function


db_fini function

Prototype

unsigned short db_fini( SQLCA * sqlca );

Description

Frees resources used by the UltraLite runtime library.

You must not make any other library calls or execute any embedded SQL commands after db_fini is called. If an error occurs during processing, the error code is set in SQLCA and the function returns 0.If there are no errors, a non-zero value is returned.

Call db_fini once for each SQLCA being used.

See also

db_init function


db_init function

Prototype

unsigned short db_init(SQLCA * sqlca ) ;

Description

Initializes the UltraLite runtime library and creates a new UltraLite database, if one does not exist.

This function must be called before any other library call is made, and before any embedded SQL command is executed. Exceptions to this rule are as follows:

  • Functions that configure database storage can be called. These functions have names starting with ULEnable.

    Deprecated feature
    It is recommended that you call ULEnable functions immediately after calling db_init. Calling ULEnable functions before db_init is deprecated.

If there are any errors during processing (for example, during initialization of the persistent store), they are returned in the SQLCA and 0 is returned. If there are no errors, a non-zero value is returned and you can begin using embedded SQL commands and functions.

In most cases, this function should be called only once (passing the address of the global sqlca variable defined in the sqlca.h header file). If you have multiple execution paths in your application, you can use more than one db_init call, as long as each one has a separate sqlca pointer. This separate SQLCA pointer can be a user-defined one, or could be a global SQLCA that has been freed using db_fini.

In multi-threaded applications, each thread must call db_init to obtain a separate SQLCA. Subsequent connections and transactions that use this SQLCA must be carried out on a single thread.

See also

db_fini function


db_start_database function

Prototype

unsigned int db_start_database( SQLCA * sqlca, char * parms );

Parameters

sqlca A pointer to a SQLCA structure. For information, see Initializing the SQL Communications Area.

parms A NULL-terminated string containing a semi-colon-delimited list of parameter settings, each of the form KEYWORD=value. Typically, only a filename is required. For example,

"DBF=c:\\db\\mydatabase.db"

For an available list of connection parameters, see Connection Parameters.

Description

Start a database if the database is not already running. This function is required when developing applications that combine embedded SQL and the C++ Component. See Combining UltraLite C/C++ interfaces.

If you use the db_start_database function to start a database, any information in UL_STORE_PARMS is ignored.

If the database was already running or was successfully started, the return value is true (non-zero) and SQLCODE is set to 0. Error information is returned in the SQLCA.


db_stop_database function

Prototype

unsigned int db_stop_database( SQLCA * sqlca, char * parms );

Parameters

sqlca A pointer to a SQLCA structure. For information, see Initializing the SQL Communications Area.

parms A NULL-terminated string containing a semi-colon-delimited list of parameter settings, each of the form KEYWORD=value. Typically, only a database file is needed. For example,

"DBF=c:\\db\\mydatabase.db"

For an available list of connection parameters, see Connection Parameters.

Description

Stop a database. This function is not commonly needed, as UltraLite automatically stops the database when all connections are closed.

This function may be useful when developing applications that combine embedded SQL and the C++ Component. See Combining UltraLite C/C++ interfaces.

This function does not stop a database that has existing connections.

A return value of TRUE indicates that there were no errors.


ULActiveSyncStream function

Prototype

ul_stream_defn ULActiveSyncStream( void );

Description

Defines an ActiveSync stream suitable for synchronization.

The ActiveSync stream is available only on Windows CE devices.

Synchronization using ULActiveSyncStream must be initiated from the ActiveSync software. The application receives a message, which must be handled in its WindowProc function. You can use ULIsSynchronizeMessage to identify the message as an instruction to synchronize.

See also

ULIsSynchronizeMessage function

ULSynchronize function

Synchronize method

ActiveSync protocol options


ULChangeEncryptionKey function

Prototype

ul_bool ULChangeEncryptionKey( SQLCA *sqlca, ul_char *new_key );

Description

Changes the encryption key for an UltraLite database.

Caution When the key is changed, every row in the database is decrypted using the old key and re-encrypted using the new key. This operation is unrecoverable. If the application is interrupted part-way through, the database is invalid and cannot be accessed. A new one must be created.
See also

Encrypting data


ULClearEncryptionKey function

Prototype

ul_bool ULClearEncryptionKey(
ul_u_long * creator,
ul_u_long * feature-num );

Description

On the Palm Computing Platform the encryption key is saved in dynamic memory as a Palm feature. Features are indexed by creator and a feature number.

This function clears the encryption key.

Parameters

creator A pointer to the creator ID of the feature holding the encryption key. A value of NULL is the default.

feature-num A pointer to the feature number holding the encryption key. A value of NULL uses the UltraLite default, which is feature number 100.

See also

ULRetrieveEncryptionKey function

ULSaveEncryptionKey function

Palm OS considerations


ULCountUploadRows function

Prototype

ul_u_long ULCountUploadRows (
SQLCA * sqlca,
ul_publication_mask publication-mask,
ul_u_long threshold );

Description

Returns the number of rows that need to be synchronized, either in a set of publications or in the whole database.

One use of the function is to prompt users to synchronize.

Parameters

sqlca A pointer to the SQLCA.

publication-mask A set of publications to check. A value of 0 corresponds to the entire database. The set is supplied as a mask. For example, the following mask corresponds to publications PUB1 and PUB2.:

UL_PUB_PUB1 | UL_PUB_PUB2

For more information on publication masks, see Designing sets of data to synchronize separately.

threshold A value that determines the maximum number of rows to count, and so limits the amount of time taken by the call. A value of 0 corresponds to no limit. A value of 1 determines if any rows need to be synchronized.

Example

The following call checks the entire database for the number of rows to be synchronized:

count = ULCountUploadRows( sqlca, 0, 0 );

The following call checks publications PUB1 and PUB2 for a maximum of 1000 rows:

count = ULCountUploadRows( sqlca,
UL_PUB_PUB1 | UL_PUB_PUB2, 1000 );

The following call checks to see if any rows need to be synchronized:

count = ULCountUploadRows( sqlca, UL_SYNC_ALL, 1 );


ULDropDatabase function

Prototype

ul_bool ULDropDatabase ( SQLCA * sqlca, ul_char * store-parms );

Description

Delete the UltraLite database file.

Caution This function deletes the database file and all data in it. Use with care.

Do not call this function while a database connection is open. Call this function only before db_init or after db_fini.

On the Palm OS, call this function only when not connected to the database (but after any ULEnable functions have been called)

Parameters

sqlca A pointer to the SQLCA.

store-parms A string of connection parameters, including the file name to delete as a keyword-value pair of the form file_name=file.udb. It is often convenient to use the UL_STORE_PARMS macro as this argument. A value of UL_NULL deletes the default database filename.

For more information, see UL_STORE_PARMS macro.

Returns

  • ul_true Indicates that database files was successfully deleted.

  • ul_false The detailed error message is defined by the sqlcode field in the SQLCA. The usual reason for failure is that an incorrect filename was supplied or that access to the file was denied, perhaps because it is opened by an application.

Example

The following call deletes the UltraLite database file myfile.udb.

#define UL_STORE_PARMS UL_TEXT("file_name=myfile.udb")
if( ULDropDatabase(&sqlca, UL_STORE_PARMS ) ){
    // success
};


ULGetDatabaseID function

Prototype

ul_u_long ULGetDatabaseID( SQLCA * sqlca )

Description

ULGetDatabaseID returns the current database ID used for global autoincrement. It returns the value set by the last call to SetDatabaseID or UL_INVALID_DATABASE_ID if the ID was never set.

Parameters

sqlca A pointer to the SQLCA.


ULGetLastDownloadTime function

Prototype

ul_bool ULGetLastDownloadTime(
SQLCA * sqlca,
ul_publication_mask publication-mask,
DECL_DATETIME * value );

Description

Obtains the last time a specified publication was downloaded.

Parameters

sqlca A pointer to the SQLCA.

publication-mask A set of publications for which the last download time is retrieved. A value of 0 corresponds to the entire database. The set is supplied as a mask. For example, the following mask corresponds to publications PUB1 and PUB2.:

UL_PUB_PUB1 | UL_PUB_PUB2

For more information on publication masks, see Designing sets of data to synchronize separately.

value A pointer to the DECL_DATETIME structure to be populated.

A value of January 1, 1990 indicates that the publication has yet to be synchronized.

Returns

  • true Indicates that value is successfully populated by the last download time of the publication specified by publication-mask.

  • false Indicates that publication-mask specifies more than one publication or that the publication is undefined. If the return value is false, the contents of value are not meaningful.

Examples

The following call populates the dt structure with the date and time that publication UL_PUB_PUB1 was downloaded:

DECL_DATETIME dt;
ret = ULGetLastDownloadTime( &sqlca, UL_PUB_PUB1, &dt );

The following call populates the dt structure with the date and time that the entire database was last downloaded. It uses the special UL_SYNC_ALL publication mask.

ret = ULGetLastDownloadTime( &sqlca, UL_SYNC_ALL, &dt );
See also

UL_SYNC_ALL macro

UL_SYNC_ALL_PUBS macro


ULGetSynchResult function

Prototype

ul_bool ULGetSynchResult( ul_synch_result * synch-result );

Description

Stores the results of the most recent synchronization, so that appropriate action can be taken in the application:

The application must allocate a ul_synch_result object before passing it to ULGetSynchResult. The function fills the ul_synch_result with the result of the last synchronization. These results are stored persistently in the database.

The function is of particular use when synchronizing applications on the Palm Computing Platform using HotSync, as the synchronization takes place outside the application itself. The SQLCODE value set in the connection reflect the result of the connecting operation itself. The synchronization status and results are written to the HotSync log only. To obtain extended synchronization result information, call ULGetSynchResult when connected to the database.

Parameters

synch-result A structure to hold the synchronization result. It is defined in ulglobal.h as follows:.

typedef struct {
an_sql_code sql_code;
ul_stream_error stream_error;
ul_bool upload_ok;
ul_bool ignored_rows;
ul_auth_status auth_status;
ul_s_long auth_value;
SQLDATETIME timestamp;
ul_synch_status status;
} ul_synch_result, * p_ul_synch_result;

where the individual members have the following meanings:

  • sql_code The SQL code from the last synchronization. For a list of SQL codes, see Error messages indexed by Adaptive Server Anywhere SQLCODE.

  • stream_error A structure of type ul_stream error.

    For more information, see stream_error synchronization parameter.

  • upload_ok Set to true if the upload was successful; false otherwise.

  • ignored_rows Set to true if uploaded rows were ignored; false otherwise.

  • auth_status The synchronization authentication status. For more information, see auth_status parameter.

  • auth_value The value used by the MobiLink synchronization server to determine the auth_status result. For more information, see auth_value synchronization parameter.

  • timestamp The time and date of the last synchronization.

  • status The status information used by the observer function. For more information, see observer synchronization parameter.

Returns

The function returns a Boolean value.

true Success.

false Failure.

Examples

The following code checks for success of the previous synchronization.

ul_synch_result synch_result;
memset( &synch_result, 0, sizeof( ul_synch_result ) );
db_init( &sqlca );
EXEC SQL CONNECT "dba" IDENTIFIED BY "sql";
if( !ULGetSynchResult( &sqlca, &synch_result ) ) {
    prMsg( "ULGetSynchResult failed" );
}


ULGlobalAutoincUsage function

Prototype

short ULGlobalAutoincUsage( SQLCA * sqlca );

Description

Obtains the percent of the default values used in all the columns having global autoincrement defaults. If the database contains more than one column with this default, this value is calculated for all columns and the maximum is returned. For example, a return value of 99 indicates that very few default values remain for at least one of the columns.

Returns

The function returns a value of type short in the range 0–100.

See also

ULSetDatabaseID function


ULGrantConnectTo function

Prototype

void ULGrantConnectTo(
SQLCA * sqlca,
ul_char * userid,
ul_char * password );

Description

Grant access to an UltraLite database for a user ID with a specified password. If an existing user ID is specified, this function updates the password for the user.

Parameters

sqlca A pointer to the SQLCA.

userid Character array holding the user ID. The maximum length is 16 characters.

password Character array holding the password for userid. The maximum length is 16 characters.

See also

User authentication in UltraLite

Authenticating users

ULRevokeConnectFrom function


ULHTTPSStream function

Prototype

ul_stream_defn ULHTTPSStream( void );

Description

Defines an UltraLite HTTPS stream suitable for synchronization via HTTP.

The HTTPS stream uses TCP/IP as its underlying transport. UltraLite applications act as Web browsers and MobiLink acts as a web server.

See also

ULSynchronize function

Synchronize method

stream synchronization parameter

HTTPS protocol options


ULHTTPStream function

Prototype

ul_stream_defn ULHTTPStream( void );

Description

Defines an UltraLite HTTP stream suitable for synchronization via HTTP.

The HTTP stream uses TCP/IP as its underlying transport. UltraLite applications act as Web browsers and MobiLink acts as a web server. UltraLite applications send POST requests to send data to the server and GET requests to read data from the server.

See also

ULSynchronize function

Synchronize method

stream synchronization parameter

HTTP protocol options


ULIsSynchronizeMessage function

Prototype

ul_bool ULIsSynchronizeMessage( ul_u_long uMsg );

Description

On Windows CE, this function checks a message to see if it is a synchronization message from the MobiLink provider for ActiveSync, so that code to handle such a message can be called.

This function should be included in the WindowProc function of your application.

Example

The following code snippet illustrates how to use ULIsSynchronizeMessage to handle a synchronization message.

LRESULT CALLBACK WindowProc( HWND hwnd,
         UINT uMsg,
         WPARAM wParam,
         LPARAM lParam )
{
  if( ULIsSynchronizeMessage( uMsg ) ) {
    // execute synchronization code
    if( wParam == 1 ) DestroyWindow( hWnd );
    return 0;
  }

  switch( uMsg ) {

  // code to handle other windows messages

  default:
    return DefWindowProc( hwnd, uMsg, wParam, lParam );
  }
  return 0;
}
See also

Adding ActiveSync synchronization to your application


ULPalmDBStream function (deprecated)

Prototype

ul_stream_defn ULPalmDBStream( void );

Description

Defines a stream under the Palm Computing Platform suitable for HotSync and Scout Sync.

This function is deprecated. The stream parameter is not needed for HotSync synchronization, and may be UL_NULL.

See also

HotSync protocol options

Synchronize method


ULPalmExit function (deprecated)

Prototype

ul_bool ULPalmExit( SQLCA * sqlca, ul_synch_info * synch_info );

Description
Deprecated feature
ULPalmExit is no longer required and is a deprecated feature. Use ULSetSynchInfo and db_fini to exit the application instead.

Saves application state for UltraLite applications on the Palm Computing Platform, and writes out an upload stream for HotSync synchronization.

Parameters

sqlca A pointer to the SQLCA.

synch_info A synchronization structure.

If you are using TCP/IP or HTTP synchronization, supply UL_NULL instead of the ul_synch_info structure. When using these streams, the synchronization information is supplied instead in the call to ULSynchronize.

If you use HotSync or Scout Sync synchronization, supply the synchronization structure. The value of the stream parameter is ignored, and may be UL_NULL.

For information on the members of the synch_info structure, see Synchronization Parameters Reference.

Returns

The function returns a Boolean value.

true Success.

false Failure.


ULPalmLaunch function (deprecated)

Prototype

UL_PALM_LAUNCH_RET ULPalmLaunch(
SQLCA * sqlca,
ul_synch_info * synch_info );

typedef enum {
LAUNCH_SUCCESS_FIRST,
LAUNCH_SUCCESS,
LAUNCH_FAIL
} UL_PALM_LAUNCH_RET;

Parameters

sqlca A pointer to the SQLCA.

synch_info A synchronization structure. For information on the members of this structure, see Synchronization parameters.

If you are using TCP/IP or HTTP synchronization, supply UL_NULL as synch_info.

Description
Deprecated feature
ULPalmLaunch is no longer required and is a deprecated feature. Use db_init to launch the application instead.

This function restores application state for UltraLite applications on the Palm Computing Platform. This function is required by all UltraLite Palm applications.

See also

Restoring state in UltraLite Palm applications

ULEnableFileDB function

ULEnablePalmRecordDB function


ULResetLastDownloadTime function

Prototype

void ULResetLastDownloadTime(
SQLCA * sqlca,
ul_publication_mask publication-mask );

Description

This function can be used to repopulate values and return an application to a known clean state. It resets the last download time so that the application resynchronizes previously downloaded data.

Parameters

sqlca A pointer to the SQLCA.

publication-mask A set of publications to check. A value of 0 corresponds to the entire database. The set is supplied as a mask. For example, the following mask corresponds to publications PUB1 and PUB2.:

UL_PUB_PUB1 | UL_PUB_PUB2

For more information on publication masks, see publication synchronization parameter.

Example

The following function call resets the last download time for all tables:

ULResetLastDownloadTime( &sqlca, UL_SYNC_ALL );
See also

ULGetLastDownloadTime function

Timestamp-based synchronization


ULRetrieveEncryptionKey function

Prototype

ul_bool ULRetrieveEncryptionKey(
ul_char * key,
ul_u_short len,
ul_u_long * creator,
ul_u_long * feature-num );

Description

On the Palm Computing Platform the encryption key is saved in dynamic memory as a Palm feature. Features are indexed by creator and a feature number.

This function retrieves the encryption key from memory.

Parameters

key A pointer to a buffer in which to hold the retrieved encryption key.

len The length of the buffer that holds the encryption key with a terminating null character.

creator A pointer to the creator ID of the feature holding the encryption key. A value of NULL is the default.

feature-num A pointer to the feature number holding the encryption key. A value of NULL uses the UltraLite default, which is feature number 100.

Returns

  • true if the operation is successful.

  • false if the operation is unsuccessful. This occurs if the feature was not found or if the supplied buffer length is insufficient to hold the key plus a terminating null character.

See also

ULClearEncryptionKey function

ULSaveEncryptionKey function

Palm OS considerations


ULRevokeConnectFrom function

Prototype

void ULRevokeConnectFrom( SQLCA * sqlca, ul_char * userid );

Description

Revoke access from an UltraLite database for a user ID.

Parameters

sqlca A pointer to the SQLCA.

userid Character array holding the user ID to be excluded from database access. The maximum length is 16 characters.

See also

User authentication in UltraLite

Authenticating users

ULGrantConnectTo function


ULRollbackPartialDownload function

Roll back the changes from a failed synchronization.

Prototype

void ULRollbackPartialDownload ( SQLCA * sqlca )

Parameters

  • sqlca A pointer to the SQL Communications Area.

    In the static C++ API the SQLCA is declared in the header file as sqlca. In the C++ Component use the Sqlca.GetCA() method.

Description

When a communication error occurs during the download phase of synchronization, UltraLite can apply the downloaded changes, so that the synchronization can be resumed from the place it was interrupted. If the download changes are not needed (the user or application does not want to resume the download at this point), ULRollbackPartialDownload rolls back the failed download transaction.

See also
  • Resuming failed downloads
  • Keep Partial Download synchronization parameter
  • Partial Download Retained synchronization parameter
  • Resume Partial Download synchronization parameter


ULSaveEncryptionKey function

Prototype

ul_bool ULSaveEncryptionKey(
ul_char * key,
ul_u_long * creator,
ul_u_long * feature-num );

Description

On the Palm Computing Platform the encryption key is saved in dynamic memory as a Palm feature. Features are indexed by creator and a feature number. They are not backed up and are cleared on any reset of the device.

This function saves the encryption key in Palm dynamic memory.

Parameters

key A pointer to the encryption key.

creator A pointer to the creator ID of the feature holding the encryption key. A value of NULL is the default.

feature-num A pointer to the feature number holding the encryption key. A value of NULL uses the UltraLite default, which is feature number 100.

Returns

  • true if the operation is successful.

  • false if the operation is unsuccessful.

See also

ULClearEncryptionKey function

ULRetrieveEncryptionKey function

Palm OS considerations


ULSetDatabaseID function

Prototype

void ULSetDatabaseID( SQLCA * sqlca, ul_u_long id );

Description

Sets the database identification number.

Parameters

sqlca A pointer to the SQLCA.

id A positive integer that uniquely identifies a particular database in a replication or synchronization setup.

See also

ULGlobalAutoincUsage function


ULSetSynchInfo function

Prototype

ul_bool ULSetSynchInfo(
SQLCA * sqlca,
ul_synch_info * synch_info );

Description

For HotSync synchronization on the Palm OS, use ULSetSynchInfo to store the synchronization parameters for use when HotSync runs. Typically, ULSetSynchInfo is called just before closing the application by calling db_fini or ULData::Close.

Parameters

sqlca A pointer to the SQLCA.

synch_info A synchronization structure. For information on the members of this structure, see Synchronization parameters.


ULSocketStream function

Prototype

ul_stream_defn ULSocketStream( void );

Description

Defines an UltraLite socket stream suitable for synchronization via TCP/IP.

See also

ULSynchronize function

Synchronize method


ULSynchronize function

Prototype

void ULSynchronize(
SQLCA * sqlca,
ul_synch_info * synch_info );

Description

Initiates synchronization in an UltraLite application.

For TCP/IP or HTTP synchronization, the ULSynchronize function initiates synchronization. Errors during synchronization that are not handled by the handle_error script are reported as SQL errors. Your application should test the SQLCODE return value of this function.

Parameters

sqlca A pointer to the SQLCA.

synch_info A synchronization structure. For information on the members of this structure, see Synchronization parameters.

See also

MobiLink Synchronization Server Options

START SYNCHRONIZATION DELETE statement [MobiLink]


UltraLite ODBC API Reference

About this chapter

This chapter describes those parts of the ODBC interface supported by UltraLite

It is not a comprehensive ODBC reference. It is intended as a quick reference to complement the main reference for ODBC, which is the Microsoft [external link] ODBC SDK documentation.

SQLAllocHandle function
SQLBindCol function
SQLBindParameter function
SQLConnect function
SQLDescribeCol function
SQLDisconnect function
SQLEndTran function
SQLExecDirect function
SQLExecute function
SQLFetch function
SQLFetchScroll function
SQLFreeHandle function
SQLGetCursorName function
SQLGetData function
SQLGetDiagRec function
SQLGetInfo function
SQLNumResultCols function
SQLPrepare function
SQLRowCount function
SQLSetCursorName function
SQLSetConnectionName function
SQLSetSuspend function
SQLSynchronize function


SQLAllocHandle function

Allocates a handle.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLAllocHandle(
SQLSMALLINT HandleType,
SQLHANDLE InputHandle,
SQLHANDLE * OutputHandle);

Parameters

  • HandleType The type of handle to be allocated. UltraLite supports the following handle types:

    • SQL_HANDLE_ENV (environment handle)
    • SQL_HANDLE_DBC (connection handle)
    • SQL_HANDLE_STMT (statement handle)

  • InputHandle The handle in whose context the new handle is to be allocated. For a connection handle, this is the environment handle; for a statement handle, this is the connection handle.

  • OutputHandle Pointer to a buffer in which to return the new handle.

Remarks

ODBC uses handles to provide the context for database operations. An environment handle provides the context for communication with a data source, like the SQL Communications Area in other interfaces. A connection handle provides a context for all database operations. A statement handle manages result sets and data modification. A descriptor handle manages the handling of result set data types.

See also
  • [external link] SQLAllocHandle in the Microsoft ODBC Programmer's Reference.


SQLBindCol function

Binds a result set column to an application data buffer, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLBindCol (
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValue,
SQLLEN BufferLength,
SQLLEN * StrLen_or_Ind );

Parameters

  • StatementHandle A handle for the statement that is to return a result set.

  • ColumnNumber The number of the column in the result set to bind to an application data buffer.

  • TargetType The identifier of the data type of the TargetValue pointer.

  • TargetValue A pointer to the data buffer to bind to the column.

  • BufferLength The length of the TargetValue buffer in bytes.

  • StrLen_or_lnd Pointer to the length or indicator buffer to bind to the column. For strings, the length buffer holds the length of the actual string that was returned, which may be less than the length allowed by the column.

Remarks

To exchange information between your application and the database, ODBC binds buffers in the application to database objects such as columns. SQLBindCol is used when executing a query to identify a buffer in your application as a place that UltraLite puts the value of a specified column.

See also
  • [external link] SQLBindCol in the Microsoft ODBC Programmer's Reference.


SQLBindParameter function

Binds a buffer parameter to a parameter marker in a SQL statement, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLBindParameter (
SQLHSTMT StatementHandle,
SQLUSMALLINT ParameterNumber,
SQLSMALLINT ParamType,
SQLSMALLINT CType,
SQLSMALLINT SqlType,
SQLULEN ColDef,
SQLSMALLINT Scale,
SQLPOINTER rgbValue,
SQLLEN cbValueMax,
SQLLEN * StrLen_or_Ind );

Parameters

  • StatementHandle A statement handle.

  • ParameterNumber The number of the parameter marker in the statement, in sequential order counting from 1.

  • ParamType The parameter type. One of the following:

    • SQL_PARAM_INPUT
    • SQL_PARAM_INPUT_OUTPUT
    • SQL_PARAM_OUTPUT

  • CType The C data type of the parameter.

  • SQLType The SQL data type of the parameter.

  • ColDef The size of the column or expression of the parameter marker.

  • Scale The number of decimal digits for the column or expression of the parameter marker.

  • rgbValue A pointer to a buffer for the parameter's data.

  • cbValueMax The length of the rgbValue buffer.

  • StrLen_or_Ind A pointer to a buffer for the parameter's length.

Remarks

To exchange information between your application and the database, ODBC binds buffers in the application to database objects such as columns. SQLBindParameter is used when executing a statement, to identify a buffer in your application as a place that UltraLite gets or sets the value of a specified parameter in a query.

See also
  • [external link] SQLBindParameter in the Microsoft ODBC Programmer's Reference.


SQLConnect function

Connects to a database, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLConnect (
SQLHDBC ConnectionHandle,
SQLTCHAR * ServerName,
SQLSMALLINT NameLength1,
SQLTCHAR * UserName,
SQLSMALLINT NameLength2,
SQLTCHAR * Authentication,
SQLSMALLINT NameLength3 );

Parameters

  • ConnectionHandle The connection handle.

  • ServerName A connection string that defines the database to which your application connects. UltraLite ODBC does not use ODBC data sources. Instead, supply a connection string containing the schema file and database file parameters, together with optional other parameters.

    The following is an example of a ServerName parameter:

    (SQLTCHAR*)UL_TEXT(
    "schema_file=customer.usm;dbf=customer.udb"
)

    For a complete list of connection parameters, see Connection Parameters.

  • NameLength1 The length of * ServerName.

  • UserName The user ID to use when connecting. The user ID can alternatively be specified in the connection string supplied to the ServerName parameter.

  • NameLength2 The length of * UserName.

  • Authentication The password to use when connecting.The password can alternatively be specified in the connection string supplied to the ServerName parameter.

  • NameLength3 The length of * Authentication.

Remarks

Connects to a database. For information about UltraLite connection parameters, see Connection Parameters.

See also
  • [external link] SQLConnect in the Microsoft ODBC Programmer's Reference.


SQLDescribeCol function

Returns the result descriptor for a column in the result set.

The result descriptor includes the column name, column size, data type, number of decimal digits, and nullability.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLDescribeCol (
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLTCHAR * ColumnName,
SQLSMALLINT BufferLength,
SQLSMALLINT * NameLength,
SQLSMALLINT * DataType,
SQLULEN * ColumnSize,
SQLSMALLINT * DecimalDigits,
SQLSMALLINT * Nullable );

Parameters

  • StatementHandle A statement handle.

  • ColumnNumber The 1-based column number of result data.

  • ColumnName Pointer to a buffer in which to return the column name.

  • BufferLength The length of *ColumnName, in characters.

  • NameLength Pointer to a buffer in which to return the total number of bytes (excluding the null-termination byte) available to return in *ColumnName.

  • DataType Pointer to a buffer in which to return the SQL data type of the column.

  • ColumnSize Pointer to a buffer in which to return the size of the column on the data source.

  • DecimalDigits Pointer to a buffer in which to return the number of decimal digits of the column on the data source.

  • Nullable Pointer to a buffer in which to return a value that indicates whether the column allows NULL values.

See also
  • [external link] SQLDescribeCol in the Microsoft ODBC Programmer's Reference


SQLDisconnect function

Disconnects the application from a database, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLDisconnect (
SQLHDBC ConnectionHandle );

Parameters

  • ConnectionHandle The handle for the connection to be closed.

Remarks

Once SQLDisconnect is called, no further operations can be carried out against the database without opening a new connection.

See also
  • SQLConnect function
  • [external link] SQLDisconnect in the Microsoft ODBC Programmer's Reference


SQLEndTran function

Commits or rolls back a transaction, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLEndTran (
SQLSMALLINT HandleType,
SQLHANDLE Handle,
SQLSMALLINT CompletionType );

Parameters

  • HandleType The type of handle to be allocated. UltraLite supports the following handle types:

    • SQL_HANDLE_ENV
    • SQL_HANDLE_DBC
    • SQL_HANDLE_STMT

  • Handle The connection handle indicating the scope of the transaction.

  • CompletionType One of the following two values:

    • SQL_COMMIT
    • SQL_ROLLBACK
See also
  • [external link] SQLEndTran in the Microsoft ODBC Programmer's Reference


SQLExecDirect function

Executes a SQL statement, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLExecDirect (
SQLHSTMT StatementHandle,
SQLTCHAR * StatementText,
SQLINTEGER TextLength );

Parameters

  • StatementHandle A statement handle.

  • StatementText The text of the SQL statement.

  • TextLength The length of * StatementText.

Remarks

Unlike SQLExecute, the statement does not need to be prepared before being executed using SQLExecDirect.

SQLExecDirect has slower performance than SQLExecute for statements executed repeatedly.

See also
  • [external link] SQLExecDirect in the Microsoft ODBC Programmer's Reference


SQLExecute function

Executes a prepared SQL statement, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLExecute (
SQLHSTMT StatementHandle );

Parameters

  • StatementHandle The handle for the statement to be executed.

Remarks

The statement must be prepared using SQLPrepare before it can be executed. If the statement has parameter markers, they must be bound to variables using SQLBindParameter before execution.

You can use SQLExecDirect to execute a statement without preparing it first. SQLExecDirect has slower performance than SQLExecute for statements executed repeatedly.

See also
  • SQLBindParameter function
  • SQLPrepare function
  • [external link] SQLExecute in the Microsoft ODBC Programmer's Reference.


SQLFetch function

Fetches the next row from a result set and returns data for all bound columns, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLFetch (
SQLHSTMT StatementHandle );

Parameters

  • StatementHandle A statement handle.

Remarks

Before fetching rows, you must have bound the columns in the result set to buffers using SQLBindCol. To fetch a row other than the next row in the result set, use SQLFetchScroll.

See also
  • SQLFetchScroll function
  • SQLBindCol function
  • [external link] SQLFetch in the Microsoft ODBC Programmer's Reference.


SQLFetchScroll function

Fetches the specified row from the result set and returns data for all bound columns.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLFetchScroll (
SQLHSTMT StatementHandle,
SQLSMALLINT FetchOrientation,
SQLLEN FetchOffset );

Parameters

  • StatementHandle A statement handle.

  • FetchOrientation The type of fetch.

  • FetchOffset The number of the row to fetch. The interpretation depends on the value of FetchOrientation.

Remarks

Before fetching rows, you must have bound the columns in the result set to buffers using SQLBindCol. SQLFetchScroll is for use in those cases where the more straightforward SQLFetch is not appropriate.

See also
  • SQLFetch function
  • SQLBindCol function
  • [external link] SQLFetchScroll in the Microsoft ODBC Programmer's Reference.


SQLFreeHandle function

Frees resources for a handle allocated for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLFreeHandle (
SQLSMALLINT HandleType,
SQLHANDLE Handle );

Parameters

  • HandleType The type of handle to be allocated. UltraLite supports the following handle types:

    • SQL_HANDLE_ENV
    • SQL_HANDLE_DBC
    • SQL_HANDLE_STMT

  • Handle The handle to be freed.

Remarks

SQLFreeHandle should be called for each handle allocated using SQLAllocHandle, when the handle is no longer needed.

See also
  • SQLAllocHandle function
  • [external link] SQLFreeHandle in the Microsoft ODBC Programmer's Reference.


SQLGetCursorName function

Returns the name associated with a cursor for a specified statement, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLGetCursorName (
SQLHSTMT StatementHandle,
SQLTCHAR * CursorName,
SQLSMALLINT BufferLength,
SQLSMALLINT * NameLength );

Parameters

  • StatementHandle A statement handle.

  • CursorName Pointer to a buffer in which to return the name of the cursor associated with StatementHandle.

  • BufferLength The length of *CursorName.

  • NameLength Pointer to memory in which to return the total number of bytes (excluding the null-termination character) available to return in *CursorName.

See also
  • SQLSetCursorName function
  • [external link] SQLGetCursorName in the Microsoft ODBC Programmer's Reference.


SQLGetData function

Retrieves data for a single column in the result set. SQLGetData is typically used to retrieve variable-length data in parts.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLGetData (
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValue,
SQLLEN BufferLength,
SQLLEN * StrLen_or_Ind );

Parameters

  • StatementHandle A statement handle.

  • ColumnNumber The number of the column in the result set to bind.

  • TargetType The output handle.

  • TargetValue A pointer to the data buffer to bind to the column.

  • BufferLength The length of the TargetValue buffer in bytes.

  • StrLen_or_Ind Pointer to the length or indicator buffer to bind to the column.

See also
  • [external link] SQLGetData in the Microsoft ODBC Programmer's Reference.


SQLGetDiagRec function

Returns the current values of multiple fields of a diagnostic status record, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLGetDiagRec (
SQLSMALLINT HandleType,
SQLHANDLE Handle,
SQLSMALLINT RecNumber,
SQLTCHAR * Sqlstate,
SQLINTEGER * NativeError,
SQLTCHAR * MessageText,
SQLSMALLINT BufferLength,
SQLSMALLINT * TextLength );

Parameters

  • HandleType The type of handle to be allocated. UltraLite supports the following handle types:

    • SQL_HANDLE_ENV
    • SQL_HANDLE_DBC
    • SQL_HANDLE_STMT

  • Handle The input handle

  • RecNumber The output handle.

  • Sqlstate The ANSI/ISO SQLSTATE value of the error. For a listing, see Error messages indexed by SQLSTATE.

  • NativeError The SQLCODE value of the error. For a listing, see Error messages indexed by Adaptive Server Anywhere SQLCODE.

  • MessageText The text of the error or status message.

  • BufferLength The length of the MessageText buffer in bytes.

  • TextLength Pointer to a buffer in which to return the total number of bytes (excluding the null-termination byte) available to return in *MessageText.

See also
  • [external link] SQLGetDiagRec in the Microsoft ODBC Programmer's Reference.


SQLGetInfo function

Returns general information about the current ODBC driver and data source, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLGetInfo (
SQLHDBC ConnectionHandle,
SQLUSMALLINT InfoType,
SQLPOINTER InfoValue,
SQLSMALLINT BufferLength,
SQLSMALLINT ODBCFAR * StringLength );

Parameters

  • ConnectionHandle A connection handle.

  • InfoType The type of information returned. The only type supported is SQL_DBMS_VER. The information returned is a character string identifying the current release of the software.

  • InfoValue Pointer to a buffer in which to return the information.

  • BufferLength The length of the InfoValue buffer in bytes.

  • StringLength Pointer to a buffer in which to return the total number of bytes (excluding the null-termination character for character data) available to return in *InfoValue.

See also
  • [external link] SQLGetInfo in the Microsoft ODBC Programmer's Reference.


SQLNumResultCols function

Returns the number of columns in a result set, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLNumResultCols (
SQLHSTMT StatementHandle,
SQLSMALLINT * ColumnCount );

Parameters

  • StatementHandle A statement handle.

  • ColumnCount Pointer to a buffer in which to return the total number of columns in the result set.

See also
  • [external link] SQLNumResultCols in the Microsoft ODBC Programmer's Reference.


SQLPrepare function

Prepares a SQL statement for execution, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLPrepare (
SQLHSTMT StatementHandle,
SQLTCHAR * StatementText,
SQLINTEGER TextLength );

Parameters

  • StatementHandle A statement handle.

  • StatementText Pointer to a buffer that holds the SQL statement text.

  • TextLength The length of *StatementText.

See also
  • SQLExecute function
  • [external link] SQLPrepare in the Microsoft ODBC Programmer's Reference.


SQLRowCount function

Returns the number of rows affected by an INSERT, UPDATE, or DELETE operation, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLRowCount (
SQLHSTMT StatementHandle,
SQLLEN * RowCount );

Parameters

  • StatementHandle A statement handle.

  • RowCount Pointer to a buffer in which the number of rows is returned.

See also
  • [external link] SQLRowCount in the Microsoft ODBC Programmer's Reference.


SQLSetCursorName function

Sets the name of a cursor associated with a SQL statement, for UltraLite ODBC.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLSetCursorName (
SQLHSTMT StatementHandle,
SQLTCHAR * CursorName,
SQLSMALLINT NameLength );

Parameters

  • StatementHandle A statement handle.

  • CursorName Pointer to a buffer holding the cursor name.

  • NameLength The length of *CursorName.

See also
  • SQLGetCursorName function
  • [external link] SQLSetCursorName in the Microsoft ODBC Programmer's Reference.


SQLSetConnectionName function

Sets a connection name for the suspend and restore operation, for UltraLite ODBC. This function is specific to UltraLite and is not part of the ODBC standard.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLSetConnectionName (
SQLHSTMT StatementHandle,
SQLTCHAR * ConnectionName,
SQLSMALLINT NameLength );

Parameters

  • StatementHandle A statement handle.

  • ConnectionName Pointer to a buffer holding the connection name.

  • NameLength The length of *ConnectionName

Remarks

SQLSetConnectionName is used to provide a connection name for use in the suspend and restore operation, together with SQLSetSuspend. Set the connection name before opening a connection in order to restore application state.

See also
  • Saving state in UltraLite Palm applications
  • SQLSetSuspend function


SQLSetSuspend function

Indicates whether the state of open cursors should be saved on closing the application, for UltraLite ODBC. This function is specific to UltraLite and is not part of the ODBC standard.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLSetSuspend (
SQLSMALLINT HandleType,
SQLHSTMT StatementHandle,
SQLSMALLINT TrueFalse );

Parameters

  • HandleType The type of handle to be allocated. UltraLite supports the following handle types:

    • SQL_HANDLE_ENV
    • SQL_HANDLE_DBC
    • SQL_HANDLE_STMT

  • StatementHandle A statement handle.

  • TrueFalse The output handle.

See also

Saving state in UltraLite Palm applications


SQLSynchronize function

Synchronizes data in the database using MobiLink synchronization, for UltraLite ODBC. This function is specific to UltraLite and is not part of the ODBC standard.

Prototype

UL_FN_SPEC SQLRETURN UL_FN_MOD SQLSynchronize (
SQLHDBC ConnectionHandle,
ul_synch_info * SynchInfo );

Parameters

  • ConnectionHandle A handle.

  • SynchInfo The structure holding synchronization information. See Synchronization Parameters Reference.

Remarks

SQLSynchronize is an extension to ODBC. It initiates a MobiLink synchronization operation.

See also
  • Synchronization Parameters Reference.
  • MobiLink Administration Guide


Synchronization Parameters Reference

About this chapter

This chapter provides reference information about synchronization parameters.

Synchronization parameters
auth_parms parameter
auth_status parameter
auth_value synchronization parameter
checkpoint_store synchronization parameter
disable_concurrency synchronization parameter
download_only synchronization parameter
keep_partial_download synchronization parameter
ignored_rows synchronization parameter
new_password synchronization parameter
num_auth_parms parameter
observer synchronization parameter
partial_download_retained synchronization parameter
password synchronization parameter
ping synchronization parameter
publication synchronization parameter
resume_partial_download synchronization parameter
security synchronization parameter
security_parms synchronization parameter
send_column_names synchronization parameter
send_download_ack synchronization parameter
stream synchronization parameter
stream_error synchronization parameter
stream_parms synchronization parameter
upload_ok synchronization parameter
upload_only synchronization parameter
user_data synchronization parameter
user_name synchronization parameter
version synchronization parameter


Synchronization parameters

The synchronization parameters are members of a structure that is provided as an argument in the call to synchronize. The ul_synch_info structure that holds the synchronization parameters is defined in ulglobal.h as follows:

struct ul_synch_info {
    ul_char *             user_name;
    ul_char *             password;
    ul_char *             new_password;
    ul_char *             version;
    p_ul_stream_defn      stream;
    ul_char *             stream_parms;
    p_ul_stream_defn      security;
    ul_char *             security_parms;
    ul_synch_observer_fn  observer;
    ul_void *             user_data;
    ul_publication_mask   publication;
    ul_bool               upload_only;
    ul_bool               download_only;
    ul_bool               send_download_ack;
    ul_bool               send_column_names;
    ul_bool               ping;
    ul_bool               checkpoint_store;
    ul_bool               disable_concurrency;
    ul_byte               num_auth_params;
    ul_char * *           auth_parms;
    ul_bool               keep_partial_download;
    ul_bool               resume_partial_download;

    // fields set on output
    ul_stream_error       stream_error;
    ul_bool               upload_ok;
    ul_bool               ignored_rows;
    ul_auth_status        auth_status;
    ul_s_long             auth_value;
    ul_bool               partial_download_retained;

    p_ul_synch_info       init_verify;
};

The init_verify field is reserved for internal use.

Use UL_TEXT around constant strings
The UL_TEXT macro allows constant strings to be compiled as single-byte strings or wide-character strings. Use this macro to enclose all constant strings supplied as members of the ul_synch_info structure so that the compiler handles these parameters correctly.

For a description of the role of each synchronization parameter, see Synchronization parameters.


auth_parms parameter

Function

Provides parameters to a custom user authentication script.

Usage

Set the parameters as follows:

ul_char * Params[ 3 ] = { UL_TEXT( "parm1" ),
                          UL_TEXT( "parm2" ),
                          UL_TEXT( "parm3" ) };
// ...
info.num_auth_parms = 3;
info.auth_parms = Params;
See also
  • Authentication Parameters synchronization parameter
  • num_auth_parms parameter
  • authenticate_parameters connection event
  • authenticate_user connection event


auth_status parameter

Function

Reports the status of MobiLink user authentication.

Usage

Access the parameter as follows:

ul_synch_info info;
// ...
returncode = info.auth_status;
Allowed values

After synchronization, the parameter must hold one of the following values. If a custom authenticate_user synchronization script at the consolidated database returns a different value, the value is interpreted according to the rules given in authenticate_user connection event.

Constant | Value | Description
UL_AUTH_STATUS_UNKNOWN | 0 | Authorization status is unknown, possibly because the connection has not yet synchronized.
UL_AUTH_STATUS_VALID | 1000 | User ID and password were valid at the time of synchronization.
UL_AUTH_STATUS_VALID_BUT_EXPIRES_SOON | 2000 | User ID and password were valid at the time of synchronization but will expire soon.
UL_AUTH_STATUS_EXPIRED | 3000 | Authorization failed: user ID or password have expired.
UL_AUTH_STATUS_INVALID | 4000 | Authorization failed: bad user ID or password.
UL_AUTH_STATUS_IN_USE | 5000 | Authorization failed: user ID is already in use.
See also
  • Authentication Status synchronization parameter
  • Authenticating MobiLink Users.


auth_value synchronization parameter

Function

Reports return values from custom user authentication synchronization scripts.

Default

The values set by the default MobiLink user authentication mechanism are described in authenticate_user connection event.

Usage

The parameter is read-only.

Access the parameter as follows:

ul_synch_info info;
// ...
returncode = info.auth_value;
See also
  • Authentication Value synchronization parameter
  • authenticate_user connection event
  • authenticate_user_hashed connection event
  • auth_status parameter


checkpoint_store synchronization parameter

Function

Adds additional checkpoints of the database during synchronization to limit database growth during the synchronization process.

Default

By default, limited checkpointing is done.

Usage

Set the parameter as follows:

ul_synch_info info;
// ...
info.checkpoint_store = ul_true ;
See also

Checkpoint Store synchronization parameter


disable_concurrency synchronization parameter

Function

Disallow database access from other threads during synchronization.

Default

By default, data access is available. Data access is read-write during the download phase, and read-only otherwise.

Usage

Set the parameter as follows:

ul_synch_info info;
// ...
info.checkpoint_store = ul_false ;
See also
  • Disable Concurrency synchronization parameter
  • Understanding concurrency in UltraLite


download_only synchronization parameter

Function

Do not upload any changes from the UltraLite database during this synchronization.

Default

The parameter is an optional Boolean value, and by default is false.

Usage

Set the parameter as follows:

ul_synch_info info;
// ...
info.download_only = ul_true;
See also
  • Download Only synchronization parameter
  • Including read-only tables in an UltraLite database.
  • upload_only synchronization parameter


keep_partial_download synchronization parameter

Function

On download errors, hold on to partial downloads rather than rolling back all changes.

Default

The parameter is an optional Boolean value, and by default is false.

Usage

Set the parameter as follows:

ul_synch_info info;
// ...
info.keep_partial_download = ul_true;
See also
  • Resuming failed downloads
  • Keep Partial Download synchronization parameter


ignored_rows synchronization parameter

Function

Reports if any rows were ignored by the MobiLink synchronization server during synchronization because of absent scripts.

The parameter is read-only.


new_password synchronization parameter

Function

Sets a new MobiLink password associated with the user name.

Default

There is no default.

Usage

Set the parameter as follows:

ul_synch_info info;
// ...
info.password = UL_TEXT( "myoldpassword" );
info.new_password = UL_TEXT( "mynewpassword" );
See also
  • New Password synchronization parameter
  • Authenticating MobiLink Users.


num_auth_parms parameter

Function

The number of authentication parameter strings passed to a custom authentication script.

Default

No parameters passed to a custom authentication script.

Usage

The parameter is used together with auth_parms to supply information to custom authentication scripts.

For more information, see auth_parms parameter.

See also
  • Number of Authentication Parameters parameter
  • auth_parms parameter
  • authenticate_parameters connection event
  • authenticate_user connection event


observer synchronization parameter

Function

A pointer to a callback function that monitors synchronization.

See also
  • Observer synchronization parameter
  • Monitoring and canceling synchronization
  • user_data synchronization parameter


partial_download_retained synchronization parameter

Function

Indicates that a partial downloads was held as a result of failure during the download phase of synchronization.

Default

The parameter is set during synchronization if a download error occurs and a partial download was retained.

See also
  • Resuming failed downloads
  • Partial Download Retained synchronization parameter


password synchronization parameter

Function

A string specifying the MobiLink password associated with the user_name. This user name and password are separate from any database user ID and password, and serves to identify and authenticate the application to the MobiLink synchronization server.

Default

There is no default.

Usage

Set the parameter as follows:

ul_synch_info info;
// ...
info.password = UL_TEXT( "mypassword" );
See also
  • Password synchronization parameter
  • Authenticating MobiLink Users.


ping synchronization parameter

Function

Confirm communications between the UltraLite client and the MobiLink synchronization server. When this parameter is set to true, no synchronization takes place.

When the MobiLink synchronization server receives a ping request, it connects to the consolidated database, authenticates the user, and then sends the authenticating user status and value back to the client.

If the ping succeeds, the MobiLink server issues an information message. If the ping does not succeed, it issues an error message.

If the MobiLink user name cannot be found in the ml_user system table and the MobiLink server is running with the command line option -zu+, the MobiLink server adds the user to ml_user.

The MobiLink synchronization server may execute the following scripts, if they exist, for a ping request:

  • begin_connection

  • authenticate_user

  • authenticate_user_hashed

  • end_connection

Default

The parameter is an optional Boolean value, and by default is false.

Usage

Set the parameter as follows:

ul_synch_info info;
// ...
info.ping = ul_true;
See also
  • Ping synchronization parameter
  • -pi option


publication synchronization parameter

Function

Specifies the publications to be synchronized.

Default

If you do not specify a publication, all data is synchronized.

Usage

The UltraLite generator identifies the publications specified on the ulgen -v command line option as upper case constants with the name UL_PUB_pubname, where pubname is the name given to the -v option.

For example, the following command line generates a publication identified by the constant UL_PUB_SALES:

ulgen -v sales ...

When synchronizing, set the publication parameter to a publication mask: an OR'd list of publication constants. For example:

ul_synch_info info;
// ...
info.publication = UL_PUB_MYPUB1 | UL_PUB_MYPUB2 ;

The special publication mask UL_SYNC_ALL describes all the tables in the database, whether in a publication or not. The mask UL_SYNC_ALL_PUBS describes all tables in publications in the database.

See also
  • Publication synchronization parameter
  • The UltraLite Generator
  • Designing sets of data to synchronize separately


resume_partial_download synchronization parameter

Function

Resume a synchronization interrupted by a communication failuer during the downloads.

Default

The parameter is a Boolean value, and by default is false.

Usage

Set the parameter as follows:

ul_synch_info info;
// ...
info.resume_partial_download = ul_true;
See also
  • Resuming failed downloads
  • Resume Partial Download synchronization parameter


security synchronization parameter

Function

Set the UltraLite client to use Certicom encryption technology when exchanging messages with the MobiLink synchronization server.

Separately-licensable option required
Use of Certicom technology requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations. For more information on this option, see Welcome to SQL Anywhere Studio.
Default

The Security parameter is null by default, corresponding to no transport-layer security.

Usage

The security stream is specified in addition to the synchronization stream. Allowed values are as follows:

  • ULSecureCerticomTLSStream() Elliptic-curve transport-layer security provided by Certicom.

  • ULSecureRSATLSStream() RSA transport-layer security provided by Certicom.

For more information, including libraries that you must link against, see Security synchronization parameter.

See also
  • Security synchronization parameter
  • MobiLink Transport-Layer Security.


security_parms synchronization parameter

Function

Sets the parameters required when using transport-layer security. This parameter must be used together with the security parameter.

For more information, see security synchronization parameter.

Usage

The ULSecureCerticomTLSStream() and ULSecureRSATLSStream() security parameters take a string composed of the following optional parameters, supplied in an semicolon-separated string.

  • certificate_company The UltraLite application only accepts server certificates when the organization field on the certificate matches this value. By default, this field is not checked.

  • certificate_unit The UltraLite application only accepts server certificates when the organization unit field on the certificate matches this value. By default, this field is not checked.

  • certificate_name The UltraLite application only accepts server certificates when the common name field on the certificate matches this value. By default, this field is not checked.

For example:

ul_synch_info info;
...
info.stream = ULSocketStream();
info.security = ULSecureCerticomTLSStream();
info.security_parms =
     UL_TEXT( "certificate_company=Sybase" )
     UL_TEXT( ";" )
     UL_TEXT( "certificate_unit=Sales" );

The security_parms parameter is a string, and by default is null.

If you use secure synchronization, you must also use the -r command-line option on the UltraLite generator. For more information, see The UltraLite Generator.

See also
  • Security Parameters synchronization parameter


send_column_names synchronization parameter

Function

When send_column_names is set to ul_true UltraLite sends each column name to the MobiLink synchronization server. By default UltraLite does not send column names.

This parameter is typically used together with the -za or -ze switch on the MobiLink synchronization server for automatically generating synchronization scripts.

See also
  • Send Column Names synchronization parameter
  • -za option


send_download_ack synchronization parameter

Function

Set this boolean parameter to true to instruct the MobiLink synchronization server that the client will provide a download acknowledgement.

If the client does send a download acknowledgement, the MobiLink synchronization server worker thread must wait for the client to apply the download. If the client does not sent a download acknowledgement, the MobiLink synchronization server is freed up sooner for its next synchronization.

Default

The default setting is false.

See also
  • Send Download Acknowledgement synchronization parameter


stream synchronization parameter

Function

Set the MobiLink synchronization stream to use for synchronization.

For more information, see stream_parms synchronization parameter.

Default

The parameter has no default value, and must be explicitly set.

Usage
//Embedded SQL
ul_synch_info info;
...
info.stream = ULSocketStream();
//Static C++ API
Connection conn;
auto ul_synch_info info;
...
conn.InitSynchInfo( &info );
info.stream = ULSocketStream();

When the type of stream requires a parameter, pass that parameter using the stream_parms parameter; otherwise, set the stream_parms parameter to null.

The following stream functions are available, but not all are available on all target platforms:

Stream Description
ULActiveSyncStream() ActiveSync synchronization (Windows CE only).

For a list of stream parameters, see ActiveSync protocol options.
ULHTTPStream() Synchronize via HTTP.

The HTTP stream uses TCP/IP as its underlying transport. UltraLite applications act as Web browsers and the MobiLink synchronization server acts as a Web server. UltraLite applications send POST requests to send data to the server and GET requests to read data from the server.

For a list of stream parameters, see HTTP protocol options.
ULHTTPSStream() Synchronize via the HTTPS synchronization stream.

The HTTPS stream uses SSL or TLS as its underlying protocol. It operates over Internet protocols (HTTP and TCP/IP).

The HTTPS stream requires the use of technology supplied by Certicom. Use of Certicom technology requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations. For more information on this option, see Welcome to SQL Anywhere Studio.

For a list of stream parameters, see HTTPS protocol options.
ULSocketStream() Synchronize via TCP/IP.

For a list of stream parameters, see TCP/IP protocol options.
See also
  • Stream Type synchronization parameter


stream_error synchronization parameter

Function

Sets a structure to hold communications error reporting information.

Access methods

This feature is not available to Java applications.

Default

The parameter has no default value, and must be explicitly set.

Description

The stream_error field is a structure of type ul_stream_error.

typedef struct ss_error {
    ss_stream_id         stream_id;
    ss_stream_context    stream_context;
    ss_error_code        stream_error_code;
    asa_uint32           system_error_code;
    rp_char              *error_string;
    asa_uint32           error_string_length;
} ss_error, *p_ss_error;

The structure is defined in sserror.h, in the h subdirectory of your SQL Anywhere directory.

The ul_stream_error fields are as follows:

  • stream_id The network layer reporting the error. This enumeration is listed in sserror.h. The following are the meaningful constants:

    Constant | Value
    STREAM_ID_TCPIP | 0
    STREAM_ID_PALM_CONDUIT | 3
    STREAM_ID_PALM_SS | 4
    STREAM_ID_HTTP | 7
    STREAM_ID_HTTPS | 8
    STREAM_ID_SECURE | 10
    STREAM_ID_CERTICOM | 12
    STREAM_ID_JAVA_CERTICOM | 13
    STREAM_ID_CERTICOM_SSL | 14
    STREAM_ID_CERTICOM_TLS | 15
    STREAM_ID_WIRESTRM | 16
    STREAM_ID_ACTIVESYNC | 23
    STREAM_ID_RSA_TLS | 24
    STREAM_ID_JAVA_RSA | 25

  • stream_context The basic network operation being performed, such as open, read, or write. For details, see sserror.h.

  • stream_error_code The error reported by the stream itself. The stream_error_code is of type ss_error_code. The stream error codes are all prefixed with STREAM_ERROR_. A write error, for example, is STREAM_ERROR_WRITE.

    For a listing of error numbers, see MobiLink Communication Error Messages. For the error code suffixes, see sserror.h.

    In this version, to find the constant associated with each number you must count down the number of lines prefixed by DO_STREAM_Error in sserror.h. For example, to find the constant for error number 10, you use the tenth DO_STREAM_ERROR entry in sserror.h, which is as follows:

    DO_STREAM_ERROR( WRITE )

    The constant associated with this error is therefore STREAM_ERROR_WRITE.

  • system_error_code A system-specific error code. For more information on the error code, you must look at your platform documentation. For Windows platforms, this is the Microsoft Developer Network documentation.

    The following are common system errors on Windows:

    • 10048 (WSAADDRINUSE) Address already in use.

    • 10053 (WSAECONNABORTED) Software caused connection abort.

    • 10054 (WSAECONNRESET) The other side of the communication closed the socket.

    • 10060 (WSAETIMEDOUT) Connection timed out.

    • 10061 (WSAECONNREFUSED) Connection refused. Typically, this means that the MobiLink server is not running or is not listening on the specified port.

    For a complete listing, see [external link] the Microsoft Developer Network web site.

  • error_string An application-provided error message. The string may or may not be empty. A non-empty error_string provides information in addition to the stream_error_code. For instance, for a write error (error code 9) the error string is a number showing how many bytes it was trying to write.

Usage

Check for SQLE_COMMUNICATIONS_ERROR as follows:

Connection conn;
auto ul_synch_info info;
...
conn.InitSynchInfo( &info );
info.stream_error.error_string = error_buff;
info.stream_error.error_string_length =
                   sizeof( error_buff );
if( !conn.Synchronize( &synch_info ) ){
    if( SQLCODE == SQLE_COMMUNICATIONS_ERROR ){
        printf( error_buff );
    // more error handline here
See also
  • Stream Error synchronization parameter


stream_parms synchronization parameter

Function

Sets network protocol options to configure the synchronization stream.

A semi-colon separated list of option assignments. Each assignment is of the form keyword=value, where the allowed sets of keywords depends on the synchronization stream.

For a list of available options for each stream, see the following sections:

  • ActiveSync protocol options

  • HotSync protocol options

  • HTTP protocol options

  • HTTPS protocol options

  • TCP/IP protocol options

Default

The parameter is optional, is a string, and by default is null.

Usage

Set the parameter as follows:

ul_synch_info info;
// ...
info.stream_parms= UL_TEXT( "host=myserver;port=2439" );
See also
  • Stream Parameters synchronization parameter
  • Network protocol options for UltraLite synchronization clients.


upload_ok synchronization parameter

Function

Reports the status of MobiLink uploads. The MobiLink synchronization server provides this information to the client.

The parameter is read-only.

Usage

After synchronization, the upload_ok parameter holds true if the upload was successful, and false otherwise.

Access the parameter as follows:

ul_synch_info info;
// ...
returncode = info.upload_ok;
See also
  • Upload OK synchronization parameter


upload_only synchronization parameter

Function

Indicates that there should be no downloads in the current synchronization, which can save communication time, especially over slow communication links. When set to true, the client waits for the upload acknowledgement from the MobiLink synchronization server, after which it terminates the synchronization session successfully.

Default

The parameter is an optional Boolean value, and by default is false.

Usage

Set the parameter to true as follows:

ul_synch_info info;
// ...
info.upload_only = ul_true;
See also
  • Upload Only synchronization parameter
  • Synchronizing high-priority changes
  • download_only synchronization parameter


user_data synchronization parameter

Function

Make application-specific information available to the synchronization observer.

Usage

When implementing the synchronization observer callback function observer, you can make application-specific information available by providing information using user_data.

See also
  • User Data synchronization parameter
  • observer synchronization parameter


user_name synchronization parameter

Function

A string specifying the user name that uniquely identifies the MobiLink client to the MobiLink synchronization server. MobiLink uses this value to determine the download content, to record the synchronization state, and to recover from interruptions during synchronization.

Default

The parameter is required, and is a string.

Usage

Set the parameter as follows:

ul_synch_info info;
// ...
info.user_name= UL_TEXT( "mluser" );
See also
  • User Name synchronization parameter
  • Authenticating MobiLink Users.
  • MobiLink users.


version synchronization parameter

Function

Each synchronization script in the consolidated database is marked with a version string. For example, there may be two different download_cursor scripts, identified by different version strings. The version string allows an UltraLite application to choose from a set of synchronization scripts.

Default

The parameter is a string, and by default is the MobiLink default version string.

Usage

Set the parameter as follows:

ul_synch_info info;
// ...
info.version = UL_TEXT( "default" );
See also
  • Version synchronization parameter
  • Script versions.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite Static Java User's Guide

Version 9.0.2

DC50033-01-0902-01

October 2004

Copyright
About This Manual
Introduction to the Static Java API
Tutorial: Build an Application Using Java
Data Access Using the Static Java API
UltraLite Static Java API Reference
Synchronization Parameters Reference


About This Manual

Subject

This manual describes the UltraLite Static Java API. It is a complement for the UltraLite Database User's Guide.

Audience

This manual is intended for application developers writing Java programs that use the UltraLite database. Familiarity with relational databases and Adaptive Server Anywhere is assumed.


Introduction to the Static Java API

About this chapter

This chapter introduces the Static Java API for UltraLite databases. It assumes that you are familiar with the UltraLite database system and the development models it offers.

For more information, see Welcome to UltraLite.


System requirements and supported platforms

The supported target platform is Sun Personal Java 1.2.

Application development requires a supported JDK. You must also have an Adaptive Server Anywhere reference database.

For more detailed information, see UltraLite development platforms, and UltraLite target platforms.


Developing Static Java applications

When developing Static Java UltraLite applications, you use a JDBC-like programming interface. In order to develop these applications you should be familiar with the Java programming language.

The development process for Static Java UltraLite applications is as follows:

  1. Design your database.

    Prepare an Adaptive Server Anywhere reference database that contains the tables and indexes you wish to include in your UltraLite database.

  2. Add SQL statements to the database.

    The SQL Statements you wish to use in your application must be added to the reference database.

  3. Generate the classes for your application.

    The UltraLite generator provides the classes your application needs.

  4. Write your application.

    Data access features in your application code use JDBC and other function calls.

    For a guide to the interface, see UltraLite Static Java API Reference.

  5. Compile your .java files.

    You can compile the generated .java files just as you compile other .java files.

For a full description of the development process, see Building UltraLite Static Java applications.


Benefits and limitations of the Static Java API

UltraLite provides several programming interfaces, including both static development models (of which the Static Java interface is one) and UltraLite components. A Java-based component (Native UltraLite for Java) is among those available.

The Static Java API has the following advantages:

  • Pure Java solution The UltraLite runtime library for the Static Java API is a pure Java application. This is different from the Native UltraLite for Java component, which shares the same C++ based UltraLite runtime library as other UltraLite interfaces. In the Native UltraLite for Java component, access to the UltraLite runtime is provided by native methods.

  • Extensive SQL support With the Static Java API you can use a wider range of SQL in your applications than using the component-based interface.

The Static Java API has the following disadvantages:

  • Complex development model The use of a reference database to hold the UltraLite database schema, together with the need to generate classes for your specific application, makes the Static Java API development process complex. The UltraLite components, including Native UltraLite for Java, provide a much simpler development process.

  • SQL must be specified at design time Only SQL statements defined at compile time can be included in your application. The UltraLite components allow dynamic use of SQL statements.

The choice of development model is guided by the needs of your particular project, and by the programming skills and experience available.


Tutorial: Build an Application Using Java

About this chapter

This chapter provides a tutorial that guides you through the process of developing an UltraLite application using the Static Java API. The first section describes how to build a very simple application. The second section describes how to add synchronization to your application.

For an overview of the development process and background information on the UltraLite database, see Building UltraLite Static Java applications.

For information on developing UltraLite Static Java Applications, see Data Access Using the Static Java API.

Introduction
Lesson 1: Add SQL statements to your reference database
Lesson 2: Run the UltraLite generator
Lesson 3: Write the application code
Lesson 4: Build and run the application
Lesson 5: Add synchronization to your application
Lesson 6: Undo the changes you have made


Introduction

This tutorial describes how to construct a very simple application using UltraLite Java. The application is a command-line application, developed using the Sun JDK, which queries data in the ULProduct table of the UltraLite 9.0 Sample database.

In this tutorial, you create a Java source file, create a project in a reference database, and use these sources to build and run your application. The early lessons describe a version of the application without synchronization. Synchronization is added in a later lesson.

To follow the tutorial, you should have a Java Development Kit installed.


Overview

In the first lesson, you write and build an application that carries out the following tasks.

  1. Connects to an UltraLite database, consisting of a single table. The table is a subset of the ULProduct table of the UltraLite Sample database.

  2. Inserts rows into the table. Initial data is usually added to an UltraLite application by synchronizing with a consolidated database. Synchronization is added later in the chapter.

  3. Writes the rows of the table to standard output.

In order to build the application, you must carry out the following steps:

  1. Create an Adaptive Server Anywhere reference database.

    Here we use the UltraLite sample database (CustDB).

  2. Add the SQL statements to be used in your application to the reference database.

  3. Run the UltraLite generator to generate the Java code and also an additional source file for this UltraLite database.

    The generator writes out a .java file holding the SQL statements, in a form you can use in your application, and a .java file holding the code that executes the queries.

  4. Write source code that implements the logic of the application.

    Here, the source code is a single file, named Sample.java.

  5. Compile and run the application.

In the second lesson you add synchronization to your application.


Create a directory to hold your files

In this tutorial, you will be creating a set of files, including source files and executable files. You should make a directory to hold these files. In addition, you should make a copy of the UltraLite sample database so that you can work on it, and be sure you still have the original sample database for other projects.

Copies of the files used in this tutorial can be found in the Samples\UltraLite\JavaTutorial subdirectory of your SQL Anywhere directory.

toggle To prepare a tutorial directory

  1. Create a directory to hold the files you will create. In the remainder of the tutorial, we assume that this directory is c:\JavaTutorial.

  2. Make a backup copy of the UltraLite 9.0 Sample database into the tutorial directory. The UltraLite 9.0 Sample database is the file custdb.db, in the Samples\UltraLite\CustDB subdirectory of your SQL Anywhere installation directory. In this tutorial, we use the original UltraLite 9.0 Sample database, and at the end of the tutorial you can copy the untouched version from the APITutorial directory back into place.


Lesson 1: Add SQL statements to your reference database

The reference database for this tutorial is the UltraLite 9.0 Sample database. In a later step, you use this same database as a consolidated database for synchronization. These two uses are separate, and in real-world projects you may use different databases for the roles of reference database and consolidated database.

Add the SQL statements to the reference database using the ul_add_statement stored procedure. In this simple application, use the following statements:

  • Insert An INSERT statement adds an initial copy of the data into the ULProduct table. This statement is not needed when synchronization is added to the application.

  • Select A SELECT statement queries the ULProduct table.

When you add a SQL statement, you must associate it with an UltraLite project. Here, we use a project name of Product. You must also add a name for the statement, which by convention is in upper case.

toggle To add the SQL statements to the reference database

  1. Start Sybase Central, and connect to the UltraLite 9.0 Sample data source using the Adaptive Server Anywhere plug-in.

    1. From the Start menu, choose Programs > SQL Anywhere 9 > Sybase Central. Sybase Central appears.

    2. From the File menu, choose Tools > Connect. The New Connection dialog appears.

    3. Select the Adaptive Server Anywhere plugin and click OK. The Connect dialog appears.

    4. On the Identification tab, select ODBC Data Source Name and type UltraLite 9.0 Sample.

  2. Add a project to the database:

    1. In Sybase Central, open the custdb database.

    2. Open the UltraLite projects folder.

      The folder contains one project already: the custapi project used for the sample application. You must create a new project.

    3. Choose File > New > UltraLite Project.

    4. Enter Product as the project name, and click Finish.

  3. Add the INSERT statement to the Product project.

    1. Double-click Product to open the project.

    2. Choose File > New > UltraLite Statement.

    3. Enter InsertProduct as the statement name. Click Next.

    4. Enter the statement text:

      INSERT INTO ULProduct ( prod_id, price, prod_name)
VALUES (?,?,?)

      The question marks in the SQL statement are placeholders for values to be inserted into the ULProduct table. These values are supplied at runtime.

    5. Click Finish to complete the operation.

    This operation in Sybase Central is equivalent to executing the following stored procedure call:

    call ul_add_statement('Product',
    'InsertProduct',
    'INSERT INTO ULProduct( prod_id, price, prod_name)
     VALUES (?,?,?) ' )

    The first argument to ul_add_statement is the project name, the second is the statement name, and the third is the SQL statement itself.

  4. Add the SELECT statement to the Product project.

    1. From the Product project, choose File > New > UltraLite Statement.

    2. Enter SelectProduct as the statement name. Click Next.

    3. Enter the statement text:

      SELECT prod_id, prod_name, price
FROM ULProduct

    4. Click Finish to complete the operation.

    This operation in Sybase Central is equivalent to executing the following stored procedure call:

    call ul_add_statement('Product',
    'SelectProduct',
    'SELECT prod_id, prod_name, price FROM ULProduct')

  5. Close Sybase Central.

You have now added the SQL statements to the database, and you are ready to generate the UltraLite database.

For more information, see ul_add_project system procedure, and ul_add_statement system procedure.


Lesson 2: Run the UltraLite generator

The UltraLite generator writes out two Java files. One contains the SQL statements, as an interface definition, which is here named ISampleSQL.java. You can use this interface definition in your main application code. The second file holds the code that implements the queries and the database, and is here named SampleDB.java.

toggle To generate the UltraLite database code

  1. Open a command prompt, and go to your JavaTutorial directory.

  2. Run the UltraLite generator with the following arguments (all on one line):

    ulgen –a -t java -c "dsn=UltraLite 9.0 Sample"
-j Product -s ISampleSQL -f SampleDB

    The arguments have the following meanings:

    • -a Generate SQL string names in upper case. The InsertProduct and SelectProduct statements come to INSERT_PRODUCT and SELECT_PRODUCT.

    • -t The language of the generated code. Generate Java code instead of C code.

    • -c The connection string to connect to the database.

    • -j The UltraLite project name. This name corresponds to the project name you provided when you added the SQL statement to the database. The generator produces code only for those statements associated with this project.

    • -s The name of the interface that contains the SQL statements as strings.

    • -f The name of the file that holds the generated database code and query execution code.


Lesson 3: Write the application code

The following code listing holds a very simple UltraLite application.

You can copy the code into a new file and save it as Sample.java in your c:\JavaTutorial directory, or open a new file and type the content.

// (1) Import required packages
import java.sql.*;
import ianywhere.ultralite.jdbc.*;
import ianywhere.ultralite.runtime.*;
// (2) Class implements the interface containing SQL statements
public class Sample implements ISampleSQL
{
  public static void main( String[] args )
  {
    try{
        // (3) Connect to the database
        java.util.Properties p = new
            java.util.Properties();
        p.put( "persist", "file" );
        SampleDB db = new SampleDB( p );
        Connection conn = db.connect();
        // (4) Initialize the database with data
        PreparedStatement pstmt1 =
            conn.prepareStatement( INSERT_PRODUCT );
        pstmt1.setInt(1, 1);
        pstmt1.setInt(2, 400);
        pstmt1.setString(3, "4x8 Drywall x100");
        int rows1=pstmt1.executeUpdate();
        pstmt1.setInt(1, 2);
        pstmt1.setInt(2, 3000);
        pstmt1.setString(3, "8' 2x4 Studs x1000");
        int rows2=pstmt1.executeUpdate();
        // (5) Query the data and write out the results
        Statement stmt = conn.createStatement();
        ResultSet result = stmt.executeQuery(
             SELECT_PRODUCT );
        while( result.next() ) {
            int id = result.getInt( 1 );
            String name = result.getString( 2 );
            int price = result.getInt( 3 );
            System.out.println ( name +
                " \tId=" + id +
                " \tPrice=" + price );
        }
        // (6) Close the connection to end
        conn.close();
    } catch (SQLException e) {
        Support.printException( e );
    }
  }
}
Explanation of the sample program

Although too simple to be useful, this example contains elements that must be present in all Java programs used for database access. The following describes the key elements in the sample program. Use these steps as a guide when creating your own UltraLite application.

The numbered steps correspond to the numbered comments in the source code.

  1. Import required packages.

    The sample program utilizes JDBC interfaces and classes and therefore must import this package. It also requires the UltraLite runtime classes, and the generated interface that contains the SQL statement strings.

  2. Define the class.

    The SQL statements used in the application are stored in a separate file, as an interface. The class must declare that it implements the interface to be able to use the SQL statements for the project. The class names are based on the statement names you provided when adding the statements to the database.

  3. Connect to the database.

    The connection is established using an instance of the database class. The database name must match the name of the generated Java class (in this case SampleDB). The file value of the persist Properties object states that the database should be persistent.

  4. Insert sample data.

    In a production application, you would generally not insert sample data. Instead, you would obtain an initial copy of data by synchronization. In the early stages of development, it can simplify your work to directly insert data.

    • Create a PreparedStatement object using the prepareStatement() method.

    • To execute SQL commands, you must create a Statement or PreparedStatement object. Use a Statement object to execute simple SQL commands without any parameters and a PreparedStatement object to execute SQL commands with parameters. The sample program first creates a PreparedStatement object to execute an insert command:

      PreparedStatement pstmt1 =
conn.prepareStatement( INSERT_PRODUCT );

      The prepareStatement method takes a SQL string as an argument; this SQL string is included from the generated interface.

  5. Execute a select SQL command using a Statement object

    • Create a Statement object using the createStatement() method.

      Unlike the PreparedStatement object, you do not need to supply a SQL statement when you create a Statement object. Therefore, a single Statement object can be used to execute more than one SQL statement.

      Statement stmt = conn.createStatement();

    • Execute your SQL query.

      Use the executeQuery() method to execute a select query. A select statement returns a ResultSet object.

    • Implement a loop to sequentially obtain query results.

      The ResultSet object maintains a cursor that initially points just before the first row. The cursor is incremented by one row each time the next() method is called. The next() method returns a true value when the cursor moves to a row with data and returns a false value when it has moved beyond the last row.

      while(result.next()) {
...
}

    • Retrieve query results using the get xxx() methods.

      Supply the column number as an argument to these methods. The sample program uses the getInt() method to retrieve the product ID and price from the first and second columns respectively, and the getString() method to retrieve the product name from the third.

      int id = result.getInt( 1 );
int price = result.getInt( 2 );
String name = result.getString( 3 );

  6. End your program.

    • Close the connection to the database, using the Connection.close() method:

      conn.close();


Lesson 4: Build and run the application

After you have created a source file Sample.java using the sample code in the previous section, you are ready to build your UltraLite application.

toggle To build your application

  1. Start the Adaptive Server Anywhere personal database server.

    By starting the database server, the UltraLite generator has access to your reference database. Start the database server from the Start menu:

    Start > Programs > Sybase SQL Anywhere 9 > UltraLite > Personal Server Sample for UltraLite.

  2. Compile your Java source files.

    Include the following locations in your classpath:

    • The current directory (use a dot in your classpath).

    • The Java runtime classes. For JDK 1.2, include the jre\lib\rt.jar file in your classpath. For JDK 1.1, include the classes.zip file from your Java installation.

    • The UltraLite runtime classes. These classes are in the following location

      %ASANY9%\UltraLite\java\lib\ulrt.jar

      where %ASANY9% represents your SQL Anywhere directory.

    Run the javac compiler as follows:

    javac *.java

You are now ready to run your application.

toggle To run your application

  1. Open a command prompt and change to the Javatutorial directory.

  2. Include the same classes in the classpath as in the earlier procedure.

  3. Enter the following command to run the application

    java Sample

    The list of two items is written out to the screen, and the application terminates.

You have now built and run your first UltraLite Java application. The next step is to add synchronization to the application.


Lesson 5: Add synchronization to your application

Once you have tested that your program is functioning properly, you can remove the lines of code that manually insert data into the ULProduct table. Replace these statements with a call to the JdbcConnection.synchronize() function to synchronize the remote database with the consolidated database. This process will fill the tables with data and you can subsequently execute a select query.

Adding synchronization actually simplifies the code. Your initial version of Sample.java uses the following lines to insert data into your UltraLite database.

PreparedStatement pstmt1 = conn.prepareStatement( ADD_PRODUCT_1 );
pstmt1.setInt(1, 1);
pstmt1.setInt(2, 400);
pstmt1.setString(3, "4x8 Drywall x100");
int rows1=pstmt1.executeUpdate();
pstmt1.setInt(1, 2);
pstmt1.setInt(2, 3000);
pstmt1.setString(3, "8' 2x4 Studs x1000");
int rows2=pstmt1.executeUpdate();

This code is included to provide an initial set of data for your application. In a production application, you would not insert an initial copy of your data from source code, but would carry out a synchronization.

toggle To add synchronization to your application

  1. Delete the generated database (udb file) from the lesson 4.

    In this lesson, data is added by synchronization and requires a clean UltraLite database.

  2. Replace the hard-coded inserts with a synchronization call.

    1. Delete the instructions listed above, which insert code.

    2. Add the following line in their place:

      UlSynchOptions synch_opts = new UlSynchOptions();
synch_opts.setUserName( "50" );
synch_opts.setPassword( "pwd50" );
synch_opts.setScriptVersion( "ul_default" );
synch_opts.setStream( new UlSocketStream() );
synch_opts.setStreamParms( "host=localhost" );
( (JdbcConnection)conn ).synchronize( synch_opts );

      The ULSocketStream argument instructs the application to synchronize over TCP/IP, to a MobiLink synchronization server on the current machine (localhost), using a MobiLink user name of 50.

  3. Compile and link your application.

    Enter the following command, with a CLASSPATH that includes the current directory, the UltraLite runtime classes, and the Java runtime classes:

    javac *.java

  4. Start the MobiLink synchronization server running against the sample database.

    From a command prompt in your JavaTutorial directory, enter the following command:

    start dbmlsrv9 -c "dsn=UltraLite 9.0 Sample"

  5. Run your application.

    From a command prompt in your JavaTutorial directory, enter the following command:

    java Sample

    The application connects, synchronizes to receive data, and writes out information to the command line. The output is as follows:

    Connecting to server:port = localhost(a.b.c.d):2439
4x8 Drywall x100        Id=1    Price=400
8' 2x4 Studs x1000      Id=2    Price=3000
Drywall Screws 10lb     Id=3    Price=40
Joint Compound 100lb    Id=4    Price=75
Joint Tape x25x500      Id=5    Price=100
Putty Knife x25         Id=6    Price=400
8' 2x10 Supports x 200  Id=7    Price=3000
400 Grit Sandpaper      Id=8    Price=75
Screwmaster Drill       Id=9    Price=40
200 Grit Sandpaper      Id=10   Price=100

In this lesson, you have added synchronization to a simple UltraLite application.

For more information on the JdbcConnection.synchronize() function, see synchronize method.


Lesson 6: Undo the changes you have made

To complete the tutorial, you should shut down the MobiLink synchronization server and restore the UltraLite 9.0 Sample database.

toggle To finish the tutorial

  1. Close down the MobiLink synchronization server.

  2. Restore the UltraLite 9.0 Sample database.

    • Delete the custdb.db and custdb.log files in the Samples\UltraLite\custdb subdirectory of your SQL Anywhere directory.

    • Copy the custdb.db file from your Javatutorial directory to the Samples\UltraLite\custdb directory.

  3. Delete the UltraLite database.

    • The UltraLite database is in the same directory as the jar file, and has a .udb extension. The application will initialize a new database next time the application is run.


Data Access Using the Static Java API

About this chapter

This chapter provides details of the UltraLite development process that are specific to the Static Java API. It explains how to write UltraLite applications using Java and provides instructions on building and deploying an UltraLite application.

Introduction
The UltraLite Static Java sample application
Connecting to and configuring your UltraLite database
Including SQL statements in UltraLite Static Java applications
Adding user authentication to your application
Configuring and managing database storage
Adding synchronization to your application
UltraLite Static Java development notes
Building UltraLite Static Java applications


Introduction

UltraLite applications can be written in the Java language using JDBC for database access.

The UltraLite development process for Java is similar to that for C/C++ static development models. For a description, see Using UltraLite Static Interfaces.

This chapter describes only those aspects of application development that are specific to UltraLite Static Java applications. It assumes an elementary familiarity with Java and JDBC.


The UltraLite Static Java sample application

This section describes how to compile and run the UltraLite Static Java version of the CustDB sample application.

The sample application is provided in the Samples\UltraLite\CustDB\java subdirectory of your SQL Anywhere directory.

The applet version of the sample uses the Sun appletviewer to view the file custdb.html, which contains a simple <APPLET> tag.

The appletviewer security restrictions require the applet to be downloaded from a Web server, rather than to be run from the file system, for socket connections to be permitted and synchronization to succeed.

The application version of CustDB persists its data to a file, while the applet version does not use persistence.

For a walkthrough of the C/C++ version of the application, which has very similar features, see Tutorial: The CustDB Sample UltraLite Application.


The UltraLite Static Java sample files

The code for the UltraLite Static Java sample application is held in the Samples\UltraLite\CustDB\java subdirectory of your SQL Anywhere directory.

The directory holds the following files:

  • Data access code The file CustDB.java holds the UltraLite-specific data access logic. The SQL statements are stored in SQL.sql.

  • User interface code The files DialogDelOrder.java, Dialogs.java, DialogNewOrder.java, and DialogUserID.java all hold user interface features.

  • readme.txt A text file containing detailed, release-dependent information about the sample.

  • Subdirectories There are two subdirectories in which you can run the sample. These are java11 (for Java 1) and java13 (for Java 2). You should make the former your current directory if you are using a 1.1.x version of the JDK, and the latter if you are using 1.2.x or later. These subdirectories contain batch files to run the samples. In each directory, the batch files depend on the JAVA_HOME environment variable, which should be set to the directory containing the JDK. For example:

    SET JAVA_HOME=c:\jdk1.3.1

  • Batch files to build the application The files build.bat and clean.bat compile the application and delete all files except the source files, respectively.

  • Files to run the sample as an application The Application.java file contains instructions necessary for running the example as a Java application, and run.bat runs the sample application.

  • Files to run the sample as an applet The Applet.java file contains instructions necessary for running the example as a Java applet, and avapplet.bat runs the sample applet using the appletviewer, with custdb.html as the Web page.

You must install and start a Web server to run the sample as an applet. The applet can be run using the appletviewer utility or by using a Web browser. For more information, see the Samples\UltraLite\CustDB\Java\readme.txt file.


Building the UltraLite Static Java sample

This section describes how to build the UltraLite Static Java sample application for the Sun Java 1 or 2 environment.

toggle To build the UltraLite Static Java sample

  1. Ensure you have the right JDK.

    You must have JDK 1.1 or JDK 1.3 to build the sample application, and the JDK tools must be in your path.

  2. Open a command prompt.

  3. Change to the Samples\UltraLite\CustDB\java\java13 subdirectory of your SQL Anywhere directory, or the java11 directory if you are using Java 1.

  4. Build the sample:

    • Set the JAVA_HOME environment variable. For example:

      SET JAVA_HOME=c:\jdk1.3.1

    • From the command prompt, enter the following command:

      build

    The build procedure carries out the following operations:

    • Loads the SQL statements into the UltraLite sample database.

      This step uses Interactive SQL, the SQL.sql file, and relies on the UltraLite 9.0 Sample data source.

    • Generates the Java database class custdb.Database.

      This step uses the UltraLite generator and the UltraLite 9.0 Sample data source.

    • Compiles the Java files.

      This step uses the JDK compiler (javac) and jar utility.


Running the UltraLite Static Java sample

You can run the sample application as a Java application or as an applet. In either case, you need to prepare to run the sample by starting the MobiLink synchronization server running on the same machine that the application is running on.

toggle To prepare to run the sample

  • Start the MobiLink synchronization server running on the UltraLite sample database:

    From the Start menu, choose Programs > SQL Anywhere 9 > MobiLink > Synchronization Server Sample.

toggle To run the sample as an application

  1. Open a command prompt in the Samples\UltraLite\CustDB\java\java13 directory (or the java11 directory if you are using Java 1).

  2. Run the sample:

    • Set the JAVA_HOME environment variable. For example:

      SET JAVA_HOME=c:\jdk1.3.1

    • Enter the following command:

      run

    The application starts and the Enter ID dialog is displayed.

  3. Enter the employee ID.

    Enter an employee ID of 50, and click OK.

    The UltraLite Customer Demonstration window is displayed. If you have run the sample as either an application or applet before, there is data in the database.

  4. If there is no data in the database, synchronize.

    From the Actions menu, choose Synchronize. The application synchronizes, and the window displays an order.

You can now carry out operations on the data in the database.

For more information on the sample database and the UltraLite features it demonstrates, see Tutorial: The CustDB Sample UltraLite Application.

toggle To run the sample as an applet using appletviewer

  1. Start a Web server and ensure that the appropriate subdirectory is configured as the default directory for the server, or as one of the virtual directories.

  2. Open a command prompt in the UltraLite\samples\CustDB\java\java13 directory, or java11 if you are using Java 1.

  3. Enter the following command:

    avapplet

    • The applet starts and a field to enter an employee ID is displayed.

  4. Enter the employee ID.

    Enter an employee ID of 50, and click OK.

    The UltraLite Customer Demonstration window is displayed. The first time you run the sample, there is no data in the database. If you have run the sample as either an application or applet before, there is data in the database.

  5. Synchronize the application:

    From the Actions menu, choose Synchronize. The application synchronizes, and the window displays an order.

    You can now carry out operations on the data in the database.

toggle To run the sample as an applet using A Web browser

  1. Start a Web server and ensure that the appropriate subdirectory is configured as the default directory for the server, or as one of the virtual directories.

  2. Start a Web browser and enter the URL for the Samples\UltraLite\CustDB\java\custdb.htm file into the browser.

    • The applet starts and a field to enter an employee ID is displayed.

  3. Enter the employee ID.

    Enter an employee ID of 50, and click OK.

    The UltraLite Customer Demonstration window is displayed. The first time you run the sample, there is no data in the database. If you have run the sample as either an application or applet before, there is data in the database.

  4. Synchronize the application:

    From the Actions menu, choose Synchronize. The application synchronizes, and the window displays an order.

For more information on the sample database and the UltraLite features it demonstrates, see Tutorial: The CustDB Sample UltraLite Application.

Resetting the sample

You can delete all compiled files, the sample database, and the generated code by running the clean.bat file.


Connecting to and configuring your UltraLite database

This section describes how to connect to an UltraLite database. It describes the recommended UltraLite method for connecting to your database, and also how you can use the standard JDBC connection model to connect.

Connections to UltraLite databases have no user IDs or passwords. For more information, see User authentication in UltraLite.

UltraLite Static Java databases can be persistent (stored in a file when the application closes) or transient (the database vanishes when the application is closed). By default, they are transient.

You configure the persistence of your UltraLite database when connecting to it. This section describes how to configure your UltraLite database.

Using the UltraLite JdbcDatabase.connect method
Loading and registering the JDBC driver
Connecting to the database using JDBC
UltraLite JDBC URLs
Using a Properties object to store connection information
Connecting to multiple databases
Configuring the UltraLite Static Java database


Using the UltraLite JdbcDatabase.connect method

The generated UltraLite database code is in the form of a class that extends JdbcDatabase, which has a connect method that establishes a connection.

The following example illustrates typical code, for a generated database class called SampleDB:

try {
   SampleDB db = new SampleDB();
   java.sql.Connection conn = db.connect();
} catch( SQLException e ){
// error processing here
}

The generated database class is supplied on the UltraLite generator command line, using the -f option.

If you wish to use a persistent database, the characteristics are specified on the connection as a Properties object. The following example illustrates typical code:

java.util.Properties p = new java.utils.Properties();
p.put( "persist", "file" );
p.put( "persistfile", "c:\\dbdir\\database.udb" );
SampleDB db = new SampleDB( p );
java.sql.Connection conn = db.connect( );

The Properties are used on the database constructor. You cannot change the persistence model of the database between connections.

The two properties specify that the database is persistent, and is stored in the file c:\dbdir\database.udb.

For more information on the properties you can specify in the URL, see UltraLite JDBC URLs.

For more information see Configuring the UltraLite Static Java database, and The generated database class.


Loading and registering the JDBC driver

The UltraLite JdbcDatabase.connect() method discussed in the previous section provides the simplest method of connecting to an UltraLite database. However, you can also establish a connection in the standard JDBC manner, and this section describes how to do so.

UltraLite applications connect to their database using a JDBC driver, which is included in the UltraLite runtime classes (ulrt.jar). You must load and register the JDBC driver in your application before connecting to the database. Use the Class.forName() method to load the driver. This method takes the driver package name as its argument:

Class.forName( "ianywhere.ultralite.jdbc.JdbcDriver");

The JDBC driver automatically registers itself when it is loaded.

Loading multiple drivers

Although there is typically only one driver registered in each application, you can load multiple drivers in one application. Load each driver using the same methods as above. The DriverManager decides which driver to use when connecting to the database.

getDriver method

The DriverManager.getDriver method returns the Driver for the specified URL.

Error handling

To handle the case where the driver cannot be found, catch ClassNotFoundException as follows:

try{
   Class.forName(
      "ianywhere.ultralite.jdbc.JdbcDriver");
} catch(ClassNotFoundException e){
   System.out.println( "Exception: " + e.getMessage() );
   e.printStackTrace();
}


Connecting to the database using JDBC

Once the driver is declared, you can connect to the database using the standard JDBC DriverManager.getConnection method.

getConnection prototypes

The JDBC DriverManager.getConnection method has several prototypes. These take the following arguments:

DriverManager.getConnection( String url, Properties info )
DriverManager.getConnection( String url )

The UltraLite driver supports each of these prototypes. The arguments are discussed in the following sections.

Driver Manager

The DriverManager class maintains a list of the Driver classes that are currently loaded. It asks each driver in the list if it is capable of connecting to the URL. Once such a driver is found, the DriverManager attempts to use it to connect to the database.

Error handling

To handle the case where a connection cannot be made, catch the SQLException as follows:

try{
   Class.forName(
      "ianywhere.ultralite.jdbc.JdbcDriver");
   Connection conn = DriverManager.getConnection(
      "jdbc:ultralite:asademo" );
   } catch(SQLException e){
   System.out.println( "Exception: " + e.getMessage() );
   e.printStackTrace();
   }


UltraLite JDBC URLs

The URL is a required argument to the DriverManager.getConnection method used to connect to UltraLite databases.

For an overview of connection methods, see Connecting to the database using JDBC.

The syntax for UltraLite JDBC URLs is as follows:

jdbc:ultralite:[database:persist:persistfile][;option=value...]

The components are all case sensitive, and have the following meanings:

  • jdbc Identifies the driver as a JDBC driver. This is mandatory.

  • ultralite Identifies the driver as the UltraLite driver. This is mandatory.

  • database The class name for the database. It is required and must be a fully-qualified name: if the database class is in a package, you must include the package name.

    For example, the URL jdbc:ultralite:MyProject causes a class named MyProject to be loaded.

    As Java classes share their name with the .java file in which they are defined, this component is the same as the output file parameter from the UltraLite generator.

    For more information, see The UltraLite Generator.

  • persist Specifies whether or not the database should be persistent. By default, it is transient.

    For more information, see Configuring the UltraLite Static Java database.

  • persistfile For persistent databases, specifies the filename.

    For more information, see Configuring the UltraLite Static Java database. The UltraLite Static Java properties are very similar to those for C/C++ applications. Their names differ only in the absence of underscore characters., except that persistfile is analogous to file_name. See UL_STORE_PARMS macro.

  • options The following options are provided:

    • uid A user ID.

    • pwd A password for the user ID.

Alternatively, you can connect using a Properties object. The following properties may be specified. Each have the same meaning as in the explicit URL syntax above:

  • database

  • persist

  • persistfile

  • user

  • password


Using a Properties object to store connection information

You can use a Properties object to store connection information, and supply this object as an argument to getConnection along with the URL.

For an overview of connection methods, see Connecting to the database using JDBC.

The following components of the URL, described in UltraLite JDBC URLs, can be supplied either as part of the URL or as a member of a Properties object.

  • persist

  • persistfile

  • The jdbc:ultralite components must be supplied in the URL.

If you wish to encrypt your database, you can do so by supplying a key property. For more information, see Encrypting UltraLite databases.


Connecting to multiple databases

UltraLite Static Java applications can connect to more than one database. To connect to more than one database, simply create more than one connection object.

For more information see Connecting to the database using JDBC.


Configuring the UltraLite Static Java database

You can configure the following aspects of the UltraLite Static Java database:

  • Whether the database is transient or persistent.

  • If the database is persistent, you can supply a filename.

  • If the database is transient, you can supply a URL for an initializing database.

  • You can set an encryption key.

These aspects can be configured by supplying special values in the database URL, or by supplying a Properties object when creating the database. The encryption key cannot be set on the URL, but must be set in a Properties object.

For more information, see Using the UltraLite JdbcDatabase.connect method, and Using a Properties object to store connection information.

Transient and persistent databases

By default, UltraLite Static Java databases are transient: they are initialized when the database object is instantiated, and vanish when the application closes down. The next time the application starts, it must reinitialize a database.

You can make UltraLite Static Java databases persistent by storing them in a file. You do this by specifying the persist and persistfile elements of the JDBC URL, or by supplying persist and persistfile Properties to the database connect method.

Initializing transient databases

The database for most UltraLite applications is initialized on the first synchronization call. For UltraLite Static Java applications that use a transient database, there is an alternative method of initializing the database. The URL for an UltraLite database that is used as the initial database is supplied in the persistfile component to the URL.

Configuring the database

The database configuration components of the URL are as follows:

  • persist This can take one of the following values:

    • none In this case, the database is transient. It is stored in memory while the application runs, but vanishes once the application terminates.

    • file In this case, the database is stored as a file. The default filename is database.udb, where database is the database class name.

    The default setting is none.

  • persistfile The meaning of this component depends on the setting for persist.

    • If the persist component has a value of none, the persistfile component is a URL for an UltraLite database file that is used to initialize the database.

      Both the schema and the data from the URL are used to initialize the application database, but there is no further connection between the two. Any changes made by your application apply only to the transient database, not to the initializing database.

      The following JDBC URL is an example:

jdbc:ultralite:transient:none:http://www.address.com/transient.udb

You can prepare the initializing database with an application that uses the persistent form of the URL to create the database, synchronize, and exit.

  • If the persist component has a value of file, the persistfile component is a filename for the persistent UltraLite database. The filename should include any extension (such as .udb) that you wish to use.


Including SQL statements in UltraLite Static Java applications

This section describes how to add SQL statements to your UltraLite application.

For information on SQL features that can and cannot be used in UltraLite application, see Overview of SQL support in UltraLite.

The SQL statements to be used in your application must be added to the reference database. The UltraLite generator writes out an interface that defines these SQL statements as public static final strings. You invoke the statements in your application by implementing the interface and referencing the SQL statement by its identifier, or by referencing it directly from the interface.

Defining the SQL statements for your application

The SQL statements to be included in the UltraLite application, and the structure of the UltraLite database itself, are defined by adding the SQL statements to the reference database for your application.

For information on reference databases, see Preparing a reference database.

Defining projects

Each SQL statement stored in the reference database is associated with a project. A project is a name, defined in the reference database, which groups the SQL statements for one application. You can store SQL statements for multiple applications in a single reference database by defining multiple projects.

For information on creating projects, see Creating an UltraLite project.

Adding statements to your project

The data access statements you are going to use in your UltraLite application must be added to your project.

For information on adding SQL statements to your database, see Adding SQL statements to an UltraLite project.


Adding user authentication to your application

For a general description of UltraLite user authentication, see User authentication in UltraLite.

When you create an UltraLite database with user authentication enabled, one authenticated user is created, with user ID DBA and password SQL. UltraLite permits up to four different users to be defined at a time, with both user ID and password being less than 16 characters long. Each user has full access to the database once successfully authenticated.

The case sensitivity of the UltraLite user ID and password is determined by the reference database. If the reference database is case insensitive (the default) then the UltraLite database is also case insensitive, including user authentication.


Enabling user authentication

Enabling user authentication requires the application to supply a valid UltraLite user ID and password when connecting to the UltraLite database. If you do not explicitly enable user authentication, UltraLite does not authenticate users.

toggle To enable user authentication

  • Call the JdbcSupport.enableUserAuthentication method before creating a new database object: For example:

    JdbcSupport.enableUserAuthentication();
java.util.Properties p = new java.util.Properties();
p.put( "persist", "file" );
SampleDB db = new SampleDB( p );

Once you have enabled user authentication, you must add user management code to your application. For more information, see Managing user IDs and passwords.


Web Links Browse Collapse Expand PDF Previous Next

UltraLite Static Java User's Guide

Data Access Using the Static Java API

Adding user authentication to your application

Managing user IDs and passwords

User authentication example


User authentication example

The following code fragment performs user management and authentication for an UltraLite Java application.

A complete sample can be found in the Samples\UltraLite\javaauth subdirectory of your SQL Anywhere directory. The code below is based on that in Samples\UltraLite\javaauth\Sample.java.

JdbcSupport.enableUserAuthentication();
// Create database environment
java.util.Properties p = new java.util.Properties();
p.put( "persist", "file" );
SampleDB db = new SampleDB( p );

// Get new user ID and password
try{
   conn = db.connect( "dba", "sql" );
   // Set user ID and password
   // a real application would prompt the user.
   uid = "50";
   pwd = "pwd50";

   db.grant( uid, pwd );
   db.revoke( "dba" );
   conn.close();
}
catch( SQLException e ){
   // dba connection failed - prompt for user ID and password
   uid = "50";
   pwd = "pwd50";
}

// Connect
conn = db.connect( uid, pwd );

The code carries out the following tasks:

  1. Opening the database object.

  2. Attempt to connect using the default user ID and password.

  3. If the connection attempt is successful, add a new user.

  4. Delete the default user from the UltraLite database.

  5. Disconnect. An updated user ID and password is now added to the database.

  6. Connect using the updated user ID and password.


Configuring and managing database storage

You can configure the following aspects of UltraLite persistent storage:

  • The amount of memory used as a cache by the UltraLite database engine.

  • Database encryption.

  • Preallocation of file-system space.

  • The file name for the database.

  • The database page size.


Encrypting UltraLite databases

By default, UltraLite databases are unencrypted on disk and in permanent memory. Text and binary columns are plainly readable within the database store when using a viewing tool such as a hex editor. Two options are provided for greater security:

  • Obfuscation Obfuscating databases provides security against straightforward attempts to view data in the database directly using a viewing tool. It is not proof against skilled and determined attempts to gain access to the data. Obfuscation has little or no performance impact.

    For more information, see Obfuscating an UltraLite database.

  • Strong encryption UltraLite database files can be strongly encrypted using the AES 128-bit algorithm, which is the same algorithm used to encrypt Adaptive Server Anywhere databases. Use of strong encryption does provide security against skilled and determined attempts to gain access to the data, but has a significant performance impact.

    Caution If the encryption key for a strongly encrypted database is lost or forgotten, there is no way to access the database. Under these circumstances, technical support cannot gain access to the database for you. It must be discarded and you must create a new database.

    For more information, see Encrypting an UltraLite database, and Changing the encryption key for a database.


Obfuscating an UltraLite database
toggle To obfuscate an UltraLite database

  • Add the following line to your code before creating the database (that is, before connecting to the database for the first time):

    UlDatabase.setDefaultObfuscation( true );


Encrypting an UltraLite database

UltraLite databases are created on the first connection attempt. To encrypt an UltraLite database, you supply an encryption key before that connection attempt. On the first attempt, the supplied key is used to encrypt the database. On subsequent attempts, the supplied key is checked against the encryption key, and connection fails unless the key matches.

toggle To strongly encrypt an UltraLite database

  1. Set a property named key before creating a database object for the first time.

    The following code reads the encryption key from the command line.

    InputStreamReader isr = new InputStreamReader( System.in );
BufferedReader br = new BufferedReader( isr );
String key = null ;
System.out.print( "Enter encryption key:" );
key = br.readLine() ;
System.out.println( "The key is: " + key );

// Connect to the database
java.util.Properties p = new java.util.Properties();
p.setProperty( "persist", "file" );
p.setProperty( "key", key );
SampleDB db = new SampleDB( p );

    Here, SampleDB is the database filename as supplied in the UltraLite generator -f command-line option.

    For more information, see The UltraLite Generator, and Using a Properties object to store connection information.

  2. Create the database object using the properties.

    For example:

    Connection conn = db.connect();

    After the first connection attempt, subsequent attempts to access the database produce an Incorrect or missing encryption key SQLException if the wrong key is supplied.

You can find a sample Java application demonstrating encryption in the directory \Samples\UltraLite\JavaSecurity. The encryption code is held in \Samples\UltraLite\JavaSecurity\Sample.java.

Here is a code snippet from the sample:

// Obtain the encryption key
InputStreamReader isr = new InputStreamReader( System.in );
BufferedReader br = new BufferedReader( isr );
String key = null ;
System.out.print( "Enter encryption key:" );
key = br.readLine() ;
System.out.println( "The key is: " + key );

java.util.Properties p = new java.util.Properties();
p.setProperty( "persist", "file" );
p.setProperty( "key", key );
SampleDB db = new SampleDB( p );
Connection conn = db.connect();


Changing the encryption key for a database

You can change the encryption key for a database. The application must already be connected to the database using the existing key before the change can be made.

Caution When the key is changed, every row in the database is decrypted using the old key and re-encrypted using the new key. This operation is unrecoverable. If the application is interrupted part-way through, the database is invalid and cannot be accessed. A new one must be created.
toggle To change the encryption key on an UltraLite database

  • Call changeEncryptionKey on the database object, supplying the new key as an argument.

    db.changeEncryptionKey( "new key" );

    For more information, see changeEncryptionKey method.


Defragmenting UltraLite databases

The UltraLite store is designed to efficiently reuse free space, so explicit defragmentation is not required under normal circumstances. This section describes a technique to explicitly defragment UltraLite databases, for use by applications with extremely strict space requirements.

UltraLite provides a defragmentation step function, which defragments a small part of the database. To defragment the entire database at once, call the defragmentation step function in a loop until it returns ul_true. This can be an expensive operation, and SQLCODE must also be checked to detect errors (an error here usually indicates a file I/O error).

Explicit defragmentation occurs incrementally under application control during idle time. Each step is a small operation.

For more information, see Class JdbcDefragIterator.

toggle To defragment an UltraLite database

  1. Cast a Connection to a JdbcConnection object. For example,

    ...
Connection conn = db.connect();
JdbcConnection jconn = (JdbcConnection)conn ;

    UltraLite provides a defragmentation step function, which defragments a small part of the database. To defragment the entire database at once, call the defragmentation step function in a loop until it returns ul_true. This can be an expensive operation, and SQLCODE must also be checked to detect errors (an error here usually indicates a file I/O error).

  2. Call getDefragIterator() to obtain a JdbcDefragIterator object. For example:

    JdbcDefragIterator defrag = jconn.getDefragIterator();

  3. During idle time, call ulStoreDefragStep() to defragment a piece of the database.

    defrag.ulStoreDefragStep();


Adding synchronization to your application

Synchronization is a key feature of many UltraLite applications. This section describes how to add synchronization to your application.

The synchronization logic that keeps UltraLite applications up to date with the consolidated database is not held in the application itself. Synchronization scripts stored in the consolidated database, together with the MobiLink synchronization server and the UltraLite runtime library, control how changes are processed when they are uploaded and determines which changes are to be downloaded.

Overview

The specifics of each synchronization is controlled by a set of synchronization parameters. These parameters are gathered into an object that is supplied as an argument in a function call to synchronize. The outline of the method is the same in each development model.

toggle To add synchronization to your application

  1. Initialize the object that holds the synchronization parameters.

    For information, see Initializing the synchronization parameters.

  2. Assign the parameter values for your application.

    For information, see Network protocol options for UltraLite synchronization clients.

  3. Call the synchronization function, supplying the structure or object as argument.

    For information, see Invoking synchronization.

You must ensure that there are no uncommitted changes when you synchronize. For more information, see Commit all changes before synchronizing.

Synchronization parameters

Synchronization specifics are controlled through a set of synchronization parameters. For information on these parameters, see Network protocol options for UltraLite synchronization clients.

Initializing the synchronization parameters
Setting synchronization parameters
Invoking synchronization
Using transport-layer security
Commit all changes before synchronizing
Adding initial data to your application
Monitoring and canceling synchronization


Initializing the synchronization parameters

The synchronization parameters are stored in a Java object. The details of any synchronization, including the URL of the MobiLink synchronization server, the script version to use, the MobiLink user name, and so on, are all held in a UlSynchOptions object.

For a complete list of synchronization parameters, see Synchronization parameters.

toggle To initialize the synchronization parameters

  1. Create a UlSynchOptions object. For example:

    UlSynchOptions opts = new UlSynchOptions();

  2. Set the required parameters.

    The UlSynchOptions() object has a set of methods to set and get its fields. For a list, see Synchronization parameters. Use these methods to set the required synchronization parameters before synchronizing. For example:

    opts.setUserName( "50" );
opts.setScriptVersion( "default" );
opts.setStream( new UlSocketStream() );


Setting synchronization parameters

The synchronization streams for UltraLite Java applications are objects, and are set by their constructors. The available streams are as follows:

  • UlSocketStream TCP/IP synchronization

  • UlSecureSocketStream TCP/IP synchronization with Certicom elliptic-curve transport-layer security.

  • UlSecureRSASocketStream TCP/IP synchronization with Certicom RSA transport-layer security.

  • UlHTTPStream HTTP synchronization.

  • UlHTTPSStream HTTPS synchronization.

The following line sets the stream to TCP/IP:

synch_opts.setStream( new UlSocketStream() );

For more information, see Synchronization parameters.

Separately-licensable option required
Use of UlHTTPSStream, UlSecureSocketStream and UlSecureRSASocketStream require Certicom technology, which in turn requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations. For more information on this option, see Welcome to SQL Anywhere Studio.

For information on the individual parameters, see Network protocol options for UltraLite synchronization clients.

Once you have initialized the synchronization parameters, and set them to the values needed for your application, you can initiate synchronization using the JdbcConnection.synchronize() method.

The method takes a UlSynchOptions object as argument. The set of calls needed to synchronize is as follows:

UlSynchOptions opts = new UlSynchOptions();
opts.setUserName( "50" );
opts.setScriptVersion( "default" );
opts.setStream( new UlSocketStream() );
opts.setStreamParms( "host=123.45.678.90" );
conn.synchronize( opts );


Invoking synchronization

The details of how to invoke synchronization depends on your target platform and on the synchronization stream.

The synchronization process can only work if the device running the UltraLite application is able to communicate with the synchronization server. For some platforms, this means that the device needs to be physically connected by placing it in its cradle or by attaching it to a server computer using a cable. You need to add error handling code to your application in case the synchronization cannot be carried out.

toggle To invoke synchronization (TCP/IP, HTTP, or HTTPS streams)

  • Construct a new ULSynchInfo object to initialize the synchronization parameters, and JdbcConnection.synchronize() to synchronize. See Adding synchronization to your application.

The synchronization call requires a structure that holds a set of parameters describing the specifics of the synchronization. The particular parameters used depend on the stream.


Using transport-layer security

For additional security during synchronization, you can use transport-layer security encrypt messages as they pass between UltraLite application and the consolidated database.

For information about encryption technology, see MobiLink Transport-Layer Security.

Transport-layer security from UltraLite Java client applications uses a separate synchronization stream. You must set up your MobiLink synchronization server as well as your UltraLite client to use this synchronization stream.

Client changes

At the client, you need to choose the UlSecureSocketStream or UlSecureRSASocketStream synchronization stream, and supply a set of stream parameters. The stream parameters include parameters that control security.

Set the parameter as follows:

UlSynchOptions opts = new UlSynchOptions();
opts.setStream(new UlSecureSocketStream() );
opts.setStreamParms( "host=myserver;"
   + "port=2439;"
   + "certificate_company=Sybase Inc.;"
   + "certificate_unit="MEC;"
   + "certificate_name=Mobilink");
// set other options here
conn.synchronize( opts );

For details on the stream parameters, see UlSecureSocketStream synchronization parameters.

Setting up the MobiLink server

As the secure synchronization streams for Java applications are separate streams, you must ensure that the MobiLink synchronization server is listening for it. To do this, you must supply the java_certicom_tls or java_rsa_tls synchronization streams, to match your choice on the client.

The following command line is an example:

dbmlsrv9 -x java_certicom_tls(certificate=mycertificate.crt;port=1234)

The security parameters for the java_certicom_tls and java_rsa_tls streams are as follows:

  • certificate The name of the certificate file that contains the server's identity. This file needs to include the server's certificate, the certificates of all the certificate authorities in the certificate signing chain, and the server's private key.

    The certificate parameter defaults to sample.crt for java_certicom_tls and rsaserver.crt for java_rsa_tls, which is the default identity for MobiLink. These files are distributed with SQL Anywhere Studio, in the same directory as the MobiLink server.

  • certificate_password The password used to encrypt the private key in the certificate file.

    The default is the password for the private key in sample.crt and rsaserver.crt, which is test.


Monitoring and canceling synchronization

This section describes how to monitor and cancel synchronization from UltraLite applications.

  • An API for monitoring synchronization progress and for canceling synchronization.

  • A progress indicator component that implements the interface, which you can add to your application.

Monitoring synchronization

To monitor synchronization, write a class that implements the UlSynchObserver interface. This interface contains a single method:

void updateSynchronizationStatus( UlSynchStatus status )

  • Register your UlSynchObserver object using the UlSynchOptions class.

  • Call the synchronize() method to synchronize.

  • UltraLite calls the updateSynchronizationStatus method of your observer class whenever the synchronization state changes. The following section describes the synchronization state.

Here is a typical sequence of instructions for synchronization. In this example, the class MyObserver implements the UlSynchObserver interface:

UlSynchObserver observer = new MyObserver ();
UlSynchOptions opts = new UlSynchOptions();
// set options
opts.setUserName( "mluser" );
opts.setPassword( "mlpwd" );
opts.setStream( new UlSocketStream() );
opts.setStreamParms( "localhost" );
opts.setObserver( observer );
opts.setUserData( myDataObject );
// synchronize
conn.synchronize( opts );


Handling synchronization status information

The class that implements UlSynchObserver, the UlSynchStatus object holds synchronization status information. This object is filled by UltraLite with synchronization status information each time your updateSynchronizationStatus method is called.

The UlSynchStatus object has the following methods:

int getState()
int getTableCount()
int getTableIndex()
Object getUserData()
UlSynchOptions getSynchOptions()
UlSqlStmt getStatement()
int getErrorCode()
boolean isOKToContinue()
void cancelSynchronization()

  • getState One of the following states:

    • STARTING No synchronization actions have yet been taken.

    • CONNECTING The synchronization stream has been built, but not yet opened.

    • SENDING_HEADER The synchronization stream has been opened, and the header is about to be sent.

    • SENDING_TABLE A table is being sent.

    • SENDING_DATA Schema information or data is being sent.

    • FINISHING_UPLOAD The upload stage is completed and a commit is being carried out.

    • RECEIVING_UPLOAD_ACK An acknowledgement that the upload is complete is being received.

    • RECEIVING_TABLE A table is being received.

    • SENDING_DATA Schema information or data is being received.

    • COMMITTING_DOWNLOAD The download stage is completed and a commit is being carried out.

    • SENDING_DOWNLOAD_ACK An acknowledgement that download is complete is being sent.

    • DISCONNECTING The synchronization stream is about to be closed.

    • DONE Synchronization has completed successfully.

    • ERROR Synchronization has completed, but with an error.

      For a description of the synchronization process, see The synchronization process.

  • getTableCount Returns the number of tables being synchronized. For each table there is a sending and receiving phase, so this number may be more than the number of tables being synchronized.

  • getTableIndex The current table which is being uploaded or downloaded, starting at 0. This number may skip values when not all tables are being synchronized.

  • getSynchOptions Returns the UlSynchOptions object.

  • sent.inserts The number of inserted rows that have been uploaded so far.

  • sent.updates The number of updated rows that have been uploaded so far.

  • sent.deletes The number of deleted rows that have been uploaded so far.

  • sent.bytes The number of bytes that have been uploaded so far.

  • received.inserts The number of inserted rows that have been downloaded so far.

  • received.updates The number of updated rows that have been downloaded so far.

  • received.deletes The number of deleted rows that have been downloaded so far.

  • received.bytes The number of bytes that have been downloaded so far.

  • cancelSynchronization Set this member to true to interrupt the synchronization. The SQL exception SQLE_INTERRUPTED is set, and the synchronization stops as if a communications error had occurred. The observer is always called with either the DONE or ERROR state so that it can do proper cleanup.

  • getUserData Returns the user data object.

  • getStatement Returns the statement that called the synchronization. The statement is an internal UltraLite statement, and this method is unlikely to be of practical use, but is included for completion.

  • getErrorCode When the synchronization state is set to ERROR, this method returns a diagnostic error code.

  • isOKToContinue This is set to false when cancelSynchronization is called. Otherwise, it is true.

Example

The following code illustrates a very simple observer function:

void updateSynchronizationStatus( UlSynchStatus status )
{
    int state = status.getState();
    System.out.println( "Sync status: " + state );
    if( state == UlSynchStatus.SENDING_TABLE ||
       state == UlSynchStatus.RECEIVING_TABLE ){
          System.out.println( "send/receive table " +
          ( status.getTableIndex() + 1 ) +
            " of " + status.getTableCount() );
    }
}
CustDB example

An example of an observer function is included in the CustDB sample application. The implementation in CustDB provides a dialog that displays synchronization progress and allows the user to cancel synchronization. The user-interface component makes the observer function platform specific.

The CustDB sample code is in the Samples\UltraLite\CustDB subdirectory of your SQL Anywhere directory. The observer function is contained in the platform-specific subdirectories of the CustDB directory.


Using the progress viewer

The UltraLite runtime library includes two progress viewer classes, which provide an implementation of synchronization monitoring, together with the ability for end users to cancel synchronization. The progress viewer classes are as follows:

  • ianywhere.ultralite.ui.SynchProgressViewer A heavyweight AWT version.

  • ianywhere.ultralite.ui.JSynchProgressViewer A Swing version of the viewer that respects the Swing threading model.

The two classes are used identically. The viewer displays a modal or modeless dialog, which shows a series of messages and a progress bar. Both the messages and the bar are updated during synchronization. The viewer also provides a Cancel button. If the user clicks the Cancel button, synchronization stops and the SQL exception SQLE_INTERRUPTED is thrown.

Threading issues

In a Java application, all events occur on a single thread called the event thread. Also, all user interface objects are created on the event thread, even if the application is on a different thread at the time. There is only one event thread in an application.

The event thread must never block. Consequently, you should not perform long operations on the event thread, as this leads to painting aberrations. Even calling the show() method on a modal dialog suspends execution of the event thread. You must therefore avoid calling the synchronize() method on the event thread.

Displaying a modal viewer

The following code snippet illustrates how to invoke a modal instance of the viewer. The import statement uses the AWT version:

import ianywhere.ultralite.ui.SynchProgressViewer;
// create a frame to display a dialog
java.awt.Frame frame = ...;
// get UltraLite connection
Connection conn = ...;
// set synchronization options
UlSynchOptions options = new UlSynchOptions();
options.setUserName( "my_user" );
...
// create the viewer
SynchProgressViewer viewer = new SynchProgressViewer( frame );
viewer.synchronize( frame, options );
// execution stops here until synchronization is complete

When invoked in this manner, the viewer carries out the following operations:

  1. registers itself as a synchronization observer,

  2. spawns a thread to do the synchronization,

  3. displays itself, blocking the current thread.

  4. When synchronization finishes, the observer callback disposes of the dialog, which lets the thread continue.

Displaying a modeless viewer

The following code snippet illustrates how to invoke a modeless instance of the viewer:

SynchProgressViewer viewer = new SynchProgressViewer( frame, false );
options.setObserver( viewer );
conn.synchronize( options );

In this case, you must ensure that the synchronization occurs on a thread other than the event thread, so that the viewer is not blocked.

Notes

  • All messages come from the SynchProgressViewerResources resource bundle.

  • The viewer implements the UlSynchObserver interface so it can hook into the synchronization process.

  • The CustDB sample application includes a progress viewer. The CustDB sample code is in the UltraLite\samples\CustDB\java subdirectory of your SQL Anywhere directory.


UltraLite Static Java development notes

This section provides notes for development of UltraLite Static Java applications.

Creating UltraLite Static Java applets


Creating UltraLite Static Java applets

If you create your JDBC program as an applet, your application can only synchronize with the machine from which the applet is loaded, which is usually the same as the HTML.

Including an applet in an HTML page

The following is a sample HTML page used to create an UltraLite applet:

<html>
   <head>
   </head>
   <body bgcolor="FFFF00">
      <applet code="CustDbApplet.class" width=440
          height=188
          archive="custdb.zip,ulrt.jar" >
      </applet>
   </body>
</html>

The applet tag specifies the following:

  • The class that the applet starts:

    code="CustDbApplet.class"

  • The size of the window in the web browser to display the applet to.

    width=440 height=188

  • The zip files that are necessary in order to run the applet.

    archive="custdb.zip,ulrt.jar"

    In this case, the custdb.zip file and the UltraLite runtime zip file are necessary in order to run the UltraLite CustDB sample application.


Building UltraLite Static Java applications

This section covers the following subjects:

  • Generating UltraLite Static Java classes

  • Compiling UltraLite Static Java applications


Generating UltraLite Static Java classes

When you have prepared a reference database, defined an UltraLite project for your application, and added SQL statements to define your data access features, all the information the generator needs is inside your reference database.

For general information on the UltraLite generator, see Generating the UltraLite data access code. For command-line options, see The UltraLite Generator.

The generator output is a Java source file with a filename of your choice. Depending on the design of your database and the sophistication of the database functionality your application requires, this file can vary greatly in both size and content.

There are several ways to customize the UltraLite generator output, depending on the nature of your application.

Overview

You generate the classes by running the UltraLite generator against the reference database.

toggle To run the UltraLite generator

  • Enter the following command at a command-prompt:

    ulgen –c "connection-string" options

    where options depend on the specifics of your project.

Common command-line combinations

When you are generating Java code, there are several options you may want to specify:

  • -t java Generate Java code. The generator is the same tool used for C/C++ development, so this option is required for all Java use.

  • -i Some Java compilers do not support inner classes correctly, and so the default behavior of the generator is not to generate Java code that includes inner classes. If you wish to take advantage of a compiler that does support inner classes, use this option.

  • -p It is common to include your generated classes in a package, which may include other classes from your application. You can use this switch to instruct the generator to include a package name for the classes in the generated files

  • -s In addition to the code for executing the SQL statements, generate the SQL statements themselves as an interface. Without this option, the strings are written out as members of the database class itself.

  • -a Make SQL string names upper case. If you choose the –a option, the identifier used in the generated file to represent each SQL statement is derived from the name you gave the statement when you added it to the database. It is a common convention in Java to use upper case letters to represent constants. As the SQL string names are constants in your Java code, you should use this option to generate string identifiers that conform to the common convention.

Example

  • The following command (which should be all on one line) generates code that represents the SQL statements in the CustDemo project, and the required database schema, with output in the file uldemo.java.

    ulgen -c "dsn=Ultralite 9.0 Sample;uid=DBA;pwd=SQL"
–a -t java -s IStatements CustDemo uldemo.java


Compiling UltraLite Static Java applications

toggle To compile the generated file

  1. Set your classpath

    When you compile your UltraLite Static Java application, the Java compiler must have access to the following classes:

    • The Java runtime classes.

    • The UltraLite runtime classes

    • The target classes (usually in the current directory).

    The following classpath gives access to these classes.

    %JAVA_HOME%\jre\lib\rt.jar;%ASANY9%\ultralite\java\lib\ulrt.jar;.

    where JAVA_HOME represents your Java installation directory, and ASANY9 represents your SQL Anywhere installation directory.

    For JDK 1.1 development, ulrt.jar is in a jdk11\lib subdirectory of the UltraLite\java directory.

  2. Compile the classes.

    With the classpath set as in step one, use javac and enter the following command (on a single line):

    javac file.java

    The compiler creates the class files for file.java.

The compilation step produces a number of class files. You must include all the generated .class files in your deployment.


Deploying Java applications

Your UltraLite application consists of the following:

  • Class files you created to implement your application.

  • Generated class files.

  • The Java core classes (rt.jar).

  • UltraLite runtime JAR file (ulrt.jar).

Your UltraLite application can be deployed in whatever manner is appropriate. You may wish to package together these class files in a JAR file, for ease of deployment.

Your UltraLite application automatically initializes its own database the first time it is invoked. At first, your database will contain no data. You can add data explicitly using INSERT statements in your application, or you can import data from a consolidated database through synchronization. Explicit INSERT statements are especially useful when developing prototypes.


UltraLite Static Java API Reference

About this chapter

This chapter describes the Static Java API for UltraLite.

Only those parts that differ from JDBC are explicitly documented.

UltraLite API reference


UltraLite API reference

This section describes extensions to the JDBC interface provided by UltraLite, and also describes JDBC features unsupported in UltraLite.

JDBC features in UltraLite
Unsupported JDBC methods
Class JdbcConnection
Class JdbcDatabase
The generated database class
Class JdbcDefragIterator
Class JdbcSupport


JDBC features in UltraLite

The following are features and limitations specific to the development of JDBC UltraLite applications.

The UltraLite Static Java API is modeled on JDBC 1.2, with the addition of the following ResultSet methods from JDBC 2.0:

  • absolute( ),

  • afterLast( ),

  • beforeFirst( ),

  • first( ),

  • isAfterLast( ),

  • isBeforeFirst( ),

  • isFirst( ),

  • isLast( ),

  • last( ),

  • previous( ),

  • relative( )

The following features are incompatible with the UltraLite development model and are not supported by UltraLite.

  • There is only limited support for metadata access (system table access). Therefore, you cannot use the DatabaseMetaData Interface. Metadata access is limited to the number and type of columns.

  • Java objects cannot be stored in the database

  • There is no support for stored procedures or stored functions.

  • Only static SQL statements are supported and they must be added to the database so that the UltraLite generator can generate them.


Unsupported JDBC methods

UltraLite does not support the following JDBC 1.2 methods. An attempt to use any of the following methods results in a SQLException with a vendor code indicating that the feature is not supported in UltraLite.

Connection interface

  • getCatalog

  • getMetaData

  • getTransactionIsolation

  • setCatalog

  • setTransactionIsolation

ResultSet interface

  • getMetaData

Statement interface

  • cancel

  • getMaxFieldSize

  • getMaxRows

  • setMaxFieldSize

  • setMaxRows


Class JdbcConnection

Package

ianywhere.ultralite.jdbc

Description

Represents an UltraLite database connection. Most methods are inherited from the JDBC Connection class. Unsupported methods throw an unsupported feature exception.

countUploadRows method
getDatabaseID method
getDefragIterator method
getLastDownloadTimeDate method
getLastDownloadTimeLong method
getLastIdentity method
globalAutoincUsage method
grant method
revoke method
setDatabaseID method
synchronize method
startSynchronizationDelete method
stopSynchronizationDelete method


countUploadRows method
Prototype

long countUploadRows( int mask, long threshold )

Description

Returns the number of rows that need to be uploaded when the next synchronization takes place.

You can use this function to determine if a synchronization is needed.

Parameters

mask A set of publications to check. A value of 0 corresponds to the entire database. The set is supplied as a mask. For example, the following mask corresponds to publications PUB1 and PUB2:

UL_PUB_PUB1 | UL_PUB_PUB2

For more information on publication masks, see publication synchronization parameter.

threshold A value that determines the maximum number of rows to count, and so limits the amount of time taken by the call. A value of 0 corresponds to no limit. A value of 1 determines if any rows need to be synchronized.

Returns

The number of rows to be uploaded.

Throws

java.sql.SQLException


getDatabaseID method
Prototype

public int getDatabaseID( ) throws SQLException

Description

getDatabaseID() returns the current database ID used for global autoincrement. It returns the value set by the last call to setDatabaseID or -1 if the ID was never set.


getDefragIterator method
Prototype

JdbcDefragIterator getDefragIterator( )

Description

Initializes and returns a defragmentation iterator.

Parameters

user_name The MobiLink user name. See user_name synchronization parameter.

password The password associated with user_name. See password synchronization parameter.

script_version The script version. See version synchronization parameter.

stream_defn The stream to use for synchronization. See stream synchronization parameter.

parms Any user-supplied parameters used for the synchronization.

See stream_parms synchronization parameter.

Returns

The defragmentation iterator.

Throws

java.sql.SQLException

See also

Defragmenting UltraLite databases


getLastDownloadTimeDate method
Prototype

java.util.Date getLastDownloadTimeDate( int mask )

Description

Returns the last time changes to the result set of a given statement were downloaded.

Parameters

mask A set of publications for which the last download time is retrieved. A value of 0 corresponds to the entire database. The set is supplied as a mask. For example, the following mask corresponds to publications PUB1 and PUB2:

UL_PUB_PUB1 | UL_PUB_PUB2

For more information on publication masks, see publication synchronization parameter.

Returns

  • The last time the statement was downloaded.


getLastDownloadTimeLong method
Prototype

long getLastDownloadTimeLong( int mask )

Description

Returns the last time changes to the result set of a given statement were downloaded.

Parameters

mask A set of publications for which the last download time is retrieved. A value of 0 corresponds to the entire database. The set is supplied as a mask. For example, the following mask corresponds to publications PUB1 and PUB2:

UL_PUB_PUB1 | UL_PUB_PUB2

For more information on publication masks, see publication synchronization parameter.

Returns

  • The last time the statement was downloaded.


getLastIdentity method
Prototype

long getLastIdentity( )

Description

Returns the most recent identity value used. This function is equivalent to the following SQL statement:

SELECT @@identity

The function is particularly useful in the context of global autoincrement columns.

Returns

The last identity value.

See also

Determining the most recently assigned value

Setting the global database identifier


globalAutoincUsage method
Prototype

short globalAutoincUsage( )

Description

Returns the maximum global autoincrement counter percentage of all tables in the database. The value is useful when deciding whether to set a database ID.

Returns

The percentage of global autoincrement values that have been used.

Throws

java.sql.SQLException

See also

Declaring default global autoincrement columns

setDatabaseID method


grant method
Prototype

void grant( String user, String password )

Description

Grants a user name and password permission to connect to an UltraLite database. To take effect, this method requires that user authentication has been enabled with JdbcSupport.enableUserAuthentication.

The grant method is supplied on JdbcConnection for applications that do not have an explicit JdbcDatabase object.

Parameters

user A string that must be entered as a user name when connecting.

password A string that must be entered as a password when connecting.

Returns

void.

Throws

java.sql.SQLException


revoke method
Prototype

void revoke( String user )

Description

Revokes permission to connect to an UltraLite database from a user name. To take effect, this method requires that user authentication has been enabled with JdbcSupport.enableUserAuthentication.

The grant method is supplied on JdbcConnection for applications that do not have an explicit JdbcDatabase object.

Parameters

user The user name that can no longer connect to the database.

Returns

void.

Throws

java.sql.SQLException


setDatabaseID method
Prototype

void setDatabaseID( int value )

Description

Sets the database ID.

Parameters

value The integer value to use as the global database identifier.

Throws

java.sql.SQLException

See also

globalAutoincUsage method


synchronize method
Prototype

void synchronize(
java.lang.String user_name,
java.lang.String password,
java.lang.String script_version,
UlStream stream_defn,
java.lang.String parms )

void synchronize(
ianywhere.ultralite.runtime UlSynchOptions opts
)

Description

Synchronizes data with a MobiLink synchronization server.

Parameters

user_name The MobiLink user name. See user_name synchronization parameter.

password The password associated with user_name. See password synchronization parameter.

script_version The script version. See version synchronization parameter.

stream_defn The stream to use for synchronization. See stream synchronization parameter.

parms Any user-supplied parameters used for the synchronization.

See stream_parms synchronization parameter.

opts A ULSynchOptions object. See Synchronization parameters.

Throws

java.sql.SQLException


startSynchronizationDelete method
Prototype

void startSynchronizationDelete( )

Description

Restart logging of deletes for MobiLink synchronization

Throws

java.sql.SQLException

See also

START SYNCHRONIZATION DELETE statement [MobiLink]


stopSynchronizationDelete method
Prototype

void stopSynchronizationDelete( )

Description

Prevent logging of deletes for MobiLink synchronization.

Throws

java.sql.SQLException

See also

STOP SYNCHRONIZATION DELETE statement [MobiLink]


Class JdbcDatabase

Package

ianywhere.ultralite.jdbc

Description

The JdbcDatabase is used directly only for obfuscating databases. The generated database class extends JdbcDatabase and provides an object that represents the UltraLite database. Most JdbcDatabase methods are used from the generated database class.

For more information, see The generated database class.


changeEncryptionKey method
Prototype

Connection changeEncryptionKey( )

Description

Changes the encryption key for an UltraLite database.

Returns

A JDBC Connection object.

Throws

java.sql.SQLException

See also

Encrypting UltraLite databases


close method
Prototype

void close( )

Description

Closes all connections to an UltraLite database. This method must be executed before an UltraLite database can be deleted.

Returns

void

Throws

java.sql.SQLException


connect method
Prototype

Connection connect( )

Connection connect( String user, String password )

Connection connect( String user, String password, Properties info )

Description

Connects to an UltraLite database. The user name and password are checked only when user authentication has been enabled with JdbcSupport.enableUserAuthentication.

Parameters

user A user name that can connect to the database.

password A string that must be entered as a password when connecting.

info A Properties object holding the user name and password.

Returns

A JDBC Connection object.

Throws

java.sql.SQLException


drop method
Prototype

void drop( )

Description

Deletes an UltraLite database file. This method should be used with care, and can be executed only after the JdbcDatabase.close() method has been called.

Returns

void

Throws

java.sql.SQLException

See also

close method


grant method
Prototype

void grant( String user, String password )

Description

Grants a user name and password permission to connect to an UltraLite database. To take effect, this method requires that user authentication has been enabled with JdbcSupport.enableUserAuthentication.

Parameters

user A string that must be entered as a user name when connecting.

password A string that must be entered as a password when connecting.

Returns

void.

Throws

java.sql.SQLException


revoke method
Prototype

void revoke( String user )

Description

Revokes permission to connect to an UltraLite database from a user name. To take effect, this method requires that user authentication has been enabled with JdbcSupport.enableUserAuthentication.

Parameters

user The user name that can no longer connect to the database.

Returns

void.

Throws

java.sql.SQLException


Web Links Browse Collapse Expand PDF Previous Next

UltraLite Static Java User's Guide

UltraLite Static Java API Reference

UltraLite API reference

Class JdbcDatabase

setDefaultObfuscation method
Prototype

setDefaultObfuscation ( true | false )

Description

Obfuscates the database

See also

Obfuscating an UltraLite database


The generated database class

Description

The generated database class extends JdbcDatabase. It provides an object that represents the UltraLite database. JdbcDatabase methods are typically used on the generated database class.

Constructor

new database-name( Properties props )

where database-name is the name of the generated database class. You can specify the class name using the UltraLite generator -f command-line option.

For more information, see The UltraLite Generator.

Parameters

props A Properties object containing some or all of the following items:

  • persist

  • persistfile

  • key

For more information, see Using a Properties object to store connection information.


Class JdbcDefragIterator

Package

ianywhere.ultralite.jdbc

Description

Provides an object used for explicit defragmentation of the database store.

ulStoreDefragStep method


ulStoreDefragStep method
Prototype

boolean ulStoreDefragStep( UlConnection conn )

Description

Defragments a portion of an UltraLite database.

Parameters

conn The current connection, as a JdbcConnection object.

Returns

true if successful.

false in unsuccessful.

Throws

java.sql.SQLException

See also

STOP SYNCHRONIZATION DELETE statement [MobiLink]


Web Links Browse Collapse Expand PDF Previous Next

UltraLite Static Java User's Guide

UltraLite Static Java API Reference

UltraLite API reference

Class JdbcSupport

Package

ianywhere.ultralite.jdbc

Description

A static class that provides methods to enable UltraLite features.


enableUserAuthentication method
Prototype

void enableUserAuthentication( )

Description

Sets the UltraLite database so that user authentication is required to connect to it. Must be called before the database object is created.

Parameters

None.

Returns

Void.

Throws

java.sql.SQLException

See also

User authentication example


disableUserAuthentication method
Prototype

void disableUserAuthentication( )

Description

Sets the UltraLite database so that user authentication is not required to connect to it. Must be called before the database object is created.

Parameters

None.

Returns

Void.

Throws

java.sql.SQLException

See also

enableUserAuthentication method


Synchronization Parameters Reference

About this chapter

This chapter provides reference information about synchronization parameters.

Synchronization parameters
auth_parms parameter
auth_status parameter
auth_value synchronization parameter
download_only synchronization parameter
ignored_rows synchronization parameter
new_password synchronization parameter
num_auth_parms parameter
observer synchronization parameter
password synchronization parameter
ping synchronization parameter
publication synchronization parameter
security synchronization parameter
security_parms synchronization parameter
stream synchronization parameter
stream_parms synchronization parameter
upload_ok synchronization parameter
upload_only synchronization parameter
user_data synchronization parameter
user_name synchronization parameter
version synchronization parameter


Synchronization parameters

The synchronization parameters are fields of the ianywhere.ultralite.runtime.UlSynchOptions object. The fields are private, and methods are provided to get and set their values. The UlSynchOptions object is provided as an argument in the call to ianywhere.ultralite.jdbc.JdbcConnection.synchronize.

Field | Access methods | See
auth_status | getAuthStatus setAuthStatus | auth_status parameter
auth_value | getAuthValue getAuthValue | auth_value synchronization parameter
download_only | getDownloadOnly setDownloadOnly | download_only synchronization parameter
ignored_rows | getIgnoredRows setIgnoredRows | ignored_rows synchronization parameter
new_password | getNewPassword setNewPassword | new_password synchronization parameter
observer | getObserver setObserver | observer synchronization parameter
password | getPassword setPassword | password synchronization parameter
ping | getPing setPing | ping synchronization parameter
publications | getSynchPublication setSynchPublication | publication synchronization parameter
stream | getStream setStream | stream synchronization parameter
stream_parms | getStreamParms setStreamParms | stream_parms synchronization parameter
upload_ok | getUploadOK setUploadOK | upload_ok synchronization parameter
upload_only | getUploadOnly setUploadOnly | upload_only synchronization parameter
user_data | getUserData setUserData | user_data synchronization parameter
user_name | getUserName setUserName | user_name synchronization parameter
version | getScriptVersion setScriptVersion | version synchronization parameter

For a description of the role of each synchronization parameter, see Synchronization parameters.


auth_parms parameter

Function

Provides parameters to a custom user authentication script.

Access method

String[ ] getAuthParms( )

void setAuthParms( String[ ] auth_parms )

Usage

Set the parameters as follows:

ul_char * Params[ 3 ] = { UL_TEXT( "parm1" ),
                          UL_TEXT( "parm2" ),
                          UL_TEXT( "parm3" ) };
// ...
info.num_auth_parms = 3;
info.auth_parms = Params;
params = new String[ num_params ];
// set params values
UlSynchOptions opts = new UlSynchOptions;
opts.setAuthParms( params );
opts.setAuthParmsNumber( num_params );
See also
  • Authentication Parameters synchronization parameter
  • num_auth_parms parameter
  • authenticate_parameters connection event
  • authenticate_user connection event


auth_status parameter

Function

Reports the status of MobiLink user authentication.

Access method

short getAuthStatus( )

void setAuthStatus( short auth_status )

Usage

Access the parameter as follows:

UlSynchOptions opts = new UlSynchOptions;
// set options here
conn.synchronize( opts );
returncode = opts.getAuthStatus();
Allowed values

After synchronization, the parameter must hold one of the following values. If a custom authenticate_user synchronization script at the consolidated database returns a different value, the value is interpreted according to the rules given in authenticate_user connection event.

Constant | Value | Description
UlDefnUL_AUTH_STATUS_UNKNOWN | 0 | Authorization status is unknown, possibly because the connection has not yet synchronized.
UlDefnUL_AUTH_STATUS_VALID | 1000 | User ID and password were valid at the time of synchronization.
UlDefnUL_AUTH_STATUS_VALID_BUT_EXPIRES_SOON | 2000 | User ID and password were valid at the time of synchronization but will expire soon.
UlDefnUL_AUTH_STATUS_EXPIRED | 3000 | Authorization failed: user ID or password have expired.
UlDefnUL_AUTH_STATUS_INVALID | 4000 | Authorization failed: bad user ID or password.
UlDefnUL_AUTH_STATUS_IN_USE | 5000 | Authorization failed: user ID is already in use.
See also
  • Authentication Status synchronization parameter
  • Authenticating MobiLink Users.


auth_value synchronization parameter

Function

Reports return values from custom user authentication synchronization scripts.

Access methods

long getAuthValue( )

void setAuthValue( long auth_value )

Default

The values set by the default MobiLink user authentication mechanism are described in authenticate_user connection event.

Usage

The parameter is read-only.

Access the parameter as follows:

UlSynchOptions opts = new UlSynchOptions;
// set other options here
conn.synchronize( opts );
returncode = opts.getAuthValue();
See also
  • Authentication Value synchronization parameter
  • authenticate_user connection event
  • authenticate_user_hashed connection event
  • auth_status parameter


download_only synchronization parameter

Function

Do not upload any changes from the UltraLite database during this synchronization.

Access methods

boolean getDownloadOnly( )

void setDownloadOnly( boolean download_only )

Default

The parameter is an optional Boolean value, and by default is false.

Usage

Set the parameter as follows:

UlSynchOptions opts = new UlSynchOptions;
opts.setDownloadOnly( true );
 // set other options here
conn.synchronize( opts );
See also
  • Download Only synchronization parameter
  • Including read-only tables in an UltraLite database.
  • upload_only synchronization parameter


ignored_rows synchronization parameter

Function

Reports if any rows were ignored by the MobiLink synchronization server during synchronization because of absent scripts.

The parameter is read-only.

Access methods

boolean getIgnoredRows( )

void setIgnoredRows( boolean ignored_rows )


new_password synchronization parameter

Function

Sets a new MobiLink password associated with the user name.

Access methods

java.lang.String getNewPassword( )

void setNewPassword( java.lang.String new_password )

Default

There is no default.

Usage

Set the parameter as follows:

UlSynchOptions opts = new UlSynchOptions;
opts.setUserName( "50" );
opts.setPassword( "mypassword" );
opts.setNewPassword( "mynewpassword" );
// set other options here
conn.synchronize( opts );
See also
  • New Password synchronization parameter
  • Authenticating MobiLink Users.


num_auth_parms parameter

Function

The number of authentication parameter strings passed to a custom authentication script.

Access methods

byte getAuthParmsNumber( )

void setAuthParmsNumber( byte value )

Default

No parameters passed to a custom authentication script.

Usage

The parameter is used together with auth_parms to supply information to custom authentication scripts.

For more information, see auth_parms parameter.

See also
  • Number of Authentication Parameters parameter
  • auth_parms parameter
  • authenticate_parameters connection event
  • authenticate_user connection event


observer synchronization parameter

Function

A pointer to a callback function that monitors synchronization.

Access methods

ianywhere.ultralite.runtime.UlSynchObserver getObserver( )

void setObserver( ianywhere.ultralite.runtime.UlSynchObserver observer )

See also
  • Observer synchronization parameter
  • Monitoring and canceling synchronization
  • user_data synchronization parameter


password synchronization parameter

Function

A string specifying the MobiLink password associated with the user_name. This user name and password are separate from any database user ID and password, and serves to identify and authenticate the application to the MobiLink synchronization server.

Access methods

java.lang.String getPassword( )

void setPassword( java.lang.String password )

Default

There is no default.

Usage

Set the parameter as follows:

UlSynchOptions opts = new UlSynchOptions;
opts.setUserName( "50" );
opts.setPassword( "mypassword" );
// set other options here
conn.synchronize( opts );
See also
  • Password synchronization parameter
  • Authenticating MobiLink Users.


ping synchronization parameter

Function

Confirm communications between the UltraLite client and the MobiLink synchronization server. When this parameter is set to true, no synchronization takes place.

When the MobiLink synchronization server receives a ping request, it connects to the consolidated database, authenticates the user, and then sends the authenticating user status and value back to the client.

If the ping succeeds, the MobiLink server issues an information message. If the ping does not succeed, it issues an error message.

If the MobiLink user name cannot be found in the ml_user system table and the MobiLink server is running with the command line option -zu+, the MobiLink server adds the user to ml_user.

The MobiLink synchronization server may execute the following scripts, if they exist, for a ping request:

  • begin_connection

  • authenticate_user

  • authenticate_user_hashed

  • end_connection

Access methods

boolean getPing( )

void setPing( boolean ping )

Default

The parameter is an optional Boolean value, and by default is false.

Usage

Set the parameter as follows:

UlSynchOptions opts = new UlSynchOptions;
opts.setUserName( "50" );
opts.setPing( true );
// set other options here
conn.synchronize( opts );
See also
  • Ping synchronization parameter
  • -pi option


publication synchronization parameter

Function

Specifies the publications to be synchronized.

Access methods

int getSynchPublication( )

void setSynchPublication( int publication )

Default

If you do not specify a publication, all data is synchronized.

Usage

The UltraLite generator identifies the publications specified on the ulgen -v command line option as upper case constants with the name UL_PUB_pubname, where pubname is the name given to the -v option.

For example, the following command line generates a publication identified by the constant sales:UL_PUB_SALES:

ulgen -v sales ...

When synchronizing, set the publication parameter to a publication mask: an OR'd list of publication constants. For example:

UlSynchOptions opts = new UlSynchOptions;
opts.setSynchPublication(
  projectname.UL_PUB_MYPUB1 |
  projectname.UL_PUB_MYPUB2 );
// set other options here
conn.synchronize( opts );

where projectname is the name of the main project class generated by the UtraLite generator.

The special publication mask UL_SYNC_ALL describes all the tables in the database, whether in a publication or not. The mask UL_SYNC_ALL_PUBS describes all tables in publications in the database.

See also
  • Publication synchronization parameter
  • The UltraLite Generator
  • Designing sets of data to synchronize separately


security synchronization parameter

Function

Set the UltraLite client to use Certicom encryption technology when exchanging messages with the MobiLink synchronization server.

Separately-licensable option required
Use of Certicom technology requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations. For more information on this option, see Welcome to SQL Anywhere Studio.
Access methods

This parameter is not used in Java.

To use secure synchronization from UltraLite Java applications, choose a separate stream. For more information, see Initializing the synchronization parameters.

See also
  • Security synchronization parameter
  • MobiLink Transport-Layer Security.


security_parms synchronization parameter

Function

Sets the parameters required when using transport-layer security. This parameter must be used together with the security parameter.

For more information, see security synchronization parameter.

Access methods

This parameter is not used in Java.

To use secure synchronization from UltraLite Java applications, choose a separate stream. For more information, see Initializing the synchronization parameters.

Usage

The ULSecureCerticomTLSStream() and ULSecureRSATLSStream() security parameters take a string composed of the following optional parameters, supplied in an semicolon-separated string.

  • certificate_company The UltraLite application only accepts server certificates when the organization field on the certificate matches this value. By default, this field is not checked.

  • certificate_unit The UltraLite application only accepts server certificates when the organization unit field on the certificate matches this value. By default, this field is not checked.

  • certificate_name The UltraLite application only accepts server certificates when the common name field on the certificate matches this value. By default, this field is not checked.

For example:

ul_synch_info info;
...
info.stream = ULSocketStream();
info.security = ULSecureCerticomTLSStream();
info.security_parms =
     UL_TEXT( "certificate_company=Sybase" )
     UL_TEXT( ";" )
     UL_TEXT( "certificate_unit=Sales" );

The security_parms parameter is a string, and by default is null.

If you use secure synchronization, you must also use the -r command-line option on the UltraLite generator. For more information, see The UltraLite Generator.

See also
  • Security Parameters synchronization parameter


stream synchronization parameter

Function

Set the MobiLink synchronization stream to use for synchronization.

For more information, see stream_parms synchronization parameter.

Access methods

ianywhere.ultralite.runtime.UlStream getStream( )

void setStream( ianywhere.ultralite.runtime.UlStream stream )

Default

The parameter has no default value, and must be explicitly set.

Usage
UlSynchOptions opts = new UlSynchOptions;
opts.setStream(new UlSocketStream() );
opts.setStreamParms( "host=myserver;port=2439" );
// set other options here
conn.synchronize( opts );

When the type of stream requires a parameter, pass that parameter using the stream_parms parameter; otherwise, set the stream_parms parameter to null.

The following stream functions are available, but not all are available on all target platforms:

Stream Description

ActiveSync (not available for Static Java)

 ActiveSync synchronization (Windows CE only).

For a list of stream parameters, see ActiveSync protocol options.

UlHTTPStream()

 Synchronize via HTTP.

The HTTP stream uses TCP/IP as its underlying transport. UltraLite applications act as Web browsers and the MobiLink synchronization server acts as a Web server. UltraLite applications send POST requests to send data to the server and GET requests to read data from the server.

For a list of stream parameters, see HTTP protocol options.

UlHTTPSStream()

 Synchronize via the HTTPS synchronization stream.

The HTTPS stream uses SSL or TLS as its underlying protocol. It operates over Internet protocols (HTTP and TCP/IP).

The HTTPS stream requires the use of technology supplied by Certicom. Use of Certicom technology requires that you obtain the separately-licensable SQL Anywhere Studio security option and is subject to export regulations. For more information on this option, see Welcome to SQL Anywhere Studio.

For a list of stream parameters, see HTTPS protocol options.

UlSocketStream()

 Synchronize via TCP/IP.

For a list of stream parameters, see TCP/IP protocol options.
UlSecureSocketStream() TCP/IP or HTTP synchronization with transport-layer security using elliptic curve encryption.

For a list of stream parameters, see UlSecureSocketStream synchronization parameters.
UlSecureRSASocketStream() TCP/IP or HTTP synchronization with transport-layer security using RSA encryption.

For a list of stream parameters, see UlSecureRSASocketStream synchronization parameters..

For information on Java synchronization streams, see Initializing the synchronization parameters.

See also
  • Stream Type synchronization parameter


stream_parms synchronization parameter

Function

Sets network protocol options to configure the synchronization stream.

A semi-colon separated list of option assignments. Each assignment is of the form keyword=value, where the allowed sets of keywords depends on the synchronization stream.

For a list of available options for each stream, see the following sections:

  • HTTP protocol options

  • HTTPS protocol options

  • TCP/IP protocol options

  • UlSecureRSASocketStream synchronization parameters

Access methods

java.lang.String getStreamParms( )

void setStreamParms( java.lang.String stream_parms )

Default

The parameter is optional, is a string, and by default is null.

Usage

Set the parameter as follows:

UlSynchOptions synch_options = new UlSynchOptions();
synch_opts.setStream( new UlSocketStream() );
synch_opts.setStreamParms( "host=myserver;port=2439" );
See also
  • Stream Parameters synchronization parameter
  • Network protocol options for UltraLite synchronization clients.


upload_ok synchronization parameter

Function

Reports the status of MobiLink uploads. The MobiLink synchronization server provides this information to the client.

The parameter is read-only.

Access methods

boolean getUploadOK( )

void setUploadOK( boolean upload_ok )

Usage

After synchronization, the upload_ok parameter holds true if the upload was successful, and false otherwise.

Access the parameter as follows:

UlSynchOptions opts = new UlSynchOptions;
// set options here
conn.synchronize( opts );
returncode = opts.getUploadOK();
See also
  • Upload OK synchronization parameter


upload_only synchronization parameter

Function

Indicates that there should be no downloads in the current synchronization, which can save communication time, especially over slow communication links. When set to true, the client waits for the upload acknowledgement from the MobiLink synchronization server, after which it terminates the synchronization session successfully.

Access methods

boolean getUploadOnly( )

void setUploadOnly( boolean upload_only )

Default

The parameter is an optional Boolean value, and by default is false.

Usage

Set the parameter to true as follows:

UlSynchOptions opts = new UlSynchOptions;
opts.setUploadOnly( true );
See also
  • Upload Only synchronization parameter
  • Synchronizing high-priority changes
  • download_only synchronization parameter


user_data synchronization parameter

Function

Make application-specific information available to the synchronization observer.

Access methods

java.lang.Object getUserData( )

void setUserData( java.lang.Object user_data )

Usage

When implementing the synchronization observer interface UlSynchObserver, you may can make application-specific information to the synchronization observer class by providing an object in the setUserData method.

See also
  • User Data synchronization parameter
  • observer synchronization parameter


user_name synchronization parameter

Function

A string specifying the user name that uniquely identifies the MobiLink client to the MobiLink synchronization server. MobiLink uses this value to determine the download content, to record the synchronization state, and to recover from interruptions during synchronization.

Access methods

java.lang.String getUserName( )

void setUserName( java.lang.String user_name )

Default

The parameter is required, and is a string.

Usage

Set the parameter as follows:

UlSynchOptions synch_options = new UlSynchOptions();
synch_opts.setUserName( "mluser" );
See also
  • User Name synchronization parameter
  • Authenticating MobiLink Users.
  • MobiLink users.


version synchronization parameter

Function

Each synchronization script in the consolidated database is marked with a version string. For example, there may be two different download_cursor scripts, identified by different version strings. The version string allows an UltraLite application to choose from a set of synchronization scripts.

Access methods

java.lang.String getScriptVersion( )

void setScriptVersion( java.lang.String version )

Default

The parameter is a string, and by default is the MobiLink default version string.

Usage

Set the parameter as follows:

UlSynchOptions synch_options = new UlSynchOptions();
synch_opts.setVersion( "default" );
See also
  • Version synchronization parameter
  • Script versions.


Web Links Browse Collapse Expand PDF Previous Next

ASA SNMP Extension Agent User's Guide

Version 9.0.2

DC00192-01-0902-01

December 2004


About This Manual

Subject

This book covers material related to running and configuring the Adaptive Server Anywhere SNMP Extension Agent.

Audience

This manual is for Adaptive Server Anywhere users who wish to use the Adaptive Server Anywhere SNMP Extension Agent on Windows 2000, Windows XP, or Windows Server 2003 (32-bit versions). It is to be used in conjunction with other manuals in the documentation set.


Finding out more and providing feedback

We would like to receive your opinions, suggestions, and feedback on this documentation.

You can provide feedback on this documentation and on the software through newsgroups set up to discuss SQL Anywhere technologies. These newsgroups can be found on the forums.sybase.com news server.

The newsgroups include the following:

  • [external link] sybase.public.sqlanywhere.general

  • [external link] sybase.public.sqlanywhere.linux

  • [external link] sybase.public.sqlanywhere.mobilink

  • [external link] sybase.public.sqlanywhere.product_futures_discussion

  • [external link] sybase.public.sqlanywhere.replication

  • [external link] sybase.public.sqlanywhere.ultralite

  • [external link] sybase.public.sqlanywhere.qanywhere

Newsgroup disclaimer
iAnywhere Solutions has no obligation to provide solutions, information or ideas on its newsgroups, nor is iAnywhere Solutions obliged to provide anything other than a systems operator to monitor the service and insure its operation and availability.

iAnywhere Solutions Technical Advisors as well as other staff assist on the newsgroup service when they have time available. They offer their help on a volunteer basis and may not be available on a regular basis to provide solutions and information. Their ability to help is based on their workload.

You can e-mail comments and suggestions to the SQL Anywhere documentation team at [external link] iasdoc@ianywhere.com. Although we do not undertake to reply to e-mails at that address, you can be sure we will read your suggestions with interest.


The Adaptive Server Anywhere SNMP Extension Agent

About this chapter

This chapter introduces you to the Adaptive Server Anywhere SNMP Extension Agent.


Introduction to the Adaptive Server Anywhere SNMP Extension Agent

If you are running Adaptive Server Anywhere on Windows 2000, Windows XP, or Windows Server 2003 (32-bit versions), you can use the Adaptive Server Anywhere SNMP Extension Agent in conjunction with SNMP management applications to manage your Adaptive Server Anywhere databases. One agent can be used to monitor several different databases running on different database servers running on different machines.

Using the Adaptive Server Anywhere SNMP Extension Agent, you can do the following:

  • retrieve the value of all server and database statistics

  • retrieve the value of all server and database properties

  • retrieve the value of all PUBLIC database options

  • set the value for any PUBLIC database option

  • execute stored procedures

  • generate traps based on property or statistic values

Supplied files

The following files for the Adaptive Server Anywhere SNMP Extension Agent are included in your SQL Anywhere Studio installation:

  • dbsnmp9.dll The Adaptive Server Anywhere SNMP Extension Agent. This file is located in C:\Program Files\Sybase\SQL Anywhere 9\win32.

  • iAnywhere.mib The Adaptive Server Anywhere MIB contains all the OIDs for database server and database properties, statistics, and options that can be accessed using the Adaptive Server Anywhere SNMP Extension Agent.

  • RDBMS-MIB.mib The is a generic MIB for relational database management systems and contains OIDs that can be accessed using the Adaptive Server Anywhere SNMP Extension Agent.

  • SNMPv2-SMI.mib This MIB is referenced by the Adaptive Server Anywhere and RDBMS MIBs.

  • SNMPv2-TC.mib This MIB is referenced by the Adaptive Server Anywhere and RDBMS MIBs.

  • SYBASE-MIB.mib The Sybase MIB. This MIB is referenced by the Adaptive Server Anywhere MIB.

  • asasnmp.ini This file lists the databases that the Adaptive Server Anywhere SNMP Extension Agent monitors. By default, this file is located in C:\Program Files\Sybase\SQL Anywhere 9\win32.


Understanding SNMP

Simple Network Management Protocol (SNMP) is a standard protocol used for network management. SNMP allows managers and agents to communicate: managers send requests to agents, and agents respond to queries from managers. Additionally, agents can notify managers when specific events occur using notifications called traps.

SNMP agents handle requests to get and set the values of variables for managed objects. Each variable has a single value, and values are generally strings or integers, although they may also be other types.

Variables are kept in a global hierarchy, and each variable has a unique number under its parent. The full name of a variable (including all its parents) is called the Object Identifier (OID). All OIDs that are owned by Sybase begin with 1.3.6.1.4.1.897.

The list of OIDs that an agent supports, including their names, types, and other information are stored in a file called a Management Information Base (MIB).

A MIB is a database that stores network management information about managed objects. The MIB is separate from the Adaptive Server Anywhere database you are monitoring using the Adaptive Server Anywhere SNMP Extension Agent. The values of MIB objects can be changed or retrieved using SNMP. MIB objects are organized in a hierarchy with the most general information about the network located at the top level of the hierarchy. The Adaptive Server Anywhere SNMP Extension Agent supports the following MIBs:

  • Adaptive Server Anywhere MIB a MIB created specifically for the Adaptive Server Anywhere SNMP Extension Agent. All the OIDs in the Adaptive Server Anywhere MIB begin with 1.3.6.1.4.1.897.2. The Adaptive Server Anywhere MIB lists the OIDs for the statistics, properties, and option values that can be retrieved, and in some cases set, using the Adaptive Server Anywhere SNMP Extension Agent.

    For more information about the Adaptive Server Anywhere MIB, see The Adaptive Server Anywhere MIB.

  • RDBMS MIB a generic, vendor-independent MIB for relational databases. This MIB contains information about the database servers and databases in your system.

    For more information about the RDBMS MIB, see The RDBMS MIB.


The Adaptive Server Anywhere MIB

The Adaptive Server Anywhere MIB was created for the Adaptive Server Anywhere SNMP Extension Agent. It includes all database server statistics and properties, as well as all database statistics, properties, and options. The statistics and properties are all read-only (with a few exceptions), and the database options are all read-write.

By default, the Adaptive Server Anywhere MIB is located in C:\Program Files\Sybase\SQL Anywhere 9\snmp\iAnywhere.mib.

For information about the tables in the Adaptive Server Anywhere MIB, see Adaptive Server Anywhere MIB Reference.

For information about setting values in the Adaptive Server Anywhere MIB, see Setting values using the Adaptive Server Anywhere SNMP Extension Agent.

The following hierarchy describes the Adaptive Server Anywhere MIB:

OID | Name | Description
1.3.6.1.4.897.2.1.1.n.db | asaServer.asaSrvStat | Returns the value of server statistic n on database db.
1.3.6.1.4.897.2.1.2.n.db | asaServer.asaSrvProp | Returns the value of server property n on database db.
1.3.6.1.4.897.2.2.1.n.db | asaDb.asaDbStat | Returns the value of database statistic n on database db.
1.3.6.1.4.897.2.2.2.n.db | asaDb.asaDbProp | Returns the value of database property n on database db.
1.3.6.1.4.897.2.2.3.n.db | asaDb.asaDbOpt | Returns the value of database option n on database db.
1.3.6.1.4.897.2.3.1 | asaAgent.asaVersion | Returns the version of the Adaptive Server Anywhere Extension Agent.
1.3.6.1.4.897.2.3.2.db | asaAgent.asaDbConnStr | Returns the connection string for database db.
1.3.6.1.4.897.2.3.3.db | asaAgent.asaConnected | Returns whether the Adaptive Server Anywhere Extension Agent is connected to database db. Setting this value to 0 causes the Adaptive Server Anywhere Extension Agent to shut down the database1, while setting this value to 1 causes the Adaptive Server Anywhere Extension Agent to attempt to start the database2.
1.3.6.1.4.897.2.3.4.db | asaAgent.asaStarted | Returns whether database db is running. Setting this value to 0 causes the Adaptive Server Anywhere Extension Agent to shut down the database, while setting this value to 1 attempts to start the database.
1.3.6.1.4.897.2.3.5.db | asaAgent.asaProc | Setting this value to a string proc_name causes the Adaptive Server Anywhere Extension Agent to executed the procedure proc_name in the database. Arguments can be supplied (for example, proc_name('string', 4)); if no arguments are supplied, parentheses () are appended to the name. Getting the value returns "".
1.3.6.1.4.897.2.4 | asaMetaData | Several virtual tables; each row represents a variable supported by the Adaptive Server Anywhere MIB.

1 Note that when stopping a database by setting this variable, the stop is unconditional, meaning that the database will be stopped even if it has active connections.

2 In order to be able to start a database by setting this variable, the DBF parameter must be specified in the connection string (along with DBN if desired and DBKEY if required), and either (a) the UtilDbPwd field must be set in the asasnmp.ini file, or (b) the start database permission on the server (specified with the -gd server option) must be set to all.

asaMetaData tables

The Adaptive Server Anywhere MIB includes metadata tables that provide a way to query the Adaptive Server Anywhere Extension Agent to find out which variables are supported.

  • asaSrvMetaData.asaSrvStatMetaDataTable lists the database server statistics (variables under asa.asaServer.asaSrvStat.)

  • asaSrvMetaData.asaSrvpropMetaDataTable lists the database server properties (variables under asa.asaServer.asaSrv.Prop.)

  • asaDbMetaData.asaDbStatMetaDataTable lists the database statistics (variables under asa.asaDb.asaDbStat.)

  • asaDbMetaData.asaDbpropMetaDataTable lists the database properties (variables under asa.asaDb.asaDbProp.)

  • asaDbMetaData.asaDbOptMetaDataTable lists the database options (variables under asa.asaDb.asaDbOpt.)

For more information about the information stored in the Adaptive Server Anywhere MIB metadata tables, see asaMetaData tables.


The RDBMS MIB

The RDBMS MIB is a generic and vendor-independent MIB (RFC 1697) for relational database-management system products. The RDBMS MIB uses virtual tables to return information on the servers and databases. The base OID is 1.3.6.1.2.1.39, and there are 9 virtual tables in this MIB. The Adaptive Server Anywhere SNMP Extension Agent supports 8 of these virtual tables.

For descriptions of the supported tables contained in the RDBMS MIB, see RDBMS MIB Reference.

The Adaptive Server Anywhere Extension Agent provides read-only access to all of the supported variables in the RDBMS MIB. None of the variables in the RDBMS MIB are writable through the Adaptive Server Anywhere Extension Agent.

A virtual table contains a fixed number of attributes and any number for rows. Elements in the table are retrieved using GET requests by appending the column number and row number to the OID of the table. A 1 must be appended to the table OID, so the OID looks as follows:

table.1.colnum.rownum

By default, the RDBMS MIB is located in C:\Program Files\Sybase\SQL Anywhere 9\snmp\RDBMS-MIB.mib.


Using the Adaptive Server Anywhere SNMP Extension Agent

In order to use the Adaptive Server Anywhere SNMP Extension Agent, you must have SNMP installed on your machine and you must create an asasnmp.ini file that contains information about the databases that are monitored by the Adaptive Server Anywhere SNMP Extension Agent.

Installing SNMP
Configuring the Adaptive Server Anywhere SNMP Extension Agent
Obtaining values using the Adaptive Server Anywhere SNMP Extension Agent
Setting values using the Adaptive Server Anywhere SNMP Extension Agent
Executing stored procedures using the Adaptive Server Anywhere SNMP Extension Agent
Using traps


Installing SNMP

Before you can use the Adaptive Server Anywhere Extension Agent, you must install SNMP on your machine. By default, SNMP is not installed on Windows 2000 or Windows XP.

toggle To install SNMP

  1. Open the Control Panel.

    • On Windows 2000, from the Start menu choose Settings > Control Panel.

    • On Windows XP, from the Start menu choose Control Panel.

  2. Double-click Add/Remove Programs.

    The Add/Remove Programs dialog appears.

  3. In the left pane of the Add/Remove Programs dialog, click Add/Remove Windows Components.

    The Windows Components wizard appears.

  4. On the first page of the Windows Components wizard, double-click Management and Monitoring Tools.

    The Management and Monitoring Tools dialog appears.

  5. Select the Simple Network Management Protocol option and then click OK.

  6. Click Next.

  7. Click Finished when the installation completes.

  8. If you are prompted, reboot your computer.

Once you have installed SNMP on your machine, two services should be running on your machine: SNMP Service and SNMP Trap Service.

toggle To check that the SNMP services are installed on your computer

  1. Open the Control Panel.

    • On Windows 2000, from the Start menu choose Settings > Control Panel.

    • On Windows XP, from the Start menu choose Control Panel.

  2. In the Control Panel, double-click Administrative Tools.

  3. Double-click Services.

    The services SNMP Service and SNMP Trap Service appear in the list of local services.

If you installed SNMP before you installed SQL Anywhere Studio, you need to stop and restart the SNMP service so it will detect the Adaptive Server Anywhere SNMP Extension Agent. If you installed SQL Anywhere Studio and then installed SNMP, the SNMP service will detect the Adaptive Server Anywhere SNMP Extension Agent automatically.

toggle To restart the SNMP service (Control Panel)

  1. Open the Control Panel.

    • On Windows 2000, from the Start menu choose Settings > Control Panel.

    • On Windows XP, from the Start menu choose Control Panel.

  2. In the Control Panel, double-click Administrative Tools.

  3. Double-click Services.

  4. Right-click SNMP Service and choose Restart from the popup menu.

    This stops and restarts the SNMP service.

toggle To restart the SNMP service (Command line)

  1. Open a command prompt and execute the following command:

    net stop snmp

    This stops the SNMP service.

  2. Execute the following command:

    net start snmp

    This starts the SNMP service.


Configuring the Adaptive Server Anywhere SNMP Extension Agent

The Adaptive Server Anywhere Extension Agent can monitor one or more databases. The databases to be monitored are stored in the asasnmp.ini file with the following format:

[ASAAgent]
TrapPollTime=time in seconds

[DBn]
ConnStr=connection string
UtilDbPwd=utility database password
CacheTime=time in seconds
Trapt=trap information
Disabled=1 or 0

By default, your SQL Anywhere Studio installation places the asasnmp.ini file in the C:\Program Files\Sybase\SQL Anywhere 9\win32 directory.

Once you edit this file, you must restart the SNMP service or reset the Adaptive Server Anywhere SNMP Extension Agent so that the new settings are used by the Agent.

toggle To restart the SNMP service (Control Panel)

  1. Open the Control Panel.

    • On Windows 2000, from the Start menu choose Settings > Control Panel.

    • On Windows XP, from the Start menu choose Control Panel.

  2. In the Control Panel, double-click Administrative Tools.

  3. Double-click Services.

  4. Right-click SNMP Service and choose Restart from the popup menu.

    This stops and restarts the SNMP service.

toggle To restart the SNMP service (Command line)

  1. Open a command prompt and execute the following command:

    net stop snmp

    This stops the SNMP service.

  2. Execute the following command:

    net start snmp

    This starts the SNMP service.

toggle To restart the Adaptive Server Anywhere SNMP Extension Agent

  • Using your SNMP management tool, change the value of the asaAgent.asaRestart property, 1.3.6.1.4.1.897.2.3.6, to 1.

You can obfuscate the contents of the asasnmp.ini file with simple encryption using the File Hiding utility (dbfhide).

For more information, see Hiding the contents of .ini files.

The ASAAgent section

The ASAAgent section of the asasnmp.ini file contains a TrapPollTime field with information about the Adaptive Server Anywhere Extension Agent. If the TrapPollTime field is not required, you can omit the entire section.

TrapPollTime This value specifies the poll frequency for dynamic traps if they are specified. The Adaptive Server Anywhere SNMP Extension Agent polls the values every 5 seconds by default. Setting this value to 0 disables dynamic traps. This field is optional.

The DBn section

Each DBn section of the asasnmp.ini file describes a database, how to connect to it, and any dynamic traps that exist for the database. The fields in this section are case sensitive.

The value for n is a number that identifies the database. The numbers must start with 1, and numbers cannot be skipped. For example, if the asasnmp.ini file contained entries for [DB1], [DB2], and [DB4], the [DB4] entry would be ignored because the file is missing the entry for [DB3].

ConnStr The connection string used to connect to the database. You must supply enough information to be able to connect to the database. This field is required.

  • If you want to use an ODBC data source to connect to the database, it must be a system data source, not a user data source.

  • If you want to use an integrated login, you must map to the SYSTEM account because the SNMP Agent runs as a service. However, this means that anything that runs as a service can then connect to the database without a password. Alternatively, you can change the account that the service runs under and then create an integrated login for that account.

  • The string ASTART=NO;IDLE=0;CON=SNMP;ASTOP=NO is prepended to the connection string. This string does the following:

    • prevents the Adaptive Server Anywhere SNMP Extension Agent from trying to autostart a database server

    • disables idle timeout since it is likely that the Adaptive Server Anywhere SNMP Extension Agent will sit idle for some time

    • names the connection so it can be identified

    • prevents the database from being shut down when the Adaptive Server Anywhere SNMP Extension Agent disconnects

    If you specify any of these values in the connection string in the asasnmp.ini file, the values in the asasnmp.ini file will override the default settings.

UtilDbPwd When setting asa.agent.asaStarted to start a database, the Adaptive Server Anywhere SNMP Extension Agent attempts to connect to the database with the DBF parameter, which tells the database server where to find the database file. However, if the permission required to start the database is DBA (the default for the network server, which can also be set using the -gd dba option for both the personal and network servers), then the server will not allow the connection.

To start a database on such a server, the Adaptive Server Anywhere SNMP Extension Agent must connect as a user with DBA authority to a database already running on the same server. This can be done by connecting to the utility database. If you specify the utility database password (contained in the server's util_db.ini file) in the asasnmp.ini file, then to start a database, the Adaptive Server Anywhere Extension Agent connects to the utility database on the same server, executes the START DATABASE statement, and then disconnects. This field is optional.

CacheTime When data is retrieved from the database, it can be cached inside the Adaptive Server Anywhere SNMP Extension Agent, so that subsequent retrievals of the same type of data (for example, server properties or database statistics) do not require communication with the database. While caching the data means that you can obtain the data more quickly on subsequent retrievals, the data may be out of date. The CacheTime field can be used to change the cache time, or disable the cache by setting the value to 0. By default, the cache time is 30 seconds. When the CacheTime parameter is set to 0, the data retrieved is always be up-to-date because data is retrieved from the database for every request. This field is optional.

DBSpaceCacheTime The rdbmsDbLimitedResourceTable in the RDBMS MIB contains information about dbspaces. When this information is retrieved from the database, it can also be cached inside the Adaptive Server Anywhere Extension Agent. The default cache time for dbspace information is 600 seconds (10 minutes). This field can be used to change the cache time (or disable the cache by setting the value to 0). This field is optional.

For more information about the rdbmsDbLimitedResourceTable table, see rdbmsDbLimitedResourceTable.

Trapt Creates a dynamic trap. The value t must be a positive integer starting at 1. Skipping numbers is not allowed. This field is optional.

Disabled If set to 1, this database entry is skipped by the Adaptive Server Anywhere SNMP Extension Agent. This is useful for temporarily removing one database from the list of databases managed by the Adaptive Server Anywhere SNMP Extension Agent, without renumbering the rest. This field is optional.

For information about creating traps, see Creating dynamic traps.

Sample asasnmp.ini file

The following is a sample asasnmp.ini file for the Adaptive Server Anywhere SNMP Extension Agent.

[ASAAgent]
[DB1]
ConnStr=UID=DBA;PWD=SQL;ENG=server1;DBN=sales;DBF=sales.db
Trap1=1.1.5 > 50000
UtilDbPwd=test
[DB2]
ConnStr=UID=DBA;PWD=SQL;ENG=server1;DBN=field;DBF=field.db
UtilDbPwd=test
Disabled=1
[DB3]
ConnStr=UID=DBA;PWD=SQL;LINKS=tcpip;ENG=server2;DBN=hq;DBF=hq.db
UtilDbPwd=test

Because there are no parameters specified in the ASAAgent section, the Adaptive Server Anywhere SNMP Extension Agent will poll values every 5 seconds.

The Adaptive Server Anywhere SNMP Extension Agent is monitoring 3 different databases running on two different servers. Database 3 is running on a different machine, so the LINKS connection parameter is required to specify the protocol. A trap is specified for DB1, which fires when the number of bytes sent by the database server is greater than 50 000.


Obtaining values using the Adaptive Server Anywhere SNMP Extension Agent

Using the Adaptive Server Anywhere SNMP Extension Agent, you can retrieve the values of all the following:

  • Database server properties

    For a list of the database server property OIDs, see Server properties.

  • Database server statistics

    For a list of the database server statistic OIDs, see Server statistics.

  • Database options

    For a list of the database option OIDs, see Database options.

  • Database properties

    For a list of the database property OIDs, see Database properties.

  • Database statistics

    For a list of the database statistic OIDs, see Database statistics.

The way you retrieve these values will depend on your SNMP management software.

Examples

The table below provides a description and sample value that could be returned for the following OIDs.

OID | Explanation | Sample value
1.3.6.1.4.1.897.2.1.1.1.1 | Server statistic ActiveReq on database 1 | 1
1.3.6.1.4.1.897.2.1.2.1.3 | Server property C2 on database 3 | NO
1.3.6.1.4.1.897.2.2.1.4.1 | Database statistic CacheRead on database 1 | 11397
1.3.6.1.4.1.897.2.2.2.7.4 | Database property CaseSensitivePasswords on database 4 | OFF
1.3.6.1.4.1.897.2.2.3.5.2 | Database option ANSI_INTEGER_OVERFLOW on database 2 | OFF
1.3.6.1.4.1.897.2.3.1 | Agent version | 9.0.1(1841)
1.3.6.1.4.1.897.2.3.2.1 | Connection string for database 1 | UID=DBA;PWD=SQL; ENG=server1; DBN=sales; DBF=sales.db


Setting values using the Adaptive Server Anywhere SNMP Extension Agent

The Adaptive Server Anywhere SNMP Extension Agent responds to SNMP get, get-next, and set queries.

You can set any database option, some server properties, and one database property using the Adaptive Server Anywhere SNMP agent.

When setting database options, the Adaptive Server Anywhere SNMP agent executes the statement:

SET OPTION PUBLIC.opt = 'value'

When setting database and server properties, the sa_server_option system procedure is used.

The way you set these values depends on your SNMP management software.

For the OIDs and information about the options and properties that can be set with the Adaptive Server Anywhere SNMP Extension Agent, see The Adaptive Server Anywhere MIB.


Executing stored procedures using the Adaptive Server Anywhere SNMP Extension Agent

The Adaptive Server Anywhere MIB includes an OID that allows you to execute a stored procedure using the Adaptive Server Anywhere SNMP Extension Agent. In order to execute the stored procedure, the user that the Adaptive Server Anywhere SNMP Extension Agent uses to connect must have one of the following:

  • execute permission on the procedure

  • be the owner of the procedure

  • have DBA authority

Any result sets or return values generated by the procedure are ignored.

To execute a stored procedure using the Adaptive Server Anywhere SNMP Extension Agent, set the value of asaAgent.asaProc (OID 1.3.6.1.4.1.897.2.3.5.db, where db is the database number in the asasnmp.ini file) to a string that is the name of a stored procedure. Optionally, you can supply arguments to the procedure; if no arguments are supplied, parentheses ( ) are appended to the procedure name.

For example, setting the value of asaAgent.asaProc to the string "pchin.updatesales( 'param1', 2)" calls the updatesales stored procedure owned by user pchin.

The way you set the value of this OID to the procedure name will depend on your SNMP management software.

For more information, see The Adaptive Server Anywhere MIB.


Using traps

A trap is an OID that is sent by an SNMP agent when a particular event occurs. Traps are initiated by the SNMP agent and can be detected by SNMP management software, which can then either deal with the event directly or query the SNMP agent for more information.

In order to receive traps, you must configure the SNMP service. The SNMP service will receive the trap information and then forward it on somewhere; however, by default, this is nowhere, so any trap listeners you have running will not detect anything. The following steps show how to configure your SNMP Service to send traps to your current machine.

toggle To configure the SNMP service

  1. Right-click My Computer and choose Manage from the popup menu.

    The Computer Management dialog appears.

  2. In the left pane, double-click Services and Applications.

  3. In the left pane, double-click Services.

  4. Locate SNMP Service in the list of services in the right pane, right-click it and choose Properties from the popup menu.

    The SNMP Service property sheet appears.

  5. Click the Traps tab.

  6. On the Traps tab, click Add.

    The SNMP Service Configuration dialog appears.

  7. In the SNMP Service Configuration dialog, type localhost in the text box and then click Add.

  8. Click OK to close the Service property sheet.

Adaptive Server Anywhere SNMP Extension Agent traps

The Adaptive Server Anywhere SNMP Extension Agent sends a trap whenever a connection is dropped by the database server. The OID of this trap is 1.3.6.1.2.1.39.2.1.

The only other traps sent by the Adaptive Server Anywhere agent are dynamic traps.

For more information about dynamic traps, see Creating dynamic traps.

Creating dynamic traps


Creating dynamic traps

A dynamic trap is a trap that is sent by the Adaptive Server Anywhere Extension Agent when a simple expression involving the value of a particular property, statistic, or option is true. Dynamic traps are created in the asasnmp.ini file. The format of the trap information in the asasnmp.ini file entry is as follows:

Trap<trapnum>=[1.3.6.1.4.1.897.2.]<oid>[.<dbnum>] <op> <value>

trapnum is the dynamic trap number. It must start at 1 and be sequential.

oid is the OID of the property, statistic, or option. OIDs in either the Adaptive Server Anywhere MIB or the RDBMS MIB are supported. If the OID given is an invalid Adaptive Server Anywhere or RDBMS OID, the Adaptive Server Anywhere MIB prefix (1.3.6.1.4.1.897.2.) is prepended.

For a list of OIDs in the Adaptive Server Anywhere MIB, see Adaptive Server Anywhere MIB Reference.

For a list of OIDs in the RDBMS MIB, see RDBMS MIB Reference.

dbnum is the database number. This field is optional, but if specified, it must match the database number of the [DBn] section of the asasnmp.ini file.

op must have one of the following values:

  • = or == (equality)

  • !=, <>, or >< (inequality)

  • <= or =< (less than or equal)

  • >= or => (greater than or equal)

  • < (less than)

  • > (greater than)

Note
Only equality or inequality are supported for string values.

value is the value to use in the expression. String values may be enclosed in single or double quotes; these quotes will not be included in the value. If you want the beginning or closing quotation marks to be included in the string, you must double them. Note that single quotes occurring within the string should not be doubled.

You can specify as many trap fields as you wish in the asasnmp.ini file. The OID used for the trap will be 1.3.6.1.4.1.897.2.4.1, and the data sent with the trap will indicate the trap number of the trap that was sent.

You can specify as many Trap fields as you wish in the asasnmp.ini file. The OID used for the trap will be 1.3.6.1.4.1.897.2.4.1, and the data sent with the trap includes the following:

  • the trap number (starts at 1 for the first dynamic trap sent by the Adaptive Server Anywhere SNMP agent)

  • the database index

  • the database name trap index (from the asasnmp.ini file)

  • the variable name

  • the variable value (this is the current value of the variable, not necessarily the threshold value)

Dynamic trap behavior

Once a dynamic trap is triggered, the trap is not be sent again until the condition that caused it to be triggered changes to FALSE and then back to TRUE again.

For example, if you have a dynamic trap set using 1.1.11.1 >= 5120, then the trap is triggered when the server's cache size reaches 5 MB (= 5120 KB) and the dynamic trap is disabled, so no more traps are sent. The only way the trap is re-enabled is if the cache size later drops below 5 MB. You would then be notified if the cache size grew to 5 MB again.

Trap examples
Trap information | Description
Trap1=1.1.5 > 10000 | Trap sent when the number of bytes sent from the server is greater than 10 000
Trap2=1.3.6.1.2.1.39.1.4.1.4.14.1 >= 10485760 | Trap sent if the size of the transaction log file is larger than 10 MB


Adaptive Server Anywhere MIB Reference

About this chapter

This chapter contains descriptions of the tables in the Adaptive Server Anywhere MIB.

The Adaptive Server Anywhere MIB


The Adaptive Server Anywhere MIB

The following sections list the OIDs of the statistics, properties, and options that can be retrieved and set using the Adaptive Server Anywhere SNMP Extension Agent. By default,


Agent

The Agent table lists information about the Adaptive Server Anywhere SNMP Extension Agent.

Writable properties are marked with an asterisk (*). The value n is the database number in the asasnmp.ini file.

OID | Type | Name | Value returned
1.3.6.1.4.1.897.2.3.1 | String | asaVersion | Agent version
1.3.6.1.4.1.897.2.3.2.n | String | asaDBConnStr | Connection string
1.3.6.1.4.1.897.2.3.3.n | Integer32 | asaConnected* | 1 if the agent is connected, 0 otherwise
1.3.6.1.4.1.897.2.3.4.n | Integer32 | asaStarted* | 1 if the database is started, 0 otherwise
1.3.6.1.4.1.897.2.3.5.n | String | asaProc* | " "
1.3.6.1.4.1.897.2.3.6 | String | asaRestart* | 0


asaMetaData tables

The following metadata tables are included in the Adaptive Server Anywhere MIB:

  • asaSrvMetaData.asaSrvStatMetaDataTable

  • asaSrvMetaData.asaSrvPropMetaDataTable

  • asaSrvMetaData.asaDbStatMetaDataTable

  • asaSrvMetaData.asaDbPropMetaDataTable

  • asaSrvMetaData.asaDbOptMetaDataTable

asaSrvMetaData.asaSrvStatMetaDataTable
asaSrvMetaData.asaSrvPropMetaDataTable
asaDbMetaData.asaDbStatMetaDataTable
asaDbMetaData.asaDbPropMetaDataTable
asaDbMetaData.asaDbOptMetaDataTable


asaSrvMetaData.asaSrvStatMetaDataTable

This table contains metadata about the database server statistics.

The value db is the database number in the asasnmp.ini file.

OID | Type | Name | Value returned
1.3.6.1.4.1.897.2.4.1.1.1.1.db | Integer32 | asaSrvStatIndex | db
1.3.6.1.4.1.897.2.4.1.1.1.2.db | Integer32 | asaSrvStatObjType | 11
1.3.6.1.4.1.897.2.4.1.1.1.3.db | Integer32 | asaSrvStatType | 12
1.3.6.1.4.1.897.2.4.1.1.1.4.db | OID | asaSrvStatOID | OID of Adaptive Server Anywhere MIB entry3
1.3.6.1.4.1.897.2.4.1.1.1.5.db | String | asaSrvStatName | Statistic name

1 Values: 1=Server, 2=Database

2 Values: 1=Statistic, 2=Property, 3=Option

3 The OID returned does not include the database number. You must append the database number to the OID before it can be used in a query.


asaSrvMetaData.asaSrvPropMetaDataTable

This table contains metadata about the database server properties.

The value db is the database number in the asasnmp.ini file.

OID | Type | Name | Value returned
1.3.6.1.4.1.897.2.4.1.2.1.1.db | Integer32 | asaSrvPropIndex | db
1.3.6.1.4.1.897.2.4.1.2.1.2.db | Integer32 | asaSrvPropObjType | 11
1.3.6.1.4.1.897.2.4.1.2.1.3.db | Integer32 | asaSrvPropType | 22
1.3.6.1.4.1.897.2.4.1.2.1.4.db | OID | asaSrvPropOID | OID of Adaptive Server Anywhere MIB entry3
1.3.6.1.4.1.897.2.4.1.2.1.5.db | String | asaSrvPropName | Property name

1 Values: 1=Server, 2=Database

2 Values: 1=Statistic, 2=Property, 3=Option

3 The OID returned does not include the database number. You must append the database number to the OID before it can be used in a query.


asaDbMetaData.asaDbStatMetaDataTable

This table contains metadata about the database statistics.

The value db is the database number in the asasnmp.ini file.

OID | Type | Name | Value returned
1.3.6.1.4.1.897.2.4.2.1.1.1.db | Integer32 | asaDbStatIndex | db
1.3.6.1.4.1.897.2.4.2.1.1.2.db | Integer32 | asaDbStatObjType | 21
1.3.6.1.4.1.897.2.4.2.1.1.3.db | Integer32 | asaDbStatType | 12
1.3.6.1.4.1.897.2.4.2.1.1.4.db | OID | asaDbStatOID | OID of Adaptive Server Anywhere MIB entry3
1.3.6.1.4.1.897.2.4.2.1.1.5.db | String | asaDbStatName | Statistic name

1 Values: 1=Server, 2=Database

2 Values: 1=Statistic, 2=Property, 3=Option

3 The OID returned does not include the database number. You must append the database number to the OID before it can be used in a query.


asaDbMetaData.asaDbPropMetaDataTable

This table contains metadata about the database properties.

The value db is the database number in the asasnmp.ini file.

OID | Type | Name | Value returned
1.3.6.1.4.1.897.2.4.2.2.1.1.db | Integer32 | asaDbPropIndex | db
1.3.6.1.4.1.897.2.4.2.2.1.2.db | Integer32 | asaDbPropObjType | 21
1.3.6.1.4.1.897.2.4.2.2.1.3.db | Integer32 | asaDbPropType | 22
1.3.6.1.4.1.897.2.4.2.2.1.4.db | OID | asaDbPropOID | OID of Adaptive Server Anywhere MIB entry3
1.3.6.1.4.1.897.2.4.2.2.1.5.db | String | asaDbPropName | Property name

1 Values: 1=Server, 2=Database

2 Values: 1=Statistic, 2=Property, 3=Option

3 The OID returned does not include the database number. You must append the database number to the OID before it can be used in a query.


asaDbMetaData.asaDbOptMetaDataTable

This table contains metadata about the database options.

The value db is the database number in the asasnmp.ini file.

OID | Type | Name | Value returned
1.3.6.1.4.1.897.2.4.2.1.1.1.db | Integer32 | asaDbOptIndex | db
1.3.6.1.4.1.897.2.4.2.1.1.2.db | Integer32 | asaDbOptObjType | 21
1.3.6.1.4.1.897.2.4.2.1.1.3.db | Integer32 | asaDbOptType | 32
1.3.6.1.4.1.897.2.4.2.1.1.4.db | OID | asaDbOptOID | OID of Adaptive Server Anywhere MIB entry3
1.3.6.1.4.1.897.2.4.2.1.1.5.db | String | asaDbOptName | Option name

1 Values: 1=Server, 2=Database

2 Values: 1=Statistic, 2=Property, 3=Option

3 The OID returned does not include the database number. You must append the database number to the OID before it can be used in a query.


Server statistics

This table lists the OIDs and names of the database server statistics that can be retrieved using the Adaptive Server Anywhere SNMP Extension Agent.

The value n is the database number in the asasnmp.ini file.

OID | Type | Name | Statistic
1.3.6.1.4.1.897.2.1.1.1.n | Integer32 | srvStatActiveReq | ActiveReq
1.3.6.1.4.1.897.2.1.1.2.n | Integer32 | srvStatAvailIO | AvailIO
1.3.6.1.4.1.897.2.1.1.3.n | Counter64 | srvStatBytesReceived | BytesReceived
1.3.6.1.4.1.897.2.1.1.4.n | Counter64 | srvStatBytesReceivedUncomp | BytesReceivedUncomp
1.3.6.1.4.1.897.2.1.1.5.n | Counter64 | srvStatBytesSent | BytesSent
1.3.6.1.4.1.897.2.1.1.6.n | Counter64 | srvStatBytesSentUncomp | BytesSentUncomp
1.3.6.1.4.1.897.2.1.1.7.n | Counter64 | srvStatCacheHitsEng | CacheHitsEng
1.3.6.1.4.1.897.2.1.1.8.n | Integer32 | srvStatCachePinned | CachePinned
1.3.6.1.4.1.897.2.1.1.9.n | Counter64 | srvStatCacheReadEng | CacheReadEng
1.3.6.1.4.1.897.2.1.1.10.n | Counter64 | srvStatCacheReplacements | CacheReplacements
1.3.6.1.4.1.897.2.1.1.11.n | Integer32 | srvStatCurrentCacheSize | CurrentCacheSize
1.3.6.1.4.1.897.2.1.1.12.n | Counter64 | srvStatDiskReadEng | DiskReadEng
1.3.6.1.4.1.897.2.1.1.13.n | Integer32 | srvStatFreeBuffers | FreeBuffers
1.3.6.1.4.1.897.2.1.1.14.n | Integer32 | srvStatJavaGlobFix | JavaGlobFix
1.3.6.1.4.1.897.2.1.1.15.n | Integer32 | srvStatLicensesInUse | LicensesInUse
1.3.6.1.4.1.897.2.1.1.16.n | Integer32 | srvStatLockedHeapPages | LockedHeapPages
1.3.6.1.4.1.897.2.1.1.17.n | Counter64 | srvStatMainHeapBytes | MainHeapBytes
1.3.6.1.4.1.897.2.1.1.18.n | Integer32 | srvStatMainHeapPages | MainHeapPages
1.3.6.1.4.1.897.2.1.1.19.n | Integer32 | srvStatMapPhysicalMemoryEng | MapPhysicalMemoryEng
1.3.6.1.4.1.897.2.1.1.20.n | Integer32 | srvStatMaxCacheSize | MaxCacheSize
1.3.6.1.4.1.897.2.1.1.21.n | Integer32 | srvStatMinCacheSize | MinCacheSize
1.3.6.1.4.1.897.2.1.1.22.n | Counter64 | srvStatMultiPacketsReceived | MultiPacketsReceived
1.3.6.1.4.1.897.2.1.1.23.n | Counter64 | srvStatMultiPacketsSent | MultiPacketsSent
1.3.6.1.4.1.897.2.1.1.24.n | Counter64 | srvStatPacketsReceived | PacketsReceived
1.3.6.1.4.1.897.2.1.1.25.n | Counter64 | srvStatPacketsReceivedUncomp | PacketsReceivedUncomp
1.3.6.1.4.1.897.2.1.1.26.n | Counter64 | srvStatPacketsSent | PacketsSent
1.3.6.1.4.1.897.2.1.1.27.n | Counter64 | srvStatPacketsSentUncomp | PacketsSentUncomp
1.3.6.1.4.1.897.2.1.1.28.n | Integer32 | srvStatPeakCacheSize | PeakCacheSize
1.3.6.1.4.1.897.2.1.1.29.n | Integer32 | srvStatRemoteputWait | RemoteputWait
1.3.6.1.4.1.897.2.1.1.30.n | Integer32 | srvStatReq | Req
1.3.6.1.4.1.897.2.1.1.31.n | Counter64 | srvStatSendFail | SendFail
1.3.6.1.4.1.897.2.1.1.32.n | Integer32 | srvStatTotalBuffers | TotalBuffers
1.3.6.1.4.1.897.2.1.1.33.n | Integer32 | srvStatUnschReq | UnschReq


Server properties

The following table lists OIDs and names of the database server properties that can be retrieved using the Adaptive Server Anywhere SNMP Extension Agent.

Writable properties are marked with an asterisk (*). The value n is the database number in the asasnmp.ini file.

OID | Type | Name | Property
1.3.6.1.4.1.897.2.1.2.1.n | String | srvPropC2 | C2
1.3.6.1.4.1.897.2.1.2.2.n | String | srvPropCharSet | CharSet
1.3.6.1.4.1.897.2.1.2.3.n | String | srvPropCommandLine | CommandLine
1.3.6.1.4.1.897.2.1.2.4.n | String | srvPropCompactPlatformVer | CompactPlatformVer
1.3.6.1.4.1.897.2.1.2.5.n | String | srvPropCompanyName | CompanyName
1.3.6.1.4.1.897.2.1.2.6.n | String | srvPropConnsDisabled* | ConnsDisabled
1.3.6.1.4.1.897.2.1.2.7.n | String | srvPropConsoleLogFile | ConsoleLogFile
1.3.6.1.4.1.897.2.1.2.8.n | String | srvPropDefaultCollation | DefaultCollation
1.3.6.1.4.1.897.2.1.2.9.n | String | srvPropIdleTimeout | IdleTimeout
1.3.6.1.4.1.897.2.1.2.10.n | String | srvPropIsIQ | IsIQ
1.3.6.1.4.1.897.2.1.2.11.n | String | srvPropIsJavaAvailable | IsJavaAvailable
1.3.6.1.4.1.897.2.1.2.12.n | String | srvPropIsNetworkServer | IsNetworkServer
1.3.6.1.4.1.897.2.1.2.13.n | String | srvPropIsRuntimeServer | IsRuntimeServer
1.3.6.1.4.1.897.2.1.2.14.n | String | srvPropJavaObjectsEnabled | JavaObjectsEnabled
1.3.6.1.4.1.897.2.1.2.15.n | String | srvPropLanguage | Language
1.3.6.1.4.1.897.2.1.2.16.n | String | srvPropLegalCopyright | LegalCopyright
1.3.6.1.4.1.897.2.1.2.17.n | String | srvPropLegalTrademarks | LegalTrademarks
1.3.6.1.4.1.897.2.1.2.18.n | String | srvPropLicenseCount | LicenseCount
1.3.6.1.4.1.897.2.1.2.19.n | String | srvPropLicensedCompany | LicensedCompany
1.3.6.1.4.1.897.2.1.2.20.n | String | srvPropLicensedUser | LicensedUser
1.3.6.1.4.1.897.2.1.2.21.n | String | srvPropLicenseType | LicenseType
1.3.6.1.4.1.897.2.1.2.22.n | String | srvPropLivenessTimeout* | LivenessTimeout
1.3.6.1.4.1.897.2.1.2.23.n | String | srvPropMachineName | MachineName
1.3.6.1.4.1.897.2.1.2.24.n | String | srvPropMaxMessage | MaxMessage
1.3.6.1.4.1.897.2.1.2.25.n | String | srvPropMessageWindowSize | MessageWindowSize
1.3.6.1.4.1.897.2.1.2.26.n | String | srvPropName | Name
1.3.6.1.4.1.897.2.1.2.27.n | String | srvPropNativeProcessorArchitecture | NativeProcessorArchitecture
1.3.6.1.4.1.897.2.1.2.28.n | String | srvPropNumProcessorsAvail | NumProcessorsAvail
1.3.6.1.4.1.897.2.1.2.29.n | String | srvPropNumProcessorsMax | NumProcessorsMax
1.3.6.1.4.1.897.2.1.2.30.n | String | srvPropOmniIdentifier | OmniIdentifier
1.3.6.1.4.1.897.2.1.2.31.n | String | srvPropPageSize | PageSize
1.3.6.1.4.1.897.2.1.2.32.n | String | srvPropPlatform | Platform
1.3.6.1.4.1.897.2.1.2.33.n | String | srvPropPlatformVer | PlatformVer
1.3.6.1.4.1.897.2.1.2.34.n | String | srvPropProcessCPU | ProcessCPU
1.3.6.1.4.1.897.2.1.2.35.n | String | srvPropProcessCPUSystem | ProcessCPUSystem
1.3.6.1.4.1.897.2.1.2.36.n | String | srvPropProcessCPUUser | ProcessCPUUser
1.3.6.1.4.1.897.2.1.2.37.n | String | srvPropProcessorArchitecture | ProcessorArchitecture
1.3.6.1.4.1.897.2.1.2.38.n | String | srvPropProductName | ProductName
1.3.6.1.4.1.897.2.1.2.39.n | String | srvPropProductVersion | ProductVersion
1.3.6.1.4.1.897.2.1.2.40.n | String | srvPropQuittingTime* | QuittingTime
1.3.6.1.4.1.897.2.1.2.41.n | String | srvPropRememberLastStatement* | RememberLastStatement
1.3.6.1.4.1.897.2.1.2.42.n | String | srvPropRequestFilterConn | RequestFilterConn
1.3.6.1.4.1.897.2.1.2.43.n | String | srvPropRequestFilterDB | RequestFilterDB
1.3.6.1.4.1.897.2.1.2.44.n | String | srvPropRequestLogFile* | RequestLogFile
1.3.6.1.4.1.897.2.1.2.45.n | String | srvPropRequestLogging* | RequestLogging
1.3.6.1.4.1.897.2.1.2.46.n | String | srvPropRequestLogMaxSize | RequestLogMaxSize
1.3.6.1.4.1.897.2.1.2.47.n | String | srvPropStartTime | StartTime
1.3.6.1.4.1.897.2.1.2.48.n | String | srvPropTempDir | TempDir
1.3.6.1.4.1.897.2.1.2.49.n | String | srvPropThreads | Threads
1.3.6.1.4.1.897.2.1.2.50.n | String | srvPropTimeZoneAdjustment | TimeZoneAdjustment
1.3.6.1.4.1.897.2.1.2.51.n | String | srvPropHttpPorts | HttpPorts
1.3.6.1.4.1.897.2.1.2.52.n | String | srvPropHttpsPorts | HttpsPorts
1.3.6.1.4.1.897.2.1.2.53.n | String | srvPropProfileFilterConn | ProfileFilterConn
1.3.6.1.4.1.897.2.1.2.54.n | String | srvPropProfileFilterUser | ProfileFilterUser
1.3.6.1.4.1.897.2.1.2.55.n | String | srvPropRequestLogNumFiles | RequestLogNumFIles
1.3.6.1.4.1.897.2.1.2.56.n | String | srvPropIsFipsAvailable | IsFipsAvailable
1.3.6.1.4.1.897.2.1.2.57.n | String | srvPropFipsMode | FipsMode


RDBMS MIB Reference

About this chapter

This chapter contains descriptions of each of the tables in the RDBMS MIB.

The RDBMS MIB


The RDBMS MIB

The following sections list the OIDs of the values that can be retrieved using the Adaptive Server Anywhere SNMP Extension Agent. By default, the RDBMS MIB is located in C:\Program Files\Sybase\SQL Anywhere 9\snmp\RDBMS-MIB.mib.

rdbmsDbTable
rdbmsDbInfoTable
rdbmsDbParamTable
rdbmsDbLimitedResourceTable
rdbmsSrvTable
rdbmsSrvInfoTable
rdbmsSrvParamTable
rdbmsSrvLimitedResourceTable


rdbmsDbTable

This table lists information about the databases installed on a system.

The value db is the database number in the asasnmp.ini file.

OID | Type | Name | Value returned
1.3.6.1.2.1.39.1.1.1.1.db | Integer | rdbmsDbIndex | db
1.3.6.1.2.1.39.1.1.1.2.db | OID | rdbmsDbPrivateMibOID | 1.3.6.1.4.1.897.2
1.3.6.1.2.1.39.1.1.1.3.db | String | rdbmsDbVendorName | property('CompanyName')
1.3.6.1.2.1.39.1.1.1.4.db | String | rdbmsDbName | db_property('name')
1.3.6.1.2.1.39.1.1.1.5.db | String | rdbmsDbContact | property('LicensedUser')


rdbmsDbInfoTable

This table provides additional information about the databases on the system.

The value db is the database number in the asasnmp.ini file.

OID | Type | Name | Value returned
1.3.6.1.2.1.39.1.2.1.1.db | String | rdbmsDbInfoProductName | property('PropertyName')
1.3.6.1.2.1.39.1.2.1.2.db | String | rdbmsDbInfoVersion | property('ProductVersion')
1.3.6.1.2.1.39.1.2.1.3.db Integer rdbmsDbInfoSizeUnits Calculated based on dbInfoSizeAllocated and dbInfoSizeUsed.

  • 1=bytes

  • 2=KB

  • 3=MB

  • 4=GB

  • 5=TB

(Each unit is 1024 times the previous.)
1.3.6.1.2.1.39.1.2.1.4.db | Integer | rdbmsDbInfoSizeAllocated | db_property('pagesize') * db_property('filesize')
1.3.6.1.2.1.39.1.2.1.5.db | Integer | rdbmsDbInfoSizeUsed | db_property('pagesize') * (db_property('filesize') - db_property('freepages') )
1.3.6.1.2.1.39.1.2.1.6.db | String | rdbmsDbInfoLastBackup | NULL1

1 This OID is not currently supported by the Adaptive Server Anywhere SNMP Extension Agent.


rdbmsDbParamTable

This table lists the configuration parameters for the databases on the system.

The value db is the database number in the asasnmp.ini file, while n is the index of the option in the asa.2.3 subtree.

OID | Type | Name | Value returned
1.3.6.1.2.1.39.1.3.1.1.db | String | rdbmsDbParamName | Option name
1.3.6.1.2.1.39.1.3.1.2.db | Integer | rdbmsDbParamSubIndex | n
1.3.6.1.2.1.39.1.3.1.3.db | OID | rdbmsDbParamID | OID in Adaptive Server Anywhere MIB corresponding to this option
1.3.6.1.2.1.39.1.3.1.4.db | String | rdbmsDbParamCurrValue | Option value
1.3.6.1.2.1.39.1.3.1.5.db | String | rdbmsDbParamComment | NULL1

1 This OID is not currently supported by the Adaptive Server Anywhere SNMP Extenstion Agent.


rdbmsDbLimitedResourceTable

This table lists free space information on each dbspace. In this table, n represents each dbspace as follows:

  • 1-13 are for normal dbspaces (numbered 0-12 in the database)

  • 14 is the transaction log file

  • 15 is the transaction log mirror file

  • 16 is the temporary file

  • 17 is the write file

The value db is the database number in the asasnmp.ini file.

OID | Type | Name | Value returned
1.3.6.1.2.1.39.1.4.1.1.n.db | String | rdbmsDbLimitedResourceName | Name of dbspace, or Transaction Log, Transaction Log Mirror, Temporary File, or Write File.
1.3.6.1.2.1.39.1.4.1.2.n.db | OID | rdbmsDbLimitedResourceID | 1.3.6.1.4.1.897.2
1.3.6.1.2.1.39.1.4.1.3.n.db | Integer | rdbmsDbLimitedResourceLimit | Free space available on disk + current file size, in bytes
1.3.6.1.2.1.39.1.4.1.4.n.db | Integer | rdbmsDbLimitedResourceCurrent | Current file size
1.3.6.1.2.1.39.1.4.1.5.n.db | Integer | rdbmsDbLimitedResourceHighwater | Current size
1.3.6.1.2.1.39.1.4.1.6.n.db | Integer | rdbmsDbLimitedResourceFailure | 01
1.3.6.1.2.1.39.1.4.1.7n.db | String | rdbmsDbLimitedResourceDescription | "Bytes"

1 This OID is not currently supported by the Adaptive Server Anywhere SNMP Extenstion Agent.


rdbmsSrvTable

This table lists the database servers running or installed on your system.

The value db is the database number in the asasnmp.ini file.

OID | Type | Name | Value returned
1.3.6.1.2.1.39.1.5.1.1.db | OID | rdbmsSrvPrivateMibOID | 1.3.6.1.4.1.897.2
1.3.6.1.2.1.39.1.5.1.2.db | String | rdbmsSrvVendorName | property('CompanyName')
1.3.6.1.2.1.39.1.5.1.3.db | String | rdbmsSrvProductName | property('ProductName')
1.3.6.1.2.1.39.1.5.1.4.db | String | rdbmsSrvContact | property('LicencedCompany')


rdbmsSrvInfoTable

This table lists additional information about the database servers in your system.

The value db is the database number in the asasnmp.ini file.

OID | Type | Name | Value returned
1.3.6.1.2.1.39.1.6.1.1.db | Integer | rdbmsSrvInfoStartupTime | property('StartTime')
1.3.6.1.2.1.39.1.6.1.2.db | Integer | rdbmsSrvInfoFinishedTransactions | 01
1.3.6.1.2.1.39.1.6.1.3.db | Integer | rdbmsSrvInfoDiskReads | property('DiskReadEng')
1.3.6.1.2.1.39.1.6.1.4.db | Integer | rdbmsSrvInfoLogicalReads | 01
1.3.6.1.2.1.39.1.6.1.5.db | Integer | rdbmsSrvInfoDiskWrites | property('DiskWriteEng')
1.3.6.1.2.1.39.1.6.1.6.db | Integer | rdbmsSrvInfoLogicalWrites | 01
1.3.6.1.2.1.39.1.6.1.7.db | Integer | rdbmsSrvInfoPageReads | 01
1.3.6.1.2.1.39.1.6.1.8.db | Integer | rdbmsSrvInfoPageDiskOutOfWrites | 01
1.3.6.1.2.1.39.1.6.1.9.db | Integer | rdbmsSrvInfoSpaces | 01
1.3.6.1.2.1.39.1.6.1.10.db | Integer | rdbmsSrvInfoHandledRequests | property('Req')
1.3.6.1.2.1.39.1.6.1.11.db | Integer | rdbmsSrvInfoRequestRecvs | property('PacketsReceivedUncomp')
1.3.6.1.2.1.39.1.6.1.12.db | Integer | rdbmsSrvInfoRequestSends | property('PacketsSentUncomp')
1.3.6.1.2.1.39.1.6.1.13.db | Integer | rdbmsSrvInfoHighwaterInboundAssociations | 01
1.3.6.1.2.1.39.1.6.1.14.db | Integer | rdbmsSrvInfoMaxInboundAssociations | 01

1 This OID is not currently supported by the Adaptive Server Anywhere SNMP Extenstion Agent.


rdbmsSrvParamTable

This table lists the server options that can be set by the Adaptive Server Anywhere SNMP Extension Agent through the Adaptive Server Anywhere MIB. n is the index, as follows:

n | Server option
1 | ConnsDisabled
2 | LivenessTimeout (default)
3 | QuittingTime
4 | RememberLastStatement
5 | RequestLogFile
6 | RequestLogging

The value db is the database number in the asasnmp.ini file.

OID | Type | Name | Value returned
1.3.6.1.2.1.39.1.7.1.1.n.db | String | rdbmsDbSrvParamName | Name of option n
1.3.6.1.2.1.39.1.7.1.2.n.db | Integer | rdbmsDbSrvParamSubIndex | n
1.3.6.1.2.1.39.1.7.1.3.n.db | OID | rdbmsDbSrvParamID | 1.3.6.1.4.1.897.2
1.3.6.1.2.1.39.1.7.1.4.n.db | String | rdbmsDbSrvParamCurrValue | Current value of option n
1.3.6.1.2.1.39.1.7.1.5.n.db | String | rdbmsDbSrvParamComment | Full name of option n


rdbmsSrvLimitedResourceTable

This table contains information about server configuration parameters.

The value db is the database number in the asasnmp.ini file, while n is the index of the resource as follows:

n | Name | Resource | Resource limit
1 | Connections | property('LicensesInUse') | property('LicenseCount')
2 | Processors | property('NumProcessorsAvail') | property('NumProcessorsMax') If this is 0, then it returns property('NumProcessorsAvail'))
OID | Type | Name | Value returned
1.3.6.1.2.1.39.1.8.1.1.db | String | rdbmsSrvLimitedResourceName | Name of resource n
1.3.6.1.2.1.39.1.8.1.2.db | OID | rdbmsSrvLimitedResourceID | OID in Adaptive Server Anywhere MIB corresponding to this option
1.3.6.1.2.1.39.1.8.1.3.db | Integer | rdbmsSrvLimitedResourceLimit | Upper limit of resource n
1.3.6.1.2.1.39.1.8.1.4.db | Integer | rdbmsSrvLimitedResourceCurrent | Current value of resource n
1.3.6.1.2.1.39.1.8.1.5.db | Integer | rdbmsSrvLimitedResourceHighwater | Current value of resource n
1.3.6.1.2.1.39.1.8.1.6.db | Integer | rdbmsSrvLimitedResourceFailures | 01
1.3.6.1.2.1.39.1.8.1.7.db | String | rdbmsSrvLimitedResourceDescription | Name of resource n

1 This OID is not currently supported by the Adaptive Server Anywhere SNMP Extenstion Agent.


SQL Anywhere Studio 9.0.2

 iAnywhere Solutions

Welcome to the SQL Anywhere Studio version 9.0.2 documentation. The links on this page direct you to some useful starting points.

For an overview of this release

  • Welcome to SQL Anywhere Studio version 9

For beginners

  • Welcome to SQL Anywhere Studio

  • MobiLink Synchronization

  • UltraLite Databases

  • SQL Remote Replication

For users of previous versions

What's new

For complete lists of new features in version 9.0.2, see the following sections:

  • Adaptive Server Anywhere databases

  • MobiLink synchronization

  • UltraLite applications

For complete lists of new features in version 9.0.1, see the following sections:

  • Adaptive Server Anywhere databases

  • MobiLink synchronization

  • UltraLite applications

For complete lists of new features in version 9.0.0, see the following sections:

  • Adaptive Server Anywhere databases

  • MobiLink synchronization

  • UltraLite applications

Behavior changes

Before using existing applications with this version of the software, be sure to review the list of behavior changes.

For complete lists of behavior changes in version 9.0.2, see the following sections:

  • Adaptive Server Anywhere

  • MobiLink synchronization

  • UltraLite applications

For complete lists of behavior changes in version 9.0.1, see the following sections:

  • Adaptive Server Anywhere

  • MobiLink synchronization

  • UltraLite applications

For complete lists of behavior changes in version 9.0.0, see the following sections:

  • Adaptive Server Anywhere

  • MobiLink synchronization

  • UltraLite applications

Upgrading

The upgrade operations are described in the following sections.

  • To access some new Adaptive Server Anywhere features you must upgrade your database. For instructions, see Upgrading Adaptive Server Anywhere databases. For additional instructions on upgrading Adaptive Server Anywhere version 5 applications, see Upgrading Version 5 Applications.

  • For information on upgrading MobiLink installations, see Upgrading MobiLink synchronization

  • For information on upgrading SQL Remote installations, see Upgrading SQL Remote replication

  • For information on upgrading UltraLite applications, see Upgrading UltraLite applications

Last-minute changes

  • Read Me First

  • Documentation errata


Please choose subentry

Please choose a subentry

To view a topic related to this index entry, double-click one of the subentries.


How To...

Filter Reset Toggle headings

To install SQL Anywhere Studio (Windows operating systems)

To install SQL Anywhere Studio (Novell NetWare or Windows CE)

To install SQL Anywhere Studio (UNIX)

To install SQL Anywhere Studio for Windows CE

To determine the IP address of your Windows CE device

To configure your desktop machine

To create an ODBC data source to connect to your Windows CE device

To start the ASA Server Example

To shut down the server

To use the ADO.NET Sample

To use the ADOCE Sample

To use the ESQL Sample

To use the ODBC Sample

To create a Windows CE database in Sybase Central and copy it directly to your Windows CE device

To create a database using the dbinit utility

To create a database using the CREATE DATABASE statement

To copy a database to your Windows CE device

To erase a database using the device interface

To erase a database using Windows Explorer

To create databases for your Windows CE device

To start a database on the server

To connect to the Alpha database using Sybase Central

To start multiple databases on the network server

To connect to the Beta database

To disconnect from the Windows CE databases

To shut down the server

To create a backup copy of the sample database

To start the sample database

To connect from Sybase Central to a database on your Windows CE device

To shut down the server

To restore the sample database

To create a backup copy of the sample database

To start the sample database

To connect from Interactive SQL to a database on your Windows CE device

To shut down the server

To restore the sample database

List all products sold by the company

List the name, description, and color of each product

List the value in stock of each product

List the products in alphabetical order

List all products colored black

List all employees born before March 13, 1964

List all employees whose last name begins with BR

List all employees whose last name begins with BR, followed by zero or more letters and a T, followed by zero or more letters

List employees with a last name that sound like Brown

List all employees born before March 13, 1964, except the employee named Whitney

List all data in the employee and sales_order tables

List all sales orders with their dates, and the employee responsible for each

List companies and the total value of their orders

List all employees and their departments

List all customers, and the dates of any orders they have placed

List all products for which there are less than 20 items in stock

List all order items for wool caps

List all order items for items that are low in stock

List the number of employees in the company

List the number of employees in the company and the birth dates of the oldest and youngest employee

List the sales representatives and the number of orders each has taken

List all sales representatives with more than 55 orders

Add a brown acrylic vest to the product table

Transfer employee #195 to department 400 in Interactive SQL

To copy the sample database

To start the personal database server running the sample database (Windows)

To start the database server running the sample database (Command prompt)

Shut down the database server running the sample database (Windows)

To create a simple ODBC data source

To connect to the sample database from Sybase Central

To shut down the database server

To close Sybase Central

To start Interactive SQL and connect to the sample database (Windows)

To start Interactive SQL and connect to the sample database (Command prompt)

To open a new Interactive SQL window

To list all the columns and rows of the employee table

To edit a row in the result set

To insert a new row into the result set

To delete a row from the result set

To copy rows from the Interactive SQL result set

To execute a SQL statement

To clear the SQL Statements pane

To enter multiple statements in SQL Statements pane

To look up the names of tables in the database

To look up column names in the database

To look up the names of procedures in the database

To save the command history to a file

To begin logging Interactive SQL commands

To stop logging Interactive SQL commands

To start Sybase Central

To connect to the sample database

To examine the tables in the sample database

To view information about the columns of the product table

To view the contents of database tables

Create a table named office

Edit the Office table

To delete the office table from the sample database

To add a group to the sample database

To add a user to the sample database

To add users to a group

To view the contents of a stored procedure

View and alter the permissions on the sp_customer_list procedure

To back up a running database

To create a new database file

To connect to your database

To create the product table

To create an AUTOINCREMENT primary key

To specify a data type for a column

To create a foreign key

To create your database files

To create ODBC data sources

To verify your new data sources

To run scripts from Interactive SQL

To add a publication and synchronization subscription to the remote database

To add a script version

To add synchronized tables to your consolidated database

To add table scripts to each synchronized table

To start the MobiLink synchronization server

To run the MobiLink synchronization client

Prepare for the tutorial

Add an address to a message type

Set the publisher

Add a remote user

Add a publication

Add a subscription

Extract the remote database

Browse through the remote database

Enter data in the consolidated database

Send the data to the remote database

Receive data at the remote database

Verify that the data has arrived

Replicate data from the remote database to the consolidated database

Delete the remote user

Delete the publication

Revoke the publishing status from the sample database

Restore the original message type settings

Shut down the remote database

Delete the remote database

Delete the inserted data from the sample database

To start PowerDesigner

To reverse engineer the database

To add a column

To check your new schema

To save the physical data model (PDM)

To generate a SQL script to create your new database

To create the new database

To start InfoMaker

To create a database profile for the SQL Anywhere Studio sample database with InfoMaker

To connect to the Adaptive Server Anywhere sample database once a data source has been created

To create the report

To preview your report

To save the report

To set up the design environment

To sort contacts

To group contacts

To adjust the group header

To arrange the headers

To add a title to the report

To add a date to the report

To add page numbers to the report

To add a total by counting the number of last names

To format the total

To print, save, and close the report

To develop a database application with Visual Basic

To upgrade a database (Sybase Central)

To upgrade a database (Command line)

To upgrade a database (SQL)

To upgrade the database file format (Sybase Central)

To upgrade the database file format (Command line)

To use the version 9.0 utilities

To upgrade a consolidated database (not DB2)

To upgrade a DB2 consolidated database

To upgrade embedded SQL applications that use an embedded database

To upgrade embedded SQL client/server applications

To use Version 5 utilities with Adaptive Server Anywhere Version 9

To upgrade ODBC applications that use an embedded database

To upgrade ODBC client/server applications

To upgrade your pbodb80.ini file

To upgrade StartLine parameters

To start the personal database server using default options (Windows except Windows CE)

To start the personal database server using default options (UNIX)

To start the database server using default options (NetWare)

To list the database server options

To stop a server using the dbstop utility

To add a new service (Sybase Central)

To add a new service (Command line)

To remove a service (Sybase Central)

To remove a service (Command line)

To change the parameters for a service

To add a new database to an existing service

To set the Sybase Central polling frequency

To start, stop, or pause a service

To check and change which group a service belongs to

To add a service or group to a list of dependencies

To open the Connect dialog (Sybase Central)

To open the Connect dialog (Interactive SQL)

To specify a driver for the connection (Sybase Central)

To connect to the sample database (Sybase Central)

To connect to the sample database (Interactive SQL)

To connect to a database on an already-running local server

To start and connect to a database

To connect from using a data source (Sybase Central or Interactive SQL)

To connect to a database on a network server ( Sybase Central or Interactive SQL )

To create an ODBC data source (ODBC Administrator)

To create an ODBC data source (Command line)

To create an ODBC file data source (ODBC Administrator)

To connect from a desktop application to a Windows CE database server

To create an integrated login to a user ID with no password

To use an integrated login

To map an integrated login (Sybase Central)

To map an integrated login (SQL)

To revoke an integrated login permission (Sybase Central)

To revoke an integrated login permission (SQL)

To adjust Adaptive Server Anywhere compression settings

To open a session

To add a server entry

To enter a Server Address

To ping a server

To rename a server entry

To delete a server entry

To change the option settings for TDS connections

To redirect messages to a file using a facility identifier

To create and access a simple XML web service

To set up a simple HTML web service

Create SOAP and DISH services.

To generate and use a JAX-RPC interface for these web services

To set an environment variable (Windows NT)

To set an environment variable (Windows 2000)

To set an environment variable (Windows XP)

To set an environment variable (UNIX)

To create a dbspace (Sybase Central)

To create a dbspace (SQL)

To pre-allocate space (Sybase Central)

To pre-allocate space (SQL)

To delete a dbspace (Sybase Central)

To delete a dbspace (SQL)

To use a write file

To connect to the utility database on the personal server (Interactive SQL)

To connect to the utility database on the network server (Interactive SQL)

To add an event to a database (Sybase Central)

To add an event to a database (SQL)

To add a manually-triggered event to a database (Sybase Central)

To add a manually-triggered event to a database (SQL)

To trigger an event handler (Sybase Central)

To trigger an event handler (SQL)

To debug an event handler

To find the default collation for your machine

To configure your character set environment

To determine the locale of a database server

To set the Adaptive Server Anywhere locale

To specify a database collation when creating a database (Sybase Central)

To specify a database collation when creating a database (command prompt)

To specify a database collation when creating a database (SQL)

To enable character set translation on a database server

To disable character set translation on a database server

To create a custom collation

To create a database with a custom collation

To convert a database from one collation to another, and translate the data's character set (using translation on reload)

To implement a backup and recovery plan

To make a full backup (overview)

To make an incremental backup (overview)

To check the validity of an entire database (Sybase Central)

To check the validity of an entire database (SQL)

To check the validity of an entire database (Command line)

To check the validity of a table (Sybase Central)

To check the validity of a table (SQL)

To validate an online transaction log

To validate an offline or backed up transaction log

To make a backup, continuing to use the original transaction log (Sybase Central)

To make a backup, continuing to use the original transaction log (SQL)

To make a backup, continuing to use the original transaction log (Command line)

To make a backup, deleting the transaction log (Sybase Central)

To make a backup, deleting the transaction log (SQL)

To make a backup, deleting the transaction log (Command line)

To make a backup, renaming the transaction log (Sybase Central)

To make a backup, renaming the transaction log (SQL)

To make a backup, renaming the transaction log (Command line)

To determine which connection has an outstanding transaction (SQL)

To determine which connection has an outstanding transaction (Adaptive Server Anywhere Console utility)

To rename the backup copy of the transaction log (SQL)

To rename the backup copy of the transaction log (Command line)

To make an archive backup to tape (Sybase Central)

To make an archive backup to tape (SQL)

To make a live backup

To recover from media failure on the database file

To recover from media failure on an unmirrored transaction log (partial recovery)

To recover from media failure on a mirrored transaction log

To restart a database using a live backup

To restore a database from an archive backup (Sybase Central)

To restore a database from an archive backup (Interactive SQL)

To recover uncommitted operations from a transaction log (Sybase Central)

To recover uncommitted operations from a transaction log (Command line)

To recover from multiple transaction logs using the -a server option

To recover from multiple transaction logs using the dbtran utility

To change the location of a transaction log (Sybase Central)

To change the location of a transaction log mirror for an existing database (Command line)

To create a database that uses a transaction log mirror (Sybase Central)

To create a database that uses a transaction log mirror (SQL)

To create a database that uses a transaction log mirror (Command line)

To start a transaction log mirror for an existing database (Sybase Central)

To start a transaction log mirror for an existing database (Command line)

To set options for a user or group (Sybase Central)

To set the options for a user or group (SQL)

To create a new user (Sybase Central)

To create a new user (SQL)

To grant RESOURCE authority to a user ID

To grant permissions on tables or columns (Sybase Central)

To grant permissions on tables or columns (SQL)

To grant permissions on views (Sybase Central)

To grant permissions on procedures (Sybase Central)

To grant permissions on procedures (SQL)

To grant remote permissions to users (Sybase Central)

To revoke remote permissions from remote users

To delete a user from the database (Sybase Central)

To delete a user from the database (SQL)

To display a list of all users connected to a database

To inspect the properties of a user's connection to a database

To disconnect users from a database

To create a new group (Sybase Central)

To create a new group (SQL)

To add a user or group to another group (Sybase Central)

To add a user or group to another group (SQL)

To remove a user or group from another group (Sybase Central)

To remove a user or group from another group (SQL)

To delete a group from the database (Sybase Central)

To delete a group from the database (SQL)

Create the primary site database

Create the replicate site database

Start the primary site database server

Start the replicate site database server

Run the rssetup script

To change the maintenance user ID and password

To change the system administrator user ID and password

To run the setup script

To determine the character set

To stop the LTM in Windows NT/2000/XP, when the LTM is not running as a service

To stop the LTM by issuing a command

To disconnect a user from a database

To back up a database file or a running database

To use the Create Custom Collation wizard

To compress a database file

To erase a database file

To hide the contents of .ini files

To create a database

To open Interactive SQL from Sybase Central

To translate a transaction log into a command file

To create a service

To change a transaction log file name

To uncompress a compressed database file

To unload a database file or a running database

To upgrade a database

To upgrade a database created with a version of Adaptive Server Anywhere that is too old to be upgraded

To validate a database

To validate a running database

To validate an individual table

To create a write file for a database

To access connection properties

To access database properties

To access database server properties

To retrieve the value of a connection property

To retrieve the values of all connection properties

To retrieve the value of a server property

To retrieve the values of all server properties

To retrieve the value of a database property

To retrieve the values of all database properties

To identify the entities in your design and their relationship to each other

To identify the required data

To normalize data in a database

To create a new database (Sybase Central)

To create a new database based on a current connection

To create a new database (SQL)

To create a new database (command line)

To erase a database (Sybase Central)

To erase a database (SQL)

To erase a database (command line)

To disconnect from a database (Sybase Central)

To disconnect from a database (SQL)

To disconnect other users from a database (SQL)

To view and edit the properties of a database object (Sybase Central)

To set options for a database (Sybase Central)

To set the options for a database (SQL)

To set a consolidated database (Sybase Central)

To display system objects in a database (Sybase Central)

To log SQL statements generated by Sybase Central

To start a database on a server without connecting (Sybase Central)

To start a database on a server without connecting (SQL)

To add jConnect metadata support to an existing database (Sybase Central)

To create a table (Sybase Central)

To create a table (SQL)

To alter an existing table (Sybase Central)

To alter an existing table (SQL)

To delete a table (Sybase Central)

To delete a table (SQL)

To create and edit the primary key (Sybase Central)

To modify the primary key of an existing table (SQL)

To create a new foreign key in a given table (Sybase Central)

To delete a foreign key (Sybase Central)

To display which tables have foreign keys that reference a given table (Sybase Central)

To modify the foreign key of an existing table (SQL)

To display system tables (Sybase Central)

To browse system tables (SQL)

To create a new view (Sybase Central)

To create a new view (SQL)

To create a view displaying the employees in the sales department (SQL)

To edit a view definition (Sybase Central)

To edit a view definition (SQL)

To delete a view (Sybase Central)

To delete a view (SQL)

To create a new index for a given table (Sybase Central)

To create a new index for a given table (SQL)

To validate an index (Sybase Central)

To validate an index (SQL)

To validate an index (command line)

To drop an index (Sybase Central)

To drop an index (SQL)

To start the Index Consultant (Sybase Central)

To start the Index Consultant (Interactive SQL)

To display the property sheet for a column

To manage constraints

To create a new domain (Sybase Central)

To assign domains to columns (Sybase Central)

To create a new domain (SQL)

To delete a domain (Sybase Central)

To delete a domain (SQL)

To set the isolation level for the current user ID

To set the isolation level for a user or group

To set the isolation level just for your present session

To view the isolation level for the current connection

To use deadlock reporting

To filter according to a connection

To filter according to a database

To reset filtering

To include host variable values

To open the Performance Monitor

To add statistics to the Sybase Central Performance Monitor

To remove statistics from the Sybase Central Performance Monitor

To choose a graph type

To set the update interval

To use the Windows Performance Monitor in Windows NT

To eliminate file fragmentation problems

To defragment all the tables in a database

To defragment individual tables

To enable profiling (Sybase Central)

To enable profiling (SQL)

To filter procedure profiling by user

To reset profiling (Sybase Central)

To reset profiling (SQL)

To disable profiling (Sybase Central)

To disable profiling (SQL)

To clear profiling (Sybase Central)

To clear profiling (SQL)

To view summary profiling information for stored procedures and functions

To view summary profiling information for events

To view summary profiling information for triggers

To view summary profiling information for system triggers

To view the profiling information for a stored procedure or function

To view profiling information for an event

To view profiling information for triggers

To view profiling information for system triggers

To view summary profiling information for all procedures

To view profiling information for specific lines within procedures

To list all the products with prices between $10 and $15, inclusive

To list all the products cheaper than $10 or more expensive than $15

To set the quoted_identifier option off for the current user ID

To create a Transact-SQL compatible database (Sybase Central)

To create a Transact-SQL compatible database (Command line)

To create a Transact-SQL compatible database (SQL)

To drop the Adaptive Server Anywhere system views from an existing database

To translate a stored procedure using Sybase Central

To write a FOR XML EXPLICIT query

To import data (Interactive SQL Data menu)

To import data into the sample database

To import data (Interactive SQL INPUT statement)

To import data (INSERT statement)

To import a table (Interactive SQL Data menu)

To import a table (Interactive SQL)

To load data with a different structure using a global temporary table

To export result sets data using Interactive SQL

To unload tables using the Unload Data dialog

To export query results (Interactive SQL Data menu)

To export query results (Interactive SQL OUTPUT statement)

To export query results (UNLOAD statement)

To unload all or part of a database (Sybase Central)

To unload all or part of a database (Command line)

To specify NULL value output (Interactive SQL)

To export a table (Command line)

To export a table (SQL)

To rebuild a database not involved in replication (Command line)

To rebuild a database involved in replication (dbunload utility)

To rebuild a database involved in replication, with manual intervention

To export table data or table schema (Command line)

To reload a database (Command line)

To minimize the downtime during a rebuild

To import remote tables (Sybase Central)

To import remote tables (single step)

To import remote tables (with modifications)

To run a command file immediately

To run a command file using the SQL Statements pane

To run a command file in batch mode

To load commands from a file into the SQL Statements pane

To create a proxy table

To create a remote server (Sybase Central)

To delete a remote server (Sybase Central)

To delete a remote server (SQL)

To alter the properties of a remote server (Sybase Central)

To alter the properties of a remote server (SQL)

To create an external login (Sybase Central)

To create an external login (SQL)

To delete an external login (Sybase Central)

To delete an external login (SQL)

To create a proxy table (Sybase Central)

To create a proxy table with the CREATE EXISTING TABLE statement (SQL)

To create a proxy table with the CREATE EXISTING TABLE statement (SQL)

To perform a join between two remote tables (SQL)

To issue a remote procedure call (Sybase Central)

To issue a remote procedure call (SQL)

To delete a remote procedure (Sybase Central)

To delete a remote procedure (SQL)

To create a new procedure (Sybase Central)

To create a new remote procedure (Sybase Central)

To create a procedure using a different tool

To alter the code of a procedure (Sybase Central)

To alter the code of a procedure (SQL)

To delete a procedure (Sybase Central)

To delete a procedure (SQL)

To run this procedure and display its output (SQL)

To create this example using Interactive SQL

To create a trigger for a given table (Sybase Central)

To create a trigger for a given table (SQL)

To alter the code of a trigger (Sybase Central)

To alter the code of a trigger (SQL)

To delete a trigger (Sybase Central)

To delete a trigger (SQL)

To list the names of all employees

To return the number of orders placed by a given customer

To enable multiple result set functionality

To start the debugger

To run the debugger_tutorial stored procedure

To diagnose the bug

To test the hypothesis

To fix the bug

To display Java source code in the debugger

Set a breakpoint in a Java class

Invoke the method from Interactive SQL

To inspect and modify the value of a variable

To set a breakpoint

To set a breakpoint (Debug menu)

To set a condition on a breakpoint

To change the status of a breakpoint

To change the status of a breakpoint (Breakpoints window)

To add a condition or count to a breakpoint

To watch the values of your variables

To display the call stack

To use a prepared statement (generic)

To use a prepared statement (embedded SQL)

To use a prepared statement (ODBC)

To use a prepared statement (ADO.NET)

To use a prepared statement (JDBC)

To use a prepared statement (Open Client)

To use a cursor (embedded SQL)

To use a cursor (ODBC, ADO.NET, JDBC, Open Client)

To loop through the rows of a result set

To control autocommit mode (ODBC)

To control autocommit mode (ADO.NET)

To control autocommit mode (JDBC)

To control autocommit mode (Open Client)

To control autocommit mode (embedded SQL)

To create and compile the class

To install the class to the sample database (Sybase Central)

To install the class to the sample database (Interactive SQL)

To create stored procedures/functions for the methods in the class

To Java-enable the sample database

To add the JDBCExamples class to the sample database

To add the Java runtime classes to a database (Sybase Central)

To add the Java runtime classes to a database (SQL)

To create a class

To install a class (Sybase Central)

To install a class (SQL)

To install a JAR (Sybase Central)

To install a JAR (SQL)

To update a class or JAR (Sybase Central)

To update a class or JAR (SQL)

To call the main method of a class from SQL

To return result sets from a Java method

To permit file access using the default security manager

To provide your own security manager

To add jConnect system objects to a database (Sybase Central )

To add jConnect system objects to a database (Interactive SQL)

To create and execute the external connection example application

To create and execute the internal connection example application

To install the JDBCExamples class

To run the JDBC Insert example

To use a Java method with arguments

To load the interface DLL dynamically

To create an embedded SQL NLM

To run the static cursor sample program

To run the dynamic cursor sample program

To run one of the compiled examples as a Windows service

To manage multiple SQLCAs in your application

To manage a cursor in embedded SQL

To receive a LONG VARCHAR or LONG BINARY value (static SQL)

To receive a value into a LONGVARCHAR or LONGBINARY structure (dynamic SQL)

To send a LONG VARCHAR or LONG BINARY value (static SQL)

To send a value using a LONGVARCHAR or LONGBINARY structure (dynamic SQL)

To include the ODBC header file in a C source file

To link an ODBC application (Windows)

To link an ODBC application (Windows CE)

To link an ODBC application (UNIX)

To build the sample ODBC program

To run the ODBC sample

To run the ODBC sample as a Windows service

To use an ODBC handle

To establish an ODBC connection

To execute a SQL statement in an ODBC application

To execute a SQL statement with bound parameters in an ODBC application

To execute a prepared SQL statement

To assign the current version number to a structure

To register the OLE DB provider

To run the Simple code sample in Visual Studio .NET

To run the Table Viewer code sample in Visual Studio .NET

To add a reference to the Adaptive Server Anywhere .NET data provider in a Visual Studio .NET project

To reference the data provider classes in your code

To connect to an Adaptive Server Anywhere database

To issue a command that returns a complete result set

To issue a command that returns only one value

To issue a command that inserts a row

To issue a command that updates a row

To issue a command that deletes a row

To obtain information about a result set using the GetSchemaTable method

To retrieve data using the AsaDataAdapter object

To insert rows into a table using the AsaDataAdapter

To update rows using the AsaDataAdapter object

To delete rows from a table using the AsaDataAdapter object

To obtain DataSet schema information using the FillSchema method

To insert a new row with an autoincremented primary key using the AsaCommand object

To insert a new row with an autoincremented primary key using the AsaDataAdapter object

To issue a command that returns a string using the GetChars method

To convert a time value using the GetTimeSpan method

To execute a stored procedure

To use an AsaTransaction object to issue a command

To use a prepared statement in Open Client

To use cursors in Open Client

To modify rows through a cursor

To prepare your machine

To install the DBI Perl module on Windows

To install DBD::ASAny on Windows

To prepare your machine

To install the DBI Perl module on UNIX

To install DBD::ASAny on UNIX

To install the PHP module on UNIX or Mac OS X

To install the PHP module on Windows

To create a PHP information test page

To create the query page that uses the SQLAnywhere PHP module

To view your web pages

To configure an EAServer to use the Microsoft DTC transaction model

To set the transaction attribute of a component

To download the International Resources Deployment Kit from the Sybase Web site

To create a silent install

To use a silent install

To turn on auditing

To retrieve auditing information from a running database server

To retrieve auditing information from a transaction log file

To use simple encryption

To create a strongly encrypted database (SQL)

To create a strongly encrypted database (command prompt)

To install and set up the operating system

To install Adaptive Server Anywhere 7.0.0

To create a C2 compliant database

To start auditing on a particular database

To stop (disable) auditing on a particular database

To revoke DBA authority from a connected user

To start the MobiLink synchronization server

To implement timestamp-based synchronization for a table

To implement snapshot-based synchronization

To partition a table among remote databases

To use global autoincrement columns

To set the global database identification number

To implement a primary key pool

To add tables to Adaptive Server Anywhere remote databases

To alter a published table in a deployed Adaptive Server Anywhere remote database

To start monitoring data

To stop the MobiLink Monitor

To export the data to a database or Excel

To create a new watch

Overview of the configuration process

To configure MobiLink clients (Adaptive Server Anywhere and UltraLite)

To configure MobiLink servers

To configure Redirector properties

To configure the NSAPI Redirector for Sun One

To test your configuration

To configure ISAPI Redirector for Microsoft web servers

To test your configuration

To install the servlet Redirector in Tomcat

To configure the Apache web server as a proxy

To check your configuration

To configure the Apache Redirector

To test your configuration

To configure the M-Business Anywhere Redirector

To test your configuration

To run the UNIX MobiLink server as a daemon

To add a new service (Sybase Central)

To remove a service (Sybase Central)

To change the parameters for a service

To start, stop, or pause a service

To check and change which group a service belongs to

To add a service or group to a list of dependencies

To configure your UltraLite client to use transport-layer security over HTTPS

To configure your UltraLite client to use transport-layer security over TCP/IP

To add a script version to a database (Sybase Central)

To remove a script version from a database (Sybase Central)

To add a script version to a database (stored procedures)

To add or delete a connection script (Sybase Central)

To add or delete a remote table in the list of synchronized tables (Sybase Central)

To add or delete a table script in a database (Sybase Central)

To add or delete all types of scripts (stored procedures)

To test your synchronization scripts

To implement synchronization scripts in Java

To implement synchronization scripts in .NET

To debug .NET scripts

To handle rows uploaded to the consolidated database

To provide an initial MobiLink password for a user (Sybase Central)

To provide initial MobiLink passwords (command line)

To prompt your end users to enter their MobiLink passwords

To prompt your end users to enter MobiLink passwords

To use predefined scripts directly in authenticate_user

To create an Adaptive Server Anywhere remote database

To deploy MobiLink remote databases by customizing a prototype

To publish one or more entire tables (Sybase Central)

To publish one or more entire tables (SQL)

To publish only some columns in a table (Sybase Central)

To publish only some columns in a table (SQL)

To create a publication using a WHERE clause (Sybase Central)

To create a publication using a WHERE clause (SQL)

To modify the properties of existing publications or articles (Sybase Central)

To add articles (Sybase Central)

To remove articles (Sybase Central)

To modify an existing publication (SQL)

To delete a publication (Sybase Central)

To delete a publication (SQL)

To add a MobiLink user to a remote database (Sybase Central)

To add a MobiLink user to a remote database (SQL)

To store MobiLink extended options in the database (Sybase Central)

To store MobiLink extended options in the database (SQL)

To configure MobiLink user properties on the command line

To specify MobiLink user properties with a client event hook

To drop a MobiLink user from a remote database (Sybase Central)

To drop a MobiLink user from a remote database (SQL)

To alter a synchronization subscription (Sybase Central)

To alter a synchronization subscription (SQL)

To delete a synchronization subscription (Sybase Central)

To delete a synchronization subscription (SQL)

To override an extended option on the dbmlsync command line

To set an extended option for a subscription, publication or user

To configure your Adaptive Server Anywhere remote database for ActiveSync

To install the MobiLink provider for ActiveSync

To register the Adaptive Server Anywhere client for use with ActiveSync

To temporarily disable upload of deletes made through a connection

To add scheduling to the synchronization subscription

To add scheduling from the dbmlsync command line

To set up the Dbmlsync Integration Component in a Windows application

To set up the Dbmlsync Integration Component in a console application (Visual Basic.NET)

To configure and start dbmlsync using the DBTools interface

To add synchronization to an UltraLite application

To synchronize subsets of data from an UltraLite database

To publish data from an UltraLite database (Schema Painter)

To publish data from an UltraLite reference database (Sybase Central)

To publish data from an UltraLite reference database (SQL)

To install and configure the MobiLink HotSync conduit

To deploy the conduit installation utility

To register the MobiLink HotSync conduit to HotSync Manager

To check that the HotSync conduit is properly installed

To configure the MobiLink HotSync conduit for synchronization

To synchronize using HTTP or HTTPS

To configure a Palm device for RAS TCP/IP via a modem

To configure Windows NT for RAS TCP/IP via serial port

To configure a Palm device for RAS TCP/IP via serial port

To test the connection

To install the MobiLink provider for ActiveSync

To register an application for use with ActiveSync

To deploy ActiveSync applications

Overview of setting up server-initiated synchronization

To set up device tracking

To manually set up device tracking

Set up the consolidated database and Notifier utility

Set up the remote database and Listener utility

Issue push requests

To create and start a new Adaptive Server Anywhere consolidated database

To add the Dealer table and download_cursor synchronization script

To create a table for push requests

To configure the Notifier utility

To define an ODBC data source for the consolidated database

To run the MobiLink synchronization server (dbmlsrv9)

To create and start a new Adaptive Server Anywhere remote database

To generate the remote database schema

To create and start the MobiLink Listener

To insert a push request directly into the PushRequest table prompting server-initiated synchronization

To make a change in the consolidated database Dealer prompting server-initiated synchronization

To create your database files

To create ODBC data sources

To create your schema

To start the MobiLink synchronization server

To start the MobiLink synchronization client

To remove tutorial materials from your computer

To create your Adaptive Server Anywhere RDBMS

To add the Product table to the consolidated schema

To define an ODBC data source for the consolidated database

To create and start Adaptive Server Anywhere remote databases

To migrate a subset of your consolidated database schema to remote1

To create a remote synchronization publication, synchronization user, and synchronization subscription

To add a script version

To add synchronized tables to your consolidated database

To add table scripts for the Product table

To run the synchronizations for remote1 and remote2

To find errors in a MobiLink synchronization log file

To detect errors in your MobiLink synchronization client log file

To install scripts for conflict detection and resolution

To configure the MobiLink Monitor to detect update conflicts.

To generate an update conflict

To detect the update conflict using the MobiLink Monitor

To remove tutorial materials from your computer

To create your databases

To set up an ODBC data source for Oracle

Create MobiLink system tables within Oracle

To verify that the system tables are installed

To drop the MobiLink system tables

To initialize your remote database

To create an ODBC data source for the remote database

To create and populate tables in the consolidated database

To create tables and synchronization information in the remote database

To start the MobiLink synchronization server

To start the MobiLink client

To create CustdbScripts.java

To compile the Java class (Windows)

To specify CustdbScripts.UploadInsert for the ULCustomer upload_insert event

To specify CustdbScripts.DownloadCursor for the ULCustomer download_cursor event

To start the MobiLink server (dbmlsrv9) and load Java assemblies

To start and synchronize the sample application

To add an order

To synchronize with the consolidated database and trigger the upload_insert event

To remove tutorial materials from your computer

To create the CustdbScripts assembly using Visual Studio .NET

To create the CustdbScripts assembly using the command line

To subscribe CustdbScripts.uploadInsert() to the upload_insert event for the ULCustomer table

To specify MLExample.CustdbScripts.DownloadCursor for the ULCustomer download_cursor event

To start the MobiLink server (dbmlsrv9) and load .NET assemblies

To start and synchronize the sample application

To add an order

To synchronize with the consolidated database and trigger the upload_insert event

To remove tutorial materials from your computer

To build the Contact sample

To run the Contact sample

To set up a consolidated database (Adaptive Server Enterprise, Oracle or SQL Server)

To set up a consolidated database (Adaptive Server Anywhere)

To set up a consolidated database (IBM DB2)

To install the sample application to a remote device

To reset the data in the sample application

To set up and run QAnywhere messaging

Start the messaging server

Create a client message store

Start the QAnywhere Agent with the TestMessage client message store

Start TestMessage

Send a message from TestMessage

Prepare your JMS provider

Start QAnywhere client and server compnents

Start the TestMessage client

Overview of setting up QAnywhere server-side components

Overview of setting up client-side components

To create a client message store

Overview of integrating a QAnywhere application with an external JMS system

To build a client application (C++ or .NET)

To initialize the QAnywhere client API (C++)

To add a reference to the QAnywhere .NET API in a Visual Studio .NET project

To reference the QAnywhere .NET API classes in your code

To initialize the QAnywhere client API (.NET)

To send a message (C++)

To send a message (.NET)

To receive messages synchronously (C++)

To receive messages synchronously (.NET)

To receive messages asynchronously (C++)

To receive messages asynchronously (.NET)

To create a transactional manager (C++)

To send multiple messages in a single transaction (C++)

To shut down QAnywhere (C++)

To shut down QAnywhere (.NET)

To install the SQL Remote software ( Windows )

To install the SQL Remote software ( UNIX )

To install the SQL Remote system objects

To install the stable queue

To upgrade SQL Remote

To uninstall the SQL Remote objects from a database

To uninstall the stable queue from a database

To prepare for the tutorial

To add tables to the consolidated database

To add an address to a message type

To create a new user as the publisher

To add a remote user

To add a publication

To add a subscription

To extract a database

To create the databases and directories for the tutorial

To add the tables to the consolidated database

To create the message type

To create a publisher for the database

To add a remote user

To create the publication

To create the subscription

To load the database information

To enter data at the consolidated database

To send the data to the remote database

To receive data at the remote database

To verify that the data has arrived

To replicate data from the remote database to the consolidated database

To add the publication to the sample database

To create a database

To install SQL Remote into the hq database

To add tables to the consolidated database

To create the message type

To create the publisher

To create the subscriber

To create the publication

To create a subscription

To create a database file named field.db

To load the data into the database using Interactive SQL

To load the data into the database as a batch process

To enter data at the Adaptive Server Enterprise database

To replicate the data from Adaptive Server Enterprise

To receive the data at Adaptive Server Anywhere

To verify that the data has arrived

To replicate data from the remote database to the consolidated database

To create an Enterprise-compatible Adaptive Server Anywhere database ( Sybase Central )

To create an Enterprise-compatible Adaptive Server Anywhere database ( Command line )

To find the dateformat settings on an Adaptive Server Enterprise database

To set the Replication_error option in Adaptive Server Anywhere

To set the Replication_error option in Adaptive Server Enterprise

To publish one or more entire tables (Sybase Central)

To publish one or more entire tables (SQL)

To publish only some columns in a table (Sybase Central)

To publish only some columns in a table (SQL)

To create a publication using a WHERE clause (Sybase Central)

To create a publication using a WHERE clause (SQL)

To create an article using a subscription expression (Sybase Central)

To create an article using a subscription expression (SQL)

To modify the properties of existing publications or articles (Sybase Central)

To add articles (Sybase Central)

To remove articles (Sybase Central)

To modify an existing publication (SQL)

To delete a publication (Sybase Central)

To delete a publication (SQL)

To set the global database identification number

To replicate the primary key pool (SQL)

To create and manage subscriptions in Sybase Central

To create an article that includes all the rows and columns of a table

To create an article that includes some of the columns and all the rows of a table

To create an article using a WHERE clause

To create an article using a subscription column

To create a subscription view

To customize the extraction procedure to omit certain triggers

To create a subscription view

To test the example

To test the example

To replicate the primary key pool

To test the primary key pool

To create a remote database from the reload file

To extract a database for a remote user (Sybase Central)

To create a new user as the publisher (Sybase Central)

To make an existing user the publisher (Sybase Central)

To revoke PUBLISH permissions (Sybase Central)

To add a new user to the database as a remote user (Sybase Central)

To make an existing user remote (Sybase Central)

To revoke REMOTE permissions (Sybase Central)

To add a message type (Sybase Central)

To alter a message type (Sybase Central)

To drop a message type (Sybase Central)

To create a message type (SQL)

To alter a message type (SQL)

To drop a message type (SQL)

To set a message control parameter (Adaptive Server Anywhere)

To set a message control parameter (Adaptive Server Enterprise)

To run the Message Agent in continuous mode

To run the Message Agent in batch mode

To configure a remote database to send log information to the consolidated database

To configure a consolidated site to receive log information

To recover the database

To recover from media failure on the C drive

To recover the database

To recover from media failure on the C drive

To unload and reload a consolidated database (manual)

To prepare your SQL Remote setup, if you have an existing SQL Remote installation

To prepare your SQL Remote setup, with no existing installation

To set up the SQL Remote Open Server

To extract a remote database from a running database (Sybase Central)

To extract a remote database from a database file or a running database (Sybase Central)

To start the ODBC Administrator (Windows)

To start the ODBC Administrator (command line)

To configure a Sybase Adaptive Server Enterprise data source (UNIX)

To configure a Sybase Adaptive Server Enterprise data source (Windows)

To configure an Oracle data source

To bind a package (UNIX)

To configure a DB2 Wire Protocol data source (Windows)

To develop an UltraLite component application

To start the MobiLink synchronization server

To start and synchronize the sample application

To add an order

To approve, deny, and delete orders

To synchronize your changes

To confirm the synchronization at the consolidated database

To browse the synchronization scripts

To create an UltraLite database (UltraLite components)

To create an UltraLite database (static interface)

To add user authentication to your application

To prompt for a new MobiLink or UltraLite password

To deploy a new schema (UltraLite components)

To deploy a new schema (embedded SQL and Static C++ API)

To use the UltraLite engine

To start the UltraLite Schema Painter

To create a new schema file

To save a file

To export a Palm schema file

To clear all of the old names in the schema file after deployment

To manually change object names

To create a schema file

To create an UltraLite database file

To create a publication holding the Customer table

To define synchronization settings

To generate the consolidated database table and script definitions

To create a consolidated database

To enter data in your UltraLite database

To synchronize your databases

To create a reference database

To create a reference database from a non-Adaptive Server Anywhere database

To create an UltraLite project (Sybase Central)

To create an UltraLite project (SQL)

To create an UltraLite project (embedded SQL)

To add a SQL statement to an UltraLite project (Sybase Central)

To add a SQL statement to an UltraLite project (SQL)

To add a SQL statement to an UltraLite project (embedded SQL)

To add the UltraLite connection parameters control

To add a reference to UltraLite for MobileVB

To add UltraLite references and controls to your Crossfire project

To connect to an UltraLite database using ULConnectionParms

To INSERT a row

To UPDATE a row

To DELETE a row

To perform a SELECT statement

To search for a row

To update a row

To insert a row

To delete a row

To add a user or change the password for an existing user

To delete an existing user

To synchronize over TCP/IP or HTTP

To add a synchronization template to your application (MobileVB)

To add a synchronization template to your application (Crossfire)

To create an UltraLite database schema

To add the UltraLite connection parameters control

To create a reference to the UltraLite for MobileVB control

To add controls to your project

Write code to connect to the UltraLite database

To open the table

To insert rows into the table

To move through the rows of the table

To update and delete rows in the table

To write code for the synchronize button

To synchronize your application

To deploy to a PocketPC device

To deploy to the Palm device

To create an UltraLite database schema

To create a Crossfire project for UltraLite

To add controls to your project

Write code to connect to the UltraLite database

To open the table

To insert rows into the table

To move through the rows of the table

To update and delete rows in the table

To write code for the synchronize button

To synchronize your application

To deploy to a PocketPC device

To deploy to the Palm device

To add a reference to UltraLite ActiveX

To add the UltraLite ActiveX control to Windows CE

To deploy a schema file to Windows CE

To connect to an UltraLite database using ULConnectionParms

To INSERT a row

To UPDATE a row

To DELETE a row

To perform a SELECT statement

To search for a row

To update a row

To insert a row

To delete a row

To add a user or change the password for an existing user

To delete an existing user

To synchronize over TCP/IP or HTTP

To add a synchronization status dialog to your project (eMbedded Visual Basic)

To create an UltraLite database schema

To create a reference to the UltraLite ActiveX control

To add controls to your project

To add UltraLite ActiveX to the emulator

To deploy the database schema file to the emulator

Write code to connect to the UltraLite database

To open the table

To insert rows into the table

To move through the rows of the table

To update and delete rows in the table

To write code for the synchronize button

To synchronize your application

To add the UltraLite ActiveX control to your device

To deploy the database schema file to your device

To deploy your application to a remote device

To deploy using the Application Install Wizard

To register the UltraLite ActiveX control

To copy the HTML files to your device

To create the database schema

To deploy the database schema to your device

To add controls to your project

To connect to the UltraLite database

To synchronize the sample database

To scroll through the list of orders

To add an order to the database

To approve or deny an order

To create a database schema

To connect to an UltraLite database

To add rows to your database

To list the rows in the table

To confirm that the Jeode VM is installed on your Windows CE device

To prepare your application to run on a Windows CE device

To deploy the UltraLite runtime to the Windows CE device

To run the application

To add synchronization to your application

To synchronize your data

To build the sample

To run the sample on Windows

To deploy the application to a Windows CE device

To run the application

To connect to an UltraLite database

To INSERT a row

To UPDATE a row

To DELETE a row

To execute a SELECT statement

To search for a row

To update a row

To delete a row

To add a user or change a password for an existing user

To delete an existing user

To set the JDK version

To add UltraLite features to a JBuilder project

To create a Visual Studio project

To create a schema file

To add an UltraLite connection to your application

To add code to maintain the listbox

To implement INSERT, UPDATE and DELETE

To deploy your application

To test your application

To connect to an UltraLite database

To INSERT a row

To UPDATE a row

To DELETE a row

To execute a SELECT statement

To search for a row

To update a row

To delete a row

To add a user or change a password for an existing user

To delete an existing user

To install and run M-Business Anywhere samples

To verify your setup

To connect to an UltraLite database using ConnectionParms

To INSERT a row

To UPDATE a row

To DELETE a row

To perform a SELECT statement

To search for a row

To update a row

To insert a row

To delete a row

To add a user or change the password for an existing user

To delete an existing user

To synchronize over TCP/IP or HTTP

To synchronize data via M-Business Anywhere

To create an UltraLite database schema

Create the application files

Configure M-Business Anywhere

Synchronize the channel for your device

Add content to your application

Open the table

Add code to insert rows

Test your application

Add navigation code to your application

Add update and delete functions to your application

Add a synchronization function to your application

To synchronize your application

To connect to an UltraLite database

To INSERT a row

To UPDATE a row

To DELETE a row

To execute a SELECT statement

To search for a row

To update a row

To delete a row

To commit a transaction

To roll back a transaction

To add a user or change a password for an existing user

To delete an existing user

To enable user authentication (Static C++ API)

To strongly encrypt an UltraLite database

To change the encryption key on an UltraLite database

To obfuscate an UltraLite database

To add synchronization to your application

To initialize the synchronization parameters (Static C++ API)

To invoke synchronization (TCP/IP, HTTP, or HTTPS streams)

To invoke synchronization (HotSync)

To generate UltraLite code for a publication

To generate UltraLite code for a UltraLite project

To generate UltraLite code for both a project and a publication

To manage multiple SQLCAs in your application

To manage a cursor in embedded SQL

To enable user authentication (embedded SQL)

To strongly encrypt an UltraLite database

To change the encryption key on an UltraLite database

To obfuscate an UltraLite database

To add synchronization to your application

To initialize the synchronization parameters (embedded SQL)

To invoke synchronization (TCP/IP, HTTP, or HTTPS streams)

To invoke synchronization (HotSync)

To build an UltraLite embedded SQL application

To build an UltraLite application (one embedded SQL file only)

To add embedded SQL preprocessing into a dependency-based development tool

To add UltraLite code generation into a dependency-based development environment

To share a single SQLCA

To share a single connection

To defragment an UltraLite database

To install the UltraLite plug-in for CodeWarrior

To create an UltraLite project in CodeWarrior

To build the CustDB sample application using CodeWarrior

To use the expanded mode runtime library from the UltraLite plug-in

To enable multi-segment code generation

To explicitly assign generated statement code to segments (embedded SQL)

To explicitly assign generated statement code to segments (static C++ API)

To assign user-defined code to segments (CodeWarrior)

To install an application on a Palm device

To build and deploy an application using the UltraLite runtime DLL

To build the CustDB sample application

To build and deploy an application using the UltraLite runtime DLL

To assign a window class name for MFC applications using eMbedded Visual C++

To add ActiveSync synchronization in the main dialog class

To add ActiveSync synchronization in the Application class

To create a database schema

To connect to an UltraLite database

To add rows to your database

To list the rows in the table

To add synchronization to your application

To synchronize your data

To deploy to a Windows CE device

To prepare a tutorial directory

To copy the sample database

To create the UltraLite database template

To generate the UltraLite interface code

To write the application source code

To add synchronization to your application

To restore the sample database

To prepare for the tutorial

To configure eMbedded Visual C++ for UltraLite development

To build the sample embedded SQL UltraLite application

To build the sample embedded SQL UltraLite application

To synchronize your application

Create and test your build environment

Create a database schema

Write code to allocate an environment handle

Write code to connect to your database

Write code to insert data into the database

Write code to query the database

To prepare a tutorial directory

To add the SQL statements to the reference database

To generate the UltraLite database code

To build your application

To run your application

To add synchronization to your application

To finish the tutorial

To build the UltraLite Static Java sample

To prepare to run the sample

To run the sample as an application

To run the sample as an applet using appletviewer

To run the sample as an applet using A Web browser

To enable user authentication

To obfuscate an UltraLite database

To strongly encrypt an UltraLite database

To change the encryption key on an UltraLite database

To defragment an UltraLite database

To add synchronization to your application

To initialize the synchronization parameters

To invoke synchronization (TCP/IP, HTTP, or HTTPS streams)

To run the UltraLite generator

To compile the generated file

To install SNMP

To check that the SNMP services are installed on your computer

To restart the SNMP service (Control Panel)

To restart the SNMP service (Command line)

To restart the SNMP service (Control Panel)

To restart the SNMP service (Command line)

To restart the Adaptive Server Anywhere SNMP Extension Agent

To configure the SNMP service


Tutorials

Tutorial: Using the database server on Windows CE

Tutorial: Managing Windows CE databases with Sybase Central

Tutorial cleanup

Tutorial: Managing Windows CE databases with Interactive SQL

Tutorial cleanup

Tutorial: Developing a Visual Basic application

Tutorial: Accessing web services from Java JAX-RPC

Tutorial: Replicate data using Replication Server

Tutorial: Getting started with the debugger

Tutorial: A Java in the database exercise

Tutorial: Using the Simple code sample

Tutorial: Using the Table Viewer code sample

Tutorial: Server-Initiated Synchronization

Tutorial overview

Tutorial: Introduction to MobiLink

Tutorial: Writing MobiLink Scripts and Monitoring Synchronizations

Tutorial cleanup

Tutorial: Using MobiLink with an Oracle 8i Consolidated Database

Tutorial: Java Synchronization Logic With Adaptive Server Anywhere

Tutorial: .NET Synchronization Logic With Adaptive Server Anywhere

Tutorial: A Sample QAnywhere Application

Tutorial cleanup

Tutorials for Adaptive Server Anywhere Users

Tutorial: Adaptive Server Anywhere replication using Sybase Central

Tutorial: Adaptive Server Anywhere replication using Interactive SQL and dbxtract

Tutorial: Adaptive Server Enterprise replication

Tutorial: The CustDB Sample UltraLite Application

Tutorial: Working with UltraLite Databases

Tutorial: A Sample UltraLite for MobileVB Application

Tutorial: A Sample Application for AppForge Crossfire

Tutorial: A Sample UltraLite ActiveX Application

Tutorial: An UltraLite ActiveX Application for Pocket IE

Tutorial: Build a Native UltraLite for Java Application

Tutorial: The CustDB Sample Application

Tutorial: Build an UltraLite.NET Application

Tutorial: A Sample Application for M-Business Anywhere

Tutorial: Build an Application Using the C++ Component

Tutorial: Build an Application Using the Static C++ API

Tutorial: Build an Application Using Embedded SQL

Tutorial: Build an Application Using ODBC

Tutorial: Build an Application Using Java